@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
@@ -33,6 +33,7 @@
33
33
  font-size: var(--type-body);
34
34
  color: var(--muted-foreground);
35
35
  line-height: 1.5;
36
+ text-wrap: pretty; /* AQ.W3 §W3.3 — prose-register orphan/river fix */
36
37
  }
37
38
 
38
39
  /* ── Labeled-field label (V.W3.T5 / A5 §5.5) ────────────────────
@@ -44,10 +45,49 @@
44
45
  .labeled-field-label {
45
46
  font-family: var(--font-display);
46
47
  font-size: var(--type-body);
47
- color: var(--muted-foreground);
48
+ /* AQ.W4 §W3.1c — the label color reads the group-state variable so the
49
+ `:has(:user-invalid)` rule below reddens it (one source of the
50
+ override value, shared with the `.has-error` fallback class). */
51
+ color: var(--field-label-color, var(--muted-foreground));
48
52
  cursor: help;
49
53
  }
50
54
 
55
+ /* AQ.W4 §W3.1c — LabeledField group error highlight. When any descendant
56
+ control is `:user-invalid`, the whole field group marks (the label
57
+ reddens via `--field-label-color`, the error region reveals). Scoped to
58
+ `.labeled-field` — never `body`, never a bare element. `:has()` Baseline
59
+ Widely; the `.has-error` / `.has-valid` fallback classes (toggled by the
60
+ `useUserInvalidAria` fallback path) are the SOLE degradation for engines
61
+ without `:has()`/`:user-invalid` (not a live+dead alias). */
62
+ .labeled-field {
63
+ --field-label-color: var(--muted-foreground);
64
+ }
65
+ .labeled-field:has(:user-invalid),
66
+ .labeled-field.has-error {
67
+ --field-label-color: var(--destructive);
68
+ }
69
+
70
+ /* The error region: hidden at rest, revealed once a descendant is
71
+ `:user-invalid` (or the `.has-error` fallback class is set). Non-color
72
+ reinforcement for the validity tint — the error TEXT is the primary
73
+ cue, the border/bg shift the supplement (forms guide: never color
74
+ alone). */
75
+ .labeled-field-error {
76
+ display: none;
77
+ font-size: var(--type-small);
78
+ color: var(--destructive);
79
+ margin-block-start: 0.25rem;
80
+ }
81
+ .labeled-field:has(:user-invalid) .labeled-field-error,
82
+ .labeled-field.has-error .labeled-field-error {
83
+ display: block;
84
+ }
85
+ /* Hide the error text once the field reads valid (the user corrected it). */
86
+ .labeled-field:has(:user-valid) .labeled-field-error,
87
+ .labeled-field.has-valid .labeled-field-error {
88
+ display: none;
89
+ }
90
+
51
91
  /* ── Popover-content recipe (V.W3.T3 / A5 §3.2) ─────────────────
52
92
  Canonical recipe for floating-tier portal containers
53
93
  (PopoverContent, DropdownMenuContent, SelectContent, etc.).
@@ -72,9 +112,28 @@
72
112
  display: none;
73
113
  }
74
114
 
115
+ /* AQ.W3 §W3.4 — tokenized thin scrollbar. Standard `scrollbar-width` +
116
+ `scrollbar-color` (Baseline Widely, Chromium 121+) is the primary path,
117
+ reading `--scrollbar-{thumb,track}` (auto-dark via `--muted-foreground`).
118
+ The legacy `::-webkit-scrollbar` family is the SOLE fallback for older
119
+ WebKit/Blink, gated on `@supports not (scrollbar-color: auto)` so modern
120
+ engines never paint it — not a live+dead alias. */
75
121
  .scrollbar-thin {
76
122
  scrollbar-width: thin;
77
- scrollbar-color: color-mix(in srgb, var(--muted-foreground) 25%, transparent) transparent;
123
+ scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
124
+ }
125
+ @supports not (scrollbar-color: auto) {
126
+ .scrollbar-thin::-webkit-scrollbar {
127
+ width: 8px;
128
+ height: 8px;
129
+ }
130
+ .scrollbar-thin::-webkit-scrollbar-track {
131
+ background: var(--scrollbar-track);
132
+ }
133
+ .scrollbar-thin::-webkit-scrollbar-thumb {
134
+ background: var(--scrollbar-thumb);
135
+ border-radius: var(--radius-pill);
136
+ }
78
137
  }
