@mkbabb/glass-ui 3.9.0 → 3.10.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 (121) hide show
  1. package/dist/{MetricBadge-lTc002u2.js → MetricBadge-BZVWIxNy.js} +6 -4
  2. package/dist/{Notification-BxK8LZMw.js → Notification-DLMhblXR.js} +2 -2
  3. package/dist/{Switch-LDKLmmgx.js → Switch-Ch-k3Rv-.js} +1 -1
  4. package/dist/animated-digit.js +1 -1
  5. package/dist/api/index.d.ts +1 -0
  6. package/dist/api.js +1 -1
  7. package/dist/aurora.js +236 -545
  8. package/dist/{badge-BvwvT50i.js → badge-CaoFJzRb.js} +1 -1
  9. package/dist/badge.js +1 -1
  10. package/dist/color.js +1 -1
  11. package/dist/{compile-DAjIoEy2.js → compile-BOXjLUxu.js} +23 -23
  12. package/dist/components/custom/aurora/composables/atoms.d.ts +21 -4
  13. package/dist/components/custom/aurora/composables/runtime.d.ts +0 -9
  14. package/dist/components/custom/aurora/composables/uniformBridge.d.ts +0 -11
  15. package/dist/components/custom/aurora/constants/renderMode.d.ts +0 -32
  16. package/dist/components/custom/aurora/constants/shaders/brush.glsl.d.ts +1 -1
  17. package/dist/components/custom/aurora/constants/shaders/mediums.glsl.d.ts +2 -2
  18. package/dist/components/custom/aurora/constants/shaders/tonemap.glsl.d.ts +1 -1
  19. package/dist/components/custom/aurora/index.d.ts +1 -1
  20. package/dist/components/custom/constellation/Constellation.vue.d.ts +73 -1
  21. package/dist/components/custom/constellation/constellationField.d.ts +255 -3
  22. package/dist/components/custom/constellation/index.d.ts +2 -2
  23. package/dist/components/custom/dock/DockTabButton.vue.d.ts +4 -3
  24. package/dist/components/custom/expandable-container/ExpandableContainer.vue.d.ts +29 -0
  25. package/dist/components/custom/fourier-field/FourierField.vue.d.ts +6 -0
  26. package/dist/components/custom/fourier-field/index.d.ts +25 -1
  27. package/dist/components/custom/fourier-field/math.d.ts +3 -8
  28. package/dist/components/custom/goo-blob/GooBlob.vue.d.ts +8 -10
  29. package/dist/components/custom/goo-blob/composables/useMetaballRenderer.d.ts +6 -14
  30. package/dist/components/custom/goo-blob/index.d.ts +1 -1
  31. package/dist/components/custom/goo-blob/types.d.ts +59 -25
  32. package/dist/components/custom/handmark/HandMark.vue.d.ts +29 -0
  33. package/dist/components/custom/handmark/brush.d.ts +219 -0
  34. package/dist/components/custom/handmark/freehand.d.ts +69 -0
  35. package/dist/components/custom/handmark/geometry.d.ts +32 -0
  36. package/dist/components/custom/handmark/index.d.ts +21 -0
  37. package/dist/components/custom/handmark/ink.d.ts +11 -0
  38. package/dist/components/custom/handmark/texture.d.ts +39 -0
  39. package/dist/components/custom/handmark/types.d.ts +53 -0
  40. package/dist/components/custom/handmark/useHandMark.d.ts +66 -0
  41. package/dist/components/custom/metric-badge/MetricBadge.vue.d.ts +8 -0
  42. package/dist/components/ui/slider/index.d.ts +20 -16
  43. package/dist/composables/color/index.d.ts +12 -7
  44. package/dist/composables/glass/webgl/shaders/procedural-color.glsl.d.ts +1 -6
  45. package/dist/composables/motion/core/index.d.ts +1 -0
  46. package/dist/composables/motion/useRouteTransition.d.ts +42 -0
  47. package/dist/constellation.js +212 -72
  48. package/dist/controls.js +1 -1
  49. package/dist/dark.js +1 -1
  50. package/dist/dock.js +1 -0
  51. package/dist/expandable-container.js +61 -38
  52. package/dist/forms.js +2 -2
  53. package/dist/fourier-field.js +89 -97
  54. package/dist/fourier-math.d.ts +1 -0
  55. package/dist/fourier-math.js +2 -0
  56. package/dist/glass-panel.js +1 -1
  57. package/dist/glass-ui.css +1 -1
  58. package/dist/glass-ui.js +81 -80
  59. package/dist/goo-blob.js +299 -284
  60. package/dist/handmark.d.ts +1 -0
  61. package/dist/handmark.js +609 -0
  62. package/dist/icon-tooltip.js +1 -1
  63. package/dist/index.d.ts +1 -0
  64. package/dist/keyboard.js +1 -1
  65. package/dist/labeled-field.js +4 -4
  66. package/dist/math-DTpRVC0e.js +27 -0
  67. package/dist/metric-badge.js +1 -1
  68. package/dist/metric-stack.js +1 -1
  69. package/dist/motion-core.js +70 -69
  70. package/dist/motion.js +2 -2
  71. package/dist/notification.js +1 -1
  72. package/dist/search.js +2 -2
  73. package/dist/{slider-DC2mwuoe.js → slider-CyzcxBoh.js} +6 -6
  74. package/dist/slider.js +1 -1
  75. package/dist/styles/animations.css +74 -18
  76. package/dist/styles/cards.css +2 -2
  77. package/dist/styles/components.css +1 -1
  78. package/dist/styles/dock/layer-group.css +16 -4
  79. package/dist/styles/dock-controls.css +39 -23
  80. package/dist/styles/drawer.css +12 -4
  81. package/dist/styles/glass.css +145 -9
  82. package/dist/styles/paper.css +68 -2
  83. package/dist/styles/theme.css +7 -0
  84. package/dist/styles/tokens.css +101 -15
  85. package/dist/styles/transitions.css +20 -2
  86. package/dist/styles/utilities.css +130 -40
  87. package/dist/styles/view-transition.css +51 -0
  88. package/dist/switch.js +1 -1
  89. package/dist/{useAnimatedNumber-C5I3wWd8.js → useAnimatedNumber-Bcpy5Etf.js} +1 -1
  90. package/dist/{useGlassRenderer-5I0YkI4t.js → useGlassRenderer-D7YGOYiM.js} +1 -1
  91. package/dist/useViewTransition-DaN5Zrox.js +21 -0
  92. package/dist/vReveal-zUIQk-rJ.js +53 -0
  93. package/dist/watercolor-dot.js +1 -1
  94. package/package.json +51 -9
  95. package/src/styles/animations.css +74 -18
  96. package/src/styles/cards.css +2 -2
  97. package/src/styles/dock/layer-group.css +16 -4
  98. package/src/styles/dock-controls.css +39 -23
  99. package/src/styles/drawer.css +12 -4
  100. package/src/styles/glass.css +145 -9
  101. package/src/styles/paper.css +68 -2
  102. package/src/styles/theme.css +7 -0
  103. package/src/styles/tokens.css +101 -15
  104. package/src/styles/transitions.css +20 -2
  105. package/src/styles/utilities.css +130 -40
  106. package/src/styles/view-transition.css +51 -0
  107. package/dist/components/custom/aurora/composables/gpuRuntime.d.ts +0 -16
  108. package/dist/components/custom/aurora/constants/shaders/aurora.wgsl.d.ts +0 -7
  109. package/dist/composables/glass/createGPUCanvas.d.ts +0 -40
  110. package/dist/vReveal-CqaCz_mC.js +0 -44
  111. /package/dist/{IconTooltip-yefK7cJc.js → IconTooltip-Cus0fvK0.js} +0 -0
  112. /package/dist/{Input-DWQQIOC4.js → Input-xuDwALQR.js} +0 -0
  113. /package/dist/{color-8jBjWiJ6.js → color-C5ls_QF7.js} +0 -0
  114. /package/dist/{constants-CS75AWHG.js → constants-yKeKnE84.js} +0 -0
  115. /package/dist/{presets-BKVyQfbt.js → presets-Dkdv55Gt.js} +0 -0
  116. /package/dist/{prng-wHuHlNHE.js → prng-D27-B3tK.js} +0 -0
  117. /package/dist/{useGlobalDark-yhL4Wp-s.js → useGlobalDark-d6waty-X.js} +0 -0
  118. /package/dist/{useIntersectionPause-Cc-H9ees.js → useIntersectionPause-Cck5Uxk8.js} +0 -0
  119. /package/dist/{useKeyboardShortcuts-Be3w_Rwk.js → useKeyboardShortcuts-CyIYrndH.js} +0 -0
  120. /package/dist/{useScrollProgress-CAH8Ofwt.js → useScrollProgress-CffFGLa5.js} +0 -0
  121. /package/dist/{useTextHighlight-DON84L8w.js → useTextHighlight-CWEi25hf.js} +0 -0
