@mkbabb/glass-ui 3.1.1 → 3.2.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 (158) hide show
  1. package/dist/{CardFooter-CSGcJkqa.js → CardFooter-3-VGho1J.js} +1 -1
  2. package/dist/{CommandShortcut-DWT19a2Y.js → CommandShortcut-C6lsz3pG.js} +3 -3
  3. package/dist/{ContextMenuSubContent-gAFxJ-qi.js → ContextMenuSubContent-DrWkXKQP.js} +4 -4
  4. package/dist/{DataTable-R8-Zidms.js → DataTable-BsrDYdoE.js} +3 -3
  5. package/dist/{DialogContent-2fALDSvc.js → DialogContent-B61rP8lj.js} +3 -3
  6. package/dist/{DialogFooter-ClrNEOVU.js → DialogFooter-Er0wA3K6.js} +2 -2
  7. package/dist/{DiscoGlyph-C3JfMnRV.js → DiscoGlyph-B7YooI2-.js} +1 -1
  8. package/dist/{GlyphFace-BRS8vUb7.js → GlyphFace-Bvk6OIas.js} +1 -1
  9. package/dist/{HoverPopover-CWFCfLx3.js → HoverPopover-BlEwqG7S.js} +1 -1
  10. package/dist/{IconTooltip-BkaA7tZ2.js → IconTooltip-DXveGjx7.js} +1 -1
  11. package/dist/{MetricBadge-DmAihkXd.js → MetricBadge-J_GBCb8e.js} +1 -1
  12. package/dist/{Notification-OqIpADml.js → Notification-DP_ApJLo.js} +3 -3
  13. package/dist/{NumberFieldContent-DTH9gb_N.js → NumberFieldContent-B6L6YrQz.js} +2 -2
  14. package/dist/{PopoverContent-EiklFrna.js → PopoverContent-CxEEUL7Y.js} +1 -1
  15. package/dist/{Progress-FApA9fm_.js → Progress-Bs44qWEM.js} +1 -1
  16. package/dist/{ScrollingText-BFd0i2zJ.js → ScrollingText-1Qjnwz6H.js} +2 -2
  17. package/dist/{SelectScrollDownButton-Dth8-wXQ.js → SelectScrollDownButton-BvvvAbuh.js} +4 -4
  18. package/dist/{Toaster-Bjlunvq4.js → Toaster-Brs6QjBU.js} +1 -1
  19. package/dist/{UnderlineTabs-DAWMLmJG.js → UnderlineTabs-B4FV2zi_.js} +1 -1
  20. package/dist/animated-digit.js +2 -2
  21. package/dist/api.js +1 -1
  22. package/dist/aurora.js +118 -150
  23. package/dist/badge.js +1 -1
  24. package/dist/button.js +1 -1
  25. package/dist/card.js +1 -1
  26. package/dist/carousel.js +5 -5
  27. package/dist/{check-dwgetki8.js → check-CdkxGxXJ.js} +1 -1
  28. package/dist/{chevron-down-DILQA1t6.js → chevron-down-pBY8sYfV.js} +1 -1
  29. package/dist/{chevron-right-fS7fal2t.js → chevron-right-BjeKC22V.js} +1 -1
  30. package/dist/{chevron-up-BtYjYQOS.js → chevron-up-DBeNHUm1.js} +1 -1
  31. package/dist/collapsible.js +1 -1
  32. package/dist/command.js +1 -1
  33. package/dist/components/custom/aurora/composables/color.d.ts +56 -8
  34. package/dist/components/custom/aurora/index.d.ts +2 -1
  35. package/dist/components/custom/aurora/presets.d.ts +1 -1
  36. package/dist/components/custom/aurora/shaders/aurora.frag.d.ts +1 -1
  37. package/dist/components/custom/configurator/Configurator.vue.d.ts +26 -0
  38. package/dist/components/custom/configurator/index.d.ts +1 -1
  39. package/dist/components/custom/dock/DockIconButton.vue.d.ts +14 -3
  40. package/dist/components/custom/dock/GlassDock.vue.d.ts +17 -0
  41. package/dist/composables/dom/index.d.ts +1 -0
  42. package/dist/composables/dom/useTextHighlight.d.ts +40 -0
  43. package/dist/composables/motion/core/index.d.ts +1 -0
  44. package/dist/composables/motion/usePrioritizedTask.d.ts +41 -0
  45. package/dist/composables/sortable/useSortable.d.ts +13 -0
  46. package/dist/configurator.js +1 -1
  47. package/dist/confirm-dialog.js +3 -3
  48. package/dist/context-menu.js +2 -2
  49. package/dist/controls.js +2 -2
  50. package/dist/dark.js +1 -1
  51. package/dist/data-table.js +1 -1
  52. package/dist/dialog.js +2 -2
  53. package/dist/disco-glyph.js +1 -1
  54. package/dist/dock.js +98 -81
  55. package/dist/dom.js +6 -5
  56. package/dist/{dropdown-menu-BvRUamNs.js → dropdown-menu-naE0skDg.js} +4 -4
  57. package/dist/dropdown-menu.js +1 -1
  58. package/dist/expandable-container.js +2 -2
  59. package/dist/forms.js +4 -4
  60. package/dist/glass-carousel.js +59 -52
  61. package/dist/glass-panel.js +2 -2
  62. package/dist/glass-ui.css +1 -1
  63. package/dist/glass-ui.js +231 -224
  64. package/dist/glyph-face.js +2 -2
  65. package/dist/header-ribbon.js +1 -1
  66. package/dist/hover-card.js +1 -1
  67. package/dist/hover-popover.js +1 -1
  68. package/dist/icon-tooltip.js +1 -1
  69. package/dist/instrument-chassis.js +1 -1
  70. package/dist/instrument-rail.js +1 -1
  71. package/dist/keyboard.js +1 -1
  72. package/dist/label.js +1 -1
  73. package/dist/labeled-field.js +6 -6
  74. package/dist/metric-badge.js +1 -1
  75. package/dist/metric-stack.js +1 -1
  76. package/dist/{minimize-2-LsCJ_eNt.js → minimize-2-BP27-qBY.js} +1 -1
  77. package/dist/motion-core.js +155 -95
  78. package/dist/motion.js +3 -3
  79. package/dist/notification.js +1 -1
  80. package/dist/number-field.js +1 -1
  81. package/dist/paper-backdrop.js +1 -1
  82. package/dist/popover.js +1 -1
  83. package/dist/{presets-a-D93K1S.js → presets-BpTf63Hp.js} +4 -4
  84. package/dist/progress.js +1 -1
  85. package/dist/pulse.js +1 -1
  86. package/dist/reactive.js +2 -2
  87. package/dist/responsive-tabs.js +2 -2
  88. package/dist/scrolling-text.js +1 -1
  89. package/dist/{search-DBAiUABx.js → search-DBG8qaRs.js} +1 -1
  90. package/dist/search.js +153 -149
  91. package/dist/select.js +3 -3
  92. package/dist/separator.js +1 -1
  93. package/dist/{sheet-CukNDezz.js → sheet-BnvZRXPq.js} +3 -3
  94. package/dist/sheet.js +1 -1
  95. package/dist/{slider-DJvHkTRe.js → slider-wx8ifVFB.js} +3 -3
  96. package/dist/slider.js +1 -1
  97. package/dist/sortable-list.js +2 -2
  98. package/dist/styles/components.css +45 -0
  99. package/dist/styles/dock.css +71 -2
  100. package/dist/styles/index.css +5 -1
  101. package/dist/styles/tokens.css +11 -0
  102. package/dist/styles/utilities.css +56 -0
  103. package/dist/supportsCssTimeline-IQY3gfKD.js +12 -0
  104. package/dist/switch.js +1 -1
  105. package/dist/tabs.js +25 -10
  106. package/dist/timeline.js +2 -2
  107. package/dist/toast.js +1 -1
  108. package/dist/toggle-group.js +1 -1
  109. package/dist/tooltip.js +1 -1
  110. package/dist/typewriter.js +1 -1
  111. package/dist/{useAnimatedNumber-DKQYVB7s.js → useAnimatedNumber-BOxrS3a6.js} +1 -1
  112. package/dist/{useConfiguratorState-CtRBE0m_.js → useConfiguratorState-Dq2gNv4A.js} +52 -40
  113. package/dist/{useIdleReady-Cmkhm03v.js → useIdleReady-sLhGo6CL.js} +1 -1
  114. package/dist/useSortable-DLK9kwZp.js +189 -0
  115. package/dist/useTextHighlight-CLST6an0.js +72 -0
  116. package/dist/{useTouchGate-D9Zvrzyc.js → useTouchGate-XX8gHfay.js} +1 -1
  117. package/dist/{useViewTransition-DYIK6Gzb.js → useViewTransition-CUJM7fXT.js} +5 -3
  118. package/dist/utils/index.d.ts +2 -1
  119. package/dist/utils/platformSupport.d.ts +8 -0
  120. package/dist/{x-q7pJa83X.js → x-C4pz9nbD.js} +1 -1
  121. package/package.json +13 -3
  122. package/src/styles/dock.css +71 -2
  123. package/src/styles/index.css +1 -1
  124. package/src/styles/tokens.css +11 -0
  125. package/src/styles/utilities.css +56 -0
  126. package/dist/useSortable-Cq2Y1JLO.js +0 -175
  127. /package/dist/{CollapsibleContent-CVMOcYlV.js → CollapsibleContent-wlmlDujU.js} +0 -0
  128. /package/dist/{ContextMenuContent-otjFIu8v.js → ContextMenuContent-De01_83g.js} +0 -0
  129. /package/dist/{HoverCardContent-DaGrgJBO.js → HoverCardContent-DGUhpRVt.js} +0 -0
  130. /package/dist/{Input-DDpFn568.js → Input-IFsIzId2.js} +0 -0
  131. /package/dist/{InstrumentChassis-CnHTMxds.js → InstrumentChassis-CqKPBNqp.js} +0 -0
  132. /package/dist/{InstrumentRail-C6dEbi8E.js → InstrumentRail-CCjvKkpB.js} +0 -0
  133. /package/dist/{Label-DJty89bp.js → Label-D53EOwLE.js} +0 -0
  134. /package/dist/{ModalOverlay-iWiAgbYH.js → ModalOverlay-B_CBtqcE.js} +0 -0
  135. /package/dist/{PaperBackdrop-CeZ-w0R0.js → PaperBackdrop-Ds-wDsKf.js} +0 -0
  136. /package/dist/{SelectGroup-DdR4tdDY.js → SelectGroup-DAgcsfFw.js} +0 -0
  137. /package/dist/{SelectSeparator-CXm_hlqA.js → SelectSeparator-DN1jzLaI.js} +0 -0
  138. /package/dist/{Separator-D8AUMhxY.js → Separator-DXxac0j8.js} +0 -0
  139. /package/dist/{Switch-Cr1t_F_U.js → Switch-imA0Hdjs.js} +0 -0
  140. /package/dist/{ToggleGroupItem-OesUouE7.js → ToggleGroupItem-Cy7xHFEo.js} +0 -0
  141. /package/dist/{TooltipProvider-DE78vbEP.js → TooltipProvider-MZFRxOvT.js} +0 -0
  142. /package/dist/{_plugin-vue_export-helper-Dq1MygBL.js → _plugin-vue_export-helper-C1je1s0u.js} +0 -0
  143. /package/dist/{badge-x46my_Fo.js → badge-Cl6JZ1B7.js} +0 -0
  144. /package/dist/{button-C0aHmBbt.js → button-DS3ULf5i.js} +0 -0
  145. /package/dist/{constants-DwBwnG8N.js → constants-DfWPi8kh.js} +0 -0
  146. /package/dist/{createLucideIcon-Bn9a1b70.js → createLucideIcon-DuDoe_ra.js} +0 -0
  147. /package/dist/{dockContext-D5NZCWJs.js → dockContext-DM58L1Jt.js} +0 -0
  148. /package/dist/{keys-CaTQS-vx.js → keys-SIKQYNx1.js} +0 -0
  149. /package/dist/{menuItemVariants-BsbGNq9C.js → menuItemVariants-C2QlXqT3.js} +0 -0
  150. /package/dist/{useGlassRenderer-Ds-nmrGz.js → useGlassRenderer-C98tZnJ7.js} +0 -0
  151. /package/dist/{useGlobalDark-B0WvLJE3.js → useGlobalDark-BUUTZvkU.js} +0 -0
  152. /package/dist/{useIntersectionPause-IY2CwPQb.js → useIntersectionPause-CUmANkoc.js} +0 -0
  153. /package/dist/{useInterval-DVgGUf_y.js → useInterval-B58LmYth.js} +0 -0
  154. /package/dist/{useKeyboardShortcuts-Dpw_RUcB.js → useKeyboardShortcuts-BQfnAHHW.js} +0 -0
  155. /package/dist/{useResizeObserver-Cg9npuM3.js → useResizeObserver-C_7GjpRn.js} +0 -0
  156. /package/dist/{useSpringMount-Cfk1XK1R.js → useSpringMount-CnizvZGm.js} +0 -0
  157. /package/dist/{useTimer-NAaj9zNq.js → useTimer-6FoosoDY.js} +0 -0
  158. /package/dist/{useUserInvalidAria-DVu1eTXG.js → useUserInvalidAria-BW5iyqWR.js} +0 -0