79
138
 
80
139
  /* ── Focus ring — auto-activates on :focus-visible ── */
@@ -95,6 +154,8 @@
95
154
 
96
155
  /* ── Interactive item (hover bg + focus ring + active scale) ── */
97
156
  .interactive-item {
157
+ /* AQ.W3 §W3.2 identity base */
158
+ scale: 1;
98
159
  border-radius: var(--radius-lg);
99
160
  user-select: none;
100
161
  transition:
@@ -102,7 +163,7 @@
102
163
  color var(--duration-fast) var(--ease-standard),
103
164
  border-color var(--duration-fast) var(--ease-standard),
104
165
  box-shadow var(--duration-fast) var(--ease-standard),
105
- transform var(--duration-fast) var(--ease-standard);
166
+ scale var(--duration-fast) var(--ease-standard);
106
167
  }
107
168
  .interactive-item:hover {
108
169
  background-color: color-mix(in srgb, var(--accent) 50%, transparent);
@@ -112,7 +173,7 @@
112
173
  box-shadow: var(--focus-ring-shadow);
113
174
  }
114
175
  .interactive-item:active {
115
- transform: scale(0.98);
176
+ scale: 0.98;
116
177
  }
117
178
  .interactive-item:disabled,
118
179
  .interactive-item[data-disabled] {
@@ -136,15 +197,19 @@
136
197
  consumer's own hover/active bg-tint cascade to acknowledge the
137
198
  press. */
138
199
  .tap-squish {
139
- transition: transform var(--duration-fast) var(--spring-snappy);
200
+ /* AQ.W3 §W3.2 identity base */
201
+ scale: 1;
202
+ transition: scale var(--duration-fast) var(--spring-snappy);
140
203
  transform-origin: center center;
141
204
  }
142
205
  .tap-squish:active {
143
- transform: scale(var(--scale-press));
206
+ scale: var(--scale-press);
144
207
  }
145
208
  @media (prefers-reduced-motion: reduce) {
146
209
  .tap-squish:active {
147
- transform: none;
210
+ /* Reset to the longhand identity (not `transform: none`) so the
211
+ press scale is neutralized under PRM. */
212
+ scale: 1;
148
213
  }
149
214
  }
150
215
 
@@ -212,6 +277,29 @@
212
277
  -webkit-mask-image: linear-gradient(to bottom, transparent, black var(--mask-fade-width), black calc(100% - var(--mask-fade-width)), transparent);
213
278
  }
214
279
 
280
+ /* ── Deferred section — render-skip an offscreen subtree (AQ.W3 §5) ──────
281
+ `content-visibility: auto` skips layout/paint/style of an offscreen
282
+ subtree — the INP-under-load lever (fourier γ, muster, speedtest, words).
283
+ `contain-intrinsic-size: auto <estimate>` is measurement-safe: the `auto`
284
+ prefix makes the engine REMEMBER the last-rendered size (no scroll-jump on
285
+ re-entry); plain `<estimate>` freezes the section + thrashes the scrollbar
286
+ — the trap this closes. Estimate is token-driven (`--deferred-section-
287
+ size`, default 30rem). `.deferred-section--cached` →
288
+ `content-visibility: hidden` (always skipped, state CACHED — cheaper to
289
+ re-show than `display:none`). Baseline Widely; unsupporting engines render
290
+ normally. JS HOOK: the engine fires `contentvisibilityautostatechange`
291
+ { skipped } at the render-skip boundary — pair with `useRAFLoop`
292
+ pause/resume: `el.addEventListener('contentvisibilityautostatechange',
293
+ e => e.skipped ? loop.pause() : loop.resume())`. */
294
+ .deferred-section {
295
+ content-visibility: auto;
296
+ contain-intrinsic-size: auto var(--deferred-section-size, 30rem);
297
+ }
298
+ .deferred-section--cached {
299
+ content-visibility: hidden;
300
+ contain-intrinsic-size: auto var(--deferred-section-size, 30rem);
301
+ }
302
+
215
303
  /* ── Card scroll-timeline host (AI.W1-α) ───────────────────────────────
216
304
  Canonical scroll-overflow host that emits the `--card-scroll` named
217
305
  scroll-timeline consumed by `<CardHeader shrink>`. Apply to the
@@ -273,6 +361,8 @@
273
361
  align-items: center;
274
362
  justify-content: center;
275
363
  text-align: center;
364
+ /* AQ.W3 §W3.2 identity base */
365
+ scale: 1;
276
366
  gap: var(--metric-badge-gap, 0.125rem);
