@mkbabb/glass-ui 2.1.0 → 3.1.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 (194) hide show
  1. package/dist/{CardFooter-Yi0xtLLd.js → CardFooter-CSGcJkqa.js} +1 -1
  2. package/dist/{CommandShortcut-_INFUMu6.js → CommandShortcut-DWT19a2Y.js} +3 -3
  3. package/dist/{ContextMenuSubContent-DCkweFW9.js → ContextMenuSubContent-gAFxJ-qi.js} +1 -1
  4. package/dist/{DataTable-Ce00dbHD.js → DataTable-R8-Zidms.js} +3 -3
  5. package/dist/{DialogContent-CmCijgX9.js → DialogContent-2fALDSvc.js} +3 -3
  6. package/dist/{DialogFooter-DRdaCok0.js → DialogFooter-ClrNEOVU.js} +2 -2
  7. package/dist/{DiscoGlyph-wRA02zAJ.js → DiscoGlyph-C3JfMnRV.js} +1 -1
  8. package/dist/{GlyphFace-BnPMUZ16.js → GlyphFace-BRS8vUb7.js} +1 -1
  9. package/dist/HoverPopover-CWFCfLx3.js +96 -0
  10. package/dist/{IconTooltip-ge_mBSWR.js → IconTooltip-BkaA7tZ2.js} +1 -1
  11. package/dist/{Input-CbakTe3B.js → Input-DDpFn568.js} +3 -5
  12. package/dist/Label-DJty89bp.js +36 -0
  13. package/dist/{MetricBadge-DRBB18Xq.js → MetricBadge-DmAihkXd.js} +1 -1
  14. package/dist/{Notification-DrI1DT2v.js → Notification-OqIpADml.js} +2 -2
  15. package/dist/NumberFieldContent-DTH9gb_N.js +141 -0
  16. package/dist/{PopoverContent-BCH4eYs8.js → PopoverContent-EiklFrna.js} +1 -1
  17. package/dist/{Progress-CCH-2UBR.js → Progress-FApA9fm_.js} +1 -1
  18. package/dist/{ScrollingText-7P8skg5W.js → ScrollingText-BFd0i2zJ.js} +2 -2
  19. package/dist/{SelectScrollDownButton-yu8EYUnu.js → SelectScrollDownButton-Dth8-wXQ.js} +2 -2
  20. package/dist/{Toaster-DY8_jtHv.js → Toaster-Bjlunvq4.js} +69 -58
  21. package/dist/UnderlineTabs-DAWMLmJG.js +37 -0
  22. package/dist/animated-digit.js +2 -2
  23. package/dist/api/index.d.ts +2 -0
  24. package/dist/api.js +1 -1
  25. package/dist/aurora.js +103 -90
  26. package/dist/badge.js +1 -1
  27. package/dist/{button-BlOW34DT.js → button-C0aHmBbt.js} +2 -0
  28. package/dist/button.js +1 -1
  29. package/dist/card.js +1 -1
  30. package/dist/carousel.js +1 -1
  31. package/dist/collapsible.js +1 -1
  32. package/dist/command.js +1 -1
  33. package/dist/components/custom/aurora/composables/runtime.d.ts +24 -1
  34. package/dist/components/custom/dialog-native/GlassDialogNative.vue.d.ts +57 -0
  35. package/dist/components/custom/dialog-native/index.d.ts +1 -0
  36. package/dist/components/custom/dock/composables/useLayerTransition.d.ts +20 -10
  37. package/dist/components/custom/hover-popover/HoverPopover.vue.d.ts +26 -4
  38. package/dist/components/custom/labeled-field/LabeledField.vue.d.ts +16 -2
  39. package/dist/components/custom/labeled-field/LabeledInput.vue.d.ts +17 -1
  40. package/dist/components/custom/labeled-field/LabeledSelect.vue.d.ts +2 -0
  41. package/dist/components/custom/labeled-field/LabeledSlider.vue.d.ts +2 -0
  42. package/dist/components/custom/labeled-field/LabeledSwitch.vue.d.ts +2 -0
  43. package/dist/components/custom/toggle-chip/ToggleChip.vue.d.ts +6 -4
  44. package/dist/components/ui/input/Input.vue.d.ts +10 -7
  45. package/dist/components/ui/label/Label.vue.d.ts +8 -0
  46. package/dist/components/ui/textarea/Textarea.vue.d.ts +45 -8
  47. package/dist/components/ui/toast/Toaster.vue.d.ts +7 -1
  48. package/dist/components/ui/toast/index.d.ts +1 -0
  49. package/dist/composables/dark/index.d.ts +1 -0
  50. package/dist/composables/dom/index.d.ts +2 -0
  51. package/dist/composables/dom/useIdleReady.d.ts +63 -0
  52. package/dist/composables/dom/useUserInvalidAria.d.ts +32 -0
  53. package/dist/composables/index.d.ts +1 -0
  54. package/dist/composables/motion/core/index.d.ts +8 -0
  55. package/dist/composables/motion/index.d.ts +0 -7
  56. package/dist/composables/motion/supportsCssTimeline.d.ts +8 -0
  57. package/dist/composables/motion/useRAFLoop.d.ts +7 -0
  58. package/dist/composables/motion/useScrollProgress.d.ts +6 -2
  59. package/dist/composables/motion/useStaggerReveal.d.ts +6 -0
  60. package/dist/composables/motion/useViewTransition.d.ts +31 -0
  61. package/dist/composables/motion/useYieldToMain.d.ts +29 -0
  62. package/dist/configurator.js +1 -1
  63. package/dist/confirm-dialog.js +2 -2
  64. package/dist/constants-DwBwnG8N.js +13 -0
  65. package/dist/context-menu.js +2 -2
  66. package/dist/controls.js +2 -2
  67. package/dist/dark.d.ts +1 -1
  68. package/dist/dark.js +13 -2
  69. package/dist/data-table.js +1 -1
  70. package/dist/dialog.js +2 -2
  71. package/dist/disco-glyph.js +1 -1
  72. package/dist/dock.js +195 -176
  73. package/dist/dom.js +5 -4
  74. package/dist/{dropdown-menu-2K-SGkZU.js → dropdown-menu-BvRUamNs.js} +2 -2
  75. package/dist/dropdown-menu.js +1 -1
  76. package/dist/expandable-container.js +3 -3
  77. package/dist/forms.d.ts +1 -0
  78. package/dist/forms.js +47 -42
  79. package/dist/glass-carousel.js +1 -1
  80. package/dist/glass-panel.js +2 -2
  81. package/dist/glass-ui.css +1 -1
  82. package/dist/glass-ui.js +156 -275
  83. package/dist/glyph-face.js +2 -2
  84. package/dist/header-ribbon.js +1 -1
  85. package/dist/hover-card.js +1 -1
  86. package/dist/hover-popover.js +1 -1
  87. package/dist/icon-tooltip.js +1 -1
  88. package/dist/index.d.ts +1 -0
  89. package/dist/instrument-chassis.js +1 -1
  90. package/dist/instrument-rail.js +1 -1
  91. package/dist/keyboard.js +1 -1
  92. package/dist/label.js +1 -1
  93. package/dist/labeled-field.js +96 -57
  94. package/dist/metric-badge.js +1 -1
  95. package/dist/metric-stack.js +1 -1
  96. package/dist/motion-core.d.ts +1 -0
  97. package/dist/motion-core.js +229 -0
  98. package/dist/motion.js +26 -228
  99. package/dist/notification.js +1 -1
  100. package/dist/number-field.d.ts +1 -0
  101. package/dist/number-field.js +2 -0
  102. package/dist/paper-backdrop.js +1 -1
  103. package/dist/popover.js +1 -1
  104. package/dist/progress.js +1 -1
  105. package/dist/pulse.js +1 -1
  106. package/dist/reactive.js +2 -2
  107. package/dist/responsive-tabs.js +3 -3
  108. package/dist/scrolling-text.js +1 -1
  109. package/dist/search.js +6 -6
  110. package/dist/select.js +3 -3
  111. package/dist/separator.js +1 -1
  112. package/dist/{sheet-CLVkb3AO.js → sheet-CukNDezz.js} +53 -53
  113. package/dist/sheet.js +1 -1
  114. package/dist/{slider-BQaLYFLh.js → slider-DJvHkTRe.js} +3 -3
  115. package/dist/slider.js +1 -1
  116. package/dist/sortable-list.js +2 -2
  117. package/dist/styles/animations.css +77 -0
  118. package/dist/styles/cards.css +6 -2
  119. package/dist/styles/dock.css +109 -109
  120. package/dist/styles/drawer.css +2 -2
  121. package/dist/styles/glass.css +89 -6
  122. package/dist/styles/index.css +10 -1
  123. package/dist/styles/instrument-chassis.css +28 -1
  124. package/dist/styles/scroll-driven.css +72 -0
  125. package/dist/styles/theme.css +6 -0
  126. package/dist/styles/tokens.css +345 -289
  127. package/dist/styles/typography.css +65 -131
  128. package/dist/styles/utilities.css +199 -81
  129. package/dist/styles/view-transition.css +62 -0
  130. package/dist/switch.d.ts +1 -0
  131. package/dist/switch.js +2 -0
  132. package/dist/tabs.js +40 -36
  133. package/dist/timeline.js +2 -2
  134. package/dist/toast.js +1 -1
  135. package/dist/toggle-group.js +1 -1
  136. package/dist/tooltip.js +1 -1
  137. package/dist/typewriter.js +1 -1
  138. package/dist/{useAnimatedNumber-DcvTR9B4.js → useAnimatedNumber-DKQYVB7s.js} +9 -20
  139. package/dist/{useConfiguratorState-BlaevW0S.js → useConfiguratorState-BR5vUDL8.js} +5 -5
  140. package/dist/{useBreakpoint-BHlX-MhR.js → useIdleReady-Cmkhm03v.js} +30 -2
  141. package/dist/{useTouchGate-BhhEMlwJ.js → useTouchGate-D9Zvrzyc.js} +1 -1
  142. package/dist/useUserInvalidAria-DVu1eTXG.js +29 -0
  143. package/dist/useViewTransition-DYIK6Gzb.js +16 -0
  144. package/dist/utils/index.d.ts +1 -0
  145. package/dist/utils/moveBefore.d.ts +15 -0
  146. package/package.json +27 -6
  147. package/src/styles/animations.css +77 -0
  148. package/src/styles/cards.css +6 -2
  149. package/src/styles/dock.css +109 -109
  150. package/src/styles/drawer.css +2 -2
  151. package/src/styles/glass.css +89 -6
  152. package/src/styles/index.css +10 -1
  153. package/src/styles/instrument-chassis.css +28 -1
  154. package/src/styles/scroll-driven.css +72 -0
  155. package/src/styles/theme.css +6 -0
  156. package/src/styles/tokens.css +345 -289
  157. package/src/styles/typography.css +65 -131
  158. package/src/styles/utilities.css +199 -81
  159. package/src/styles/view-transition.css +62 -0
  160. package/dist/HoverPopover-Btv4RQfv.js +0 -80
  161. package/dist/Label-C8QMJSsf.js +0 -32
  162. package/dist/UnderlineTabs-BtrUcXn-.js +0 -64
  163. package/dist/composables/motion/useSpringOrchestrator.d.ts +0 -15
  164. /package/dist/{CollapsibleContent-DHRuXE3P.js → CollapsibleContent-CVMOcYlV.js} +0 -0
  165. /package/dist/{ContextMenuContent-CvXfU5qz.js → ContextMenuContent-otjFIu8v.js} +0 -0
  166. /package/dist/{HoverCardContent-4nN5-5bz.js → HoverCardContent-DaGrgJBO.js} +0 -0
  167. /package/dist/{InstrumentChassis-DOaVYyWq.js → InstrumentChassis-CnHTMxds.js} +0 -0
  168. /package/dist/{InstrumentRail-jHDqXj70.js → InstrumentRail-C6dEbi8E.js} +0 -0
  169. /package/dist/{ModalOverlay-DKLVY-cj.js → ModalOverlay-iWiAgbYH.js} +0 -0
  170. /package/dist/{PaperBackdrop-Bc2drCqJ.js → PaperBackdrop-CeZ-w0R0.js} +0 -0
  171. /package/dist/{SelectGroup-O69GTQ77.js → SelectGroup-DdR4tdDY.js} +0 -0
  172. /package/dist/{SelectSeparator-GTHxKO0a.js → SelectSeparator-CXm_hlqA.js} +0 -0
  173. /package/dist/{Separator-_NCypg_C.js → Separator-D8AUMhxY.js} +0 -0
  174. /package/dist/{Switch-CL0uxu8F.js → Switch-Cr1t_F_U.js} +0 -0
  175. /package/dist/{ToggleGroupItem-BYG_8M9M.js → ToggleGroupItem-OesUouE7.js} +0 -0
  176. /package/dist/{TooltipProvider-C5QLSPto.js → TooltipProvider-DE78vbEP.js} +0 -0
  177. /package/dist/{_plugin-vue_export-helper-n-_DRHWS.js → _plugin-vue_export-helper-Dq1MygBL.js} +0 -0
  178. /package/dist/{badge-BbxVKZfw.js → badge-x46my_Fo.js} +0 -0
  179. /package/dist/composables/{motion → dark}/installDarkModeSync.d.ts +0 -0
  180. /package/dist/{dockContext-BDGSrwsV.js → dockContext-D5NZCWJs.js} +0 -0
  181. /package/dist/{keys-DVkcUktU.js → keys-CaTQS-vx.js} +0 -0
  182. /package/dist/{menuItemVariants-B2nDL7zH.js → menuItemVariants-BsbGNq9C.js} +0 -0
  183. /package/dist/{presets-BMzCDrmR.js → presets-a-D93K1S.js} +0 -0
  184. /package/dist/{search-ocd8tmL9.js → search-DBAiUABx.js} +0 -0
  185. /package/dist/{useGlassRenderer-DMDdMH55.js → useGlassRenderer-Ds-nmrGz.js} +0 -0
  186. /package/dist/{useGlobalDark-PMiP5Jku.js → useGlobalDark-B0WvLJE3.js} +0 -0
  187. /package/dist/{useIntersectionPause-CXYfYg_C.js → useIntersectionPause-IY2CwPQb.js} +0 -0
  188. /package/dist/{useInterval-COlTCeVa.js → useInterval-DVgGUf_y.js} +0 -0
  189. /package/dist/{useKeyboardShortcuts-B1ev1YEC.js → useKeyboardShortcuts-Dpw_RUcB.js} +0 -0
  190. /package/dist/{useResizeObserver-F4aRR4Cj.js → useResizeObserver-Cg9npuM3.js} +0 -0
  191. /package/dist/{useSortable-Ck0rBJ4g.js → useSortable-Cq2Y1JLO.js} +0 -0
  192. /package/dist/{useSpringMount-BTRBNzXP.js → useSpringMount-Cfk1XK1R.js} +0 -0
  193. /package/dist/{useTimer-lp5NlH4w.js → useTimer-NAaj9zNq.js} +0 -0
  194. /package/dist/{x-cdWAmO-q.js → x-q7pJa83X.js} +0 -0
