{"id":8341,"date":"2026-05-07T10:43:44","date_gmt":"2026-05-07T10:43:44","guid":{"rendered":"https:\/\/albertogelpi.com\/?page_id=8341"},"modified":"2026-08-29T23:18:01","modified_gmt":"2026-08-29T23:18:01","slug":"old_director-film-commercial-rome-2","status":"publish","type":"page","link":"https:\/\/albertogelpi.com\/it\/","title":{"rendered":"Reel"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"8341\" class=\"elementor elementor-8341\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d77b031 e-con-full e-flex e-con e-parent\" data-id=\"d77b031\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-686763e animated-slow elementor-invisible elementor-widget elementor-widget-video\" data-id=\"686763e\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;video_type&quot;:&quot;vimeo&quot;,&quot;loop&quot;:&quot;yes&quot;,&quot;image_overlay&quot;:{&quot;url&quot;:&quot;https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2023\\\/03\\\/Reel2023_thumb.jpg&quot;,&quot;id&quot;:4876,&quot;size&quot;:&quot;&quot;,&quot;alt&quot;:&quot;&quot;,&quot;source&quot;:&quot;library&quot;},&quot;lightbox&quot;:&quot;yes&quot;,&quot;show_image_overlay&quot;:&quot;yes&quot;,&quot;start&quot;:0,&quot;lightbox_content_animation&quot;:&quot;fadeIn&quot;,&quot;_animation&quot;:&quot;fadeIn&quot;}\" data-widget_type=\"video.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-wrapper elementor-open-lightbox\">\n\t\t\t\t\t\t\t<div class=\"elementor-custom-embed-image-overlay\" data-elementor-open-lightbox=\"yes\" data-elementor-lightbox=\"{&quot;type&quot;:&quot;video&quot;,&quot;videoType&quot;:&quot;vimeo&quot;,&quot;url&quot;:&quot;https:\\\/\\\/player.vimeo.com\\\/video\\\/670691031?color&amp;autopause=0&amp;loop=1&amp;muted=0&amp;title=0&amp;portrait=0&amp;byline=0#t=&quot;,&quot;autoplay&quot;:&quot;&quot;,&quot;modalOptions&quot;:{&quot;id&quot;:&quot;elementor-lightbox-686763e&quot;,&quot;entranceAnimation&quot;:&quot;fadeIn&quot;,&quot;entranceAnimation_tablet&quot;:&quot;&quot;,&quot;entranceAnimation_mobile&quot;:&quot;&quot;,&quot;videoAspectRatio&quot;:&quot;219&quot;}}\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJ0eXBlIjoidmlkZW8iLCJ2aWRlb1R5cGUiOiJ2aW1lbyIsInVybCI6Imh0dHBzOlwvXC9wbGF5ZXIudmltZW8uY29tXC92aWRlb1wvNjcwNjkxMDMxP2NvbG9yJmF1dG9wYXVzZT0wJmxvb3A9MSZtdXRlZD0wJnRpdGxlPTAmcG9ydHJhaXQ9MCZieWxpbmU9MCN0PSIsImF1dG9wbGF5IjoiIiwibW9kYWxPcHRpb25zIjp7ImlkIjoiZWxlbWVudG9yLWxpZ2h0Ym94LTY4Njc2M2UiLCJlbnRyYW5jZUFuaW1hdGlvbiI6ImZhZGVJbiIsImVudHJhbmNlQW5pbWF0aW9uX3RhYmxldCI6IiIsImVudHJhbmNlQW5pbWF0aW9uX21vYmlsZSI6IiIsInZpZGVvQXNwZWN0UmF0aW8iOiIyMTkifX0%3D\">\n\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1040\" height=\"700\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/03\/Reel2023_thumb.jpg\" class=\"attachment-full size-full wp-image-4876\" alt=\"\" srcset=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/03\/Reel2023_thumb.jpg 1040w, https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/03\/Reel2023_thumb-300x202.jpg 300w, https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/03\/Reel2023_thumb-1024x689.jpg 1024w, https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/03\/Reel2023_thumb-768x517.jpg 768w\" sizes=\"(max-width: 1040px) 100vw, 1040px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-custom-embed-play\" role=\"button\" aria-label=\"Play Video\" tabindex=\"0\">\n\t\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-play\"><\/i>\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-50e0074 e-flex e-con-boxed e-con e-parent\" data-id=\"50e0074\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;animation&quot;:&quot;none&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-3f6a123 e-con-full e-flex e-con e-child\" data-id=\"3f6a123\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<h1 data-interaction-id=\"e23d440\" class=\"e-e23d440-f0a7a75 e-heading-base\">This space is part of my<\/h1>\n\t\t\t\t\t<h1 data-interaction-id=\"aa33a32\" class=\"e-aa33a32-4bcec80 e-heading-base\">life.<\/h1>\n\t\t\t\t\t<h4 data-interaction-id=\"dd6992e\" class=\"e-dd6992e-491a486 e-heading-base\">stories, projects and the way I shape them.<\/h4>\n\t\t\t\t\t<h1 data-interaction-id=\"c8a5ac1\" class=\"e-c8a5ac1-f4ec4e4 e-heading-base\">a long journey<\/h1>\n\t\t\t\t\t<h4 data-interaction-id=\"78b3083\" class=\"e-78b3083-545fceb e-heading-base\">filled with attempt, struggles, falls,<\/h4>\n\t\t\t\t\t<h1 data-interaction-id=\"94ed64b\" class=\"e-94ed64b-a688603 e-heading-base\">successes,<\/h1>\n\t\t\t\t\t<h4 data-interaction-id=\"c54e765\" class=\"e-c54e765-9b1baec e-heading-base\">fears and laughter.<\/h4>\n\t\t\t\t\t<h4 data-interaction-id=\"8e1c961\" class=\"e-8e1c961-921011c e-heading-base\">My goal:<\/h4>\n\t\t\t\t\t<h1 data-interaction-id=\"8a27fee\" class=\"e-8a27fee-a929955 e-heading-base\">crafting<\/h1>\n\t\t\t\t\t<h1 data-interaction-id=\"db1376f\" class=\"e-db1376f-cdb4fea e-heading-base\">emotions.<\/h1>\n\t\t\t\t\t<h4 data-interaction-id=\"0c2f7e6\" class=\"e-0c2f7e6-e9936ff e-heading-base\">In a film, a documentary, or in a thirty-second commercial.<\/h4>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-17b455d e-con-full e-flex e-con e-parent\" data-id=\"17b455d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6edc922 animated-slow elementor-view-default elementor-invisible elementor-widget elementor-widget-icon\" data-id=\"6edc922\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_animation_delay&quot;:1000}\" data-widget_type=\"icon.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper\">\n\t\t\t<div class=\"elementor-icon\">\n\t\t\t<i aria-hidden=\"true\" class=\"fas fa-grip-vertical\"><\/i>\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<h1 data-interaction-id=\"7ac28f0\" class=\"e-7ac28f0-6251103 e-heading-base\">FEATURES<\/h1>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-03181d5 e-grid animated-slow e-con-boxed elementor-invisible e-con e-parent\" data-id=\"03181d5\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;animation&quot;:&quot;fadeIn&quot;,&quot;animation_delay&quot;:700}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bae0c13 elementor-arrows-position-inside elementor-widget elementor-widget-image-carousel\" data-id=\"bae0c13\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;slides_to_show&quot;:&quot;1&quot;,&quot;navigation&quot;:&quot;arrows&quot;,&quot;lazyload&quot;:&quot;yes&quot;,&quot;speed&quot;:2500,&quot;autoplay&quot;:&quot;yes&quot;,&quot;pause_on_hover&quot;:&quot;yes&quot;,&quot;pause_on_interaction&quot;:&quot;yes&quot;,&quot;autoplay_speed&quot;:5000,&quot;infinite&quot;:&quot;yes&quot;,&quot;effect&quot;:&quot;slide&quot;}\" data-widget_type=\"image-carousel.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-carousel-wrapper swiper\" role=\"region\" aria-roledescription=\"carousel\" aria-label=\"Image Carousel\" dir=\"ltr\">\n\t\t\t<div class=\"elementor-image-carousel swiper-wrapper\" aria-live=\"off\">\n\t\t\t\t\t\t\t\t<div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"bae0c13\" data-elementor-lightbox-title=\"Shadow of the Wolf\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTEyMSwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9Tb3RXMy0xLmpwZyIsInNsaWRlc2hvdyI6ImJhZTBjMTMifQ%3D%3D\" href=\"https:\/\/albertogelpi.com\/index.php\/shadow-of-the-wolf\/\"><figure class=\"swiper-slide-inner\"><img class=\"swiper-slide-image swiper-lazy\" data-src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg\" alt=\"Elisabetta De Vito\" \/><div class=\"swiper-lazy-preloader\"><\/div><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"2 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"bae0c13\" data-elementor-lightbox-title=\"Film_Carousel\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTM2MCwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9Tb3RXMDEuanBnIiwic2xpZGVzaG93IjoiYmFlMGMxMyJ9\" href=\"https:\/\/albertogelpi.com\/index.php\/shadow-of-the-wolf\/\"><figure class=\"swiper-slide-inner\"><img class=\"swiper-slide-image swiper-lazy\" data-src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW01-768x322.jpg\" alt=\"Shadow of the Wolf\" \/><div class=\"swiper-lazy-preloader\"><\/div><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"3 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"bae0c13\" data-elementor-lightbox-title=\"SotW2\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTExMywidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9Tb3RXMi5qcGciLCJzbGlkZXNob3ciOiJiYWUwYzEzIn0%3D\" href=\"https:\/\/albertogelpi.com\/index.php\/shadow-of-the-wolf\/\"><figure class=\"swiper-slide-inner\"><img class=\"swiper-slide-image swiper-lazy\" data-src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW2-768x322.jpg\" alt=\"Christopher Lambert\" \/><div class=\"swiper-lazy-preloader\"><\/div><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"4 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"bae0c13\" data-elementor-lightbox-title=\"Shadow of the wolf\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTExMiwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9Tb3RXLmpwZyIsInNsaWRlc2hvdyI6ImJhZTBjMTMifQ%3D%3D\" href=\"https:\/\/albertogelpi.com\/index.php\/shadow-of-the-wolf\/\"><figure class=\"swiper-slide-inner\"><img class=\"swiper-slide-image swiper-lazy\" data-src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW-768x322.jpg\" alt=\"Raniero Monaco Di Lapio\" \/><div class=\"swiper-lazy-preloader\"><\/div><\/figure><\/a><\/div>\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-prev\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-left\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-next\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-right\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<a class=\"elementor-element elementor-element-bdcb5d2 e-con e-atomic-element e-flexbox-base e-bdcb5d2-33d4cfd \" data-id=\"bdcb5d2\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"bdcb5d2\" href=\"https:\/\/albertogelpi.com\/index.php\/shadow-of-the-wolf\/\" target=\"_self\">\n    \t\t\t<h2 data-interaction-id=\"f090792\" class=\"e-f090792-da83ce5 e-heading-base\">SHADOW OF THE WOLF<\/h2>\n\t\t\t\t\t<h4 data-interaction-id=\"20c5105\" class=\"e-20c5105-6203a0d e-heading-base\">2020 | thriller drama<\/h4>\n\t\t\t\t\t<p class=\"e-3a38160-96b2e33 e-paragraph-base\" data-interaction-id=\"3a38160\">Nico is a policeman who has returned to his country after years to say goodbye to his mother, Eleonora, who suddenly fell ill. In the same days, some corpses are found in the woods, put on display as in a macabre warning.<\/p>\n\t\t\n<\/a>\n\t\t<div class=\"elementor-element elementor-element-0a9e0a7 elementor-arrows-position-inside elementor-widget elementor-widget-image-carousel\" data-id=\"0a9e0a7\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;slides_to_show&quot;:&quot;1&quot;,&quot;navigation&quot;:&quot;arrows&quot;,&quot;speed&quot;:2500,&quot;autoplay&quot;:&quot;yes&quot;,&quot;pause_on_hover&quot;:&quot;yes&quot;,&quot;pause_on_interaction&quot;:&quot;yes&quot;,&quot;autoplay_speed&quot;:5000,&quot;infinite&quot;:&quot;yes&quot;,&quot;effect&quot;:&quot;slide&quot;}\" data-widget_type=\"image-carousel.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-carousel-wrapper swiper\" role=\"region\" aria-roledescription=\"carousel\" aria-label=\"Image Carousel\" dir=\"ltr\">\n\t\t\t<div class=\"elementor-image-carousel swiper-wrapper\" aria-live=\"off\">\n\t\t\t\t\t\t\t\t<div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"0a9e0a7\" data-elementor-lightbox-title=\"Film_Carousel\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTE5MSwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9NU1RfMDMuanBnIiwic2xpZGVzaG93IjoiMGE5ZTBhNyJ9\" href=\"https:\/\/albertogelpi.com\/index.php\/my-second-chance\/\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/MST_03-768x322.jpg\" alt=\"Maria Chiara Di Mitri\" \/><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"2 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"0a9e0a7\" data-elementor-lightbox-title=\"Film_Carousel\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTI5MCwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9NU1RfMDQuanBnIiwic2xpZGVzaG93IjoiMGE5ZTBhNyJ9\" href=\"https:\/\/albertogelpi.com\/index.php\/my-second-chance\/\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/MST_04-768x322.jpg\" alt=\"La mia Seconda Volta\" \/><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"3 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"0a9e0a7\" data-elementor-lightbox-title=\"Film_Carousel\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTE4OSwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9NU1RfMDEuanBnIiwic2xpZGVzaG93IjoiMGE5ZTBhNyJ9\" href=\"https:\/\/albertogelpi.com\/index.php\/my-second-chance\/\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/MST_01-768x322.jpg\" alt=\"Aurora Ruffino Simone Riccioni\" \/><\/figure><\/a><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"4 of 4\"><a data-elementor-open-lightbox=\"yes\" data-elementor-lightbox-slideshow=\"0a9e0a7\" data-elementor-lightbox-title=\"Film_Carousel\" data-e-action-hash=\"#elementor-action%3Aaction%3Dlightbox%26settings%3DeyJpZCI6NTE5MCwidXJsIjoiaHR0cHM6XC9cL2FsYmVydG9nZWxwaS5jb21cL3dwLWNvbnRlbnRcL3VwbG9hZHNcLzIwMjVcLzEwXC9NU1RfMDIuanBnIiwic2xpZGVzaG93IjoiMGE5ZTBhNyJ9\" href=\"https:\/\/albertogelpi.com\/index.php\/my-second-chance\/\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/MST_02-768x322.jpg\" alt=\"Paola Sotgiu\" \/><\/figure><\/a><\/div>\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-prev\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-left\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-next\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-right\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<a class=\"elementor-element elementor-element-52bbb39 e-con e-atomic-element e-flexbox-base e-52bbb39-fa341a0 \" data-id=\"52bbb39\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"52bbb39\" href=\"https:\/\/albertogelpi.com\/index.php\/my-second-chance\/\" target=\"_self\">\n    \t\t\t<h2 data-interaction-id=\"bd13aab\" class=\"e-bd13aab-6123f97 e-heading-base\">MY SECOND CHANCE<\/h2>\n\t\t\t\t\t<h4 data-interaction-id=\"e5bd2f1\" class=\"e-e5bd2f1-625a0d3 e-heading-base\">2019 | young adult<\/h4>\n\t\t\t\t\t<p class=\"e-c8195d4-3f4cb38 e-paragraph-base\" data-interaction-id=\"c8195d4\">Eighteen years old, full of life and creative, a talent still finding its direction: this is Giorgia. She can't wait to finish her final year at art school and escape from the small town where she grew up... the very same town where Ludovica moved to study at the Academy of Fine Arts.<\/p>\n\t\t\n<\/a>\n\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3910950 e-con-full animated-slow e-flex elementor-invisible e-con e-parent\" data-id=\"3910950\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeInUp&quot;,&quot;shape_divider_top&quot;:&quot;tilt&quot;}\">\n\t\t\t\t<div class=\"elementor-shape elementor-shape-top\" aria-hidden=\"true\" data-negative=\"false\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 1000 100\" preserveAspectRatio=\"none\">\n\t<path class=\"elementor-shape-fill\" d=\"M0,6V0h1000v100L0,6z\"\/>\n<\/svg>\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d58fa3 e-con-full e-flex e-con e-child\" data-id=\"8d58fa3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9e34ad8 animated-slow elementor-view-default elementor-invisible elementor-widget elementor-widget-icon\" data-id=\"9e34ad8\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_animation_delay&quot;:1200}\" data-widget_type=\"icon.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper\">\n\t\t\t<div class=\"elementor-icon\">\n\t\t\t<i aria-hidden=\"true\" class=\"fas fa-grip-vertical\"><\/i>\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<h1 data-interaction-id=\"6a000b5\" class=\"e-6a000b5-3558ef7 e-heading-base\">documentaries<\/h1>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-46f2101 animated-slow elementor-widget-mobile__width-initial elementor-invisible elementor-widget elementor-widget-html\" data-id=\"46f2101\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;,&quot;_animation_delay&quot;:0}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"it\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <meta name=\"description\" content=\"Image Accordion Widget - Responsive gallery with expandable panels\">\r\n    <title>Image Accordion Widget<\/title>\r\n    \r\n    <!-- Google Fonts -->\r\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Abel&family=Inter:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\">\r\n    \r\n    <script>\r\n        \/* ============================================\r\n         * \ud83c\udfa8 CONFIGURAZIONE WIDGET - MODIFICA QUI\r\n         * ============================================ *\/\r\n        \r\n        const ACCORDION_CONFIG = {\r\n            \/\/ ===== IMPOSTAZIONI GENERALI =====\r\n            totalImages: 4,\r\n            borderRadius: '12px',\r\n\r\n            \/\/ ===== GAP TRA PANNELLI (non genera bordo sul pannello espanso) =====\r\n            panelGap: {\r\n                desktop: '5px',   \/\/ >= 768px\r\n                mobile:  '2px'    \/\/ <  768px\r\n            },\r\n            \r\n            \/\/ ===== NUMERO IMMAGINI PER BLOCCO =====\r\n            \/\/ Opzione 1: Numero FISSO per tutte le risoluzioni (ignora responsive)\r\n            fixedPanelsPerBlock: 4,\r\n\r\n            \/\/ Opzione 2: Responsive (usato se fixedPanelsPerBlock \u00e8 commentato\/null)\r\n            panelsPerBlock: {\r\n                desktop_xl: 7,      \/\/ Schermi >= 1400px\r\n                desktop_l:  6,      \/\/ Schermi >= 1200px\r\n                desktop_m:  5,      \/\/ Schermi >= 992px\r\n                tablet:     4,      \/\/ Schermi >= 768px\r\n                mobile:     3       \/\/ Schermi < 768px\r\n            },\r\n            \r\n            \/\/ ===== ANIMAZIONI =====\r\n            transitionDuration: '0.6s',\r\n            zoomDuration: '0.8s',\r\n            zoomScale: 1.08,\r\n            \r\n            \/\/ ===== COLORI =====\r\n            backgroundColor: '#DAE1DF',\r\n            overlayBackground: 'rgba(0, 0, 0, 0.5)',\r\n            textColor: '#ffffff',\r\n            \r\n            \/\/ ===== FONT =====\r\n            titleFont: \"'Abel', sans-serif\",\r\n            titleSize: '2.0rem',\r\n            titleWeight: '400',\r\n            descriptionFont: \"'Inter', sans-serif\",\r\n            descriptionSize: '1rem',\r\n            descriptionWeight: '400',\r\n            \r\n            \/\/ ===== IMMAGINI =====\r\n            images: [\r\n                {\r\n                    path: 'https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/02\/doc_hanbury3.jpg',\r\n                    title: '<h2>THE TREES OF LIFE',\r\n                    description: 'The Botanical Gardens of Menton, Antibes, Hanbury: <br>a voyage across <b>Planet Earth<\/b>.',\r\n                    link: 'https:\/\/albertogelpi.com\/index.php\/botanical-gardens\/'\r\n                },\r\n                {\r\n                    path: 'https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/02\/doc_heritage4.jpg',\r\n                    title: '<h2>HERITAGE',\r\n                    description: 'The <b>Italian hearth<\/b> of Scotland.',\r\n                    link: 'https:\/\/albertogelpi.com\/index.php\/heritage\/'\r\n                },\r\n                {\r\n                    path: 'https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/03\/doc_aip2.jpg',\r\n                    title: '<h2>AFFIANCO',\r\n                    description: 'Lives in the Mirror:<br> <b>(extra)<\/b>ordinary stories of <br> <b>Primary Immunodeficiencies.',\r\n                    link: 'https:\/\/albertogelpi.com\/index.php\/affianco\/'\r\n                },\r\n                {\r\n                    path: 'https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/03\/doc_cronache-animali2.jpg',\r\n                    title: '<h2>ANIMAL CHRONICLES',\r\n                    description: 'Stories of <b>men<\/b> and <b>animals<\/b><br>in the North.',\r\n                    link: 'https:\/\/albertogelpi.com\/index.php\/animal_chronicles\/'\r\n                },\r\n            ]\r\n        };\r\n    <\/script>\r\n    \r\n    <style>\r\n        \/* ============================================\r\n           CSS CUSTOM PROPERTIES\r\n           ============================================ *\/\r\n        :root {\r\n            --transition-duration: 0.6s;\r\n            --transition-timing: cubic-bezier(0.4, 0, 0.2, 1);\r\n            --zoom-duration: 0.8s;\r\n            --zoom-scale: 1.08;\r\n            --overlay-bg: rgba(0, 0, 0, 0.5);\r\n            --text-color: #ffffff;\r\n            --nav-button-bg: rgba(255, 255, 255, 0.9);\r\n            --nav-button-hover: rgba(255, 255, 255, 1);\r\n            --border-radius: 10px;\r\n            --panel-gap: 5px;        \/* Aggiornato via JS \u2014 spazio TRA pannelli *\/\r\n            --background-color: #DAE1DF;\r\n            --title-font: 'Abel', sans-serif;\r\n            --title-size: 2.5rem;\r\n            --title-weight: 700;\r\n            --description-font: 'Inter', sans-serif;\r\n            --description-size: 1rem;\r\n            --description-weight: 400;\r\n        }\r\n\r\n        \/* ============================================\r\n           RESET & BASE STYLES\r\n           ============================================ *\/\r\n        * {\r\n            margin: 0;\r\n            padding: 0;\r\n            box-sizing: border-box;\r\n        }\r\n\r\n        body {\r\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\r\n            line-height: 1.6;\r\n            background-color: #f5f5f5;\r\n            padding: 20px;\r\n        }\r\n\r\n        \/* ============================================\r\n           ACCORDION CONTAINER\r\n           ============================================ *\/\r\n        .accordion-container {\r\n            max-width: 1400px;\r\n            margin: 0 auto;\r\n            position: relative;\r\n            overflow: hidden;\r\n            background: var(--background-color);\r\n            border-radius: 12px;\r\n            box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);\r\n        }\r\n\r\n        .accordion-wrapper {\r\n            position: relative;\r\n            width: 100%;\r\n            height: 500px;\r\n            overflow: hidden;\r\n        }\r\n\r\n        \/* ============================================\r\n           ACCORDION TRACK\r\n           gap: crea spazio SOLO tra pannelli adiacenti,\r\n           mai sui bordi esterni \u2192 nessun bordo visivo\r\n           sul pannello espanso\r\n           ============================================ *\/\r\n        .accordion-track {\r\n            display: flex;\r\n            height: 100%;\r\n            gap: var(--panel-gap);\r\n        }\r\n\r\n        \/* ============================================\r\n           PANEL STYLES\r\n           ============================================ *\/\r\n        .accordion-panel {\r\n            position: relative;\r\n            flex: 1;\r\n            height: 100%;\r\n            overflow: hidden;\r\n            cursor: pointer;\r\n            transition: flex var(--transition-duration) var(--transition-timing);\r\n            border-radius: var(--border-radius);\r\n        }\r\n        \r\n        .accordion-panel.expanded {\r\n            flex: 3;\r\n        }\r\n        \r\n        .accordion-panel.hidden {\r\n            display: none;\r\n        }\r\n\r\n        .accordion-panel a {\r\n            display: block;\r\n            width: 100%;\r\n            height: 100%;\r\n            text-decoration: none;\r\n            color: inherit;\r\n            position: relative;\r\n        }\r\n\r\n        \/* Immagine occupa l'intero pannello \u2014 zero inset \u2192 zero bordo visivo *\/\r\n        .panel-image {\r\n            position: absolute;\r\n            top: 0;\r\n            left: 0;\r\n            right: 0;\r\n            bottom: 0;\r\n            background-size: cover;\r\n            background-position: center;\r\n            background-repeat: no-repeat;\r\n            transition: transform var(--zoom-duration) cubic-bezier(0.25, 0.46, 0.45, 0.94);\r\n            border-radius: var(--border-radius);\r\n        }\r\n\r\n        .accordion-panel:hover .panel-image {\r\n            transform: scale(var(--zoom-scale));\r\n        }\r\n\r\n        \/* Overlay scuro *\/\r\n        .panel-overlay {\r\n            position: absolute;\r\n            top: 0;\r\n            left: 0;\r\n            width: 100%;\r\n            height: 100%;\r\n            background: var(--overlay-bg);\r\n            opacity: 0;\r\n            transition: opacity var(--transition-duration) var(--transition-timing);\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            padding: 20px;\r\n            pointer-events: none;\r\n        }\r\n\r\n        .accordion-panel.expanded .panel-overlay {\r\n            opacity: 1;\r\n        }\r\n\r\n        \/* Testo overlay *\/\r\n        .panel-text {\r\n            color: var(--text-color);\r\n            text-align: center;\r\n            opacity: 0;\r\n            transform: translateY(20px);\r\n            transition: all var(--transition-duration) var(--transition-timing);\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 4px;\r\n        }\r\n\r\n        .accordion-panel.expanded .panel-text {\r\n            opacity: 1;\r\n            transform: translateY(0);\r\n        }\r\n        \r\n        .panel-title {\r\n            font-family: var(--title-font);\r\n            font-size: var(--title-size);\r\n            font-weight: var(--title-weight);\r\n            text-transform: uppercase;\r\n            letter-spacing: 2px;\r\n            line-height: 1.2;\r\n        }\r\n        \r\n        .panel-title h2 {\r\n            margin: 0;\r\n        }\r\n        \r\n        .panel-description {\r\n            font-family: var(--description-font);\r\n            font-size: var(--description-size);\r\n            font-weight: var(--description-weight);\r\n            letter-spacing: 0.5px;\r\n            line-height: 1.5;\r\n            opacity: 0.9;\r\n        }\r\n\r\n        \/* ============================================\r\n           NAVIGATION CONTROLS\r\n           ============================================ *\/\r\n        .nav-controls {\r\n            position: absolute;\r\n            top: 50%;\r\n            transform: translateY(-50%);\r\n            width: 100%;\r\n            height: 0;\r\n            pointer-events: none;\r\n            z-index: 10;\r\n        }\r\n\r\n        .nav-button {\r\n            pointer-events: all;\r\n            position: absolute;\r\n            top: 50%;\r\n            transform: translateY(-50%);\r\n            width: 50px;\r\n            height: 50px;\r\n            border: none;\r\n            border-radius: 50%;\r\n            background: var(--nav-button-bg);\r\n            cursor: pointer;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            transition: all 0.3s ease;\r\n            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n        }\r\n        \r\n        #prevBtn { left: 20px; }\r\n        #nextBtn { right: 20px; }\r\n\r\n        .nav-button:hover:not(:disabled) {\r\n            background: var(--nav-button-hover);\r\n            box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);\r\n        }\r\n        \r\n        #prevBtn:hover:not(:disabled) { transform: translateY(-50%) scale(1.1); }\r\n        #nextBtn:hover:not(:disabled) { transform: translateY(-50%) scale(1.1); }\r\n\r\n        .nav-button:disabled { display: none; }\r\n\r\n        .nav-button svg {\r\n            width: 24px;\r\n            height: 24px;\r\n            fill: #333;\r\n        }\r\n\r\n        \/* ============================================\r\n           DOTS INDICATOR\r\n           ============================================ *\/\r\n        .dots-indicator {\r\n            display: flex;\r\n            gap: 10px;\r\n            align-items: center;\r\n            justify-content: center;\r\n            padding: 20px 0;\r\n            max-width: 1400px;\r\n            margin: 0 auto;\r\n        }\r\n\r\n        .dot {\r\n            width: 12px;\r\n            height: 12px;\r\n            flex-shrink: 0;\r\n            border-radius: 50%;\r\n            background: rgba(255, 255, 255, 0.3);\r\n            border: 2px solid rgba(255, 255, 255, 0.5);\r\n            cursor: pointer;\r\n            transition: all 0.3s ease;\r\n            padding: 0;\r\n        }\r\n\r\n        .dot.active {\r\n            background: rgba(255, 255, 255, 1);\r\n            border-color: rgba(255, 255, 255, 1);\r\n            width: 14px;\r\n            height: 14px;\r\n        }\r\n\r\n        .dot:hover { background: rgba(255, 255, 255, 0.6); }\r\n\r\n        \/* ============================================\r\n           RESPONSIVE\r\n           ============================================ *\/\r\n        @media (min-width: 768px) and (max-width: 991px) {\r\n            .accordion-wrapper { height: 400px; }\r\n            .panel-title { font-size: 2rem; }\r\n            .panel-description { font-size: 0.9rem; }\r\n        }\r\n\r\n        @media (max-width: 767px) {\r\n            body { padding: 0; }\r\n\r\n            .accordion-container {\r\n                border-radius: 0;\r\n                box-shadow: none;\r\n                max-width: 100%;\r\n            }\r\n\r\n            .accordion-wrapper { height: 380px; }\r\n            .nav-controls { display: none; }\r\n\r\n            .panel-title {\r\n                font-size: 1.3rem;\r\n                letter-spacing: 1px;\r\n            }\r\n\r\n            .panel-description { font-size: 0.8rem; }\r\n            .panel-overlay { padding: 12px; }\r\n            .dots-indicator { padding: 14px 0; }\r\n        }\r\n\r\n        \/* ============================================\r\n           ACCESSIBILITY\r\n           ============================================ *\/\r\n        .accordion-panel:focus-within {\r\n            outline: 3px solid #4A90E2;\r\n            outline-offset: 2px;\r\n        }\r\n\r\n        .nav-button:focus,\r\n        .dot:focus {\r\n            outline: 2px solid #4A90E2;\r\n            outline-offset: 2px;\r\n        }\r\n\r\n        \/* ============================================\r\n           UTILITIES\r\n           ============================================ *\/\r\n        .no-select {\r\n            -webkit-user-select: none;\r\n            -moz-user-select: none;\r\n            -ms-user-select: none;\r\n            user-select: none;\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n    <div class=\"accordion-container\" id=\"accordionContainer\">\r\n        <div class=\"accordion-wrapper no-select\">\r\n            <div class=\"accordion-track\" id=\"accordionTrack\">\r\n                <!-- Pannelli inseriti dinamicamente via JS -->\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"nav-controls\">\r\n            <button class=\"nav-button\" id=\"prevBtn\" aria-label=\"Blocco precedente\">\r\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\">\r\n                    <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"\/>\r\n                <\/svg>\r\n            <\/button>\r\n            <button class=\"nav-button\" id=\"nextBtn\" aria-label=\"Blocco successivo\">\r\n                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\">\r\n                    <path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"\/>\r\n                <\/svg>\r\n            <\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"dots-indicator\" id=\"dotsIndicator\"><\/div>\r\n\r\n    <script>\r\n        class ImageAccordion {\r\n            constructor(config) {\r\n                this.config = config;\r\n                this.container    = document.getElementById('accordionContainer');\r\n                this.track        = document.getElementById('accordionTrack');\r\n                this.prevBtn      = document.getElementById('prevBtn');\r\n                this.nextBtn      = document.getElementById('nextBtn');\r\n                this.dotsIndicator = document.getElementById('dotsIndicator');\r\n                \r\n                this.currentBlock       = 0;\r\n                this.expandedPanelIndex = 0;\r\n                this.isDesktop          = this.detectDesktop();\r\n                this.touchStartX        = 0;\r\n                this.touchEndX          = 0;\r\n                this.isDragging         = false;\r\n                \r\n                this.init();\r\n            }\r\n            \r\n            detectDesktop() {\r\n                return window.innerWidth >= 992;\r\n            }\r\n\r\n            \/* --------------------------------------------------\r\n               applyCSSVariables\r\n               Applica tutte le variabili CSS dalla config.\r\n               Il gap viene gestito separatamente da applyResponsiveGap()\r\n               per supportare valori diversi per breakpoint.\r\n            -------------------------------------------------- *\/\r\n            applyCSSVariables() {\r\n                const root = document.documentElement;\r\n                root.style.setProperty('--transition-duration', this.config.transitionDuration);\r\n                root.style.setProperty('--zoom-duration',       this.config.zoomDuration);\r\n                root.style.setProperty('--zoom-scale',          this.config.zoomScale);\r\n                root.style.setProperty('--overlay-bg',          this.config.overlayBackground);\r\n                root.style.setProperty('--text-color',          this.config.textColor);\r\n                root.style.setProperty('--border-radius',       this.config.borderRadius);\r\n                root.style.setProperty('--background-color',    this.config.backgroundColor);\r\n                root.style.setProperty('--title-font',          this.config.titleFont);\r\n                root.style.setProperty('--title-size',          this.config.titleSize);\r\n                root.style.setProperty('--title-weight',        this.config.titleWeight);\r\n                root.style.setProperty('--description-font',    this.config.descriptionFont);\r\n                root.style.setProperty('--description-size',    this.config.descriptionSize);\r\n                root.style.setProperty('--description-weight',  this.config.descriptionWeight);\r\n                \r\n                \/\/ Applica il gap responsive\r\n                this.applyResponsiveGap();\r\n            }\r\n\r\n            \/* --------------------------------------------------\r\n               applyResponsiveGap\r\n               Imposta --panel-gap in base alla larghezza corrente.\r\n               Desktop >= 768px \u2192 panelGap.desktop\r\n               Mobile  <  768px \u2192 panelGap.mobile\r\n            -------------------------------------------------- *\/\r\n            applyResponsiveGap() {\r\n                const gap = window.innerWidth >= 768\r\n                    ? this.config.panelGap.desktop\r\n                    : this.config.panelGap.mobile;\r\n                document.documentElement.style.setProperty('--panel-gap', gap);\r\n            }\r\n            \r\n            init() {\r\n                this.applyCSSVariables();\r\n                this.updatePanelsPerBlock();\r\n                this.renderPanels();\r\n                \r\n                \/\/ Nascondi pannelli non del primo blocco\r\n                this.track.querySelectorAll('.accordion-panel').forEach((panel, index) => {\r\n                    if (index >= this.panelsPerBlock) panel.classList.add('hidden');\r\n                });\r\n                \r\n                this.renderDots();\r\n                this.attachEventListeners();\r\n                this.updateNavigation();\r\n                this.expandPanel(0);\r\n            }\r\n            \r\n            updatePanelsPerBlock() {\r\n                if (this.config.fixedPanelsPerBlock) {\r\n                    this.panelsPerBlock = this.config.fixedPanelsPerBlock;\r\n                } else {\r\n                    const w = window.innerWidth;\r\n                    if      (w >= 1400) this.panelsPerBlock = this.config.panelsPerBlock.desktop_xl;\r\n                    else if (w >= 1200) this.panelsPerBlock = this.config.panelsPerBlock.desktop_l;\r\n                    else if (w >= 992)  this.panelsPerBlock = this.config.panelsPerBlock.desktop_m;\r\n                    else if (w >= 768)  this.panelsPerBlock = this.config.panelsPerBlock.tablet;\r\n                    else                this.panelsPerBlock = this.config.panelsPerBlock.mobile;\r\n                }\r\n                this.totalBlocks = Math.ceil(this.config.images.length \/ this.panelsPerBlock);\r\n            }\r\n            \r\n            renderPanels() {\r\n                this.track.innerHTML = '';\r\n                this.config.images.forEach((image, index) => {\r\n                    const panel = document.createElement('div');\r\n                    panel.className    = 'accordion-panel';\r\n                    panel.dataset.index = index;\r\n                    panel.innerHTML = `\r\n                        <a href=\"${image.link}\" aria-label=\"${image.title}\">\r\n                            <div class=\"panel-image\" style=\"background-image: url('${image.path}')\"><\/div>\r\n                            <div class=\"panel-overlay\">\r\n                                <div class=\"panel-text\">\r\n                                    <div class=\"panel-title\">${image.title}<\/div>\r\n                                    <div class=\"panel-description\">${image.description}<\/div>\r\n                                <\/div>\r\n                            <\/div>\r\n                        <\/a>\r\n                    `;\r\n                    this.track.appendChild(panel);\r\n                });\r\n            }\r\n            \r\n            renderDots() {\r\n                this.dotsIndicator.innerHTML = '';\r\n                if (this.totalBlocks <= 1) {\r\n                    this.dotsIndicator.style.display = 'none';\r\n                    return;\r\n                }\r\n                this.dotsIndicator.style.display = 'flex';\r\n                for (let i = 0; i < this.totalBlocks; i++) {\r\n                    const dot = document.createElement('button');\r\n                    dot.className = 'dot' + (i === this.currentBlock ? ' active' : '');\r\n                    dot.setAttribute('aria-label', `Vai al blocco ${i + 1}`);\r\n                    dot.dataset.block = i;\r\n                    dot.addEventListener('click', () => this.goToBlock(i));\r\n                    this.dotsIndicator.appendChild(dot);\r\n                }\r\n            }\r\n            \r\n            attachEventListeners() {\r\n                this.prevBtn.addEventListener('click', () => this.previousBlock());\r\n                this.nextBtn.addEventListener('click', () => this.nextBlock());\r\n                \r\n                \/\/ Desktop: hover\r\n                if (this.isDesktop) {\r\n                    this.track.addEventListener('mouseover', (e) => {\r\n                        const panel = e.target.closest('.accordion-panel');\r\n                        if (panel && !panel.classList.contains('hidden')) {\r\n                            const index      = parseInt(panel.dataset.index);\r\n                            const blockIndex = Math.floor(index \/ this.panelsPerBlock);\r\n                            if (blockIndex === this.currentBlock) this.expandPanel(index);\r\n                        }\r\n                    });\r\n                }\r\n                \r\n                \/\/ Mobile\/Tablet: click\r\n                this.track.addEventListener('click', (e) => {\r\n                    if (!this.isDesktop) {\r\n                        e.preventDefault();\r\n                        const panel = e.target.closest('.accordion-panel');\r\n                        if (panel) {\r\n                            const index      = parseInt(panel.dataset.index);\r\n                            const blockIndex = Math.floor(index \/ this.panelsPerBlock);\r\n                            if (blockIndex !== this.currentBlock) this.goToBlock(blockIndex);\r\n                            this.expandPanel(index);\r\n                        }\r\n                    }\r\n                });\r\n                \r\n                \/\/ Swipe\r\n                this.track.addEventListener('touchstart', (e) => {\r\n                    this.touchStartX = e.changedTouches[0].screenX;\r\n                    this.isDragging  = true;\r\n                }, { passive: true });\r\n                \r\n                this.track.addEventListener('touchend', (e) => {\r\n                    if (!this.isDragging) return;\r\n                    this.touchEndX  = e.changedTouches[0].screenX;\r\n                    this.handleSwipe();\r\n                    this.isDragging = false;\r\n                }, { passive: true });\r\n                \r\n                \/\/ Resize\r\n                let resizeTimeout;\r\n                window.addEventListener('resize', () => {\r\n                    clearTimeout(resizeTimeout);\r\n                    resizeTimeout = setTimeout(() => {\r\n                        \/\/ Aggiorna gap responsive\r\n                        this.applyResponsiveGap();\r\n\r\n                        const oldPanelsPerBlock = this.panelsPerBlock;\r\n                        const wasDesktop        = this.isDesktop;\r\n                        \r\n                        this.updatePanelsPerBlock();\r\n                        this.isDesktop = this.detectDesktop();\r\n                        \r\n                        if (oldPanelsPerBlock !== this.panelsPerBlock) {\r\n                            this.currentBlock = Math.floor(this.expandedPanelIndex \/ this.panelsPerBlock);\r\n                            this.renderDots();\r\n                            this.updateNavigation();\r\n                            this.updatePanelVisibility();\r\n                        }\r\n                    }, 250);\r\n                });\r\n                \r\n                \/\/ Keyboard\r\n                document.addEventListener('keydown', (e) => {\r\n                    if      (e.key === 'ArrowLeft')  this.previousBlock();\r\n                    else if (e.key === 'ArrowRight') this.nextBlock();\r\n                });\r\n            }\r\n            \r\n            handleSwipe() {\r\n                const diff = this.touchStartX - this.touchEndX;\r\n                if (Math.abs(diff) > 50) {\r\n                    if (diff > 0) this.nextBlock();\r\n                    else          this.previousBlock();\r\n                }\r\n            }\r\n            \r\n            expandPanel(index) {\r\n                this.track.querySelectorAll('.accordion-panel').forEach(p => p.classList.remove('expanded'));\r\n                const target = this.track.querySelector(`[data-index=\"${index}\"]`);\r\n                if (target) {\r\n                    target.classList.add('expanded');\r\n                    this.expandedPanelIndex = index;\r\n                }\r\n            }\r\n            \r\n            previousBlock() {\r\n                if (this.currentBlock > 0) this.goToBlock(this.currentBlock - 1);\r\n            }\r\n            \r\n            nextBlock() {\r\n                if (this.currentBlock < this.totalBlocks - 1) this.goToBlock(this.currentBlock + 1);\r\n            }\r\n            \r\n            goToBlock(blockIndex) {\r\n                if (blockIndex < 0 || blockIndex >= this.totalBlocks) return;\r\n                this.currentBlock = blockIndex;\r\n                this.updatePanelVisibility();\r\n                this.updateNavigation();\r\n                this.updateDots();\r\n                this.expandPanel(blockIndex * this.panelsPerBlock);\r\n            }\r\n            \r\n            updatePanelVisibility() {\r\n                const allPanels   = this.track.querySelectorAll('.accordion-panel');\r\n                const startIndex  = this.currentBlock * this.panelsPerBlock;\r\n                const endIndex    = Math.min(startIndex + this.panelsPerBlock, this.config.images.length);\r\n                const duration    = parseFloat(this.config.transitionDuration) * 1000;\r\n\r\n                \/\/ Fade out\r\n                this.track.style.transition = `opacity ${this.config.transitionDuration} ease-out`;\r\n                this.track.style.opacity    = '0';\r\n                \r\n                setTimeout(() => {\r\n                    allPanels.forEach((panel, index) => {\r\n                        panel.classList.remove('expanded');\r\n                        if (index >= startIndex && index < endIndex) panel.classList.remove('hidden');\r\n                        else                                          panel.classList.add('hidden');\r\n                    });\r\n                    \r\n                    requestAnimationFrame(() => {\r\n                        this.track.style.transition = `opacity ${this.config.transitionDuration} ease-in`;\r\n                        this.track.style.opacity    = '1';\r\n                        this.expandPanel(startIndex);\r\n                    });\r\n                    \r\n                    setTimeout(() => {\r\n                        this.track.style.transition = '';\r\n                        this.track.style.opacity    = '';\r\n                    }, duration);\r\n                }, duration);\r\n            }\r\n            \r\n            updateNavigation() {\r\n                this.prevBtn.disabled = this.currentBlock === 0;\r\n                this.nextBtn.disabled = this.currentBlock === this.totalBlocks - 1;\r\n            }\r\n            \r\n            updateDots() {\r\n                this.dotsIndicator.querySelectorAll('.dot').forEach((dot, index) => {\r\n                    dot.classList.toggle('active', index === this.currentBlock);\r\n                });\r\n            }\r\n        }\r\n        \r\n        document.addEventListener('DOMContentLoaded', () => {\r\n            if (ACCORDION_CONFIG.images.length !== ACCORDION_CONFIG.totalImages) {\r\n                console.warn(`\u26a0\ufe0f totalImages (${ACCORDION_CONFIG.totalImages}) non corrisponde alle immagini fornite (${ACCORDION_CONFIG.images.length})`);\r\n            }\r\n            const accordion = new ImageAccordion(ACCORDION_CONFIG);\r\n            window.accordion = accordion;\r\n            console.log('\u2705 Image Accordion inizializzato');\r\n        });\r\n    <\/script>\r\n\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-04ebc3a e-con-full animated-slow e-flex e-con e-parent\" data-id=\"04ebc3a\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;animation&quot;:&quot;none&quot;,&quot;shape_divider_top&quot;:&quot;tilt&quot;}\">\n\t\t\t\t<div class=\"elementor-shape elementor-shape-top\" aria-hidden=\"true\" data-negative=\"false\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 1000 100\" preserveAspectRatio=\"none\">\n\t<path class=\"elementor-shape-fill\" d=\"M0,6V0h1000v100L0,6z\"\/>\n<\/svg>\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b0e2e8a e-con-full e-flex e-con e-child\" data-id=\"b0e2e8a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a0ce325 animated-slow elementor-widget-mobile__width-initial elementor-view-default elementor-invisible elementor-widget elementor-widget-icon\" data-id=\"a0ce325\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_animation_delay&quot;:1200}\" data-widget_type=\"icon.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-wrapper\">\n\t\t\t<div class=\"elementor-icon\">\n\t\t\t<i aria-hidden=\"true\" class=\"fas fa-grip-vertical\"><\/i>\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<h1 data-interaction-id=\"835c1f8\" class=\"e-835c1f8-162d2af e-heading-base\">commercials<\/h1>\n\t\t\t\t\t<img decoding=\"async\" class=\"e-image-base e-e7dbb5d-e87e6d6\" data-interaction-id=\"e7dbb5d\" id=\"7680\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/03\/swipe-3x_loop-count.gif\" width=\"150\" height=\"150\" srcset=\"\" alt=\"\"\/>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f7417d0 animated-slow elementor-invisible elementor-widget elementor-widget-html\" data-id=\"f7417d0\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n\/* ==== VARIABILI CSS ==== *\/\r\n:root {\r\n  --gallery-bg: #000000;\r\n  --overlay-color: rgba(0, 0, 0, 0.15);\r\n  --transition-speed: 0.9s;\r\n}\r\n\r\n\/* ==== STILE BASE ==== *\/\r\n.scrolling-gallery {\r\n  overflow: hidden;\r\n  width: 100%;\r\n  background-color: var(--gallery-bg);\r\n  padding: 5px 0;\r\n  position: relative;\r\n  isolation: isolate;\r\n  cursor: grab;\r\n}\r\n\r\n.scrolling-gallery.is-dragging {\r\n  cursor: grabbing;\r\n  user-select: none;\r\n}\r\n\r\n\/* ==== RIGA SCORRIMENTO ==== *\/\r\n.scrolling-row {\r\n  display: flex;\r\n  flex-wrap: nowrap;\r\n  width: auto;\r\n  will-change: transform;\r\n}\r\n\r\n\/* ==== CONTENITORE IMMAGINI ==== *\/\r\n.image-wrapper {\r\n  position: relative;\r\n  display: inline-block;\r\n  margin-right: 15px;\r\n  border-radius: var(--border-radius);\r\n  overflow: hidden;\r\n  flex-shrink: 0;\r\n  cursor: pointer;\r\n}\r\n\r\n.is-dragging .image-wrapper {\r\n  pointer-events: none;\r\n}\r\n\r\n\/* ==== IMMAGINE BASE ==== *\/\r\n.image-wrapper img {\r\n  aspect-ratio: 16 \/ 9;\r\n  width: 25vw;\r\n  height: auto;\r\n  object-fit: cover;\r\n  display: block;\r\n  transition: transform var(--transition-speed) cubic-bezier(0.25, 1, 0.5, 1),\r\n              filter 0.4s ease;\r\n  will-change: filter, transform;\r\n  user-select: none;\r\n  -webkit-user-drag: none;\r\n}\r\n\r\n\/* ==== OVERLAY ARANCIONE ==== *\/\r\n.image-wrapper::before {\r\n  content: '';\r\n  position: absolute;\r\n  inset: 0;\r\n  background-color: var(--overlay-color);\r\n  opacity: 0;\r\n  filter: saturate(100%) sepia(100%) hue-rotate(340deg) brightness(.4) saturate(100%);\r\n  transition: opacity 1s ease-out;\r\n  pointer-events: none;\r\n  z-index: 1;\r\n}\r\n\r\n\/* ==== TESTO HOVER ==== *\/\r\n.hover-text {\r\n  position: absolute;\r\n  top: 50%;\r\n  left: 50%;\r\n  font-family: 'Abel';\r\n  font-size: 12px;\r\n  font-weight: bold;\r\n  letter-spacing: 2px;\r\n  color: #FD8B00;\r\n  text-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\r\n  white-space: nowrap;\r\n  opacity: 0;\r\n  transform: translate(-50%, -50%);\r\n  transition: opacity 0.5s ease;\r\n  pointer-events: none;\r\n  z-index: 2;\r\n  will-change: opacity;\r\n  background-color: rgba(0, 0, 0, 0.45);\r\n  padding: 3px 3px;\r\n}\r\n\r\n.hover-text .letter {\r\n  display: inline-block;\r\n}\r\n\r\n\/* ==== TESTO SORGENTE PER TRANSLATEPRESS ====\r\n   Nascosto visivamente (tecnica screen-reader-only, non display:none)\r\n   cos\u00ec il parser HTML lato server di TranslatePress lo trova e lo traduce\r\n   al primo caricamento della pagina. Il JS legge questo nodo, non l'attributo. *\/\r\n.hover-text-source {\r\n  position: absolute;\r\n  width: 1px;\r\n  height: 1px;\r\n  padding: 0;\r\n  margin: -1px;\r\n  overflow: hidden;\r\n  clip: rect(0, 0, 0, 0);\r\n  white-space: nowrap;\r\n  border: 0;\r\n}\r\n\r\n\/* ==== STATO HOVER ==== *\/\r\n.image-wrapper:hover::before { opacity: 1; }\r\n.image-wrapper:hover .hover-text { opacity: 1; }\r\n.image-wrapper:hover img {\r\n  transform: scale(1.1);\r\n  filter: blur(2px) sepia(60%) hue-rotate(340deg) brightness(0.5);\r\n}\r\n.image-wrapper:focus-visible {\r\n  outline: 3px solid #fff;\r\n  outline-offset: 2px;\r\n}\r\n\r\n\/* ==== LIGHTBOX MODAL \u2014 sistema film card ==== *\/\r\n.ag-video-modal {\r\n  position: fixed;\r\n  top: 0;\r\n  left: 0;\r\n  width: 100%;\r\n  height: 100%;\r\n  background-color: rgba(0, 0, 0, 0.9);\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n  z-index: 999999;\r\n  padding: 20px;\r\n  opacity: 0;\r\n  animation: agFadeIn 0.3s ease forwards;\r\n}\r\n\r\n@keyframes agFadeIn {\r\n  to { opacity: 1; }\r\n}\r\n\r\n.ag-modal-content {\r\n  position: relative;\r\n  width: 100%;\r\n  max-width: 1100px;\r\n  aspect-ratio: 16 \/ 9;\r\n  background: #000;\r\n  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);\r\n  animation: agScaleIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\r\n}\r\n\r\n@keyframes agScaleIn {\r\n  from { transform: scale(0.9); opacity: 0; }\r\n  to   { transform: scale(1);   opacity: 1; }\r\n}\r\n\r\n.ag-modal-content iframe {\r\n  width: 100%;\r\n  height: 100%;\r\n  border: none;\r\n}\r\n\r\n.ag-modal-close {\r\n  position: absolute;\r\n  top: -50px;\r\n  right: 0;\r\n  width: 32px !important;\r\n  height: 32px !important;\r\n  min-width: 32px !important;\r\n  min-height: 32px !important;\r\n  max-width: 32px !important;\r\n  max-height: 32px !important;\r\n  padding: 0 !important;\r\n  background: #FD8B00 !important;\r\n  border: none !important;\r\n  border-radius: 50% !important;\r\n  color: #fff !important;\r\n  font-size: 20px !important;\r\n  line-height: 32px !important;\r\n  font-family: Arial, sans-serif !important;\r\n  cursor: pointer;\r\n  transition: background 0.2s ease;\r\n  z-index: 1;\r\n  display: flex !important;\r\n  align-items: center !important;\r\n  justify-content: center !important;\r\n}\r\n\r\n.ag-modal-close:hover { background: #ff721a !important; }\r\n\r\n.ag-modal-close:focus-visible {\r\n  outline: 3px solid #fff;\r\n  outline-offset: 4px;\r\n}\r\n\r\n\/* Loading Spinner *\/\r\n.ag-modal-loading {\r\n  position: absolute;\r\n  inset: 0;\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n  background: #000;\r\n}\r\n\r\n.ag-spinner {\r\n  width: 50px;\r\n  height: 50px;\r\n  border: 4px solid rgba(255, 255, 255, 0.1);\r\n  border-top-color: #FD8B00;\r\n  border-radius: 50%;\r\n  animation: agSpin 0.8s linear infinite;\r\n}\r\n\r\n@keyframes agSpin {\r\n  to { transform: rotate(360deg); }\r\n}\r\n\r\nbody.ag-modal-open { overflow: hidden; }\r\n\r\n\/* ==== RESPONSIVE ==== *\/\r\n@media (max-width: 1024px) {\r\n  .scrolling-gallery,\r\n  .scrolling-gallery.is-dragging { cursor: default; }\r\n  .image-wrapper img { width: 35vw; }\r\n  .hover-text { opacity: 1; }\r\n}\r\n\r\n@media (max-width: 768px) {\r\n  .image-wrapper img { width: 50vw; }\r\n\r\n  .ag-modal-close {\r\n    top: 10px !important;\r\n    right: 10px !important;\r\n    width: 40px !important;\r\n    height: 40px !important;\r\n    font-size: 28px !important;\r\n    line-height: 40px !important;\r\n    position: fixed !important;\r\n  }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n  .image-wrapper img { width: 70vw; }\r\n}\r\n\r\n@media (orientation: landscape) and (max-height: 500px) {\r\n  .ag-video-modal { padding: 0; }\r\n\r\n  .ag-modal-content {\r\n    width: 100vw;\r\n    max-width: 100vw;\r\n    height: 100vh;\r\n    height: 100dvh;\r\n    aspect-ratio: unset;\r\n  }\r\n\r\n  .ag-modal-close {\r\n    top: 8px !important;\r\n    right: 8px !important;\r\n    position: fixed !important;\r\n    opacity: 0.85;\r\n  }\r\n}\r\n\r\n@supports not (aspect-ratio: 16 \/ 9) {\r\n  .ag-modal-content {\r\n    padding-bottom: 56.25%;\r\n    height: 0;\r\n  }\r\n  .ag-modal-content iframe {\r\n    position: absolute;\r\n    top: 0; left: 0;\r\n  }\r\n}\r\n\r\n@media (prefers-reduced-motion: reduce) {\r\n  *, *::before, *::after {\r\n    animation-duration: 0.01ms !important;\r\n    animation-iteration-count: 1 !important;\r\n    transition-duration: 0.01ms !important;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<!-- HTML PULITO: solo gli item originali, senza duplicati manuali -->\r\n<div class=\"scrolling-gallery\">\r\n  <div class=\"scrolling-row scroll-left\" style=\"animation-duration: 70s;\">\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Larissa Iapichino\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/01\/Larissa_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/758448534\" alt=\"Larissa Iapichino\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">LARISSA IAPICHINO - promo<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Contraffazione\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/10\/Contraffazione_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/762957942\" alt=\"Contraffazione\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">COUNTERFEIT GOODS - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Juvenia\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/03\/Juvenia_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/688068417\" alt=\"Juvenia\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">THE IMPOSSIBLE - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video SSG\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2023\/02\/ssg_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/797674791\" alt=\"SSG\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">OUR SKY - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n(function () {\r\n  'use strict';\r\n\r\n  window.GelpiGallery = window.GelpiGallery || {\r\n    instances: [],\r\n    initialized: false\r\n  };\r\n\r\n  const CONFIG = {\r\n    vimeoParams: '?dnt=1&autoplay=1&title=0&byline=0&portrait=0',\r\n    minDecryptDuration: 40,\r\n    maxDecryptDuration: 100,\r\n    decryptFrameRate: 30, \/\/ ms per tick (era 8: troppo aggressivo, inutile a livello visivo)\r\n    directionThreshold: 6,\r\n    dragSensitivity: 1.0,\r\n    hoverDebounce: 50,\r\n    preloadHoverDelay: 300, \/\/ ms di hover continuo prima di scaldare il player\r\n    proactivePreload: true  \/\/ scalda un video durante l'idle time dopo il caricamento pagina\r\n  };\r\n\r\n  const CHARS = '\u2580\u2584\u2588\u258c\u2590\u2591\u2592\u2593@#$%&*+=<>?';\r\n\r\n  \/\/ Stringhe fisse della modale video: gestite qui e non da TranslatePress,\r\n  \/\/ perch\u00e9 il contenuto \u00e8 generato via JS e non \u00e8 mai visibile al parser lato server.\r\n  const UI_STRINGS = {\r\n    en: { close: 'Close video', closeTitle: 'Close (ESC)', player: 'Video player' },\r\n    it: { close: 'Chiudi video', closeTitle: 'Chiudi (ESC)', player: 'Video player' }\r\n  };\r\n\r\n  function currentLang() {\r\n    const lang = (document.documentElement.lang || 'en').toLowerCase();\r\n    return lang.startsWith('it') ? 'it' : 'en';\r\n  }\r\n\r\n  function debounce(func, wait) {\r\n    let timeout;\r\n    return function (...args) {\r\n      clearTimeout(timeout);\r\n      timeout = setTimeout(() => func(...args), wait);\r\n    };\r\n  }\r\n\r\n  \/\/ Legge il titolo dal nodo statico traducibile lato server (fallback su data-text\r\n  \/\/ per compatibilit\u00e0 con eventuali markup non ancora aggiornati).\r\n  function getWrapperText(textEl) {\r\n    const src = textEl.querySelector('.hover-text-source');\r\n    if (src) return src.textContent.trim();\r\n    return (textEl.getAttribute('data-text') || '').trim();\r\n  }\r\n\r\n  function getLettersContainer(textEl) {\r\n    return textEl.querySelector('.hover-text-letters');\r\n  }\r\n\r\n  \/\/ ===== LIGHTBOX \u2014 sistema film card =====\r\n  const GelpiModal = {\r\n\r\n\topen(vimeoUrl) {\r\n\t  document.querySelectorAll('.ag-video-modal').forEach(m => {\r\n\t\tconst f = m.querySelector('iframe');\r\n\t\tif (f) f.src = '';\r\n\t\tm.remove();\r\n\t  });\r\n\r\n\t  const videoId = this.extractVimeoId(vimeoUrl);\r\n\t  if (!videoId) {\r\n\t\tconsole.error('[GelpiGallery] ID Vimeo non valido:', vimeoUrl);\r\n\t\treturn;\r\n\t  }\r\n\r\n\t  const embedUrl = `https:\/\/player.vimeo.com\/video\/${videoId}${CONFIG.vimeoParams}`;\r\n\t  const strings = UI_STRINGS[currentLang()];\r\n\r\n\t  const modal = document.createElement('div');\r\n\t  modal.className = 'ag-video-modal';\r\n\t  modal.setAttribute('role', 'dialog');\r\n\t  modal.setAttribute('aria-modal', 'true');\r\n\t  modal.setAttribute('aria-label', strings.player);\r\n\t  modal.setAttribute('data-no-translation', ''); \/\/ esclude il modal dallo scanner TranslatePress\r\n\r\n\t  modal.innerHTML = `\r\n\t\t<div class=\"ag-modal-content\">\r\n\t\t  <button\r\n\t\t\ttype=\"button\"\r\n\t\t\tclass=\"ag-modal-close\"\r\n\t\t\taria-label=\"${strings.close}\"\r\n\t\t\ttitle=\"${strings.closeTitle}\"\r\n\t\t  >&times;<\/button>\r\n\t\t  <div class=\"ag-modal-loading\">\r\n\t\t\t<div class=\"ag-spinner\"><\/div>\r\n\t\t  <\/div>\r\n\t\t  <iframe\r\n\t\t\tallow=\"autoplay; fullscreen; picture-in-picture\"\r\n\t\t\tallowfullscreen\r\n\t\t\ttitle=\"${strings.player}\"\r\n\t\t  ><\/iframe>\r\n\t\t<\/div>\r\n\t  `;\r\n\r\n\t  document.body.appendChild(modal);\r\n\t  document.body.classList.add('ag-modal-open');\r\n\r\n\t  \/\/ L'iframe di preload nascosto non serve pi\u00f9: la modale reale prende il suo posto.\r\n\t  GelpiPreload.clear();\r\n\r\n\t  const openTime = Date.now();\r\n\r\n\t  const iframe  = modal.querySelector('iframe');\r\n\t  const loading = modal.querySelector('.ag-modal-loading');\r\n\t  const removeSpinner = () => { if (loading?.parentNode) loading.remove(); };\r\n\t  iframe.addEventListener('load', removeSpinner);\r\n\t  setTimeout(removeSpinner, 3000);\r\n\t  iframe.src = embedUrl;\r\n\r\n\t  this._setupClose(modal, openTime);\r\n\t  setTimeout(() => modal.querySelector('.ag-modal-close').focus(), 100);\r\n\t},\r\n\r\n    close(modal) {\r\n      const iframe = modal.querySelector('iframe');\r\n      if (iframe) iframe.src = '';\r\n\r\n      modal.style.animation = 'agFadeIn 0.2s ease reverse';\r\n      setTimeout(() => {\r\n        if (modal.parentNode) modal.parentNode.removeChild(modal);\r\n        document.body.classList.remove('ag-modal-open');\r\n      }, 200);\r\n    },\r\n\r\n\t_setupClose(modal, openTime) {\r\n\t  modal.querySelector('.ag-modal-close')\r\n\t\t.addEventListener('click', () => this.close(modal));\r\n\r\n\t  modal.addEventListener('click', (e) => {\r\n\t\tif (Date.now() - openTime < 400) return;\r\n\t\tif (e.target === modal) this.close(modal);\r\n\t  });\r\n\r\n\t  const escHandler = (e) => {\r\n\t\tif (e.key === 'Escape') {\r\n\t\t  this.close(modal);\r\n\t\t  document.removeEventListener('keydown', escHandler);\r\n\t\t}\r\n\t  };\r\n\t  document.addEventListener('keydown', escHandler);\r\n\t},\r\n\r\n    extractVimeoId(url) {\r\n      if (!url) return null;\r\n      if (\/^\\d+$\/.test(url)) return url;\r\n      const m = url.match(\/(?:vimeo\\.com\\\/(?:video\\\/)?|player\\.vimeo\\.com\\\/video\\\/)(\\d+)\/);\r\n      return m ? m[1] : null;\r\n    }\r\n  };\r\n\r\n  \/\/ ===== PRELOAD SU HOVER =====\r\n  \/\/ Scalda il player Vimeo durante l'hover, prima del click, cos\u00ec quando\r\n  \/\/ arriva il click parte del bootstrap del player \u00e8 gi\u00e0 avvenuto.\r\n  \/\/ Un solo iframe nascosto alla volta: l'hover pi\u00f9 recente sostituisce il precedente.\r\n  const GelpiPreload = {\r\n    activeFrame: null,\r\n    timer: null,\r\n\r\n    warm(vimeoUrl, immediate = false) {\r\n      clearTimeout(this.timer);\r\n\r\n      const start = () => {\r\n        const videoId = GelpiModal.extractVimeoId(vimeoUrl);\r\n        if (!videoId) return;\r\n        this.clear();\r\n        const frame = document.createElement('iframe');\r\n        frame.style.cssText = 'position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;border:0;';\r\n        frame.setAttribute('aria-hidden', 'true');\r\n        frame.tabIndex = -1;\r\n        \/\/ muted=1 e autoplay=1: fa partire davvero il buffering, non solo il bootstrap del player.\r\n        \/\/ Se preferisci scaldare solo la connessione senza consumare banda ad ogni hover,\r\n        \/\/ sostituisci con: ?dnt=1&autoplay=0\r\n        frame.src = `https:\/\/player.vimeo.com\/video\/${videoId}?dnt=1&autoplay=1&muted=1&background=1`;\r\n        document.body.appendChild(frame);\r\n        this.activeFrame = frame;\r\n      };\r\n\r\n      \/\/ immediate=true: usato dal preload proattivo all'avvio pagina, salta il debounce dell'hover\r\n      if (immediate) {\r\n        start();\r\n        return;\r\n      }\r\n      this.timer = setTimeout(start, CONFIG.preloadHoverDelay);\r\n    },\r\n\r\n    cancel() {\r\n      clearTimeout(this.timer);\r\n    },\r\n\r\n    clear() {\r\n      if (this.activeFrame) {\r\n        this.activeFrame.remove();\r\n        this.activeFrame = null;\r\n      }\r\n    }\r\n  };\r\n\r\n  \/\/ ===== PRELOAD PROATTIVO ALL'AVVIO =====\r\n  \/\/ La lentezza al primissimo utilizzo (~10s) \u00e8 quasi interamente il costo one-time\r\n  \/\/ di scaricare e inizializzare l'app del player Vimeo (JS, font, interfaccia),\r\n  \/\/ non il video specifico: una volta pagato, ogni video successivo parte veloce.\r\n  \/\/ Il preload su hover arriva troppo tardi nell'uso reale perch\u00e9 l'utente clicca\r\n  \/\/ prima che quei secondi bastino. Scaldando UN video durante l'idle time dopo il\r\n  \/\/ caricamento pagina, quel costo si consuma mentre l'utente sta ancora leggendo.\r\n  function warmPlayerOnIdle() {\r\n    if (!CONFIG.proactivePreload || window.GelpiGallery.playerWarmed) return;\r\n\r\n    \/\/ Rispetta connessioni lente o Data Saver: non forzare download extra\r\n    \/\/ a chi ha gi\u00e0 banda limitata.\r\n    const conn = navigator.connection || navigator.webkitConnection;\r\n    if (conn && (conn.saveData || \/2g\/.test(conn.effectiveType || ''))) return;\r\n\r\n    const firstVideoImg = document.querySelector('.scrolling-gallery .image-wrapper img[data-vimeo]');\r\n    if (!firstVideoImg) return;\r\n\r\n    window.GelpiGallery.playerWarmed = true;\r\n    const run = () => GelpiPreload.warm(firstVideoImg.getAttribute('data-vimeo'), true);\r\n\r\n    if ('requestIdleCallback' in window) {\r\n      requestIdleCallback(run, { timeout: 4000 });\r\n    } else {\r\n      setTimeout(run, 2500);\r\n    }\r\n  }\r\n\r\n  \/\/ ===== SCROLLING GALLERY =====\r\n  class ScrollingGallery {\r\n    constructor(galleryElement, instanceId) {\r\n      this.gallery = galleryElement;\r\n      this.instanceId = instanceId;\r\n      this.row = this.gallery.querySelector('.scrolling-row');\r\n      this.loopWidth = 0;\r\n\r\n      this.dragState = {\r\n        active: false,\r\n        direction: null,\r\n        startX: 0,\r\n        startY: 0,\r\n        currentX: 0,\r\n        translateX: 0,\r\n        hasMoved: false,\r\n        startTarget: null\r\n      };\r\n\r\n      this.animationState = {\r\n        isAnimating: true,\r\n        isPaused: false,\r\n        currentPosition: 0,\r\n        animationFrame: null,\r\n        speed: 0,\r\n        lastTime: null\r\n      };\r\n\r\n      this.activeAnimations = new Map();\r\n      this.boundHandlers = {};\r\n      this.init();\r\n    }\r\n\r\n    init() {\r\n      this.setupInfiniteLoop();\r\n      this.calculateInitialSpeed();\r\n      this.attachDragEvents();\r\n      this.attachWrapperEvents();\r\n\t  this.prefillTextForTouch();\r\n      this.attachHoverPauseEvents();\r\n      this.attachVisibilityHandler();\r\n      this.startManualAnimation();\r\n      console.log(`[GelpiGallery] Istanza #${this.instanceId} inizializzata \u2014 loopWidth: ${this.loopWidth}px`);\r\n    }\r\n\r\n    \/\/ ===== AUTO-CLONE LOOP INFINITO =====\r\n    setupInfiniteLoop() {\r\n      const originalItems = Array.from(this.row.children);\r\n      if (originalItems.length === 0) return;\r\n\r\n      let originalWidth = 0;\r\n      originalItems.forEach(item => {\r\n        const style = getComputedStyle(item);\r\n        originalWidth += item.offsetWidth + parseFloat(style.marginRight || 0);\r\n      });\r\n      this.loopWidth = originalWidth;\r\n\r\n      const containerWidth = this.gallery.offsetWidth;\r\n      const minTotalWidth = containerWidth * 3;\r\n      const copiesNeeded = Math.ceil(minTotalWidth \/ originalWidth) + 1;\r\n\r\n      for (let i = 0; i < copiesNeeded; i++) {\r\n        originalItems.forEach(item => {\r\n\t\tconst clone = item.cloneNode(true);\r\n\t\tclone.setAttribute('aria-hidden', 'true');\r\n\t\tclone.removeAttribute('tabindex');\r\n\t\tScrollingGallery.prepareTextEl(clone.querySelector('.hover-text'));\r\n\t\tthis.row.appendChild(clone);\r\n        });\r\n      }\r\n    }\r\n\r\n    calculateInitialSpeed() {\r\n      const durationStr = this.row.style.animationDuration ||\r\n                          getComputedStyle(this.row).animationDuration;\r\n      const duration = parseFloat(durationStr) || 70;\r\n      const direction = this.row.classList.contains('scroll-left') ? -1 : 1;\r\n      this.animationState.speed = (this.loopWidth \/ duration) * direction;\r\n    }\r\n\r\n    startManualAnimation() {\r\n      const animate = (currentTime) => {\r\n        if (!this.animationState.isAnimating) return;\r\n\r\n        if (this.animationState.lastTime === null) {\r\n          this.animationState.lastTime = currentTime;\r\n        }\r\n        const delta = (currentTime - this.animationState.lastTime) \/ 1000;\r\n        this.animationState.lastTime = currentTime;\r\n\r\n        if (!this.animationState.isPaused && !this.dragState.active) {\r\n          this.animationState.currentPosition += this.animationState.speed * delta;\r\n\r\n          if (this.animationState.speed < 0) {\r\n            if (this.animationState.currentPosition <= -this.loopWidth) {\r\n              this.animationState.currentPosition += this.loopWidth;\r\n            }\r\n          } else {\r\n            if (this.animationState.currentPosition >= 0) {\r\n              this.animationState.currentPosition -= this.loopWidth;\r\n            }\r\n          }\r\n\r\n          this.row.style.transform = `translate3d(${this.animationState.currentPosition}px, 0, 0)`;\r\n        }\r\n\r\n        this.animationState.animationFrame = requestAnimationFrame(animate);\r\n      };\r\n\r\n      this.animationState.animationFrame = requestAnimationFrame(animate);\r\n    }\r\n\r\n    stopManualAnimation() {\r\n      this.animationState.isAnimating = false;\r\n      if (this.animationState.animationFrame) {\r\n        cancelAnimationFrame(this.animationState.animationFrame);\r\n        this.animationState.animationFrame = null;\r\n      }\r\n    }\r\n\r\n    normalizePosition() {\r\n      if (this.animationState.speed < 0) {\r\n        while (this.animationState.currentPosition > 0)\r\n          this.animationState.currentPosition -= this.loopWidth;\r\n        while (this.animationState.currentPosition < -this.loopWidth)\r\n          this.animationState.currentPosition += this.loopWidth;\r\n      } else {\r\n        while (this.animationState.currentPosition < -this.loopWidth)\r\n          this.animationState.currentPosition += this.loopWidth;\r\n        while (this.animationState.currentPosition > 0)\r\n          this.animationState.currentPosition -= this.loopWidth;\r\n      }\r\n    }\r\n\r\n    \/\/ ===== DRAG \/ TOUCH =====\r\n    attachDragEvents() {\r\n      this.boundHandlers.mouseMove = this.onMouseMove.bind(this);\r\n      this.boundHandlers.mouseUp   = this.onMouseUp.bind(this);\r\n      this.boundHandlers.touchMove = this.onTouchMove.bind(this);\r\n      this.boundHandlers.touchEnd  = this.onTouchEnd.bind(this);\r\n\r\n      this.gallery.addEventListener('mousedown', (e) => this.onMouseDown(e));\r\n      this.gallery.addEventListener('mouseleave', (e) => {\r\n        if (this.dragState.active) this.onMouseUp(e);\r\n      });\r\n\r\n      this.gallery.addEventListener('touchstart', (e) => this.onTouchStart(e), { passive: false });\r\n    }\r\n\r\n    onMouseDown(e) {\r\n      if (e.target.closest('a, button')) return;\r\n      e.preventDefault();\r\n\r\n      this.dragState.active      = true;\r\n      this.dragState.direction   = 'horizontal';\r\n      this.dragState.startX      = e.pageX;\r\n      this.dragState.currentX    = e.pageX;\r\n      this.dragState.hasMoved    = false;\r\n      this.dragState.startTarget = e.target;\r\n      this.dragState.translateX  = this.animationState.currentPosition;\r\n\r\n      this.gallery.classList.add('is-dragging');\r\n      document.addEventListener('mousemove', this.boundHandlers.mouseMove);\r\n      document.addEventListener('mouseup',   this.boundHandlers.mouseUp);\r\n    }\r\n\r\n    onMouseMove(e) {\r\n      if (!this.dragState.active) return;\r\n      e.preventDefault();\r\n\r\n      const delta = (e.pageX - this.dragState.currentX) * CONFIG.dragSensitivity;\r\n      this.dragState.currentX    = e.pageX;\r\n      this.dragState.translateX += delta;\r\n\r\n      if (Math.abs(e.pageX - this.dragState.startX) > CONFIG.directionThreshold) {\r\n        this.dragState.hasMoved = true;\r\n      }\r\n\r\n      this.row.style.transform = `translate3d(${this.dragState.translateX}px, 0, 0)`;\r\n    }\r\n\r\n    onMouseUp(e) {\r\n      if (!this.dragState.active) return;\r\n      this.dragState.active = false;\r\n      this.gallery.classList.remove('is-dragging');\r\n\r\n      document.removeEventListener('mousemove', this.boundHandlers.mouseMove);\r\n      document.removeEventListener('mouseup',   this.boundHandlers.mouseUp);\r\n\r\n      if (!this.dragState.hasMoved && this.dragState.startTarget) {\r\n        this._openFromTarget(this.dragState.startTarget);\r\n      }\r\n\r\n      if (this.dragState.hasMoved) {\r\n        this.animationState.currentPosition = this.dragState.translateX;\r\n        this.normalizePosition();\r\n        this.animationState.lastTime = null;\r\n      }\r\n\r\n      this.dragState.startTarget = null;\r\n      if (!this.gallery.matches(':hover')) {\r\n        this.animationState.isPaused = false;\r\n      }\r\n    }\r\n\r\n    onTouchStart(e) {\r\n      if (e.touches.length !== 1) return;\r\n      const t = e.touches[0];\r\n\r\n      this.dragState.active      = false;\r\n      this.dragState.direction   = null;\r\n      this.dragState.startX      = t.pageX;\r\n      this.dragState.startY      = t.pageY;\r\n      this.dragState.currentX    = t.pageX;\r\n      this.dragState.hasMoved    = false;\r\n      this.dragState.startTarget = e.target;\r\n      this.dragState.translateX  = this.animationState.currentPosition;\r\n\r\n      document.addEventListener('touchmove',   this.boundHandlers.touchMove,  { passive: false });\r\n      document.addEventListener('touchend',    this.boundHandlers.touchEnd,   { passive: true });\r\n      document.addEventListener('touchcancel', this.boundHandlers.touchEnd,   { passive: true });\r\n    }\r\n\r\n\tonTouchMove(e) {\r\n\t  if (e.touches.length !== 1) return;\r\n\t  const t = e.touches[0];\r\n\t  const absX = Math.abs(t.pageX - this.dragState.startX);\r\n\t  const absY = Math.abs(t.pageY - this.dragState.startY);\r\n\t  if (this.dragState.direction === null) {\r\n\t\tif (absX < CONFIG.directionThreshold && absY < CONFIG.directionThreshold) return;\r\n\t\tthis.dragState.direction = absX >= absY ? 'horizontal' : 'vertical';\r\n\t  }\r\n\t  if (absX > CONFIG.directionThreshold || absY > CONFIG.directionThreshold) {\r\n\t\tthis.dragState.hasMoved = true;\r\n\t  }\r\n\t  if (this.dragState.direction === 'vertical') return;\r\n\t  e.preventDefault();\r\n\t  if (!this.dragState.active) {\r\n\t\tthis.dragState.active = true;\r\n\t\tthis.gallery.classList.add('is-dragging');\r\n\t\tthis.animationState.isPaused = true;\r\n\t  }\r\n\t  const delta = (t.pageX - this.dragState.currentX) * CONFIG.dragSensitivity;\r\n\t  this.dragState.currentX    = t.pageX;\r\n\t  this.dragState.translateX += delta;\r\n\t  this.dragState.hasMoved    = true;\r\n\t  this.row.style.transform = `translate3d(${this.dragState.translateX}px, 0, 0)`;\r\n\t}\r\n\r\n    onTouchEnd(e) {\r\n      document.removeEventListener('touchmove',   this.boundHandlers.touchMove);\r\n      document.removeEventListener('touchend',    this.boundHandlers.touchEnd);\r\n      document.removeEventListener('touchcancel', this.boundHandlers.touchEnd);\r\n\r\n      if (!this.dragState.hasMoved && this.dragState.startTarget) {\r\n        this._openFromTarget(this.dragState.startTarget);\r\n      }\r\n\r\n      if (this.dragState.active) {\r\n        this.gallery.classList.remove('is-dragging');\r\n\r\n        if (this.dragState.hasMoved) {\r\n          this.animationState.currentPosition = this.dragState.translateX;\r\n          this.normalizePosition();\r\n          this.animationState.lastTime = null;\r\n        }\r\n      }\r\n\r\n      this.dragState.active      = false;\r\n      this.dragState.direction   = null;\r\n      this.dragState.startTarget = null;\r\n      this.animationState.isPaused = false;\r\n    }\r\n\r\n    _openFromTarget(target) {\r\n      const wrapper = target.closest('.image-wrapper');\r\n      if (!wrapper) return;\r\n      const vimeoUrl = wrapper.querySelector('img')?.getAttribute('data-vimeo');\r\n      if (vimeoUrl) GelpiModal.open(vimeoUrl);\r\n    }\r\n\r\n    \/\/ ===== HOVER PAUSE =====\r\n    attachHoverPauseEvents() {\r\n      this.gallery.addEventListener('mouseenter', () => {\r\n        if (!this.dragState.active) this.animationState.isPaused = true;\r\n      }, { passive: true });\r\n\r\n      this.gallery.addEventListener('mouseleave', () => {\r\n        if (!this.dragState.active) {\r\n          this.animationState.isPaused = false;\r\n          this.animationState.lastTime = null;\r\n        }\r\n      }, { passive: true });\r\n    }\r\n\r\n    \/\/ ===== TESTO DECRYPT + PRELOAD SU HOVER =====\r\n\tattachWrapperEvents() {\r\n\t  const allWrappers = Array.from(this.row.querySelectorAll('.image-wrapper'));\r\n\r\n\t  allWrappers.forEach(wrapper => {\r\n\t\tconst textEl = wrapper.querySelector('.hover-text');\r\n\t\tconst vimeoUrl = wrapper.querySelector('img')?.getAttribute('data-vimeo');\r\n\r\n\t\tconst debouncedEnter = debounce(() => {\r\n\t\t  if (!this.dragState.active) {\r\n\t\t\tthis.activeAnimations.set(wrapper, this.initializeAndAnimateText(textEl));\r\n\t\t\tif (vimeoUrl) GelpiPreload.warm(vimeoUrl);\r\n\t\t  }\r\n\t\t}, CONFIG.hoverDebounce);\r\n\r\n\t\twrapper.addEventListener('mouseenter', debouncedEnter, { passive: true });\r\n\t\twrapper.addEventListener('mouseleave', () => {\r\n\t\t  this.activeAnimations.delete(wrapper);\r\n\t\t  this.resetText(textEl);\r\n\t\t  GelpiPreload.cancel();\r\n\t\t}, { passive: true });\r\n\r\n\t\tif (!wrapper.hasAttribute('aria-hidden')) {\r\n\t\t  wrapper.addEventListener('keydown', (e) => {\r\n\t\t\tif (e.key === 'Enter' || e.key === ' ') {\r\n\t\t\t  e.preventDefault();\r\n\t\t\t  this._openFromTarget(wrapper);\r\n\t\t\t}\r\n\t\t  });\r\n\t\t}\r\n\t  });\r\n\t}\r\n\r\n    \/\/ Cancella timer pendenti prima di ricostruire il testo: evita che\r\n    \/\/ hover ripetuti rapidi accumulino setInterval orfani su nodi staccati.\r\n    cancelPendingAnimation(textEl) {\r\n      (textEl._trpTimeouts  || []).forEach(id => clearTimeout(id));\r\n      (textEl._trpIntervals || []).forEach(id => clearInterval(id));\r\n      textEl._trpTimeouts  = [];\r\n      textEl._trpIntervals = [];\r\n    }\r\n\r\n    initializeAndAnimateText(textEl) {\r\n      const text = getWrapperText(textEl);\r\n      const lettersEl = getLettersContainer(textEl);\r\n      if (!text || !lettersEl) return;\r\n\r\n      this.cancelPendingAnimation(textEl);\r\n\r\n      lettersEl.innerHTML = text.split('').map(c =>\r\n        c === ' ' ? `<span class=\"letter\">&nbsp;<\/span>` : `<span class=\"letter\"><\/span>`\r\n      ).join('');\r\n\r\n      const nonSpaceIndices = [];\r\n      text.split('').forEach((c, i) => { if (c !== ' ') nonSpaceIndices.push(i); });\r\n      const shuffled = nonSpaceIndices.sort(() => Math.random() - 0.5);\r\n      const letterEls = lettersEl.querySelectorAll('.letter');\r\n      const animations = shuffled.map((origIdx, pos) => {\r\n        const duration = CONFIG.minDecryptDuration +\r\n          Math.random() * (CONFIG.maxDecryptDuration - CONFIG.minDecryptDuration);\r\n        return this.decryptLetter(letterEls[origIdx], text[origIdx], pos * 50, duration, textEl);\r\n      });\r\n      return Promise.all(animations);\r\n    }\r\n\r\n    decryptLetter(el, target, delay, duration, textEl) {\r\n      return new Promise(resolve => {\r\n        const timeoutId = setTimeout(() => {\r\n          const end = Date.now() + duration;\r\n          const iv = setInterval(() => {\r\n            if (Date.now() >= end || el.textContent === target) {\r\n              el.textContent = target;\r\n              clearInterval(iv);\r\n              resolve();\r\n            } else {\r\n              el.textContent = target === ' '\r\n                ? '\\u00A0'\r\n                : CHARS[Math.floor(Math.random() * CHARS.length)];\r\n            }\r\n          }, CONFIG.decryptFrameRate);\r\n          if (textEl._trpIntervals) textEl._trpIntervals.push(iv);\r\n        }, delay);\r\n        if (textEl._trpTimeouts) textEl._trpTimeouts.push(timeoutId);\r\n      });\r\n    }\r\n\r\n    resetText(textEl) {\r\n      this.cancelPendingAnimation(textEl);\r\n      const text = getWrapperText(textEl);\r\n      const lettersEl = getLettersContainer(textEl);\r\n      if (!text || !lettersEl) return;\r\n      lettersEl.innerHTML = text.split('').map(c =>\r\n        c === ' ' ? `<span class=\"letter\">&nbsp;<\/span>` : `<span class=\"letter\"><\/span>`\r\n      ).join('');\r\n    }\r\n\r\n\tprefillTextForTouch() {\r\n\t  if (window.innerWidth > 1024) return;\r\n\t  Array.from(this.row.querySelectorAll('.image-wrapper')).forEach(wrapper => {\r\n\t\tconst textEl = wrapper.querySelector('.hover-text');\r\n\t\tif (!textEl) return;\r\n\t\tconst text = getWrapperText(textEl);\r\n\t\tconst lettersEl = getLettersContainer(textEl);\r\n\t\tif (!text || !lettersEl) return;\r\n\t\tlettersEl.innerHTML = text.split('').map(c =>\r\n\t\t  c === ' ' ? `<span class=\"letter\">&nbsp;<\/span>` : `<span class=\"letter\">${c}<\/span>`\r\n\t\t).join('');\r\n\t  });\r\n\t}\r\n\r\n\tstatic prepareTextEl(textEl) {\r\n\t  if (!textEl) return;\r\n\t  const text = getWrapperText(textEl);\r\n\t  const lettersEl = getLettersContainer(textEl);\r\n\t  if (!text || !lettersEl) return;\r\n\t  lettersEl.innerHTML = text.split('').map(c =>\r\n\t\tc === ' ' ? `<span class=\"letter\">&nbsp;<\/span>` : `<span class=\"letter\"><\/span>`\r\n\t  ).join('');\r\n\t}\r\n\r\n    \/\/ ===== VISIBILITY =====\r\n    attachVisibilityHandler() {\r\n      const handler = () => {\r\n        if (!this.dragState.active) {\r\n          this.animationState.isPaused = document.hidden;\r\n          if (!document.hidden) this.animationState.lastTime = null;\r\n        }\r\n      };\r\n      document.addEventListener('visibilitychange', handler);\r\n      this.boundHandlers.visibilityHandler = handler;\r\n    }\r\n\r\n    \/\/ ===== CLEANUP =====\r\n    destroy() {\r\n      document.removeEventListener('mousemove',        this.boundHandlers.mouseMove);\r\n      document.removeEventListener('mouseup',          this.boundHandlers.mouseUp);\r\n      document.removeEventListener('touchmove',        this.boundHandlers.touchMove);\r\n      document.removeEventListener('touchend',         this.boundHandlers.touchEnd);\r\n      document.removeEventListener('touchcancel',      this.boundHandlers.touchEnd);\r\n      document.removeEventListener('visibilitychange', this.boundHandlers.visibilityHandler);\r\n      this.stopManualAnimation();\r\n      this.activeAnimations.clear();\r\n      console.log(`[GelpiGallery] Istanza #${this.instanceId} distrutta`);\r\n    }\r\n  }\r\n\r\n  \/\/ ===== INIZIALIZZAZIONE =====\r\n  function initializeGalleries() {\r\n    if (window.GelpiGallery.initialized) {\r\n      console.warn('[GelpiGallery] Gi\u00e0 inizializzato, skip');\r\n      return;\r\n    }\r\n\r\n    const galleries = document.querySelectorAll('.scrolling-gallery');\r\n    if (galleries.length === 0) {\r\n      console.warn('[GelpiGallery] Nessuna gallery trovata');\r\n      return;\r\n    }\r\n\r\n    galleries.forEach((g, i) => {\r\n      window.GelpiGallery.instances.push(new ScrollingGallery(g, i + 1));\r\n    });\r\n\r\n    window.GelpiGallery.initialized = true;\r\n    console.log(`[GelpiGallery] ${galleries.length} gallery inizializzate`);\r\n\r\n    warmPlayerOnIdle();\r\n  }\r\n\r\n  if (document.readyState === 'loading') {\r\n    document.addEventListener('DOMContentLoaded', initializeGalleries);\r\n  } else {\r\n    initializeGalleries();\r\n  }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d95715f animated-slow elementor-invisible elementor-widget elementor-widget-html\" data-id=\"d95715f\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    .scrolling-logos-container {\r\n        width: 100%;\r\n        overflow: hidden;\r\n        position: relative;\r\n        background: #000;\r\n        display: flex;\r\n        align-items: center;\r\n    }\r\n\r\n    .scrolling-logos-wrapper {\r\n        display: flex;\r\n        align-items: center;\r\n        will-change: transform;\r\n    }\r\n\r\n    .scrolling-logos-wrapper img {\r\n        display: block;\r\n        height: auto;\r\n        flex-shrink: 0;\r\n        user-select: none;\r\n        -webkit-user-drag: none;\r\n        pointer-events: none;\r\n    }\r\n\r\n    @keyframes scroll-left {\r\n        from { transform: translateX(0); }\r\n        to   { transform: translateX(-50%); }\r\n    }\r\n\r\n    @keyframes scroll-right {\r\n        from { transform: translateX(-50%); }\r\n        to   { transform: translateX(0); }\r\n    }\r\n\r\n    .scroll-left  { animation: scroll-left  var(--scroll-speed) linear infinite; }\r\n    .scroll-right { animation: scroll-right var(--scroll-speed) linear infinite; }\r\n<\/style>\r\n\r\n<div class=\"scrolling-logos-container\">\r\n    <div class=\"scrolling-logos-wrapper\"><\/div>\r\n<\/div>\r\n\r\n<script>\r\n(function() {\r\n    'use strict';\r\n\r\n    \/\/ ========================================\r\n    \/\/ \u2699\ufe0f PARAMETRI DI CONFIGURAZIONE\r\n    \/\/ ========================================\r\n    const CONFIG = {\r\n        imageUrl:    'https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/clients_01.jpg',\r\n        direction:   'right',\r\n        opacity:     1,\r\n        speed:       400,\r\n        imageHeight: 50\r\n    };\r\n\r\n    \/\/ ========================================\r\n    \/\/ TROVA IL PROPRIO CONTAINER (multi-instance safe)\r\n    \/\/ ========================================\r\n    const currentScript = document.currentScript;\r\n    if (!currentScript) return;\r\n\r\n    const container = currentScript.previousElementSibling;\r\n    if (!container || !container.classList.contains('scrolling-logos-container')) return;\r\n\r\n    const wrapper = container.querySelector('.scrolling-logos-wrapper');\r\n    if (!wrapper) return;\r\n\r\n    \/\/ ========================================\r\n    \/\/ VARIABILI\r\n    \/\/ ========================================\r\n    let imageCache  = null;\r\n    let isLoading   = false;\r\n    let resizeTimer = null;\r\n\r\n    \/\/ ========================================\r\n    \/\/ RENDER\r\n    \/\/ ========================================\r\n    function render(imgData) {\r\n        const scale       = CONFIG.imageHeight \/ imgData.naturalHeight;\r\n        const scaledWidth = Math.round(imgData.naturalWidth * scale);\r\n\r\n        container.style.height = CONFIG.imageHeight + 'px';\r\n\r\n        const containerWidth = container.offsetWidth || window.innerWidth || 1200;\r\n\r\n        \/\/ Quante immagini servono per coprire il container (un \"set\")\r\n        \/\/ Il wrapper contiene 2 set identici \u2192 translateX(-50%) = loop seamless\r\n        const perSet     = Math.max(Math.ceil(containerWidth \/ scaledWidth) + 1, 2);\r\n        const totalImgs  = perSet * 2;\r\n\r\n        wrapper.innerHTML = '';\r\n\r\n        const fragment = document.createDocumentFragment();\r\n        for (let i = 0; i < totalImgs; i++) {\r\n            const img    = document.createElement('img');\r\n            img.src      = CONFIG.imageUrl;\r\n            img.alt      = '';\r\n            img.width    = scaledWidth;\r\n            img.height   = CONFIG.imageHeight;\r\n            img.style.opacity = CONFIG.opacity;\r\n            img.draggable    = false;\r\n            fragment.appendChild(img);\r\n        }\r\n        wrapper.appendChild(fragment);\r\n\r\n        \/\/ Riavvia animazione (force reflow)\r\n        wrapper.className = 'scrolling-logos-wrapper';\r\n        wrapper.offsetHeight; \/\/ reflow\r\n        wrapper.style.setProperty('--scroll-speed', CONFIG.speed + 's');\r\n        wrapper.classList.add('scroll-' + CONFIG.direction);\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ LOAD IMMAGINE + CACHE\r\n    \/\/ ========================================\r\n    function loadAndRender() {\r\n        if (isLoading) return;\r\n        isLoading = true;\r\n\r\n        if (imageCache) {\r\n            render(imageCache);\r\n            isLoading = false;\r\n            return;\r\n        }\r\n\r\n        const testImg = new Image();\r\n        const timeout = setTimeout(() => { isLoading = false; }, 3000);\r\n\r\n        testImg.onload = () => {\r\n            clearTimeout(timeout);\r\n            imageCache = {\r\n                naturalWidth:  testImg.naturalWidth,\r\n                naturalHeight: testImg.naturalHeight\r\n            };\r\n            render(imageCache);\r\n            isLoading = false;\r\n        };\r\n\r\n        testImg.onerror = () => {\r\n            clearTimeout(timeout);\r\n            isLoading = false;\r\n        };\r\n\r\n        testImg.src = CONFIG.imageUrl;\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ RESIZE \u2014 ResizeObserver (pi\u00f9 preciso di window resize)\r\n    \/\/ ========================================\r\n    if (typeof ResizeObserver !== 'undefined') {\r\n        const ro = new ResizeObserver(() => {\r\n            if (!imageCache) return;\r\n            clearTimeout(resizeTimer);\r\n            resizeTimer = setTimeout(() => render(imageCache), 300);\r\n        });\r\n        ro.observe(container);\r\n    } else {\r\n        \/\/ Fallback per browser vecchi\r\n        window.addEventListener('resize', function() {\r\n            if (!imageCache) return;\r\n            clearTimeout(resizeTimer);\r\n            resizeTimer = setTimeout(() => render(imageCache), 500);\r\n        }, { passive: true });\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ START\r\n    \/\/ ========================================\r\n    if (document.readyState === 'loading') {\r\n        document.addEventListener('DOMContentLoaded', loadAndRender);\r\n    } else {\r\n        loadAndRender();\r\n    }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e069d4a animated-slow elementor-invisible elementor-widget elementor-widget-html\" data-id=\"e069d4a\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"scrolling-gallery\">\r\n  <div class=\"scrolling-row scroll-right\" style=\"animation-duration: 70s;\">\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Life\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/Life_thumb-1.jpg\" data-vimeo=\"https:\/\/vimeo.com\/661717295\" alt=\"Life\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">FORUM SPORT CENTER - promo<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Il Romanista\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/LoveIT_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/556274666\" alt=\"Il Romanista\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">IL ROMANISTA - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Shultz\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2026\/06\/Shultz_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/434002230\" alt=\"Shultz\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">SHULTZ Italia - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video PrimaDonna Class\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/PrimaDonna_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/252197817\" alt=\"PrimaDonna\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">DE'LONGHI - commercial<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n  <\/div>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7ad1466 animated-slow elementor-invisible elementor-widget elementor-widget-html\" data-id=\"7ad1466\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    .scrolling-logos-container {\r\n        width: 100%;\r\n        overflow: hidden;\r\n        position: relative;\r\n        background: #000;\r\n        display: flex;\r\n        align-items: center;\r\n    }\r\n\r\n    .scrolling-logos-wrapper {\r\n        display: flex;\r\n        align-items: center;\r\n        will-change: transform;\r\n    }\r\n\r\n    .scrolling-logos-wrapper img {\r\n        display: block;\r\n        height: auto;\r\n        flex-shrink: 0;\r\n        user-select: none;\r\n        -webkit-user-drag: none;\r\n        pointer-events: none;\r\n    }\r\n\r\n    @keyframes scroll-left {\r\n        from { transform: translateX(0); }\r\n        to   { transform: translateX(-50%); }\r\n    }\r\n\r\n    @keyframes scroll-right {\r\n        from { transform: translateX(-50%); }\r\n        to   { transform: translateX(0); }\r\n    }\r\n\r\n    .scroll-left  { animation: scroll-left  var(--scroll-speed) linear infinite; }\r\n    .scroll-right { animation: scroll-right var(--scroll-speed) linear infinite; }\r\n<\/style>\r\n\r\n<div class=\"scrolling-logos-container\">\r\n    <div class=\"scrolling-logos-wrapper\"><\/div>\r\n<\/div>\r\n\r\n<script>\r\n(function() {\r\n    'use strict';\r\n\r\n    \/\/ ========================================\r\n    \/\/ \u2699\ufe0f PARAMETRI DI CONFIGURAZIONE\r\n    \/\/ ========================================\r\n    const CONFIG = {\r\n        imageUrl:    'https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/clients_02.jpg',\r\n        direction:   'right',\r\n        opacity:     1,\r\n        speed:       400,\r\n        imageHeight: 50\r\n    };\r\n\r\n    \/\/ ========================================\r\n    \/\/ TROVA IL PROPRIO CONTAINER (multi-instance safe)\r\n    \/\/ ========================================\r\n    const currentScript = document.currentScript;\r\n    if (!currentScript) return;\r\n\r\n    const container = currentScript.previousElementSibling;\r\n    if (!container || !container.classList.contains('scrolling-logos-container')) return;\r\n\r\n    const wrapper = container.querySelector('.scrolling-logos-wrapper');\r\n    if (!wrapper) return;\r\n\r\n    \/\/ ========================================\r\n    \/\/ VARIABILI\r\n    \/\/ ========================================\r\n    let imageCache  = null;\r\n    let isLoading   = false;\r\n    let resizeTimer = null;\r\n\r\n    \/\/ ========================================\r\n    \/\/ RENDER\r\n    \/\/ ========================================\r\n    function render(imgData) {\r\n        const scale       = CONFIG.imageHeight \/ imgData.naturalHeight;\r\n        const scaledWidth = Math.round(imgData.naturalWidth * scale);\r\n\r\n        container.style.height = CONFIG.imageHeight + 'px';\r\n\r\n        const containerWidth = container.offsetWidth || window.innerWidth || 1200;\r\n        const perSet    = Math.max(Math.ceil(containerWidth \/ scaledWidth) + 1, 2);\r\n        const totalImgs = perSet * 2;\r\n\r\n        wrapper.innerHTML = '';\r\n\r\n        const fragment = document.createDocumentFragment();\r\n        for (let i = 0; i < totalImgs; i++) {\r\n            const img     = document.createElement('img');\r\n            img.src       = CONFIG.imageUrl;\r\n            img.alt       = '';\r\n            img.width     = scaledWidth;\r\n            img.height    = CONFIG.imageHeight;\r\n            img.style.opacity = CONFIG.opacity;\r\n            img.draggable = false;\r\n            fragment.appendChild(img);\r\n        }\r\n        wrapper.appendChild(fragment);\r\n\r\n        wrapper.className = 'scrolling-logos-wrapper';\r\n        wrapper.offsetHeight;\r\n        wrapper.style.setProperty('--scroll-speed', CONFIG.speed + 's');\r\n        wrapper.classList.add('scroll-' + CONFIG.direction);\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ LOAD IMMAGINE + CACHE\r\n    \/\/ ========================================\r\n    function loadAndRender() {\r\n        if (isLoading) return;\r\n        isLoading = true;\r\n\r\n        if (imageCache) {\r\n            render(imageCache);\r\n            isLoading = false;\r\n            return;\r\n        }\r\n\r\n        const testImg = new Image();\r\n        const timeout = setTimeout(() => { isLoading = false; }, 3000);\r\n\r\n        testImg.onload = () => {\r\n            clearTimeout(timeout);\r\n            imageCache = {\r\n                naturalWidth:  testImg.naturalWidth,\r\n                naturalHeight: testImg.naturalHeight\r\n            };\r\n            render(imageCache);\r\n            isLoading = false;\r\n        };\r\n\r\n        testImg.onerror = () => {\r\n            clearTimeout(timeout);\r\n            isLoading = false;\r\n        };\r\n\r\n        testImg.src = CONFIG.imageUrl;\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ RESIZE \u2014 ResizeObserver\r\n    \/\/ ========================================\r\n    if (typeof ResizeObserver !== 'undefined') {\r\n        const ro = new ResizeObserver(() => {\r\n            if (!imageCache) return;\r\n            clearTimeout(resizeTimer);\r\n            resizeTimer = setTimeout(() => render(imageCache), 300);\r\n        });\r\n        ro.observe(container);\r\n    } else {\r\n        window.addEventListener('resize', function() {\r\n            if (!imageCache) return;\r\n            clearTimeout(resizeTimer);\r\n            resizeTimer = setTimeout(() => render(imageCache), 500);\r\n        }, { passive: true });\r\n    }\r\n\r\n    \/\/ ========================================\r\n    \/\/ START\r\n    \/\/ ========================================\r\n    if (document.readyState === 'loading') {\r\n        document.addEventListener('DOMContentLoaded', loadAndRender);\r\n    } else {\r\n        loadAndRender();\r\n    }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2bda907 animated-slow elementor-invisible elementor-widget elementor-widget-html\" data-id=\"2bda907\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeInUp&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"scrolling-gallery\">\r\n  <div class=\"scrolling-row scroll-left\" style=\"animation-duration: 70s;\">\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video My Mime\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/MyMime_thumb-1.jpg\" data-vimeo=\"https:\/\/vimeo.com\/111981845\" alt=\"My Mime\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">H\u00c4AGEN DAZS - spec<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Il Biellese\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/Biellese_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/132824797\" alt=\"Il Biellese\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">BIELLESE MOUNTAINS - promo<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Ravenna Festival\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/Ravenna_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/145770133\" alt=\"Ravenna Festival\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">RAVENNA FESTIVAL - promo<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n    <div class=\"image-wrapper\" tabindex=\"0\" role=\"button\" aria-label=\"Apri video Whispers\">\r\n      <img decoding=\"async\" src=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2022\/01\/Whispers_thumb.jpg\" data-vimeo=\"https:\/\/vimeo.com\/101067647\" alt=\"Whispers\" loading=\"lazy\">\r\n      <span class=\"hover-text\" data-no-dynamic-translation>\r\n        <span class=\"hover-text-source\" aria-hidden=\"true\">WHISPERS - short film<\/span>\r\n        <span class=\"hover-text-letters\" aria-hidden=\"true\"><\/span>\r\n      <\/span>\r\n    <\/div>\r\n\r\n  <\/div>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\n<hr class=\"e-4c2f21c-ccb6852 e-divider-base\" data-interaction-id=\"4c2f21c\"   \/>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>https:\/\/vimeo.com\/670691031 This space is part of my life. stories, projects and the way I shape them. a long journey filled with attempt, struggles, falls, successes, fears and laughter. My goal: crafting emotions. In a film, a documentary, or in a thirty-second commercial. FEATURES SHADOW OF THE WOLF 2020 | thriller drama Nico is a policeman [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"iawp_total_views":160,"footnotes":""},"class_list":["post-8341","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Reel - ALBERTO GELPI<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/albertogelpi.com\/it\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Reel - ALBERTO GELPI\" \/>\n<meta property=\"og:description\" content=\"https:\/\/vimeo.com\/670691031 This space is part of my life. stories, projects and the way I shape them. a long journey filled with attempt, struggles, falls, successes, fears and laughter. My goal: crafting emotions. In a film, a documentary, or in a thirty-second commercial. FEATURES SHADOW OF THE WOLF 2020 | thriller drama Nico is a policeman [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/albertogelpi.com\/it\/\" \/>\n<meta property=\"og:site_name\" content=\"ALBERTO GELPI\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/albertogelpidirector\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-29T23:18:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/\",\"url\":\"https:\\\/\\\/albertogelpi.com\\\/\",\"name\":\"Reel - ALBERTO GELPI\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/SotW3-1-768x322.jpg\",\"datePublished\":\"2026-05-07T10:43:44+00:00\",\"dateModified\":\"2026-08-29T23:18:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/albertogelpi.com\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#primaryimage\",\"url\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/SotW3-1-768x322.jpg\",\"contentUrl\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2025\\\/10\\\/SotW3-1-768x322.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/albertogelpi.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Reel\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#website\",\"url\":\"https:\\\/\\\/albertogelpi.com\\\/\",\"name\":\"ALBERTO GELPI\",\"description\":\"Commercial and Film Director based in Rome - Italy\",\"publisher\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#\\\/schema\\\/person\\\/66be0b84de075dc41595a2f5355b2925\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/albertogelpi.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/#\\\/schema\\\/person\\\/66be0b84de075dc41595a2f5355b2925\",\"name\":\"Alberto Gelpi\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/Alberto_Gelpi_profilo.jpeg\",\"url\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/Alberto_Gelpi_profilo.jpeg\",\"contentUrl\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/Alberto_Gelpi_profilo.jpeg\",\"width\":800,\"height\":1200,\"caption\":\"Alberto Gelpi\"},\"logo\":{\"@id\":\"https:\\\/\\\/albertogelpi.com\\\/wp-content\\\/uploads\\\/2018\\\/10\\\/Alberto_Gelpi_profilo.jpeg\"},\"sameAs\":[\"https:\\\/\\\/albertogelpi.com\",\"https:\\\/\\\/www.facebook.com\\\/albertogelpidirector\",\"https:\\\/\\\/www.instagram.com\\\/albertogelpi\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/albertogelpi\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Reel - ALBERTO GELPI","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/albertogelpi.com\/it\/","og_locale":"it_IT","og_type":"article","og_title":"Reel - ALBERTO GELPI","og_description":"https:\/\/vimeo.com\/670691031 This space is part of my life. stories, projects and the way I shape them. a long journey filled with attempt, struggles, falls, successes, fears and laughter. My goal: crafting emotions. In a film, a documentary, or in a thirty-second commercial. FEATURES SHADOW OF THE WOLF 2020 | thriller drama Nico is a policeman [&hellip;]","og_url":"https:\/\/albertogelpi.com\/it\/","og_site_name":"ALBERTO GELPI","article_publisher":"https:\/\/www.facebook.com\/albertogelpidirector","article_modified_time":"2026-08-29T23:18:01+00:00","og_image":[{"url":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Tempo di lettura stimato":"5 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/albertogelpi.com\/","url":"https:\/\/albertogelpi.com\/","name":"Reel - ALBERTO GELPI","isPartOf":{"@id":"https:\/\/albertogelpi.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/albertogelpi.com\/#primaryimage"},"image":{"@id":"https:\/\/albertogelpi.com\/#primaryimage"},"thumbnailUrl":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg","datePublished":"2026-05-07T10:43:44+00:00","dateModified":"2026-08-29T23:18:01+00:00","breadcrumb":{"@id":"https:\/\/albertogelpi.com\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/albertogelpi.com\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/albertogelpi.com\/#primaryimage","url":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg","contentUrl":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2025\/10\/SotW3-1-768x322.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/albertogelpi.com\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/albertogelpi.com\/"},{"@type":"ListItem","position":2,"name":"Reel"}]},{"@type":"WebSite","@id":"https:\/\/albertogelpi.com\/#website","url":"https:\/\/albertogelpi.com\/","name":"ALBERTO GELPI","description":"Commercial and Film Director based in Rome - Italy","publisher":{"@id":"https:\/\/albertogelpi.com\/#\/schema\/person\/66be0b84de075dc41595a2f5355b2925"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/albertogelpi.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":["Person","Organization"],"@id":"https:\/\/albertogelpi.com\/#\/schema\/person\/66be0b84de075dc41595a2f5355b2925","name":"Alberto Gelpi","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2018\/10\/Alberto_Gelpi_profilo.jpeg","url":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2018\/10\/Alberto_Gelpi_profilo.jpeg","contentUrl":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2018\/10\/Alberto_Gelpi_profilo.jpeg","width":800,"height":1200,"caption":"Alberto Gelpi"},"logo":{"@id":"https:\/\/albertogelpi.com\/wp-content\/uploads\/2018\/10\/Alberto_Gelpi_profilo.jpeg"},"sameAs":["https:\/\/albertogelpi.com","https:\/\/www.facebook.com\/albertogelpidirector","https:\/\/www.instagram.com\/albertogelpi","https:\/\/www.linkedin.com\/in\/albertogelpi"]}]}},"_links":{"self":[{"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/pages\/8341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/comments?post=8341"}],"version-history":[{"count":43,"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/pages\/8341\/revisions"}],"predecessor-version":[{"id":8444,"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/pages\/8341\/revisions\/8444"}],"wp:attachment":[{"href":"https:\/\/albertogelpi.com\/it\/wp-json\/wp\/v2\/media?parent=8341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}