@@ -1,8 +1,8 @@
1
1
  import { t as e } from "./cn-DJXf4yaB.js";
2
- import { t } from "./createLucideIcon-Bn9a1b70.js";
3
- import { t as n } from "./chevron-down-DILQA1t6.js";
4
- import { t as r } from "./_plugin-vue_export-helper-Dq1MygBL.js";
5
- import { t as i } from "./Label-DJty89bp.js";
2
+ import { t } from "./createLucideIcon-DuDoe_ra.js";
3
+ import { t as n } from "./chevron-down-pBY8sYfV.js";
4
+ import { t as r } from "./_plugin-vue_export-helper-C1je1s0u.js";
5
+ import { t as i } from "./Label-D53EOwLE.js";
6
6
  import { Fragment as a, computed as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, inject as p, normalizeClass as m, normalizeStyle as h, openBlock as g, provide as _, reactive as v, ref as y, renderList as b, renderSlot as x, toDisplayString as S, toRaw as C, unref as w, useId as T, watch as E, withCtx as D } from "vue";
7
7
  var O = t("rotate-ccw", [["path", {
8
8
  d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
@@ -19,17 +19,17 @@ function j() {
19
19
  }
20
20
  //#endregion
21
21
  //#region src/components/custom/configurator/Configurator.vue?vue&type=script&setup=true&lang.ts
22
- var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }, N = { class: "configurator-aside flex min-h-0 min-w-0 flex-col border-t border-border/40 lg:border-l lg:border-t-0" }, P = {
22
+ var M = {
23
23
  key: 0,
24
24
  class: "configurator-presets shrink-0 border-b border-border/40 px-3 py-2"
25
- }, F = {
25
+ }, N = {
26
26
  class: "flex gap-2 overflow-x-auto scroll-fade-mask scrollbar-hidden",
27
27
  role: "tablist",
28
28
  "aria-label": "Presets"
29
- }, I = ["aria-selected", "onClick"], L = { class: "flex flex-col" }, R = {
29
+ }, P = ["aria-selected", "onClick"], F = { class: "flex flex-col" }, I = {
30
30
  key: 1,
31
31
  class: "configurator-footer shrink-0 border-t border-border/40 px-3 py-2"
32
- }, z = /* @__PURE__ */ f({
32
+ }, L = /* @__PURE__ */ f({
33
33
  __name: "Configurator",
34
34
  props: {
35
35
  presets: {},
@@ -38,6 +38,8 @@ var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }
38
38
  activeLayer: {},
39
39
  scrollMode: { default: "auto" },
40
40
  density: { default: "comfortable" },
41
+ asideSide: { default: "right" },
42
+ asideWidth: {},
41
43
  class: { type: [
42
44
  Boolean,
43
45
  null,
@@ -54,46 +56,56 @@ var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }
54
56
  setup(t, { emit: n }) {
55
57
  let r = t;
56
58
  A(o(() => r.density));
57
- let i = n, u = o(() => e("configurator glass-floating rounded-panel border border-border/60 overflow-hidden", "grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_minmax(280px,360px)]", "min-h-0", r.class)), d = o(() => {
59
+ let i = n, u = o(() => e("configurator glass-floating rounded-panel border border-border/60 overflow-hidden", "grid grid-cols-1", "lg:grid-cols-[minmax(0,1fr)_minmax(var(--configurator-aside-min,280px),var(--configurator-aside-max,360px))]", "min-h-0", r.class)), d = o(() => {
60
+ if (r.asideWidth == null) return;
61
+ let [e, t] = Array.isArray(r.asideWidth) ? r.asideWidth : [r.asideWidth, r.asideWidth];
62
+ return {
63
+ "--configurator-aside-min": e,
64
+ "--configurator-aside-max": t
65
+ };
66
+ }), f = o(() => r.asideSide === "left" ? "lg:col-start-2" : ""), p = o(() => r.asideSide === "left" ? "lg:col-start-1 lg:row-start-1" : ""), _ = o(() => r.asideSide === "left" ? "lg:border-r lg:border-l-0" : "lg:border-l"), v = o(() => {
58
67
  switch (r.scrollMode) {
59
68
  case "always": return "overflow-y-auto scroll-fade-y scrollbar-thin";
60
69
  case "never": return "overflow-visible";
61
70
  default: return "overflow-y-auto scroll-fade-y scrollbar-thin";
62
71
  }
63
72
  });
64
- return (n, r) => (g(), c("section", { class: m(u.value) }, [l("div", M, [x(n.$slots, "stage")]), l("aside", N, [
65
- n.$slots.presets || t.presets && t.presets.length > 0 ? (g(), c("div", P, [x(n.$slots, "presets", {
73
+ return (n, r) => (g(), c("section", {
74
+ class: m(u.value),
75
+ style: h(d.value)
76
+ }, [l("div", { class: m(w(e)("configurator-stage relative min-h-0 min-w-0 overflow-hidden", f.value)) }, [x(n.$slots, "stage")], 2), l("aside", { class: m(w(e)("configurator-aside flex min-h-0 min-w-0 flex-col border-t border-border/40 lg:border-t-0", _.value, p.value)) }, [
77
+ n.$slots.presets || t.presets && t.presets.length > 0 ? (g(), c("div", M, [x(n.$slots, "presets", {
66
78
  presets: t.presets,
67
79
  activePreset: t.activePreset
68
- }, () => [l("div", F, [(g(!0), c(a, null, b(t.presets, (n) => (g(), c("button", {
80
+ }, () => [l("div", N, [(g(!0), c(a, null, b(t.presets, (n) => (g(), c("button", {
69
81
  key: n.key,
70
82
  type: "button",
71
83
  role: "tab",
72
84
  "aria-selected": n.key === t.activePreset,
73
85
  class: m(w(e)("focus-ring shrink-0 rounded-pill border px-3 py-1 text-xs font-medium transition-colors", n.key === t.activePreset ? "border-foreground/40 bg-foreground text-background" : "border-border/40 bg-card/40 text-foreground hover:bg-card/70")),
74
86
  onClick: (e) => i("select-preset", n.key)
75
- }, S(n.label), 11, I))), 128))])])])) : s("", !0),
76
- l("div", { class: m(w(e)("configurator-controls flex-1 min-h-0", d.value)) }, [x(n.$slots, "controls", {
87
+ }, S(n.label), 11, P))), 128))])])])) : s("", !0),
88
+ l("div", { class: m(w(e)("configurator-controls flex-1 min-h-0", v.value)) }, [x(n.$slots, "controls", {
77
89
  layers: t.layers,
78
90
  activeLayer: t.activeLayer,
79
91
  selectLayer: (e) => i("select-layer", e)
80
- }, () => [l("div", L, [x(n.$slots, "default")])])], 2),
81
- n.$slots.footer ? (g(), c("div", R, [x(n.$slots, "footer", { reset: () => i("reset") })])) : s("", !0)
82
- ])], 2));
92
+ }, () => [l("div", F, [x(n.$slots, "default")])])], 2),
93
+ n.$slots.footer ? (g(), c("div", I, [x(n.$slots, "footer", { reset: () => i("reset") })])) : s("", !0)
94
+ ], 2)], 6));
83
95
  }
84
- }), B = ["data-state"], V = [
96
+ }), R = ["data-state"], z = [
85
97
  "aria-expanded",
86
98
  "aria-controls",
87
99
  "data-state"
88
- ], H = { class: "flex min-w-0 items-baseline gap-2" }, U = { class: "text-sm font-semibold text-foreground" }, W = {
100
+ ], B = { class: "flex min-w-0 items-baseline gap-2" }, V = { class: "text-sm font-semibold text-foreground" }, H = {
89
101
  key: 0,
90
102
  class: "truncate text-micro font-mono text-muted-foreground/70"
91
- }, G = [
103
+ }, U = [
92
104
  "id",
93
105
  "aria-hidden",
94
106
  "inert",
95
107
  "data-state"
96
- ], K = { class: "min-h-0 overflow-hidden" }, q = /* @__PURE__ */ f({
108
+ ], W = { class: "min-h-0 overflow-hidden" }, G = /* @__PURE__ */ f({
97
109
  __name: "ConfiguratorLayer",
98
110
  props: {
99
111
  label: {},
@@ -144,26 +156,26 @@ var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }
144
156
  "aria-controls": p.value,
145
157
  "data-state": v.value,
146
158
  onClick: _
147
- }, [l("div", H, [l("span", U, S(t.label), 1), t.sub ? (g(), c("span", W, S(t.sub), 1)) : s("", !0)]), d(w(n), {
159
+ }, [l("div", B, [l("span", V, S(t.label), 1), t.sub ? (g(), c("span", H, S(t.sub), 1)) : s("", !0)]), d(w(n), {
148
160
  class: "h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-180",
149
161
  "aria-hidden": "true"
150
- })], 10, V), l("div", {
162
+ })], 10, z), l("div", {
151
163
  id: p.value,
152
164
  role: "region",
153
165
  "aria-hidden": !u.value,
154
- inert: !u.value,
166
+ inert: !u.value || void 0,
155
167
  "data-state": v.value,
156
168
  class: "configurator-layer-region grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
157
169
  style: h({ gridTemplateRows: u.value ? "1fr" : "0fr" })
158
- }, [l("div", K, [l("div", { class: m(w(e)("configurator-layer-body px-3 py-2 space-y-2", i.bodyClass)) }, [x(r.$slots, "default")], 2)])], 12, G)], 10, B));
170
+ }, [l("div", W, [l("div", { class: m(w(e)("configurator-layer-body px-3 py-2 space-y-2", i.bodyClass)) }, [x(r.$slots, "default")], 2)])], 12, U)], 10, R));
159
171
  }