@@ -296,3 +296,80 @@
296
296
  animation: none;
297
297
  }
298
298
  }
299
+
300
+ /* ── §TOP-LAYER ENTRY/EXIT (AQ.W5 §Design 2) ───────────────────────────────
301
+ *
302
+ * A pure-CSS entry/exit grammar for NATIVE top-layer surfaces — `[popover]`
303
+ * elements and native `<dialog>` — keyed off `:popover-open` / `dialog[open]`,
304
+ * plus a glass `::backdrop`. This replaces the per-frame inline-style entry the
305
+ * platform now owns: `@starting-style` + `transition` + `transition-behavior:
306
+ * allow-discrete` + `overlay`.
307
+ *
308
+ * SCOPE: this applies ONLY to elements tagged `.glass-top-layer`. It does NOT
309
+ * touch reka-ui's portaled overlays — those keep their `tw-animate-css`
310
+ * data-state fade (distinct selectors, no cascade fight, mirroring the
311
+ * `[data-scrim-animation]` discipline above). `DialogContent`'s `spring` opt-in
312
+ * (`useSpringMount`) is also untouched — a legitimate iOS-physics variant, not a
313
+ * duplicate of this fade.
314
+ *
315
+ * Baseline: `@starting-style` = Widely Available; `transition-behavior:
316
+ * allow-discrete` + `overlay` = Newly Available → adopt natively, gate the
317
+ * whole grammar on `@supports (overlay: auto)`. A non-supporting engine shows
318
+ * the element instantly (acceptable for a native top-layer surface; glass-ui
319
+ * ships no JS top-layer coordinator — that is reka-ui Dialog's remit).
320
+ *
321
+ * Uses `scale:` (the longhand) not `transform: scale()` so it composes with the
322
+ * identity-base transform work and does not mint a stacking context. Every
323
+ * visual axis reads a `--top-layer-*` token (tokens.css §20).
324
+ */
325
+ @supports (overlay: auto) {
326
+ /* Base (closed / exit) + the transition list. `allow-discrete` MUST come
327
+ * after the property longhands, never negated. */
328
+ .glass-top-layer[popover],
329
+ dialog.glass-top-layer {
330
+ opacity: 0;
331
+ scale: var(--top-layer-enter-scale, 0.96);
332
+ transition-property: opacity, scale, display, overlay;
333
+ transition-duration: var(--duration-normal);
334
+ transition-timing-function: var(--ease-apple-spring);
335
+ transition-behavior: allow-discrete;
336
+ }
337
+
338
+ /* Open state + `@starting-style` entry (starting-style AFTER the open
339
+ * selector so the entry interpolates from the closed values). */
340
+ .glass-top-layer[popover]:popover-open,
341
+ dialog.glass-top-layer[open] {
342
+ opacity: 1;
343
+ scale: 1;
344
+ @starting-style {
345
+ opacity: 0;
346
+ scale: var(--top-layer-enter-scale, 0.96);
347
+ }
348
+ }
349
+
350
+ /* Glass backdrop — blur + dim, animated discretely. `::backdrop` only
351
+ * exists for `showModal()` dialogs, NOT `[popover]` (popovers are
352
+ * non-modal — correct, no scrim). */
353
+ dialog.glass-top-layer::backdrop {
354
+ background-color: hsl(var(--background) / 0);
355
+ backdrop-filter: blur(var(--top-layer-backdrop-blur, 8px));
356
+ transition: display var(--duration-normal) allow-discrete,
357
+ overlay var(--duration-normal) allow-discrete,
358
+ background-color var(--duration-normal) var(--ease-standard);
359
+ }
360
+ dialog.glass-top-layer[open]::backdrop {
361
+ background-color: hsl(var(--background) / var(--top-layer-backdrop-dim, 0.5));
362
+ @starting-style {
363
+ background-color: hsl(var(--background) / 0);
364
+ }
365
+ }
366
+ }
367
+
368
+ /* Reduced-motion carve — flatten the scale to a fade, shorten the duration. */
369
+ @media (prefers-reduced-motion: reduce) {
370
+ .glass-top-layer[popover],
371
+ dialog.glass-top-layer {
372
+ scale: none;
373
+ transition-duration: var(--duration-fast);
374
+ }
375
+ }
@@ -33,12 +33,16 @@
33
33
  @utility cartoon-surface {
34
34
  border-width: 2px;
35
35
  box-shadow: var(--shadow-cartoon-md);
36
+ /* Individual-transform identity base (AQ.W3 §W3.2) — state-driven 2D lift on
37
+ a card surface that often hosts portaled content; `translate: 0` at rest
38
+ mints the stacking context once. Longhand maps `translate(x, y)` 1:1. */
39
+ translate: 0;
36
40
  transition:
37
- transform var(--duration-normal) var(--ease-apple-spring),
41
+ translate var(--duration-normal) var(--ease-apple-spring),
38
42
  box-shadow var(--duration-normal) var(--ease-apple);
39
43
 
40
44
  &:hover:not(:disabled) {
41
- transform: translate(var(--lift-sm), var(--lift-sm));
45
+ translate: var(--lift-sm) var(--lift-sm);
42
46
  box-shadow: var(--shadow-cartoon-lg);
43
47
  }
44
48
  }
