@mhmo91/schmancy 0.10.19 → 0.10.20

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 (326) hide show
  1. package/custom-elements.json +0 -13
  2. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js → overlay.confirm-body-mYm0zq4k.js} +1 -1
  3. package/dist/agent/{overlay.confirm-body-D3jQyXgA.js.map → overlay.confirm-body-mYm0zq4k.js.map} +1 -1
  4. package/dist/agent/schmancy.agent.js +808 -882
  5. package/dist/agent/schmancy.agent.js.map +1 -1
  6. package/dist/agent/schmancy.manifest.json +1 -9
  7. package/dist/area-C7MNn-3e.cjs +12 -0
  8. package/dist/area-C7MNn-3e.cjs.map +1 -0
  9. package/dist/{area-BIipuSyO.js → area-CRe41aIG.js} +91 -130
  10. package/dist/area-CRe41aIG.js.map +1 -0
  11. package/dist/area.cjs +1 -1
  12. package/dist/area.js +1 -1
  13. package/dist/{autocomplete-Mrb3koUN.js → autocomplete-CRDFL4Ul.js} +2 -2
  14. package/dist/{autocomplete-Mrb3koUN.js.map → autocomplete-CRDFL4Ul.js.map} +1 -1
  15. package/dist/{autocomplete-B8CE5vGw.cjs → autocomplete-CqUl7o0e.cjs} +1 -1
  16. package/dist/{autocomplete-B8CE5vGw.cjs.map → autocomplete-CqUl7o0e.cjs.map} +1 -1
  17. package/dist/autocomplete.cjs +1 -1
  18. package/dist/autocomplete.js +1 -1
  19. package/dist/avatar.cjs +1 -1
  20. package/dist/avatar.js +1 -1
  21. package/dist/badge.cjs +1 -1
  22. package/dist/badge.js +1 -1
  23. package/dist/{boat-OatK_MGh.cjs → boat-BHV5kOlN.cjs} +1 -1
  24. package/dist/{boat-OatK_MGh.cjs.map → boat-BHV5kOlN.cjs.map} +1 -1
  25. package/dist/{boat-CNWIQPA1.js → boat-XajM8A3M.js} +1 -1
  26. package/dist/{boat-CNWIQPA1.js.map → boat-XajM8A3M.js.map} +1 -1
  27. package/dist/boat.cjs +1 -1
  28. package/dist/boat.js +1 -1
  29. package/dist/breadcrumb.cjs +1 -1
  30. package/dist/breadcrumb.js +1 -1
  31. package/dist/{busy-CMKX4oQf.cjs → busy-BlBZ5ZOs.cjs} +1 -1
  32. package/dist/{busy-CMKX4oQf.cjs.map → busy-BlBZ5ZOs.cjs.map} +1 -1
  33. package/dist/{busy-Cetzws-m.js → busy-D8YsqVBf.js} +1 -1
  34. package/dist/{busy-Cetzws-m.js.map → busy-D8YsqVBf.js.map} +1 -1
  35. package/dist/busy.cjs +1 -1
  36. package/dist/busy.js +1 -1
  37. package/dist/button.cjs +15 -9
  38. package/dist/button.cjs.map +1 -1
  39. package/dist/button.js +15 -9
  40. package/dist/button.js.map +1 -1
  41. package/dist/{card-D2k3dRL0.js → card-C9TljY2Z.js} +1 -1
  42. package/dist/{card-D2k3dRL0.js.map → card-C9TljY2Z.js.map} +1 -1
  43. package/dist/{card-8VXoo2C_.cjs → card-yT_St83D.cjs} +1 -1
  44. package/dist/{card-8VXoo2C_.cjs.map → card-yT_St83D.cjs.map} +1 -1
  45. package/dist/card.cjs +1 -1
  46. package/dist/card.js +1 -1
  47. package/dist/{checkbox-8hNsBejz.js → checkbox-BDgh4rge.js} +1 -1
  48. package/dist/{checkbox-8hNsBejz.js.map → checkbox-BDgh4rge.js.map} +1 -1
  49. package/dist/{checkbox-Cq5wzeaY.cjs → checkbox-Dz2lkJs0.cjs} +1 -1
  50. package/dist/{checkbox-Cq5wzeaY.cjs.map → checkbox-Dz2lkJs0.cjs.map} +1 -1
  51. package/dist/checkbox.cjs +1 -1
  52. package/dist/checkbox.js +1 -1
  53. package/dist/{chips-Dx_WvOGk.cjs → chips-M7Dr2npv.cjs} +2 -4
  54. package/dist/chips-M7Dr2npv.cjs.map +1 -0
  55. package/dist/{chips-D1kJrbzo.js → chips-N7fu0hA4.js} +3 -5
  56. package/dist/chips-N7fu0hA4.js.map +1 -0
  57. package/dist/chips.cjs +1 -1
  58. package/dist/chips.js +2 -2
  59. package/dist/connectivity.cjs +1 -1
  60. package/dist/connectivity.js +1 -1
  61. package/dist/content-drawer.cjs +1 -1
  62. package/dist/content-drawer.js +1 -1
  63. package/dist/{date-range-H903Vt_r.cjs → date-range-D2vxD814.cjs} +1 -1
  64. package/dist/{date-range-H903Vt_r.cjs.map → date-range-D2vxD814.cjs.map} +1 -1
  65. package/dist/{date-range-Dv-DM6mB.js → date-range-DFWOMgI3.js} +2 -2
  66. package/dist/{date-range-Dv-DM6mB.js.map → date-range-DFWOMgI3.js.map} +1 -1
  67. package/dist/{date-range-inline-Bvs2ZvEY.cjs → date-range-inline-C5JuZ_Kw.cjs} +1 -1
  68. package/dist/{date-range-inline-Bvs2ZvEY.cjs.map → date-range-inline-C5JuZ_Kw.cjs.map} +1 -1
  69. package/dist/{date-range-inline-TWWnTZlw.js → date-range-inline-D3q1OoKk.js} +1 -1
  70. package/dist/{date-range-inline-TWWnTZlw.js.map → date-range-inline-D3q1OoKk.js.map} +1 -1
  71. package/dist/date-range-inline.cjs +1 -1
  72. package/dist/date-range-inline.js +1 -1
  73. package/dist/date-range.cjs +1 -1
  74. package/dist/date-range.js +1 -1
  75. package/dist/delay.cjs +1 -1
  76. package/dist/delay.js +1 -1
  77. package/dist/{details-Cpg8sH2F.js → details-BrUPmd92.js} +2 -2
  78. package/dist/details-BrUPmd92.js.map +1 -0
  79. package/dist/{details-CwSDur6j.cjs → details-DmDEInaL.cjs} +2 -2
  80. package/dist/details-DmDEInaL.cjs.map +1 -0
  81. package/dist/details.cjs +1 -1
  82. package/dist/details.js +1 -1
  83. package/dist/{divider-Be833gGZ.js → divider-BLijs8ba.js} +1 -1
  84. package/dist/{divider-Be833gGZ.js.map → divider-BLijs8ba.js.map} +1 -1
  85. package/dist/{divider-BNdVLE0H.cjs → divider-B_Ts_-qz.cjs} +1 -1
  86. package/dist/{divider-BNdVLE0H.cjs.map → divider-B_Ts_-qz.cjs.map} +1 -1
  87. package/dist/divider.cjs +1 -1
  88. package/dist/divider.js +1 -1
  89. package/dist/dropdown.cjs +1 -1
  90. package/dist/dropdown.js +1 -1
  91. package/dist/{expand-CtoffNNj.js → expand-C-xSpg7M.js} +2 -2
  92. package/dist/{expand-CtoffNNj.js.map → expand-C-xSpg7M.js.map} +1 -1
  93. package/dist/{expand-BP6RLzHw.cjs → expand-DV5sWUB6.cjs} +1 -1
  94. package/dist/{expand-BP6RLzHw.cjs.map → expand-DV5sWUB6.cjs.map} +1 -1
  95. package/dist/expand.cjs +1 -1
  96. package/dist/expand.js +1 -1
  97. package/dist/{float-CfbQM_2v.cjs → float-LyKef0LY.cjs} +1 -1
  98. package/dist/{float-CfbQM_2v.cjs.map → float-LyKef0LY.cjs.map} +1 -1
  99. package/dist/{float-KmbhaQHA.js → float-Y22yVBE2.js} +1 -1
  100. package/dist/{float-KmbhaQHA.js.map → float-Y22yVBE2.js.map} +1 -1
  101. package/dist/float.cjs +1 -1
  102. package/dist/float.js +1 -1
  103. package/dist/{form-CuBIrKOA.cjs → form-C_smXI2-.cjs} +1 -1
  104. package/dist/{form-CuBIrKOA.cjs.map → form-C_smXI2-.cjs.map} +1 -1
  105. package/dist/{form-8IcmP8uV.js → form-LFkEQkOX.js} +8 -8
  106. package/dist/{form-8IcmP8uV.js.map → form-LFkEQkOX.js.map} +1 -1
  107. package/dist/form.cjs +1 -1
  108. package/dist/form.js +6 -6
  109. package/dist/handover/agent-runtime-followups.md +1 -1
  110. package/dist/handover/agent-runtime-v1.md +3 -3
  111. package/dist/{icons-D7df1ysG.js → icons-B3pFrwKC.js} +1 -1
  112. package/dist/{icons-D7df1ysG.js.map → icons-B3pFrwKC.js.map} +1 -1
  113. package/dist/{icons-BJld4JHp.cjs → icons-CCNy4Egc.cjs} +1 -1
  114. package/dist/{icons-BJld4JHp.cjs.map → icons-CCNy4Egc.cjs.map} +1 -1
  115. package/dist/icons.cjs +1 -1
  116. package/dist/icons.js +1 -1
  117. package/dist/{iframe-DAbgW9tT.js → iframe-BbFlCEyP.js} +1 -1
  118. package/dist/{iframe-DAbgW9tT.js.map → iframe-BbFlCEyP.js.map} +1 -1
  119. package/dist/{iframe-GT6D8l5Z.cjs → iframe-CCcmLZ_K.cjs} +1 -1
  120. package/dist/{iframe-GT6D8l5Z.cjs.map → iframe-CCcmLZ_K.cjs.map} +1 -1
  121. package/dist/iframe.cjs +1 -1
  122. package/dist/iframe.js +1 -1
  123. package/dist/index.cjs +1 -1
  124. package/dist/index.js +27 -27
  125. package/dist/{input-DC6ap_uN.js → input-Dkneo4uA.js} +2 -2
  126. package/dist/{input-DC6ap_uN.js.map → input-Dkneo4uA.js.map} +1 -1
  127. package/dist/{input-chip-c5n547tg.js → input-chip-C1-TYu4v.js} +1 -1
  128. package/dist/{input-chip-c5n547tg.js.map → input-chip-C1-TYu4v.js.map} +1 -1
  129. package/dist/{input-chip-MsiMu-b5.cjs → input-chip-F5NEkkBU.cjs} +1 -1
  130. package/dist/{input-chip-MsiMu-b5.cjs.map → input-chip-F5NEkkBU.cjs.map} +1 -1
  131. package/dist/{input-BE9wEEw4.cjs → input-sBZ89wz1.cjs} +1 -1
  132. package/dist/{input-BE9wEEw4.cjs.map → input-sBZ89wz1.cjs.map} +1 -1
  133. package/dist/input.cjs +1 -1
  134. package/dist/input.js +1 -1
  135. package/dist/json.cjs +1 -1
  136. package/dist/json.js +2 -2
  137. package/dist/kbd.cjs +1 -1
  138. package/dist/kbd.js +1 -1
  139. package/dist/layout.cjs +1 -1
  140. package/dist/layout.js +1 -1
  141. package/dist/{lightbox-HqJBBjAT.cjs → lightbox-B4m5lxGs.cjs} +1 -1
  142. package/dist/{lightbox-HqJBBjAT.cjs.map → lightbox-B4m5lxGs.cjs.map} +1 -1
  143. package/dist/{lightbox-CNX9Eg3U.js → lightbox-D7hYFspE.js} +1 -1
  144. package/dist/{lightbox-CNX9Eg3U.js.map → lightbox-D7hYFspE.js.map} +1 -1
  145. package/dist/lightbox.cjs +1 -1
  146. package/dist/lightbox.js +1 -1
  147. package/dist/{list-bhyuQSyO.cjs → list-C2ycz-yr.cjs} +1 -1
  148. package/dist/{list-bhyuQSyO.cjs.map → list-C2ycz-yr.cjs.map} +1 -1
  149. package/dist/{list-C76Pb-c1.js → list-Ou72tSeq.js} +1 -1
  150. package/dist/{list-C76Pb-c1.js.map → list-Ou72tSeq.js.map} +1 -1
  151. package/dist/list.cjs +1 -1
  152. package/dist/list.js +1 -1
  153. package/dist/{menu-BqKQ-s0C.cjs → menu-ComSx-T0.cjs} +1 -1
  154. package/dist/{menu-BqKQ-s0C.cjs.map → menu-ComSx-T0.cjs.map} +1 -1
  155. package/dist/{menu-C5ksITpG.js → menu-YHbpRa7x.js} +2 -2
  156. package/dist/{menu-C5ksITpG.js.map → menu-YHbpRa7x.js.map} +1 -1
  157. package/dist/menu.cjs +1 -1
  158. package/dist/menu.js +1 -1
  159. package/dist/mixins-B9kY_60p.js +636 -0
  160. package/dist/{mixins-DCVXqL1Q.js.map → mixins-B9kY_60p.js.map} +1 -1
  161. package/dist/mixins-BwGJwK7X.cjs +254 -0
  162. package/dist/{mixins-Du9HMrIG.cjs.map → mixins-BwGJwK7X.cjs.map} +1 -1
  163. package/dist/mixins.cjs +1 -1
  164. package/dist/mixins.js +1 -1
  165. package/dist/nav-drawer.cjs +1 -1
  166. package/dist/nav-drawer.js +1 -1
  167. package/dist/navigation-bar.cjs +1 -1
  168. package/dist/navigation-bar.js +1 -1
  169. package/dist/navigation-rail.cjs +1 -1
  170. package/dist/navigation-rail.js +1 -1
  171. package/dist/{notification-DR3gvWt8.cjs → notification-DZhL0ZEg.cjs} +1 -1
  172. package/dist/{notification-DR3gvWt8.cjs.map → notification-DZhL0ZEg.cjs.map} +1 -1
  173. package/dist/{notification-eZxtr3NN.js → notification-O4Q5pyio.js} +2 -2
  174. package/dist/{notification-eZxtr3NN.js.map → notification-O4Q5pyio.js.map} +1 -1
  175. package/dist/notification.cjs +1 -1
  176. package/dist/notification.js +1 -1
  177. package/dist/{option-CBEHYG4U.js → option-BCks0a4i.js} +1 -1
  178. package/dist/{option-CBEHYG4U.js.map → option-BCks0a4i.js.map} +1 -1
  179. package/dist/{option-BDOKUqTy.cjs → option-C2VKw8Yt.cjs} +1 -1
  180. package/dist/{option-BDOKUqTy.cjs.map → option-C2VKw8Yt.cjs.map} +1 -1
  181. package/dist/option.cjs +1 -1
  182. package/dist/option.js +1 -1
  183. package/dist/{overlay-oxM9OLXP.js → overlay-C0YSnxoV.js} +8 -10
  184. package/dist/overlay-C0YSnxoV.js.map +1 -0
  185. package/dist/{overlay-DG6EeyKt.cjs → overlay-CG1gc1Jw.cjs} +2 -2
  186. package/dist/overlay-CG1gc1Jw.cjs.map +1 -0
  187. package/dist/overlay.cjs +1 -1
  188. package/dist/{overlay.confirm-body-78e1WrN9.cjs → overlay.confirm-body-B-Kmn7LF.cjs} +1 -1
  189. package/dist/{overlay.confirm-body-78e1WrN9.cjs.map → overlay.confirm-body-B-Kmn7LF.cjs.map} +1 -1
  190. package/dist/{overlay.confirm-body-D_P2e7l6.js → overlay.confirm-body-BmOnrKbF.js} +1 -1
  191. package/dist/{overlay.confirm-body-D_P2e7l6.js.map → overlay.confirm-body-BmOnrKbF.js.map} +1 -1
  192. package/dist/overlay.js +3 -3
  193. package/dist/{overlay.service-DQkGPUY7.cjs → overlay.service-BPKV2a8w.cjs} +1 -1
  194. package/dist/{overlay.service-DQkGPUY7.cjs.map → overlay.service-BPKV2a8w.cjs.map} +1 -1
  195. package/dist/{overlay.service-C8NwO4Bx.js → overlay.service-CRoq9Gu-.js} +2 -2
  196. package/dist/{overlay.service-C8NwO4Bx.js.map → overlay.service-CRoq9Gu-.js.map} +1 -1
  197. package/dist/page.cjs +1 -1
  198. package/dist/page.js +2 -2
  199. package/dist/{progress-CMSst_2U.cjs → progress-B9RWAFv5.cjs} +1 -1
  200. package/dist/{progress-CMSst_2U.cjs.map → progress-B9RWAFv5.cjs.map} +1 -1
  201. package/dist/{progress-C4kDZfb7.js → progress-CEEl7vdd.js} +1 -1
  202. package/dist/{progress-C4kDZfb7.js.map → progress-CEEl7vdd.js.map} +1 -1
  203. package/dist/progress.cjs +1 -1
  204. package/dist/progress.js +1 -1
  205. package/dist/radio-group-C2y6H5YY.cjs +19 -0
  206. package/dist/radio-group-C2y6H5YY.cjs.map +1 -0
  207. package/dist/radio-group-VERF_8rC.js +71 -0
  208. package/dist/radio-group-VERF_8rC.js.map +1 -0
  209. package/dist/radio-group.cjs +1 -1
  210. package/dist/radio-group.js +1 -1
  211. package/dist/range.cjs +1 -1
  212. package/dist/range.js +1 -1
  213. package/dist/{scroll-C1klVgSQ.js → scroll-Bj7FsS08.js} +1 -1
  214. package/dist/{scroll-C1klVgSQ.js.map → scroll-Bj7FsS08.js.map} +1 -1
  215. package/dist/{scroll-S-bXF2u6.cjs → scroll-Djz3pJfX.cjs} +1 -1
  216. package/dist/{scroll-S-bXF2u6.cjs.map → scroll-Djz3pJfX.cjs.map} +1 -1
  217. package/dist/{select-UU2pB67h.js → select-ClJj_2AP.js} +3 -3
  218. package/dist/select-ClJj_2AP.js.map +1 -0
  219. package/dist/select-CngphfDB.cjs +56 -0
  220. package/dist/select-CngphfDB.cjs.map +1 -0
  221. package/dist/select.cjs +1 -1
  222. package/dist/select.js +1 -1
  223. package/dist/skeleton.cjs +1 -1
  224. package/dist/skeleton.js +1 -1
  225. package/dist/skills/SKILL.md +12 -0
  226. package/dist/skills/schmancy/SKILL.md +12 -0
  227. package/dist/slider.cjs +1 -1
  228. package/dist/slider.js +1 -1
  229. package/dist/{splash-screen-ChMkAPLU.js → splash-screen-BQsBy3O1.js} +1 -1
  230. package/dist/{splash-screen-ChMkAPLU.js.map → splash-screen-BQsBy3O1.js.map} +1 -1
  231. package/dist/{splash-screen-BvaDkvJU.cjs → splash-screen-CntIFk2h.cjs} +1 -1
  232. package/dist/{splash-screen-BvaDkvJU.cjs.map → splash-screen-CntIFk2h.cjs.map} +1 -1
  233. package/dist/splash-screen.cjs +1 -1
  234. package/dist/splash-screen.js +1 -1
  235. package/dist/{src-DnunCC4X.js → src-BAXhEv8f.js} +32 -32
  236. package/dist/{src-DnunCC4X.js.map → src-BAXhEv8f.js.map} +1 -1
  237. package/dist/{src-BIlD63Cz.cjs → src-ChFa-FDD.cjs} +1 -1
  238. package/dist/{src-BIlD63Cz.cjs.map → src-ChFa-FDD.cjs.map} +1 -1
  239. package/dist/steps.cjs +1 -1
  240. package/dist/steps.js +1 -1
  241. package/dist/{surface-DCRy-EyT.js → surface-CHUJSY1o.js} +1 -1
  242. package/dist/{surface-DCRy-EyT.js.map → surface-CHUJSY1o.js.map} +1 -1
  243. package/dist/{surface-DWwQDX9r.cjs → surface-CXmQuXun.cjs} +1 -1
  244. package/dist/{surface-DWwQDX9r.cjs.map → surface-CXmQuXun.cjs.map} +1 -1
  245. package/dist/surface.cjs +1 -1
  246. package/dist/surface.js +1 -1
  247. package/dist/switch.cjs +1 -1
  248. package/dist/switch.js +1 -1
  249. package/dist/table.cjs +1 -1
  250. package/dist/table.js +1 -1
  251. package/dist/{tabs-lxQHWEb7.cjs → tabs-Bku0sC0p.cjs} +1 -1
  252. package/dist/{tabs-lxQHWEb7.cjs.map → tabs-Bku0sC0p.cjs.map} +1 -1
  253. package/dist/{tabs-CkDNLbiS.js → tabs-DPVX21WM.js} +1 -1
  254. package/dist/{tabs-CkDNLbiS.js.map → tabs-DPVX21WM.js.map} +1 -1
  255. package/dist/tabs.cjs +1 -1
  256. package/dist/tabs.js +1 -1
  257. package/dist/teleport.cjs +1 -1
  258. package/dist/teleport.js +1 -1
  259. package/dist/{textarea-CNa4dSvF.cjs → textarea-CqJNviYi.cjs} +1 -1
  260. package/dist/{textarea-CNa4dSvF.cjs.map → textarea-CqJNviYi.cjs.map} +1 -1
  261. package/dist/{textarea-DkfGmRSI.js → textarea-D6z1UZzs.js} +1 -1
  262. package/dist/{textarea-DkfGmRSI.js.map → textarea-D6z1UZzs.js.map} +1 -1
  263. package/dist/textarea.cjs +1 -1
  264. package/dist/textarea.js +1 -1
  265. package/dist/{theme-CMyXTDht.cjs → theme-BpKVBJCr.cjs} +1 -1
  266. package/dist/{theme-CMyXTDht.cjs.map → theme-BpKVBJCr.cjs.map} +1 -1
  267. package/dist/{theme-CNWRYdfn.js → theme-DbHfINBV.js} +1 -1
  268. package/dist/{theme-CNWRYdfn.js.map → theme-DbHfINBV.js.map} +1 -1
  269. package/dist/{theme-button-CixloLin.js → theme-button-BeU8Nbs2.js} +1 -1
  270. package/dist/{theme-button-CixloLin.js.map → theme-button-BeU8Nbs2.js.map} +1 -1
  271. package/dist/{theme-button-kMhsX5Oe.cjs → theme-button-Cof9I85G.cjs} +1 -1
  272. package/dist/{theme-button-kMhsX5Oe.cjs.map → theme-button-Cof9I85G.cjs.map} +1 -1
  273. package/dist/theme-button.cjs +1 -1
  274. package/dist/theme-button.js +1 -1
  275. package/dist/theme.cjs +1 -1
  276. package/dist/theme.js +2 -2
  277. package/dist/tree.cjs +1 -1
  278. package/dist/tree.js +1 -1
  279. package/dist/typography.cjs +1 -1
  280. package/dist/typography.js +1 -1
  281. package/dist/visually-hidden.cjs +1 -1
  282. package/dist/visually-hidden.js +1 -1
  283. package/dist/{window-qaGFMn_4.cjs → window-Cql1aIX2.cjs} +1 -1
  284. package/dist/{window-qaGFMn_4.cjs.map → window-Cql1aIX2.cjs.map} +1 -1
  285. package/dist/{window-BcvDNi9D.js → window-DmMNsos0.js} +1 -1
  286. package/dist/{window-BcvDNi9D.js.map → window-DmMNsos0.js.map} +1 -1
  287. package/dist/window.cjs +1 -1
  288. package/dist/window.js +1 -1
  289. package/package.json +1 -1
  290. package/skills/schmancy/SKILL.md +12 -0
  291. package/src/CLAUDE.md +20 -0
  292. package/src/area/area.component.ts +155 -342
  293. package/src/button/button.ts +8 -5
  294. package/src/button/icon-button.ts +8 -5
  295. package/src/chips/filter-chip.ts +1 -3
  296. package/src/details/details.ts +1 -1
  297. package/src/form/fields/radio-group/radio-button.ts +22 -44
  298. package/src/form/fields/radio-group/radio-group.ts +20 -75
  299. package/src/form/fields/select/select.ts +3 -2
  300. package/src/overlay/overlay.component.ts +29 -39
  301. package/src/overlay/overlay.positioning.ts +10 -2
  302. package/src/state/schmancy-state.html +897 -0
  303. package/src/state/schmancy-state.md +981 -0
  304. package/types/src/area/area.component.d.ts +0 -15
  305. package/types/src/button/icon-button.d.ts +1 -1
  306. package/types/src/form/fields/radio-group/radio-button.d.ts +2 -5
  307. package/types/src/form/fields/radio-group/radio-group.d.ts +2 -10
  308. package/types/src/overlay/overlay.positioning.d.ts +9 -1
  309. package/dist/area-BIipuSyO.js.map +0 -1
  310. package/dist/area-C-EMiNEE.cjs +0 -12
  311. package/dist/area-C-EMiNEE.cjs.map +0 -1
  312. package/dist/chips-D1kJrbzo.js.map +0 -1
  313. package/dist/chips-Dx_WvOGk.cjs.map +0 -1
  314. package/dist/details-Cpg8sH2F.js.map +0 -1
  315. package/dist/details-CwSDur6j.cjs.map +0 -1
  316. package/dist/mixins-DCVXqL1Q.js +0 -636
  317. package/dist/mixins-Du9HMrIG.cjs +0 -254
  318. package/dist/overlay-DG6EeyKt.cjs.map +0 -1
  319. package/dist/overlay-oxM9OLXP.js.map +0 -1
  320. package/dist/radio-group-DB9D2ZkA.js +0 -108
  321. package/dist/radio-group-DB9D2ZkA.js.map +0 -1
  322. package/dist/radio-group-dVUvYFq7.cjs +0 -40
  323. package/dist/radio-group-dVUvYFq7.cjs.map +0 -1
  324. package/dist/select-UU2pB67h.js.map +0 -1
  325. package/dist/select-fu_-rZyn.cjs +0 -56
  326. package/dist/select-fu_-rZyn.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"input-BE9wEEw4.cjs","names":[],"sources":["../src/form/fields/input/input.scss?inline","../src/form/fields/input/input.ts"],"sourcesContent":[" @reference \"tailwindcss\";\n\n:host {\n\t@apply block w-full min-w-0;\n\t/* Ensure no constraints on mobile */\n\tmax-width: 100%;\n\tbox-sizing: border-box;\n}\n\n/* Date input container needs special handling on mobile */\n.date-input-container {\n\t@apply w-full;\n\t/* Explicit width for mobile Safari */\n\twidth: 100% !important;\n\tmax-width: 100% !important;\n\tmin-width: 0;\n}\n\n/* Reset native input styles for consistency */\ninput {\n\t/* Remove all native styling */\n\t@apply appearance-none rounded-[8px];\n\t/* Prevent Safari zoom on focus */\n\tfont-size: 16px;\n\twidth: -webkit-fill-available;\n\t/* Ensure border radius is applied */\n\tborder-radius: 8px;\n\t/* Smooth transitions for luminous focus */\n\ttransition:\n\t\tbox-shadow 300ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\tborder-color 200ms ease;\n}\n\n/* Luminous focus glow — light-based depth on focus */\ninput:focus {\n\tbox-shadow:\n\t\t0 0 0 1px var(--schmancy-sys-color-secondary-default),\n\t\t0 0 16px -4px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 20%, transparent);\n}\n\n/* Luminous error glow — red glow on error focus */\ninput[aria-invalid=\"true\"] {\n\tbox-shadow: 0 0 12px -4px color-mix(in srgb, var(--schmancy-sys-color-error-default) 15%, transparent);\n}\ninput[aria-invalid=\"true\"]:focus {\n\tbox-shadow:\n\t\t0 0 0 1px var(--schmancy-sys-color-error-default),\n\t\t0 0 16px -4px color-mix(in srgb, var(--schmancy-sys-color-error-default) 25%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n\tinput { transition: none; }\n}\n\n/* Remove number input spinners */\ninput[type='number']::-webkit-inner-spin-button,\ninput[type='number']::-webkit-outer-spin-button {\n\t-webkit-appearance: none;\n\tappearance: none;\n\t@apply m-0;\n}\n\ninput[type='number'] {\n\t-moz-appearance: textfield;\n\tappearance: textfield;\n}\n\n/* Autofill styling */\n@keyframes onAutoFillStart {\n\tfrom {}\n\tto {}\n}\n\ninput:-webkit-autofill {\n\tanimation-name: onAutoFillStart;\n\t/* Use box-shadow trick to override autofill background */\n\t-webkit-box-shadow: 0 0 0 30px var(--schmancy-sys-color-surface-highest) inset !important;\n\t-webkit-text-fill-color: var(--schmancy-sys-color-surface-on) !important;\n}\n\n/* Simplified autofill for all browsers */\ninput:autofill {\n\tbackground-color: var(--schmancy-sys-color-surface-highest) !important;\n\tcolor: var(--schmancy-sys-color-surface-on) !important;\n}\n\n/* Date and datetime inputs need special handling */\ninput[type=\"date\"],\ninput[type=\"datetime-local\"],\ninput[type=\"time\"],\ninput[type=\"month\"],\ninput[type=\"week\"] {\n\t/* Ensure consistent height and padding */\n\t@apply block w-full rounded-[8px];\n\t/* Reset WebKit styling */\n\t-webkit-appearance: none;\n\tappearance: none;\n\t/* Ensure text doesn't get cut off */\n\tline-height: inherit;\n\t/* Force full width on mobile */\n\twidth: 100% !important;\n\tmin-width: 100%;\n\tmax-width: 100%;\n\t/* Remove any default margins */\n\tmargin: 0;\n\t/* Force border radius */\n\tborder-radius: 8px !important;\n\toverflow: hidden;\n}\n\n/* WebKit date/time edit container - this is what needs centering */\ninput::-webkit-datetime-edit,\ninput::-webkit-datetime-edit-fields-wrapper {\n\t/* Center the date/time fields vertically */\n\tdisplay: flex;\n\talign-items: center;\n\theight: 100%;\n\t/* Ensure full width on mobile */\n\twidth: 100%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\ninput::-webkit-datetime-edit {\n\t/* Ensure the edit container fills available space */\n\tflex: 1;\n\twidth: 100%;\n}\n\ninput::-webkit-datetime-edit-fields-wrapper {\n\t/* Make fields wrapper expand */\n\tflex: 1;\n\twidth: 100%;\n\tjustify-content: space-between;\n}\n\ninput::-webkit-datetime-edit-text {\n\t/* Ensure separators are also centered */\n\tdisplay: flex;\n\talign-items: center;\n}\n\n/* Individual date fields */\ninput::-webkit-datetime-edit-day-field,\ninput::-webkit-datetime-edit-month-field,\ninput::-webkit-datetime-edit-year-field,\ninput::-webkit-datetime-edit-hour-field,\ninput::-webkit-datetime-edit-minute-field,\ninput::-webkit-datetime-edit-second-field,\ninput::-webkit-datetime-edit-millisecond-field,\ninput::-webkit-datetime-edit-meridiem-field {\n\t/* Ensure fields don't shrink */\n\tflex-shrink: 0;\n\tpadding: 0 2px;\n}\n\n/* Safari date input calendar icon */\ninput[type=\"date\"]::-webkit-calendar-picker-indicator,\ninput[type=\"datetime-local\"]::-webkit-calendar-picker-indicator,\ninput[type=\"time\"]::-webkit-calendar-picker-indicator,\ninput[type=\"month\"]::-webkit-calendar-picker-indicator,\ninput[type=\"week\"]::-webkit-calendar-picker-indicator {\n\t/* Make the calendar icon more subtle */\n\topacity: 0.5;\n\tcursor: pointer;\n}\n\n/* Firefox date input styling */\n@-moz-document url-prefix() {\n\tinput[type=\"date\"],\n\tinput[type=\"datetime-local\"],\n\tinput[type=\"time\"] {\n\t\t/* Firefox needs explicit height */\n\t\tmin-height: inherit;\n\t}\n}\n\n/* iOS Safari specific fixes */\n@supports (-webkit-touch-callout: none) {\n\tinput[type=\"date\"],\n\tinput[type=\"datetime-local\"],\n\tinput[type=\"time\"],\n\tinput[type=\"month\"],\n\tinput[type=\"week\"] {\n\t\t/* iOS Safari needs explicit width */\n\t\twidth: -webkit-fill-available !important;\n\t\twidth: fill-available !important;\n\t\t/* Remove default iOS styling */\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\tborder-radius: 0;\n\t\t/* Remove default padding that causes issues */\n\t\tpadding-left: 12px !important;\n\t\tpadding-right: 12px !important;\n\t}\n\t\n\t/* Target shadow DOM elements on iOS */\n\tinput::-webkit-datetime-edit {\n\t\t/* Force full width */\n\t\twidth: 100% !important;\n\t\tpadding-left: 0 !important;\n\t\tpadding-right: 0 !important;\n\t}\n\t\n\tinput::-webkit-datetime-edit-fields-wrapper {\n\t\t/* Ensure proper spacing on mobile */\n\t\twidth: 100% !important;\n\t\tpadding: 0 !important;\n\t\tmargin: 0 !important;\n\t}\n}\n","import { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { distinctUntilChanged, filter, fromEvent, map, takeUntil, timer } from 'rxjs'\n\nimport { SchmancyFormField } from '@mixins/index'\n\n// Import styles\nimport style from './input.scss?inline'\n\n// If you want to be form-associated, define the type on `ElementInternals`.\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-input': SchmancyInput\n\t\t'sch-input': SchmancyInput\n\t}\n}\n\ntype EventDetails = {\n\tvalue: string\n}\n\n/**\n * Custom events the component may emit:\n * - 'input': on every keystroke\n * - 'change': on native blur/change\n * - 'enter': specifically when user presses Enter\n */\nexport type SchmancyInputInputEvent = CustomEvent<EventDetails>\nexport type SchmancyInputChangeEvent = CustomEvent<EventDetails>\nexport type SchmancyInputEnterEvent = CustomEvent<EventDetails>\n\n/**\n * Size variants for the input - M3 spec aligned.\n * - xxs: Ultra-compact (24dp) - for menu cards, compact UIs\n * - xs: Dense/compact (32dp) - M3 density -3\n * - sm: Default (40dp) - M3 density 0\n * - md: Standard (48dp) - M3 large\n * - lg: Extra large (56dp) - M3 extra large\n */\nexport type InputSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg'\n\n/**\n * Enhanced version of the SchmancyInput component with improved form integration\n * and compatibility with legacy API.\n *\n * This component uses the native form association API and maintains parity with\n * native input behaviors while providing a stylish, accessible interface.\n *\n * @prop {string} name - Name attribute for form submission (inherited from FormFieldMixin)\n * @prop {string} label - Label text for the form field (inherited from FormFieldMixin)\n * @prop {boolean} required - Whether the field is required (inherited from FormFieldMixin)\n * @prop {boolean} disabled - Whether the field is disabled (inherited from FormFieldMixin)\n * @prop {boolean} readonly - Whether the field is read-only (inherited from FormFieldMixin)\n * @prop {boolean} error - Whether the field is in an error state (inherited from FormFieldMixin)\n * @prop {string} validationMessage - The validation message to display (inherited from FormFieldMixin)\n * @prop {string} hint - Optional hint text to display below the field (inherited from FormFieldMixin)\n */\n@customElement('schmancy-input')\nexport default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {\n\t// ----------------------------\n\t// A) Public properties\n\t// ----------------------------\n\n\t/** Auto-incrementing counter for generating unique IDs */\n\tstatic _idCounter = 0\n\n\t/** Override value to be string only for input element */\n\t@property({ type: String, reflect: true })\n\tpublic override value = ''\n\n\n\t/**\n\t * The type of input. (e.g. 'text', 'password', 'email', etc.)\n\t */\n\t@property({ reflect: true })\n\tpublic type: HTMLInputElement['type'] = 'text'\n\n\n\t@property()\n\tpublic placeholder = ''\n\n\n\t/** Pattern validation attribute. */\n\t@property({ type: String, reflect: true })\n\tpublic pattern?: string\n\n\n\t/** If true, we visually show a pointer cursor even if readOnly. */\n\t@property({ type: Boolean, reflect: true }) public clickable = false\n\n\t/** Whether browser spellcheck is enabled. */\n\t@property({ type: Boolean, reflect: true })\n\tpublic spellcheck = false\n\n\t/**\n\t * Text alignment within the input.\n\t * - 'left' | 'center' | 'right'\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic align: 'left' | 'center' | 'right' = 'left'\n\n\t/** inputmode attribute (affects on-screen keyboards in mobile). */\n\t@property()\n\tpublic inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'\n\n\t@property({ type: Number, reflect: true })\n\tpublic minlength?: number\n\n\t@property({ type: Number })\n\tpublic maxlength?: number\n\n\t@property()\n\tpublic min?: string\n\n\t@property()\n\tpublic max?: string\n\n\t@property({ reflect: true })\n\tpublic step?: string = 'any'\n\n\t/** If true, auto-focus this input on first render. */\n\t@property({ type: Boolean })\n\tpublic autofocus = false\n\n\t/** Autocomplete/autofill hints. */\n\t@property({ type: String, reflect: true })\n\tpublic autocomplete: AutoFill = 'on'\n\n\t/**\n\t * tabIndex for focusing by tab key. Typically 0 or -1.\n\t */\n\t@property({ type: Number, reflect: true })\n\tpublic override tabIndex = 0\n\n\n\t/**\n\t * The size of the input.\n\t * - 'xxs': Ultra-compact size (24px) - for menu cards\n\t * - 'xs': Extra small, very compact size (32px)\n\t * - 'sm': Small, compact size (40px)\n\t * - 'md': Medium size (default) (48px)\n\t * - 'lg': Large size (56px)\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic size: InputSize = 'md'\n\n\t/**\n\t * For datalist support\n\t */\n\t@property({ type: String })\n\tpublic list?: string\n\n\n\t// ----------------------------\n\t// B) Queries & Refs\n\t// ----------------------------\n\t@query('input') private inputElement!: HTMLInputElement\n\tprivate inputRef = createRef<HTMLInputElement>()\n\n\t// ----------------------------\n\t// C) Internal States\n\t// ----------------------------\n\n\t/**\n\t * For integration with browser's autofill support\n\t */\n\t@state()\n\tprivate isAutofilled = false\n\n\t// `touched`, `dirty`, `submitted`, and `validateOn` come from FormFieldMixin.\n\t// `_defaultValue` (mixin) replaces the old `defaultValue` field.\n\n\t// ----------------------------\n\t// D) Form-associated logic\n\t// ----------------------------\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tdelegatesFocus: true, // so focus() goes to <input>\n\t}\n\n\t/**\n\t * If user did not provide an ID, auto-generate one so <label for=\"...\">\n\t * and various aria-* attributes can reference it.\n\t */\n\tprotected override willUpdate(changedProps: Map<PropertyKey, unknown>) {\n\t\tif (!this.id) {\n\t\t\tthis.id = `sch-input-${SchmancyInput._idCounter++}`\n\t\t}\n\t\tsuper.willUpdate(changedProps as never)\n\t}\n\n\n\t// `updated()` removed — FormFieldMixin's `willUpdate` recomputes `dirty`,\n\t// triggers `checkValidity()` when `_shouldShowError()` is true, and updates\n\t// `:state(dirty)` automatically.\n\t//\n\t// Default value capture is also handled by the mixin (`firstUpdated` sets\n\t// `_defaultValue` from `value`).\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Form reset and submit are now handled by the mixin via FACE callbacks\n\t\t// (`formResetCallback`) and by `<schmancy-form>`'s submit sweep\n\t\t// (`markSubmitted()`). No manual form listeners needed.\n\t\tthis.setupExternalLabelAssociation()\n\t}\n\n\t/**\n\t * Set up external label association for native HTML label support\n\t */\n\tprivate setupExternalLabelAssociation() {\n\t\tif (this.id) {\n\t\t\tconst setupLabelClickListener = () => {\n\t\t\t\tconst labels = document.querySelectorAll(`label[for=\"${this.id}\"]`)\n\t\t\t\tlabels.forEach(label => {\n\t\t\t\t\t// Use RxJS for label click events\n\t\t\t\t\tfromEvent(label, 'click')\n\t\t\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t\t\t.subscribe(() => {\n\t\t\t\t\t\t\tthis.focus()\n\t\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Initialize after DOM is ready\n\t\t\tif (document.readyState === 'complete') {\n\t\t\t\tsetupLabelClickListener()\n\t\t\t} else {\n\t\t\t\t// Use RxJS for DOMContentLoaded event\n\t\t\t\tfromEvent(document, 'DOMContentLoaded')\n\t\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t\t.subscribe(setupLabelClickListener)\n\t\t\t}\n\t\t}\n\t}\n\n\t// `disconnectedCallback`, `resetToDefault`, `shouldShowValidation`, and\n\t// `validateInput` are gone — the mixin's `willUpdate` runs `checkValidity()`\n\t// at the right moments (Phase 2/3/4 of the validation contract) and\n\t// `formResetCallback` → `resetForm()` handles reset.\n\n\t/**\n\t * Check validity. Folds in the inner native input's structured\n\t * `ValidityState` flags (`typeMismatch`, `patternMismatch`, `tooShort`,\n\t * `tooLong`, `rangeUnderflow`, `rangeOverflow`, `stepMismatch`, `badInput`)\n\t * via `internals.setValidity` so consumers can target specific flags via\n\t * `field.validity.<flag>` and `:state(value-missing|type-mismatch|…)`.\n\t *\n\t * The visual `error` flag is still gated by the mixin's `_shouldShowError()`.\n\t */\n\t/**\n\t * Re-run checkValidity AFTER render so the native inner input's `.value`\n\t * binding has propagated. The mixin's willUpdate fires checkValidity too\n\t * early — at that point native.validity still reflects the previous value.\n\t */\n\tprotected override updated(changedProps: Map<PropertyKey, unknown>) {\n\t\tsuper.updated?.(changedProps)\n\t\tif (\n\t\t\tchangedProps.has('value') ||\n\t\t\tchangedProps.has('required') ||\n\t\t\tchangedProps.has('type') ||\n\t\t\tchangedProps.has('pattern') ||\n\t\t\tchangedProps.has('min') ||\n\t\t\tchangedProps.has('max') ||\n\t\t\tchangedProps.has('minlength') ||\n\t\t\tchangedProps.has('maxlength')\n\t\t) {\n\t\t\tthis.checkValidity()\n\t\t}\n\t}\n\n\t/**\n\t * Pick the first matching `errorMessages` override for the failing flags.\n\t * Order matches the natural priority of validity flags (valueMissing\n\t * before more specific ones — empty trumps malformed).\n\t */\n\tprivate _firstMatchingErrorMessage(v: ValidityState): string | undefined {\n\t\tconst m = this.errorMessages\n\t\tif (!m) return undefined\n\t\tif (v.valueMissing && m.valueMissing) return m.valueMissing\n\t\tif (v.typeMismatch && m.typeMismatch) return m.typeMismatch\n\t\tif (v.patternMismatch && m.patternMismatch) return m.patternMismatch\n\t\tif (v.tooShort && m.tooShort) return m.tooShort\n\t\tif (v.tooLong && m.tooLong) return m.tooLong\n\t\tif (v.rangeUnderflow && m.rangeUnderflow) return m.rangeUnderflow\n\t\tif (v.rangeOverflow && m.rangeOverflow) return m.rangeOverflow\n\t\tif (v.stepMismatch && m.stepMismatch) return m.stepMismatch\n\t\tif (v.badInput && m.badInput) return m.badInput\n\t\treturn undefined\n\t}\n\n\tpublic override checkValidity() {\n\t\t// Prefer @query (always live) over @ref (may lag during initial paint).\n\t\tconst native = this.inputElement ?? this.inputRef.value\n\t\tconst v = native?.validity\n\t\tif (v && !v.valid) {\n\t\t\t// Surface the native flags. valueMissing also surfaces here when\n\t\t\t// `required` + empty — overrides the mixin's coarse check.\n\t\t\tconst flags: ValidityStateFlags = {\n\t\t\t\tvalueMissing: v.valueMissing || undefined,\n\t\t\t\ttypeMismatch: v.typeMismatch || undefined,\n\t\t\t\tpatternMismatch: v.patternMismatch || undefined,\n\t\t\t\ttooShort: v.tooShort || undefined,\n\t\t\t\ttooLong: v.tooLong || undefined,\n\t\t\t\trangeUnderflow: v.rangeUnderflow || undefined,\n\t\t\t\trangeOverflow: v.rangeOverflow || undefined,\n\t\t\t\tstepMismatch: v.stepMismatch || undefined,\n\t\t\t\tbadInput: v.badInput || undefined,\n\t\t\t\tcustomError: v.customError || undefined,\n\t\t\t}\n\t\t\t// errorMessages override: pick the first matching flag and use the\n\t\t\t// consumer-provided copy. Falls back to the native browser message.\n\t\t\tconst overrideMessage = this._firstMatchingErrorMessage(v)\n\t\t\tthis.internals?.setValidity(\n\t\t\t\tflags,\n\t\t\t\toverrideMessage || native.validationMessage || this.validationMessage || 'Invalid value',\n\t\t\t)\n\t\t\tif (this._shouldShowError()) {\n\t\t\t\tthis.error = true\n\t\t\t\t// Always reflect the current flag's message — previous\n\t\t\t\t// validationMessage may be stale (different flag).\n\t\t\t\tconst newMessage = overrideMessage || native.validationMessage\n\t\t\t\tif (newMessage) this.validationMessage = newMessage\n\t\t\t\t// Mirror flags into :state() so CSS can target specifics.\n\t\t\t\tfor (const flag of [\n\t\t\t\t\t'value-missing',\n\t\t\t\t\t'type-mismatch',\n\t\t\t\t\t'pattern-mismatch',\n\t\t\t\t\t'too-short',\n\t\t\t\t\t'too-long',\n\t\t\t\t\t'range-underflow',\n\t\t\t\t\t'range-overflow',\n\t\t\t\t\t'step-mismatch',\n\t\t\t\t\t'bad-input',\n\t\t\t\t]) {\n\t\t\t\t\tthis.internals?.states.delete(flag)\n\t\t\t\t}\n\t\t\t\tif (v.valueMissing) this.internals?.states.add('value-missing')\n\t\t\t\tif (v.typeMismatch) this.internals?.states.add('type-mismatch')\n\t\t\t\tif (v.patternMismatch) this.internals?.states.add('pattern-mismatch')\n\t\t\t\tif (v.tooShort) this.internals?.states.add('too-short')\n\t\t\t\tif (v.tooLong) this.internals?.states.add('too-long')\n\t\t\t\tif (v.rangeUnderflow) this.internals?.states.add('range-underflow')\n\t\t\t\tif (v.rangeOverflow) this.internals?.states.add('range-overflow')\n\t\t\t\tif (v.stepMismatch) this.internals?.states.add('step-mismatch')\n\t\t\t\tif (v.badInput) this.internals?.states.add('bad-input')\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\t// Native says valid — but the mixin's `required` check might still\n\t\t// fire (mixin checks `value === ''` directly, native may treat empty\n\t\t// differently for type=email/url with no value).\n\t\tconst parentValid = super.checkValidity()\n\t\tif (parentValid) {\n\t\t\t// Clear specific-flag :state() entries.\n\t\t\tfor (const flag of [\n\t\t\t\t'value-missing',\n\t\t\t\t'type-mismatch',\n\t\t\t\t'pattern-mismatch',\n\t\t\t\t'too-short',\n\t\t\t\t'too-long',\n\t\t\t\t'range-underflow',\n\t\t\t\t'range-overflow',\n\t\t\t\t'step-mismatch',\n\t\t\t\t'bad-input',\n\t\t\t]) {\n\t\t\t\tthis.internals?.states.delete(flag)\n\t\t\t}\n\t\t}\n\t\treturn parentValid\n\t}\n\n\t/**\n\t * Show validation UI and check validity.\n\t * Marks the field as submitted so the mixin's gate flips to \"always show.\"\n\t */\n\tpublic override reportValidity() {\n\t\tthis.markSubmitted()\n\t\tconst inputValid = this.inputRef.value?.reportValidity() ?? true\n\t\tconst parentValid = super.reportValidity()\n\t\treturn inputValid && parentValid\n\t}\n\n\t/** Set a custom validation error on both the inner input and the mixin. */\n\tpublic override setCustomValidity(message: string) {\n\t\tif (this.inputRef.value) {\n\t\t\tthis.inputRef.value.setCustomValidity(message)\n\t\t}\n\t\tsuper.setCustomValidity(message)\n\t}\n\n\t// ----------------------------\n\t// E) Lifecycle Hooks & Event Handlers\n\t// ----------------------------\n\tfirstUpdated() {\n\t\t// Autofocus if desired\n\t\tif (this.autofocus) {\n\t\t\t// Schedule focus after initial render — RxJS timer for cancel-on-disconnect.\n\t\t\ttimer(0)\n\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t.subscribe(() => this.focus())\n\t\t}\n\n\t\t// Subscribe to input events\n\t\tthis.setupInputEvents()\n\t\tthis.setupFocusBlurEvents()\n\t\tthis.setupAutofillDetection()\n\t\tthis.setupEnterKeyEvents()\n\t}\n\n\t/**\n\t * Set up input event handling for value changes\n\t */\n\tprivate setupInputEvents() {\n\t\tfromEvent<InputEvent>(this.inputElement, 'input')\n\t\t\t.pipe(\n\t\t\t\tmap(ev => {\n\t\t\t\t\t// Stop native event from bubbling - we'll dispatch our own custom event\n\t\t\t\t\tev.stopPropagation()\n\n\t\t\t\t\t// Capture all input event properties for complete event forwarding\n\t\t\t\t\tconst inputEvent = ev as InputEvent\n\t\t\t\t\tconst target = ev.target as HTMLInputElement\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalue: target.value,\n\t\t\t\t\t\tinputType: inputEvent.inputType,\n\t\t\t\t\t\tdata: inputEvent.data,\n\t\t\t\t\t\tisComposing: inputEvent.isComposing,\n\t\t\t\t\t\toriginalEvent: ev,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(eventData => {\n\t\t\t\t// Update component value\n\t\t\t\tthis.value = eventData.value\n\n\t\t\t\t// `dirty` is a getter on the mixin (value vs _defaultValue) — no manual set.\n\n\t\t\t\t// Fire custom 'input' event with extended details\n\t\t\t\tconst customEvent = new CustomEvent<EventDetails>('input', {\n\t\t\t\t\tdetail: { value: eventData.value },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t})\n\n\t\t\t\t// Add additional properties to match native events more closely\n\t\t\t\tObject.defineProperties(customEvent, {\n\t\t\t\t\tinputType: { value: eventData.inputType },\n\t\t\t\t\tdata: { value: eventData.data },\n\t\t\t\t\tisComposing: { value: eventData.isComposing },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(customEvent)\n\n\t\t\t\t// Mixin's willUpdate runs checkValidity() on value-change when\n\t\t\t\t// _shouldShowError() is true — no manual validateInput() call.\n\t\t\t})\n\n\t\t// Subscribe to native change events (usually on blur)\n\t\tfromEvent<Event>(this.inputElement, 'change')\n\t\t\t.pipe(\n\t\t\t\tmap(ev => {\n\t\t\t\t\t// Stop native event from bubbling - we'll dispatch our own custom event\n\t\t\t\t\tev.stopPropagation()\n\t\t\t\t\treturn (ev.target as HTMLInputElement).value\n\t\t\t\t}),\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(value => {\n\t\t\t\tthis.value = value\n\t\t\t\tthis.emitChange({ value })\n\t\t\t\t// Validation runs automatically via mixin's willUpdate.\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up focus/blur event handling\n\t */\n\tprivate setupFocusBlurEvents() {\n\t\tfromEvent<FocusEvent>(this.inputElement, 'focus')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(ev => {\n\t\t\t\t// Create a custom focus event that includes standard props\n\t\t\t\tconst focusEvent = new CustomEvent('focus', {\n\t\t\t\t\tbubbles: ev.bubbles,\n\t\t\t\t\tcancelable: ev.cancelable,\n\t\t\t\t\tcomposed: ev.composed,\n\t\t\t\t})\n\n\t\t\t\t// Add focus-specific properties\n\t\t\t\tObject.defineProperties(focusEvent, {\n\t\t\t\t\trelatedTarget: { value: ev.relatedTarget },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(focusEvent)\n\t\t\t})\n\n\t\tfromEvent<FocusEvent>(this.inputElement, 'blur')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(ev => {\n\t\t\t\t// Mark as touched on blur — mixin's willUpdate handles the rest\n\t\t\t\t// (validates if dirty, broadcasts :state(touched), etc.).\n\t\t\t\tthis.markTouched()\n\n\t\t\t\t// Create a custom blur event that includes standard props\n\t\t\t\tconst blurEvent = new CustomEvent('blur', {\n\t\t\t\t\tbubbles: ev.bubbles,\n\t\t\t\t\tcancelable: ev.cancelable,\n\t\t\t\t\tcomposed: ev.composed,\n\t\t\t\t})\n\n\t\t\t\t// Add blur-specific properties\n\t\t\t\tObject.defineProperties(blurEvent, {\n\t\t\t\t\trelatedTarget: { value: ev.relatedTarget },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(blurEvent)\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up autofill detection\n\t */\n\tprivate setupAutofillDetection() {\n\t\t// Detect autofill animation (Chrome, etc.)\n\t\tfromEvent<AnimationEvent>(this.inputElement, 'animationstart')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.animationName === 'onAutoFillStart'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(ev => {\n\t\t\t\tconst { value } = ev.target as HTMLInputElement\n\t\t\t\tthis.value = value\n\t\t\t\tthis.isAutofilled = true\n\t\t\t\t// `dirty` is a getter on the mixin — recomputes from value vs _defaultValue.\n\n\t\t\t\t// Dispatch autofill event for integration with autofill systems\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('autofill', {\n\t\t\t\t\t\tdetail: { value },\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}),\n\t\t\t\t)\n\n\t\t\t\t// Also propagate as a change event like browsers do\n\t\t\t\tthis.emitChange({ value })\n\t\t\t})\n\n\t\t// Detect end of autofill (Chrome)\n\t\tfromEvent<AnimationEvent>(this.inputElement, 'animationstart')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.animationName === 'onAutoFillCancel'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.isAutofilled = false\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up enter key event handling\n\t */\n\tprivate setupEnterKeyEvents() {\n\t\t// Listen for Enter on keydown\n\t\tfromEvent<KeyboardEvent>(this.inputElement, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.key === 'Enter'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(ev => {\n\t\t\t\tconst { value } = ev.target as HTMLInputElement\n\t\t\t\t\n\t\t\t\t// Update value if changed (mixin recomputes dirty automatically)\n\t\t\t\tif (this.value !== value) {\n\t\t\t\t\tthis.value = value\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Blur the input to trigger change event naturally\n\t\t\t\t// This mimics what happens when you tab out of the field\n\t\t\t\tthis.inputElement.blur()\n\n\t\t\t\t// Dispatch enhanced enter event\n\t\t\t\tconst enterEvent = new CustomEvent<EventDetails>('enter', {\n\t\t\t\t\tdetail: { value: this.value },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t})\n\n\t\t\t\t// Add extra keyboard event props\n\t\t\t\tObject.defineProperties(enterEvent, {\n\t\t\t\t\tkey: { value: 'Enter' },\n\t\t\t\t\tcode: { value: 'Enter' },\n\t\t\t\t\tkeyCode: { value: 13 },\n\t\t\t\t\twhich: { value: 13 },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(enterEvent)\n\t\t\t})\n\t}\n\n\t// ----------------------------\n\t// F) Utility Methods\n\t// ----------------------------\n\t/** Selects all text within the input. */\n\tpublic select() {\n\t\treturn this.inputRef.value?.select()\n\t}\n\n\t/** Returns the native validity state of the inner <input>. */\n\tpublic getValidity(): ValidityState | undefined {\n\t\treturn this.inputRef.value?.validity\n\t}\n\n\t/**\n\t * Sets the selection range. Mirrors native input.setSelectionRange\n\t */\n\tpublic setSelectionRange(start: number, end: number, direction?: 'forward' | 'backward' | 'none') {\n\t\tthis.inputRef.value?.setSelectionRange(start, end, direction)\n\t}\n\n\t/**\n\t * Returns the selected text within the input (start position)\n\t */\n\tpublic get selectionStart(): number | null {\n\t\treturn this.inputRef.value?.selectionStart ?? null\n\t}\n\n\t/**\n\t * Returns the selected text within the input (end position)\n\t */\n\tpublic get selectionEnd(): number | null {\n\t\treturn this.inputRef.value?.selectionEnd ?? null\n\t}\n\n\t/**\n\t * Returns the direction of selection\n\t */\n\tpublic get selectionDirection(): 'forward' | 'backward' | 'none' | null {\n\t\treturn this.inputRef.value?.selectionDirection ?? null\n\t}\n\n\t/**\n\t * Sets the range of text to be selected.\n\t */\n\tpublic setRangeText(\n\t\treplacement: string,\n\t\tstart?: number,\n\t\tend?: number,\n\t\tselectMode?: 'select' | 'start' | 'end' | 'preserve',\n\t) {\n\t\tif (start !== undefined && end !== undefined) {\n\t\t\tthis.inputRef.value?.setRangeText(replacement, start, end, selectMode)\n\t\t} else {\n\t\t\tthis.inputRef.value?.setRangeText(replacement)\n\t\t}\n\t}\n\n\t/**\n\t * Override to forward focus to the internal <input>.\n\t * Also dispatch a 'focus' event for external listeners.\n\t */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.inputRef.value?.focus(options)\n\t\tthis.dispatchEvent(new Event('focus'))\n\t}\n\n\t/**\n\t * Override to forward clicks to the internal <input>.\n\t * Also dispatch a 'click' event for external listeners.\n\t */\n\tpublic override click() {\n\t\tthis.inputRef.value?.click()\n\t\tthis.dispatchEvent(new Event('click'))\n\t}\n\n\t/** Forward blur to the internal <input>. */\n\tpublic override blur() {\n\t\tthis.inputRef.value?.blur()\n\t\tthis.dispatchEvent(new Event('blur'))\n\t}\n\n\t// ----------------------------\n\t// G) Rendering\n\t// ----------------------------\n\tprotected override render() {\n\t\t// Determine height and padding based on size - M3 spec aligned\n\t\tconst getHeightAndPadding = () => {\n\t\t\tswitch (this.size) {\n\t\t\t\tcase 'xxs':\n\t\t\t\t\t// Ultra-compact: 24dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '24px',\n\t\t\t\t\t\tpadding: '0 8px',\n\t\t\t\t\t\tfontSize: '0.625rem', // 10px\n\t\t\t\t\t}\n\t\t\t\tcase 'xs':\n\t\t\t\t\t// M3 dense: 32dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '32px',\n\t\t\t\t\t\tpadding: '0 12px',\n\t\t\t\t\t\tfontSize: '0.75rem', // 12px\n\t\t\t\t\t}\n\t\t\t\tcase 'sm':\n\t\t\t\t\t// M3 default: 40dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '40px',\n\t\t\t\t\t\tpadding: '0 16px',\n\t\t\t\t\t\tfontSize: '0.875rem', // 14px - M3 body-large\n\t\t\t\t\t}\n\t\t\t\tcase 'lg':\n\t\t\t\t\t// M3 extra large: 56dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '56px',\n\t\t\t\t\t\tpadding: '0 20px',\n\t\t\t\t\t\tfontSize: '1rem', // 16px\n\t\t\t\t\t}\n\t\t\t\tcase 'md':\n\t\t\t\tdefault:\n\t\t\t\t\t// M3 standard: 48dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '48px',\n\t\t\t\t\t\tpadding: '0 16px',\n\t\t\t\t\t\tfontSize: '0.875rem', // 14px - M3 body-large\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst { height, padding, fontSize } = getHeightAndPadding()\n\n\t\t// Check if it's a date-type input\n\t\tconst isDateType = ['date', 'datetime-local', 'time', 'month', 'week'].includes(this.type)\n\n\t\tconst inputClasses = {\n\t\t\t// Base styles - outlined rounded input\n\t\t\t'block w-full min-w-0 rounded-2xl border bg-surface-containerLowest text-surface-on': true,\n\t\t\t// Border color\n\t\t\t'border-outline': !this.error,\n\t\t\t'border-error-default': this.error,\n\t\t\t// Focus styles\n\t\t\t'outline-secondary-default focus:outline-1 focus:border-secondary-default': true,\n\t\t\t// Disabled styles\n\t\t\t'disabled:opacity-40 disabled:cursor-not-allowed': true,\n\t\t\t// Placeholder\n\t\t\t'placeholder:text-muted': true,\n\t\t\t// Ring styles (subtle focus ring)\n\t\t\t'ring-0 focus:ring-1 focus:ring-inset': true,\n\t\t\t// Ring colors based on error state\n\t\t\t'focus:ring-secondary-default': !this.error,\n\t\t\t'focus:ring-error-default': this.error,\n\t\t\t// Readonly styles\n\t\t\t'caret-transparent focus:outline-hidden cursor-pointer select-none': this.readonly,\n\t\t\t'cursor-pointer': this.clickable,\n\t\t\t// Text alignment (date inputs always left-aligned)\n\t\t\t'text-left': this.align === 'left' || isDateType,\n\t\t\t'text-center': this.align === 'center' && !isDateType,\n\t\t\t'text-right': this.align === 'right' && !isDateType,\n\t\t\t// Autofill\n\t\t\tautofilled: this.isAutofilled,\n\t\t}\n\n\t\tconst labelClasses = {\n\t\t\t'block mb-1 font-medium': true,\n\t\t\t'opacity-40': this.disabled,\n\t\t\t'text-[10px]': this.size === 'xxs',\n\t\t\t'text-xs': this.size === 'xs',\n\t\t\t'text-sm': this.size === 'sm',\n\t\t\t'text-base': this.size === 'md',\n\t\t\t'text-lg': this.size === 'lg',\n\t\t\t'text-primary-default': !this.error,\n\t\t\t'text-error-default': this.error,\n\t\t}\n\n\t\tconst styles = {\n\t\t\theight,\n\t\t\tpadding,\n\t\t\tfontSize,\n\t\t\t// Ensure vertical centering for all input types\n\t\t\tlineHeight: height,\n\t\t}\n\n\t\t/**\n\t\t * - If `this.label` is present, we render a proper `<label for=\"${this.id}\">`.\n\t\t * - If not, we add an aria-label to the <input> for better accessibility.\n\t\t * - If there's a `hint`, we reference it via aria-describedby.\n\t\t * - If there's an error, we set aria-invalid and could set aria-errormessage.\n\t\t */\n\t\treturn html`\n\t\t\t<div class=\"w-full min-w-0 ${isDateType ? 'date-input-container' : ''}\">\n\t\t\t\t${when(\n\t\t\t\t\tthis.label,\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<label\n\t\t\t\t\t\t\tfor=${this.id}\n\t\t\t\t\t\t\tclass=${this.classMap(labelClasses)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t${this.label}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\n\t\t\t\t<input\n\t\t\t\t\t${ref(this.inputRef)}\n\t\t\t\t\tid=${this.id}\n\t\t\t\t\tname=${this.name}\n\t\t\t\t\tclass=${this.classMap(inputClasses)}\n\t\t\t\t\tstyle=${this.styleMap(styles)}\n\t\t\t\t\t.value=${this.value}\n\t\t\t\t\t.type=${this.type}\n\t\t\t\t\t.autocomplete=${this.autocomplete}\n\t\t\t\t\t.spellcheck=${this.spellcheck}\n\t\t\t\t\tplaceholder=${this.placeholder}\n\t\t\t\t\tinputmode=${ifDefined(this.inputmode)}\n\t\t\t\t\tpattern=${ifDefined(this.pattern)}\n\t\t\t\t\t.step=${this.step ?? ''}\n\t\t\t\t\tminlength=${ifDefined(this.minlength)}\n\t\t\t\t\tmaxlength=${ifDefined(this.maxlength)}\n\t\t\t\t\tmin=${ifDefined(this.min)}\n\t\t\t\t\tmax=${ifDefined(this.max)}\n\t\t\t\t\tlist=${ifDefined(this.list)}\n\t\t\t\t\t?required=${this.required}\n\t\t\t\t\t?disabled=${this.disabled}\n\t\t\t\t\t?readonly=${this.readonly}\n\t\t\t\t\taria-invalid=${this.error ? 'true' : 'false'}\n\t\t\t\t\taria-required=${this.required ? 'true' : 'false'}\n\t\t\t\t\taria-labelledby=${this.label ? `label-${this.id}` : nothing}\n\t\t\t\t\taria-describedby=${this.hint || this.validationMessage ? `hint-${this.id}` : nothing}\n\t\t\t\t\taria-label=${ifDefined(!this.label ? this.placeholder || 'Input' : undefined)}\n\t\t\t\t/>\n\n\t\t\t\t${when(\n\t\t\t\t\tthis.hint || (this.error && this.validationMessage),\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tid=\"hint-${this.id}\"\n\t\t\t\t\t\t\tclass=\"mt-1 text-sm ${this.error ? 'text-error-default' : 'text-surface-onVariant'}\"\n\t\t\t\t\t\t\trole=${ifDefined(this.error ? 'alert' : undefined)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t${this.error && this.validationMessage ? this.validationMessage : this.hint}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\n/**\n * Register the component with the legacy tag name for backward compatibility\n * @prop {string} label - Label text for the form field (inherited from FormFieldMixin)\n * @prop {boolean} required - Whether the field is required (inherited from FormFieldMixin)\n * @prop {boolean} disabled - Whether the field is disabled (inherited from FormFieldMixin)\n * @prop {boolean} readonly - Whether the field is read-only (inherited from FormFieldMixin)\n * @prop {boolean} error - Whether the field is in an error state (inherited from FormFieldMixin)\n * @prop {string} validationMessage - The validation message to display (inherited from FormFieldMixin)\n * @prop {string} hint - Optional hint text to display below the field (inherited from FormFieldMixin)\n */\n@customElement('sch-input')\nexport class SchmancyInputCompat extends SchmancyInput {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"input-sBZ89wz1.cjs","names":[],"sources":["../src/form/fields/input/input.scss?inline","../src/form/fields/input/input.ts"],"sourcesContent":[" @reference \"tailwindcss\";\n\n:host {\n\t@apply block w-full min-w-0;\n\t/* Ensure no constraints on mobile */\n\tmax-width: 100%;\n\tbox-sizing: border-box;\n}\n\n/* Date input container needs special handling on mobile */\n.date-input-container {\n\t@apply w-full;\n\t/* Explicit width for mobile Safari */\n\twidth: 100% !important;\n\tmax-width: 100% !important;\n\tmin-width: 0;\n}\n\n/* Reset native input styles for consistency */\ninput {\n\t/* Remove all native styling */\n\t@apply appearance-none rounded-[8px];\n\t/* Prevent Safari zoom on focus */\n\tfont-size: 16px;\n\twidth: -webkit-fill-available;\n\t/* Ensure border radius is applied */\n\tborder-radius: 8px;\n\t/* Smooth transitions for luminous focus */\n\ttransition:\n\t\tbox-shadow 300ms cubic-bezier(0.34, 1.56, 0.64, 1),\n\t\tborder-color 200ms ease;\n}\n\n/* Luminous focus glow — light-based depth on focus */\ninput:focus {\n\tbox-shadow:\n\t\t0 0 0 1px var(--schmancy-sys-color-secondary-default),\n\t\t0 0 16px -4px color-mix(in srgb, var(--schmancy-sys-color-secondary-default) 20%, transparent);\n}\n\n/* Luminous error glow — red glow on error focus */\ninput[aria-invalid=\"true\"] {\n\tbox-shadow: 0 0 12px -4px color-mix(in srgb, var(--schmancy-sys-color-error-default) 15%, transparent);\n}\ninput[aria-invalid=\"true\"]:focus {\n\tbox-shadow:\n\t\t0 0 0 1px var(--schmancy-sys-color-error-default),\n\t\t0 0 16px -4px color-mix(in srgb, var(--schmancy-sys-color-error-default) 25%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n\tinput { transition: none; }\n}\n\n/* Remove number input spinners */\ninput[type='number']::-webkit-inner-spin-button,\ninput[type='number']::-webkit-outer-spin-button {\n\t-webkit-appearance: none;\n\tappearance: none;\n\t@apply m-0;\n}\n\ninput[type='number'] {\n\t-moz-appearance: textfield;\n\tappearance: textfield;\n}\n\n/* Autofill styling */\n@keyframes onAutoFillStart {\n\tfrom {}\n\tto {}\n}\n\ninput:-webkit-autofill {\n\tanimation-name: onAutoFillStart;\n\t/* Use box-shadow trick to override autofill background */\n\t-webkit-box-shadow: 0 0 0 30px var(--schmancy-sys-color-surface-highest) inset !important;\n\t-webkit-text-fill-color: var(--schmancy-sys-color-surface-on) !important;\n}\n\n/* Simplified autofill for all browsers */\ninput:autofill {\n\tbackground-color: var(--schmancy-sys-color-surface-highest) !important;\n\tcolor: var(--schmancy-sys-color-surface-on) !important;\n}\n\n/* Date and datetime inputs need special handling */\ninput[type=\"date\"],\ninput[type=\"datetime-local\"],\ninput[type=\"time\"],\ninput[type=\"month\"],\ninput[type=\"week\"] {\n\t/* Ensure consistent height and padding */\n\t@apply block w-full rounded-[8px];\n\t/* Reset WebKit styling */\n\t-webkit-appearance: none;\n\tappearance: none;\n\t/* Ensure text doesn't get cut off */\n\tline-height: inherit;\n\t/* Force full width on mobile */\n\twidth: 100% !important;\n\tmin-width: 100%;\n\tmax-width: 100%;\n\t/* Remove any default margins */\n\tmargin: 0;\n\t/* Force border radius */\n\tborder-radius: 8px !important;\n\toverflow: hidden;\n}\n\n/* WebKit date/time edit container - this is what needs centering */\ninput::-webkit-datetime-edit,\ninput::-webkit-datetime-edit-fields-wrapper {\n\t/* Center the date/time fields vertically */\n\tdisplay: flex;\n\talign-items: center;\n\theight: 100%;\n\t/* Ensure full width on mobile */\n\twidth: 100%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\ninput::-webkit-datetime-edit {\n\t/* Ensure the edit container fills available space */\n\tflex: 1;\n\twidth: 100%;\n}\n\ninput::-webkit-datetime-edit-fields-wrapper {\n\t/* Make fields wrapper expand */\n\tflex: 1;\n\twidth: 100%;\n\tjustify-content: space-between;\n}\n\ninput::-webkit-datetime-edit-text {\n\t/* Ensure separators are also centered */\n\tdisplay: flex;\n\talign-items: center;\n}\n\n/* Individual date fields */\ninput::-webkit-datetime-edit-day-field,\ninput::-webkit-datetime-edit-month-field,\ninput::-webkit-datetime-edit-year-field,\ninput::-webkit-datetime-edit-hour-field,\ninput::-webkit-datetime-edit-minute-field,\ninput::-webkit-datetime-edit-second-field,\ninput::-webkit-datetime-edit-millisecond-field,\ninput::-webkit-datetime-edit-meridiem-field {\n\t/* Ensure fields don't shrink */\n\tflex-shrink: 0;\n\tpadding: 0 2px;\n}\n\n/* Safari date input calendar icon */\ninput[type=\"date\"]::-webkit-calendar-picker-indicator,\ninput[type=\"datetime-local\"]::-webkit-calendar-picker-indicator,\ninput[type=\"time\"]::-webkit-calendar-picker-indicator,\ninput[type=\"month\"]::-webkit-calendar-picker-indicator,\ninput[type=\"week\"]::-webkit-calendar-picker-indicator {\n\t/* Make the calendar icon more subtle */\n\topacity: 0.5;\n\tcursor: pointer;\n}\n\n/* Firefox date input styling */\n@-moz-document url-prefix() {\n\tinput[type=\"date\"],\n\tinput[type=\"datetime-local\"],\n\tinput[type=\"time\"] {\n\t\t/* Firefox needs explicit height */\n\t\tmin-height: inherit;\n\t}\n}\n\n/* iOS Safari specific fixes */\n@supports (-webkit-touch-callout: none) {\n\tinput[type=\"date\"],\n\tinput[type=\"datetime-local\"],\n\tinput[type=\"time\"],\n\tinput[type=\"month\"],\n\tinput[type=\"week\"] {\n\t\t/* iOS Safari needs explicit width */\n\t\twidth: -webkit-fill-available !important;\n\t\twidth: fill-available !important;\n\t\t/* Remove default iOS styling */\n\t\t-webkit-appearance: none;\n\t\tappearance: none;\n\t\tborder-radius: 0;\n\t\t/* Remove default padding that causes issues */\n\t\tpadding-left: 12px !important;\n\t\tpadding-right: 12px !important;\n\t}\n\t\n\t/* Target shadow DOM elements on iOS */\n\tinput::-webkit-datetime-edit {\n\t\t/* Force full width */\n\t\twidth: 100% !important;\n\t\tpadding-left: 0 !important;\n\t\tpadding-right: 0 !important;\n\t}\n\t\n\tinput::-webkit-datetime-edit-fields-wrapper {\n\t\t/* Ensure proper spacing on mobile */\n\t\twidth: 100% !important;\n\t\tpadding: 0 !important;\n\t\tmargin: 0 !important;\n\t}\n}\n","import { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { createRef, ref } from 'lit/directives/ref.js'\nimport { when } from 'lit/directives/when.js'\nimport { distinctUntilChanged, filter, fromEvent, map, takeUntil, timer } from 'rxjs'\n\nimport { SchmancyFormField } from '@mixins/index'\n\n// Import styles\nimport style from './input.scss?inline'\n\n// If you want to be form-associated, define the type on `ElementInternals`.\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-input': SchmancyInput\n\t\t'sch-input': SchmancyInput\n\t}\n}\n\ntype EventDetails = {\n\tvalue: string\n}\n\n/**\n * Custom events the component may emit:\n * - 'input': on every keystroke\n * - 'change': on native blur/change\n * - 'enter': specifically when user presses Enter\n */\nexport type SchmancyInputInputEvent = CustomEvent<EventDetails>\nexport type SchmancyInputChangeEvent = CustomEvent<EventDetails>\nexport type SchmancyInputEnterEvent = CustomEvent<EventDetails>\n\n/**\n * Size variants for the input - M3 spec aligned.\n * - xxs: Ultra-compact (24dp) - for menu cards, compact UIs\n * - xs: Dense/compact (32dp) - M3 density -3\n * - sm: Default (40dp) - M3 density 0\n * - md: Standard (48dp) - M3 large\n * - lg: Extra large (56dp) - M3 extra large\n */\nexport type InputSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg'\n\n/**\n * Enhanced version of the SchmancyInput component with improved form integration\n * and compatibility with legacy API.\n *\n * This component uses the native form association API and maintains parity with\n * native input behaviors while providing a stylish, accessible interface.\n *\n * @prop {string} name - Name attribute for form submission (inherited from FormFieldMixin)\n * @prop {string} label - Label text for the form field (inherited from FormFieldMixin)\n * @prop {boolean} required - Whether the field is required (inherited from FormFieldMixin)\n * @prop {boolean} disabled - Whether the field is disabled (inherited from FormFieldMixin)\n * @prop {boolean} readonly - Whether the field is read-only (inherited from FormFieldMixin)\n * @prop {boolean} error - Whether the field is in an error state (inherited from FormFieldMixin)\n * @prop {string} validationMessage - The validation message to display (inherited from FormFieldMixin)\n * @prop {string} hint - Optional hint text to display below the field (inherited from FormFieldMixin)\n */\n@customElement('schmancy-input')\nexport default class SchmancyInput extends SchmancyFormField(unsafeCSS(style)) {\n\t// ----------------------------\n\t// A) Public properties\n\t// ----------------------------\n\n\t/** Auto-incrementing counter for generating unique IDs */\n\tstatic _idCounter = 0\n\n\t/** Override value to be string only for input element */\n\t@property({ type: String, reflect: true })\n\tpublic override value = ''\n\n\n\t/**\n\t * The type of input. (e.g. 'text', 'password', 'email', etc.)\n\t */\n\t@property({ reflect: true })\n\tpublic type: HTMLInputElement['type'] = 'text'\n\n\n\t@property()\n\tpublic placeholder = ''\n\n\n\t/** Pattern validation attribute. */\n\t@property({ type: String, reflect: true })\n\tpublic pattern?: string\n\n\n\t/** If true, we visually show a pointer cursor even if readOnly. */\n\t@property({ type: Boolean, reflect: true }) public clickable = false\n\n\t/** Whether browser spellcheck is enabled. */\n\t@property({ type: Boolean, reflect: true })\n\tpublic spellcheck = false\n\n\t/**\n\t * Text alignment within the input.\n\t * - 'left' | 'center' | 'right'\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic align: 'left' | 'center' | 'right' = 'left'\n\n\t/** inputmode attribute (affects on-screen keyboards in mobile). */\n\t@property()\n\tpublic inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'\n\n\t@property({ type: Number, reflect: true })\n\tpublic minlength?: number\n\n\t@property({ type: Number })\n\tpublic maxlength?: number\n\n\t@property()\n\tpublic min?: string\n\n\t@property()\n\tpublic max?: string\n\n\t@property({ reflect: true })\n\tpublic step?: string = 'any'\n\n\t/** If true, auto-focus this input on first render. */\n\t@property({ type: Boolean })\n\tpublic autofocus = false\n\n\t/** Autocomplete/autofill hints. */\n\t@property({ type: String, reflect: true })\n\tpublic autocomplete: AutoFill = 'on'\n\n\t/**\n\t * tabIndex for focusing by tab key. Typically 0 or -1.\n\t */\n\t@property({ type: Number, reflect: true })\n\tpublic override tabIndex = 0\n\n\n\t/**\n\t * The size of the input.\n\t * - 'xxs': Ultra-compact size (24px) - for menu cards\n\t * - 'xs': Extra small, very compact size (32px)\n\t * - 'sm': Small, compact size (40px)\n\t * - 'md': Medium size (default) (48px)\n\t * - 'lg': Large size (56px)\n\t */\n\t@property({ type: String, reflect: true })\n\tpublic size: InputSize = 'md'\n\n\t/**\n\t * For datalist support\n\t */\n\t@property({ type: String })\n\tpublic list?: string\n\n\n\t// ----------------------------\n\t// B) Queries & Refs\n\t// ----------------------------\n\t@query('input') private inputElement!: HTMLInputElement\n\tprivate inputRef = createRef<HTMLInputElement>()\n\n\t// ----------------------------\n\t// C) Internal States\n\t// ----------------------------\n\n\t/**\n\t * For integration with browser's autofill support\n\t */\n\t@state()\n\tprivate isAutofilled = false\n\n\t// `touched`, `dirty`, `submitted`, and `validateOn` come from FormFieldMixin.\n\t// `_defaultValue` (mixin) replaces the old `defaultValue` field.\n\n\t// ----------------------------\n\t// D) Form-associated logic\n\t// ----------------------------\n\tprotected static shadowRootOptions = {\n\t\t...LitElement.shadowRootOptions,\n\t\tdelegatesFocus: true, // so focus() goes to <input>\n\t}\n\n\t/**\n\t * If user did not provide an ID, auto-generate one so <label for=\"...\">\n\t * and various aria-* attributes can reference it.\n\t */\n\tprotected override willUpdate(changedProps: Map<PropertyKey, unknown>) {\n\t\tif (!this.id) {\n\t\t\tthis.id = `sch-input-${SchmancyInput._idCounter++}`\n\t\t}\n\t\tsuper.willUpdate(changedProps as never)\n\t}\n\n\n\t// `updated()` removed — FormFieldMixin's `willUpdate` recomputes `dirty`,\n\t// triggers `checkValidity()` when `_shouldShowError()` is true, and updates\n\t// `:state(dirty)` automatically.\n\t//\n\t// Default value capture is also handled by the mixin (`firstUpdated` sets\n\t// `_defaultValue` from `value`).\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\n\t\t// Form reset and submit are now handled by the mixin via FACE callbacks\n\t\t// (`formResetCallback`) and by `<schmancy-form>`'s submit sweep\n\t\t// (`markSubmitted()`). No manual form listeners needed.\n\t\tthis.setupExternalLabelAssociation()\n\t}\n\n\t/**\n\t * Set up external label association for native HTML label support\n\t */\n\tprivate setupExternalLabelAssociation() {\n\t\tif (this.id) {\n\t\t\tconst setupLabelClickListener = () => {\n\t\t\t\tconst labels = document.querySelectorAll(`label[for=\"${this.id}\"]`)\n\t\t\t\tlabels.forEach(label => {\n\t\t\t\t\t// Use RxJS for label click events\n\t\t\t\t\tfromEvent(label, 'click')\n\t\t\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t\t\t.subscribe(() => {\n\t\t\t\t\t\t\tthis.focus()\n\t\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Initialize after DOM is ready\n\t\t\tif (document.readyState === 'complete') {\n\t\t\t\tsetupLabelClickListener()\n\t\t\t} else {\n\t\t\t\t// Use RxJS for DOMContentLoaded event\n\t\t\t\tfromEvent(document, 'DOMContentLoaded')\n\t\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t\t.subscribe(setupLabelClickListener)\n\t\t\t}\n\t\t}\n\t}\n\n\t// `disconnectedCallback`, `resetToDefault`, `shouldShowValidation`, and\n\t// `validateInput` are gone — the mixin's `willUpdate` runs `checkValidity()`\n\t// at the right moments (Phase 2/3/4 of the validation contract) and\n\t// `formResetCallback` → `resetForm()` handles reset.\n\n\t/**\n\t * Check validity. Folds in the inner native input's structured\n\t * `ValidityState` flags (`typeMismatch`, `patternMismatch`, `tooShort`,\n\t * `tooLong`, `rangeUnderflow`, `rangeOverflow`, `stepMismatch`, `badInput`)\n\t * via `internals.setValidity` so consumers can target specific flags via\n\t * `field.validity.<flag>` and `:state(value-missing|type-mismatch|…)`.\n\t *\n\t * The visual `error` flag is still gated by the mixin's `_shouldShowError()`.\n\t */\n\t/**\n\t * Re-run checkValidity AFTER render so the native inner input's `.value`\n\t * binding has propagated. The mixin's willUpdate fires checkValidity too\n\t * early — at that point native.validity still reflects the previous value.\n\t */\n\tprotected override updated(changedProps: Map<PropertyKey, unknown>) {\n\t\tsuper.updated?.(changedProps)\n\t\tif (\n\t\t\tchangedProps.has('value') ||\n\t\t\tchangedProps.has('required') ||\n\t\t\tchangedProps.has('type') ||\n\t\t\tchangedProps.has('pattern') ||\n\t\t\tchangedProps.has('min') ||\n\t\t\tchangedProps.has('max') ||\n\t\t\tchangedProps.has('minlength') ||\n\t\t\tchangedProps.has('maxlength')\n\t\t) {\n\t\t\tthis.checkValidity()\n\t\t}\n\t}\n\n\t/**\n\t * Pick the first matching `errorMessages` override for the failing flags.\n\t * Order matches the natural priority of validity flags (valueMissing\n\t * before more specific ones — empty trumps malformed).\n\t */\n\tprivate _firstMatchingErrorMessage(v: ValidityState): string | undefined {\n\t\tconst m = this.errorMessages\n\t\tif (!m) return undefined\n\t\tif (v.valueMissing && m.valueMissing) return m.valueMissing\n\t\tif (v.typeMismatch && m.typeMismatch) return m.typeMismatch\n\t\tif (v.patternMismatch && m.patternMismatch) return m.patternMismatch\n\t\tif (v.tooShort && m.tooShort) return m.tooShort\n\t\tif (v.tooLong && m.tooLong) return m.tooLong\n\t\tif (v.rangeUnderflow && m.rangeUnderflow) return m.rangeUnderflow\n\t\tif (v.rangeOverflow && m.rangeOverflow) return m.rangeOverflow\n\t\tif (v.stepMismatch && m.stepMismatch) return m.stepMismatch\n\t\tif (v.badInput && m.badInput) return m.badInput\n\t\treturn undefined\n\t}\n\n\tpublic override checkValidity() {\n\t\t// Prefer @query (always live) over @ref (may lag during initial paint).\n\t\tconst native = this.inputElement ?? this.inputRef.value\n\t\tconst v = native?.validity\n\t\tif (v && !v.valid) {\n\t\t\t// Surface the native flags. valueMissing also surfaces here when\n\t\t\t// `required` + empty — overrides the mixin's coarse check.\n\t\t\tconst flags: ValidityStateFlags = {\n\t\t\t\tvalueMissing: v.valueMissing || undefined,\n\t\t\t\ttypeMismatch: v.typeMismatch || undefined,\n\t\t\t\tpatternMismatch: v.patternMismatch || undefined,\n\t\t\t\ttooShort: v.tooShort || undefined,\n\t\t\t\ttooLong: v.tooLong || undefined,\n\t\t\t\trangeUnderflow: v.rangeUnderflow || undefined,\n\t\t\t\trangeOverflow: v.rangeOverflow || undefined,\n\t\t\t\tstepMismatch: v.stepMismatch || undefined,\n\t\t\t\tbadInput: v.badInput || undefined,\n\t\t\t\tcustomError: v.customError || undefined,\n\t\t\t}\n\t\t\t// errorMessages override: pick the first matching flag and use the\n\t\t\t// consumer-provided copy. Falls back to the native browser message.\n\t\t\tconst overrideMessage = this._firstMatchingErrorMessage(v)\n\t\t\tthis.internals?.setValidity(\n\t\t\t\tflags,\n\t\t\t\toverrideMessage || native.validationMessage || this.validationMessage || 'Invalid value',\n\t\t\t)\n\t\t\tif (this._shouldShowError()) {\n\t\t\t\tthis.error = true\n\t\t\t\t// Always reflect the current flag's message — previous\n\t\t\t\t// validationMessage may be stale (different flag).\n\t\t\t\tconst newMessage = overrideMessage || native.validationMessage\n\t\t\t\tif (newMessage) this.validationMessage = newMessage\n\t\t\t\t// Mirror flags into :state() so CSS can target specifics.\n\t\t\t\tfor (const flag of [\n\t\t\t\t\t'value-missing',\n\t\t\t\t\t'type-mismatch',\n\t\t\t\t\t'pattern-mismatch',\n\t\t\t\t\t'too-short',\n\t\t\t\t\t'too-long',\n\t\t\t\t\t'range-underflow',\n\t\t\t\t\t'range-overflow',\n\t\t\t\t\t'step-mismatch',\n\t\t\t\t\t'bad-input',\n\t\t\t\t]) {\n\t\t\t\t\tthis.internals?.states.delete(flag)\n\t\t\t\t}\n\t\t\t\tif (v.valueMissing) this.internals?.states.add('value-missing')\n\t\t\t\tif (v.typeMismatch) this.internals?.states.add('type-mismatch')\n\t\t\t\tif (v.patternMismatch) this.internals?.states.add('pattern-mismatch')\n\t\t\t\tif (v.tooShort) this.internals?.states.add('too-short')\n\t\t\t\tif (v.tooLong) this.internals?.states.add('too-long')\n\t\t\t\tif (v.rangeUnderflow) this.internals?.states.add('range-underflow')\n\t\t\t\tif (v.rangeOverflow) this.internals?.states.add('range-overflow')\n\t\t\t\tif (v.stepMismatch) this.internals?.states.add('step-mismatch')\n\t\t\t\tif (v.badInput) this.internals?.states.add('bad-input')\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\t// Native says valid — but the mixin's `required` check might still\n\t\t// fire (mixin checks `value === ''` directly, native may treat empty\n\t\t// differently for type=email/url with no value).\n\t\tconst parentValid = super.checkValidity()\n\t\tif (parentValid) {\n\t\t\t// Clear specific-flag :state() entries.\n\t\t\tfor (const flag of [\n\t\t\t\t'value-missing',\n\t\t\t\t'type-mismatch',\n\t\t\t\t'pattern-mismatch',\n\t\t\t\t'too-short',\n\t\t\t\t'too-long',\n\t\t\t\t'range-underflow',\n\t\t\t\t'range-overflow',\n\t\t\t\t'step-mismatch',\n\t\t\t\t'bad-input',\n\t\t\t]) {\n\t\t\t\tthis.internals?.states.delete(flag)\n\t\t\t}\n\t\t}\n\t\treturn parentValid\n\t}\n\n\t/**\n\t * Show validation UI and check validity.\n\t * Marks the field as submitted so the mixin's gate flips to \"always show.\"\n\t */\n\tpublic override reportValidity() {\n\t\tthis.markSubmitted()\n\t\tconst inputValid = this.inputRef.value?.reportValidity() ?? true\n\t\tconst parentValid = super.reportValidity()\n\t\treturn inputValid && parentValid\n\t}\n\n\t/** Set a custom validation error on both the inner input and the mixin. */\n\tpublic override setCustomValidity(message: string) {\n\t\tif (this.inputRef.value) {\n\t\t\tthis.inputRef.value.setCustomValidity(message)\n\t\t}\n\t\tsuper.setCustomValidity(message)\n\t}\n\n\t// ----------------------------\n\t// E) Lifecycle Hooks & Event Handlers\n\t// ----------------------------\n\tfirstUpdated() {\n\t\t// Autofocus if desired\n\t\tif (this.autofocus) {\n\t\t\t// Schedule focus after initial render — RxJS timer for cancel-on-disconnect.\n\t\t\ttimer(0)\n\t\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t\t.subscribe(() => this.focus())\n\t\t}\n\n\t\t// Subscribe to input events\n\t\tthis.setupInputEvents()\n\t\tthis.setupFocusBlurEvents()\n\t\tthis.setupAutofillDetection()\n\t\tthis.setupEnterKeyEvents()\n\t}\n\n\t/**\n\t * Set up input event handling for value changes\n\t */\n\tprivate setupInputEvents() {\n\t\tfromEvent<InputEvent>(this.inputElement, 'input')\n\t\t\t.pipe(\n\t\t\t\tmap(ev => {\n\t\t\t\t\t// Stop native event from bubbling - we'll dispatch our own custom event\n\t\t\t\t\tev.stopPropagation()\n\n\t\t\t\t\t// Capture all input event properties for complete event forwarding\n\t\t\t\t\tconst inputEvent = ev as InputEvent\n\t\t\t\t\tconst target = ev.target as HTMLInputElement\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalue: target.value,\n\t\t\t\t\t\tinputType: inputEvent.inputType,\n\t\t\t\t\t\tdata: inputEvent.data,\n\t\t\t\t\t\tisComposing: inputEvent.isComposing,\n\t\t\t\t\t\toriginalEvent: ev,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(eventData => {\n\t\t\t\t// Update component value\n\t\t\t\tthis.value = eventData.value\n\n\t\t\t\t// `dirty` is a getter on the mixin (value vs _defaultValue) — no manual set.\n\n\t\t\t\t// Fire custom 'input' event with extended details\n\t\t\t\tconst customEvent = new CustomEvent<EventDetails>('input', {\n\t\t\t\t\tdetail: { value: eventData.value },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t})\n\n\t\t\t\t// Add additional properties to match native events more closely\n\t\t\t\tObject.defineProperties(customEvent, {\n\t\t\t\t\tinputType: { value: eventData.inputType },\n\t\t\t\t\tdata: { value: eventData.data },\n\t\t\t\t\tisComposing: { value: eventData.isComposing },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(customEvent)\n\n\t\t\t\t// Mixin's willUpdate runs checkValidity() on value-change when\n\t\t\t\t// _shouldShowError() is true — no manual validateInput() call.\n\t\t\t})\n\n\t\t// Subscribe to native change events (usually on blur)\n\t\tfromEvent<Event>(this.inputElement, 'change')\n\t\t\t.pipe(\n\t\t\t\tmap(ev => {\n\t\t\t\t\t// Stop native event from bubbling - we'll dispatch our own custom event\n\t\t\t\t\tev.stopPropagation()\n\t\t\t\t\treturn (ev.target as HTMLInputElement).value\n\t\t\t\t}),\n\t\t\t\tdistinctUntilChanged(),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(value => {\n\t\t\t\tthis.value = value\n\t\t\t\tthis.emitChange({ value })\n\t\t\t\t// Validation runs automatically via mixin's willUpdate.\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up focus/blur event handling\n\t */\n\tprivate setupFocusBlurEvents() {\n\t\tfromEvent<FocusEvent>(this.inputElement, 'focus')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(ev => {\n\t\t\t\t// Create a custom focus event that includes standard props\n\t\t\t\tconst focusEvent = new CustomEvent('focus', {\n\t\t\t\t\tbubbles: ev.bubbles,\n\t\t\t\t\tcancelable: ev.cancelable,\n\t\t\t\t\tcomposed: ev.composed,\n\t\t\t\t})\n\n\t\t\t\t// Add focus-specific properties\n\t\t\t\tObject.defineProperties(focusEvent, {\n\t\t\t\t\trelatedTarget: { value: ev.relatedTarget },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(focusEvent)\n\t\t\t})\n\n\t\tfromEvent<FocusEvent>(this.inputElement, 'blur')\n\t\t\t.pipe(takeUntil(this.disconnecting))\n\t\t\t.subscribe(ev => {\n\t\t\t\t// Mark as touched on blur — mixin's willUpdate handles the rest\n\t\t\t\t// (validates if dirty, broadcasts :state(touched), etc.).\n\t\t\t\tthis.markTouched()\n\n\t\t\t\t// Create a custom blur event that includes standard props\n\t\t\t\tconst blurEvent = new CustomEvent('blur', {\n\t\t\t\t\tbubbles: ev.bubbles,\n\t\t\t\t\tcancelable: ev.cancelable,\n\t\t\t\t\tcomposed: ev.composed,\n\t\t\t\t})\n\n\t\t\t\t// Add blur-specific properties\n\t\t\t\tObject.defineProperties(blurEvent, {\n\t\t\t\t\trelatedTarget: { value: ev.relatedTarget },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(blurEvent)\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up autofill detection\n\t */\n\tprivate setupAutofillDetection() {\n\t\t// Detect autofill animation (Chrome, etc.)\n\t\tfromEvent<AnimationEvent>(this.inputElement, 'animationstart')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.animationName === 'onAutoFillStart'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(ev => {\n\t\t\t\tconst { value } = ev.target as HTMLInputElement\n\t\t\t\tthis.value = value\n\t\t\t\tthis.isAutofilled = true\n\t\t\t\t// `dirty` is a getter on the mixin — recomputes from value vs _defaultValue.\n\n\t\t\t\t// Dispatch autofill event for integration with autofill systems\n\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\tnew CustomEvent('autofill', {\n\t\t\t\t\t\tdetail: { value },\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcomposed: true,\n\t\t\t\t\t}),\n\t\t\t\t)\n\n\t\t\t\t// Also propagate as a change event like browsers do\n\t\t\t\tthis.emitChange({ value })\n\t\t\t})\n\n\t\t// Detect end of autofill (Chrome)\n\t\tfromEvent<AnimationEvent>(this.inputElement, 'animationstart')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.animationName === 'onAutoFillCancel'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(() => {\n\t\t\t\tthis.isAutofilled = false\n\t\t\t})\n\t}\n\n\t/**\n\t * Set up enter key event handling\n\t */\n\tprivate setupEnterKeyEvents() {\n\t\t// Listen for Enter on keydown\n\t\tfromEvent<KeyboardEvent>(this.inputElement, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(ev => ev.key === 'Enter'),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe(ev => {\n\t\t\t\tconst { value } = ev.target as HTMLInputElement\n\t\t\t\t\n\t\t\t\t// Update value if changed (mixin recomputes dirty automatically)\n\t\t\t\tif (this.value !== value) {\n\t\t\t\t\tthis.value = value\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Blur the input to trigger change event naturally\n\t\t\t\t// This mimics what happens when you tab out of the field\n\t\t\t\tthis.inputElement.blur()\n\n\t\t\t\t// Dispatch enhanced enter event\n\t\t\t\tconst enterEvent = new CustomEvent<EventDetails>('enter', {\n\t\t\t\t\tdetail: { value: this.value },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t})\n\n\t\t\t\t// Add extra keyboard event props\n\t\t\t\tObject.defineProperties(enterEvent, {\n\t\t\t\t\tkey: { value: 'Enter' },\n\t\t\t\t\tcode: { value: 'Enter' },\n\t\t\t\t\tkeyCode: { value: 13 },\n\t\t\t\t\twhich: { value: 13 },\n\t\t\t\t})\n\n\t\t\t\tthis.dispatchEvent(enterEvent)\n\t\t\t})\n\t}\n\n\t// ----------------------------\n\t// F) Utility Methods\n\t// ----------------------------\n\t/** Selects all text within the input. */\n\tpublic select() {\n\t\treturn this.inputRef.value?.select()\n\t}\n\n\t/** Returns the native validity state of the inner <input>. */\n\tpublic getValidity(): ValidityState | undefined {\n\t\treturn this.inputRef.value?.validity\n\t}\n\n\t/**\n\t * Sets the selection range. Mirrors native input.setSelectionRange\n\t */\n\tpublic setSelectionRange(start: number, end: number, direction?: 'forward' | 'backward' | 'none') {\n\t\tthis.inputRef.value?.setSelectionRange(start, end, direction)\n\t}\n\n\t/**\n\t * Returns the selected text within the input (start position)\n\t */\n\tpublic get selectionStart(): number | null {\n\t\treturn this.inputRef.value?.selectionStart ?? null\n\t}\n\n\t/**\n\t * Returns the selected text within the input (end position)\n\t */\n\tpublic get selectionEnd(): number | null {\n\t\treturn this.inputRef.value?.selectionEnd ?? null\n\t}\n\n\t/**\n\t * Returns the direction of selection\n\t */\n\tpublic get selectionDirection(): 'forward' | 'backward' | 'none' | null {\n\t\treturn this.inputRef.value?.selectionDirection ?? null\n\t}\n\n\t/**\n\t * Sets the range of text to be selected.\n\t */\n\tpublic setRangeText(\n\t\treplacement: string,\n\t\tstart?: number,\n\t\tend?: number,\n\t\tselectMode?: 'select' | 'start' | 'end' | 'preserve',\n\t) {\n\t\tif (start !== undefined && end !== undefined) {\n\t\t\tthis.inputRef.value?.setRangeText(replacement, start, end, selectMode)\n\t\t} else {\n\t\t\tthis.inputRef.value?.setRangeText(replacement)\n\t\t}\n\t}\n\n\t/**\n\t * Override to forward focus to the internal <input>.\n\t * Also dispatch a 'focus' event for external listeners.\n\t */\n\tpublic override focus(options?: FocusOptions) {\n\t\tthis.inputRef.value?.focus(options)\n\t\tthis.dispatchEvent(new Event('focus'))\n\t}\n\n\t/**\n\t * Override to forward clicks to the internal <input>.\n\t * Also dispatch a 'click' event for external listeners.\n\t */\n\tpublic override click() {\n\t\tthis.inputRef.value?.click()\n\t\tthis.dispatchEvent(new Event('click'))\n\t}\n\n\t/** Forward blur to the internal <input>. */\n\tpublic override blur() {\n\t\tthis.inputRef.value?.blur()\n\t\tthis.dispatchEvent(new Event('blur'))\n\t}\n\n\t// ----------------------------\n\t// G) Rendering\n\t// ----------------------------\n\tprotected override render() {\n\t\t// Determine height and padding based on size - M3 spec aligned\n\t\tconst getHeightAndPadding = () => {\n\t\t\tswitch (this.size) {\n\t\t\t\tcase 'xxs':\n\t\t\t\t\t// Ultra-compact: 24dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '24px',\n\t\t\t\t\t\tpadding: '0 8px',\n\t\t\t\t\t\tfontSize: '0.625rem', // 10px\n\t\t\t\t\t}\n\t\t\t\tcase 'xs':\n\t\t\t\t\t// M3 dense: 32dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '32px',\n\t\t\t\t\t\tpadding: '0 12px',\n\t\t\t\t\t\tfontSize: '0.75rem', // 12px\n\t\t\t\t\t}\n\t\t\t\tcase 'sm':\n\t\t\t\t\t// M3 default: 40dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '40px',\n\t\t\t\t\t\tpadding: '0 16px',\n\t\t\t\t\t\tfontSize: '0.875rem', // 14px - M3 body-large\n\t\t\t\t\t}\n\t\t\t\tcase 'lg':\n\t\t\t\t\t// M3 extra large: 56dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '56px',\n\t\t\t\t\t\tpadding: '0 20px',\n\t\t\t\t\t\tfontSize: '1rem', // 16px\n\t\t\t\t\t}\n\t\t\t\tcase 'md':\n\t\t\t\tdefault:\n\t\t\t\t\t// M3 standard: 48dp height\n\t\t\t\t\treturn {\n\t\t\t\t\t\theight: '48px',\n\t\t\t\t\t\tpadding: '0 16px',\n\t\t\t\t\t\tfontSize: '0.875rem', // 14px - M3 body-large\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst { height, padding, fontSize } = getHeightAndPadding()\n\n\t\t// Check if it's a date-type input\n\t\tconst isDateType = ['date', 'datetime-local', 'time', 'month', 'week'].includes(this.type)\n\n\t\tconst inputClasses = {\n\t\t\t// Base styles - outlined rounded input\n\t\t\t'block w-full min-w-0 rounded-2xl border bg-surface-containerLowest text-surface-on': true,\n\t\t\t// Border color\n\t\t\t'border-outline': !this.error,\n\t\t\t'border-error-default': this.error,\n\t\t\t// Focus styles\n\t\t\t'outline-secondary-default focus:outline-1 focus:border-secondary-default': true,\n\t\t\t// Disabled styles\n\t\t\t'disabled:opacity-40 disabled:cursor-not-allowed': true,\n\t\t\t// Placeholder\n\t\t\t'placeholder:text-muted': true,\n\t\t\t// Ring styles (subtle focus ring)\n\t\t\t'ring-0 focus:ring-1 focus:ring-inset': true,\n\t\t\t// Ring colors based on error state\n\t\t\t'focus:ring-secondary-default': !this.error,\n\t\t\t'focus:ring-error-default': this.error,\n\t\t\t// Readonly styles\n\t\t\t'caret-transparent focus:outline-hidden cursor-pointer select-none': this.readonly,\n\t\t\t'cursor-pointer': this.clickable,\n\t\t\t// Text alignment (date inputs always left-aligned)\n\t\t\t'text-left': this.align === 'left' || isDateType,\n\t\t\t'text-center': this.align === 'center' && !isDateType,\n\t\t\t'text-right': this.align === 'right' && !isDateType,\n\t\t\t// Autofill\n\t\t\tautofilled: this.isAutofilled,\n\t\t}\n\n\t\tconst labelClasses = {\n\t\t\t'block mb-1 font-medium': true,\n\t\t\t'opacity-40': this.disabled,\n\t\t\t'text-[10px]': this.size === 'xxs',\n\t\t\t'text-xs': this.size === 'xs',\n\t\t\t'text-sm': this.size === 'sm',\n\t\t\t'text-base': this.size === 'md',\n\t\t\t'text-lg': this.size === 'lg',\n\t\t\t'text-primary-default': !this.error,\n\t\t\t'text-error-default': this.error,\n\t\t}\n\n\t\tconst styles = {\n\t\t\theight,\n\t\t\tpadding,\n\t\t\tfontSize,\n\t\t\t// Ensure vertical centering for all input types\n\t\t\tlineHeight: height,\n\t\t}\n\n\t\t/**\n\t\t * - If `this.label` is present, we render a proper `<label for=\"${this.id}\">`.\n\t\t * - If not, we add an aria-label to the <input> for better accessibility.\n\t\t * - If there's a `hint`, we reference it via aria-describedby.\n\t\t * - If there's an error, we set aria-invalid and could set aria-errormessage.\n\t\t */\n\t\treturn html`\n\t\t\t<div class=\"w-full min-w-0 ${isDateType ? 'date-input-container' : ''}\">\n\t\t\t\t${when(\n\t\t\t\t\tthis.label,\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<label\n\t\t\t\t\t\t\tfor=${this.id}\n\t\t\t\t\t\t\tclass=${this.classMap(labelClasses)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t${this.label}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\n\t\t\t\t<input\n\t\t\t\t\t${ref(this.inputRef)}\n\t\t\t\t\tid=${this.id}\n\t\t\t\t\tname=${this.name}\n\t\t\t\t\tclass=${this.classMap(inputClasses)}\n\t\t\t\t\tstyle=${this.styleMap(styles)}\n\t\t\t\t\t.value=${this.value}\n\t\t\t\t\t.type=${this.type}\n\t\t\t\t\t.autocomplete=${this.autocomplete}\n\t\t\t\t\t.spellcheck=${this.spellcheck}\n\t\t\t\t\tplaceholder=${this.placeholder}\n\t\t\t\t\tinputmode=${ifDefined(this.inputmode)}\n\t\t\t\t\tpattern=${ifDefined(this.pattern)}\n\t\t\t\t\t.step=${this.step ?? ''}\n\t\t\t\t\tminlength=${ifDefined(this.minlength)}\n\t\t\t\t\tmaxlength=${ifDefined(this.maxlength)}\n\t\t\t\t\tmin=${ifDefined(this.min)}\n\t\t\t\t\tmax=${ifDefined(this.max)}\n\t\t\t\t\tlist=${ifDefined(this.list)}\n\t\t\t\t\t?required=${this.required}\n\t\t\t\t\t?disabled=${this.disabled}\n\t\t\t\t\t?readonly=${this.readonly}\n\t\t\t\t\taria-invalid=${this.error ? 'true' : 'false'}\n\t\t\t\t\taria-required=${this.required ? 'true' : 'false'}\n\t\t\t\t\taria-labelledby=${this.label ? `label-${this.id}` : nothing}\n\t\t\t\t\taria-describedby=${this.hint || this.validationMessage ? `hint-${this.id}` : nothing}\n\t\t\t\t\taria-label=${ifDefined(!this.label ? this.placeholder || 'Input' : undefined)}\n\t\t\t\t/>\n\n\t\t\t\t${when(\n\t\t\t\t\tthis.hint || (this.error && this.validationMessage),\n\t\t\t\t\t() => html`\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tid=\"hint-${this.id}\"\n\t\t\t\t\t\t\tclass=\"mt-1 text-sm ${this.error ? 'text-error-default' : 'text-surface-onVariant'}\"\n\t\t\t\t\t\t\trole=${ifDefined(this.error ? 'alert' : undefined)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t${this.error && this.validationMessage ? this.validationMessage : this.hint}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t`,\n\t\t\t\t)}\n\t\t\t</div>\n\t\t`\n\t}\n}\n\n/**\n * Register the component with the legacy tag name for backward compatibility\n * @prop {string} label - Label text for the form field (inherited from FormFieldMixin)\n * @prop {boolean} required - Whether the field is required (inherited from FormFieldMixin)\n * @prop {boolean} disabled - Whether the field is disabled (inherited from FormFieldMixin)\n * @prop {boolean} readonly - Whether the field is read-only (inherited from FormFieldMixin)\n * @prop {boolean} error - Whether the field is in an error state (inherited from FormFieldMixin)\n * @prop {string} validationMessage - The validation message to display (inherited from FormFieldMixin)\n * @prop {string} hint - Optional hint text to display below the field (inherited from FormFieldMixin)\n */\n@customElement('sch-input')\nexport class SchmancyInputCompat extends SchmancyInput {}\n"],"mappings":"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"}
