@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.
- package/dist/{MetricBadge-lTc002u2.js → MetricBadge-BZVWIxNy.js} +6 -4
- package/dist/{Notification-BxK8LZMw.js → Notification-DLMhblXR.js} +2 -2
- package/dist/{Switch-LDKLmmgx.js → Switch-Ch-k3Rv-.js} +1 -1
- package/dist/animated-digit.js +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api.js +1 -1
- package/dist/aurora.js +236 -545
- package/dist/{badge-BvwvT50i.js → badge-CaoFJzRb.js} +1 -1
- package/dist/badge.js +1 -1
- package/dist/color.js +1 -1
- package/dist/{compile-DAjIoEy2.js → compile-BOXjLUxu.js} +23 -23
- package/dist/components/custom/aurora/composables/atoms.d.ts +21 -4
- package/dist/components/custom/aurora/composables/runtime.d.ts +0 -9
- package/dist/components/custom/aurora/composables/uniformBridge.d.ts +0 -11
- package/dist/components/custom/aurora/constants/renderMode.d.ts +0 -32
- package/dist/components/custom/aurora/constants/shaders/brush.glsl.d.ts +1 -1
- package/dist/components/custom/aurora/constants/shaders/mediums.glsl.d.ts +2 -2
- package/dist/components/custom/aurora/constants/shaders/tonemap.glsl.d.ts +1 -1
- package/dist/components/custom/aurora/index.d.ts +1 -1
- package/dist/components/custom/constellation/Constellation.vue.d.ts +73 -1
- package/dist/components/custom/constellation/constellationField.d.ts +255 -3
- package/dist/components/custom/constellation/index.d.ts +2 -2
- package/dist/components/custom/dock/DockTabButton.vue.d.ts +4 -3
- package/dist/components/custom/expandable-container/ExpandableContainer.vue.d.ts +29 -0
- package/dist/components/custom/fourier-field/FourierField.vue.d.ts +6 -0
- package/dist/components/custom/fourier-field/index.d.ts +25 -1
- package/dist/components/custom/fourier-field/math.d.ts +3 -8
- package/dist/components/custom/goo-blob/GooBlob.vue.d.ts +8 -10
- package/dist/components/custom/goo-blob/composables/useMetaballRenderer.d.ts +6 -14
- package/dist/components/custom/goo-blob/index.d.ts +1 -1
- package/dist/components/custom/goo-blob/types.d.ts +59 -25
- package/dist/components/custom/handmark/HandMark.vue.d.ts +29 -0
- package/dist/components/custom/handmark/brush.d.ts +219 -0
- package/dist/components/custom/handmark/freehand.d.ts +69 -0
- package/dist/components/custom/handmark/geometry.d.ts +32 -0
- package/dist/components/custom/handmark/index.d.ts +21 -0
- package/dist/components/custom/handmark/ink.d.ts +11 -0
- package/dist/components/custom/handmark/texture.d.ts +39 -0
- package/dist/components/custom/handmark/types.d.ts +53 -0
- package/dist/components/custom/handmark/useHandMark.d.ts +66 -0
- package/dist/components/custom/metric-badge/MetricBadge.vue.d.ts +8 -0
- package/dist/components/ui/slider/index.d.ts +20 -16
- package/dist/composables/color/index.d.ts +12 -7
- package/dist/composables/glass/webgl/shaders/procedural-color.glsl.d.ts +1 -6
- package/dist/composables/motion/core/index.d.ts +1 -0
- package/dist/composables/motion/useRouteTransition.d.ts +42 -0
- package/dist/constellation.js +212 -72
- package/dist/controls.js +1 -1
- package/dist/dark.js +1 -1
- package/dist/dock.js +1 -0
- package/dist/expandable-container.js +61 -38
- package/dist/forms.js +2 -2
- package/dist/fourier-field.js +89 -97
- package/dist/fourier-math.d.ts +1 -0
- package/dist/fourier-math.js +2 -0
- package/dist/glass-panel.js +1 -1
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +81 -80
- package/dist/goo-blob.js +299 -284
- package/dist/handmark.d.ts +1 -0
- package/dist/handmark.js +609 -0
- package/dist/icon-tooltip.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/keyboard.js +1 -1
- package/dist/labeled-field.js +4 -4
- package/dist/math-DTpRVC0e.js +27 -0
- package/dist/metric-badge.js +1 -1
- package/dist/metric-stack.js +1 -1
- package/dist/motion-core.js +70 -69
- package/dist/motion.js +2 -2
- package/dist/notification.js +1 -1
- package/dist/search.js +2 -2
- package/dist/{slider-DC2mwuoe.js → slider-CyzcxBoh.js} +6 -6
- package/dist/slider.js +1 -1
- package/dist/styles/animations.css +74 -18
- package/dist/styles/cards.css +2 -2
- package/dist/styles/components.css +1 -1
- package/dist/styles/dock/layer-group.css +16 -4
- package/dist/styles/dock-controls.css +39 -23
- package/dist/styles/drawer.css +12 -4
- package/dist/styles/glass.css +145 -9
- package/dist/styles/paper.css +68 -2
- package/dist/styles/theme.css +7 -0
- package/dist/styles/tokens.css +101 -15
- package/dist/styles/transitions.css +20 -2
- package/dist/styles/utilities.css +130 -40
- package/dist/styles/view-transition.css +51 -0
- package/dist/switch.js +1 -1
- package/dist/{useAnimatedNumber-C5I3wWd8.js → useAnimatedNumber-Bcpy5Etf.js} +1 -1
- package/dist/{useGlassRenderer-5I0YkI4t.js → useGlassRenderer-D7YGOYiM.js} +1 -1
- package/dist/useViewTransition-DaN5Zrox.js +21 -0
- package/dist/vReveal-zUIQk-rJ.js +53 -0
- package/dist/watercolor-dot.js +1 -1
- package/package.json +51 -9
- package/src/styles/animations.css +74 -18
- package/src/styles/cards.css +2 -2
- package/src/styles/dock/layer-group.css +16 -4
- package/src/styles/dock-controls.css +39 -23
- package/src/styles/drawer.css +12 -4
- package/src/styles/glass.css +145 -9
- package/src/styles/paper.css +68 -2
- package/src/styles/theme.css +7 -0
- package/src/styles/tokens.css +101 -15
- package/src/styles/transitions.css +20 -2
- package/src/styles/utilities.css +130 -40
- package/src/styles/view-transition.css +51 -0
- package/dist/components/custom/aurora/composables/gpuRuntime.d.ts +0 -16
- package/dist/components/custom/aurora/constants/shaders/aurora.wgsl.d.ts +0 -7
- package/dist/composables/glass/createGPUCanvas.d.ts +0 -40
- package/dist/vReveal-CqaCz_mC.js +0 -44
- /package/dist/{IconTooltip-yefK7cJc.js → IconTooltip-Cus0fvK0.js} +0 -0
- /package/dist/{Input-DWQQIOC4.js → Input-xuDwALQR.js} +0 -0
- /package/dist/{color-8jBjWiJ6.js → color-C5ls_QF7.js} +0 -0
- /package/dist/{constants-CS75AWHG.js → constants-yKeKnE84.js} +0 -0
- /package/dist/{presets-BKVyQfbt.js → presets-Dkdv55Gt.js} +0 -0
- /package/dist/{prng-wHuHlNHE.js → prng-D27-B3tK.js} +0 -0
- /package/dist/{useGlobalDark-yhL4Wp-s.js → useGlobalDark-d6waty-X.js} +0 -0
- /package/dist/{useIntersectionPause-Cc-H9ees.js → useIntersectionPause-Cck5Uxk8.js} +0 -0
- /package/dist/{useKeyboardShortcuts-Be3w_Rwk.js → useKeyboardShortcuts-CyIYrndH.js} +0 -0
- /package/dist/{useScrollProgress-CAH8Ofwt.js → useScrollProgress-CffFGLa5.js} +0 -0
- /package/dist/{useTextHighlight-DON84L8w.js → useTextHighlight-CWEi25hf.js} +0 -0
package/src/styles/tokens.css
CHANGED
|
@@ -80,9 +80,12 @@
|
|
|
80
80
|
--duration-xxl: 1.5s;
|
|
81
81
|
--duration-shimmer-fast: 3s;
|
|
82
82
|
--duration-shimmer: 5s;
|
|
83
|
-
/* Sparkle micro-event — primary-CTA disco-grain sparkle sweep
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
/* Sparkle micro-event — primary-CTA disco-grain sparkle sweep.
|
|
84
|
+
@deprecated 3.10 — the disco-star is EXCISED (D6.b); the `sparkle-sweep`
|
|
85
|
+
keyframe is tombstoned (animations.css) and no live recipe consumes this
|
|
86
|
+
duration. Retained one minor so an out-of-tree consumer resolves a value
|
|
87
|
+
rather than `unset`; full delete (this token + the theme bridge + the
|
|
88
|
+
keyframe) lands in 3.11. */
|
|
86
89
|
--duration-sparkle: 600ms;
|
|
87
90
|
|
|
88
91
|
/* AH.W5-e (FA-8 §4d) — motion-duration + staged-reveal canon.
|
|
@@ -181,7 +184,7 @@
|
|
|
181
184
|
The BUTTON family (`.btn-pill` / `.tap-squish` / `.glass-btn` /
|
|
182
185
|
`btn-interactive`) UNIFIES its `scale` transform leg onto ONE register —
|
|
183
186
|
`--spring-smooth` — so hover + press read as one motion language (the
|
|
184
|
-
hover lift is the restrained `--scale-hover-btn` = 1.
|
|
187
|
+
hover lift is the restrained `--scale-hover-btn` = 1.05, not the 1.08
|
|
185
188
|
`--scale-hover`). Springs read alive on TRANSFORM and ENTER (overshoot =
|
|
186
189
|
physicality); a spring on a COLOR or an EXIT reads as a wobble/hesitation.
|
|
187
190
|
`--ease-apple` is the ambient-only register (consumed solely by the Pulse
|
|
@@ -511,6 +514,26 @@
|
|
|
511
514
|
field recedes further: BELOW the slides 0.92 max-legibility reference. */
|
|
512
515
|
--constellation-alpha: 0.80;
|
|
513
516
|
|
|
517
|
+
/* §interaction — the warp spring + the gravity-well tunings (NUMERIC, NOT
|
|
518
|
+
colors — read ONCE on mount via parseFloat, never reach a Canvas2D
|
|
519
|
+
fillStyle, so immune to the W30 light-dark()/Canvas2D leak; AY.W-CON2).
|
|
520
|
+
Mode-INVARIANT, declared ONCE in :root (the .dark arm needs no numeric
|
|
521
|
+
re-declare — a per-mode value SPLIT is what proof:constellation-tokens
|
|
522
|
+
clause (c) flags, and these tunings are identical in both modes).
|
|
523
|
+
`--constellation-warp-response` is the keyframes.js ANGULAR PERIOD (the
|
|
524
|
+
SwiftUI .spring(response:) axis), NOT a settle-duration — at ζ=1 the 2%
|
|
525
|
+
settle lands at t₂ ≈ 5.83/ω₀ ≈ 0.93·response (the engine keeps the
|
|
526
|
+
keyframes.js ω₀ = 2π/response convention, mints no second ω). */
|
|
527
|
+
--constellation-warp-response: 0.55; /* s — keyframes.js angular period (NOT a settle) */
|
|
528
|
+
--constellation-warp-zeta: 1.0; /* critically damped — a focal mark must NOT ring */
|
|
529
|
+
--constellation-well-gain: 14000; /* inverse-square force scale (the held-pull gain) */
|
|
530
|
+
--constellation-well-reach: 340; /* base-width px — the well's reach (k-scaled at step) */
|
|
531
|
+
--constellation-well-ramp: 4.0; /* 1/s — the ARM rate (≈0.25s bloom; release is the fixed brisk WELL_RELEASE_RAMP — the field-cools invariant, not consumer-tunable) */
|
|
532
|
+
--constellation-well-max-speed: 4.0; /* base-width px/frame cap — the no-slingshot clamp */
|
|
533
|
+
--constellation-well-hold-ms: 140; /* ms hold before the well arms */
|
|
534
|
+
--constellation-wander-idle: 8000; /* ms — min idle between auto re-targets (the W-CON1 drift cadence) */
|
|
535
|
+
--constellation-wander-jitter: 8000; /* ms — random extra idle per cadence (so the rhythm is not metronomic) */
|
|
536
|
+
|
|
514
537
|
/* ═══════════════════════════════════════════════
|
|
515
538
|
§6 SECTION PALETTE — 13-stop jewel tones (light)
|
|
516
539
|
═══════════════════════════════════════════════ */
|
|
@@ -1052,13 +1075,22 @@
|
|
|
1052
1075
|
|
|
1053
1076
|
/* Overlay scrim rungs — substrate-aware modal/dialog backdrop tints.
|
|
1054
1077
|
Three weights cover the deployed range: dialog-scroll (subtle),
|
|
1055
|
-
canonical modal (default), drawer/full-cover (strong).
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1078
|
+
canonical modal (default), drawer/full-cover (strong).
|
|
1079
|
+
|
|
1080
|
+
AY.W-PRIM-POLISH D3 — the scrim is its OWN identity token, NOT derived
|
|
1081
|
+
from `--shadow-color`. A scrim's role is to RECEDE: it must pin to INK in
|
|
1082
|
+
BOTH modes. The cartoon-shadow family rides `--shadow-color: var(--foreground)`
|
|
1083
|
+
(correct — a shadow re-tints under `.dark` by construction), but a scrim
|
|
1084
|
+
that does the same FLOODS the dark room with a cream fog (the old dark
|
|
1085
|
+
overlay painted `srgb(0.91… / 0.5)`, a near-white wash that BRIGHTENED the
|
|
1086
|
+
page at the modal moment). `--overlay-scrim-ink` is a fixed warm near-black
|
|
1087
|
+
(the light-mode `--foreground` value), re-resolved verbatim in `.dark` so
|
|
1088
|
+
the scrim recedes in both modes. Clean break, no alias (no-backwards-compat).
|
|
1089
|
+
The `--shadow-color` / `--shadow-cartoon-*` family is UNTOUCHED. */
|
|
1090
|
+
--overlay-scrim-ink: hsl(24 10% 10%);
|
|
1091
|
+
--overlay-scrim: color-mix(in srgb, var(--overlay-scrim-ink) 50%, transparent);
|
|
1092
|
+
--overlay-scrim-strong: color-mix(in srgb, var(--overlay-scrim-ink) 80%, transparent);
|
|
1093
|
+
--overlay-scrim-subtle: color-mix(in srgb, var(--overlay-scrim-ink) 40%, transparent);
|
|
1062
1094
|
|
|
1063
1095
|
/* ═══════════════════════════════════════════════
|
|
1064
1096
|
§9 ANIMATION OFFSETS
|
|
@@ -1485,8 +1517,15 @@
|
|
|
1485
1517
|
--opacity-icon-muted: 0.8;
|
|
1486
1518
|
|
|
1487
1519
|
--focus-ring-width: 2px;
|
|
1488
|
-
|
|
1489
|
-
|
|
1520
|
+
/* D6.b — the focus-ring color routes through a `--focus-ring-color`
|
|
1521
|
+
indirection (default `--ring`, so the resolved shadow is byte-identical to
|
|
1522
|
+
the prior hard `--ring` recipe). An opt-in channel (the `focus-ring-gold`
|
|
1523
|
+
utility, utilities.css) overrides ONLY this color to mint a gilded
|
|
1524
|
+
"you are here / this is live" ring — gold is the transient STATE voice;
|
|
1525
|
+
the resting active mark stays its structural color (the four-voice law). */
|
|
1526
|
+
--focus-ring-color: var(--ring);
|
|
1527
|
+
--focus-ring-shadow: 0 0 0 var(--focus-ring-width) color-mix(in srgb, var(--focus-ring-color) 30%, transparent),
|
|
1528
|
+
0 0 8px color-mix(in srgb, var(--focus-ring-color) 15%, transparent);
|
|
1490
1529
|
--focus-ring: var(--focus-ring-shadow);
|
|
1491
1530
|
|
|
1492
1531
|
/* ═══════════════════════════════════════════════
|
|
@@ -1508,10 +1547,40 @@
|
|
|
1508
1547
|
--gold: oklch(0.751 0.147 84.2);
|
|
1509
1548
|
--gold-light: oklch(0.890 0.183 96.1);
|
|
1510
1549
|
--gold-dark: oklch(0.599 0.132 64.2);
|
|
1550
|
+
/* AY.W-PRIM-POLISH D1 — the saturated CTA plate the AW.W13 gold-CTA contract
|
|
1551
|
+
names. A FIXED deep gold (mode-INVARIANT — the gold-CTA hover backplate must
|
|
1552
|
+
be dark in BOTH modes so the white label clears ≥4.5:1; deepening toward the
|
|
1553
|
+
mode-flipping `--foreground` brightened the dark plate to a cream-gold and
|
|
1554
|
+
broke dark). ~`--gold-dark` deepened toward warm-ink → ~rgb(120,87,45),
|
|
1555
|
+
6.5:1 white in light / 5.5:1 in dark. The opaque base of `btn-audacious-gold`
|
|
1556
|
+
:hover. */
|
|
1557
|
+
--gold-deep: oklch(0.487 0.103 63.0);
|
|
1558
|
+
|
|
1559
|
+
/* D6.b — the chrome-gold additions (the rim + the legible ink), completing
|
|
1560
|
+
the gold quad into the gilt FAMILY. Gold is a metal, not a hue — it must
|
|
1561
|
+
read as reflectance, so it lives at the EDGE and the HIGHLIGHT, rarely as
|
|
1562
|
+
an area.
|
|
1563
|
+
|
|
1564
|
+
--gold-rim — the gilt EDGE catch: `--gold` at 40% over the surface, the
|
|
1565
|
+
1px tooled bevel light the `.glass-gilt` modifier + the gilt dock button
|
|
1566
|
+
paint. Non-text → no contrast floor.
|
|
1567
|
+
|
|
1568
|
+
--gold-ink — legible gold-toned TEXT. Derived (NOT guessed) to clear the
|
|
1569
|
+
cream-law ② floor (APCA |Lc| ≥ 45) against `--card` in BOTH arms; the raw
|
|
1570
|
+
`--gold-dark` does not (it was minted as a plate hue). LIGHT arm:
|
|
1571
|
+
oklch(0.560 0.118 70) → |Lc| 69.9 on the cream `--card` (hsl 48 12% 98%).
|
|
1572
|
+
The dark-arm pair lifts L (the warm-dark stock) in the `.dark` block,
|
|
1573
|
+
reaching |Lc| 77.1 on the dark `--card`. Both verified by
|
|
1574
|
+
`proof:gold-ink-contrast`. */
|
|
1575
|
+
--gold-rim: color-mix(in oklab, var(--gold) 40%, transparent);
|
|
1576
|
+
--gold-ink: oklch(0.560 0.118 70);
|
|
1511
1577
|
|
|
1512
1578
|
--color-gold: var(--gold);
|
|
1513
1579
|
--color-gold-light: var(--gold-light);
|
|
1514
1580
|
--color-gold-dark: var(--gold-dark);
|
|
1581
|
+
--color-gold-deep: var(--gold-deep);
|
|
1582
|
+
--color-gold-rim: var(--gold-rim);
|
|
1583
|
+
--color-gold-ink: var(--gold-ink);
|
|
1515
1584
|
|
|
1516
1585
|
/* ═══════════════════════════════════════════════
|
|
1517
1586
|
§14 RAINBOW PALETTE — oklch (AV.W16 TW2; mode-independent, no .dark
|
|
@@ -1767,8 +1836,18 @@
|
|
|
1767
1836
|
flat ease. STRICTLY transform-scoped: it must never touch the surface-tier
|
|
1768
1837
|
`[data-held]` fades (background/border/box-shadow), which stay on
|
|
1769
1838
|
`--duration-fast var(--ease-standard)`. The duration pairs with
|
|
1770
|
-
`--duration-fast`; consumers retune the whole feel via this one token.
|
|
1771
|
-
|
|
1839
|
+
`--duration-fast`; consumers retune the whole feel via this one token.
|
|
1840
|
+
|
|
1841
|
+
AY.W-DOCK2 (D6) — the register is `--spring-smooth`, the §6 easing-doctrine
|
|
1842
|
+
transform-press register (tokens.css §2: transform hover/press/active →
|
|
1843
|
+
`--spring-smooth`/`--spring-snappy`, NEVER `--spring-bouncy`; a press must
|
|
1844
|
+
settle, never overshoot into a visible bounce). The prior `--spring-bouncy`
|
|
1845
|
+
ROOT default was off-doctrine, shadowed for the four named controls by a
|
|
1846
|
+
per-surface re-point in dock-controls.css — the exact per-surface fork the
|
|
1847
|
+
doctrine kills. The re-point is now a DEAD byte-identical redeclaration and is
|
|
1848
|
+
DELETED; the ROOT token IS the doctrine register, so any other consumer of
|
|
1849
|
+
`--dock-press-spring` inherits the correct smooth register. */
|
|
1850
|
+
--dock-press-spring: var(--duration-fast) var(--spring-smooth);
|
|
1772
1851
|
}
|
|
1773
1852
|
|
|
1774
1853
|
/* AX.W51 D18 — the GLOBAL coarse-pointer comfort amplification. The WHOLE library
|
|
@@ -2112,6 +2191,13 @@
|
|
|
2112
2191
|
--gold: oklch(0.784 0.143 86.0);
|
|
2113
2192
|
--gold-light: oklch(0.898 0.182 97.4);
|
|
2114
2193
|
--gold-dark: oklch(0.678 0.150 63.8);
|
|
2194
|
+
/* D6.b — the dark-arm gilt ink. `--gold-rim` auto-re-resolves (its color-mix
|
|
2195
|
+
reads the dark `--gold` above — no override). `--gold-ink` MUST lift L for
|
|
2196
|
+
the dark `--card` (hsl 24 8% 10%): a deep gold-dark ink would vanish into
|
|
2197
|
+
the near-black plate, so the dark ink is a BRIGHT gold —
|
|
2198
|
+
oklch(0.860 0.158 90) → |Lc| 77.1 on the dark `--card` (cream-law ②;
|
|
2199
|
+
verified by proof:gold-ink-contrast). */
|
|
2200
|
+
--gold-ink: oklch(0.860 0.158 90);
|
|
2115
2201
|
}
|
|
2116
2202
|
|
|
2117
2203
|
/* ═══════════════════════════════════════════════
|
|
@@ -184,10 +184,28 @@
|
|
|
184
184
|
* surface). The grammar is single-event entrance + dwell + exit;
|
|
185
185
|
* the next toast (if any) enters on its own contract.
|
|
186
186
|
*
|
|
187
|
+
* §6 EASING-DOCTRINE EXEMPTION (AY.W-MOTION — DELIBERATE KEEP).
|
|
188
|
+
* Every glass-ui-OWNED entrance surface (`dialog-scale`, `pop`,
|
|
189
|
+
* `dropdown`, `fade-slide`, `dock-in`) rides the house `--spring-*`
|
|
190
|
+
* enter / `--ease-out`/`--ease-standard` exit vocabulary (the §6
|
|
191
|
+
* doctrine, tokens.css:162-190). The Toast does NOT — and that is
|
|
192
|
+
* BY DESIGN, not an unexamined default. The reka-ui `ToastRoot`
|
|
193
|
+
* primitive OWNS its data-state choreography: the entrance slide
|
|
194
|
+
* direction tracks the viewport origin AND the swipe-end gesture
|
|
195
|
+
* (`data-[swipe=end]:slide-out-to-right-full`), so the entrance/exit
|
|
196
|
+
* are coupled to reka's `tw-animate-css` data-state machinery. The §6
|
|
197
|
+
* spring vocabulary governs glass-ui-OWNED surfaces; the reka-Toast
|
|
198
|
+
* entrance is not one — re-authoring it onto a `<Transition>` would
|
|
199
|
+
* fork the primitive's swipe-coupled contract (and `tw-animate-css`
|
|
200
|
+
* is the shipped optionalPeer this contract depends on). The gate
|
|
201
|
+
* (proof:animation-coherence) carries the Toast surface in its
|
|
202
|
+
* REGISTER_ASSIGNMENT_ALLOW set so this keep reads as a gated,
|
|
203
|
+
* deliberate exemption.
|
|
204
|
+
*
|
|
187
205
|
* PRM is honoured at the `@media (prefers-reduced-motion: reduce)`
|
|
188
206
|
* block below — the slide motion retires; the fade-in/out
|
|
189
|
-
* remains. No source change
|
|
190
|
-
* documentation closure for the
|
|
207
|
+
* remains. No source motion change; this comment block IS the
|
|
208
|
+
* documentation closure for the toast contract row.
|
|
191
209
|
*/
|
|
192
210
|
|
|
193
211
|
/* ── Reduced motion: preserve fades, remove transform/scale motion ── */
|
package/src/styles/utilities.css
CHANGED
|
@@ -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
|
-
/*
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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:
|
|
904
|
-
|
|
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
|
|
910
|
-
|
|
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:
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
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
|
|
934
|
-
color-mix(in srgb, var(--color-gold
|
|
935
|
-
color-mix(in srgb, var(--color-gold
|
|
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)
|
|
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.
|
|
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; }
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { GPUCanvasFrame, GPUCanvasSetupArgs } from "../../../../composables/glass/createGPUCanvas";
|
|
2
|
-
import type { CursorState } from "./cursorModel";
|
|
3
|
-
import type { AuroraConfig } from "../constants/presets";
|
|
4
|
-
export interface GPUAuroraDeps {
|
|
5
|
-
canvas: HTMLCanvasElement;
|
|
6
|
-
getConfig: () => AuroraConfig;
|
|
7
|
-
cursor: CursorState;
|
|
8
|
-
getReducedMotion: () => boolean;
|
|
9
|
-
/** The frozen frame-time offset under reduced motion (matches the WebGL2 path). */
|
|
10
|
-
frozenOffset: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* The `setup` callback for `createGPUCanvas`. Builds the pipeline once on the device,
|
|
14
|
-
* returns the frame hooks. The single render pass draws the WGSL aurora base field.
|
|
15
|
-
*/
|
|
16
|
-
export declare function createGPUAuroraSetup(deps: GPUAuroraDeps): ({ device, context, format }: GPUCanvasSetupArgs) => GPUCanvasFrame;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
declare const WGSL_MAX_NUCLEI = 6;
|
|
2
|
-
declare const WGSL_MAX_STOPS = 8;
|
|
3
|
-
export declare const AURORA_VERTEX_WGSL = "\nstruct VSOut {\n @builtin(position) pos: vec4f,\n @location(0) uv: vec2f,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {\n // Full-screen triangle (matches the WebGL2 [-1,-1, 3,-1, -1,3] quad).\n var p = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));\n var out: VSOut;\n let xy = p[vi];\n out.pos = vec4f(xy, 0.0, 1.0);\n out.uv = 0.5 * (xy + vec2f(1.0));\n return out;\n}";
|
|
4
|
-
export declare const AURORA_FRAGMENT_WGSL = "\nconst PI: f32 = 3.141592653589793;\nconst W_LUMA: vec3f = vec3f(0.2126, 0.7152, 0.0722);\nconst MAX_NUCLEI: u32 = 6u;\nconst MAX_STOPS: u32 = 8u;\n\n// The uniform struct \u2014 ONLY constant-indexed scalars (safe in the uniform address\n// space). The five count/enum fields are f32 (AX.W07 1a): the WebGPU write path packs\n// them as floats and the shader i32-casts at each use, so WGSL never reads a float\n// bit-pattern as a raw i32. The dynamically-indexed arrays moved OUT to struct Field\n// below (AX.W07 1b).\nstruct Uniforms {\n time: f32,\n stopCount: f32,\n nucleiCount: f32,\n softmaxBeta: f32,\n valueVariance: f32,\n warpAmount: f32,\n warpScale: f32,\n warpDrift: f32,\n warpMode: f32,\n noiseOctaves: f32,\n medium: f32,\n breathDepth: f32,\n breathPeriod: f32,\n saturation: f32,\n paperGrain: f32,\n alpha: f32,\n // AX.W11 \u2014 the huePath enum (f32-packed, i32()-cast in samplePalette) carries the\n // shared ramp's OKLab-rectangular-vs-OKLCh-hue-arc dispatch into the WebGPU twin so\n // a huePath:'increasing' rainbow config arcs identically to the WebGL2 oracle. The\n // CPU pad keeps the buffer vec4-aligned (WGPU_UNIFORM_FLOATS rounds to 20).\n huePath: f32,\n};\n\n// The dynamically-indexed arrays \u2014 bound var<storage, read> (AX.W07 1b). A runtime\n// palette/nuclei index into a var<uniform> array<vec4f> returns [0,0,0,0] on Metal\n// (MSL forbids dynamic indexing of constant); storage is always-legal. The vec4 stride\n// is std140-identical to the uniform layout, so the move is byte-exact.\nstruct Field {\n palette: array<vec4f, 8>, // .xyz = linear-sRGB stop\n nucleiPos: array<vec4f, 6>, // .xy pos, .z radius, .w paletteBias\n nucleiMod: array<vec4f, 6>, // .x valueBias, .y elong, .z angle, .w driftRadius\n};\n\n@group(0) @binding(0) var<uniform> U: Uniforms;\n@group(0) @binding(1) var<storage, read> F: Field;\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n return select(pow((c + 0.055) / 1.055, 2.4), c / 12.92, c <= 0.04045);\n}\nfn srgbToLinear(c: vec3f) -> vec3f {\n return vec3f(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\nfn linearToSrgbCh(c: f32) -> f32 {\n return select(1.055 * pow(c, 1.0 / 2.4) - 0.055, c * 12.92, c <= 0.0031308);\n}\nfn linearToSrgb(c: vec3f) -> vec3f {\n return vec3f(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\nconst FBM_ROT: mat2x2f = mat2x2f(0.8, 0.6, -0.6, 0.8);\n\nconst LINEAR_SRGB_TO_LMS: mat3x3f = mat3x3f(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\nconst LMS_TO_OKLAB: mat3x3f = mat3x3f(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\nconst OKLAB_TO_LMS: mat3x3f = mat3x3f(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\nconst LMS_TO_LINEAR_SRGB: mat3x3f = mat3x3f(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\nfn srgbToOklab(c: vec3f) -> vec3f {\n let lin = srgbToLinear(c);\n let lms = LINEAR_SRGB_TO_LMS * lin;\n let lmsCbrt = sign(lms) * pow(abs(lms), vec3f(1.0 / 3.0));\n return LMS_TO_OKLAB * lmsCbrt;\n}\nfn oklabToLinearSrgb(lab: vec3f) -> vec3f {\n let lms_ = OKLAB_TO_LMS * lab;\n let lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\nfn oklabToOklch(lab: vec3f) -> vec3f {\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 vec3f(lab.x, C, H);\n}\nfn oklchToOklab(lch: vec3f) -> vec3f {\n return vec3f(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\nfn interpolateHueTurns(h0: f32, h1: f32, t: f32, method: i32) -> f32 {\n let TAU = 2.0 * PI;\n var a = h0 / TAU;\n var b = h1 / TAU;\n let i = b - a;\n if (method == 0) { // shorter\n if (i > 0.5) { a = a + 1.0; } else if (i < -0.5) { b = b + 1.0; }\n } else if (method == 1) { // longer\n if (i > 0.0 && i < 0.5) { a = a + 1.0; } else if (i > -0.5 && i <= 0.0) { b = b + 1.0; }\n } else if (method == 2) { // increasing\n if (i < 0.0) { b = b + 1.0; }\n } else { // decreasing\n if (i > 0.0) { a = a + 1.0; }\n }\n let r = fract(a + t * (b - a));\n return r * TAU;\n}\n\nfn mixPaletteOklab(linA: vec3f, linB: vec3f, t: f32) -> vec3f {\n let labA = LMS_TO_OKLAB * (sign(LINEAR_SRGB_TO_LMS * linA) * pow(abs(LINEAR_SRGB_TO_LMS * linA), vec3f(1.0 / 3.0)));\n let labB = LMS_TO_OKLAB * (sign(LINEAR_SRGB_TO_LMS * linB) * pow(abs(LINEAR_SRGB_TO_LMS * linB), vec3f(1.0 / 3.0)));\n let lab = mix(labA, labB, vec3f(t));\n return oklabToLinearSrgb(lab);\n}\n\nfn mixPaletteOklchArc(linA: vec3f, linB: vec3f, t: f32, method: i32) -> vec3f {\n let labA = LMS_TO_OKLAB * (sign(LINEAR_SRGB_TO_LMS * linA) * pow(abs(LINEAR_SRGB_TO_LMS * linA), vec3f(1.0 / 3.0)));\n let labB = LMS_TO_OKLAB * (sign(LINEAR_SRGB_TO_LMS * linB) * pow(abs(LINEAR_SRGB_TO_LMS * linB), vec3f(1.0 / 3.0)));\n let lchA = oklabToOklch(labA);\n let lchB = oklabToOklch(labB);\n let L = mix(lchA.x, lchB.x, t);\n let C = mix(lchA.y, lchB.y, t);\n let H = interpolateHueTurns(lchA.z, lchB.z, t, method);\n return oklabToLinearSrgb(oklchToOklab(vec3f(L, C, H)));\n}\n\nfn samplePaletteRamp(a: vec3f, b: vec3f, tRaw: f32, huePath: i32) -> vec3f {\n let t = smoothstep(0.0, 1.0, tRaw);\n if (huePath == 2 || huePath == 3) {\n return mixPaletteOklchArc(a, b, t, huePath);\n }\n return mixPaletteOklab(a, b, t);\n}\n\n// AX.W12 \u2014 the painterly-medium organic noise basis (PCG2D integer-bit hash + 2D\n// simplex gradient noise), SPLICED from the shared procedural-color chunk \u2014 the EXACT\n// twin of the GLSL leaf aurora.frag.ts splices, so the hash can NEVER drift between\n// backends (proof:aurora-noise-hash-equivalence locks the twins to 1e-6). The WebGPU\n// single-pass fs_main below stays the smooth pole (it runs no medium body \u2014 the\n// painterly mediums are the W7c/W14 multi-pass), so the leaf is single-sourced HERE for\n// the twin-equivalence contract; the W14 painterly passes consume it.\n\nfn pcg2d(v0: vec2u) -> vec2u {\n var v = v0 * 1664525u + vec2u(1013904223u);\n v.x = v.x + v.y * 1664525u;\n v.y = v.y + v.x * 1664525u;\n v = v ^ (v >> vec2u(16u));\n v.x = v.x + v.y * 1664525u;\n v.y = v.y + v.x * 1664525u;\n v = v ^ (v >> vec2u(16u));\n return v;\n}\n\nfn pcgHash2(p: vec2f) -> f32 {\n let u = bitcast<vec2u>(p);\n return f32(pcg2d(u).x) * (1.0 / 4294967296.0);\n}\n\nfn pcgGrad2(cell: vec2i) -> vec2f {\n let h = pcg2d(bitcast<vec2u>(cell));\n let ang = f32(h.x) * (1.0 / 4294967296.0) * 6.28318530717958647692;\n return vec2f(cos(ang), sin(ang));\n}\n\nfn gnoise(p: vec2f) -> f32 {\n let F2 = 0.36602540378443864676;\n let G2 = 0.21132486540518711775;\n let s = (p.x + p.y) * F2;\n let i = floor(p + vec2f(s));\n let tt = (i.x + i.y) * G2;\n let x0 = p - (i - vec2f(tt));\n var i1 = vec2i(0, 1);\n if (x0.x > x0.y) { i1 = vec2i(1, 0); }\n let x1 = x0 - vec2f(i1) + vec2f(G2);\n let x2 = x0 - vec2f(1.0) + vec2f(2.0 * G2);\n let ii = vec2i(i);\n var n = 0.0;\n var t0 = 0.5 - dot(x0, x0);\n if (t0 > 0.0) { t0 = t0 * t0; n = n + t0 * t0 * dot(pcgGrad2(ii), x0); }\n var t1 = 0.5 - dot(x1, x1);\n if (t1 > 0.0) { t1 = t1 * t1; n = n + t1 * t1 * dot(pcgGrad2(ii + i1), x1); }\n var t2 = 0.5 - dot(x2, x2);\n if (t2 > 0.0) { t2 = t2 * t2; n = n + t2 * t2 * dot(pcgGrad2(ii + vec2i(1, 1)), x2); }\n return 70.0 * n;\n}\n\nfn hash21(p0: vec2f) -> f32 {\n var p = fract(p0 * vec2f(123.34, 456.21));\n p = p + dot(p, p + 45.32);\n return fract(p.x * p.y);\n}\nfn vnoise(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n let a = hash21(i);\n let b = hash21(i + vec2f(1.0, 0.0));\n let c = hash21(i + vec2f(0.0, 1.0));\n let d = hash21(i + vec2f(1.0, 1.0));\n return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);\n}\nfn fbm(p0: vec2f) -> f32 {\n var v = 0.0;\n var a = 0.5;\n var p = p0;\n let octaves = i32(U.noiseOctaves); // AX.W07 1a \u2014 i32()-cast the f32-packed count.\n for (var i = 0; i < 5; i = i + 1) {\n if (i >= octaves) { break; }\n v = v + a * vnoise(p);\n p = FBM_ROT * p * 2.02;\n a = a * 0.5;\n }\n return v;\n}\n\nfn samplePalette(id: f32) -> vec3f {\n // AX.W11 \u2014 splice the SHARED samplePaletteRamp (the smoothstep ease + the OKLab-\n // rectangular-vs-OKLCh-hue-arc huePath dispatch), the EXACT twin the GLSL oracle\n // splices. The body here only selects the bracketing stop pair + the raw inter-stop\n // t (the W07 storage-Field dynamic index), then hands them to the shared ramp.\n let n = i32(U.stopCount); // AX.W07 1a \u2014 i32()-cast the f32-packed count.\n if (n <= 1) { return F.palette[0].xyz; }\n let t = clamp(id, 0.0, 1.0) * f32(n - 1);\n let i0 = i32(floor(t));\n let i1 = min(i0 + 1, n - 1);\n let f = t - f32(i0);\n // AX.W07 1b \u2014 read the palette from the storage Field (dynamic i0/i1 index);\n // AX.W11 \u2014 i32()-cast the f32-packed huePath enum (parity with the count casts).\n return samplePaletteRamp(F.palette[i0].xyz, F.palette[i1].xyz, f, i32(U.huePath));\n}\n\nfn domainWarp(p: vec2f, t: f32) -> vec2f {\n let drift = t * U.warpDrift * 5.0;\n let q = vec2f(\n fbm(p * U.warpScale + vec2f(drift, 0.0)),\n fbm(p * U.warpScale + vec2f(5.2, 1.3 + drift))\n );\n let r = vec2f(\n fbm(p * U.warpScale + 4.0 * q + vec2f(1.7, 9.2)),\n fbm(p * U.warpScale + 4.0 * q + vec2f(8.3, 2.8))\n );\n return p + U.warpAmount * r;\n}\n\nfn nucleiField(p: vec2f, t: f32) -> vec2f {\n // Returns (paletteId, valueMod) \u2014 softmax over the nuclei (isotropic; the WebGPU\n // twin keeps the parity-floor isotropic Gaussian).\n var accumId = 0.0;\n var accumVal = 0.0;\n var w = 0.0;\n let n = i32(U.nucleiCount); // AX.W07 1a \u2014 i32()-cast the f32-packed count.\n for (var i = 0; i < 6; i = i + 1) {\n if (i >= n) { break; }\n // AX.W07 1b \u2014 read the nuclei from the storage Field (dynamic i index).\n let pos = F.nucleiPos[i].xy;\n let rad = max(F.nucleiPos[i].z, 0.01);\n let d2 = dot(p - pos, p - pos);\n let wi = exp((-U.softmaxBeta * d2) / (rad * rad));\n accumId = accumId + wi * F.nucleiPos[i].w;\n accumVal = accumVal + wi * F.nucleiMod[i].x;\n w = w + wi;\n }\n if (w < 1e-4) { return vec2f(0.5, 0.0); }\n return vec2f(accumId / w, accumVal / w);\n}\n\n// ACES (Narkowicz) \u2014 matches the GLSL tonemap.\nfn aces(x: vec3f) -> vec3f {\n let a = 2.51; let b = 0.03; let c = 2.43; let d = 0.59; let e = 0.14;\n return clamp((x * (a * x + b)) / (x * (c * x + d) + e), vec3f(0.0), vec3f(1.0));\n}\n\n@fragment\nfn fs_main(@location(0) uv: vec2f) -> @location(0) vec4f {\n let t = U.time;\n let pw = domainWarp(uv, t);\n let nf = nucleiField(pw, t);\n var col = samplePalette(nf.x);\n col = col * (1.0 + U.valueVariance * nf.y);\n\n // Breath.\n let breath = sin(t * 6.2831 / max(U.breathPeriod, 1.0));\n col = col * (1.0 + U.breathDepth * breath * 0.5);\n\n // (The WebGPU smooth pole; the painterly mediums run the W7c multi-pass passes.)\n col = aces(col);\n col = linearToSrgb(col); // the mandatory OETF (linear \u2192 display).\n return vec4f(col * U.alpha, U.alpha); // premultiply AFTER the OETF (parity).\n}";
|
|
5
|
-
/** The assembled WGSL module string (vertex + fragment) for createGPUCanvas. */
|
|
6
|
-
export declare const AURORA_WGSL: string;
|
|
7
|
-
export { WGSL_MAX_NUCLEI, WGSL_MAX_STOPS };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/** The per-frame hooks a consumer's WebGPU `setup` returns (mirrors WebGLCanvasFrame). */
|
|
2
|
-
export interface GPUCanvasFrame {
|
|
3
|
-
frame: (timeSec: number) => void;
|
|
4
|
-
shouldContinue: () => boolean;
|
|
5
|
-
resize: () => void;
|
|
6
|
-
time?: (elapsedSec: number) => number;
|
|
7
|
-
teardown?: () => void;
|
|
8
|
-
}
|
|
9
|
-
export interface GPUCanvasSetupArgs {
|
|
10
|
-
device: GPUDevice;
|
|
11
|
-
context: GPUCanvasContext;
|
|
12
|
-
/** The swapchain format (`navigator.gpu.getPreferredCanvasFormat()`). */
|
|
13
|
-
format: GPUTextureFormat;
|
|
14
|
-
}
|
|
15
|
-
export interface GPUCanvasOptions {
|
|
16
|
-
/** The pre-acquired `GPUDevice` (from `resolveRenderModeAsync`'s adapter→device). */
|
|
17
|
-
device: GPUDevice;
|
|
18
|
-
/** Alpha mode for the swapchain (premultiplied to match the WebGL2 premultiply). */
|
|
19
|
-
alphaMode?: GPUCanvasAlphaMode;
|
|
20
|
-
mode?: "live" | "capture";
|
|
21
|
-
respectReducedMotion?: boolean;
|
|
22
|
-
/** Build the pipeline + bind group on the configured context. Returns frame hooks. */
|
|
23
|
-
setup: (args: GPUCanvasSetupArgs) => GPUCanvasFrame;
|
|
24
|
-
}
|
|
25
|
-
export interface GPUCanvasHandle {
|
|
26
|
-
arm: () => void;
|
|
27
|
-
suspend: (reason?: "tab-hidden" | "off-screen" | "manual") => void;
|
|
28
|
-
resume: (reason?: "tab-hidden" | "off-screen" | "manual") => void;
|
|
29
|
-
wake: () => void;
|
|
30
|
-
renderAt: (timeSec: number) => void;
|
|
31
|
-
dispose: () => void;
|
|
32
|
-
readonly device: GPUDevice | null;
|
|
33
|
-
readonly reducedMotion: boolean;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Build a WebGPU canvas over the shared lifecycle core. The `GPUDevice` is acquired
|
|
37
|
-
* by `resolveRenderModeAsync` (the probe) and passed in — `createGPUCanvas` configures
|
|
38
|
-
* the canvas context + threads the consumer `setup` through the agnostic schedule.
|
|
39
|
-
*/
|
|
40
|
-
export declare function createGPUCanvas(canvas: HTMLCanvasElement, options: GPUCanvasOptions): GPUCanvasHandle;
|
package/dist/vReveal-CqaCz_mC.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
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/useViewTransition.ts
|
|
16
|
-
function r() {
|
|
17
|
-
return typeof document < "u" && typeof document.startViewTransition == "function";
|
|
18
|
-
}
|
|
19
|
-
function i(e, t) {
|
|
20
|
-
let n = typeof document > "u" ? void 0 : document;
|
|
21
|
-
if (!n || typeof n.startViewTransition != "function") return e(), {
|
|
22
|
-
finished: Promise.resolve(),
|
|
23
|
-
transitioned: !1
|
|
24
|
-
};
|
|
25
|
-
let r = t?.types && t.types.length > 0 ? n.startViewTransition({
|
|
26
|
-
update: () => e(),
|
|
27
|
-
types: t.types
|
|
28
|
-
}) : n.startViewTransition(() => e());
|
|
29
|
-
return r.ready?.catch(() => {}), {
|
|
30
|
-
finished: r.finished.then(() => void 0, () => void 0),
|
|
31
|
-
transitioned: !0
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/composables/motion/vReveal.ts
|
|
36
|
-
function a(e, t) {
|
|
37
|
-
e.setAttribute("data-reveal", t.arg === "fade" ? "fade" : ""), e.style.setProperty("--d", String(t.value ?? 0));
|
|
38
|
-
}
|
|
39
|
-
var o = {
|
|
40
|
-
mounted: a,
|
|
41
|
-
updated: a
|
|
42
|
-
};
|
|
43
|
-
//#endregion
|
|
44
|
-
export { e as a, n as i, i as n, t as o, r, o as t };
|
|
File without changes
|