@pieai/swimmer-ui-kit 1.10.1 → 1.11.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,71 @@
3
3
  All notable changes to `@pieai/swimmer-ui-kit`.
4
4
  Format: [Keep a Changelog](https://keepachangelog.com); versioning: semver.
5
5
 
6
+ ## Unreleased
7
+
8
+ ### Added
9
+
10
+ - **Morph shape evolution and content cross-blur.** `LiquidGroup.Item` now
11
+ accepts `morph={{ shape, speed, bounce, contentBlur }}`. The adopted centre →
12
+ size → corner timeline makes the liquid change form like jelly, while the
13
+ default `contentBlur: 7` is written to the content wrapper only and clears as
14
+ the motion settles. The brand-kit token default deliberately enables shape;
15
+ pass `shape: false` for a calm opt-out.
16
+ - **Surface-glued Bend.** `effect="bend"` follows an externally moved child,
17
+ bows its long edges and deforms its rounded caps without a lagging body or
18
+ tail. It publishes `--lg-bend-x`, `--lg-bend-y`, `--lg-bend-xn`, and
19
+ `--lg-bend-yn` on the item for content tilt/rotation.
20
+ - **Knob stories and budget evidence.** Storybook now exposes conservative,
21
+ default, and bold points for Morph and Bend, plus contentBlur off/default/bold
22
+ comparisons and a combined filter-area readout.
23
+
24
+ ### Performance
25
+
26
+ - Morph content-blur and Bend deformation slack are part of the existing
27
+ 480,000 CSS-pixel filter-area ceiling. The shared requestAnimationFrame clock
28
+ remains event-driven and sleeps completely after stillness; an over-budget
29
+ group snaps to static filtered rendering with a development warning.
30
+ - **Image Melt and contact dissolve for `LiquidGroup.Item`.** The first two
31
+ `effect="melt"` items now render the donor-shaped measured image pair with
32
+ crisp-face seam masks, two-palette colour mixing, and a visible marbling
33
+ pass. `dissolve` is an image-only contact modifier with liquid displacement
34
+ and release hysteresis; DOM text stays in the crisp content layer, and the
35
+ modifier is ignored with a development warning under `effect="move"`.
36
+ Numeric knobs are token-backed, share the 480,000 px² filter-area and
37
+ process-wide concurrency budgets, degrade visibly with a one-time warning
38
+ when over budget, and sleep their requestAnimationFrame clock at rest.
39
+
40
+ ## 1.11.0
41
+
42
+ ### Added
43
+
44
+ - **The rest of the donor's liquid vocabulary.** `morph.shape` gives the
45
+ surface a timeline instead of a resize — the mass travels to the new centre,
46
+ size follows, corners sharpen last. `morph.contentBlur` acts on your content
47
+ rather than the silhouette, which is what makes text read as sitting *in* the
48
+ liquid instead of on it. `effect="bend"` deforms the body with velocity while
49
+ staying glued to its content, and publishes `--lg-bend-x/y` plus unitless
50
+ twins so the content can lean with it. `effect="melt"` runs two images into
51
+ each other with real colour averaging and a marbling pass at the seam, and
52
+ `dissolve` is the same physics as an image-only modifier on a morph item.
53
+ All of them ship on: an effect that defaults to off is one nobody sees, and
54
+ 1.10.0 spent a release proving that with `waviness: 0`.
55
+
56
+ Every effect enabled at once measures 307,892 px² of the 480,000 the process
57
+ budget allows, degrades to a static snap rather than throwing when it runs
58
+ out, and the shared clock still stops dead at rest.
59
+
60
+ The donor's general observer is still not taken, and now the reason is
61
+ written down rather than grouped into a list: this kit's loop meters a
62
+ process-wide budget and sleeps completely when nothing moves, and the donor's
63
+ does neither. Effects are recipes; the loop is the kitchen.
64
+
65
+ ### Fixed
66
+
67
+ - **Image dissolve no longer inherits the default content blur.** `contentBlur`
68
+ arriving on by default reached the DOM text that image-only `dissolve` exists
69
+ to keep crisp. Neither adoption was wrong on its own; the combination was.
70
+
6
71
  ## 1.10.1
7
72
 
8
73
  ### Fixed
package/NOTICE CHANGED
@@ -32,12 +32,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
32
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
33
  SOFTWARE.
34
34
 
35
- Liquid-gooey morph filter
36
- -------------------------
37
- The liquid morph primitive in `src/LiquidGroup.tsx` and its supporting filter,
38
- geometry, shadow, and spring modules is an original SwimmerUIKit
39
- implementation informed by the `liquid-gooey` package in the Libraries
40
- repository (https://github.com/Jakubantalik/Libraries/tree/main/packages/liquid-gooey),
35
+ Liquid-gooey Morph/Bend adaptations
36
+ -----------------------------------
37
+ The liquid primitive in `src/LiquidGroup.tsx` and its supporting filter,
38
+ geometry, shadow, spring, evolve, and Move modules includes direct local
39
+ adaptations from the `liquid-gooey` package in the Libraries repository
40
+ (https://github.com/Jakubantalik/Libraries/tree/main/packages/liquid-gooey),
41
41
  Copyright (c) 2026 Jakub Antalik, licensed under the MIT License.
42
42
 
43
43
  The reviewed upstream state is pinned in `donors-individual-lock.json` at commit
@@ -46,22 +46,81 @@ The reviewed upstream state is pinned in `donors-individual-lock.json` at commit
46
46
  checkout is `<portfolio-root>/_donors-individual/for_SwimmerUIKit/` and is not
47
47
  packaged or loaded at runtime.
48
48
 
49
- We took the donor's morph-specific ideas and small implementation patterns:
50
- the SVG silhouette/content split, the Gaussian-blur plus alpha color-matrix
51
- filter, rounded-rectangle geometry, token-compatible shadow passes, and spring
52
- to easing compilation. We also adapted its Move center spring, velocity-axis
49
+ We directly adapted its Morph centre/size/radius spring timeline and motion
50
+ envelope for `morph.shape`, its 7px-default content cross-blur for
51
+ `morph.contentBlur`, and its Bend velocity-bowed path, horizontal cap
52
+ deformation, surface-glued tracking, and `--lg-bend-x` / `--lg-bend-y` /
53
+ `--lg-bend-xn` / `--lg-bend-yn` CSS variable outlet. The local implementations
54
+ are in `src/liquidGooeyEvolve.ts` and `src/liquidGooeyMove.ts`; their file
55
+ headers repeat this source URL, pinned commit, copyright, MIT license, and
56
+ NOTICE pointer. We also adapted the donor's Move center spring, velocity-axis
53
57
  stretch, and lagging tail/mid-droplet physics for the selected segmented
54
- indicator and progress leading edge. This package now directly adapts the
55
- donor's group-level `waviness` / `wavinessFreq` filter pass: a fixed-seed
56
- `feTurbulence` field and `feDisplacementMap` move the silhouette before its
57
- shadow passes consume it, so the shadow follows the same edge. We did not take
58
- the donor's melt, bend, or dissolve systems, its general observer, or its
59
- image-melt engine. We changed the implementation for this kit by making fill
60
- and shadow values token-driven, keeping waviness static with a shipped-off
61
- token default, adding a process-wide animated-group and filter-area budget
62
- that includes the displacement slack, and putting the shared
63
- requestAnimationFrame clock to sleep after stillness. The actual interactive
64
- content remains outside the filtered SVG layer.
58
+ indicator and progress leading edge. This package directly adapts the donor's
59
+ group-level `waviness` / `wavinessFreq` filter pass: a fixed-seed `feTurbulence`
60
+ field and `feDisplacementMap` move the silhouette before its shadow passes
61
+ consume it, so the shadow follows the same edge.
62
+
63
+ The local implementation also adapts the donor's pairwise image-melt engine in
64
+ `src/liquidGooeyImageMelt.tsx`, including the two-item pairing, measured image
65
+ rects, crisp-face seam masks, two-palette colour mixing, and marbling pass. Its
66
+ contact dissolve masks only `<img>` pixels; text remains in the unfiltered DOM
67
+ content layer. The dissolve math is a scoped adaptation of the donor's contact
68
+ observer behavior, not a transplant of the donor's general observer loop.
69
+
70
+ SwimmerUIKit changes the implementation for this kit by making effect values
71
+ token-driven, keeping texture static with a visible 6px default, and adding
72
+ process-wide animated-group and filter-area budgets that include waviness,
73
+ Morph content-blur, Bend deformation, Melt marbling, and dissolve displacement
74
+ slack. The shared requestAnimationFrame clocks sleep after stillness, and
75
+ over-budget effects degrade visibly with a development warning. The actual
76
+ interactive content remains outside the filtered SVG layer; Morph's blur is
77
+ applied to the content wrapper only, Bend content receives inherited CSS
78
+ variables, and image labels stay crisp above the image layer.
79
+
80
+ The MIT License text for that material:
81
+
82
+ MIT License
83
+
84
+ Copyright (c) 2026 Jakub
85
+
86
+ Permission is hereby granted, free of charge, to any person obtaining a copy
87
+ of this software and associated documentation files (the "Software"), to deal
88
+ in the Software without restriction, including without limitation the rights
89
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
90
+ copies of the Software, and to permit persons to whom the Software is
91
+ furnished to do so, subject to the following conditions:
92
+
93
+ The above copyright notice and this permission notice shall be included in all
94
+ copies or substantial portions of the Software.
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
97
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
98
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
99
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
100
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
101
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
102
+ SOFTWARE.
103
+
104
+ Liquid-gooey image Melt and contact dissolve
105
+ --------------------------------------------
106
+ Portions of the pairwise image-melt and contact-image dissolve implementation
107
+ in `src/liquidGooeyImageMelt.tsx` are adapted from liquid-gooey by Jakub
108
+ Antalik (https://github.com/Jakubantalik/Libraries/tree/main/packages/liquid-gooey),
109
+ Copyright (c) 2026 Jakub, licensed under the MIT License.
110
+
111
+ Source URL: https://github.com/Jakubantalik/Libraries/blob/3862ffa345217443b63696a8c331a0664eea4b04/packages/liquid-gooey/src/imageMelt.tsx
112
+ Pinned donor commit: `3862ffa345217443b63696a8c331a0664eea4b04`
113
+ The scoped contact-dissolve math was reviewed from the same commit's
114
+ `src/observer.ts`. The donor's general observer loop was not imported;
115
+ the kit retains its own budgeted and idle-sleeping runtime. This is a local
116
+ adaptation, not a runtime dependency on the donor checkout.
117
+
118
+ The adapted surface keeps the donor's two-item Melt pairing, measured image
119
+ rects, crisp-face seam masks, two-palette colour mixing and marbling pass. Its
120
+ contact dissolve masks only `<img>` pixels; text remains in the unfiltered DOM
121
+ content layer. SwimmerUIKit adds token-backed knobs, its 480,000 px² filter-area
122
+ and process-wide concurrency budgets, graceful development-visible degradation,
123
+ and a sleeping requestAnimationFrame clock.
65
124
 
66
125
  The MIT License text for that material:
67
126
 
package/dist/index.d.ts CHANGED
@@ -9,6 +9,13 @@ import { TextareaHTMLAttributes } from 'react';
9
9
  /** Opt in to placeholders on purpose, and stop being told about it. */
10
10
  export declare function acknowledgeClayPlaceholders(): void;
11
11
 
12
+ export declare interface BendTuning {
13
+ /** Vertical bow strength, 0..1. */
14
+ vertical?: number;
15
+ /** Horizontal cap deformation, 0..1. */
16
+ horizontal?: number;
17
+ }
18
+
12
19
  export declare const CLAY_ASSET_BASE_PATH: "/assets/game/ui/clay/phase03-clay-kit";
13
20
 
14
21
  export declare const CLAY_ASSET_SIZE_TOKENS: {
@@ -274,6 +281,35 @@ export declare const CLAY_LAYER_TOKENS: {
274
281
  * without putting physics constants in the engine.
275
282
  */
276
283
  declare const CLAY_LIQUID_GOOEY_TOKENS: {
284
+ readonly morphShape: "var(--game-ui-liquid-gooey-morph-shape)";
285
+ readonly morphSpeed: "var(--game-ui-liquid-gooey-morph-speed)";
286
+ readonly morphBounce: "var(--game-ui-liquid-gooey-morph-bounce)";
287
+ readonly evolveMassStiffness: "var(--game-ui-liquid-gooey-evolve-mass-stiffness)";
288
+ readonly evolveMassDamping: "var(--game-ui-liquid-gooey-evolve-mass-damping)";
289
+ readonly evolveSizeStiffness: "var(--game-ui-liquid-gooey-evolve-size-stiffness)";
290
+ readonly evolveSizeDamping: "var(--game-ui-liquid-gooey-evolve-size-damping)";
291
+ readonly evolveRadiusStiffness: "var(--game-ui-liquid-gooey-evolve-radius-stiffness)";
292
+ readonly evolveRadiusDamping: "var(--game-ui-liquid-gooey-evolve-radius-damping)";
293
+ readonly evolveContentBlur: "var(--game-ui-liquid-gooey-evolve-content-blur)";
294
+ readonly evolveRoundness: "var(--game-ui-liquid-gooey-evolve-roundness)";
295
+ readonly evolveCornerDuration: "var(--game-ui-liquid-gooey-evolve-corner-duration)";
296
+ readonly evolveCornerDelay: "var(--game-ui-liquid-gooey-evolve-corner-delay)";
297
+ readonly evolveCornerEase: "var(--game-ui-liquid-gooey-evolve-corner-ease)";
298
+ readonly evolveAnticipation: "var(--game-ui-liquid-gooey-evolve-anticipation)";
299
+ readonly evolveTravel: "var(--game-ui-liquid-gooey-evolve-travel)";
300
+ readonly contentBlurAreaMultiplier: "var(--game-ui-liquid-gooey-content-blur-area-multiplier)";
301
+ readonly bendVertical: "var(--game-ui-liquid-gooey-bend-vertical)";
302
+ readonly bendHorizontal: "var(--game-ui-liquid-gooey-bend-horizontal)";
303
+ readonly bendVelocityVertical: "var(--game-ui-liquid-gooey-bend-velocity-vertical)";
304
+ readonly bendVelocityHorizontal: "var(--game-ui-liquid-gooey-bend-velocity-horizontal)";
305
+ readonly bendSmoothing: "var(--game-ui-liquid-gooey-bend-smoothing)";
306
+ readonly bendActiveThreshold: "var(--game-ui-liquid-gooey-bend-active-threshold)";
307
+ readonly bendVerticalCap: "var(--game-ui-liquid-gooey-bend-vertical-cap)";
308
+ readonly bendHorizontalCap: "var(--game-ui-liquid-gooey-bend-horizontal-cap)";
309
+ readonly bendRadiusMin: "var(--game-ui-liquid-gooey-bend-radius-min)";
310
+ readonly bendRadiusMax: "var(--game-ui-liquid-gooey-bend-radius-max)";
311
+ readonly bendLeadingCapFactor: "var(--game-ui-liquid-gooey-bend-leading-cap-factor)";
312
+ readonly bendTrailingCapFactor: "var(--game-ui-liquid-gooey-bend-trailing-cap-factor)";
277
313
  readonly moveStiffness: "var(--game-ui-liquid-gooey-move-stiffness)";
278
314
  readonly moveDamping: "var(--game-ui-liquid-gooey-move-damping)";
279
315
  readonly moveStretch: "var(--game-ui-liquid-gooey-move-stretch)";
@@ -303,6 +339,31 @@ declare const CLAY_LIQUID_GOOEY_TOKENS: {
303
339
  readonly moveIntegrationRate: "var(--game-ui-liquid-gooey-move-integration-rate)";
304
340
  readonly waviness: "var(--game-ui-liquid-gooey-waviness)";
305
341
  readonly wavinessFreq: "var(--game-ui-liquid-gooey-waviness-freq)";
342
+ readonly meltBlur: "var(--game-ui-liquid-gooey-melt-blur)";
343
+ readonly meltContrast: "var(--game-ui-liquid-gooey-melt-contrast)";
344
+ readonly meltReach: "var(--game-ui-liquid-gooey-melt-reach)";
345
+ readonly meltFade: "var(--game-ui-liquid-gooey-melt-fade)";
346
+ readonly meltWarp: "var(--game-ui-liquid-gooey-melt-warp)";
347
+ readonly meltMix: "var(--game-ui-liquid-gooey-melt-mix)";
348
+ readonly meltMixBlur: "var(--game-ui-liquid-gooey-melt-mix-blur)";
349
+ readonly meltGravity: "var(--game-ui-liquid-gooey-melt-gravity)";
350
+ readonly meltWaviness: "var(--game-ui-liquid-gooey-melt-waviness)";
351
+ readonly dissolveBlur: "var(--game-ui-liquid-gooey-dissolve-blur)";
352
+ readonly dissolveWarp: "var(--game-ui-liquid-gooey-dissolve-warp)";
353
+ readonly dissolvePull: "var(--game-ui-liquid-gooey-dissolve-pull)";
354
+ readonly dissolveRange: "var(--game-ui-liquid-gooey-dissolve-range)";
355
+ readonly dissolveZone: "var(--game-ui-liquid-gooey-dissolve-zone)";
356
+ readonly dissolveMix: "var(--game-ui-liquid-gooey-dissolve-mix)";
357
+ readonly dissolveGravity: "var(--game-ui-liquid-gooey-dissolve-gravity)";
358
+ readonly dissolveTaper: "var(--game-ui-liquid-gooey-dissolve-taper)";
359
+ readonly dissolveWarpFreq: "var(--game-ui-liquid-gooey-dissolve-warp-freq)";
360
+ readonly dissolveFlowSpeed: "var(--game-ui-liquid-gooey-dissolve-flow-speed)";
361
+ readonly dissolveDetail: "var(--game-ui-liquid-gooey-dissolve-detail)";
362
+ readonly dissolveReleaseMs: "var(--game-ui-liquid-gooey-dissolve-release-ms)";
363
+ readonly dissolveFadeMs: "var(--game-ui-liquid-gooey-dissolve-fade-ms)";
364
+ readonly dissolveStrength: "var(--game-ui-liquid-gooey-dissolve-strength)";
365
+ readonly dissolveSink: "var(--game-ui-liquid-gooey-dissolve-sink)";
366
+ readonly dissolveSeamBlur: "var(--game-ui-liquid-gooey-dissolve-seam-blur)";
306
367
  };
307
368
  export { CLAY_LIQUID_GOOEY_TOKENS }
308
369
  export { CLAY_LIQUID_GOOEY_TOKENS as GAME_UI_LIQUID_GOOEY_TOKENS }
@@ -592,6 +653,35 @@ export declare const CLAY_UI_TOKENS: {
592
653
  readonly bloom: "var(--game-ui-liquid-metal-bloom)";
593
654
  };
594
655
  readonly liquidGooey: {
656
+ readonly morphShape: "var(--game-ui-liquid-gooey-morph-shape)";
657
+ readonly morphSpeed: "var(--game-ui-liquid-gooey-morph-speed)";
658
+ readonly morphBounce: "var(--game-ui-liquid-gooey-morph-bounce)";
659
+ readonly evolveMassStiffness: "var(--game-ui-liquid-gooey-evolve-mass-stiffness)";
660
+ readonly evolveMassDamping: "var(--game-ui-liquid-gooey-evolve-mass-damping)";
661
+ readonly evolveSizeStiffness: "var(--game-ui-liquid-gooey-evolve-size-stiffness)";
662
+ readonly evolveSizeDamping: "var(--game-ui-liquid-gooey-evolve-size-damping)";
663
+ readonly evolveRadiusStiffness: "var(--game-ui-liquid-gooey-evolve-radius-stiffness)";
664
+ readonly evolveRadiusDamping: "var(--game-ui-liquid-gooey-evolve-radius-damping)";
665
+ readonly evolveContentBlur: "var(--game-ui-liquid-gooey-evolve-content-blur)";
666
+ readonly evolveRoundness: "var(--game-ui-liquid-gooey-evolve-roundness)";
667
+ readonly evolveCornerDuration: "var(--game-ui-liquid-gooey-evolve-corner-duration)";
668
+ readonly evolveCornerDelay: "var(--game-ui-liquid-gooey-evolve-corner-delay)";
669
+ readonly evolveCornerEase: "var(--game-ui-liquid-gooey-evolve-corner-ease)";
670
+ readonly evolveAnticipation: "var(--game-ui-liquid-gooey-evolve-anticipation)";
671
+ readonly evolveTravel: "var(--game-ui-liquid-gooey-evolve-travel)";
672
+ readonly contentBlurAreaMultiplier: "var(--game-ui-liquid-gooey-content-blur-area-multiplier)";
673
+ readonly bendVertical: "var(--game-ui-liquid-gooey-bend-vertical)";
674
+ readonly bendHorizontal: "var(--game-ui-liquid-gooey-bend-horizontal)";
675
+ readonly bendVelocityVertical: "var(--game-ui-liquid-gooey-bend-velocity-vertical)";
676
+ readonly bendVelocityHorizontal: "var(--game-ui-liquid-gooey-bend-velocity-horizontal)";
677
+ readonly bendSmoothing: "var(--game-ui-liquid-gooey-bend-smoothing)";
678
+ readonly bendActiveThreshold: "var(--game-ui-liquid-gooey-bend-active-threshold)";
679
+ readonly bendVerticalCap: "var(--game-ui-liquid-gooey-bend-vertical-cap)";
680
+ readonly bendHorizontalCap: "var(--game-ui-liquid-gooey-bend-horizontal-cap)";
681
+ readonly bendRadiusMin: "var(--game-ui-liquid-gooey-bend-radius-min)";
682
+ readonly bendRadiusMax: "var(--game-ui-liquid-gooey-bend-radius-max)";
683
+ readonly bendLeadingCapFactor: "var(--game-ui-liquid-gooey-bend-leading-cap-factor)";
684
+ readonly bendTrailingCapFactor: "var(--game-ui-liquid-gooey-bend-trailing-cap-factor)";
595
685
  readonly moveStiffness: "var(--game-ui-liquid-gooey-move-stiffness)";
596
686
  readonly moveDamping: "var(--game-ui-liquid-gooey-move-damping)";
597
687
  readonly moveStretch: "var(--game-ui-liquid-gooey-move-stretch)";
@@ -621,6 +711,31 @@ export declare const CLAY_UI_TOKENS: {
621
711
  readonly moveIntegrationRate: "var(--game-ui-liquid-gooey-move-integration-rate)";
622
712
  readonly waviness: "var(--game-ui-liquid-gooey-waviness)";
623
713
  readonly wavinessFreq: "var(--game-ui-liquid-gooey-waviness-freq)";
714
+ readonly meltBlur: "var(--game-ui-liquid-gooey-melt-blur)";
715
+ readonly meltContrast: "var(--game-ui-liquid-gooey-melt-contrast)";
716
+ readonly meltReach: "var(--game-ui-liquid-gooey-melt-reach)";
717
+ readonly meltFade: "var(--game-ui-liquid-gooey-melt-fade)";
718
+ readonly meltWarp: "var(--game-ui-liquid-gooey-melt-warp)";
719
+ readonly meltMix: "var(--game-ui-liquid-gooey-melt-mix)";
720
+ readonly meltMixBlur: "var(--game-ui-liquid-gooey-melt-mix-blur)";
721
+ readonly meltGravity: "var(--game-ui-liquid-gooey-melt-gravity)";
722
+ readonly meltWaviness: "var(--game-ui-liquid-gooey-melt-waviness)";
723
+ readonly dissolveBlur: "var(--game-ui-liquid-gooey-dissolve-blur)";
724
+ readonly dissolveWarp: "var(--game-ui-liquid-gooey-dissolve-warp)";
725
+ readonly dissolvePull: "var(--game-ui-liquid-gooey-dissolve-pull)";
726
+ readonly dissolveRange: "var(--game-ui-liquid-gooey-dissolve-range)";
727
+ readonly dissolveZone: "var(--game-ui-liquid-gooey-dissolve-zone)";
728
+ readonly dissolveMix: "var(--game-ui-liquid-gooey-dissolve-mix)";
729
+ readonly dissolveGravity: "var(--game-ui-liquid-gooey-dissolve-gravity)";
730
+ readonly dissolveTaper: "var(--game-ui-liquid-gooey-dissolve-taper)";
731
+ readonly dissolveWarpFreq: "var(--game-ui-liquid-gooey-dissolve-warp-freq)";
732
+ readonly dissolveFlowSpeed: "var(--game-ui-liquid-gooey-dissolve-flow-speed)";
733
+ readonly dissolveDetail: "var(--game-ui-liquid-gooey-dissolve-detail)";
734
+ readonly dissolveReleaseMs: "var(--game-ui-liquid-gooey-dissolve-release-ms)";
735
+ readonly dissolveFadeMs: "var(--game-ui-liquid-gooey-dissolve-fade-ms)";
736
+ readonly dissolveStrength: "var(--game-ui-liquid-gooey-dissolve-strength)";
737
+ readonly dissolveSink: "var(--game-ui-liquid-gooey-dissolve-sink)";
738
+ readonly dissolveSeamBlur: "var(--game-ui-liquid-gooey-dissolve-seam-blur)";
624
739
  };
625
740
  };
626
741
 
@@ -685,6 +800,83 @@ export declare const DEFAULT_LIQUID_GOOEY_FILTER_AREA_BUDGET = 480000;
685
800
  */
686
801
  export declare const DEFAULT_LIQUID_METAL_CONTEXT_BUDGET = 2;
687
802
 
803
+ export declare const DISSOLVE_DEFAULTS: ResolvedDissolveOptions;
804
+
805
+ export declare interface DissolveOptions {
806
+ /** Melt blur in px. */
807
+ blur?: number;
808
+ /** Displacement strength of the liquid warp. */
809
+ warp?: number;
810
+ /** Magnetic drift toward the contact, in px. */
811
+ pull?: number;
812
+ /** Distance at which melting starts. */
813
+ range?: number;
814
+ /** Size of the melt zone around the contact, in px. */
815
+ zone?: number;
816
+ /** 0..1 two-liquid erosion strength. */
817
+ mix?: number;
818
+ /** Px the melt is drawn toward the neighbour's centre. */
819
+ gravity?: number;
820
+ /** 0..1 pointiness of the directional flow. */
821
+ taper?: number;
822
+ /** Noise frequency multiplier. */
823
+ warpFreq?: number;
824
+ /** Px/s the noise field may drift while the item is moving. */
825
+ flowSpeed?: number;
826
+ /** Noise style. */
827
+ warpStyle?: 'fractalNoise' | 'turbulence';
828
+ /** Noise octaves. */
829
+ detail?: number;
830
+ /** Whether the dissolve is currently allowed to grow. */
831
+ active?: boolean;
832
+ /** Structural release time in ms. */
833
+ releaseMs?: number;
834
+ /** Opacity fade time in ms. */
835
+ fadeMs?: number;
836
+ /** 0..1 overall dissolve ceiling. */
837
+ strength?: number;
838
+ /** Fraction of the smaller body at which the seam has been swallowed. */
839
+ sink?: number;
840
+ /** Plain blur radius for the guaranteed-smooth seam wash. */
841
+ seamBlur?: number;
842
+ }
843
+
844
+ export declare type DissolveValue = boolean | number | DissolveOptions;
845
+
846
+ /**
847
+ * Morph shape physics adapted from `liquid-gooey` by Jakub Antalik.
848
+ *
849
+ * Source: https://github.com/Jakubantalik/Libraries/tree/main/packages/liquid-gooey
850
+ * Pinned commit: 3862ffa345217443b63696a8c331a0664eea4b04
851
+ * Copyright (c) 2026 Jakub Antalik. Licensed under the MIT License.
852
+ * See NOTICE for the attribution and license text. This local module keeps
853
+ * the donor's centre -> size -> corner timeline and content cross-blur, but
854
+ * routes every tunable value through SwimmerUIKit's token layer.
855
+ */
856
+ declare interface EvolveOptions {
857
+ /** Spring driving the liquid mass's centre. */
858
+ massStiffness?: number;
859
+ massDamping?: number;
860
+ /** Spring driving width and height. */
861
+ sizeStiffness?: number;
862
+ sizeDamping?: number;
863
+ /** Spring driving the corner radius. */
864
+ radiusStiffness?: number;
865
+ radiusDamping?: number;
866
+ /** Maximum content cross-blur during the morph, in px. */
867
+ contentBlur?: number;
868
+ /** 0..1 droplet roundness during a shape transition. */
869
+ roundness?: number;
870
+ /** Corner-forming timeline. */
871
+ cornerDuration?: number;
872
+ cornerDelay?: number;
873
+ cornerEase?: string;
874
+ /** Ramp-in time for the droplet lead, in ms. */
875
+ anticipation?: number;
876
+ /** Maximum droplet lead toward the destination, in px. */
877
+ travel?: number;
878
+ }
879
+
688
880
  export declare function FirstSessionHud({ authenticated, batteryCount, className, dailyStreak, iconSlots, labels, onHistory, onSettings, onWardrobe, playerName, }: FirstSessionHudProps): ReactNode;
689
881
 
690
882
  export declare interface FirstSessionHudIconSlots {
@@ -792,6 +984,35 @@ export declare const GAME_UI_TARGETS: {
792
984
  export declare const GAME_UI_THEME_CONTRACT: readonly ["--game-ui-bg", "--game-ui-surface", "--game-ui-surface-raised", "--game-ui-panel", "--game-ui-panel-strong", "--game-ui-panel-deep", "--game-ui-text", "--game-ui-text-muted", "--game-ui-accent", "--game-ui-accent-bright", "--game-ui-secondary", "--game-ui-success", "--game-ui-success-bright", "--game-ui-danger", "--game-ui-danger-bright", "--game-ui-warning", "--game-ui-focus-ring", "--game-ui-border-subtle", "--game-ui-border-strong", "--game-ui-disabled", "--game-ui-ink-deep", "--game-ui-border-ink", "--game-ui-wood", "--game-ui-ink-title", "--game-ui-ink-heading", "--game-ui-liquid-metal-face", "--game-ui-liquid-metal-ink"];
793
985
 
794
986
  export declare const GAME_UI_TOKENS: {
987
+ readonly morphShape: "var(--game-ui-liquid-gooey-morph-shape)";
988
+ readonly morphSpeed: "var(--game-ui-liquid-gooey-morph-speed)";
989
+ readonly morphBounce: "var(--game-ui-liquid-gooey-morph-bounce)";
990
+ readonly evolveMassStiffness: "var(--game-ui-liquid-gooey-evolve-mass-stiffness)";
991
+ readonly evolveMassDamping: "var(--game-ui-liquid-gooey-evolve-mass-damping)";
992
+ readonly evolveSizeStiffness: "var(--game-ui-liquid-gooey-evolve-size-stiffness)";
993
+ readonly evolveSizeDamping: "var(--game-ui-liquid-gooey-evolve-size-damping)";
994
+ readonly evolveRadiusStiffness: "var(--game-ui-liquid-gooey-evolve-radius-stiffness)";
995
+ readonly evolveRadiusDamping: "var(--game-ui-liquid-gooey-evolve-radius-damping)";
996
+ readonly evolveContentBlur: "var(--game-ui-liquid-gooey-evolve-content-blur)";
997
+ readonly evolveRoundness: "var(--game-ui-liquid-gooey-evolve-roundness)";
998
+ readonly evolveCornerDuration: "var(--game-ui-liquid-gooey-evolve-corner-duration)";
999
+ readonly evolveCornerDelay: "var(--game-ui-liquid-gooey-evolve-corner-delay)";
1000
+ readonly evolveCornerEase: "var(--game-ui-liquid-gooey-evolve-corner-ease)";
1001
+ readonly evolveAnticipation: "var(--game-ui-liquid-gooey-evolve-anticipation)";
1002
+ readonly evolveTravel: "var(--game-ui-liquid-gooey-evolve-travel)";
1003
+ readonly contentBlurAreaMultiplier: "var(--game-ui-liquid-gooey-content-blur-area-multiplier)";
1004
+ readonly bendVertical: "var(--game-ui-liquid-gooey-bend-vertical)";
1005
+ readonly bendHorizontal: "var(--game-ui-liquid-gooey-bend-horizontal)";
1006
+ readonly bendVelocityVertical: "var(--game-ui-liquid-gooey-bend-velocity-vertical)";
1007
+ readonly bendVelocityHorizontal: "var(--game-ui-liquid-gooey-bend-velocity-horizontal)";
1008
+ readonly bendSmoothing: "var(--game-ui-liquid-gooey-bend-smoothing)";
1009
+ readonly bendActiveThreshold: "var(--game-ui-liquid-gooey-bend-active-threshold)";
1010
+ readonly bendVerticalCap: "var(--game-ui-liquid-gooey-bend-vertical-cap)";
1011
+ readonly bendHorizontalCap: "var(--game-ui-liquid-gooey-bend-horizontal-cap)";
1012
+ readonly bendRadiusMin: "var(--game-ui-liquid-gooey-bend-radius-min)";
1013
+ readonly bendRadiusMax: "var(--game-ui-liquid-gooey-bend-radius-max)";
1014
+ readonly bendLeadingCapFactor: "var(--game-ui-liquid-gooey-bend-leading-cap-factor)";
1015
+ readonly bendTrailingCapFactor: "var(--game-ui-liquid-gooey-bend-trailing-cap-factor)";
795
1016
  readonly moveStiffness: "var(--game-ui-liquid-gooey-move-stiffness)";
796
1017
  readonly moveDamping: "var(--game-ui-liquid-gooey-move-damping)";
797
1018
  readonly moveStretch: "var(--game-ui-liquid-gooey-move-stretch)";
@@ -821,6 +1042,31 @@ export declare const GAME_UI_TOKENS: {
821
1042
  readonly moveIntegrationRate: "var(--game-ui-liquid-gooey-move-integration-rate)";
822
1043
  readonly waviness: "var(--game-ui-liquid-gooey-waviness)";
823
1044
  readonly wavinessFreq: "var(--game-ui-liquid-gooey-waviness-freq)";
1045
+ readonly meltBlur: "var(--game-ui-liquid-gooey-melt-blur)";
1046
+ readonly meltContrast: "var(--game-ui-liquid-gooey-melt-contrast)";
1047
+ readonly meltReach: "var(--game-ui-liquid-gooey-melt-reach)";
1048
+ readonly meltFade: "var(--game-ui-liquid-gooey-melt-fade)";
1049
+ readonly meltWarp: "var(--game-ui-liquid-gooey-melt-warp)";
1050
+ readonly meltMix: "var(--game-ui-liquid-gooey-melt-mix)";
1051
+ readonly meltMixBlur: "var(--game-ui-liquid-gooey-melt-mix-blur)";
1052
+ readonly meltGravity: "var(--game-ui-liquid-gooey-melt-gravity)";
1053
+ readonly meltWaviness: "var(--game-ui-liquid-gooey-melt-waviness)";
1054
+ readonly dissolveBlur: "var(--game-ui-liquid-gooey-dissolve-blur)";
1055
+ readonly dissolveWarp: "var(--game-ui-liquid-gooey-dissolve-warp)";
1056
+ readonly dissolvePull: "var(--game-ui-liquid-gooey-dissolve-pull)";
1057
+ readonly dissolveRange: "var(--game-ui-liquid-gooey-dissolve-range)";
1058
+ readonly dissolveZone: "var(--game-ui-liquid-gooey-dissolve-zone)";
1059
+ readonly dissolveMix: "var(--game-ui-liquid-gooey-dissolve-mix)";
1060
+ readonly dissolveGravity: "var(--game-ui-liquid-gooey-dissolve-gravity)";
1061
+ readonly dissolveTaper: "var(--game-ui-liquid-gooey-dissolve-taper)";
1062
+ readonly dissolveWarpFreq: "var(--game-ui-liquid-gooey-dissolve-warp-freq)";
1063
+ readonly dissolveFlowSpeed: "var(--game-ui-liquid-gooey-dissolve-flow-speed)";
1064
+ readonly dissolveDetail: "var(--game-ui-liquid-gooey-dissolve-detail)";
1065
+ readonly dissolveReleaseMs: "var(--game-ui-liquid-gooey-dissolve-release-ms)";
1066
+ readonly dissolveFadeMs: "var(--game-ui-liquid-gooey-dissolve-fade-ms)";
1067
+ readonly dissolveStrength: "var(--game-ui-liquid-gooey-dissolve-strength)";
1068
+ readonly dissolveSink: "var(--game-ui-liquid-gooey-dissolve-sink)";
1069
+ readonly dissolveSeamBlur: "var(--game-ui-liquid-gooey-dissolve-seam-blur)";
824
1070
  readonly iconSm: "var(--game-ui-asset-icon-sm)";
825
1071
  readonly iconMd: "var(--game-ui-asset-icon-md)";
826
1072
  readonly iconLg: "var(--game-ui-asset-icon-lg)";
@@ -2044,6 +2290,29 @@ export declare function getLiquidMetalContextBudget(): {
2044
2290
  used: number;
2045
2291
  };
2046
2292
 
2293
+ export declare const IMAGE_MELT_DEFAULTS: Required<ImageMeltOptions>;
2294
+
2295
+ export declare interface ImageMeltOptions {
2296
+ /** Goo sigma: how far the bodies reach for each other and how wide colour averaging runs. */
2297
+ blur?: number;
2298
+ /** Alpha-contrast slope of the liquid boundary. */
2299
+ contrast?: number;
2300
+ /** How far each crisp face dissolves back before its neighbour. */
2301
+ reach?: number;
2302
+ /** Softness of the crisp-face dissolve mask. */
2303
+ fade?: number;
2304
+ /** Turbulence displacement of the molten layer, in px. */
2305
+ warp?: number;
2306
+ /** 0..1 two-liquid marbling strength in the touch area. */
2307
+ mix?: number;
2308
+ /** Blur of the marble pass's source colours. */
2309
+ mixBlur?: number;
2310
+ /** How deep the marble zone reaches into each card. */
2311
+ gravity?: number;
2312
+ /** Wavelength control of the warp noise. */
2313
+ waviness?: number;
2314
+ }
2315
+
2047
2316
  declare interface LiquidGooeyBudgetOptions {
2048
2317
  maxAnimatedGroups?: number;
2049
2318
  maxFilterArea?: number;
@@ -2057,8 +2326,10 @@ declare interface LiquidGooeyBudgetState {
2057
2326
 
2058
2327
  /**
2059
2328
  * Merges nearby item silhouettes into one shape while leaving their content
2060
- * accessible and unfiltered. Do NOT add border, outline, or box-shadow to
2061
- * children directly; pass the shared treatment to <LiquidGroup>.
2329
+ * accessible and separately filtered. Morph content may cross-blur while it
2330
+ * moves; Bend keeps its content surface-glued and exposes its live CSS vars.
2331
+ * Do NOT add border, outline, or box-shadow to children directly; pass the
2332
+ * shared treatment to <LiquidGroup>.
2062
2333
  */
2063
2334
  export declare const LiquidGroup: ForwardRefExoticComponent<LiquidGroupProps & RefAttributes<HTMLDivElement>> & {
2064
2335
  Item: ForwardRefExoticComponent<LiquidItemProps & RefAttributes<HTMLDivElement>>;
@@ -2078,6 +2349,8 @@ export declare const LiquidGroup: ForwardRefExoticComponent<LiquidGroupProps & R
2078
2349
  * | --- | --- |
2079
2350
  * | **merge** (Morph) | two things become one: reward settling, collecting, confirming |
2080
2351
  * | **follow** (Move) | selection, progress, dragging |
2352
+ * | **shape** (Morph shape) | the liquid changes size and corners like jelly |
2353
+ * | **bend** | speed bows the surface while content stays glued to it |
2081
2354
  * | **dissolve** | replacement, transition |
2082
2355
  * | **still** | THE DEFAULT |
2083
2356
  *
@@ -2099,7 +2372,7 @@ export declare interface LiquidGroupProps extends Omit<HTMLAttributes<HTMLDivEle
2099
2372
  shadow?: string;
2100
2373
  /** Optional stroke syntax rebuilt on the merged silhouette. Note: Do NOT add border to children directly! */
2101
2374
  stroke?: string;
2102
- /** Max px the liquid boundary undulates. Defaults to the CSS token (0). */
2375
+ /** Max px the liquid boundary undulates. Defaults to the CSS token (6). */
2103
2376
  waviness?: number;
2104
2377
  /** Noise frequency of the undulation; lower values make longer waves. */
2105
2378
  wavinessFreq?: number;
@@ -2130,6 +2403,20 @@ export declare interface LiquidItemProps extends Omit<HTMLAttributes<HTMLDivElem
2130
2403
  delay?: number;
2131
2404
  /** Override the measured content border radius for the silhouette. */
2132
2405
  radius?: number | CornerRadii;
2406
+ /** Select the adopted item surface behavior. Bend follows child geometry. */
2407
+ effect?: 'morph' | 'move' | 'melt' | 'bend';
2408
+ /** Morph shape, tempo, bounce, and content cross-blur tuning. */
2409
+ morph?: MorphTuning;
2410
+ /** Bend strengths for vertical bow and horizontal cap deformation. */
2411
+ bend?: BendTuning;
2412
+ /** Follow a child moved by external code; Bend implies this automatically. */
2413
+ observe?: boolean;
2414
+ /** Numeric knobs for the pairwise image Melt surface, plus an optional source URL. */
2415
+ melt?: ImageMeltOptions & {
2416
+ src?: string;
2417
+ };
2418
+ /** Contact image modifier. Text and other DOM content remain on the crisp layer. */
2419
+ dissolve?: boolean | number | DissolveOptions;
2133
2420
  }
2134
2421
 
2135
2422
  export declare function LiquidMetalButton({ children, className, onClick, sound, type, renderer, ...props }: LiquidMetalButtonProps): ReactNode;
@@ -2149,10 +2436,46 @@ export declare interface LiquidMetalButtonProps extends ButtonHTMLAttributes<HTM
2149
2436
 
2150
2437
  export declare type LiquidMetalRendererMode = 'auto' | 'css' | 'webgl';
2151
2438
 
2439
+ export declare interface MorphTuning {
2440
+ /** Whether shape-change physics is enabled. The kit default is token-on. */
2441
+ shape?: boolean;
2442
+ /** Tempo multiplier. */
2443
+ speed?: number;
2444
+ /** 0..1 overshoot amount. */
2445
+ bounce?: number;
2446
+ /** Maximum content cross-blur, in px. */
2447
+ contentBlur?: number;
2448
+ /** Raw evolve escape hatch. */
2449
+ advanced?: Partial<EvolveOptions>;
2450
+ }
2451
+
2152
2452
  export declare function playGameInteractionSound(options?: GameInteractionSoundOptions): boolean;
2153
2453
 
2154
2454
  export declare function playGameInteractionSoundForContext(audioContext: GameInteractionAudioContext, options?: GameInteractionSoundOptions): boolean;
2155
2455
 
2456
+ declare interface ResolvedDissolveOptions {
2457
+ blur: number;
2458
+ warp: number;
2459
+ pull: number;
2460
+ range: number;
2461
+ zone: number;
2462
+ mix: number;
2463
+ gravity: number;
2464
+ taper: number;
2465
+ warpFreq: number;
2466
+ flowSpeed: number;
2467
+ warpStyle: 'fractalNoise' | 'turbulence';
2468
+ detail: number;
2469
+ active: boolean;
2470
+ releaseMs: number;
2471
+ fadeMs: number;
2472
+ strength: number;
2473
+ sink: number;
2474
+ seamBlur: number;
2475
+ }
2476
+
2477
+ export declare function resolveDissolveOptions(element: HTMLElement | null, input: DissolveValue): ResolvedDissolveOptions;
2478
+
2156
2479
  /**
2157
2480
  * Point the sculpted set at somewhere other than the default path — a CDN, a
2158
2481
  * sub-path deploy, a host whose static root is not `/`. Pass no trailing slash.