277
367
  max-width: var(--metric-badge-max-width, 8rem);
278
368
  min-height: var(--metric-badge-min-height, 1.5rem);
@@ -297,7 +387,7 @@
297
387
  background var(--duration-fast) var(--ease-standard),
298
388
  border-color var(--duration-fast) var(--ease-standard),
299
389
  box-shadow var(--duration-fast) var(--ease-standard),
300
- transform var(--duration-fast) var(--ease-standard);
390
+ scale var(--duration-fast) var(--ease-standard);
301
391
  }
302
392
 
303
393
  .metric-badge > span {
@@ -310,11 +400,11 @@
310
400
  border-color: var(--metric-badge-hover-border, var(--glass-border-resting));
311
401
  background: var(--metric-badge-hover-bg, var(--glass-bg-resting));
312
402
  box-shadow: var(--metric-badge-hover-shadow, 0 2px 10px color-mix(in srgb, var(--shadow-color) 12%, transparent), var(--glass-highlight));
313
- transform: scale(var(--metric-badge-hover-scale, 1.02));
403
+ scale: var(--metric-badge-hover-scale, 1.02);
314
404
  }
315
405
 
316
406
  .metric-badge:active {
317
- transform: scale(var(--metric-badge-press-scale, 0.96));
407
+ scale: var(--metric-badge-press-scale, 0.96);
318
408
  }
319
409
 
320
410
  .metric-badge:focus-visible {
@@ -460,34 +550,28 @@
460
550
  color: color-mix(in srgb, var(--muted-foreground) 50%, transparent);
461
551
  }
462
552
 