package/dist/input.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./input-BE9wEEw4.cjs`);exports.SchmancyInput=e.n,Object.defineProperty(exports,`SchmancyInputCompat`,{enumerable:!0,get:function(){return e.t}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./input-sBZ89wz1.cjs`);exports.SchmancyInput=e.n,Object.defineProperty(exports,`SchmancyInputCompat`,{enumerable:!0,get:function(){return e.t}});
package/dist/input.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./input-DC6ap_uN.js";
1
+ import { n as e, t } from "./input-Dkneo4uA.js";
2
2
  export { e as SchmancyInput, t as SchmancyInputCompat };
package/dist/json.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-Du9HMrIG.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./notification-DR3gvWt8.cjs`);let r=require(`lit/decorators.js`),i=require(`lit`),a=require(`lit/directives/unsafe-html.js`);var o=class extends e.c{constructor(...e){super(...e),this.data={},this.highlightKeys=[],this.compact=!1}static{this.styles=[i.css`:host { display: block }`]}highlightChanges(e,t){let n=e;return t.forEach(e=>{let t=RegExp(`("${e}":\\s*)([^,\\n}]+)`,`g`);n=n.replace(t,(e,t,n)=>`${t}<span class="text-warning-default font-bold">${n}</span>`)}),n}async copyJSON(){try{await navigator.clipboard.writeText(JSON.stringify(this.data,null,2)),n.r.success(`JSON copied to clipboard`)}catch{n.r.error(`Failed to copy JSON`)}}render(){let e=JSON.stringify(this.data,null,this.compact?0:2),t=this.highlightKeys.length>0?this.highlightChanges(e,this.highlightKeys):e;return i.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BwGJwK7X.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./notification-DZhL0ZEg.cjs`);let r=require(`lit/decorators.js`),i=require(`lit`),a=require(`lit/directives/unsafe-html.js`);var o=class extends e.c{constructor(...e){super(...e),this.data={},this.highlightKeys=[],this.compact=!1}static{this.styles=[i.css`:host { display: block }`]}highlightChanges(e,t){let n=e;return t.forEach(e=>{let t=RegExp(`("${e}":\\s*)([^,\\n}]+)`,`g`);n=n.replace(t,(e,t,n)=>`${t}<span class="text-warning-default font-bold">${n}</span>`)}),n}async copyJSON(){try{await navigator.clipboard.writeText(JSON.stringify(this.data,null,2)),n.r.success(`JSON copied to clipboard`)}catch{n.r.error(`Failed to copy JSON`)}}render(){let e=JSON.stringify(this.data,null,this.compact?0:2),t=this.highlightKeys.length>0?this.highlightChanges(e,this.highlightKeys):e;return i.html`
2
2
  <div
3
3
  class="bg-surface-container rounded-lg p-2 font-mono overflow-auto cursor-pointer hover:bg-surface-container-high transition-colors"
4
4
  @click=${this.copyJSON}
package/dist/json.js CHANGED
@@ -1,6 +1,6 @@
1
- import { c as e } from "./mixins-DCVXqL1Q.js";
1
+ import { c as e } from "./mixins-B9kY_60p.js";
2
2
  import { a as t } from "./active-host-BP0zy_Y9.js";
3
- import { r as n } from "./notification-eZxtr3NN.js";
3
+ import { r as n } from "./notification-O4Q5pyio.js";
4
4
  import { customElement as r, property as i } from "lit/decorators.js";
5
5
  import { css as a, html as o } from "lit";
6
6
  import { unsafeHTML as s } from "lit/directives/unsafe-html.js";
package/dist/kbd.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-Du9HMrIG.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`lit/decorators.js`),r=require(`lit`);var i=class extends e.c{constructor(...e){super(...e),this.size=`md`}static{this.styles=[r.css`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BwGJwK7X.cjs`),t=require(`./active-host-jH3iloCR.cjs`);let n=require(`lit/decorators.js`),r=require(`lit`);var i=class extends e.c{constructor(...e){super(...e),this.size=`md`}static{this.styles=[r.css`
2
2
  :host {
3
3
  display: inline-block;
4
4
  vertical-align: middle;
package/dist/kbd.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as e } from "./mixins-DCVXqL1Q.js";
1
+ import { c as e } from "./mixins-B9kY_60p.js";
2
2
  import { a as t } from "./active-host-BP0zy_Y9.js";
3
3
  import { customElement as n, property as r } from "lit/decorators.js";
4
4
  import { css as i, html as a } from "lit";
package/dist/layout.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./scroll-S-bXF2u6.cjs`);Object.defineProperty(exports,`SchmancyScroll`,{enumerable:!0,get:function(){return e.t}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./scroll-Djz3pJfX.cjs`);Object.defineProperty(exports,`SchmancyScroll`,{enumerable:!0,get:function(){return e.t}});
package/dist/layout.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./scroll-C1klVgSQ.js";
1
+ import { t as e } from "./scroll-Bj7FsS08.js";
2
2
  export { e as SchmancyScroll };
@@ -1,4 +1,4 @@
1
- require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-Du9HMrIG.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./overlay-stack-Dk0xETTy.cjs`);let r=require(`rxjs`),i=require(`rxjs/operators`),a=require(`lit/directives/style-map.js`),o=require(`lit/decorators.js`),s=require(`lit`),c=require(`lit/directives/ref.js`),l=require(`lit/directives/when.js`),u=require(`lit/async-directive.js`),d=require(`lit/directive.js`);var f=class extends e.c{constructor(...e){super(...e),this.src=``,this.images=[],this.initialIndex=0,this.open=!1,this.currentIndex=0,this.isLoading=!1,this.zIndex=1e4,this.swipeThreshold=50,this.overlayRef=(0,c.createRef)(),this.contentRef=(0,c.createRef)(),this.imageRef=(0,c.createRef)(),this.handleClose=()=>{this.open=!1},this.handlePrevious=()=>{this.isGalleryMode&&this.images.length>1&&(this.isLoading=!0,this.currentIndex=(this.currentIndex-1+this.images.length)%this.images.length,this.dispatchEvent(new CustomEvent(`change`,{detail:{index:this.currentIndex},bubbles:!0,composed:!0})))},this.handleNext=()=>{this.isGalleryMode&&this.images.length>1&&(this.isLoading=!0,this.currentIndex=(this.currentIndex+1)%this.images.length,this.dispatchEvent(new CustomEvent(`change`,{detail:{index:this.currentIndex},bubbles:!0,composed:!0})))},this.handleImageLoad=()=>{this.isLoading=!1},this.handleOverlayClick=e=>{e.target===e.currentTarget&&this.handleClose()}}static{this.styles=[s.css`
1
+ require(`./chunk-CncqDLb2.cjs`);const e=require(`./mixins-BwGJwK7X.cjs`),t=require(`./active-host-jH3iloCR.cjs`),n=require(`./overlay-stack-Dk0xETTy.cjs`);let r=require(`rxjs`),i=require(`rxjs/operators`),a=require(`lit/directives/style-map.js`),o=require(`lit/decorators.js`),s=require(`lit`),c=require(`lit/directives/ref.js`),l=require(`lit/directives/when.js`),u=require(`lit/async-directive.js`),d=require(`lit/directive.js`);var f=class extends e.c{constructor(...e){super(...e),this.src=``,this.images=[],this.initialIndex=0,this.open=!1,this.currentIndex=0,this.isLoading=!1,this.zIndex=1e4,this.swipeThreshold=50,this.overlayRef=(0,c.createRef)(),this.contentRef=(0,c.createRef)(),this.imageRef=(0,c.createRef)(),this.handleClose=()=>{this.open=!1},this.handlePrevious=()=>{this.isGalleryMode&&this.images.length>1&&(this.isLoading=!0,this.currentIndex=(this.currentIndex-1+this.images.length)%this.images.length,this.dispatchEvent(new CustomEvent(`change`,{detail:{index:this.currentIndex},bubbles:!0,composed:!0})))},this.handleNext=()=>{this.isGalleryMode&&this.images.length>1&&(this.isLoading=!0,this.currentIndex=(this.currentIndex+1)%this.images.length,this.dispatchEvent(new CustomEvent(`change`,{detail:{index:this.currentIndex},bubbles:!0,composed:!0})))},this.handleImageLoad=()=>{this.isLoading=!1},this.handleOverlayClick=e=>{e.target===e.currentTarget&&this.handleClose()}}static{this.styles=[s.css`
2
2
  :host {
3
3
  display: contents;
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lightbox-HqJBBjAT.cjs","names":[],"sources":["../src/lightbox/lightbox.ts","../src/lightbox/flip-directive.ts","../src/lightbox/lightbox.directive.ts","../src/lightbox/lightbox-service.ts"],"sourcesContent":["import { css, html, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { when } from 'lit/directives/when.js'\nimport { ref, createRef, Ref } from 'lit/directives/ref.js'\nimport { fromEvent } from 'rxjs'\nimport { filter, takeUntil, tap, switchMap, map, first } from 'rxjs/operators'\nimport { SchmancyElement } from '@mixins/index'\nimport { overlayStack } from '../utils/overlay-stack'\n\n@customElement('schmancy-lightbox')\nexport class SchmancyLightbox extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n`]\n\n\t@property({ type: String }) src: string = ''\n\t@property({ type: Array }) images: string[] = []\n\t@property({ type: Number }) initialIndex: number = 0\n\t@property({ type: Boolean }) open: boolean = false\n\n\t@state() private currentIndex: number = 0\n\t@state() private isLoading: boolean = false\n\t@state() private zIndex: number = 10000\n\n\tprivate readonly swipeThreshold = 50\n\tprivate overlayRef: Ref<HTMLDivElement> = createRef()\n\tprivate contentRef: Ref<HTMLDivElement> = createRef()\n\tprivate imageRef: Ref<HTMLImageElement> = createRef()\n\n\tprivate get isGalleryMode(): boolean {\n\t\treturn this.images.length > 0\n\t}\n\n\tprivate get currentImageSrc(): string {\n\t\tif (this.isGalleryMode) {\n\t\t\treturn this.images[this.currentIndex] || ''\n\t\t}\n\t\treturn this.src\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tthis.currentIndex = this.initialIndex\n\t}\n\n\tupdated(changedProperties: PropertyValues) {\n\t\tsuper.updated(changedProperties)\n\n\t\tif (changedProperties.has('open')) {\n\t\t\tif (this.open) {\n\t\t\t\t// Set dynamic z-index for proper stacking with sheets/dialogs\n\t\t\t\tthis.zIndex = overlayStack.getNextZIndex()\n\t\t\t\tdocument.body.style.overflow = 'hidden'\n\t\t\t\tthis.animateIn()\n\t\t\t\tthis.setupEventListeners()\n\t\t\t} else {\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t\tthis.animateOut()\n\t\t\t}\n\t\t}\n\n\t\tif (changedProperties.has('initialIndex')) {\n\t\t\tthis.currentIndex = this.initialIndex\n\t\t}\n\n\t\tif (changedProperties.has('currentIndex') && this.open) {\n\t\t\tthis.animateImageChange()\n\t\t}\n\t}\n\n\tprivate animateIn() {\n\t\tconst overlay = this.overlayRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst image = this.imageRef.value\n\n\t\tif (overlay) {\n\t\t\t// Set initial styles\n\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0)'\n\t\t\toverlay.style.opacity = '0'\n\n\t\t\t// Animate to visible state\n\t\t\toverlay.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0 },\n\t\t\t\t\t{ opacity: 1 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 300,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\t// Manually set background color after a tick\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.95)'\n\t\t\t})\n\t\t}\n\n\t\tif (content) {\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 400,\n\t\t\t\t\tdelay: 100,\n\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.56, 0.64, 1)', // Spring effect\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (image) {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 350,\n\t\t\t\t\tdelay: 150,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate animateOut() {\n\t\tconst overlay = this.overlayRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst image = this.imageRef.value\n\n\t\tif (image) {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 200,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (content) {\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 250,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (overlay) {\n\t\t\tconst animation = overlay.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 1 },\n\t\t\t\t\t{ opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 250,\n\t\t\t\t\tdelay: 50,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tanimation.onfinish = () => {\n\t\t\t\t// Reset background color\n\t\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0)'\n\t\t\t\toverlayStack.release()\n\t\t\t\tthis.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate animateImageChange() {\n\t\tconst image = this.imageRef.value\n\t\tif (!image) return\n\n\t\t// Fade out\n\t\tconst fadeOut = image.animate(\n\t\t\t[\n\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 150,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\n\t\t// Fade in after fade out completes\n\t\tfadeOut.onfinish = () => {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 200,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate setupEventListeners() {\n\t\t// Keyboard navigation\n\t\tfromEvent<KeyboardEvent>(document, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(e => {\n\t\t\t\t\tswitch (e.key) {\n\t\t\t\t\t\tcase 'Escape':\n\t\t\t\t\t\t\tthis.handleClose()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\t\t\tthis.handlePrevious()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'ArrowRight':\n\t\t\t\t\t\t\tthis.handleNext()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Touch/swipe events for mobile\n\t\tif (!this.isGalleryMode || this.images.length <= 1) return\n\n\t\tconst content = this.contentRef.value\n\t\tif (!content) return\n\n\t\tconst touchStart$ = fromEvent<TouchEvent>(content, 'touchstart')\n\t\tconst touchEnd$ = fromEvent<TouchEvent>(content, 'touchend')\n\n\t\ttouchStart$\n\t\t\t.pipe(\n\t\t\t\tswitchMap(startEvent => {\n\t\t\t\t\tconst startX = startEvent.touches[0].clientX\n\t\t\t\t\treturn touchEnd$.pipe(\n\t\t\t\t\t\tfirst(),\n\t\t\t\t\t\tmap(endEvent => {\n\t\t\t\t\t\t\tconst endX = endEvent.changedTouches[0].clientX\n\t\t\t\t\t\t\treturn endX - startX\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\tfilter(distance => Math.abs(distance) > this.swipeThreshold),\n\t\t\t\ttap(distance => (distance > 0 ? this.handlePrevious() : this.handleNext())),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate handleClose = () => {\n\t\tthis.open = false\n\t}\n\n\tprivate handlePrevious = () => {\n\t\tif (this.isGalleryMode && this.images.length > 1) {\n\t\t\tthis.isLoading = true\n\t\t\tthis.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('change', {\n\t\t\t\t\tdetail: { index: this.currentIndex },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate handleNext = () => {\n\t\tif (this.isGalleryMode && this.images.length > 1) {\n\t\t\tthis.isLoading = true\n\t\t\tthis.currentIndex = (this.currentIndex + 1) % this.images.length\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('change', {\n\t\t\t\t\tdetail: { index: this.currentIndex },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate handleImageLoad = () => {\n\t\tthis.isLoading = false\n\t}\n\n\tprivate handleOverlayClick = (e: Event) => {\n\t\t// Close when clicking the overlay (not the content)\n\t\tif (e.target === e.currentTarget) {\n\t\t\tthis.handleClose()\n\t\t}\n\t}\n\n\trender() {\n\t\tif (!this.open) return html``\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\t${ref(this.overlayRef)}\n\t\t\t\tclass=\"fixed inset-0 flex items-center justify-center backdrop-blur-sm\"\n\t\t\t\tstyle=\"z-index: ${this.zIndex}\"\n\t\t\t\t@click=${this.handleOverlayClick}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\t${ref(this.contentRef)}\n\t\t\t\t\tclass=\"relative max-w-[90vw] max-h-[90vh]\"\n\t\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t\t>\n\t\t\t\t\t<!-- Close Button -->\n\t\t\t\t\t<button\n\t\t\t\t\t\tclass=\"absolute top-4 right-4 md:top-4 md:right-4 sm:top-2 sm:right-2 bg-white/15 backdrop-blur-md text-white w-11 h-11 rounded-full flex items-center justify-center cursor-pointer z-10 transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t@click=${this.handleClose}\n\t\t\t\t\t\taria-label=\"Close lightbox\"\n\t\t\t\t\t\ttitle=\"Close (Esc)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<schmancy-icon>close</schmancy-icon>\n\t\t\t\t\t</button>\n\n\t\t\t\t\t<!-- Touch Zones for Gallery Navigation -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isGalleryMode && this.images.length > 1,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute top-0 bottom-0 left-0 w-1/3 cursor-pointer z-5\"\n\t\t\t\t\t\t\t\t@click=${this.handlePrevious}\n\t\t\t\t\t\t\t></div>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute top-0 bottom-0 right-0 w-1/3 cursor-pointer z-5\"\n\t\t\t\t\t\t\t\t@click=${this.handleNext}\n\t\t\t\t\t\t\t></div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\n\t\t\t\t\t<!-- Loading Spinner -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isLoading,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div class=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n\t\t\t\t\t\t\t\t<schmancy-progress indeterminate></schmancy-progress>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\n\t\t\t\t\t<!-- Main Image -->\n\t\t\t\t\t<img\n\t\t\t\t\t\t${ref(this.imageRef)}\n\t\t\t\t\t\tclass=\"max-w-[90vw] max-h-[90vh] object-contain rounded select-none touch-pinch-zoom ${this\n\t\t\t\t\t\t\t.isGalleryMode\n\t\t\t\t\t\t\t? 'cursor-default'\n\t\t\t\t\t\t\t: 'cursor-pointer'}\"\n\t\t\t\t\t\t.src=${this.currentImageSrc}\n\t\t\t\t\t\talt=\"Full size image\"\n\t\t\t\t\t\t@load=${this.handleImageLoad}\n\t\t\t\t\t\t@click=${() => (!this.isGalleryMode ? this.handleClose() : null)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<!-- Navigation Controls (Gallery Mode Only) -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isGalleryMode && this.images.length > 1,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute bottom-[-3.5rem] md:bottom-[-3.5rem] sm:bottom-[-3rem] left-1/2 -translate-x-1/2 flex items-center gap-4 z-10\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"bg-white/15 backdrop-blur-md text-white w-10 h-10 rounded-full flex items-center justify-center cursor-pointer transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t\t\t\t@click=${this.handlePrevious}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous image\"\n\t\t\t\t\t\t\t\t\ttitle=\"Previous (←)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<schmancy-icon>arrow_back</schmancy-icon>\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-white text-base font-medium min-w-16 text-center\" aria-live=\"polite\">\n\t\t\t\t\t\t\t\t\t${this.currentIndex + 1} / ${this.images.length}\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"bg-white/15 backdrop-blur-md text-white w-10 h-10 rounded-full flex items-center justify-center cursor-pointer transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t\t\t\t@click=${this.handleNext}\n\t\t\t\t\t\t\t\t\taria-label=\"Next image\"\n\t\t\t\t\t\t\t\t\ttitle=\"Next (→)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<schmancy-icon>arrow_forward</schmancy-icon>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-lightbox': SchmancyLightbox\n\t}\n}\n","import { directive, PartInfo, PartType, ElementPart } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { noChange } from 'lit'\n\nexport interface FlipOptions {\n\t/** Source element to animate from (uses element's bounding rect) */\n\tsourceElement?: HTMLElement\n\t/** Click position - can be MouseEvent, TouchEvent, or {x, y} coordinates */\n\tposition?: { x: number; y: number } | MouseEvent | TouchEvent\n\t/** Animation duration in ms (total for both stages) */\n\tduration?: number\n\t/** CSS easing function */\n\teasing?: string\n\t/** Whether to animate scale (default: true) */\n\tscale?: boolean\n\t/** Enable blackbird two-stage arc animation (default: true) */\n\tblackbird?: boolean\n}\n\n/** Extract x,y coordinates from various position inputs */\nfunction extractPosition(pos: FlipOptions['position']): { x: number; y: number } | null {\n\tif (!pos) return null\n\n\tif ('clientX' in pos) {\n\t\t// MouseEvent\n\t\treturn { x: pos.clientX, y: pos.clientY }\n\t} else if ('touches' in pos && pos.touches.length) {\n\t\t// TouchEvent\n\t\treturn { x: pos.touches[0].clientX, y: pos.touches[0].clientY }\n\t} else if ('x' in pos && 'y' in pos) {\n\t\t// Position object\n\t\treturn { x: pos.x, y: pos.y }\n\t}\n\n\treturn null\n}\n\n/**\n * Calculate arc control point for bird-like curved trajectory\n * Birds arc UP when taking off and arc DOWN when landing\n */\nfunction calculateArcPoint(\n\tstart: { x: number; y: number },\n\tend: { x: number; y: number },\n\tarcDirection: 'up' | 'down' = 'up',\n\tintensity: number = 0.3,\n): { x: number; y: number } {\n\tconst midX = (start.x + end.x) / 2\n\tconst midY = (start.y + end.y) / 2\n\tconst distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))\n\n\t// Arc height proportional to distance, but capped\n\tconst arcHeight = Math.min(distance * intensity, 150)\n\n\treturn {\n\t\tx: midX,\n\t\ty: arcDirection === 'up' ? midY - arcHeight : midY + arcHeight,\n\t}\n}\n\nclass FlipDirective extends AsyncDirective {\n\tprivate element?: HTMLElement\n\tprivate hasAnimated = false\n\n\tconstructor(partInfo: PartInfo) {\n\t\tsuper(partInfo)\n\t\tif (partInfo.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('flip directive can only be used on elements')\n\t\t}\n\t}\n\n\trender(_options?: FlipOptions) {\n\t\treturn noChange\n\t}\n\n\tupdate(part: ElementPart, [options]: [FlipOptions?]) {\n\t\tthis.element = part.element as HTMLElement\n\n\t\t// Animate if we have either a source element or position\n\t\tconst hasSource = options?.sourceElement || options?.position\n\t\tif (!this.hasAnimated && hasSource) {\n\t\t\tthis.hasAnimated = true\n\t\t\tthis.animateIn(options)\n\t\t}\n\n\t\treturn noChange\n\t}\n\n\tprivate animateIn(options?: FlipOptions) {\n\t\tif (!this.element) return\n\n\t\t// Check reduced motion preference\n\t\tif (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n\t\tconst totalDuration = options?.duration ?? 600\n\t\tconst animateScale = options?.scale !== false\n\t\tconst useBlackbird = options?.blackbird !== false\n\n\t\t// Get positions\n\t\tconst clickPos = extractPosition(options?.position)\n\t\tconst sourceRect = options?.sourceElement?.getBoundingClientRect()\n\n\t\tconst animate = () => {\n\t\t\tconst targetRect = this.element!.getBoundingClientRect()\n\t\t\tconst targetCenter = {\n\t\t\t\tx: targetRect.left + targetRect.width / 2,\n\t\t\t\ty: targetRect.top + targetRect.height / 2,\n\t\t\t}\n\n\t\t\t// Determine source point\n\t\t\tlet sourceCenter: { x: number; y: number }\n\t\t\tlet sourceScale = { x: 0.1, y: 0.1 }\n\n\t\t\tif (sourceRect) {\n\t\t\t\tsourceCenter = {\n\t\t\t\t\tx: sourceRect.left + sourceRect.width / 2,\n\t\t\t\t\ty: sourceRect.top + sourceRect.height / 2,\n\t\t\t\t}\n\t\t\t\tif (animateScale) {\n\t\t\t\t\tsourceScale = {\n\t\t\t\t\t\tx: sourceRect.width / targetRect.width,\n\t\t\t\t\t\ty: sourceRect.height / targetRect.height,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (clickPos) {\n\t\t\t\tsourceCenter = clickPos\n\t\t\t} else {\n\t\t\t\tsourceCenter = { x: window.innerWidth / 2, y: window.innerHeight / 2 }\n\t\t\t}\n\n\t\t\t// Calculate deltas from target (where element is) to source (where we start)\n\t\t\tconst sourceDelta = {\n\t\t\t\tx: sourceCenter.x - targetCenter.x,\n\t\t\t\ty: sourceCenter.y - targetCenter.y,\n\t\t\t}\n\n\t\t\tif (useBlackbird && clickPos && sourceRect) {\n\t\t\t\t// TWO-STAGE BLACKBIRD ANIMATION\n\t\t\t\t// Stage 1: Source element → Click position (takeoff arc - UP)\n\t\t\t\t// Stage 2: Click position → Final destination (landing arc - DOWN)\n\n\t\t\t\tconst clickDelta = {\n\t\t\t\t\tx: clickPos.x - targetCenter.x,\n\t\t\t\t\ty: clickPos.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\t// Calculate arc control points\n\t\t\t\tconst takeoffArc = calculateArcPoint(sourceCenter, clickPos, 'up', 0.4)\n\t\t\t\tconst landingArc = calculateArcPoint(clickPos, targetCenter, 'down', 0.3)\n\n\t\t\t\t// Arc deltas relative to target\n\t\t\t\tconst takeoffArcDelta = {\n\t\t\t\t\tx: takeoffArc.x - targetCenter.x,\n\t\t\t\t\ty: takeoffArc.y - targetCenter.y,\n\t\t\t\t}\n\t\t\t\tconst landingArcDelta = {\n\t\t\t\t\tx: landingArc.x - targetCenter.x,\n\t\t\t\t\ty: landingArc.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\t// Intermediate scale at click position\n\t\t\t\tconst midScale = 0.3\n\n\t\t\t\t// Create keyframes for two-stage arc animation\n\t\t\t\t// 0% → 25% → 50% → 75% → 100%\n\t\t\t\t// Source → Takeoff Arc → Click → Landing Arc → Final\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 0% - Start at source element\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(${sourceScale.x}, ${sourceScale.y})`,\n\t\t\t\t\t\t\topacity: 0.6,\n\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 25% - Peak of takeoff arc (bird lifts up)\n\t\t\t\t\t\t\ttransform: `translate(${takeoffArcDelta.x}px, ${takeoffArcDelta.y}px) scale(${midScale * 0.7})`,\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\toffset: 0.25,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 50% - At click position (transition point)\n\t\t\t\t\t\t\ttransform: `translate(${clickDelta.x}px, ${clickDelta.y}px) scale(${midScale})`,\n\t\t\t\t\t\t\topacity: 0.9,\n\t\t\t\t\t\t\toffset: 0.5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 75% - Landing arc (bird descends toward target)\n\t\t\t\t\t\t\ttransform: `translate(${landingArcDelta.x}px, ${landingArcDelta.y}px) scale(0.6)`,\n\t\t\t\t\t\t\topacity: 0.95,\n\t\t\t\t\t\t\toffset: 0.75,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 100% - Final position\n\t\t\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\toffset: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)', // Slight overshoot for organic feel\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t} else if (useBlackbird && clickPos) {\n\t\t\t\t// SINGLE-STAGE with arc (click position to final)\n\t\t\t\tconst arcPoint = calculateArcPoint(clickPos, targetCenter, 'down', 0.35)\n\t\t\t\tconst arcDelta = {\n\t\t\t\t\tx: arcPoint.x - targetCenter.x,\n\t\t\t\t\ty: arcPoint.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(0.1)`,\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${arcDelta.x}px, ${arcDelta.y}px) scale(0.5)`,\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\toffset: 0.5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\toffset: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\t// SIMPLE animation (fallback)\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(${sourceScale.x}, ${sourceScale.y})`,\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transform: 'translate(0, 0) scale(1, 1)', opacity: 1 },\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: options?.easing ?? 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Handle image loading\n\t\tif (this.element instanceof HTMLImageElement) {\n\t\t\tif (this.element.complete) {\n\t\t\t\trequestAnimationFrame(animate)\n\t\t\t} else {\n\t\t\t\tthis.element.addEventListener('load', () => requestAnimationFrame(animate), { once: true })\n\t\t\t}\n\t\t} else {\n\t\t\trequestAnimationFrame(animate)\n\t\t}\n\t}\n}\n\nexport const flip = directive(FlipDirective)\n","import { directive, PartInfo, PartType, ElementPart } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { noChange, TemplateResult } from 'lit'\nimport { html, render } from 'lit'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { flip } from './flip-directive.js'\n\nexport interface LightboxOptions {\n\timages?: string[]\n\tindex?: number\n\toverlay?: TemplateResult\n}\n\nclass LightboxDirective extends AsyncDirective {\n\tprivate element?: HTMLImageElement\n\tprivate clickHandler?: EventListener\n\tprivate keyHandler?: EventListener\n\tprivate overlayElement?: HTMLDivElement\n\tprivate currentIndex = 0\n\tprivate images: string[] = []\n\tprivate overlay?: TemplateResult\n\tprivate clickPosition?: { x: number; y: number }\n\n\tconstructor(partInfo: PartInfo) {\n\t\tsuper(partInfo)\n\t\tif (partInfo.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('lightbox directive can only be used on elements')\n\t\t}\n\t}\n\n\trender(_options?: LightboxOptions) {\n\t\treturn noChange\n\t}\n\n\tupdate(part: ElementPart, [options]: [LightboxOptions?]) {\n\t\tthis.element = part.element as HTMLImageElement\n\n\t\t// Setup click handler\n\t\tif (!this.clickHandler) {\n\t\t\tthis.clickHandler = (e: Event) => {\n\t\t\t\te.preventDefault()\n\t\t\t\te.stopPropagation()\n\n\t\t\t\t// Capture click position from MouseEvent or TouchEvent\n\t\t\t\tif ('clientX' in e) {\n\t\t\t\t\tthis.clickPosition = { x: (e as MouseEvent).clientX, y: (e as MouseEvent).clientY }\n\t\t\t\t} else if ('touches' in e && (e as TouchEvent).touches.length) {\n\t\t\t\t\tconst touch = (e as TouchEvent).touches[0]\n\t\t\t\t\tthis.clickPosition = { x: touch.clientX, y: touch.clientY }\n\t\t\t\t}\n\n\t\t\t\tif (options?.images && options.images.length > 0) {\n\t\t\t\t\tthis.images = options.images\n\t\t\t\t\tthis.currentIndex = options.index || 0\n\t\t\t\t} else {\n\t\t\t\t\tthis.images = [this.element!.src]\n\t\t\t\t\tthis.currentIndex = 0\n\t\t\t\t}\n\t\t\t\tthis.overlay = options?.overlay\n\n\t\t\t\tthis.open()\n\t\t\t}\n\n\t\t\tthis.element.addEventListener('click', this.clickHandler)\n\t\t\tthis.element.style.cursor = 'pointer'\n\t\t\tthis.element.classList.add('hover:opacity-80', 'transition-opacity')\n\t\t}\n\n\t\treturn noChange\n\t}\n\n\tprivate open() {\n\t\t// Create overlay container with flex centering\n\t\tthis.overlayElement = document.createElement('div')\n\t\tthis.overlayElement.className = 'fixed inset-0 flex items-center justify-center opacity-0 bg-black/95 backdrop-blur-sm'\n\t\tthis.overlayElement.style.zIndex = '1000'\n\n\t\t// Render lightbox content using Lit\n\t\trender(this.renderLightbox(), this.overlayElement)\n\n\t\t// Add to body\n\t\tdocument.body.appendChild(this.overlayElement)\n\t\tdocument.body.style.overflow = 'hidden'\n\n\t\t// Animate in overlay\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.overlayElement!.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: 300,\n\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t})\n\n\t\t// Setup keyboard\n\t\tthis.keyHandler = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') this.close()\n\t\t\tif (e.key === 'ArrowLeft' && this.images.length > 1) this.prev()\n\t\t\tif (e.key === 'ArrowRight' && this.images.length > 1) this.next()\n\t\t}\n\t\tdocument.addEventListener('keydown', this.keyHandler)\n\n\t\t// Click overlay to close\n\t\tthis.overlayElement.addEventListener('click', e => {\n\t\t\tif (e.target === this.overlayElement) this.close()\n\t\t})\n\t}\n\n\tprivate close() {\n\t\tif (!this.overlayElement) return\n\n\t\tconst contentContainer = this.overlayElement.querySelector('[data-lightbox-content]') as HTMLElement\n\n\t\t// Animate back to click position\n\t\tif (contentContainer && this.clickPosition) {\n\t\t\tconst rect = contentContainer.getBoundingClientRect()\n\n\t\t\t// Animate container shrinking toward click point\n\t\t\tconst deltaX = this.clickPosition.x - (rect.left + rect.width / 2)\n\t\t\tconst deltaY = this.clickPosition.y - (rect.top + rect.height / 2)\n\n\t\t\tconst containerAnim = contentContainer.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'translate(0, 0) scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: `translate(${deltaX}px, ${deltaY}px) scale(0.1)`, opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 300,\n\t\t\t\t\teasing: 'cubic-bezier(0.4, 0, 0.2, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tthis.overlayElement.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: 250,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\n\t\t\tcontainerAnim.onfinish = () => {\n\t\t\t\tthis.overlayElement?.remove()\n\t\t\t\tthis.overlayElement = undefined\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t}\n\t\t} else {\n\t\t\t// Fallback to simple fade\n\t\t\tconst animation = this.overlayElement.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: 250,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\n\t\t\tanimation.onfinish = () => {\n\t\t\t\tthis.overlayElement?.remove()\n\t\t\t\tthis.overlayElement = undefined\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t}\n\t\t}\n\n\t\tif (this.keyHandler) {\n\t\t\tdocument.removeEventListener('keydown', this.keyHandler)\n\t\t\tthis.keyHandler = undefined\n\t\t}\n\t}\n\n\tprivate prev() {\n\t\tthis.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length\n\t\tthis.updateImage()\n\t}\n\n\tprivate next() {\n\t\tthis.currentIndex = (this.currentIndex + 1) % this.images.length\n\t\tthis.updateImage()\n\t}\n\n\tprivate updateImage() {\n\t\tif (!this.overlayElement) return\n\t\trender(this.renderLightbox(), this.overlayElement)\n\t}\n\n\tprivate renderLightbox() {\n\t\tconst currentSrc = this.images[this.currentIndex]\n\t\tconst isGallery = this.images.length > 1\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tdata-lightbox-content\n\t\t\t\tclass=\"relative\"\n\t\t\t\tstyle=${styleMap({\n\t\t\t\t\ttransformOrigin: 'center center',\n\t\t\t\t})}\n\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute top-2 right-2 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.close()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Image container with optional overlay -->\n\t\t\t\t<div class=\"relative\">\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc=${currentSrc}\n\t\t\t\t\t\t${flip({\n\t\t\t\t\t\t\tsourceElement: this.element,\n\t\t\t\t\t\t\tposition: this.clickPosition,\n\t\t\t\t\t\t\tduration: 600,\n\t\t\t\t\t\t\tscale: true,\n\t\t\t\t\t\t\tblackbird: true,\n\t\t\t\t\t\t})}\n\t\t\t\t\t\tclass=\"object-contain rounded-lg\"\n\t\t\t\t\t\tstyle=\"max-height: calc(100vh - 40px); max-width: 90vw;\"\n\t\t\t\t\t\t@click=${() => !isGallery && this.close()}\n\t\t\t\t\t/>\n\t\t\t\t\t${this.overlay ? this.overlay : ''}\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Gallery controls -->\n\t\t\t\t${isGallery\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<div class=\"flex items-center justify-center gap-4 text-white mt-4\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.prev()}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\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</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-lg\">${this.currentIndex + 1} / ${this.images.length}</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.next()}\n\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\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</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tdisconnected() {\n\t\tif (this.element && this.clickHandler) {\n\t\t\tthis.element.removeEventListener('click', this.clickHandler)\n\t\t}\n\t\tthis.close()\n\t}\n}\n\nexport const lightbox = directive(LightboxDirective)\n","import { filter, fromEvent, map, Subject, switchMap, takeUntil, tap } from 'rxjs'\nimport { html, render } from 'lit'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { ComponentType } from '../area/router.types'\nimport { discoverComponent } from '@mixins/discovery.service'\nimport { overlayStack } from '../utils/overlay-stack'\nimport { lightbox as lightboxDirective, type LightboxOptions } from './lightbox.directive'\n\nexport type LightboxConfig = {\n\t// Image mode\n\timage?: string\n\timages?: string[]\n\tindex?: number\n\toverlay?: ComponentType\n\n\t// Component-only mode (no image background)\n\tcomponent?: ComponentType\n\n\tprops?: Record<string, unknown>\n}\n\n\n/**\n * Lightbox service for centralized lightbox management.\n * Follows the same patterns as DialogService.\n */\nclass LightboxService {\n\tprivate static instance: LightboxService\n\n\t// Subject for lightbox opening requests\n\tprivate pushSubject = new Subject<LightboxConfig>()\n\n\t// Subject for lightbox dismissal requests\n\tprivate dismissSubject = new Subject<void>()\n\n\t// Track active lightbox\n\tprivate activeLightbox?: {\n\t\telement: HTMLDivElement\n\t\tconfig: LightboxConfig\n\t\tcurrentIndex: number\n\t\timages: string[]\n\t}\n\n\tprivate constructor() {\n\t\tthis.setupLightboxOpeningLogic()\n\t\tthis.setupLightboxDismissLogic()\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tpublic static getInstance(): LightboxService {\n\t\tif (!LightboxService.instance) {\n\t\t\tLightboxService.instance = new LightboxService()\n\t\t}\n\t\treturn LightboxService.instance\n\t}\n\n\t/**\n\t * Sets up the main lightbox opening logic using RxJS pipes\n\t */\n\tprivate setupLightboxOpeningLogic() {\n\t\tthis.pushSubject\n\t\t\t.pipe(\n\t\t\t\tswitchMap(config => {\n\t\t\t\t\t// Use discoverComponent to find schmancy-theme (same pattern as sheet.service.ts)\n\t\t\t\t\treturn discoverComponent<HTMLElement>('schmancy-theme').pipe(\n\t\t\t\t\t\tmap(theme => {\n\t\t\t\t\t\t\t// Determine container - use theme or fallback to body\n\t\t\t\t\t\t\tconst container = theme || document.body\n\n\t\t\t\t\t\t\t// Create overlay element\n\t\t\t\t\t\t\tconst overlay = document.createElement('div')\n\t\t\t\t\t\t\toverlay.className = 'fixed inset-0 flex items-center justify-center opacity-0 bg-black/95 backdrop-blur-sm'\n\t\t\t\t\t\t\toverlay.style.zIndex = String(overlayStack.getNextZIndex())\n\n\t\t\t\t\t\t\tcontainer.appendChild(overlay)\n\t\t\t\t\t\t\tdocument.body.style.overflow = 'hidden'\n\n\t\t\t\t\t\t\treturn { overlay, config, container }\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\ttap(({ overlay, config }) => {\n\t\t\t\t\t// Setup images array\n\t\t\t\t\tlet images: string[] = []\n\t\t\t\t\tlet currentIndex = 0\n\n\t\t\t\t\tif (config.images && config.images.length > 0) {\n\t\t\t\t\t\timages = config.images\n\t\t\t\t\t\tcurrentIndex = config.index || 0\n\t\t\t\t\t} else if (config.image) {\n\t\t\t\t\t\timages = [config.image]\n\t\t\t\t\t\tcurrentIndex = 0\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store active lightbox state\n\t\t\t\t\tthis.activeLightbox = {\n\t\t\t\t\t\telement: overlay,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcurrentIndex,\n\t\t\t\t\t\timages,\n\t\t\t\t\t}\n\n\t\t\t\t\t// Keyboard handling via RxJS\n\t\t\t\t\tfromEvent<KeyboardEvent>(document, 'keydown').pipe(\n\t\t\t\t\t\ttakeUntil(this.dismissSubject),\n\t\t\t\t\t\tfilter(() => !!this.activeLightbox),\n\t\t\t\t\t\ttap(e => {\n\t\t\t\t\t\t\tif (e.key === 'Escape') this.dismiss()\n\t\t\t\t\t\t\tif (e.key === 'ArrowLeft' && this.activeLightbox!.images.length > 1) this.navigatePrev()\n\t\t\t\t\t\t\tif (e.key === 'ArrowRight' && this.activeLightbox!.images.length > 1) this.navigateNext()\n\t\t\t\t\t\t})\n\t\t\t\t\t).subscribe()\n\n\t\t\t\t\t// Click overlay to close via RxJS\n\t\t\t\t\tfromEvent<MouseEvent>(overlay, 'click').pipe(\n\t\t\t\t\t\ttakeUntil(this.dismissSubject),\n\t\t\t\t\t\tfilter(e => e.target === overlay),\n\t\t\t\t\t\ttap(() => this.dismiss())\n\t\t\t\t\t).subscribe()\n\n\t\t\t\t\t// Render content\n\t\t\t\t\tif (config.component) {\n\t\t\t\t\t\tthis.renderComponent(overlay, config)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.renderLightbox(overlay, config, images, currentIndex)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Animate in\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\toverlay.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\t\t\t\tduration: 300,\n\t\t\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t/**\n\t * Sets up the lightbox dismissal logic\n\t */\n\tprivate setupLightboxDismissLogic() {\n\t\tthis.dismissSubject\n\t\t\t.pipe(\n\t\t\t\ttap(() => {\n\t\t\t\t\tif (!this.activeLightbox) return\n\n\t\t\t\t\tconst { element } = this.activeLightbox\n\n\t\t\t\t\t// Animate out\n\t\t\t\t\tconst animation = element.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t})\n\n\t\t\t\t\tanimation.onfinish = () => {\n\t\t\t\t\t\telement.remove()\n\t\t\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t\t\t\toverlayStack.release()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.activeLightbox = undefined\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t/**\n\t * Push/open a lightbox\n\t */\n\tpublic push(config: LightboxConfig): void {\n\t\t// Close any existing lightbox first\n\t\tif (this.activeLightbox) {\n\t\t\tthis.dismiss()\n\t\t}\n\t\tthis.pushSubject.next(config)\n\t}\n\n\t/**\n\t * Dismiss the lightbox\n\t */\n\tpublic dismiss(): void {\n\t\tthis.dismissSubject.next()\n\t}\n\n\t/**\n\t * Navigate to previous image\n\t */\n\tprivate navigatePrev(): void {\n\t\tif (!this.activeLightbox || this.activeLightbox.images.length <= 1) return\n\n\t\tconst { images, config, element } = this.activeLightbox\n\t\tthis.activeLightbox.currentIndex = (this.activeLightbox.currentIndex - 1 + images.length) % images.length\n\t\tthis.renderLightbox(element, config, images, this.activeLightbox.currentIndex)\n\t}\n\n\t/**\n\t * Navigate to next image\n\t */\n\tprivate navigateNext(): void {\n\t\tif (!this.activeLightbox || this.activeLightbox.images.length <= 1) return\n\n\t\tconst { images, config, element } = this.activeLightbox\n\t\tthis.activeLightbox.currentIndex = (this.activeLightbox.currentIndex + 1) % images.length\n\t\tthis.renderLightbox(element, config, images, this.activeLightbox.currentIndex)\n\t}\n\n\t/**\n\t * Render component-only mode (no image background)\n\t */\n\tprivate renderComponent(overlay: HTMLDivElement, config: LightboxConfig): void {\n\t\tif (!config.component) return\n\n\t\t// Create the component\n\t\tlet component: HTMLElement\n\t\tif (typeof config.component === 'string') {\n\t\t\tcomponent = document.createElement(config.component)\n\t\t} else {\n\t\t\tcomponent = new (config.component as CustomElementConstructor)()\n\t\t}\n\n\t\t// Set props\n\t\tif (config.props) {\n\t\t\tObject.entries(config.props).forEach(([key, value]) => {\n\t\t\t\t;(component as unknown as Record<string, unknown>)[key] = value\n\t\t\t})\n\t\t}\n\n\t\t// Create wrapper with close button\n\t\tconst template = html`\n\t\t\t<div class=\"relative\" @click=${(e: Event) => e.stopPropagation()}>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute -top-12 right-0 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.dismiss()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Component container -->\n\t\t\t\t<div id=\"lightbox-component-container\"></div>\n\t\t\t</div>\n\t\t`\n\n\t\trender(template, overlay)\n\n\t\t// Append component after render\n\t\tconst container = overlay.querySelector('#lightbox-component-container')\n\t\tif (container) {\n\t\t\tcontainer.appendChild(component)\n\t\t}\n\t}\n\n\t/**\n\t * Render image lightbox\n\t */\n\tprivate renderLightbox(overlay: HTMLDivElement, config: LightboxConfig, images: string[], currentIndex: number): void {\n\t\tconst currentSrc = images[currentIndex]\n\t\tconst isGallery = images.length > 1\n\n\t\t// Create overlay component if specified\n\t\tlet overlayComponent: HTMLElement | null = null\n\t\tif (config.overlay) {\n\t\t\tif (typeof config.overlay === 'string') {\n\t\t\t\toverlayComponent = document.createElement(config.overlay)\n\t\t\t} else if (typeof config.overlay === 'function') {\n\t\t\t\toverlayComponent = new (config.overlay as CustomElementConstructor)()\n\t\t\t}\n\n\t\t\t// Set props on the component\n\t\t\tif (config.props && overlayComponent) {\n\t\t\t\tObject.entries(config.props).forEach(([key, value]) => {\n\t\t\t\t\t;(overlayComponent as unknown as Record<string, unknown>)[key] = value\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst template = html`\n\t\t\t<div\n\t\t\t\tclass=\"relative\"\n\t\t\t\tstyle=${styleMap({ maxWidth: '90vw', maxHeight: '90vh' })}\n\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute top-4 right-4 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.dismiss()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Image container with optional overlay -->\n\t\t\t\t<div class=\"relative\" id=\"lightbox-image-container\">\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc=${currentSrc}\n\t\t\t\t\t\tclass=\"max-w-full object-contain rounded-lg\"\n\t\t\t\t\t\tstyle=${styleMap({ maxHeight: '85vh' })}\n\t\t\t\t\t\t@click=${() => !isGallery && this.dismiss()}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Gallery controls -->\n\t\t\t\t${isGallery\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute left-1/2 -translate-x-1/2 flex items-center gap-4 text-white\"\n\t\t\t\t\t\t\t\tstyle=${styleMap({ bottom: '-60px' })}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.navigatePrev()}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\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</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-lg\">${currentIndex + 1} / ${images.length}</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.navigateNext()}\n\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\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</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\n\t\trender(template, overlay)\n\n\t\t// Append overlay component to image container after render\n\t\tif (overlayComponent) {\n\t\t\tconst container = overlay.querySelector('#lightbox-image-container')\n\t\t\tif (container) {\n\t\t\t\t// Remove any existing overlay component\n\t\t\t\tconst existing = container.querySelector('[data-lightbox-overlay]')\n\t\t\t\tif (existing) existing.remove()\n\n\t\t\t\toverlayComponent.setAttribute('data-lightbox-overlay', '')\n\t\t\t\tcontainer.appendChild(overlayComponent)\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Unified lightbox type - works as both directive and service\n */\nexport type LightboxAPI = {\n\t(options?: LightboxOptions): ReturnType<typeof lightboxDirective>\n\tpush: (config: LightboxConfig) => void\n\tdismiss: () => void\n}\n\n/**\n * Unified lightbox export - works as both directive and service:\n * - Directive: ${lightbox()} or ${lightbox({ overlay: html`...` })}\n * - Service: lightbox.push({ image, overlay: 'component-name', props })\n */\nexport const lightbox: LightboxAPI = Object.assign(\n\t// Callable as directive (backward compatible)\n\t(options?: LightboxOptions) => lightboxDirective(options),\n\t// Also has service methods\n\t{\n\t\tpush: (config: LightboxConfig) => LightboxService.getInstance().push(config),\n\t\tdismiss: () => LightboxService.getInstance().dismiss(),\n\t},\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"lightbox-B4m5lxGs.cjs","names":[],"sources":["../src/lightbox/lightbox.ts","../src/lightbox/flip-directive.ts","../src/lightbox/lightbox.directive.ts","../src/lightbox/lightbox-service.ts"],"sourcesContent":["import { css, html, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { when } from 'lit/directives/when.js'\nimport { ref, createRef, Ref } from 'lit/directives/ref.js'\nimport { fromEvent } from 'rxjs'\nimport { filter, takeUntil, tap, switchMap, map, first } from 'rxjs/operators'\nimport { SchmancyElement } from '@mixins/index'\nimport { overlayStack } from '../utils/overlay-stack'\n\n@customElement('schmancy-lightbox')\nexport class SchmancyLightbox extends SchmancyElement {\n\tstatic styles = [css`\n\t:host {\n\t\tdisplay: contents;\n\t}\n`]\n\n\t@property({ type: String }) src: string = ''\n\t@property({ type: Array }) images: string[] = []\n\t@property({ type: Number }) initialIndex: number = 0\n\t@property({ type: Boolean }) open: boolean = false\n\n\t@state() private currentIndex: number = 0\n\t@state() private isLoading: boolean = false\n\t@state() private zIndex: number = 10000\n\n\tprivate readonly swipeThreshold = 50\n\tprivate overlayRef: Ref<HTMLDivElement> = createRef()\n\tprivate contentRef: Ref<HTMLDivElement> = createRef()\n\tprivate imageRef: Ref<HTMLImageElement> = createRef()\n\n\tprivate get isGalleryMode(): boolean {\n\t\treturn this.images.length > 0\n\t}\n\n\tprivate get currentImageSrc(): string {\n\t\tif (this.isGalleryMode) {\n\t\t\treturn this.images[this.currentIndex] || ''\n\t\t}\n\t\treturn this.src\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback()\n\t\tthis.currentIndex = this.initialIndex\n\t}\n\n\tupdated(changedProperties: PropertyValues) {\n\t\tsuper.updated(changedProperties)\n\n\t\tif (changedProperties.has('open')) {\n\t\t\tif (this.open) {\n\t\t\t\t// Set dynamic z-index for proper stacking with sheets/dialogs\n\t\t\t\tthis.zIndex = overlayStack.getNextZIndex()\n\t\t\t\tdocument.body.style.overflow = 'hidden'\n\t\t\t\tthis.animateIn()\n\t\t\t\tthis.setupEventListeners()\n\t\t\t} else {\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t\tthis.animateOut()\n\t\t\t}\n\t\t}\n\n\t\tif (changedProperties.has('initialIndex')) {\n\t\t\tthis.currentIndex = this.initialIndex\n\t\t}\n\n\t\tif (changedProperties.has('currentIndex') && this.open) {\n\t\t\tthis.animateImageChange()\n\t\t}\n\t}\n\n\tprivate animateIn() {\n\t\tconst overlay = this.overlayRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst image = this.imageRef.value\n\n\t\tif (overlay) {\n\t\t\t// Set initial styles\n\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0)'\n\t\t\toverlay.style.opacity = '0'\n\n\t\t\t// Animate to visible state\n\t\t\toverlay.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0 },\n\t\t\t\t\t{ opacity: 1 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 300,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\t// Manually set background color after a tick\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.95)'\n\t\t\t})\n\t\t}\n\n\t\tif (content) {\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 400,\n\t\t\t\t\tdelay: 100,\n\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.56, 0.64, 1)', // Spring effect\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (image) {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 350,\n\t\t\t\t\tdelay: 150,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate animateOut() {\n\t\tconst overlay = this.overlayRef.value\n\t\tconst content = this.contentRef.value\n\t\tconst image = this.imageRef.value\n\n\t\tif (image) {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 200,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (content) {\n\t\t\tcontent.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: 'scale(0.95)', opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 250,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\n\t\tif (overlay) {\n\t\t\tconst animation = overlay.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 1 },\n\t\t\t\t\t{ opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 250,\n\t\t\t\t\tdelay: 50,\n\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tanimation.onfinish = () => {\n\t\t\t\t// Reset background color\n\t\t\t\toverlay.style.backgroundColor = 'rgba(0, 0, 0, 0)'\n\t\t\t\toverlayStack.release()\n\t\t\t\tthis.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate animateImageChange() {\n\t\tconst image = this.imageRef.value\n\t\tif (!image) return\n\n\t\t// Fade out\n\t\tconst fadeOut = image.animate(\n\t\t\t[\n\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t],\n\t\t\t{\n\t\t\t\tduration: 150,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t},\n\t\t)\n\n\t\t// Fade in after fade out completes\n\t\tfadeOut.onfinish = () => {\n\t\t\timage.animate(\n\t\t\t\t[\n\t\t\t\t\t{ opacity: 0, transform: 'scale(0.98)' },\n\t\t\t\t\t{ opacity: 1, transform: 'scale(1)' },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 200,\n\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate setupEventListeners() {\n\t\t// Keyboard navigation\n\t\tfromEvent<KeyboardEvent>(document, 'keydown')\n\t\t\t.pipe(\n\t\t\t\tfilter(() => this.open),\n\t\t\t\ttap(e => {\n\t\t\t\t\tswitch (e.key) {\n\t\t\t\t\t\tcase 'Escape':\n\t\t\t\t\t\t\tthis.handleClose()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\t\t\tthis.handlePrevious()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'ArrowRight':\n\t\t\t\t\t\t\tthis.handleNext()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\n\t\t// Touch/swipe events for mobile\n\t\tif (!this.isGalleryMode || this.images.length <= 1) return\n\n\t\tconst content = this.contentRef.value\n\t\tif (!content) return\n\n\t\tconst touchStart$ = fromEvent<TouchEvent>(content, 'touchstart')\n\t\tconst touchEnd$ = fromEvent<TouchEvent>(content, 'touchend')\n\n\t\ttouchStart$\n\t\t\t.pipe(\n\t\t\t\tswitchMap(startEvent => {\n\t\t\t\t\tconst startX = startEvent.touches[0].clientX\n\t\t\t\t\treturn touchEnd$.pipe(\n\t\t\t\t\t\tfirst(),\n\t\t\t\t\t\tmap(endEvent => {\n\t\t\t\t\t\t\tconst endX = endEvent.changedTouches[0].clientX\n\t\t\t\t\t\t\treturn endX - startX\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\tfilter(distance => Math.abs(distance) > this.swipeThreshold),\n\t\t\t\ttap(distance => (distance > 0 ? this.handlePrevious() : this.handleNext())),\n\t\t\t\ttakeUntil(this.disconnecting),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\tprivate handleClose = () => {\n\t\tthis.open = false\n\t}\n\n\tprivate handlePrevious = () => {\n\t\tif (this.isGalleryMode && this.images.length > 1) {\n\t\t\tthis.isLoading = true\n\t\t\tthis.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('change', {\n\t\t\t\t\tdetail: { index: this.currentIndex },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate handleNext = () => {\n\t\tif (this.isGalleryMode && this.images.length > 1) {\n\t\t\tthis.isLoading = true\n\t\t\tthis.currentIndex = (this.currentIndex + 1) % this.images.length\n\t\t\tthis.dispatchEvent(\n\t\t\t\tnew CustomEvent('change', {\n\t\t\t\t\tdetail: { index: this.currentIndex },\n\t\t\t\t\tbubbles: true,\n\t\t\t\t\tcomposed: true,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate handleImageLoad = () => {\n\t\tthis.isLoading = false\n\t}\n\n\tprivate handleOverlayClick = (e: Event) => {\n\t\t// Close when clicking the overlay (not the content)\n\t\tif (e.target === e.currentTarget) {\n\t\t\tthis.handleClose()\n\t\t}\n\t}\n\n\trender() {\n\t\tif (!this.open) return html``\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\t${ref(this.overlayRef)}\n\t\t\t\tclass=\"fixed inset-0 flex items-center justify-center backdrop-blur-sm\"\n\t\t\t\tstyle=\"z-index: ${this.zIndex}\"\n\t\t\t\t@click=${this.handleOverlayClick}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\t${ref(this.contentRef)}\n\t\t\t\t\tclass=\"relative max-w-[90vw] max-h-[90vh]\"\n\t\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t\t>\n\t\t\t\t\t<!-- Close Button -->\n\t\t\t\t\t<button\n\t\t\t\t\t\tclass=\"absolute top-4 right-4 md:top-4 md:right-4 sm:top-2 sm:right-2 bg-white/15 backdrop-blur-md text-white w-11 h-11 rounded-full flex items-center justify-center cursor-pointer z-10 transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t@click=${this.handleClose}\n\t\t\t\t\t\taria-label=\"Close lightbox\"\n\t\t\t\t\t\ttitle=\"Close (Esc)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<schmancy-icon>close</schmancy-icon>\n\t\t\t\t\t</button>\n\n\t\t\t\t\t<!-- Touch Zones for Gallery Navigation -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isGalleryMode && this.images.length > 1,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute top-0 bottom-0 left-0 w-1/3 cursor-pointer z-5\"\n\t\t\t\t\t\t\t\t@click=${this.handlePrevious}\n\t\t\t\t\t\t\t></div>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute top-0 bottom-0 right-0 w-1/3 cursor-pointer z-5\"\n\t\t\t\t\t\t\t\t@click=${this.handleNext}\n\t\t\t\t\t\t\t></div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\n\t\t\t\t\t<!-- Loading Spinner -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isLoading,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div class=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n\t\t\t\t\t\t\t\t<schmancy-progress indeterminate></schmancy-progress>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\n\t\t\t\t\t<!-- Main Image -->\n\t\t\t\t\t<img\n\t\t\t\t\t\t${ref(this.imageRef)}\n\t\t\t\t\t\tclass=\"max-w-[90vw] max-h-[90vh] object-contain rounded select-none touch-pinch-zoom ${this\n\t\t\t\t\t\t\t.isGalleryMode\n\t\t\t\t\t\t\t? 'cursor-default'\n\t\t\t\t\t\t\t: 'cursor-pointer'}\"\n\t\t\t\t\t\t.src=${this.currentImageSrc}\n\t\t\t\t\t\talt=\"Full size image\"\n\t\t\t\t\t\t@load=${this.handleImageLoad}\n\t\t\t\t\t\t@click=${() => (!this.isGalleryMode ? this.handleClose() : null)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<!-- Navigation Controls (Gallery Mode Only) -->\n\t\t\t\t\t${when(\n\t\t\t\t\t\tthis.isGalleryMode && this.images.length > 1,\n\t\t\t\t\t\t() => html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute bottom-[-3.5rem] md:bottom-[-3.5rem] sm:bottom-[-3rem] left-1/2 -translate-x-1/2 flex items-center gap-4 z-10\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"bg-white/15 backdrop-blur-md text-white w-10 h-10 rounded-full flex items-center justify-center cursor-pointer transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t\t\t\t@click=${this.handlePrevious}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous image\"\n\t\t\t\t\t\t\t\t\ttitle=\"Previous (←)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<schmancy-icon>arrow_back</schmancy-icon>\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-white text-base font-medium min-w-16 text-center\" aria-live=\"polite\">\n\t\t\t\t\t\t\t\t\t${this.currentIndex + 1} / ${this.images.length}\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"bg-white/15 backdrop-blur-md text-white w-10 h-10 rounded-full flex items-center justify-center cursor-pointer transition-all duration-200 hover:bg-white/25 hover:scale-105 active:scale-95\"\n\t\t\t\t\t\t\t\t\t@click=${this.handleNext}\n\t\t\t\t\t\t\t\t\taria-label=\"Next image\"\n\t\t\t\t\t\t\t\t\ttitle=\"Next (→)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<schmancy-icon>arrow_forward</schmancy-icon>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`,\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'schmancy-lightbox': SchmancyLightbox\n\t}\n}\n","import { directive, PartInfo, PartType, ElementPart } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { noChange } from 'lit'\n\nexport interface FlipOptions {\n\t/** Source element to animate from (uses element's bounding rect) */\n\tsourceElement?: HTMLElement\n\t/** Click position - can be MouseEvent, TouchEvent, or {x, y} coordinates */\n\tposition?: { x: number; y: number } | MouseEvent | TouchEvent\n\t/** Animation duration in ms (total for both stages) */\n\tduration?: number\n\t/** CSS easing function */\n\teasing?: string\n\t/** Whether to animate scale (default: true) */\n\tscale?: boolean\n\t/** Enable blackbird two-stage arc animation (default: true) */\n\tblackbird?: boolean\n}\n\n/** Extract x,y coordinates from various position inputs */\nfunction extractPosition(pos: FlipOptions['position']): { x: number; y: number } | null {\n\tif (!pos) return null\n\n\tif ('clientX' in pos) {\n\t\t// MouseEvent\n\t\treturn { x: pos.clientX, y: pos.clientY }\n\t} else if ('touches' in pos && pos.touches.length) {\n\t\t// TouchEvent\n\t\treturn { x: pos.touches[0].clientX, y: pos.touches[0].clientY }\n\t} else if ('x' in pos && 'y' in pos) {\n\t\t// Position object\n\t\treturn { x: pos.x, y: pos.y }\n\t}\n\n\treturn null\n}\n\n/**\n * Calculate arc control point for bird-like curved trajectory\n * Birds arc UP when taking off and arc DOWN when landing\n */\nfunction calculateArcPoint(\n\tstart: { x: number; y: number },\n\tend: { x: number; y: number },\n\tarcDirection: 'up' | 'down' = 'up',\n\tintensity: number = 0.3,\n): { x: number; y: number } {\n\tconst midX = (start.x + end.x) / 2\n\tconst midY = (start.y + end.y) / 2\n\tconst distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))\n\n\t// Arc height proportional to distance, but capped\n\tconst arcHeight = Math.min(distance * intensity, 150)\n\n\treturn {\n\t\tx: midX,\n\t\ty: arcDirection === 'up' ? midY - arcHeight : midY + arcHeight,\n\t}\n}\n\nclass FlipDirective extends AsyncDirective {\n\tprivate element?: HTMLElement\n\tprivate hasAnimated = false\n\n\tconstructor(partInfo: PartInfo) {\n\t\tsuper(partInfo)\n\t\tif (partInfo.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('flip directive can only be used on elements')\n\t\t}\n\t}\n\n\trender(_options?: FlipOptions) {\n\t\treturn noChange\n\t}\n\n\tupdate(part: ElementPart, [options]: [FlipOptions?]) {\n\t\tthis.element = part.element as HTMLElement\n\n\t\t// Animate if we have either a source element or position\n\t\tconst hasSource = options?.sourceElement || options?.position\n\t\tif (!this.hasAnimated && hasSource) {\n\t\t\tthis.hasAnimated = true\n\t\t\tthis.animateIn(options)\n\t\t}\n\n\t\treturn noChange\n\t}\n\n\tprivate animateIn(options?: FlipOptions) {\n\t\tif (!this.element) return\n\n\t\t// Check reduced motion preference\n\t\tif (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n\t\tconst totalDuration = options?.duration ?? 600\n\t\tconst animateScale = options?.scale !== false\n\t\tconst useBlackbird = options?.blackbird !== false\n\n\t\t// Get positions\n\t\tconst clickPos = extractPosition(options?.position)\n\t\tconst sourceRect = options?.sourceElement?.getBoundingClientRect()\n\n\t\tconst animate = () => {\n\t\t\tconst targetRect = this.element!.getBoundingClientRect()\n\t\t\tconst targetCenter = {\n\t\t\t\tx: targetRect.left + targetRect.width / 2,\n\t\t\t\ty: targetRect.top + targetRect.height / 2,\n\t\t\t}\n\n\t\t\t// Determine source point\n\t\t\tlet sourceCenter: { x: number; y: number }\n\t\t\tlet sourceScale = { x: 0.1, y: 0.1 }\n\n\t\t\tif (sourceRect) {\n\t\t\t\tsourceCenter = {\n\t\t\t\t\tx: sourceRect.left + sourceRect.width / 2,\n\t\t\t\t\ty: sourceRect.top + sourceRect.height / 2,\n\t\t\t\t}\n\t\t\t\tif (animateScale) {\n\t\t\t\t\tsourceScale = {\n\t\t\t\t\t\tx: sourceRect.width / targetRect.width,\n\t\t\t\t\t\ty: sourceRect.height / targetRect.height,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (clickPos) {\n\t\t\t\tsourceCenter = clickPos\n\t\t\t} else {\n\t\t\t\tsourceCenter = { x: window.innerWidth / 2, y: window.innerHeight / 2 }\n\t\t\t}\n\n\t\t\t// Calculate deltas from target (where element is) to source (where we start)\n\t\t\tconst sourceDelta = {\n\t\t\t\tx: sourceCenter.x - targetCenter.x,\n\t\t\t\ty: sourceCenter.y - targetCenter.y,\n\t\t\t}\n\n\t\t\tif (useBlackbird && clickPos && sourceRect) {\n\t\t\t\t// TWO-STAGE BLACKBIRD ANIMATION\n\t\t\t\t// Stage 1: Source element → Click position (takeoff arc - UP)\n\t\t\t\t// Stage 2: Click position → Final destination (landing arc - DOWN)\n\n\t\t\t\tconst clickDelta = {\n\t\t\t\t\tx: clickPos.x - targetCenter.x,\n\t\t\t\t\ty: clickPos.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\t// Calculate arc control points\n\t\t\t\tconst takeoffArc = calculateArcPoint(sourceCenter, clickPos, 'up', 0.4)\n\t\t\t\tconst landingArc = calculateArcPoint(clickPos, targetCenter, 'down', 0.3)\n\n\t\t\t\t// Arc deltas relative to target\n\t\t\t\tconst takeoffArcDelta = {\n\t\t\t\t\tx: takeoffArc.x - targetCenter.x,\n\t\t\t\t\ty: takeoffArc.y - targetCenter.y,\n\t\t\t\t}\n\t\t\t\tconst landingArcDelta = {\n\t\t\t\t\tx: landingArc.x - targetCenter.x,\n\t\t\t\t\ty: landingArc.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\t// Intermediate scale at click position\n\t\t\t\tconst midScale = 0.3\n\n\t\t\t\t// Create keyframes for two-stage arc animation\n\t\t\t\t// 0% → 25% → 50% → 75% → 100%\n\t\t\t\t// Source → Takeoff Arc → Click → Landing Arc → Final\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 0% - Start at source element\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(${sourceScale.x}, ${sourceScale.y})`,\n\t\t\t\t\t\t\topacity: 0.6,\n\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 25% - Peak of takeoff arc (bird lifts up)\n\t\t\t\t\t\t\ttransform: `translate(${takeoffArcDelta.x}px, ${takeoffArcDelta.y}px) scale(${midScale * 0.7})`,\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\toffset: 0.25,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 50% - At click position (transition point)\n\t\t\t\t\t\t\ttransform: `translate(${clickDelta.x}px, ${clickDelta.y}px) scale(${midScale})`,\n\t\t\t\t\t\t\topacity: 0.9,\n\t\t\t\t\t\t\toffset: 0.5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 75% - Landing arc (bird descends toward target)\n\t\t\t\t\t\t\ttransform: `translate(${landingArcDelta.x}px, ${landingArcDelta.y}px) scale(0.6)`,\n\t\t\t\t\t\t\topacity: 0.95,\n\t\t\t\t\t\t\toffset: 0.75,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// 100% - Final position\n\t\t\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\toffset: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)', // Slight overshoot for organic feel\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t} else if (useBlackbird && clickPos) {\n\t\t\t\t// SINGLE-STAGE with arc (click position to final)\n\t\t\t\tconst arcPoint = calculateArcPoint(clickPos, targetCenter, 'down', 0.35)\n\t\t\t\tconst arcDelta = {\n\t\t\t\t\tx: arcPoint.x - targetCenter.x,\n\t\t\t\t\ty: arcPoint.y - targetCenter.y,\n\t\t\t\t}\n\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(0.1)`,\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${arcDelta.x}px, ${arcDelta.y}px) scale(0.5)`,\n\t\t\t\t\t\t\topacity: 0.8,\n\t\t\t\t\t\t\toffset: 0.5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: 'translate(0, 0) scale(1)',\n\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\toffset: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: 'cubic-bezier(0.34, 1.2, 0.64, 1)',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\t// SIMPLE animation (fallback)\n\t\t\t\tthis.element!.animate(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransform: `translate(${sourceDelta.x}px, ${sourceDelta.y}px) scale(${sourceScale.x}, ${sourceScale.y})`,\n\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ transform: 'translate(0, 0) scale(1, 1)', opacity: 1 },\n\t\t\t\t\t],\n\t\t\t\t\t{\n\t\t\t\t\t\tduration: totalDuration,\n\t\t\t\t\t\teasing: options?.easing ?? 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Handle image loading\n\t\tif (this.element instanceof HTMLImageElement) {\n\t\t\tif (this.element.complete) {\n\t\t\t\trequestAnimationFrame(animate)\n\t\t\t} else {\n\t\t\t\tthis.element.addEventListener('load', () => requestAnimationFrame(animate), { once: true })\n\t\t\t}\n\t\t} else {\n\t\t\trequestAnimationFrame(animate)\n\t\t}\n\t}\n}\n\nexport const flip = directive(FlipDirective)\n","import { directive, PartInfo, PartType, ElementPart } from 'lit/directive.js'\nimport { AsyncDirective } from 'lit/async-directive.js'\nimport { noChange, TemplateResult } from 'lit'\nimport { html, render } from 'lit'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { flip } from './flip-directive.js'\n\nexport interface LightboxOptions {\n\timages?: string[]\n\tindex?: number\n\toverlay?: TemplateResult\n}\n\nclass LightboxDirective extends AsyncDirective {\n\tprivate element?: HTMLImageElement\n\tprivate clickHandler?: EventListener\n\tprivate keyHandler?: EventListener\n\tprivate overlayElement?: HTMLDivElement\n\tprivate currentIndex = 0\n\tprivate images: string[] = []\n\tprivate overlay?: TemplateResult\n\tprivate clickPosition?: { x: number; y: number }\n\n\tconstructor(partInfo: PartInfo) {\n\t\tsuper(partInfo)\n\t\tif (partInfo.type !== PartType.ELEMENT) {\n\t\t\tthrow new Error('lightbox directive can only be used on elements')\n\t\t}\n\t}\n\n\trender(_options?: LightboxOptions) {\n\t\treturn noChange\n\t}\n\n\tupdate(part: ElementPart, [options]: [LightboxOptions?]) {\n\t\tthis.element = part.element as HTMLImageElement\n\n\t\t// Setup click handler\n\t\tif (!this.clickHandler) {\n\t\t\tthis.clickHandler = (e: Event) => {\n\t\t\t\te.preventDefault()\n\t\t\t\te.stopPropagation()\n\n\t\t\t\t// Capture click position from MouseEvent or TouchEvent\n\t\t\t\tif ('clientX' in e) {\n\t\t\t\t\tthis.clickPosition = { x: (e as MouseEvent).clientX, y: (e as MouseEvent).clientY }\n\t\t\t\t} else if ('touches' in e && (e as TouchEvent).touches.length) {\n\t\t\t\t\tconst touch = (e as TouchEvent).touches[0]\n\t\t\t\t\tthis.clickPosition = { x: touch.clientX, y: touch.clientY }\n\t\t\t\t}\n\n\t\t\t\tif (options?.images && options.images.length > 0) {\n\t\t\t\t\tthis.images = options.images\n\t\t\t\t\tthis.currentIndex = options.index || 0\n\t\t\t\t} else {\n\t\t\t\t\tthis.images = [this.element!.src]\n\t\t\t\t\tthis.currentIndex = 0\n\t\t\t\t}\n\t\t\t\tthis.overlay = options?.overlay\n\n\t\t\t\tthis.open()\n\t\t\t}\n\n\t\t\tthis.element.addEventListener('click', this.clickHandler)\n\t\t\tthis.element.style.cursor = 'pointer'\n\t\t\tthis.element.classList.add('hover:opacity-80', 'transition-opacity')\n\t\t}\n\n\t\treturn noChange\n\t}\n\n\tprivate open() {\n\t\t// Create overlay container with flex centering\n\t\tthis.overlayElement = document.createElement('div')\n\t\tthis.overlayElement.className = 'fixed inset-0 flex items-center justify-center opacity-0 bg-black/95 backdrop-blur-sm'\n\t\tthis.overlayElement.style.zIndex = '1000'\n\n\t\t// Render lightbox content using Lit\n\t\trender(this.renderLightbox(), this.overlayElement)\n\n\t\t// Add to body\n\t\tdocument.body.appendChild(this.overlayElement)\n\t\tdocument.body.style.overflow = 'hidden'\n\n\t\t// Animate in overlay\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.overlayElement!.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\tduration: 300,\n\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\t\t})\n\n\t\t// Setup keyboard\n\t\tthis.keyHandler = (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') this.close()\n\t\t\tif (e.key === 'ArrowLeft' && this.images.length > 1) this.prev()\n\t\t\tif (e.key === 'ArrowRight' && this.images.length > 1) this.next()\n\t\t}\n\t\tdocument.addEventListener('keydown', this.keyHandler)\n\n\t\t// Click overlay to close\n\t\tthis.overlayElement.addEventListener('click', e => {\n\t\t\tif (e.target === this.overlayElement) this.close()\n\t\t})\n\t}\n\n\tprivate close() {\n\t\tif (!this.overlayElement) return\n\n\t\tconst contentContainer = this.overlayElement.querySelector('[data-lightbox-content]') as HTMLElement\n\n\t\t// Animate back to click position\n\t\tif (contentContainer && this.clickPosition) {\n\t\t\tconst rect = contentContainer.getBoundingClientRect()\n\n\t\t\t// Animate container shrinking toward click point\n\t\t\tconst deltaX = this.clickPosition.x - (rect.left + rect.width / 2)\n\t\t\tconst deltaY = this.clickPosition.y - (rect.top + rect.height / 2)\n\n\t\t\tconst containerAnim = contentContainer.animate(\n\t\t\t\t[\n\t\t\t\t\t{ transform: 'translate(0, 0) scale(1)', opacity: 1 },\n\t\t\t\t\t{ transform: `translate(${deltaX}px, ${deltaY}px) scale(0.1)`, opacity: 0 },\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tduration: 300,\n\t\t\t\t\teasing: 'cubic-bezier(0.4, 0, 0.2, 1)',\n\t\t\t\t\tfill: 'forwards',\n\t\t\t\t},\n\t\t\t)\n\n\t\t\tthis.overlayElement.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: 250,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\n\t\t\tcontainerAnim.onfinish = () => {\n\t\t\t\tthis.overlayElement?.remove()\n\t\t\t\tthis.overlayElement = undefined\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t}\n\t\t} else {\n\t\t\t// Fallback to simple fade\n\t\t\tconst animation = this.overlayElement.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\tduration: 250,\n\t\t\t\teasing: 'ease-out',\n\t\t\t\tfill: 'forwards',\n\t\t\t})\n\n\t\t\tanimation.onfinish = () => {\n\t\t\t\tthis.overlayElement?.remove()\n\t\t\t\tthis.overlayElement = undefined\n\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t}\n\t\t}\n\n\t\tif (this.keyHandler) {\n\t\t\tdocument.removeEventListener('keydown', this.keyHandler)\n\t\t\tthis.keyHandler = undefined\n\t\t}\n\t}\n\n\tprivate prev() {\n\t\tthis.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length\n\t\tthis.updateImage()\n\t}\n\n\tprivate next() {\n\t\tthis.currentIndex = (this.currentIndex + 1) % this.images.length\n\t\tthis.updateImage()\n\t}\n\n\tprivate updateImage() {\n\t\tif (!this.overlayElement) return\n\t\trender(this.renderLightbox(), this.overlayElement)\n\t}\n\n\tprivate renderLightbox() {\n\t\tconst currentSrc = this.images[this.currentIndex]\n\t\tconst isGallery = this.images.length > 1\n\n\t\treturn html`\n\t\t\t<div\n\t\t\t\tdata-lightbox-content\n\t\t\t\tclass=\"relative\"\n\t\t\t\tstyle=${styleMap({\n\t\t\t\t\ttransformOrigin: 'center center',\n\t\t\t\t})}\n\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute top-2 right-2 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.close()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Image container with optional overlay -->\n\t\t\t\t<div class=\"relative\">\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc=${currentSrc}\n\t\t\t\t\t\t${flip({\n\t\t\t\t\t\t\tsourceElement: this.element,\n\t\t\t\t\t\t\tposition: this.clickPosition,\n\t\t\t\t\t\t\tduration: 600,\n\t\t\t\t\t\t\tscale: true,\n\t\t\t\t\t\t\tblackbird: true,\n\t\t\t\t\t\t})}\n\t\t\t\t\t\tclass=\"object-contain rounded-lg\"\n\t\t\t\t\t\tstyle=\"max-height: calc(100vh - 40px); max-width: 90vw;\"\n\t\t\t\t\t\t@click=${() => !isGallery && this.close()}\n\t\t\t\t\t/>\n\t\t\t\t\t${this.overlay ? this.overlay : ''}\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Gallery controls -->\n\t\t\t\t${isGallery\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<div class=\"flex items-center justify-center gap-4 text-white mt-4\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.prev()}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\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</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-lg\">${this.currentIndex + 1} / ${this.images.length}</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.next()}\n\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\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</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\t}\n\n\tdisconnected() {\n\t\tif (this.element && this.clickHandler) {\n\t\t\tthis.element.removeEventListener('click', this.clickHandler)\n\t\t}\n\t\tthis.close()\n\t}\n}\n\nexport const lightbox = directive(LightboxDirective)\n","import { filter, fromEvent, map, Subject, switchMap, takeUntil, tap } from 'rxjs'\nimport { html, render } from 'lit'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { ComponentType } from '../area/router.types'\nimport { discoverComponent } from '@mixins/discovery.service'\nimport { overlayStack } from '../utils/overlay-stack'\nimport { lightbox as lightboxDirective, type LightboxOptions } from './lightbox.directive'\n\nexport type LightboxConfig = {\n\t// Image mode\n\timage?: string\n\timages?: string[]\n\tindex?: number\n\toverlay?: ComponentType\n\n\t// Component-only mode (no image background)\n\tcomponent?: ComponentType\n\n\tprops?: Record<string, unknown>\n}\n\n\n/**\n * Lightbox service for centralized lightbox management.\n * Follows the same patterns as DialogService.\n */\nclass LightboxService {\n\tprivate static instance: LightboxService\n\n\t// Subject for lightbox opening requests\n\tprivate pushSubject = new Subject<LightboxConfig>()\n\n\t// Subject for lightbox dismissal requests\n\tprivate dismissSubject = new Subject<void>()\n\n\t// Track active lightbox\n\tprivate activeLightbox?: {\n\t\telement: HTMLDivElement\n\t\tconfig: LightboxConfig\n\t\tcurrentIndex: number\n\t\timages: string[]\n\t}\n\n\tprivate constructor() {\n\t\tthis.setupLightboxOpeningLogic()\n\t\tthis.setupLightboxDismissLogic()\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tpublic static getInstance(): LightboxService {\n\t\tif (!LightboxService.instance) {\n\t\t\tLightboxService.instance = new LightboxService()\n\t\t}\n\t\treturn LightboxService.instance\n\t}\n\n\t/**\n\t * Sets up the main lightbox opening logic using RxJS pipes\n\t */\n\tprivate setupLightboxOpeningLogic() {\n\t\tthis.pushSubject\n\t\t\t.pipe(\n\t\t\t\tswitchMap(config => {\n\t\t\t\t\t// Use discoverComponent to find schmancy-theme (same pattern as sheet.service.ts)\n\t\t\t\t\treturn discoverComponent<HTMLElement>('schmancy-theme').pipe(\n\t\t\t\t\t\tmap(theme => {\n\t\t\t\t\t\t\t// Determine container - use theme or fallback to body\n\t\t\t\t\t\t\tconst container = theme || document.body\n\n\t\t\t\t\t\t\t// Create overlay element\n\t\t\t\t\t\t\tconst overlay = document.createElement('div')\n\t\t\t\t\t\t\toverlay.className = 'fixed inset-0 flex items-center justify-center opacity-0 bg-black/95 backdrop-blur-sm'\n\t\t\t\t\t\t\toverlay.style.zIndex = String(overlayStack.getNextZIndex())\n\n\t\t\t\t\t\t\tcontainer.appendChild(overlay)\n\t\t\t\t\t\t\tdocument.body.style.overflow = 'hidden'\n\n\t\t\t\t\t\t\treturn { overlay, config, container }\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}),\n\t\t\t\ttap(({ overlay, config }) => {\n\t\t\t\t\t// Setup images array\n\t\t\t\t\tlet images: string[] = []\n\t\t\t\t\tlet currentIndex = 0\n\n\t\t\t\t\tif (config.images && config.images.length > 0) {\n\t\t\t\t\t\timages = config.images\n\t\t\t\t\t\tcurrentIndex = config.index || 0\n\t\t\t\t\t} else if (config.image) {\n\t\t\t\t\t\timages = [config.image]\n\t\t\t\t\t\tcurrentIndex = 0\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store active lightbox state\n\t\t\t\t\tthis.activeLightbox = {\n\t\t\t\t\t\telement: overlay,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcurrentIndex,\n\t\t\t\t\t\timages,\n\t\t\t\t\t}\n\n\t\t\t\t\t// Keyboard handling via RxJS\n\t\t\t\t\tfromEvent<KeyboardEvent>(document, 'keydown').pipe(\n\t\t\t\t\t\ttakeUntil(this.dismissSubject),\n\t\t\t\t\t\tfilter(() => !!this.activeLightbox),\n\t\t\t\t\t\ttap(e => {\n\t\t\t\t\t\t\tif (e.key === 'Escape') this.dismiss()\n\t\t\t\t\t\t\tif (e.key === 'ArrowLeft' && this.activeLightbox!.images.length > 1) this.navigatePrev()\n\t\t\t\t\t\t\tif (e.key === 'ArrowRight' && this.activeLightbox!.images.length > 1) this.navigateNext()\n\t\t\t\t\t\t})\n\t\t\t\t\t).subscribe()\n\n\t\t\t\t\t// Click overlay to close via RxJS\n\t\t\t\t\tfromEvent<MouseEvent>(overlay, 'click').pipe(\n\t\t\t\t\t\ttakeUntil(this.dismissSubject),\n\t\t\t\t\t\tfilter(e => e.target === overlay),\n\t\t\t\t\t\ttap(() => this.dismiss())\n\t\t\t\t\t).subscribe()\n\n\t\t\t\t\t// Render content\n\t\t\t\t\tif (config.component) {\n\t\t\t\t\t\tthis.renderComponent(overlay, config)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.renderLightbox(overlay, config, images, currentIndex)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Animate in\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\toverlay.animate([{ opacity: 0 }, { opacity: 1 }], {\n\t\t\t\t\t\t\tduration: 300,\n\t\t\t\t\t\t\teasing: 'cubic-bezier(0.25, 1, 0.5, 1)',\n\t\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t/**\n\t * Sets up the lightbox dismissal logic\n\t */\n\tprivate setupLightboxDismissLogic() {\n\t\tthis.dismissSubject\n\t\t\t.pipe(\n\t\t\t\ttap(() => {\n\t\t\t\t\tif (!this.activeLightbox) return\n\n\t\t\t\t\tconst { element } = this.activeLightbox\n\n\t\t\t\t\t// Animate out\n\t\t\t\t\tconst animation = element.animate([{ opacity: 1 }, { opacity: 0 }], {\n\t\t\t\t\t\tduration: 250,\n\t\t\t\t\t\teasing: 'ease-out',\n\t\t\t\t\t\tfill: 'forwards',\n\t\t\t\t\t})\n\n\t\t\t\t\tanimation.onfinish = () => {\n\t\t\t\t\t\telement.remove()\n\t\t\t\t\t\tdocument.body.style.overflow = ''\n\t\t\t\t\t\toverlayStack.release()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.activeLightbox = undefined\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.subscribe()\n\t}\n\n\t/**\n\t * Push/open a lightbox\n\t */\n\tpublic push(config: LightboxConfig): void {\n\t\t// Close any existing lightbox first\n\t\tif (this.activeLightbox) {\n\t\t\tthis.dismiss()\n\t\t}\n\t\tthis.pushSubject.next(config)\n\t}\n\n\t/**\n\t * Dismiss the lightbox\n\t */\n\tpublic dismiss(): void {\n\t\tthis.dismissSubject.next()\n\t}\n\n\t/**\n\t * Navigate to previous image\n\t */\n\tprivate navigatePrev(): void {\n\t\tif (!this.activeLightbox || this.activeLightbox.images.length <= 1) return\n\n\t\tconst { images, config, element } = this.activeLightbox\n\t\tthis.activeLightbox.currentIndex = (this.activeLightbox.currentIndex - 1 + images.length) % images.length\n\t\tthis.renderLightbox(element, config, images, this.activeLightbox.currentIndex)\n\t}\n\n\t/**\n\t * Navigate to next image\n\t */\n\tprivate navigateNext(): void {\n\t\tif (!this.activeLightbox || this.activeLightbox.images.length <= 1) return\n\n\t\tconst { images, config, element } = this.activeLightbox\n\t\tthis.activeLightbox.currentIndex = (this.activeLightbox.currentIndex + 1) % images.length\n\t\tthis.renderLightbox(element, config, images, this.activeLightbox.currentIndex)\n\t}\n\n\t/**\n\t * Render component-only mode (no image background)\n\t */\n\tprivate renderComponent(overlay: HTMLDivElement, config: LightboxConfig): void {\n\t\tif (!config.component) return\n\n\t\t// Create the component\n\t\tlet component: HTMLElement\n\t\tif (typeof config.component === 'string') {\n\t\t\tcomponent = document.createElement(config.component)\n\t\t} else {\n\t\t\tcomponent = new (config.component as CustomElementConstructor)()\n\t\t}\n\n\t\t// Set props\n\t\tif (config.props) {\n\t\t\tObject.entries(config.props).forEach(([key, value]) => {\n\t\t\t\t;(component as unknown as Record<string, unknown>)[key] = value\n\t\t\t})\n\t\t}\n\n\t\t// Create wrapper with close button\n\t\tconst template = html`\n\t\t\t<div class=\"relative\" @click=${(e: Event) => e.stopPropagation()}>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute -top-12 right-0 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.dismiss()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Component container -->\n\t\t\t\t<div id=\"lightbox-component-container\"></div>\n\t\t\t</div>\n\t\t`\n\n\t\trender(template, overlay)\n\n\t\t// Append component after render\n\t\tconst container = overlay.querySelector('#lightbox-component-container')\n\t\tif (container) {\n\t\t\tcontainer.appendChild(component)\n\t\t}\n\t}\n\n\t/**\n\t * Render image lightbox\n\t */\n\tprivate renderLightbox(overlay: HTMLDivElement, config: LightboxConfig, images: string[], currentIndex: number): void {\n\t\tconst currentSrc = images[currentIndex]\n\t\tconst isGallery = images.length > 1\n\n\t\t// Create overlay component if specified\n\t\tlet overlayComponent: HTMLElement | null = null\n\t\tif (config.overlay) {\n\t\t\tif (typeof config.overlay === 'string') {\n\t\t\t\toverlayComponent = document.createElement(config.overlay)\n\t\t\t} else if (typeof config.overlay === 'function') {\n\t\t\t\toverlayComponent = new (config.overlay as CustomElementConstructor)()\n\t\t\t}\n\n\t\t\t// Set props on the component\n\t\t\tif (config.props && overlayComponent) {\n\t\t\t\tObject.entries(config.props).forEach(([key, value]) => {\n\t\t\t\t\t;(overlayComponent as unknown as Record<string, unknown>)[key] = value\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst template = html`\n\t\t\t<div\n\t\t\t\tclass=\"relative\"\n\t\t\t\tstyle=${styleMap({ maxWidth: '90vw', maxHeight: '90vh' })}\n\t\t\t\t@click=${(e: Event) => e.stopPropagation()}\n\t\t\t>\n\t\t\t\t<!-- Close button -->\n\t\t\t\t<button\n\t\t\t\t\tclass=\"absolute top-4 right-4 z-10 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center text-white transition-colors\"\n\t\t\t\t\t@click=${() => this.dismiss()}\n\t\t\t\t\taria-label=\"Close\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"text-2xl\">×</span>\n\t\t\t\t</button>\n\n\t\t\t\t<!-- Image container with optional overlay -->\n\t\t\t\t<div class=\"relative\" id=\"lightbox-image-container\">\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc=${currentSrc}\n\t\t\t\t\t\tclass=\"max-w-full object-contain rounded-lg\"\n\t\t\t\t\t\tstyle=${styleMap({ maxHeight: '85vh' })}\n\t\t\t\t\t\t@click=${() => !isGallery && this.dismiss()}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Gallery controls -->\n\t\t\t\t${isGallery\n\t\t\t\t\t? html`\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"absolute left-1/2 -translate-x-1/2 flex items-center gap-4 text-white\"\n\t\t\t\t\t\t\t\tstyle=${styleMap({ bottom: '-60px' })}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.navigatePrev()}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous\"\n\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</button>\n\n\t\t\t\t\t\t\t\t<div class=\"text-lg\">${currentIndex + 1} / ${images.length}</div>\n\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclass=\"w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition-colors\"\n\t\t\t\t\t\t\t\t\t@click=${() => this.navigateNext()}\n\t\t\t\t\t\t\t\t\taria-label=\"Next\"\n\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</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t`\n\t\t\t\t\t: ''}\n\t\t\t</div>\n\t\t`\n\n\t\trender(template, overlay)\n\n\t\t// Append overlay component to image container after render\n\t\tif (overlayComponent) {\n\t\t\tconst container = overlay.querySelector('#lightbox-image-container')\n\t\t\tif (container) {\n\t\t\t\t// Remove any existing overlay component\n\t\t\t\tconst existing = container.querySelector('[data-lightbox-overlay]')\n\t\t\t\tif (existing) existing.remove()\n\n\t\t\t\toverlayComponent.setAttribute('data-lightbox-overlay', '')\n\t\t\t\tcontainer.appendChild(overlayComponent)\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Unified lightbox type - works as both directive and service\n */\nexport type LightboxAPI = {\n\t(options?: LightboxOptions): ReturnType<typeof lightboxDirective>\n\tpush: (config: LightboxConfig) => void\n\tdismiss: () => void\n}\n\n/**\n * Unified lightbox export - works as both directive and service:\n * - Directive: ${lightbox()} or ${lightbox({ overlay: html`...` })}\n * - Service: lightbox.push({ image, overlay: 'component-name', props })\n */\nexport const lightbox: LightboxAPI = Object.assign(\n\t// Callable as directive (backward compatible)\n\t(options?: LightboxOptions) => lightboxDirective(options),\n\t// Also has service methods\n\t{\n\t\tpush: (config: LightboxConfig) => LightboxService.getInstance().push(config),\n\t\tdismiss: () => LightboxService.getInstance().dismiss(),\n\t},\n)\n"],"mappings":"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"}