@mkbabb/glass-ui 3.5.0 → 3.6.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/{DataTable-DyKc_26a.js → DataTable-BGVXx0Ww.js} +1 -1
- package/dist/{NumberFieldContent-jO-zGOHf.js → NumberFieldContent-Bhhmk95p.js} +1 -1
- package/dist/animated-digit.js +1 -1
- package/dist/api/index.d.ts +2 -1
- package/dist/api.js +1 -1
- package/dist/aurora.js +259 -81
- package/dist/{button-i8Ek5vvg.js → button-BcMzVrqs.js} +2 -2
- package/dist/button.js +1 -1
- package/dist/carousel.js +1 -1
- package/dist/color.js +1 -1
- package/dist/components/custom/aurora/composables/color.d.ts +35 -2
- package/dist/components/custom/aurora/composables/glSetup.d.ts +1 -1
- package/dist/components/custom/aurora/composables/uniformBridge.d.ts +6 -0
- package/dist/components/custom/aurora/constants/presets.d.ts +9 -0
- package/dist/components/custom/aurora/constants/shaders/composition.glsl.d.ts +1 -1
- package/dist/components/custom/aurora/index.d.ts +3 -2
- package/dist/components/custom/constellation/Constellation.vue.d.ts +45 -0
- package/dist/components/custom/constellation/constellationField.d.ts +85 -0
- package/dist/components/custom/constellation/index.d.ts +3 -0
- package/dist/components/custom/dock/GlassDock.vue.d.ts +34 -3
- package/dist/composables/glass/canvas2d/index.d.ts +2 -0
- package/dist/composables/glass/canvas2d/useCanvas2D.d.ts +48 -0
- package/dist/composables/glass/index.d.ts +2 -0
- package/dist/composables/motion/core/index.d.ts +1 -0
- package/dist/composables/motion/index.d.ts +1 -0
- package/dist/composables/motion/useAnimatedNumberMap.d.ts +29 -0
- package/dist/composables/motion/useStagger.d.ts +50 -0
- package/dist/confirm-dialog.js +1 -1
- package/dist/constellation.d.ts +1 -0
- package/dist/constellation.js +182 -0
- package/dist/controls.js +1 -1
- package/dist/dark.js +1 -1
- package/dist/data-table.js +1 -1
- package/dist/dock.js +121 -102
- package/dist/expandable-container.js +1 -1
- package/dist/forms.js +1 -1
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +79 -78
- package/dist/goo-blob.js +3 -3
- package/dist/icon-tooltip.js +1 -1
- package/dist/keyboard.js +1 -1
- package/dist/labeled-field.js +2 -2
- package/dist/motion-core.js +90 -49
- package/dist/motion.js +31 -21
- package/dist/number-field.js +1 -1
- package/dist/responsive-tabs.js +1 -1
- package/dist/search.js +1 -1
- package/dist/sortable-list.js +1 -1
- package/dist/styles/dock.css +185 -1
- package/dist/styles/glass-refract.css +60 -0
- package/dist/styles/glass-specular-track.css +43 -130
- package/dist/styles/glass.css +243 -27
- package/dist/styles/index.css +1 -0
- package/dist/styles/theme.css +6 -0
- package/dist/styles/tokens.css +33 -0
- package/dist/tabs.js +2 -2
- package/dist/{useAnimatedNumber-BF6r64lA.js → useAnimatedNumber-DfVgP4te.js} +1 -1
- package/dist/useCanvas2D-BeNJqqIS.js +95 -0
- package/dist/watercolor-dot.js +1 -1
- package/package.json +21 -1
- package/src/styles/dock.css +185 -1
- package/src/styles/glass-refract.css +60 -0
- package/src/styles/glass-specular-track.css +43 -130
- package/src/styles/glass.css +243 -27
- package/src/styles/index.css +1 -0
- package/src/styles/theme.css +6 -0
- package/src/styles/tokens.css +33 -0
- /package/dist/{IconTooltip-BTyYn4mr.js → IconTooltip-DZlCkU-0.js} +0 -0
- /package/dist/{Input-CU9CNKmo.js → Input-CRJ2owjN.js} +0 -0
- /package/dist/{UnderlineTabs-Cq_AD03t.js → UnderlineTabs-CuIK16JI.js} +0 -0
- /package/dist/{color-rkK4RMx2.js → color-DS-iLRVM.js} +0 -0
- /package/dist/{compile-DVgAxagk.js → compile-C62K_FpC.js} +0 -0
- /package/dist/{constants-DsCdlK9I.js → constants-C8NMonuo.js} +0 -0
- /package/dist/{presets-1OhFpaIC.js → presets-Dyv9Zl7W.js} +0 -0
- /package/dist/{prng-Bz_1Tydc.js → prng-CjVgzjQT.js} +0 -0
- /package/dist/{useGlobalDark-CWiaCoEw.js → useGlobalDark-D7R9OypB.js} +0 -0
- /package/dist/{useIntersectionPause-DAdVPVp4.js → useIntersectionPause-DsQYGc8V.js} +0 -0
- /package/dist/{useKeyboardShortcuts-BQfnAHHW.js → useKeyboardShortcuts-i8tHd5WO.js} +0 -0
- /package/dist/{useSortable-DnyGXKKY.js → useSortable-muI29agz.js} +0 -0
- /package/dist/{useViewTransition-CJnqg6wl.js → useViewTransition-DI0Rs2rV.js} +0 -0
package/dist/styles/tokens.css
CHANGED
|
@@ -700,6 +700,32 @@
|
|
|
700
700
|
--glass-edge-light: inset 0 0 0 0.75px hsl(0 0% 100% / 0.18);
|
|
701
701
|
--glass-edge-light-dark: inset 0 0 0 0.75px hsl(0 0% 100% / 0.10);
|
|
702
702
|
|
|
703
|
+
/* AW.W23 — content-aware adaptive tint (the Baseline-2025 "tint informed by
|
|
704
|
+
surrounding content" axis, WWDC25 sess. 219). A surface can tint toward a
|
|
705
|
+
consumer-provided dominant backdrop color via a `color-mix(in oklab, …)`
|
|
706
|
+
recipe (oklab is the mwg-preferred space for tint generation; NEVER a
|
|
707
|
+
lightness-shift in `oklch(from …)` — browsers don't gamut-map yet).
|
|
708
|
+
|
|
709
|
+
DEFAULT is zero delta: `--glass-tint-source` is the warm-white card itself
|
|
710
|
+
and `--glass-tint-strength` is 0%, so the rung background mixes 0% toward
|
|
711
|
+
the source = byte-identical to today. A consumer sets `--glass-tint-source`
|
|
712
|
+
to a sampled aurora hue + a strength ≤30% to bias the surface. Alpha-safe:
|
|
713
|
+
the mix is bounded ≤30% and never re-points the card's own alpha. */
|
|
714
|
+
--glass-tint-source: var(--card);
|
|
715
|
+
--glass-tint-strength: 0%;
|
|
716
|
+
|
|
717
|
+
/* AW.W23 — chromatic edge dispersion (the "polished glass" rim fringe Apple
|
|
718
|
+
shows). A warm fringe on one edge + a cool fringe on the other, low-alpha,
|
|
719
|
+
biased warm-cream/NCSU-red (NOT iOS-blue). Composed OVER the W22 uniform
|
|
720
|
+
rim under `prefers-reduced-transparency: no-preference`; dropped under
|
|
721
|
+
`reduce` (it is a transparency garnish). The two directional inset rings
|
|
722
|
+
read as light refracting through the glass edge. */
|
|
723
|
+
--glass-fringe-warm: oklch(0.92 0.06 40 / 0.22);
|
|
724
|
+
--glass-fringe-cool: oklch(0.90 0.05 230 / 0.16);
|
|
725
|
+
--glass-edge-dispersion:
|
|
726
|
+
inset 0.75px 0 0 0 var(--glass-fringe-warm),
|
|
727
|
+
inset -0.75px 0 0 0 var(--glass-fringe-cool);
|
|
728
|
+
|
|
703
729
|
/* Chassis curvature illusion — a subtle radial gradient at the chassis
|
|
704
730
|
top centre that lifts the surface without committing to literal 3D.
|
|
705
731
|
Composed into <InstrumentChassis>'s background stack. */
|
|
@@ -1586,6 +1612,13 @@
|
|
|
1586
1612
|
`.dark` (mirroring the `--glass-specular` remap above). The lit token
|
|
1587
1613
|
resolves to the `-dark` alpha on the deeper canvas. */
|
|
1588
1614
|
--glass-edge-light: var(--glass-edge-light-dark);
|
|
1615
|
+
|
|
1616
|
+
/* AW.W23 — the chromatic-fringe + adaptive-tint dark arm. The fringe drops
|
|
1617
|
+
to a lower-luminance warm/cool pair on the deep canvas; `--glass-tint-
|
|
1618
|
+
source` auto-flips with `--card` (no override needed — the default already
|
|
1619
|
+
resolves the dark card). */
|
|
1620
|
+
--glass-fringe-warm: oklch(0.78 0.07 40 / 0.18);
|
|
1621
|
+
--glass-fringe-cool: oklch(0.74 0.06 230 / 0.14);
|
|
1589
1622
|
--glass-curvature-overlay: radial-gradient(
|
|
1590
1623
|
ellipse at 50% -20%,
|
|
1591
1624
|
hsl(0 0% 100% / 0.06),
|
package/dist/tabs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as e } from "./cn-DJXf4yaB.js";
|
|
2
2
|
import { t } from "./_plugin-vue_export-helper-C1je1s0u.js";
|
|
3
3
|
import { i as n, n as r, r as i, t as a } from "./TooltipProvider-D-JrSqDu.js";
|
|
4
|
-
import { t as o } from "./UnderlineTabs-
|
|
4
|
+
import { t as o } from "./UnderlineTabs-CuIK16JI.js";
|
|
5
5
|
import { Fragment as s, computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createTextVNode as p, createVNode as m, defineComponent as h, mergeModels as g, nextTick as _, normalizeClass as v, normalizeStyle as y, onMounted as b, onUnmounted as x, openBlock as S, ref as C, renderList as w, renderSlot as T, toDisplayString as E, unref as D, useModel as O, watch as k, withCtx as A } from "vue";
|
|
6
6
|
//#region src/components/custom/tabs/composables/useBouncySlider.ts
|
|
7
7
|
function j(e) {
|
|
@@ -208,7 +208,7 @@ var M = [
|
|
|
208
208
|
}, () => [p(E(e.label), 1)], !0)], 10, N))], 64))), 128))
|
|
209
209
|
], 2));
|
|
210
210
|
}
|
|
211
|
-
}), [["__scopeId", "data-v-
|
|
211
|
+
}), [["__scopeId", "data-v-45c0ed13"]]), F = /* @__PURE__ */ h({
|
|
212
212
|
__name: "BouncyTabs",
|
|
213
213
|
props: /* @__PURE__ */ g({
|
|
214
214
|
options: {},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, t } from "./constants-
|
|
1
|
+
import { n as e, t } from "./constants-C8NMonuo.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
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { getCurrentScope as e, onScopeDispose as t, toValue as n } from "vue";
|
|
2
|
+
//#region src/composables/glass/canvas2d/useCanvas2D.ts
|
|
3
|
+
var r = "200px";
|
|
4
|
+
function i(i) {
|
|
5
|
+
let { setup: a, autoStart: o = !0, contextAttrs: s, rootMargin: c = r } = i, l = i.respectReducedMotion ?? !0, u = () => n(i.canvas), d = /* @__PURE__ */ new Set(), f = () => d.size === 0, p = 0, m = null, h = null, g = !1, _ = !1, v = typeof window < "u", y = typeof document < "u", b = l && v && window.matchMedia ? window.matchMedia("(prefers-reduced-motion: reduce)") : null, x = b?.matches ?? !1;
|
|
6
|
+
function S() {
|
|
7
|
+
if (!f() || !h || !m) {
|
|
8
|
+
p = 0;
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
h.render(m, v ? performance.now() : 0), p = x ? 0 : requestAnimationFrame(S);
|
|
12
|
+
}
|
|
13
|
+
function C() {
|
|
14
|
+
g && f() && !p && h && m && (p = requestAnimationFrame(S));
|
|
15
|
+
}
|
|
16
|
+
function w() {
|
|
17
|
+
g && h && m && h.render(m, v ? performance.now() : 0);
|
|
18
|
+
}
|
|
19
|
+
function T() {
|
|
20
|
+
let e = b?.matches ?? !1;
|
|
21
|
+
e !== x && (x = e, C());
|
|
22
|
+
}
|
|
23
|
+
b?.addEventListener("change", T);
|
|
24
|
+
function E(e = "manual") {
|
|
25
|
+
let t = f();
|
|
26
|
+
d.add(e), t && !f() && (cancelAnimationFrame(p), p = 0);
|
|
27
|
+
}
|
|
28
|
+
function D(e = "manual") {
|
|
29
|
+
let t = !f();
|
|
30
|
+
d.delete(e), t && f() && g && h && (x ? w() : C());
|
|
31
|
+
}
|
|
32
|
+
function O() {
|
|
33
|
+
document.hidden ? E("tab-hidden") : D("tab-hidden");
|
|
34
|
+
}
|
|
35
|
+
y && document.addEventListener("visibilitychange", O), y && document.hidden && d.add("tab-hidden");
|
|
36
|
+
let k = null;
|
|
37
|
+
function A(e) {
|
|
38
|
+
e.skipped ? E("off-screen") : D("off-screen");
|
|
39
|
+
}
|
|
40
|
+
function j(e) {
|
|
41
|
+
if (k) return;
|
|
42
|
+
let t = e.parentElement;
|
|
43
|
+
t && (k = t, t.addEventListener("contentvisibilityautostatechange", A));
|
|
44
|
+
}
|
|
45
|
+
function M() {
|
|
46
|
+
k?.removeEventListener("contentvisibilityautostatechange", A), k = null;
|
|
47
|
+
}
|
|
48
|
+
let N = null;
|
|
49
|
+
function P(e) {
|
|
50
|
+
N || typeof IntersectionObserver > "u" || (N = new IntersectionObserver((e) => {
|
|
51
|
+
for (let t of e) t.isIntersecting || t.intersectionRatio > 0 ? D("off-screen") : E("off-screen");
|
|
52
|
+
}, { rootMargin: c }), N.observe(e));
|
|
53
|
+
}
|
|
54
|
+
let F = null, I = !1;
|
|
55
|
+
function L(e) {
|
|
56
|
+
if (!m) return;
|
|
57
|
+
let t = e.clientWidth || e.offsetWidth || 0, n = e.clientHeight || e.offsetHeight || 0;
|
|
58
|
+
if (!t || !n) return;
|
|
59
|
+
let r = Math.min(v && window.devicePixelRatio || 1, 2);
|
|
60
|
+
e.width = Math.round(t * r), e.height = Math.round(n * r), m.setTransform(r, 0, 0, r, 0, 0), !I && !p && w();
|
|
61
|
+
}
|
|
62
|
+
function R(e) {
|
|
63
|
+
F || typeof ResizeObserver > "u" || (F = new ResizeObserver(() => {
|
|
64
|
+
let e = u();
|
|
65
|
+
e && L(e);
|
|
66
|
+
}), F.observe(e));
|
|
67
|
+
}
|
|
68
|
+
function z() {
|
|
69
|
+
if (g || _) return;
|
|
70
|
+
let e = u();
|
|
71
|
+
if (!e) return;
|
|
72
|
+
let t = e.getContext("2d", s);
|
|
73
|
+
if (!t) throw Error("[useCanvas2D] 2D context unavailable");
|
|
74
|
+
m = t, h = a(m), g = !0, R(e), j(e), P(e), I = !0, L(e), I = !1, x ? w() : f() && (p = requestAnimationFrame(S));
|
|
75
|
+
}
|
|
76
|
+
function B() {
|
|
77
|
+
_ || (_ = !0, cancelAnimationFrame(p), p = 0, y && document.removeEventListener("visibilitychange", O), b?.removeEventListener("change", T), M(), N?.disconnect(), N = null, F?.disconnect(), F = null, h?.teardown?.(), h = null, m = null, d.clear());
|
|
78
|
+
}
|
|
79
|
+
return o && z(), e() && t(B), {
|
|
80
|
+
arm: z,
|
|
81
|
+
suspend: E,
|
|
82
|
+
resume: D,
|
|
83
|
+
wake: C,
|
|
84
|
+
dispose: B,
|
|
85
|
+
isRunning: f,
|
|
86
|
+
get ctx() {
|
|
87
|
+
return m;
|
|
88
|
+
},
|
|
89
|
+
get reducedMotion() {
|
|
90
|
+
return x;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { i as t };
|
package/dist/watercolor-dot.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./_plugin-vue_export-helper-C1je1s0u.js";
|
|
2
|
-
import { n as t, t as n } from "./prng-
|
|
2
|
+
import { n as t, t as n } from "./prng-CjVgzjQT.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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mkbabb/glass-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Glassmorphic design system — Vue 3.5 components, reka-ui primitives, Tailwind CSS v4 tokens",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -118,6 +118,9 @@
|
|
|
118
118
|
"header-ribbon": [
|
|
119
119
|
"dist/header-ribbon.d.ts"
|
|
120
120
|
],
|
|
121
|
+
"constellation": [
|
|
122
|
+
"dist/constellation.d.ts"
|
|
123
|
+
],
|
|
121
124
|
"scrolling-text": [
|
|
122
125
|
"dist/scrolling-text.d.ts"
|
|
123
126
|
],
|
|
@@ -306,6 +309,10 @@
|
|
|
306
309
|
"types": "./dist/header-ribbon.d.ts",
|
|
307
310
|
"import": "./dist/header-ribbon.js"
|
|
308
311
|
},
|
|
312
|
+
"./constellation": {
|
|
313
|
+
"types": "./dist/constellation.d.ts",
|
|
314
|
+
"import": "./dist/constellation.js"
|
|
315
|
+
},
|
|
309
316
|
"./metric-badge": {
|
|
310
317
|
"types": "./dist/metric-badge.d.ts",
|
|
311
318
|
"import": "./dist/metric-badge.js"
|
|
@@ -551,6 +558,7 @@
|
|
|
551
558
|
"proof:vt-names": "node scripts/proof-vt-names.mjs",
|
|
552
559
|
"proof:dock-animation-live": "node scripts/proof-dock-animation-live.mjs",
|
|
553
560
|
"proof:dock-clip-reveal": "node scripts/proof-dock-clip-reveal.mjs",
|
|
561
|
+
"proof:dock-layering-polish": "node scripts/proof-dock-layering-polish.mjs",
|
|
554
562
|
"proof:dock-motion-parity": "node scripts/proof-dock-motion-parity.mjs",
|
|
555
563
|
"proof:dock-motion-single-source": "node scripts/proof-dock-motion-single-source.mjs",
|
|
556
564
|
"proof:dock-opacity-lockstep": "node scripts/proof-dock-opacity-lockstep.mjs",
|
|
@@ -585,6 +593,8 @@
|
|
|
585
593
|
"proof:no-value-default": "node scripts/proof-no-value-default.mjs",
|
|
586
594
|
"proof:blob-space-gamma": "node scripts/proof-blob-space-gamma.mjs",
|
|
587
595
|
"proof:aurora-space-gamma": "node scripts/proof-aurora-space-gamma.mjs",
|
|
596
|
+
"proof:aurora-oklch-interp": "node scripts/proof-aurora-oklch-interp.mjs",
|
|
597
|
+
"proof:aurora-derive-gamut": "vitest run tests/components/custom/aurora/derive-color.test.ts",
|
|
588
598
|
"proof:shader-shared-source": "node scripts/proof-shader-shared-source.mjs",
|
|
589
599
|
"proof:blob-color-equivalence": "vitest run tests/components/custom/goo-blob/blob-color-equivalence.test.ts",
|
|
590
600
|
"proof:fail-explicit": "node scripts/proof-fail-explicit.mjs",
|
|
@@ -597,9 +607,19 @@
|
|
|
597
607
|
"proof:no-test-in-src": "node scripts/proof-no-test-in-src.mjs",
|
|
598
608
|
"proof:spring-tokens-synced": "node scripts/proof-spring-tokens-synced.mjs",
|
|
599
609
|
"proof:offscreen-pause": "node scripts/proof-offscreen-pause.mjs",
|
|
610
|
+
"proof:constellation-substrate-single": "node scripts/proof-constellation-substrate-single.mjs",
|
|
611
|
+
"proof:canvas2d-substrate": "vitest run tests/composables/glass/canvas2d/useCanvas2D.test.ts",
|
|
612
|
+
"proof:constellation-field": "vitest run tests/components/custom/constellation/constellationField.test.ts",
|
|
613
|
+
"proof:input-invalid-aria": "node scripts/proof-input-invalid-aria.mjs",
|
|
614
|
+
"proof:styling-hygiene": "node scripts/proof-styling-hygiene.mjs",
|
|
600
615
|
"proof:subpath-enumeration": "node scripts/proof-subpath-enumeration.mjs",
|
|
601
616
|
"proof:no-orphan-composable": "node scripts/proof-no-orphan-composable.mjs",
|
|
602
617
|
"proof:speedtest-boundary": "node scripts/proof-speedtest-boundary.mjs",
|
|
618
|
+
"proof:glass-material-unified": "node scripts/proof-glass-material-unified.mjs",
|
|
619
|
+
"proof:glass-material-sota": "node scripts/proof-glass-material-sota.mjs",
|
|
620
|
+
"proof:glass-card-tiers": "node scripts/proof-glass-card-tiers.mjs",
|
|
621
|
+
"proof:primitive-affordance": "node scripts/proof-primitive-affordance.mjs",
|
|
622
|
+
"proof:reka-binding-idiom": "node scripts/proof-reka-binding-idiom.mjs",
|
|
603
623
|
"proof:all": "node scripts/gates.mjs --run local",
|
|
604
624
|
"gates:verify-ci": "node scripts/gates.mjs --verify-ci",
|
|
605
625
|
"profile:bundle": "node scripts/profile-bundle.mjs",
|
package/src/styles/dock.css
CHANGED
|
@@ -60,6 +60,19 @@
|
|
|
60
60
|
--dock-wrap-max-width: calc(100vw - var(--dock-viewport-inline-gutter, 1rem));
|
|
61
61
|
--dock-separator-height: calc(var(--dock-h, var(--size-icon-btn)) * 0.5);
|
|
62
62
|
--dock-collapsed-hover-scale: var(--scale-hover-dock);
|
|
63
|
+
/* AW.W3 — the spring-keyed child stagger knobs. `--dock-stagger-window-size`
|
|
64
|
+
is the fraction of the morph each child reveals over; `--dock-stagger-rise`
|
|
65
|
+
is the px the child rises from as it fades in. Consumers retune the
|
|
66
|
+
cascade feel per instance. */
|
|
67
|
+
--dock-stagger-window-size: 0.55;
|
|
68
|
+
--dock-stagger-rise: 4px;
|
|
69
|
+
/* AW.W3b — big-dock tokens. `--dock-card-radius` is the finite card-shell
|
|
70
|
+
radius (default --radius-dock-card = --radius-3xl, density-scaled
|
|
71
|
+
below); `--dock-tile-min` is the grid tile minimum (auto-fill track
|
|
72
|
+
floor). Both are density-scaled (compact tighter, spacious looser) — the
|
|
73
|
+
card radius + tile size ride the density cascade, never magic numbers. */
|
|
74
|
+
--dock-card-radius: var(--radius-dock-card);
|
|
75
|
+
--dock-tile-min: 4.5rem;
|
|
63
76
|
/* Individual-transform identity base (AQ.W3 §W3.2). `scale: 1` at rest
|
|
64
77
|
mints the stacking context once so a portaled popover over `--z-dock`
|
|
65
78
|
stays above the dock during a hover scale (the load-bearing
|
|
@@ -300,12 +313,28 @@
|
|
|
300
313
|
only. Width is driven by the inner `.dock-layers` FLIP via
|
|
301
314
|
`useLayerTransition`; pinning it here would race the FLIP and
|
|
302
315
|
reintroduce the `width: auto` non-interpolation diagnosed in
|
|
303
|
-
R1+R6.
|
|
316
|
+
R1+R6.
|
|
317
|
+
|
|
318
|
+
AW.W3 — the collapsed-hover `scale` (the `.collapsed:hover` rule below) +
|
|
319
|
+
the press squish (`--scale-press-dock` on the dock controls) ride the
|
|
320
|
+
INDIVIDUAL `scale` property, NOT `transform`. Adding `scale
|
|
321
|
+
var(--dock-motion-resize)` here unifies the hover scale onto the SAME dock
|
|
322
|
+
spring vocabulary as the morph, so a collapsed→hover→expand gesture reads as
|
|
323
|
+
ONE continuous spring rather than a `scale`-ease handed off to the
|
|
324
|
+
width-spring. Under PRM the global gate strips `scale` from the
|
|
325
|
+
transition-property → the hover scale snaps (0 morph frames). */
|
|
304
326
|
.glass-dock:not(.vertical) {
|
|
305
327
|
transition:
|
|
306
328
|
padding var(--dock-motion-resize),
|
|
307
329
|
box-shadow var(--dock-motion-standard),
|
|
308
330
|
transform var(--dock-motion-resize),
|
|
331
|
+
scale var(--dock-motion-resize),
|
|
332
|
+
/* AW.W3b — the pill↔card corner radius morphs on the SAME spring the
|
|
333
|
+
aperture rides (ONE free interpolation). Without this the
|
|
334
|
+
shape-card collapsed↔expanded radius snaps discretely. The list is
|
|
335
|
+
shared by ALL horizontal docks — the radius transition also glides
|
|
336
|
+
the wrap collapsed↔expanded radius swap (desirable). */
|
|
337
|
+
border-radius var(--dock-motion-resize),
|
|
309
338
|
background var(--dock-motion-standard),
|
|
310
339
|
border-color var(--dock-motion-standard);
|
|
311
340
|
}
|
|
@@ -339,6 +368,7 @@
|
|
|
339
368
|
padding var(--dock-motion-resize),
|
|
340
369
|
box-shadow var(--dock-motion-standard),
|
|
341
370
|
transform var(--dock-motion-resize),
|
|
371
|
+
scale var(--dock-motion-resize),
|
|
342
372
|
background var(--dock-motion-standard),
|
|
343
373
|
border-color var(--dock-motion-standard);
|
|
344
374
|
}
|
|
@@ -357,6 +387,38 @@
|
|
|
357
387
|
border-radius: var(--radius-xl);
|
|
358
388
|
}
|
|
359
389
|
|
|
390
|
+
/* AW.W3b — horizontal-root shape rules. The `shape-*` class previously bound
|
|
391
|
+
ONLY under `.variant-rail`; on a horizontal `variant-dock` the prop silently
|
|
392
|
+
no-op'd (the root hardwired `--radius-dock` = `--radius-pill`). These rules
|
|
393
|
+
close that documented-but-dead prop — `shape="rounded"` / `shape="card"` now
|
|
394
|
+
paint on a horizontal dock. Scoped to `variant-dock:not(.vertical)` so the
|
|
395
|
+
rail + instrument-strip variants (which own their own radius) are untouched. */
|
|
396
|
+
.glass-dock.variant-dock:not(.vertical).shape-rounded {
|
|
397
|
+
border-radius: var(--radius-xl);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* The big-dock CARD shell — a FINITE concentric radius above 2xl, below pill.
|
|
401
|
+
It does NOT collapse to a stadium. Collapsed it returns to a pill (the morph
|
|
402
|
+
target); the pill↔card swap glides on the `--dock-motion-resize` spring
|
|
403
|
+
(`border-radius` is in the `:not(.vertical)` transition list). */
|
|
404
|
+
.glass-dock.variant-dock:not(.vertical).shape-card {
|
|
405
|
+
border-radius: var(--dock-card-radius);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.glass-dock.variant-dock:not(.vertical).shape-card.collapsed {
|
|
409
|
+
border-radius: var(--radius-pill);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* The squircle reads markedly better at the large card radius — an
|
|
413
|
+
`@supports`-gated ENHANCEMENT only (Chrome 139+, no FF/Safari 2026). The
|
|
414
|
+
border-radius arc is the CONTRACT; the squircle is the better tier (the
|
|
415
|
+
baseline arc is the acceptable contract, NOT a degraded fallback). */
|
|
416
|
+
@supports (corner-shape: squircle) {
|
|
417
|
+
.glass-dock.variant-dock:not(.vertical).shape-card {
|
|
418
|
+
corner-shape: squircle;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
360
422
|
/* AJ-W1-δ — `instrument-strip` variant (per G-AJ-D7 Path 1).
|
|
361
423
|
*
|
|
362
424
|
* The speedtest survey cockpit's vertical rail needs chassis-strip
|
|
@@ -438,6 +500,13 @@
|
|
|
438
500
|
justify-content: center;
|
|
439
501
|
}
|
|
440
502
|
|
|
503
|
+
/* AW.W3 — the collapsed-hover scale rides the unified dock spring vocabulary.
|
|
504
|
+
The `scale var(--dock-motion-resize)` arm was added to the `.glass-dock`
|
|
505
|
+
root transition above, so this hover scale settles on the SAME spring curve
|
|
506
|
+
the expand morph uses — a collapsed→hover→expand gesture is one continuous
|
|
507
|
+
spring, not a `scale`-ease handed off to the width-spring. The hover scale
|
|
508
|
+
and the press squish (`--scale-press-dock`) are now one register on the dock
|
|
509
|
+
surface. */
|
|
441
510
|
.glass-dock.collapsed:hover {
|
|
442
511
|
background: var(--glass-bg-wash);
|
|
443
512
|
border-color: var(--glass-border-floating);
|
|
@@ -659,6 +728,72 @@
|
|
|
659
728
|
inset: 0;
|
|
660
729
|
}
|
|
661
730
|
|
|
731
|
+
/* AW.W3 — the spring-keyed child stagger. While the size spring drives the
|
|
732
|
+
morph, the driver arms the container (`.dock-layers` / `.dock-layer-stack`)
|
|
733
|
+
with `data-revealing` and writes the morph's normalized progress to
|
|
734
|
+
`--dock-morph-progress` (0 → 1) every frame. Each direct child of the
|
|
735
|
+
ACTIVE pane reveals when that progress crosses a per-child onset, so the
|
|
736
|
+
controls cascade IN ON the physical morph — a fast flick and a slow
|
|
737
|
+
hover-open both choreograph correctly, and an interrupted morph carries the
|
|
738
|
+
cascade with it (no orphaned timers). This is a per-CHILD opacity onset; the
|
|
739
|
+
active PANE itself stays statically opacity:1 (revealed by the aperture —
|
|
740
|
+
the W2 clip-reveal contract is NOT regressed).
|
|
741
|
+
|
|
742
|
+
The reveal is a pure `calc` ramp: `opacity = clamp(0, (progress − onset) /
|
|
743
|
+
window, 1)`. `--dock-stagger-onset` steps per child (nth-child); the window
|
|
744
|
+
is `--dock-stagger-window`. The children also rise a few px on a `translate`
|
|
745
|
+
that resolves on the same ramp. ONLY children inside the `[data-revealing]`
|
|
746
|
+
active pane are armed — at rest the children carry no opacity authority (the
|
|
747
|
+
default cascade leaves them at 1).
|
|
748
|
+
|
|
749
|
+
PRM: the driver never arms `data-revealing` on the synchronous PRM swap (the
|
|
750
|
+
FLIP fast-path returns before the spring; the spring's `respectReducedMotion`
|
|
751
|
+
settles instantly), so the children paint at full opacity at once. The
|
|
752
|
+
global PRM gate also strips `translate` from the transition-property — the
|
|
753
|
+
rise snaps. The cascade collapses to 0 stagger frames under PRM. */
|
|
754
|
+
.dock-layers[data-revealing] .dock-layer--full > *,
|
|
755
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > * {
|
|
756
|
+
--dock-stagger-window: var(--dock-stagger-window-size, 0.55);
|
|
757
|
+
--dock-stagger-onset: 0;
|
|
758
|
+
opacity: clamp(
|
|
759
|
+
0,
|
|
760
|
+
calc(
|
|
761
|
+
(var(--dock-morph-progress, 1) - var(--dock-stagger-onset)) /
|
|
762
|
+
var(--dock-stagger-window)
|
|
763
|
+
),
|
|
764
|
+
1
|
|
765
|
+
);
|
|
766
|
+
translate: 0
|
|
767
|
+
calc(
|
|
768
|
+
(1 - clamp(0, calc((var(--dock-morph-progress, 1) - var(--dock-stagger-onset)) / var(--dock-stagger-window)), 1)) *
|
|
769
|
+
var(--dock-stagger-rise, 4px)
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/* Per-child onsets — each successive control starts a beat later, so the row
|
|
774
|
+
fills outer→in on expand. The onsets are fractions of the morph progress;
|
|
775
|
+
capped so even a long row finishes within the morph window. */
|
|
776
|
+
.dock-layers[data-revealing] .dock-layer--full > *:nth-child(2),
|
|
777
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > *:nth-child(2) {
|
|
778
|
+
--dock-stagger-onset: 0.08;
|
|
779
|
+
}
|
|
780
|
+
.dock-layers[data-revealing] .dock-layer--full > *:nth-child(3),
|
|
781
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > *:nth-child(3) {
|
|
782
|
+
--dock-stagger-onset: 0.16;
|
|
783
|
+
}
|
|
784
|
+
.dock-layers[data-revealing] .dock-layer--full > *:nth-child(4),
|
|
785
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > *:nth-child(4) {
|
|
786
|
+
--dock-stagger-onset: 0.24;
|
|
787
|
+
}
|
|
788
|
+
.dock-layers[data-revealing] .dock-layer--full > *:nth-child(5),
|
|
789
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > *:nth-child(5) {
|
|
790
|
+
--dock-stagger-onset: 0.32;
|
|
791
|
+
}
|
|
792
|
+
.dock-layers[data-revealing] .dock-layer--full > *:nth-child(n + 6),
|
|
793
|
+
.dock-layer-stack[data-revealing] .dock-layer-item-host.is-active > *:nth-child(n + 6) {
|
|
794
|
+
--dock-stagger-onset: 0.4;
|
|
795
|
+
}
|
|
796
|
+
|
|
662
797
|
/* AW.W2 — the at-rest clip-lift moved to `.expanded:not([data-morphing])` /
|
|
663
798
|
`.always-expanded:not([data-morphing])` (the clip-shell block at the top).
|
|
664
799
|
A plain `overflow: visible` here would lift the clip DURING the morph (the
|
|
@@ -676,6 +811,46 @@
|
|
|
676
811
|
cursor: default;
|
|
677
812
|
}
|
|
678
813
|
|
|
814
|
+
/* ── AW.W3b — `layout="grid"` the 2D auto-grid big dock ──────────────
|
|
815
|
+
The active layer becomes a self-wrapping tile grid (Launchpad / Stage-Manager
|
|
816
|
+
track symmetry — `auto-fill` columns floored at `--dock-tile-min`, explicit
|
|
817
|
+
`grid-auto-rows` so the concentric look holds). DISTINCT from
|
|
818
|
+
`overflow="wrap"`'s content-ordered flex-wrap. A `layout="grid"` dock is
|
|
819
|
+
`alwaysExpanded` by contract (GlassDock.vue), so there is NO width morph and
|
|
820
|
+
hence NO per-frame grid-column reflow. `white-space: normal` releases the
|
|
821
|
+
single-row nowrap so the tiles wrap. */
|
|
822
|
+
.glass-dock.layout-grid {
|
|
823
|
+
white-space: normal;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
.glass-dock.layout-grid .dock-layer--full {
|
|
827
|
+
display: grid;
|
|
828
|
+
grid-template-columns: repeat(
|
|
829
|
+
auto-fill,
|
|
830
|
+
minmax(var(--dock-tile-min, 4.5rem), 1fr)
|
|
831
|
+
);
|
|
832
|
+
grid-auto-rows: var(--dock-tile-min, 4.5rem);
|
|
833
|
+
gap: var(--dock-layer-gap, 0.375rem);
|
|
834
|
+
width: 100%;
|
|
835
|
+
height: auto;
|
|
836
|
+
white-space: normal;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/* A grid dock fills the inline cap; the active layer is the panel body, not a
|
|
840
|
+
shrink-to-fit row. The cap is the `--dock-max-inline-size` clamp (KEPT). */
|
|
841
|
+
.glass-dock.layout-grid .dock-layers {
|
|
842
|
+
width: 100%;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/* CONCENTRIC inner tiles — inner radius = outer card radius − padding (the
|
|
846
|
+
universal macOS / visionOS / Raycast rule). NEVER nest two pills
|
|
847
|
+
(stadium-in-stadium); a finite outer + a stepped-down inner. */
|
|
848
|
+
.glass-dock.layout-grid.shape-card .dock-layer--full > * {
|
|
849
|
+
border-radius: calc(
|
|
850
|
+
var(--dock-card-radius) - var(--dock-padding-inline, 0.5rem)
|
|
851
|
+
);
|
|
852
|
+
}
|
|
853
|
+
|
|
679
854
|
/* ── Scroll-on-overflow opt-in (GlassDock `overflow="scroll"`) ───────
|
|
680
855
|
The default contract grows-to-fit then overflows visibly past the
|
|
681
856
|
axis cap. `overflow="scroll"` instead makes the dock the scroll port
|
|
@@ -748,6 +923,15 @@
|
|
|
748
923
|
min-height: var(--dock-wrap-layer-min-height, var(--dock-layer-height, 2rem));
|
|
749
924
|
gap: var(--dock-wrap-row-gap, 0.25rem)
|
|
750
925
|
var(--dock-wrap-column-gap, var(--dock-layer-gap, 0.375rem));
|
|
926
|
+
/* AW.W3b — the graceful wrap-morph. The wrap/unwrap row-reflow flips
|
|
927
|
+
`flex-wrap` at the `--dock-overflow-bp` `@media` boundary; without a
|
|
928
|
+
transition the rows JUMP-CUT. Sequencing the layer's `min-height`
|
|
929
|
+
through the `--dock-motion-resize` spring MORPHS the reflow. The global
|
|
930
|
+
PRM gate strips `min-height` from the transition-property under reduce →
|
|
931
|
+
the morph snaps (0 morph frames) while the reflow still completes. The
|
|
932
|
+
wrap radius swap (`.collapsed` / `@media`) glides too — `border-radius`
|
|
933
|
+
is in the shared `:not(.vertical)` transition list (AW.W3b scope 2). */
|
|
934
|
+
transition: min-height var(--dock-motion-resize);
|
|
751
935
|
}
|
|
752
936
|
|
|
753
937
|
.glass-dock.dock-overflow-wrap .dock-layer--summary {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* AW.W23 — the #glass-refract convex-lens SVG filter, shipped as a library
|
|
2
|
+
* asset so `.glass-refract` works OUT OF THE BOX (no consumer hand-mounts a
|
|
3
|
+
* filter node).
|
|
4
|
+
*
|
|
5
|
+
* The refraction recipe is the canonical 3-primitive graph (kube.io /
|
|
6
|
+
* LogRocket, 2025):
|
|
7
|
+
*
|
|
8
|
+
* feImage — a pre-baked displacement map computed from the convex-
|
|
9
|
+
* squircle surface profile y = ⁴√(1 − (1 − x)⁴) (Apple's
|
|
10
|
+
* preferred corner curve) via Snell's law (n₁ = 1 air,
|
|
11
|
+
* n₂ = 1.5 glass). The map is authored as an embedded SVG
|
|
12
|
+
* whose R channel carries the x-shift and G channel the
|
|
13
|
+
* y-shift (neutral 128 = no shift; bright edges bend light
|
|
14
|
+
* inward like a lens), expressed as two crossed linear
|
|
15
|
+
* gradients over the squircle silhouette.
|
|
16
|
+
* feDisplacementMap— displaces the backdrop by the baked map (R = x-shift,
|
|
17
|
+
* G = y-shift, `scale` = max px, neutral 128).
|
|
18
|
+
* feImage specular — a soft top-left specular highlight…
|
|
19
|
+
* feBlend screen — …blended `screen` over the displaced backdrop for the
|
|
20
|
+
* polished-glass catch.
|
|
21
|
+
*
|
|
22
|
+
* The filter ships INLINE as a data-URI in the `backdrop-filter` declaration, so
|
|
23
|
+
* the consumer gets it with zero markup. `backdrop-filter: url(#…)` is
|
|
24
|
+
* Chromium-only (WebKit bug 245510 open, Firefox not shipping), so the whole
|
|
25
|
+
* decl sits behind `@supports (backdrop-filter: url(#…))`; a non-supporting
|
|
26
|
+
* engine paints the un-gated blur base alone (no broken `url()` reference).
|
|
27
|
+
*
|
|
28
|
+
* RE-HOME (AW.W23 — decouple from the W22-folded compound). At HEAD the
|
|
29
|
+
* refraction rule was bound to `.glass-specular-track.glass-refract`. W22 folds
|
|
30
|
+
* `glass-specular-track` into `.glass-material`, retiring the compound's left
|
|
31
|
+
* operand, so the rule is re-homed onto `.glass-material.glass-refract` — the
|
|
32
|
+
* refraction garnish opts in on ANY `.glass-material` surface, no dependency on
|
|
33
|
+
* the now-aliased `glass-specular-track` class. The garnish stays PE-only over
|
|
34
|
+
* the blur base; it is NEVER promoted to the card/primitive substrate
|
|
35
|
+
* (feDisplacementMap is resize-expensive — only the `scale` attr animates
|
|
36
|
+
* without rebuilding the map).
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
@layer components {
|
|
40
|
+
/* The shipped filter graph as a data-URI SVG. A `0×0` host SVG mounted via
|
|
41
|
+
the CSS asset keeps the `#glass-refract` id resolvable in-document. */
|
|
42
|
+
.glass-refract {
|
|
43
|
+
/* The named convex-lens displacement filter, baked from the squircle
|
|
44
|
+
surface profile. Composed as a custom property so the @supports arm
|
|
45
|
+
below references one source. */
|
|
46
|
+
--glass-refract-filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='glass-refract' x='0' y='0' width='100%25' height='100%25'%3E%3CfeImage href='data:image/svg+xml,%253Csvg xmlns=%2522http://www.w3.org/2000/svg%2522 width=%2522100%2522 height=%2522100%2522%253E%253CradialGradient id=%2522m%2522 cx=%252250%2525%2522 cy=%252250%2525%2522 r=%252250%2525%2522%253E%253Cstop offset=%25220%2525%2522 stop-color=%2522rgb(128,128,128)%2522/%253E%253Cstop offset=%252270%2525%2522 stop-color=%2522rgb(128,128,128)%2522/%253E%253Cstop offset=%2522100%2525%2522 stop-color=%2522rgb(255,255,128)%2522/%253E%253C/radialGradient%253E%253Crect width=%2522100%2522 height=%2522100%2522 fill=%2522url(%2523m)%2522/%253E%253C/svg%253E' result='map'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='map' scale='28' xChannelSelector='R' yChannelSelector='G' result='disp'/%3E%3CfeImage href='data:image/svg+xml,%253Csvg xmlns=%2522http://www.w3.org/2000/svg%2522 width=%2522100%2522 height=%2522100%2522%253E%253CradialGradient id=%2522s%2522 cx=%252230%2525%2522 cy=%252225%2525%2522 r=%252260%2525%2522%253E%253Cstop offset=%25220%2525%2522 stop-color=%2522rgba(255,255,255,0.5)%2522/%253E%253Cstop offset=%2522100%2525%2522 stop-color=%2522rgba(255,255,255,0)%2522/%253E%253C/radialGradient%253E%253Crect width=%2522100%2522 height=%2522100%2522 fill=%2522url(%2523s)%2522/%253E%253C/svg%253E' result='spec'/%3E%3CfeBlend in='disp' in2='spec' mode='screen'/%3E%3C/filter%3E%3C/svg%3E#glass-refract");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* The gated consuming selector — RE-HOMED onto `.glass-material.glass-refract`
|
|
50
|
+
(decoupled from the W22-folded `.glass-specular-track` compound). The
|
|
51
|
+
refraction composes the shipped `#glass-refract` filter OVER the host's
|
|
52
|
+
existing blur; it is additive (the blur already painted, this sharpens the
|
|
53
|
+
refraction edge where the engine supports it). */
|
|
54
|
+
@supports (backdrop-filter: url("#glass-refract")) {
|
|
55
|
+
.glass-material.glass-refract,
|
|
56
|
+
.glass-refract {
|
|
57
|
+
backdrop-filter: var(--glass-blur-resting) var(--glass-refract-filter);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|