@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
@@ -46,8 +46,15 @@
46
46
 
47
47
  The `.glass-dock` SHELL is OUT of this group BY DESIGN — it hand-rolls a
48
48
  parallel surface (its own `--glass-*-dock` family + a local rim + an
49
- instrument-strip `::before`) the dock arm owns; the dock's catch-light
50
- lives on its CONTROL (`.dock-icon-button`, listed below), not the shell.
49
+ instrument-strip `::before`) the dock arm owns. The COHESION CONSEQUENCE is
50
+ DELIBERATE: the dock shell carries NO shared edge-gleam / moving-specular
51
+ `::before` (its only `::before` is the `variant-instrument-strip` engraved
52
+ bezel, dock/shell.css — a different effect). The dock's catch-light lives on
53
+ its CONTROLS (`.dock-icon-button` et al., listed below + in the opt-in
54
+ transition block), which ARE in the material group — NOT on the shell plate.
55
+ Adding a shell gleam would re-introduce glass-on-glass over the controls, so
56
+ the shell-without-gleam is a NAMED EXEMPTION, gated as `dock-shell-exempt` in
57
+ proof:glass-cohesion (the only exemption beside the legibility allowlist).
51
58
 
52
59
  The selector GROUP is the single source. Adding a surface to the band
53
60
  material is one comma-entry here, not a new opt-in class string. */
@@ -146,6 +153,37 @@
146
153
  a plain low-alpha warm overlay (the gleam composes normally — no blend, no
147
154
  blowout), the no-workaround floor; NOT a `screen` fallback. */
148
155
  mix-blend-mode: plus-lighter;
156
+ /* The moving-specular TRANSITION is NOT declared here. An idle/unwired
157
+ `::before` is STATIC (no interpolation track), so a bare glass rung / an
158
+ un-armed Card / a glass Button at rest attaches ZERO animation tracks (the
159
+ keyframes.js runtime counts 0 idle tracks, not 19). The transition rides
160
+ ONLY the WIRED + interactive surfaces — the opt-in scoped block below. */
161
+ }
162
+
163
+ /* AY.W-GLASS — the moving-specular transition is OPT-IN (the Card wire-or-omit
164
+ pattern, generalized). It attaches ONLY to a WIRED surface
165
+ (`.glass-specular-track` — Card emits it conditionally, the dock controls + the
166
+ Slider thumb compose it) OR to any glass surface under `:hover`/`:active` (the
167
+ pointer is present, so the interpolation is legitimately live). An idle/unwired
168
+ `.glass-floating` / `.glass-wash` / bare-rung `::before` carries NO transition
169
+ and thus NO keyframes.js track. The §6 register is PRESERVED (still
170
+ `--ease-standard` on the position-tracked + surface-opacity legs — H-motion §6
171
+ "position-tracked → --ease-standard"; only the SELECTOR scope changes). The dock
172
+ controls keep the always-on transition (they are interactive controls; their rest
173
+ intensity is 0 so they paint nothing at rest, but a control legitimately carries
174
+ the transition). */
175
+ .glass-specular-track::before,
176
+ .glass-material:hover::before, .glass-material:active::before,
177
+ .glass-wash:hover::before, .glass-wash:active::before,
178
+ .glass-quiet:hover::before, .glass-quiet:active::before,
179
+ .glass-resting:hover::before, .glass-resting:active::before,
180
+ .glass-floating:hover::before, .glass-floating:active::before,
181
+ .glass-overlay:hover::before, .glass-overlay:active::before,
182
+ .glass-card:hover::before, .glass-card:active::before,
183
+ .dock-icon-button::before,
184
+ .dock-tab-button::before,
185
+ .dock-select-trigger::before,
186
+ .dock-dropdown-trigger::before {
149
187
  /* Smooth the position + intensity between pointer samples (the typed
150
188
  @property regs make the percentage stops interpolable). */
151
189
  transition:
@@ -222,6 +260,97 @@
222
260
  --specular-intensity: var(--glass-specular-intensity-active, 0.16);
223
261
  }
224
262
 