@@ -22,6 +22,29 @@
22
22
  --dock-motion-resize: var(--duration-normal) var(--spring-snappy);
23
23
  }
24
24
 
25
+ /* Shared four-state contract — the focus-visible ring + disabled paint are
26
+ identical across every dock control, so they are expressed ONCE here as a
27
+ comma group over the control family rather than copied per rule-set. The
28
+ group keeps full class+pseudo specificity (NOT `:where()`, which would
29
+ zero the class and let a per-control :hover box-shadow override the focus
30
+ ring). Per-control transition extensions (the box-shadow fade on
31
+ focus-visible) stay with their own selectors below where they differ. */
32
+ .dock-icon-button:focus-visible,
33
+ .dock-tab-button:focus-visible,
34
+ .dock-select-trigger:focus-visible,
35
+ .dock-dropdown-trigger:focus-visible {
36
+ box-shadow: var(--focus-ring-shadow);
37
+ outline: none;
38
+ }
39
+
40
+ .dock-icon-button:disabled,
41
+ .dock-tab-button:disabled,
42
+ .dock-select-trigger:disabled,
43
+ .dock-dropdown-trigger:disabled {
44
+ opacity: var(--opacity-disabled);
45
+ cursor: not-allowed;
46
+ }
47
+
25
48
  .glass-dock {
26
49
  --dock-surface-blur: var(--glass-blur-dock, var(--glass-blur-wash));
27
50
  /* J.W3.C — vertical-rail max-block + horizontal max-inline caps
@@ -33,6 +56,11 @@
33
56
  --dock-wrap-max-width: calc(100vw - var(--dock-viewport-inline-gutter, 1rem));
34
57
  --dock-separator-height: calc(var(--dock-h, var(--size-icon-btn)) * 0.5);
35
58
  --dock-collapsed-hover-scale: var(--scale-hover-dock);
59
+ /* Individual-transform identity base (AQ.W3 §W3.2). `scale: 1` at rest
60
+ mints the stacking context once so a portaled popover over `--z-dock`
61
+ stays above the dock during a hover scale (the load-bearing
62
+ stacking-context guarantee). Covers every dock scale site. */
63
+ scale: 1;
36
64
  position: relative;
37
65
  display: inline-flex;
38
66
  align-items: center;
@@ -68,6 +96,7 @@
68
96
  --dock-trigger-padding-inline: var(--dock-density-compact-trigger-padding-inline, 0.4375rem);
69
97
  --dock-tab-padding-block: var(--dock-density-compact-tab-padding-block, 0.3125rem);
70
98
  --dock-tab-padding-inline: var(--dock-density-compact-tab-padding-inline, 0.625rem);
99
+ --dock-tab-h: 32px;
71
100
  }