@@ -143,6 +143,20 @@
143
143
  box-shadow: var(--focus-ring-shadow);
144
144
  }
145
145
 
146
+ /* D6.b — `focus-ring-gold`: the opt-in gilded focus ring. Overrides ONLY
147
+ `--focus-ring-color` (tokens.css) → the shared `--focus-ring-shadow`
148
+ re-resolves to gold for THIS element; the default ring elsewhere is
149
+ unchanged. Gold-as-state is the "you are here / this is live" mark — a
150
+ transient highlight (appears on focus-visible, gone on blur), so gold is
151
+ lawful here where a permanent gold furniture would not be. Mirror of the
152
+ `focus-ring` custom-property pattern: a consumer composes
153
+ `class="focus-ring focus-ring-gold"` to gild the ring on the active rung;
154
+ the resting mark keeps its structural color (the four-voice law: red is
155
+ identity, gold is distinction). */
156
+ .focus-ring-gold {
157
+ --focus-ring-color: var(--gold);
158
+ }
159
+
146
160
  /* ── Hairline-accent — 0.5px catch-light + under-shadow pair ──
147
161
  Composes the canonical `--border-hairline` token (tokens.css §
148
162
  Glass-decorative). Adopt at any surface that wants the canonical
@@ -366,6 +380,30 @@
366
380
  }
367
381
  }
368
382
 
383
+ /* D6.b — `.text-gilt`: the brand-polish ONE-SHOT shimmer. Same gold-clip
384
+ gradient pass as `.gold-shimmer`, but the gold passes ONCE then SETS — a
385
+ seal being pressed, not a marquee looping forever. This is the lawful home
386
+ for the chassis "Complete!" celebration the disco-star used to carry: the
387
+ gold sweeps once over the completion label on resolve, then holds the
388
+ static gold gradient.
389
+
390
+ `animation-iteration-count: 1` + `animation-fill-mode: forwards` so the
391
+ slide runs exactly one pass and the final keyframe (background-position
392
+ -200%) sticks — no per-frame repaint after settle. PRM users get the
393
+ static gradient, no pass (the gold is still present, just unanimated). */
394
+ .text-gilt {
395
+ background: linear-gradient(90deg, var(--color-gold-dark), var(--color-gold-light), var(--color-gold), var(--color-gold-light), var(--color-gold-dark));
396
+ background-size: 250% 100%;
397
+ background-clip: text;
398
+ -webkit-background-clip: text;
399
+ color: transparent;
400
+ }
401
+ @media (prefers-reduced-motion: no-preference) {
402
+ .text-gilt {
403
+ animation: gold-shimmer-slide var(--duration-shimmer) var(--ease-out-expo) 1 forwards;
404
+ }
405
+ }
406
+
369
407
  /* ── Keyboard key ── */
