@ds-mo/ui 13.14.0 → 13.16.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 (329) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +73 -22
  3. package/dist/agent.json +300 -69
  4. package/dist/angular/ds-agent-questionnaire.d.ts +19 -0
  5. package/dist/angular/ds-agent-questionnaire.js +46 -0
  6. package/dist/angular/ds-agent-response.d.ts +1 -1
  7. package/dist/angular/ds-agent-response.js +3 -3
  8. package/dist/angular/ds-agent-source-list.d.ts +9 -2
  9. package/dist/angular/ds-agent-source-list.js +7 -3
  10. package/dist/angular/ds-agent-tool-call.d.ts +9 -2
  11. package/dist/angular/ds-agent-tool-call.js +9 -5
  12. package/dist/angular/ds-bar-title.d.ts +1 -1
  13. package/dist/angular/ds-bar-title.js +3 -3
  14. package/dist/angular/ds-checkbox.d.ts +1 -1
  15. package/dist/angular/ds-checkbox.js +3 -3
  16. package/dist/angular/ds-message-composer.d.ts +1 -1
  17. package/dist/angular/ds-message-composer.js +3 -3
  18. package/dist/angular/ds-radio.js +2 -1
  19. package/dist/angular/ds-shell-page.d.ts +1 -1
  20. package/dist/angular/ds-shell-page.js +3 -3
  21. package/dist/angular/ds-table.d.ts +1 -1
  22. package/dist/angular/ds-table.js +3 -3
  23. package/dist/angular/index.d.ts +1 -1
  24. package/dist/angular/index.js +1 -0
  25. package/dist/angular/proxies.d.ts +1 -0
  26. package/dist/angular/proxies.js +1 -0
  27. package/dist/components/ds-agent-activity.js +1 -1
  28. package/dist/components/ds-agent-questionnaire.d.ts +24 -0
  29. package/dist/components/ds-agent-questionnaire.js +2 -0
  30. package/dist/components/ds-agent-questionnaire.js.map +1 -0
  31. package/dist/components/ds-agent-response.js +1 -1
  32. package/dist/components/ds-agent-response.js.map +1 -1
  33. package/dist/components/ds-agent-source-list.js +1 -1
  34. package/dist/components/ds-agent-tool-call.js +1 -1
  35. package/dist/components/ds-attachment-list.js +1 -1
  36. package/dist/components/ds-badge.js +1 -1
  37. package/dist/components/ds-banner.js +1 -1
  38. package/dist/components/ds-bar-nav.js +1 -1
  39. package/dist/components/ds-bar-title.js +1 -1
  40. package/dist/components/ds-bar-workflow.js +1 -1
  41. package/dist/components/ds-breadcrumb.js +1 -1
  42. package/dist/components/ds-button-filled.js +1 -1
  43. package/dist/components/ds-button-unfilled.js +1 -1
  44. package/dist/components/ds-card-chart.js +1 -1
  45. package/dist/components/ds-card-overview.js +1 -1
  46. package/dist/components/ds-card-overview.js.map +1 -1
  47. package/dist/components/ds-card-setting.js +1 -1
  48. package/dist/components/ds-chart-legend.js +1 -1
  49. package/dist/components/ds-chart-legend.js.map +1 -1
  50. package/dist/components/ds-chart.js +1 -1
  51. package/dist/components/ds-chart.js.map +1 -1
  52. package/dist/components/ds-checkbox.js +1 -1
  53. package/dist/components/ds-chip.js +1 -1
  54. package/dist/components/ds-chip.js.map +1 -1
  55. package/dist/components/ds-code-block.js +1 -1
  56. package/dist/components/ds-conversation-list-item.js +1 -1
  57. package/dist/components/ds-conversation-list-item.js.map +1 -1
  58. package/dist/components/ds-conversation-list-section.js +1 -1
  59. package/dist/components/ds-conversation-list.js +1 -1
  60. package/dist/components/ds-divider.js +1 -1
  61. package/dist/components/ds-empty-state.js +1 -1
  62. package/dist/components/ds-field.js +1 -1
  63. package/dist/components/ds-input.js +1 -1
  64. package/dist/components/ds-input.js.map +1 -1
  65. package/dist/components/ds-markdown.js +1 -1
  66. package/dist/components/ds-menu.js +1 -1
  67. package/dist/components/ds-message-actions.js +1 -1
  68. package/dist/components/ds-message-bubble.js +1 -1
  69. package/dist/components/ds-message-bubble.js.map +1 -1
  70. package/dist/components/ds-message-composer.js +1 -1
  71. package/dist/components/ds-message-composer.js.map +1 -1
  72. package/dist/components/ds-message-scroller.js +1 -1
  73. package/dist/components/ds-message-scroller.js.map +1 -1
  74. package/dist/components/ds-message.js +1 -1
  75. package/dist/components/ds-mobile-bar-nav.js +1 -1
  76. package/dist/components/ds-mobile-header.js +1 -1
  77. package/dist/components/ds-mobile-section-switcher.js +1 -1
  78. package/dist/components/ds-mobile-sheet-nav.js +1 -1
  79. package/dist/components/ds-modal.js +1 -1
  80. package/dist/components/ds-panel-nav.js +1 -1
  81. package/dist/components/ds-panel-sub-nav.js +1 -1
  82. package/dist/components/ds-panel-sub-nav.js.map +1 -1
  83. package/dist/components/ds-panel-tool-header.js +1 -1
  84. package/dist/components/ds-panel-tool-search.js +1 -1
  85. package/dist/components/ds-panel-tools.js +1 -1
  86. package/dist/components/ds-radio.js +1 -1
  87. package/dist/components/ds-radio.js.map +1 -1
  88. package/dist/components/ds-scroll-overlay.js +1 -1
  89. package/dist/components/ds-select.js +1 -1
  90. package/dist/components/ds-select.js.map +1 -1
  91. package/dist/components/ds-shell-app.js +1 -1
  92. package/dist/components/ds-shell-app.js.map +1 -1
  93. package/dist/components/ds-shell-page.js +1 -1
  94. package/dist/components/ds-shell-tools.js +1 -1
  95. package/dist/components/ds-skeleton.js +1 -1
  96. package/dist/components/ds-slider.js +1 -1
  97. package/dist/components/ds-slider.js.map +1 -1
  98. package/dist/components/ds-swatch-picker.js +1 -1
  99. package/dist/components/ds-switch.js +1 -1
  100. package/dist/components/ds-tab-group.js +1 -1
  101. package/dist/components/ds-table.js +1 -1
  102. package/dist/components/ds-table.js.map +1 -1
  103. package/dist/components/ds-tag.js +1 -1
  104. package/dist/components/ds-text.js +1 -1
  105. package/dist/components/ds-toast.js +1 -1
  106. package/dist/components/ds-tooltip-chart.js +1 -1
  107. package/dist/components/ds-tooltip.js +1 -1
  108. package/dist/components/ds-typing-indicator.js +1 -1
  109. package/dist/components/index.d.ts +10 -0
  110. package/dist/components/{p-PQgDzzn9.js → p-00or0yGw.js} +2 -2
  111. package/dist/components/p-B2SoinWf.js +2 -0
  112. package/dist/components/p-B2SoinWf.js.map +1 -0
  113. package/dist/components/{p-C5ecLNZA.js → p-B53Vpuqq.js} +2 -2
  114. package/dist/components/{p-BULWzaBs.js → p-B69Re7HW.js} +2 -2
  115. package/dist/components/{p-CeyoHpPn.js → p-B94M62Tx.js} +2 -2
  116. package/dist/components/p-BAAjiAIF.js +2 -0
  117. package/dist/components/p-BAAjiAIF.js.map +1 -0
  118. package/dist/components/p-BMAZWEDa.js +2 -0
  119. package/dist/components/p-BMAZWEDa.js.map +1 -0
  120. package/dist/components/p-BMc0DE59.js +2 -0
  121. package/dist/components/p-BMc0DE59.js.map +1 -0
  122. package/dist/components/{p-B6z51yBf.js → p-BNkU9dcc.js} +2 -2
  123. package/dist/components/p-BPbE-Kbl.js +2 -0
  124. package/dist/components/p-BPbE-Kbl.js.map +1 -0
  125. package/dist/components/{p-B6linhwY.js → p-BRze4tRe.js} +2 -2
  126. package/dist/components/p-BtUgncSJ.js +2 -0
  127. package/dist/components/p-BtUgncSJ.js.map +1 -0
  128. package/dist/components/p-BxR8omPQ.js +2 -0
  129. package/dist/components/p-BxR8omPQ.js.map +1 -0
  130. package/dist/components/p-C891ueIx.js +2 -0
  131. package/dist/components/p-C891ueIx.js.map +1 -0
  132. package/dist/components/{p-CY19gMiz.js → p-CJq3n5kA.js} +2 -2
  133. package/dist/components/p-CKo3OFG1.js +2 -0
  134. package/dist/components/p-CKo3OFG1.js.map +1 -0
  135. package/dist/components/p-CMbcRN92.js +2 -0
  136. package/dist/components/{p-cPh32CFB.js.map → p-CMbcRN92.js.map} +1 -1
  137. package/dist/components/p-CXduurfd.js.map +1 -1
  138. package/dist/components/{p-DLwM1RNL.js → p-CdKz-QT2.js} +2 -2
  139. package/dist/components/p-CdKz-QT2.js.map +1 -0
  140. package/dist/components/p-CnIvWEVm.js +2 -0
  141. package/dist/components/{p-BPS17WvI.js.map → p-CnIvWEVm.js.map} +1 -1
  142. package/dist/components/p-CnUq7E8S.js +2 -0
  143. package/dist/components/{p-DyDkQ8H9.js.map → p-CnUq7E8S.js.map} +1 -1
  144. package/dist/components/{p-C9StMCWg.js → p-Cohb8T7G.js} +2 -2
  145. package/dist/components/p-CqDJRVT8.js +2 -0
  146. package/dist/components/p-CqDJRVT8.js.map +1 -0
  147. package/dist/components/p-CsXC1cHI.js +2 -0
  148. package/dist/components/{p-DYAQVvOu.js.map → p-CsXC1cHI.js.map} +1 -1
  149. package/dist/components/p-D4j0deyd.js +2 -0
  150. package/dist/components/{p-DAM4CDXT.js.map → p-D4j0deyd.js.map} +1 -1
  151. package/dist/components/p-D5sIwLjA.js +2 -0
  152. package/dist/components/p-D5sIwLjA.js.map +1 -0
  153. package/dist/components/p-D9CDoQBx.js +2 -0
  154. package/dist/components/{p-C-aCs6ID.js.map → p-D9CDoQBx.js.map} +1 -1
  155. package/dist/components/p-D9FdOR_m.js +2 -0
  156. package/dist/components/{p-BSdAFIcG.js.map → p-D9FdOR_m.js.map} +1 -1
  157. package/dist/components/p-DStd98dM.js +2 -0
  158. package/dist/components/{p-Azjx2SsL.js.map → p-DStd98dM.js.map} +1 -1
  159. package/dist/components/p-Dbobj7DI.js +2 -0
  160. package/dist/components/p-Dbobj7DI.js.map +1 -0
  161. package/dist/components/{p-BNiIyZCn.js → p-Dhx_3_tf.js} +2 -2
  162. package/dist/components/p-Dhx_3_tf.js.map +1 -0
  163. package/dist/components/p-DrvEhJhO.js +2 -0
  164. package/dist/components/p-DrvEhJhO.js.map +1 -0
  165. package/dist/components/p-DyqLVdJp.js +2 -0
  166. package/dist/components/{p-CCYgBUUS.js.map → p-DyqLVdJp.js.map} +1 -1
  167. package/dist/components/p-GWUTrIlk.js +2 -0
  168. package/dist/components/p-GWUTrIlk.js.map +1 -0
  169. package/dist/components/p-NQOI5gN1.js +2 -0
  170. package/dist/components/p-NQOI5gN1.js.map +1 -0
  171. package/dist/components/p-Qf-os3lG.js +2 -0
  172. package/dist/components/{p-B8HG9OFh.js.map → p-Qf-os3lG.js.map} +1 -1
  173. package/dist/components/{p-DMJEOAwP.js → p-chA2WA5x.js} +2 -2
  174. package/dist/components/{p-DwKC_9u2.js → p-dEouiXJ8.js} +2 -2
  175. package/dist/components/p-m5CSrx_s.js +2 -0
  176. package/dist/components/{p-B1JB0Zn-.js.map → p-m5CSrx_s.js.map} +1 -1
  177. package/dist/docs/components.json +964 -11
  178. package/dist/lib/components/ShellApp/shell-app-types.d.ts +12 -0
  179. package/dist/lib/utils/index.js +41 -4
  180. package/dist/lib/utils/index.js.map +2 -2
  181. package/dist/lib/utils/resolve-css-length-px.d.ts +1 -1
  182. package/dist/mcp-data/registry/agent-activity.json +1 -1
  183. package/dist/mcp-data/registry/agent-questionnaire.json +273 -0
  184. package/dist/mcp-data/registry/agent-response.json +32 -11
  185. package/dist/mcp-data/registry/agent-source-list.json +33 -13
  186. package/dist/mcp-data/registry/agent-tool-call.json +59 -18
  187. package/dist/mcp-data/registry/attachment-list.json +1 -1
  188. package/dist/mcp-data/registry/avatar.json +1 -1
  189. package/dist/mcp-data/registry/badge.json +1 -1
  190. package/dist/mcp-data/registry/banner.json +1 -1
  191. package/dist/mcp-data/registry/bar-nav.json +2 -2
  192. package/dist/mcp-data/registry/bar-title.json +39 -4
  193. package/dist/mcp-data/registry/bar-workflow.json +1 -1
  194. package/dist/mcp-data/registry/breadcrumb.json +2 -2
  195. package/dist/mcp-data/registry/button-filled.json +1 -1
  196. package/dist/mcp-data/registry/button-unfilled.json +1 -1
  197. package/dist/mcp-data/registry/card-chart.json +1 -1
  198. package/dist/mcp-data/registry/card-overview.json +1 -1
  199. package/dist/mcp-data/registry/card-setting.json +1 -1
  200. package/dist/mcp-data/registry/chart-legend.json +2 -2
  201. package/dist/mcp-data/registry/chart.json +2 -2
  202. package/dist/mcp-data/registry/checkbox.json +26 -9
  203. package/dist/mcp-data/registry/chip.json +2 -2
  204. package/dist/mcp-data/registry/code-block.json +14 -6
  205. package/dist/mcp-data/registry/conversation-list-item.json +2 -2
  206. package/dist/mcp-data/registry/conversation-list-section.json +1 -1
  207. package/dist/mcp-data/registry/conversation-list.json +1 -1
  208. package/dist/mcp-data/registry/divider.json +1 -1
  209. package/dist/mcp-data/registry/empty-state.json +1 -1
  210. package/dist/mcp-data/registry/field.json +1 -1
  211. package/dist/mcp-data/registry/icon.json +1 -1
  212. package/dist/mcp-data/registry/input.json +1 -1
  213. package/dist/mcp-data/registry/loader.json +1 -1
  214. package/dist/mcp-data/registry/markdown.json +1 -1
  215. package/dist/mcp-data/registry/menu.json +2 -2
  216. package/dist/mcp-data/registry/message-actions.json +1 -1
  217. package/dist/mcp-data/registry/message-bubble.json +2 -2
  218. package/dist/mcp-data/registry/message-composer.json +30 -8
  219. package/dist/mcp-data/registry/message-scroller.json +17 -9
  220. package/dist/mcp-data/registry/message.json +1 -1
  221. package/dist/mcp-data/registry/mobile-bar-nav.json +1 -1
  222. package/dist/mcp-data/registry/mobile-header.json +1 -1
  223. package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
  224. package/dist/mcp-data/registry/mobile-sheet-nav.json +1 -1
  225. package/dist/mcp-data/registry/modal.json +1 -1
  226. package/dist/mcp-data/registry/panel-nav.json +2 -2
  227. package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
  228. package/dist/mcp-data/registry/panel-tool-header.json +1 -1
  229. package/dist/mcp-data/registry/panel-tool-search.json +1 -1
  230. package/dist/mcp-data/registry/panel-tools.json +2 -2
  231. package/dist/mcp-data/registry/radio.json +24 -11
  232. package/dist/mcp-data/registry/registry.json +303 -69
  233. package/dist/mcp-data/registry/scroll-overlay.json +1 -1
  234. package/dist/mcp-data/registry/select.json +2 -2
  235. package/dist/mcp-data/registry/shell-app.json +5 -5
  236. package/dist/mcp-data/registry/shell-page.json +78 -5
  237. package/dist/mcp-data/registry/shell-tools.json +1 -1
  238. package/dist/mcp-data/registry/skeleton.json +1 -1
  239. package/dist/mcp-data/registry/slider.json +2 -2
  240. package/dist/mcp-data/registry/swatch-picker.json +2 -2
  241. package/dist/mcp-data/registry/switch.json +2 -2
  242. package/dist/mcp-data/registry/tab-group.json +1 -1
  243. package/dist/mcp-data/registry/table.json +89 -13
  244. package/dist/mcp-data/registry/tag.json +1 -1
  245. package/dist/mcp-data/registry/text.json +2 -2
  246. package/dist/mcp-data/registry/toast.json +1 -1
  247. package/dist/mcp-data/registry/tooltip-chart.json +5 -3
  248. package/dist/mcp-data/registry/tooltip.json +1 -1
  249. package/dist/mcp-data/registry/typing-indicator.json +1 -1
  250. package/dist/react/components.d.ts +1 -0
  251. package/dist/react/components.js +1 -0
  252. package/dist/react/ds-agent-questionnaire.d.ts +13 -0
  253. package/dist/react/ds-agent-questionnaire.js +15 -0
  254. package/dist/react/ds-agent-source-list.d.ts +7 -2
  255. package/dist/react/ds-agent-source-list.js +1 -1
  256. package/dist/react/ds-agent-tool-call.d.ts +7 -2
  257. package/dist/react/ds-agent-tool-call.js +1 -1
  258. package/dist/styles/prose.css +21 -4
  259. package/dist/styles/table.css +161 -10
  260. package/dist/types/components/AgentQuestionnaire/AgentQuestionnaire.d.ts +49 -0
  261. package/dist/types/components/AgentQuestionnaire/agent-questionnaire-model.d.ts +13 -0
  262. package/dist/types/components/AgentResponse/AgentResponse.d.ts +3 -1
  263. package/dist/types/components/AgentSourceList/AgentSourceList.d.ts +5 -0
  264. package/dist/types/components/AgentToolCall/AgentToolCall.d.ts +21 -0
  265. package/dist/types/components/BarTitle/BarTitle.d.ts +5 -0
  266. package/dist/types/components/Checkbox/Checkbox.d.ts +3 -0
  267. package/dist/types/components/MessageComposer/MessageComposer.d.ts +3 -0
  268. package/dist/types/components/MessageScroller/MessageScroller.d.ts +21 -1
  269. package/dist/types/components/Radio/Radio.d.ts +4 -0
  270. package/dist/types/components/ShellApp/shell-app-types.d.ts +12 -0
  271. package/dist/types/components/ShellPage/ShellPage.d.ts +9 -0
  272. package/dist/types/components/Table/Table.d.ts +30 -0
  273. package/dist/types/components/Table/table-cell-model.d.ts +2 -0
  274. package/dist/types/components/Table/table-layout-controller.d.ts +6 -0
  275. package/dist/types/components/Table/table-types.d.ts +3 -0
  276. package/dist/types/components/Table/table-viewport-fit-controller.d.ts +53 -0
  277. package/dist/types/components/conversation-types.d.ts +51 -2
  278. package/dist/types/components.d.ts +249 -2
  279. package/dist/types/utils/resolve-css-length-px.d.ts +1 -1
  280. package/package.json +5 -3
  281. package/dist/components/p-Azjx2SsL.js +0 -2
  282. package/dist/components/p-B1JB0Zn-.js +0 -2
  283. package/dist/components/p-B2t8alvH.js +0 -2
  284. package/dist/components/p-B2t8alvH.js.map +0 -1
  285. package/dist/components/p-B8HG9OFh.js +0 -2
  286. package/dist/components/p-BJMRBHKW.js +0 -2
  287. package/dist/components/p-BJMRBHKW.js.map +0 -1
  288. package/dist/components/p-BJVzrR_P.js +0 -2
  289. package/dist/components/p-BJVzrR_P.js.map +0 -1
  290. package/dist/components/p-BL0JHLJp.js +0 -2
  291. package/dist/components/p-BL0JHLJp.js.map +0 -1
  292. package/dist/components/p-BNiIyZCn.js.map +0 -1
  293. package/dist/components/p-BPS17WvI.js +0 -2
  294. package/dist/components/p-BSdAFIcG.js +0 -2
  295. package/dist/components/p-C-aCs6ID.js +0 -2
  296. package/dist/components/p-CCYgBUUS.js +0 -2
  297. package/dist/components/p-CE82aQZr.js +0 -2
  298. package/dist/components/p-CE82aQZr.js.map +0 -1
  299. package/dist/components/p-COmqMfQo.js +0 -2
  300. package/dist/components/p-COmqMfQo.js.map +0 -1
  301. package/dist/components/p-Ch5yT3UA.js +0 -2
  302. package/dist/components/p-Ch5yT3UA.js.map +0 -1
  303. package/dist/components/p-CiUciD5Z.js +0 -2
  304. package/dist/components/p-CiUciD5Z.js.map +0 -1
  305. package/dist/components/p-D6g070eY.js +0 -2
  306. package/dist/components/p-D6g070eY.js.map +0 -1
  307. package/dist/components/p-DAM4CDXT.js +0 -2
  308. package/dist/components/p-DLwM1RNL.js.map +0 -1
  309. package/dist/components/p-DYAQVvOu.js +0 -2
  310. package/dist/components/p-DmblUQ4D.js +0 -2
  311. package/dist/components/p-DmblUQ4D.js.map +0 -1
  312. package/dist/components/p-DyDkQ8H9.js +0 -2
  313. package/dist/components/p-Dz3Ufmr4.js +0 -2
  314. package/dist/components/p-Dz3Ufmr4.js.map +0 -1
  315. package/dist/components/p-cPh32CFB.js +0 -2
  316. package/dist/components/p-fkQhr5s9.js +0 -2
  317. package/dist/components/p-fkQhr5s9.js.map +0 -1
  318. package/dist/components/p-oOKTL-yx.js +0 -2
  319. package/dist/components/p-oOKTL-yx.js.map +0 -1
  320. /package/dist/components/{p-PQgDzzn9.js.map → p-00or0yGw.js.map} +0 -0
  321. /package/dist/components/{p-C5ecLNZA.js.map → p-B53Vpuqq.js.map} +0 -0
  322. /package/dist/components/{p-BULWzaBs.js.map → p-B69Re7HW.js.map} +0 -0
  323. /package/dist/components/{p-CeyoHpPn.js.map → p-B94M62Tx.js.map} +0 -0
  324. /package/dist/components/{p-B6z51yBf.js.map → p-BNkU9dcc.js.map} +0 -0
  325. /package/dist/components/{p-B6linhwY.js.map → p-BRze4tRe.js.map} +0 -0
  326. /package/dist/components/{p-CY19gMiz.js.map → p-CJq3n5kA.js.map} +0 -0
  327. /package/dist/components/{p-C9StMCWg.js.map → p-Cohb8T7G.js.map} +0 -0
  328. /package/dist/components/{p-DMJEOAwP.js.map → p-chA2WA5x.js.map} +0 -0
  329. /package/dist/components/{p-DwKC_9u2.js.map → p-dEouiXJ8.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "shell-page",
4
4
  "title": "ShellPage",
5
- "description": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, application-supplied BarTitle capacity, stable scroll compaction, and independent page-content inset and canvas surface without creating a nested scroll container.",
5
+ "description": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, application-supplied BarTitle capacity, optional scroll compaction, and independent page-content inset and canvas surface without creating a nested scroll container.",
6
6
  "type": "registry:ui",
7
7
  "meta": {
8
8
  "library": "@ds-mo/ui",
@@ -13,7 +13,7 @@
13
13
  "intent": {
14
14
  "audience": "general",
15
15
  "status": "stable",
16
- "summary": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, application-supplied BarTitle capacity, stable scroll compaction, and independent page-content inset and canvas surface without creating a nested scroll container.",
16
+ "summary": "The standard routed-page boundary inside ShellApp, owning sticky BarTitle or BarWorkflow placement, application-supplied BarTitle capacity, optional scroll compaction, and independent page-content inset and canvas surface without creating a nested scroll container.",
17
17
  "useWhen": [
18
18
  "Rendering a standard routed page inside ShellApp's default content region.",
19
19
  "BarTitle should expand at a roomy page top, compact after scroll, or use constrained action layout when the application shell reports reduced capacity.",
@@ -58,6 +58,9 @@
58
58
  "headerPresentation=auto selects the matching header variant from headerCapacity and scroll position.",
59
59
  "expanded, compact, and constrained are explicit overrides for exceptional layouts and deterministic examples.",
60
60
  "contentInset=default supplies standard page gutters; none permits maps, canvases, and other full-bleed content.",
61
+ "contentInsetBlockStart=none removes only the gutter adjacent to the page header while retaining the responsive inline and bottom gutters.",
62
+ "contentInsetBlockStartSize can provide an exact roomy top seam, while compactContentInsetBlockStartSize independently defines the compact and constrained seam. ShellPage exposes their resolved sticky-header offset through --ds-shell-page-content-block-start-offset for viewport-fitted descendants.",
63
+ "scrollCompaction=false keeps a roomy header expanded and pinned during page scrolling; capacity changes still select compact or constrained variants.",
61
64
  "contentSurface=primary keeps the standard page canvas; secondary paints both the inset gutter and the canvas beneath routed content. Desktop and tablet BarTitle chrome matches that canvas in expanded, compact, and constrained presentations; MobileHeader remains primary.",
62
65
  "contentInset and contentSurface are independent: either surface supports standard responsive gutters or a full-bleed page-owned layout.",
63
66
  "The header slot accepts one desktop BarTitle or BarWorkflow; mobile-header accepts the corresponding MobileHeader presentation. The default slot owns router output and all page product content."
@@ -65,10 +68,12 @@
65
68
  "responsiveBehavior": [
66
69
  "The owning application shell resolves viewport and persistent-chrome state into the explicit headerCapacity prop; ShellPage never guesses the cause of reduced width from its own rendered size.",
67
70
  "Roomy capacity expands at the top and compacts after scroll; compact capacity stays compact; constrained capacity uses the constrained action layout.",
71
+ "Pages with scrollCompaction=false keep roomy headers expanded while still responding to compact or constrained capacity from tools and breakpoints.",
68
72
  "A ShellPage-managed BarTitle remains concealed until headerCapacity is available and its rendered variant matches the resolved presentation, preventing a default-variant flash during route activation.",
69
73
  "responsiveMode=mobile hides and inerts the desktop header, exposes mobile-header, and disables desktop scroll-compaction geometry.",
70
74
  "Update headerCapacity synchronously with shell layout state so opening tools or crossing application breakpoints cannot briefly render the wrong presentation.",
71
75
  "The default content inset is balanced on every side: 32px in desktop mode and 16px in tablet and mobile modes.",
76
+ "contentInsetBlockStart can independently remove the top gutter for table and canvas pages that should meet the sticky header; exact roomy and compact block-start sizes support pages whose seam changes with header capacity.",
72
77
  "The selected content surface persists unchanged across desktop, tablet, and mobile modes.",
73
78
  "On a secondary desktop or tablet page, BarTitle matches the page canvas across capacity and scroll-driven variant changes; the separate mobile-header presentation remains primary.",
74
79
  "The flow-preservation spacer follows contentSurface so compacting a secondary page cannot expose a primary strip before its content.",
@@ -108,6 +113,14 @@
108
113
  },
109
114
  "api": {
110
115
  "props": {
116
+ "compactContentInsetBlockStartSize": {
117
+ "type": "string",
118
+ "resolvedType": "string | undefined",
119
+ "attribute": "compact-content-inset-block-start-size",
120
+ "required": false,
121
+ "mutable": false,
122
+ "description": "Exact block-start content inset while the header is compact or constrained."
123
+ },
111
124
  "contentInset": {
112
125
  "type": "ShellPageContentInset",
113
126
  "resolvedType": "\"default\" | \"none\"",
@@ -117,6 +130,23 @@
117
130
  "mutable": false,
118
131
  "description": "Standard page gutters, or no inset for full-bleed page content."
119
132
  },
133
+ "contentInsetBlockStart": {
134
+ "type": "ShellPageContentInset",
135
+ "resolvedType": "\"default\" | \"none\"",
136
+ "attribute": "content-inset-block-start",
137
+ "default": "'default'",
138
+ "required": false,
139
+ "mutable": false,
140
+ "description": "Preserve the responsive side/end gutters while allowing content to meet the header."
141
+ },
142
+ "contentInsetBlockStartSize": {
143
+ "type": "string",
144
+ "resolvedType": "string | undefined",
145
+ "attribute": "content-inset-block-start-size",
146
+ "required": false,
147
+ "mutable": false,
148
+ "description": "Exact block-start content inset, overriding the responsive default when provided."
149
+ },
120
150
  "contentSurface": {
121
151
  "type": "ShellPageContentSurface",
122
152
  "resolvedType": "\"primary\" | \"secondary\"",
@@ -151,6 +181,15 @@
151
181
  "required": false,
152
182
  "mutable": false,
153
183
  "description": "Explicit shell breakpoint presentation. Mobile uses the dedicated mobile-header slot."
184
+ },
185
+ "scrollCompaction": {
186
+ "type": "boolean",
187
+ "resolvedType": "boolean",
188
+ "attribute": "scroll-compaction",
189
+ "default": "true",
190
+ "required": false,
191
+ "mutable": false,
192
+ "description": "Allow roomy automatic headers to compact as the page scrolls."
154
193
  }
155
194
  },
156
195
  "events": [],
@@ -158,6 +197,14 @@
158
197
  "slots": []
159
198
  },
160
199
  "props": {
200
+ "compactContentInsetBlockStartSize": {
201
+ "type": "string",
202
+ "resolvedType": "string | undefined",
203
+ "attribute": "compact-content-inset-block-start-size",
204
+ "required": false,
205
+ "mutable": false,
206
+ "description": "Exact block-start content inset while the header is compact or constrained."
207
+ },
161
208
  "contentInset": {
162
209
  "type": "ShellPageContentInset",
163
210
  "resolvedType": "\"default\" | \"none\"",
@@ -167,6 +214,23 @@
167
214
  "mutable": false,
168
215
  "description": "Standard page gutters, or no inset for full-bleed page content."
169
216
  },
217
+ "contentInsetBlockStart": {
218
+ "type": "ShellPageContentInset",
219
+ "resolvedType": "\"default\" | \"none\"",
220
+ "attribute": "content-inset-block-start",
221
+ "default": "'default'",
222
+ "required": false,
223
+ "mutable": false,
224
+ "description": "Preserve the responsive side/end gutters while allowing content to meet the header."
225
+ },
226
+ "contentInsetBlockStartSize": {
227
+ "type": "string",
228
+ "resolvedType": "string | undefined",
229
+ "attribute": "content-inset-block-start-size",
230
+ "required": false,
231
+ "mutable": false,
232
+ "description": "Exact block-start content inset, overriding the responsive default when provided."
233
+ },
170
234
  "contentSurface": {
171
235
  "type": "ShellPageContentSurface",
172
236
  "resolvedType": "\"primary\" | \"secondary\"",
@@ -201,6 +265,15 @@
201
265
  "required": false,
202
266
  "mutable": false,
203
267
  "description": "Explicit shell breakpoint presentation. Mobile uses the dedicated mobile-header slot."
268
+ },
269
+ "scrollCompaction": {
270
+ "type": "boolean",
271
+ "resolvedType": "boolean",
272
+ "attribute": "scroll-compaction",
273
+ "default": "true",
274
+ "required": false,
275
+ "mutable": false,
276
+ "description": "Allow roomy automatic headers to compact as the page scrolls."
204
277
  }
205
278
  },
206
279
  "events": [],
@@ -228,7 +301,7 @@
228
301
  },
229
302
  "peerDependencies": {
230
303
  "required": [
231
- "@ds-mo/tokens ^6.0.0",
304
+ "@ds-mo/tokens ^6.2.1",
232
305
  "@ds-mo/icons ^6.6.0"
233
306
  ],
234
307
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -243,12 +316,12 @@
243
316
  "files": [
244
317
  {
245
318
  "path": "src/wc/components/ShellPage/ShellPage.css",
246
- "content": ":host {\n --_shell-page-content-background: var(--color-background-primary);\n --_shell-page-header-background: var(--color-background-primary);\n display: block;\n position: relative;\n min-width: 0;\n min-height: 100%;\n box-sizing: border-box;\n background: var(--_shell-page-content-background);\n}\n\n:host(.shell-page-host--surface-secondary) {\n --_shell-page-content-background: var(--color-background-secondary);\n}\n\n:host(.shell-page-host--surface-secondary[responsive-mode='desktop']),\n:host(.shell-page-host--surface-secondary[responsive-mode='tablet']) {\n --_shell-page-header-background: var(--color-background-secondary);\n}\n\n.shell-page__scroll-sentinel {\n position: absolute;\n inset-block-start: var(--ds-shell-page-header-travel, 0);\n inset-inline-start: 0;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-stroke-width-012);\n pointer-events: none;\n}\n\n.shell-page__sticky-header {\n position: sticky;\n inset-block-start: var(--ds-shell-page-sticky-offset, 0);\n z-index: var(--dimension-z-index-raised);\n min-width: 0;\n background: var(--_shell-page-header-background);\n overflow: visible;\n overflow-anchor: none;\n}\n\n.shell-page__desktop-header ::slotted(ds-bar-title),\n.shell-page__desktop-header ::slotted(ds-bar-workflow),\n.shell-page__mobile-header ::slotted(ds-mobile-header) {\n display: block;\n min-width: 0;\n}\n\n.shell-page__desktop-header[hidden],\n.shell-page__mobile-header[hidden] {\n display: none;\n}\n\n:host(.shell-page-host--mobile) .shell-page__scroll-sentinel,\n:host(.shell-page-host--mobile) .shell-page__flow-spacer {\n display: none;\n}\n\n.shell-page__flow-spacer {\n height: var(--ds-shell-page-flow-spacer, 0);\n background: var(--_shell-page-content-background);\n}\n\n.shell-page__content {\n min-width: 0;\n box-sizing: border-box;\n background: var(--_shell-page-content-background);\n}\n\n:host(.shell-page-host--inset-default) .shell-page__content {\n padding: var(--dimension-space-400);\n}\n\n:host(.shell-page-host--inset-default[responsive-mode='tablet']) .shell-page__content,\n:host(.shell-page-host--inset-default[responsive-mode='mobile']) .shell-page__content {\n padding: var(--dimension-space-200);\n}\n\n:host(.shell-page-host--inset-none) .shell-page__content {\n padding: 0;\n}\n",
319
+ "content": ":host {\n --_shell-page-content-background: var(--color-background-primary);\n --_shell-page-header-background: var(--color-background-primary);\n --_shell-page-responsive-content-block-start-inset: var(--dimension-space-400);\n --_shell-page-content-block-start-inset: var(\n --ds-shell-page-content-block-start-inset,\n var(--_shell-page-responsive-content-block-start-inset)\n );\n --ds-shell-page-sticky-header-block-size: var(--dimension-size-600);\n --ds-shell-page-content-block-start-offset: calc(\n var(--ds-shell-page-sticky-header-block-size) +\n var(--_shell-page-content-block-start-inset)\n );\n display: block;\n position: relative;\n min-width: 0;\n min-height: 100%;\n box-sizing: border-box;\n background: var(--_shell-page-content-background);\n}\n\n:host(.shell-page-host--surface-secondary) {\n --_shell-page-content-background: var(--color-background-secondary);\n}\n\n:host(.shell-page-host--surface-secondary[responsive-mode='desktop']),\n:host(.shell-page-host--surface-secondary[responsive-mode='tablet']) {\n --_shell-page-header-background: var(--color-background-secondary);\n}\n\n:host([responsive-mode='tablet']),\n:host([responsive-mode='mobile']) {\n --_shell-page-responsive-content-block-start-inset: var(--dimension-space-200);\n}\n\n:host(.shell-page-host--header-compact),\n:host(.shell-page-host--header-constrained) {\n --_shell-page-content-block-start-inset: var(\n --ds-shell-page-compact-content-block-start-inset,\n var(--_shell-page-responsive-content-block-start-inset)\n );\n}\n\n:host(.shell-page-host--inset-none),\n:host(.shell-page-host--block-start-inset-none) {\n --_shell-page-content-block-start-inset: 0px;\n}\n\n.shell-page__scroll-sentinel {\n position: absolute;\n inset-block-start: var(--ds-shell-page-header-travel, 0);\n inset-inline-start: 0;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-stroke-width-012);\n pointer-events: none;\n}\n\n.shell-page__sticky-header {\n position: sticky;\n inset-block-start: var(--ds-shell-page-sticky-offset, 0);\n z-index: var(--dimension-z-index-raised);\n min-width: 0;\n background: var(--_shell-page-header-background);\n overflow: visible;\n overflow-anchor: none;\n}\n\n.shell-page__desktop-header ::slotted(ds-bar-title),\n.shell-page__desktop-header ::slotted(ds-bar-workflow),\n.shell-page__mobile-header ::slotted(ds-mobile-header) {\n display: block;\n min-width: 0;\n}\n\n.shell-page__desktop-header[hidden],\n.shell-page__mobile-header[hidden] {\n display: none;\n}\n\n:host(.shell-page-host--mobile) .shell-page__scroll-sentinel,\n:host(.shell-page-host--mobile) .shell-page__flow-spacer {\n display: none;\n}\n\n.shell-page__flow-spacer {\n height: var(--ds-shell-page-flow-spacer, 0);\n background: var(--_shell-page-content-background);\n}\n\n.shell-page__content {\n min-width: 0;\n box-sizing: border-box;\n background: var(--_shell-page-content-background);\n}\n\n:host(.shell-page-host--inset-default) .shell-page__content {\n padding: var(--dimension-space-400);\n padding-block-start: var(--_shell-page-content-block-start-inset);\n}\n\n:host(.shell-page-host--inset-default[responsive-mode='tablet']) .shell-page__content,\n:host(.shell-page-host--inset-default[responsive-mode='mobile']) .shell-page__content {\n padding: var(--dimension-space-200);\n padding-block-start: var(--_shell-page-content-block-start-inset);\n}\n\n:host(.shell-page-host--inset-none) .shell-page__content {\n padding: 0;\n}\n",
247
320
  "type": "registry:ui"
248
321
  },
249
322
  {
250
323
  "path": "src/wc/components/ShellPage/ShellPage.tsx",
251
- "content": "import { Component, Element, h, Host, Prop, State, Watch } from '@stencil/core';\nimport type { ShellResponsiveMode } from '../../shell/shell-responsive';\nimport { resolveCssLengthPx } from '../../utils/resolve-css-length-px';\nimport type { BarTitleVariant } from '../BarTitle/bar-title-types';\nimport { resolveShellPageHeaderVariant } from './shell-page-responsive';\nimport type {\n ShellPageCapacity,\n ShellPageContentInset,\n ShellPageContentSurface,\n ShellPageHeaderPresentation,\n} from './shell-page-types';\n\ntype BarTitleElement = HTMLElement & { variant: BarTitleVariant };\n\n@Component({\n tag: 'ds-shell-page',\n styleUrl: 'ShellPage.css',\n scoped: true,\n})\nexport class ShellPage {\n private static readonly MAX_HEADER_REVEAL_FRAMES = 12;\n private static readonly MAX_HEADER_GEOMETRY_FRAMES = 12;\n\n @Element() el!: HTMLElement;\n\n /** Automatic capacity/scroll behavior, or an explicit header variant override. */\n @Prop() headerPresentation: ShellPageHeaderPresentation = 'auto';\n\n /** Available page-header capacity supplied by the owning application shell. */\n @Prop() headerCapacity?: ShellPageCapacity;\n\n /** Standard page gutters, or no inset for full-bleed page content. */\n @Prop() contentInset: ShellPageContentInset = 'default';\n\n /** Canvas surface painted around and beneath routed page content. */\n @Prop() contentSurface: ShellPageContentSurface = 'primary';\n\n /** Explicit shell breakpoint presentation. Mobile uses the dedicated mobile-header slot. */\n @Prop({ attribute: 'responsive-mode', reflect: true })\n responsiveMode: ShellResponsiveMode = 'desktop';\n\n @State() private pageTopVisible = true;\n\n private sentinelEl: HTMLElement | null = null;\n private spacerEl: HTMLElement | null = null;\n private stickyHeaderEl: HTMLElement | null = null;\n private headerEl: BarTitleElement | null = null;\n private expandedHeaderHeight = 0;\n private headerTravel = 0;\n private expandedGeometryFrozen = false;\n private headerResizeObserver: ResizeObserver | null = null;\n private headerMutationObserver: MutationObserver | null = null;\n private headerRevealFrame: number | null = null;\n private headerGeometryFrame: number | null = null;\n private reconnectFrame: number | null = null;\n private scrollRoot: HTMLElement | Window | null = null;\n private hasLoaded = false;\n\n @Watch('headerCapacity')\n @Watch('headerPresentation')\n handleHeaderContractChange() {\n this.syncHeaderVariant(true);\n }\n\n @Watch('responsiveMode')\n handleResponsiveModeChange() {\n this.observeHeader(this.responsiveMode === 'mobile' ? null : this.findHeader());\n }\n\n componentDidLoad() {\n this.hasLoaded = true;\n this.connectRuntime();\n }\n\n componentDidRender() {\n this.syncHeaderVariant();\n }\n\n connectedCallback() {\n if (!this.hasLoaded) return;\n if (this.reconnectFrame !== null) cancelAnimationFrame(this.reconnectFrame);\n this.reconnectFrame = requestAnimationFrame(() => {\n this.reconnectFrame = null;\n if (this.el.isConnected) this.connectRuntime();\n });\n }\n\n disconnectedCallback() {\n if (this.reconnectFrame !== null) cancelAnimationFrame(this.reconnectFrame);\n this.reconnectFrame = null;\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerMutationObserver?.disconnect();\n this.headerMutationObserver = null;\n this.cancelHeaderReveal();\n this.cancelHeaderGeometrySync();\n this.headerEl?.style.removeProperty('--ds-bar-title-divider-inset');\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = null;\n }\n\n private connectRuntime() {\n this.observeHeader(this.responsiveMode === 'mobile' ? null : this.findHeader());\n this.connectScrollRoot();\n }\n\n private get effectiveVariant(): BarTitleVariant {\n return resolveShellPageHeaderVariant(\n this.headerPresentation,\n this.headerCapacity ?? 'roomy',\n this.pageTopVisible\n );\n }\n\n private get headerContractResolved(): boolean {\n return this.headerPresentation !== 'auto' || this.headerCapacity !== undefined;\n }\n\n private get isScrollCompacted(): boolean {\n return (\n this.headerPresentation === 'auto' && this.headerCapacity === 'roomy' && !this.pageTopVisible\n );\n }\n\n private composedParent(element: Element): Element | null {\n return (element as HTMLElement).assignedSlot?.parentElement ?? element.parentElement;\n }\n\n private findScrollRoot(): HTMLElement | Window {\n let ancestor = this.composedParent(this.el);\n while (ancestor && ancestor !== document.documentElement) {\n const overflow = getComputedStyle(ancestor).overflowY;\n if (overflow === 'auto' || overflow === 'scroll' || overflow === 'overlay') {\n return ancestor as HTMLElement;\n }\n ancestor = this.composedParent(ancestor);\n }\n return window;\n }\n\n private connectScrollRoot() {\n const next = this.findScrollRoot();\n if (next === this.scrollRoot) return;\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = next;\n this.scrollRoot.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n\n private get scrollRootResolved(): boolean {\n const shell = this.el.closest('ds-shell-app');\n if (!shell) return true;\n const expected = shell.querySelector<HTMLElement>('.shell-app__content');\n return expected !== null && this.scrollRoot === expected;\n }\n\n private handleScroll = () => {\n if (!this.sentinelEl || !this.scrollRoot) return;\n const rootTop =\n this.scrollRoot === window ? 0 : (this.scrollRoot as HTMLElement).getBoundingClientRect().top;\n this.syncHeaderDividerInset(rootTop);\n const nextPageTopVisible = this.sentinelEl.getBoundingClientRect().top >= rootTop;\n if (\n !nextPageTopVisible &&\n this.pageTopVisible &&\n this.headerEl?.classList.contains(this.variantClass('expanded'))\n ) {\n this.captureExpandedHeaderGeometry(this.headerEl);\n this.expandedGeometryFrozen = true;\n }\n if (\n nextPageTopVisible &&\n this.expandedGeometryFrozen &&\n this.el.getBoundingClientRect().top >= rootTop\n ) {\n this.expandedGeometryFrozen = false;\n if (this.headerEl?.classList.contains(this.variantClass('expanded'))) {\n this.captureExpandedHeaderGeometry(this.headerEl);\n }\n }\n this.pageTopVisible = nextPageTopVisible;\n };\n\n private findHeader(): BarTitleElement | null {\n return this.el.querySelector<BarTitleElement>('ds-bar-title');\n }\n\n private get compactHeaderHeight(): number {\n return resolveCssLengthPx('--dimension-size-600', 0);\n }\n\n private syncHeaderDividerInset(rootTop?: number) {\n const header = this.headerEl;\n if (!header) return;\n\n const ownsScrollTransition =\n this.headerPresentation === 'auto' && this.headerCapacity === 'roomy';\n const expandedInset = resolveCssLengthPx('--dimension-space-400', 0);\n if (\n !ownsScrollTransition ||\n !this.sentinelEl ||\n !this.scrollRoot ||\n this.headerTravel <= 0 ||\n expandedInset <= 0\n ) {\n header.style.removeProperty('--ds-bar-title-divider-inset');\n return;\n }\n\n const scrollRootTop =\n rootTop ??\n (this.scrollRoot === window\n ? 0\n : (this.scrollRoot as HTMLElement).getBoundingClientRect().top);\n const remainingTravel = this.sentinelEl.getBoundingClientRect().top - scrollRootTop;\n const progress = Math.min(1, Math.max(0, 1 - remainingTravel / this.headerTravel));\n header.style.setProperty('--ds-bar-title-divider-inset', `${expandedInset * (1 - progress)}px`);\n }\n\n private setHeaderTravel(distance: number) {\n const next = Math.max(0, distance);\n if (Math.abs(next - this.headerTravel) < 0.5) return;\n this.headerTravel = next;\n this.el.style.setProperty('--ds-shell-page-header-travel', `${next}px`);\n this.handleScroll();\n }\n\n private measureHeaderTravel(header: BarTitleElement) {\n const anchor = header.querySelector<HTMLElement>('[data-shell-page-header-anchor]');\n const compactHeight = this.compactHeaderHeight;\n if (!anchor || compactHeight <= 0) return;\n\n const headerRect = header.getBoundingClientRect();\n const anchorRect = anchor.getBoundingClientRect();\n if (headerRect.height <= 0 || anchorRect.height <= 0) return;\n\n const expandedAnchorTop = anchorRect.top - headerRect.top;\n const compactAnchorTop = Math.max(0, (compactHeight - anchorRect.height) / 2);\n this.setHeaderTravel(expandedAnchorTop - compactAnchorTop);\n }\n\n private captureExpandedHeaderGeometry(header: BarTitleElement) {\n this.expandedHeaderHeight = header.getBoundingClientRect().height;\n this.measureHeaderTravel(header);\n }\n\n private setSpacerHeight(height: number) {\n if (!this.spacerEl) return;\n this.spacerEl.style.setProperty('--ds-shell-page-flow-spacer', `${Math.max(0, height)}px`);\n }\n\n private variantClass(variant: BarTitleVariant): string {\n return `bar-title-host--${variant}`;\n }\n\n private setStickyHeaderOffset(renderedVariant: BarTitleVariant) {\n this.stickyHeaderEl?.style.setProperty(\n '--ds-shell-page-sticky-offset',\n renderedVariant === 'expanded' &&\n this.headerPresentation === 'auto' &&\n this.headerCapacity === 'roomy'\n ? `${-this.headerTravel}px`\n : '0px'\n );\n }\n\n private syncRenderedHeaderGeometry(header: BarTitleElement) {\n const renderedVariant = this.effectiveVariant;\n if (!header.classList.contains(this.variantClass(renderedVariant))) return;\n\n // Update both flow-preservation pieces before reading layout. Otherwise a\n // reverse compact → expanded render can briefly contain the tall header and\n // the compact spacer together, giving browser scroll anchoring a transient\n // height change to compensate.\n this.setSpacerHeight(\n this.isScrollCompacted ? this.expandedHeaderHeight - this.compactHeaderHeight : 0\n );\n this.setStickyHeaderOffset(renderedVariant);\n\n if (renderedVariant === 'expanded' && !this.expandedGeometryFrozen) {\n this.captureExpandedHeaderGeometry(header);\n this.setStickyHeaderOffset(renderedVariant);\n }\n }\n\n private cancelHeaderGeometrySync() {\n if (this.headerGeometryFrame !== null) cancelAnimationFrame(this.headerGeometryFrame);\n this.headerGeometryFrame = null;\n }\n\n private scheduleHeaderGeometrySync(header: BarTitleElement) {\n this.cancelHeaderGeometrySync();\n let framesRemaining = ShellPage.MAX_HEADER_GEOMETRY_FRAMES;\n let framesElapsed = 0;\n const sync = () => {\n if (this.headerEl !== header) return;\n framesRemaining -= 1;\n framesElapsed += 1;\n // In WebKit a child's componentDidLoad can precede its assignment into\n // the parent's rendered slot. Revalidate after ShellApp has had a frame\n // to expose the actual content scroller.\n this.connectScrollRoot();\n this.syncRenderedHeaderGeometry(header);\n const geometryReady =\n this.effectiveVariant !== 'expanded' ||\n (this.expandedHeaderHeight > 0 && this.headerTravel > 0);\n if (\n (geometryReady && this.scrollRootResolved && framesElapsed >= 2) ||\n framesRemaining <= 0\n ) {\n this.headerGeometryFrame = null;\n return;\n }\n this.headerGeometryFrame = requestAnimationFrame(sync);\n };\n this.headerGeometryFrame = requestAnimationFrame(sync);\n }\n\n private cancelHeaderReveal() {\n if (this.headerRevealFrame !== null) cancelAnimationFrame(this.headerRevealFrame);\n this.headerRevealFrame = null;\n this.headerEl?.removeAttribute('data-shell-page-syncing');\n }\n\n private revealHeaderWhenSynced(header: BarTitleElement, variant: BarTitleVariant) {\n // Stencil normally re-renders within a frame or two of a prop change. Stop\n // polling at the cap, but fail closed: a stale variant must never paint.\n let framesRemaining = ShellPage.MAX_HEADER_REVEAL_FRAMES;\n const reveal = () => {\n if (this.headerEl !== header) {\n header.removeAttribute('data-shell-page-syncing');\n return;\n }\n framesRemaining -= 1;\n if (header.classList.contains(this.variantClass(variant))) {\n header.removeAttribute('data-shell-page-syncing');\n this.headerRevealFrame = null;\n return;\n }\n if (framesRemaining <= 0) {\n this.headerRevealFrame = null;\n return;\n }\n this.headerRevealFrame = requestAnimationFrame(reveal);\n };\n this.headerRevealFrame = requestAnimationFrame(reveal);\n }\n\n private syncHeaderVariant(concealUntilSynced = false) {\n const header = this.headerEl;\n if (!header) return;\n\n this.syncHeaderDividerInset();\n if (!this.headerContractResolved) {\n this.cancelHeaderReveal();\n header.setAttribute('data-shell-page-syncing', '');\n return;\n }\n\n const next = this.effectiveVariant;\n const renderedVariantIsStale = !header.classList.contains(this.variantClass(next));\n if (!renderedVariantIsStale) this.syncRenderedHeaderGeometry(header);\n if (concealUntilSynced) {\n this.cancelHeaderReveal();\n header.setAttribute('data-shell-page-syncing', '');\n }\n if (header.variant !== next) header.variant = next;\n if (concealUntilSynced) {\n this.revealHeaderWhenSynced(header, next);\n }\n }\n\n private observeHeader(header: BarTitleElement | null) {\n this.cancelHeaderReveal();\n this.cancelHeaderGeometrySync();\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerMutationObserver?.disconnect();\n this.headerMutationObserver = null;\n this.headerEl?.style.removeProperty('--ds-bar-title-divider-inset');\n this.headerEl = header;\n this.expandedHeaderHeight = 0;\n this.expandedGeometryFrozen = false;\n this.setHeaderTravel(0);\n this.setSpacerHeight(0);\n this.stickyHeaderEl?.style.setProperty('--ds-shell-page-sticky-offset', '0px');\n\n if (!header) return;\n if (header.classList.contains(this.variantClass('expanded'))) {\n this.captureExpandedHeaderGeometry(header);\n }\n if (typeof ResizeObserver !== 'undefined') {\n this.headerResizeObserver = new ResizeObserver(() => {\n this.syncRenderedHeaderGeometry(header);\n });\n this.headerResizeObserver.observe(header);\n }\n if (typeof MutationObserver !== 'undefined') {\n this.headerMutationObserver = new MutationObserver(() => {\n this.syncRenderedHeaderGeometry(header);\n });\n this.headerMutationObserver.observe(header, {\n attributes: true,\n attributeFilter: ['class'],\n childList: true,\n subtree: true,\n });\n }\n this.syncHeaderVariant(true);\n this.scheduleHeaderGeometrySync(header);\n }\n\n private handleHeaderSlotChange = (event: Event) => {\n if (this.responsiveMode === 'mobile') return;\n const slot = event.target as HTMLSlotElement;\n const header = slot\n .assignedElements()\n .find(element => element.tagName.toLowerCase() === 'ds-bar-title');\n this.observeHeader((header as BarTitleElement | undefined) ?? null);\n };\n\n render() {\n const mobile = this.responsiveMode === 'mobile';\n return (\n <Host\n role=\"main\"\n class={{\n 'shell-page-host--inset-default': this.contentInset === 'default',\n 'shell-page-host--inset-none': this.contentInset === 'none',\n 'shell-page-host--surface-primary': this.contentSurface === 'primary',\n 'shell-page-host--surface-secondary': this.contentSurface === 'secondary',\n 'shell-page-host--mobile': mobile,\n [`shell-page-host--header-${this.effectiveVariant}`]: true,\n }}\n >\n <div\n ref={el => {\n this.sentinelEl = el ?? null;\n }}\n class=\"shell-page__scroll-sentinel\"\n aria-hidden=\"true\"\n />\n <div\n ref={el => {\n this.stickyHeaderEl = el ?? null;\n }}\n class=\"shell-page__sticky-header\"\n >\n <div\n class=\"shell-page__desktop-header\"\n hidden={mobile}\n aria-hidden={mobile ? 'true' : undefined}\n inert={mobile ? true : undefined}\n >\n <slot name=\"header\" onSlotchange={this.handleHeaderSlotChange} />\n </div>\n <div\n class=\"shell-page__mobile-header\"\n hidden={!mobile}\n aria-hidden={!mobile ? 'true' : undefined}\n inert={!mobile ? true : undefined}\n >\n <slot name=\"mobile-header\" />\n </div>\n </div>\n <div\n ref={el => {\n this.spacerEl = el ?? null;\n }}\n class=\"shell-page__flow-spacer\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__content\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",
324
+ "content": "import { Component, Element, h, Host, Prop, State, Watch } from '@stencil/core';\nimport type { ShellResponsiveMode } from '../../shell/shell-responsive';\nimport { resolveCssLengthPx } from '../../utils/resolve-css-length-px';\nimport type { BarTitleVariant } from '../BarTitle/bar-title-types';\nimport { resolveShellPageHeaderVariant } from './shell-page-responsive';\nimport type {\n ShellPageCapacity,\n ShellPageContentInset,\n ShellPageContentSurface,\n ShellPageHeaderPresentation,\n} from './shell-page-types';\n\ntype BarTitleElement = HTMLElement & { variant: BarTitleVariant };\n\n@Component({\n tag: 'ds-shell-page',\n styleUrl: 'ShellPage.css',\n scoped: true,\n})\nexport class ShellPage {\n private static readonly MAX_HEADER_REVEAL_FRAMES = 12;\n private static readonly MAX_HEADER_GEOMETRY_FRAMES = 12;\n\n @Element() el!: HTMLElement;\n\n /** Automatic capacity/scroll behavior, or an explicit header variant override. */\n @Prop() headerPresentation: ShellPageHeaderPresentation = 'auto';\n\n /** Available page-header capacity supplied by the owning application shell. */\n @Prop() headerCapacity?: ShellPageCapacity;\n\n /** Standard page gutters, or no inset for full-bleed page content. */\n @Prop() contentInset: ShellPageContentInset = 'default';\n\n /** Preserve the responsive side/end gutters while allowing content to meet the header. */\n @Prop() contentInsetBlockStart: ShellPageContentInset = 'default';\n\n /** Exact block-start content inset, overriding the responsive default when provided. */\n @Prop() contentInsetBlockStartSize?: string;\n\n /** Exact block-start content inset while the header is compact or constrained. */\n @Prop() compactContentInsetBlockStartSize?: string;\n\n /** Allow roomy automatic headers to compact as the page scrolls. */\n @Prop() scrollCompaction: boolean = true;\n\n /** Canvas surface painted around and beneath routed page content. */\n @Prop() contentSurface: ShellPageContentSurface = 'primary';\n\n /** Explicit shell breakpoint presentation. Mobile uses the dedicated mobile-header slot. */\n @Prop({ attribute: 'responsive-mode', reflect: true })\n responsiveMode: ShellResponsiveMode = 'desktop';\n\n @State() private pageTopVisible = true;\n\n private sentinelEl: HTMLElement | null = null;\n private spacerEl: HTMLElement | null = null;\n private stickyHeaderEl: HTMLElement | null = null;\n private headerEl: BarTitleElement | null = null;\n private expandedHeaderHeight = 0;\n private headerTravel = 0;\n private expandedGeometryFrozen = false;\n private headerResizeObserver: ResizeObserver | null = null;\n private headerMutationObserver: MutationObserver | null = null;\n private headerRevealFrame: number | null = null;\n private headerGeometryFrame: number | null = null;\n private reconnectFrame: number | null = null;\n private scrollRoot: HTMLElement | Window | null = null;\n private hasLoaded = false;\n\n @Watch('headerCapacity')\n @Watch('headerPresentation')\n @Watch('scrollCompaction')\n handleHeaderContractChange() {\n this.syncHeaderVariant(true);\n }\n\n @Watch('responsiveMode')\n handleResponsiveModeChange() {\n this.observeHeader(this.responsiveMode === 'mobile' ? null : this.findHeader());\n }\n\n componentDidLoad() {\n this.hasLoaded = true;\n this.connectRuntime();\n }\n\n componentDidRender() {\n this.syncHeaderVariant();\n }\n\n connectedCallback() {\n if (!this.hasLoaded) return;\n if (this.reconnectFrame !== null) cancelAnimationFrame(this.reconnectFrame);\n this.reconnectFrame = requestAnimationFrame(() => {\n this.reconnectFrame = null;\n if (this.el.isConnected) this.connectRuntime();\n });\n }\n\n disconnectedCallback() {\n if (this.reconnectFrame !== null) cancelAnimationFrame(this.reconnectFrame);\n this.reconnectFrame = null;\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerMutationObserver?.disconnect();\n this.headerMutationObserver = null;\n this.cancelHeaderReveal();\n this.cancelHeaderGeometrySync();\n this.headerEl?.style.removeProperty('--ds-bar-title-divider-inset');\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = null;\n }\n\n private connectRuntime() {\n this.observeHeader(this.responsiveMode === 'mobile' ? null : this.findHeader());\n this.connectScrollRoot();\n }\n\n private get effectiveVariant(): BarTitleVariant {\n return resolveShellPageHeaderVariant(\n this.headerPresentation,\n this.headerCapacity ?? 'roomy',\n this.scrollCompaction ? this.pageTopVisible : true\n );\n }\n\n private get headerContractResolved(): boolean {\n return this.headerPresentation !== 'auto' || this.headerCapacity !== undefined;\n }\n\n private get isScrollCompacted(): boolean {\n return (\n this.scrollCompaction &&\n this.headerPresentation === 'auto' &&\n this.headerCapacity === 'roomy' &&\n !this.pageTopVisible\n );\n }\n\n private get contentInsetStyles(): { [name: string]: string } {\n const styles: { [name: string]: string } = {};\n const expanded = this.contentInsetBlockStartSize?.trim();\n const compact = this.compactContentInsetBlockStartSize?.trim();\n if (expanded) styles['--ds-shell-page-content-block-start-inset'] = expanded;\n if (compact) styles['--ds-shell-page-compact-content-block-start-inset'] = compact;\n return styles;\n }\n\n private composedParent(element: Element): Element | null {\n return (element as HTMLElement).assignedSlot?.parentElement ?? element.parentElement;\n }\n\n private findScrollRoot(): HTMLElement | Window {\n let ancestor = this.composedParent(this.el);\n while (ancestor && ancestor !== document.documentElement) {\n const overflow = getComputedStyle(ancestor).overflowY;\n if (overflow === 'auto' || overflow === 'scroll' || overflow === 'overlay') {\n return ancestor as HTMLElement;\n }\n ancestor = this.composedParent(ancestor);\n }\n return window;\n }\n\n private connectScrollRoot() {\n const next = this.findScrollRoot();\n if (next === this.scrollRoot) return;\n this.scrollRoot?.removeEventListener('scroll', this.handleScroll);\n this.scrollRoot = next;\n this.scrollRoot.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n\n private get scrollRootResolved(): boolean {\n const shell = this.el.closest('ds-shell-app');\n if (!shell) return true;\n const expected = shell.querySelector<HTMLElement>('.shell-app__content');\n return expected !== null && this.scrollRoot === expected;\n }\n\n private handleScroll = () => {\n if (!this.sentinelEl || !this.scrollRoot) return;\n const rootTop =\n this.scrollRoot === window ? 0 : (this.scrollRoot as HTMLElement).getBoundingClientRect().top;\n this.syncHeaderDividerInset(rootTop);\n const nextPageTopVisible = this.sentinelEl.getBoundingClientRect().top >= rootTop;\n if (\n this.scrollCompaction &&\n !nextPageTopVisible &&\n this.pageTopVisible &&\n this.headerEl?.classList.contains(this.variantClass('expanded'))\n ) {\n this.captureExpandedHeaderGeometry(this.headerEl);\n this.expandedGeometryFrozen = true;\n }\n if (\n nextPageTopVisible &&\n this.expandedGeometryFrozen &&\n this.el.getBoundingClientRect().top >= rootTop\n ) {\n this.expandedGeometryFrozen = false;\n if (this.headerEl?.classList.contains(this.variantClass('expanded'))) {\n this.captureExpandedHeaderGeometry(this.headerEl);\n }\n }\n this.pageTopVisible = nextPageTopVisible;\n };\n\n private findHeader(): BarTitleElement | null {\n return this.el.querySelector<BarTitleElement>('ds-bar-title');\n }\n\n private get compactHeaderHeight(): number {\n return resolveCssLengthPx('--dimension-size-600', 0);\n }\n\n private syncHeaderDividerInset(rootTop?: number) {\n const header = this.headerEl;\n if (!header) return;\n\n const ownsScrollTransition =\n this.scrollCompaction &&\n this.headerPresentation === 'auto' &&\n this.headerCapacity === 'roomy';\n const expandedInset = resolveCssLengthPx('--dimension-space-400', 0);\n if (\n !ownsScrollTransition ||\n !this.sentinelEl ||\n !this.scrollRoot ||\n this.headerTravel <= 0 ||\n expandedInset <= 0\n ) {\n header.style.removeProperty('--ds-bar-title-divider-inset');\n return;\n }\n\n const scrollRootTop =\n rootTop ??\n (this.scrollRoot === window\n ? 0\n : (this.scrollRoot as HTMLElement).getBoundingClientRect().top);\n const remainingTravel = this.sentinelEl.getBoundingClientRect().top - scrollRootTop;\n const progress = Math.min(1, Math.max(0, 1 - remainingTravel / this.headerTravel));\n header.style.setProperty('--ds-bar-title-divider-inset', `${expandedInset * (1 - progress)}px`);\n }\n\n private setHeaderTravel(distance: number) {\n const next = Math.max(0, distance);\n if (Math.abs(next - this.headerTravel) < 0.5) return;\n this.headerTravel = next;\n this.el.style.setProperty('--ds-shell-page-header-travel', `${next}px`);\n this.handleScroll();\n }\n\n private measureHeaderTravel(header: BarTitleElement) {\n const anchor = header.querySelector<HTMLElement>('[data-shell-page-header-anchor]');\n const compactHeight = this.compactHeaderHeight;\n if (!anchor || compactHeight <= 0) return;\n\n const headerRect = header.getBoundingClientRect();\n const anchorRect = anchor.getBoundingClientRect();\n if (headerRect.height <= 0 || anchorRect.height <= 0) return;\n\n const expandedAnchorTop = anchorRect.top - headerRect.top;\n const compactAnchorTop = Math.max(0, (compactHeight - anchorRect.height) / 2);\n this.setHeaderTravel(expandedAnchorTop - compactAnchorTop);\n }\n\n private captureExpandedHeaderGeometry(header: BarTitleElement) {\n // Keep the largest observed expanded geometry for this header instance.\n // During a variant handoff Chromium can briefly report the compact box\n // before the child host class mutation is delivered; that transient must\n // not erase the flow reservation captured at the roomy page top.\n this.expandedHeaderHeight = Math.max(\n this.expandedHeaderHeight,\n header.getBoundingClientRect().height\n );\n this.measureHeaderTravel(header);\n }\n\n private setSpacerHeight(height: number) {\n if (!this.spacerEl) return;\n this.spacerEl.style.setProperty('--ds-shell-page-flow-spacer', `${Math.max(0, height)}px`);\n }\n\n private variantClass(variant: BarTitleVariant): string {\n return `bar-title-host--${variant}`;\n }\n\n private setStickyHeaderOffset(renderedVariant: BarTitleVariant) {\n this.stickyHeaderEl?.style.setProperty(\n '--ds-shell-page-sticky-offset',\n renderedVariant === 'expanded' &&\n this.scrollCompaction &&\n this.headerPresentation === 'auto' &&\n this.headerCapacity === 'roomy'\n ? `${-this.headerTravel}px`\n : '0px'\n );\n }\n\n private syncRenderedHeaderGeometry(header: BarTitleElement) {\n const renderedVariant = this.effectiveVariant;\n if (!header.classList.contains(this.variantClass(renderedVariant))) return;\n\n const renderedHeight = header.getBoundingClientRect().height;\n if (renderedHeight > 0) {\n this.el.style.setProperty('--ds-shell-page-sticky-header-block-size', `${renderedHeight}px`);\n }\n\n // Update both flow-preservation pieces before reading layout. Otherwise a\n // reverse compact → expanded render can briefly contain the tall header and\n // the compact spacer together, giving browser scroll anchoring a transient\n // height change to compensate.\n this.setSpacerHeight(\n this.isScrollCompacted ? this.expandedHeaderHeight - this.compactHeaderHeight : 0\n );\n this.setStickyHeaderOffset(renderedVariant);\n\n if (renderedVariant === 'expanded' && !this.expandedGeometryFrozen) {\n this.captureExpandedHeaderGeometry(header);\n this.setStickyHeaderOffset(renderedVariant);\n }\n }\n\n private cancelHeaderGeometrySync() {\n if (this.headerGeometryFrame !== null) cancelAnimationFrame(this.headerGeometryFrame);\n this.headerGeometryFrame = null;\n }\n\n private scheduleHeaderGeometrySync(header: BarTitleElement) {\n this.cancelHeaderGeometrySync();\n let framesRemaining = ShellPage.MAX_HEADER_GEOMETRY_FRAMES;\n let framesElapsed = 0;\n const sync = () => {\n if (this.headerEl !== header) return;\n framesRemaining -= 1;\n framesElapsed += 1;\n // In WebKit a child's componentDidLoad can precede its assignment into\n // the parent's rendered slot. Revalidate after ShellApp has had a frame\n // to expose the actual content scroller.\n this.connectScrollRoot();\n this.syncRenderedHeaderGeometry(header);\n const geometryReady =\n this.effectiveVariant !== 'expanded' ||\n (this.expandedHeaderHeight > 0 && this.headerTravel > 0);\n if (\n (geometryReady && this.scrollRootResolved && framesElapsed >= 2) ||\n framesRemaining <= 0\n ) {\n this.headerGeometryFrame = null;\n return;\n }\n this.headerGeometryFrame = requestAnimationFrame(sync);\n };\n this.headerGeometryFrame = requestAnimationFrame(sync);\n }\n\n private cancelHeaderReveal() {\n if (this.headerRevealFrame !== null) cancelAnimationFrame(this.headerRevealFrame);\n this.headerRevealFrame = null;\n this.headerEl?.removeAttribute('data-shell-page-syncing');\n }\n\n private revealHeaderWhenSynced(header: BarTitleElement, variant: BarTitleVariant) {\n // Stencil normally re-renders within a frame or two of a prop change. Stop\n // polling at the cap, but fail closed: a stale variant must never paint.\n let framesRemaining = ShellPage.MAX_HEADER_REVEAL_FRAMES;\n const reveal = () => {\n if (this.headerEl !== header) {\n header.removeAttribute('data-shell-page-syncing');\n return;\n }\n framesRemaining -= 1;\n if (header.classList.contains(this.variantClass(variant))) {\n header.removeAttribute('data-shell-page-syncing');\n this.headerRevealFrame = null;\n return;\n }\n if (framesRemaining <= 0) {\n this.headerRevealFrame = null;\n return;\n }\n this.headerRevealFrame = requestAnimationFrame(reveal);\n };\n this.headerRevealFrame = requestAnimationFrame(reveal);\n }\n\n private syncHeaderVariant(concealUntilSynced = false) {\n const header = this.headerEl;\n if (!header) return;\n\n this.syncHeaderDividerInset();\n if (!this.headerContractResolved) {\n this.cancelHeaderReveal();\n header.setAttribute('data-shell-page-syncing', '');\n return;\n }\n\n const next = this.effectiveVariant;\n const renderedVariantIsStale = !header.classList.contains(this.variantClass(next));\n if (!renderedVariantIsStale) this.syncRenderedHeaderGeometry(header);\n if (renderedVariantIsStale && this.isScrollCompacted) {\n // Preserve the expanded flow before asking BarTitle to become compact.\n // This prevents the sentinel from moving back into view during the\n // parent/child render handoff and keeps the variant transition stable.\n this.setSpacerHeight(this.expandedHeaderHeight - this.compactHeaderHeight);\n this.setStickyHeaderOffset(next);\n }\n if (concealUntilSynced) {\n this.cancelHeaderReveal();\n header.setAttribute('data-shell-page-syncing', '');\n }\n if (header.variant !== next) {\n header.variant = next;\n // The child update and its MutationObserver callback can land in\n // different phases across engines. Poll the rendered class as the\n // authoritative handoff before committing sticky/spacer geometry.\n this.scheduleHeaderGeometrySync(header);\n }\n if (concealUntilSynced) {\n this.revealHeaderWhenSynced(header, next);\n }\n }\n\n private observeHeader(header: BarTitleElement | null) {\n this.cancelHeaderReveal();\n this.cancelHeaderGeometrySync();\n this.headerResizeObserver?.disconnect();\n this.headerResizeObserver = null;\n this.headerMutationObserver?.disconnect();\n this.headerMutationObserver = null;\n this.headerEl?.style.removeProperty('--ds-bar-title-divider-inset');\n this.headerEl = header;\n this.expandedHeaderHeight = 0;\n this.expandedGeometryFrozen = false;\n this.setHeaderTravel(0);\n this.setSpacerHeight(0);\n this.stickyHeaderEl?.style.setProperty('--ds-shell-page-sticky-offset', '0px');\n\n if (!header) return;\n if (header.classList.contains(this.variantClass('expanded'))) {\n this.captureExpandedHeaderGeometry(header);\n }\n if (typeof ResizeObserver !== 'undefined') {\n this.headerResizeObserver = new ResizeObserver(() => {\n this.syncRenderedHeaderGeometry(header);\n });\n this.headerResizeObserver.observe(header);\n }\n if (typeof MutationObserver !== 'undefined') {\n this.headerMutationObserver = new MutationObserver(() => {\n this.syncRenderedHeaderGeometry(header);\n });\n this.headerMutationObserver.observe(header, {\n attributes: true,\n attributeFilter: ['class'],\n childList: true,\n subtree: true,\n });\n }\n this.syncHeaderVariant(true);\n this.scheduleHeaderGeometrySync(header);\n }\n\n private handleHeaderSlotChange = (event: Event) => {\n if (this.responsiveMode === 'mobile') return;\n const slot = event.target as HTMLSlotElement;\n const header = slot\n .assignedElements()\n .find(element => element.tagName.toLowerCase() === 'ds-bar-title');\n this.observeHeader((header as BarTitleElement | undefined) ?? null);\n };\n\n render() {\n const mobile = this.responsiveMode === 'mobile';\n return (\n <Host\n role=\"main\"\n style={this.contentInsetStyles}\n class={{\n 'shell-page-host--inset-default': this.contentInset === 'default',\n 'shell-page-host--inset-none': this.contentInset === 'none',\n 'shell-page-host--block-start-inset-none': this.contentInsetBlockStart === 'none',\n 'shell-page-host--surface-primary': this.contentSurface === 'primary',\n 'shell-page-host--surface-secondary': this.contentSurface === 'secondary',\n 'shell-page-host--mobile': mobile,\n [`shell-page-host--header-${this.effectiveVariant}`]: true,\n }}\n >\n <div\n ref={el => {\n this.sentinelEl = el ?? null;\n }}\n class=\"shell-page__scroll-sentinel\"\n aria-hidden=\"true\"\n />\n <div\n ref={el => {\n this.stickyHeaderEl = el ?? null;\n }}\n class=\"shell-page__sticky-header\"\n >\n <div\n class=\"shell-page__desktop-header\"\n hidden={mobile}\n aria-hidden={mobile ? 'true' : undefined}\n inert={mobile ? true : undefined}\n >\n <slot name=\"header\" onSlotchange={this.handleHeaderSlotChange} />\n </div>\n <div\n class=\"shell-page__mobile-header\"\n hidden={!mobile}\n aria-hidden={!mobile ? 'true' : undefined}\n inert={!mobile ? true : undefined}\n >\n <slot name=\"mobile-header\" />\n </div>\n </div>\n <div\n ref={el => {\n this.spacerEl = el ?? null;\n }}\n class=\"shell-page__flow-spacer\"\n aria-hidden=\"true\"\n />\n <div class=\"shell-page__content\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",
252
325
  "type": "registry:ui"
253
326
  },
254
327
  {
@@ -390,7 +390,7 @@
390
390
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: headers, items.",
391
391
  "peerDependencies": {
392
392
  "required": [
393
- "@ds-mo/tokens ^6.0.0",
393
+ "@ds-mo/tokens ^6.2.1",
394
394
  "@ds-mo/icons ^6.6.0"
395
395
  ],
396
396
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -255,7 +255,7 @@
255
255
  },
256
256
  "peerDependencies": {
257
257
  "required": [
258
- "@ds-mo/tokens ^6.0.0",
258
+ "@ds-mo/tokens ^6.2.1",
259
259
  "@ds-mo/icons ^6.6.0"
260
260
  ],
261
261
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -629,7 +629,7 @@
629
629
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: formatOptions, valueTexts.",
630
630
  "peerDependencies": {
631
631
  "required": [
632
- "@ds-mo/tokens ^6.0.0",
632
+ "@ds-mo/tokens ^6.2.1",
633
633
  "@ds-mo/icons ^6.6.0"
634
634
  ],
635
635
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -646,7 +646,7 @@
646
646
  "files": [
647
647
  {
648
648
  "path": "src/wc/components/Slider/Slider.css",
649
- "content": "@import '../../utils/control-inactive.css';\n@import '../../utils/field-stack.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n --ds-slider-control-size: var(--dimension-size-400);\n --ds-slider-thumb-size: var(--dimension-size-200);\n --ds-slider-track-size: var(--dimension-size-100);\n --ds-slider-track-stroke: var(--dimension-stroke-width-012);\n --ds-slider-vertical-length: calc(var(--dimension-size-800) * 3);\n box-sizing: border-box;\n width: 100%;\n color: var(--color-foreground-primary);\n}\n\n:host(.slider--sm) {\n --ds-slider-control-size: var(--dimension-size-300);\n --ds-slider-thumb-size: var(--dimension-size-150);\n --ds-slider-track-size: var(--dimension-size-075);\n}\n\n:host(.slider--xs) {\n --ds-slider-control-size: var(--dimension-size-200);\n --ds-slider-thumb-size: var(--dimension-size-100);\n --ds-slider-track-size: var(--dimension-size-050);\n}\n\n:host(.slider--vertical) {\n width: fit-content;\n min-width: var(--dimension-form-width-xs);\n}\n\n.slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.slider__label {\n min-width: 0;\n}\n\n.slider__value {\n flex-shrink: 0;\n}\n\n.slider__control {\n position: relative;\n width: 100%;\n height: var(--ds-slider-control-size);\n border-radius: var(--dimension-radius-half);\n cursor: default;\n touch-action: none;\n user-select: none;\n}\n\n:host(.slider--vertical) .slider__control {\n align-self: center;\n width: var(--ds-slider-control-size);\n height: var(--ds-slider-vertical-length);\n}\n\n:host(.slider--readonly) .slider__control {\n cursor: default;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity) on the host. */\n:host(.ds-control-inactive) .slider__control {\n cursor: not-allowed;\n}\n\n.slider__rail {\n position: absolute;\n top: 50%;\n right: 0;\n left: 0;\n height: var(--ds-slider-track-size);\n overflow: hidden;\n border-radius: var(--dimension-radius-025);\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-slider-track-stroke) var(--color-border-secondary);\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n:host(.slider--thumb-center) .slider__rail {\n right: calc(var(--ds-slider-thumb-size) / 2);\n left: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n.slider__indicator {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n border-radius: inherit;\n background-color: var(--color-background-bold-brand);\n}\n\n:host(.slider--range) .slider__indicator {\n left: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n width: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--thumb-center) .slider__indicator {\n left: calc(var(--ds-slider-start-pct, 0) * 1%);\n width: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n.slider__thumb {\n position: absolute;\n top: 50%;\n left: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n width: var(--ds-slider-thumb-size);\n height: var(--ds-slider-thumb-size);\n transform: translateY(-50%);\n z-index: 1;\n}\n\n.slider__thumb--active {\n z-index: 2;\n}\n\n.slider__input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n appearance: none;\n pointer-events: none;\n z-index: 2;\n}\n\n.slider__thumb-visual {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n overflow: visible;\n border-radius: var(--dimension-radius-025);\n background-color: var(--color-background-primary);\n box-shadow: var(--effect-elevation-elevated-sm);\n pointer-events: none;\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.slider__thumb-wash {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: transparent;\n transition: background-color var(--effect-motion-short-2);\n}\n\n:host(:not(.slider--readonly):not(.ds-control-inactive)) .slider__thumb:hover .slider__thumb-wash {\n background-color: var(--color-interaction-hover);\n}\n\n:host([data-dragging]:not(.slider--readonly):not(.ds-control-inactive))\n .slider__thumb--active .slider__thumb-wash {\n background-color: var(--color-interaction-pressed);\n}\n\n.slider__input:focus-visible + .slider__thumb-visual,\n:host([data-review-focus]) .slider__thumb[data-index='0'] .slider__thumb-visual {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n:host(.slider--vertical) .slider__rail {\n top: 0;\n right: auto;\n bottom: 0;\n left: 50%;\n width: var(--ds-slider-track-size);\n height: auto;\n transform: translateX(-50%);\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__rail {\n top: calc(var(--ds-slider-thumb-size) / 2);\n bottom: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n:host(.slider--vertical) .slider__indicator {\n top: auto;\n right: 0;\n bottom: 0;\n left: 0;\n width: auto;\n height: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--range) .slider__indicator {\n bottom: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n height: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__indicator {\n bottom: calc(var(--ds-slider-start-pct, 0) * 1%);\n height: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n:host(.slider--vertical) .slider__thumb {\n top: auto;\n bottom: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n left: 50%;\n transform: translateX(-50%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .slider__thumb-visual,\n .slider__thumb-wash {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n .slider__rail {\n border: var(--ds-slider-track-stroke) solid var(--ds-forced-color-content);\n box-shadow: none;\n }\n\n .slider__indicator {\n background-color: var(--ds-forced-color-selected);\n }\n\n .slider__thumb-visual {\n border:\n var(--dimension-stroke-width-012) solid\n var(--ds-forced-color-control-boundary);\n background-color: var(--ds-forced-color-surface);\n box-shadow: none;\n }\n\n .slider__input:focus-visible + .slider__thumb-visual,\n :host([data-review-focus]) .slider__thumb[data-index='0'] .slider__thumb-visual {\n outline-color: var(--ds-forced-color-selected);\n }\n}\n",
649
+ "content": "@import '../../utils/control-inactive.css';\n@import '../../utils/field-stack.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n --ds-slider-control-size: var(--dimension-size-400);\n --ds-slider-thumb-size: var(--dimension-size-200);\n --ds-slider-track-size: var(--dimension-size-100);\n --ds-slider-track-stroke: var(--dimension-stroke-width-012);\n --ds-slider-vertical-length: calc(var(--dimension-size-800) * 3);\n box-sizing: border-box;\n width: 100%;\n color: var(--color-foreground-primary);\n}\n\n:host(.slider--sm) {\n --ds-slider-control-size: var(--dimension-size-300);\n --ds-slider-thumb-size: var(--dimension-size-150);\n --ds-slider-track-size: var(--dimension-size-075);\n}\n\n:host(.slider--xs) {\n --ds-slider-control-size: var(--dimension-size-200);\n --ds-slider-thumb-size: var(--dimension-size-100);\n --ds-slider-track-size: var(--dimension-size-050);\n}\n\n:host(.slider--vertical) {\n width: fit-content;\n min-width: var(--dimension-form-width-xs);\n}\n\n.slider__label-row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.slider__label {\n min-width: 0;\n}\n\n.slider__value {\n flex-shrink: 0;\n}\n\n.slider__control {\n position: relative;\n width: 100%;\n height: var(--ds-slider-control-size);\n border-radius: var(--dimension-radius-half);\n cursor: default;\n touch-action: none;\n user-select: none;\n}\n\n:host(.slider--vertical) .slider__control {\n align-self: center;\n width: var(--ds-slider-control-size);\n height: var(--ds-slider-vertical-length);\n}\n\n:host(.slider--readonly) .slider__control {\n cursor: default;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity) on the host. */\n:host(.ds-control-inactive) .slider__control {\n cursor: not-allowed;\n}\n\n.slider__rail {\n position: absolute;\n top: 50%;\n right: 0;\n left: 0;\n height: var(--ds-slider-track-size);\n overflow: hidden;\n border-radius: var(--dimension-radius-025);\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-slider-track-stroke) var(--color-border-secondary);\n transform: translateY(-50%);\n pointer-events: none;\n}\n\n:host(.slider--thumb-center) .slider__rail {\n right: calc(var(--ds-slider-thumb-size) / 2);\n left: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n.slider__indicator {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n border-radius: inherit;\n background-color: var(--color-background-bold-brand);\n}\n\n:host(.slider--range) .slider__indicator {\n left: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n width: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--thumb-center) .slider__indicator {\n left: calc(var(--ds-slider-start-pct, 0) * 1%);\n width: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n.slider__thumb {\n position: absolute;\n top: 50%;\n left: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n width: var(--ds-slider-thumb-size);\n height: var(--ds-slider-thumb-size);\n transform: translateY(-50%);\n z-index: 1;\n}\n\n.slider__thumb--active {\n z-index: 2;\n}\n\n.slider__input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n appearance: none;\n pointer-events: none;\n z-index: 2;\n}\n\n.slider__thumb-visual {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n overflow: visible;\n border-radius: var(--dimension-radius-025);\n background-color: var(--color-background-primary);\n box-shadow: var(--effect-elevation-elevated-sm);\n pointer-events: none;\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.slider__thumb-wash {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: transparent;\n transition: background-color var(--effect-motion-short-2);\n}\n\n@media (hover: hover) and (pointer: fine) {\n :host(:not(.slider--readonly):not(.ds-control-inactive))\n .slider__thumb:hover\n .slider__thumb-wash {\n background-color: var(--color-interaction-hover);\n }\n}\n\n:host([data-dragging]:not(.slider--readonly):not(.ds-control-inactive))\n .slider__thumb--active .slider__thumb-wash {\n background-color: var(--color-interaction-pressed);\n}\n\n.slider__input:focus-visible + .slider__thumb-visual,\n:host([data-review-focus]) .slider__thumb[data-index='0'] .slider__thumb-visual {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n:host(.slider--vertical) .slider__rail {\n top: 0;\n right: auto;\n bottom: 0;\n left: 50%;\n width: var(--ds-slider-track-size);\n height: auto;\n transform: translateX(-50%);\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__rail {\n top: calc(var(--ds-slider-thumb-size) / 2);\n bottom: calc(var(--ds-slider-thumb-size) / 2);\n}\n\n:host(.slider--vertical) .slider__indicator {\n top: auto;\n right: 0;\n bottom: 0;\n left: 0;\n width: auto;\n height: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-end-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--range) .slider__indicator {\n bottom: calc(\n var(--ds-slider-thumb-size) / 2 +\n (var(--ds-slider-start-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size))\n );\n height: calc(\n ((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) / 100) *\n (100% - var(--ds-slider-thumb-size))\n );\n}\n\n:host(.slider--vertical.slider--thumb-center) .slider__indicator {\n bottom: calc(var(--ds-slider-start-pct, 0) * 1%);\n height: calc((var(--ds-slider-end-pct, 0) - var(--ds-slider-start-pct, 0)) * 1%);\n}\n\n:host(.slider--vertical) .slider__thumb {\n top: auto;\n bottom: calc((var(--ds-slider-thumb-pct, 0) / 100) * (100% - var(--ds-slider-thumb-size)));\n left: 50%;\n transform: translateX(-50%);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .slider__thumb-visual,\n .slider__thumb-wash {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n .slider__rail {\n border: var(--ds-slider-track-stroke) solid var(--ds-forced-color-content);\n box-shadow: none;\n }\n\n .slider__indicator {\n background-color: var(--ds-forced-color-selected);\n }\n\n .slider__thumb-visual {\n border:\n var(--dimension-stroke-width-012) solid\n var(--ds-forced-color-control-boundary);\n background-color: var(--ds-forced-color-surface);\n box-shadow: none;\n }\n\n .slider__input:focus-visible + .slider__thumb-visual,\n :host([data-review-focus]) .slider__thumb[data-index='0'] .slider__thumb-visual {\n outline-color: var(--ds-forced-color-selected);\n }\n}\n",
650
650
  "type": "registry:ui"
651
651
  },
652
652
  {
@@ -199,7 +199,7 @@
199
199
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: options, sections.",
200
200
  "peerDependencies": {
201
201
  "required": [
202
- "@ds-mo/tokens ^6.0.0",
202
+ "@ds-mo/tokens ^6.2.1",
203
203
  "@ds-mo/icons ^6.6.0"
204
204
  ],
205
205
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -214,7 +214,7 @@
214
214
  "files": [
215
215
  {
216
216
  "path": "src/wc/components/SwatchPicker/SwatchPicker.css",
217
- "content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n box-sizing: border-box;\n display: block;\n width: 100%;\n --_swatch-inner-inset: calc(\n var(--dimension-stroke-width-025) + var(--dimension-space-025)\n );\n --_swatch-ring-bg: var(--color-background-primary);\n --_swatch-select-motion: var(--effect-motion-short-3);\n}\n\n.swatch-picker {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n width: 100%;\n min-height: var(--dimension-size-400);\n gap: var(--dimension-space-100);\n padding: var(--dimension-space-100);\n}\n\n.swatch-picker__option {\n position: relative;\n box-sizing: border-box;\n flex: 0 0 auto;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n background: transparent;\n cursor: default;\n isolation: isolate;\n}\n\n.swatch-picker__fill,\n.swatch-picker__border,\n.swatch-picker__interaction,\n.swatch-picker__halo,\n.swatch-picker__stroke {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n pointer-events: none;\n}\n\n.swatch-picker__fill {\n z-index: 1;\n background-color: var(--_swatch-preview-color);\n background-image: var(--_swatch-preview-image);\n background-repeat: no-repeat;\n background-position: center;\n background-size: cover;\n opacity: var(--_swatch-preview-opacity);\n transition:\n inset var(--_swatch-select-motion);\n}\n\n.swatch-picker__border {\n z-index: 2;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-012) var(--color-border-secondary);\n transition:\n inset var(--_swatch-select-motion);\n}\n\n.swatch-picker__interaction {\n z-index: 3;\n background-color: transparent;\n transition:\n inset var(--_swatch-select-motion),\n background-color 0s;\n}\n\n.swatch-picker__option:hover:not(:disabled) .swatch-picker__interaction {\n background-color: var(--color-interaction-hover);\n}\n\n.swatch-picker__option:active:not(:disabled) .swatch-picker__interaction {\n background-color: var(--color-interaction-pressed);\n}\n\n.swatch-picker__halo,\n.swatch-picker__stroke {\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n.swatch-picker__halo {\n z-index: 4;\n box-shadow: inset 0 0 0 var(--_swatch-inner-inset) var(--_swatch-ring-bg);\n}\n\n.swatch-picker__stroke {\n z-index: 5;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-025) var(--color-border-bold-brand);\n}\n\n.swatch-picker__option--selected .swatch-picker__fill,\n.swatch-picker__option--selected .swatch-picker__border,\n.swatch-picker__option--selected .swatch-picker__interaction {\n inset: var(--_swatch-inner-inset);\n}\n\n.swatch-picker__option--selected .swatch-picker__halo,\n.swatch-picker__option--selected .swatch-picker__stroke {\n opacity: 1;\n transform: scale(1);\n}\n\n.swatch-picker__divider {\n flex: 0 0 auto;\n align-self: center;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-size-300);\n background-color: var(--color-border-tertiary);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .swatch-picker__fill,\n .swatch-picker__border,\n .swatch-picker__interaction,\n .swatch-picker__halo,\n .swatch-picker__stroke {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n .swatch-picker__fill {\n forced-color-adjust: none;\n }\n\n .swatch-picker__border {\n box-shadow: none;\n outline: var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);\n outline-offset: calc(-1 * var(--dimension-stroke-width-012));\n }\n\n .swatch-picker__halo {\n box-shadow: none;\n }\n\n .swatch-picker__stroke {\n box-shadow: none;\n outline: var(--dimension-stroke-width-025) solid var(--ds-forced-color-selected);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025));\n }\n\n .swatch-picker__divider {\n background-color: var(--ds-forced-color-content);\n }\n}\n",
217
+ "content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n box-sizing: border-box;\n display: block;\n width: 100%;\n --_swatch-inner-inset: calc(\n var(--dimension-stroke-width-025) + var(--dimension-space-025)\n );\n --_swatch-ring-bg: var(--color-background-primary);\n --_swatch-select-motion: var(--effect-motion-short-3);\n}\n\n.swatch-picker {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n width: 100%;\n min-height: var(--dimension-size-400);\n gap: var(--dimension-space-100);\n padding: var(--dimension-space-100);\n}\n\n.swatch-picker__option {\n position: relative;\n box-sizing: border-box;\n flex: 0 0 auto;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n background: transparent;\n cursor: default;\n isolation: isolate;\n}\n\n.swatch-picker__fill,\n.swatch-picker__border,\n.swatch-picker__interaction,\n.swatch-picker__halo,\n.swatch-picker__stroke {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n pointer-events: none;\n}\n\n.swatch-picker__fill {\n z-index: 1;\n background-color: var(--_swatch-preview-color);\n background-image: var(--_swatch-preview-image);\n background-repeat: no-repeat;\n background-position: center;\n background-size: cover;\n opacity: var(--_swatch-preview-opacity);\n transition:\n inset var(--_swatch-select-motion);\n}\n\n.swatch-picker__border {\n z-index: 2;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-012) var(--color-border-secondary);\n transition:\n inset var(--_swatch-select-motion);\n}\n\n.swatch-picker__interaction {\n z-index: 3;\n background-color: transparent;\n transition:\n inset var(--_swatch-select-motion),\n background-color 0s;\n}\n\n@media (hover: hover) and (pointer: fine) {\n .swatch-picker__option:hover:not(:disabled) .swatch-picker__interaction {\n background-color: var(--color-interaction-hover);\n }\n}\n\n.swatch-picker__option:active:not(:disabled) .swatch-picker__interaction {\n background-color: var(--color-interaction-pressed);\n}\n\n.swatch-picker__halo,\n.swatch-picker__stroke {\n opacity: 0;\n transform: scale(1.2);\n transform-origin: center;\n transition:\n opacity var(--_swatch-select-motion),\n transform var(--_swatch-select-motion);\n}\n\n.swatch-picker__halo {\n z-index: 4;\n box-shadow: inset 0 0 0 var(--_swatch-inner-inset) var(--_swatch-ring-bg);\n}\n\n.swatch-picker__stroke {\n z-index: 5;\n box-shadow: inset 0 0 0 var(--dimension-stroke-width-025) var(--color-border-bold-brand);\n}\n\n.swatch-picker__option--selected .swatch-picker__fill,\n.swatch-picker__option--selected .swatch-picker__border,\n.swatch-picker__option--selected .swatch-picker__interaction {\n inset: var(--_swatch-inner-inset);\n}\n\n.swatch-picker__option--selected .swatch-picker__halo,\n.swatch-picker__option--selected .swatch-picker__stroke {\n opacity: 1;\n transform: scale(1);\n}\n\n.swatch-picker__divider {\n flex: 0 0 auto;\n align-self: center;\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-size-300);\n background-color: var(--color-border-tertiary);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .swatch-picker__fill,\n .swatch-picker__border,\n .swatch-picker__interaction,\n .swatch-picker__halo,\n .swatch-picker__stroke {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n .swatch-picker__fill {\n forced-color-adjust: none;\n }\n\n .swatch-picker__border {\n box-shadow: none;\n outline: var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);\n outline-offset: calc(-1 * var(--dimension-stroke-width-012));\n }\n\n .swatch-picker__halo {\n box-shadow: none;\n }\n\n .swatch-picker__stroke {\n box-shadow: none;\n outline: var(--dimension-stroke-width-025) solid var(--ds-forced-color-selected);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025));\n }\n\n .swatch-picker__divider {\n background-color: var(--ds-forced-color-content);\n }\n}\n",
218
218
  "type": "registry:ui"
219
219
  },
220
220
  {
@@ -334,7 +334,7 @@
334
334
  },
335
335
  "peerDependencies": {
336
336
  "required": [
337
- "@ds-mo/tokens ^6.0.0",
337
+ "@ds-mo/tokens ^6.2.1",
338
338
  "@ds-mo/icons ^6.6.0"
339
339
  ],
340
340
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
@@ -349,7 +349,7 @@
349
349
  "files": [
350
350
  {
351
351
  "path": "src/wc/components/Switch/Switch.css",
352
- "content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n --ds-switch-width: var(--dimension-size-400);\n --ds-switch-height: var(--dimension-size-250);\n --ds-switch-thumb-size: var(--dimension-size-150);\n --ds-switch-gap: var(--dimension-space-050);\n --ds-switch-stroke: var(--dimension-stroke-width-012);\n --ds-switch-inset: var(--ds-switch-gap);\n --ds-switch-thumb-hover: var(--color-interaction-hover);\n --ds-switch-thumb-pressed: var(--color-interaction-pressed);\n --ds-switch-travel: calc(\n var(--ds-switch-width) - var(--ds-switch-thumb-size) - var(--ds-switch-inset) -\n var(--ds-switch-inset)\n );\n position: relative;\n display: inline-flex;\n width: var(--ds-switch-width);\n height: var(--ds-switch-height);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n flex-shrink: 0;\n overflow: visible;\n cursor: default;\n user-select: none;\n outline: none;\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-switch-stroke) var(--color-border-secondary);\n transition:\n background-color var(--effect-motion-short-3),\n box-shadow var(--effect-motion-short-3);\n}\n\n:host(.switch--lg) {\n --ds-switch-width: var(--dimension-size-500);\n --ds-switch-height: var(--dimension-size-300);\n --ds-switch-thumb-size: var(--dimension-iconography-sm);\n --ds-switch-gap: var(--dimension-space-050);\n}\n\n:host(.switch--sm) {\n --ds-switch-width: var(--dimension-size-300);\n --ds-switch-height: var(--dimension-size-200);\n --ds-switch-thumb-size: calc(var(--dimension-size-base) * 5 / 4);\n --ds-switch-gap: calc(var(--dimension-space-025) + var(--dimension-space-012));\n}\n\n:host(.switch--xs) {\n --ds-switch-width: var(--dimension-size-250);\n --ds-switch-height: var(--dimension-size-150);\n --ds-switch-thumb-size: var(--dimension-size-100);\n --ds-switch-gap: var(--dimension-space-025);\n}\n\n:host(.checked) {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n:host(.switch--readonly),\n:host(.switch--presentation) {\n cursor: default;\n}\n\n:host(.switch--presentation) {\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n.thumb {\n position: absolute;\n top: 50%;\n left: var(--ds-switch-inset);\n width: var(--ds-switch-thumb-size);\n height: var(--ds-switch-thumb-size);\n border-radius: var(--dimension-radius-half);\n background-color: var(--color-foreground-tertiary);\n box-shadow: none;\n transform: translateY(-50%);\n transition:\n background-color var(--effect-motion-short-3),\n transform var(--effect-motion-short-3);\n pointer-events: none;\n}\n\n.thumb::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n}\n\n:host(:hover:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-hover);\n}\n\n:host(:active:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-pressed);\n}\n\n:host(.checked) .thumb {\n background-color: var(--color-background-primary);\n box-shadow: none;\n transform: translate3d(var(--ds-switch-travel), -50%, 0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .thumb {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n :host {\n border: var(--ds-switch-stroke) solid var(--ds-forced-color-content);\n box-shadow: none;\n }\n\n :host(.checked) {\n background-color: var(--ds-forced-color-selected);\n border-color: var(--ds-forced-color-selected);\n }\n\n .thumb {\n background-color: var(--ds-forced-color-content);\n }\n\n :host(.checked) .thumb {\n background-color: var(--ds-forced-color-on-selected);\n }\n}\n",
352
+ "content": "@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n --ds-switch-width: var(--dimension-size-400);\n --ds-switch-height: var(--dimension-size-250);\n --ds-switch-thumb-size: var(--dimension-size-150);\n --ds-switch-gap: var(--dimension-space-050);\n --ds-switch-stroke: var(--dimension-stroke-width-012);\n --ds-switch-inset: var(--ds-switch-gap);\n --ds-switch-thumb-hover: var(--color-interaction-hover);\n --ds-switch-thumb-pressed: var(--color-interaction-pressed);\n --ds-switch-travel: calc(\n var(--ds-switch-width) - var(--ds-switch-thumb-size) - var(--ds-switch-inset) -\n var(--ds-switch-inset)\n );\n position: relative;\n display: inline-flex;\n width: var(--ds-switch-width);\n height: var(--ds-switch-height);\n padding: 0;\n border: none;\n border-radius: var(--dimension-radius-half);\n box-sizing: border-box;\n flex-shrink: 0;\n overflow: visible;\n cursor: default;\n user-select: none;\n outline: none;\n background-color: transparent;\n box-shadow: inset 0 0 0 var(--ds-switch-stroke) var(--color-border-secondary);\n transition:\n background-color var(--effect-motion-short-3),\n box-shadow var(--effect-motion-short-3);\n}\n\n:host(.switch--lg) {\n --ds-switch-width: var(--dimension-size-500);\n --ds-switch-height: var(--dimension-size-300);\n --ds-switch-thumb-size: var(--dimension-iconography-sm);\n --ds-switch-gap: var(--dimension-space-050);\n}\n\n:host(.switch--sm) {\n --ds-switch-width: var(--dimension-size-300);\n --ds-switch-height: var(--dimension-size-200);\n --ds-switch-thumb-size: calc(var(--dimension-size-base) * 5 / 4);\n --ds-switch-gap: calc(var(--dimension-space-025) + var(--dimension-space-012));\n}\n\n:host(.switch--xs) {\n --ds-switch-width: var(--dimension-size-250);\n --ds-switch-height: var(--dimension-size-150);\n --ds-switch-thumb-size: var(--dimension-size-100);\n --ds-switch-gap: var(--dimension-space-025);\n}\n\n:host(.checked) {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n:host(.switch--readonly),\n:host(.switch--presentation) {\n cursor: default;\n}\n\n:host(.switch--presentation) {\n pointer-events: none;\n}\n\n/* Inactive: `.ds-control-inactive` (50% opacity). */\n\n.thumb {\n position: absolute;\n top: 50%;\n left: var(--ds-switch-inset);\n width: var(--ds-switch-thumb-size);\n height: var(--ds-switch-thumb-size);\n border-radius: var(--dimension-radius-half);\n background-color: var(--color-foreground-tertiary);\n box-shadow: none;\n transform: translateY(-50%);\n transition:\n background-color var(--effect-motion-short-3),\n transform var(--effect-motion-short-3);\n pointer-events: none;\n}\n\n.thumb::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: transparent;\n pointer-events: none;\n}\n\n@media (hover: hover) and (pointer: fine) {\n :host(:hover:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-hover);\n }\n}\n\n:host(:active:not(:disabled):not(.ds-control-inactive):not(.switch--readonly):not(.switch--presentation))\n .thumb::after {\n background: var(--ds-switch-thumb-pressed);\n}\n\n:host(.checked) .thumb {\n background-color: var(--color-background-primary);\n box-shadow: none;\n transform: translate3d(var(--ds-switch-travel), -50%, 0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .thumb {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n :host {\n border: var(--ds-switch-stroke) solid var(--ds-forced-color-content);\n box-shadow: none;\n }\n\n :host(.checked) {\n background-color: var(--ds-forced-color-selected);\n border-color: var(--ds-forced-color-selected);\n }\n\n .thumb {\n background-color: var(--ds-forced-color-content);\n }\n\n :host(.checked) .thumb {\n background-color: var(--ds-forced-color-on-selected);\n }\n}\n",
353
353
  "type": "registry:ui"
354
354
  },
355
355
  {
@@ -238,7 +238,7 @@
238
238
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: tabs.",
239
239
  "peerDependencies": {
240
240
  "required": [
241
- "@ds-mo/tokens ^6.0.0",
241
+ "@ds-mo/tokens ^6.2.1",
242
242
  "@ds-mo/icons ^6.6.0"
243
243
  ],
244
244
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."