263
+ /* ── LIQUID by tier — the moving-specular hover catch-light is the
264
+ FLOATING / OVERLAY tier's PROPERTY, not a per-surface wire (D6.c M10) ──────
265
+ The shared `:hover::before` rule above already lifts `--specular-intensity`
266
+ to the hover rung on EVERY material surface, so the catch-light wakes on
267
+ hover library-wide. What this block promotes is the FLOATING / OVERLAY
268
+ tier's identity: a navigation/overlay-band surface (a Dialog, a Sheet, a
269
+ Popover, the dock crest's `.glass-floating`) reads as LIQUID OUT OF THE BOX
270
+ — the catch-light is a tier guarantee, documented here so a consumer reaches
271
+ for `variant="floating"` and inherits the lens without a `useSpecularTracking`
272
+ wire. The pointer-anchored TRACKING still rides `useSpecularTracking` (a
273
+ host can sharpen the lens to the cursor); un-wired, the catch-light sits at
274
+ the centred `50%` fallback and breathes on hover — felt, not garish.
275
+
276
+ The magnitude rides the SAME `--glass-specular-intensity-hover` cohort the
277
+ aurora-calibrated π-ledger judges (tokens.css §specular-intensity), so the
278
+ liquid tier never out-shouts a number — it is the SAME gleam, named as a
279
+ tier default. The OPT-OUT survives: `.glass-no-liquid` on a floating/overlay
280
+ surface pins the rest rung (a flat tier for dense data, the deft escape). */
281
+ .glass-floating:not(.glass-no-liquid),
282
+ .glass-overlay:not(.glass-no-liquid) {
283
+ --glass-liquid: 1; /* the tier carries the liquid identity (informational marker) */
284
+ }
285
+ .glass-floating.glass-no-liquid:hover::before,
286
+ .glass-overlay.glass-no-liquid:hover::before,
287
+ .glass-floating.glass-no-liquid:active::before,
288
+ .glass-overlay.glass-no-liquid:active::before {
289
+ /* The deft escape — a dense-data floating surface that wants a FLAT tier
290
+ pins the catch-light at the clean rest rung even on hover/active. */
291
+ --specular-intensity: var(--glass-specular-intensity-rest, 0);
292
+ }
293
+ @media (prefers-reduced-motion: reduce) {
294
+ /* PRM fence — the liquid tier degrades to the static centred gleam. The
295
+ `useSpecularTracking` write is already PRM-gated (it skips the pointer
296
+ write under reduce); this pins the CSS half (`--specular-x/y: 50%`
297
+ centred) AND kills the position-track `transition` so an un-wired liquid
298
+ tile does NOT animate a travelling catch-light on hover under PRM. The
299
+ gleam may still LIFT on hover (a discrete opacity step, no interpolation
300
+ track) — the correct PRM degrade: no MOTION, the surface still responds.
301
+ This mirrors the shared moving-specular PRM bracket (one static-pin
302
+ convention across the specular cohort). */
303
+ .glass-floating::before,
304
+ .glass-overlay::before {
305
+ --specular-x: 50%;
306
+ --specular-y: 50%;
307
+ transition: none;
308
+ }
309
+ }
310
+
311
+ /* ── The GILT EDGE — `.glass-gilt`, the gilt-tooled glass modifier (D6.c M3/M12) ──
312
+ A fine book's cover is gold-tooled at the EDGE — never a gold fill. The
313
+ modifier composes on ANY tier (the tier is the FROST; the gilt is the
314
+ hairline gold catch on its rim) so a featured card OR the dock crest wears
315
+ the same recipe over its own backdrop. Two box-shadow layers ride INSIDE
316
+ the tier (they do not perturb the tier's own elevation stack — they are
317
+ additive inset rings):
318
+ (1) a 1px inset ring on `--gold-rim` — the tooled gold edge (D6.b lands
319
+ `--gold-rim` = `--gold` at ~40%α over the surface; referenced by name,
320
+ so the gilt resolves the moment the token cohort is minted), and
321
+ (2) a 0.5px gold top-catch highlight — the bevel light reading off the
322
+ upper edge, `--gold-light` at low α so it is a catch, not a band.
323
+ The surface still reads as cream-glass; the gold is the bevel light, the
324
+ SCARCE flourish (the consumption budget — at most one gilt surface per
325
+ route — is the atlas's D7 rule, not enforced here). */
326
+ .glass-gilt {
327
+ box-shadow:
328
+ inset 0 0 0 1px var(--gold-rim, color-mix(in oklab, var(--gold) 40%, transparent)),
329
+ inset 0 0.5px 0 0 color-mix(in oklab, var(--gold-light) 35%, transparent),
330
+ var(--glass-material-rim),
331
+ var(--glass-shadow-floating);
332
+ }
333
+
334
+ /* The liquid-metal CATCH-LIGHT (D6.c M12) — `.glass-gilt` overrides the
335
+ moving-specular `::before` sweep COLOR from warm-cream to GOLD, so the light
336
+ travelling across the gilt edge is golden the way gold leaf catches a warm
337
+ highlight. This is the single richest moment in the platform — gold + liquid
338
+ + specular — and therefore the most scarce (ONE surface ever, the title-page
339
+ flourish; the budget lives in D7). The geometry (bounded circle, the
340
+ `--glass-specular-size` falloff, the `plus-lighter` blend, the mask) is
341
+ INHERITED verbatim from the shared `::before`; only the gradient color stops
342
+ shift to the warm-gold mix. The intensity still rides the `--specular-intensity`
343
+ opacity multiplier (0 at rest), so a resting gilt surface paints NO gold sweep
344
+ — it wakes on hover like every liquid tier. */
345
+ .glass-gilt::before {
346
+ background: radial-gradient(
347
+ circle var(--glass-specular-size, 36%) at var(--specular-x, 50%) var(--specular-y, 50%),
348
+ color-mix(in oklab, var(--gold-light) 60%, hsl(40 35% 92%)) 0%,
349
+ hsl(40 35% 92% / 0) 70%,
350
+ transparent 100%
351
+ );
352
+ }
353
+
225
354
  /* ── Five-tier surface ladder (v0.8.0; visual only, no geometry) ──
226
355
  Tier semantics, alpha-monotonic per R3-spec §A:
227
356
  wash ~0.30α + light blur (was `subtle`)
@@ -430,7 +559,10 @@
430
559
  background: var(--paper-clean-texture);
431
560
  background-repeat: repeat;
432
561
  background-size: var(--paper-texture-size);
433
- opacity: var(--glass-grain-opacity);
562
+ /* D6.c M5 — the grain rung lifted off the dead 0.025 floor to a felt-but-
563
+ deft 0.038 (the page rung; the kitsch ceiling is ~0.05). The canonical
564
+ token still wins; this is the felt floor a no-override mount inherits. */
565
+ opacity: var(--glass-grain-opacity, 0.038);
434
566
  pointer-events: none;