463
- /* ── Hover lift — translate-y + shadow on hover (3 levels) ── */
464
- .hover-lift {
465
- transition-property: transform, box-shadow;
553
+ /* ── Hover lift — translate-y + shadow on hover (3 levels) ──
554
+ The shared transition is expressed once over the family; the three
555
+ :hover rules carry the per-level translate + shadow. */
556
+ :where(.hover-lift, .hover-lift-md, .hover-lift-lg) {
557
+ /* Individual-transform identity base (AQ.W3 §W3.2) — `translate: 0` at
558
+ rest mints the stacking context once so the hover lift does not
559
+ flicker it into being. */
560
+ translate: 0;
561
+ transition-property: translate, box-shadow;
466
562
  transition-duration: var(--duration-normal);
467
563
  transition-timing-function: var(--ease-standard);
468
564
  }
469
565
  .hover-lift:hover:not(:disabled):not([aria-disabled='true']) {
470
- transform: translateY(var(--lift-sm));
566
+ translate: 0 var(--lift-sm);
471
567
  box-shadow: var(--shadow-md);
472
568
  }
473
-
474
- .hover-lift-md {
475
- transition-property: transform, box-shadow;
476
- transition-duration: var(--duration-normal);
477
- transition-timing-function: var(--ease-standard);
478
- }
479
569
  .hover-lift-md:hover:not(:disabled):not([aria-disabled='true']) {
480
- transform: translateY(var(--lift-md));
570
+ translate: 0 var(--lift-md);
481
571
  box-shadow: var(--shadow-md);
482
572
  }
483
-
484
- .hover-lift-lg {
485
- transition-property: transform, box-shadow;
486
- transition-duration: var(--duration-normal);
487
- transition-timing-function: var(--ease-standard);
488
- }
489
573
  .hover-lift-lg:hover:not(:disabled):not([aria-disabled='true']) {
490
- transform: translateY(var(--lift-lg));
574
+ translate: 0 var(--lift-lg);
491
575
  box-shadow: var(--shadow-lg);
492
576
  }
493
577
 
@@ -501,22 +585,23 @@
501
585
  the whole cartoon read.
502
586
  (Per audit U.W0.C-c §1.3 / Union 1 — collapses the dual-system
503
587
  drift onto the token-driven shadow.) */
588
+ :where(.shadow-cartoon-sm, .shadow-cartoon-md, .shadow-cartoon-lg) {
589
+ border: 2px solid var(--border);
590
+ }
591
+ /* Static cartoon-stamp lift (AQ.W3 §W3.2). NOT state-driven, so the
592
+ identity base is not strictly required, but the `translate:` longhand
593
+ keeps the family uniform with the state-driven sites above. */
504
594
  .shadow-cartoon-sm {
505
595
  box-shadow: var(--shadow-cartoon-sm);
506
- border: 2px solid var(--border);
507
- transform: translateY(-1px);
596
+ translate: 0 -1px;
508
597
  }
509
-
510
598
  .shadow-cartoon-md {
511
599
  box-shadow: var(--shadow-cartoon-md);
512
- border: 2px solid var(--border);
513
- transform: translateY(-1px);
600
+ translate: 0 -1px;
514
601
  }
515
-
516
602
  .shadow-cartoon-lg {
517
603
  box-shadow: var(--shadow-cartoon-lg);
518
- border: 2px solid var(--border);
519
- transform: translateY(-2px);
604
+ translate: 0 -2px;
520
605
  }
521
606
 
522
607
  /* ── Divider utilities ── */
@@ -554,10 +639,13 @@
554
639
  `class="scale-on-hover"`; transition + easing bind to the canonical
555
640
  `--duration-fast` + `--ease-standard` tokens. */
556
641
  @utility scale-on-hover {
557
- @apply transition-transform duration-fast ease-standard;
642
+ /* Individual-transform identity base (AQ.W3 §W3.2). Transition the `scale`
643
+ longhand (not `transform`) so the migrated hover scale animates. */
644
+ scale: 1;
645
+ transition: scale var(--duration-fast) var(--ease-standard);
558
646
 
559
647
  &:hover {
560
- transform: scale(var(--scale-hover));
648
+ scale: var(--scale-hover);
561
649
  }
562
650
  }
563
651
 
@@ -574,21 +662,14 @@
574
662
  data-[state=closed]:duration-[var(--duration-fast)];
575
663
  }
576
664
 
577
- /* ── Audacious primary CTA recipe (K.W6 HEADLINE) ────────────────────
578
- Lifted from `dock.css` `.dock-tab-button[data-tier="primary"]` per
579
- K.W6 spec §3 (Option B drop phase-tinting from the canonical
580
- variant; phase-tint stays as a dock-local extension). Composes three
581
- at-rest marks (top-highlight via --glass-highlight, bottom under-shadow
582
- via --border-hairline, baseline glass via --card surface) with three
583
- disco accents on hover (specular swap via --glass-specular, sparkle
584
- sweep via the ::after star, disco-grain via --paper-clean-texture
585
- blended with a --primary radial). Reservation: disco fires on hover
586
- only — at rest the button reads as a Vignelli-restrained composed
587
- glass surface.
588
-
589
- Pair with `bg-primary text-primary-foreground` for the canonical
590
- Button variant; the utility owns the texture/highlight/sparkle
591
- composition only. */
665
+ /* ── Audacious primary CTA recipe ────────────────────────────────────────
666
+ Composes three at-rest marks (top-highlight via --glass-highlight, bottom
667
+ under-shadow via --border-hairline, baseline glass) with three disco accents
668
+ on hover (specular swap via --glass-specular, sparkle sweep via the ::after
669
+ star, disco-grain via --paper-clean-texture blended with a --primary radial).
670
+ Disco fires on hover only at rest the button reads as a restrained glass
671
+ surface. Pair with `bg-primary text-primary-foreground`; the utility owns
672
+ the texture/highlight/sparkle composition only. */
592
673
  @utility btn-audacious {
593
674
  position: relative;
594
675
  isolation: isolate;
@@ -782,21 +863,11 @@
782
863
  padding-inline: var(--table-head-px, 1rem);
783
864
  }
