@mkbabb/glass-ui 3.13.0 → 4.0.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 (304) hide show
  1. package/dist/CardAction-XH4YBVEK.js +158 -0
  2. package/dist/{CommandShortcut-RowNEO6i.js → CommandShortcut-DdtWXxOK.js} +57 -52
  3. package/dist/{ContextMenuSubContent-BQmxTAdw.js → ContextMenuSubContent-B0Vs6atR.js} +1 -1
  4. package/dist/{DataTable-BCddn3T3.js → DataTable-C464Zbqd.js} +99 -97
  5. package/dist/DialogContent-DDE6pQBU.js +103 -0
  6. package/dist/{DialogFooter-Blu4t7tJ.js → DialogFooter-8eZbdmPc.js} +1 -1
  7. package/dist/FadingScroll-DwNnvKMs.js +76 -0
  8. package/dist/{HoverPopover-CISOJQuZ.js → HoverPopover-Dpzwvc4t.js} +1 -1
  9. package/dist/IconChip-BDw1j5mu.js +54 -0
  10. package/dist/{MetricBadge-C9QMz1KT.js → MetricBadge-BpC0R_Ec.js} +1 -1
  11. package/dist/{Notification-DdwNxIrI.js → Notification-DKjKsQq8.js} +8 -8
  12. package/dist/{NumberFieldContent-CqaN-SvN.js → NumberFieldContent-1VtwDSgf.js} +1 -1
  13. package/dist/PopoverContent-BTorlp--.js +127 -0
  14. package/dist/{Progress-DwlUKGbr.js → Progress-hAT4gqGH.js} +97 -77
  15. package/dist/{ScrollingText-DfFrwSph.js → ScrollingText-CUVFTWk2.js} +2 -2
  16. package/dist/{SelectScrollDownButton-CiDUxfEj.js → SelectScrollDownButton-C1jb3b3K.js} +22 -6
  17. package/dist/{Switch-CsIuYP_e.js → Switch-Dr--uLGH.js} +1 -1
  18. package/dist/{Toaster-D6q4HtXu.js → Toaster-Bm_HQSpc.js} +6 -6
  19. package/dist/{ToggleGroupItem-D_AHlRw9.js → ToggleGroupItem-Dzk9hWsF.js} +1 -1
  20. package/dist/animated-digit.js +2 -2
  21. package/dist/api/index.d.ts +8 -5
  22. package/dist/api.js +2 -2
  23. package/dist/aurora.js +132 -117
  24. package/dist/{button-ChXMfsud.js → button-BNDWhAZb.js} +2 -2
  25. package/dist/button.js +1 -1
  26. package/dist/card.js +1 -1
  27. package/dist/carousel.d.ts +1 -1
  28. package/dist/carousel.js +97 -141
  29. package/dist/collapsible.js +1 -1
  30. package/dist/color-swatch.d.ts +1 -0
  31. package/dist/color-swatch.js +47 -0
  32. package/dist/color.js +1 -1
  33. package/dist/command.js +1 -1
  34. package/dist/components/custom/aurora/constants/presets.d.ts +28 -0
  35. package/dist/components/custom/aurora/constants/renderMode.d.ts +2 -0
  36. package/dist/components/custom/aurora/index.d.ts +1 -1
  37. package/dist/components/custom/color-swatch/ColorSwatch.vue.d.ts +22 -0
  38. package/dist/components/custom/color-swatch/index.d.ts +1 -0
  39. package/dist/components/custom/configurator/Configurator.vue.d.ts +19 -8
  40. package/dist/components/custom/constellation/Constellation.vue.d.ts +18 -206
  41. package/dist/components/custom/constellation/composables/useConstellation.d.ts +26 -0
  42. package/dist/components/custom/constellation/constellationField.d.ts +2 -369
  43. package/dist/components/custom/constellation/constellationTypes.d.ts +369 -0
  44. package/dist/components/custom/constellation/index.d.ts +1 -1
  45. package/dist/components/custom/dock/DockRail.vue.d.ts +17 -16
  46. package/dist/components/custom/dock/DockSection.vue.d.ts +69 -0
  47. package/dist/components/custom/dock/DockSeparator.vue.d.ts +49 -1
  48. package/dist/components/custom/dock/DockTabButton.vue.d.ts +5 -5
  49. package/dist/components/custom/dock/constants.d.ts +35 -0
  50. package/dist/components/custom/dock/index.d.ts +2 -0
  51. package/dist/components/custom/expandable-container/ExpandableContainer.vue.d.ts +10 -0
  52. package/dist/components/custom/fading-scroll/FadingScroll.vue.d.ts +25 -0
  53. package/dist/components/custom/fading-scroll/composables/useFadingScroll.d.ts +31 -0
  54. package/dist/components/custom/fading-scroll/constants.d.ts +19 -0
  55. package/dist/components/custom/fading-scroll/index.d.ts +2 -0
  56. package/dist/components/custom/fourier-field/FourierField.vue.d.ts +7 -0
  57. package/dist/components/custom/fourier-field/index.d.ts +1 -1
  58. package/dist/components/custom/fourier-field/math.d.ts +17 -0
  59. package/dist/components/custom/glass-panel/GlassPanel.vue.d.ts +8 -0
  60. package/dist/components/custom/goo-blob/composables/useMetaballRenderer.d.ts +11 -1
  61. package/dist/components/custom/goo-blob/constants.d.ts +6 -1
  62. package/dist/components/custom/handmark/HandMark.vue.d.ts +29 -0
  63. package/dist/components/custom/handmark/brush.d.ts +269 -0
  64. package/dist/components/custom/handmark/composables/useHandMark.d.ts +89 -0
  65. package/dist/components/custom/handmark/constants.d.ts +39 -0
  66. package/dist/components/custom/handmark/freehand.d.ts +69 -0
  67. package/dist/components/custom/handmark/geometry.d.ts +52 -0
  68. package/dist/components/custom/handmark/index.d.ts +27 -0
  69. package/dist/components/custom/handmark/ink.d.ts +11 -0
  70. package/dist/components/custom/handmark/texture.d.ts +39 -0
  71. package/dist/components/custom/handmark/types.d.ts +62 -0
  72. package/dist/components/custom/icon-chip/IconChip.vue.d.ts +4 -0
  73. package/dist/components/custom/icon-chip/index.d.ts +2 -0
  74. package/dist/components/custom/icon-chip/types.d.ts +72 -0
  75. package/dist/components/custom/instrument-chassis/InstrumentChassis.vue.d.ts +15 -2
  76. package/dist/components/custom/pager-dots/PagerDots.vue.d.ts +39 -0
  77. package/dist/components/custom/pager-dots/index.d.ts +2 -0
  78. package/dist/components/custom/tabs/SegmentedTabs.vue.d.ts +20 -25
  79. package/dist/components/custom/tabs/composables/useTabIndicator.d.ts +30 -21
  80. package/dist/components/custom/tabs/constants.d.ts +9 -3
  81. package/dist/components/custom/tabs/index.d.ts +1 -1
  82. package/dist/components/custom/watercolor-dot/WatercolorDot.vue.d.ts +14 -0
  83. package/dist/components/ui/_shared/index.d.ts +2 -0
  84. package/dist/components/ui/_shared/menuItemVariants.d.ts +19 -0
  85. package/dist/components/ui/_shared/useSurfaceAxis.d.ts +41 -0
  86. package/dist/components/ui/card/Card.vue.d.ts +1 -1
  87. package/dist/components/ui/carousel/index.d.ts +0 -1
  88. package/dist/components/ui/command/Command.vue.d.ts +3 -0
  89. package/dist/components/ui/dialog/DialogContent.vue.d.ts +8 -3
  90. package/dist/components/ui/drawer/DrawerContent.vue.d.ts +5 -0
  91. package/dist/components/ui/index.d.ts +0 -1
  92. package/dist/components/ui/popover/PopoverContent.vue.d.ts +3 -0
  93. package/dist/components/ui/progress/ProgressSectioned.vue.d.ts +14 -3
  94. package/dist/components/ui/select/SelectTrigger.vue.d.ts +27 -4
  95. package/dist/components/ui/sheet/SheetContent.vue.d.ts +6 -0
  96. package/dist/components/ui/skeleton/Skeleton.vue.d.ts +3 -0
  97. package/dist/composables/dark/index.d.ts +1 -1
  98. package/dist/composables/dark/useGlobalDark.d.ts +23 -1
  99. package/dist/composables/motion/useViewTransition.d.ts +36 -1
  100. package/dist/configurator.js +1 -1
  101. package/dist/confirm-dialog.js +2 -2
  102. package/dist/constellation.js +92 -94
  103. package/dist/context-menu.js +2 -2
  104. package/dist/controls.js +10 -4
  105. package/dist/dark.d.ts +1 -1
  106. package/dist/dark.js +1 -1
  107. package/dist/data-table.js +1 -1
  108. package/dist/dialog.js +2 -2
  109. package/dist/dock.js +510 -321
  110. package/dist/{dockContext-BegmJVmx.js → dockContext-Bu1Avy-a.js} +1 -1
  111. package/dist/dom.js +5 -5
  112. package/dist/{dropdown-menu-DzkkyBwX.js → dropdown-menu-BJ7E9js_.js} +2 -2
  113. package/dist/dropdown-menu.js +1 -1
  114. package/dist/expandable-container.js +42 -38
  115. package/dist/fading-scroll.d.ts +1 -0
  116. package/dist/fading-scroll.js +2 -0
  117. package/dist/forms.js +3 -3
  118. package/dist/fourier-field.js +38 -37
  119. package/dist/fourier-math.js +2 -2
  120. package/dist/glass-panel.js +39 -36
  121. package/dist/glass-ui.css +1 -1
  122. package/dist/glass-ui.js +129 -145
  123. package/dist/goo-blob.js +86 -81
  124. package/dist/handmark.d.ts +1 -0
  125. package/dist/handmark.js +707 -0
  126. package/dist/header-ribbon.js +1 -1
  127. package/dist/hover-card.js +1 -1
  128. package/dist/hover-popover.js +1 -1
  129. package/dist/icon-chip.d.ts +1 -0
  130. package/dist/icon-chip.js +2 -0
  131. package/dist/icon-tooltip.js +1 -1
  132. package/dist/index.d.ts +2 -2
  133. package/dist/keyboard.js +1 -1
  134. package/dist/label.js +1 -1
  135. package/dist/labeled-field.js +6 -6
  136. package/dist/{math-U6-RrLmV.js → math-DeuJwLFx.js} +11 -3
  137. package/dist/{menuItemVariants-DPiEarb0.js → menuItemVariants-DWRQXBxJ.js} +10 -4
  138. package/dist/metric-badge.js +1 -1
  139. package/dist/metric-cell.js +25 -22
  140. package/dist/metric-stack.js +1 -1
  141. package/dist/motion-core.js +33 -32
  142. package/dist/motion-curves.js +1 -1
  143. package/dist/motion.js +4 -4
  144. package/dist/notification.js +1 -1
  145. package/dist/number-field.js +1 -1
  146. package/dist/pager-dots.d.ts +1 -0
  147. package/dist/pager-dots.js +91 -0
  148. package/dist/paper-backdrop.js +1 -1
  149. package/dist/popover.js +1 -1
  150. package/dist/{presets-BKVyQfbt.js → presets-BW2b-fr1.js} +14 -1
  151. package/dist/progress.js +1 -1
  152. package/dist/pulse.js +1 -1
  153. package/dist/reactive.js +2 -2
  154. package/dist/scrolling-text.js +1 -1
  155. package/dist/search.js +5 -5
  156. package/dist/select.js +3 -3
  157. package/dist/separator.js +1 -1
  158. package/dist/{sheet-1fChZjtw.js → sheet-CquRYOAw.js} +59 -55
  159. package/dist/sheet.js +1 -1
  160. package/dist/{slider-B-JP2JlI.js → slider-DQ95MET2.js} +7 -7
  161. package/dist/slider.js +1 -1
  162. package/dist/sortable-list.js +3 -3
  163. package/dist/styles/animations.css +11 -26
  164. package/dist/styles/components.css +1 -1
  165. package/dist/styles/configurator.css +35 -0
  166. package/dist/styles/dock/density.css +19 -0
  167. package/dist/styles/dock/overflow.css +15 -0
  168. package/dist/styles/dock/rail-extend.css +168 -71
  169. package/dist/styles/dock/section.css +59 -0
  170. package/dist/styles/dock/shell.css +34 -5
  171. package/dist/styles/dock-controls/icon-button.css +11 -1
  172. package/dist/styles/dock-controls/tab-button.css +24 -83
  173. package/dist/styles/dock-controls/triggers.css +7 -0
  174. package/dist/styles/dock.css +6 -3
  175. package/dist/styles/drawer.css +46 -0
  176. package/dist/styles/feedback-tone.css +104 -0
  177. package/dist/styles/glass/ladder.css +68 -22
  178. package/dist/styles/glass/surface-axis.css +113 -0
  179. package/dist/styles/glass/surfaces.css +88 -12
  180. package/dist/styles/glass.css +5 -2
  181. package/dist/styles/icon-chip.css +149 -0
  182. package/dist/styles/index.css +67 -5
  183. package/dist/styles/instrument-chassis.css +42 -0
  184. package/dist/styles/menu.css +127 -0
  185. package/dist/styles/segmented-tabs.css +160 -89
  186. package/dist/styles/select.css +50 -0
  187. package/dist/styles/theme/bridges.css +11 -1
  188. package/dist/styles/tokens/color-radius.css +40 -13
  189. package/dist/styles/tokens/dark-arm.css +124 -16
  190. package/dist/styles/tokens/glass.css +83 -23
  191. package/dist/styles/tokens/light-dark.css +48 -19
  192. package/dist/styles/tokens/offsets-sizing.css +62 -0
  193. package/dist/styles/tokens/property-regs.css +3 -10
  194. package/dist/styles/tokens/scale-paper.css +45 -2
  195. package/dist/styles/tokens/scheme-motion.css +32 -14
  196. package/dist/styles/transitions.css +7 -7
  197. package/dist/styles/typography/scale.css +153 -0
  198. package/dist/styles/typography/semantic.css +220 -0
  199. package/dist/styles/typography/utilities.css +159 -0
  200. package/dist/styles/typography.css +23 -507
  201. package/dist/styles/utilities/a11y-overrides.css +33 -4
  202. package/dist/styles/utilities/base.css +177 -1
  203. package/dist/styles/utilities/btn.css +18 -201
  204. package/dist/styles/view-transition.css +4 -1
  205. package/dist/switch.js +1 -1
  206. package/dist/tabs.js +154 -183
  207. package/dist/timeline.js +2 -2
  208. package/dist/toast.js +1 -1
  209. package/dist/toggle-chip.js +3 -1
  210. package/dist/toggle-group.js +1 -1
  211. package/dist/typewriter.js +1 -1
  212. package/dist/{useAnimatedNumber-C5I3wWd8.js → useAnimatedNumber-C_3wZLx4.js} +1 -1
  213. package/dist/useConfiguratorState-kiIlun8I.js +303 -0
  214. package/dist/{useGlobalDark-yhL4Wp-s.js → useGlobalDark-C28t0VWJ.js} +22 -3
  215. package/dist/{useRAFLoop-Bxv0o6L5.js → useRAFLoop-CdwJ7284.js} +1 -1
  216. package/dist/{useSpringMount-CI2jOstM.js → useSpringMount-CvopqiFr.js} +1 -1
  217. package/dist/useSurfaceAxis-CMnF2zHb.js +7 -0
  218. package/dist/{useTouchGate-Dg7MQI1G.js → useTouchGate-28Tk2-t2.js} +1 -1
  219. package/dist/{vReveal-CqaCz_mC.js → useViewTransition-COsPjQVZ.js} +15 -12
  220. package/dist/vReveal-D9k0jADx.js +10 -0
  221. package/dist/watercolor-dot.js +12 -5
  222. package/package.json +71 -7
  223. package/src/styles/animations.css +11 -26
  224. package/src/styles/configurator.css +35 -0
  225. package/src/styles/dock/density.css +19 -0
  226. package/src/styles/dock/overflow.css +15 -0
  227. package/src/styles/dock/rail-extend.css +168 -71
  228. package/src/styles/dock/section.css +59 -0
  229. package/src/styles/dock/shell.css +34 -5
  230. package/src/styles/dock-controls/icon-button.css +11 -1
  231. package/src/styles/dock-controls/tab-button.css +24 -83
  232. package/src/styles/dock-controls/triggers.css +7 -0
  233. package/src/styles/dock.css +6 -3
  234. package/src/styles/drawer.css +42 -0
  235. package/src/styles/feedback-tone.css +104 -0
  236. package/src/styles/glass/ladder.css +68 -22
  237. package/src/styles/glass/surface-axis.css +113 -0
  238. package/src/styles/glass/surfaces.css +88 -12
  239. package/src/styles/glass.css +5 -2
  240. package/src/styles/icon-chip.css +149 -0
  241. package/src/styles/index.css +66 -4
  242. package/src/styles/instrument-chassis.css +42 -0
  243. package/src/styles/menu.css +127 -0
  244. package/src/styles/segmented-tabs.css +156 -87
  245. package/src/styles/select.css +50 -0
  246. package/src/styles/theme/bridges.css +11 -1
  247. package/src/styles/tokens/color-radius.css +40 -13
  248. package/src/styles/tokens/dark-arm.css +124 -16
  249. package/src/styles/tokens/glass.css +83 -23
  250. package/src/styles/tokens/light-dark.css +48 -19
  251. package/src/styles/tokens/offsets-sizing.css +62 -0
  252. package/src/styles/tokens/property-regs.css +3 -10
  253. package/src/styles/tokens/scale-paper.css +45 -2
  254. package/src/styles/tokens/scheme-motion.css +32 -14
  255. package/src/styles/transitions.css +7 -7
  256. package/src/styles/typography/scale.css +153 -0
  257. package/src/styles/typography/semantic.css +220 -0
  258. package/src/styles/typography/utilities.css +159 -0
  259. package/src/styles/typography.css +23 -507
  260. package/src/styles/utilities/a11y-overrides.css +33 -4
  261. package/src/styles/utilities/base.css +177 -1
  262. package/src/styles/utilities/btn.css +18 -201
  263. package/src/styles/view-transition.css +4 -1
  264. package/dist/CardAction-Cj2eycQ2.js +0 -157
  265. package/dist/DialogContent-Dl9WkAoS.js +0 -100
  266. package/dist/PopoverContent-BYwt2-4x.js +0 -121
  267. package/dist/TabsList-Dttss653.js +0 -105
  268. package/dist/components/custom/underline/GlassUnderline.vue.d.ts +0 -84
  269. package/dist/components/custom/underline/index.d.ts +0 -2
  270. package/dist/components/custom/underline/types.d.ts +0 -56
  271. package/dist/components/ui/carousel/CarouselDots.vue.d.ts +0 -4
  272. package/dist/underline.d.ts +0 -1
  273. package/dist/underline.js +0 -85
  274. package/dist/useConfiguratorState-DAoeHVue.js +0 -287
  275. /package/dist/{CollapsibleContent-CP9qF1v4.js → CollapsibleContent-C_s6fG7r.js} +0 -0
  276. /package/dist/{ContextMenuContent-CT3AS1WX.js → ContextMenuContent-ON3x7cuk.js} +0 -0
  277. /package/dist/{HoverCardContent-Csywg3YF.js → HoverCardContent-DkMaQzH5.js} +0 -0
  278. /package/dist/{IconTooltip-DPzE09X9.js → IconTooltip-DSjasZIt.js} +0 -0
  279. /package/dist/{Input-DWQQIOC4.js → Input-DVG_J0ne.js} +0 -0
  280. /package/dist/{Label-r3WzWrsj.js → Label-Ck9SWEKM.js} +0 -0
  281. /package/dist/{ModalOverlay-DVLI2VRr.js → ModalOverlay-CkPRRgl_.js} +0 -0
  282. /package/dist/{PaperBackdrop-DIXTtVq6.js → PaperBackdrop-nBKe0vkB.js} +0 -0
  283. /package/dist/{SelectGroup-aumMgWLs.js → SelectGroup-Dcczq44n.js} +0 -0
  284. /package/dist/{SelectSeparator-BQ_1Fcbp.js → SelectSeparator-DK2y1Bun.js} +0 -0
  285. /package/dist/{Separator-0JE6LtNu.js → Separator-BArl4OaB.js} +0 -0
  286. /package/dist/{_plugin-vue_export-helper-ok8pgSl5.js → _plugin-vue_export-helper-CBt_VvXa.js} +0 -0
  287. /package/dist/{color-CUYeFbgd.js → color-DweYl7pE.js} +0 -0
  288. /package/dist/{compile-B7NGOBcP.js → compile-EXXzEr1q.js} +0 -0
  289. /package/dist/{constants-CS75AWHG.js → constants-BPOqYJAm.js} +0 -0
  290. /package/dist/{createContext-BM46COQ-.js → createContext-B2RaZ-b8.js} +0 -0
  291. /package/dist/{prng-D27-B3tK.js → prng-Cg22zv8g.js} +0 -0
  292. /package/dist/{springPresets--YdWTHtm.js → springPresets-WXaLbu8u.js} +0 -0
  293. /package/dist/{useIntersectionPause-Cc-H9ees.js → useIntersectionPause-Bj4sPkMh.js} +0 -0
  294. /package/dist/{useInterval-iHludrxk.js → useInterval-CNdua40W.js} +0 -0
  295. /package/dist/{useKeyboardShortcuts-Be3w_Rwk.js → useKeyboardShortcuts-BXWXOZ-9.js} +0 -0
  296. /package/dist/{useLiquidFlex-BL0lLLN2.js → useLiquidFlex-C12hXwOZ.js} +0 -0
  297. /package/dist/{useResizeObserver-BhgdhOIj.js → useResizeObserver-V6nq5gJb.js} +0 -0
  298. /package/dist/{useResolveTokenColor-Dvn2RZJW.js → useResolveTokenColor-NUG2zYAW.js} +0 -0
  299. /package/dist/{useScrollProgress-Dlvx-L3v.js → useScrollProgress-D7bYU2RK.js} +0 -0
  300. /package/dist/{useSortable-muI29agz.js → useSortable-BVqlJRBR.js} +0 -0
  301. /package/dist/{useTextHighlight-DmRYkOBx.js → useTextHighlight-NmBM5V_4.js} +0 -0
  302. /package/dist/{useTimer-Dzarvzuk.js → useTimer-B_PAasDL.js} +0 -0
  303. /package/dist/{useUserInvalidAria-B2h6jAM_.js → useUserInvalidAria-CDfJuakL.js} +0 -0
  304. /package/dist/{useViewportReady-B40FK4Pa.js → useViewportReady-CvBcCYDf.js} +0 -0
