@mkbabb/glass-ui 6.0.0 → 7.0.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 (910) hide show
  1. package/README.md +36 -34
  2. package/dist/DropdownMenuTrigger-ClIq8RJE.js +93 -0
  3. package/dist/FeedbackMark-DZq5001h.js +23 -0
  4. package/dist/Input-9BlLluik.js +77 -0
  5. package/dist/{PagerDots-BoTQ7g5l.js → PagerDots-BEq0MgtH.js} +85 -81
  6. package/dist/Surface-kFQeYrYv.js +82 -0
  7. package/dist/accent-tone-solve-Cw7WkRD9.js +14 -0
  8. package/dist/animated-digit.js +5 -5
  9. package/dist/asElement-CRnm6A2v.js +9 -0
  10. package/dist/aurora.js +831 -776
  11. package/dist/axes.js +25 -14
  12. package/dist/badge-u65NClWn.js +62 -0
  13. package/dist/badge.js +1 -1
  14. package/dist/blob-config.js +1 -1
  15. package/dist/blob.js +442 -395
  16. package/dist/button-Bu9F4uU6.js +98 -0
  17. package/dist/button.js +2 -2
  18. package/dist/canvas.js +1 -1
  19. package/dist/card-Bk96VI2R.js +234 -0
  20. package/dist/card.js +2 -2
  21. package/dist/carousel.js +109 -169
  22. package/dist/chip-DFZQr6rV.js +129 -0
  23. package/dist/chip.js +2 -81
  24. package/dist/{class-names-5jotTFzp.js → class-names-Cpy5eaBk.js} +11 -4
  25. package/dist/collapsible-BAP95XTt.js +154 -0
  26. package/dist/collapsible.js +1 -1
  27. package/dist/color.js +46 -50
  28. package/dist/{procedural-color.wgsl-B9mLK7v0.js → color.wgsl-Ct5o9dpf.js} +155 -121
  29. package/dist/command-SFqDQ65h.js +320 -0
  30. package/dist/command.js +1 -1
  31. package/dist/completion-seal.js +54 -54
  32. package/dist/components/_shared/FeedbackMark.vue.d.ts +11 -0
  33. package/dist/components/_shared/axes.d.ts +9 -3
  34. package/dist/components/_shared/class-names.d.ts +9 -8
  35. package/dist/components/_shared/control-size.d.ts +2 -0
  36. package/dist/components/_shared/disclosure-context.d.ts +7 -0
  37. package/dist/components/_shared/disclosure.css +1 -0
  38. package/dist/components/_shared/feedback.d.ts +7 -0
  39. package/dist/components/_shared/field-control.css +1 -0
  40. package/dist/components/_shared/field-surfaces.css +1 -1
  41. package/dist/components/_shared/fieldControl.d.ts +13 -0
  42. package/dist/components/_shared/floating.d.ts +14 -0
  43. package/dist/components/_shared/index.d.ts +2 -6
  44. package/dist/components/_shared/interaction.d.ts +23 -0
  45. package/dist/components/_shared/menu.css +1 -1
  46. package/dist/components/_shared/menuRowClass.d.ts +2 -0
  47. package/dist/components/_shared/primitive.d.ts +19 -0
  48. package/dist/components/_shared/resolveSurfaceClass.d.ts +3 -0
  49. package/dist/components/_shared/selection.d.ts +7 -0
  50. package/dist/components/_shared/useMotionAxis.d.ts +3 -2
  51. package/dist/components/accordion/Accordion.vue.d.ts +41 -16
  52. package/dist/components/accordion/AccordionContent.vue.d.ts +11 -9
  53. package/dist/components/accordion/AccordionItem.vue.d.ts +12 -9
  54. package/dist/components/accordion/AccordionTrigger.vue.d.ts +8 -11
  55. package/dist/components/accordion/index.d.ts +4 -4
  56. package/dist/components/alert/Alert.vue.d.ts +9 -5
  57. package/dist/components/alert/index.d.ts +17 -8
  58. package/dist/components/animated-digit/AnimatedDigit.vue.d.ts +2 -3
  59. package/dist/components/aurora/Aurora.vue.d.ts +37 -42
  60. package/dist/components/aurora/composables/atoms-fields.d.ts +13 -2
  61. package/dist/components/aurora/composables/atoms.d.ts +52 -50
  62. package/dist/components/aurora/composables/auroraFallbackGround.d.ts +13 -13
  63. package/dist/components/aurora/composables/auroraImageSource.d.ts +4 -5
  64. package/dist/components/aurora/composables/color.d.ts +15 -20
  65. package/dist/components/aurora/composables/frameLoop.d.ts +14 -11
  66. package/dist/components/aurora/composables/glSetup.d.ts +19 -2
  67. package/dist/components/aurora/composables/runtime.d.ts +56 -60
  68. package/dist/components/aurora/composables/uniformBridge.d.ts +9 -14
  69. package/dist/components/aurora/composables/uniformBridgeWGPU.d.ts +21 -22
  70. package/dist/components/aurora/composables/uniformBridgeWGPUImage.d.ts +13 -13
  71. package/dist/components/aurora/composables/useAurora.d.ts +19 -30
  72. package/dist/components/aurora/composables/wgpuSetup.d.ts +10 -8
  73. package/dist/components/aurora/constants/budget.d.ts +12 -25
  74. package/dist/components/aurora/constants/presets.d.ts +47 -58
  75. package/dist/components/aurora/constants/renderMode.d.ts +21 -36
  76. package/dist/components/aurora/constants/shaders/aurora-image.wgsl.d.ts +1 -1
  77. package/dist/components/aurora/constants/shaders/aurora-mediums.wgsl.d.ts +1 -1
  78. package/dist/components/aurora/constants/shaders/aurora.wgsl.d.ts +1 -1
  79. package/dist/components/aurora/constants/shaders/brush.glsl.d.ts +1 -1
  80. package/dist/components/aurora/constants/shaders/composition.glsl.d.ts +1 -1
  81. package/dist/components/aurora/constants/shaders/flow.glsl.d.ts +1 -1
  82. package/dist/components/aurora/constants/shaders/metal-medium.glsl.d.ts +2 -2
  83. package/dist/components/aurora/constants/shaders/oil-modes.glsl.d.ts +1 -1
  84. package/dist/components/aurora/constants/shaders/vangogh-medium.glsl.d.ts +1 -1
  85. package/dist/components/aurora/index.d.ts +2 -1
  86. package/dist/components/avatar/Avatar.vue.d.ts +72 -11
  87. package/dist/components/avatar/AvatarFallback.vue.d.ts +1 -2
  88. package/dist/components/avatar/AvatarImage.vue.d.ts +12 -8
  89. package/dist/components/avatar/index.d.ts +3 -9
  90. package/dist/components/avatar/styles.css +1 -0
  91. package/dist/components/badge/Badge.vue.d.ts +2 -9
  92. package/dist/components/badge/index.d.ts +32 -9
  93. package/dist/components/blob/Blob.vue.d.ts +5 -12
  94. package/dist/components/blob/composables/blobSimulation.d.ts +80 -0
  95. package/dist/components/blob/composables/buildMetaballProgram.d.ts +1 -1
  96. package/dist/components/blob/composables/resolveBlobSurface.d.ts +6 -0
  97. package/dist/components/blob/composables/satelliteKinematics.d.ts +3 -3
  98. package/dist/components/blob/composables/uniformBridgeWGPU.d.ts +1 -1
  99. package/dist/components/blob/composables/uploadBlobUniforms.d.ts +4 -31
  100. package/dist/components/blob/composables/useBlobMood.d.ts +5 -5
  101. package/dist/components/blob/composables/useBlobPointer.d.ts +11 -12
  102. package/dist/components/blob/composables/useMetaballRenderer.d.ts +27 -24
  103. package/dist/components/blob/composables/wgpuSetup.d.ts +7 -5
  104. package/dist/components/blob/config.d.ts +1 -1
  105. package/dist/components/blob/index.d.ts +2 -2
  106. package/dist/components/blob/presets.d.ts +2 -2
  107. package/dist/components/blob/shaders/metaball-palette.wgsl.d.ts +1 -1
  108. package/dist/components/blob/shaders/metaball-uniforms.glsl.d.ts +1 -1
  109. package/dist/components/blob/shaders/metaball.wgsl.d.ts +1 -1
  110. package/dist/components/blob/shaders/sdf-body.glsl.d.ts +1 -1
  111. package/dist/components/blob/shaders/watercolor-edges.glsl.d.ts +1 -1
  112. package/dist/components/blob/types.d.ts +28 -60
  113. package/dist/components/button/Button.vue.d.ts +26 -20
  114. package/dist/components/button/index.d.ts +1 -9
  115. package/dist/components/button/styles.css +1 -0
  116. package/dist/components/card/Card.vue.d.ts +20 -155
  117. package/dist/components/card/CardAction.vue.d.ts +0 -7
  118. package/dist/components/card/CardContent.vue.d.ts +2 -2
  119. package/dist/components/card/CardDescription.vue.d.ts +2 -2
  120. package/dist/components/card/CardFooter.vue.d.ts +2 -2
  121. package/dist/components/card/CardHeader.vue.d.ts +3 -42
  122. package/dist/components/card/CardTitle.vue.d.ts +6 -3
  123. package/dist/components/card/card-scroll.css +1 -1
  124. package/dist/components/card/index.d.ts +1 -3
  125. package/dist/components/card/styles.css +1 -1
  126. package/dist/components/carousel/index.d.ts +0 -2
  127. package/dist/components/carousel/interface.d.ts +2 -0
  128. package/dist/components/checkbox/Checkbox.vue.d.ts +17 -9
  129. package/dist/components/checkbox/index.d.ts +1 -1
  130. package/dist/components/checkbox/styles.css +1 -0
  131. package/dist/components/chip/Chip.vue.d.ts +12 -7
  132. package/dist/components/chip/chipVariants.d.ts +20 -43
  133. package/dist/components/chip/index.d.ts +1 -1
  134. package/dist/components/chip/types.d.ts +45 -30
  135. package/dist/components/collapsible/Collapsible.vue.d.ts +22 -9
  136. package/dist/components/collapsible/CollapsibleContent.vue.d.ts +11 -5
  137. package/dist/components/collapsible/CollapsibleTrigger.vue.d.ts +12 -9
  138. package/dist/components/collapsible/index.d.ts +3 -3
  139. package/dist/components/combobox/Combobox.vue.d.ts +10 -20
  140. package/dist/components/combobox/ComboboxAnchor.vue.d.ts +2 -6
  141. package/dist/components/combobox/ComboboxEmpty.vue.d.ts +2 -6
  142. package/dist/components/combobox/ComboboxGroup.vue.d.ts +2 -7
  143. package/dist/components/combobox/ComboboxInput.vue.d.ts +7 -12
  144. package/dist/components/combobox/ComboboxItem.vue.d.ts +7 -11
  145. package/dist/components/combobox/ComboboxItemIndicator.vue.d.ts +2 -6
  146. package/dist/components/combobox/ComboboxList.vue.d.ts +14 -17
  147. package/dist/components/combobox/ComboboxTrigger.vue.d.ts +16 -0
  148. package/dist/components/combobox/index.d.ts +2 -1
  149. package/dist/components/combobox/types.d.ts +87 -0
  150. package/dist/components/command/Command.vue.d.ts +9 -23
  151. package/dist/components/command/CommandDialog.vue.d.ts +4 -9
  152. package/dist/components/command/CommandEmpty.vue.d.ts +2 -6
  153. package/dist/components/command/CommandGroup.vue.d.ts +2 -7
  154. package/dist/components/command/CommandInput.vue.d.ts +6 -7
  155. package/dist/components/command/CommandItem.vue.d.ts +7 -11
  156. package/dist/components/command/CommandList.vue.d.ts +12 -19
  157. package/dist/components/command/CommandSeparator.vue.d.ts +2 -6
  158. package/dist/components/command/CommandShortcut.vue.d.ts +2 -2
  159. package/dist/components/command/dialogContext.d.ts +6 -0
  160. package/dist/components/command/index.d.ts +10 -10
  161. package/dist/components/command/styles.css +1 -0
  162. package/dist/components/command/types.d.ts +27 -0
  163. package/dist/components/completion-seal/CompletionSeal.vue.d.ts +2 -2
  164. package/dist/components/completion-seal/constants.d.ts +2 -2
  165. package/dist/components/configurator/Configurator.vue.d.ts +6 -6
  166. package/dist/components/configurator/ConfiguratorLayer.vue.d.ts +14 -18
  167. package/dist/components/configurator/ConfiguratorRow.vue.d.ts +14 -17
  168. package/dist/components/configurator/size.d.ts +5 -7
  169. package/dist/components/configurator/styles.css +1 -1
  170. package/dist/components/constellation/Constellation.vue.d.ts +1 -1
  171. package/dist/components/constellation/composables/createConstellationField.d.ts +2 -2
  172. package/dist/components/constellation/constants.d.ts +8 -8
  173. package/dist/components/constellation/constellationField.d.ts +5 -6
  174. package/dist/components/constellation/constellationInteraction.d.ts +8 -8
  175. package/dist/components/constellation/constellationTypes.d.ts +53 -54
  176. package/dist/components/constellation/constellationWell.d.ts +2 -2
  177. package/dist/components/dark-mode-toggle/DarkModeToggle.vue.d.ts +12 -0
  178. package/dist/components/dark-mode-toggle/dark-mode-toggle.css +1 -0
  179. package/dist/components/dark-mode-toggle/index.d.ts +2 -0
  180. package/dist/components/data-table/DataTable.vue.d.ts +11 -59
  181. package/dist/components/data-table/composables/useDataTableRowIdentity.d.ts +5 -23
  182. package/dist/components/data-table/index.d.ts +1 -1
  183. package/dist/components/data-table/styles.css +1 -0
  184. package/dist/components/data-table/types.d.ts +10 -12
  185. package/dist/components/deck/index.d.ts +0 -1
  186. package/dist/components/dialog/Dialog.vue.d.ts +8 -3
  187. package/dist/components/dialog/DialogClose.vue.d.ts +3 -1
  188. package/dist/components/dialog/DialogContent.vue.d.ts +27 -90
  189. package/dist/components/dialog/DialogDescription.vue.d.ts +5 -6
  190. package/dist/components/dialog/DialogTitle.vue.d.ts +5 -6
  191. package/dist/components/dialog/DialogTrigger.vue.d.ts +3 -1
  192. package/dist/components/{_shared → dialog}/ModalOverlay.vue.d.ts +18 -16
  193. package/dist/components/dialog/dialogStageContext.d.ts +7 -0
  194. package/dist/components/dialog/index.d.ts +8 -8
  195. package/dist/components/dialog/placement.css +1 -1
  196. package/dist/components/dialog/sheet-motion.d.ts +17 -0
  197. package/dist/components/dock/DockControl.vue.d.ts +9 -12
  198. package/dist/components/dock/DockCrossfade.vue.d.ts +4 -8
  199. package/dist/components/dock/DockLayer.vue.d.ts +2 -3
  200. package/dist/components/dock/DockLayerGroup.vue.d.ts +6 -6
  201. package/dist/components/dock/DockSeparator.vue.d.ts +8 -8
  202. package/dist/components/dock/composables/dockContext.d.ts +4 -14
  203. package/dist/components/dock/composables/dockCrossfadeContext.d.ts +6 -7
  204. package/dist/components/dock/composables/dockMorphMeasure.d.ts +7 -86
  205. package/dist/components/dock/composables/index.d.ts +1 -1
  206. package/dist/components/dock/composables/useDockClickIntegrity.d.ts +1 -1
  207. package/dist/components/dock/composables/useDockHold.d.ts +4 -5
  208. package/dist/components/dock/composables/useDockMorph.d.ts +26 -0
  209. package/dist/components/dock/composables/useDockOverflowFit.d.ts +4 -6
  210. package/dist/components/dock/composables/useDockSearch.d.ts +8 -8
  211. package/dist/components/dock/composables/useDockShellProps.d.ts +46 -43
  212. package/dist/components/dock/composables/useDockSpring.d.ts +7 -11
  213. package/dist/components/dock/composables/useDockState.d.ts +12 -3
  214. package/dist/components/dock/composables/useDockTouchGate.d.ts +14 -23
  215. package/dist/components/dock/constants.d.ts +5 -78
  216. package/dist/components/dock/index.d.ts +2 -7
  217. package/dist/components/dock/styles/controls.css +1 -1
  218. package/dist/components/dock/styles/crossfade.css +1 -1
  219. package/dist/components/dock/styles/density.css +1 -1
  220. package/dist/components/dock/styles/index.css +1 -1
  221. package/dist/components/dock/styles/layer-group.css +1 -1
  222. package/dist/components/dock/styles/layers.css +1 -1
  223. package/dist/components/dock/styles/morph.css +1 -1
  224. package/dist/components/dock/styles/shape.css +1 -1
  225. package/dist/components/dock/styles/shell.css +1 -1
  226. package/dist/components/drawer/Drawer.vue.d.ts +17 -20
  227. package/dist/components/drawer/DrawerContent.vue.d.ts +15 -16
  228. package/dist/components/drawer/DrawerDescription.vue.d.ts +5 -6
  229. package/dist/components/drawer/DrawerOverlay.vue.d.ts +6 -6
  230. package/dist/components/drawer/DrawerTitle.vue.d.ts +5 -6
  231. package/dist/components/drawer/composables/drawerSnapContext.d.ts +7 -1
  232. package/dist/components/drawer/composables/useDrawerSnap.d.ts +3 -1
  233. package/dist/components/drawer/constants.d.ts +7 -25
  234. package/dist/components/drawer/index.d.ts +10 -10
  235. package/dist/components/drawer/styles.css +1 -1
  236. package/dist/components/dropdown-menu/DropdownMenu.vue.d.ts +43 -16
  237. package/dist/components/dropdown-menu/DropdownMenuCheckboxItem.vue.d.ts +22 -13
  238. package/dist/components/dropdown-menu/DropdownMenuContent.vue.d.ts +28 -19
  239. package/dist/components/dropdown-menu/DropdownMenuGroup.vue.d.ts +6 -4
  240. package/dist/components/dropdown-menu/DropdownMenuItem.vue.d.ts +21 -9
  241. package/dist/components/dropdown-menu/DropdownMenuLabel.vue.d.ts +9 -9
  242. package/dist/components/dropdown-menu/DropdownMenuRadioGroup.vue.d.ts +13 -6
  243. package/dist/components/dropdown-menu/DropdownMenuRadioItem.vue.d.ts +18 -11
  244. package/dist/components/dropdown-menu/DropdownMenuSeparator.vue.d.ts +5 -6
  245. package/dist/components/dropdown-menu/DropdownMenuShortcut.vue.d.ts +7 -8
  246. package/dist/components/dropdown-menu/DropdownMenuSub.vue.d.ts +15 -7
  247. package/dist/components/dropdown-menu/DropdownMenuSubContent.vue.d.ts +24 -17
  248. package/dist/components/dropdown-menu/DropdownMenuSubTrigger.vue.d.ts +11 -9
  249. package/dist/components/dropdown-menu/DropdownMenuTrigger.vue.d.ts +15 -8
  250. package/dist/components/dropdown-menu/index.d.ts +15 -15
  251. package/dist/components/dropdown-menu/styles.css +1 -0
  252. package/dist/components/dropdown-menu/useMenuTrigger.d.ts +2 -9
  253. package/dist/components/easing/composables/useEasingPicker.d.ts +5 -8
  254. package/dist/components/easing/constants.d.ts +1 -1
  255. package/dist/components/expandable-container/ExpandableContainer.vue.d.ts +1 -25
  256. package/dist/components/expandable-container/styles.css +1 -0
  257. package/dist/components/fading-scroll/FadingScroll.vue.d.ts +4 -0
  258. package/dist/components/fading-scroll/composables/useFadingScroll.d.ts +4 -0
  259. package/dist/components/fading-scroll/constants.d.ts +1 -2
  260. package/dist/components/fourier-field/FourierField.vue.d.ts +3 -5
  261. package/dist/components/fourier-field/composables/fourierFieldGLSetup.d.ts +1 -1
  262. package/dist/components/fourier-field/composables/fourierFieldWGPUSetup.d.ts +1 -1
  263. package/dist/components/fourier-field/composables/useFourierField.d.ts +4 -4
  264. package/dist/components/fourier-field/constants.d.ts +10 -10
  265. package/dist/components/fourier-field/index.d.ts +3 -3
  266. package/dist/components/fourier-field/presets.d.ts +3 -3
  267. package/dist/components/fourier-field/shaders/fourier-field.glsl.d.ts +2 -2
  268. package/dist/components/fourier-field/shaders/fourier-field.render.wgsl.d.ts +1 -1
  269. package/dist/components/handmark/HandMark.vue.d.ts +1 -1
  270. package/dist/components/handmark/brush.d.ts +1 -1
  271. package/dist/components/handmark/composables/useHandMark.d.ts +4 -4
  272. package/dist/components/handmark/constants.d.ts +10 -10
  273. package/dist/components/handmark/geometry.d.ts +8 -8
  274. package/dist/components/handmark/index.d.ts +7 -8
  275. package/dist/components/handmark/noise.d.ts +3 -3
  276. package/dist/components/handmark/types.d.ts +2 -2
  277. package/dist/components/header-ribbon/HeaderRibbon.vue.d.ts +3 -21
  278. package/dist/components/header-ribbon/styles.css +1 -0
  279. package/dist/components/header-ribbon/types.d.ts +5 -2
  280. package/dist/components/index.d.ts +0 -3
  281. package/dist/components/infinite-scroll/composables/types.d.ts +1 -1
  282. package/dist/components/input/Input.vue.d.ts +10 -35
  283. package/dist/components/input/index.d.ts +2 -1
  284. package/dist/components/input/types.d.ts +22 -0
  285. package/dist/components/instrument-chassis/InstrumentChassis.vue.d.ts +10 -84
  286. package/dist/components/instrument-chassis/index.d.ts +1 -2
  287. package/dist/components/instrument-chassis/styles.css +1 -1
  288. package/dist/components/instrument-chassis/types.d.ts +13 -0
  289. package/dist/components/label/Label.vue.d.ts +9 -14
  290. package/dist/components/label/index.d.ts +1 -1
  291. package/dist/components/labeled-field/LabeledField.vue.d.ts +10 -108
  292. package/dist/components/labeled-field/LabeledInput.vue.d.ts +3 -23
  293. package/dist/components/labeled-field/LabeledSelect.vue.d.ts +12 -18
  294. package/dist/components/labeled-field/LabeledSlider.vue.d.ts +12 -18
  295. package/dist/components/labeled-field/LabeledSwitch.vue.d.ts +14 -17
  296. package/dist/components/labeled-field/index.d.ts +1 -0
  297. package/dist/components/labeled-field/types.d.ts +50 -0
  298. package/dist/components/liquid-grid/composables/liquidGrid.d.ts +5 -5
  299. package/dist/components/liquid-grid/constants.d.ts +6 -7
  300. package/dist/components/liquid-grid/shaders/liquid-grid.glsl.d.ts +1 -1
  301. package/dist/components/liquid-grid/shaders/liquid-grid.wgsl.d.ts +1 -1
  302. package/dist/components/metric/Metric.vue.d.ts +24 -0
  303. package/dist/components/metric/MetricCell.vue.d.ts +26 -0
  304. package/dist/components/metric/MetricRow.vue.d.ts +22 -0
  305. package/dist/components/metric/MetricStack.vue.d.ts +16 -0
  306. package/dist/components/metric/coalesce-metric.d.ts +7 -28
  307. package/dist/components/metric/index.d.ts +5 -0
  308. package/dist/components/metric/styles.css +1 -0
  309. package/dist/components/metric/types.d.ts +32 -0
  310. package/dist/components/number-field/NumberField.vue.d.ts +21 -9
  311. package/dist/components/number-field/NumberFieldContent.vue.d.ts +2 -2
  312. package/dist/components/number-field/NumberFieldDecrement.vue.d.ts +6 -6
  313. package/dist/components/number-field/NumberFieldIncrement.vue.d.ts +6 -6
  314. package/dist/components/number-field/NumberFieldInput.vue.d.ts +1 -6
  315. package/dist/components/number-field/context.d.ts +6 -0
  316. package/dist/components/number-field/index.d.ts +5 -5
  317. package/dist/components/number-field/styles.css +1 -0
  318. package/dist/components/pager-dots/constants.d.ts +1 -2
  319. package/dist/components/pager-dots/index.d.ts +0 -2
  320. package/dist/components/paper-backdrop/PaperBackdrop.vue.d.ts +1 -14
  321. package/dist/components/paper-backdrop/index.d.ts +1 -1
  322. package/dist/components/popover/Popover.vue.d.ts +24 -36
  323. package/dist/components/popover/PopoverContent.vue.d.ts +23 -29
  324. package/dist/components/popover/PopoverTrigger.vue.d.ts +12 -7
  325. package/dist/components/popover/index.d.ts +3 -3
  326. package/dist/components/popover/popoverContext.d.ts +3 -4
  327. package/dist/components/progress/Progress.vue.d.ts +5 -13
  328. package/dist/components/progress/index.d.ts +1 -0
  329. package/dist/components/progress/types.d.ts +19 -0
  330. package/dist/components/pulse/Pulse.vue.d.ts +8 -47
  331. package/dist/components/pulse/index.d.ts +1 -0
  332. package/dist/components/radio-group/RadioGroup.vue.d.ts +27 -15
  333. package/dist/components/radio-group/RadioGroupItem.vue.d.ts +9 -6
  334. package/dist/components/radio-group/index.d.ts +2 -0
  335. package/dist/components/radio-group/styles.css +1 -0
  336. package/dist/components/scroll-progress-rim/styles.css +1 -1
  337. package/dist/components/search/FuzzySearch.vue.d.ts +2 -2
  338. package/dist/components/search/SearchBar.vue.d.ts +2 -2
  339. package/dist/components/search/searchVariants.d.ts +15 -17
  340. package/dist/components/select/Select.vue.d.ts +25 -14
  341. package/dist/components/select/SelectContent.vue.d.ts +26 -29
  342. package/dist/components/select/SelectGroup.vue.d.ts +7 -11
  343. package/dist/components/select/SelectItem.vue.d.ts +24 -13
  344. package/dist/components/select/SelectLabel.vue.d.ts +7 -11
  345. package/dist/components/select/SelectScrollDownButton.vue.d.ts +3 -4
  346. package/dist/components/select/SelectScrollUpButton.vue.d.ts +3 -4
  347. package/dist/components/select/SelectSeparator.vue.d.ts +5 -6
  348. package/dist/components/select/SelectTrigger.vue.d.ts +15 -41
  349. package/dist/components/select/SelectValue.vue.d.ts +13 -7
  350. package/dist/components/select/index.d.ts +16 -8
  351. package/dist/components/separator/Separator.vue.d.ts +11 -6
  352. package/dist/components/separator/index.d.ts +1 -1
  353. package/dist/components/skeleton/Skeleton.vue.d.ts +3 -31
  354. package/dist/components/slider/Slider.vue.d.ts +10 -37
  355. package/dist/components/slider/index.d.ts +1 -45
  356. package/dist/components/slider/types.d.ts +25 -0
  357. package/dist/components/sortable-list/SortableList.vue.d.ts +1 -1
  358. package/dist/components/sortable-list/composables/ghostRenderer.d.ts +1 -1
  359. package/dist/components/sortable-list/composables/touchGate.d.ts +1 -1
  360. package/dist/components/sortable-list/composables/transitionTiming.d.ts +1 -1
  361. package/dist/components/status-dot/StatusDot.vue.d.ts +7 -10
  362. package/dist/components/status-dot/index.d.ts +1 -0
  363. package/dist/components/surface/Surface.vue.d.ts +13 -21
  364. package/dist/components/surface/index.d.ts +2 -2
  365. package/dist/components/switch/Switch.vue.d.ts +20 -11
  366. package/dist/components/switch/index.d.ts +2 -1
  367. package/dist/components/switch/styles.css +1 -0
  368. package/dist/components/table/Table.vue.d.ts +1 -1
  369. package/dist/components/tabs/SegmentedTabs.vue.d.ts +21 -13
  370. package/dist/components/tabs/composables/useTabDragMorph.d.ts +6 -6
  371. package/dist/components/tabs/composables/useTabResponsive.d.ts +5 -6
  372. package/dist/components/tabs/composables/useTabRovingFocus.d.ts +16 -16
  373. package/dist/components/tabs/constants.d.ts +1 -1
  374. package/dist/components/tabs/index.d.ts +1 -1
  375. package/dist/components/tabs/styles/drag.css +1 -1
  376. package/dist/components/tabs/styles/segmented.css +1 -1
  377. package/dist/components/tags-input/TagsInput.vue.d.ts +28 -15
  378. package/dist/components/tags-input/TagsInputInput.vue.d.ts +8 -6
  379. package/dist/components/tags-input/TagsInputItem.vue.d.ts +9 -8
  380. package/dist/components/tags-input/TagsInputItemDelete.vue.d.ts +5 -6
  381. package/dist/components/tags-input/TagsInputItemText.vue.d.ts +5 -6
  382. package/dist/components/tags-input/context.d.ts +5 -0
  383. package/dist/components/tags-input/index.d.ts +5 -5
  384. package/dist/components/tags-input/styles.css +1 -0
  385. package/dist/components/textarea/Textarea.vue.d.ts +10 -55
  386. package/dist/components/textarea/index.d.ts +2 -1
  387. package/dist/components/textarea/types.d.ts +22 -0
  388. package/dist/components/timeline/ContinuousMarkers.vue.d.ts +2 -4
  389. package/dist/components/timeline/ContinuousRail.vue.d.ts +3 -6
  390. package/dist/components/timeline/ContinuousTimeline.vue.d.ts +12 -13
  391. package/dist/components/timeline/GlassTimeline.vue.d.ts +7 -8
  392. package/dist/components/timeline/ScrubberTimeline.vue.d.ts +4 -4
  393. package/dist/components/timeline/SegmentedTimeline.vue.d.ts +2 -3
  394. package/dist/components/timeline/geometry.d.ts +3 -4
  395. package/dist/components/timeline/types.d.ts +3 -3
  396. package/dist/components/toast/Toast.vue.d.ts +37 -79
  397. package/dist/components/toast/ToastAction.vue.d.ts +5 -5
  398. package/dist/components/toast/ToastClose.vue.d.ts +4 -5
  399. package/dist/components/toast/ToastDescription.vue.d.ts +4 -5
  400. package/dist/components/toast/ToastTitle.vue.d.ts +4 -5
  401. package/dist/components/toast/Toaster.vue.d.ts +1 -1
  402. package/dist/components/toast/index.d.ts +8 -9
  403. package/dist/components/toast/use-toast.d.ts +20 -163
  404. package/dist/components/toggle-group/ToggleGroup.vue.d.ts +44 -22
  405. package/dist/components/toggle-group/ToggleGroupItem.vue.d.ts +11 -9
  406. package/dist/components/toggle-group/index.d.ts +3 -2
  407. package/dist/components/toggle-group/styles.css +1 -0
  408. package/dist/components/toggle-group/toggleGroupContext.d.ts +4 -15
  409. package/dist/components/tooltip/Tooltip.vue.d.ts +20 -7
  410. package/dist/components/tooltip/TooltipContent.vue.d.ts +20 -12
  411. package/dist/components/tooltip/TooltipProvider.vue.d.ts +12 -5
  412. package/dist/components/tooltip/TooltipTrigger.vue.d.ts +12 -5
  413. package/dist/components/tooltip/index.d.ts +4 -4
  414. package/dist/components/typewriter/composables/useTypewriter.d.ts +1 -0
  415. package/dist/components/typewriter/utils/timing.d.ts +0 -2
  416. package/dist/components/watercolor-dot/WatercolorDot.vue.d.ts +5 -18
  417. package/dist/components/watercolor-dot/useWatercolorBlob.d.ts +1 -4
  418. package/dist/composables/color/accent-tone-solve.d.ts +2 -5
  419. package/dist/composables/color/index.d.ts +31 -38
  420. package/dist/composables/color/useAccentTone.d.ts +0 -3
  421. package/dist/composables/color/value.d.ts +21 -0
  422. package/dist/composables/context/createContext.d.ts +2 -2
  423. package/dist/composables/dark/index.d.ts +1 -1
  424. package/dist/composables/dark/useGlobalDark.d.ts +7 -6
  425. package/dist/composables/dom/useBreakpoint.d.ts +2 -2
  426. package/dist/composables/dom/useClipboard.d.ts +28 -52
  427. package/dist/composables/dom/useDocumentVisibility.d.ts +3 -1
  428. package/dist/composables/dom/useIdleReady.d.ts +5 -6
  429. package/dist/composables/dom/useTokenColor.d.ts +2 -2
  430. package/dist/composables/dom/useUserInvalidAria.d.ts +2 -3
  431. package/dist/composables/dom/useViewportReady.d.ts +4 -4
  432. package/dist/composables/glass/backdropLuminanceSample.d.ts +7 -6
  433. package/dist/composables/glass/canvas2d/useCanvas2D.d.ts +7 -1
  434. package/dist/composables/glass/textureUpload.d.ts +8 -10
  435. package/dist/composables/glass/useGlassBackdropLuminance.d.ts +11 -19
  436. package/dist/composables/glass/useSpecularPointer.d.ts +6 -6
  437. package/dist/composables/glass/useSpecularTracking.d.ts +12 -15
  438. package/dist/composables/glass/wave/waveField.d.ts +2 -2
  439. package/dist/composables/glass/wave/waveField.glsl.d.ts +1 -1
  440. package/dist/composables/glass/wave/waveField.wgsl.d.ts +1 -1
  441. package/dist/composables/glass/webgl/backingSize.d.ts +5 -8
  442. package/dist/composables/glass/webgl/compile.d.ts +1 -1
  443. package/dist/composables/glass/webgl/createCanvasLifecycle.d.ts +20 -20
  444. package/dist/composables/glass/webgl/useWebGLCanvas.d.ts +16 -28
  445. package/dist/composables/glass/webgl/visibility.d.ts +3 -4
  446. package/dist/composables/glass/webgpu/useGpuSubstrate.d.ts +10 -10
  447. package/dist/composables/glass/webgpu/useWebGPUCanvas.d.ts +1 -1
  448. package/dist/composables/glass/webgpu/webgpuCanvasTypes.d.ts +12 -10
  449. package/dist/composables/glass/webgpu/webgpuDevice.d.ts +15 -16
  450. package/dist/composables/motion/core/asElement.d.ts +2 -0
  451. package/dist/composables/motion/{constants.d.ts → core/constants.d.ts} +2 -3
  452. package/dist/composables/motion/core/index.d.ts +20 -23
  453. package/dist/composables/motion/core/useReducedMotion.d.ts +5 -0
  454. package/dist/composables/motion/core/useViewTransition.d.ts +44 -0
  455. package/dist/composables/motion/index.d.ts +14 -16
  456. package/dist/composables/motion/{useDockCtaReceive.d.ts → morph/useDockCtaReceive.d.ts} +2 -3
  457. package/dist/composables/motion/{useDragMorph.d.ts → morph/useDragMorph.d.ts} +7 -7
  458. package/dist/composables/motion/morph/useElementMorph.d.ts +50 -0
  459. package/dist/composables/motion/{useLeadTrail.d.ts → morph/useLeadTrail.d.ts} +6 -6
  460. package/dist/composables/motion/{useSelectionGroup.d.ts → morph/useSelectionGroup.d.ts} +7 -5
  461. package/dist/composables/motion/{useSelectionIndicator.d.ts → morph/useSelectionIndicator.d.ts} +9 -16
  462. package/dist/composables/motion/{useNumericTransition.d.ts → number/useNumericTransition.d.ts} +2 -2
  463. package/dist/composables/motion/{pointerFieldMappings.d.ts → pointer/pointerFieldMappings.d.ts} +7 -10
  464. package/dist/composables/motion/{usePointerVelocityField.d.ts → pointer/usePointerVelocityField.d.ts} +1 -1
  465. package/dist/composables/motion/{bloomUpField.d.ts → reveal/bloomUpField.d.ts} +1 -1
  466. package/dist/composables/motion/reveal/useBloomUp.d.ts +33 -0
  467. package/dist/composables/motion/{useLiquidReveal.d.ts → reveal/useLiquidReveal.d.ts} +5 -5
  468. package/dist/composables/motion/{useStagger.d.ts → reveal/useStagger.d.ts} +3 -3
  469. package/dist/composables/motion/reveal/useStaggerReveal.d.ts +28 -0
  470. package/dist/composables/motion/{useScrollChrome.d.ts → scroll/useScrollChrome.d.ts} +2 -2
  471. package/dist/composables/motion/{useScrollProgress.d.ts → scroll/useScrollProgress.d.ts} +12 -2
  472. package/dist/composables/motion/{springPresets.d.ts → spring/springPresets.d.ts} +8 -7
  473. package/dist/composables/motion/{springProjection.d.ts → spring/springProjection.d.ts} +3 -0
  474. package/dist/composables/motion/{useLiquidFlex.d.ts → spring/useLiquidFlex.d.ts} +11 -12
  475. package/dist/composables/motion/{useLiquidPress.d.ts → spring/useLiquidPress.d.ts} +3 -3
  476. package/dist/composables/motion/{useSpring.d.ts → spring/useSpring.d.ts} +5 -2
  477. package/dist/composables/motion/{useSpringMount.d.ts → spring/useSpringMount.d.ts} +8 -1
  478. package/dist/composables/sidebar/types.d.ts +3 -3
  479. package/dist/{configurator-CSENXXSy.js → configurator-M5OaIlJd.js} +11 -11
  480. package/dist/configurator.js +1 -1
  481. package/dist/{constants-DRZmNIY-.js → constants-nBz23tJE.js} +1 -1
  482. package/dist/constellation.js +125 -124
  483. package/dist/{createCanvasLifecycle-hsFkQVdl.js → createCanvasLifecycle-DbXRwjU_.js} +87 -82
  484. package/dist/dark-mode-toggle.d.ts +1 -0
  485. package/dist/dark-mode-toggle.js +43 -0
  486. package/dist/dark.js +1 -1
  487. package/dist/data-table-BygKg6ZA.js +491 -0
  488. package/dist/data-table.js +1 -1
  489. package/dist/deck.js +3 -3
  490. package/dist/dialog-TNRDkcE4.js +385 -0
  491. package/dist/dialog.js +1 -1
  492. package/dist/dock.js +523 -940
  493. package/dist/dockContext-BUTlGRNJ.js +13 -0
  494. package/dist/dom.js +52 -114
  495. package/dist/drawer.js +262 -209
  496. package/dist/dropdown-menu-BlbnvMaZ.js +507 -0
  497. package/dist/dropdown-menu.js +2 -2
  498. package/dist/easing.js +294 -278
  499. package/dist/expandable-container.js +107 -93
  500. package/dist/fading-scroll-DhxXIhm2.js +96 -0
  501. package/dist/fading-scroll.js +1 -1
  502. package/dist/field-control.css_vue_type_style_index_0_src_true_lang-CeLay9Tk.js +21 -0
  503. package/dist/floating-dB5TD88k.js +7 -0
  504. package/dist/{flow.glsl-DEGFGE11.js → flow.wgsl-Cd2GUkPx.js} +2 -2
  505. package/dist/fonts/README.md +14 -18
  506. package/dist/forms.js +279 -174
  507. package/dist/fourier-field.js +148 -148
  508. package/dist/glass-ui.css +1 -1
  509. package/dist/glass-ui.js +512 -373
  510. package/dist/handmark.js +4 -4
  511. package/dist/header-ribbon.js +37 -68
  512. package/dist/index.d.ts +9 -18
  513. package/dist/infinite-scroll.js +31 -28
  514. package/dist/instrument-chassis.js +54 -2
  515. package/dist/label-DnMqH7jr.js +55 -0
  516. package/dist/label.js +1 -1
  517. package/dist/labeled-field.js +291 -214
  518. package/dist/liquid-grid.js +141 -151
  519. package/dist/menuRowClass-Nh7CtMON.js +12 -0
  520. package/dist/metric.d.ts +1 -0
  521. package/dist/metric.js +192 -0
  522. package/dist/motion-core.js +73 -165
  523. package/dist/motion.js +104 -161
  524. package/dist/number-field-Boe09SvX.js +154 -0
  525. package/dist/number-field.js +1 -1
  526. package/dist/pager-dots.js +2 -2
  527. package/dist/paper-backdrop.js +16 -24
  528. package/dist/{pointerFieldMappings-CZojkgKj.js → pointerFieldMappings-DP5tla5z.js} +4 -7
  529. package/dist/popover-BQGYXZyO.js +244 -0
  530. package/dist/popover.js +1 -1
  531. package/dist/{presets-CxeNvxuO.js → presets-5myqNv59.js} +1 -1
  532. package/dist/primitive-B2t2jdqM.js +11 -0
  533. package/dist/progress-DClbhRAT.js +88 -0
  534. package/dist/progress.js +1 -1
  535. package/dist/pulse.js +29 -43
  536. package/dist/reactive.js +1 -1
  537. package/dist/resolveCanvasColor-DS_6DBxA.js +82 -0
  538. package/dist/resolveSurfaceClass-DCZ4PZcy.js +6 -0
  539. package/dist/{scrollReader-C2oK9Hb8.js → scrollReader-Brf5cQNo.js} +1 -1
  540. package/dist/search.js +241 -213
  541. package/dist/select-BcBAyLXA.js +336 -0
  542. package/dist/select.js +1 -1
  543. package/dist/selection-DqIULxRG.js +6 -0
  544. package/dist/separator-CgZInrX-.js +75 -0
  545. package/dist/separator.js +1 -1
  546. package/dist/sidebar.js +53 -42
  547. package/dist/slider-DzqeQmMu.js +162 -0
  548. package/dist/slider.js +2 -2
  549. package/dist/sortable-list.js +9 -8
  550. package/dist/springPresets-rCii5KqX.js +52 -0
  551. package/dist/status-dot.js +26 -43
  552. package/dist/styles/accessibility.css +1 -1
  553. package/dist/styles/animations.css +1 -1
  554. package/dist/styles/components.css +1 -1
  555. package/dist/styles/glass/a11y-fallback.css +1 -1
  556. package/dist/styles/glass/accent-tone.css +1 -1
  557. package/dist/styles/glass/control-surfaces.css +1 -1
  558. package/dist/styles/glass/defined.css +1 -1
  559. package/dist/styles/glass/glass-atom.css +1 -1
  560. package/dist/styles/glass/glass-capsule.css +1 -1
  561. package/dist/styles/glass/glass-chip.css +1 -1
  562. package/dist/styles/glass/ladder.css +1 -1
  563. package/dist/styles/glass/liquid-fill.css +1 -1
  564. package/dist/styles/glass/material-roles.css +1 -1
  565. package/dist/styles/glass/material.css +1 -1
  566. package/dist/styles/glass/reveal.css +1 -1
  567. package/dist/styles/glass/squircle.css +1 -1
  568. package/dist/styles/glass/surface-axis.css +1 -1
  569. package/dist/styles/glass/surfaces-pager.css +1 -1
  570. package/dist/styles/glass/surfaces.css +1 -1
  571. package/dist/styles/glass-refract.css +1 -1
  572. package/dist/styles/glass.css +1 -1
  573. package/dist/styles/index.css +1 -1
  574. package/dist/styles/paper.css +1 -1
  575. package/dist/styles/scroll-driven.css +1 -1
  576. package/dist/styles/theme/bridges.css +1 -1
  577. package/dist/styles/theme/radius.css +1 -1
  578. package/dist/styles/tokens/color-radius.css +1 -1
  579. package/dist/styles/tokens/dark-arm.css +1 -1
  580. package/dist/styles/tokens/glass-deep.css +1 -1
  581. package/dist/styles/tokens/glass-fx.css +1 -1
  582. package/dist/styles/tokens/glass.css +1 -1
  583. package/dist/styles/tokens/light-dark.css +1 -1
  584. package/dist/styles/tokens/manifest.d.ts +14 -0
  585. package/dist/styles/tokens/manifest.ts +56 -0
  586. package/dist/styles/tokens/motion-registers.css +1 -1
  587. package/dist/styles/tokens/offsets.css +1 -1
  588. package/dist/styles/tokens/property-regs-specular.css +1 -1
  589. package/dist/styles/tokens/property-regs.css +1 -1
  590. package/dist/styles/tokens/scale-paper.css +1 -1
  591. package/dist/styles/tokens/scheme-motion.css +1 -1
  592. package/dist/styles/tokens/scheme-spring.css +1 -1
  593. package/dist/styles/tokens/scroll-tokens.css +1 -1
  594. package/dist/styles/tokens/shadow.css +1 -1
  595. package/dist/styles/tokens/sizing-config.css +1 -1
  596. package/dist/styles/tokens/sizing.css +1 -1
  597. package/dist/styles/tokens.d.ts +4 -9
  598. package/dist/styles/tokens.ts +5 -9
  599. package/dist/styles/transitions.css +1 -1
  600. package/dist/styles/typography/scale.css +1 -1
  601. package/dist/styles/typography/semantic.css +1 -1
  602. package/dist/styles/typography/utilities.css +1 -1
  603. package/dist/styles/utilities/a11y-overrides.css +1 -1
  604. package/dist/styles/utilities/base-misc.css +1 -1
  605. package/dist/styles/utilities/base.css +1 -1
  606. package/dist/styles/utilities/btn.css +1 -1
  607. package/dist/styles/utilities/components.css +1 -1
  608. package/dist/styles/utilities/metal.css +1 -1
  609. package/dist/styles/utilities/responsive.css +1 -0
  610. package/dist/styles/view-transition.css +1 -1
  611. package/dist/{supportsCssTimeline-Dz-GVxXM.js → supportsCssTimeline-C2zyWpl8.js} +1 -1
  612. package/dist/surface.js +2 -3
  613. package/dist/switch-DZjQuFLa.js +54 -0
  614. package/dist/switch.js +1 -1
  615. package/dist/tabs.js +141 -169
  616. package/dist/timeline.js +86 -87
  617. package/dist/toast-CH5mnsYT.js +267 -0
  618. package/dist/toast.js +1 -1
  619. package/dist/toggle-group-O6jBo7AE.js +150 -0
  620. package/dist/toggle-group.js +1 -1
  621. package/dist/tokens.js +96 -5
  622. package/dist/tooltip-Drx5qnw_.js +148 -0
  623. package/dist/tooltip.js +1 -1
  624. package/dist/typewriter.js +222 -193
  625. package/dist/{useAccentTone-C-p6WdPe.js → useAccentTone-DyInfHXE.js} +2 -2
  626. package/dist/{useAnimatedNumber-BRVVaFFc.js → useAnimatedNumber-WPtMz0AN.js} +2 -2
  627. package/dist/useClipboard-D36OTaeT.js +53 -0
  628. package/dist/useDockCtaReceive-DkrOTM0q.js +146 -0
  629. package/dist/useDocumentVisibility-Dh_TGXsU.js +21 -0
  630. package/dist/useDragMorph-BogSV_nv.js +293 -0
  631. package/dist/{useIntersectionPause-B-dbxl9w.js → useIntersectionPause-B5mAU6XY.js} +15 -15
  632. package/dist/useLeadTrail-AW1-zZcd.js +74 -0
  633. package/dist/{useLiquidFlex-Ch4exNvN.js → useLiquidFlex-TJZmRqyY.js} +1 -1
  634. package/dist/useLiquidPress-BOxuDkKa.js +101 -0
  635. package/dist/useMotionAxis-D-rtIhca.js +19 -0
  636. package/dist/usePointerVelocityField-DsIf7yyq.js +121 -0
  637. package/dist/useRAFLoop-B3YlWK4M.js +98 -0
  638. package/dist/useReducedMotion-vCXA_vyM.js +27 -0
  639. package/dist/useRoutePointer-B8itM7Ka.js +53 -0
  640. package/dist/useScrollProgress-CSFYXIZT.js +43 -0
  641. package/dist/useScrollTrigger-BDdqptlc.js +87 -0
  642. package/dist/useSelectionGroup-B5XplBbo.js +132 -0
  643. package/dist/{useSpring-BBSKFx_0.js → useSpring-9u2_shxV.js} +2 -2
  644. package/dist/useSpringMount-uQ8QL9Ff.js +74 -0
  645. package/dist/useTabRovingFocus-YnWh-Ytr.js +169 -0
  646. package/dist/useTextHighlight-mfwNIC1f.js +112 -0
  647. package/dist/{useTouchGate-Cj5fOkTv.js → useTouchGate-B4mzQcHJ.js} +1 -1
  648. package/dist/vSpecular-DMJo8pfD.js +68 -0
  649. package/dist/value-DMhh2R94.js +33 -0
  650. package/dist/watercolor-dot.js +77 -103
  651. package/package.json +163 -232
  652. package/dist/DropdownMenuTrigger-BzQtd9lt.js +0 -65
  653. package/dist/FadingScroll-C1ZWEjmG.js +0 -83
  654. package/dist/Input-B4WQ_CMc.js +0 -57
  655. package/dist/Surface-BWRfwyn8.js +0 -59
  656. package/dist/accent-tone-solve-Dii9ePhK.js +0 -20
  657. package/dist/badge-C0C-rTBu.js +0 -80
  658. package/dist/button-32mg6xA8.js +0 -194
  659. package/dist/card-16xmzIr3.js +0 -303
  660. package/dist/coalesce-metric-znAcLzkB.js +0 -13
  661. package/dist/collapsible-bPzS1aQk.js +0 -63
  662. package/dist/color-swatch.d.ts +0 -1
  663. package/dist/color-swatch.js +0 -48
  664. package/dist/command-BjPjUU9z.js +0 -307
  665. package/dist/components/_shared/menuItemVariants.d.ts +0 -51
  666. package/dist/components/_shared/useControlSize.d.ts +0 -46
  667. package/dist/components/_shared/useStalePropWarning.d.ts +0 -27
  668. package/dist/components/_shared/useSurfaceAxis.d.ts +0 -64
  669. package/dist/components/card/ScrollCard.vue.d.ts +0 -33
  670. package/dist/components/card/ScrollCardHeader.vue.d.ts +0 -17
  671. package/dist/components/carousel/CarouselNext.vue.d.ts +0 -21
  672. package/dist/components/carousel/CarouselPrevious.vue.d.ts +0 -21
  673. package/dist/components/color-swatch/ColorSwatch.vue.d.ts +0 -22
  674. package/dist/components/color-swatch/index.d.ts +0 -1
  675. package/dist/components/controls/DarkModeToggle.vue.d.ts +0 -32
  676. package/dist/components/controls/dark-mode-toggle.css +0 -1
  677. package/dist/components/controls/index.d.ts +0 -1
  678. package/dist/components/data-table/DataTablePagination.vue.d.ts +0 -13
  679. package/dist/components/dock/DockSection.vue.d.ts +0 -69
  680. package/dist/components/dock/DockStack.vue.d.ts +0 -73
  681. package/dist/components/dock/composables/dockMorphContext.d.ts +0 -91
  682. package/dist/components/dock/composables/useDockFisheye.d.ts +0 -24
  683. package/dist/components/dock/composables/useDockPopover.d.ts +0 -70
  684. package/dist/components/dock/styles/fisheye.css +0 -1
  685. package/dist/components/dock/styles/popover.css +0 -1
  686. package/dist/components/dock/styles/section.css +0 -1
  687. package/dist/components/focus-scope/FocusScope.vue.d.ts +0 -20
  688. package/dist/components/focus-scope/index.d.ts +0 -2
  689. package/dist/components/goo-filter/GooFilter.vue.d.ts +0 -22
  690. package/dist/components/goo-filter/index.d.ts +0 -1
  691. package/dist/components/icon-chip/IconChip.vue.d.ts +0 -4
  692. package/dist/components/icon-chip/index.d.ts +0 -2
  693. package/dist/components/icon-chip/styles.css +0 -1
  694. package/dist/components/icon-chip/types.d.ts +0 -92
  695. package/dist/components/icon-tooltip/IconTooltip.vue.d.ts +0 -16
  696. package/dist/components/icon-tooltip/index.d.ts +0 -1
  697. package/dist/components/instrument-chassis/ChassisDivider.vue.d.ts +0 -30
  698. package/dist/components/metric-badge/MetricBadge.vue.d.ts +0 -40
  699. package/dist/components/metric-badge/index.d.ts +0 -2
  700. package/dist/components/metric-cell/MetricCell.vue.d.ts +0 -108
  701. package/dist/components/metric-cell/index.d.ts +0 -2
  702. package/dist/components/metric-stack/MetricRow.vue.d.ts +0 -120
  703. package/dist/components/metric-stack/MetricStack.vue.d.ts +0 -92
  704. package/dist/components/metric-stack/index.d.ts +0 -4
  705. package/dist/components/notification/Notification.vue.d.ts +0 -16
  706. package/dist/components/notification/index.d.ts +0 -1
  707. package/dist/components/progress/ProgressDefault.vue.d.ts +0 -9
  708. package/dist/components/progress/ProgressGradient.vue.d.ts +0 -26
  709. package/dist/components/progress/ProgressLiquid.vue.d.ts +0 -22
  710. package/dist/components/progress/valueMarks.css +0 -1
  711. package/dist/components/spa-view/SpaView.vue.d.ts +0 -50
  712. package/dist/components/spa-view/index.d.ts +0 -2
  713. package/dist/components/split-chars/SplitChars.vue.d.ts +0 -53
  714. package/dist/components/split-chars/index.d.ts +0 -1
  715. package/dist/components/tabs/composables/useEyeglassLive.d.ts +0 -17
  716. package/dist/components/toggle/Toggle.vue.d.ts +0 -29
  717. package/dist/components/toggle/index.d.ts +0 -26
  718. package/dist/composables/glass/webgl/shaders/glass-refract.glsl.d.ts +0 -36
  719. package/dist/composables/motion/curves.d.ts +0 -48
  720. package/dist/composables/motion/gooBarbellGeometry.d.ts +0 -79
  721. package/dist/composables/motion/morphSignatures.d.ts +0 -88
  722. package/dist/composables/motion/suite.d.ts +0 -2
  723. package/dist/composables/motion/useBloomUp.d.ts +0 -97
  724. package/dist/composables/motion/useCharStagger.d.ts +0 -44
  725. package/dist/composables/motion/useElementMorph.d.ts +0 -107
  726. package/dist/composables/motion/useGooMorph.d.ts +0 -72
  727. package/dist/composables/motion/usePrioritizedTask.d.ts +0 -41
  728. package/dist/composables/motion/useStaggerReveal.d.ts +0 -52
  729. package/dist/composables/motion/useViewTransition.d.ts +0 -81
  730. package/dist/composables/virtual/index.d.ts +0 -4
  731. package/dist/composables/virtual/useVirtualSectionWindow.d.ts +0 -72
  732. package/dist/composables/virtual/useWindowedStore.d.ts +0 -43
  733. package/dist/composables/virtual/virtualSectionLayout.d.ts +0 -103
  734. package/dist/controls.d.ts +0 -1
  735. package/dist/controls.js +0 -83
  736. package/dist/data-table-DveMdgBM.js +0 -629
  737. package/dist/dialog-BzQxKrUr.js +0 -281
  738. package/dist/dockContext-4S9qP0Z4.js +0 -13
  739. package/dist/dropdown-menu-DORIA52F.js +0 -378
  740. package/dist/focus-scope-DUTKveod.js +0 -23
  741. package/dist/focus-scope.d.ts +0 -1
  742. package/dist/focus-scope.js +0 -2
  743. package/dist/icon-chip-BWuxz1-u.js +0 -57
  744. package/dist/icon-chip.d.ts +0 -1
  745. package/dist/icon-chip.js +0 -2
  746. package/dist/icon-tooltip-CO6rw0dZ.js +0 -25
  747. package/dist/icon-tooltip.d.ts +0 -1
  748. package/dist/icon-tooltip.js +0 -2
  749. package/dist/instrument-chassis-Cvstg4_U.js +0 -65
  750. package/dist/label-Cj38tJKG.js +0 -36
  751. package/dist/menuItemVariants-D6AOzzND.js +0 -36
  752. package/dist/metric-badge.d.ts +0 -1
  753. package/dist/metric-badge.js +0 -79
  754. package/dist/metric-cell.d.ts +0 -1
  755. package/dist/metric-cell.js +0 -61
  756. package/dist/metric-stack.d.ts +0 -1
  757. package/dist/metric-stack.js +0 -113
  758. package/dist/motion-curves.d.ts +0 -1
  759. package/dist/motion-curves.js +0 -146
  760. package/dist/notification-DVs7ODMg.js +0 -52
  761. package/dist/notification.d.ts +0 -1
  762. package/dist/notification.js +0 -2
  763. package/dist/number-field-PvkGedHk.js +0 -140
  764. package/dist/popover-WMgyRSyN.js +0 -256
  765. package/dist/progress-C-HHuFZy.js +0 -192
  766. package/dist/resolveCanvasColor-yarP5bdk.js +0 -93
  767. package/dist/select-BIv4R3Ir.js +0 -326
  768. package/dist/separator-CBU94kTM.js +0 -62
  769. package/dist/slider-Cc_qw6GA.js +0 -166
  770. package/dist/spa-view.d.ts +0 -1
  771. package/dist/spa-view.js +0 -46
  772. package/dist/springPresets-h5VKJQqG.js +0 -58
  773. package/dist/styles/glass/progress-rail.css +0 -1
  774. package/dist/switch-Boj4Ucn5.js +0 -49
  775. package/dist/toast-kAbchIN2.js +0 -281
  776. package/dist/toggle-group-BPchFsns.js +0 -178
  777. package/dist/tooltip-BmOQJzh0.js +0 -111
  778. package/dist/useControlSize-CFfOk8I-.js +0 -9
  779. package/dist/useDockCtaReceive-CK-RLASa.js +0 -257
  780. package/dist/useDocumentVisibility-YeBDGqtI.js +0 -17
  781. package/dist/useDragMorph-7ygF9O0m.js +0 -93
  782. package/dist/useGooMorph-D1F6QJlH.js +0 -349
  783. package/dist/useLeadTrail-BYu8dq4G.js +0 -74
  784. package/dist/useLiquidPress-BYcwwGQV.js +0 -68
  785. package/dist/useMotionAxis-DCCXMC-i.js +0 -20
  786. package/dist/usePointerVelocityField-BdvnO0py.js +0 -122
  787. package/dist/useRAFLoop-BtwQ9DyY.js +0 -109
  788. package/dist/useRoutePointer-BDNMFN73.js +0 -52
  789. package/dist/useScrollProgress-DZI4nf4v.js +0 -35
  790. package/dist/useSelectionGroup-LDzBdR1Y.js +0 -215
  791. package/dist/useSpringMount-C6-DBx4e.js +0 -71
  792. package/dist/useSpringPress-BypV_KO-.js +0 -36
  793. package/dist/useSurfaceAxis-DudiZVOR.js +0 -10
  794. package/dist/useTabRovingFocus-DkLYwo4L.js +0 -143
  795. package/dist/vReveal-DZfWl9XI.js +0 -10
  796. package/dist/vSpecular-CQFmLNzA.js +0 -68
  797. package/src/fonts/README.md +0 -124
  798. package/src/fonts/fira-code/OFL.txt +0 -93
  799. package/src/fonts/fira-code/fira-code-latin-ext.woff2 +0 -0
  800. package/src/fonts/fira-code/fira-code-latin.woff2 +0 -0
  801. package/src/fonts/plus-jakarta-sans/OFL.txt +0 -93
  802. package/src/fonts/plus-jakarta-sans/plus-jakarta-sans-latin-ext.woff2 +0 -0
  803. package/src/fonts/plus-jakarta-sans/plus-jakarta-sans-latin.woff2 +0 -0
  804. package/src/styles/accessibility.css +0 -48
  805. package/src/styles/animations.css +0 -468
  806. package/src/styles/draw-in.css +0 -89
  807. package/src/styles/fonts.css +0 -143
  808. package/src/styles/glass/a11y-fallback.css +0 -188
  809. package/src/styles/glass/accent-tone.css +0 -66
  810. package/src/styles/glass/control-surfaces.css +0 -171
  811. package/src/styles/glass/deep.css +0 -114
  812. package/src/styles/glass/defined.css +0 -88
  813. package/src/styles/glass/glass-atom.css +0 -247
  814. package/src/styles/glass/glass-capsule.css +0 -175
  815. package/src/styles/glass/glass-chip.css +0 -211
  816. package/src/styles/glass/grain-overlay.css +0 -79
  817. package/src/styles/glass/ladder-undershadow.css +0 -61
  818. package/src/styles/glass/ladder.css +0 -452
  819. package/src/styles/glass/liquid-enter.css +0 -240
  820. package/src/styles/glass/liquid-fill.css +0 -65
  821. package/src/styles/glass/material-roles.css +0 -18
  822. package/src/styles/glass/material.css +0 -500
  823. package/src/styles/glass/progress-rail.css +0 -78
  824. package/src/styles/glass/reveal.css +0 -333
  825. package/src/styles/glass/rim.css +0 -122
  826. package/src/styles/glass/squircle.css +0 -58
  827. package/src/styles/glass/surface-axis.css +0 -136
  828. package/src/styles/glass/surfaces-pager.css +0 -79
  829. package/src/styles/glass/surfaces.css +0 -434
  830. package/src/styles/glass-refract.css +0 -112
  831. package/src/styles/glass-specular-track.css +0 -74
  832. package/src/styles/glass.css +0 -110
  833. package/src/styles/index.css +0 -288
  834. package/src/styles/paper.css +0 -187
  835. package/src/styles/scroll-choreography.css +0 -294
  836. package/src/styles/scroll-chrome.css +0 -123
  837. package/src/styles/scroll-driven.css +0 -123
  838. package/src/styles/theme/bridges.css +0 -380
  839. package/src/styles/theme/dark.css +0 -7
  840. package/src/styles/theme/literals.css +0 -104
  841. package/src/styles/theme/radius.css +0 -148
  842. package/src/styles/theme.css +0 -33
  843. package/src/styles/tokens/color-radius.css +0 -308
  844. package/src/styles/tokens/dark-arm-glass.css +0 -55
  845. package/src/styles/tokens/dark-arm.css +0 -455
  846. package/src/styles/tokens/glass-deep.css +0 -126
  847. package/src/styles/tokens/glass-fx.css +0 -480
  848. package/src/styles/tokens/glass.css +0 -477
  849. package/src/styles/tokens/light-dark.css +0 -216
  850. package/src/styles/tokens/motion-registers.css +0 -93
  851. package/src/styles/tokens/offsets.css +0 -142
  852. package/src/styles/tokens/on-glass-fg.css +0 -39
  853. package/src/styles/tokens/property-regs-specular.css +0 -160
  854. package/src/styles/tokens/property-regs.css +0 -448
  855. package/src/styles/tokens/scale-paper.css +0 -495
  856. package/src/styles/tokens/scheme-motion.css +0 -425
  857. package/src/styles/tokens/scheme-spring.css +0 -282
  858. package/src/styles/tokens/scroll-tokens.css +0 -137
  859. package/src/styles/tokens/shadow.css +0 -206
  860. package/src/styles/tokens/sizing-config.css +0 -110
  861. package/src/styles/tokens/sizing.css +0 -505
  862. package/src/styles/tokens.css +0 -68
  863. package/src/styles/tokens.ts +0 -58
  864. package/src/styles/transitions.css +0 -228
  865. package/src/styles/typography/scale.css +0 -166
  866. package/src/styles/typography/semantic.css +0 -233
  867. package/src/styles/typography/utilities.css +0 -197
  868. package/src/styles/typography.css +0 -46
  869. package/src/styles/utilities/a11y-overrides.css +0 -184
  870. package/src/styles/utilities/base-misc.css +0 -307
  871. package/src/styles/utilities/base.css +0 -337
  872. package/src/styles/utilities/btn.css +0 -306
  873. package/src/styles/utilities/components.css +0 -337
  874. package/src/styles/utilities/metal.css +0 -272
  875. package/src/styles/utilities.css +0 -24
  876. package/src/styles/view-transition.css +0 -67
  877. package/src/styles/viz-reveal.css +0 -63
  878. /package/dist/{_plugin-vue_export-helper-C1je1s0u.js → _plugin-vue_export-helper-B3ysoDQm.js} +0 -0
  879. /package/dist/{compile-DK3Fri1B.js → compile-D7VYG3gi.js} +0 -0
  880. /package/dist/composables/glass/{webgl/shaders/procedural-color.glsl.d.ts → procedural/color.glsl.d.ts} +0 -0
  881. /package/dist/{components/aurora/constants/shaders/procedural-color.wgsl.d.ts → composables/glass/procedural/color.wgsl.d.ts} +0 -0
  882. /package/dist/composables/motion/{motionTempo.d.ts → core/motionTempo.d.ts} +0 -0
  883. /package/dist/composables/motion/{useIntersectionPause.d.ts → core/useIntersectionPause.d.ts} +0 -0
  884. /package/dist/composables/motion/{useRAFLoop.d.ts → core/useRAFLoop.d.ts} +0 -0
  885. /package/dist/composables/motion/{useYieldToMain.d.ts → core/useYieldToMain.d.ts} +0 -0
  886. /package/dist/composables/motion/{useAnimatedNumber.d.ts → number/useAnimatedNumber.d.ts} +0 -0
  887. /package/dist/composables/motion/{useAnimatedNumberMap.d.ts → number/useAnimatedNumberMap.d.ts} +0 -0
  888. /package/dist/composables/motion/{useCountup.d.ts → number/useCountup.d.ts} +0 -0
  889. /package/dist/composables/motion/{useRoutePointer.d.ts → pointer/useRoutePointer.d.ts} +0 -0
  890. /package/dist/composables/motion/{useTextHighlight.d.ts → reveal/useTextHighlight.d.ts} +0 -0
  891. /package/dist/composables/motion/{vReveal.d.ts → reveal/vReveal.d.ts} +0 -0
  892. /package/dist/composables/motion/{scrollReader.d.ts → scroll/scrollReader.d.ts} +0 -0
  893. /package/dist/composables/motion/{supportsCssTimeline.d.ts → scroll/supportsCssTimeline.d.ts} +0 -0
  894. /package/dist/composables/motion/{useScrollPin.d.ts → scroll/useScrollPin.d.ts} +0 -0
  895. /package/dist/composables/motion/{useScrollScene.d.ts → scroll/useScrollScene.d.ts} +0 -0
  896. /package/dist/composables/motion/{useScrollTrigger.d.ts → scroll/useScrollTrigger.d.ts} +0 -0
  897. /package/dist/composables/motion/{useSpringPress.d.ts → spring/useSpringPress.d.ts} +0 -0
  898. /package/dist/{createContext-FU0n5MGK.js → createContext-BhkE9mLH.js} +0 -0
  899. /package/dist/{dark-DIH-blY1.js → dark-z_P5QwqI.js} +0 -0
  900. /package/dist/{motionTempo-CMS5b0Vu.js → motionTempo-tscp92Nm.js} +0 -0
  901. /package/dist/{prng-Dz2_9RJu.js → prng-2uS6J_A1.js} +0 -0
  902. /package/dist/{rendererStatus-C2-zC2Q-.js → rendererStatus-BxUlBLVy.js} +0 -0
  903. /package/dist/{useDragVelocity-CbMZEBaC.js → useDragVelocity-6ONX0sr0.js} +0 -0
  904. /package/dist/{useFuzzySearch-BOgep7RE.js → useFuzzySearch-CUnZknpm.js} +0 -0
  905. /package/dist/{useResizeObserver-BcUTquV7.js → useResizeObserver-CdUlm2QZ.js} +0 -0
  906. /package/dist/{useResolveTokenColor-C07e-qaT.js → useResolveTokenColor-B2FfJnd9.js} +0 -0
  907. /package/dist/{useTimer-D8koDvJS.js → useTimer-C3yfti4C.js} +0 -0
  908. /package/dist/{useUserInvalidAria-Cr4nR3tu.js → useUserInvalidAria-0GNrddMX.js} +0 -0
  909. /package/dist/{valueDomain-B8L04u3U.js → valueDomain-SbVzoHMH.js} +0 -0
  910. /package/dist/{writeVelocityWeight-D_AcvTsE.js → writeVelocityWeight-DoGOCW3e.js} +0 -0