72
101
 
73
102
  /* Comfortable density — the GlassDock default. Sits between compact
@@ -82,6 +111,7 @@
82
111
  --dock-trigger-padding-inline: var(--dock-density-comfortable-trigger-padding-inline, 0.5rem);
83
112
  --dock-tab-padding-block: var(--dock-density-comfortable-tab-padding-block, 0.4375rem);
84
113
  --dock-tab-padding-inline: var(--dock-density-comfortable-tab-padding-inline, 0.75rem);
114
+ --dock-tab-h: 38px;
85
115
  }
86
116
 
87
117
  .glass-dock[data-density="spacious"] {
@@ -94,6 +124,7 @@
94
124
  --dock-trigger-padding-inline: var(--dock-density-spacious-trigger-padding-inline, 0.625rem);
95
125
  --dock-tab-padding-block: var(--dock-density-spacious-tab-padding-block, 0.5rem);
96
126
  --dock-tab-padding-inline: var(--dock-density-spacious-tab-padding-inline, 0.875rem);
127
+ --dock-tab-h: 44px;
97
128
  }
98
129
 
99
130
  /* Audacious density — typography-forward chrome where the dock reads as
@@ -111,41 +142,13 @@
111
142
  --dock-tab-padding-block: var(--dock-density-audacious-tab-padding-block, 0.5rem);
112
143
  --dock-tab-padding-inline: var(--dock-density-audacious-tab-padding-inline, 1.5rem);
113
144
  --dock-tab-min-height: var(--dock-density-audacious-tab-min-height, 3.5rem);
145
+ --dock-tab-h: var(--dock-density-audacious-tab-min-height, 3.5rem);
114
146
  }
115
147
 
116
- /* Dock tab-button density-keyed height (R3-spec / audit-E P0-3;
117
- consolidated into dock.css at Q.W3 Lane A formerly split into
118
- utilities.css and surviving only by import-cascade accident).
119
- The four bare DockIconButton consumers solve their density-keyed
120
- height via `--dock-control-size` (set per density tier above);
121
- DockTabButton's analogous `--dock-tab-h` knob lives in the same
122
- density rungs so the tab-button row no longer free-floats to the
123
- glyph + padding sum. Compact density lands at 32px to match the
124
- deployed product's bottom-dock height. The `.dock-tab-button` rule
125
- (further down this file) consumes `--dock-tab-h`. */
126
- .glass-dock[data-density="compact"] {
127
- --dock-tab-h-compact: 32px;
128
- --dock-tab-h: var(--dock-tab-h-compact);
129
- }
130
- .glass-dock[data-density="comfortable"] {
131
- --dock-tab-h-comfortable: 38px;
132
- --dock-tab-h: var(--dock-tab-h-comfortable);
133
- }
134
- .glass-dock[data-density="spacious"] {
135
- --dock-tab-h-spacious: 44px;
136
- --dock-tab-h: var(--dock-tab-h-spacious);
137
- }
138
- .glass-dock[data-density="audacious"] {
139
- --dock-tab-h-audacious: var(--dock-density-audacious-tab-min-height, 3.5rem);
140
- --dock-tab-h: var(--dock-tab-h-audacious);
141
- }
142
-
143
- /* Density-audacious mobile carve (R3-spec / audit-D D-Rec-5;
144
- consolidated into dock.css at Q.W3 Lane A). At narrow viewports
145
- the audacious-dock label glyphs compress so the audacious chrome
146
- doesn't overflow its host: `≤14px at <480` and `15px at 480–719`.
147
- Consumer dock label spans bind `font-size: var(--dock-label-size)`
148
- (typography.css `.dock-label` recipe is the canonical consumer). */
148
+ /* Density-audacious mobile carve at narrow viewports the audacious-dock
149
+ label glyphs compress so the chrome doesn't overflow its host
150
+ (≤14px at <480, 15px at 480–719). Consumer dock label spans bind
151
+ `font-size: var(--dock-label-size)` (typography.css `.dock-label`). */
149
152
  @media (max-width: 479px) {
150
153
  .glass-dock[data-density="audacious"] {
151
154
  --dock-label-size: 14px;
@@ -188,22 +191,11 @@
188
191
  border-color var(--dock-motion-standard);
189
192
  }
190
193
 
191
- /* Z.W2.T2 — vertical rails grow-to-fit + clamp, no scroll. Per A2 §B6
192
- + A4 special-focus: canon-intent is grow-and-wrap, not scroll. The
193
- prior `overflow-y: auto` produced the "dock scrolls when it
194
- shouldn't" regression at narrow viewports; the right escape is to
195
- let descendants wrap to multiple rows (consumers opt-in via
196
- `dock-wrap`) or to clamp via `--dock-max-block-size` and let the
197
- cap fail visibly rather than mask the overflow as a scroll
198
- affordance.
199
-
200
- The edge-fade `mask-image` retired here in lockstep with the
201
- horizontal `.dock-layers` rule. With grow-to-fit + visible
202
- overflow the rail never scrolls, so a scroll-feather mask has
203
- nothing to feather — it only bled a transparent ramp onto the
204
- top and bottom rail items, casting a stray directional shadow
205
- on those edge controls. J.W3.C's auto + mask-fade shape is fully
206
- superseded: grow-to-fit is the whole contract, no feather. */
194
+ /* Vertical rails grow-to-fit + clamp, no scroll: descendants wrap to
195
+ multiple rows (opt-in via `dock-wrap`) or clamp via
196
+ `--dock-max-block-size`; the cap fails visibly rather than masking
197
+ overflow as a scroll affordance. No edge-fade mask a rail that never
198
+ scrolls has nothing to feather. */
207
199
  .glass-dock.vertical {
208
200
  display: inline-flex;
209
201
  flex-direction: column;
@@ -321,7 +313,7 @@
321
313
  background: var(--glass-bg-wash);
322
314
  border-color: var(--glass-border-floating);
323
315
  box-shadow: var(--shadow-dock-override, var(--shadow-dock));
324
- transform: scale(var(--dock-collapsed-hover-scale));
316
+ scale: var(--dock-collapsed-hover-scale);
325
317
  }
326
318
 
327
319
  /* J.W5.C — held-state substrate response.
@@ -344,6 +336,15 @@
344
336
  box-shadow var(--duration-fast) var(--ease-standard);
345
337
  }
346
338
 
339
+ /* AQ.W3 §W3.1b — open-descendant surface response. When a dock-hosted
340
+ trigger (`[data-state="open"]`) is open, the dock root holds its elevated
341
+ read natively (no consumer JS). Idempotent with `[data-held]` above (same
342
+ floating paint, different trigger). Decorative; `:has()` Baseline Widely. */
343
+ .glass-dock:has([data-state="open"]) {
344
+ background: var(--glass-bg-floating, var(--glass-bg-resting));
345
+ border-color: var(--glass-border-floating, var(--glass-border-resting));
346
+ }
347
+
347
348
  .glass-dock:where(.fixed) {
348
349
  z-index: var(--z-dock);
349
350
  }
@@ -382,23 +383,11 @@
382
383
  transition: width var(--dock-motion-resize);
383
384
  }
