{"id":3814,"date":"2026-09-20T19:14:34","date_gmt":"2026-09-20T19:14:34","guid":{"rendered":"https:\/\/er.digion.app\/?page_id=3814"},"modified":"2026-09-20T19:30:03","modified_gmt":"2026-09-20T19:30:03","slug":"garage-doors-2","status":"publish","type":"page","link":"https:\/\/er.digion.app\/mk\/garage-doors-2\/","title":{"rendered":"Garage doors"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3814\" class=\"elementor elementor-3814\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-367dc2d e-con-full e-flex e-con e-parent\" data-id=\"367dc2d\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-849c55b e-flex e-con-boxed e-con e-parent\" data-id=\"849c55b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-18f48ef e-con-full e-flex e-con e-child\" data-id=\"18f48ef\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-aa033f5 elementor-widget elementor-widget-html\" data-id=\"aa033f5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\r\n\/* ==========================================\r\n   EFTINIJA ROLS\r\n   On-demand interactive videos\r\n   ========================================== *\/\r\n\r\n.hover-video-card .eft-hover-video {\r\n    position: absolute;\r\n    inset: 0;\r\n\r\n    width: 100%;\r\n    height: 100%;\r\n\r\n    object-fit: cover;\r\n\r\n    opacity: 0;\r\n    z-index: 1;\r\n\r\n    pointer-events: none;\r\n\r\n    transition: opacity 0.15s ease;\r\n}\r\n\r\n\r\n\/* Original Elementor image *\/\r\n\r\n.hover-video-card .elementor-cta__bg {\r\n    z-index: 0;\r\n}\r\n\r\n\r\n\/* Elementor overlay stays above video *\/\r\n\r\n.hover-video-card .elementor-cta__bg-overlay {\r\n    z-index: 2;\r\n}\r\n\r\n\r\n\/* Show video after first frame is ready *\/\r\n\r\n.hover-video-card.video-ready .eft-hover-video {\r\n    opacity: 1;\r\n}\r\n<\/style>\r\n\r\n\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n\r\n    \/* ==========================================\r\n       VIDEO MAP\r\n       ========================================== *\/\r\n\r\n    const videoSources = {\r\n\r\n        'video-garage':\r\n            'https:\/\/er.digion.app\/wp-content\/uploads\/garage_segmental.mp4',\r\n\r\n        'video-barrier':\r\n            'https:\/\/er.digion.app\/wp-content\/uploads\/parking-barrier.mp4',\r\n\r\n        'video-metalworking':\r\n            'https:\/\/er.digion.app\/wp-content\/uploads\/metalworking.mp4'\r\n\r\n    };\r\n\r\n\r\n    const cards =\r\n        document.querySelectorAll('.hover-video-card');\r\n\r\n\r\n    if (!cards.length) return;\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       DEVICE TYPE\r\n       ========================================== *\/\r\n\r\n    const isDesktop =\r\n        window.matchMedia(\r\n            '(hover: hover) and (pointer: fine)'\r\n        ).matches;\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       FIND VIDEO URL\r\n       ========================================== *\/\r\n\r\n    function getVideoURL(card) {\r\n\r\n        for (const className in videoSources) {\r\n\r\n            if (\r\n                card.classList.contains(className)\r\n            ) {\r\n\r\n                return videoSources[className];\r\n\r\n            }\r\n\r\n        }\r\n\r\n        return null;\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       CREATE VIDEO\r\n       \r\n       IMPORTANT:\r\n       This function is NOT called on page load.\r\n       ========================================== *\/\r\n\r\n    function createVideo(card) {\r\n\r\n\r\n        \/* Already loaded *\/\r\n\r\n        if (card._eftVideo) {\r\n\r\n            return card._eftVideo;\r\n\r\n        }\r\n\r\n\r\n        const videoURL =\r\n            getVideoURL(card);\r\n\r\n\r\n        if (!videoURL) return null;\r\n\r\n\r\n        const wrapper =\r\n            card.querySelector(\r\n                '.elementor-cta__bg-wrapper'\r\n            );\r\n\r\n\r\n        if (!wrapper) return null;\r\n\r\n\r\n\r\n        \/* Create video *\/\r\n\r\n        const video =\r\n            document.createElement('video');\r\n\r\n\r\n        video.className =\r\n            'eft-hover-video';\r\n\r\n\r\n        video.muted = true;\r\n        video.defaultMuted = true;\r\n\r\n        video.loop = true;\r\n        video.playsInline = true;\r\n\r\n\r\n        video.setAttribute(\r\n            'muted',\r\n            ''\r\n        );\r\n\r\n        video.setAttribute(\r\n            'playsinline',\r\n            ''\r\n        );\r\n\r\n        video.setAttribute(\r\n            'webkit-playsinline',\r\n            ''\r\n        );\r\n\r\n\r\n        \/*\r\n         * IMPORTANT:\r\n         *\r\n         * metadata instead of auto.\r\n         *\r\n         * We don't ask browser to aggressively\r\n         * preload unnecessary video data.\r\n         *\/\r\n\r\n        video.preload = 'metadata';\r\n\r\n\r\n        wrapper.appendChild(video);\r\n\r\n\r\n        card._eftVideo = video;\r\n\r\n\r\n\r\n        \/* ======================================\r\n           SHOW ONLY WHEN FRAME EXISTS\r\n           ====================================== *\/\r\n\r\n        video.addEventListener(\r\n            'loadeddata',\r\n            function () {\r\n\r\n                card.classList.add(\r\n                    'video-ready'\r\n                );\r\n\r\n            },\r\n            { once: true }\r\n        );\r\n\r\n\r\n\r\n        \/*\r\n         * Network request starts ONLY NOW.\r\n         *\r\n         * This function itself is only called\r\n         * when user actually interacts.\r\n         *\/\r\n\r\n        video.src = videoURL;\r\n\r\n\r\n        return video;\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       PLAY\r\n       ========================================== *\/\r\n\r\n    function playVideo(card) {\r\n\r\n\r\n        const video =\r\n            createVideo(card);\r\n\r\n\r\n        if (!video) return;\r\n\r\n\r\n\r\n        \/*\r\n         * Mobile:\r\n         * only one video allowed to play.\r\n         *\/\r\n\r\n        if (!isDesktop) {\r\n\r\n            cards.forEach(\r\n                function (otherCard) {\r\n\r\n                    if (\r\n                        otherCard !== card &&\r\n                        otherCard._eftVideo\r\n                    ) {\r\n\r\n                        otherCard\r\n                            ._eftVideo\r\n                            .pause();\r\n\r\n                    }\r\n\r\n                }\r\n            );\r\n\r\n        }\r\n\r\n\r\n\r\n        video.play()\r\n            .catch(function () {});\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       PAUSE\r\n       ========================================== *\/\r\n\r\n    function pauseVideo(card) {\r\n\r\n        if (!card._eftVideo) return;\r\n\r\n\r\n        \/*\r\n         * Don't reset currentTime.\r\n         *\r\n         * Keep exact frame.\r\n         *\/\r\n\r\n        card._eftVideo.pause();\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       DESKTOP\r\n       \r\n       NOTHING downloads until actual hover.\r\n       ========================================== *\/\r\n\r\n    if (isDesktop) {\r\n\r\n\r\n        cards.forEach(\r\n            function (card) {\r\n\r\n\r\n                card.addEventListener(\r\n                    'mouseenter',\r\n                    function () {\r\n\r\n                        playVideo(card);\r\n\r\n                    }\r\n                );\r\n\r\n\r\n                card.addEventListener(\r\n                    'mouseleave',\r\n                    function () {\r\n\r\n                        pauseVideo(card);\r\n\r\n                    }\r\n                );\r\n\r\n\r\n            }\r\n        );\r\n\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       MOBILE\r\n       \r\n       NOTHING downloads until card has\r\n       actual visual focus.\r\n       ========================================== *\/\r\n\r\n    else {\r\n\r\n\r\n        let activeCard = null;\r\n\r\n        let ticking = false;\r\n\r\n\r\n\r\n        function updateMobileFocus() {\r\n\r\n\r\n            ticking = false;\r\n\r\n\r\n            const viewportHeight =\r\n                window.innerHeight;\r\n\r\n\r\n            const viewportCenter =\r\n                viewportHeight \/ 2;\r\n\r\n\r\n            let closestCard = null;\r\n\r\n            let closestDistance =\r\n                Infinity;\r\n\r\n\r\n\r\n            \/* ==================================\r\n               FIND CARD CLOSEST TO CENTER\r\n               ================================== *\/\r\n\r\n            cards.forEach(\r\n                function (card) {\r\n\r\n\r\n                    const rect =\r\n                        card.getBoundingClientRect();\r\n\r\n\r\n                    \/*\r\n                     * Ignore cards outside viewport\r\n                     *\/\r\n\r\n                    if (\r\n                        rect.bottom <= 0 ||\r\n                        rect.top >= viewportHeight\r\n                    ) {\r\n\r\n                        return;\r\n\r\n                    }\r\n\r\n\r\n\r\n                    const cardCenter =\r\n                        rect.top +\r\n                        (rect.height \/ 2);\r\n\r\n\r\n\r\n                    const distance =\r\n                        Math.abs(\r\n                            cardCenter -\r\n                            viewportCenter\r\n                        );\r\n\r\n\r\n\r\n                    if (\r\n                        distance <\r\n                        closestDistance\r\n                    ) {\r\n\r\n                        closestDistance =\r\n                            distance;\r\n\r\n                        closestCard =\r\n                            card;\r\n\r\n                    }\r\n\r\n\r\n                }\r\n            );\r\n\r\n\r\n\r\n            \/* ==================================\r\n               FOCUS ZONE\r\n\r\n               17% above center\r\n               +\r\n               17% below center\r\n\r\n               = 34% total active zone\r\n               ================================== *\/\r\n\r\n            const focusDistance =\r\n                viewportHeight * 0.17;\r\n\r\n\r\n\r\n            \/* ==================================\r\n               CARD HAS REAL FOCUS\r\n               ================================== *\/\r\n\r\n            if (\r\n                closestCard &&\r\n                closestDistance <=\r\n                    focusDistance\r\n            ) {\r\n\r\n\r\n                \/*\r\n                 * Already playing correct card\r\n                 *\/\r\n\r\n                if (\r\n                    activeCard ===\r\n                    closestCard\r\n                ) {\r\n\r\n                    return;\r\n\r\n                }\r\n\r\n\r\n\r\n                \/*\r\n                 * Pause old card\r\n                 *\/\r\n\r\n                if (activeCard) {\r\n\r\n                    pauseVideo(\r\n                        activeCard\r\n                    );\r\n\r\n                }\r\n\r\n\r\n\r\n                \/*\r\n                 * Activate new card\r\n                 *\/\r\n\r\n                activeCard =\r\n                    closestCard;\r\n\r\n\r\n                \/*\r\n                 * THIS is when video starts\r\n                 * downloading for first time.\r\n                 *\/\r\n\r\n                playVideo(\r\n                    activeCard\r\n                );\r\n\r\n\r\n            }\r\n\r\n\r\n            \/* ==================================\r\n               NOTHING HAS FOCUS\r\n               ================================== *\/\r\n\r\n            else {\r\n\r\n\r\n                if (activeCard) {\r\n\r\n\r\n                    pauseVideo(\r\n                        activeCard\r\n                    );\r\n\r\n\r\n                    activeCard = null;\r\n\r\n\r\n                }\r\n\r\n\r\n            }\r\n\r\n\r\n        }\r\n\r\n\r\n\r\n        \/* ======================================\r\n           EFFICIENT SCROLL CHECK\r\n           ====================================== *\/\r\n\r\n        function requestFocusUpdate() {\r\n\r\n\r\n            if (ticking) return;\r\n\r\n\r\n            ticking = true;\r\n\r\n\r\n            requestAnimationFrame(\r\n                updateMobileFocus\r\n            );\r\n\r\n\r\n        }\r\n\r\n\r\n\r\n        window.addEventListener(\r\n            'scroll',\r\n            requestFocusUpdate,\r\n            { passive: true }\r\n        );\r\n\r\n\r\n        window.addEventListener(\r\n            'resize',\r\n            requestFocusUpdate,\r\n            { passive: true }\r\n        );\r\n\r\n\r\n        requestFocusUpdate();\r\n\r\n\r\n    }\r\n\r\n\r\n\r\n    \/* ==========================================\r\n       STOP VIDEOS WHEN TAB HIDDEN\r\n       ========================================== *\/\r\n\r\n    document.addEventListener(\r\n        'visibilitychange',\r\n        function () {\r\n\r\n\r\n            if (!document.hidden) return;\r\n\r\n\r\n            cards.forEach(\r\n                function (card) {\r\n\r\n                    pauseVideo(card);\r\n\r\n                }\r\n            );\r\n\r\n\r\n        }\r\n    );\r\n\r\n\r\n});\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-29da640 elementor-widget elementor-widget-heading\" data-id=\"29da640\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Our products &amp; services<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-549c10a elementor-widget elementor-widget-text-editor\" data-id=\"549c10a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>In our product range, you will find certified garage doors, windows, doors, gates, and fences that will allow you to create a fully functional, modern, and aesthetically appealing home of your dreams.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Our products &amp; services In our product range, you will find certified garage doors, windows, doors, gates, and fences that will allow you to create a fully functional, modern, and aesthetically appealing home of your dreams.<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-3814","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/pages\/3814","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/comments?post=3814"}],"version-history":[{"count":4,"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/pages\/3814\/revisions"}],"predecessor-version":[{"id":3819,"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/pages\/3814\/revisions\/3819"}],"wp:attachment":[{"href":"https:\/\/er.digion.app\/mk\/wp-json\/wp\/v2\/media?parent=3814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}