784
865
 
785
- /* ── Rainbow gradient backgrounds (Q.W3 Lane E re-promote) ──────────────
866
+ /* ── Rainbow gradient backgrounds ───────────────────────────────────────
786
867
  `.rainbow-vivid` + `.rainbow-pastel` paint a left-to-right 7-stop spectrum
787
868
  from the canonical `--rainbow-*` / `--rainbow-pastel-*` token families
788
- (tokens.css §14). They were retired at `b0debec` (D.W2.D, 2026-04-30)
789
- under a zero-consumer audit that did not include keyframes.js in its
790
- sweep corpus — keyframes.js's `AnimationMenuBar.vue` round play button
791
- composes `rainbow-vivid` (playing) / `rainbow-pastel` (idle) and silently
792
- lost its gradient when the recipes left the library. The `--rainbow-*`
793
- color tokens survived the retiral; only the class recipes were dropped.
794
-
795
- Re-promoted as `@utility` recipes — the token half is canonical, so the
796
- class form that paints it belongs alongside it. Not a backwards-compat
797
- alias: it is a substrate REVERT, the revert IS the consumer rediscovery
798
- (≥ 1 consumer exists post-revert, satisfying L invariant 8). Faithful
799
- to the pre-`b0debec` recipe bodies. */
869
+ (tokens.css §14). Consumed by keyframes.js's `AnimationMenuBar.vue` round
870
+ play button — `rainbow-vivid` (playing) / `rainbow-pastel` (idle). */
800
871
  @utility rainbow-vivid {
801
872
  background: linear-gradient(
802
873
  to right,
@@ -823,32 +894,28 @@
823
894
  );
824
895
  }
825
896
 