384
385
 
385
- /* Z.W2.T2 — horizontal dock content grows visibly when the active
386
- layer's natural width exceeds the dock's content area. Per
387
- A2 §B6 + A4 special-focus: the canon-intent for the bottom dock
388
- is grow-to-fit; consumers needing wrap opt into `dock-wrap`. The
389
- prior `overflow-x: auto` produced the user-reported "dock scrolls
390
- when it shouldn't" — the wrong escape valve.
391
-
392
- The edge-fade `mask-image` retired here. Once Z.W2.T2 made the
393
- dock grow-to-fit, content is never clipped and never scrolls, so
394
- the mask had nothing left to feather — it was kept only "for
395
- visual symmetry" with the vertical rule. In practice the 1rem
396
- transparent ramp at each edge bled onto the first and last dock
397
- items: the rightmost control (e.g. a settings cog) had its outer
398
- edge faded into the glass backdrop, which read as a stray
399
- directional shadow on that item. A scroll-affordance feather on
400
- a surface that never scrolls is pure cosmetic damage, so it is
401
- removed at the root rather than masked per-consumer. */
386
+ /* Horizontal dock content grows visibly when the active layer's natural
387
+ width exceeds the content area (grow-to-fit; consumers needing wrap opt
388
+ into `dock-wrap`). No edge-fade mask content never clips or scrolls,
389
+ so a feather has nothing to feather and only bleeds a stray ramp onto
390
+ the edge controls. */
402
391
  .glass-dock.expanded:not(.dock-wrap) > .dock-layers {
403
392
  overflow-x: visible;
404
393
  }