370
408
  .kbd {
371
409
  display: inline-flex;
@@ -570,6 +608,56 @@
570
608
  letter-spacing: 0.1em;
571
609
  }
572
610
 
611
+ /* D6.b — `MetricBadge variant="record"`: the gilded record/peak value.
612
+ The highest-leverage gold moment on a DATA atlas — a tiny gilt pill on the
613
+ single record / peak / featured figure (the all-time-high, the top
614
+ district). Gold marks the SUPERLATIVE, exactly one per view: a gilt pill on
615
+ a single figure reads as a medal — civic and earned, not decorative.
616
+
617
+ The recipe composes ON the base `.metric-badge` glass plate (it is a
618
+ MODIFIER, never a replacement): a 1px `--gold-rim` tooled edge + `--gold-ink`
619
+ text + a FAINT gold wash (≤8% alpha — never an opaque gold fill, which would
620
+ read as a fourth DATA category and break one-color-one-meaning). The wash
621
+ sits over the badge's own `--glass-bg-quiet` plate via `color-mix`, so the
622
+ cream glass still reads through; the gold is the leaf, not the area.
623
+
624
+ `--gold-ink` clears cream-law ② (APCA |Lc| ≥ 45) on `--card` in both arms
625
+ (proof:gold-ink-contrast), and the faint wash only lightens the plate it
626
+ sits on, so the ink stays legible. */
627
+ .metric-badge--record {
628
+ border-color: var(--gold-rim);
629
+ background:
630
+ linear-gradient(
631
+ 0deg,
632
+ color-mix(in oklab, var(--gold) 8%, transparent),
633
+ color-mix(in oklab, var(--gold) 8%, transparent)
634
+ ),
635
+ var(--metric-badge-bg, var(--glass-bg-quiet));
636
+ box-shadow:
637
+ inset 0 0 0 1px var(--gold-rim),
638
+ inset 0 0.5px 0 0
639
+ color-mix(in oklab, var(--gold-light) 30%, transparent),
640
+ 0 1px 6px color-mix(in srgb, var(--shadow-color) 8%, transparent);
641
+ }
642
+
643
+ /* The record value reads in legible gold ink (the medal numeral). Scoped to
644
+ the amount slot so the unit/label keep their muted register — the gold is
645
+ on the figure, not the furniture. */
646
+ .metric-badge--record .metric-badge__amount {
647
+ color: var(--gold-ink);
648
+ }
649
+
650
+ .metric-badge--record:hover {
651
+ /* Hover deepens the rim to full `--gold` and lifts the wash one rung —
652
+ the gilt edge catches a touch more light, never a fill. */
653
+ border-color: var(--gold);
654
+ box-shadow:
655
+ inset 0 0 0 1px var(--gold),
656
+ inset 0 0.5px 0 0
657
+ color-mix(in oklab, var(--gold-light) 40%, transparent),
658
+ 0 2px 10px color-mix(in srgb, var(--shadow-color) 12%, transparent);
659
+ }
660
+
573
661
  /* Q.W3 Lane A — the `.glass-dock[data-density="…"]` density rungs that
574
662
  set `--dock-tab-h` + `--dock-label-size` were consolidated into
575
663
  `dock.css` (their canonical dock-styles home). They formerly lived
@@ -851,28 +939,17 @@
851
939
  --ripple-radius: var(--ripple-radius-max, 12rem);
852
940
  }
853
941
 
854
- /* Sparkle glyph — hidden at rest, animated on hover. The star
855
- sweeps diagonally from top-left to bottom-right per the canonical
856
- sparkle-sweep keyframe (animations.css). */
857
- &::after {
858
- content: "✦";
859
- position: absolute;
860
- top: 0.25rem;
861
- left: 0.5rem;
862
- color: hsl(0 0% 100% / 0.7);
863
- font-size: 0.75rem;
864
- line-height: 1;
865
- pointer-events: none;
866
- opacity: 0;
867
- will-change: transform, opacity;
868
- z-index: 1;
869
- }
870
-
871
- @media (prefers-reduced-motion: no-preference) {
872
- &:hover::after {
873
- animation: sparkle-sweep var(--duration-sparkle) var(--ease-out-expo);
874
- }
875
- }
942
+ /* D6.b — the disco-star EXCISED. The `::after { content:"✦" }` glyph and
943
+ its `&:hover::after { animation: sparkle-sweep … }` trigger are gone (the
944
+ user's named removal: "remove the disco star from all glass-ui elements").
945
+ A primary action now announces itself by SETTLING into a richer surface,
946
+ not by emitting a sparkle: the whole hover affirmation rides the existing
947
+ `&:hover` specular catch-light box-shadow (`--glass-specular`, above) —
948
+ honest physics, not casino-skeuomorphism. Gold CTAs add the
949
+ `btn-gold-bg-sweep` metal-catch (a metal catching light is honest; a star
950
+ is not). One garish gesture out, zero garish gestures in. The
951
+ `sparkle-sweep` keyframe is TOMBSTONED in animations.css (empty body,
952
+ full delete in 3.11); `--duration-sparkle` is `@deprecated` in tokens.css. */
876
953
 