@@ -41,6 +41,7 @@
41
41
  @import "./dock/layer-group.css";
42
42
  @import "./dock/overflow.css";
43
43
  @import "./dock/rail-extend.css";
44
+ @import "./dock/section.css";
44
45
  @import "./dock/morph-bridge.css";
45
46
 
46
47
  /* AX.W01 — the SINGLE morph scalar. `useLayerTransition` writes it once per frame
@@ -81,10 +82,12 @@
81
82
  --dock-motion-fast: var(--duration-fast) var(--ease-standard);
82
83
  --dock-motion-standard: var(--duration-normal) var(--ease-standard);
83
84
  /* AT.W6-dock-c — the FLIP-fallback timing. `--dock-resize-spring` (the
84
- `--spring-snappy` linear()) is the single source curve the native
85
+ `--spring-dock` linear()) is the single source curve the native
85
86
  View-Transition path ALSO consumes, so the morph is timing-identical
86
- across engines. */
87
- --dock-motion-resize: var(--duration-normal) var(--dock-resize-spring);
87
+ across engines. BA.W-GLASS-CAL Unit 3 — the duration leg re-times off
88
+ the generic `--duration-normal` (0.3s) onto `--spring-dock-duration`
89
+ (0.28s, the dock spring's OWN 2%-band envelope settle). */
90
+ --dock-motion-resize: var(--spring-dock-duration) var(--dock-resize-spring);
88
91
  }