@@ -650,11 +639,30 @@
650
639
  min-width: 0;
651
640
  }
652
641
 
642
+ /* AP.W3 — axis-aware layer pane. The stack + `useLayerTransition` are
643
+ axis-aware, but the pane was hardcoded to a no-wrap ROW with
644
+ `width: max-content` — forcing a `vertical` group's content onto one
645
+ horizontal line that could not grow down (the vertical-overflow fight).
646
+ A vertical group stacks in a column, stretches, wraps, and block-sizes
647
+ to the height the stack animates. Horizontal byte-identical. */
648
+ .dock-layer-group.vertical .dock-layer-item-host {
649
+ flex-direction: column;
650
+ align-items: stretch;
651
+ white-space: normal;
652
+ }
653
+
654
+ .dock-layer-group.vertical .dock-layer-item-host.is-active {
655
+ width: auto;
656
+ height: max-content;
657
+ }
658
+
653
659
  .dock-icon-button {
654
660
  display: inline-flex;
655
661
  align-items: center;
656
662
  justify-content: center;
657
663
  flex-shrink: 0;
664
+ /* AQ.W3 §W3.2 identity base */
665
+ scale: 1;
658
666
  width: var(--dock-control-size, var(--size-icon-btn));
659
667
  height: var(--dock-control-size, var(--size-icon-btn));
660
668
  padding: var(--dock-icon-padding, 0);
@@ -667,7 +675,7 @@
667
675
  transition:
668
676
  background-color var(--dock-motion-fast),
669
677
  color var(--dock-motion-fast),
670
- transform var(--dock-motion-fast),
678
+ scale var(--dock-motion-fast),
671
679
  opacity var(--dock-motion-fast);
672
680
  }