435
567
  mix-blend-mode: overlay;
436
568
  }
@@ -947,17 +1079,20 @@
947
1079
  .glass-resting,
948
1080
  .glass-floating,
949
1081
  .glass-overlay,
950
- .glass-card {
1082
+ .glass-card,
1083
+ .glass-drawer {
951
1084
  border: 1px solid CanvasText;
952
1085
  }
953
1086
 
954
1087
  /* The floating + overlay rungs (Dialog / Sheet / Popover / DropdownMenu /
955
- HoverCard compose them) get the canonical `Canvas` fill so the modal reads as
956
- a DISTINCT boxed region OVER the page, not a transparent overlap — the
957
- hierarchy survives. The `CanvasText` edge above already draws the box; this
958
- opaque fill separates the floating layer from the content beneath it. */
1088
+ HoverCard compose them) + the Drawer (the overlay-band sheet, drawer.css)
1089
+ get the canonical `Canvas` fill so the modal reads as a DISTINCT boxed
1090
+ region OVER the page, not a transparent overlap — the hierarchy survives.
1091
+ The `CanvasText` edge above already draws the box; this opaque fill
1092
+ separates the floating layer from the content beneath it. */
959
1093
  .glass-floating,
960
- .glass-overlay {
1094
+ .glass-overlay,
1095
+ .glass-drawer {
961
1096
  background: Canvas;
962
1097
  }
963
1098
 
@@ -972,6 +1107,7 @@
972
1107
  .glass-floating::before,
973
1108
  .glass-overlay::before,
974
1109
  .glass-card::before,
1110
+ .glass-drawer::before,
975
1111
  .glass-wash::after,
976
1112
  .glass-quiet::after,
977
1113
  .glass-resting::after,
@@ -7,8 +7,54 @@
7
7
  *
8
8
  * Texture: feTurbulence baseFrequency 0.65, 4 octaves, desaturated via
9
9
  * feColorMatrix, blended multiply (light) / soft-light (dark). Tiles ~60px.
10
+ *
11
+ * ── THE GRAIN RUNGS (D6.c M5 — the printed-paper tooth, FELT not seen) ─────────
12
+ * The warm-paper grain must be FELT at rest — a premium editorial stock has a
13
+ * felt depth, and the measured finding (ds2-medium M5 / fd-usf-gallery §F) is
14
+ * that the shipped `--glass-grain-opacity: 0.025` floor reads as NOTHING. This
15
+ * file lifts the grain off that floor and mints a SECOND rung for chart plates:
16
+ *
17
+ * --glass-grain-opacity — the PAGE grain. Lifted here to a perceptible-
18
+ * but-deft 0.038 default (the local floor below).
19
+ * Numeric justification: the kitsch line is
20
+ * ~0.05 (above it the grain reads as screen-noise
21
+ * / a dirty monitor, ds2-medium M5); 0.025 is
22
+ * sub-perceptual ("felt as nothing"). 0.038 is
23
+ * the calibrated MIDPOINT — ~1.5× the dead floor,
24
+ * ~0.76× the kitsch ceiling — felt at rest, never
25
+ * seen AS grain. (The canonical token still lives
26
+ * in tokens.css; this utility reads it with the
27
+ * lifted fallback so a no-override mount is felt.)
28
+ * --glass-grain-opacity-plate — the PLATE grain (NEW rung). A chart plate is
29
+ * the FIGURE's "paper", so it wants slightly more
30
+ * tooth than the page (M5): 0.045 — still below
31
+ * the 0.05 kitsch ceiling, distinctly felt so the
32
+ * plate reads as PRINTED on the same stock as the
33
+ * page, not pasted onto it.
34
+ *
35
+ * THE DATA-REGION MASK CONTRACT (M5, non-negotiable). Grain on the FRAME, never
36
+ * under the FIGURE — a fleck over a choropleth reads as a data artifact; on the
37
+ * plate margin it reads as paper. `paper-grain-overlay` exposes a custom-property
38
+ * MASK SLOT (`--paper-grain-mask`) so a consumer can carve the data viewport out
39
+ * of the grain ::after: set it to a gradient/`url()` that is transparent over the
40
+ * data region and opaque over the frame, and the grain is masked off the figure.
41
+ * Default `none` (the whole surface is grained — the page/card case, no data to
42
+ * fence). The plate rung is opt-in via `[data-grain="plate"]`.
10
43
  */
11
44
 
45
+ /* The grain rung DEFAULTS — lifted off the tokens.css floor (D6.c M5). These are
46
+ plain custom-property fallbacks the utilities read; a consumer/tokens.css value
47
+ still wins (`var(--glass-grain-opacity, <floor>)`), so this only sets the floor
48
+ a no-override mount inherits. The plate rung is minted here (no canonical
49
+ tokens.css home is touched in this lane — D6.b owns tokens.css). */
50
+ @layer components {
51
+ :root {
52
+ /* The PLATE grain rung — distinct from the page rung; the figure's paper
53
+ wants more tooth. Minted in this lane; a consumer overrides at :root. */
54
+ --glass-grain-opacity-plate: 0.045;
55
+ }
56
+ }
57
+
12
58
  @utility paper-underpaint {
13
59
  position: fixed;
14
60
  inset: 0;
@@ -17,7 +63,8 @@
17
63
  background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeBlend mode='multiply' in2='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
18
64
  background-repeat: repeat;
19
65
  background-size: 60px 60px;
20
- opacity: var(--glass-grain-opacity);
66
+ /* Lifted floor — the page grain is FELT at rest (0.038), not the dead 0.025. */
67
+ opacity: var(--glass-grain-opacity, 0.038);
21
68
  mix-blend-mode: multiply;
22
69
  }
23
70
 
@@ -39,8 +86,27 @@
39
86
  background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeBlend mode='multiply' in2='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
40
87
  background-repeat: repeat;
41
88
  background-size: 60px 60px;
42
- opacity: var(--glass-grain-opacity);
89
+ /* Lifted floor — felt on the frame at rest (0.038). */
90
+ opacity: var(--glass-grain-opacity, 0.038);
43
91
  mix-blend-mode: overlay;
92
+ /* THE DATA-REGION MASK SLOT (M5). Default `none` = the whole surface is
93
+ grained (page/card — no data to fence). A consumer that grains a chart
94
+ plate sets `--paper-grain-mask` to a gradient/url() transparent over the
95
+ data viewport + opaque over the frame, carving the figure out of the
96
+ grain so no fleck lands on a tier fill. `mask` is Baseline; a
97
+ non-supporting engine ignores it and keeps the full-surface grain (the
98
+ page case is unaffected — the mask only matters when a consumer fences
99
+ the data region). */
100
+ mask: var(--paper-grain-mask, none);
101
+ -webkit-mask: var(--paper-grain-mask, none);
102
+ }
103
+
104
+ /* The PLATE rung — a chart plate opts in via `[data-grain="plate"]` to the
105
+ higher-tooth `--glass-grain-opacity-plate` (the figure's paper reads as the
106
+ same stock as the page, with a touch more tooth). Pair with the mask slot to
107
+ fence the data viewport. */
108
+ &[data-grain="plate"]::after {
109
+ opacity: var(--glass-grain-opacity-plate, 0.045);
44
110
  }