89
92
 
90
93
  /* Shared four-state contract — the focus-visible ring + disabled paint are
@@ -60,6 +60,52 @@
60
60
  box-shadow: var(--glass-material-rim), var(--glass-shadow-overlay);
61
61
  }
62
62
 
63
+ /*
64
+ * BA.W-SURFACE-AXIS — the shared {glass·veil·opaque} surface decoration ON TOP of
65
+ * the `.glass-drawer` recipe. `.glass-drawer` is UNLAYERED (this file), so the
66
+ * `@layer components` `[data-surface]` seam in glass/surface-axis.css would LOSE
67
+ * to it (an unlayered rule always beats a layered one — the AZ.W-DOCK-RAIL
68
+ * cascade-win trap). The fix is the SAME-LAYER carve: these `.glass-drawer[data-
69
+ * surface=…]` rules sit unlayered alongside `.glass-drawer` and win by specificity
70
+ * (attr+class > class), composing the SAME veil/opaque deltas the shared seam
71
+ * declares — NO `glass-drawer`-local recipe fork (they read the same `--veil-*` /
72
+ * `--glass-level` machinery). The `glass` rung is the identity (no rule).
73
+ */
74
+ .glass-drawer[data-surface="veil"] {
75
+ --veil-bg: color-mix(
76
+ in oklab,
77
+ var(--glass-bg-quiet),
78
+ var(--glass-tint-source) var(--glass-tint-strength)
79
+ );
80
+ --veil-blur: var(--glass-blur-quiet);
81
+ background: var(--veil-bg);
82
+ -webkit-backdrop-filter: var(--veil-blur);
83
+
84
+ backdrop-filter: var(--veil-blur);
85
+ -webkit-backdrop-filter: var(--veil-blur);
86
+ border: none;
87
+ box-shadow: none;
88
+ }
89
+
90
+ .glass-drawer[data-surface="opaque"] {
91
+ /* The solid-card escape. The `.glass-drawer` background reads the `:root`-baked
92
+ `--glass-bg-overlay` token (which substitutes `--glass-level` at :root), so a
93
+ per-element `--glass-level: 0` cannot re-resolve it — the substitution-vs-
94
+ inheritance trap (mirrors surface-axis.css). Set the SOLID plate AT THE
95
+ ELEMENT; still flip the level/tint knobs for a nested glass descendant. */
96
+ --glass-level: 0;
97
+ --glass-tint-strength: 0%;
98
+ /* The SOLID --card plate via the house color-mix idiom (solid --card, expressed
99
+ as the cohesion-sanctioned mix the token ladder speaks — NOT the bare
100
+ `var(--card)` the cohesion D1 check forbids for the always-on drawer plate;
101
+ this is the EXPLICIT opt-out behind `surface="opaque"`, not the default). */
102
+ background: color-mix(in srgb, var(--card), transparent 0%);
103
+ -webkit-backdrop-filter: none;
104
+
105
+ backdrop-filter: none;
106
+ -webkit-backdrop-filter: none;
107
+ }
108
+
63
109
  /*
64
110
  * Detented (snap-point) sheets fill the viewport height. vaul positions the
65
111
  * sheet by translating it DOWN by `innerHeight - (fraction * innerHeight)` —
@@ -0,0 +1,104 @@
1
+ /* feedback-tone.css — the ONE shared tinted-glass tone recipe (BA.W-FEEDBACK-TONE).
2
+
3
+ THE COLLAPSE: Toast, Notification, and Alert each carried an INDEPENDENT tone map
4
+ (the Toast variant map painted SOLID `bg-{success,warning,info,destructive}` opaque
5
+ token plates over a `glass-floating` base; the Notification type map painted
6
+ `bg-<tone>/90` near-opaque slabs; Alert alone was correct in SHAPE — glass-wash plate
7
+ + tone-on-rim — but HARDCODED its `border-<tone>/40` rim per variant). Three tone
8
+ maps, three calibration sites, and TWO of them painted a colored SLAB that occluded
9
+ the backdrop (the R8-12/R8-13 "not glassy at all" defect; the blur track survived but
10
+ was inert behind a 100%-opaque plate).
11
+
12
+ This file mints the tone register ONCE. Every feedback tone reads as COLORED GLASS:
13
+ a tinted-glass wash (the rung bg mixed a BOUNDED % toward the tone, the SAME
14
+ `color-mix(in oklab, <rung bg>, <tint> <strength>)` seam the W55 `--glass-tint-*`
15
+ legibility lift and the `--veil-bg` plate already run — ZERO new compositing path) +
16
+ a tone-keyed rim + a full-chroma glyph. The backdrop STILL shows through (α stays
17
+ translucent, the W2 π floor < ~0.92). The body ink stays `--foreground` /
18
+ `--card-foreground` for legibility (the Alert discipline — body never tone-tinted),
19
+ so the tone is ONE deliberate color event per surface (the AZ.W-SUFFUSE one-color-
20
+ event idiom), never a full-bleed fill.
21
+
22
+ THE ONE KNOB: `--feedback-tone-strength` tints all four tones at once (the bounded
23
+ mix %, the toast-glass §A band). The four tone hues map to the HOUSE tokens
24
+ `--success` / `--warning` / `--info` / `--destructive` (presets-in-consumers — NO new
25
+ colors). A consumer recalibrates the tone weight with ONE override.
26
+
27
+ THE RUNG: the register reads `--feedback-tone-rung` (default the floating-chrome rung
28
+ `--glass-bg-floating`, the Toast/Notification overlay register). Alert RE-POINTS it to
29
+ `--glass-bg-wash` on its own surface (a content panel rides wash, not floating — the
30
+ register difference is correct; only the tone SOURCE unifies, not the rung). The rung
31
+ reads `--glass-bg-*` DIRECTLY (the same tokens W-SURFACE-AXIS's glass arm routes), so
32
+ the tone tint rides ON the glass surface — a re-point, not a fork.
33
+
34
+ THE SUBSTITUTION TRAP (the recurring AX.W55 / dock-scale class): `--feedback-tone-rung`
35
+ resolves the `--glass-bg-floating` token, which BAKES `var(--glass-level)` at its
36
+ `:root` declaration (level=1). A descendant `--glass-level: 0` does NOT re-resolve the
37
+ baked rung — but that is the CORRECT register here: a feedback surface IS translucent
38
+ glass by design; the `opaque`/level-0 escape is W-SURFACE-AXIS's `[data-surface]`
39
+ concern, not a tone-register knob. The tone register composes the tint AT THE ELEMENT
40
+ off the resolved rung, so the `color-mix` re-resolves whenever `--tone`/`--feedback-
41
+ tone-strength`/the rung change (the W55 element-level tint discipline). */
42
+ @layer components {
43
+ :root {
44
+ /* The bounded mix % — the tone wash strength. 18% reads as colored GLASS
45
+ (the backdrop shows through, the silhouette is unmistakably tinted) without
46
+ tipping toward a slab; the toast-glass §A band is ≈12–22%. ONE knob retunes
47
+ all four tones. */
48
+ --feedback-tone-strength: 18%;
49
+ /* The rung the tint mixes over — the floating-chrome register (Toast /
50
+ Notification). Alert re-points it to the wash rung on its own surface. */
51
+ --feedback-tone-rung: var(--glass-bg-floating);
52
+ /* The rim weight — a tone-keyed border, a thin tinted rim (not a loud edge). */
53
+ --feedback-tone-border-strength: 40%;
54
+ }
55
+
56
+ /* ── The parametric register ──────────────────────────────────────────────────
57
+ A surface declares `--tone` (one of the four house tokens) + composes
58
+ `.feedback-tone`; the tinted-glass wash + the tone-keyed rim resolve off the ONE
59
+ recipe. The glyph carries the FULL-chroma tone (`[&>svg]` via the consumer's own
60
+ class, or the `.feedback-tone-glyph` helper below). The `default` (un-toned)
61
+ surface simply omits `.feedback-tone` — the bare glass rung paints.
62
+
63
+ `--tone` has NO `:root` default ON PURPOSE: a `.feedback-tone` surface with no
64
+ `--tone` set would mix the rung toward `initial` (transparent) — a no-op wash, the
65
+ same as the bare rung; this is the safe degenerate, not a paint bug. Every real
66
+ consumer sets `--tone` via its `.feedback-tone-<name>` register. */
67
+ .feedback-tone {
68
+ background: color-mix(
69
+ in oklab,
70
+ var(--feedback-tone-rung),
71
+ var(--tone) var(--feedback-tone-strength)
72
+ );
73
+ border-color: color-mix(
74
+ in oklab,
75
+ transparent,
76
+ var(--tone) var(--feedback-tone-border-strength)
77
+ );
78
+ }
79
+
80
+ /* The four house tone registers — each binds `--tone` to its house token. A surface
81
+ maps its variant/type onto the matching class (Toast `variant` /
82
+ Notification `type` / Alert `variant`); the `error` notification type maps to the
83
+ destructive tone (the three-maps-into-one collapse — `error` IS destructive). */
84
+ .feedback-tone-success {
85
+ --tone: var(--success);
86
+ }
87
+ .feedback-tone-warning {
88
+ --tone: var(--warning);
89
+ }
90
+ .feedback-tone-info {
91
+ --tone: var(--info);
92
+ }
93
+ .feedback-tone-destructive {
94
+ --tone: var(--destructive);
95
+ }
96
+
97
+ /* The glyph helper — the leading status glyph carries the FULL-chroma tone (the one
98
+ color event's saturated note over the tinted wash). A consumer composes it on its
99
+ icon, or reads `var(--tone)` directly in an arbitrary `[&>svg]:text-(--tone)`
100
+ utility. */
101
+ .feedback-tone-glyph {
102
+ color: var(--tone);
103
+ }
104
+ }
@@ -141,6 +141,13 @@
141
141
  .glass-card {
142
142
  --glass-tint-source: var(--glass-tint-ink);
143
143
  --glass-tint-strength: var(--glass-tint-strength-aa);
144
+ /* BA.W-DARK-MATERIAL scope 7 — the --muted-foreground lift moves HERE, into the
145
+ declared/sampled BRIGHT condition. The muted L40 tier cannot clear 4.5:1 on a
146
+ translucent FULL-AA-darkened plate (darkening moves the plate toward muted's
147
+ own luminance), so it lifts to the full ink ONLY where the plate actually
148
+ darkens — NOT on the calm-light unconditional floor (where it stays the muted
149
+ register, the slides caption read). */
150
+ --muted-foreground: var(--foreground);
144
151
  }
