@mhmo91/schmancy 0.10.36 → 0.10.38

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 (572) hide show
  1. package/custom-elements.json +54 -31
  2. package/dist/SchmancyElement-BNnyBOwk.js +286 -0
  3. package/dist/{SchmancyElement-C3CpdNsi.js.map → SchmancyElement-BNnyBOwk.js.map} +1 -1
  4. package/dist/SchmancyElement-C41uPa6l.cjs +2 -0
  5. package/dist/{SchmancyElement-BBzRWB1w.cjs.map → SchmancyElement-C41uPa6l.cjs.map} +1 -1
  6. package/dist/agent/schmancy.agent.js +2432 -2361
  7. package/dist/agent/schmancy.agent.js.map +1 -1
  8. package/dist/agent/schmancy.manifest.json +4 -22
  9. package/dist/area-2FrTZI_T.cjs +21 -0
  10. package/dist/area-2FrTZI_T.cjs.map +1 -0
  11. package/dist/{area-BA96mwFY.js → area-KVDzhT4s.js} +4 -4
  12. package/dist/area-KVDzhT4s.js.map +1 -0
  13. package/dist/area.cjs +1 -1
  14. package/dist/area.js +2 -2
  15. package/dist/{audio-D52h1jAT.js → audio-D3gnp15Y.js} +1 -1
  16. package/dist/{audio-D52h1jAT.js.map → audio-D3gnp15Y.js.map} +1 -1
  17. package/dist/{audio-B_jT9Xr7.cjs → audio-EaD0Ggfh.cjs} +1 -1
  18. package/dist/{audio-B_jT9Xr7.cjs.map → audio-EaD0Ggfh.cjs.map} +1 -1
  19. package/dist/audio.cjs +1 -1
  20. package/dist/audio.js +2 -2
  21. package/dist/autocomplete-DMmxsvUe.cjs +115 -0
  22. package/dist/autocomplete-DMmxsvUe.cjs.map +1 -0
  23. package/dist/{autocomplete-CI4QJXAN.js → autocomplete-DWiEqlQf.js} +96 -96
  24. package/dist/autocomplete-DWiEqlQf.js.map +1 -0
  25. package/dist/autocomplete.cjs +1 -1
  26. package/dist/autocomplete.js +1 -1
  27. package/dist/avatar.cjs +1 -1
  28. package/dist/avatar.js +3 -3
  29. package/dist/badge.cjs +1 -1
  30. package/dist/badge.js +1 -1
  31. package/dist/{boat-_N1x5U_3.js → boat-DmyG7y1V.js} +4 -4
  32. package/dist/{boat-_N1x5U_3.js.map → boat-DmyG7y1V.js.map} +1 -1
  33. package/dist/{boat-I4B1UNMc.cjs → boat-dB1_qLm0.cjs} +1 -1
  34. package/dist/{boat-I4B1UNMc.cjs.map → boat-dB1_qLm0.cjs.map} +1 -1
  35. package/dist/boat.cjs +1 -1
  36. package/dist/boat.js +1 -1
  37. package/dist/breadcrumb.cjs +3 -3
  38. package/dist/breadcrumb.cjs.map +1 -1
  39. package/dist/breadcrumb.js +4 -4
  40. package/dist/breadcrumb.js.map +1 -1
  41. package/dist/{busy-BIUonyPk.cjs → busy-Cj_PV7oC.cjs} +1 -1
  42. package/dist/{busy-BIUonyPk.cjs.map → busy-Cj_PV7oC.cjs.map} +1 -1
  43. package/dist/{busy-CCB3qKnh.js → busy-enYCTssB.js} +2 -2
  44. package/dist/{busy-CCB3qKnh.js.map → busy-enYCTssB.js.map} +1 -1
  45. package/dist/busy.cjs +1 -1
  46. package/dist/busy.js +1 -1
  47. package/dist/{button-C89bPnHt.js → button-BQSOVnHn.js} +10 -9
  48. package/dist/button-BQSOVnHn.js.map +1 -0
  49. package/dist/button-WRmXlNyw.cjs +62 -0
  50. package/dist/button-WRmXlNyw.cjs.map +1 -0
  51. package/dist/button.cjs +6 -6
  52. package/dist/button.cjs.map +1 -1
  53. package/dist/button.js +17 -16
  54. package/dist/button.js.map +1 -1
  55. package/dist/{card-CFsCgJKZ.js → card-BHTz1GwB.js} +16 -16
  56. package/dist/card-BHTz1GwB.js.map +1 -0
  57. package/dist/{card-BO93_oxQ.cjs → card-ThG_ZaQE.cjs} +3 -3
  58. package/dist/card-ThG_ZaQE.cjs.map +1 -0
  59. package/dist/card.cjs +1 -1
  60. package/dist/card.js +1 -1
  61. package/dist/{checkbox-CFUBUFtW.cjs → checkbox-C4zeib84.cjs} +2 -2
  62. package/dist/{checkbox-CFUBUFtW.cjs.map → checkbox-C4zeib84.cjs.map} +1 -1
  63. package/dist/{checkbox-Bh7q0djq.js → checkbox-Ce0DlAdW.js} +6 -6
  64. package/dist/{checkbox-Bh7q0djq.js.map → checkbox-Ce0DlAdW.js.map} +1 -1
  65. package/dist/checkbox.cjs +1 -1
  66. package/dist/checkbox.js +1 -1
  67. package/dist/{chips-BfzpsyV1.cjs → chips-B1jui8Pe.cjs} +3 -3
  68. package/dist/chips-B1jui8Pe.cjs.map +1 -0
  69. package/dist/{chips-6YaoRmeG.js → chips-DAy6v93f.js} +20 -19
  70. package/dist/chips-DAy6v93f.js.map +1 -0
  71. package/dist/chips.cjs +1 -1
  72. package/dist/chips.js +2 -2
  73. package/dist/connectivity.cjs +1 -1
  74. package/dist/connectivity.js +3 -3
  75. package/dist/content-drawer.cjs +1 -1
  76. package/dist/content-drawer.js +1 -1
  77. package/dist/cursor-glow-Ah7VXSj7.js.map +1 -1
  78. package/dist/cursor-glow-Bulq-38P.cjs.map +1 -1
  79. package/dist/{date-range-N-A249O9.cjs → date-range-BUaPgbTZ.cjs} +2 -2
  80. package/dist/date-range-BUaPgbTZ.cjs.map +1 -0
  81. package/dist/{date-range-CEo_Kjqw.js → date-range-NTpoA1in.js} +4 -4
  82. package/dist/date-range-NTpoA1in.js.map +1 -0
  83. package/dist/{date-range-inline-DFopysWF.cjs → date-range-inline-D0I6k84h.cjs} +1 -1
  84. package/dist/{date-range-inline-DFopysWF.cjs.map → date-range-inline-D0I6k84h.cjs.map} +1 -1
  85. package/dist/{date-range-inline-BwialV9j.js → date-range-inline-DjRdMZ1z.js} +2 -2
  86. package/dist/{date-range-inline-BwialV9j.js.map → date-range-inline-DjRdMZ1z.js.map} +1 -1
  87. package/dist/date-range-inline.cjs +1 -1
  88. package/dist/date-range-inline.js +1 -1
  89. package/dist/date-range.cjs +1 -1
  90. package/dist/date-range.js +1 -1
  91. package/dist/delay.cjs +1 -1
  92. package/dist/delay.js +2 -2
  93. package/dist/{details-GtpfI2hA.js → details-CY49XVfp.js} +43 -35
  94. package/dist/details-CY49XVfp.js.map +1 -0
  95. package/dist/details-DQNj2oaU.cjs +164 -0
  96. package/dist/details-DQNj2oaU.cjs.map +1 -0
  97. package/dist/details.cjs +1 -1
  98. package/dist/details.js +1 -1
  99. package/dist/{directives-CvYGSW_a.cjs → directives-Bb0S1DKZ.cjs} +4 -4
  100. package/dist/directives-Bb0S1DKZ.cjs.map +1 -0
  101. package/dist/{directives-C2dXgpCY.js → directives-Bfm1lkoy.js} +30 -23
  102. package/dist/directives-Bfm1lkoy.js.map +1 -0
  103. package/dist/directives.cjs +1 -1
  104. package/dist/directives.js +2 -2
  105. package/dist/{divider-D0pGX2VB.js → divider-BeyX_C0A.js} +2 -2
  106. package/dist/{divider-D0pGX2VB.js.map → divider-BeyX_C0A.js.map} +1 -1
  107. package/dist/{divider-rNsWCvMi.cjs → divider-Ck2C1sKl.cjs} +1 -1
  108. package/dist/{divider-rNsWCvMi.cjs.map → divider-Ck2C1sKl.cjs.map} +1 -1
  109. package/dist/divider.cjs +1 -1
  110. package/dist/divider.js +1 -1
  111. package/dist/dropdown.cjs +1 -1
  112. package/dist/dropdown.js +2 -2
  113. package/dist/{expand-FcKAzJta.js → expand-BYsSEtp6.js} +53 -53
  114. package/dist/expand-BYsSEtp6.js.map +1 -0
  115. package/dist/expand-CUF163mg.cjs +141 -0
  116. package/dist/expand-CUF163mg.cjs.map +1 -0
  117. package/dist/expand.cjs +1 -1
  118. package/dist/expand.js +1 -1
  119. package/dist/fab.cjs +1 -1
  120. package/dist/fab.js +2 -2
  121. package/dist/{float-CQ1WEp3M.js → float-Cgllk_H9.js} +2 -2
  122. package/dist/{float-CQ1WEp3M.js.map → float-Cgllk_H9.js.map} +1 -1
  123. package/dist/{float-CDjgxWyy.cjs → float-OvqX0nqG.cjs} +1 -1
  124. package/dist/{float-CDjgxWyy.cjs.map → float-OvqX0nqG.cjs.map} +1 -1
  125. package/dist/float.cjs +1 -1
  126. package/dist/float.js +1 -1
  127. package/dist/form-4GKROq2P.cjs +27 -0
  128. package/dist/form-4GKROq2P.cjs.map +1 -0
  129. package/dist/{form-H24puioV.js → form-DxaV_Ose.js} +39 -39
  130. package/dist/form-DxaV_Ose.js.map +1 -0
  131. package/dist/form.cjs +3 -3
  132. package/dist/form.cjs.map +1 -1
  133. package/dist/form.js +34 -34
  134. package/dist/form.js.map +1 -1
  135. package/dist/gravity-6pL6CfIr.cjs.map +1 -1
  136. package/dist/gravity-sVK3zGBF.js.map +1 -1
  137. package/dist/handover/agent-runtime-followups.md +1 -1
  138. package/dist/handover/agent-runtime-v1.md +3 -3
  139. package/dist/{icons-DBxfN91B.js → icons-CJ2mXcBi.js} +9 -9
  140. package/dist/icons-CJ2mXcBi.js.map +1 -0
  141. package/dist/icons-sZ-LybA9.cjs +24 -0
  142. package/dist/icons-sZ-LybA9.cjs.map +1 -0
  143. package/dist/icons.cjs +1 -1
  144. package/dist/icons.js +1 -1
  145. package/dist/{iframe-BDVElN8z.js → iframe-DWvN5nGB.js} +11 -11
  146. package/dist/iframe-DWvN5nGB.js.map +1 -0
  147. package/dist/{iframe-CG-z9qev.cjs → iframe-DpCv-QH2.cjs} +7 -7
  148. package/dist/iframe-DpCv-QH2.cjs.map +1 -0
  149. package/dist/iframe.cjs +1 -1
  150. package/dist/iframe.js +1 -1
  151. package/dist/index.cjs +1 -1
  152. package/dist/index.js +37 -37
  153. package/dist/{input-Bt_o4sYo.js → input-BCCHz6tB.js} +7 -7
  154. package/dist/input-BCCHz6tB.js.map +1 -0
  155. package/dist/{input-B14Nn6xD.cjs → input-Z-3N5JMv.cjs} +2 -2
  156. package/dist/input-Z-3N5JMv.cjs.map +1 -0
  157. package/dist/{input-chip-DEqO0DXc.js → input-chip-BOrcKH-H.js} +2 -2
  158. package/dist/{input-chip-DEqO0DXc.js.map → input-chip-BOrcKH-H.js.map} +1 -1
  159. package/dist/{input-chip-ugYu9Fn9.cjs → input-chip-ChAgRCXZ.cjs} +1 -1
  160. package/dist/{input-chip-ugYu9Fn9.cjs.map → input-chip-ChAgRCXZ.cjs.map} +1 -1
  161. package/dist/input.cjs +1 -1
  162. package/dist/input.js +1 -1
  163. package/dist/json.cjs +1 -1
  164. package/dist/json.js +3 -3
  165. package/dist/kbd.cjs +1 -1
  166. package/dist/kbd.js +2 -2
  167. package/dist/{layout-BJ_43VrH.js → layout-CFiG3lNT.js} +1 -1
  168. package/dist/{layout-BJ_43VrH.js.map → layout-CFiG3lNT.js.map} +1 -1
  169. package/dist/{layout-DF9ZaQ-b.cjs → layout-DZ4dpLh9.cjs} +1 -1
  170. package/dist/{layout-DF9ZaQ-b.cjs.map → layout-DZ4dpLh9.cjs.map} +1 -1
  171. package/dist/layout.cjs +1 -1
  172. package/dist/layout.js +2 -2
  173. package/dist/lazy-BaAiIUru.js +19 -0
  174. package/dist/lazy-BaAiIUru.js.map +1 -0
  175. package/dist/lazy-C-7a4FAe.cjs +1 -0
  176. package/dist/lazy-C-7a4FAe.cjs.map +1 -0
  177. package/dist/{lightbox-ZmuoBBFT.js → lightbox-B7Y4Nij_.js} +2 -2
  178. package/dist/lightbox-B7Y4Nij_.js.map +1 -0
  179. package/dist/{lightbox-B47Zoqv-.cjs → lightbox-Dpwsn8Qr.cjs} +1 -1
  180. package/dist/lightbox-Dpwsn8Qr.cjs.map +1 -0
  181. package/dist/lightbox.cjs +1 -1
  182. package/dist/lightbox.js +1 -1
  183. package/dist/{list-CaSWrlG2.cjs → list-BhM-6dAi.cjs} +1 -1
  184. package/dist/{list-CaSWrlG2.cjs.map → list-BhM-6dAi.cjs.map} +1 -1
  185. package/dist/{list-C47xzld_.js → list-C5WVoIfJ.js} +2 -2
  186. package/dist/{list-C47xzld_.js.map → list-C5WVoIfJ.js.map} +1 -1
  187. package/dist/list.cjs +1 -1
  188. package/dist/list.js +1 -1
  189. package/dist/magnetic-DKtc4umC.cjs.map +1 -1
  190. package/dist/magnetic-DaOOv5Dz.js.map +1 -1
  191. package/dist/{menu-8RObM6Ie.js → menu-CBAAJoHu.js} +3 -3
  192. package/dist/{menu-8RObM6Ie.js.map → menu-CBAAJoHu.js.map} +1 -1
  193. package/dist/{menu-Jpsy85SX.cjs → menu-DFQjJk3H.cjs} +1 -1
  194. package/dist/{menu-Jpsy85SX.cjs.map → menu-DFQjJk3H.cjs.map} +1 -1
  195. package/dist/menu.cjs +1 -1
  196. package/dist/menu.js +1 -1
  197. package/dist/{mixins-DTzfFVyv.js → mixins-DGBI7YPO.js} +11 -11
  198. package/dist/mixins-DGBI7YPO.js.map +1 -0
  199. package/dist/{mixins-DPdzC9ZH.cjs → mixins-fIpzhVMd.cjs} +1 -1
  200. package/dist/mixins-fIpzhVMd.cjs.map +1 -0
  201. package/dist/mixins.cjs +1 -1
  202. package/dist/mixins.js +2 -2
  203. package/dist/nav-drawer.cjs +1 -1
  204. package/dist/nav-drawer.js +1 -1
  205. package/dist/navigation-bar.cjs +1 -1
  206. package/dist/navigation-bar.js +1 -1
  207. package/dist/navigation-rail.cjs +3 -3
  208. package/dist/navigation-rail.cjs.map +1 -1
  209. package/dist/navigation-rail.js +11 -10
  210. package/dist/navigation-rail.js.map +1 -1
  211. package/dist/notification-B6yDL91t.cjs +24 -0
  212. package/dist/notification-B6yDL91t.cjs.map +1 -0
  213. package/dist/{notification-Ccktcj9H.js → notification-BB9OBRCr.js} +22 -22
  214. package/dist/notification-BB9OBRCr.js.map +1 -0
  215. package/dist/notification.cjs +1 -1
  216. package/dist/notification.js +1 -1
  217. package/dist/{option-CkMxwBqU.js → option-B21ImL0k.js} +2 -2
  218. package/dist/{option-CkMxwBqU.js.map → option-B21ImL0k.js.map} +1 -1
  219. package/dist/{option-0aNiVB3Q.cjs → option-CJQM5I9q.cjs} +1 -1
  220. package/dist/{option-0aNiVB3Q.cjs.map → option-CJQM5I9q.cjs.map} +1 -1
  221. package/dist/option.cjs +1 -1
  222. package/dist/option.js +1 -1
  223. package/dist/{overlay-H3Wt_dgQ.js → overlay-CWsihJ-E.js} +75 -67
  224. package/dist/overlay-CWsihJ-E.js.map +1 -0
  225. package/dist/overlay-DkIX9Ig3.cjs +58 -0
  226. package/dist/overlay-DkIX9Ig3.cjs.map +1 -0
  227. package/dist/overlay.cjs +1 -1
  228. package/dist/{overlay.confirm-body-Dxn_wNm3.js → overlay.confirm-body-CPqqPNks.js} +10 -10
  229. package/dist/overlay.confirm-body-CPqqPNks.js.map +1 -0
  230. package/dist/{overlay.confirm-body-CR9xaqOE.cjs → overlay.confirm-body-DwTfiNlV.cjs} +3 -3
  231. package/dist/overlay.confirm-body-DwTfiNlV.cjs.map +1 -0
  232. package/dist/overlay.js +4 -4
  233. package/dist/overlay.service-DU1nqh6A.cjs +1 -0
  234. package/dist/{overlay.service-DEj3rfRr.cjs.map → overlay.service-DU1nqh6A.cjs.map} +1 -1
  235. package/dist/{overlay.service-C46kOtUi.js → overlay.service-KTgBxjFb.js} +4 -4
  236. package/dist/{overlay.service-C46kOtUi.js.map → overlay.service-KTgBxjFb.js.map} +1 -1
  237. package/dist/{progress-zs18GR6C.cjs → progress-B-Qg44XY.cjs} +1 -1
  238. package/dist/{progress-zs18GR6C.cjs.map → progress-B-Qg44XY.cjs.map} +1 -1
  239. package/dist/{progress-BK7gSq8j.js → progress-CUSS1sNz.js} +2 -2
  240. package/dist/{progress-BK7gSq8j.js.map → progress-CUSS1sNz.js.map} +1 -1
  241. package/dist/progress.cjs +1 -1
  242. package/dist/progress.js +1 -1
  243. package/dist/{radio-group-1HCpzRUB.js → radio-group-AHLvrN8O.js} +7 -7
  244. package/dist/radio-group-AHLvrN8O.js.map +1 -0
  245. package/dist/{radio-group-DbYlyPc-.cjs → radio-group-BEtvCSS1.cjs} +2 -2
  246. package/dist/radio-group-BEtvCSS1.cjs.map +1 -0
  247. package/dist/radio-group.cjs +1 -1
  248. package/dist/radio-group.js +1 -1
  249. package/dist/range.cjs +1 -1
  250. package/dist/range.js +2 -2
  251. package/dist/select-BWpV2iv-.cjs +56 -0
  252. package/dist/select-BWpV2iv-.cjs.map +1 -0
  253. package/dist/{select-CEyhNtZ2.js → select-Cawz88lG.js} +46 -46
  254. package/dist/select-Cawz88lG.js.map +1 -0
  255. package/dist/select.cjs +1 -1
  256. package/dist/select.js +1 -1
  257. package/dist/skeleton.cjs +1 -1
  258. package/dist/skeleton.js +2 -2
  259. package/dist/skills/SKILL.md +17 -11
  260. package/dist/skills/overlay.md +14 -7
  261. package/dist/skills/schmancy/SKILL.md +17 -11
  262. package/dist/skills/schmancy/overlay.md +14 -7
  263. package/dist/skills/schmancy/steps.md +68 -34
  264. package/dist/skills/steps.md +68 -34
  265. package/dist/slider.cjs +1 -1
  266. package/dist/slider.js +2 -2
  267. package/dist/{sound.service-DO4SmUUT.js → sound.service-CK-5zob-.js} +4 -3
  268. package/dist/sound.service-CK-5zob-.js.map +1 -0
  269. package/dist/{sound.service-G_8GV_6L.cjs → sound.service-D2GGaBXc.cjs} +1 -1
  270. package/dist/sound.service-D2GGaBXc.cjs.map +1 -0
  271. package/dist/{splash-screen-B1mM4_xz.js → splash-screen-BUEtjHXC.js} +13 -13
  272. package/dist/splash-screen-BUEtjHXC.js.map +1 -0
  273. package/dist/{splash-screen-cbz4bxjB.cjs → splash-screen-DqPuipox.cjs} +6 -6
  274. package/dist/splash-screen-DqPuipox.cjs.map +1 -0
  275. package/dist/splash-screen.cjs +1 -1
  276. package/dist/splash-screen.js +1 -1
  277. package/dist/{src-tncsWsTY.js → src-CIqAj3Eh.js} +45 -45
  278. package/dist/src-CIqAj3Eh.js.map +1 -0
  279. package/dist/{src-czeiuT1m.cjs → src-CYqBQTyt.cjs} +6 -6
  280. package/dist/src-CYqBQTyt.cjs.map +1 -0
  281. package/dist/{state-Cx0aoL5e.cjs → state-BxDNox-2.cjs} +1 -1
  282. package/dist/{state-Cx0aoL5e.cjs.map → state-BxDNox-2.cjs.map} +1 -1
  283. package/dist/{state-DJDp3N7J.js → state-CnZCDMT0.js} +9 -9
  284. package/dist/{state-DJDp3N7J.js.map → state-CnZCDMT0.js.map} +1 -1
  285. package/dist/state.cjs +1 -1
  286. package/dist/state.js +2 -2
  287. package/dist/steps.cjs +35 -19
  288. package/dist/steps.cjs.map +1 -1
  289. package/dist/steps.js +96 -73
  290. package/dist/steps.js.map +1 -1
  291. package/dist/{surface-CYBl8_a3.js → surface-BMdG3dKQ.js} +2 -2
  292. package/dist/{surface-CYBl8_a3.js.map → surface-BMdG3dKQ.js.map} +1 -1
  293. package/dist/{surface-C3cxTcJD.cjs → surface-CWwYD_z2.cjs} +1 -1
  294. package/dist/{surface-C3cxTcJD.cjs.map → surface-CWwYD_z2.cjs.map} +1 -1
  295. package/dist/surface.cjs +1 -1
  296. package/dist/surface.js +1 -1
  297. package/dist/switch.cjs +4 -4
  298. package/dist/switch.cjs.map +1 -1
  299. package/dist/switch.js +11 -11
  300. package/dist/switch.js.map +1 -1
  301. package/dist/table.cjs +1 -1
  302. package/dist/table.js +2 -2
  303. package/dist/{tabs-DHy93Q3N.js → tabs-CDQYDc6v.js} +2 -2
  304. package/dist/{tabs-DHy93Q3N.js.map → tabs-CDQYDc6v.js.map} +1 -1
  305. package/dist/{tabs-ORQ_Zd43.cjs → tabs-CbD9E1gd.cjs} +1 -1
  306. package/dist/{tabs-ORQ_Zd43.cjs.map → tabs-CbD9E1gd.cjs.map} +1 -1
  307. package/dist/tabs.cjs +1 -1
  308. package/dist/tabs.js +1 -1
  309. package/dist/teleport.cjs +1 -1
  310. package/dist/teleport.js +1 -1
  311. package/dist/textarea-Brgi-vD2.cjs +43 -0
  312. package/dist/textarea-Brgi-vD2.cjs.map +1 -0
  313. package/dist/{textarea-DHIMt-ly.js → textarea-MPyrMi-S.js} +4 -4
  314. package/dist/textarea-MPyrMi-S.js.map +1 -0
  315. package/dist/textarea.cjs +1 -1
  316. package/dist/textarea.js +1 -1
  317. package/dist/{theme-CJpjkqHr.cjs → theme-BMbXoqi0.cjs} +1 -1
  318. package/dist/{theme-CJpjkqHr.cjs.map → theme-BMbXoqi0.cjs.map} +1 -1
  319. package/dist/{theme-CgI9PRco.js → theme-DZu-xmVp.js} +5 -5
  320. package/dist/{theme-CgI9PRco.js.map → theme-DZu-xmVp.js.map} +1 -1
  321. package/dist/{theme-button--FuBkuVr.cjs → theme-button-B0OLb-43.cjs} +1 -1
  322. package/dist/{theme-button--FuBkuVr.cjs.map → theme-button-B0OLb-43.cjs.map} +1 -1
  323. package/dist/{theme-button-D-FXb3oO.js → theme-button-D_qGvEYs.js} +2 -2
  324. package/dist/{theme-button-D-FXb3oO.js.map → theme-button-D_qGvEYs.js.map} +1 -1
  325. package/dist/theme-button.cjs +1 -1
  326. package/dist/theme-button.js +1 -1
  327. package/dist/theme.cjs +1 -1
  328. package/dist/theme.js +3 -3
  329. package/dist/{theme.service-BfTK1Wtl.js → theme.service-7VkM-hVf.js} +15 -11
  330. package/dist/theme.service-7VkM-hVf.js.map +1 -0
  331. package/dist/theme.service-B15FdjOS.cjs +1 -0
  332. package/dist/theme.service-B15FdjOS.cjs.map +1 -0
  333. package/dist/tree.cjs +4 -4
  334. package/dist/tree.cjs.map +1 -1
  335. package/dist/tree.js +8 -8
  336. package/dist/tree.js.map +1 -1
  337. package/dist/{typography-CxA3sx9B.cjs → typography-D4Fo1UGh.cjs} +3 -3
  338. package/dist/{typography-CxA3sx9B.cjs.map → typography-D4Fo1UGh.cjs.map} +1 -1
  339. package/dist/{typography-BEGLfHwz.js → typography-SZhjb_4R.js} +9 -9
  340. package/dist/{typography-BEGLfHwz.js.map → typography-SZhjb_4R.js.map} +1 -1
  341. package/dist/typography.cjs +1 -1
  342. package/dist/typography.js +1 -1
  343. package/dist/visually-hidden.cjs +1 -1
  344. package/dist/visually-hidden.js +2 -2
  345. package/dist/{window-B_n4P9az.js → window-BDVyrBnk.js} +101 -100
  346. package/dist/window-BDVyrBnk.js.map +1 -0
  347. package/dist/window-BbBYjm7R.cjs +59 -0
  348. package/dist/window-BbBYjm7R.cjs.map +1 -0
  349. package/dist/window.cjs +1 -1
  350. package/dist/window.js +1 -1
  351. package/package.json +1 -1
  352. package/skills/schmancy/SKILL.md +17 -11
  353. package/skills/schmancy/overlay.md +14 -7
  354. package/skills/schmancy/steps.md +68 -34
  355. package/src/area/area.component.ts +1 -1
  356. package/src/area/area.service.test.ts +2 -2
  357. package/src/area/area.service.ts +1 -1
  358. package/src/area/lazy.ts +87 -83
  359. package/src/audio/sound.service.ts +3 -3
  360. package/src/breadcrumb/breadcrumb.ts +2 -2
  361. package/src/button/button.ts +11 -11
  362. package/src/button/icon-button.ts +18 -18
  363. package/src/card/card.ts +16 -16
  364. package/src/content-drawer/drawer.ts +6 -6
  365. package/src/details/details.ts +55 -55
  366. package/src/directives/ai-badge.ts +2 -1
  367. package/src/directives/animate-text.ts +2 -1
  368. package/src/directives/art/art.directive.ts +2 -1
  369. package/src/directives/battery.ts +2 -1
  370. package/src/directives/confirm-click.ts +5 -3
  371. package/src/directives/cursor-glow.ts +2 -1
  372. package/src/directives/cycle-text.ts +2 -1
  373. package/src/directives/depth-of-field.ts +2 -1
  374. package/src/directives/drag.ts +4 -2
  375. package/src/directives/fyi.ts +2 -1
  376. package/src/directives/gravity.ts +2 -1
  377. package/src/directives/hummingbird.ts +2 -1
  378. package/src/directives/intersect.ts +3 -2
  379. package/src/directives/liquid.ts +2 -1
  380. package/src/directives/living-border.ts +2 -1
  381. package/src/directives/long-press.ts +2 -1
  382. package/src/directives/magnetic.ts +2 -1
  383. package/src/directives/missed-punch.ts +2 -1
  384. package/src/directives/nebula.ts +6 -5
  385. package/src/directives/overflow-within.ts +2 -1
  386. package/src/directives/reveal.ts +193 -118
  387. package/src/directives/urgent.ts +2 -1
  388. package/src/directives/working-snake.ts +2 -1
  389. package/src/expand/expand-root.component.ts +27 -27
  390. package/src/expand/expand.component.ts +48 -48
  391. package/src/form/fields/autocomplete/autocomplete.ts +154 -154
  392. package/src/form/fields/checkbox/checkbox.ts +4 -4
  393. package/src/form/fields/chips/chips.ts +2 -2
  394. package/src/form/fields/chips/filter-chip.ts +15 -15
  395. package/src/form/fields/date-range/date-range.ts +2 -2
  396. package/src/form/fields/input/input.ts +12 -12
  397. package/src/form/fields/radio-group/radio-button.ts +2 -2
  398. package/src/form/fields/radio-group/radio-group.ts +3 -3
  399. package/src/form/fields/select/select.ts +56 -56
  400. package/src/form/fields/switch/switch.ts +10 -10
  401. package/src/form/fields/textarea/textarea.ts +2 -2
  402. package/src/form/form-summary.ts +33 -33
  403. package/src/form/form.ts +45 -45
  404. package/src/icons/icon.ts +10 -8
  405. package/src/iframe/iframe.ts +11 -11
  406. package/src/lightbox/flip-directive.ts +2 -1
  407. package/src/lightbox/lightbox.directive.ts +2 -1
  408. package/src/nav-drawer/navbar.ts +3 -3
  409. package/src/navigation-rail/navigation-rail.ts +10 -10
  410. package/src/notification/notification.ts +22 -22
  411. package/src/overlay/overlay.component.ts +106 -83
  412. package/src/overlay/overlay.confirm-body.ts +4 -4
  413. package/src/overlay/overlay.service.ts +3 -3
  414. package/src/overlay/overlay.types.ts +4 -2
  415. package/src/splash-screen/splash-screen.ts +11 -11
  416. package/src/state/index.ts +12 -12
  417. package/src/state/schmancy-context.ts +9 -9
  418. package/src/steps/index.ts +1 -1
  419. package/src/steps/schmancy-step.ts +91 -65
  420. package/src/steps/{schmancy-steps-container.ts → schmancy-steps.ts} +18 -38
  421. package/src/steps/steps.context.ts +5 -4
  422. package/src/steps/steps.test.ts +120 -0
  423. package/src/teleport/teleport.component.ts +2 -2
  424. package/src/theme/theme.service.ts +17 -17
  425. package/src/tree/tree.ts +7 -7
  426. package/src/typography/typography.ts +7 -7
  427. package/src/window/window-manager.ts +20 -20
  428. package/src/window/window.ts +100 -100
  429. package/types/mixins/SchmancyElement.d.ts +3 -2
  430. package/types/mixins/formField.mixin.d.ts +1 -1
  431. package/types/src/area/area.service.d.ts +1 -1
  432. package/types/src/area/lazy.d.ts +0 -6
  433. package/types/src/audio/sound.service.d.ts +1 -2
  434. package/types/src/breadcrumb/breadcrumb.d.ts +1 -1
  435. package/types/src/button/button.d.ts +3 -3
  436. package/types/src/button/icon-button.d.ts +6 -7
  437. package/types/src/card/card.d.ts +5 -5
  438. package/types/src/content-drawer/drawer.d.ts +1 -1
  439. package/types/src/details/details.d.ts +2 -21
  440. package/types/src/directives/ai-badge.d.ts +2 -2
  441. package/types/src/directives/animate-text.d.ts +2 -2
  442. package/types/src/directives/art/art.directive.d.ts +2 -2
  443. package/types/src/directives/battery.d.ts +2 -2
  444. package/types/src/directives/confirm-click.d.ts +2 -2
  445. package/types/src/directives/cursor-glow.d.ts +2 -2
  446. package/types/src/directives/cycle-text.d.ts +2 -2
  447. package/types/src/directives/depth-of-field.d.ts +2 -2
  448. package/types/src/directives/drag.d.ts +4 -4
  449. package/types/src/directives/fyi.d.ts +2 -2
  450. package/types/src/directives/gravity.d.ts +2 -2
  451. package/types/src/directives/hummingbird.d.ts +2 -2
  452. package/types/src/directives/intersect.d.ts +2 -2
  453. package/types/src/directives/liquid.d.ts +2 -2
  454. package/types/src/directives/living-border.d.ts +2 -2
  455. package/types/src/directives/long-press.d.ts +2 -2
  456. package/types/src/directives/magnetic.d.ts +2 -2
  457. package/types/src/directives/missed-punch.d.ts +2 -2
  458. package/types/src/directives/nebula.d.ts +2 -2
  459. package/types/src/directives/overflow-within.d.ts +2 -2
  460. package/types/src/directives/reveal.d.ts +17 -7
  461. package/types/src/directives/urgent.d.ts +2 -2
  462. package/types/src/directives/working-snake.d.ts +2 -2
  463. package/types/src/expand/expand-root.component.d.ts +8 -8
  464. package/types/src/expand/expand.component.d.ts +11 -11
  465. package/types/src/form/fields/autocomplete/autocomplete.d.ts +29 -29
  466. package/types/src/form/fields/checkbox/checkbox.d.ts +1 -1
  467. package/types/src/form/fields/chips/chips.d.ts +1 -1
  468. package/types/src/form/fields/chips/filter-chip.d.ts +1 -2
  469. package/types/src/form/fields/input/input.d.ts +3 -3
  470. package/types/src/form/fields/radio-group/radio-button.d.ts +1 -1
  471. package/types/src/form/fields/radio-group/radio-group.d.ts +1 -1
  472. package/types/src/form/fields/select/select.d.ts +8 -8
  473. package/types/src/form/fields/switch/switch.d.ts +3 -3
  474. package/types/src/form/fields/textarea/textarea.d.ts +1 -1
  475. package/types/src/form/form-summary.d.ts +7 -7
  476. package/types/src/form/form.d.ts +11 -11
  477. package/types/src/icons/icon.d.ts +2 -2
  478. package/types/src/iframe/iframe.d.ts +3 -3
  479. package/types/src/lightbox/flip-directive.d.ts +2 -2
  480. package/types/src/lightbox/lightbox.directive.d.ts +2 -2
  481. package/types/src/nav-drawer/navbar.d.ts +1 -1
  482. package/types/src/navigation-rail/navigation-rail.d.ts +2 -2
  483. package/types/src/notification/notification.d.ts +8 -8
  484. package/types/src/overlay/overlay.component.d.ts +16 -16
  485. package/types/src/overlay/overlay.confirm-body.d.ts +1 -1
  486. package/types/src/overlay/overlay.types.d.ts +4 -2
  487. package/types/src/splash-screen/splash-screen.d.ts +2 -2
  488. package/types/src/state/index.d.ts +1 -1
  489. package/types/src/state/schmancy-context.d.ts +3 -3
  490. package/types/src/steps/index.d.ts +1 -1
  491. package/types/src/steps/schmancy-step.d.ts +8 -23
  492. package/types/src/steps/{schmancy-steps-container.d.ts → schmancy-steps.d.ts} +8 -9
  493. package/types/src/steps/steps.context.d.ts +2 -1
  494. package/types/src/steps/steps.test.d.ts +2 -0
  495. package/types/src/teleport/teleport.component.d.ts +1 -1
  496. package/types/src/theme/theme.service.d.ts +1 -4
  497. package/types/src/tree/tree.d.ts +3 -3
  498. package/types/src/typography/typography.d.ts +1 -1
  499. package/types/src/window/window-manager.d.ts +2 -2
  500. package/types/src/window/window.d.ts +20 -20
  501. package/dist/SchmancyElement-BBzRWB1w.cjs +0 -2
  502. package/dist/SchmancyElement-C3CpdNsi.js +0 -284
  503. package/dist/area-BA96mwFY.js.map +0 -1
  504. package/dist/area-DtyQDdOF.cjs +0 -21
  505. package/dist/area-DtyQDdOF.cjs.map +0 -1
  506. package/dist/autocomplete-Bts5Jwwr.cjs +0 -115
  507. package/dist/autocomplete-Bts5Jwwr.cjs.map +0 -1
  508. package/dist/autocomplete-CI4QJXAN.js.map +0 -1
  509. package/dist/button-C89bPnHt.js.map +0 -1
  510. package/dist/button-CkwQH-g3.cjs +0 -62
  511. package/dist/button-CkwQH-g3.cjs.map +0 -1
  512. package/dist/card-BO93_oxQ.cjs.map +0 -1
  513. package/dist/card-CFsCgJKZ.js.map +0 -1
  514. package/dist/chips-6YaoRmeG.js.map +0 -1
  515. package/dist/chips-BfzpsyV1.cjs.map +0 -1
  516. package/dist/date-range-CEo_Kjqw.js.map +0 -1
  517. package/dist/date-range-N-A249O9.cjs.map +0 -1
  518. package/dist/details-BLRPV8sY.cjs +0 -164
  519. package/dist/details-BLRPV8sY.cjs.map +0 -1
  520. package/dist/details-GtpfI2hA.js.map +0 -1
  521. package/dist/directives-C2dXgpCY.js.map +0 -1
  522. package/dist/directives-CvYGSW_a.cjs.map +0 -1
  523. package/dist/expand-FcKAzJta.js.map +0 -1
  524. package/dist/expand-tffQHGbZ.cjs +0 -141
  525. package/dist/expand-tffQHGbZ.cjs.map +0 -1
  526. package/dist/form-H24puioV.js.map +0 -1
  527. package/dist/form-VYhbbir3.cjs +0 -27
  528. package/dist/form-VYhbbir3.cjs.map +0 -1
  529. package/dist/icons-B_a1HStW.cjs +0 -24
  530. package/dist/icons-B_a1HStW.cjs.map +0 -1
  531. package/dist/icons-DBxfN91B.js.map +0 -1
  532. package/dist/iframe-BDVElN8z.js.map +0 -1
  533. package/dist/iframe-CG-z9qev.cjs.map +0 -1
  534. package/dist/input-B14Nn6xD.cjs.map +0 -1
  535. package/dist/input-Bt_o4sYo.js.map +0 -1
  536. package/dist/lazy-CayEFyC3.cjs +0 -1
  537. package/dist/lazy-CayEFyC3.cjs.map +0 -1
  538. package/dist/lazy-D-bO2r4m.js +0 -13
  539. package/dist/lazy-D-bO2r4m.js.map +0 -1
  540. package/dist/lightbox-B47Zoqv-.cjs.map +0 -1
  541. package/dist/lightbox-ZmuoBBFT.js.map +0 -1
  542. package/dist/mixins-DPdzC9ZH.cjs.map +0 -1
  543. package/dist/mixins-DTzfFVyv.js.map +0 -1
  544. package/dist/notification-Ccktcj9H.js.map +0 -1
  545. package/dist/notification-DSkB-sn0.cjs +0 -24
  546. package/dist/notification-DSkB-sn0.cjs.map +0 -1
  547. package/dist/overlay-BS-ta-zq.cjs +0 -58
  548. package/dist/overlay-BS-ta-zq.cjs.map +0 -1
  549. package/dist/overlay-H3Wt_dgQ.js.map +0 -1
  550. package/dist/overlay.confirm-body-CR9xaqOE.cjs.map +0 -1
  551. package/dist/overlay.confirm-body-Dxn_wNm3.js.map +0 -1
  552. package/dist/overlay.service-DEj3rfRr.cjs +0 -1
  553. package/dist/radio-group-1HCpzRUB.js.map +0 -1
  554. package/dist/radio-group-DbYlyPc-.cjs.map +0 -1
  555. package/dist/select-B-SSmUDe.cjs +0 -56
  556. package/dist/select-B-SSmUDe.cjs.map +0 -1
  557. package/dist/select-CEyhNtZ2.js.map +0 -1
  558. package/dist/sound.service-DO4SmUUT.js.map +0 -1
  559. package/dist/sound.service-G_8GV_6L.cjs.map +0 -1
  560. package/dist/splash-screen-B1mM4_xz.js.map +0 -1
  561. package/dist/splash-screen-cbz4bxjB.cjs.map +0 -1
  562. package/dist/src-czeiuT1m.cjs.map +0 -1
  563. package/dist/src-tncsWsTY.js.map +0 -1
  564. package/dist/textarea-CEUaDURR.cjs +0 -43
  565. package/dist/textarea-CEUaDURR.cjs.map +0 -1
  566. package/dist/textarea-DHIMt-ly.js.map +0 -1
  567. package/dist/theme.service-BfTK1Wtl.js.map +0 -1
  568. package/dist/theme.service-Dg7LO0Qz.cjs +0 -1
  569. package/dist/theme.service-Dg7LO0Qz.cjs.map +0 -1
  570. package/dist/window-B_n4P9az.js.map +0 -1
  571. package/dist/window-Vl1u1-EG.cjs +0 -59
  572. package/dist/window-Vl1u1-EG.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-BDVyrBnk.js","names":["#state$"],"sources":["../src/window/window-manager.ts","../src/window/window-position.ts","../src/window/window.ts"],"sourcesContent":["/**\n * Window Manager — singleton service for multi-window coordination.\n *\n * Tracks all schmancy-window instances: positions, z-indices, focus, visual states.\n * Components register on connectedCallback, unregister on disconnectedCallback.\n * Focus changes, position updates, and overlap queries all flow through here.\n *\n * Follows the ThemeService singleton pattern (theme/theme.service.ts).\n *\n * Example:\n * windowManager.register('chat-1', bounds, 'bottom-right')\n * windowManager.focus('chat-1') // bumps z-index, updates focusedId\n * const overlaps = windowManager.findOverlaps(projectedBounds, 'chat-1')\n */\n\nimport { BehaviorSubject, Observable, distinctUntilChanged, map } from 'rxjs'\nimport { overlayStack } from '../utils/overlay-stack.js'\nimport type { WindowBounds, WindowRecord, WindowRegistryState, SnapTarget } from './window-registry.js'\n\nconst STORAGE_PREFIX = 'schmancy-window-'\nconst LEGACY_STORAGE_PREFIX = 'schmancy-float-'\n\nclass WindowManagerService {\n\tprivate static instance: WindowManagerService\n\n\treadonly #state$ = new BehaviorSubject<WindowRegistryState>({\n\t\twindows: new Map(),\n\t\tfocusedId: null,\n\t\tstackOrder: [],\n\t})\n\n\treadonly state$ = this.#state$.asObservable()\n\n\tprivate constructor() {}\n\n\tstatic getInstance(): WindowManagerService {\n\t\tif (!WindowManagerService.instance) {\n\t\t\tWindowManagerService.instance = new WindowManagerService()\n\t\t}\n\t\treturn WindowManagerService.instance\n\t}\n\n\t// ── Synchronous accessors ──────────────────────────────────────────\n\n\tget windows(): Map<string, WindowRecord> {\n\t\treturn this.#state$.value.windows\n\t}\n\n\tget focusedId(): string | null {\n\t\treturn this.#state$.value.focusedId\n\t}\n\n\t// ── Registration ───────────────────────────────────────────────────\n\n\tregister(id: string, initialBounds: WindowBounds, snapTarget: SnapTarget): void {\n\t\tconst state = this.#state$.value\n\t\tif (state.windows.has(id)) return\n\n\t\tconst zIndex = overlayStack.assignZIndex(id)\n\t\tconst record: WindowRecord = {\n\t\t\tid,\n\t\t\tbounds: initialBounds,\n\t\t\tvisualState: 'normal',\n\t\t\tzIndex,\n\t\t\topen: false,\n\t\t\tsnapTarget,\n\t\t}\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, record)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder })\n\t}\n\n\tunregister(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\n\t\toverlayStack.releaseId(id)\n\t\tconst windows = new Map(state.windows)\n\t\twindows.delete(id)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\t\tconst focusedId = state.focusedId === id ? null : state.focusedId\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId })\n\t}\n\n\t// ── State mutations ────────────────────────────────────────────────\n\n\tupdateBounds(id: string, bounds: WindowBounds): void {\n\t\tthis.updateRecord(id, { bounds })\n\t}\n\n\tupdateVisualState(id: string, visualState: WindowRecord['visualState']): void {\n\t\tthis.updateRecord(id, { visualState })\n\t}\n\n\tupdateOpen(id: string, open: boolean): void {\n\t\tthis.updateRecord(id, { open })\n\t}\n\n\tfocus(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\t\tif (state.focusedId === id) return\n\n\t\tconst zIndex = overlayStack.bringToFront(id)\n\t\tconst windows = new Map(state.windows)\n\t\tconst record = windows.get(id)\n\t\tif (record) {\n\t\t\twindows.set(id, { ...record, zIndex })\n\t\t}\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId: id })\n\t}\n\n\t// ── Queries ────────────────────────────────────────────────────────\n\n\tfindOverlaps(bounds: WindowBounds, excludeId: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [id, record] of this.#state$.value.windows) {\n\t\t\tif (id === excludeId) continue\n\t\t\tif (rectsOverlap(bounds, record.bounds)) {\n\t\t\t\tresult.push(record)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tgetNeighbors(id: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [otherId, record] of this.#state$.value.windows) {\n\t\t\tif (otherId !== id) result.push(record)\n\t\t}\n\t\treturn result\n\t}\n\n\t// ── Selectors ──────────────────────────────────────────────────────\n\n\tselectWindow(id: string): Observable<WindowRecord | undefined> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.windows.get(id)),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\tselectFocused(): Observable<string | null> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.focusedId),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\t// ── Persistence ────────────────────────────────────────────────────\n\n\tloadPosition(id: string): { x: number; y: number; anchor: string } | null {\n\t\ttry {\n\t\t\t// Try new key first, fall back to legacy\n\t\t\tconst raw = localStorage.getItem(STORAGE_PREFIX + id) ?? localStorage.getItem(LEGACY_STORAGE_PREFIX + id)\n\t\t\tif (!raw) return null\n\t\t\treturn JSON.parse(raw) as { x: number; y: number; anchor: string }\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\tsavePosition(id: string, data: { x: number; y: number; anchor: string }): void {\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_PREFIX + id, JSON.stringify(data))\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tclearPosition(id: string): void {\n\t\ttry {\n\t\t\tlocalStorage.removeItem(STORAGE_PREFIX + id)\n\t\t\tlocalStorage.removeItem(LEGACY_STORAGE_PREFIX + id)\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t// ── Internal ───────────────────────────────────────────────────────\n\n\tprivate updateRecord(id: string, updates: Partial<WindowRecord>): void {\n\t\tconst state = this.#state$.value\n\t\tconst record = state.windows.get(id)\n\t\tif (!record) return\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, { ...record, ...updates })\n\t\tthis.#state$.next({ ...state, windows })\n\t}\n}\n\n/** Simple rect overlap check (inline — no circular import with window-position) */\nfunction rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\nexport const windowManager = WindowManagerService.getInstance()\n","/**\n * Window Position — pure functions for overlap resolution, cascade, and snapping.\n *\n * All functions are stateless: they take window bounds and viewport dimensions,\n * return new bounds. No side effects, no DOM access, no subscriptions.\n *\n * Example:\n * const projected = { left: 100, top: 400, width: 360, height: 500 }\n * const neighbors = windowManager.findOverlaps(projected, 'my-id')\n * const resolved = resolveOverlap(projected, neighbors, { width: 1440, height: 900 })\n * // → { left: 144, top: 444, width: 360, height: 500 } (cascaded away from conflict)\n */\n\nimport type { WindowBounds, WindowRecord } from './window-registry.js'\n\nconst HEAD_HEIGHT = 44\nconst CASCADE_OFFSET = HEAD_HEIGHT\nconst MAX_CASCADE_ATTEMPTS = 10\n\n/** Check if two rectangles overlap (edges touching does NOT count as overlap) */\nexport function rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\n/**\n * Resolve overlap by cascading diagonally until no conflict.\n * Shifts by (HEAD_HEIGHT, HEAD_HEIGHT) per attempt, clamped to viewport.\n */\nexport function resolveOverlap(\n\tcandidate: WindowBounds,\n\texisting: WindowRecord[],\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\tconst bounds = { ...candidate }\n\n\tfor (let attempt = 0; attempt < MAX_CASCADE_ATTEMPTS; attempt++) {\n\t\tconst hasOverlap = existing.some(w => rectsOverlap(bounds, w.bounds))\n\t\tif (!hasOverlap) break\n\n\t\tbounds.left += CASCADE_OFFSET\n\t\tbounds.top += CASCADE_OFFSET\n\t}\n\n\treturn clampToViewport(bounds, viewport)\n}\n\n/**\n * Clamp bounds so the window stays fully within the viewport.\n */\nexport function clampToViewport(\n\tbounds: WindowBounds,\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\treturn {\n\t\twidth: bounds.width,\n\t\theight: bounds.height,\n\t\tleft: Math.max(0, Math.min(bounds.left, viewport.width - bounds.width)),\n\t\ttop: Math.max(0, Math.min(bounds.top, viewport.height - bounds.height)),\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport {\n\tanimationFrameScheduler,\n\tauditTime,\n\tcatchError,\n\tEMPTY,\n\tfilter,\n\tfinalize,\n\tfrom,\n\tfromEvent,\n\tmap,\n\tmerge,\n\tObservable,\n\tswitchMap,\n\ttake,\n\ttakeUntil,\n\ttap,\n} from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\nimport type { SnapCorner, WindowBounds, WindowVisualState } from './window-registry.js'\nimport { windowManager } from './window-manager.js'\nimport { resolveOverlap } from './window-position.js'\n\nconst HEAD_HEIGHT = 48\nconst DRAG_THRESHOLD = 5\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-window')\nexport default class SchmancyWindow extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** Override the expanded panel height (e.g. '400px', '50vh'). */\n\t@property({ type: String }) expandedHeight?: string\n\t/** When true, uses a lower elevation shadow in the collapsed state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the window is anchored to. */\n\t@property({ type: String }) corner: SnapCorner = 'bottom-right'\n\t/** When true, window can be resized by the user. */\n\t@property({ type: Boolean }) resizable = false\n\t/** When true, window stays at its dragged position instead of snapping to a corner. */\n\t@property({ type: Boolean }) freePosition = false\n\t/** Visual state of the window (minimized, normal, maximized). */\n\t@property({ type: String, reflect: true }) visualState: WindowVisualState = 'normal'\n\t/** Minimum width in pixels. */\n\t@property({ type: Number }) minWidth = 280\n\t/** Minimum height in pixels. */\n\t@property({ type: Number }) minHeight = 200\n\n\t/** Whether the body is expanded. */\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\tprivate currentAnimation?: Animation\n\n\t/** Lazy rendering: body content not in DOM until first expand. */\n\t@state() private hasOpened = false\n\n\t// Internal position -- plain fields, updated directly during drag\n\tprivate position: Position = { x: 16, y: 16 }\n\t@state() private currentCorner: SnapCorner = 'bottom-right'\n\n\t// Track applied corner to avoid unnecessary style.removeProperty calls during drag\n\tprivate appliedCorner: string = ''\n\n\t// Refs\n\tprivate containerRef = createRef<HTMLElement>()\n\tprivate bodyRef = createRef<HTMLElement>()\n\tprivate headRef = createRef<HTMLElement>()\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this.currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${HEAD_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${HEAD_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate applyContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\t// Only clear position properties when corner changes (avoids 4 style invalidations per drag frame)\n\t\tif (this.appliedCorner !== this.currentCorner) {\n\t\t\tcontainer.style.removeProperty('left')\n\t\t\tcontainer.style.removeProperty('right')\n\t\t\tcontainer.style.removeProperty('top')\n\t\t\tcontainer.style.removeProperty('bottom')\n\t\t\tthis.appliedCorner = this.currentCorner\n\t\t}\n\t\tconst { x, y } = this.position\n\t\tif (this.currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this.currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate static readonly VALID_CORNERS = new Set<string>(['top-left', 'top-right', 'bottom-left', 'bottom-right'])\n\n\tprivate loadPosition() {\n\t\tconst saved = windowManager.loadPosition(this.id)\n\t\tif (saved) {\n\t\t\tthis.position = { x: saved.x, y: saved.y }\n\t\t\tif (SchmancyWindow.VALID_CORNERS.has(saved.anchor)) {\n\t\t\t\tthis.currentCorner = saved.anchor as SnapCorner\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate savePosition() {\n\t\twindowManager.savePosition(this.id, { ...this.position, anchor: this.currentCorner })\n\t}\n\n\tprivate validateBounds() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this.currentCorner.includes('right')\n\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this.position.x - rect.width : this.position.x\n\t\tconst actualTop = isBottom ? vh - this.position.y - rect.height : this.position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis.position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis.applyContainerPosition()\n\t}\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate reorientToNearestCorner(skipAnimation = false): void {\n\t\t// Free position mode: skip corner snapping\n\t\tif (this.freePosition) {\n\t\t\tthis.savePosition()\n\t\t\tconst rect = this.containerRef.value?.getBoundingClientRect()\n\t\t\tif (rect) {\n\t\t\t\twindowManager.updateBounds(this.id, { left: rect.left, top: rect.top, width: rect.width, height: rect.height })\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// F -- record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L -- calculate nearest corner using head visual center\n\t\tconst currentIsBottom = this.currentCorner.includes('bottom')\n\t\tconst headCenterX = rect.left + rect.width / 2\n\t\tconst headCenterY = currentIsBottom\n\t\t\t? rect.bottom - HEAD_HEIGHT / 2\n\t\t\t: rect.top + HEAD_HEIGHT / 2\n\t\tconst side = headCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = headCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: SnapCorner = `${vert}-${side}` as SnapCorner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis.currentCorner = newCorner\n\t\tthis.position = { x: 16, y: 16 }\n\t\tthis.applyContainerPosition()\n\t\t// Sync clip-path to new corner\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis.savePosition()\n\t\t\tconst snapRect = container.getBoundingClientRect()\n\t\t\twindowManager.updateBounds(this.id, { left: snapRect.left, top: snapRect.top, width: snapRect.width, height: snapRect.height })\n\t\t\treturn\n\t\t}\n\n\t\t// I -- invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.translate = `${dx}px ${dy}px`\n\n\t\t// P -- play: animate from the inverse offset to natural resting position\n\t\tconst flipKeyframes: Keyframe[] = [{ translate: `${dx}px ${dy}px` }, { translate: '0px 0px' }]\n\t\tconst anim = container.animate(\n\t\t\tflipKeyframes,\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) container.style.translate = ''\n\t\t\t\t// Report final resting bounds after animation completes\n\t\t\t\tconst finalRect = container.getBoundingClientRect()\n\t\t\t\twindowManager.updateBounds(this.id, { left: finalRect.left, top: finalRect.top, width: finalRect.width, height: finalRect.height })\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate drag$(): Observable<never> {\n\t\treturn new Observable(() => {\n\t\t\tconst head = this.headRef.value\n\t\t\tconst container = this.containerRef.value\n\t\t\tif (!head || !container) return\n\n\t\t\tlet didDrag = false\n\n\t\t\tconst sub = fromEvent<PointerEvent>(head, 'pointerdown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\tfilter(e => {\n\t\t\t\t\tconst tag = (e.target as HTMLElement).tagName?.toLowerCase()\n\t\t\t\t\treturn !['input', 'textarea', 'select', 'button'].includes(tag)\n\t\t\t\t\t\t&& !(e.target as HTMLElement).closest('schmancy-input, schmancy-icon-button, button, a')\n\t\t\t\t}),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t)\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(e => {\n\t\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\t\trect,\n\t\t\t\t\t\t\tvw: window.innerWidth,\n\t\t\t\t\t\t\tvh: window.innerHeight,\n\t\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\t\twasOpen,\n\t\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, rect, vw, vh, isBottom, wasOpen, pointerId }) => {\n\t\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\t\t\t\tmap(e => ({ clientX: e.clientX, clientY: e.clientY })),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst end$ = fromEvent<PointerEvent>(window, 'pointerup').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(true)\n\t\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move\n\t\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\t\t\t\t\t\t\tif (body) {\n\t\t\t\t\t\t\t\t\t\t\tbody.inert = true\n\t\t\t\t\t\t\t\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t\tconst minTop = isBottom ? HEAD_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - HEAD_HEIGHT\n\t\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\t\tthis.position = {\n\t\t\t\t\t\t\t\t\tx: this.currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.applyContainerPosition()\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\t\tthis.reorientToNearestCorner()\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(false)\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe()\n\n\t\t\treturn () => sub.unsubscribe()\n\t\t})\n\t}\n\n\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Pipeline 1: DOM setup + manager registration + drag + z-index sync\n\t\tfrom(this.updateComplete).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.currentCorner = this.corner\n\t\t\t\tthis.loadPosition()\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t\tthis.initDOMState()\n\t\t\t\t// Register with window manager\n\t\t\t\tconst container = this.containerRef.value\n\t\t\t\tif (container) {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst bounds: WindowBounds = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n\t\t\t\t\twindowManager.register(this.id, bounds, this.freePosition ? 'free' : this.currentCorner)\n\t\t\t\t}\n\t\t\t}),\n\t\t\tswitchMap(() => merge(\n\t\t\t\tthis.drag$(),\n\t\t\t\twindowManager.selectWindow(this.id).pipe(\n\t\t\t\t\ttap(record => {\n\t\t\t\t\t\tif (!record) return\n\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\tif (container) container.style.zIndex = String(record.zIndex)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\n\t\t// Pipeline 3: Environment -- one subscription\n\t\tmerge(\n\t\t\tfromEvent(window, 'resize').pipe(\n\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\ttap(() => this.validateBounds()),\n\t\t\t),\n\t\t\ttheme.bottomOffset$.pipe(\n\t\t\t\ttap(() => this.applyContainerPosition()),\n\t\t\t),\n\t\t).pipe(takeUntil(this.disconnecting)).subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\twindowManager.unregister(this.id)\n\t}\n\n\tprivate initDOMState() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.applyContainerPosition()\n\n\t\tif (this.open) {\n\t\t\tthis.hasOpened = true\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (body) {\n\t\t\t\tbody.inert = false\n\t\t\t\tbody.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (body) {\n\t\t\t\tbody.inert = true\n\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate animateOpen() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.hasOpened = true\n\t\tthis.open = true\n\n\t\t// Overlap avoidance\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst projectedBounds: WindowBounds = {\n\t\t\tleft: rect.left,\n\t\t\ttop: this.isBottomCorner ? rect.top - 400 : rect.top,\n\t\t\twidth: rect.width,\n\t\t\theight: 400 + HEAD_HEIGHT,\n\t\t}\n\t\tconst overlaps = windowManager.findOverlaps(projectedBounds, this.id)\n\t\tif (overlaps.length > 0) {\n\t\t\tconst resolved = resolveOverlap(projectedBounds, overlaps, { width: window.innerWidth, height: window.innerHeight })\n\t\t\tif (Math.abs(resolved.left - projectedBounds.left) > 10 || Math.abs(resolved.top - projectedBounds.top) > 10) {\n\t\t\t\tconst isRight = this.currentCorner.includes('right')\n\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\tthis.position = {\n\t\t\t\t\tx: isRight ? window.innerWidth - resolved.left - resolved.width : resolved.left,\n\t\t\t\t\ty: isBottom ? window.innerHeight - resolved.top - resolved.height : resolved.top,\n\t\t\t\t}\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t}\n\t\t}\n\n\t\tif (body) {\n\t\t\tbody.style.visibility = 'visible'\n\t\t\tbody.inert = false\n\t\t}\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) {\n\t\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\t\tcontainer.style.overflow = ''\n\t\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\t}\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t}\n\n\tprivate animateClose() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst body = this.bodyRef.value\n\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.7),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.open = false\n\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t}\n\n\t// ============================================\n\t// VISUAL STATE HELPERS\n\t// ============================================\n\n\t/** Apply drag visuals directly on DOM refs — avoids full Lit re-render for cursor + opacity */\n\tprivate applyDragVisuals(dragging: boolean) {\n\t\tconst head = this.headRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (head) {\n\t\t\thead.classList.toggle('cursor-grabbing', dragging)\n\t\t\thead.classList.toggle('cursor-move', !dragging)\n\t\t}\n\t\tif (container) {\n\t\t\tcontainer.style.opacity = dragging ? '0.95' : ''\n\t\t}\n\t}\n\n\tprivate handleFocus = () => windowManager.focus(this.id)\n\n\tprivate handleHeadKeydown = (e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\te.preventDefault()\n\t\t\tthis.toggle()\n\t\t\treturn\n\t\t}\n\t\tif (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n\t\t\te.preventDefault()\n\t\t\tconst step = e.shiftKey ? 20 : 5\n\t\t\tconst dx = e.key === 'ArrowRight' ? step : e.key === 'ArrowLeft' ? -step : 0\n\t\t\tconst dy = e.key === 'ArrowDown' ? step : e.key === 'ArrowUp' ? -step : 0\n\t\t\tthis.position = { x: this.position.x + dx, y: this.position.y + dy }\n\t\t\tthis.applyContainerPosition()\n\t\t\tthis.savePosition()\n\t\t}\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this.animateClose()\n\t\telse this.animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.animateOpen()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tthis.animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this.currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tfixed: true,\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst bodyStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'cursor-move': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t\t@pointerdown=${this.handleFocus}\n\t\t\t>\n\t\t\t\t<!-- Details section (visually above summary for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this.bodyRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${bodyStyles}\n\t\t\t\t\trole=\"region\"\n\t\t\t\t\taria-label=\"Expandable content\"\n\t\t\t\t>\n\t\t\t\t\t${this.hasOpened ? html`<slot name=\"details\"></slot>` : nothing}\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Summary section -- always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-lowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${HEAD_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this.headRef)}\n\t\t\t\t\t\t${cursorGlow({ radius: 200, intensity: 0.10 })}\n\t\t\t\t\t\tclass=${headClasses}\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\ttitle=\"Drag to move, click to expand\"\n\t\t\t\t\t\taria-label=\"${this.open ? 'Collapse window' : 'Expand window'}\"\n\t\t\t\t\t\t@keydown=${this.handleHeadKeydown}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\twidth=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n\t\t\t\t\t\t\tclass=\"shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open ? 'rotate-180' : ''}\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-window': SchmancyWindow\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./SchmancyElement-C41uPa6l.cjs`);require(`./mixins-fIpzhVMd.cjs`);const t=require(`./animation-CCOIW4wJ.cjs`),n=require(`./reduced-motion-Ds-HjMzn.cjs`),r=require(`./cursor-glow-Bulq-38P.cjs`),i=require(`./theme.service-B15FdjOS.cjs`),a=require(`./overlay-stack-Bdr9lOqi.cjs`);let o=require(`rxjs`),s=require(`lit/directives/class-map.js`),c=require(`lit/directives/style-map.js`),l=require(`lit/decorators.js`),u=require(`lit`),d=require(`lit/directives/ref.js`);var f=`schmancy-window-`,p=`schmancy-float-`;function m(e,t){return!(e.left>=t.left+t.width||e.left+e.width<=t.left||e.top>=t.top+t.height||e.top+e.height<=t.top)}var h,g=class e{#e;constructor(){this.#e=new o.BehaviorSubject({windows:new Map,focusedId:null,stackOrder:[]}),this.state$=this.#e.asObservable()}static getInstance(){return e.instance||=new e,e.instance}get windows(){return this.#e.value.windows}get focusedId(){return this.#e.value.focusedId}register(e,t,n){let r=this.#e.value;if(r.windows.has(e))return;let i={id:e,bounds:t,visualState:`normal`,zIndex:a.t.assignZIndex(e),open:!1,snapTarget:n},o=new Map(r.windows);o.set(e,i);let s=a.t.getStackOrder();this.#e.next({...r,windows:o,stackOrder:s})}unregister(e){let t=this.#e.value;if(!t.windows.has(e))return;a.t.releaseId(e);let n=new Map(t.windows);n.delete(e);let r=a.t.getStackOrder(),i=t.focusedId===e?null:t.focusedId;this.#e.next({...t,windows:n,stackOrder:r,focusedId:i})}updateBounds(e,t){this.updateRecord(e,{bounds:t})}updateVisualState(e,t){this.updateRecord(e,{visualState:t})}updateOpen(e,t){this.updateRecord(e,{open:t})}focus(e){let t=this.#e.value;if(!t.windows.has(e)||t.focusedId===e)return;let n=a.t.bringToFront(e),r=new Map(t.windows),i=r.get(e);i&&r.set(e,{...i,zIndex:n});let o=a.t.getStackOrder();this.#e.next({...t,windows:r,stackOrder:o,focusedId:e})}findOverlaps(e,t){let n=[];for(let[r,i]of this.#e.value.windows)r!==t&&m(e,i.bounds)&&n.push(i);return n}getNeighbors(e){let t=[];for(let[n,r]of this.#e.value.windows)n!==e&&t.push(r);return t}selectWindow(e){return this.#e.pipe((0,o.map)(t=>t.windows.get(e)),(0,o.distinctUntilChanged)())}selectFocused(){return this.#e.pipe((0,o.map)(e=>e.focusedId),(0,o.distinctUntilChanged)())}loadPosition(e){try{let t=localStorage.getItem(f+e)??localStorage.getItem(p+e);return t?JSON.parse(t):null}catch{return null}}savePosition(e,t){try{localStorage.setItem(f+e,JSON.stringify(t))}catch{}}clearPosition(e){try{localStorage.removeItem(f+e),localStorage.removeItem(p+e)}catch{}}updateRecord(e,t){let n=this.#e.value,r=n.windows.get(e);if(!r)return;let i=new Map(n.windows);i.set(e,{...r,...t}),this.#e.next({...n,windows:i})}}.getInstance();function _(e,t,n){let r={...e};for(let e=0;e<10&&t.some(e=>{return t=r,n=e.bounds,!(t.left>=n.left+n.width||t.left+t.width<=n.left||t.top>=n.top+n.height||t.top+t.height<=n.top);var t,n});e++)r.left+=44,r.top+=44;return function(e,t){return{width:e.width,height:e.height,left:Math.max(0,Math.min(e.left,t.width-e.width)),top:Math.max(0,Math.min(e.top,t.height-e.height))}}(r,n)}var v=48,y=class extends e.t{static{h=this}constructor(...e){super(...e),this.id=`default`,this.lowered=!1,this.corner=`bottom-right`,this.resizable=!1,this.freePosition=!1,this.visualState=`normal`,this.minWidth=280,this.minHeight=200,this.open=!1,this.hasOpened=!1,this.position={x:16,y:16},this.currentCorner=`bottom-right`,this.appliedCorner=``,this.containerRef=(0,d.createRef)(),this.bodyRef=(0,d.createRef)(),this.headRef=(0,d.createRef)(),this.handleFocus=()=>g.focus(this.id),this.handleHeadKeydown=e=>{if(e.key===`Enter`||e.key===` `)return e.preventDefault(),void this.toggle();if(e.key===`ArrowUp`||e.key===`ArrowDown`||e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let t=e.shiftKey?20:5,n=e.key===`ArrowRight`?t:e.key===`ArrowLeft`?-t:0,r=e.key===`ArrowDown`?t:e.key===`ArrowUp`?-t:0;this.position={x:this.position.x+n,y:this.position.y+r},this.applyContainerPosition(),this.savePosition()}}}static{this.styles=[u.css`