673
681
 
@@ -681,11 +689,11 @@
681
689
  .dock-icon-button:hover:not(:disabled) {
682
690
  background: var(--muted);
683
691
  color: var(--btn-hover-color, var(--foreground));
684
- transform: scale(var(--scale-hover-dock));
692
+ scale: var(--scale-hover-dock);
685
693
  }
686
694
 
687
695
  .dock-icon-button:active:not(:disabled) {
688
- transform: scale(var(--scale-press-dock));
696
+ scale: var(--scale-press-dock);
689
697
  }
690
698
 
691
699
  .dock-icon-button:focus:not(:focus-visible) {
@@ -693,22 +701,17 @@
693
701
  outline: none;
694
702
  }
695
703
 
704
+ /* focus-visible ring + disabled paint hoisted to the shared `:where()`
705
+ group at the top; this rule adds only the box-shadow fade transition. */
696
706
  .dock-icon-button:focus-visible {
697
- box-shadow: var(--focus-ring-shadow);
698
- outline: none;
699
707
  transition:
700
708
  background-color var(--dock-motion-fast),
701
709
  color var(--dock-motion-fast),
702
- transform var(--dock-motion-fast),
710
+ scale var(--dock-motion-fast),
703
711
  opacity var(--dock-motion-fast),
704
712
  box-shadow var(--dock-motion-fast);
705
713
  }
706
714
 
707
- .dock-icon-button:disabled {
708
- opacity: var(--opacity-disabled);
709
- cursor: not-allowed;
710
- }
711
-
712
715
  /* O.W6 Lane B — token-ladder active paint. Defaults match the prior
713
716
  hardcoded recipe (--muted bg + --foreground color, no transform / border
714
717
  / shadow). Consumers override the active variant via the
@@ -718,7 +721,7 @@
718
721
  .dock-icon-button:is(.is-active, .active, [aria-expanded="true"], [aria-pressed="true"]) {
719
722
  background: var(--dock-active-bg);
720
723
  color: var(--dock-active-color);
721
- transform: scale(var(--dock-active-scale));
724
+ scale: var(--dock-active-scale);
722
725
  border: var(--dock-active-border);
723
726
  box-shadow: var(--dock-active-shadow);
724
727
  }
@@ -822,10 +825,12 @@
822
825
  cursor: pointer;
823
826
  white-space: nowrap;
824
827
  outline: none;
828
+ /* AQ.W3 §W3.2 identity base */
829
+ scale: 1;
825
830
  transition:
826
831
  background-color var(--dock-motion-fast),
827
832
  color var(--dock-motion-fast),
828
- transform var(--dock-motion-fast);
833
+ scale var(--dock-motion-fast);
829
834
  }
830
835
 
831
836
  .dock-tab-button:hover:not(:disabled) {
@@ -834,22 +839,15 @@
834
839
  }
835
840
 
836
841
  .dock-tab-button:active:not(:disabled) {
837
- transform: scale(var(--scale-press-dock));
842
+ scale: var(--scale-press-dock);
838
843
  }
839
844
 
840
845
  .dock-tab-button:focus:not(:focus-visible) {
841
846
  box-shadow: none;
842
847
  }
843
848
 
844
- .dock-tab-button:focus-visible {
845
- box-shadow: var(--focus-ring-shadow);
846
- outline: none;
847
- }
848
-
849
- .dock-tab-button:disabled {
850
- opacity: var(--opacity-disabled);
851
- cursor: not-allowed;
852
- }
849
+ /* focus-visible ring + disabled paint hoisted to the shared `:where()`
850
+ group at the top. */
853
851
 
854
852
  .dock-tab-button:is(.is-active, .active, [aria-current="page"], [aria-pressed="true"]) {
855
853
  background: var(--surface-tint-10);
@@ -958,6 +956,8 @@
958
956
  align-items: center;
959
957
  justify-content: center;
960
958
  flex-shrink: 0;
959
+ /* AQ.W3 §W3.2 identity base */
960
+ scale: 1;
961
961
  gap: var(--dock-trigger-gap, 0.25rem);
962
962
  min-height: var(--dock-trigger-min-height, auto);
963
963
  padding:
@@ -973,7 +973,7 @@
973
973
  transition:
974
974
  background-color var(--dock-motion-fast),
975
975
  color var(--dock-motion-fast),
976
- transform var(--dock-motion-fast),
976
+ scale var(--dock-motion-fast),
977
977
  opacity var(--dock-motion-fast);
978
978
  }