160
- }), J = ["data-density"], Y = { class: "flex items-baseline justify-between gap-3" }, X = { class: "flex min-w-0 items-baseline gap-2" }, Z = {
172
+ }), K = ["data-density"], q = { class: "flex items-baseline justify-between gap-3" }, J = { class: "flex min-w-0 items-baseline gap-2" }, Y = {
161
173
  key: 0,
162
174
  class: "truncate text-micro font-mono text-muted-foreground/70"
163
- }, Q = ["aria-label"], $ = { class: "flex items-center" }, ee = {
175
+ }, X = ["aria-label"], Z = { class: "flex items-center" }, Q = {
164
176
  key: 0,
165
177
  class: "text-micro leading-snug text-muted-foreground/80"
166
- }, te = /* @__PURE__ */ r(/* @__PURE__ */ f({
178
+ }, $ = /* @__PURE__ */ r(/* @__PURE__ */ f({
167
179
  __name: "ConfiguratorRow",
168
180
  props: {
169
181
  label: {},
@@ -186,10 +198,10 @@ var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }
186
198
  class: m(w(e)("configurator-row flex flex-col gap-1.5 py-2", r.class)),
187
199
  "data-density": p.value
188
200
  }, [
189
- l("div", Y, [l("div", X, [d(w(i), { class: "truncate text-sm font-medium text-foreground" }, {
201
+ l("div", q, [l("div", J, [d(w(i), { class: "truncate text-sm font-medium text-foreground" }, {
190
202
  default: D(() => [u(S(t.label), 1)]),
191
203
  _: 1
192
- }), t.name ? (g(), c("span", Z, S(t.name), 1)) : s("", !0)]), t.canReset ? (g(), c("button", {
204
+ }), t.name ? (g(), c("span", Y, S(t.name), 1)) : s("", !0)]), t.canReset ? (g(), c("button", {
193
205
  key: 0,
194
206
  type: "button",
195
207
  class: "focus-ring inline-flex h-6 w-6 items-center justify-center rounded-pill text-muted-foreground/60 transition-colors hover:bg-foreground/5 hover:text-foreground active:scale-[var(--scale-press,0.97)]",
@@ -198,15 +210,15 @@ var M = { class: "configurator-stage relative min-h-0 min-w-0 overflow-hidden" }
198
210
  }, [d(w(O), {
199
211
  class: "h-3 w-3",
200
212
  "aria-hidden": "true"
201
- })], 8, Q)) : s("", !0)]),
202
- l("div", $, [x(n.$slots, "default", {}, void 0, !0)]),
203
- t.description ? (g(), c("p", ee, S(t.description), 1)) : s("", !0)
204
- ], 10, J));
213
+ })], 8, X)) : s("", !0)]),
214
+ l("div", Z, [x(n.$slots, "default", {}, void 0, !0)]),
215
+ t.description ? (g(), c("p", Q, S(t.description), 1)) : s("", !0)
216
+ ], 10, K));
205
217
  }