45
111
  }
46
112
 
@@ -308,6 +308,13 @@
308
308
  --color-gold: var(--gold);
309
309
  --color-gold-light: var(--gold-light);
310
310
  --color-gold-dark: var(--gold-dark);
311
+ --color-gold-deep: var(--gold-deep);
312
+ /* D6.b — the gilt family: the rim (gilt edge) + the legible gold ink. The
313
+ `@theme` bridge surfaces `text-gold-ink` / `border-gold-rim` utilities
314
+ beside the existing gold quad. `--gold-ink` clears cream-law ② on `--card`
315
+ in both arms (proof:gold-ink-contrast). */
316
+ --color-gold-rim: var(--gold-rim);
317
+ --color-gold-ink: var(--gold-ink);
311
318
 
312
319
  --color-rainbow-red: var(--rainbow-red);
313
320
  --color-rainbow-orange: var(--rainbow-orange);
@@ -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, success
84
- affirmations. R5 vocab.γ gap row 3 (single-site at dock.css:735 today,
85
- reserved for J.W2.7 §17 audacious-CTA buildout). */
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.035, not the 1.08
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). Currently
1056
- 5 raw `bg-black/{40,50,80}` sites across Dialog/Sheet/Drawer/
1057
- ConfirmDialog hardcode the value; W2.A migrates consumers.
1058
- R5 vocab.γ gap row 2. */
1059
- --overlay-scrim: color-mix(in srgb, var(--shadow-color) 50%, transparent);
1060
- --overlay-scrim-strong: color-mix(in srgb, var(--shadow-color) 80%, transparent);
1061
- --overlay-scrim-subtle: color-mix(in srgb, var(--shadow-color) 40%, transparent);
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
- --focus-ring-shadow: 0 0 0 var(--focus-ring-width) color-mix(in srgb, var(--ring) 30%, transparent),
1489
- 0 0 8px color-mix(in srgb, var(--ring) 15%, transparent);
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
- --dock-press-spring: var(--duration-fast) var(--spring-bouncy);
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 in W4; this comment block IS the
190
- * documentation closure for the W4-M.3 toast contract row.
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 ── */