877
954
  /* PRM bracket — the press-ripple retires; the press still reads
878
955
  via the audacious recipe's transform/scale beat (the ripple is
@@ -900,14 +977,14 @@
900
977
  token triad (tokens.css §13).
901
978
 
902
979
  Design register:
903
- • PRM no-preference: shimmer sweeps continuously at `--duration-shimmer`
904
- rate; the sparkle-sweep (from btn-audacious) coexists on hover.
980
+ • PRM no-preference: the gold sweep IS the gold-CTA affirmation — a metal
981
+ catching light is honest physics (the disco-star is gone, D6.b).
905
982
  • PRM reduce: static gold tint shows on hover; no animation.
906
983
  • The gold shimmer is a background-image layer ABOVE the existing
907
984
  btn-audacious paper-grain + primary-radial layers, blended with
908
985
  `overlay` so the glass substrate reads through at partial opacity.
909
- • The `::before` ripple and `::after` sparkle from btn-audacious are
910
- unchanged; this modifier only retunes the hover background layers.
986
+ • The `::before` ripple from btn-audacious is unchanged; the `::after`
987
+ sparkle is EXCISED (D6.b) — this modifier only retunes the hover layers.
911
988
  • Consumer applies: `<Button variant="gold-audacious">Next →</Button>` */
912
989
  @utility btn-audacious-gold {
913
990
  /* At rest: a faint warm gold tint over the glass surface reads as "warm
@@ -920,27 +997,40 @@
920
997
  color-mix(in srgb, var(--color-gold) 8%, transparent)
921
998
  );
922
999
 
923
- /* Hover: replace the audacious primary-radial with a gold sweep shimmer.
924
- The shimmer gradient rides above the paper-grain texture; the `overlay`
925
- blend-mode concentrates the gold on bright grain facets and recedes on
926
- dark ones — the same lens metaphor as the btn-audacious primary radial. */
1000
+ /* Hover: deepen the plate to a SATURATED gold the white label clears (AW.W13
1001
+ names a "saturated gold backplate"; the D1 fix). The bottom layer is the
1002
+ OPAQUE fixed deep gold (`--color-gold-deep`, mode-INVARIANT) — a solid plate
1003
+ at ~6.5:1 (light) / ~5.5:1 (dark) against white, well below the ~0.18
1004
+ luminance floor white text needs for ≥4.5:1 (was a translucent 22-30% wash
1005
+ over near-cream glass → 1.29:1 white-on-pale-gold). The plate is FIXED-dark
1006
+ in both modes — deepening toward the mode-flipping `--foreground` brightened
1007
+ the dark plate to a cream-gold; `--color-gold-deep` does not flip. The
1008
+ shimmer sweep rides ABOVE as a LOW-alpha gold gradient (normal blend, ≤18% —
1009
+ it textures the plate without brightening it past the floor), and the
1010
+ paper-grain overlays for the disco facet. */
927
1011
  &:hover:not(:disabled) {
928
1012
  background-image:
929
1013
  var(--paper-clean-texture),
930
1014
  linear-gradient(
931
1015
  90deg,
932
1016
  transparent 0%,
933
- color-mix(in srgb, var(--color-gold-dark) 22%, transparent) 25%,
934
- color-mix(in srgb, var(--color-gold-light) 30%, transparent) 50%,
935
- color-mix(in srgb, var(--color-gold-dark) 22%, transparent) 75%,
1017
+ color-mix(in srgb, var(--color-gold) 14%, transparent) 25%,
1018
+ color-mix(in srgb, var(--color-gold) 18%, transparent) 50%,
1019
+ color-mix(in srgb, var(--color-gold) 14%, transparent) 75%,
936
1020
  transparent 100%
1021
+ ),
1022
+ linear-gradient(
1023
+ 135deg,
1024
+ var(--color-gold-deep),
1025
+ color-mix(in srgb, var(--color-gold-deep), var(--color-gold-dark) 18%) 50%,
1026
+ var(--color-gold-deep)
937
1027
  );
938
- background-blend-mode: overlay, normal;
939
- background-size: var(--paper-texture-size), 250% 100%;
940
- background-position: 0 0, 100% 0;
1028
+ background-blend-mode: overlay, normal, normal;
1029
+ background-size: var(--paper-texture-size), 250% 100%, 100% 100%;
1030
+ background-position: 0 0, 100% 0, 0 0;
941
1031
  box-shadow:
942
1032
  var(--glass-specular),
943
- 0 0 0 1px color-mix(in srgb, var(--color-gold) 30%, transparent),
1033
+ 0 0 0 1px color-mix(in srgb, var(--color-gold-dark) 40%, transparent),
944
1034
  0 0.5px 0 0 rgb(0 0 0 / 0.06);
945
1035
  }
946
1036
 
@@ -956,8 +1046,8 @@
956
1046
  a text-clip gradient). This variant sweeps the `background-position` of the
957
1047
  250% wide gradient across the button's bounding box. */
958
1048
  @keyframes btn-gold-bg-sweep {
959
- 0% { background-position: 0 0, 100% 0; }
960
- 100% { background-position: 0 0, -100% 0; }
1049
+ 0% { background-position: 0 0, 100% 0, 0 0; }
1050
+ 100% { background-position: 0 0, -100% 0, 0 0; }
961
1051
  }
962
1052
 