826
- /* ── Interactive-button four-state recipe (Q.W3 Lane E re-promote) ───────
897
+ /* ── Interactive-button four-state recipe ────────────────────────────────
827
898
  `.btn-interactive` carries the canonical "Button-with-spring-hover"
828
899
  four-state contract — transition + hover-scale (`--scale-hover`) +
829
- active-press (`--scale-press`) + disabled-opacity (`--opacity-disabled`)
830
- + focus-ring fade-in. Same shape as `.btn-audacious` (a composition-only
831
- recipe a Button variant opts into). Retired at `b0debec` (D.W2.D)
832
- alongside the rainbow recipes under the same incomplete audit corpus;
833
- keyframes.js consumes it at 7 sites (CubeScene, EasingScene, demo/cube,
834
- AnimationControlsGroup RIBBON_BUTTON_CLASS, PlaybackRibbon Reverse).
835
-
836
- The Button primitive's own variants emit the four states except
837
- `hover:scale-*` — `.btn-interactive` is the canonical opt-in that adds
838
- the spring-hover lift. Faithful to the pre-`b0debec` recipe body. */
900
+ active-press (`--scale-press`) + disabled-opacity + focus-ring fade-in.
901
+ The Button primitive's variants emit the four states except `hover:scale-*`;
902
+ this is the canonical opt-in that adds the spring-hover lift. Consumed by
903
+ keyframes.js at 7 sites. */
839
904
  @utility btn-interactive {
905
+ /* AQ.W3 §W3.2 identity base */
906
+ scale: 1;
840
907
  transition:
841
908
  background-color var(--duration-fast) var(--ease-standard),
842
909
  color var(--duration-fast) var(--ease-standard),
843
- transform var(--duration-fast) var(--ease-standard),
910
+ scale var(--duration-fast) var(--ease-standard),
844
911
  opacity var(--duration-fast) var(--ease-standard);
845
912
 
846
913
  &:hover {
847
- transform: scale(var(--scale-hover));
914
+ scale: var(--scale-hover);
848
915
  }
849
916
 
850
917
  &:active {
851
- transform: scale(var(--scale-press));
918
+ scale: var(--scale-press);
852
919
  }
853
920
 
854
921
  &:disabled {
@@ -864,7 +931,7 @@
864
931
  transition:
865
932
  background-color var(--duration-fast) var(--ease-standard),
866
933
  color var(--duration-fast) var(--ease-standard),
867
- transform var(--duration-fast) var(--ease-standard),
934
+ scale var(--duration-fast) var(--ease-standard),
868
935
  opacity var(--duration-fast) var(--ease-standard),
869
936
  box-shadow var(--duration-fast) var(--ease-standard);
870
937
  }
@@ -891,3 +958,54 @@ html.no-transition *::before,
891
958
  html.no-transition *::after {
892
959
  transition-duration: 0s !important;
893
960
  }
961
+
962
+ /* ── Forced-colors restoration (AQ.W2 §5) ──────────────────────────────
963
+ Windows High Contrast / forced-colors mode STRIPS `box-shadow` — so the
964
+ glass focus rings (box-shadow + `outline: none`) vanish, leaving keyboard
965
+ users with no visible focus (a WCAG 2.4.7 failure forced-colors exposes).
966
+ Restore a real `outline` keyed to the system `Highlight` color (outline
967
+ survives forced-colors; box-shadow does not). The box-shadow ring stays the
968
+ primary in normal mode (it carries the glass aesthetic) — these two are
969
+ mutually exclusive by media query, NOT a parallel path.
970
+
971
+ `forced-color-adjust: none` is deliberately NOT used — glass-ui's
972
+ glassmorphic chrome is decorative and yields to the user's forced palette
973
+ (css forced-colors guidance). Baseline Widely Available; this IS the
974
+ fallback mechanism (it only activates under forced-colors), so no nested
975
+ guard. */
976
+ @media (forced-colors: active) {
977
+ .focus-ring:focus-visible,
978
+ .glass-btn:focus-visible,
979
+ .interactive-item:focus-visible,
980
+ .input-pill:focus,
981
+ .input-pill:focus-visible {
982
+ outline: 2px solid Highlight;
983
+ outline-offset: 2px;
984
+ }
985
+
986
+ /* Structural edges borne ONLY by box-shadow (the hairline catch-light /
987
+ glass pill edge / card plate) also vanish — restore a real border so
988
+ the silhouette survives. CanvasText is the system text/border color. */
989
+ .hairline-accent,
990
+ .glass-dock,
991
+ .glass-card {
992
+ border: 1px solid CanvasText;
993
+ }
994
+ }
995
+
996
+ /* ── Coarse-pointer touch-target floor (AQ.W3 §7) ───────────────────────────
997
+ General-surface companion to the dock-scoped R0G-6 floor (dock.css). On
998
+ coarse pointers the small icon-button/trigger surfaces OUTSIDE the dock lift
999
+ to the WCAG 2.5.5 (44px) minimum — ONE amendment retiring the per-consumer
1000
+ `min-h-[44px]` one-liners. Token-driven (`--touch-target`); fine-pointer
1001
+ byte-identical. Targets `Button size="icon"` (via the `data-size="icon"`
1002
+ attr Button.vue reflects), ExpandableContainer + ResponsiveTabs triggers.
1003
+ `min-block/inline-size` only RAISES — a larger explicit size is never lost. */
1004
+ @media (pointer: coarse) {
1005
+ [data-size="icon"],
1006
+ .expandable-container__trigger,
1007
+ .responsive-tabs__trigger {
1008
+ min-block-size: var(--touch-target, 2.75rem);
1009
+ min-inline-size: var(--touch-target, 2.75rem);
1010
+ }
1011
+ }
@@ -0,0 +1,62 @@
1
+ /*
2
+ * view-transition.css — the View-Transitions CSS substrate (AQ.W5 §Design 3b).
3
+ *
4
+ * Cascade rung after scroll-driven.css. Token-first shared-class recipes for the
5
+ * group-transition case — the substrate the `useViewTransition` helper
6
+ * (`@mkbabb/glass-ui/motion-core`) pairs with. The helper wraps the DOM
7
+ * mutation; this CSS owns the LOOK of the cross-fade/slide. The consumer adds
8
+ * `view-transition-class: gl-list-item` plus a UNIQUE `view-transition-name`
9
+ * per tracked element (the runtime MANDATORY — ≤ 1 element per name per state,
10
+ * else the transition is skipped silently).
11
+ *
12
+ * Consumed across the AQ↔muster J seam: J.W5's verdict re-rank tags each row
13
+ * `view-transition-class: gl-list-item; view-transition-name: row-<id>` and
14
+ * calls `startViewTransition(() => render())`; the dock layer swap (W6) reuses
15
+ * the same group recipe.
16
+ *
17
+ * Baseline: same-document `view-transitions` + `view-transition-class` = Newly
18
+ * Available. The helper's instant-update fallback (calls `mutate()` synchronously
19
+ * when `document.startViewTransition` is absent) is the ≤ 20-LOC feature-detected
20
+ * fallback — no CSS counterpart is needed because a non-supporting engine simply
21
+ * never generates the `::view-transition*` pseudo tree.
22
+ *
23
+ * Reduced-motion: `animation: none` on every VT pseudo. The native swap still
24
+ * runs (state mutates instantly), just without motion — the correct PRM degrade.
25
+ */
26
+
27
+ @media (prefers-reduced-motion: reduce) {
28
+ ::view-transition-group(*),
29
+ ::view-transition-old(*),
30
+ ::view-transition-new(*) {
31
+ animation: none !important;
32
+ }
33
+ }
34
+
35
+ /* Shared group class — consumers add `view-transition-class: gl-list-item` on
36
+ * each tracked element plus a unique `view-transition-name` per element. */
37
+ ::view-transition-group(.gl-list-item) {
38
+ animation-duration: var(--vt-duration, var(--duration-normal));
39
+ animation-timing-function: var(--vt-ease, var(--ease-apple-spring));
40
+ }
41
+
42
+ /* Added / removed members — the `:only-child` trick from the group guide: a
43
+ * member present in only ONE of the old/new states slides instead of cross-fades. */
44
+ ::view-transition-new(.gl-list-item):only-child { animation-name: gl-vt-slide-in; }
45
+ ::view-transition-old(.gl-list-item):only-child { animation-name: gl-vt-slide-out; }
46
+
47
+ /* AQ.W6 §Design 7 — the dock layer group recipe. `<GlassDock>` (.dock-layers)
48
+ * and `<DockLayerGroup>` (.dock-layer-stack) carry `view-transition-class:
49
+ * gl-dock-layer` + a page-unique `view-transition-name` on a View-Transitions
50
+ * engine, so the collapsed↔expanded width + the layer-pane swap morph as a VT
51
+ * group instead of the JS FLIP. The `--dock-motion-resize` spring maps here to
52
+ * `--vt-ease`; both default to the apple-spring. PRM zeroes the animation above. */
53
+ ::view-transition-group(.gl-dock-layer) {
54
+ animation-duration: var(--vt-duration, var(--duration-normal));
55
+ animation-timing-function: var(--vt-ease, var(--ease-apple-spring));
56
+ }
57
+
58
+ @keyframes gl-vt-slide-in { from { opacity: 0; translate: 0 var(--vt-rise, 8px); } }
59
+ @keyframes gl-vt-slide-out { to { opacity: 0; translate: 0 var(--vt-rise, 8px); } }
60
+
61
+ /* Keep the non-transitioned UI interactive while the snapshot animates. */
62
+ ::view-transition { pointer-events: none; }
@@ -0,0 +1 @@
1
+ export * from "./components/ui/switch";
package/dist/switch.js ADDED
@@ -0,0 +1,2 @@
1
+ import { t as e } from "./Switch-Cr1t_F_U.js";
2
+ export { e as Switch };