206
- }), [["__scopeId", "data-v-e6e34000"]]);
218
+ }), [["__scopeId", "data-v-7854fb95"]]);
207
219
  //#endregion
208
220
  //#region src/components/custom/configurator/useConfiguratorState.ts
209
- function ne(e) {
221
+ function ee(e) {
210
222
  let t = C(e);
211
223
  if (typeof structuredClone != "function") throw Error("[glass-ui:configurator] structuredClone is unavailable in this runtime. Pass a custom clone via ConfiguratorStateOptions.clone for environments without structured-clone support.");
212
224
  try {
@@ -215,11 +227,11 @@ function ne(e) {
215
227
  throw Error("[glass-ui:configurator] structuredClone failed: " + (e instanceof Error ? e.message : String(e)) + ". Preset values must be structured-cloneable (no functions, symbols, DOM nodes, or class instances). Pass a custom clone via ConfiguratorStateOptions.clone if the data shape requires it.");
216
228
  }
217
229
  }
218
- function re(e, t) {
230
+ function te(e, t) {
219
231
  return JSON.stringify(e) === JSON.stringify(t);
220
232
  }
221
- function ie(e) {
222
- let t = e.clone ?? ne, n = e.equals ?? re, r = e.presets, i = e.cloneMode ?? "commit-on-write", a = e.initialPreset ?? (r.length > 0 ? r[0].key : void 0), s = a ? r.find((e) => e.key === a) : void 0, c = v(s ? t(s.config) : {}), l = y(a), u = i === "per-preset" ? Object.fromEntries(r.map((e) => [e.key, t(e.config)])) : null, d = o(() => l.value), f = o(() => {
233
+ function ne(e) {
234
+ let t = e.clone ?? ee, n = e.equals ?? te, r = e.presets, i = e.cloneMode ?? "commit-on-write", a = e.initialPreset ?? (r.length > 0 ? r[0].key : void 0), s = a ? r.find((e) => e.key === a) : void 0, c = v(s ? t(s.config) : {}), l = y(a), u = i === "per-preset" ? Object.fromEntries(r.map((e) => [e.key, t(e.config)])) : null, d = o(() => l.value), f = o(() => {
223
235
  let e = l.value;
224
236
  if (!e) return !1;
225
237
  let t = r.find((t) => t.key === e);
@@ -265,4 +277,4 @@ function ie(e) {
265
277
  };
266
278
  }
267
279
  //#endregion
268
- export { k as a, z as i, te as n, A as o, q as r, j as s, ie as t };
280
+ export { k as a, L as i, $ as n, A as o, G as r, j as s, ne as t };
@@ -1,4 +1,4 @@
1
- import { t as e } from "./useGlobalDark-B0WvLJE3.js";
1
+ import { t as e } from "./useGlobalDark-BUUTZvkU.js";
2
2
  import { getCurrentScope as t, onMounted as n, onScopeDispose as r, readonly as i, ref as a, toValue as o, watch as s } from "vue";
3
3
  //#region src/composables/dom/useTokenColor.ts
4
4
  function c(t, r = {}) {
@@ -0,0 +1,189 @@
1
+ import { computed as e, onScopeDispose as t, shallowRef as n } from "vue";
2
+ //#region src/composables/sortable/useSortable.ts
3
+ function r(e) {
4
+ return e ? e.replace(/\//g, " ").split(/\s+/).filter(Boolean).some((e) => parseFloat(e) !== 0) : !1;
5
+ }
6
+ var i = "[data-sortable-handle]", a = "is-sortable-drop-above", o = "is-sortable-drop-below", s = "sortable-drag-ghost", c = "is-sortable-dragging", l = /* @__PURE__ */ new Set();
7
+ function u(e, t, n) {
8
+ if (!e.group) return null;
9
+ for (let r of l) {
10
+ if (r === e || r.group !== e.group) continue;
11
+ let i = r.getContainer();
12
+ if (!i) continue;
13
+ let a = i.getBoundingClientRect();
14
+ if (t >= a.left && t <= a.right && n >= a.top && n <= a.bottom) return r;
15
+ }
16
+ return null;
17
+ }
18
+ function d(d) {
19
+ let { items: f, getId: p, onReorder: m, onInsert: h, group: g, handleSelector: _ = i, axis: v = "y" } = d, y = n(null), b = n(null), x = n(null), S = null, C = null, w = 0, T = 0, E = null, D = null, O = /* @__PURE__ */ new Map(), k = /* @__PURE__ */ new Map();
20
+ function A() {
21
+ return f.value;
22
+ }
23
+ function j(e) {
24
+ let t = A();
25
+ for (let n = 0; n < t.length; n++) if (p(t[n]) === e) return n;
26
+ return -1;
27
+ }
28
+ function M(e, t, n, r, i) {
29
+ let a = i ? n : r;
30
+ for (let n = 0; n < t.length; n++) {
31
+ let r = e.get(t[n].id);
32
+ if (!r) continue;
33
+ let o = r.getBoundingClientRect();
34
+ if (a < (i ? o.left + o.width / 2 : o.top + o.height / 2)) return n;
35
+ }
36
+ return t.length;
37
+ }
38
+ function N(e, t) {
39
+ return M(O, A().map((e) => ({ id: p(e) })), e, t, v === "x");
40
+ }
41
+ function P(e) {
42
+ return _ === null ? !0 : e instanceof Element ? e.closest(_) !== null : !1;
43
+ }
44
+ function F(e) {
45
+ let t = getComputedStyle(e).borderRadius;
46
+ if (r(t)) return t;
47
+ for (let t of e.querySelectorAll("*")) {
48
+ let e = getComputedStyle(t).borderRadius;
49
+ if (r(e)) return e;
50
+ }
51
+ return null;
52
+ }
53
+ function I(e, t, n) {
54
+ let r = e.getBoundingClientRect();
55
+ w = t - r.left, T = n - r.top;
56
+ let i = e.cloneNode(!0);
57
+ i.classList.add(s);
58
+ let a = F(e);
59
+ a && (i.style.borderRadius = a), i.style.position = "fixed", i.style.left = `${r.left}px`, i.style.top = `${r.top}px`, i.style.width = `${r.width}px`, i.style.height = `${r.height}px`, i.style.margin = "0", i.style.pointerEvents = "none", i.style.zIndex = "9999", i.id && i.removeAttribute("id");
60
+ for (let e of i.querySelectorAll("[id]")) e.removeAttribute("id");
61
+ document.body.appendChild(i), C = i;
62
+ }
63
+ function L(e, t) {
64
+ C && (C.style.left = `${e - w}px`, C.style.top = `${t - T}px`);
65
+ }
66
+ function R() {
67
+ C && C.parentNode && C.parentNode.removeChild(C), C = null;
68
+ }
69
+ function z(e, t) {
70
+ let n = O.get(e);
71
+ if (!(n instanceof HTMLElement)) return;
72
+ y.value = e, b.value = {
73
+ x: t.clientX,
74
+ y: t.clientY
75
+ }, x.value = j(e), S = null, E = n, n.classList.add(c), I(n, t.clientX, t.clientY);
76
+ let r = t.currentTarget;
77
+ if (r && "setPointerCapture" in r) try {
78
+ r.setPointerCapture(t.pointerId);
79
+ } catch {}
80
+ document.addEventListener("pointermove", B), document.addEventListener("pointerup", V), document.addEventListener("pointercancel", V);
81
+ }
82
+ function B(e) {
83
+ if (y.value === null) return;
84
+ b.value = {
85
+ x: e.clientX,
86
+ y: e.clientY
87
+ }, L(e.clientX, e.clientY);
88
+ let t = u(K, e.clientX, e.clientY);
89
+ if (t) {
90
+ S && S !== t && S.setExternalDropIndex(null), S = t;
91
+ let n = t.getItems().map((e) => ({ id: t.getId(e) })), r = M(t.getElements(), n, e.clientX, e.clientY, v === "x");
92
+ t.setExternalDropIndex(r), x.value = null;
93
+ } else S &&= (S.setExternalDropIndex(null), null), x.value = N(e.clientX, e.clientY);
94
+ }
95
+ function V(e) {
96
+ let t = y.value, n = S, r = x.value;
97
+ if (H(), t === null) return;
98
+ let i = A(), a = i.findIndex((e) => p(e) === t);
99
+ if (a < 0) return;
100
+ if (n) {
101
+ let e = i[a], t = i.slice();
102
+ t.splice(a, 1), m(t);
103
+ let r = n.getExternalDropIndex?.() ?? null;
104
+ n.setExternalDropIndex(null), n.acceptExternal(r ?? 0, e);
105
+ return;
106
+ }
107
+ if (r === null) return;
108
+ let o = r;
109
+ if (o > a && --o, o === a) return;
110
+ let s = i.slice(), [c] = s.splice(a, 1);
111
+ s.splice(o, 0, c), m(s);
112
+ }
113
+ function H() {
114
+ R(), E &&= (E.classList.remove(c), null), S &&= (S.setExternalDropIndex(null), null), y.value = null, b.value = null, x.value = null, document.removeEventListener("pointermove", B), document.removeEventListener("pointerup", V), document.removeEventListener("pointercancel", V);
115
+ }
116
+ function U(t) {
117
+ let n = k.get(t);
118
+ if (n) return n;
119
+ let r = (e) => {
120
+ e === null ? O.delete(t) : O.set(t, e);
121
+ };
122
+ function i(e, n) {
123
+ let r = j(t);
124
+ return r < 0 ? {
125
+ above: !1,
126
+ below: !1
127
+ } : e === n ? {
128
+ above: !1,
129
+ below: r === n - 1
130
+ } : {
131
+ above: r === e,
132
+ below: !1
133
+ };
134
+ }
135
+ let s = e(() => {
136
+ let e = {
137
+ [a]: !1,
138
+ [o]: !1
139
+ };
140
+ if (y.value !== null && x.value !== null) {
141
+ let t = i(x.value, A().length);
142
+ t.above && (e[a] = !0), t.below && (e[o] = !0);
143
+ }
144
+ if (W.value !== null && y.value === null) {
145
+ let t = i(W.value, A().length);
146
+ t.above && (e[a] = !0), t.below && (e[o] = !0);
147
+ }
148
+ return e;
149
+ }), c = {
150
+ ref: r,
151
+ dataAttrs: { "data-sortable-id": String(t) },
152
+ class: s,
153
+ onPointerdown: (e) => {
154
+ e.button === 0 && P(e.target) && (e.preventDefault(), z(t, e));
155
+ }
156
+ };
157
+ return k.set(t, c), c;
158
+ }
159
+ let W = n(null), G = {
160
+ ref: (e) => {
161
+ D = e;
162
+ },
163
+ dataAttrs: { "data-sortable-container": g ?? "" }
164
+ }, K = {
165
+ group: g,
166
+ getContainer: () => D,
167
+ getItems: () => f.value,
168
+ getId: (e) => p(e),
169
+ getElements: () => O,
170
+ setExternalDropIndex: (e) => {
171
+ W.value = e;
172
+ },
173
+ acceptExternal: (e, t) => {
174
+ h && h(e, t);
175
+ }
176
+ };
177
+ return K.getExternalDropIndex = () => W.value, l.add(K), t(() => {
178
+ l.delete(K), H();
179
+ }), {
180
+ registerItem: U,
181
+ container: G,
182
+ isDragging: e(() => y.value !== null),
183
+ dragId: e(() => y.value),
184
+ dragPosition: e(() => b.value),
185
+ dropIndex: e(() => x.value)
186
+ };
187
+ }
188
+ //#endregion
189
+ export { d as t };
@@ -0,0 +1,72 @@
1
+ import { getCurrentScope as e, onScopeDispose as t } from "vue";
2
+ //#region src/composables/dom/useTextHighlight.ts
3
+ var n = /* @__PURE__ */ new Map();
4
+ function r() {
5
+ return typeof CSS < "u" && "highlights" in CSS && typeof globalThis.Highlight == "function";
6
+ }
7
+ function i(e) {
8
+ let t = n.get(e);
9
+ if (!t || t.size === 0) {
10
+ CSS.highlights.delete(e);
11
+ return;
12
+ }
13
+ let r = new Highlight();
14
+ for (let e of t) for (let t of e.ranges) r.add(t);
15
+ CSS.highlights.set(e, r);
16
+ }
17
+ function a(e, t) {
18
+ let n = t.trim().toLowerCase();
19
+ if (!n) return [];
20
+ let r = e.toLowerCase(), i = [], a = 0;
21
+ for (;;) {
22
+ let e = r.indexOf(n, a);
23
+ if (e === -1) break;
24
+ i.push({
25
+ start: e,
26
+ end: e + n.length
27
+ }), a = e + n.length;
28
+ }
29
+ return i;
30
+ }
31
+ function o(o) {
32
+ let s = r(), c = null;
33
+ function l() {
34
+ if (c) return c;
35
+ c = { ranges: [] };
36
+ let e = n.get(o);
37
+ return e || (e = /* @__PURE__ */ new Set(), n.set(o, e)), e.add(c), c;
38
+ }
39
+ function u(e) {
40
+ s && (l().ranges = e.slice(), i(o));
41
+ }
42
+ function d(e, t, n = a) {
43
+ if (!s) return;
44
+ let r = [], i = document.createTreeWalker(e, NodeFilter.SHOW_TEXT);
45
+ for (let e = i.nextNode(); e; e = i.nextNode()) {
46
+ let i = e.textContent ?? "";
47
+ if (i) for (let a of n(i, t)) {
48
+ if (a.start >= a.end) continue;
49
+ let t = document.createRange();
50
+ t.setStart(e, a.start), t.setEnd(e, a.end), r.push(t);
51
+ }
52
+ }
53
+ u(r);
54
+ }
55
+ function f() {
56
+ !s || !c || (c.ranges = [], i(o));
57
+ }
58
+ function p() {
59
+ if (!s || !c) return;
60
+ n.get(o)?.delete(c), i(o);
61
+ let e = n.get(o);
62
+ e && e.size === 0 && n.delete(o), c = null;
63
+ }
64
+ return e() && t(p), {
65
+ set: u,
66
+ setFromMatches: d,
67
+ clear: f,
68
+ supported: s
69
+ };
70
+ }
71
+ //#endregion
72
+ export { o as t };
@@ -1,4 +1,4 @@
1
- import { t as e } from "./useTimer-NAaj9zNq.js";
1
+ import { t as e } from "./useTimer-6FoosoDY.js";
2
2
  import { getCurrentScope as t, onScopeDispose as n, ref as r } from "vue";
3
3
  //#region src/composables/dom/useTouchGate.ts
4
4
  var i = /* @__PURE__ */ new Set(), a = !1;
@@ -4,11 +4,13 @@ function e() {
4
4
  }
5
5
  function t(e) {
6
6
  let t = typeof document > "u" ? void 0 : document;
7
- return !t || typeof t.startViewTransition != "function" ? (e(), {
7
+ if (!t || typeof t.startViewTransition != "function") return e(), {
8
8
  finished: Promise.resolve(),
9
9
  transitioned: !1
10
- }) : {
11
- finished: t.startViewTransition(() => e()).finished.then(() => void 0, () => void 0),
10
+ };
11
+ let n = t.startViewTransition(() => e());
12
+ return n.ready?.catch(() => {}), {
13
+ finished: n.finished.then(() => void 0, () => void 0),
12
14
  transitioned: !0
13
15
  };
14
16
  }
@@ -1,2 +1,3 @@
1
1
  export { cn } from "./cn";
2
- export { moveBeforeSafe, supportsMoveBefore } from "./moveBefore";
2
+ export { moveBeforeSafe } from "./moveBefore";
3
+ export { supportsMoveBefore, supportsScrollTimeline, supportsViewTimeline, supportsPostTask, } from "./platformSupport";
@@ -0,0 +1,8 @@
1
+ export { supportsMoveBefore } from "./moveBefore";
2
+ export { supportsScrollTimeline, supportsViewTimeline, } from "../composables/motion/supportsCssTimeline";
3
+ /**
4
+ * True when `scheduler.postTask` is available — the feature-detected predicate
5
+ * gating the prioritized-task fast path (vs the MessageChannel macrotask
6
+ * fallback in `postTaskSafe`).
7
+ */
8
+ export declare function supportsPostTask(): boolean;
@@ -1,4 +1,4 @@
1
- import { t as e } from "./createLucideIcon-Bn9a1b70.js";
1
+ import { t as e } from "./createLucideIcon-DuDoe_ra.js";
2
2
  var t = e("x", [["path", {
3
3
  d: "M18 6 6 18",
4
4
  key: "1bl5f8"
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@mkbabb/glass-ui",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "description": "Glassmorphic design system — Vue 3.5 components, reka-ui primitives, Tailwind CSS v4 tokens",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mkbabb/glass-ui.git"
9
+ },
10
+ "homepage": "https://github.com/mkbabb/glass-ui#readme",
11
+ "bugs": "https://github.com/mkbabb/glass-ui/issues",
6
12
  "type": "module",
7
13
  "types": "./dist/index.d.ts",
8
14
  "typesVersions": {
@@ -517,10 +523,13 @@
517
523
  "proof:consumers:build": "bash scripts/proof-consumers-build.sh",
518
524
  "proof:runtime": "node scripts/proof-runtime.mjs",
519
525
  "proof:theme": "node scripts/proof-theme-style.mjs",
526
+ "proof:components-css": "node scripts/proof-components-css.mjs",
520
527
  "proof:resolution": "node scripts/proof-resolution-contract.mjs",
521
528
  "proof:phantom-classes": "node scripts/proof-phantom-classes.mjs",
522
529
  "proof:vt-names": "node scripts/proof-vt-names.mjs",
523
- "proof:all": "npm run proof:package && npm run proof:theme && npm run proof:consumers:static && npm run proof:consumers:build && npm run proof:runtime && npm run proof:vt-names",
530
+ "proof:lockfile": "node scripts/proof-lockfile.mjs",
531
+ "proof:all": "node scripts/gates.mjs --run local",
532
+ "gates:verify-ci": "node scripts/gates.mjs --verify-ci",
524
533
  "profile:bundle": "node scripts/profile-bundle.mjs",
525
534
  "profile:budget": "node scripts/profile-bundle.mjs --enforce",
526
535
  "profile:aurora": "node scripts/profile-aurora.mjs",
@@ -533,7 +542,8 @@
533
542
  },
534
543
  "peerDependencies": {
535
544
  "@lucide/vue": "^1.16.0",
536
- "@mkbabb/keyframes.js": "^2.2.0",
545
+ "@mkbabb/keyframes.js": "^2.2.0 || ^3.0.0",
546
+ "@mkbabb/value.js": "^0.10.0",
537
547
  "@vueuse/core": "^14.0",
538
548
  "class-variance-authority": "^0.7",
539
549
  "clsx": "^2.0",
@@ -489,6 +489,56 @@
489
489
  overflow-y: visible;
490
490
  }
491
491
 
492
+ /* ── Scroll-on-overflow opt-in (GlassDock `overflow="scroll"`) ───────
493
+ The default contract grows-to-fit then overflows visibly past the
494
+ axis cap. `overflow="scroll"` instead makes the dock the scroll port
495
+ on its layout axis, pairing the existing cap with a hidden-scrollbar
496
+ scroll region so over-cap content stays reachable. The rounded pill
497
+ masks the scroll edge; both axes keep their cap. */
498
+
499
+ /* Inline axis (horizontal docks). The active layer becomes the scroll
500
+ port: `min-width: 0` releases the flex item's `min-content` floor so
501
+ it can shrink under the clamped `.dock-layers` track, then `overflow-x:
502
+ auto` scrolls its over-cap content. `.dock-layers` must KEEP clipping
503
+ so the pill's rounded edge masks the scroll boundary — hence the
504
+ grow-mode `overflow-x: visible` (`.dock-layers`, above) is overridden
505
+ back to `hidden` here. */
506
+ .glass-dock.dock-scroll-x.expanded:not(.dock-wrap) > .dock-layers {
507
+ overflow-x: hidden;
508
+ }
509
+
510
+ .glass-dock.dock-scroll-x .dock-layer--full {
511
+ min-width: 0;
512
+ overflow-x: auto;
513
+ scrollbar-width: none;
514
+ /* Trap the inline-scroll momentum at the dock's own boundary so a
515
+ wheel/trackpad gesture that bottoms out the pill does NOT chain into
516
+ scrolling the page behind it (the dock is a self-contained scroll
517
+ port, not a window into the route scroller). */
518
+ overscroll-behavior-x: contain;
519
+ }
520
+
521
+ .glass-dock.dock-scroll-x .dock-layer--full::-webkit-scrollbar {
522
+ display: none;
523
+ }
524
+
525
+ /* Block axis (vertical rails). The root keeps its `max-block-size` cap
526
+ and scrolls its over-cap children — cap + scroll is the correct
527
+ pairing the grow-mode contract split apart. Ties the
528
+ `.vertical.always-expanded` visible default on specificity and wins on
529
+ source order. */
530
+ .glass-dock.vertical.dock-scroll-y {
531
+ overflow-y: auto;
532
+ scrollbar-width: none;
533
+ /* Same momentum-trap as the inline port — a rail that bottoms out must
534
+ not chain its remaining wheel delta into the page scroller behind it. */
535
+ overscroll-behavior-y: contain;
536
+ }
537
+
538
+ .glass-dock.vertical.dock-scroll-y::-webkit-scrollbar {
539
+ display: none;
540
+ }
541
+
492
542
  .glass-dock.dock-wrap {
493
543
  white-space: normal;
494
544
  border-radius: var(--radius-2xl);
@@ -670,7 +720,11 @@
670
720
  border: none;
671
721
  background: transparent;
672
722
  border-radius: var(--dock-control-radius, var(--radius-pill));
673
- color: color-mix(in srgb, var(--foreground) calc(var(--opacity-icon-muted) * 100%), transparent);
723
+ /* Foreground base routes through `--dock-fg-on-aurora` (defaults to
724
+ `--foreground`, byte-identical to before) so a consumer floating the
725
+ dock over an aurora can lift contrast per-backdrop. The muted icon
726
+ weight mixes that base down with `--opacity-icon-muted`. */
727
+ color: color-mix(in srgb, var(--dock-fg-on-aurora, var(--foreground)) calc(var(--opacity-icon-muted) * 100%), transparent);
674
728
  outline: none;
675
729
  transition:
676
730
  background-color var(--dock-motion-fast),
@@ -968,7 +1022,8 @@
968
1022
  border: none;
969
1023
  background: transparent;
970
1024
  border-radius: var(--dock-control-radius, var(--radius-pill));
971
- color: color-mix(in srgb, var(--foreground) calc(var(--opacity-icon-muted) * 100%), transparent);
1025
+ /* Shares the dock-icon-button legibility base (`--dock-fg-on-aurora`). */
1026
+ color: color-mix(in srgb, var(--dock-fg-on-aurora, var(--foreground)) calc(var(--opacity-icon-muted) * 100%), transparent);
972
1027
  outline: none;
973
1028
  transition:
974
1029
  background-color var(--dock-motion-fast),
@@ -1081,5 +1136,19 @@
1081
1136
  --dock-control-size: var(--dock-touch-target, 2.75rem);
1082
1137
  --size-icon-btn: var(--dock-touch-target, 2.75rem);
1083
1138
  }
1139
+
1140
+ /* S-2 — the in-dock floor above lifts the control-SIZE token, which
1141
+ only reaches a DockIconButton that has a `.glass-dock` ancestor.
1142
+ A STANDALONE DockIconButton (a routed settings gear, no dock
1143
+ wrapper) reads the bare `--size-icon-btn` and would fall below the
1144
+ 44px WCAG target. This button-level floor holds the touch box
1145
+ regardless of ancestry; the in-dock rule above stays (more specific,
1146
+ and it also reserves the slot in the dock's width-math). Compact
1147
+ buttons opt out — they are auto-sized affordances, not primary
1148
+ targets. */
1149
+ .dock-icon-button:not(.dock-icon-button--compact) {
1150
+ min-block-size: var(--dock-touch-target, 2.75rem);
1151
+ min-inline-size: var(--dock-touch-target, 2.75rem);
1152
+ }
1084
1153
  }
1085
1154
  }