2
+ :host {
3
+ display: contents;
4
+ position: relative;
5
+ z-index: 1000;
6
+ }
7
+ :host([hidden]) {
8
+ display: none !important;
9
+ }
10
+ `]}get panelWidth(){return this.expandedWidth??`min(360px, calc(100vw - 32px))`}get isBottomCorner(){return this.currentCorner.startsWith(`bottom`)}get closedClipPath(){return this.isBottomCorner?`inset(calc(100% - 48px) 0px 0px 0px round 22px)`:`inset(0px 0px calc(100% - 48px) 0px round 22px)`}get openClipPath(){return`inset(0px 0px 0px 0px round 12px)`}get elevation(){return this.open?4:this.lowered?1:3}applyContainerPosition(){let e=this.containerRef.value;if(!e)return;this.appliedCorner!==this.currentCorner&&(e.style.removeProperty(`left`),e.style.removeProperty(`right`),e.style.removeProperty(`top`),e.style.removeProperty(`bottom`),this.appliedCorner=this.currentCorner);let{x:t,y:n}=this.position;this.currentCorner.includes(`right`)?e.style.right=`${t}px`:e.style.left=`${t}px`,this.currentCorner.includes(`bottom`)?e.style.bottom=`${n+i.n.bottomOffset}px`:e.style.top=`${n}px`}static{this.VALID_CORNERS=new Set([`top-left`,`top-right`,`bottom-left`,`bottom-right`])}loadPosition(){let e=g.loadPosition(this.id);e&&(this.position={x:e.x,y:e.y},h.VALID_CORNERS.has(e.anchor)&&(this.currentCorner=e.anchor))}savePosition(){g.savePosition(this.id,{...this.position,anchor:this.currentCorner})}validateBounds(){let e=this.containerRef.value;if(!e)return;let t=e.getBoundingClientRect();if(t.width===0)return;let n=window.innerWidth,r=window.innerHeight,i=this.currentCorner.includes(`right`),a=this.currentCorner.includes(`bottom`),o=i?n-this.position.x-t.width:this.position.x,s=a?r-this.position.y-t.height:this.position.y,c=Math.max(0,Math.min(o,n-t.width)),l=Math.max(0,Math.min(s,r-t.height));this.position={x:i?n-c-t.width:c,y:a?r-l-t.height:l},this.applyContainerPosition()}reorientToNearestCorner(e=!1){if(this.freePosition){this.savePosition();let e=this.containerRef.value?.getBoundingClientRect();e&&g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height});return}let r=this.containerRef.value;if(!r)return;let i=r.getBoundingClientRect(),a=this.currentCorner.includes(`bottom`),s=i.left+i.width/2,c=a?i.bottom-24:i.top+24,l=s>window.innerWidth/2?`right`:`left`,u=`${c>window.innerHeight/2?`bottom`:`top`}-${l}`;if(this.currentCorner=u,this.position={x:16,y:16},this.applyContainerPosition(),this.open||(r.style.clipPath=this.closedClipPath),e||n.t.value){this.savePosition();let e=r.getBoundingClientRect();g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height});return}let d=r.getBoundingClientRect(),f=i.left-d.left,p=i.top-d.top;r.style.translate=`${f}px ${p}px`;let m=[{translate:`${f}px ${p}px`},{translate:`0px 0px`}];(0,o.from)(r.animate(m,{duration:t.d.duration,easing:t.d.easingFallback,fill:`forwards`}).finished).pipe((0,o.take)(1),(0,o.tap)(()=>{r.isConnected&&(r.style.translate=``);let e=r.getBoundingClientRect();g.updateBounds(this.id,{left:e.left,top:e.top,width:e.width,height:e.height})}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.savePosition()}drag$(){return new o.Observable(()=>{let e=this.headRef.value,t=this.containerRef.value;if(!e||!t)return;let n=!1,r=(0,o.fromEvent)(e,`pointerdown`).pipe((0,o.filter)(e=>e.button===0),(0,o.filter)(e=>{let t=e.target.tagName?.toLowerCase();return![`input`,`textarea`,`select`,`button`].includes(t)&&!e.target.closest(`schmancy-input, schmancy-icon-button, button, a`)}),(0,o.tap)(e=>{e.preventDefault(),e.stopPropagation()})).pipe((0,o.map)(e=>{let r=t.getBoundingClientRect(),i=this.currentCorner.includes(`bottom`),a=this.open;return n=!1,{startX:e.clientX,startY:e.clientY,offsetX:e.clientX-r.left,offsetY:e.clientY-r.top,rect:r,vw:window.innerWidth,vh:window.innerHeight,isBottom:i,wasOpen:a,pointerId:e.pointerId}}),(0,o.switchMap)(({startX:e,startY:r,offsetX:i,offsetY:a,rect:s,vw:c,vh:l,isBottom:u,wasOpen:d,pointerId:f})=>{let p=(0,o.fromEvent)(window,`pointermove`).pipe((0,o.filter)(e=>e.pointerId===f),(0,o.auditTime)(0,o.animationFrameScheduler),(0,o.map)(e=>({clientX:e.clientX,clientY:e.clientY}))),m=(0,o.fromEvent)(window,`pointerup`).pipe((0,o.filter)(e=>e.pointerId===f));return p.pipe((0,o.tap)(({clientX:o,clientY:f})=>{let p=o-e,m=f-r;if(Math.sqrt(p*p+m*m)>5&&!n&&(n=!0,this.applyDragVisuals(!0),d)){this.open=!1,t.style.clipPath=this.closedClipPath,t.style.overflow=`hidden`;let e=this.bodyRef.value;e&&(e.inert=!0,e.style.visibility=`hidden`)}if(!n)return;let h=Math.max(0,Math.min(o-i,c-s.width)),g=u?v-s.height:0,_=u?l-s.height:l-v,y=Math.max(g,Math.min(f-a,_));this.position={x:this.currentCorner.includes(`right`)?c-h-s.width:h,y:u?l-y-s.height:y},this.applyContainerPosition()}),(0,o.takeUntil)(m),(0,o.finalize)(()=>{n?(this.reorientToNearestCorner(),this.applyDragVisuals(!1),n=!1):(n=!1,this.toggle())}))})).subscribe();return()=>r.unsubscribe()})}connectedCallback(){super.connectedCallback(),(0,o.from)(this.updateComplete).pipe((0,o.take)(1),(0,o.tap)(()=>{this.currentCorner=this.corner,this.loadPosition(),this.applyContainerPosition(),this.initDOMState();let e=this.containerRef.value;if(e){let t=e.getBoundingClientRect(),n={left:t.left,top:t.top,width:t.width,height:t.height};g.register(this.id,n,this.freePosition?`free`:this.currentCorner)}}),(0,o.switchMap)(()=>(0,o.merge)(this.drag$(),g.selectWindow(this.id).pipe((0,o.tap)(e=>{if(!e)return;let t=this.containerRef.value;t&&(t.style.zIndex=String(e.zIndex))})))),(0,o.takeUntil)(this.disconnecting)).subscribe(),(0,o.merge)((0,o.fromEvent)(window,`resize`).pipe((0,o.auditTime)(0,o.animationFrameScheduler),(0,o.tap)(()=>this.validateBounds())),i.n.bottomOffset$.pipe((0,o.tap)(()=>this.applyContainerPosition()))).pipe((0,o.takeUntil)(this.disconnecting)).subscribe()}disconnectedCallback(){super.disconnectedCallback(),g.unregister(this.id)}initDOMState(){let e=this.containerRef.value,t=this.bodyRef.value;e&&(this.applyContainerPosition(),this.open?(this.hasOpened=!0,e.style.overflow=``,t&&(t.inert=!1,t.style.visibility=`visible`)):(e.style.clipPath=this.closedClipPath,e.style.overflow=`hidden`,t&&(t.inert=!0,t.style.visibility=`hidden`)))}animateOpen(){let e=this.containerRef.value,r=this.bodyRef.value;if(!e)return;this.hasOpened=!0,this.open=!0;let i=e.getBoundingClientRect(),a={left:i.left,top:this.isBottomCorner?i.top-400:i.top,width:i.width,height:448},s=g.findOverlaps(a,this.id);if(s.length>0){let e=_(a,s,{width:window.innerWidth,height:window.innerHeight});if(Math.abs(e.left-a.left)>10||Math.abs(e.top-a.top)>10){let t=this.currentCorner.includes(`right`),n=this.currentCorner.includes(`bottom`);this.position={x:t?window.innerWidth-e.left-e.width:e.left,y:n?window.innerHeight-e.top-e.height:e.top},this.applyContainerPosition()}}if(r&&(r.style.visibility=`visible`,r.inert=!1),n.t.value)return e.style.clipPath=``,e.style.overflow=``,void this.dispatchScopedEvent(`window-toggle`,{state:`expanded`});this.currentAnimation?.cancel(),e.style.overflow=`hidden`,e.style.willChange=`opacity`;let c=[{clipPath:this.closedClipPath,opacity:.95},{clipPath:this.openClipPath,opacity:1}],l=e.animate(c,{duration:t.f.duration,easing:t.f.easingFallback,fill:`forwards`});this.currentAnimation=l,(0,o.from)(l.finished).pipe((0,o.take)(1),(0,o.tap)(()=>{e.isConnected&&(e.style.clipPath=``,e.style.overflow=``,e.style.willChange=``)}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.dispatchScopedEvent(`window-toggle`,{state:`expanded`})}animateClose(){let e=this.containerRef.value;if(!e)return;if(n.t.value){e.style.clipPath=this.closedClipPath,e.style.overflow=`hidden`,this.open=!1;let t=this.bodyRef.value;t&&(t.inert=!0,t.style.visibility=`hidden`),this.dispatchScopedEvent(`window-toggle`,{state:`collapsed`});return}this.currentAnimation?.cancel(),e.style.overflow=`hidden`,e.style.willChange=`opacity`;let r=[{clipPath:this.openClipPath,opacity:1},{clipPath:this.closedClipPath,opacity:.95}],i=e.animate(r,{duration:Math.round(.7*t.f.duration),easing:`cubic-bezier(0.4, 0, 0.8, 0.15)`,fill:`forwards`});this.currentAnimation=i,(0,o.from)(i.finished).pipe((0,o.take)(1),(0,o.tap)(()=>{this.open=!1,e.style.willChange=``;let t=this.bodyRef.value;t&&(t.inert=!0,t.style.visibility=`hidden`)}),(0,o.catchError)(()=>o.EMPTY),(0,o.takeUntil)(this.disconnecting)).subscribe(),this.dispatchScopedEvent(`window-toggle`,{state:`collapsed`})}applyDragVisuals(e){let t=this.headRef.value,n=this.containerRef.value;t&&(t.classList.toggle(`cursor-grabbing`,e),t.classList.toggle(`cursor-move`,!e)),n&&(n.style.opacity=e?`0.95`:``)}toggle(){this.open?this.animateClose():this.animateOpen()}expand(){this.open||this.animateOpen()}close(){this.open&&this.animateClose()}render(){let e=this.currentCorner.startsWith(`bottom`),t=(0,s.classMap)({fixed:!0,flex:!0,"flex-col":e,"flex-col-reverse":!e,"z-1000":!0,"rounded-2xl":this.open,"rounded-[22px]":!this.open,"overflow-hidden":!0}),n=(0,c.styleMap)({width:this.panelWidth,"max-height":`calc(100vh - 32px)`,"pointer-events":`none`}),i=(0,c.styleMap)({"pointer-events":this.open?`auto`:`none`}),a=(0,s.classMap)({"h-full":!0,"px-3":!0,flex:!0,"items-center":!0,"gap-2":!0,"select-none":!0,"cursor-move":!0});return u.html`
11
+ <schmancy-surface
12
+ ${(0,d.ref)(this.containerRef)}
13
+ type="glass"
14
+ .elevation=${this.elevation}
15
+ class=${t}
16
+ style=${n}
17
+ aria-expanded=${this.open}
18
+ @pointerdown=${this.handleFocus}
19
+ >
20
+ <!-- Details section (visually above summary for bottom corners) -->
21
+ <section
22
+ ${(0,d.ref)(this.bodyRef)}
23
+ class="flex-1 min-h-0 overflow-hidden flex flex-col"
24
+ style=${i}
25
+ role="region"
26
+ aria-label="Expandable content"
27
+ >
28
+ ${this.hasOpened?u.html`<slot name="details"></slot>`:u.nothing}
29
+ </section>
30
+
31
+ <!-- Summary section -- always interactive, always visible -->
32
+ <section
33
+ class="shrink-0 bg-surface-lowest"
34
+ style=${(0,c.styleMap)({"pointer-events":`auto`,height:`48px`})}
35
+ >
36
+ <div
37
+ ${(0,d.ref)(this.headRef)}
38
+ ${r.t({radius:200,intensity:.1})}
39
+ class=${a}
40
+ role="button"
41
+ tabindex="0"
42
+ title="Drag to move, click to expand"
43
+ aria-label="${this.open?`Collapse window`:`Expand window`}"
44
+ @keydown=${this.handleHeadKeydown}
45
+ >
46
+ <div class="flex-1 min-w-0">
47
+ <slot></slot>
48
+ </div>
49
+ <svg
50
+ width="16" height="16" viewBox="0 0 24 24" fill="none"
51
+ class="shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open?`rotate-180`:``}"
52
+ aria-hidden="true"
53
+ >
54
+ <path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
55
+ </svg>
56
+ </div>
57
+ </section>
58
+ </schmancy-surface>
59
+ `}};e.u([(0,l.property)({type:String})],y.prototype,`id`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`expandedWidth`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`expandedHeight`,void 0),e.u([(0,l.property)({type:Boolean,reflect:!0})],y.prototype,`lowered`,void 0),e.u([(0,l.property)({type:String})],y.prototype,`corner`,void 0),e.u([(0,l.property)({type:Boolean})],y.prototype,`resizable`,void 0),e.u([(0,l.property)({type:Boolean})],y.prototype,`freePosition`,void 0),e.u([(0,l.property)({type:String,reflect:!0})],y.prototype,`visualState`,void 0),e.u([(0,l.property)({type:Number})],y.prototype,`minWidth`,void 0),e.u([(0,l.property)({type:Number})],y.prototype,`minHeight`,void 0),e.u([(0,l.property)({type:Boolean,reflect:!0})],y.prototype,`open`,void 0),e.u([(0,l.state)()],y.prototype,`hasOpened`,void 0),e.u([(0,l.state)()],y.prototype,`currentCorner`,void 0);var b=y=h=e.u([(0,l.customElement)(`schmancy-window`)],y);Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return b}});
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window-BbBYjm7R.cjs","names":["#state$"],"sources":["../src/window/window-manager.ts","../src/window/window-position.ts","../src/window/window.ts"],"sourcesContent":["/**\n * Window Manager — singleton service for multi-window coordination.\n *\n * Tracks all schmancy-window instances: positions, z-indices, focus, visual states.\n * Components register on connectedCallback, unregister on disconnectedCallback.\n * Focus changes, position updates, and overlap queries all flow through here.\n *\n * Follows the ThemeService singleton pattern (theme/theme.service.ts).\n *\n * Example:\n * windowManager.register('chat-1', bounds, 'bottom-right')\n * windowManager.focus('chat-1') // bumps z-index, updates focusedId\n * const overlaps = windowManager.findOverlaps(projectedBounds, 'chat-1')\n */\n\nimport { BehaviorSubject, Observable, distinctUntilChanged, map } from 'rxjs'\nimport { overlayStack } from '../utils/overlay-stack.js'\nimport type { WindowBounds, WindowRecord, WindowRegistryState, SnapTarget } from './window-registry.js'\n\nconst STORAGE_PREFIX = 'schmancy-window-'\nconst LEGACY_STORAGE_PREFIX = 'schmancy-float-'\n\nclass WindowManagerService {\n\tprivate static instance: WindowManagerService\n\n\treadonly #state$ = new BehaviorSubject<WindowRegistryState>({\n\t\twindows: new Map(),\n\t\tfocusedId: null,\n\t\tstackOrder: [],\n\t})\n\n\treadonly state$ = this.#state$.asObservable()\n\n\tprivate constructor() {}\n\n\tstatic getInstance(): WindowManagerService {\n\t\tif (!WindowManagerService.instance) {\n\t\t\tWindowManagerService.instance = new WindowManagerService()\n\t\t}\n\t\treturn WindowManagerService.instance\n\t}\n\n\t// ── Synchronous accessors ──────────────────────────────────────────\n\n\tget windows(): Map<string, WindowRecord> {\n\t\treturn this.#state$.value.windows\n\t}\n\n\tget focusedId(): string | null {\n\t\treturn this.#state$.value.focusedId\n\t}\n\n\t// ── Registration ───────────────────────────────────────────────────\n\n\tregister(id: string, initialBounds: WindowBounds, snapTarget: SnapTarget): void {\n\t\tconst state = this.#state$.value\n\t\tif (state.windows.has(id)) return\n\n\t\tconst zIndex = overlayStack.assignZIndex(id)\n\t\tconst record: WindowRecord = {\n\t\t\tid,\n\t\t\tbounds: initialBounds,\n\t\t\tvisualState: 'normal',\n\t\t\tzIndex,\n\t\t\topen: false,\n\t\t\tsnapTarget,\n\t\t}\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, record)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder })\n\t}\n\n\tunregister(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\n\t\toverlayStack.releaseId(id)\n\t\tconst windows = new Map(state.windows)\n\t\twindows.delete(id)\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\t\tconst focusedId = state.focusedId === id ? null : state.focusedId\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId })\n\t}\n\n\t// ── State mutations ────────────────────────────────────────────────\n\n\tupdateBounds(id: string, bounds: WindowBounds): void {\n\t\tthis.updateRecord(id, { bounds })\n\t}\n\n\tupdateVisualState(id: string, visualState: WindowRecord['visualState']): void {\n\t\tthis.updateRecord(id, { visualState })\n\t}\n\n\tupdateOpen(id: string, open: boolean): void {\n\t\tthis.updateRecord(id, { open })\n\t}\n\n\tfocus(id: string): void {\n\t\tconst state = this.#state$.value\n\t\tif (!state.windows.has(id)) return\n\t\tif (state.focusedId === id) return\n\n\t\tconst zIndex = overlayStack.bringToFront(id)\n\t\tconst windows = new Map(state.windows)\n\t\tconst record = windows.get(id)\n\t\tif (record) {\n\t\t\twindows.set(id, { ...record, zIndex })\n\t\t}\n\t\tconst stackOrder = overlayStack.getStackOrder()\n\n\t\tthis.#state$.next({ ...state, windows, stackOrder, focusedId: id })\n\t}\n\n\t// ── Queries ────────────────────────────────────────────────────────\n\n\tfindOverlaps(bounds: WindowBounds, excludeId: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [id, record] of this.#state$.value.windows) {\n\t\t\tif (id === excludeId) continue\n\t\t\tif (rectsOverlap(bounds, record.bounds)) {\n\t\t\t\tresult.push(record)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tgetNeighbors(id: string): WindowRecord[] {\n\t\tconst result: WindowRecord[] = []\n\t\tfor (const [otherId, record] of this.#state$.value.windows) {\n\t\t\tif (otherId !== id) result.push(record)\n\t\t}\n\t\treturn result\n\t}\n\n\t// ── Selectors ──────────────────────────────────────────────────────\n\n\tselectWindow(id: string): Observable<WindowRecord | undefined> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.windows.get(id)),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\tselectFocused(): Observable<string | null> {\n\t\treturn this.#state$.pipe(\n\t\t\tmap(state => state.focusedId),\n\t\t\tdistinctUntilChanged(),\n\t\t)\n\t}\n\n\t// ── Persistence ────────────────────────────────────────────────────\n\n\tloadPosition(id: string): { x: number; y: number; anchor: string } | null {\n\t\ttry {\n\t\t\t// Try new key first, fall back to legacy\n\t\t\tconst raw = localStorage.getItem(STORAGE_PREFIX + id) ?? localStorage.getItem(LEGACY_STORAGE_PREFIX + id)\n\t\t\tif (!raw) return null\n\t\t\treturn JSON.parse(raw) as { x: number; y: number; anchor: string }\n\t\t} catch {\n\t\t\treturn null\n\t\t}\n\t}\n\n\tsavePosition(id: string, data: { x: number; y: number; anchor: string }): void {\n\t\ttry {\n\t\t\tlocalStorage.setItem(STORAGE_PREFIX + id, JSON.stringify(data))\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\tclearPosition(id: string): void {\n\t\ttry {\n\t\t\tlocalStorage.removeItem(STORAGE_PREFIX + id)\n\t\t\tlocalStorage.removeItem(LEGACY_STORAGE_PREFIX + id)\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t// ── Internal ───────────────────────────────────────────────────────\n\n\tprivate updateRecord(id: string, updates: Partial<WindowRecord>): void {\n\t\tconst state = this.#state$.value\n\t\tconst record = state.windows.get(id)\n\t\tif (!record) return\n\n\t\tconst windows = new Map(state.windows)\n\t\twindows.set(id, { ...record, ...updates })\n\t\tthis.#state$.next({ ...state, windows })\n\t}\n}\n\n/** Simple rect overlap check (inline — no circular import with window-position) */\nfunction rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\nexport const windowManager = WindowManagerService.getInstance()\n","/**\n * Window Position — pure functions for overlap resolution, cascade, and snapping.\n *\n * All functions are stateless: they take window bounds and viewport dimensions,\n * return new bounds. No side effects, no DOM access, no subscriptions.\n *\n * Example:\n * const projected = { left: 100, top: 400, width: 360, height: 500 }\n * const neighbors = windowManager.findOverlaps(projected, 'my-id')\n * const resolved = resolveOverlap(projected, neighbors, { width: 1440, height: 900 })\n * // → { left: 144, top: 444, width: 360, height: 500 } (cascaded away from conflict)\n */\n\nimport type { WindowBounds, WindowRecord } from './window-registry.js'\n\nconst HEAD_HEIGHT = 44\nconst CASCADE_OFFSET = HEAD_HEIGHT\nconst MAX_CASCADE_ATTEMPTS = 10\n\n/** Check if two rectangles overlap (edges touching does NOT count as overlap) */\nexport function rectsOverlap(a: WindowBounds, b: WindowBounds): boolean {\n\treturn !(a.left >= b.left + b.width || a.left + a.width <= b.left || a.top >= b.top + b.height || a.top + a.height <= b.top)\n}\n\n/**\n * Resolve overlap by cascading diagonally until no conflict.\n * Shifts by (HEAD_HEIGHT, HEAD_HEIGHT) per attempt, clamped to viewport.\n */\nexport function resolveOverlap(\n\tcandidate: WindowBounds,\n\texisting: WindowRecord[],\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\tconst bounds = { ...candidate }\n\n\tfor (let attempt = 0; attempt < MAX_CASCADE_ATTEMPTS; attempt++) {\n\t\tconst hasOverlap = existing.some(w => rectsOverlap(bounds, w.bounds))\n\t\tif (!hasOverlap) break\n\n\t\tbounds.left += CASCADE_OFFSET\n\t\tbounds.top += CASCADE_OFFSET\n\t}\n\n\treturn clampToViewport(bounds, viewport)\n}\n\n/**\n * Clamp bounds so the window stays fully within the viewport.\n */\nexport function clampToViewport(\n\tbounds: WindowBounds,\n\tviewport: { width: number; height: number },\n): WindowBounds {\n\treturn {\n\t\twidth: bounds.width,\n\t\theight: bounds.height,\n\t\tleft: Math.max(0, Math.min(bounds.left, viewport.width - bounds.width)),\n\t\ttop: Math.max(0, Math.min(bounds.top, viewport.height - bounds.height)),\n\t}\n}\n","import { SchmancyElement } from '@mixins/index'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport {\n\tanimationFrameScheduler,\n\tauditTime,\n\tcatchError,\n\tEMPTY,\n\tfilter,\n\tfinalize,\n\tfrom,\n\tfromEvent,\n\tmap,\n\tmerge,\n\tObservable,\n\tswitchMap,\n\ttake,\n\ttakeUntil,\n\ttap,\n} from 'rxjs'\nimport { SPRING_SMOOTH, SPRING_SNAPPY } from '../utils/animation.js'\nimport { cursorGlow } from '../directives/cursor-glow'\nimport { reducedMotion$ } from '../directives/reduced-motion'\nimport { theme } from '../theme/theme.service.js'\nimport type { SnapCorner, WindowBounds, WindowVisualState } from './window-registry.js'\nimport { windowManager } from './window-manager.js'\nimport { resolveOverlap } from './window-position.js'\n\nconst HEAD_HEIGHT = 48\nconst DRAG_THRESHOLD = 5\n\ninterface Position {\n\tx: number\n\ty: number\n}\n\n@customElement('schmancy-window')\nexport default class SchmancyWindow extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t\tposition: relative;\n\t\tz-index: 1000;\n\t}\n\t:host([hidden]) {\n\t\tdisplay: none !important;\n\t}\n`]\n\n\t@property({ type: String }) id: string = 'default'\n\t/** Override the expanded panel width (e.g. '320px', '24rem'). Defaults to responsive sizing. */\n\t@property({ type: String }) expandedWidth?: string\n\t/** Override the expanded panel height (e.g. '400px', '50vh'). */\n\t@property({ type: String }) expandedHeight?: string\n\t/** When true, uses a lower elevation shadow in the collapsed state. */\n\t@property({ type: Boolean, reflect: true }) lowered: boolean = false\n\t/** Corner the window is anchored to. */\n\t@property({ type: String }) corner: SnapCorner = 'bottom-right'\n\t/** When true, window can be resized by the user. */\n\t@property({ type: Boolean }) resizable = false\n\t/** When true, window stays at its dragged position instead of snapping to a corner. */\n\t@property({ type: Boolean }) freePosition = false\n\t/** Visual state of the window (minimized, normal, maximized). */\n\t@property({ type: String, reflect: true }) visualState: WindowVisualState = 'normal'\n\t/** Minimum width in pixels. */\n\t@property({ type: Number }) minWidth = 280\n\t/** Minimum height in pixels. */\n\t@property({ type: Number }) minHeight = 200\n\n\t/** Whether the body is expanded. */\n\t@property({ type: Boolean, reflect: true }) open = false\n\n\tprivate currentAnimation?: Animation\n\n\t/** Lazy rendering: body content not in DOM until first expand. */\n\t@state() private hasOpened = false\n\n\t// Internal position -- plain fields, updated directly during drag\n\tprivate position: Position = { x: 16, y: 16 }\n\t@state() private currentCorner: SnapCorner = 'bottom-right'\n\n\t// Track applied corner to avoid unnecessary style.removeProperty calls during drag\n\tprivate appliedCorner: string = ''\n\n\t// Refs\n\tprivate containerRef = createRef<HTMLElement>()\n\tprivate bodyRef = createRef<HTMLElement>()\n\tprivate headRef = createRef<HTMLElement>()\n\n\t// ============================================\n\t// COMPUTED\n\t// ============================================\n\n\tprivate get panelWidth(): string {\n\t\treturn this.expandedWidth ?? 'min(360px, calc(100vw - 32px))'\n\t}\n\n\tprivate get isBottomCorner(): boolean {\n\t\treturn this.currentCorner.startsWith('bottom')\n\t}\n\n\tprivate get closedClipPath(): string {\n\t\treturn this.isBottomCorner\n\t\t\t? `inset(calc(100% - ${HEAD_HEIGHT}px) 0px 0px 0px round 22px)`\n\t\t\t: `inset(0px 0px calc(100% - ${HEAD_HEIGHT}px) 0px round 22px)`\n\t}\n\n\tprivate get openClipPath(): string {\n\t\treturn 'inset(0px 0px 0px 0px round 12px)'\n\t}\n\n\tprivate get elevation(): 0 | 1 | 2 | 3 | 4 | 5 {\n\t\tif (this.open) return 4\n\t\treturn this.lowered ? 1 : 3\n\t}\n\n\t// ============================================\n\t// POSITION MANAGEMENT\n\t// ============================================\n\n\tprivate applyContainerPosition() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\t// Only clear position properties when corner changes (avoids 4 style invalidations per drag frame)\n\t\tif (this.appliedCorner !== this.currentCorner) {\n\t\t\tcontainer.style.removeProperty('left')\n\t\t\tcontainer.style.removeProperty('right')\n\t\t\tcontainer.style.removeProperty('top')\n\t\t\tcontainer.style.removeProperty('bottom')\n\t\t\tthis.appliedCorner = this.currentCorner\n\t\t}\n\t\tconst { x, y } = this.position\n\t\tif (this.currentCorner.includes('right')) {\n\t\t\tcontainer.style.right = `${x}px`\n\t\t} else {\n\t\t\tcontainer.style.left = `${x}px`\n\t\t}\n\t\tif (this.currentCorner.includes('bottom')) {\n\t\t\tcontainer.style.bottom = `${y + theme.bottomOffset}px`\n\t\t} else {\n\t\t\tcontainer.style.top = `${y}px`\n\t\t}\n\t}\n\n\tprivate static readonly VALID_CORNERS = new Set<string>(['top-left', 'top-right', 'bottom-left', 'bottom-right'])\n\n\tprivate loadPosition() {\n\t\tconst saved = windowManager.loadPosition(this.id)\n\t\tif (saved) {\n\t\t\tthis.position = { x: saved.x, y: saved.y }\n\t\t\tif (SchmancyWindow.VALID_CORNERS.has(saved.anchor)) {\n\t\t\t\tthis.currentCorner = saved.anchor as SnapCorner\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate savePosition() {\n\t\twindowManager.savePosition(this.id, { ...this.position, anchor: this.currentCorner })\n\t}\n\n\tprivate validateBounds() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tif (rect.width === 0) return\n\t\tconst vw = window.innerWidth\n\t\tconst vh = window.innerHeight\n\t\tconst isRight = this.currentCorner.includes('right')\n\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\tconst actualLeft = isRight ? vw - this.position.x - rect.width : this.position.x\n\t\tconst actualTop = isBottom ? vh - this.position.y - rect.height : this.position.y\n\t\tconst newLeft = Math.max(0, Math.min(actualLeft, vw - rect.width))\n\t\tconst newTop = Math.max(0, Math.min(actualTop, vh - rect.height))\n\t\tthis.position = {\n\t\t\tx: isRight ? vw - newLeft - rect.width : newLeft,\n\t\t\ty: isBottom ? vh - newTop - rect.height : newTop,\n\t\t}\n\t\tthis.applyContainerPosition()\n\t}\n\n\t// ============================================\n\t// CORNER SNAPPING\n\t// ============================================\n\n\tprivate reorientToNearestCorner(skipAnimation = false): void {\n\t\t// Free position mode: skip corner snapping\n\t\tif (this.freePosition) {\n\t\t\tthis.savePosition()\n\t\t\tconst rect = this.containerRef.value?.getBoundingClientRect()\n\t\t\tif (rect) {\n\t\t\t\twindowManager.updateBounds(this.id, { left: rect.left, top: rect.top, width: rect.width, height: rect.height })\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\t// F -- record current screen position before DOM mutation\n\t\tconst rect = container.getBoundingClientRect()\n\n\t\t// L -- calculate nearest corner using head visual center\n\t\tconst currentIsBottom = this.currentCorner.includes('bottom')\n\t\tconst headCenterX = rect.left + rect.width / 2\n\t\tconst headCenterY = currentIsBottom\n\t\t\t? rect.bottom - HEAD_HEIGHT / 2\n\t\t\t: rect.top + HEAD_HEIGHT / 2\n\t\tconst side = headCenterX > window.innerWidth / 2 ? 'right' : 'left'\n\t\tconst vert = headCenterY > window.innerHeight / 2 ? 'bottom' : 'top'\n\t\tconst newCorner: SnapCorner = `${vert}-${side}` as SnapCorner\n\n\t\t// Snap corner and reset offset to standard edge gap\n\t\tthis.currentCorner = newCorner\n\t\tthis.position = { x: 16, y: 16 }\n\t\tthis.applyContainerPosition()\n\t\t// Sync clip-path to new corner\n\t\tif (!this.open) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t}\n\n\t\tif (skipAnimation || reducedMotion$.value) {\n\t\t\tthis.savePosition()\n\t\t\tconst snapRect = container.getBoundingClientRect()\n\t\t\twindowManager.updateBounds(this.id, { left: snapRect.left, top: snapRect.top, width: snapRect.width, height: snapRect.height })\n\t\t\treturn\n\t\t}\n\n\t\t// I -- invert: shift element back to its original visual position\n\t\tconst newRect = container.getBoundingClientRect()\n\t\tconst dx = rect.left - newRect.left\n\t\tconst dy = rect.top - newRect.top\n\t\tcontainer.style.translate = `${dx}px ${dy}px`\n\n\t\t// P -- play: animate from the inverse offset to natural resting position\n\t\tconst flipKeyframes: Keyframe[] = [{ translate: `${dx}px ${dy}px` }, { translate: '0px 0px' }]\n\t\tconst anim = container.animate(\n\t\t\tflipKeyframes,\n\t\t\t{\n\t\t\t\tduration: SPRING_SMOOTH.duration,\n\t\t\t\teasing: SPRING_SMOOTH.easingFallback,\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) container.style.translate = ''\n\t\t\t\t// Report final resting bounds after animation completes\n\t\t\t\tconst finalRect = container.getBoundingClientRect()\n\t\t\t\twindowManager.updateBounds(this.id, { left: finalRect.left, top: finalRect.top, width: finalRect.width, height: finalRect.height })\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.savePosition()\n\t}\n\n\t// ============================================\n\t// DRAG PIPELINE\n\t// ============================================\n\n\tprivate drag$(): Observable<never> {\n\t\treturn new Observable(() => {\n\t\t\tconst head = this.headRef.value\n\t\t\tconst container = this.containerRef.value\n\t\t\tif (!head || !container) return\n\n\t\t\tlet didDrag = false\n\n\t\t\tconst sub = fromEvent<PointerEvent>(head, 'pointerdown').pipe(\n\t\t\t\tfilter(e => e.button === 0),\n\t\t\t\tfilter(e => {\n\t\t\t\t\tconst tag = (e.target as HTMLElement).tagName?.toLowerCase()\n\t\t\t\t\treturn !['input', 'textarea', 'select', 'button'].includes(tag)\n\t\t\t\t\t\t&& !(e.target as HTMLElement).closest('schmancy-input, schmancy-icon-button, button, a')\n\t\t\t\t}),\n\t\t\t\ttap(e => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}),\n\t\t\t)\n\t\t\t\t.pipe(\n\t\t\t\t\tmap(e => {\n\t\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\t\t\tconst wasOpen = this.open\n\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstartX: e.clientX,\n\t\t\t\t\t\t\tstartY: e.clientY,\n\t\t\t\t\t\t\toffsetX: e.clientX - rect.left,\n\t\t\t\t\t\t\toffsetY: e.clientY - rect.top,\n\t\t\t\t\t\t\trect,\n\t\t\t\t\t\t\tvw: window.innerWidth,\n\t\t\t\t\t\t\tvh: window.innerHeight,\n\t\t\t\t\t\t\tisBottom,\n\t\t\t\t\t\t\twasOpen,\n\t\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tswitchMap(({ startX, startY, offsetX, offsetY, rect, vw, vh, isBottom, wasOpen, pointerId }) => {\n\t\t\t\t\t\tconst move$ = fromEvent<PointerEvent>(window, 'pointermove').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\t\t\t\tmap(e => ({ clientX: e.clientX, clientY: e.clientY })),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tconst end$ = fromEvent<PointerEvent>(window, 'pointerup').pipe(\n\t\t\t\t\t\t\tfilter(e => e.pointerId === pointerId),\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn move$.pipe(\n\t\t\t\t\t\t\ttap(({ clientX, clientY }) => {\n\t\t\t\t\t\t\t\tconst dx = clientX - startX\n\t\t\t\t\t\t\t\tconst dy = clientY - startY\n\t\t\t\t\t\t\t\tif (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD && !didDrag) {\n\t\t\t\t\t\t\t\t\tdidDrag = true\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(true)\n\t\t\t\t\t\t\t\t\t// Collapse on first confirmed drag move\n\t\t\t\t\t\t\t\t\tif (wasOpen) {\n\t\t\t\t\t\t\t\t\t\tthis.open = false\n\t\t\t\t\t\t\t\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\t\t\t\t\t\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\t\t\t\t\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\t\t\t\t\t\t\tif (body) {\n\t\t\t\t\t\t\t\t\t\t\tbody.inert = true\n\t\t\t\t\t\t\t\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!didDrag) return\n\n\t\t\t\t\t\t\t\tconst left = Math.max(0, Math.min(clientX - offsetX, vw - rect.width))\n\t\t\t\t\t\t\t\tconst minTop = isBottom ? HEAD_HEIGHT - rect.height : 0\n\t\t\t\t\t\t\t\tconst maxTop = isBottom ? vh - rect.height : vh - HEAD_HEIGHT\n\t\t\t\t\t\t\t\tconst top = Math.max(minTop, Math.min(clientY - offsetY, maxTop))\n\n\t\t\t\t\t\t\t\tthis.position = {\n\t\t\t\t\t\t\t\t\tx: this.currentCorner.includes('right') ? vw - left - rect.width : left,\n\t\t\t\t\t\t\t\t\ty: isBottom ? vh - top - rect.height : top,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.applyContainerPosition()\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\ttakeUntil(end$),\n\t\t\t\t\t\t\tfinalize(() => {\n\t\t\t\t\t\t\t\tif (didDrag) {\n\t\t\t\t\t\t\t\t\tthis.reorientToNearestCorner()\n\t\t\t\t\t\t\t\t\tthis.applyDragVisuals(false)\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdidDrag = false\n\t\t\t\t\t\t\t\t\tthis.toggle()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.subscribe()\n\n\t\t\treturn () => sub.unsubscribe()\n\t\t})\n\t}\n\n\t// ============================================\n\t// LIFECYCLE\n\t// ============================================\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Pipeline 1: DOM setup + manager registration + drag + z-index sync\n\t\tfrom(this.updateComplete).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.currentCorner = this.corner\n\t\t\t\tthis.loadPosition()\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t\tthis.initDOMState()\n\t\t\t\t// Register with window manager\n\t\t\t\tconst container = this.containerRef.value\n\t\t\t\tif (container) {\n\t\t\t\t\tconst rect = container.getBoundingClientRect()\n\t\t\t\t\tconst bounds: WindowBounds = { left: rect.left, top: rect.top, width: rect.width, height: rect.height }\n\t\t\t\t\twindowManager.register(this.id, bounds, this.freePosition ? 'free' : this.currentCorner)\n\t\t\t\t}\n\t\t\t}),\n\t\t\tswitchMap(() => merge(\n\t\t\t\tthis.drag$(),\n\t\t\t\twindowManager.selectWindow(this.id).pipe(\n\t\t\t\t\ttap(record => {\n\t\t\t\t\t\tif (!record) return\n\t\t\t\t\t\tconst container = this.containerRef.value\n\t\t\t\t\t\tif (container) container.style.zIndex = String(record.zIndex)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\n\t\t// Pipeline 3: Environment -- one subscription\n\t\tmerge(\n\t\t\tfromEvent(window, 'resize').pipe(\n\t\t\t\tauditTime(0, animationFrameScheduler),\n\t\t\t\ttap(() => this.validateBounds()),\n\t\t\t),\n\t\t\ttheme.bottomOffset$.pipe(\n\t\t\t\ttap(() => this.applyContainerPosition()),\n\t\t\t),\n\t\t).pipe(takeUntil(this.disconnecting)).subscribe()\n\t}\n\n\tdisconnectedCallback() {\n\t\tsuper.disconnectedCallback()\n\t\twindowManager.unregister(this.id)\n\t}\n\n\tprivate initDOMState() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.applyContainerPosition()\n\n\t\tif (this.open) {\n\t\t\tthis.hasOpened = true\n\t\t\tcontainer.style.overflow = ''\n\t\t\tif (body) {\n\t\t\t\tbody.inert = false\n\t\t\t\tbody.style.visibility = 'visible'\n\t\t\t}\n\t\t} else {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tif (body) {\n\t\t\t\tbody.inert = true\n\t\t\t\tbody.style.visibility = 'hidden'\n\t\t\t}\n\t\t}\n\t}\n\n\t// ============================================\n\t// ANIMATION\n\t// ============================================\n\n\tprivate animateOpen() {\n\t\tconst container = this.containerRef.value\n\t\tconst body = this.bodyRef.value\n\t\tif (!container) return\n\n\t\tthis.hasOpened = true\n\t\tthis.open = true\n\n\t\t// Overlap avoidance\n\t\tconst rect = container.getBoundingClientRect()\n\t\tconst projectedBounds: WindowBounds = {\n\t\t\tleft: rect.left,\n\t\t\ttop: this.isBottomCorner ? rect.top - 400 : rect.top,\n\t\t\twidth: rect.width,\n\t\t\theight: 400 + HEAD_HEIGHT,\n\t\t}\n\t\tconst overlaps = windowManager.findOverlaps(projectedBounds, this.id)\n\t\tif (overlaps.length > 0) {\n\t\t\tconst resolved = resolveOverlap(projectedBounds, overlaps, { width: window.innerWidth, height: window.innerHeight })\n\t\t\tif (Math.abs(resolved.left - projectedBounds.left) > 10 || Math.abs(resolved.top - projectedBounds.top) > 10) {\n\t\t\t\tconst isRight = this.currentCorner.includes('right')\n\t\t\t\tconst isBottom = this.currentCorner.includes('bottom')\n\t\t\t\tthis.position = {\n\t\t\t\t\tx: isRight ? window.innerWidth - resolved.left - resolved.width : resolved.left,\n\t\t\t\t\ty: isBottom ? window.innerHeight - resolved.top - resolved.height : resolved.top,\n\t\t\t\t}\n\t\t\t\tthis.applyContainerPosition()\n\t\t\t}\n\t\t}\n\n\t\tif (body) {\n\t\t\tbody.style.visibility = 'visible'\n\t\t\tbody.inert = false\n\t\t}\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = ''\n\t\t\tcontainer.style.overflow = ''\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst openKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t]\n\t\tconst anim = container.animate(openKeyframes, {\n\t\t\tduration: SPRING_SNAPPY.duration,\n\t\t\teasing: SPRING_SNAPPY.easingFallback,\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tif (container.isConnected) {\n\t\t\t\t\tcontainer.style.clipPath = ''\n\t\t\t\t\tcontainer.style.overflow = ''\n\t\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\t}\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'expanded' })\n\t}\n\n\tprivate animateClose() {\n\t\tconst container = this.containerRef.value\n\t\tif (!container) return\n\n\t\tif (reducedMotion$.value) {\n\t\t\tcontainer.style.clipPath = this.closedClipPath\n\t\t\tcontainer.style.overflow = 'hidden'\n\t\t\tthis.open = false\n\t\t\tconst body = this.bodyRef.value\n\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t\t\treturn\n\t\t}\n\n\t\tthis.currentAnimation?.cancel()\n\t\tcontainer.style.overflow = 'hidden'\n\t\tcontainer.style.willChange = 'opacity'\n\t\tconst closeKeyframes: Keyframe[] = [\n\t\t\t{ clipPath: this.openClipPath, opacity: 1 },\n\t\t\t{ clipPath: this.closedClipPath, opacity: 0.95 },\n\t\t]\n\t\tconst anim = container.animate(closeKeyframes, {\n\t\t\tduration: Math.round(SPRING_SNAPPY.duration * 0.7),\n\t\t\teasing: 'cubic-bezier(0.4, 0, 0.8, 0.15)',\n\t\t\tfill: 'forwards',\n\t\t})\n\t\tthis.currentAnimation = anim\n\n\t\tfrom(anim.finished).pipe(\n\t\t\ttake(1),\n\t\t\ttap(() => {\n\t\t\t\tthis.open = false\n\t\t\t\tcontainer.style.willChange = ''\n\t\t\t\tconst body = this.bodyRef.value\n\t\t\t\tif (body) { body.inert = true; body.style.visibility = 'hidden' }\n\t\t\t}),\n\t\t\tcatchError(() => EMPTY),\n\t\t\ttakeUntil(this.disconnecting),\n\t\t).subscribe()\n\n\t\tthis.dispatchScopedEvent('window-toggle', { state: 'collapsed' })\n\t}\n\n\t// ============================================\n\t// VISUAL STATE HELPERS\n\t// ============================================\n\n\t/** Apply drag visuals directly on DOM refs — avoids full Lit re-render for cursor + opacity */\n\tprivate applyDragVisuals(dragging: boolean) {\n\t\tconst head = this.headRef.value\n\t\tconst container = this.containerRef.value\n\t\tif (head) {\n\t\t\thead.classList.toggle('cursor-grabbing', dragging)\n\t\t\thead.classList.toggle('cursor-move', !dragging)\n\t\t}\n\t\tif (container) {\n\t\t\tcontainer.style.opacity = dragging ? '0.95' : ''\n\t\t}\n\t}\n\n\tprivate handleFocus = () => windowManager.focus(this.id)\n\n\tprivate handleHeadKeydown = (e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter' || e.key === ' ') {\n\t\t\te.preventDefault()\n\t\t\tthis.toggle()\n\t\t\treturn\n\t\t}\n\t\tif (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n\t\t\te.preventDefault()\n\t\t\tconst step = e.shiftKey ? 20 : 5\n\t\t\tconst dx = e.key === 'ArrowRight' ? step : e.key === 'ArrowLeft' ? -step : 0\n\t\t\tconst dy = e.key === 'ArrowDown' ? step : e.key === 'ArrowUp' ? -step : 0\n\t\t\tthis.position = { x: this.position.x + dx, y: this.position.y + dy }\n\t\t\tthis.applyContainerPosition()\n\t\t\tthis.savePosition()\n\t\t}\n\t}\n\n\t// ============================================\n\t// PUBLIC API\n\t// ============================================\n\n\ttoggle() {\n\t\tif (this.open) this.animateClose()\n\t\telse this.animateOpen()\n\t}\n\n\texpand() {\n\t\tif (this.open) return\n\t\tthis.animateOpen()\n\t}\n\n\tclose() {\n\t\tif (!this.open) return\n\t\tthis.animateClose()\n\t}\n\n\t// ============================================\n\t// RENDER\n\t// ============================================\n\n\tprotected render(): unknown {\n\t\tconst isBottom = this.currentCorner.startsWith('bottom')\n\n\t\tconst containerClasses = classMap({\n\t\t\tfixed: true,\n\t\t\tflex: true,\n\t\t\t'flex-col': isBottom,\n\t\t\t'flex-col-reverse': !isBottom,\n\t\t\t'z-1000': true,\n\t\t\t'rounded-2xl': this.open,\n\t\t\t'rounded-[22px]': !this.open,\n\t\t\t'overflow-hidden': true,\n\t\t})\n\n\t\tconst containerStyles = styleMap({\n\t\t\twidth: this.panelWidth,\n\t\t\t'max-height': 'calc(100vh - 32px)',\n\t\t\t'pointer-events': 'none',\n\t\t})\n\n\t\tconst bodyStyles = styleMap({\n\t\t\t'pointer-events': this.open ? 'auto' : 'none',\n\t\t})\n\n\t\tconst headClasses = classMap({\n\t\t\t'h-full': true,\n\t\t\t'px-3': true,\n\t\t\tflex: true,\n\t\t\t'items-center': true,\n\t\t\t'gap-2': true,\n\t\t\t'select-none': true,\n\t\t\t'cursor-move': true,\n\t\t})\n\n\t\treturn html`\n\t\t\t<schmancy-surface\n\t\t\t\t${ref(this.containerRef)}\n\t\t\t\ttype=\"glass\"\n\t\t\t\t.elevation=${this.elevation}\n\t\t\t\tclass=${containerClasses}\n\t\t\t\tstyle=${containerStyles}\n\t\t\t\taria-expanded=${this.open}\n\t\t\t\t@pointerdown=${this.handleFocus}\n\t\t\t>\n\t\t\t\t<!-- Details section (visually above summary for bottom corners) -->\n\t\t\t\t<section\n\t\t\t\t\t${ref(this.bodyRef)}\n\t\t\t\t\tclass=\"flex-1 min-h-0 overflow-hidden flex flex-col\"\n\t\t\t\t\tstyle=${bodyStyles}\n\t\t\t\t\trole=\"region\"\n\t\t\t\t\taria-label=\"Expandable content\"\n\t\t\t\t>\n\t\t\t\t\t${this.hasOpened ? html`<slot name=\"details\"></slot>` : nothing}\n\t\t\t\t</section>\n\n\t\t\t\t<!-- Summary section -- always interactive, always visible -->\n\t\t\t\t<section\n\t\t\t\t\tclass=\"shrink-0 bg-surface-lowest\"\n\t\t\t\t\tstyle=${styleMap({ 'pointer-events': 'auto', height: `${HEAD_HEIGHT}px` })}\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\t${ref(this.headRef)}\n\t\t\t\t\t\t${cursorGlow({ radius: 200, intensity: 0.10 })}\n\t\t\t\t\t\tclass=${headClasses}\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t\ttitle=\"Drag to move, click to expand\"\n\t\t\t\t\t\taria-label=\"${this.open ? 'Collapse window' : 'Expand window'}\"\n\t\t\t\t\t\t@keydown=${this.handleHeadKeydown}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div class=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\twidth=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n\t\t\t\t\t\t\tclass=\"shrink-0 text-surface-on/40 transition-transform duration-200 ${this.open ? 'rotate-180' : ''}\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t</section>\n\t\t\t</schmancy-surface>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-window': SchmancyWindow\n\t}\n}\n"],"mappings":"igBAmBA,IAAM,EAAiB,mBACjB,EAAwB,kBAmL9B,SAAS,EAAa,EAAiB,EAAA,CACtC,MAAA,EAAS,EAAE,MAAQ,EAAE,KAAO,EAAE,OAAS,EAAE,KAAO,EAAE,OAAS,EAAE,MAAQ,EAAE,KAAO,EAAE,IAAM,EAAE,QAAU,EAAE,IAAM,EAAE,QAAU,EAAE,IACzH,CAEA,IAAA,EAAa,EArLb,MAAM,CAAA,CAGL,GAQA,aAAA,CAAA,KAAA,GARmB,IAAI,EAAA,gBAAqC,CAC3D,QAAS,IAAI,IACb,UAAW,KACX,WAAY,CAAA,CAAA,CAAA,EAAA,KAAA,OAGK,KAAA,GAAa,aAAA,CAER,CAEvB,OAAA,aAAO,CAIN,MAHK,CACJ,EAAqB,WAAW,IAAI,EAE9B,EAAqB,QAC7B,CAIA,IAAA,SAAI,CACH,OAAO,KAAA,GAAa,MAAM,OAC3B,CAEA,IAAA,WAAI,CACH,OAAO,KAAA,GAAa,MAAM,SAC3B,CAIA,SAAS,EAAY,EAA6B,EAAA,CACjD,IAAM,EAAQ,KAAA,GAAa,MAC3B,GAAI,EAAM,QAAQ,IAAI,CAAA,EAAK,OAG3B,IAAM,EAAuB,CAC5B,GAAA,EACA,OAAQ,EACR,YAAa,SACb,OALc,EAAA,EAAa,aAAa,CAAA,EAMxC,KAAA,CAAM,EACN,WAAA,CAAA,EAGK,EAAU,IAAI,IAAI,EAAM,OAAA,EAC9B,EAAQ,IAAI,EAAI,CAAA,EAChB,IAAM,EAAa,EAAA,EAAa,cAAA,EAEhC,KAAA,GAAa,KAAK,CAAA,GAAK,EAAO,QAAA,EAAS,WAAA,CAAA,CAAA,CACxC,CAEA,WAAW,EAAA,CACV,IAAM,EAAQ,KAAA,GAAa,MAC3B,GAAA,CAAK,EAAM,QAAQ,IAAI,CAAA,EAAK,OAE5B,EAAA,EAAa,UAAU,CAAA,EACvB,IAAM,EAAU,IAAI,IAAI,EAAM,OAAA,EAC9B,EAAQ,OAAO,CAAA,EACf,IAAM,EAAa,EAAA,EAAa,cAAA,EAC1B,EAAY,EAAM,YAAc,EAAK,KAAO,EAAM,UAExD,KAAA,GAAa,KAAK,CAAA,GAAK,EAAO,QAAA,EAAS,WAAA,EAAY,UAAA,CAAA,CAAA,CACpD,CAIA,aAAa,EAAY,EAAA,CACxB,KAAK,aAAa,EAAI,CAAE,OAAA,CAAA,CAAA,CACzB,CAEA,kBAAkB,EAAY,EAAA,CAC7B,KAAK,aAAa,EAAI,CAAE,YAAA,CAAA,CAAA,CACzB,CAEA,WAAW,EAAY,EAAA,CACtB,KAAK,aAAa,EAAI,CAAE,KAAA,CAAA,CAAA,CACzB,CAEA,MAAM,EAAA,CACL,IAAM,EAAQ,KAAA,GAAa,MAE3B,GADA,CAAK,EAAM,QAAQ,IAAI,CAAA,GACnB,EAAM,YAAc,EAAI,OAE5B,IAAM,EAAS,EAAA,EAAa,aAAa,CAAA,EACnC,EAAU,IAAI,IAAI,EAAM,OAAA,EACxB,EAAS,EAAQ,IAAI,CAAA,EACvB,GACH,EAAQ,IAAI,EAAI,CAAA,GAAK,EAAQ,OAAA,CAAA,CAAA,EAE9B,IAAM,EAAa,EAAA,EAAa,cAAA,EAEhC,KAAA,GAAa,KAAK,CAAA,GAAK,EAAO,QAAA,EAAS,WAAA,EAAY,UAAW,CAAA,CAAA,CAC/D,CAIA,aAAa,EAAsB,EAAA,CAClC,IAAM,EAAyB,CAAA,EAC/B,IAAK,GAAA,CAAO,EAAI,KAAW,KAAA,GAAa,MAAM,QACzC,IAAO,GACP,EAAa,EAAQ,EAAO,MAAA,GAC/B,EAAO,KAAK,CAAA,EAGd,OAAO,CACR,CAEA,aAAa,EAAA,CACZ,IAAM,EAAyB,CAAA,EAC/B,IAAK,GAAA,CAAO,EAAS,KAAW,KAAA,GAAa,MAAM,QAC9C,IAAY,GAAI,EAAO,KAAK,CAAA,EAEjC,OAAO,CACR,CAIA,aAAa,EAAA,CACZ,OAAO,KAAA,GAAa,MAAA,EAAA,EAAA,KACf,GAAS,EAAM,QAAQ,IAAI,CAAA,CAAA,GAAG,EAAA,EAAA,sBAAA,CAAA,CAGpC,CAEA,eAAA,CACC,OAAO,KAAA,GAAa,MAAA,EAAA,EAAA,KACf,GAAS,EAAM,SAAA,GAAS,EAAA,EAAA,sBAAA,CAAA,CAG9B,CAIA,aAAa,EAAA,CACZ,GAAA,CAEC,IAAM,EAAM,aAAa,QAAQ,EAAiB,CAAA,GAAO,aAAa,QAAQ,EAAwB,CAAA,EACtG,OAAK,EACE,KAAK,MAAM,CAAA,EADD,IAElB,MAAA,CACC,OAAO,IACR,CACD,CAEA,aAAa,EAAY,EAAA,CACxB,GAAA,CACC,aAAa,QAAQ,EAAiB,EAAI,KAAK,UAAU,CAAA,CAAA,CAC1D,MAAA,CAEA,CACD,CAEA,cAAc,EAAA,CACb,GAAA,CACC,aAAa,WAAW,EAAiB,CAAA,EACzC,aAAa,WAAW,EAAwB,CAAA,CACjD,MAAA,CAEA,CACD,CAIA,aAAqB,EAAY,EAAA,CAChC,IAAM,EAAQ,KAAA,GAAa,MACrB,EAAS,EAAM,QAAQ,IAAI,CAAA,EACjC,GAAA,CAAK,EAAQ,OAEb,IAAM,EAAU,IAAI,IAAI,EAAM,OAAA,EAC9B,EAAQ,IAAI,EAAI,CAAA,GAAK,EAAA,GAAW,CAAA,CAAA,EAChC,KAAA,GAAa,KAAK,CAAA,GAAK,EAAO,QAAA,CAAA,CAAA,CAC/B,CAAA,EAQiD,YAAA,EC/KlD,SAAgB,EACf,EACA,EACA,EAAA,CAEA,IAAM,EAAS,CAAA,GAAK,CAAA,EAEpB,IAAK,IAAI,EAAU,EAAG,EAlBM,IAmBR,EAAS,KAAK,GAAA,CAAK,MAhBX,GAgBwB,EAhBP,EAgBe,EAAE,OAAA,EAfrD,EAAE,MAAQ,EAAE,KAAO,EAAE,OAAS,EAAE,KAAO,EAAE,OAAS,EAAE,MAAQ,EAAE,KAAO,EAAE,IAAM,EAAE,QAAU,EAAE,IAAM,EAAE,QAAU,EAAE,SAD5F,EAAiB,CAAA,CAAA,EAeS,IAIrD,EAAO,MAvBc,GAwBrB,EAAO,KAxBc,GA2BtB,OAMD,SACC,EACA,EAAA,CAEA,MAAO,CACN,MAAO,EAAO,MACd,OAAQ,EAAO,OACf,KAAM,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,KAAM,EAAS,MAAQ,EAAO,KAAA,CAAA,EAChE,IAAK,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,IAAK,EAAS,OAAS,EAAO,MAAA,CAAA,CAAA,CAEjE,EAhBwB,EAAQ,CAAA,CAChC,CCbA,IAAM,EAAc,GASL,EAAA,cAA6B,EAAA,CAAA,CAAA,OAAA,EAAA,IAAA,CAAA,YAAA,GAAA,EAAA,CAAA,MAAA,GAAA,CAAA,EAAA,KAAA,GAYF,UAAA,KAAA,QAAA,CAMsB,EAAA,KAAA,OAEd,eAAA,KAAA,UAAA,CAER,EAAA,KAAA,aAAA,CAEG,EAAA,KAAA,YAEgC,SAAA,KAAA,SAErC,IAAA,KAAA,UAEC,IAAA,KAAA,KAAA,CAGW,EAAA,KAAA,UAAA,CAKtB,EAAA,KAAA,SAGA,CAAE,EAAG,GAAI,EAAG,EAAA,EAAA,KAAA,cACI,eAAA,KAAA,cAGb,GAAA,KAAA,cAAA,EAAA,EAAA,WAAA,EAAA,KAAA,SAAA,EAAA,EAAA,WAAA,EAAA,KAAA,SAAA,EAAA,EAAA,WAAA,EAAA,KAAA,gBA+eJ,EAAc,MAAM,KAAK,EAAA,EAAA,KAAA,kBAExB,GAAA,CAC5B,GAAI,EAAE,MAAQ,SAAW,EAAE,MAAQ,IAGlC,OAFA,EAAE,eAAA,EAAA,KACF,KAAK,OAAA,EAGN,GAAI,EAAE,MAAQ,WAAa,EAAE,MAAQ,aAAe,EAAE,MAAQ,aAAe,EAAE,MAAQ,aAAc,CACpG,EAAE,eAAA,EACF,IAAM,EAAO,EAAE,SAAW,GAAK,EACzB,EAAK,EAAE,MAAQ,aAAe,EAAO,EAAE,MAAQ,YAAR,CAAuB,EAAO,EACrE,EAAK,EAAE,MAAQ,YAAc,EAAO,EAAE,MAAQ,UAAR,CAAqB,EAAO,EACxE,KAAK,SAAW,CAAE,EAAG,KAAK,SAAS,EAAI,EAAI,EAAG,KAAK,SAAS,EAAI,CAAA,EAChE,KAAK,uBAAA,EACL,KAAK,aAAA,CACN,CAAA,CAAA,CAAA,OAAA,KAAA,OA3iBe,CAAC,EAAA,GAAG;;;;;;;;;GAuDpB,IAAA,YAAY,CACX,OAAO,KAAK,eAAiB,gCAC9B,CAEA,IAAA,gBAAY,CACX,OAAO,KAAK,cAAc,WAAW,QAAA,CACtC,CAEA,IAAA,gBAAY,CACX,OAAO,KAAK,eACT,kDACA,iDACJ,CAEA,IAAA,cAAY,CACX,MAAO,mCACR,CAEA,IAAA,WAAY,CACX,OAAI,KAAK,KAAa,EACf,KAAK,QAAU,EAAI,CAC3B,CAMA,wBAAA,CACC,IAAM,EAAY,KAAK,aAAa,MACpC,GAAA,CAAK,EAAW,OAEZ,KAAK,gBAAkB,KAAK,gBAC/B,EAAU,MAAM,eAAe,MAAA,EAC/B,EAAU,MAAM,eAAe,OAAA,EAC/B,EAAU,MAAM,eAAe,KAAA,EAC/B,EAAU,MAAM,eAAe,QAAA,EAC/B,KAAK,cAAgB,KAAK,eAE3B,GAAA,CAAM,EAAE,EAAA,EAAG,GAAM,KAAK,SAClB,KAAK,cAAc,SAAS,OAAA,EAC/B,EAAU,MAAM,MAAQ,GAAG,EAAA,IAE3B,EAAU,MAAM,KAAO,GAAG,EAAA,IAEvB,KAAK,cAAc,SAAS,QAAA,EAC/B,EAAU,MAAM,OAAS,GAAG,EAAI,EAAA,EAAM,aAAA,IAEtC,EAAU,MAAM,IAAM,GAAG,EAAA,GAE3B,CAAA,OAAA,KAAA,cAEwC,IAAI,IAAY,CAAC,WAAY,YAAa,cAAe,cAAA,CAAA,CAAA,CAEjG,cAAA,CACC,IAAM,EAAQ,EAAc,aAAa,KAAK,EAAA,EAC1C,IACH,KAAK,SAAW,CAAE,EAAG,EAAM,EAAG,EAAG,EAAM,CAAA,EACvC,EAAmB,cAAc,IAAI,EAAM,MAAA,IAC1C,KAAK,cAAgB,EAAM,QAG9B,CAEA,cAAA,CACC,EAAc,aAAa,KAAK,GAAI,CAAA,GAAK,KAAK,SAAU,OAAQ,KAAK,aAAA,CAAA,CACtE,CAEA,gBAAA,CACC,IAAM,EAAY,KAAK,aAAa,MACpC,GAAA,CAAK,EAAW,OAChB,IAAM,EAAO,EAAU,sBAAA,EACvB,GAAI,EAAK,QAAU,EAAG,OACtB,IAAM,EAAK,OAAO,WACZ,EAAK,OAAO,YACZ,EAAU,KAAK,cAAc,SAAS,OAAA,EACtC,EAAW,KAAK,cAAc,SAAS,QAAA,EACvC,EAAa,EAAU,EAAK,KAAK,SAAS,EAAI,EAAK,MAAQ,KAAK,SAAS,EACzE,EAAY,EAAW,EAAK,KAAK,SAAS,EAAI,EAAK,OAAS,KAAK,SAAS,EAC1E,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,EAAY,EAAK,EAAK,KAAA,CAAA,EACrD,EAAS,KAAK,IAAI,EAAG,KAAK,IAAI,EAAW,EAAK,EAAK,MAAA,CAAA,EACzD,KAAK,SAAW,CACf,EAAG,EAAU,EAAK,EAAU,EAAK,MAAQ,EACzC,EAAG,EAAW,EAAK,EAAS,EAAK,OAAS,CAAA,EAE3C,KAAK,uBAAA,CACN,CAMA,wBAAgC,EAAA,CAAgB,EAAA,CAE/C,GAAI,KAAK,aAAc,CACtB,KAAK,aAAA,EACL,IAAM,EAAO,KAAK,aAAa,OAAO,sBAAA,EAClC,GACH,EAAc,aAAa,KAAK,GAAI,CAAE,KAAM,EAAK,KAAM,IAAK,EAAK,IAAK,MAAO,EAAK,MAAO,OAAQ,EAAK,MAAA,CAAA,EAEvG,MACD,CAEA,IAAM,EAAY,KAAK,aAAa,MACpC,GAAA,CAAK,EAAW,OAGhB,IAAM,EAAO,EAAU,sBAAA,EAGjB,EAAkB,KAAK,cAAc,SAAS,QAAA,EAC9C,EAAc,EAAK,KAAO,EAAK,MAAQ,EACvC,EAAc,EACjB,EAAK,OAAS,GACd,EAAK,IAAM,GACR,EAAO,EAAc,OAAO,WAAa,EAAI,QAAU,OAEvD,EAAwB,GADjB,EAAc,OAAO,YAAc,EAAI,SAAW,MAAA,GACtB,IAWzC,GARA,KAAK,cAAgB,EACrB,KAAK,SAAW,CAAE,EAAG,GAAI,EAAG,EAAA,EAC5B,KAAK,uBAAA,EAEA,KAAK,OACT,EAAU,MAAM,SAAW,KAAK,gBAG7B,GAAiB,EAAA,EAAe,MAAO,CAC1C,KAAK,aAAA,EACL,IAAM,EAAW,EAAU,sBAAA,EAC3B,EAAc,aAAa,KAAK,GAAI,CAAE,KAAM,EAAS,KAAM,IAAK,EAAS,IAAK,MAAO,EAAS,MAAO,OAAQ,EAAS,MAAA,CAAA,EACtH,MACD,CAGA,IAAM,EAAU,EAAU,sBAAA,EACpB,EAAK,EAAK,KAAO,EAAQ,KACzB,EAAK,EAAK,IAAM,EAAQ,IAC9B,EAAU,MAAM,UAAY,GAAG,EAAA,KAAQ,EAAA,IAGvC,IAAM,EAA4B,CAAC,CAAE,UAAW,GAAG,EAAA,KAAQ,EAAA,GAAA,EAAU,CAAE,UAAW,SAAA,CAAA,GASlF,EAAA,EAAA,MARa,EAAU,QACtB,EACA,CACC,SAAU,EAAA,EAAc,SACxB,OAAQ,EAAA,EAAc,eACtB,KAAM,UAAA,CAAA,EAGE,QAAA,EAAU,MAAA,EAAA,EAAA,MACd,CAAA,GAAC,EAAA,EAAA,SAAA,CAED,EAAU,cAAa,EAAU,MAAM,UAAY,IAEvD,IAAM,EAAY,EAAU,sBAAA,EAC5B,EAAc,aAAa,KAAK,GAAI,CAAE,KAAM,EAAU,KAAM,IAAK,EAAU,IAAK,MAAO,EAAU,MAAO,OAAQ,EAAU,MAAA,CAAA,CAAA,CAAA,GAC1H,EAAA,EAAA,gBACgB,EAAA,KAAA,GAAK,EAAA,EAAA,WACZ,KAAK,aAAA,CAAA,EACd,UAAA,EAEF,KAAK,aAAA,CACN,CAMA,OAAA,CACC,OAAO,IAAI,EAAA,eAAA,CACV,IAAM,EAAO,KAAK,QAAQ,MACpB,EAAY,KAAK,aAAa,MACpC,GAAA,CAAK,GAAA,CAAS,EAAW,OAEzB,IAAI,EAAA,CAAU,EAER,GAAA,EAAA,EAAA,WAA8B,EAAM,aAAA,EAAe,MAAA,EAAA,EAAA,QACjD,GAAK,EAAE,SAAW,CAAX,GAAY,EAAA,EAAA,QACnB,GAAA,CACN,IAAM,EAAO,EAAE,OAAuB,SAAS,YAAA,EAC/C,MAAA,CAAQ,CAAC,QAAS,WAAY,SAAU,QAAA,EAAU,SAAS,CAAA,GAAA,CACrD,EAAE,OAAuB,QAAQ,iDAAA,CAAA,CAAA,GACvC,EAAA,EAAA,KACG,GAAA,CACH,EAAE,eAAA,EACF,EAAE,gBAAA,CAAA,CAAA,CAAA,EAGF,MAAA,EAAA,EAAA,KACI,GAAA,CACH,IAAM,EAAO,EAAU,sBAAA,EACjB,EAAW,KAAK,cAAc,SAAS,QAAA,EACvC,EAAU,KAAK,KAErB,MADA,GAAA,CAAU,EACH,CACN,OAAQ,EAAE,QACV,OAAQ,EAAE,QACV,QAAS,EAAE,QAAU,EAAK,KAC1B,QAAS,EAAE,QAAU,EAAK,IAC1B,KAAA,EACA,GAAI,OAAO,WACX,GAAI,OAAO,YACX,SAAA,EACA,QAAA,EACA,UAAW,EAAE,SAAA,CAAA,CAAA,GAEd,EAAA,EAAA,YAAA,CACY,OAAA,EAAQ,OAAA,EAAQ,QAAA,EAAS,QAAA,EAAS,KAAA,EAAM,GAAA,EAAI,GAAA,EAAI,SAAA,EAAU,QAAA,EAAS,UAAA,KAAA,CAC/E,IAAM,GAAA,EAAA,EAAA,WAAgC,OAAQ,aAAA,EAAe,MAAA,EAAA,EAAA,QACrD,GAAK,EAAE,YAAc,CAAA,GAAS,EAAA,EAAA,WAC3B,EAAG,EAAA,uBAAA,GAAuB,EAAA,EAAA,KAChC,IAAA,CAAQ,QAAS,EAAE,QAAS,QAAS,EAAE,OAAA,EAAA,CAAA,EAEtC,GAAA,EAAA,EAAA,WAA+B,OAAQ,WAAA,EAAa,MAAA,EAAA,EAAA,QAClD,GAAK,EAAE,YAAc,CAAA,CAAA,EAG7B,OAAO,EAAM,MAAA,EAAA,EAAA,MAAA,CACL,QAAA,EAAS,QAAA,KAAA,CACf,IAAM,EAAK,EAAU,EACf,EAAK,EAAU,EACrB,GAAI,KAAK,KAAK,EAAK,EAAK,EAAK,CAAA,EA9Rd,GAAA,CA8RuC,IACrD,EAAA,CAAU,EACV,KAAK,iBAAA,CAAiB,CAAA,EAElB,GAAS,CACZ,KAAK,KAAA,CAAO,EACZ,EAAU,MAAM,SAAW,KAAK,eAChC,EAAU,MAAM,SAAW,SAC3B,IAAM,EAAO,KAAK,QAAQ,MACtB,IACH,EAAK,MAAA,CAAQ,EACb,EAAK,MAAM,WAAa,SAE1B,CAED,GAAA,CAAK,EAAS,OAEd,IAAM,EAAO,KAAK,IAAI,EAAG,KAAK,IAAI,EAAU,EAAS,EAAK,EAAK,KAAA,CAAA,EACzD,EAAS,EAAW,EAAc,EAAK,OAAS,EAChD,EAAS,EAAW,EAAK,EAAK,OAAS,EAAK,EAC5C,EAAM,KAAK,IAAI,EAAQ,KAAK,IAAI,EAAU,EAAS,CAAA,CAAA,EAEzD,KAAK,SAAW,CACf,EAAG,KAAK,cAAc,SAAS,OAAA,EAAW,EAAK,EAAO,EAAK,MAAQ,EACnE,EAAG,EAAW,EAAK,EAAM,EAAK,OAAS,CAAA,EAExC,KAAK,uBAAA,CAAA,CAAA,GACL,EAAA,EAAA,WACS,CAAA,GAAI,EAAA,EAAA,cAAA,CAET,GACH,KAAK,wBAAA,EACL,KAAK,iBAAA,CAAiB,CAAA,EACtB,EAAA,CAAU,IAEV,EAAA,CAAU,EACV,KAAK,OAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAMT,UAAA,EAEF,UAAa,EAAI,YAAA,CAAA,CAAA,CAEnB,CAMA,mBAAA,CACC,MAAM,kBAAA,GAGN,EAAA,EAAA,MAAK,KAAK,cAAA,EAAgB,MAAA,EAAA,EAAA,MACpB,CAAA,GAAC,EAAA,EAAA,SAAA,CAEL,KAAK,cAAgB,KAAK,OAC1B,KAAK,aAAA,EACL,KAAK,uBAAA,EACL,KAAK,aAAA,EAEL,IAAM,EAAY,KAAK,aAAa,MACpC,GAAI,EAAW,CACd,IAAM,EAAO,EAAU,sBAAA,EACjB,EAAuB,CAAE,KAAM,EAAK,KAAM,IAAK,EAAK,IAAK,MAAO,EAAK,MAAO,OAAQ,EAAK,MAAA,EAC/F,EAAc,SAAS,KAAK,GAAI,EAAQ,KAAK,aAAe,OAAS,KAAK,aAAA,CAC3E,CAAA,CAAA,GACA,EAAA,EAAA,gBAAA,EAAA,EAAA,OAEA,KAAK,MAAA,EACL,EAAc,aAAa,KAAK,EAAA,EAAI,MAAA,EAAA,EAAA,KAC/B,GAAA,CACH,GAAA,CAAK,EAAQ,OACb,IAAM,EAAY,KAAK,aAAa,MAChC,IAAW,EAAU,MAAM,OAAS,OAAO,EAAO,MAAA,EAAA,CAAA,CAAA,CAAA,CAAA,GAGxD,EAAA,EAAA,WACS,KAAK,aAAA,CAAA,EACd,UAAA,GAIF,EAAA,EAAA,QAAA,EAAA,EAAA,WACW,OAAQ,QAAA,EAAU,MAAA,EAAA,EAAA,WACjB,EAAG,EAAA,uBAAA,GAAuB,EAAA,EAAA,SAC1B,KAAK,eAAA,CAAA,CAAA,EAEhB,EAAA,EAAM,cAAc,MAAA,EAAA,EAAA,SACT,KAAK,uBAAA,CAAA,CAAA,CAAA,EAEf,MAAA,EAAA,EAAA,WAAe,KAAK,aAAA,CAAA,EAAgB,UAAA,CACvC,CAEA,sBAAA,CACC,MAAM,qBAAA,EACN,EAAc,WAAW,KAAK,EAAA,CAC/B,CAEA,cAAA,CACC,IAAM,EAAY,KAAK,aAAa,MAC9B,EAAO,KAAK,QAAQ,MACrB,IAEL,KAAK,uBAAA,EAED,KAAK,MACR,KAAK,UAAA,CAAY,EACjB,EAAU,MAAM,SAAW,GACvB,IACH,EAAK,MAAA,CAAQ,EACb,EAAK,MAAM,WAAa,aAGzB,EAAU,MAAM,SAAW,KAAK,eAChC,EAAU,MAAM,SAAW,SACvB,IACH,EAAK,MAAA,CAAQ,EACb,EAAK,MAAM,WAAa,WAG3B,CAMA,aAAA,CACC,IAAM,EAAY,KAAK,aAAa,MAC9B,EAAO,KAAK,QAAQ,MAC1B,GAAA,CAAK,EAAW,OAEhB,KAAK,UAAA,CAAY,EACjB,KAAK,KAAA,CAAO,EAGZ,IAAM,EAAO,EAAU,sBAAA,EACjB,EAAgC,CACrC,KAAM,EAAK,KACX,IAAK,KAAK,eAAiB,EAAK,IAAM,IAAM,EAAK,IACjD,MAAO,EAAK,MACZ,OAAQ,GAAA,EAEH,EAAW,EAAc,aAAa,EAAiB,KAAK,EAAA,EAClE,GAAI,EAAS,OAAS,EAAG,CACxB,IAAM,EAAW,EAAe,EAAiB,EAAU,CAAE,MAAO,OAAO,WAAY,OAAQ,OAAO,WAAA,CAAA,EACtG,GAAI,KAAK,IAAI,EAAS,KAAO,EAAgB,IAAA,EAAQ,IAAM,KAAK,IAAI,EAAS,IAAM,EAAgB,GAAA,EAAO,GAAI,CAC7G,IAAM,EAAU,KAAK,cAAc,SAAS,OAAA,EACtC,EAAW,KAAK,cAAc,SAAS,QAAA,EAC7C,KAAK,SAAW,CACf,EAAG,EAAU,OAAO,WAAa,EAAS,KAAO,EAAS,MAAQ,EAAS,KAC3E,EAAG,EAAW,OAAO,YAAc,EAAS,IAAM,EAAS,OAAS,EAAS,GAAA,EAE9E,KAAK,uBAAA,CACN,CACD,CAOA,GALI,IACH,EAAK,MAAM,WAAa,UACxB,EAAK,MAAA,CAAQ,GAGV,EAAA,EAAe,MAIlB,MAHA,GAAU,MAAM,SAAW,GAC3B,EAAU,MAAM,SAAW,GAAA,KAC3B,KAAK,oBAAoB,gBAAiB,CAAE,MAAO,UAAA,CAAA,EAIpD,KAAK,kBAAkB,OAAA,EACvB,EAAU,MAAM,SAAW,SAC3B,EAAU,MAAM,WAAa,UAC7B,IAAM,EAA4B,CACjC,CAAE,SAAU,KAAK,eAAgB,QAAS,GAAA,EAC1C,CAAE,SAAU,KAAK,aAAc,QAAS,CAAA,CAAA,EAEnC,EAAO,EAAU,QAAQ,EAAe,CAC7C,SAAU,EAAA,EAAc,SACxB,OAAQ,EAAA,EAAc,eACtB,KAAM,UAAA,CAAA,EAEP,KAAK,iBAAmB,GAExB,EAAA,EAAA,MAAK,EAAK,QAAA,EAAU,MAAA,EAAA,EAAA,MACd,CAAA,GAAC,EAAA,EAAA,SAAA,CAED,EAAU,cACb,EAAU,MAAM,SAAW,GAC3B,EAAU,MAAM,SAAW,GAC3B,EAAU,MAAM,WAAa,GAAA,CAAA,GAE9B,EAAA,EAAA,gBACgB,EAAA,KAAA,GAAK,EAAA,EAAA,WACZ,KAAK,aAAA,CAAA,EACd,UAAA,EAEF,KAAK,oBAAoB,gBAAiB,CAAE,MAAO,UAAA,CAAA,CACpD,CAEA,cAAA,CACC,IAAM,EAAY,KAAK,aAAa,MACpC,GAAA,CAAK,EAAW,OAEhB,GAAI,EAAA,EAAe,MAAO,CACzB,EAAU,MAAM,SAAW,KAAK,eAChC,EAAU,MAAM,SAAW,SAC3B,KAAK,KAAA,CAAO,EACZ,IAAM,EAAO,KAAK,QAAQ,MACtB,IAAQ,EAAK,MAAA,CAAQ,EAAM,EAAK,MAAM,WAAa,UACvD,KAAK,oBAAoB,gBAAiB,CAAE,MAAO,WAAA,CAAA,EACnD,MACD,CAEA,KAAK,kBAAkB,OAAA,EACvB,EAAU,MAAM,SAAW,SAC3B,EAAU,MAAM,WAAa,UAC7B,IAAM,EAA6B,CAClC,CAAE,SAAU,KAAK,aAAc,QAAS,CAAA,EACxC,CAAE,SAAU,KAAK,eAAgB,QAAS,GAAA,CAAA,EAErC,EAAO,EAAU,QAAQ,EAAgB,CAC9C,SAAU,KAAK,MAA+B,GAAzB,EAAA,EAAc,QAAA,EACnC,OAAQ,kCACR,KAAM,UAAA,CAAA,EAEP,KAAK,iBAAmB,GAExB,EAAA,EAAA,MAAK,EAAK,QAAA,EAAU,MAAA,EAAA,EAAA,MACd,CAAA,GAAC,EAAA,EAAA,SAAA,CAEL,KAAK,KAAA,CAAO,EACZ,EAAU,MAAM,WAAa,GAC7B,IAAM,EAAO,KAAK,QAAQ,MACtB,IAAQ,EAAK,MAAA,CAAQ,EAAM,EAAK,MAAM,WAAa,SAAA,CAAA,GACvD,EAAA,EAAA,gBACgB,EAAA,KAAA,GAAK,EAAA,EAAA,WACZ,KAAK,aAAA,CAAA,EACd,UAAA,EAEF,KAAK,oBAAoB,gBAAiB,CAAE,MAAO,WAAA,CAAA,CACpD,CAOA,iBAAyB,EAAA,CACxB,IAAM,EAAO,KAAK,QAAQ,MACpB,EAAY,KAAK,aAAa,MAChC,IACH,EAAK,UAAU,OAAO,kBAAmB,CAAA,EACzC,EAAK,UAAU,OAAO,cAAA,CAAgB,CAAA,GAEnC,IACH,EAAU,MAAM,QAAU,EAAW,OAAS,GAEhD,CAyBA,QAAA,CACK,KAAK,KAAM,KAAK,aAAA,EACf,KAAK,YAAA,CACX,CAEA,QAAA,CACK,KAAK,MACT,KAAK,YAAA,CACN,CAEA,OAAA,CACM,KAAK,MACV,KAAK,aAAA,CACN,CAMA,QAAA,CACC,IAAM,EAAW,KAAK,cAAc,WAAW,QAAA,EAEzC,GAAA,EAAA,EAAA,UAA4B,CACjC,MAAA,CAAO,EACP,KAAA,CAAM,EACN,WAAY,EACZ,mBAAA,CAAqB,EACrB,SAAA,CAAU,EACV,cAAe,KAAK,KACpB,iBAAA,CAAmB,KAAK,KACxB,kBAAA,CAAmB,CAAA,CAAA,EAGd,GAAA,EAAA,EAAA,UAA2B,CAChC,MAAO,KAAK,WACZ,aAAc,qBACd,iBAAkB,MAAA,CAAA,EAGb,GAAA,EAAA,EAAA,UAAsB,CAC3B,iBAAkB,KAAK,KAAO,OAAS,MAAA,CAAA,EAGlC,GAAA,EAAA,EAAA,UAAuB,CAC5B,SAAA,CAAU,EACV,OAAA,CAAQ,EACR,KAAA,CAAM,EACN,eAAA,CAAgB,EAChB,QAAA,CAAS,EACT,cAAA,CAAe,EACf,cAAA,CAAe,CAAA,CAAA,EAGhB,MAAO,GAAA,IAAI;;gBAEH,KAAK,YAAA,EAAA;;iBAEE,KAAK,UAAA;YACV,EAAA;YACA,EAAA;oBACQ,KAAK,KAAA;mBACN,KAAK,YAAA;;;;iBAIb,KAAK,OAAA,EAAA;;aAEH,EAAA;;;;OAIN,KAAK,UAAY,EAAA,IAAI,+BAAiC,EAAA,QAAA;;;;;;4BAMvC,CAAE,iBAAkB,OAAQ,OAAQ,MAAA,CAAA,EAAA;;;kBAG9C,KAAK,OAAA,EAAA;QACT,EAAA,EAAW,CAAE,OAAQ,IAAK,UAAW,EAAA,CAAA,EAAA;cAC/B,EAAA;;;;oBAIM,KAAK,KAAO,kBAAoB,gBAAA;iBACnC,KAAK,kBAAA;;;;;;;8EAOwD,KAAK,KAAO,aAAe,GAAA;;;;;;;;GASxG,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UA9oBU,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,KAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhB,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,gBAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhB,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,iBAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhB,CAAE,KAAM,QAAS,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,UAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhC,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,SAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhB,CAAE,KAAM,OAAA,CAAA,CAAA,EAAS,EAAA,UAAA,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEjB,CAAE,KAAM,OAAA,CAAA,CAAA,EAAS,EAAA,UAAA,eAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEjB,CAAE,KAAM,OAAQ,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,cAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAE/B,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,WAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAEhB,CAAE,KAAM,MAAA,CAAA,CAAA,EAAQ,EAAA,UAAA,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,UAGhB,CAAE,KAAM,QAAS,QAAA,CAAS,CAAA,CAAA,CAAA,EAAM,EAAA,UAAA,OAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EAKnC,EAAA,UAAA,YAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,CAAA,EAIA,EAAA,UAAA,gBAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,eA3CO,iBAAA,CAAA,EAAiB,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA,EAAA,OAAA,eAAA,QAAA,IAAA,CAAA,WAAA,CAAA,EAAA,IAAA,UAAA,CAAA,OAAA,CAAA,CAAA,CAAA"}
package/dist/window.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./window-Vl1u1-EG.cjs`);exports.SchmancyWindow=e.t,exports.windowManager=e.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./window-BbBYjm7R.cjs`);exports.SchmancyWindow=e.t,exports.windowManager=e.n;
package/dist/window.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./window-B_n4P9az.js";
1
+ import { n as e, t } from "./window-BDVyrBnk.js";
2
2
  export { t as SchmancyWindow, e as windowManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhmo91/schmancy",
3
- "version": "0.10.36",
3
+ "version": "0.10.38",
4
4
  "description": "UI library build with web components",
5
5
  "main": "./dist/index.js",
6
6
  "customElements": "custom-elements.json",
@@ -74,21 +74,24 @@ Use component tags (`<schmancy-menu>`, `<schmancy-dropdown>`, `<schmancy-tooltip
74
74
  - Register the tag in `HTMLElementTagNameMap` for TypeScript.
75
75
 
76
76
  **SIGNALS_ARE_THE_API**
77
- State signals are the integration layer between co-located Schmancy view components; each view component owns its IO directly and has zero property inputs and zero custom event outputs when state signals cover the shared state.
77
+ State signals are the integration layer between co-located Schmancy view components: each view component owns its IO directly and carries zero property inputs and zero custom-event outputs whenever a state signal covers the shared state. A `.property=${value}` input from a parent, a `CustomEvent` a sibling or parent handles, or a co-located orchestrator whose routing complexity does not exceed schmancy's `.guard`+`@redirect` (a linear flow, no branching, no cross-route hand-off) means that shared state belongs in a signal both components read and write directly in `render()`/`connectedCallback()`, and the orchestrator is deleted when passing data down and receiving events up was its only job.
78
78
 
79
- - Detection signals: a view component with `.property=${value}` inputs from a parent; a view component dispatching `CustomEvent`s that a sibling or parent handles; an orchestrator file co-located with a view where routing complexity does not exceed schmancy's `.guard`+`@redirect` capability (i.e., the flow is a linear sequence with no branching or cross-route hand-off).
80
- - Remediation: move shared state into schmancy state signals; have each component read/write signals directly in render() and connectedCallback(); delete the orchestrator if its only job was to pass data down and receive events up.
79
+ **TYPOGRAPHY_NO_REDUNDANT_COLOR**
80
+ A `<schmancy-typography>` color class earns its place only by overriding the component's default render color. A `class` carrying `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any utility matching the default restates what the component already renders and is removed; a color class stays only when it intentionally diverges (`text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it was redundant.
81
81
 
82
- **TYPOGRAPHY_NO_REDUNDANT_COLOR** (`TYPOGRAPHY_NO_REDUNDANT_COLOR`). `schmancy-typography` color classes override the component's default rendering color.
82
+ **EVENTS_UP_PROPS_DOWN**
83
+ When two components genuinely cannot share a signal (a generic reusable component that must not import app state), user actions travel upward as `CustomEvent` dispatch and data travels downward as Lit property bindings — never as callable property bindings. A `.onXxx=${fn}` / `.handleXxx=${fn}` in a parent template is the violation; the child dispatches `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` and the parent binds `@xxx=${handler}`.
83
84
 
84
- - Detection signals: `class` attributes on `<schmancy-typography>` containing `text-on-surface`, `text-surface-on`, `text-surface-on-variant`, or any other color utility that matches the component's default — these restate what the component already renders and add no information.
85
- - Remediation: remove the redundant color class from the `class` attribute. Keep a color class only when it intentionally overrides the default (e.g. `text-primary-default`, `text-error`, a custom accent). The test: if removing the class produces no visual change, it is redundant.
85
+ **CONTROLLED_VALUE_ECHO_IS_NOT_INTENT**
86
+ A value-controlled `<schmancy-*>` component (`schmancy-steps`, `schmancy-input`, `schmancy-select`, `schmancy-switch`, `schmancy-tabs` any whose reference table documents its change event as firing on "property set or user interaction") emits that event on the consumer's own programmatic `.value=${…}` binding too, including the first-render echo. A `@change` handler reads intent as the delta between the event's value and the value currently driving the binding and early-returns on equality before any state write, so the component echoing a binding the consumer itself set never propagates as a user action.
86
87
 
87
- **EVENTS_UP_PROPS_DOWN** (cross-component communication when signals don't cover it)
88
- When two components genuinely cannot share a signal (e.g., a generic reusable component that must not import app state), user actions travel upward via `CustomEvent` dispatch and data travels downward via Lit property bindings — not via callable property bindings (`onXxx`, `handleXxx`) set on child elements.
89
-
90
- - Detection signals: `.onXxx=${fn}` or `.handleXxx=${fn}` callable property bindings in a parent template.
91
- - Remediation: dispatch `new CustomEvent('xxx', { detail, bubbles: true, composed: true })` in the child; bind `@xxx=${handler}` in the parent.
88
+ ```ts
89
+ @change=${(e: CustomEvent<{ value: number }>) => {
90
+ const next = STEPS[e.detail.value - 1]
91
+ if (next.key === stepKey(currentStep.get())) return // programmatic echo of the step we already show — not a click
92
+ viewingStep.set(next.key)
93
+ }}
94
+ ```
92
95
 
93
96
  **State**
94
97
  - States live at module scope. Many small states beat one monolith. Use `state('feature/name').{memory,session,local,idb}(initial)` from `@mhmo91/schmancy/state`.
@@ -96,6 +99,9 @@ When two components genuinely cannot share a signal (e.g., a generic reusable co
96
99
  - `await state.ready` (or `if (state.loaded)`) before reading persisted-backend values that hydrate asynchronously.
97
100
  - Storage tiers: `.memory()` (regenerable) · `.session()` (per-tab) · `.local()` (user prefs) · `.idb()` (>100-entry collections).
98
101
 
102
+ **SIGNAL_TRACKING_BEYOND_RENDER**
103
+ A `SchmancyElement` makes any imperative side-effect reactive to signal changes by running it inside `this.updateEffect(fn, { manualDispose: true })`, which applies the same auto-tracking the component's `render()` receives to any arbitrary effect and returns a disposer for integration with the component's teardown path.
104
+
99
105
  **Routing**
100
106
  - Route guards are `Observable<boolean>`, never cached booleans.
101
107
  - `when="tag-name"` must exactly match `@customElement('tag-name')`.
@@ -14,17 +14,24 @@ import {
14
14
 
15
15
  ## The novel default — anchored
16
16
 
17
- When you're triggering an overlay from a user gesture (click, touch), pass the event as `anchor`. The overlay blooms from the point of attention instead of materializing at the viewport center.
17
+ Schmancy tracks the last user gesture automatically. When you call `show()` from a `@click` handler, the overlay positions itself near the interaction point without you passing anything:
18
18
 
19
19
  ```ts
20
- private handlePick = (ev: MouseEvent) => {
21
- show(TemplatePicker, { anchor: ev, props: { kind: 'email' } })
20
+ private handlePick = () => {
21
+ show(TemplatePicker, { props: { kind: 'email' } })
22
22
  .pipe(takeUntil(this.disconnecting))
23
23
  .subscribe(picked => { if (picked) this.template = picked })
24
24
  }
25
25
  ```
26
26
 
27
- Centered is the fallback (no anchor given). Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout the system does.
27
+ Pass `anchor` explicitly only when the gesture and the `show()` call are decoupled — e.g. the click fires in a child component but `show()` runs in a parent, or you're opening from a programmatic trigger with no gesture context:
28
+
29
+ ```ts
30
+ show(Picker, { anchor: ev }) // explicit — only when gesture context is lost
31
+ show(Picker) // idiomatic — gesture tracked automatically
32
+ ```
33
+
34
+ Centered is the fallback when there is genuinely no gesture context. Sheet is the responsive adaptation (narrow viewport / touch / oversized content). You never pick layout — the system does.
28
35
 
29
36
  ## Content forms
30
37
 
@@ -33,11 +40,11 @@ Centered is the fallback (no anchor given). Sheet is the responsive adaptation (
33
40
  | Form | When to use |
34
41
  |---|---|
35
42
  | `show(MyComponent)` | Component class — most common |
36
- | `show(html\`...\`)` | Inline template (eager — values frozen at call site) |
37
- | `show(() => html\`...\`)` | **Preferred for templates** — factory called at mount time; closed-over variables are read lazily, no snapshot staleness |
43
+ | `show(html\`...\`)` | Inline template (eager — a frozen one-shot snapshot, never re-renders) |
44
+ | `show(() => html\`...\`)` | **Reactive form** — factory re-invoked when any signal it reads changes (parity with a component's render()); closed-over variables always current |
38
45
  | `show(lazy(() => import('./x')))` | Async / code-split component |
39
46
 
40
- Always prefer `() => html\`...\`` over `html\`...\`` when the template closes over any variable — the factory form evaluates those variables at mount time rather than baking them in at the call site.
47
+ Always prefer `() => html\`...\`` over `html\`...\``: the factory form is reactive — the overlay re-runs it whenever a signal it reads changes, exactly like a component's `render()`. The eager `html\`...\`` form is a frozen snapshot captured at the call site and never updates. Bind `.value=${someState.value}` inside a factory and the overlay content tracks the state live.
41
48
 
42
49
  ## Default padding
43
50
 
@@ -1,53 +1,87 @@
1
- # schmancy-steps-container / schmancy-step
1
+ # schmancy-steps / schmancy-step
2
2
 
3
- > Vertical stepper with collapsible steps, completion state, and navigation.
3
+ > Vertical stepper with orientation rail and optional collapsible content. Dual render mode decided per step by content presence.
4
4
 
5
5
  ## Usage
6
+
6
7
  ```html
7
- <schmancy-steps-container currentStep="1" @change=${(e) => handleStep(e.detail.value)}>
8
- <schmancy-step position="1" title="Account" description="Create your account">
8
+ <!-- Rail mode (no slotted content) dot + connector + label -->
9
+ <schmancy-steps
10
+ class="flex flex-col"
11
+ .value=${activeStep}
12
+ @change=${(e) => handleStep(e.detail.value)}
13
+ >
14
+ <schmancy-step position="1" label="Organisation"></schmancy-step>
15
+ <schmancy-step position="2" label="Legal entity"></schmancy-step>
16
+ <schmancy-step position="3" label="Location"></schmancy-step>
17
+ <schmancy-step position="4" label="Done"></schmancy-step>
18
+ </schmancy-steps>
19
+
20
+ <!-- Content mode (slotted content) — collapsible card, active step expands -->
21
+ <schmancy-steps .value=${activeStep} @change=${(e) => handleStep(e.detail.value)}>
22
+ <schmancy-step position="1" label="Account" description="Create your account">
9
23
  <schmancy-input label="Email" required></schmancy-input>
10
24
  </schmancy-step>
11
- <schmancy-step position="2" title="Profile" description="Set up profile">
25
+ <schmancy-step position="2" label="Profile" description="Set up profile">
12
26
  <schmancy-input label="Name" required></schmancy-input>
13
27
  </schmancy-step>
14
- </schmancy-steps-container>
28
+ </schmancy-steps>
15
29
  ```
16
30
 
17
- ## Properties (schmancy-steps-container)
18
- | Property | Type | Default | Description |
19
- |----------|------|---------|-------------|
20
- | currentStep | number | `1` | Currently active step (1-based) |
21
- | gap | number | `4` | Gap between steps (Tailwind scale) |
31
+ ## Properties schmancy-steps
22
32
 
23
- ## Properties (schmancy-step)
24
33
  | Property | Type | Default | Description |
25
- |----------|------|---------|-------------|
26
- | position | number | `1` | Step position (1-based) |
27
- | title | string | `''` | Step title |
28
- | description | string | `''` | Step description |
29
- | completed | boolean | `false` | Explicitly mark as complete |
30
- | lockBack | boolean | `false` | Prevent navigating to previous steps |
31
-
32
- ## Events (schmancy-steps-container)
34
+ |---|---|---|---|
35
+ | `value` | `number` | `1` | Active step (1-based). Reflected attribute. |
36
+ | `lockBack` | `boolean` | `false` | Block back-navigation for the whole stepper. |
37
+
38
+ Layout (spacing, orientation, width) is set by Tailwind classes on the host element; the primitive owns no layout props.
39
+
40
+ ## Events — schmancy-steps
41
+
33
42
  | Event | Detail | Description |
34
- |-------|--------|-------------|
35
- | change | `{ value: number }` | When current step changes |
43
+ |---|---|---|
44
+ | `change` | `{ value: number }` | Active step changed (property set or step click). |
45
+
46
+ ```ts
47
+ export type SchmancyStepsChangeEvent = CustomEvent<{ value: number }>
48
+ ```
49
+
50
+ ## Properties — schmancy-step
51
+
52
+ | Property | Type | Default | Description |
53
+ |---|---|---|---|
54
+ | `position` | `number` | `1` | This step's 1-based index. Unique within the container. |
55
+ | `label` | `string` | `''` | Step label. |
56
+ | `description` | `string` | `''` | Secondary line (content mode only). |
57
+ | `completed` | `boolean` | `false` | Force complete status regardless of order. |
58
+
59
+ ## Dual render mode
60
+
61
+ A `<schmancy-step>` detects its own content via `slotchange`:
62
+
63
+ - **With slotted content** — renders an interactive card row (icon circle, check/dot, label + description, `bg-primary-container/20` active card). The active step expands with `flex: 1 1 auto`; inactive steps collapse.
64
+ - **Without slotted content** — renders a minimal orientation rail row (dot + connector + label). Use this for a left-panel navigation rail.
65
+
66
+ ## Step status
67
+
68
+ | Condition | Status |
69
+ |---|---|
70
+ | `position < value` or `completed` | `complete` |
71
+ | `position === value` | `current` |
72
+ | `position > value` | `upcoming` |
73
+
74
+ Clicking a `complete` or `current` step sets `value` and emits `change`. `upcoming` steps are inert. Back-navigation is blocked when the container has `lockBack`.
36
75
 
37
76
  ## Examples
77
+
38
78
  ```html
39
- <!-- With locked steps -->
40
- <schmancy-steps-container currentStep="2">
41
- <schmancy-step position="1" title="Step 1" completed lockBack>
42
- <!-- Already completed, cannot go back -->
43
- </schmancy-step>
44
- <schmancy-step position="2" title="Step 2">
79
+ <!-- Lock back-navigation after the first step -->
80
+ <schmancy-steps .value=${step} lockBack @change=${onStep}>
81
+ <schmancy-step position="1" label="Review" completed></schmancy-step>
82
+ <schmancy-step position="2" label="Confirm">
45
83
  <p>Current step content</p>
46
84
  </schmancy-step>
47
- <schmancy-step position="3" title="Step 3">
48
- <!-- Not yet reachable -->
49
- </schmancy-step>
50
- </schmancy-steps-container>
85
+ <schmancy-step position="3" label="Done"></schmancy-step>
86
+ </schmancy-steps>
51
87
  ```
52
-
53
- Only the active step renders its slotted content. Completed steps show a checkmark. Active step expands with `flex: 1`.
@@ -245,7 +245,7 @@ export class SchmancyArea extends SchmancyElement {
245
245
  area.$current.next(area.current)
246
246
 
247
247
  if (area.enableHistoryMode) {
248
- area._updateBrowserHistory(
248
+ area.updateBrowserHistory(
249
249
  this.name,
250
250
  activeRoute,
251
251
  carry.historyStrategy ?? HISTORY_STRATEGY.push,
@@ -938,8 +938,8 @@ describe('AreaService - Integration Tests', () => {
938
938
  props: {}
939
939
  })
940
940
 
941
- // Call _updateBrowserHistory directly to test history behavior
942
- area._updateBrowserHistory('main', {
941
+ // Call updateBrowserHistory directly to test history behavior
942
+ area.updateBrowserHistory('main', {
943
943
  area: 'main',
944
944
  component: 'test',
945
945
  state: {},
@@ -352,7 +352,7 @@ class AreaService implements AreaSubscription {
352
352
  /**
353
353
  * Update browser history state (called by area components)
354
354
  */
355
- _updateBrowserHistory(areaName: string, route: ActiveRoute, historyStrategy?: string, clearQueryParams?: string[] | boolean | null, customPath?: string) {
355
+ updateBrowserHistory(areaName: string, route: ActiveRoute, historyStrategy?: string, clearQueryParams?: string[] | boolean | null, customPath?: string) {
356
356
  if (!this.enableHistoryMode) return
357
357
 
358
358
  try {