@@ -4,24 +4,25 @@ import type { BlobConfig } from "../types";
4
4
  import type { BlobMoodSystem } from "./useBlobMood";
5
5
  import type { BlobPointer } from "./useBlobPointer";
6
6
  import type { BlobSatelliteSystem } from "./useBlobSatellites";
7
- export interface UseMetaballRendererOptions {
7
+ import { type BlobSettledFrame } from "./blobSimulation";
8
+ interface UseMetaballRendererOptions {
8
9
  canvasRef: Ref<HTMLCanvasElement | null>;
9
10
  /** The base color, ALREADY un-wrapped to a CONCRETE string by the SFC (DOM-free). */
10
11
  color: Ref<string>;
11
12
  /**
12
13
  * The Fresnel rim color, ALREADY un-wrapped to a CONCRETE string by the SFC
13
- * (AX.W16 — the renderer no longer reaches the DOM for the `var()`-cascade read;
14
+ * The renderer does not reach the DOM for the `var()` cascade;
14
15
  * the SFC's `resolveTokenColor` leaf does ALL un-wrapping before the renderer sees
15
16
  * it). A `var(--token)` rim arrives here already resolved to `rgb(...)`.
16
17
  */
17
18
  rimColor: Ref<string>;
18
19
  /**
19
- * The multi-stop palette, ALREADY un-wrapped to CONCRETE strings by the SFC
20
- * (AX.W16). EMPTY falls back to the base color (uStopCount <= 1).
20
+ * The multi-stop palette, already unwrapped to concrete strings by the SFC.
21
+ * An empty list falls back to the base color (`uStopCount <= 1`).
21
22
  */
22
23
  paletteStops: Ref<string[]>;
23
24
  /**
24
- * F9.R1 (BG.W-BLOB-SATELLITE-SHADE) — the OPTIONAL per-satellite explicit shades,
25
+ * the OPTIONAL per-satellite explicit shades,
25
26
  * ALREADY un-wrapped to CONCRETE strings by the SFC (mirroring `paletteStops`).
26
27
  * Absent/EMPTY → the derived palette shade (the GL seam stays OFF, byte-identical).
27
28
  */
@@ -31,36 +32,35 @@ export interface UseMetaballRendererOptions {
31
32
  satellites: BlobSatelliteSystem;
32
33
  config: BlobConfig;
33
34
  /**
34
- * BI.W-E10-AURORA-ENTRANCE (value.js T-60) — the reveal-bloom CONSUMER DOOR
35
- * (the twin of `AuroraRuntimeOptions.revealBloom`; the door lands on BOTH
35
+ * Reveal-bloom consumer door, paired with `AuroraRuntimeOptions.revealBloom`.
36
36
  * chromatic runtimes). The one-shot cold-first-VISIBLE `filter`-bloom
37
37
  * (`data-substrate-reveal` → `@keyframes substrate-reveal-bloom`). Defaults
38
38
  * `true` — the blob keeps a materialize entrance, but the keyframe is now
39
39
  * PALETTE-HONEST (brightness/saturate never dip below 1, viz-reveal.css), so it
40
- * never transits the `brightness<1`/`saturate<1` gray veil T-60 condemned over
41
- * the chromatic field. A consumer (BI.W-BLOB-SEAMS, or an arrival-sync host)
40
+ * never transits a `brightness<1`/`saturate<1` gray veil over
41
+ * the chromatic field. A consumer or arrival-sync host
42
42
  * opts out with `false`.
43
43
  */
44
44
  revealBloom?: boolean;
45
45
  }
46
- /** The renderer's public control surface — pause/resume + wake the demand loop. */
47
- export interface UseMetaballRendererReturn {
46
+ /** The component-facing renderer controls — pause/resume + wake the demand loop. */
47
+ interface UseMetaballRendererReturn {
48
48
  pause: () => void;
49
49
  resume: () => void;
50
50
  /**
51
- * BA.W-GOO-REDRESS — re-arm the demand-parked loop on demand (the public twin
51
+ * re-arm the demand-parked loop on demand (the public twin
52
52
  * of the internal `color`/`paletteStops` wake watchers). The SFC's pointer-wake
53
53
  * wire calls this so a first hover over a fully-parked blob (all satellites
54
- * orbiting → the AX.W16 quiescence gate has parked the rAF) repaints on the
54
+ * orbiting → the quiescence gate has parked the rAF) repaints on the
55
55
  * SAME frame instead of waiting up to an orbit horizon for the next scheduled
56
- * satellite wake (root cause 2 / BA-goo-3). It is the EXISTING substrate wake
56
+ * satellite wake (root cause 2). It is the EXISTING substrate wake
57
57
  * handle — NO new rAF, NO second wake path (the single-substrate-loop invariant).
58
58
  */
59
59
  wake: () => void;
60
60
  /**
61
- * BI.W-BLOB-SEAMS (GAP-L5 / value.js T-49) — the public QUIESCENCE seam. `true`
61
+ * Public quiescence seam. `true`
62
62
  * IFF the engine is at rest: the mood is settled, the pointer is at rest, AND no
63
- * satellite is mid-transition (merging / absorbed / emerging / FISSIONING) —
63
+ * satellite is mid-transition (merging, absorbed, emerging, FISSIONING) —
64
64
  * i.e. zero in-flight fission beat. Derived from the SAME predicate the demand
65
65
  * gate (`shouldContinue`) reads to decide whether to park — NO parallel busy-flag
66
66
  * (the U3 single-signal discipline; the seam READS what the engine already knows,
@@ -70,21 +70,23 @@ export interface UseMetaballRendererReturn {
70
70
  * consumer observes it, never writes it.
71
71
  */
72
72
  settled: Readonly<Ref<boolean>>;
73
+ /** Last quiescent frame actually drawn by either backend; `null` before settle. */
74
+ settledFrame: Readonly<Ref<BlobSettledFrame | null>>;
73
75
  readonly rendererStatus: Readonly<Ref<RendererStatus>>;
74
76
  }
75
77
  /**
76
- * The GooBlob renderer — composes the `createGpuSubstrate` picker (BB.W-VIZ-SUITE /
77
- * W-GOOBLOB-WGPU): the WebGPU-first `metaball.wgsl` primary OR the WebGL2
78
+ * The Blob renderer composes `createGpuSubstrate`: the WebGPU-first
79
+ * `metaball.wgsl` primary or the WebGL2
78
80
  * `metaball.frag.ts` fallback, selected ONCE by `navigator.gpu` feature-detect. Both
79
- * backends compose the SAME `createCanvasLifecycle` leaf (AU.W6), so the demand-driven
81
+ * backends compose the same `createCanvasLifecycle` leaf, so demand-driven
80
82
  * scheduling + offscreen-park + live-PRM-freeze are byte-identical across backends.
81
83
  *
82
84
  * This module owns ONLY the metaball-specific concerns: compiling the shader, building
83
85
  * the quad + uniform cache (the WebGL2 `buildMetaballProgram` leaf) OR the WGSL pipeline
84
86
  * + the typed-struct uniform buffer (the WGSL `createBlobWGPUSetup` leaf), and the
85
- * per-frame SIMULATION advance + uniform upload derived from the mood / pointer /
86
- * satellite systems and the resolved base color. The simulation advance is SHARED — the
87
- * `resolveFrame(timeSec)` closure advances the systems and returns the settled
87
+ * per-frame engine upload derived from shared simulation state. `blobSimulation`
88
+ * owns the clocks, quiescence, scheduled wake, and `resolveFrame(timeSec)` that returns the
89
+ * settled
88
90
  * `BlobFrameState`; the WebGL2 `drawFrame` and the WGSL `frame` both call it, so the
89
91
  * physics is substrate-agnostic and only the upload+draw leg differs. The generic
90
92
  * lifecycle (context creation, the suspend/resume model, the demand-driven rAF loop, the
@@ -95,8 +97,9 @@ export interface UseMetaballRendererReturn {
95
97
  *
96
98
  * Color is resolved INTERNALLY through the `/color` leaf (`cssToOklch →
97
99
  * oklchToGammaRgb`) — the GAMMA-sRGB triple fed straight into the base-color uniform
98
- * (the faithful AU.W7 lift paints gamma). The renderer is DOM-FREE: it never un-wraps
100
+ * directly. The renderer is DOM-free: it never unwraps
99
101
  * a `var(--token)` — the SFC's `resolveTokenColor` leaf does that BEFORE handing
100
- * concrete strings here (inv-K-3 seam); the value.js 1×1-canvas DOM probe is gone.
102
+ * concrete strings here.
101
103
  */
102
104
  export declare function useMetaballRenderer(options: UseMetaballRendererOptions): UseMetaballRendererReturn;
105
+ export {};
@@ -1,19 +1,21 @@
1
- import type { WebGPUCanvasFrame } from "../../../composables/glass/webgpu/useWebGPUCanvas";
1
+ import type { WebGPUCanvasFrame, BackingSize } from "../../../composables/glass/webgpu/useWebGPUCanvas";
2
2
  import type { BlobConfig } from "../types";
3
3
  import type { BlobPointer } from "./useBlobPointer";
4
4
  import type { BlobSatelliteSystem } from "./useBlobSatellites";
5
- import type { BlobFrameState } from "./uploadBlobUniforms";
5
+ import type { BlobFrameState } from "./blobSimulation";
6
6
  export interface BlobWGPUSetupDeps {
7
7
  canvas: HTMLCanvasElement;
8
8
  config: BlobConfig;
9
9
  pointer: BlobPointer;
10
10
  satellites: BlobSatelliteSystem;
11
11
  /** Resolve the per-frame state (advances the sim, returns the settled values). */
12
- resolveFrame: (timeSec: number) => BlobFrameState | null;
12
+ resolveFrame: (timeSec: number) => BlobFrameState;
13
13
  /** Demand-gate (the renderer's quiescence layer — substrate-agnostic). */
14
14
  shouldContinue: () => boolean;
15
- /** Reduced-motion read (the substrate owns the query; the renderer drives tempo). */
16
- getReducedMotion: () => boolean;
15
+ /** Records the backing geometry already measured by the shared lifecycle. */
16
+ onResize: (size: BackingSize) => void;
17
+ /** Records a frame only after its draw submission succeeds. */
18
+ onDraw: (frame: BlobFrameState) => void;
17
19
  }
18
20
  /**
19
21
  * Build the goo-blob `setupWGPU(device, context, format)` callback. Closes over the
@@ -1,3 +1,3 @@
1
- export type { BlobMood, BlobMerge, BlobVariant, BlobQuality, MoodParams, MetaballSource, BlobConfig, BlobGeometry, BlobSatelliteTiming, BlobMembrane, BlobColor, BlobSurface, BlobInteraction, SatellitePhase, SatelliteInternal, } from "./types";
1
+ export type { BlobMood, BlobMerge, BlobQuality, MoodParams, MetaballSource, BlobConfig, BlobGeometry, BlobSatelliteTiming, BlobMembrane, BlobColor, BlobSurface, BlobInteraction, SatellitePhase, SatelliteInternal, } from "./types";
2
2
  export { BLOB_CONFIG_DEFAULTS, BLOB_CONFIG_KEY } from "./types";
3
3
  export { BLOB_HERO, LIGHTNESS_FLOOR_BRACKET, LIGHTNESS_FLOOR_DEFAULT, clampLightnessFloor, } from "./presets";
@@ -1,8 +1,8 @@
1
1
  export { default as Blob } from "./Blob.vue";
2
- export type { BlobMood, BlobMerge, BlobVariant, BlobQuality, MoodParams, MetaballSource, BlobConfig, BlobGeometry, BlobSatelliteTiming, BlobMembrane, BlobColor, BlobSurface, BlobInteraction, SatellitePhase, SatelliteInternal, } from "./types";
2
+ export type { BlobMood, BlobMerge, BlobQuality, MoodParams, MetaballSource, BlobConfig, BlobGeometry, BlobSatelliteTiming, BlobMembrane, BlobColor, BlobSurface, BlobInteraction, SatellitePhase, SatelliteInternal, } from "./types";
3
3
  export { BLOB_CONFIG_DEFAULTS, BLOB_CONFIG_KEY } from "./types";
4
4
  export { BLOB_HERO, LIGHTNESS_FLOOR_BRACKET, LIGHTNESS_FLOOR_DEFAULT, clampLightnessFloor, } from "./presets";
5
5
  export { useBlobMood, type BlobMoodSystem } from "./composables/useBlobMood";
6
6
  export { useBlobPointer, type BlobPointer } from "./composables/useBlobPointer";
7
7
  export { useBlobSatellites, type BlobSatelliteSystem, } from "./composables/useBlobSatellites";
8
- export { useMetaballRenderer, type UseMetaballRendererOptions, } from "./composables/useMetaballRenderer";
8
+ export type { BlobSettledFrame } from "./composables/blobSimulation";
@@ -1,11 +1,11 @@
1
1
  import type { BlobConfig } from "./types";
2
- /** The D8 OKLab-L ink-floor bracket — `[min, max]` (BI.W-BLOB-SEAMS / value.js GAP-L5). */
2
+ /** OKLab-L ink-floor bracket expressed as `[min, max]`. */
3
3
  export declare const LIGHTNESS_FLOOR_BRACKET: readonly [number, number];
4
4
  /** The default derived-palette OKLab-L floor (mid-bracket). */
5
5
  export declare const LIGHTNESS_FLOOR_DEFAULT = 0.15;
6
6
  /**
7
7
  * Clamp a lightness-floor value into the {@link LIGHTNESS_FLOOR_BRACKET} `[0.12, 0.20]`.
8
- * A non-finite / omitted value resolves to {@link LIGHTNESS_FLOOR_DEFAULT} (0.15). Pass
8
+ * A non-finite, omitted value resolves to {@link LIGHTNESS_FLOOR_DEFAULT} (0.15). Pass
9
9
  * the result to `deriveBlobPalette`'s `lightnessFloor` so a consumer/HERO body never
10
10
  * derives below the ink floor NOR above the deep-body ceiling — the bracket is the
11
11
  * contract, the atom is the knob.
@@ -1 +1 @@
1
- export declare const METABALL_PALETTE_WGSL = "\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// W11.b \u2014 sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// AX.W15 \u2014 de-synced breath (three DETUNED sines at irrational ratios).\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n";
1
+ export declare const METABALL_PALETTE_WGSL = "\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// Sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// De-synced breath using three detuned sines at irrational ratios.\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n";
@@ -1 +1 @@
1
- export declare const METABALL_UNIFORMS_GLSL = "#version 300 es\nprecision highp float;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nuniform vec2 uResolution;\nuniform float uTime;\nuniform vec3 uBaseColor;\n\n// Multi-stop palette (W11.b) \u2014 2-4 in-family OKLCh stops (uploaded GAMMA sRGB, like\n// uBaseColor). uStopCount <= 1 falls back to uBaseColor (the single-color default,\n// zero regression). MAX_BLOB_STOPS is a compile-time #define.\n#define MAX_BLOB_STOPS 4\nuniform int uStopCount;\nuniform vec3 uPalette[MAX_BLOB_STOPS];\n\n// Pointer\nuniform vec2 uPointer;\nuniform float uPointerActive;\nuniform float uPointerAttraction;\nuniform float uPointerStrength;\n\n// Main body\nuniform float uBodyRadius;\n\n// Pulsation\nuniform float uPulsePhase;\nuniform float uPulseAmp;\n\n// Surface noise\nuniform float uNoiseAmp;\nuniform float uNoiseFreq;\nuniform float uNoiseSpeed;\n\n// Gooey\nuniform float uSmoothK;\nuniform float uMerge; // 0 = quadratic smin, 1 = circular smin (rounder menisci)\n\n// BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 gate. 1.0 = the plain shadowless lightless\n// fill-only floor (variant=\"blob\"); 0.0 = the full lit pipeline (variant=\"meatball\" /\n// STAGE 2). The WebGL2 fallback transcribes the SAME stripped branch the WGSL primary\n// gates (research/viz/goo-blob.md \u00A75 \u2014 the GLSL twin).\n// BD.W-GOO-CAROUSEL-DECK \u2014 uStage is now DERIVED from uMorphT (uStage = uMorphT<=0 ?\n// 1 : 0) at upload; the SHADING morph (below) reads uMorphT directly.\nuniform float uStage;\n\n// BD.W-GOO-CAROUSEL-DECK \u2014 the blob to meatball SHADING-MORPH scalar. 0.0 = the flat blob\n// fill (byte-identical to the STAGE-1 floor), 1.0 = the fully-dressed lit meatball; the\n// in-between LERPS the surface shading (NOT the geometry \u2014 the smin field is shared). The\n// renderer resolves it from config.morphT (variant to endpoint back-compat: blob to 0,\n// meatball to 1). A consumer ANIMATING morphT 0 to 1 gets the live morph.\nuniform float uMorphT;\n\n// AX.W16 (arm 5) \u2014 the PRE-FBM bounding-discard radius (UV space). main() early-outs\n// to a transparent write for any fragment OUTSIDE this radius BEFORE the two 3-octave\n// FBM calls + the OKLCh round-trip. The renderer uploads it PADDED by every\n// outward-expanding term (body + eccentric orbit + sat radius + smin band + FBM edge\n// amplitude + click-pulse + a lean/squash safety pad) so it NEVER clips the wet\n// meniscus (IQ: inflate the bound to match any outward op).\nuniform float uMaxReach;\n\n// Membrane \u2014 domain-warp strength on the FBM edge displacement (0 = plain fbm).\nuniform float uWarpAmp;\n\n// Lit glass surface (W9.b) \u2014 gated behind uLit so the flat fill stays default.\nuniform float uLit; // 0 = flat fill (default), 1 = lit droplet\nuniform vec3 uRimColor; // Fresnel rim tint (GAMMA sRGB, via the /color leaf)\nuniform vec3 uLightDir; // normalized light direction (x, y, z)\nuniform float uSpecStrength; // Blinn-Phong specular weight\nuniform float uSpecShininess; // specular exponent (16-64, tight glint)\nuniform float uRimPower; // Fresnel/Schlick exponent (~2-3)\nuniform float uRimStrength; // Fresnel rim weight\n\n// BC.W-GOOBLOB-MEATBALL \u2014 the procedural 2D SDF soft-shadow march (T2, the GLSL twin of\n// the WGSL res.z/res.w lanes). uShadow gates the IQ rmshadows soft contact shadow that\n// FOLLOWS the irregular silhouette; uShadowSoftness is the penumbra hardness (4-48).\nuniform float uShadow; // 0 = no shadow, 1 = the soft contact shadow ON\nuniform float uShadowSoftness; // penumbra hardness (inverse light-source size, 4-48)\n\n// Iridescence + fake subsurface (W11.a) \u2014 translucent-gel read.\nuniform float uIridescence; // warm-pearl rim sheen weight (0 = off)\nuniform float uIridHue; // base hue (radians) the cosine palette biases toward (warm)\nuniform float uIridSpeed; // animated-thickness scroll for the iridescent t\nuniform float uSssScale; // fast-SSS back-light weight\nuniform float uSssPower; // fast-SSS exponent\nuniform float uCoreGlow; // thickness-driven inner-luminosity lift\n\n// Color perturbation (perceptually uniform \u2014 OKLCh L/C/h)\nuniform float uHueRange; // degrees of hue swing (converted to radians)\nuniform float uSatShift; // OKLCh chroma swing\nuniform float uBrightnessShift; // OKLCh lightness bias\nuniform float uColorNoiseFreq;\nuniform float uColorNoiseSpeed;\n\n// Satellites (max 4)\n#define MAX_SATS 4\nuniform int uSatCount;\nuniform vec2 uSatPos[MAX_SATS];\nuniform float uSatRadius[MAX_SATS];\nuniform float uSatOpacity[MAX_SATS];\n\n// F9.R1 (BG.W-BLOB-SATELLITE-SHADE) \u2014 the per-satellite EXPLICIT-SHADE seam (the GL\n// color-seam widen the value.js hero blob asked for; the BA-VJS-5 / C-1 residual, the\n// W-GOO-REDRESS arm-B book discharged). uSatColorActive == 0 is the DEFAULT (the derived\n// palette shade \u2014 byte-identical to HEAD): blendSatColor() early-returns and touches\n// nothing. When a consumer supplies explicit per-satellite shades (uSatColor[i], GAMMA\n// sRGB, at uSatColorAmt[i] weight \u2014 typically 1) the fragment blends the base palette\n// OKLCh toward each satellite's shade, weighted by that satellite's smin-field proximity\n// at this pixel. The body keeps the derived base (the ask is per-SATELLITE).\nuniform int uSatColorActive;\nuniform vec3 uSatColor[MAX_SATS];\nuniform float uSatColorAmt[MAX_SATS];\n\n// Pointer trail (W10) \u2014 a decaying-radius pseudopod toward the cursor. uTrail is a\n// COMPILE-TIME-SIZED array (GLSL ES 3.00 forbids a uniform-sized array) with a\n// DYNAMIC break on uTrailCount, mirroring the satellite loop. Later samples paint\n// smaller metaballs (r *= 1 - i/N) so the trail tapers into a tail.\n#define TRAIL_N 15\nuniform int uTrailCount;\nuniform vec2 uTrailPos[TRAIL_N];\nuniform float uTrailRadius[TRAIL_N];\n\n// Velocity-driven volume-preserving squash-and-stretch (W10).\nuniform vec2 uVelocity; // smoothed pointer velocity (motion direction + speed)\nuniform float uStretch; // squash-stretch magnitude (0 = off)\n\nconst float PI = 3.141592653589793;\n";
1
+ export declare const METABALL_UNIFORMS_GLSL = "#version 300 es\nprecision highp float;\n\nin vec2 vUv;\nout vec4 fragColor;\n\nuniform vec2 uResolution;\nuniform float uTime;\nuniform vec3 uBaseColor;\n\n// Multi-stop palette \u2014 2-4 in-family OKLCh stops (uploaded GAMMA sRGB, like\n// uBaseColor). uStopCount <= 1 falls back to uBaseColor (the single-color default,\n// zero regression). MAX_BLOB_STOPS is a compile-time #define.\n#define MAX_BLOB_STOPS 4\nuniform int uStopCount;\nuniform vec3 uPalette[MAX_BLOB_STOPS];\n\n// Pointer\nuniform vec2 uPointer;\nuniform float uPointerActive;\nuniform float uPointerAttraction;\nuniform float uPointerStrength;\n\n// Main body\nuniform float uBodyRadius;\n\n// Pulsation\nuniform float uPulsePhase;\nuniform float uPulseAmp;\n\n// Surface noise\nuniform float uNoiseAmp;\nuniform float uNoiseFreq;\nuniform float uNoiseSpeed;\n\n// Gooey\nuniform float uSmoothK;\nuniform float uMerge; // 0 = quadratic smin, 1 = circular smin (rounder menisci)\n\n// The stripped-surface gate. 1.0 = the flat shadowless fill-only floor; 0.0 = the\n// dressed pipeline. It is derived from the single uMorphT surface scalar.\nuniform float uStage;\n\n// The blob-to-meatball shading-morph scalar. 0.0 = the flat blob\n// fill (byte-identical to the STAGE-1 floor), 1.0 = the fully-dressed lit meatball; the\n// in-between LERPS the surface shading (NOT the geometry \u2014 the smin field is shared). The\n// renderer clamps it from config.morphT. Animating 0 to 1 gets the live morph.\nuniform float uMorphT;\n\n// The pre-FBM bounding-discard radius in UV space. main() early-outs\n// to a transparent write for any fragment OUTSIDE this radius BEFORE the two 3-octave\n// FBM calls + the OKLCh round-trip. The renderer uploads it PADDED by every\n// outward-expanding term (body + eccentric orbit + sat radius + smin band + FBM edge\n// amplitude + click-pulse + a lean/squash safety pad) so it NEVER clips the wet\n// meniscus (IQ: inflate the bound to match any outward op).\nuniform float uMaxReach;\n\n// Membrane \u2014 domain-warp strength on the FBM edge displacement (0 = plain fbm).\nuniform float uWarpAmp;\n\n// Lit glass surface \u2014 gated behind uLit so the flat fill stays default.\nuniform float uLit; // 0 = flat fill (default), 1 = lit droplet\nuniform vec3 uRimColor; // Fresnel rim tint (GAMMA sRGB, via the /color leaf)\nuniform vec3 uLightDir; // normalized light direction (x, y, z)\nuniform float uSpecStrength; // Blinn-Phong specular weight\nuniform float uSpecShininess; // specular exponent (16-64, tight glint)\nuniform float uRimPower; // Fresnel/Schlick exponent (~2-3)\nuniform float uRimStrength; // Fresnel rim weight\n\n// The procedural 2D SDF soft-shadow march, the GLSL twin of\n// the WGSL res.z/res.w lanes). uShadow gates the IQ rmshadows soft contact shadow that\n// FOLLOWS the irregular silhouette; uShadowSoftness is the penumbra hardness (4-48).\nuniform float uShadow; // 0 = no shadow, 1 = the soft contact shadow ON\nuniform float uShadowSoftness; // penumbra hardness (inverse light-source size, 4-48)\n\n// Iridescence + fake subsurface \u2014 translucent-gel read.\nuniform float uIridescence; // warm-pearl rim sheen weight (0 = off)\nuniform float uIridHue; // base hue (radians) the cosine palette biases toward (warm)\nuniform float uIridSpeed; // animated-thickness scroll for the iridescent t\nuniform float uSssScale; // fast-SSS back-light weight\nuniform float uSssPower; // fast-SSS exponent\nuniform float uCoreGlow; // thickness-driven inner-luminosity lift\n\n// Color perturbation (perceptually uniform \u2014 OKLCh L/C/h)\nuniform float uHueRange; // degrees of hue swing (converted to radians)\nuniform float uSatShift; // OKLCh chroma swing\nuniform float uBrightnessShift; // OKLCh lightness bias\nuniform float uColorNoiseFreq;\nuniform float uColorNoiseSpeed;\n\n// Satellites (max 4)\n#define MAX_SATS 4\nuniform int uSatCount;\nuniform vec2 uSatPos[MAX_SATS];\nuniform float uSatRadius[MAX_SATS];\nuniform float uSatOpacity[MAX_SATS];\n\n// The per-satellite explicit-shade seam widens the GL color contract for the hero blob.\n// uSatColorActive == 0 is the default (the derived\n// palette shade, UNCHANGED): blendSatColor() early-returns and touches\n// nothing. When a consumer supplies explicit per-satellite shades (uSatColor[i], GAMMA\n// sRGB, at uSatColorAmt[i] weight \u2014 typically 1) the fragment blends the base palette\n// OKLCh toward each satellite's shade, weighted by that satellite's smin-field proximity\n// at this pixel. The body keeps the derived base (the ask is per-SATELLITE).\nuniform int uSatColorActive;\nuniform vec3 uSatColor[MAX_SATS];\nuniform float uSatColorAmt[MAX_SATS];\n\n// Pointer trail \u2014 a decaying-radius pseudopod toward the cursor. uTrail is a\n// COMPILE-TIME-SIZED array (GLSL ES 3.00 forbids a uniform-sized array) with a\n// DYNAMIC break on uTrailCount, mirroring the satellite loop. Later samples paint\n// smaller metaballs (r *= 1 - i/N) so the trail tapers into a tail.\n#define TRAIL_N 15\nuniform int uTrailCount;\nuniform vec2 uTrailPos[TRAIL_N];\nuniform float uTrailRadius[TRAIL_N];\n\n// Velocity-driven volume-preserving squash-and-stretch.\nuniform vec2 uVelocity; // smoothed pointer velocity (motion direction + speed)\nuniform float uStretch; // squash-stretch magnitude (0 = off)\n\nconst float PI = 3.141592653589793;\n";
@@ -1 +1 @@
1
- export declare const METABALL_WGSL = "\nconst MAX_SATS: i32 = 4;\nconst TRAIL_N: i32 = 15;\nconst MAX_BLOB_STOPS: i32 = 4;\nconst PI: f32 = 3.141592653589793;\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\n// Scalars packed into vec4 lanes; per-satellite / per-trail / per-palette rows packed\n// into a vec4 so the array stride is the natural 16 bytes (no std140 stride trap \u2014 the\n// parity-blowout suspect the wave's \u00A7Triumvirate names).\nstruct Uniforms {\n // s0: (uTime, uBodyRadius, uPulsePhase, uPulseAmp)\n s0: vec4<f32>,\n // s1: (uNoiseAmp, uNoiseFreq, uNoiseSpeed, uWarpAmp)\n s1: vec4<f32>,\n // s2: (uSmoothK, uMerge, uMaxReach, uLit)\n s2: vec4<f32>,\n // s3: (uSpecStrength, uSpecShininess, uRimPower, uRimStrength)\n s3: vec4<f32>,\n // s4: (uIridescence, uIridHue, uIridSpeed, uSssScale)\n s4: vec4<f32>,\n // s5: (uSssPower, uCoreGlow, uHueRange, uSatShift)\n s5: vec4<f32>,\n // s6: (uBrightnessShift, uColorNoiseFreq, uColorNoiseSpeed, uStretch)\n s6: vec4<f32>,\n // s7: (uPointerActive, uPointerAttraction, uPointerStrength, uStage)\n // BC.W-GOOBLOB-PLAIN \u2014 uStage gates the STAGE-1 stripped floor: 1.0 = the plain\n // shadowless lightless fill-only floor (variant=\"blob\"); 0.0 = the full lit\n // pipeline (variant=\"meatball\" / STAGE 2). It rides the spare s7.w lane the typed-\n // struct SoT (uniformBridgeWGPU.ts) reserved.\n s7: vec4<f32>,\n // ptr: (uPointer.x, uPointer.y, uVelocity.x, uVelocity.y)\n ptr: vec4<f32>,\n // base: (uBaseColor.rgb, _pad)\n base: vec4<f32>,\n // rim: (uRimColor.rgb, _pad)\n rim: vec4<f32>,\n // light: (uLightDir.xyz, _pad)\n light: vec4<f32>,\n // res: (uResolution.x, uResolution.y, uShadow, uShadowSoftness)\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow march rides the spare res.z/res.w lanes the\n // typed-struct SoT (uniformBridgeWGPU.ts) reserved (the EXTEND, never a re-fork): res.z\n // = uShadow (1.0 = the variant=meatball shadow ON), res.w = uShadowSoftness (the\n // penumbra hardness, inverse light-source size \u2192 4-48).\n res: vec4<f32>,\n // ints: (uStopCount, uSatCount, uTrailCount, _pad)\n ints: vec4<i32>,\n palette: array<vec4<f32>, 4>,\n satPos: array<vec4<f32>, 4>, // (pos.x, pos.y, radius, opacity)\n trailPos: array<vec4<f32>, 15>, // (pos.x, pos.y, radius, _pad)\n};\n\n@group(0) @binding(0) var<uniform> u: Uniforms;\n\n// Noise + FBM (BC.W-CARVE6 -> metaball-noise.wgsl) \u2014 spliced AFTER the FBM_ROT_WGSL chunk\n// below. NB: do NOT name the chunk with a template-interpolation form in a WGSL comment \u2014\n// it injects the whole multi-line chunk into this // comment line and breaks the parse\n// (BD.W-VIZ-BROKEN-FIX D3c).\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nconst FBM_LACUNARITY: f32 = 1.8;\nconst FBM_GAIN: f32 = 0.42;\n\n// \u2500\u2500 Noise (blob-LOCAL 3D-p3 hash + IQ analytic-derivative gradient noise) \u2500\u2500\nfn hash21(p: vec2<f32>) -> f32 {\n var p3 = fract(vec3<f32>(p.x, p.y, p.x) * 0.1031);\n p3 = p3 + dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient (d/dx, d/dy) in\n// .yz, from one eval. The quintic fade has a continuous 2nd derivative.\nfn noised(p: vec2<f32>) -> vec3<f32> {\n let i = floor(p);\n let f = fract(p);\n let uu = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n let ga = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 0.0)), hash21(i + vec2<f32>(7.3, 0.0)));\n let gb = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 0.0)), hash21(i + vec2<f32>(8.3, 0.0)));\n let gc = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 1.0)), hash21(i + vec2<f32>(7.3, 1.0)));\n let gd = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 1.0)), hash21(i + vec2<f32>(8.3, 1.0)));\n\n let va = dot(ga, f - vec2<f32>(0.0, 0.0));\n let vb = dot(gb, f - vec2<f32>(1.0, 0.0));\n let vc = dot(gc, f - vec2<f32>(0.0, 1.0));\n let vd = dot(gd, f - vec2<f32>(1.0, 1.0));\n\n let n = va + uu.x * (vb - va) + uu.y * (vc - va) + uu.x * uu.y * (va - vb - vc + vd);\n let value = 0.5 + 0.5 * n;\n\n let grad =\n ga + uu.x * (gb - ga) + uu.y * (gc - ga) + uu.x * uu.y * (ga - gb - gc + gd) +\n du * (vec2<f32>(uu.y, uu.x) * (va - vb - vc + vd) + vec2<f32>(vb, vc) - va);\n return vec3<f32>(value, 0.5 * grad);\n}\n\nfn fbm(p0: vec2<f32>, octaves: i32) -> f32 {\n var value = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n value = value + amp * noised(p * freq).x;\n p = FBM_ROT * p;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n }\n return value;\n}\n\n// FBM with ANALYTIC GRADIENT \u2014 value in .x, \u2202/\u2202x, \u2202/\u2202y in .yz. The gradient accumulates\n// noised()'s analytic gradient per octave, chain-ruled through the per-octave frequency\n// scale AND the FBM_ROT rotation (the keystone feed for the analytic surface normal).\nfn fbmG(p: vec2<f32>, octaves: i32) -> vec3<f32> {\n var value = 0.0;\n var grad = vec2<f32>(0.0, 0.0);\n var amp = 0.5;\n var freq = 1.0;\n var rotAccum = mat2x2<f32>(1.0, 0.0, 0.0, 1.0);\n var pp = p;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n let n = noised(pp * freq);\n value = value + amp * n.x;\n grad = grad + amp * freq * (transpose(rotAccum) * n.yz);\n pp = FBM_ROT * pp;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n rotAccum = FBM_ROT * rotAccum;\n }\n return vec3<f32>(value, grad);\n}\n\n// One domain-warp pass with the ANALYTIC GRADIENT carried (warp-Jacobian approximation).\nfn fbmWarpedG(p: vec2<f32>, octaves: i32, warpAmp: f32) -> vec3<f32> {\n if (warpAmp <= 0.0) { return fbmG(p, octaves); }\n let q = vec2<f32>(fbm(p + vec2<f32>(0.0, 0.0), octaves),\n fbm(p + vec2<f32>(5.2, 1.3), octaves));\n return fbmG(p + warpAmp * (q - 0.5), octaves);\n}\n\n\n// \u2500\u2500 SDF body (value+gradient circle + the IQ normalized smin, value+gradient form) \u2500\u2500\nfn sdgCircle(p: vec2<f32>, center: vec2<f32>, radius: f32) -> vec3<f32> {\n let d = p - center;\n let len = length(d);\n var grad = vec2<f32>(0.0, 1.0);\n if (len > 1e-6) { grad = d / len; }\n return vec3<f32>(len - radius, grad);\n}\n\nfn sminQuadraticG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * 4.0;\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = h * h * k * 0.25;\n var w = 1.0 - 0.5 * h * h;\n if (a.x < b.x) { w = 0.5 * h * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminCircularG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * (1.0 / (1.0 - sqrt(0.5)));\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n var w = 1.0 - 0.5 * h;\n if (a.x < b.x) { w = 0.5 * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminG(a: vec3<f32>, b: vec3<f32>, k: f32) -> vec3<f32> {\n if (u.s2.y > 0.5) { return sminCircularG(a, b, k); }\n return sminQuadraticG(a, b, k);\n}\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n if (c <= 0.04045) { return c / 12.92; }\n return pow((c + 0.055) / 1.055, 2.4);\n}\nfn srgbToLinear(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfn linearToSrgbCh(c: f32) -> f32 {\n if (c <= 0.0031308) { return c * 12.92; }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nfn linearToSrgb(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS, row-major \u2192 WGSL columns (= the transpose).\nconst LINEAR_SRGB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients, row-major \u2192 WGSL columns.\nconst LMS_TO_OKLAB: mat3x3<f32> = mat3x3<f32>(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF, row-major \u2192 WGSL columns.\nconst OKLAB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB, row-major \u2192 WGSL columns.\nconst LMS_TO_LINEAR_SRGB: mat3x3<f32> = mat3x3<f32>(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\nfn cbrt3(v: vec3<f32>) -> vec3<f32> {\n return sign(v) * pow(abs(v), vec3<f32>(1.0 / 3.0));\n}\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nfn srgbToOklab(c: vec3<f32>) -> vec3<f32> {\n let lin = srgbToLinear(c);\n let lms = LINEAR_SRGB_TO_LMS * lin;\n return LMS_TO_OKLAB * cbrt3(lms);\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nfn oklabToLinearSrgb(lab: vec3<f32>) -> vec3<f32> {\n let lms_ = OKLAB_TO_LMS * lab;\n let lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS, folded to [0, 2pi). Mirrors value.js rawOklabToOklch.\nfn oklabToOklch(lab: vec3<f32>) -> vec3<f32> {\n let C = length(lab.yz);\n var H = atan2(lab.z, lab.y);\n if (H < 0.0) { H = H + 2.0 * PI; }\n return vec3<f32>(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nfn oklchToOklab(lch: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\n// OKLCh gamut clamp + palette sample + breath (BC.W-CARVE6 -> metaball-palette.wgsl)\n// \u2014 spliced AFTER the OKLCH_MATRICES_WGSL chunk above (its matrix source). NB: do NOT\n// write the chunk's identifier with a template-interpolation form in a WGSL comment \u2014 it\n// would inject the whole multi-line matrices chunk INTO this // comment line and break the\n// parse at the first injected newline (BD.W-VIZ-BROKEN-FIX D3c \u2014 the live WGSL syntax error\n// that silently fell every metaball/goo-dot to the WebGL2 net, masking the WGSL primary).\n\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// W11.b \u2014 sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// AX.W15 \u2014 de-synced breath (three DETUNED sines at irrational ratios).\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n\n\n// AX.W15 \u2014 the composite SDF field WITH its ANALYTIC GRADIENT vec3(dist, \u2202/\u2202x, \u2202/\u2202y).\nfn sceneDistG(uv: vec2<f32>) -> vec3<f32> {\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uNoiseAmp = u.s1.x;\n let uNoiseFreq = u.s1.y;\n let uNoiseSpeed = u.s1.z;\n let uWarpAmp = u.s1.w;\n let uSmoothK = u.s2.x;\n let uTime = u.s0.x;\n let uVelocity = u.ptr.zw;\n let uStretch = u.s6.w;\n let uSatCount = u.ints.y;\n let uTrailCount = u.ints.z;\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Velocity-driven VOLUME-PRESERVING squash-and-stretch (tanh-saturated).\n var bodyUv = uv;\n var ax = vec2<f32>(1.0, 0.0);\n var perp = vec2<f32>(0.0, 1.0);\n var sa = 1.0;\n let speed = length(uVelocity);\n let squashed = uStretch > 0.0 && speed > 1e-4;\n if (squashed) {\n ax = uVelocity / speed;\n perp = vec2<f32>(-ax.y, ax.x);\n sa = 1.0 + tanh(speed * 1.6) * uStretch;\n bodyUv = vec2<f32>(dot(uv, ax) / sa, dot(uv, perp) * sa);\n }\n\n // Domain-warped FBM displacement WITH its analytic gradient.\n let fbmv = fbmWarpedG(bodyUv * uNoiseFreq + uTime * uNoiseSpeed, 3, uWarpAmp);\n let bodyDisplacement = (fbmv.x - 0.5) * uNoiseAmp;\n let dispGradBody = uNoiseAmp * uNoiseFreq * fbmv.yz;\n\n let bodyG = sdgCircle(bodyUv, vec2<f32>(0.0), bodyR + bodyDisplacement);\n let bodyGradBody = bodyG.yz - dispGradBody;\n\n var bodyGradUv: vec2<f32>;\n if (squashed) {\n let scaled = vec2<f32>(bodyGradBody.x / sa, bodyGradBody.y * sa);\n bodyGradUv = scaled.x * ax + scaled.y * perp;\n } else {\n bodyGradUv = bodyGradBody;\n }\n var d = vec3<f32>(bodyG.x, bodyGradUv);\n\n // Satellites \u2014 smin-merged into the body.\n for (var i = 0; i < MAX_SATS; i = i + 1) {\n if (i >= uSatCount) { break; }\n let s = u.satPos[i];\n var satG = sdgCircle(uv, s.xy, s.z);\n satG.x = satG.x + (1.0 - s.w) * 0.3;\n d = sminG(d, satG, uSmoothK);\n }\n\n // Pointer trail \u2014 a decaying-radius pseudopod.\n for (var i = 0; i < TRAIL_N; i = i + 1) {\n if (i >= uTrailCount) { break; }\n let tp = u.trailPos[i];\n let trailG = sdgCircle(uv, tp.xy, tp.z);\n d = sminG(d, trailG, uSmoothK);\n }\n return d;\n}\n\n// AX.W15 \u2014 the analytic surface normal from the field gradient.\nfn surfaceNormalFromGrad(grad2d: vec2<f32>, d: f32, bodyR: f32) -> vec3<f32> {\n let g = normalize(grad2d + vec2<f32>(1e-6));\n let interior = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let z = sqrt(max(0.0, 1.0 - (1.0 - interior) * (1.0 - interior)));\n return normalize(vec3<f32>(g * (1.0 - z), z) + vec3<f32>(0.0, 0.0, 1e-6));\n}\n\n// \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the 2D SDF soft-shadow march (IQ rmshadows improved-penumbra,\n// research/viz/goo-blob.md \u00A72.3). A procedural soft contact shadow that FOLLOWS the\n// irregular metaball silhouette (NOT a hard disc / box shadow). Marches a ray from ro\n// along rd (the in-plane projection of uLightDir), accumulating the closest miss via\n// the Aaltonen penumbra (y = h*h/(2*ph) + d = sqrt(h*h - y*y)) that kills the\n// banding the naive res = min(res, h/(w*t)) shows. CHEAP: 24 steps, re-uses the SAME\n// sceneDistG().x field (NO separate field re-eval, NO FBO/multi-pass \u2014 the procedural\n// field needs none, \u00A72.3). w is the penumbra hardness (inverse light-source size \u2192\n// uShadowSoftness). It is derivative-FREE (no fwidth/dpdx/dpdy), so it is fragment-safe\n// here. Returns 1.0 (fully lit) \u2192 0.0 (fully occluded). \u2500\u2500\nfn softShadow2D(ro: vec2<f32>, rd: vec2<f32>, mint: f32, maxt: f32, w: f32) -> f32 {\n var res = 1.0;\n var ph = 1e20;\n var t = mint;\n for (var i = 0; i < 24; i = i + 1) {\n if (t >= maxt) { break; }\n let h = sceneDistG(ro + rd * t).x;\n if (h < 0.001) { return 0.0; }\n let y = h * h / (2.0 * ph);\n let dd = sqrt(max(h * h - y * y, 0.0));\n res = min(res, dd / (w * max(0.001, t - y)));\n ph = h;\n t = t + h;\n }\n return clamp(res, 0.0, 1.0);\n}\n\n// \u2500\u2500 Full-screen triangle vertex stage (the pilot idiom \u2014 no vertex buffer) \u2500\u2500\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {\n var p = vec2<f32>(-1.0, -1.0);\n if (vi == 1u) { p = vec2<f32>(3.0, -1.0); }\n else if (vi == 2u) { p = vec2<f32>(-1.0, 3.0); }\n var out: VSOut;\n out.pos = vec4<f32>(p, 0.0, 1.0);\n // vUv = aPos * 0.5 + 0.5 (the metaball.vert convention).\n out.uv = p * 0.5 + 0.5;\n return out;\n}\n\n// \u2500\u2500 Fragment stage (the main() transcription) \u2500\u2500\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n let uTime = u.s0.x;\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uMaxReach = u.s2.z;\n let uLit = u.s2.w;\n let uPointerActive = u.s7.x;\n let uPointerAttraction = u.s7.y;\n let uPointerStrength = u.s7.z;\n // BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 gate (1.0 = the plain shadowless fill-only floor).\n let uStage = u.s7.w;\n // BD.W-GOO-CAROUSEL-DECK \u2014 the blob to meatball SHADING-MORPH scalar (the base.w pad\n // lane; the typed-struct SoT writes it). 0 = flat blob, 1 = lit meatball, in-between\n // lerps the surface shading (the smin geometry is shared).\n let uMorphT = clamp(u.base.w, 0.0, 1.0);\n let uPointer = u.ptr.xy;\n let uHueRange = u.s5.z;\n let uSatShift = u.s5.w;\n let uBrightnessShift = u.s6.x;\n let uColorNoiseFreq = u.s6.y;\n let uColorNoiseSpeed = u.s6.z;\n let uIridescence = u.s4.x;\n let uIridHue = u.s4.y;\n let uIridSpeed = u.s4.z;\n let uSssScale = u.s4.w;\n let uSssPower = u.s5.x;\n let uCoreGlow = u.s5.y;\n let uSpecStrength = u.s3.x;\n let uSpecShininess = u.s3.y;\n let uRimPower = u.s3.z;\n let uRimStrength = u.s3.w;\n let uLightDir = u.light.xyz;\n let uRimColor = u.rim.rgb;\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow gate + penumbra hardness (res.z/res.w lanes).\n let uShadow = u.res.z;\n let uShadowSoftness = u.res.w;\n\n var uv = in.uv - 0.5;\n\n // PRE-FBM bounding test (BD.W-VIZ-BROKEN-FIX D3c \u2014 the uniformity fix). The GLSL fallback\n // EARLY-RETURNS transparent here (a perf skip of the FBM border); WGSL CANNOT \u2014 an early\n // return predicated on the per-fragment uv makes the fwidth(d)/fwidth(Nh) calls below\n // reachable only through non-uniform control flow, which the WGSL uniformity analyzer\n // REJECTS (fwidth must only be called from uniform control flow) so the metaball WGSL\n // module never compiled and every GooBlob + goo-dot fell silently to the WebGL2 net (the\n // \"broken TOTALLY\" the user reports, the un-exercised Safari-primary surface). So the\n // bound is folded into the FINAL alpha (a flag, NOT a control-flow return): the derivative\n // builtins stay in UNIFORM control flow, and an outside fragment writes transparent at the\n // end \u2014 gestalt-identical to the GLSL early-out, just without the WGSL-illegal pre-\n // derivative return. sceneDistG is derivative-FREE so running it on the border costs only\n // ALU (no correctness hazard); the real GPU swallows it.\n let inBounds = dot(uv, uv) <= uMaxReach * uMaxReach;\n\n // Pointer deformation \u2014 sign per AY.W-BLOB-CONFIG D2.\n if (uPointerActive > 0.5) {\n let pointerDir = uPointer - uv;\n let pointerDist = length(pointerDir);\n let influence = smoothstep(0.5, 0.0, pointerDist) * uPointerAttraction * uPointerStrength;\n uv = uv + normalize(pointerDir + vec2<f32>(1e-6)) * influence;\n }\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Composite domain-warped membrane field WITH its analytic gradient.\n let scene = sceneDistG(uv);\n let d = scene.x;\n let fieldGrad = scene.yz;\n\n // \u2500\u2500 fwidth SITE #1 (metaball.frag.ts line 266) \u2014 AA-edge half-width from the SDF\n // screen-space gradient. The WGSL fragment-stage fwidth() transcription. In UNIFORM\n // control flow (no early return precedes it \u2014 the bounding test above is a flag). \u2500\u2500\n let aa = max(fwidth(d), 1e-6);\n // The bounding test (D3c) folds in here: an out-of-bounds fragment is forced transparent\n // (the GLSL early-out's transparent WRITE, expressed as an alpha gate, not a return).\n let alpha = (1.0 - smoothstep(-aa, aa, d)) * select(0.0, 1.0, inBounds);\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the WGSL uniformity STRUCTURAL fix (the meatball-armer).\n // The Toksvig screen-space derivative (fwidth SITE #2) is hoisted HERE, into the SAME\n // uniform control flow fwidth(d) above already arms in (top-level fs_main, before the\n // per-fragment alpha < 0.001 early-return and the uLit/uShadow non-uniform branches).\n // WGSL uniformity analysis rejects a fwidth() reached only through a return predicated\n // on a per-fragment value (the alpha < 0.001 early-out) nested under further branches\n // \u2014 exactly the BB residual that kept the normal-derivative inside the lit branch from\n // compiling, so the WGSL primary never armed and GooBlob fell to the WebGL2 net. Nh is\n // the uniform-flow surface normal computed for this derivative ONLY (byte-identical to\n // the lit block's own N = surfaceNormalFromGrad(...) below \u2014 the SAME inputs, so\n // nVar = length(fwidth(Nh)) IS the Toksvig clamp the lit block reads); the named lit-\n // block N stays AFTER the uStage early-return (the STAGE-1 floor reaches no lit work).\n // nVar is a pure uniform-flow value the lit block READS \u2014 no derivative in non-uniform\n // flow; the math is byte-identical to the GLSL fallback's Toksvig clamp, only its\n // EVALUATION POINT moved. The shadow march (T2) reuses d (the same sceneDistG().x).\n let Nh = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n // \u2500\u2500 fwidth SITE #2 (metaball.frag.ts line 364) \u2014 Toksvig normal-variance specular\n // clamp, the WGSL fragment-stage fwidth() of the surface normal. NOW in uniform\n // control flow (the structural fix), so the WGSL primary ARMS + paints the full lit\n // creature instead of falling to the stripped WebGL2 fallback. \u2500\u2500\n let nVar = length(fwidth(Nh));\n\n if (alpha < 0.001) {\n return vec4<f32>(0.0);\n }\n\n // Edit #4 \u2014 perceptually-uniform OKLCh variation.\n let colorNoise = fbm(uv * uColorNoiseFreq + uTime * uColorNoiseSpeed, 3);\n var oklch = samplePaletteOklch(colorNoise);\n\n oklch.z = oklch.z + (colorNoise - 0.5) * uHueRange * (PI / 180.0);\n oklch.y = max(oklch.y + (colorNoise - 0.5) * uSatShift, 0.0);\n oklch.x = clamp(oklch.x + uBrightnessShift, 0.0, 1.0);\n\n // \u2500\u2500 BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 stripped floor (variant=blob). \u2500\u2500\n // The minimal verifiable floor: SDF + smin (the meatball field, already in d/\n // alpha above) + fwidth-AA (the crisp alpha above) + warm-cream fill. NO surface\n // normal, NO Fresnel, NO lit glint, NO iridescence, NO fake-SSS, NO shadow \u2014\n // deliberately FLAT. It returns BEFORE any of the STAGE-2 dressing is reached. The\n // STAGE-1 path simply never READS the hoisted Nh/nVar or the lit/shadow blocks; the\n // normal-derivative is now in UNIFORM control flow above (BC.W-GOOBLOB-MEATBALL \u2014 the\n // structural armer), so BOTH the STAGE-1 floor AND the STAGE-2 lit path arm on Metal\n // (the BB residual that kept STAGE 2 falling to the WebGL2 net is CLOSED). The\n // teaching contrast: this is the \"it renders, it meatballs, it works on Safari\"\n // floor STAGE 2 layers the lit/shadow onto via the SAME uniforms.\n // BD.W-GOO-CAROUSEL-DECK \u2014 the flat blob fill is snapshotted from the PRE-dressing\n // oklch (the dressing mutates oklch below). At morphT <= 0 (a pure blob) emit the\n // flat fill + dither and return \u2014 the byte-identical STAGE-1 floor, zero dressing cost.\n let flatOkl = gamutClampOklch(oklch);\n let flatLin = oklabToLinearSrgb(oklchToOklab(flatOkl));\n let flatRgbBase = clamp(linearToSrgb(flatLin), vec3<f32>(0.0), vec3<f32>(1.0));\n if (uMorphT <= 0.0) {\n let fc1 = in.pos.xy;\n let ign1 = fract(52.9829189 * fract(dot(fc1, vec2<f32>(0.06711056, 0.00583715))));\n let rgb1 = clamp(flatRgbBase + (ign1 - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb1 * alpha, alpha);\n }\n\n // The named surface normal the lit/iridescence/SSS blocks read (byte-identical inputs to\n // the hoisted Nh above \u2014 the Toksvig nVar = length(fwidth(Nh)) IS this N's screen-space\n // variance). It sits AFTER the uStage early-return so the STAGE-1 floor reaches no lit work.\n let N = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n let V = vec3<f32>(0.0, 0.0, 1.0);\n let thickness = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let fres = pow(1.0 - max(dot(N, V), 0.0), 2.5);\n\n // \u2500\u2500 W11.a iridescence \u2014 warm-biased IQ cosine palette driving OKLCh HUE \u2500\u2500\n if (uIridescence > 0.0) {\n let t = fres + 0.3 * colorNoise + uTime * uIridSpeed;\n let iridHue = uIridHue + 0.18 * PI * cos(2.0 * PI * t);\n let w = fres * uIridescence;\n oklch.z = mix(oklch.z, iridHue, w);\n oklch.y = min(oklch.y + 0.04 * w, oklch.y + 0.08);\n oklch.x = min(oklch.x + 0.05 * w, 1.0);\n }\n\n // \u2500\u2500 W11.a fake subsurface translucency \u2014 thickness inner-glow + back-light \u2500\u2500\n if (uCoreGlow > 0.0 || uSssScale > 0.0) {\n oklch.x = min(oklch.x + uCoreGlow * (1.0 - exp(-3.0 * thickness)), 1.0);\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let back = pow(clamp(dot(V, -(L + N * thickness)), 0.0, 1.0), uSssPower);\n let sss = back * uSssScale * (1.0 - thickness);\n oklch.x = min(oklch.x + sss, 1.0);\n oklch.z = oklch.z + sss * 0.1 * (1.0 - thickness);\n }\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the soft contact shadow (T2). A procedural soft shadow that\n // FOLLOWS the irregular silhouette: march from this fragment's uv toward the in-plane\n // projection of uLightDir; where the metaball field occludes the light (the body\n // shadows itself opposite the light, a satellite shadows the body across the neck), the\n // march returns < 1 and DARKENS the OKLCh L \u2014 a soft grounded contact band UNDER the\n // dome, congruent with (but PROCEDURAL, silhouette-following, unlike) the CSS gel-dome\n // drop-shadow. Concentrated on the AWAY-facing lower rim (an away-facing weight \u00D7 a\n // thin-rim Gaussian band) so the deep-lit interior + the light-facing edge stay bright\n // and the grounded shadow reads at the lower silhouette edge \u2014 the warm-cream body mean\n // holds. Gated uShadow > 0.5; variant=blob (STAGE 1) ships shadowless. \u2500\u2500\n if (uShadow > 0.5) {\n let L2 = normalize(uLightDir.xy + vec2<f32>(1e-6));\n // w increases with the inverse light-source size \u2192 uShadowSoftness (a harder penumbra at a\n // higher value). Start the march just off the surface so a fragment never self-shadows\n // at t=0; cap the reach at the body span.\n let sh = softShadow2D(uv, L2, max(aa, 0.004), bodyR * 1.5, max(uShadowSoftness, 4.0));\n // The contact band sits on the LOWER rim (the side AWAY from the light) \u2014 gated by\n // dot(fieldGrad, L2) < 0 (the rim facing away from L2) AND the thin-rim weight\n // (a Gaussian band peaking at thickness \u2248 0.18 so the deep-lit interior + the\n // light-facing edge stay BRIGHT \u2014 the warm-cream body mean holds). The 0.20 cap keeps\n // it a soft GROUNDING whisper, never a gouge (the warm-cream identity + the\n // proof:blob-warm-default floor hold).\n let away = clamp(-dot(normalize(fieldGrad + vec2<f32>(1e-6)), L2), 0.0, 1.0);\n let band = exp(-pow((thickness - 0.18) / 0.16, 2.0));\n let shadowDarken = (1.0 - sh) * away * band * 0.20;\n oklch.x = max(oklch.x - shadowDarken, 0.0);\n }\n\n oklch = gamutClampOklch(oklch);\n\n var lin = oklabToLinearSrgb(oklchToOklab(oklch));\n\n // \u2500\u2500 W9.b lit glass surface \u2014 Blinn-Phong glint + Fresnel rim, in LINEAR \u2500\u2500\n if (uLit > 0.5) {\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let H = normalize(L + V);\n\n let warmCream = oklabToLinearSrgb(oklchToOklab(vec3<f32>(0.97, 0.03, radians(85.0))));\n\n // \u2500\u2500 fwidth SITE #2 \u2014 Toksvig normal-variance specular clamp. nVar is the HOISTED\n // length(fwidth(N)) (BC.W-GOOBLOB-MEATBALL \u2014 computed once at the top of fs_main\n // in uniform control flow, so the WGSL primary ARMS on Metal). The math is\n // byte-identical to the GLSL fallback (length(fwidth(N))); only its evaluation\n // point moved out of this non-uniform if (uLit > 0.5) branch. \u2500\u2500\n let shininess = uSpecShininess / (1.0 + 24.0 * nVar);\n let energyNorm = (shininess + 2.0) / 8.0;\n let spec = pow(max(dot(N, H), 0.0), shininess) * uSpecStrength * energyNorm;\n\n var rimOkl = oklabToOklch(srgbToOklab(uRimColor));\n let bodyL = oklch.x;\n let dL = abs(rimOkl.x - bodyL);\n let lack = clamp((0.22 - dL) / 0.22, 0.0, 1.0);\n // target is a WGSL RESERVED word (W3C WGSL 16.2) so a \"var target\" declaration is an\n // invalid identifier: the shader module fails to compile and the WGSL primary never\n // arms (the GooBlob reserved-keyword bug BC.W-WEBGPU-EVERYWHERE W7 catches). Renamed to\n // a valid identifier; the math + the value are byte-identical.\n var targetL = 0.18;\n if (bodyL < 0.5) { targetL = 0.92; }\n rimOkl.x = clamp(mix(rimOkl.x, targetL, lack), 0.0, 1.0);\n rimOkl.y = rimOkl.y * mix(1.0, 0.5, lack);\n let rimLin = oklabToLinearSrgb(oklchToOklab(rimOkl));\n\n let rimFres = pow(1.0 - max(dot(N, V), 0.0), uRimPower);\n let rim = rimFres * uRimStrength * (1.0 - 0.6 * thickness);\n\n var highlight = max(warmCream * spec, rimLin * rim);\n highlight = min(highlight, vec3<f32>(0.85));\n lin = lin + highlight;\n }\n\n var rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n\n // BD.W-GOO-CAROUSEL-DECK \u2014 the blob\u2194meatball SHADING-MORPH compose: lerp the flat blob\n // fill -> the dressed meatball surface on uMorphT (the geometry/alpha is shared; only\n // the surface shading interpolates). morphT == 1 is byte-identical to the dressed\n // meatball; the morphT == 0 case already returned the flat fill above.\n rgb = mix(flatRgbBase, rgb, uMorphT);\n\n // IGN dither \u2014 1-LSB triangular dither in DISPLAY space, AFTER linearToSrgb.\n let fragCoord = in.pos.xy;\n let ign = fract(52.9829189 * fract(dot(fragCoord, vec2<f32>(0.06711056, 0.00583715))));\n rgb = clamp(rgb + (ign - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n\n // premultiply AFTER the OETF: straight-alpha gamma \u2192 premultiplied.\n return vec4<f32>(rgb * alpha, alpha);\n}\n";
1
+ export declare const METABALL_WGSL = "\nconst MAX_SATS: i32 = 4;\nconst TRAIL_N: i32 = 15;\nconst MAX_BLOB_STOPS: i32 = 4;\nconst PI: f32 = 3.141592653589793;\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\n// Scalars packed into vec4 lanes; per-satellite, per-trail, per-palette rows packed\n// into a vec4 so the array stride is the natural 16 bytes (no std140 stride trap \u2014 the\n// parity-blowout suspect).\nstruct Uniforms {\n // s0: (uTime, uBodyRadius, uPulsePhase, uPulseAmp)\n s0: vec4<f32>,\n // s1: (uNoiseAmp, uNoiseFreq, uNoiseSpeed, uWarpAmp)\n s1: vec4<f32>,\n // s2: (uSmoothK, uMerge, uMaxReach, uLit)\n s2: vec4<f32>,\n // s3: (uSpecStrength, uSpecShininess, uRimPower, uRimStrength)\n s3: vec4<f32>,\n // s4: (uIridescence, uIridHue, uIridSpeed, uSssScale)\n s4: vec4<f32>,\n // s5: (uSssPower, uCoreGlow, uHueRange, uSatShift)\n s5: vec4<f32>,\n // s6: (uBrightnessShift, uColorNoiseFreq, uColorNoiseSpeed, uStretch)\n s6: vec4<f32>,\n // s7: (uPointerActive, uPointerAttraction, uPointerStrength, uStage)\n // uStage gates the stripped floor: 1.0 = flat and shadowless; 0.0 = dressed. It\n // is derived from the single morph scalar and rides the spare s7.w lane.\n s7: vec4<f32>,\n // ptr: (uPointer.x, uPointer.y, uVelocity.x, uVelocity.y)\n ptr: vec4<f32>,\n // base: (uBaseColor.rgb, _pad)\n base: vec4<f32>,\n // rim: (uRimColor.rgb, _pad)\n rim: vec4<f32>,\n // light: (uLightDir.xyz, _pad)\n light: vec4<f32>,\n // res: (uResolution.x, uResolution.y, uShadow, uShadowSoftness)\n // the soft-shadow march rides the spare res.z/res.w lanes the\n // typed-struct SoT (uniformBridgeWGPU.ts) reserved (the EXTEND, never a re-fork): res.z\n // = uShadow (1.0 = the dressed shadow ON), res.w = uShadowSoftness (the\n // penumbra hardness, inverse light-source size \u2192 4-48).\n res: vec4<f32>,\n // ints: (uStopCount, uSatCount, uTrailCount, _pad)\n ints: vec4<i32>,\n palette: array<vec4<f32>, 4>,\n satPos: array<vec4<f32>, 4>, // (pos.x, pos.y, radius, opacity)\n trailPos: array<vec4<f32>, 15>, // (pos.x, pos.y, radius, _pad)\n};\n\n@group(0) @binding(0) var<uniform> u: Uniforms;\n\n// Noise + FBM from metaball-noise.wgsl, spliced after the FBM_ROT_WGSL chunk\n// below. NB: do NOT name the chunk with a template-interpolation form in a WGSL comment \u2014\n// it injects the whole multi-line chunk into this // comment line and breaks the parse\n// at the first injected newline.\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nconst FBM_LACUNARITY: f32 = 1.8;\nconst FBM_GAIN: f32 = 0.42;\n\n// \u2500\u2500 Noise (blob-LOCAL 3D-p3 hash + IQ analytic-derivative gradient noise) \u2500\u2500\nfn hash21(p: vec2<f32>) -> f32 {\n var p3 = fract(vec3<f32>(p.x, p.y, p.x) * 0.1031);\n p3 = p3 + dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient (d/dx, d/dy) in\n// .yz, from one eval. The quintic fade has a continuous 2nd derivative.\nfn noised(p: vec2<f32>) -> vec3<f32> {\n let i = floor(p);\n let f = fract(p);\n let uu = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n let ga = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 0.0)), hash21(i + vec2<f32>(7.3, 0.0)));\n let gb = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 0.0)), hash21(i + vec2<f32>(8.3, 0.0)));\n let gc = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 1.0)), hash21(i + vec2<f32>(7.3, 1.0)));\n let gd = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 1.0)), hash21(i + vec2<f32>(8.3, 1.0)));\n\n let va = dot(ga, f - vec2<f32>(0.0, 0.0));\n let vb = dot(gb, f - vec2<f32>(1.0, 0.0));\n let vc = dot(gc, f - vec2<f32>(0.0, 1.0));\n let vd = dot(gd, f - vec2<f32>(1.0, 1.0));\n\n let n = va + uu.x * (vb - va) + uu.y * (vc - va) + uu.x * uu.y * (va - vb - vc + vd);\n let value = 0.5 + 0.5 * n;\n\n let grad =\n ga + uu.x * (gb - ga) + uu.y * (gc - ga) + uu.x * uu.y * (ga - gb - gc + gd) +\n du * (vec2<f32>(uu.y, uu.x) * (va - vb - vc + vd) + vec2<f32>(vb, vc) - va);\n return vec3<f32>(value, 0.5 * grad);\n}\n\nfn fbm(p0: vec2<f32>, octaves: i32) -> f32 {\n var value = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n value = value + amp * noised(p * freq).x;\n p = FBM_ROT * p;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n }\n return value;\n}\n\n// FBM with ANALYTIC GRADIENT \u2014 value in .x, \u2202/\u2202x, \u2202/\u2202y in .yz. The gradient accumulates\n// noised()'s analytic gradient per octave, chain-ruled through the per-octave frequency\n// scale AND the FBM_ROT rotation (the keystone feed for the analytic surface normal).\nfn fbmG(p: vec2<f32>, octaves: i32) -> vec3<f32> {\n var value = 0.0;\n var grad = vec2<f32>(0.0, 0.0);\n var amp = 0.5;\n var freq = 1.0;\n var rotAccum = mat2x2<f32>(1.0, 0.0, 0.0, 1.0);\n var pp = p;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n let n = noised(pp * freq);\n value = value + amp * n.x;\n grad = grad + amp * freq * (transpose(rotAccum) * n.yz);\n pp = FBM_ROT * pp;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n rotAccum = FBM_ROT * rotAccum;\n }\n return vec3<f32>(value, grad);\n}\n\n// One domain-warp pass with the ANALYTIC GRADIENT carried (warp-Jacobian approximation).\nfn fbmWarpedG(p: vec2<f32>, octaves: i32, warpAmp: f32) -> vec3<f32> {\n if (warpAmp <= 0.0) { return fbmG(p, octaves); }\n let q = vec2<f32>(fbm(p + vec2<f32>(0.0, 0.0), octaves),\n fbm(p + vec2<f32>(5.2, 1.3), octaves));\n return fbmG(p + warpAmp * (q - 0.5), octaves);\n}\n\n\n// \u2500\u2500 SDF body (value+gradient circle + the IQ normalized smin, value+gradient form) \u2500\u2500\nfn sdgCircle(p: vec2<f32>, center: vec2<f32>, radius: f32) -> vec3<f32> {\n let d = p - center;\n let len = length(d);\n var grad = vec2<f32>(0.0, 1.0);\n if (len > 1e-6) { grad = d / len; }\n return vec3<f32>(len - radius, grad);\n}\n\nfn sminQuadraticG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * 4.0;\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = h * h * k * 0.25;\n var w = 1.0 - 0.5 * h * h;\n if (a.x < b.x) { w = 0.5 * h * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminCircularG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * (1.0 / (1.0 - sqrt(0.5)));\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n var w = 1.0 - 0.5 * h;\n if (a.x < b.x) { w = 0.5 * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminG(a: vec3<f32>, b: vec3<f32>, k: f32) -> vec3<f32> {\n if (u.s2.y > 0.5) { return sminCircularG(a, b, k); }\n return sminQuadraticG(a, b, k);\n}\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n if (c <= 0.04045) { return c / 12.92; }\n return pow((c + 0.055) / 1.055, 2.4);\n}\nfn srgbToLinear(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfn linearToSrgbCh(c: f32) -> f32 {\n if (c <= 0.0031308) { return c * 12.92; }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nfn linearToSrgb(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS, row-major \u2192 WGSL columns (= the transpose).\nconst LINEAR_SRGB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients, row-major \u2192 WGSL columns.\nconst LMS_TO_OKLAB: mat3x3<f32> = mat3x3<f32>(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF, row-major \u2192 WGSL columns.\nconst OKLAB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB, row-major \u2192 WGSL columns.\nconst LMS_TO_LINEAR_SRGB: mat3x3<f32> = mat3x3<f32>(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\nfn cbrt3(v: vec3<f32>) -> vec3<f32> {\n return sign(v) * pow(abs(v), vec3<f32>(1.0 / 3.0));\n}\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nfn srgbToOklab(c: vec3<f32>) -> vec3<f32> {\n let lin = srgbToLinear(c);\n let lms = LINEAR_SRGB_TO_LMS * lin;\n return LMS_TO_OKLAB * cbrt3(lms);\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nfn oklabToLinearSrgb(lab: vec3<f32>) -> vec3<f32> {\n let lms_ = OKLAB_TO_LMS * lab;\n let lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS, folded to [0, 2pi). Mirrors value.js rawOklabToOklch.\nfn oklabToOklch(lab: vec3<f32>) -> vec3<f32> {\n let C = length(lab.yz);\n var H = atan2(lab.z, lab.y);\n if (H < 0.0) { H = H + 2.0 * PI; }\n return vec3<f32>(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nfn oklchToOklab(lch: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\n// OKLCh gamut clamp, palette sample, and breath from metaball-palette.wgsl,\n// spliced AFTER the OKLCH_MATRICES_WGSL chunk above (its matrix source). NB: do NOT\n// write the chunk's identifier with a template-interpolation form in a WGSL comment \u2014 it\n// would inject the whole multi-line matrices chunk INTO this // comment line and break the\n// parse at the first injected newline, the live WGSL syntax error\n// that silently fell every metaball/goo-dot to the WebGL2 net, masking the WGSL primary).\n\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// Sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// De-synced breath using three detuned sines at irrational ratios.\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n\n\n// The composite SDF field with its analytic gradient: vec3(dist, \u2202/\u2202x, \u2202/\u2202y).\nfn sceneDistG(uv: vec2<f32>) -> vec3<f32> {\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uNoiseAmp = u.s1.x;\n let uNoiseFreq = u.s1.y;\n let uNoiseSpeed = u.s1.z;\n let uWarpAmp = u.s1.w;\n let uSmoothK = u.s2.x;\n let uTime = u.s0.x;\n let uVelocity = u.ptr.zw;\n let uStretch = u.s6.w;\n let uSatCount = u.ints.y;\n let uTrailCount = u.ints.z;\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Velocity-driven VOLUME-PRESERVING squash-and-stretch (tanh-saturated).\n var bodyUv = uv;\n var ax = vec2<f32>(1.0, 0.0);\n var perp = vec2<f32>(0.0, 1.0);\n var sa = 1.0;\n let speed = length(uVelocity);\n let squashed = uStretch > 0.0 && speed > 1e-4;\n if (squashed) {\n ax = uVelocity / speed;\n perp = vec2<f32>(-ax.y, ax.x);\n sa = 1.0 + tanh(speed * 1.6) * uStretch;\n bodyUv = vec2<f32>(dot(uv, ax) / sa, dot(uv, perp) * sa);\n }\n\n // Domain-warped FBM displacement WITH its analytic gradient.\n let fbmv = fbmWarpedG(bodyUv * uNoiseFreq + uTime * uNoiseSpeed, 3, uWarpAmp);\n let bodyDisplacement = (fbmv.x - 0.5) * uNoiseAmp;\n let dispGradBody = uNoiseAmp * uNoiseFreq * fbmv.yz;\n\n let bodyG = sdgCircle(bodyUv, vec2<f32>(0.0), bodyR + bodyDisplacement);\n let bodyGradBody = bodyG.yz - dispGradBody;\n\n var bodyGradUv: vec2<f32>;\n if (squashed) {\n let scaled = vec2<f32>(bodyGradBody.x / sa, bodyGradBody.y * sa);\n bodyGradUv = scaled.x * ax + scaled.y * perp;\n } else {\n bodyGradUv = bodyGradBody;\n }\n var d = vec3<f32>(bodyG.x, bodyGradUv);\n\n // Satellites \u2014 smin-merged into the body.\n for (var i = 0; i < MAX_SATS; i = i + 1) {\n if (i >= uSatCount) { break; }\n let s = u.satPos[i];\n var satG = sdgCircle(uv, s.xy, s.z);\n satG.x = satG.x + (1.0 - s.w) * 0.3;\n d = sminG(d, satG, uSmoothK);\n }\n\n // Pointer trail \u2014 a decaying-radius pseudopod.\n for (var i = 0; i < TRAIL_N; i = i + 1) {\n if (i >= uTrailCount) { break; }\n let tp = u.trailPos[i];\n let trailG = sdgCircle(uv, tp.xy, tp.z);\n d = sminG(d, trailG, uSmoothK);\n }\n return d;\n}\n\n// The analytic surface normal from the field gradient.\nfn surfaceNormalFromGrad(grad2d: vec2<f32>, d: f32, bodyR: f32) -> vec3<f32> {\n let g = normalize(grad2d + vec2<f32>(1e-6));\n let interior = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let z = sqrt(max(0.0, 1.0 - (1.0 - interior) * (1.0 - interior)));\n return normalize(vec3<f32>(g * (1.0 - z), z) + vec3<f32>(0.0, 0.0, 1e-6));\n}\n\n// \u2500\u2500 2D SDF soft-shadow march (IQ rmshadows improved penumbra) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Based on research/viz/goo-blob.md \u00A72.3. A procedural soft contact shadow that follows the\n// irregular metaball silhouette (NOT a hard disc, box shadow). Marches a ray from ro\n// along rd (the in-plane projection of uLightDir), accumulating the closest miss via\n// the Aaltonen penumbra (y = h*h/(2*ph) + d = sqrt(h*h - y*y)) that kills the\n// banding the naive res = min(res, h/(w*t)) shows. CHEAP: 24 steps, re-uses the SAME\n// sceneDistG().x field (NO separate field re-eval, NO FBO/multi-pass \u2014 the procedural\n// field needs none, \u00A72.3). w is the penumbra hardness (inverse light-source size \u2192\n// uShadowSoftness). It is derivative-FREE (no fwidth/dpdx/dpdy), so it is fragment-safe\n// here. Returns 1.0 (fully lit) \u2192 0.0 (fully occluded). \u2500\u2500\nfn softShadow2D(ro: vec2<f32>, rd: vec2<f32>, mint: f32, maxt: f32, w: f32) -> f32 {\n var res = 1.0;\n var ph = 1e20;\n var t = mint;\n for (var i = 0; i < 24; i = i + 1) {\n if (t >= maxt) { break; }\n let h = sceneDistG(ro + rd * t).x;\n if (h < 0.001) { return 0.0; }\n let y = h * h / (2.0 * ph);\n let dd = sqrt(max(h * h - y * y, 0.0));\n res = min(res, dd / (w * max(0.001, t - y)));\n ph = h;\n t = t + h;\n }\n return clamp(res, 0.0, 1.0);\n}\n\n// \u2500\u2500 Full-screen triangle vertex stage (the pilot idiom \u2014 no vertex buffer) \u2500\u2500\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {\n var p = vec2<f32>(-1.0, -1.0);\n if (vi == 1u) { p = vec2<f32>(3.0, -1.0); }\n else if (vi == 2u) { p = vec2<f32>(-1.0, 3.0); }\n var out: VSOut;\n out.pos = vec4<f32>(p, 0.0, 1.0);\n // vUv = aPos * 0.5 + 0.5 (the metaball.vert convention).\n out.uv = p * 0.5 + 0.5;\n return out;\n}\n\n// \u2500\u2500 Fragment stage (the main() transcription) \u2500\u2500\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n let uTime = u.s0.x;\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uMaxReach = u.s2.z;\n let uLit = u.s2.w;\n let uPointerActive = u.s7.x;\n let uPointerAttraction = u.s7.y;\n let uPointerStrength = u.s7.z;\n // The stage-1 gate (1.0 = the plain shadowless fill-only floor).\n let uStage = u.s7.w;\n // The blob-to-meatball shading-morph scalar (the base.w pad\n // lane; the typed-struct SoT writes it). 0 = flat blob, 1 = lit meatball, in-between\n // lerps the surface shading (the smin geometry is shared).\n let uMorphT = clamp(u.base.w, 0.0, 1.0);\n let uPointer = u.ptr.xy;\n let uHueRange = u.s5.z;\n let uSatShift = u.s5.w;\n let uBrightnessShift = u.s6.x;\n let uColorNoiseFreq = u.s6.y;\n let uColorNoiseSpeed = u.s6.z;\n let uIridescence = u.s4.x;\n let uIridHue = u.s4.y;\n let uIridSpeed = u.s4.z;\n let uSssScale = u.s4.w;\n let uSssPower = u.s5.x;\n let uCoreGlow = u.s5.y;\n let uSpecStrength = u.s3.x;\n let uSpecShininess = u.s3.y;\n let uRimPower = u.s3.z;\n let uRimStrength = u.s3.w;\n let uLightDir = u.light.xyz;\n let uRimColor = u.rim.rgb;\n // The soft-shadow gate + penumbra hardness (res.z/res.w lanes).\n let uShadow = u.res.z;\n let uShadowSoftness = u.res.w;\n\n var uv = in.uv - 0.5;\n\n // Pre-FBM bounding test, expressed for uniform derivative flow. The GLSL fallback\n // EARLY-RETURNS transparent here (a perf skip of the FBM border); WGSL CANNOT \u2014 an early\n // return predicated on the per-fragment uv makes the fwidth(d)/fwidth(Nh) calls below\n // reachable only through non-uniform control flow, which the WGSL uniformity analyzer\n // REJECTS (fwidth must only be called from uniform control flow) so the metaball WGSL\n // module never compiled and every GooBlob + goo-dot fell silently to the WebGL2 net (the\n // \"broken TOTALLY\" the user reports, the un-exercised Safari-primary surface). So the\n // bound is folded into the FINAL alpha (a flag, NOT a control-flow return): the derivative\n // builtins stay in UNIFORM control flow, and an outside fragment writes transparent at the\n // end \u2014 gestalt-identical to the GLSL early-out, just without the WGSL-illegal pre-\n // derivative return. sceneDistG is derivative-FREE so running it on the border costs only\n // ALU (no correctness hazard); the real GPU swallows it.\n let inBounds = dot(uv, uv) <= uMaxReach * uMaxReach;\n\n // Pointer deformation preserves the signed attraction direction.\n if (uPointerActive > 0.5) {\n let pointerDir = uPointer - uv;\n let pointerDist = length(pointerDir);\n let influence = smoothstep(0.5, 0.0, pointerDist) * uPointerAttraction * uPointerStrength;\n uv = uv + normalize(pointerDir + vec2<f32>(1e-6)) * influence;\n }\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Composite domain-warped membrane field WITH its analytic gradient.\n let scene = sceneDistG(uv);\n let d = scene.x;\n let fieldGrad = scene.yz;\n\n // \u2500\u2500 fwidth SITE #1 (metaball.frag.ts line 266) \u2014 AA-edge half-width from the SDF\n // screen-space gradient. The WGSL fragment-stage fwidth() transcription. In UNIFORM\n // control flow (no early return precedes it \u2014 the bounding test above is a flag). \u2500\u2500\n let aa = max(fwidth(d), 1e-6);\n // The bounding test (D3c) folds in here: an out-of-bounds fragment is forced transparent\n // (the GLSL early-out's transparent WRITE, expressed as an alpha gate, not a return).\n let alpha = (1.0 - smoothstep(-aa, aa, d)) * select(0.0, 1.0, inBounds);\n\n // \u2500\u2500 WGSL uniformity structure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // The Toksvig screen-space derivative (fwidth SITE #2) is hoisted HERE, into the SAME\n // uniform control flow fwidth(d) above already arms in (top-level fs_main, before the\n // per-fragment alpha < 0.001 early-return and the uLit/uShadow non-uniform branches).\n // WGSL uniformity analysis rejects a fwidth() reached only through a return predicated\n // on a per-fragment value (the alpha < 0.001 early-out) nested under further branches\n // exactly the residual that kept the normal derivative inside the lit branch from\n // compiling, so the WGSL primary never armed and GooBlob fell to the WebGL2 net. Nh is\n // the uniform-flow surface normal computed for this derivative ONLY (byte-identical to\n // the lit block's own N = surfaceNormalFromGrad(...) below \u2014 the SAME inputs, so\n // nVar = length(fwidth(Nh)) IS the Toksvig clamp the lit block reads); the named lit-\n // block N stays AFTER the uStage early-return (the STAGE-1 floor reaches no lit work).\n // nVar is a pure uniform-flow value the lit block READS \u2014 no derivative in non-uniform\n // flow; the math is byte-identical to the GLSL fallback's Toksvig clamp, only its\n // EVALUATION POINT moved. The shadow march (T2) reuses d (the same sceneDistG().x).\n let Nh = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n // \u2500\u2500 fwidth SITE #2 (metaball.frag.ts line 364) \u2014 Toksvig normal-variance specular\n // clamp, the WGSL fragment-stage fwidth() of the surface normal. NOW in uniform\n // control flow (the structural fix), so the WGSL primary ARMS + paints the full lit\n // creature instead of falling to the stripped WebGL2 fallback. \u2500\u2500\n let nVar = length(fwidth(Nh));\n\n if (alpha < 0.001) {\n return vec4<f32>(0.0);\n }\n\n // Edit #4 \u2014 perceptually-uniform OKLCh variation.\n let colorNoise = fbm(uv * uColorNoiseFreq + uTime * uColorNoiseSpeed, 3);\n var oklch = samplePaletteOklch(colorNoise);\n\n oklch.z = oklch.z + (colorNoise - 0.5) * uHueRange * (PI / 180.0);\n oklch.y = max(oklch.y + (colorNoise - 0.5) * uSatShift, 0.0);\n oklch.x = clamp(oklch.x + uBrightnessShift, 0.0, 1.0);\n\n // \u2500\u2500 The stripped flat floor (morphT=0). \u2500\u2500\n // The minimal verifiable floor: SDF + smin (the meatball field, already in d/\n // alpha above) + fwidth-AA (the crisp alpha above) + warm-cream fill. NO surface\n // normal, NO Fresnel, NO lit glint, NO iridescence, NO fake-SSS, NO shadow \u2014\n // deliberately FLAT. It returns BEFORE any of the STAGE-2 dressing is reached. The\n // STAGE-1 path simply never READS the hoisted Nh/nVar or the lit/shadow blocks; the\n // normal derivative is now in uniform control flow above, so both the stage-1 floor\n // and the stage-2 lit path arm on Metal. The residual that kept stage 2 falling to\n // the WebGL2 path is closed. The\n // teaching contrast: this is the \"it renders, it meatballs, it works on Safari\"\n // floor STAGE 2 layers the lit/shadow onto via the SAME uniforms.\n // The flat blob fill is snapshotted from the pre-dressing\n // oklch (the dressing mutates oklch below). At morphT <= 0 (a pure blob) emit the\n // flat fill + dither and return \u2014 the byte-identical STAGE-1 floor, zero dressing cost.\n let flatOkl = gamutClampOklch(oklch);\n let flatLin = oklabToLinearSrgb(oklchToOklab(flatOkl));\n let flatRgbBase = clamp(linearToSrgb(flatLin), vec3<f32>(0.0), vec3<f32>(1.0));\n if (uMorphT <= 0.0) {\n let fc1 = in.pos.xy;\n let ign1 = fract(52.9829189 * fract(dot(fc1, vec2<f32>(0.06711056, 0.00583715))));\n let rgb1 = clamp(flatRgbBase + (ign1 - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb1 * alpha, alpha);\n }\n\n // The named surface normal the lit/iridescence/SSS blocks read (byte-identical inputs to\n // the hoisted Nh above \u2014 the Toksvig nVar = length(fwidth(Nh)) IS this N's screen-space\n // variance). It sits AFTER the uStage early-return so the STAGE-1 floor reaches no lit work.\n let N = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n let V = vec3<f32>(0.0, 0.0, 1.0);\n let thickness = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let fres = pow(1.0 - max(dot(N, V), 0.0), 2.5);\n\n // \u2500\u2500 iridescence \u2014 warm-biased IQ cosine palette driving OKLCh HUE \u2500\u2500\n if (uIridescence > 0.0) {\n let t = fres + 0.3 * colorNoise + uTime * uIridSpeed;\n let iridHue = uIridHue + 0.18 * PI * cos(2.0 * PI * t);\n let w = fres * uIridescence;\n oklch.z = mix(oklch.z, iridHue, w);\n oklch.y = min(oklch.y + 0.04 * w, oklch.y + 0.08);\n oklch.x = min(oklch.x + 0.05 * w, 1.0);\n }\n\n // \u2500\u2500 fake subsurface translucency \u2014 thickness inner-glow + back-light \u2500\u2500\n if (uCoreGlow > 0.0 || uSssScale > 0.0) {\n oklch.x = min(oklch.x + uCoreGlow * (1.0 - exp(-3.0 * thickness)), 1.0);\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let back = pow(clamp(dot(V, -(L + N * thickness)), 0.0, 1.0), uSssPower);\n let sss = back * uSssScale * (1.0 - thickness);\n oklch.x = min(oklch.x + sss, 1.0);\n oklch.z = oklch.z + sss * 0.1 * (1.0 - thickness);\n }\n\n // \u2500\u2500 Soft contact shadow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // A procedural soft shadow that\n // FOLLOWS the irregular silhouette: march from this fragment's uv toward the in-plane\n // projection of uLightDir; where the metaball field occludes the light (the body\n // shadows itself opposite the light, a satellite shadows the body across the neck), the\n // march returns < 1 and DARKENS the OKLCh L \u2014 a soft grounded contact band UNDER the\n // dome, congruent with (but PROCEDURAL, silhouette-following, unlike) the CSS gel-dome\n // drop-shadow. Concentrated on the AWAY-facing lower rim (an away-facing weight \u00D7 a\n // thin-rim Gaussian band) so the deep-lit interior + the light-facing edge stay bright\n // and the grounded shadow reads at the lower silhouette edge \u2014 the warm-cream body mean\n // holds. Gated uShadow > 0.5; morphT=0 ships shadowless. \u2500\u2500\n if (uShadow > 0.5) {\n let L2 = normalize(uLightDir.xy + vec2<f32>(1e-6));\n // w increases with the inverse light-source size \u2192 uShadowSoftness (a harder penumbra at a\n // higher value). Start the march just off the surface so a fragment never self-shadows\n // at t=0; cap the reach at the body span.\n let sh = softShadow2D(uv, L2, max(aa, 0.004), bodyR * 1.5, max(uShadowSoftness, 4.0));\n // The contact band sits on the LOWER rim (the side AWAY from the light) \u2014 gated by\n // dot(fieldGrad, L2) < 0 (the rim facing away from L2) AND the thin-rim weight\n // (a Gaussian band peaking at thickness \u2248 0.18 so the deep-lit interior + the\n // light-facing edge stay BRIGHT \u2014 the warm-cream body mean holds). The 0.20 cap keeps\n // it a soft grounding whisper, never a gouge (the warm-cream identity + the\n // floor hold).\n let away = clamp(-dot(normalize(fieldGrad + vec2<f32>(1e-6)), L2), 0.0, 1.0);\n let band = exp(-pow((thickness - 0.18) / 0.16, 2.0));\n let shadowDarken = (1.0 - sh) * away * band * 0.20;\n oklch.x = max(oklch.x - shadowDarken, 0.0);\n }\n\n oklch = gamutClampOklch(oklch);\n\n var lin = oklabToLinearSrgb(oklchToOklab(oklch));\n\n // \u2500\u2500 lit glass surface \u2014 Blinn-Phong glint + Fresnel rim, in LINEAR \u2500\u2500\n if (uLit > 0.5) {\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let H = normalize(L + V);\n\n let warmCream = oklabToLinearSrgb(oklchToOklab(vec3<f32>(0.97, 0.03, radians(85.0))));\n\n // \u2500\u2500 fwidth SITE #2 \u2014 Toksvig normal-variance specular clamp. nVar is the HOISTED\n // length(fwidth(N)), computed once at the top of fs_main\n // in uniform control flow so the WGSL primary arms on Metal. The math is\n // byte-identical to the GLSL fallback (length(fwidth(N))); only its evaluation\n // point moved out of this non-uniform if (uLit > 0.5) branch. \u2500\u2500\n let shininess = uSpecShininess / (1.0 + 24.0 * nVar);\n let energyNorm = (shininess + 2.0) / 8.0;\n let spec = pow(max(dot(N, H), 0.0), shininess) * uSpecStrength * energyNorm;\n\n var rimOkl = oklabToOklch(srgbToOklab(uRimColor));\n let bodyL = oklch.x;\n let dL = abs(rimOkl.x - bodyL);\n let lack = clamp((0.22 - dL) / 0.22, 0.0, 1.0);\n // target is a WGSL RESERVED word (W3C WGSL 16.2) so a \"var target\" declaration is an\n // invalid identifier: the shader module fails to compile and the WGSL primary never\n // arms, so it is named targetL, a valid identifier; the math + the value\n // are identical.\n var targetL = 0.18;\n if (bodyL < 0.5) { targetL = 0.92; }\n rimOkl.x = clamp(mix(rimOkl.x, targetL, lack), 0.0, 1.0);\n rimOkl.y = rimOkl.y * mix(1.0, 0.5, lack);\n let rimLin = oklabToLinearSrgb(oklchToOklab(rimOkl));\n\n let rimFres = pow(1.0 - max(dot(N, V), 0.0), uRimPower);\n let rim = rimFres * uRimStrength * (1.0 - 0.6 * thickness);\n\n var highlight = max(warmCream * spec, rimLin * rim);\n highlight = min(highlight, vec3<f32>(0.85));\n lin = lin + highlight;\n }\n\n var rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n\n // Compose the blob\u2194meatball shading morph: lerp the flat blob\n // fill -> the dressed meatball surface on uMorphT (the geometry/alpha is shared; only\n // the surface shading interpolates). morphT == 1 is byte-identical to the dressed\n // meatball; the morphT == 0 case already returned the flat fill above.\n rgb = mix(flatRgbBase, rgb, uMorphT);\n\n // IGN dither \u2014 1-LSB triangular dither in DISPLAY space, AFTER linearToSrgb.\n let fragCoord = in.pos.xy;\n let ign = fract(52.9829189 * fract(dot(fragCoord, vec2<f32>(0.06711056, 0.00583715))));\n rgb = clamp(rgb + (ign - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n\n // premultiply AFTER the OETF: straight-alpha gamma \u2192 premultiplied.\n return vec4<f32>(rgb * alpha, alpha);\n}\n";
@@ -1 +1 @@
1
- export declare const METABALL_SDF_GLSL = "// --- SDF ---\n\nfloat sdCircle(vec2 p, vec2 center, float radius) {\n return length(p - center) - radius;\n}\n\n// AX.W15 \u2014 the VALUE+GRADIENT circle: returns vec3(d, dd/dx, dd/dy). The circle\n// gradient is the UNIT radial direction (p - center)/length(p - center) (the\n// eikonal property holds EXACTLY for a circle), guarded at the degenerate centre.\n// This is the keystone of the analytic-gradient smin: carrying the gradient\n// through the scene field DELETES the per-pixel 4-tap normal (4 full sceneDist\n// evals, each running 3-octave FBM + the sat/trail loops).\nvec3 sdgCircle(vec2 p, vec2 center, float radius) {\n vec2 d = p - center;\n float len = length(d);\n vec2 grad = len > 1e-6 ? d / len : vec2(0.0, 1.0);\n return vec3(len - radius, grad);\n}\n\n// IQ 2024 quadratic-polynomial smin, NORMALIZED so k is a blend band in distance\n// units. The k *= 4.0 pre-scale makes the h*h*k*0.25 poly's effective blend width\n// equal to k (the un-normalized form's width was 0.25*k).\nfloat sminQuadratic(float a, float b, float k) {\n k *= 4.0;\n float h = max(k - abs(a - b), 0.0) / k;\n return min(a, b) - h * h * k * 0.25;\n}\n\n// IQ circular smin \u2014 a quarter-circle fillet at the seam (rounder than the\n// quadratic). The k *= 1.0/(1.0-sqrt(0.5)) factor normalizes k to the same\n// blend-band units so the merge axis swaps shape without re-tuning uSmoothK.\nfloat sminCircular(float a, float b, float k) {\n k *= 1.0 / (1.0 - sqrt(0.5));\n float h = max(k - abs(a - b), 0.0) / k;\n return min(a, b) - k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n}\n\n// Config-gated merge dispatch \u2014 uMerge 0 = quadratic, 1 = circular.\nfloat smin(float a, float b, float k) {\n if (uMerge > 0.5) return sminCircular(a, b, k);\n return sminQuadratic(a, b, k);\n}\n\n// AX.W15 \u2014 the VALUE+GRADIENT smin. a/b are vec3(dist, grad.xy); the blended\n// gradient is mix(a.yz, b.yz, w) with the interpolation weight w the distance\n// blend uses (IQ's vec2-smin insight). This propagates the analytic gradient\n// through the merge so the surface normal reads the field gradient DIRECTLY \u2014 no\n// finite-difference tap. The blend weight matches each variant.\nvec3 sminQuadraticG(vec3 a, vec3 b, float k) {\n k *= 4.0;\n float h = max(k - abs(a.x - b.x), 0.0) / k;\n float m = h * h * k * 0.25;\n // h-weight that selects which surface dominates (0 \u2192 a, 1 \u2192 b).\n float w = (a.x < b.x) ? 0.5 * h * h : 1.0 - 0.5 * h * h;\n float dist = min(a.x, b.x) - m;\n vec2 grad = mix(a.yz, b.yz, w);\n return vec3(dist, grad);\n}\n\nvec3 sminCircularG(vec3 a, vec3 b, float k) {\n k *= 1.0 / (1.0 - sqrt(0.5));\n float h = max(k - abs(a.x - b.x), 0.0) / k;\n float m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n float w = (a.x < b.x) ? 0.5 * h : 1.0 - 0.5 * h;\n float dist = min(a.x, b.x) - m;\n vec2 grad = mix(a.yz, b.yz, w);\n return vec3(dist, grad);\n}\n\nvec3 sminG(vec3 a, vec3 b, float k) {\n if (uMerge > 0.5) return sminCircularG(a, b, k);\n return sminQuadraticG(a, b, k);\n}";
1
+ export declare const METABALL_SDF_GLSL = "// --- SDF ---\n\nfloat sdCircle(vec2 p, vec2 center, float radius) {\n return length(p - center) - radius;\n}\n\n// Value and gradient circle: returns vec3(d, dd/dx, dd/dy). The circle\n// gradient is the UNIT radial direction (p - center)/length(p - center) (the\n// eikonal property holds EXACTLY for a circle), guarded at the degenerate centre.\n// This is the keystone of the analytic-gradient smin: carrying the gradient\n// through the scene field DELETES the per-pixel 4-tap normal (4 full sceneDist\n// evals, each running 3-octave FBM + the sat/trail loops).\nvec3 sdgCircle(vec2 p, vec2 center, float radius) {\n vec2 d = p - center;\n float len = length(d);\n vec2 grad = len > 1e-6 ? d / len : vec2(0.0, 1.0);\n return vec3(len - radius, grad);\n}\n\n// IQ 2024 quadratic-polynomial smin, NORMALIZED so k is a blend band in distance\n// units. The k *= 4.0 pre-scale makes the h*h*k*0.25 poly's effective blend width\n// equal to k (the un-normalized form's width was 0.25*k).\nfloat sminQuadratic(float a, float b, float k) {\n k *= 4.0;\n float h = max(k - abs(a - b), 0.0) / k;\n return min(a, b) - h * h * k * 0.25;\n}\n\n// IQ circular smin \u2014 a quarter-circle fillet at the seam (rounder than the\n// quadratic). The k *= 1.0/(1.0-sqrt(0.5)) factor normalizes k to the same\n// blend-band units so the merge axis swaps shape without re-tuning uSmoothK.\nfloat sminCircular(float a, float b, float k) {\n k *= 1.0 / (1.0 - sqrt(0.5));\n float h = max(k - abs(a - b), 0.0) / k;\n return min(a, b) - k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n}\n\n// Config-gated merge dispatch \u2014 uMerge 0 = quadratic, 1 = circular.\nfloat smin(float a, float b, float k) {\n if (uMerge > 0.5) return sminCircular(a, b, k);\n return sminQuadratic(a, b, k);\n}\n\n// Value and gradient smin. a/b are vec3(dist, grad.xy); the blended\n// gradient is mix(a.yz, b.yz, w) with the interpolation weight w the distance\n// blend uses (IQ's vec2-smin insight). This propagates the analytic gradient\n// through the merge so the surface normal reads the field gradient DIRECTLY \u2014 no\n// finite-difference tap. The blend weight matches each variant.\nvec3 sminQuadraticG(vec3 a, vec3 b, float k) {\n k *= 4.0;\n float h = max(k - abs(a.x - b.x), 0.0) / k;\n float m = h * h * k * 0.25;\n // h-weight that selects which surface dominates (0 \u2192 a, 1 \u2192 b).\n float w = (a.x < b.x) ? 0.5 * h * h : 1.0 - 0.5 * h * h;\n float dist = min(a.x, b.x) - m;\n vec2 grad = mix(a.yz, b.yz, w);\n return vec3(dist, grad);\n}\n\nvec3 sminCircularG(vec3 a, vec3 b, float k) {\n k *= 1.0 / (1.0 - sqrt(0.5));\n float h = max(k - abs(a.x - b.x), 0.0) / k;\n float m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n float w = (a.x < b.x) ? 0.5 * h : 1.0 - 0.5 * h;\n float dist = min(a.x, b.x) - m;\n vec2 grad = mix(a.yz, b.yz, w);\n return vec3(dist, grad);\n}\n\nvec3 sminG(vec3 a, vec3 b, float k) {\n if (uMerge > 0.5) return sminCircularG(a, b, k);\n return sminQuadraticG(a, b, k);\n}";
@@ -1,2 +1,2 @@
1
- export declare const METABALL_EDGE_NOISE_PRE_GLSL = "// --- Noise ---\n\nfloat hash21(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient\n// (d/dx, d/dy) in .yz, from one eval. The quintic fade has a continuous 2nd\n// derivative so the gradient is smooth (a cubic smoothstep fade would crease it).\n// (Inigo Quilez, https://iquilezles.org/articles/gradientnoise/.)\nvec3 noised(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n\n // Quintic fade + its derivative.\n vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n vec2 du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n // Per-corner gradient vectors from the hash (centred to [-1, 1]).\n vec2 ga = -1.0 + 2.0 * vec2(hash21(i + vec2(0.0, 0.0)), hash21(i + vec2(7.3, 0.0)));\n vec2 gb = -1.0 + 2.0 * vec2(hash21(i + vec2(1.0, 0.0)), hash21(i + vec2(8.3, 0.0)));\n vec2 gc = -1.0 + 2.0 * vec2(hash21(i + vec2(0.0, 1.0)), hash21(i + vec2(7.3, 1.0)));\n vec2 gd = -1.0 + 2.0 * vec2(hash21(i + vec2(1.0, 1.0)), hash21(i + vec2(8.3, 1.0)));\n\n float va = dot(ga, f - vec2(0.0, 0.0));\n float vb = dot(gb, f - vec2(1.0, 0.0));\n float vc = dot(gc, f - vec2(0.0, 1.0));\n float vd = dot(gd, f - vec2(1.0, 1.0));\n\n // Value, remapped to [0,1] so it drops in for the prior valueNoise.\n float n = va + u.x * (vb - va) + u.y * (vc - va) + u.x * u.y * (va - vb - vc + vd);\n float value = 0.5 + 0.5 * n;\n\n // Analytic gradient (chain rule through the bilinear blend + the fade).\n vec2 grad =\n ga + u.x * (gb - ga) + u.y * (gc - ga) + u.x * u.y * (ga - gb - gc + gd) +\n du * (vec2(u.y, u.x) * (va - vb - vc + vd) + vec2(vb, vc) - va);\n return vec3(value, 0.5 * grad);\n}\n\n// Rotated-octave FBM over the analytic gradient noise: a fixed ~0.5 rad 2x2\n// rotation between octaves breaks the axis-aligned banding. The rotation CONSTANT\n// is spliced from the shared chunk (AV.W2 \u2014 the one FBM_ROT); the loops below\n// stay blob-local (param octaves + the LIQUID lacunarity/persistence, per \u00A73a).";
1
+ export declare const METABALL_EDGE_NOISE_PRE_GLSL = "// --- Noise ---\n\nfloat hash21(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient\n// (d/dx, d/dy) in .yz, from one eval. The quintic fade has a continuous 2nd\n// derivative so the gradient is smooth (a cubic smoothstep fade would crease it).\n// (Inigo Quilez, https://iquilezles.org/articles/gradientnoise/.)\nvec3 noised(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n\n // Quintic fade + its derivative.\n vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n vec2 du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n // Per-corner gradient vectors from the hash (centred to [-1, 1]).\n vec2 ga = -1.0 + 2.0 * vec2(hash21(i + vec2(0.0, 0.0)), hash21(i + vec2(7.3, 0.0)));\n vec2 gb = -1.0 + 2.0 * vec2(hash21(i + vec2(1.0, 0.0)), hash21(i + vec2(8.3, 0.0)));\n vec2 gc = -1.0 + 2.0 * vec2(hash21(i + vec2(0.0, 1.0)), hash21(i + vec2(7.3, 1.0)));\n vec2 gd = -1.0 + 2.0 * vec2(hash21(i + vec2(1.0, 1.0)), hash21(i + vec2(8.3, 1.0)));\n\n float va = dot(ga, f - vec2(0.0, 0.0));\n float vb = dot(gb, f - vec2(1.0, 0.0));\n float vc = dot(gc, f - vec2(0.0, 1.0));\n float vd = dot(gd, f - vec2(1.0, 1.0));\n\n // Value, remapped to [0,1] so it drops in as the valueNoise.\n float n = va + u.x * (vb - va) + u.y * (vc - va) + u.x * u.y * (va - vb - vc + vd);\n float value = 0.5 + 0.5 * n;\n\n // Analytic gradient (chain rule through the bilinear blend + the fade).\n vec2 grad =\n ga + u.x * (gb - ga) + u.y * (gc - ga) + u.x * u.y * (ga - gb - gc + gd) +\n du * (vec2(u.y, u.x) * (va - vb - vc + vd) + vec2(vb, vc) - va);\n return vec3(value, 0.5 * grad);\n}\n\n// Rotated-octave FBM over the analytic gradient noise: a fixed ~0.5 rad 2x2\n// rotation between octaves breaks the axis-aligned banding. The rotation CONSTANT\n// is spliced from the shared chunk; the loops below\n// stay blob-local (param octaves + the LIQUID lacunarity/persistence, per \u00A73a).";
2
2
  export declare const METABALL_EDGE_NOISE_POST_GLSL: string;
@@ -3,22 +3,7 @@ export type BlobMood = "idle" | "happy" | "curious" | "sleepy" | "excited";
3
3
  /** Smin merge variant — `quadratic` (cheap, creased) | `circular` (rounder menisci). */
4
4
  export type BlobMerge = "quadratic" | "circular";
5
5
  /**
6
- * The render-variant axis (BC.W-GOOBLOB-PLAIN — STAGE 1 owns the first two members).
7
- *
8
- * - `"blob"` — the STAGE-1 first-principles floor: a plain shadowless lightless
9
- * fill-only droplet (SDF + smin satellites + fwidth-AA + warm-cream fill). The
10
- * minimal verifiable "it renders, it meatballs, it works on Safari" register the
11
- * `uStage` gate strips the lit/shadow blocks for. NO specular, NO iridescence, NO
12
- * SSS, NO shadow — deliberately minimal.
13
- * - `"meatball"` — the full lit register (the default): STAGE 2 builds the lit-glass
14
- * surface / Fresnel rim / iridescence / SSS / shadow ON the same field via the
15
- * `uLit`/`uShadow` flags. Byte-identical to the pre-STAGE-1 default pipeline.
16
- *
17
- * `"dot-matrix"` / `"dot-sphere"` are the later-sub-wave siblings (not STAGE 1).
18
- */
19
- export type BlobVariant = "blob" | "meatball";
20
- /**
21
- * Render-quality axis (AX.W16) — `full` (default) renders the metaball pass at the
6
+ * Render-quality axis: `full` (default) renders the metaball pass at the
22
7
  * clamped DPR; `half` renders the backing store at HALF resolution and lets the
23
8
  * browser bilinear-upsample on composite (~4× fragment savings for weak GPUs — the
24
9
  * blob is the ideal candidate: the soft FBM/AA edge hides the interpolation).
@@ -45,11 +30,11 @@ export interface MetaballSource {
45
30
  radius: number;
46
31
  opacity: number;
47
32
  /**
48
- * BD.W-GOOBLOB-MERCURY-COLONY — the per-source SPLIT token (default `false`). When a
33
+ * the per-source SPLIT token (default `false`). When a
49
34
  * satellite is mid-`fissioning`, this is `true` and the uniform packers DROP the
50
35
  * `orbitWiden` bridge to nominal for it ALONE, so its neck thins past the smin reach
51
36
  * and SNAPS into a free bead. Every non-fissioning source keeps the full bridge (the
52
- * R8-07 "instant fully-detached disc" cure). Trail sources never fission (`false`).
37
+ * "instant fully-detached disc" cure). Trail sources never fission (`false`).
53
38
  */
54
39
  fissioning?: boolean;
55
40
  }
@@ -82,17 +67,17 @@ export interface SatelliteInternal {
82
67
  * `phase`, but exposed on the published `MetaballSource` (below) so the GL leaves can
83
68
  * gate the bridge widen per-satellite WITHOUT importing the satellite internals. A
84
69
  * fissioning satellite drops to nominal bridge (its neck snaps); every other
85
- * satellite keeps the full+capped widen (R8-07 cured).
70
+ * satellite keeps the full+capped widen ( cured).
86
71
  */
87
72
  fissioning: boolean;
88
73
  /**
89
- * BD.W-GOOBLOB-MERCURY-COLONY — the phase-local SNAP latch: false at the fission
74
+ * the phase-local SNAP latch: false at the fission
90
75
  * beat start, set true once the neck crosses the snap band (so the body-pulse recoil
91
76
  * kick fires EXACTLY ONCE per pinch, not every frame across the snap window).
92
77
  */
93
78
  snapFired: boolean;
94
79
  }
95
- /** Body / orbit / satellite geometry — the contained-droplet length cohort (W15). */
80
+ /** Body, orbit, and satellite geometry. */
96
81
  export interface BlobGeometry {
97
82
  canvasSize: number;
98
83
  bodyRadius: number;
@@ -134,14 +119,12 @@ export interface BlobColor {
134
119
  colorNoiseFreq: number;
135
120
  colorNoiseSpeed: number;
136
121
  /**
137
- * BI.W-BLOB-SEAMS (GAP-L5 / value.js D8) — the OKLab-L ink FLOOR the derived
138
- * palette's deepest (body) stop is clamped to, so a seed-derived hero body never
139
- * collapses toward an illegible near-black. A CONFIG atom (the consumer/HERO sets
140
- * it; the palette derivation reads it via `deriveBlobPalette`'s `lightnessFloor`
141
- * param). Bracket-bounded `[0.12, 0.20]` OKLab L — see `LIGHTNESS_FLOOR_BRACKET` /
142
- * `clampLightnessFloor` (`./presets`); default 0.15. This does NOT affect the bare
143
- * default paint (its `paletteStops` are pre-baked CSS strings) — it is the floor a
144
- * consumer DERIVING a palette off `config.color.lightnessFloor` applies.
122
+ * The OKLab-L floor for the deepest derived palette stop, preventing a
123
+ * seed-derived hero body from collapsing toward an illegible near-black.
124
+ * Palette derivation reads it through `deriveBlobPalette.lightnessFloor`.
125
+ * Bounded to `[0.12, 0.20]` OKLab L by `LIGHTNESS_FLOOR_BRACKET` and
126
+ * `clampLightnessFloor`; default 0.15. This does not affect the pre-baked
127
+ * default `paletteStops`.
145
128
  */
146
129
  lightnessFloor?: number;
147
130
  }
@@ -149,14 +132,13 @@ export interface BlobColor {
149
132
  export interface BlobSurface {
150
133
  lit: boolean;
151
134
  /**
152
- * The procedural 2D SDF soft-shadow march (BC.W-GOOBLOB-MEATBALL T2). A soft contact
153
- * shadow FOLLOWING the irregular silhouette (NOT a hard disc/box shadow), gated behind
154
- * the shader `uShadow` flag. Default ON (the `meatball` register); the `blob` STAGE-1
155
- * floor ships shadowless via the `uStage` gate.
135
+ * Procedural 2D SDF soft-shadow march. The contact shadow follows the irregular
136
+ * silhouette rather than a disc or box, gated by `uShadow`. Default on; the
137
+ * flat `blob` stage is shadowless through `uStage`.
156
138
  */
157
139
  shadow: boolean;
158
140
  /**
159
- * Soft-shadow penumbra hardness (BC.W-GOOBLOB-MEATBALL T2) — the inverse light-source
141
+ * Soft-shadow penumbra hardness: the inverse light-source
160
142
  * size fed to the IQ rmshadows march `w` term (a higher value = a harder penumbra).
161
143
  * Range 4–48, default 16.
162
144
  */
@@ -184,29 +166,29 @@ export interface BlobSurface {
184
166
  /** Thickness-driven inner-luminosity (core glow) lift. */
185
167
  coreGlow: number;
186
168
  /**
187
- * BD.W-GOOBLOB-MERCURY-COLONY — the MERCURY-COLONY split register (the OPT-IN scalar,
188
- * 0..1, default the calm floor `0`). At `0` the shipped `variant:"blob"` default stays
189
- * calm + gate-faithful: a permanently-bonded merge/un-merge breath, NO pinch (so
190
- * `proof:blob-render`/`-studio`/`-page` are UNMOVED — `orbitRadius 0.17` is NOT
169
+ * the MERCURY-COLONY split register (the OPT-IN scalar,
170
+ * 0..1, default the calm floor `0`). At `0` a flat-surface configuration stays
171
+ * calm: a permanently bonded merge/unmerge breath with no pinch, so the existing
172
+ * studio and page presets remain unchanged and `orbitRadius 0.17` is not
191
173
  * re-based). Lifting it toward `1` arms the `fissioning` beat: the colony breathes a
192
174
  * satellite OUT through a thinning neck whose gap exceeds the smin reach so it SNAPS
193
175
  * into a free orbiting bead (the mercury pinch), then re-merges next cycle. This is a
194
- * DERIVED bundling over the EXISTING `surface` atom (the variant IS the bundle) — NOT
176
+ * DERIVED bundling over the EXISTING `surface` atom — NOT
195
177
  * a 9th geometry atom; the split rides MOTION (the satellite moves) on the EXISTING
196
178
  * phase machine, NOT a global smin-band re-base (which would lean-regress per
197
- * AZ.W-BLOB-STUDIO D2). Mood-coupled: `excited` splits more, `sleepy` barely. The
179
+ * D2). Mood-coupled: `excited` splits more, `sleepy` barely. The
198
180
  * `colony`/`mercury` register a consumer/studio opts into.
199
181
  */
200
182
  fissionAmp: number;
201
183
  }
202
- /** Pointer interaction — lean / squash-stretch / click-impulse. */
184
+ /** Pointer interaction — lean, squash-stretch, click-impulse. */
203
185
  export interface BlobInteraction {
204
186
  pointerAttraction: number;
205
187
  pointerStrength: number;
206
188
  /**
207
189
  * Velocity-driven volume-preserving squash-and-stretch magnitude (0 = off).
208
190
  *
209
- * AY.W-BLOB-CONFIG D3 — a SWAMPED fine-detail axis. The squash rides the smoothed
191
+ * D3 — a SWAMPED fine-detail axis. The squash rides the smoothed
210
192
  * spring velocity (`useBlobPointer`'s critically-damped `response: 0.18` follow),
211
193
  * which is heavily damped and down-scaled into body space — so the tanh-saturated
212
194
  * elongation reads at the noise floor (a live readback measured 0% body-aspect change
@@ -230,25 +212,11 @@ export interface BlobConfig {
230
212
  surface: BlobSurface;
231
213
  interaction: BlobInteraction;
232
214
  /**
233
- * The render variant (BC.W-GOOBLOB-PLAIN) — `"meatball"` (default, the full lit
234
- * pipeline) | `"blob"` (the STAGE-1 plain shadowless fill-only floor). `"blob"`
235
- * sets the shader `uStage` gate so the lit/shadow/iridescence/SSS blocks are NOT
236
- * reached — the minimal verifiable floor. `"meatball"` is byte-identical to the
237
- * pre-STAGE-1 default (the `surface.lit` flag still owns the lit-on/off within it).
238
- */
239
- variant: BlobVariant;
240
- /**
241
- * BD.W-GOO-CAROUSEL-DECK — the blob↔meatball SHADING-MORPH scalar (0..1). The user's
242
- * "MORPH BLOB and MEATBALL from one to another" — a CONTINUOUS in-between, not a hard
243
- * `variant` cut. `0` = the flat warm-cream blob (byte-identical to `variant: "blob"`);
244
- * `1` = the fully-dressed lit meatball (byte-identical to `variant: "meatball"`);
245
- * `0 < morphT < 1` lerps the SURFACE shading (the smin GEOMETRY is shared, so only the
246
- * fill→lit/shadow/iridescence dressing interpolates). UNSET (the default) → the value
247
- * is resolved from `variant` (blob → 0, meatball → 1), so the existing `variant` prop
248
- * is byte-back-compat. A consumer ANIMATING this (a `useSpring`/registered-scalar) gets
249
- * the live morph.
215
+ * The sole flat↔dressed surface axis. Values are clamped to `[0, 1]`: `0` is the
216
+ * flat warm-cream blob, `1` is the fully dressed lit meatball, and intermediate
217
+ * values smoothly interpolate the surface over the shared smin geometry.
250
218
  */
251
- morphT?: number;
219
+ morphT: number;
252
220
  quality: BlobQuality;
253
221
  tempo: number;
254
222
  }