963
1053
  /* ── Table density utilities — AN.R0 ─────────────────────────────────────
@@ -1037,7 +1127,7 @@
1037
1127
  states except `hover:scale-*`; this is the canonical opt-in that adds the
1038
1128
  spring-hover lift. Consumed by keyframes.js at 7 sites.
1039
1129
 
1040
- AX.W52 §6 — the hover lift is the restrained `--scale-hover-btn` (1.035, NOT
1130
+ AX.W52 §6 — the hover lift is the restrained `--scale-hover-btn` (1.05, NOT
1041
1131
  the emphatic 1.08 `--scale-hover`) routed through `--spring-smooth` — the ONE
1042
1132
  button scale register the §6 doctrine records and the gate asserts across
1043
1133
  `.btn-pill`/`.tap-squish`/`.glass-btn`/`btn-interactive`. The surface legs
@@ -60,5 +60,56 @@
60
60
  @keyframes gl-vt-slide-in { from { opacity: 0; translate: 0 var(--vt-rise, 8px); } }
61
61
  @keyframes gl-vt-slide-out { to { opacity: 0; translate: 0 var(--vt-rise, 8px); } }
62
62
 
63
+ /* ── gl-shared-element — the named-pair MORPH group (D6.c M6) ──────────────────
64
+ * Distinct from `.gl-list-item` (a cross-fade of MANY members in a re-rank): a
65
+ * shared-element morph is ONE element that exists in BOTH the old and new states
66
+ * under the SAME `view-transition-name`, so the browser MORPHS it in place — the
67
+ * group interpolates its size+position (transform) while old/new cross-fade. The
68
+ * editorial case: the gallery card's title IS the dashboard masthead's title, so
69
+ * the name you clicked GROWS into the name you read (the card → masthead route
70
+ * morph). The consumer adds `view-transition-class: gl-shared-element` plus a
71
+ * MATCHED `view-transition-name: <id>` on BOTH the source and destination element
72
+ * (the MANDATORY runtime rule — ≤1 element per name per state, else the morph is
73
+ * skipped silently), and wraps the navigation in `useRouteTransition` /
74
+ * `startViewTransition`.
75
+ *
76
+ * The morph rides the SMOOTH register (the 700ms-class spring, C-ANIM-VIZ-MAP T1
77
+ * §7) — a longer, gentler curve than the list-item cross-fade, because a morph
78
+ * that travels across the viewport wants room to read. The old/new cross-fade is
79
+ * softened so the morphing GROUP is the figure and the rest recedes. */
80
+ ::view-transition-group(.gl-shared-element) {
81
+ animation-duration: var(--vt-morph-duration, var(--duration-slow, 500ms));
82
+ animation-timing-function: var(--vt-morph-ease, var(--spring-smooth, ease-in-out));
83
+ }
84
+ ::view-transition-old(.gl-shared-element),
85
+ ::view-transition-new(.gl-shared-element) {
86
+ /* The image pair cross-fades UNDER the group's size/position morph — softer
87
+ than the group curve so the morph (the size/position travel) is the figure
88
+ and the pixel cross-fade is the recessive fill. */
89
+ animation-duration: var(--vt-morph-duration, var(--duration-slow, 500ms));
90
+ animation-timing-function: var(--vt-ease, var(--spring-smooth, ease-in-out));
91
+ }
92
+
93
+ /* ── gl-expand — the plate → fullscreen MORPH recipe (D6.c M7) ─────────────────
94
+ * The expand verb (a plate growing to fullscreen) is a SHARED-ELEMENT morph, not
95
+ * an opacity jump-cut: the plate IS the fullscreen surface, growing. It is a
96
+ * specialization of `gl-shared-element` — the SAME named-pair morph, with the
97
+ * expand register (a touch snappier than a route morph, because the surface stays
98
+ * in place and only the rect grows, so it wants less travel-room). `ExpandableContainer`
99
+ * wires the `view-transition-name` plumbing on its plate↔fullscreen surfaces (an
100
+ * opt-in `viewTransitionName` prop), so a consumer opts in and the open/close
101
+ * mutation — wrapped in `startViewTransition` — morphs the plate's rect to the
102
+ * fullscreen rect and back. The named pair is the SAME element across states
103
+ * (the slot content), so the browser captures one group and grows it. */
104
+ ::view-transition-group(.gl-expand) {
105
+ animation-duration: var(--vt-expand-duration, var(--duration-normal, 240ms));
106
+ animation-timing-function: var(--vt-expand-ease, var(--spring-bouncy, ease-out));
107
+ }
108
+ ::view-transition-old(.gl-expand),
109
+ ::view-transition-new(.gl-expand) {
110
+ animation-duration: var(--vt-expand-duration, var(--duration-normal, 240ms));
111
+ animation-timing-function: var(--vt-ease, var(--spring-bouncy, ease-out));
112
+ }
113
+
63
114
  /* Keep the non-transitioned UI interactive while the snapshot animates. */
64
115
  ::view-transition { pointer-events: none; }
package/dist/switch.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./Switch-LDKLmmgx.js";
1
+ import { t as e } from "./Switch-Ch-k3Rv-.js";
2
2
  export { e as Switch };
@@ -1,4 +1,4 @@
1
- import { n as e, t } from "./constants-CS75AWHG.js";
1
+ import { n as e, t } from "./constants-yKeKnE84.js";
2
2
  import { getCurrentScope as n, onScopeDispose as r, readonly as i, ref as a, shallowRef as o, toValue as s, watch as c } from "vue";
3
3
  import { SmoothProgress as l } from "@mkbabb/keyframes.js";
4
4
  //#region src/composables/motion/useAnimatedNumber.ts
