@mhmo91/schmancy 0.10.25 → 0.10.26
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.
- package/dist/agent/{overlay.confirm-body-DozUyDYx.js → overlay.confirm-body-DJrL6tio.js} +1 -1
- package/dist/agent/{overlay.confirm-body-DozUyDYx.js.map → overlay.confirm-body-DJrL6tio.js.map} +1 -1
- package/dist/agent/schmancy.agent.js +1779 -1792
- package/dist/agent/schmancy.agent.js.map +1 -1
- package/dist/{area-DrVE5pXW.cjs → area-DkvO_oiO.cjs} +1 -1
- package/dist/{area-DrVE5pXW.cjs.map → area-DkvO_oiO.cjs.map} +1 -1
- package/dist/{area-1EG1LrkX.js → area-fC1_kvAW.js} +1 -1
- package/dist/{area-1EG1LrkX.js.map → area-fC1_kvAW.js.map} +1 -1
- package/dist/area.cjs +1 -1
- package/dist/area.js +1 -1
- package/dist/{autocomplete-6pdZxEab.cjs → autocomplete-Aa2IstyX.cjs} +1 -1
- package/dist/{autocomplete-6pdZxEab.cjs.map → autocomplete-Aa2IstyX.cjs.map} +1 -1
- package/dist/{autocomplete-nrIcCilw.js → autocomplete-Hb-C11a3.js} +2 -2
- package/dist/{autocomplete-nrIcCilw.js.map → autocomplete-Hb-C11a3.js.map} +1 -1
- package/dist/autocomplete.cjs +1 -1
- package/dist/autocomplete.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +2 -2
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/boat-BEq-AHmL.cjs +85 -0
- package/dist/boat-BEq-AHmL.cjs.map +1 -0
- package/dist/{boat--fLgbDAE.js → boat-BW6aRcdY.js} +27 -21
- package/dist/boat-BW6aRcdY.js.map +1 -0
- package/dist/boat.cjs +1 -1
- package/dist/boat.js +1 -1
- package/dist/breadcrumb.cjs +1 -1
- package/dist/breadcrumb.js +1 -1
- package/dist/{busy-DVCIxBVf.cjs → busy-CKpIblIO.cjs} +1 -1
- package/dist/{busy-DVCIxBVf.cjs.map → busy-CKpIblIO.cjs.map} +1 -1
- package/dist/{busy-DshZcVZ4.js → busy-D-ucQFSB.js} +1 -1
- package/dist/{busy-DshZcVZ4.js.map → busy-D-ucQFSB.js.map} +1 -1
- package/dist/busy.cjs +1 -1
- package/dist/busy.js +1 -1
- package/dist/{button-D9UJ7I6Z.js → button-BU-X0a0S.js} +1 -1
- package/dist/{button-D9UJ7I6Z.js.map → button-BU-X0a0S.js.map} +1 -1
- package/dist/{button-JrTMzwHY.cjs → button-HzLpB3NP.cjs} +1 -1
- package/dist/{button-JrTMzwHY.cjs.map → button-HzLpB3NP.cjs.map} +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{card-CTotavhH.cjs → card-CcrUlgd3.cjs} +1 -1
- package/dist/{card-CTotavhH.cjs.map → card-CcrUlgd3.cjs.map} +1 -1
- package/dist/{card-BvCFuX3J.js → card-ueXBeJ6q.js} +1 -1
- package/dist/{card-BvCFuX3J.js.map → card-ueXBeJ6q.js.map} +1 -1
- package/dist/card.cjs +1 -1
- package/dist/card.js +1 -1
- package/dist/{checkbox-GPsdCUbs.js → checkbox-CW1kk4Tu.js} +1 -1
- package/dist/{checkbox-GPsdCUbs.js.map → checkbox-CW1kk4Tu.js.map} +1 -1
- package/dist/{checkbox-By4fFmjt.cjs → checkbox-qsp-I5C6.cjs} +1 -1
- package/dist/{checkbox-By4fFmjt.cjs.map → checkbox-qsp-I5C6.cjs.map} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/{chips-27umqnat.js → chips-C_F6-gfe.js} +2 -2
- package/dist/{chips-27umqnat.js.map → chips-C_F6-gfe.js.map} +1 -1
- package/dist/{chips-BZf9sGA8.cjs → chips-Dluk6RV4.cjs} +1 -1
- package/dist/{chips-BZf9sGA8.cjs.map → chips-Dluk6RV4.cjs.map} +1 -1
- package/dist/chips.cjs +1 -1
- package/dist/chips.js +2 -2
- package/dist/connectivity.cjs +1 -1
- package/dist/connectivity.js +1 -1
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/{date-range-wDVHcr0u.js → date-range-ASZ8h_Il.js} +2 -2
- package/dist/{date-range-wDVHcr0u.js.map → date-range-ASZ8h_Il.js.map} +1 -1
- package/dist/{date-range-BJnLWCRF.cjs → date-range-BFOqXAI2.cjs} +1 -1
- package/dist/{date-range-BJnLWCRF.cjs.map → date-range-BFOqXAI2.cjs.map} +1 -1
- package/dist/{date-range-inline-B6uKUliV.cjs → date-range-inline-BNmNOpL0.cjs} +1 -1
- package/dist/{date-range-inline-B6uKUliV.cjs.map → date-range-inline-BNmNOpL0.cjs.map} +1 -1
- package/dist/{date-range-inline-BNbbRfIA.js → date-range-inline-DHrgolLn.js} +1 -1
- package/dist/{date-range-inline-BNbbRfIA.js.map → date-range-inline-DHrgolLn.js.map} +1 -1
- package/dist/date-range-inline.cjs +1 -1
- package/dist/date-range-inline.js +1 -1
- package/dist/date-range.cjs +1 -1
- package/dist/date-range.js +1 -1
- package/dist/delay.cjs +1 -1
- package/dist/delay.js +1 -1
- package/dist/{details-Ckxpwacj.js → details-B9RgRw6c.js} +1 -1
- package/dist/{details-Ckxpwacj.js.map → details-B9RgRw6c.js.map} +1 -1
- package/dist/{details-DNrWIes6.cjs → details-Bx9c4XQR.cjs} +1 -1
- package/dist/{details-DNrWIes6.cjs.map → details-Bx9c4XQR.cjs.map} +1 -1
- package/dist/details.cjs +1 -1
- package/dist/details.js +1 -1
- package/dist/{directives-F15SJZUR.cjs → directives-Dq0zi2KR.cjs} +13 -11
- package/dist/{directives-F15SJZUR.cjs.map → directives-Dq0zi2KR.cjs.map} +1 -1
- package/dist/{directives-BBMqe8x3.js → directives-sWKTEJDb.js} +27 -46
- package/dist/{directives-BBMqe8x3.js.map → directives-sWKTEJDb.js.map} +1 -1
- package/dist/directives.cjs +1 -1
- package/dist/directives.js +1 -1
- package/dist/{divider-BzcZGo4S.js → divider-C7BtzDcK.js} +1 -1
- package/dist/{divider-BzcZGo4S.js.map → divider-C7BtzDcK.js.map} +1 -1
- package/dist/{divider-Cde33ivs.cjs → divider-DH0BvTOv.cjs} +1 -1
- package/dist/{divider-Cde33ivs.cjs.map → divider-DH0BvTOv.cjs.map} +1 -1
- package/dist/divider.cjs +1 -1
- package/dist/divider.js +1 -1
- package/dist/dropdown.cjs +1 -1
- package/dist/dropdown.js +1 -1
- package/dist/{expand-Db4V0jj-.cjs → expand-CPMF44eL.cjs} +1 -1
- package/dist/{expand-Db4V0jj-.cjs.map → expand-CPMF44eL.cjs.map} +1 -1
- package/dist/{expand-DI144OzN.js → expand-DcMx9dHY.js} +2 -2
- package/dist/{expand-DI144OzN.js.map → expand-DcMx9dHY.js.map} +1 -1
- package/dist/expand.cjs +1 -1
- package/dist/expand.js +1 -1
- package/dist/{float--RScf9BZ.cjs → float-CgBN4H3g.cjs} +1 -1
- package/dist/{float--RScf9BZ.cjs.map → float-CgBN4H3g.cjs.map} +1 -1
- package/dist/{float-DIyzy1c2.js → float-DkUw5TN4.js} +1 -1
- package/dist/{float-DIyzy1c2.js.map → float-DkUw5TN4.js.map} +1 -1
- package/dist/float.cjs +1 -1
- package/dist/float.js +1 -1
- package/dist/{form-DWNpOsIU.cjs → form-DxApnyVx.cjs} +1 -1
- package/dist/{form-DWNpOsIU.cjs.map → form-DxApnyVx.cjs.map} +1 -1
- package/dist/{form-RtXH8UHQ.js → form-kSgJf_h4.js} +8 -8
- package/dist/{form-RtXH8UHQ.js.map → form-kSgJf_h4.js.map} +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.js +6 -6
- package/dist/handover/agent-runtime-followups.md +1 -1
- package/dist/handover/agent-runtime-v1.md +3 -3
- package/dist/{icons-bNxlWLlk.cjs → icons-3F1nQAn_.cjs} +1 -1
- package/dist/{icons-bNxlWLlk.cjs.map → icons-3F1nQAn_.cjs.map} +1 -1
- package/dist/{icons-DXanGDZ_.js → icons-DsfpmrVO.js} +1 -1
- package/dist/{icons-DXanGDZ_.js.map → icons-DsfpmrVO.js.map} +1 -1
- package/dist/icons.cjs +1 -1
- package/dist/icons.js +1 -1
- package/dist/{iframe-BlHK0cjy.js → iframe-KrV4Cak-.js} +1 -1
- package/dist/{iframe-BlHK0cjy.js.map → iframe-KrV4Cak-.js.map} +1 -1
- package/dist/{iframe-B1XWRaLC.cjs → iframe-sTXBw6zB.cjs} +1 -1
- package/dist/{iframe-B1XWRaLC.cjs.map → iframe-sTXBw6zB.cjs.map} +1 -1
- package/dist/iframe.cjs +1 -1
- package/dist/iframe.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +28 -28
- package/dist/{input-C-_XU9AX.cjs → input-DMoggdSN.cjs} +1 -1
- package/dist/{input-C-_XU9AX.cjs.map → input-DMoggdSN.cjs.map} +1 -1
- package/dist/{input-chip-5aYnuRZ_.cjs → input-chip-B1iNQW2m.cjs} +1 -1
- package/dist/{input-chip-5aYnuRZ_.cjs.map → input-chip-B1iNQW2m.cjs.map} +1 -1
- package/dist/{input-chip-l--zCMGR.js → input-chip-DHbfUatc.js} +1 -1
- package/dist/{input-chip-l--zCMGR.js.map → input-chip-DHbfUatc.js.map} +1 -1
- package/dist/{input-CiGa8Dkl.js → input-zj3eaZM_.js} +1 -1
- package/dist/{input-CiGa8Dkl.js.map → input-zj3eaZM_.js.map} +1 -1
- package/dist/input.cjs +1 -1
- package/dist/input.js +1 -1
- package/dist/json.cjs +1 -1
- package/dist/json.js +2 -2
- package/dist/kbd.cjs +1 -1
- package/dist/kbd.js +1 -1
- package/dist/layout.cjs +1 -1
- package/dist/layout.js +1 -1
- package/dist/{lightbox-CfRDkeeb.cjs → lightbox-86F2RgXy.cjs} +1 -1
- package/dist/{lightbox-CfRDkeeb.cjs.map → lightbox-86F2RgXy.cjs.map} +1 -1
- package/dist/{lightbox-D9oiu1Nv.js → lightbox-CAcXlJlv.js} +1 -1
- package/dist/{lightbox-D9oiu1Nv.js.map → lightbox-CAcXlJlv.js.map} +1 -1
- package/dist/lightbox.cjs +1 -1
- package/dist/lightbox.js +1 -1
- package/dist/{list-BOlRka4v.js → list-BIjJ6T1c.js} +1 -1
- package/dist/{list-BOlRka4v.js.map → list-BIjJ6T1c.js.map} +1 -1
- package/dist/{list-CDJi3_Ut.cjs → list-CUbI0RM6.cjs} +1 -1
- package/dist/{list-CDJi3_Ut.cjs.map → list-CUbI0RM6.cjs.map} +1 -1
- package/dist/list.cjs +1 -1
- package/dist/list.js +1 -1
- package/dist/{menu-XyrLmCi_.js → menu-CtFcvxgU.js} +2 -2
- package/dist/{menu-XyrLmCi_.js.map → menu-CtFcvxgU.js.map} +1 -1
- package/dist/{menu-CJaDL2cd.cjs → menu-DGMrjR_a.cjs} +1 -1
- package/dist/{menu-CJaDL2cd.cjs.map → menu-DGMrjR_a.cjs.map} +1 -1
- package/dist/menu.cjs +1 -1
- package/dist/menu.js +1 -1
- package/dist/mixins-CKbQ6BJo.js +642 -0
- package/dist/{mixins-DySzfmal.js.map → mixins-CKbQ6BJo.js.map} +1 -1
- package/dist/mixins-DSy-enUd.cjs +254 -0
- package/dist/{mixins-CsYsIJOI.cjs.map → mixins-DSy-enUd.cjs.map} +1 -1
- package/dist/mixins.cjs +1 -1
- package/dist/mixins.js +1 -1
- package/dist/nav-drawer.cjs +1 -1
- package/dist/nav-drawer.js +1 -1
- package/dist/navigation-bar.cjs +1 -1
- package/dist/navigation-bar.js +1 -1
- package/dist/navigation-rail.cjs +1 -1
- package/dist/navigation-rail.js +1 -1
- package/dist/{notification-CHrEY4u8.js → notification-BqyMYtP7.js} +2 -2
- package/dist/{notification-CHrEY4u8.js.map → notification-BqyMYtP7.js.map} +1 -1
- package/dist/{notification-DKp4tjaB.cjs → notification-D5eOdsMT.cjs} +1 -1
- package/dist/{notification-DKp4tjaB.cjs.map → notification-D5eOdsMT.cjs.map} +1 -1
- package/dist/notification.cjs +1 -1
- package/dist/notification.js +1 -1
- package/dist/{option-Vpy4UQ-D.js → option-C3UyYQi_.js} +1 -1
- package/dist/{option-Vpy4UQ-D.js.map → option-C3UyYQi_.js.map} +1 -1
- package/dist/{option-nRk4MuXH.cjs → option-DJ3R-2Wn.cjs} +1 -1
- package/dist/{option-nRk4MuXH.cjs.map → option-DJ3R-2Wn.cjs.map} +1 -1
- package/dist/option.cjs +1 -1
- package/dist/option.js +1 -1
- package/dist/{overlay-jlkcrt8F.js → overlay-D1hFkcFA.js} +3 -3
- package/dist/{overlay-jlkcrt8F.js.map → overlay-D1hFkcFA.js.map} +1 -1
- package/dist/{overlay-HNrWZ4sB.cjs → overlay-D7nQaT5U.cjs} +1 -1
- package/dist/{overlay-HNrWZ4sB.cjs.map → overlay-D7nQaT5U.cjs.map} +1 -1
- package/dist/overlay.cjs +1 -1
- package/dist/{overlay.confirm-body-CYShkjI6.js → overlay.confirm-body-B4eCDLmU.js} +1 -1
- package/dist/{overlay.confirm-body-CYShkjI6.js.map → overlay.confirm-body-B4eCDLmU.js.map} +1 -1
- package/dist/{overlay.confirm-body-B8dFI3cj.cjs → overlay.confirm-body-P18SmJL2.cjs} +1 -1
- package/dist/{overlay.confirm-body-B8dFI3cj.cjs.map → overlay.confirm-body-P18SmJL2.cjs.map} +1 -1
- package/dist/overlay.js +3 -3
- package/dist/{overlay.service-BqhhxVJp.js → overlay.service-02ZLZ8Ib.js} +2 -2
- package/dist/{overlay.service-BqhhxVJp.js.map → overlay.service-02ZLZ8Ib.js.map} +1 -1
- package/dist/{overlay.service-BTPn7Uv7.cjs → overlay.service-m-8omCA-.cjs} +1 -1
- package/dist/{overlay.service-BTPn7Uv7.cjs.map → overlay.service-m-8omCA-.cjs.map} +1 -1
- package/dist/{progress-CAp_4jtq.cjs → progress-CY-UbvOB.cjs} +1 -1
- package/dist/{progress-CAp_4jtq.cjs.map → progress-CY-UbvOB.cjs.map} +1 -1
- package/dist/{progress-8Bn88GK_.js → progress-YjdEWDI5.js} +1 -1
- package/dist/{progress-8Bn88GK_.js.map → progress-YjdEWDI5.js.map} +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-CN44mAoc.cjs → radio-group--UamzqAm.cjs} +1 -1
- package/dist/{radio-group-CN44mAoc.cjs.map → radio-group--UamzqAm.cjs.map} +1 -1
- package/dist/{radio-group-GNHA7qJR.js → radio-group-aKXKHqUp.js} +1 -1
- package/dist/{radio-group-GNHA7qJR.js.map → radio-group-aKXKHqUp.js.map} +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +1 -1
- package/dist/range.cjs +1 -1
- package/dist/range.js +1 -1
- package/dist/{select-BnuXRHS4.js → select-B0Qk4PfT.js} +2 -2
- package/dist/{select-BnuXRHS4.js.map → select-B0Qk4PfT.js.map} +1 -1
- package/dist/{select-DZNns5Pa.cjs → select-CIquL8LY.cjs} +1 -1
- package/dist/{select-DZNns5Pa.cjs.map → select-CIquL8LY.cjs.map} +1 -1
- package/dist/select.cjs +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.cjs +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +1 -1
- package/dist/{splash-screen-CUP_elaT.js → splash-screen-CP_Idse2.js} +1 -1
- package/dist/{splash-screen-CUP_elaT.js.map → splash-screen-CP_Idse2.js.map} +1 -1
- package/dist/{splash-screen-DeoPRrOu.cjs → splash-screen-rg56AXCf.cjs} +1 -1
- package/dist/{splash-screen-DeoPRrOu.cjs.map → splash-screen-rg56AXCf.cjs.map} +1 -1
- package/dist/splash-screen.cjs +1 -1
- package/dist/splash-screen.js +1 -1
- package/dist/{src-DQ4wr0qq.cjs → src-BAaNnqwc.cjs} +1 -1
- package/dist/{src-DQ4wr0qq.cjs.map → src-BAaNnqwc.cjs.map} +1 -1
- package/dist/{src-B1VkLX3l.js → src-Do0IGupa.js} +34 -34
- package/dist/{src-B1VkLX3l.js.map → src-Do0IGupa.js.map} +1 -1
- package/dist/steps.cjs +1 -1
- package/dist/steps.js +1 -1
- package/dist/{surface-LkaZQXZn.cjs → surface-B7a2O5-9.cjs} +1 -1
- package/dist/{surface-LkaZQXZn.cjs.map → surface-B7a2O5-9.cjs.map} +1 -1
- package/dist/{surface-hOvkrjGN.js → surface-DGewe6IV.js} +1 -1
- package/dist/{surface-hOvkrjGN.js.map → surface-DGewe6IV.js.map} +1 -1
- package/dist/surface.cjs +1 -1
- package/dist/surface.js +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.js +1 -1
- package/dist/{tabs-CfwIHhHo.js → tabs-g2aM43TH.js} +1 -1
- package/dist/{tabs-CfwIHhHo.js.map → tabs-g2aM43TH.js.map} +1 -1
- package/dist/{tabs-bplzstz6.cjs → tabs-n4dO5fo1.cjs} +1 -1
- package/dist/{tabs-bplzstz6.cjs.map → tabs-n4dO5fo1.cjs.map} +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/dist/{textarea-C1A5xuw9.js → textarea-D5hw4jsP.js} +1 -1
- package/dist/{textarea-C1A5xuw9.js.map → textarea-D5hw4jsP.js.map} +1 -1
- package/dist/{textarea-hrDp5gQq.cjs → textarea-DDx_7AfQ.cjs} +1 -1
- package/dist/{textarea-hrDp5gQq.cjs.map → textarea-DDx_7AfQ.cjs.map} +1 -1
- package/dist/textarea.cjs +1 -1
- package/dist/textarea.js +1 -1
- package/dist/{theme-BniFOMEo.js → theme-BMYkheaA.js} +1 -1
- package/dist/{theme-BniFOMEo.js.map → theme-BMYkheaA.js.map} +1 -1
- package/dist/{theme-DmR6PKV8.cjs → theme-BdZAj0CO.cjs} +1 -1
- package/dist/{theme-DmR6PKV8.cjs.map → theme-BdZAj0CO.cjs.map} +1 -1
- package/dist/{theme-button--ruZIb0T.js → theme-button-DdI6kxY3.js} +1 -1
- package/dist/{theme-button--ruZIb0T.js.map → theme-button-DdI6kxY3.js.map} +1 -1
- package/dist/{theme-button-a0LgZ7hQ.cjs → theme-button-R2f_kLEl.cjs} +1 -1
- package/dist/{theme-button-a0LgZ7hQ.cjs.map → theme-button-R2f_kLEl.cjs.map} +1 -1
- package/dist/theme-button.cjs +1 -1
- package/dist/theme-button.js +1 -1
- package/dist/theme.cjs +1 -1
- package/dist/theme.js +2 -2
- package/dist/tree.cjs +1 -1
- package/dist/tree.js +1 -1
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +1 -1
- package/dist/visually-hidden.cjs +1 -1
- package/dist/visually-hidden.js +1 -1
- package/dist/{window-Bp7zWZpu.cjs → window-LOGPpN8K.cjs} +1 -1
- package/dist/{window-Bp7zWZpu.cjs.map → window-LOGPpN8K.cjs.map} +1 -1
- package/dist/{window-BT9JecWy.js → window-MQxhTodp.js} +1 -1
- package/dist/{window-BT9JecWy.js.map → window-MQxhTodp.js.map} +1 -1
- package/dist/window.cjs +1 -1
- package/dist/window.js +1 -1
- package/package.json +1 -1
- package/src/boat/boat.ts +33 -23
- package/src/directives/nebula.ts +64 -61
- package/types/src/directives/nebula.d.ts +1 -1
- package/dist/boat--fLgbDAE.js.map +0 -1
- package/dist/boat-BIB-gPqy.cjs +0 -80
- package/dist/boat-BIB-gPqy.cjs.map +0 -1
- package/dist/mixins-CsYsIJOI.cjs +0 -254
- package/dist/mixins-DySzfmal.js +0 -642
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightbox-CfRDkeeb.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-86F2RgXy.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,4 +1,4 @@
|
|
|
1
|
-
import { c as e, y as t } from "./mixins-
|
|
1
|
+
import { c as e, y as t } from "./mixins-CKbQ6BJo.js";
|
|
2
2
|
import { a as n } from "./active-host-BP0zy_Y9.js";
|
|
3
3
|
import { t as r } from "./overlay-stack-D2rgxQLh.js";
|
|
4
4
|
import { Subject as i, filter as a, fromEvent as o, map as s, switchMap as c, takeUntil as l, tap as u } from "rxjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightbox-D9oiu1Nv.js","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-CAcXlJlv.js","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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"}
|
package/dist/lightbox.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./lightbox-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./lightbox-86F2RgXy.cjs`);Object.defineProperty(exports,`SchmancyLightbox`,{enumerable:!0,get:function(){return e.i}}),exports.flip=e.r,exports.lightbox=e.t,exports.lightboxDirective=e.n;
|
package/dist/lightbox.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as e, n as t, r as n, t as r } from "./lightbox-
|
|
1
|
+
import { i as e, n as t, r as n, t as r } from "./lightbox-CAcXlJlv.js";
|
|
2
2
|
export { e as SchmancyLightbox, n as flip, r as lightbox, t as lightboxDirective };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as e } from "./mixins-
|
|
1
|
+
import { c as e } from "./mixins-CKbQ6BJo.js";
|
|
2
2
|
import { a as t } from "./active-host-BP0zy_Y9.js";
|
|
3
3
|
import { consume as n, createContext as r, provide as i } from "@lit/context";
|
|
4
4
|
import { customElement as a, property as o, queryAssignedElements as s } from "lit/decorators.js";
|