145
152
  }
146
153
 
@@ -182,19 +189,35 @@
182
189
  TOWARD muted's own luminance), so the low-contrast muted register resolves to
183
190
  the legible dark ink (clears ~10:1) — a token re-point on the same inheriting
184
191
  axis as the tint. */
185
- :where(
186
- .glass-floating,
187
- .glass-overlay,
188
- .glass-card,
189
- .glass-resting,
190
- .glass-quiet,
191
- .glass-wash
192
- ) {
192
+ /* The OVERLAY band (.glass-floating/.glass-overlay — Dialog/Sheet/Popover/DropdownMenu/
193
+ HoverCard/Command/Tooltip/Toast/Select-content) keeps the FULL unconditional AA darken
194
+ + the muted lift: it floats over WHATEVER the consumer painted (frequently a light/
195
+ near-white app surface — the canonical G2 case), so darkening toward the warm-ink is
196
+ the correct DEFAULT over an UNKNOWN surface. Over a DARK page this becomes the
197
+ luminous-dark LIFT (the dark-arm re-tunes --glass-tint-strength-aa to 12% — the plate
198
+ lifts off the deep page). A dark-substrate consumer who wants the pristine plate sets
199
+ `--glass-tint-strength: 0%`. */
200
+ :where(.glass-floating, .glass-overlay) {
193
201
  --glass-tint-source: var(--glass-tint-ink);
194
202
  --glass-tint-strength: var(--glass-tint-strength-aa);
195
203
  --muted-foreground: var(--foreground);
196
204
  }
197
205
 
206
+ /* BA.W-DARK-MATERIAL scope 7 — the plain CONTENT tiers self-engage the SUB-PERCEPTUAL
207
+ FLOOR unconditionally, NOT the full AA darken (the R9-1 slides gray-slab fix). Over a
208
+ calm LIGHT page the floor (--glass-tint-strength-floor: 4%) is a silhouette whisper —
209
+ the translucent cream card stays warm (L ≈ 0.94), no gray slab. Over a DARK page the
210
+ floor re-resolves to the luminous-dark lift (12% in the dark arm — the plate lifts off
211
+ the deep page, the desired register). The FULL AA darken engages on these tiers ONLY
212
+ under the declared/sampled BRIGHT signal (the @container --glass-backdrop:light bucket
213
+ above — where the muted lift also lives now). NO unconditional --muted-foreground lift
214
+ here: on the calm-light floor the caption keeps the muted register (the slides read).
215
+ A consumer opts a light-page card out via `--glass-tint-strength: 0%` on an ancestor. */
216
+ :where(.glass-card, .glass-resting, .glass-quiet, .glass-wash) {
217
+ --glass-tint-source: var(--glass-tint-ink);
218
+ --glass-tint-strength: var(--glass-tint-strength-floor);
219
+ }
220
+
198
221
  /* AX.W55 — the `contrast-color()` foreground-ink flip (Chrome 147+/Safari 26+).
199
222
  A PROGRESSIVE-ENHANCEMENT layer, NEVER the load-bearing floor (Open-Q #5
200
223
  ratified): the declarative bucket above already carries AA on ALL engines (it
@@ -207,6 +230,20 @@
207
230
  white, illegible on the still-light translucent plate). The bucket is the floor;
208
231
  this is the native refinement. Scoped to the bright bucket. */
209
232
  @supports (color: contrast-color(white)) {
233
+ /* The bright-bucket ink flip — the content tiers + overlay band over a DECLARED/
234
+ sampled bright backdrop. BA.W-DARK-MATERIAL scope 6 — the SYSTEMIC contrast-color()
235
+ selection-inversion fix (approach A, lockstep-lift). At HEAD this block lifted only
236
+ --muted-foreground (and the surface `color`) to contrast-color(--card) (white over
237
+ a light plate, L100), but the ACTIVE control register (a SegmentedTabs active tab,
238
+ the curve-picker selected label) reads var(--foreground) DIRECTLY (L90, un-lifted) —
239
+ a control sets its OWN `color: var(--foreground)` which wins over the inherited
240
+ surface `color`, so the inactive (muted→white) read BRIGHTER than the active
241
+ (--foreground), inverting selection. The fix lifts --foreground ITSELF in lockstep
242
+ with --muted-foreground: now an active register reading --foreground resolves the
243
+ SAME anchored contrast-color ink as the lifted inactive, so selected ≥ unselected
244
+ everywhere (the inversion gone for ANY --muted-foreground/--foreground selection
245
+ pairing inside a glass card — the SYSTEMIC library-seam fix, not a curve-picker
246
+ one-off). Progressive enhancement only — the declarative darken is the AA floor. */
210
247
  @container style(--glass-backdrop: light) {
211
248
  .glass-material,
212
249
  .glass-wash,
@@ -216,25 +253,26 @@
216
253
  .glass-overlay,
217
254
  .glass-card {
218
255
  color: contrast-color(var(--card));
256
+ --foreground: contrast-color(var(--card));
257
+ --muted-foreground: contrast-color(var(--card));
219
258
  }
220
259
  }
221
- /* AY.W-A11Y-PERF O-1 / AZ.W-ADAPTIVE-AUTO Arm 1 — the same contrast-color
222
- refinement for the SELF-ENGAGED band + content tiers (the @container block
223
- above queries an ancestor; these surfaces engage their own tint
224
- unconditionally, so their ink-flip companion mirrors that). The muted
225
- register flips to the same anchored dark ink. Progressive enhancement only
226
- — the declarative darken above is the AA floor on all engines. */
227
- :where(
228
- .glass-floating,
229
- .glass-overlay,
230
- .glass-card,
231
- .glass-resting,
232
- .glass-quiet,
233
- .glass-wash
234
- ) {
260
+ /* The OVERLAY band self-engages the darken UNCONDITIONALLY (it floats over an
261
+ UNKNOWN consumer surface), so its ink-flip companion mirrors that — UNCONDITIONAL.
262
+ --foreground lifts in lockstep with --muted-foreground (the scope-6 lockstep). */
263
+ :where(.glass-floating, .glass-overlay) {
235
264
  color: contrast-color(var(--card));
265
+ --foreground: contrast-color(var(--card));
236
266
  --muted-foreground: contrast-color(var(--card));
237
267
  }
268
+ /* BA.W-DARK-MATERIAL scope 7 — the content-tier ink flip is GATED on the bright
269
+ signal (it moved INTO the @container bucket above), NOT unconditional. Over a calm
270
+ LIGHT page the content tiers only carry the 4% silhouette floor (still a warm cream
271
+ plate), so flipping the ink to the contrast-color DARK ink there is correct only
272
+ where the plate ACTUALLY darkens to the bright-bucket AA — the unconditional flip
273
+ would force a white-on-cream / dark-on-darkened mismatch on the calm card. The
274
+ content tiers therefore take NO unconditional contrast-color flip; their flip lives
275
+ in the @container bucket with the rest of the bright-condition darken. */
238
276
  }
239
277
 
240
278
  /* ── The opaque escape (AX.W54) ───────────────────
@@ -248,6 +286,14 @@
248
286
  a consumer that wants a flat surface). */
249
287
  .glass-opaque {
250
288
  --glass-level: 0;
289
+ /* BA.W-DARK-MATERIAL scope 7 — the opaque escape suppresses the adaptive TINT axis
290
+ too (not just the opacity/blur level). A solid opaque plate has no translucent
291
+ backdrop to darken-over, so the self-engage tint is meaningless on it; zeroing the
292
+ strength keeps the opaque escape bucket-INVARIANT (the unset floor and the bright
293
+ bucket resolve the SAME solid plate — the byte-identity canary). Without this, the
294
+ scope-7 unconditional content-tier floor (4%) tinted even the solid plate, breaking
295
+ the opt-out's "flat surface" contract. */
296
+ --glass-tint-strength: 0%;
251
297
  }
252
298
 
253
299
  /* ── Content-aware under-shadow modifier (AV.W15 M4) ──────────────
@@ -0,0 +1,113 @@
1
+ /* glass/surface-axis.css — the ONE shared {glass·veil·opaque} surface-decoration
2
+ axis (BA.W-SURFACE-AXIS).
3
+
4
+ The house minted `--glass-level` (the opacity knob, AX.W54) and `--glass-tint-*`
5
+ (the legibility seam, AX.W55) as SHARED inheriting axes, but left the
6
+ {glass·veil·opaque} surface-DECORATION choice as a per-component one-off
7
+ (`<Card>` had the only true axis; `<Dialog>` a binary string; everyone else
8
+ none). This seam factors that choice ONCE — every enrolled surface composes a
9
+ base glass tier + the `[data-surface]` attribute, and these rules apply the
10
+ three-rung decoration UNIFORMLY:
11
+
12
+ glass — the resolved tier's plain glass rung (IDENTITY; no rule needed —
13
+ the bare tier paints).
14
+ veil — the borderless/rimless text-legibility plate: the `--glass-bg-quiet`
15
+ fill + blur with the box border AND rim STRIPPED (the boxed look
16
+ reads as a dividing line on a text plate). Reads `--glass-bg-quiet`
17
+ + the W55 `--glass-tint-*` seam through the SAME `--glass-*` ladder,
18
+ so `--glass-level` / the bright-bucket darken retune it in lockstep
19
+ with every glass surface — NO veil-local recipe fork.
20
+ opaque — the `--glass-level:0` solid-card escape (the `.glass-opaque` rung):
21
+ solid `--card` + `blur(0)` through the ONE level knob, the tint axis
22
+ zeroed (a solid plate has no translucent backdrop to darken-over).
23
+
24
+ NO second axis: `cartoon` stays a Card-local decoration (it is NOT a
25
+ {glass·veil·opaque} member — the shared axis is the three-rung MATERIAL
26
+ decoration; cartoon rides Card's own `surface` superset). The `Surface` union +
27
+ the `surfaceClass(surface, tier)` resolver are the TS half
28
+ (`src/components/ui/_shared/useSurfaceAxis.ts`); this file is the CSS half.
29
+
30
+ Cascade: `@layer components`, @import-ed AFTER ladder.css so the attr rules
31
+ (specificity 0-1-0, equal to the `.glass-*` classes) win by source order over
32
+ the base rung's border/box-shadow. */
33
+ @layer components {
34
+ /* ── veil — the borderless text-legibility plate ──────────────────────────
35
+ Composes the SAME deltas as the `veil-surface` @utility (cards.css), keyed
36
+ off the SAME `--glass-bg-quiet` + `--glass-tint-*` tokens (no recipe fork).
37
+ Each delta is an overridable `--veil-*` rung so a consumer re-points the
38
+ plate to any other ladder rung. */
39
+ [data-surface="veil"] {
40
+ --veil-bg: color-mix(
41
+ in oklab,
42
+ var(--glass-bg-quiet),
43
+ var(--glass-tint-source) var(--glass-tint-strength)
44
+ );
45
+ --veil-blur: var(--glass-blur-quiet);
46
+ /* The three veil deltas over a bare rung — each overridable. */
47
+ --veil-border: none;
48
+ --veil-shadow: none;
49
+ --veil-feather: none;
50
+
51
+ background: var(--veil-bg);
52
+ backdrop-filter: var(--veil-blur);
53
+ -webkit-backdrop-filter: var(--veil-blur);
54
+ border: var(--veil-border);
55
+ box-shadow: var(--veil-shadow);
56
+ /* The optional radial feather — a `mask-image` only painted when
57
+ `--veil-feather` is set to a gradient (default `none` = no mask = a
58
+ clean rectangle). `mask-image: none` is the identity. */
59
+ mask-image: var(--veil-feather);
60
+ }
61
+
62
+ /* ── opaque — the solid-card escape ───────────────────────────────────────
63
+ The level-0 endpoint of the SAME glass machinery — a solid `--card` plate
64
+ with `blur(0)`. A surface that ALSO carries a base tier keeps its glass
65
+ edge/rim/under-shadow (a solid plate with a glass edge, not a bare div).
66
+
67
+ THE SUBSTITUTION-VS-INHERITANCE TRAP (the recurring AX.W55 / dock-scale
68
+ class, live-found in the π readback): the `--glass-bg-*` tier tokens bake
69
+ `var(--glass-level)` at their `:root` DECLARATION (where level=1), so a
70
+ DESCENDANT element's `--glass-level: 0` does NOT re-resolve the `:root`-baked
71
+ `--glass-bg-floating` — the plate stayed translucent (α 0.8, NOT solid). The
72
+ `.glass-opaque` class works only when `--glass-level` is set at `:root` (the
73
+ cohesion fixture's pattern); a PER-ELEMENT opaque surface (the whole point of
74
+ `surface="opaque"`) needs the solid plate composed AT THE ELEMENT. So the
75
+ opaque rung sets the SOLID `--card` background + `blur(0)` DIRECTLY (the
76
+ level-0 endpoint resolved here, not via the baked token) — AND still flips the
77
+ `--glass-level: 0` / `--glass-tint-strength: 0%` knobs so a NESTED glass
78
+ descendant + any consumer reading the level scalar see the opaque register
79
+ coherently. The adaptive TINT axis is zeroed (a solid plate has no
80
+ translucent backdrop to darken-over — the bucket-INVARIANT contract). */
81
+ [data-surface="opaque"] {
82
+ --glass-level: 0;
83
+ --glass-tint-strength: 0%;
84
+ /* The SOLID --card plate composed at the element via the house color-mix
85
+ idiom (`--card` over transparent at 0% transparent = fully solid --card)
86
+ — functionally `var(--card)`, expressed as the cohesion-sanctioned mix
87
+ the token ladder already speaks. */
88
+ background: color-mix(in srgb, var(--card), transparent 0%);
89
+ backdrop-filter: none;
90
+ -webkit-backdrop-filter: none;
91
+ }
92
+
93
+ /* ── .paper-ink-mark — the PAPER ink-hairline MARK register ────────────────
94
+ (BA.W-SURFACE-AXIS scope 8). The 2px `--foreground` ink mark on a paper
95
+ surface — NO plate, NO blur, NO glass. This is a MARK register, NOT a
96
+ `[data-surface]` plate rung: a `[data-surface]` value DECORATES a glass
97
+ plate (fill + edge + rim); `.paper-ink-mark` is the opposite — a bare ink
98
+ hairline drawn directly on paper, the math-paper section-rail / underline-
99
+ tab vocabulary. Recorded here (the surface-decoration seam) co-located with
100
+ the plate axis but DISTINCT from it — the canon note is in CLAUDE.md.
101
+
102
+ ≥2 consumers at birth: (1) the math-paper section rail (the `border-l-[3px]`
103
+ family composes it for a VERTICAL left-edge ink rail); (2) W-TABS's re-cut
104
+ underline indicator (a HORIZONTAL 2px ink mark — W-TABS CONSUMES this seam,
105
+ a shape gap there triumvirates HERE per the DAG §5 seam rule). The register
106
+ exposes ONE knob (`--paper-ink-mark-weight`, default 2px) + the ink color;
107
+ the consumer applies the weight on whichever edge/axis it draws (a left
108
+ `border-inline-start-width` rail, a bottom `block-size` underline). */
109
+ .paper-ink-mark {
110
+ --paper-ink-mark-weight: 2px;
111
+ --paper-ink-mark-color: var(--foreground);
112
+ }
113
+ }
@@ -43,6 +43,17 @@
43
43
 
44
44
  /* ── Glassmorphic circular icon button ── */
45
45
 
46
+ /* BA.W-DEMO-AFFORDANCES (IG-A4) — the two size registers below are
47
+ MUTUALLY EXCLUSIVE; never stack `.glass-btn` and `.btn-pill` on one
48
+ element. `.glass-btn` is the FIXED-square icon primitive (width/height:
49
+ var(--size-icon-btn) + contain:paint) — `.btn-pill` is the CONTENT-WIDTH
50
+ text pill. Stacked, the fixed square wins and contain:paint clips the
51
+ wrapped label into a ~40px blob (the R8-17 "play button" defect). A
52
+ text-bearing `.glass-btn` collapses the same way even without `.btn-pill`.
53
+ For a play/replay affordance reach for <StoryPlayButton> (demo) or a real
54
+ <Button> with a leading Lucide glyph, never an icon-button carrying text.
55
+ Machine-locked by proof:demo-affordances (W1 — no class co-occurrence,
56
+ no text-bearing icon button). */
46
57
  .glass-btn {
47
58
  @apply flex items-center justify-center cursor-pointer;
48
59
 
@@ -72,7 +83,7 @@
72
83
  background var(--duration-fast) var(--ease-standard),
73
84
  border-color var(--duration-fast) var(--ease-standard),
74
85
  color var(--duration-fast) var(--ease-standard),
75
- scale var(--duration-normal) var(--spring-smooth);
86
+ scale var(--spring-smooth-duration) var(--spring-smooth);
76
87
  }
77
88
 
78
89
  .glass-btn:hover:not(:disabled) {
@@ -141,7 +152,7 @@
141
152
  box-shadow var(--duration-fast) var(--ease-standard),
142
153
  color var(--duration-fast) var(--ease-standard),
143
154
  opacity var(--duration-fast) var(--ease-standard),
144
- scale var(--duration-fast) var(--spring-smooth);
155
+ scale var(--spring-smooth-duration) var(--spring-smooth);
145
156
  }
146
157
 
147
158
  .btn-pill > * {
@@ -189,16 +200,21 @@
189
200
  `:focus-visible` accent ring + the `:user-invalid`/`[aria-invalid]`
190
201
  destructive ring below still win by order + specificity.
191
202
  AX.W54 — moved off the srgb `--surface-tint-15` fork onto the glass
192
- border seam (`--glass-border-floating`, the matching 15%α rung) so the
193
- pill is ONE glass model with the rest of the ladder, not a divergent
194
- tint axis. */
195
- border: 1.5px solid var(--glass-border-floating);
196
- background: var(--glass-bg-quiet);
197
- /* AX.W54 — the pill reads as REAL glass: the quiet-tier 10px blur (the
198
- same `--glass-blur-quiet` its `--glass-bg-quiet` background pairs with),
199
- not the sub-perceptual `blur(1px)` wash it carried — and the
200
- `--glass-level` knob now clarifies it in lockstep with every surface. */
201
- backdrop-filter: var(--glass-blur-quiet);
203
+ border seam so the pill is ONE glass model with the rest of the ladder.
204
+ BA.W-SURFACE-AXIS scope 7 — re-pointed onto the SHARED `--control-surface-*`
205
+ REST register so Input/Textarea/NumberField/Select/Combobox/TagsInput are
206
+ ONE material at rest (the input rung was the warmer of the two; Select rode
207
+ the `glass-wash` gray — the no-gray control-family seam). The register reads
208
+ the same `--glass-*` ladder, so `--glass-level`/the W55 bright bucket retune
209
+ the whole form family in lockstep (--control-surface-border defaults to the
210
+ `--glass-border-floating` 15%α rung, --control-surface-bg to `--glass-bg-quiet`,
211
+ --control-surface-blur to `--glass-blur-quiet`). */
212
+ border: 1.5px solid var(--control-surface-border);
213
+ background: var(--control-surface-bg);
214
+ /* The control's REAL glass blur — the shared register's quiet-tier radius
215
+ (the same `--control-surface-blur` pairs with `--control-surface-bg`); the
216
+ `--glass-level` knob clarifies it in lockstep with every surface. */
217
+ backdrop-filter: var(--control-surface-blur);
202
218
  padding: 0 calc(1rem * var(--ui-scale));
203
219
  font-size: var(--control-text);
204
220
  color: var(--foreground);
@@ -214,6 +230,24 @@
214
230
  color: var(--surface-tint-35);
215
231
  }
216
232
 
233
+ /* BA.W-SURFACE-AXIS scope 7 — the shared control REST surface class. The
234
+ NON-pill control families (the Select trigger, the TagsInput root) that do
235
+ NOT compose `.input-pill` but want the SAME resting material read this — so
236
+ the whole form band is ONE register at rest (the Select default rode the
237
+ lighter `glass-wash` gray before; this is the no-gray control-family seam).
238
+ It carries the bg/border/blur ONLY (each control owns its own height/radius/
239
+ padding/font), so a non-pill control composes `.control-surface` + its own
240
+ geometry. The hover lift brightens the fill one step toward the resting rung. */
241
+ .control-surface {
242
+ background: var(--control-surface-bg);
243
+ border: 1px solid var(--control-surface-border);
244
+ backdrop-filter: var(--control-surface-blur);
245
+ -webkit-backdrop-filter: var(--control-surface-blur);
246
+ }
247
+ .control-surface:hover:not(:disabled, [data-disabled]) {
248
+ background: var(--control-surface-bg-hover);
249
+ }
250
+
217
251
  /* AQ.W4 §W4.6 — keyboard-focus ring only. Was bare `:focus` (showed the
218
252
  accent ring on a mouse click); `:focus-visible` matches the
219
253
  `.focus-ring` / `.glass-btn` / dock-control discipline. Ordered BEFORE
@@ -291,6 +325,48 @@
291
325
  border-color: var(--surface-tint-15);
292
326
  }
293
327
 
328
+ /* ── BA.W-PAGER — the glass pager pill chassis (.glass-pager-ring) ──────────
329
+ The ONE pager-CHASSIS ring register: a `--radius-pill` glass-floating pill
330
+ (the DockRail-chip recipe — `--glass-bg-floating` + `--glass-blur-floating`
331
+ + `--glass-edge-light`/`--glass-specular` + the soft drop + the `.dark`
332
+ box-shadow arm). It encapsulates BOTH the `<PagerDots ring>` dot rail AND
333
+ the `<CarouselPager>` counter (the counter re-registers OFF the opaque
334
+ `bg-card` slab onto this — the R9/R10-5 dark-slab class dies in the same
335
+ edit). NEVER an opaque `bg-card` plate: this is the house "controls in a
336
+ glass pill" idiom, translucent (reads the substrate through it), already
337
+ dark/light-safe, already specular-rimmed (≥2-consumer-proven on the dock
338
+ rail-extend chips + the dock collapsed pill). The legibility floor over the
339
+ carousel's image content rides the SAME rebuilt registers
340
+ (W-DARK-MATERIAL/W-NO-GRAY) — no local opaque fallback. */
341
+ .glass-pager-ring {
342
+ display: inline-flex;
343
+ align-items: center;
344
+ gap: 0.375rem;
345
+ padding-inline: 0.625rem;
346
+ padding-block: 0.3125rem;
347
+ border-radius: var(--radius-pill);
348
+ background: var(--glass-bg-floating);
349
+ backdrop-filter: var(--glass-blur-floating);
350
+ -webkit-backdrop-filter: var(--glass-blur-floating);
351
+ box-shadow:
352
+ var(--glass-edge-light),
353
+ var(--glass-specular),
354
+ 0 2px 6px -2px color-mix(in srgb, var(--shadow-color) 22%, transparent);
355
+ /* §6 EASING DOCTRINE — the surface channel cross-fades on the bezier
356
+ `--ease-standard` (NEVER a spring; a surface prop on a spring is the
357
+ violation). */
358
+ transition:
359
+ background-color var(--duration-fast) var(--ease-standard),
360
+ box-shadow var(--duration-fast) var(--ease-standard),
361
+ border-color var(--duration-fast) var(--ease-standard);
362
+ }
363
+ .dark .glass-pager-ring {
364
+ box-shadow:
365
+ var(--glass-edge-light-dark),
366
+ var(--glass-specular-dark),
367
+ 0 2px 6px -2px color-mix(in srgb, var(--shadow-color) 30%, transparent);
368
+ }
369
+
294
370
  /* ── AW.W23 — chromatic edge dispersion (the polished-glass rim fringe) ──
295
371
  An opt-in `.glass-chromatic` composes the warm/cool oklab fringe OVER the
296
372
  W22 uniform rim (it does NOT replace it — the rim still rides each rung's
@@ -40,11 +40,14 @@
40
40
  * docs/precepts/design-idioms.md §cohesion-aware partials.
41
41
  */
42
42
 
43
- /* CSS @import rules must precede every other rule. The six partials @import in
44
- cascade order: */
43
+ /* CSS @import rules must precede every other rule. The seven partials @import in
44
+ cascade order (surface-axis.css AFTER ladder/surfaces so its [data-surface]
45
+ decoration attr rules win over the base rung by source order; BEFORE the
46
+ squircle + a11y @supports overrides, which must stay last): */
45
47
  @import "./glass/material.css";
46
48
  @import "./glass/ladder.css";
47
49
  @import "./glass/surfaces.css";
50
+ @import "./glass/surface-axis.css";
48
51
  @import "./glass/progress-rail.css";
49
52
  @import "./glass/squircle.css";
50
53
  @import "./glass/a11y-fallback.css";