@@ -41,7 +41,7 @@ function o(e, t = {}) {
41
41
  preserveAspectRatio="none" x="0%" y="0%" width="100%" height="100%" />
42
42
  <feBlend in="blurred" in2="specular" mode="screen" result="final" />
43
43
  </filter>
44
- `, document.body.appendChild(p), e.style.backdropFilter = `url(#${n}) blur(${o * .15}px) saturate(1.6) brightness(1.05)`, e.style.setProperty("-webkit-backdrop-filter", e.style.backdropFilter), e.style.border = "1px solid rgba(255,255,255,0.25)", e.style.boxShadow = "\n inset 0 0.5px 0 0 rgba(255,255,255,0.3),\n inset 0 -0.5px 0 0 rgba(0,0,0,0.05),\n 0 4px 16px rgba(0,0,0,0.08)\n ";
44
+ `, document.body.appendChild(p), e.style.backdropFilter = `url(#${n}) blur(${o * .15}px) saturate(var(--glass-saturate, 1.6)) brightness(1.05)`, e.style.setProperty("-webkit-backdrop-filter", e.style.backdropFilter), e.style.border = "1px solid var(--glass-border-floating)", e.style.boxShadow = "var(--glass-material-rim), var(--glass-shadow-floating)";
45
45
  let h = new ResizeObserver(() => {
46
46
  let t = e.getBoundingClientRect(), n = Math.max(Math.ceil(t.width / 4), 32), a = Math.max(Math.ceil(t.height / 4), 32);
47
47
  r(c, n, a, s), i(l, n, a);
@@ -0,0 +1,21 @@
1
+ //#region src/composables/motion/useViewTransition.ts
2
+ function e() {
3
+ return typeof document < "u" && typeof document.startViewTransition == "function";
4
+ }
5
+ function t(e, t) {
6
+ let n = typeof document > "u" ? void 0 : document;
7
+ if (!n || typeof n.startViewTransition != "function") return e(), {
8
+ finished: Promise.resolve(),
9
+ transitioned: !1
10
+ };
11
+ let r = t?.types && t.types.length > 0 ? n.startViewTransition({
12
+ update: () => e(),
13
+ types: t.types
14
+ }) : n.startViewTransition(() => e());
15
+ return r.ready?.catch(() => {}), {
16
+ finished: r.finished.then(() => void 0, () => void 0),
17
+ transitioned: !0
18
+ };
19
+ }
20
+ //#endregion
21
+ export { e as n, t };
@@ -0,0 +1,53 @@
1
+ //#region src/utils/moveBefore.ts
2
+ function e(e, t, n) {
3
+ let r = e;
4
+ typeof r.moveBefore == "function" ? r.moveBefore(t, n) : e.insertBefore(t, n);
5
+ }
6
+ function t() {
7
+ return typeof Element < "u" && "moveBefore" in Element.prototype;
8
+ }
9
+ //#endregion
10
+ //#region src/utils/platformSupport.ts
11
+ function n() {
12
+ return typeof globalThis.scheduler?.postTask == "function";
13
+ }
14
+ //#endregion
15
+ //#region src/composables/motion/useRouteTransition.ts
16
+ function r() {
17
+ return typeof window > "u" || typeof window.matchMedia != "function" ? !1 : window.matchMedia("(prefers-reduced-motion: reduce)").matches;
18
+ }
19
+ function i() {
20
+ return typeof document < "u" && typeof document.startViewTransition == "function";
21
+ }
22
+ function a() {
23
+ function e(e, t) {
24
+ let n = typeof document > "u" ? void 0 : document;
25
+ if (!n || typeof n.startViewTransition != "function" || r()) return {
26
+ finished: (async () => e())().then(() => void 0, () => void 0),
27
+ transitioned: !1
28
+ };
29
+ let i = t?.types && t.types.length > 0 ? n.startViewTransition({
30
+ update: () => e(),
31
+ types: t.types
32
+ }) : n.startViewTransition(() => e());
33
+ return i.ready?.catch(() => {}), {
34
+ finished: i.finished.then(() => void 0, () => void 0),
35
+ transitioned: !0
36
+ };
37
+ }
38
+ return {
39
+ navigate: e,
40
+ supported: i()
41
+ };
42
+ }
43
+ //#endregion
44
+ //#region src/composables/motion/vReveal.ts
45
+ function o(e, t) {
46
+ e.setAttribute("data-reveal", t.arg === "fade" ? "fade" : ""), e.style.setProperty("--d", String(t.value ?? 0));
47
+ }
48
+ var s = {
49
+ mounted: o,
50
+ updated: o
51
+ };
52
+ //#endregion
53
+ export { e as a, n as i, i as n, t as o, a as r, s as t };
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./_plugin-vue_export-helper-ok8pgSl5.js";
2
- import { n as t, t as n } from "./prng-wHuHlNHE.js";
2
+ import { n as t, t as n } from "./prng-D27-B3tK.js";
3
3
  import { computed as r, createBlock as i, createElementVNode as a, defineComponent as o, normalizeClass as s, normalizeStyle as c, onUnmounted as l, openBlock as u, ref as d, renderSlot as f, resolveDynamicComponent as p, toRef as m, useId as h, watch as g, withCtx as _ } from "vue";
4
4
  //#region src/components/custom/watercolor-dot/prng.ts
5
5
  function v(e, t, n) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mkbabb/glass-ui",
3
- "version": "3.9.0",
4
- "description": "Glassmorphic design system — Vue 3.5 components, reka-ui primitives, Tailwind CSS v4 tokens",
3
+ "version": "3.10.0",
4
+ "description": "Glassmorphic design system \u2014 Vue 3.5 components, reka-ui primitives, Tailwind CSS v4 tokens",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -58,6 +58,9 @@
58
58
  "fourier-field": [
59
59
  "dist/fourier-field.d.ts"
60
60
  ],
61
+ "fourier-math": [
62
+ "dist/fourier-math.d.ts"
63
+ ],
61
64
  "goo-blob": [
62
65
  "dist/goo-blob.d.ts"
63
66
  ],
@@ -297,6 +300,10 @@
297
300
  "types": "./dist/fourier-field.d.ts",
298
301
  "import": "./dist/fourier-field.js"
299
302
  },
303
+ "./fourier-math": {
304
+ "types": "./dist/fourier-math.d.ts",
305
+ "import": "./dist/fourier-math.js"
306
+ },
300
307
  "./goo-blob": {
301
308
  "types": "./dist/goo-blob.d.ts",
302
309
  "import": "./dist/goo-blob.js"
@@ -305,6 +312,10 @@
305
312
  "types": "./dist/watercolor-dot.d.ts",
306
313
  "import": "./dist/watercolor-dot.js"
307
314
  },
315
+ "./handmark": {
316
+ "types": "./dist/handmark.d.ts",
317
+ "import": "./dist/handmark.js"
318
+ },
308
319
  "./configurator": {
309
320
  "types": "./dist/configurator.d.ts",
310
321
  "import": "./dist/configurator.js"
@@ -554,6 +565,9 @@
554
565
  "proof:phantom-classes": "node scripts/proof-phantom-classes.mjs",
555
566
  "proof:vt-names": "node scripts/proof-vt-names.mjs",
556
567
  "proof:dock-animation-live": "node scripts/proof-dock-animation-live.mjs",
568
+ "proof:dock-rail-cohesion": "node scripts/proof-dock-rail-cohesion.mjs",
569
+ "proof:dock-lockstep-bornred": "node scripts/proof-dock-lockstep-bornred.mjs",
570
+ "proof:dock-items-lag-capture": "node scripts/proof-dock-items-lag-capture.mjs",
557
571
  "proof:dock-orchestrator-single": "node scripts/proof-dock-orchestrator-single.mjs",
558
572
  "proof:dock-clip-reveal": "node scripts/proof-dock-clip-reveal.mjs",
559
573
  "proof:dock-layering-polish": "node scripts/proof-dock-layering-polish.mjs",
@@ -575,6 +589,7 @@
575
589
  "proof:card-cartoon-consumers": "node scripts/proof-card-cartoon-consumers.mjs",
576
590
  "proof:doc-consistency": "node scripts/proof-doc-consistency.mjs",
577
591
  "proof:au-w0-reground": "node scripts/proof-au-w0-reground.mjs",
592
+ "proof:ay-w0-reground": "node scripts/proof-ay-w0-reground.mjs",
578
593
  "proof:au-w1-design": "node scripts/proof-au-w1-design.mjs",
579
594
  "proof:au-final": "node scripts/proof-au-final.mjs",
580
595
  "proof:strict-templates": "node scripts/proof-strict-templates.mjs",
@@ -616,12 +631,12 @@
616
631
  "proof:aurora-oilpastel-medium": "node scripts/proof-aurora-oilpastel-medium.mjs",
617
632
  "proof:aurora-stroke-composite": "node scripts/proof-aurora-stroke-composite.mjs",
618
633
  "proof:aurora-painterly-statistics": "node scripts/proof-aurora-painterly-statistics.mjs",
634
+ "proof:aurora-arresting-ref": "node scripts/aurora-arresting-metric.mjs tests-visual/fixtures/starry-night-crop.png",
619
635
  "proof:aurora-atoms-roundtrip": "node scripts/proof-aurora-atoms-roundtrip.mjs",
620
- "proof:aurora-wgsl-equivalence": "node scripts/proof-aurora-wgsl-equivalence.mjs",
621
- "proof:aurora-noise-hash-equivalence": "node scripts/proof-aurora-noise-hash-equivalence.mjs",
622
- "proof:aurora-backend-fallback": "node scripts/proof-aurora-backend-fallback.mjs",
623
- "proof:webgpu-substrate-single": "node scripts/proof-webgpu-substrate-single.mjs",
624
- "proof:aurora-webgpu-render": "node scripts/proof-aurora-webgpu-render.mjs",
636
+ "proof:aur2-residue": "node scripts/proof-aur2-residue.mjs",
637
+ "proof:aurora-arresting": "node scripts/proof-aurora-arresting.mjs",
638
+ "proof:aurora-atoms-render": "node scripts/proof-aurora-atoms-render.mjs",
639
+ "proof:aurora-studio": "node scripts/proof-aurora-studio.mjs",
625
640
  "proof:aurora-interaction-prm": "node scripts/proof-aurora-interaction-prm.mjs",
626
641
  "proof:shader-shared-source": "node scripts/proof-shader-shared-source.mjs",
627
642
  "proof:blob-color-equivalence": "vitest run tests/components/custom/goo-blob/blob-color-equivalence.test.ts",
@@ -640,12 +655,24 @@
640
655
  "proof:constellation-substrate-single": "node scripts/proof-constellation-substrate-single.mjs",
641
656
  "proof:constellation-tokens": "node scripts/proof-constellation-tokens.mjs",
642
657
  "proof:constellation-warp-live": "node scripts/proof-constellation-warp-live.mjs",
658
+ "proof:constellation-egg-live": "node scripts/proof-constellation-egg-live.mjs",
659
+ "proof:constellation-freeze-live": "node scripts/proof-constellation-freeze-live.mjs",
660
+ "proof:fourier-field-intensity": "node scripts/proof-fourier-field-intensity.mjs",
661
+ "proof:fourier-field-visibility-live": "node scripts/proof-fourier-field-visibility-live.mjs",
662
+ "proof:constellation-refit-live": "node scripts/proof-constellation-refit-live.mjs",
643
663
  "proof:canvas2d-substrate": "vitest run tests/composables/glass/canvas2d/useCanvas2D.test.ts",
644
664
  "proof:resolve-canvas-color": "vitest run tests/composables/glass/canvas2d/resolveCanvasColor.test.ts",
645
665
  "proof:text-highlight": "vitest run tests/composables/motion/text-highlight-home.test.ts tests/composables/motion/useTextHighlight.test.ts",
646
666
  "proof:constellation-field": "vitest run tests/components/custom/constellation/constellationField.test.ts",
647
667
  "proof:input-invalid-aria": "node scripts/proof-input-invalid-aria.mjs",
648
668
  "proof:subpath-enumeration": "node scripts/proof-subpath-enumeration.mjs",
669
+ "proof:handmark-export": "node scripts/proof-handmark-export.mjs",
670
+ "proof:handmark-tests": "vitest run tests/components/custom/handmark",
671
+ "proof:no-disco-star": "node scripts/proof-no-disco-star.mjs",
672
+ "proof:gold-ink-contrast": "node scripts/proof-gold-ink-contrast.mjs",
673
+ "proof:glass-gilt": "node scripts/proof-glass-gilt.mjs",
674
+ "proof:crayon-wipe-compositor": "node scripts/proof-crayon-wipe-compositor.mjs",
675
+ "proof:metric-badge-record": "vitest run tests/components/custom/metric-badge/MetricBadge.record.test.ts",
649
676
  "proof:no-orphan-composable": "node scripts/proof-no-orphan-composable.mjs",
650
677
  "proof:speedtest-boundary": "node scripts/proof-speedtest-boundary.mjs",
651
678
  "proof:glass-material-unified": "node scripts/proof-glass-material-unified.mjs",
@@ -658,11 +685,14 @@
658
685
  "proof:ui-scale": "node scripts/proof-ui-scale.mjs",
659
686
  "proof:dropdown-type-scale": "node scripts/proof-dropdown-type-scale.mjs",
660
687
  "proof:forced-colors-skin": "node scripts/proof-forced-colors-skin.mjs",
661
- "proof:glass-one-model": "node scripts/proof-glass-level.mjs --one-model",
688
+ "proof:glass-cohesion": "node scripts/proof-glass-cohesion.mjs",
662
689
  "proof:adaptive-glass": "node scripts/proof-adaptive-glass.mjs",
663
690
  "proof:dark-semantic-contrast": "node scripts/proof-dark-semantic-contrast.mjs",
664
691
  "proof:glass-material-demo": "node scripts/proof-glass-material-demo.mjs",
665
692
  "proof:blob-live-truth": "node scripts/proof-blob-live-truth.mjs",
693
+ "proof:blob-config-atoms": "node scripts/proof-blob-config-atoms.mjs",
694
+ "proof:blob3-strip": "node scripts/proof-blob3-strip.mjs",
695
+ "proof:blob-config": "node scripts/proof-blob-config.mjs",
666
696
  "proof:tabs-unified": "node scripts/proof-tabs-unified.mjs",
667
697
  "proof:glass-material-sota": "node scripts/proof-glass-material-sota.mjs",
668
698
  "proof:primitive-affordance": "node scripts/proof-primitive-affordance.mjs",
@@ -673,10 +703,13 @@
673
703
  "proof:substrate-paints-color": "node scripts/proof-substrate-paints-color.mjs",
674
704
  "proof:deck-progress-rail": "node scripts/proof-deck-progress-rail.mjs",
675
705
  "proof:blob-render": "node scripts/proof-blob-render.mjs",
706
+ "proof:blob-warm-default": "node scripts/proof-blob-warm-default.mjs",
676
707
  "proof:blob-integration": "node scripts/proof-blob-integration.mjs",
677
708
  "proof:gate-script-parity": "node scripts/proof-gate-script-parity.mjs",
678
709
  "proof:all": "node scripts/gates.mjs --run local",
679
- "proof:live-verified-ledger": "node scripts/proof-live-verified-ledger.mjs",
710
+ "proof:live-verified-ledger": "node scripts/proof-live-verified-ledger.mjs --tranche=AY",
711
+ "proof:live-verified-ledger:ay": "node scripts/proof-live-verified-ledger.mjs --tranche=AY",
712
+ "proof:live-verified-ledger:ax": "node scripts/proof-live-verified-ledger.mjs --tranche=AX",
680
713
  "proof:disposition-live": "node scripts/proof-disposition-live.mjs",
681
714
  "proof:gen-ci-fresh": "node scripts/proof-gen-ci-fresh.mjs",
682
715
  "gates:verify-ci": "node scripts/gates.mjs --verify-ci",
@@ -694,11 +727,13 @@
694
727
  "peerDependencies": {
695
728
  "@lucide/vue": "^1.16.0",
696
729
  "@mkbabb/keyframes.js": "^2.2.0 || ^3.0.0 || ^4.0.0",
730
+ "@mkbabb/pencil-boil": "^0.4.0",
697
731
  "@mkbabb/value.js": "^0.10.0 || ^0.11.0",
698
732
  "@vueuse/core": "^14.0",
699
733
  "class-variance-authority": "^0.7",
700
734
  "clsx": "^2.0",
701
735
  "embla-carousel-vue": "^8.0",
736
+ "perfect-freehand": "^1.2.3",
702
737
  "reka-ui": "^2.0",
703
738
  "tailwindcss": "^4.0",
704
739
  "tw-animate-css": "^1.2.5",
@@ -715,9 +750,15 @@
715
750
  "@mkbabb/keyframes.js": {
716
751
  "optional": true
717
752
  },
753
+ "@mkbabb/pencil-boil": {
754
+ "optional": true
755
+ },
718
756
  "@mkbabb/value.js": {
719
757
  "optional": true
720
758
  },
759
+ "perfect-freehand": {
760
+ "optional": true
761
+ },
721
762
  "tw-animate-css": {
722
763
  "optional": true
723
764
  }
@@ -725,6 +766,7 @@
725
766
  "devDependencies": {
726
767
  "@lucide/vue": "^1.16.0",
727
768
  "@mkbabb/keyframes.js": "^2.2.0",
769
+ "@mkbabb/pencil-boil": "^0.4.0",
728
770
  "@mkbabb/value.js": "^0.10.0",
729
771
  "@tailwindcss/postcss": "^4.3.0",
730
772
  "@tailwindcss/vite": "^4.3.0",