979
979
 
@@ -984,12 +984,12 @@
984
984
  }
985
985
 
986
986
  .dock-dropdown-trigger:hover:not(:disabled) {
987
- transform: scale(var(--scale-hover-dock));
987
+ scale: var(--scale-hover-dock);
988
988
  }
989
989
 
990
990
  .dock-select-trigger:active:not(:disabled),
991
991
  .dock-dropdown-trigger:active:not(:disabled) {
992
- transform: scale(var(--scale-press-dock));
992
+ scale: var(--scale-press-dock);
993
993
  }
994
994
 
995
995
  .dock-select-trigger:focus:not(:focus-visible),
@@ -998,24 +998,18 @@
998
998
  outline: none;
999
999
  }
1000
1000
 
1001
+ /* focus-visible ring + disabled paint hoisted to the shared `:where()`
1002
+ group at the top; this rule adds only the box-shadow fade transition. */
1001
1003
  .dock-select-trigger:focus-visible,
1002
1004
  .dock-dropdown-trigger:focus-visible {
1003
- box-shadow: var(--focus-ring-shadow);
1004
- outline: none;
1005
1005
  transition:
1006
1006
  background-color var(--dock-motion-fast),
1007
1007
  color var(--dock-motion-fast),
1008
- transform var(--dock-motion-fast),
1008
+ scale var(--dock-motion-fast),
1009
1009
  opacity var(--dock-motion-fast),
1010
1010
  box-shadow var(--dock-motion-fast);
1011
1011
  }
1012
1012
 
1013
- .dock-select-trigger:disabled,
1014
- .dock-dropdown-trigger:disabled {
1015
- opacity: var(--opacity-disabled);
1016
- cursor: not-allowed;
1017
- }
1018
-
1019
1013
  .dock-select-trigger:is(.is-active, .active, [aria-expanded="true"], [aria-pressed="true"]),
1020
1014
  .dock-dropdown-trigger:is(.is-active, .active, [aria-expanded="true"], [aria-pressed="true"]) {
1021
1015
  background: var(--muted);
@@ -1027,11 +1021,14 @@
1027
1021
  height: var(--dock-trigger-icon-size, 0.75rem);
1028
1022
  flex-shrink: 0;
1029
1023
  opacity: 0.5;
1030
- transition: transform var(--dock-motion-fast);
1024
+ /* Individual-transform identity base (AQ.W3 §W3.2) — `rotate:` longhand
1025
+ for family consistency (not a stacking-context hazard: child glyph). */
1026
+ rotate: 0deg;
1027
+ transition: rotate var(--dock-motion-fast);
1031
1028
  }
1032
1029
 
1033
1030
  .dock-select-trigger[data-state="open"] .dock-select-trigger__chevron {
1034
- transform: rotate(180deg);
1031
+ rotate: 180deg;
1035
1032
  }
1036
1033
 
1037
1034
  @media (min-width: 640px) {
@@ -1072,12 +1069,15 @@
1072
1069
  that wires `var(--size-icon-btn)` for trigger sizing) inherit
1073
1070
  the same floor.
1074
1071
 
1075
- Density overrides (`[data-density="compact"]` etc.) still win
1076
- inside `@layer components` ordering consumers that explicitly
1077
- opt into compact density on touch devices get their compact size
1078
- back. The media-query only lifts the *default* path. */
1072
+ AP.W3 R0G-6 — selector is `.glass-dock[data-density]`, not bare
1073
+ `.glass-dock`: the always-present density setter (0,2,0) shadowed a
1074
+ bare (0,1,0) coarse floor, pinning the touch box at 40px. The
1075
+ presence-selector (0,2,0) wins by source order, lifting
1076
+ `--dock-control-size` to 44px — read by both the button box and the
1077
+ dock width-math, so the slot reserves 44px (no overflow). Fine pointer
1078
+ byte-identical. Proof: design/W1.2-motion-carve-and-dock.md §B.2. */
1079
1079
  @media (pointer: coarse) {
1080
- .glass-dock {
1080
+ .glass-dock[data-density] {
1081
1081
  --dock-control-size: var(--dock-touch-target, 2.75rem);
1082
1082
  --size-icon-btn: var(--dock-touch-target, 2.75rem);
1083
1083
  }
@@ -46,7 +46,7 @@
46
46
  border-bottom: 0;
47
47
  border-start-start-radius: var(--radius-panel);
48
48
  border-start-end-radius: var(--radius-panel);
49
- background-color: hsl(var(--background));
49
+ background-color: var(--background);
50
50
  box-shadow: var(--shadow-2xl);
51
51
  }
52
52
 
@@ -98,7 +98,7 @@
98
98
  width: var(--drawer-handle-w);
99
99
  height: var(--drawer-handle-h);
100
100
  border-radius: var(--radius-pill);
101
- background-color: hsl(var(--drawer-handle-color));
101
+ background-color: var(--drawer-handle-color);
102
102
  opacity: var(--drawer-handle-opacity);
103
103
  transition: opacity var(--duration-fast) var(--ease-out),
104
104
  width var(--duration-fast) var(--ease-out);