{"id":2098,"date":"2026-05-13T20:09:45","date_gmt":"2026-05-13T20:09:45","guid":{"rendered":"https:\/\/millepiani.com\/nouvelle-page-ascenseurs\/"},"modified":"2026-09-15T22:12:01","modified_gmt":"2026-09-15T22:12:01","slug":"nouvelle-page-ascenseurs","status":"publish","type":"page","link":"https:\/\/millepiani.com\/fr\/","title":{"rendered":"Nouvelle page Ascenseurs"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2098\" class=\"elementor elementor-2098 elementor-219\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3046b07 e-con-full e-flex e-con e-parent\" data-id=\"3046b07\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-148a94c elementor-widget elementor-widget-html\" data-id=\"148a94c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- 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\r\n  href=\"https:\/\/fonts.googleapis.com\/css2?family=Afacad+Flux:wght@100..1000&display=swap\"\r\n  rel=\"stylesheet\"\r\n>\r\n\r\n<div id=\"mp-fullpage-wrapper\">\r\n\r\n  <!-- SLIDE 01: HOME -->\r\n  <section class=\"section mp-slide-section mp-dark-slide active\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/06\/millepiani.jpg');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay mp-overlay-home\"><\/div>\r\n\r\n    <div class=\"mp-content mp-home-content\">\r\n      <p class=\"mp-kicker\">\r\n        NOUS CONCEVONS ET FABRIQUONS\r\n      <\/p>\r\n\r\n      <h1>\r\n        ASCENSEURS, MONTE-CHARGES ET ESCALIERS M\u00c9CANIQUES, POUR UNE MOBILIT\u00c9\r\n        EFFICACE ET S\u00dbRE\r\n      <\/h1>\r\n\r\n      <p class=\"mp-desc\">\r\n        Nous analysons les besoins de chaque type de b\u00e2timent et\r\n        garantissons la solution la plus adapt\u00e9e au client, de la\r\n        conception \u00e0 l\u2019installation finale de l\u2019\u00e9quipement.\r\n      <\/p>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 02: ASCENSORI -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/06\/Experience-copia-1-1.png');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>ASCENSEURS<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Nous concevons et r\u00e9alisons des ascenseurs qui allient design,\r\n        confort et grande fiabilit\u00e9. Des solutions con\u00e7ues pour les\r\n        b\u00e2timents r\u00e9sidentiels, commerciaux et les installations publiques,\r\n        avec une s\u00e9curit\u00e9 maximale, des \u00e9conomies d\u2019\u00e9nergie et une qualit\u00e9\r\n        durable.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/ascenseurs\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 03: PIATTAFORME ELEVATRICI -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/image-7-1.jpg');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>\r\n        PLATES-FORMES<br>\r\n        <span>\u00c9L\u00c9VATRICES<\/span>\r\n      <\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Con\u00e7ues pour une utilisation intuitive et conformes aux\r\n        normes de s\u00e9curit\u00e9, les plates-formes Millepiani peuvent\r\n        \u00eatre command\u00e9es en toute autonomie.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/plateformes-elevatrices\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 04: MONTACARICHI -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/Rectangle_3.png');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>MONTE-CHARGES<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Simple, robuste, s\u00fbr : Hercules est la solution id\u00e9ale\r\n        pour le transport vertical de charges et de personnes.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/monte-charges-et-monte-plats\/\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 05: TAPPETI E SCALE MOBILI -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/image_8.png');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>TROTTOIRS ROULANTS ET ESCALIERS M\u00c9CANIQUES<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Une gamme d\u2019escaliers m\u00e9caniques qui int\u00e8gre des solutions\r\n        de transport vertical et de mobilit\u00e9 automatis\u00e9e dans des\r\n        espaces publics et priv\u00e9s.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/trottoirs-roulants-et-escaliers-mecaniques\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 06: SERVOSCALE -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/image_9.png');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>MONTE-ESCALIERS<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Une solution pratique et s\u00fbre pour se d\u00e9placer confortablement\r\n        entre les \u00e9tages : un nouveau standard de mobilit\u00e9 automatis\u00e9e\r\n        pour les b\u00e2timents modernes.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/monte-escaliers\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 07: MODERNIZZAZIONE ASCENSORI -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/image_10.png');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>MODERNISATION DES INSTALLATIONS<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Un service complet de conseil et de modernisation des installations,\r\n        visant \u00e0 am\u00e9liorer les performances et la s\u00e9curit\u00e9 du\r\n        transport vertical.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/modernisation-des-installations\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 08: PARTI ELETTRICHE -->\r\n  <section class=\"section mp-slide-section mp-dark-slide\">\r\n    <div\r\n      class=\"mp-bg\"\r\n      style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/image-5-1-1-1.jpg');\"\r\n    ><\/div>\r\n\r\n    <div class=\"mp-overlay\"><\/div>\r\n\r\n    <div class=\"mp-content\">\r\n      <h2>PIECES DETACHEES<\/h2>\r\n\r\n      <p class=\"mp-desc\">\r\n        Tableaux et composants \u00e9lectriques polyvalents et peu encombrants,\r\n        con\u00e7us pour simplifier l\u2019installation et am\u00e9liorer la\r\n        mobilit\u00e9 automatis\u00e9e.\r\n      <\/p>\r\n\r\n      <a\r\n        href=\"https:\/\/millepiani.com\/fr\/pieces-detachees\/\"\r\n        class=\"mp-btn\"\r\n      >\r\n        EN SAVOIR PLUS\r\n\r\n        <span>\r\n          <img decoding=\"async\"\r\n            src=\"https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png\"\r\n            alt=\"\"\r\n          >\r\n        <\/span>\r\n      <\/a>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 09: SERVIZI -->\r\n  <section class=\"section mp-slide-section mp-services-section\">\r\n    <div class=\"mp-services-wrap\">\r\n\r\n      <div class=\"mp-services-left\">\r\n        <p class=\"mp-about\">\u00c0 PROPOS DE NOUS<\/p>\r\n\r\n        <h2>\r\n          NOS<br>\r\n          <strong>SERVICES<\/strong>\r\n        <\/h2>\r\n\r\n        <div class=\"mp-tabs\">\r\n          <button\r\n            class=\"mp-tab is-active\"\r\n            type=\"button\"\r\n            data-tab=\"assistenza\"\r\n          >\r\n            ASSISTANCE\r\n          <\/button>\r\n\r\n          <button\r\n            class=\"mp-tab\"\r\n            type=\"button\"\r\n            data-tab=\"manutenzione\"\r\n          >\r\n            MAINTENANCE\r\n          <\/button>\r\n\r\n          <button\r\n            class=\"mp-tab\"\r\n            type=\"button\"\r\n            data-tab=\"agevolazioni\"\r\n          >\r\n            AVANTAGES FISCAUX\r\n          <\/button>\r\n        <\/div>\r\n\r\n        <div class=\"mp-tab-panels\">\r\n          <div\r\n            class=\"mp-tab-panel is-active\"\r\n            data-panel=\"assistenza\"\r\n          >\r\n            Le bon fonctionnement d\u2019une installation offre\r\n            s\u00e9curit\u00e9 et tranquillit\u00e9 aux personnes et garantit\r\n            la libert\u00e9 de mouvement. La rapidit\u00e9 des interventions\r\n            r\u00e9duit au minimum les d\u00e9sagr\u00e9ments et la r\u00e9gularit\u00e9\r\n            des contr\u00f4les permet de maintenir un niveau constant\r\n            de performance de l\u2019installation.\r\n          <\/div>\r\n\r\n          <div\r\n            class=\"mp-tab-panel\"\r\n            data-panel=\"manutenzione\"\r\n          >\r\n            Un service de maintenance programm\u00e9e permet de\r\n            pr\u00e9server au fil du temps l\u2019efficacit\u00e9, la s\u00e9curit\u00e9\r\n            et la fiabilit\u00e9 de l\u2019installation. Nos techniciens\r\n            sp\u00e9cialis\u00e9s effectuent des contr\u00f4les p\u00e9riodiques,\r\n            des v\u00e9rifications fonctionnelles et des interventions\r\n            pr\u00e9ventives.\r\n          <\/div>\r\n\r\n          <div\r\n            class=\"mp-tab-panel\"\r\n            data-panel=\"agevolazioni\"\r\n          >\r\n            Nous proposons un service de conseil d\u00e9di\u00e9 afin\r\n            d\u2019identifier les avantages fiscaux disponibles en cas\r\n            d\u2019installation, de remplacement ou de modernisation\r\n            des \u00e9quipements.\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <a href=\"#preventivo\" class=\"mp-info-btn\">\r\n          DEMANDER DES INFORMATIONS\r\n        <\/a>\r\n      <\/div>\r\n\r\n      <div\r\n        class=\"mp-services-image\"\r\n        style=\"background-image: url('https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/IMG_5885-scaled.jpg');\"\r\n      ><\/div>\r\n\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- SLIDE 10: PREVENTIVO -->\r\n  <section\r\n    class=\"section mp-quote-section mp-quote-compact mp-quote-desktop-stack\"\r\n    id=\"preventivo\"\r\n  >\r\n    <div class=\"mp-quote-bg\"><\/div>\r\n    <div class=\"mp-quote-overlay\"><\/div>\r\n\r\n    <div class=\"mp-quote-inner\">\r\n\r\n      <!-- INFORMAZIONI E CONTATTI -->\r\n      <div class=\"mp-quote-info\">\r\n        <p class=\"mp-quote-kicker\">Contactez-nous<\/p>\r\n\r\n        <h2 class=\"mp-quote-title\">\r\n          Demandez un<br>\r\n          devis<br>\r\n          gratuit\r\n        <\/h2>\r\n\r\n        <p class=\"mp-quote-description\">\r\n          Vous \u00eates int\u00e9ress\u00e9 par nos produits ou recherchez\r\n          une solution personnalis\u00e9e sp\u00e9cialement con\u00e7ue pour\r\n          vous ? Nous vous invitons \u00e0 nous contacter : nous sommes\r\n          \u00e0 votre disposition pour vous conseiller et vous guider\r\n          dans le choix de la solution la mieux adapt\u00e9e \u00e0 vos besoins.\r\n        <\/p>\r\n\r\n        <div class=\"mp-quote-contacts\">\r\n\r\n          <a\r\n            href=\"tel:+390296690901\"\r\n            class=\"mp-quote-contact\"\r\n          >\r\n            <span class=\"mp-quote-contact-icon\">\r\n              <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n                <path\r\n                  d=\"M22 16.92v3a2 2 0 0 1-2.18 2A19.86 19.86 0 0 1 11.19 19 19.5 19.5 0 0 1 5 12.81 19.86 19.86 0 0 1 2.08 4.18 2 2 0 0 1 4.06 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.69a16 16 0 0 0 6.31 6.31l1.23-1.23a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z\"\r\n                ><\/path>\r\n              <\/svg>\r\n            <\/span>\r\n\r\n            <span>\r\n              <strong>T\u00e9l\u00e9phone<\/strong>\r\n              +39 02 96690901\r\n            <\/span>\r\n          <\/a>\r\n\r\n          <a\r\n            href=\"mailto:info@millepiani.com\"\r\n            class=\"mp-quote-contact\"\r\n          >\r\n            <span class=\"mp-quote-contact-icon\">\r\n              <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n                <path\r\n                  d=\"M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z\"\r\n                ><\/path>\r\n                <path d=\"m22 6-10 7L2 6\"><\/path>\r\n              <\/svg>\r\n            <\/span>\r\n\r\n            <span>\r\n              <strong>E-mail<\/strong>\r\n              info@millepiani.com\r\n            <\/span>\r\n          <\/a>\r\n\r\n          <div class=\"mp-quote-contact\">\r\n            <span class=\"mp-quote-contact-icon\">\r\n              <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n                <path\r\n                  d=\"M21 10c0 7-9 12-9 12S3 17 3 10a9 9 0 0 1 18 0z\"\r\n                ><\/path>\r\n                <circle cx=\"12\" cy=\"10\" r=\"3\"><\/circle>\r\n              <\/svg>\r\n            <\/span>\r\n\r\n            <span>\r\n              <strong>Bureau<\/strong>\r\n              Via Della Longura, 21 Misinto MB\r\n            <\/span>\r\n          <\/div>\r\n\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <!-- MODULO PREVENTIVO -->\r\n      <div class=\"mp-quote-form-card\">\r\n        <form\r\n          class=\"mp-quote-form\"\r\n          id=\"mpQuoteForm\"\r\n          enctype=\"multipart\/form-data\"\r\n          data-success-url=\"\/grazie\/\"\r\n          novalidate\r\n        >\r\n          <div\r\n            class=\"mp-form-status\"\r\n            id=\"mpFormStatus\"\r\n            aria-live=\"polite\"\r\n          ><\/div>\r\n\r\n          <!-- DATI PERSONALI E SOCIET\u00c0 -->\r\n          <div class=\"mp-form-grid\">\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"text\"\r\n                name=\"name\"\r\n                id=\"mpName\"\r\n                placeholder=\" \"\r\n                required\r\n                autocomplete=\"given-name\"\r\n              >\r\n              <label for=\"mpName\">Pr\u00e9nom *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"text\"\r\n                name=\"surname\"\r\n                id=\"mpSurname\"\r\n                placeholder=\" \"\r\n                required\r\n                autocomplete=\"family-name\"\r\n              >\r\n              <label for=\"mpSurname\">Nom *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"email\"\r\n                name=\"email\"\r\n                id=\"mpEmail\"\r\n                placeholder=\" \"\r\n                required\r\n                autocomplete=\"email\"\r\n              >\r\n              <label for=\"mpEmail\">E-mail *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"tel\"\r\n                name=\"phone\"\r\n                id=\"mpPhone\"\r\n                placeholder=\" \"\r\n                required\r\n                autocomplete=\"tel\"\r\n              >\r\n              <label for=\"mpPhone\">Num\u00e9ro de t\u00e9l\u00e9phone *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <select name=\"role\" id=\"mpRole\">\r\n                <option value=\"\" selected>S\u00e9lectionnez<\/option>\r\n                <option value=\"progettista\">Concepteur<\/option>\r\n\r\n                <option value=\"impresa_di_costruzioni\">\r\n                  Entreprise de construction\r\n                <\/option>\r\n\r\n                <option value=\"proprietario_edificio\">\r\n                  Propri\u00e9taire du b\u00e2timent\r\n                <\/option>\r\n\r\n                <option value=\"amministratore_edificio\">\r\n                  Gestionnaire du b\u00e2timent\r\n                <\/option>\r\n\r\n                <option value=\"consulente_ascensori\">\r\n                  Consultant en ascenseurs\r\n                <\/option>\r\n\r\n                <option value=\"ente_pubblico\">Organisme public<\/option>\r\n                <option value=\"cerco_lavoro\">Je cherche un emploi<\/option>\r\n\r\n                <option value=\"utente_passeggero\">\r\n                  Usager\/Passager\r\n                <\/option>\r\n\r\n                <option value=\"studente\">\u00c9tudiant<\/option>\r\n                <option value=\"altro\">Autre<\/option>\r\n              <\/select>\r\n\r\n              <label for=\"mpRole\">Quel est votre r\u00f4le ?<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"text\"\r\n                name=\"company\"\r\n                id=\"mpCompany\"\r\n                placeholder=\" \"\r\n                autocomplete=\"organization\"\r\n              >\r\n              <label for=\"mpCompany\">Nom de l\u2019entreprise<\/label>\r\n            <\/div>\r\n\r\n          <\/div>\r\n\r\n          <!-- PAESE, PROVINCIA E CITT\u00c0 -->\r\n          <div class=\"mp-form-grid mp-location-grid\">\r\n\r\n            <div class=\"mp-field\">\r\n              <select\r\n                name=\"country\"\r\n                id=\"mpCountry\"\r\n                required\r\n                autocomplete=\"country-name\"\r\n              >\r\n                <option value=\"Italia\" selected>Italie<\/option>\r\n                <option value=\"Estero\">\u00c9tranger<\/option>\r\n              <\/select>\r\n\r\n              <label for=\"mpCountry\">Pays\/R\u00e9gion *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <select\r\n                name=\"province\"\r\n                id=\"mpProvince\"\r\n                required\r\n                autocomplete=\"address-level2\"\r\n              >\r\n                <option value=\"\" selected disabled>S\u00e9lectionnez<\/option>\r\n\r\n                <option value=\"AG\">Agrigento<\/option>\r\n                <option value=\"AL\">Alessandria<\/option>\r\n                <option value=\"AN\">Ancona<\/option>\r\n                <option value=\"AO\">Aosta<\/option>\r\n                <option value=\"AR\">Arezzo<\/option>\r\n                <option value=\"AP\">Ascoli Piceno<\/option>\r\n                <option value=\"AT\">Asti<\/option>\r\n                <option value=\"AV\">Avellino<\/option>\r\n                <option value=\"BA\">Bari<\/option>\r\n                <option value=\"BT\">Barletta-Andria-Trani<\/option>\r\n                <option value=\"BL\">Belluno<\/option>\r\n                <option value=\"BN\">Benevento<\/option>\r\n                <option value=\"BG\">Bergamo<\/option>\r\n                <option value=\"BI\">Biella<\/option>\r\n                <option value=\"BO\">Bologna<\/option>\r\n                <option value=\"BZ\">Bolzano<\/option>\r\n                <option value=\"BS\">Brescia<\/option>\r\n                <option value=\"BR\">Brindisi<\/option>\r\n                <option value=\"CA\">Cagliari<\/option>\r\n                <option value=\"CL\">Caltanissetta<\/option>\r\n                <option value=\"CB\">Campobasso<\/option>\r\n                <option value=\"CE\">Caserta<\/option>\r\n                <option value=\"CT\">Catania<\/option>\r\n                <option value=\"CZ\">Catanzaro<\/option>\r\n                <option value=\"CH\">Chieti<\/option>\r\n                <option value=\"CO\">Como<\/option>\r\n                <option value=\"CS\">Cosenza<\/option>\r\n                <option value=\"CR\">Cremona<\/option>\r\n                <option value=\"KR\">Crotone<\/option>\r\n                <option value=\"CN\">Cuneo<\/option>\r\n                <option value=\"EN\">Enna<\/option>\r\n                <option value=\"FM\">Fermo<\/option>\r\n                <option value=\"FE\">Ferrara<\/option>\r\n                <option value=\"FI\">Firenze<\/option>\r\n                <option value=\"FG\">Foggia<\/option>\r\n                <option value=\"FC\">Forl\u00ec-Cesena<\/option>\r\n                <option value=\"FR\">Frosinone<\/option>\r\n                <option value=\"GE\">Genova<\/option>\r\n                <option value=\"GO\">Gorizia<\/option>\r\n                <option value=\"GR\">Grosseto<\/option>\r\n                <option value=\"IM\">Imperia<\/option>\r\n                <option value=\"IS\">Isernia<\/option>\r\n                <option value=\"SP\">La Spezia<\/option>\r\n                <option value=\"AQ\">L'Aquila<\/option>\r\n                <option value=\"LT\">Latina<\/option>\r\n                <option value=\"LE\">Lecce<\/option>\r\n                <option value=\"LC\">Lecco<\/option>\r\n                <option value=\"LI\">Livorno<\/option>\r\n                <option value=\"LO\">Lodi<\/option>\r\n                <option value=\"LU\">Lucca<\/option>\r\n                <option value=\"MC\">Macerata<\/option>\r\n                <option value=\"MN\">Mantova<\/option>\r\n                <option value=\"MS\">Massa-Carrara<\/option>\r\n                <option value=\"MT\">Matera<\/option>\r\n                <option value=\"ME\">Messina<\/option>\r\n                <option value=\"MI\">Milano<\/option>\r\n                <option value=\"MO\">Modena<\/option>\r\n                <option value=\"MB\">Monza e Brianza<\/option>\r\n                <option value=\"NA\">Napoli<\/option>\r\n                <option value=\"NO\">Novara<\/option>\r\n                <option value=\"NU\">Nuoro<\/option>\r\n                <option value=\"OR\">Oristano<\/option>\r\n                <option value=\"PD\">Padova<\/option>\r\n                <option value=\"PA\">Palermo<\/option>\r\n                <option value=\"PR\">Parma<\/option>\r\n                <option value=\"PV\">Pavia<\/option>\r\n                <option value=\"PG\">Perugia<\/option>\r\n                <option value=\"PU\">Pesaro e Urbino<\/option>\r\n                <option value=\"PE\">Pescara<\/option>\r\n                <option value=\"PC\">Piacenza<\/option>\r\n                <option value=\"PI\">Pisa<\/option>\r\n                <option value=\"PT\">Pistoia<\/option>\r\n                <option value=\"PN\">Pordenone<\/option>\r\n                <option value=\"PZ\">Potenza<\/option>\r\n                <option value=\"PO\">Prato<\/option>\r\n                <option value=\"RG\">Ragusa<\/option>\r\n                <option value=\"RA\">Ravenna<\/option>\r\n                <option value=\"RC\">Reggio Calabria<\/option>\r\n                <option value=\"RE\">Reggio Emilia<\/option>\r\n                <option value=\"RI\">Rieti<\/option>\r\n                <option value=\"RN\">Rimini<\/option>\r\n                <option value=\"RM\">Roma<\/option>\r\n                <option value=\"RO\">Rovigo<\/option>\r\n                <option value=\"SA\">Salerno<\/option>\r\n                <option value=\"SS\">Sassari<\/option>\r\n                <option value=\"SV\">Savona<\/option>\r\n                <option value=\"SI\">Siena<\/option>\r\n                <option value=\"SR\">Siracusa<\/option>\r\n                <option value=\"SO\">Sondrio<\/option>\r\n                <option value=\"SU\">Sud Sardegna<\/option>\r\n                <option value=\"TA\">Taranto<\/option>\r\n                <option value=\"TE\">Teramo<\/option>\r\n                <option value=\"TR\">Terni<\/option>\r\n                <option value=\"TO\">Torino<\/option>\r\n                <option value=\"TP\">Trapani<\/option>\r\n                <option value=\"TN\">Trento<\/option>\r\n                <option value=\"TV\">Treviso<\/option>\r\n                <option value=\"TS\">Trieste<\/option>\r\n                <option value=\"UD\">Udine<\/option>\r\n                <option value=\"VA\">Varese<\/option>\r\n                <option value=\"VE\">Venezia<\/option>\r\n                <option value=\"VB\">Verbano-Cusio-Ossola<\/option>\r\n                <option value=\"VC\">Vercelli<\/option>\r\n                <option value=\"VR\">Verona<\/option>\r\n                <option value=\"VV\">Vibo Valentia<\/option>\r\n                <option value=\"VI\">Vicenza<\/option>\r\n                <option value=\"VT\">Viterbo<\/option>\r\n\r\n                <option value=\"estero\">Province \u00e9trang\u00e8re<\/option>\r\n              <\/select>\r\n\r\n              <label for=\"mpProvince\">Province *<\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-field\">\r\n              <input\r\n                type=\"text\"\r\n                name=\"city\"\r\n                id=\"mpCity\"\r\n                placeholder=\" \"\r\n                required\r\n                autocomplete=\"address-level2\"\r\n              >\r\n              <label for=\"mpCity\">Ville *<\/label>\r\n            <\/div>\r\n\r\n          <\/div>\r\n\r\n          <!-- MOTIVO DELLA RICHIESTA -->\r\n          <div class=\"mp-field mp-field-full\">\r\n            <select\r\n              name=\"contact_reason\"\r\n              id=\"mpContactReason\"\r\n              required\r\n            >\r\n              <option value=\"\" selected disabled>S\u00e9lectionnez<\/option>\r\n\r\n              <option value=\"nuovo_impianto\">\r\n                Installation d\u2019un nouvel \u00e9quipement dans un b\u00e2timent neuf\/existant\r\n              <\/option>\r\n\r\n              <option value=\"sostituzione_ascensore\">\r\n                Remplacement d\u2019un ascenseur existant\r\n              <\/option>\r\n\r\n              <option value=\"ammodernamento_impianto\">\r\n                Modernisation d\u2019une installation\r\n              <\/option>\r\n\r\n              <option value=\"assistenza_manutenzione\">\r\n                Je suis int\u00e9ress\u00e9 par le service d\u2019assistance et de maintenance\r\n              <\/option>\r\n\r\n              <option value=\"ricambi\">\r\n                Pi\u00e8ces d\u00e9tach\u00e9es pour ascenseurs Millepiani\r\n              <\/option>\r\n\r\n              <option value=\"altro\">\r\n                Autre\r\n              <\/option>\r\n            <\/select>\r\n\r\n            <label for=\"mpContactReason\">\r\n              Pourquoi souhaitez-vous \u00eatre contact\u00e9 ? *\r\n            <\/label>\r\n          <\/div>\r\n\r\n          <!-- MESSAGGIO -->\r\n          <div class=\"mp-field mp-field-full\">\r\n            <textarea\r\n              name=\"message\"\r\n              id=\"mpMessage\"\r\n              rows=\"4\"\r\n              placeholder=\" \"\r\n            ><\/textarea>\r\n\r\n            <label for=\"mpMessage\">\r\n              Comment pouvons-nous vous aider ?\r\n            <\/label>\r\n          <\/div>\r\n\r\n          <!-- PRIVACY, CAPTCHA E INVIO -->\r\n          <div class=\"mp-form-foot\">\r\n\r\n            <div class=\"mp-privacy-box\">\r\n              <label\r\n                class=\"mp-privacy-check\"\r\n                for=\"mpPrivacyAcceptance\"\r\n              >\r\n                <input\r\n                  type=\"checkbox\"\r\n                  name=\"privacy_acceptance\"\r\n                  id=\"mpPrivacyAcceptance\"\r\n                  value=\"accepted\"\r\n                  required\r\n                >\r\n\r\n                <span>\r\n                  J\u2019accepte la\r\n                  <a\r\n                    href=\"\/privacy-policy\/\"\r\n                    target=\"_blank\"\r\n                    rel=\"noopener noreferrer\"\r\n                  >\r\n                    Politique de confidentialit\u00e9\r\n                  <\/a>. *\r\n                <\/span>\r\n              <\/label>\r\n\r\n              <label\r\n                class=\"mp-privacy-check\"\r\n                for=\"mpExistingContract\"\r\n              >\r\n                <input\r\n                  type=\"checkbox\"\r\n                  name=\"existing_contract\"\r\n                  id=\"mpExistingContract\"\r\n                  value=\"yes\"\r\n                >\r\n\r\n                <span>\r\n                  J\u2019ai d\u00e9j\u00e0 un contrat en cours avec Millepiani\r\n                <\/span>\r\n              <\/label>\r\n            <\/div>\r\n\r\n            <div class=\"mp-captcha\">\r\n              <div\r\n                class=\"g-recaptcha\"\r\n                data-sitekey=\"6LfxY6ktAAAAAFBbvnofa2IpjG_zaaX5UdOtJuTS\"\r\n              ><\/div>\r\n            <\/div>\r\n\r\n            <button\r\n              type=\"submit\"\r\n              class=\"mp-submit-btn\"\r\n            >\r\n              <span>Envoyer le message<\/span>\r\n            <\/button>\r\n\r\n          <\/div>\r\n        <\/form>\r\n      <\/div>\r\n\r\n    <\/div>\r\n  <\/section>\r\n\r\n<\/div>\r\n\r\n<!-- GSAP: mantieni un solo caricamento, prima del nuovo JavaScript. -->\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.12.5\/gsap.min.js\"><\/script>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60597c6 elementor-widget elementor-widget-shortcode\" data-id=\"60597c6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><script>\/*\r\n * MILLEPIANI FULLSCREEN\r\n *\r\n * Desktop: navigazione a sezioni con fade all'arrivo.\r\n * Mobile: tutte le sezioni visibili e scorrimento normale.\r\n *\r\n * Sostituisce completamente il JavaScript precedente.\r\n * Mantieni HTML, CSS e caricamento di GSAP.\r\n *\/\r\n\r\n(() => {\r\n  'use strict';\r\n\r\n  function boot() {\r\n    const wrapper = document.querySelector('#mp-fullpage-wrapper');\r\n\r\n    if (!wrapper) return;\r\n    if (wrapper.dataset.mpNativeReady === 'v2-mobile') return;\r\n\r\n    if (wrapper.dataset.mpNativeReady) {\r\n      console.error(\r\n        'Millepiani: rimuovere il vecchio JavaScript prima di caricare questa versione.'\r\n      );\r\n      return;\r\n    }\r\n\r\n    wrapper.dataset.mpNativeReady = 'v2-mobile';\r\n\r\n    const originalParent = wrapper.parentNode;\r\n    const originalNext = wrapper.nextSibling;\r\n\r\n    let configured = false;\r\n    let desktopMode = false;\r\n    let pointerActive = false;\r\n    let resizeTimer = 0;\r\n\r\n    \/\/ Conserva gli stili modificati su mobile per ripristinarli su desktop.\r\n    const mobileStyleBackup = new Map();\r\n\r\n    \/* CSS DI FUNZIONAMENTO *\/\r\n\r\n    const mechanics = document.createElement('style');\r\n\r\n    mechanics.id = 'mp-fullscreen-v2-style';\r\n\r\n    mechanics.textContent = `\r\n      \/* DESKTOP *\/\r\n\r\n      html.mp-viewport-mode,\r\n      html.mp-viewport-mode body.mp-native-ready {\r\n        height: 100% !important;\r\n        overflow: hidden !important;\r\n        overscroll-behavior: none;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper {\r\n        position: fixed !important;\r\n        inset: var(--mp-fullscreen-top, 0px) 0 0 0 !important;\r\n        display: block !important;\r\n        height: calc(100vh - var(--mp-fullscreen-top, 0px)) !important;\r\n        height: calc(100dvh - var(--mp-fullscreen-top, 0px)) !important;\r\n        width: 100% !important;\r\n        min-height: 0 !important;\r\n        max-height: none !important;\r\n        margin: 0 !important;\r\n        padding: 0 !important;\r\n        border: 0 !important;\r\n        transform: none !important;\r\n        overflow-x: hidden !important;\r\n        overflow-y: auto !important;\r\n        overscroll-behavior: contain;\r\n        scroll-behavior: auto !important;\r\n        scroll-snap-type: none !important;\r\n        overflow-anchor: none;\r\n        z-index: var(--mp-fullscreen-layer, 1);\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper > .section {\r\n        position: relative !important;\r\n        width: 100% !important;\r\n        height: auto !important;\r\n        min-height: var(--mp-screen-height, 100vh) !important;\r\n        max-height: none !important;\r\n        margin-top: 0 !important;\r\n        margin-bottom: 0 !important;\r\n        box-sizing: border-box;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper > .mp-footer,\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper > .mp-footer-section {\r\n        min-height: 0 !important;\r\n        height: auto !important;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready .mp-services-wrap,\r\n      html.mp-viewport-mode body.mp-native-ready #preventivo.mp-quote-desktop-stack .mp-quote-inner {\r\n        min-height: var(--mp-screen-height, 100vh) !important;\r\n        height: auto !important;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper .mp-quote-section {\r\n        overflow: visible !important;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper .mp-quote-bg,\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper .mp-quote-overlay {\r\n        transform: none !important;\r\n      }\r\n\r\n      html.mp-viewport-mode body.mp-native-ready #mp-fullpage-wrapper .section:focus {\r\n        outline: none;\r\n      }\r\n\r\n      \/* MOBILE: PAGINA NORMALE E TUTTE LE SEZIONI VISIBILI *\/\r\n\r\n      html.mp-free-mobile,\r\n      html.mp-free-mobile body.mp-native-ready {\r\n        position: static !important;\r\n        height: auto !important;\r\n        max-height: none !important;\r\n        transform: none !important;\r\n        touch-action: auto !important;\r\n        scroll-snap-type: none !important;\r\n        overscroll-behavior: auto !important;\r\n      }\r\n\r\n      html.mp-free-mobile {\r\n        overflow-x: hidden !important;\r\n        overflow-y: auto !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready {\r\n        overflow: visible !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper {\r\n        display: block !important;\r\n        position: relative !important;\r\n        inset: auto !important;\r\n        height: auto !important;\r\n        min-height: 0 !important;\r\n        max-height: none !important;\r\n        overflow: visible !important;\r\n        transform: none !important;\r\n        touch-action: auto !important;\r\n        scroll-snap-type: none !important;\r\n        overscroll-behavior: auto !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .section {\r\n        display: block !important;\r\n        position: relative !important;\r\n        inset: auto !important;\r\n        width: 100% !important;\r\n        height: auto !important;\r\n        min-height: 100vh !important;\r\n        min-height: 100svh !important;\r\n        max-height: none !important;\r\n        flex: none !important;\r\n        float: none !important;\r\n        opacity: 1 !important;\r\n        visibility: visible !important;\r\n        transform: none !important;\r\n        transition: none !important;\r\n        animation: none !important;\r\n        touch-action: auto !important;\r\n        overflow: hidden !important;\r\n        content-visibility: visible !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-content {\r\n        display: flex !important;\r\n        position: relative !important;\r\n        inset: auto !important;\r\n        width: 100% !important;\r\n        max-width: none !important;\r\n        height: auto !important;\r\n        min-height: 100svh !important;\r\n        max-height: none !important;\r\n        margin: 0 !important;\r\n        padding: 100px 24px 80px !important;\r\n        flex-direction: column !important;\r\n        align-items: flex-start !important;\r\n        justify-content: flex-start !important;\r\n        transform: none !important;\r\n        z-index: 3;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-services-wrap,\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-quote-inner,\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-news-inner,\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-quote-form-card {\r\n        position: relative !important;\r\n        height: auto !important;\r\n        max-height: none !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-mobile-reveal {\r\n        opacity: 1 !important;\r\n        visibility: visible !important;\r\n        transform: none !important;\r\n        transition: none !important;\r\n        animation: none !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-footer,\r\n      html.mp-free-mobile body.mp-native-ready #mp-fullpage-wrapper .mp-footer-section {\r\n        min-height: 0 !important;\r\n        height: auto !important;\r\n      }\r\n\r\n      html.mp-free-mobile #mp-section-nav,\r\n      html.mp-free-mobile .mp-desktop-fixed-quote-btn {\r\n        display: none !important;\r\n      }\r\n    `;\r\n\r\n    document.head.append(mechanics);\r\n\r\n    \/* CONFIGURAZIONE *\/\r\n\r\n    const mobileQuery = window.matchMedia('(max-width: 1024px)');\r\n\r\n    const reducedQuery = window.matchMedia(\r\n      '(prefers-reduced-motion: reduce)'\r\n    );\r\n\r\n    const quote = wrapper.querySelector(\r\n      '.mp-quote-section, #preventivo'\r\n    );\r\n\r\n    const footer = document.querySelector('.mp-footer');\r\n    const footerParent = footer?.parentNode;\r\n    const footerNext = footer?.nextSibling;\r\n    const footerClasses = footer?.className;\r\n\r\n    const languageSegment = window.location.pathname\r\n      .split('\/')\r\n      .filter(Boolean)[0];\r\n\r\n    const language = ['en', 'fr', 'ru'].includes(languageSegment)\r\n      ? languageSegment\r\n      : 'it';\r\n\r\n    const labels = {\r\n      it: [\r\n        'Richiedi preventivo gratuito',\r\n        'Navigazione sezioni',\r\n        'Sezione',\r\n        'Pi\u00e8 di pagina'\r\n      ],\r\n      en: [\r\n        'Request a free quote',\r\n        'Section navigation',\r\n        'Section',\r\n        'Footer'\r\n      ],\r\n      fr: [\r\n        'Demander un devis gratuit',\r\n        'Navigation des sections',\r\n        'Section',\r\n        'Pied de page'\r\n      ],\r\n      ru: [\r\n        '\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0440\u0430\u0441\u0447\u0451\u0442 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438',\r\n        '\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043f\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u043c',\r\n        '\u0420\u0430\u0437\u0434\u0435\u043b',\r\n        '\u041f\u043e\u0434\u0432\u0430\u043b'\r\n      ]\r\n    }[language];\r\n\r\n    const animatedSelector =\r\n      '.mp-kicker, .mp-content h1, .mp-content h2, .mp-desc, ' +\r\n      '.mp-btn, .mp-services-left, .mp-services-image, ' +\r\n      '.mp-quote-info, .mp-quote-form-card, ' +\r\n      '.mp-news-heading, .mp-news-card';\r\n\r\n    const wheelControls =\r\n      'input, textarea, select, ' +\r\n      '[contenteditable]:not([contenteditable=\"false\"]), ' +\r\n      '[role=\"dialog\"], .mp-captcha, .g-recaptcha';\r\n\r\n    const interactive =\r\n      'input, textarea, select, button, a, ' +\r\n      '[contenteditable]:not([contenteditable=\"false\"]), ' +\r\n      '[role=\"slider\"], [role=\"dialog\"], ' +\r\n      '.mp-captcha, .g-recaptcha';\r\n\r\n    let sections = [];\r\n    let active = -1;\r\n    let nav;\r\n\r\n    let animationFrame = 0;\r\n    let scrollFrame = 0;\r\n    let settleTimer = 0;\r\n\r\n    let wheelLast = 0;\r\n    let wheelConsumed = false;\r\n    let wheelSum = 0;\r\n\r\n    let moving = false;\r\n    let suppressSettleUntil = 0;\r\n\r\n    let sectionFadeObserver = null;\r\n\r\n    const preparedSections = new WeakSet();\r\n\r\n    const mobileObserver = new IntersectionObserver(\r\n      entries => {\r\n        entries.forEach(entry => {\r\n          if (entry.isIntersecting) {\r\n            entry.target.classList.add('is-visible');\r\n          }\r\n        });\r\n      },\r\n      {\r\n        threshold: 0,\r\n        rootMargin: '0px 0px -30px 0px'\r\n      }\r\n    );\r\n\r\n    \/* MISURE E SCORRIMENTO *\/\r\n\r\n    function scrollY() {\r\n      return desktopMode ? wrapper.scrollTop : window.scrollY;\r\n    }\r\n\r\n    function viewportHeight() {\r\n      return desktopMode\r\n        ? wrapper.clientHeight\r\n        : window.innerHeight;\r\n    }\r\n\r\n    function topOf(element) {\r\n      const rect = element.getBoundingClientRect();\r\n\r\n      return desktopMode\r\n        ? rect.top -\r\n            wrapper.getBoundingClientRect().top +\r\n            wrapper.scrollTop\r\n        : rect.top + window.scrollY;\r\n    }\r\n\r\n    function maxScroll() {\r\n      return desktopMode\r\n        ? Math.max(\r\n            0,\r\n            wrapper.scrollHeight - wrapper.clientHeight\r\n          )\r\n        : Math.max(\r\n            0,\r\n            document.documentElement.scrollHeight -\r\n              window.innerHeight\r\n          );\r\n    }\r\n\r\n    function clamp(value) {\r\n      return Math.max(0, Math.min(maxScroll(), value));\r\n    }\r\n\r\n    function writeScroll(value) {\r\n      const scroller = desktopMode ? wrapper : window;\r\n\r\n      scroller.scrollTo({\r\n        top: clamp(value),\r\n        behavior: 'instant'\r\n      });\r\n    }\r\n\r\n    function syncViewport() {\r\n      if (desktopMode) {\r\n        wrapper.style.setProperty(\r\n          '--mp-screen-height',\r\n          wrapper.clientHeight + 'px'\r\n        );\r\n      } else {\r\n        wrapper.style.removeProperty('--mp-screen-height');\r\n      }\r\n    }\r\n\r\n    function insidePage() {\r\n      return desktopMode;\r\n    }\r\n\r\n    \/* ELEMENTI DA ANIMARE *\/\r\n\r\n    function targets(section) {\r\n      return [...section.querySelectorAll(animatedSelector)];\r\n    }\r\n\r\n    function prepareSection(section) {\r\n      if (\r\n        !section ||\r\n        !window.gsap ||\r\n        mobileQuery.matches ||\r\n        reducedQuery.matches\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const items = targets(section);\r\n\r\n      if (!items.length) return;\r\n\r\n      window.gsap.killTweensOf(items);\r\n\r\n      window.gsap.set(items, {\r\n        autoAlpha: 0,\r\n        clearProps: 'transform'\r\n      });\r\n\r\n      preparedSections.add(section);\r\n    }\r\n\r\n    function setupSectionFades() {\r\n      sectionFadeObserver?.disconnect();\r\n      sectionFadeObserver = null;\r\n\r\n      if (\r\n        !window.gsap ||\r\n        mobileQuery.matches ||\r\n        reducedQuery.matches\r\n      ) {\r\n        sections.forEach(section => {\r\n          showSection(section, false);\r\n        });\r\n\r\n        return;\r\n      }\r\n\r\n      function outsideViewport(section) {\r\n        const rect = section.getBoundingClientRect();\r\n        const viewport = wrapper.getBoundingClientRect();\r\n\r\n        return (\r\n          rect.bottom <= viewport.top ||\r\n          rect.top >= viewport.bottom\r\n        );\r\n      }\r\n\r\n      sections.forEach(section => {\r\n        if (outsideViewport(section)) {\r\n          prepareSection(section);\r\n        }\r\n      });\r\n\r\n      sectionFadeObserver = new IntersectionObserver(\r\n        entries => {\r\n          entries.forEach(entry => {\r\n            if (\r\n              !entry.isIntersecting &&\r\n              outsideViewport(entry.target)\r\n            ) {\r\n              prepareSection(entry.target);\r\n            }\r\n          });\r\n        },\r\n        {\r\n          root: wrapper,\r\n          threshold: 0\r\n        }\r\n      );\r\n\r\n      sections.forEach(section => {\r\n        sectionFadeObserver.observe(section);\r\n      });\r\n    }\r\n\r\n    function showSection(section, animate = true) {\r\n      if (!section) return;\r\n\r\n      section.classList.add('is-visible');\r\n\r\n      const gsap = window.gsap;\r\n\r\n      if (!gsap) return;\r\n\r\n      const items = targets(section);\r\n\r\n      const bg = section.querySelector(\r\n        '.mp-bg, .mp-quote-bg'\r\n      );\r\n\r\n      if (bg) {\r\n        gsap.killTweensOf(bg);\r\n\r\n        gsap.set(bg, {\r\n          clearProps: 'transform,opacity,visibility'\r\n        });\r\n      }\r\n\r\n      preparedSections.delete(section);\r\n\r\n      if (!items.length) return;\r\n\r\n      gsap.killTweensOf(items);\r\n\r\n      if (\r\n        !animate ||\r\n        mobileQuery.matches ||\r\n        reducedQuery.matches\r\n      ) {\r\n        gsap.set(items, {\r\n          autoAlpha: 1,\r\n          clearProps: 'transform,opacity,visibility'\r\n        });\r\n\r\n        return;\r\n      }\r\n\r\n      \/\/ Mantiene l'opacit\u00e0 preparata prima dello scorrimento.\r\n      gsap.set(items, {\r\n        clearProps: 'transform'\r\n      });\r\n\r\n      gsap.to(items, {\r\n        autoAlpha: 1,\r\n        duration: 0.85,\r\n        stagger: 0.07,\r\n        ease: 'sine.out',\r\n        overwrite: true,\r\n        clearProps: 'opacity,visibility'\r\n      });\r\n    }\r\n\r\n    \/* SEZIONE ATTIVA *\/\r\n\r\n    function setActive(index, animate = true) {\r\n      if (\r\n        moving ||\r\n        index < 0 ||\r\n        !sections[index]\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const changed = active !== index;\r\n\r\n      active = index;\r\n\r\n      sections.forEach((section, i) => {\r\n        section.classList.toggle('active', i === index);\r\n      });\r\n\r\n      const section = sections[index];\r\n\r\n      document.body.classList.toggle(\r\n        'mp-dark-dots',\r\n        section.matches(\r\n          '.mp-services-section, .mp-news-section, ' +\r\n          '.mp-footer, .mp-footer-section'\r\n        )\r\n      );\r\n\r\n      document.body.classList.toggle(\r\n        'mp-on-quote-section',\r\n        section === quote\r\n      );\r\n\r\n      document\r\n        .querySelectorAll(\r\n          '.mp-desktop-fixed-quote-btn, ' +\r\n          '.mp-mobile-fixed-quote-btn'\r\n        )\r\n        .forEach(button => {\r\n          button.hidden = section === quote;\r\n        });\r\n\r\n      nav?.querySelectorAll('a').forEach((link, i) => {\r\n        link.classList.toggle('active', i === index);\r\n\r\n        if (i === index) {\r\n          link.setAttribute('aria-current', 'true');\r\n        } else {\r\n          link.removeAttribute('aria-current');\r\n        }\r\n      });\r\n\r\n      if (\r\n        changed ||\r\n        preparedSections.has(section)\r\n      ) {\r\n        showSection(section, animate);\r\n      }\r\n    }\r\n\r\n    function detectSection() {\r\n      if (!sections.length) return -1;\r\n\r\n      const y = scrollY();\r\n      const last = sections.at(-1);\r\n\r\n      if (\r\n        last.matches('.mp-footer, .mp-footer-section') &&\r\n        y >= maxScroll() - 3 &&\r\n        topOf(last) - y < viewportHeight()\r\n      ) {\r\n        return sections.length - 1;\r\n      }\r\n\r\n      const probe =\r\n        y + Math.min(140, viewportHeight() * 0.2);\r\n\r\n      let index = 0;\r\n\r\n      sections.forEach((section, i) => {\r\n        if (topOf(section) <= probe) {\r\n          index = i;\r\n        }\r\n      });\r\n\r\n      return index;\r\n    }\r\n\r\n    \/* SPOSTAMENTO TRA SEZIONI *\/\r\n\r\n    function stopMotion() {\r\n      cancelAnimationFrame(animationFrame);\r\n\r\n      animationFrame = 0;\r\n      moving = false;\r\n    }\r\n\r\n    function ease(t) {\r\n      return t < 0.5\r\n        ? 8 * t ** 4\r\n        : 1 - ((-2 * t + 2) ** 4) \/ 2;\r\n    }\r\n\r\n    function moveTo(index, focus = false) {\r\n      const section = sections[index];\r\n\r\n      if (!section) return;\r\n\r\n      stopMotion();\r\n      clearTimeout(settleTimer);\r\n\r\n      \/\/ MOBILE: scorrimento nativo del browser.\r\n      if (mobileQuery.matches) {\r\n        section.scrollIntoView({\r\n          behavior: reducedQuery.matches ? 'auto' : 'smooth',\r\n          block: 'start'\r\n        });\r\n\r\n        if (focus) {\r\n          if (!section.hasAttribute('tabindex')) {\r\n            section.tabIndex = -1;\r\n          }\r\n\r\n          section.focus({\r\n            preventScroll: true\r\n          });\r\n        }\r\n\r\n        return;\r\n      }\r\n\r\n      \/\/ DESKTOP: nasconde la destinazione prima dello scroll.\r\n      if (index !== active) {\r\n        prepareSection(section);\r\n      }\r\n\r\n      const startY = scrollY();\r\n      const endY = clamp(topOf(section));\r\n\r\n      const started = performance.now();\r\n      const duration = reducedQuery.matches ? 0 : 820;\r\n\r\n      moving = true;\r\n\r\n      function finish() {\r\n        moving = false;\r\n        animationFrame = 0;\r\n\r\n        suppressSettleUntil = performance.now() + 200;\r\n\r\n        setActive(index);\r\n\r\n        if (focus) {\r\n          if (!section.hasAttribute('tabindex')) {\r\n            section.tabIndex = -1;\r\n          }\r\n\r\n          section.focus({\r\n            preventScroll: true\r\n          });\r\n        }\r\n      }\r\n\r\n      function step(now) {\r\n        const t = duration\r\n          ? Math.min(1, (now - started) \/ duration)\r\n          : 1;\r\n\r\n        writeScroll(\r\n          startY + (endY - startY) * ease(t)\r\n        );\r\n\r\n        if (t < 1) {\r\n          animationFrame = requestAnimationFrame(step);\r\n        } else {\r\n          finish();\r\n        }\r\n      }\r\n\r\n      animationFrame = requestAnimationFrame(step);\r\n    }\r\n\r\n    function nextDestination(direction) {\r\n      const y = scrollY();\r\n      const index = detectSection();\r\n      const section = sections[index];\r\n\r\n      if (!section) return -1;\r\n\r\n      const top = topOf(section);\r\n      const bottom = top + section.offsetHeight;\r\n\r\n      \/\/ Consente la lettura delle sezioni pi\u00f9 alte della finestra.\r\n      if (section.offsetHeight > viewportHeight() + 4) {\r\n        if (\r\n          direction > 0 &&\r\n          y < bottom - viewportHeight() - 4\r\n        ) {\r\n          return -1;\r\n        }\r\n\r\n        if (\r\n          direction < 0 &&\r\n          y > top + 4\r\n        ) {\r\n          return -1;\r\n        }\r\n      }\r\n\r\n      if (\r\n        direction < 0 &&\r\n        y > top + 8\r\n      ) {\r\n        return index;\r\n      }\r\n\r\n      const next = index + direction;\r\n\r\n      return next >= 0 && next < sections.length\r\n        ? next\r\n        : -1;\r\n    }\r\n\r\n    \/* ROTELLA E AREE INTERNE SCORREVOLI *\/\r\n\r\n    function hasScrollableParent(element, direction) {\r\n      for (\r\n        let node = element;\r\n        node &&\r\n        node !== wrapper &&\r\n        node !== document.body;\r\n        node = node.parentElement\r\n      ) {\r\n        const style = getComputedStyle(node);\r\n\r\n        if (\r\n          \/(auto|scroll)\/.test(style.overflowY) &&\r\n          node.scrollHeight > node.clientHeight + 2\r\n        ) {\r\n          const canScroll = direction > 0\r\n            ? node.scrollTop + node.clientHeight <\r\n              node.scrollHeight - 2\r\n            : node.scrollTop > 2;\r\n\r\n          if (canScroll) return true;\r\n        }\r\n      }\r\n\r\n      return false;\r\n    }\r\n\r\n    function wheel(event) {\r\n      if (\r\n        mobileQuery.matches ||\r\n        event.ctrlKey ||\r\n        event.metaKey ||\r\n        Math.abs(event.deltaX) > Math.abs(event.deltaY) ||\r\n        !event.deltaY ||\r\n        !insidePage()\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const direction = Math.sign(event.deltaY);\r\n\r\n      if (\r\n        event.target.closest(wheelControls) ||\r\n        hasScrollableParent(event.target, direction)\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const now = performance.now();\r\n\r\n      if (now - wheelLast > 180) {\r\n        wheelConsumed = false;\r\n        wheelSum = 0;\r\n      }\r\n\r\n      wheelLast = now;\r\n\r\n      if (moving || wheelConsumed) {\r\n        event.preventDefault();\r\n        return;\r\n      }\r\n\r\n      const destination = nextDestination(direction);\r\n\r\n      if (\r\n        destination < 0 ||\r\n        Math.abs(\r\n          clamp(topOf(sections[destination])) - scrollY()\r\n        ) < 2\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const delta = event.deltaY * (\r\n        event.deltaMode === 1\r\n          ? 16\r\n          : event.deltaMode === 2\r\n            ? viewportHeight()\r\n            : 1\r\n      );\r\n\r\n      if (Math.sign(wheelSum) !== direction) {\r\n        wheelSum = 0;\r\n      }\r\n\r\n      wheelSum += delta;\r\n\r\n      event.preventDefault();\r\n\r\n      if (Math.abs(wheelSum) < 24) return;\r\n\r\n      wheelConsumed = true;\r\n\r\n      moveTo(destination);\r\n    }\r\n\r\n    \/* ALLINEAMENTO DESKTOP *\/\r\n\r\n    function snapDestination() {\r\n      const y = scrollY();\r\n      const height = viewportHeight();\r\n\r\n      for (const section of sections) {\r\n        const top = topOf(section);\r\n\r\n        const bottomPosition =\r\n          top + section.offsetHeight - height;\r\n\r\n        if (\r\n          section.offsetHeight > height + 4 &&\r\n          y >= top - 2 &&\r\n          y <= bottomPosition + 2\r\n        ) {\r\n          return -1;\r\n        }\r\n      }\r\n\r\n      let nearest = -1;\r\n      let distance = Infinity;\r\n\r\n      sections.forEach((section, index) => {\r\n        const delta = Math.abs(\r\n          clamp(topOf(section)) - y\r\n        );\r\n\r\n        if (delta < distance) {\r\n          nearest = index;\r\n          distance = delta;\r\n        }\r\n      });\r\n\r\n      return distance > 2 ? nearest : -1;\r\n    }\r\n\r\n    function settle() {\r\n      if (\r\n        !desktopMode ||\r\n        moving ||\r\n        pointerActive\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const remaining =\r\n        suppressSettleUntil - performance.now();\r\n\r\n      if (remaining > 0) {\r\n        settleTimer = setTimeout(\r\n          settle,\r\n          remaining + 20\r\n        );\r\n        return;\r\n      }\r\n\r\n      if (\r\n        document.activeElement?.closest(wheelControls)\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      const nearest = snapDestination();\r\n\r\n      if (nearest >= 0) {\r\n        moveTo(nearest);\r\n      }\r\n    }\r\n\r\n    function onScroll() {\r\n      if (!scrollFrame) {\r\n        scrollFrame = requestAnimationFrame(() => {\r\n          scrollFrame = 0;\r\n\r\n          if (moving) return;\r\n\r\n          const index = detectSection();\r\n          const section = sections[index];\r\n\r\n          if (!section) return;\r\n\r\n          const y = scrollY();\r\n          const top = topOf(section);\r\n          const height = viewportHeight();\r\n\r\n          const aligned =\r\n            Math.abs(y - clamp(top)) <= 3;\r\n\r\n          const insideTallSection =\r\n            section.offsetHeight > height + 4 &&\r\n            y >= top - 3 &&\r\n            y <= top + section.offsetHeight - height + 3;\r\n\r\n          if (\r\n            !desktopMode ||\r\n            aligned ||\r\n            insideTallSection\r\n          ) {\r\n            setActive(index);\r\n          }\r\n        });\r\n      }\r\n\r\n      clearTimeout(settleTimer);\r\n\r\n      if (!moving && desktopMode) {\r\n        settleTimer = setTimeout(settle, 180);\r\n      }\r\n    }\r\n\r\n    wrapper.addEventListener(\r\n      'wheel',\r\n      wheel,\r\n      { passive: false }\r\n    );\r\n\r\n    wrapper.addEventListener(\r\n      'scroll',\r\n      () => {\r\n        if (desktopMode) {\r\n          onScroll();\r\n        }\r\n      },\r\n      { passive: true }\r\n    );\r\n\r\n    window.addEventListener(\r\n      'scroll',\r\n      () => {\r\n        if (!desktopMode) {\r\n          onScroll();\r\n        }\r\n      },\r\n      { passive: true }\r\n    );\r\n\r\n    \/* TASTIERA *\/\r\n\r\n    window.addEventListener('keydown', event => {\r\n      if (event.key === 'Escape') {\r\n        stopMotion();\r\n        return;\r\n      }\r\n\r\n      if (\r\n        mobileQuery.matches ||\r\n        event.defaultPrevented ||\r\n        event.altKey ||\r\n        event.ctrlKey ||\r\n        event.metaKey ||\r\n        event.target.closest(interactive) ||\r\n        !insidePage()\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      let destination = -1;\r\n\r\n      if (event.key === 'Home') {\r\n        destination = 0;\r\n      } else if (event.key === 'End') {\r\n        destination = sections.length - 1;\r\n      } else {\r\n        const direction =\r\n          ['ArrowDown', 'PageDown'].includes(event.key) ||\r\n          (event.key === ' ' && !event.shiftKey)\r\n            ? 1\r\n            : ['ArrowUp', 'PageUp'].includes(event.key) ||\r\n              (event.key === ' ' && event.shiftKey)\r\n              ? -1\r\n              : 0;\r\n\r\n        if (!direction) return;\r\n\r\n        if (moving) {\r\n          event.preventDefault();\r\n          return;\r\n        }\r\n\r\n        destination = nextDestination(direction);\r\n\r\n        if (destination < 0 && desktopMode) {\r\n          event.preventDefault();\r\n\r\n          const section = sections[detectSection()];\r\n\r\n          if (\r\n            section &&\r\n            section.offsetHeight > viewportHeight() + 4\r\n          ) {\r\n            const top = topOf(section);\r\n\r\n            const lastPosition =\r\n              top +\r\n              section.offsetHeight -\r\n              viewportHeight();\r\n\r\n            const step = event.key.startsWith('Arrow')\r\n              ? 60\r\n              : viewportHeight() * 0.85;\r\n\r\n            writeScroll(\r\n              Math.max(\r\n                top,\r\n                Math.min(\r\n                  lastPosition,\r\n                  scrollY() + direction * step\r\n                )\r\n              )\r\n            );\r\n          }\r\n\r\n          return;\r\n        }\r\n      }\r\n\r\n      if (destination >= 0) {\r\n        event.preventDefault();\r\n        moveTo(destination);\r\n      }\r\n    });\r\n\r\n    \/* POINTER, TOUCH E FOCUS *\/\r\n\r\n    function pointerStart() {\r\n      pointerActive = true;\r\n\r\n      stopMotion();\r\n      clearTimeout(settleTimer);\r\n    }\r\n\r\n    function pointerEnd() {\r\n      pointerActive = false;\r\n\r\n      clearTimeout(settleTimer);\r\n\r\n      if (desktopMode) {\r\n        settleTimer = setTimeout(settle, 200);\r\n      }\r\n    }\r\n\r\n    wrapper.addEventListener(\r\n      'pointerdown',\r\n      pointerStart,\r\n      { passive: true }\r\n    );\r\n\r\n    window.addEventListener(\r\n      'pointerup',\r\n      pointerEnd,\r\n      { passive: true }\r\n    );\r\n\r\n    window.addEventListener(\r\n      'pointercancel',\r\n      pointerEnd,\r\n      { passive: true }\r\n    );\r\n\r\n    wrapper.addEventListener(\r\n      'touchstart',\r\n      pointerStart,\r\n      { passive: true }\r\n    );\r\n\r\n    window.addEventListener(\r\n      'touchend',\r\n      pointerEnd,\r\n      { passive: true }\r\n    );\r\n\r\n    window.addEventListener(\r\n      'touchcancel',\r\n      pointerEnd,\r\n      { passive: true }\r\n    );\r\n\r\n    wrapper.addEventListener('focusin', event => {\r\n      stopMotion();\r\n      clearTimeout(settleTimer);\r\n\r\n      const section = event.target.closest('.section');\r\n\r\n      if (section) {\r\n        setActive(\r\n          sections.indexOf(section),\r\n          false\r\n        );\r\n      }\r\n    });\r\n\r\n    \/* PULSANTI PREVENTIVO *\/\r\n\r\n    function createButtons() {\r\n      if (!quote) return;\r\n\r\n      for (const type of ['desktop', 'mobile']) {\r\n        const className =\r\n          `mp-${type}-fixed-quote-btn`;\r\n\r\n        if (document.querySelector(`.${className}`)) {\r\n          continue;\r\n        }\r\n\r\n        const link = document.createElement('a');\r\n\r\n        link.href = '#preventivo';\r\n        link.className = className;\r\n\r\n        link.textContent = type === 'desktop'\r\n          ? labels[0].toUpperCase()\r\n          : labels[0];\r\n\r\n        if (type === 'desktop') {\r\n          const span = document.createElement('span');\r\n          const image = document.createElement('img');\r\n\r\n          image.src =\r\n            'https:\/\/millepiani.com\/wp-content\/uploads\/2026\/05\/lsicon_arrow-left-outline.png';\r\n\r\n          image.alt = '';\r\n\r\n          span.append(image);\r\n          link.append(span);\r\n        }\r\n\r\n        document.body.append(link);\r\n      }\r\n    }\r\n\r\n    document.addEventListener('click', event => {\r\n      const link = event.target.closest(\r\n        'a[href=\"#preventivo\"]'\r\n      );\r\n\r\n      if (\r\n        !link ||\r\n        !quote ||\r\n        event.defaultPrevented ||\r\n        event.button !== 0 ||\r\n        event.ctrlKey ||\r\n        event.metaKey ||\r\n        event.shiftKey ||\r\n        event.altKey\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      event.preventDefault();\r\n\r\n      moveTo(\r\n        sections.indexOf(quote),\r\n        true\r\n      );\r\n    });\r\n\r\n    \/* PALLINI DESKTOP *\/\r\n\r\n    function buildNav() {\r\n      nav?.remove();\r\n\r\n      nav = document.createElement('nav');\r\n\r\n      nav.id = 'mp-section-nav';\r\n      nav.setAttribute('aria-label', labels[1]);\r\n\r\n      const list = document.createElement('ul');\r\n\r\n      sections.forEach((section, index) => {\r\n        if (!section.id) {\r\n          let id = `mp-section-${index + 1}`;\r\n\r\n          while (document.getElementById(id)) {\r\n            id += '-native';\r\n          }\r\n\r\n          section.id = id;\r\n        }\r\n\r\n        const li = document.createElement('li');\r\n        const link = document.createElement('a');\r\n\r\n        const title = section\r\n          .querySelector('h1, h2, h3')\r\n          ?.textContent\r\n          .replace(\/\\s+\/g, ' ')\r\n          .trim();\r\n\r\n        link.href = `#${section.id}`;\r\n\r\n        link.setAttribute(\r\n          'aria-label',\r\n          title ||\r\n            (\r\n              section === footer\r\n                ? labels[3]\r\n                : `${labels[2]} ${index + 1}`\r\n            )\r\n        );\r\n\r\n        link.title = link.getAttribute('aria-label');\r\n\r\n        const dot = document.createElement('span');\r\n\r\n        dot.setAttribute('aria-hidden', 'true');\r\n\r\n        link.append(dot);\r\n\r\n        link.addEventListener('click', event => {\r\n          if (\r\n            event.ctrlKey ||\r\n            event.metaKey ||\r\n            event.shiftKey ||\r\n            event.altKey ||\r\n            event.button !== 0\r\n          ) {\r\n            return;\r\n          }\r\n\r\n          event.preventDefault();\r\n\r\n          moveTo(index, true);\r\n        });\r\n\r\n        li.append(link);\r\n        list.append(li);\r\n      });\r\n\r\n      nav.append(list);\r\n      document.body.append(nav);\r\n    }\r\n\r\n    \/* SBLOCCO COMPLETO DEL LAYOUT MOBILE *\/\r\n\r\n    function forceMobileStyles(element, properties) {\r\n      if (!element?.style) return;\r\n\r\n      let saved = mobileStyleBackup.get(element);\r\n\r\n      if (!saved) {\r\n        saved = new Map();\r\n        mobileStyleBackup.set(element, saved);\r\n      }\r\n\r\n      \/\/ Salva solo le propriet\u00e0 che questa funzione modifica.\r\n      Object.keys(properties).forEach(property => {\r\n        if (!saved.has(property)) {\r\n          saved.set(property, {\r\n            value: element.style.getPropertyValue(property),\r\n            priority: element.style.getPropertyPriority(property)\r\n          });\r\n        }\r\n      });\r\n\r\n      Object.entries(properties).forEach(([property, value]) => {\r\n        element.style.setProperty(\r\n          property,\r\n          value,\r\n          'important'\r\n        );\r\n      });\r\n    }\r\n\r\n    function restoreMobileStyles() {\r\n      mobileStyleBackup.forEach((saved, element) => {\r\n        saved.forEach((original, property) => {\r\n          if (original.value) {\r\n            element.style.setProperty(\r\n              property,\r\n              original.value,\r\n              original.priority\r\n            );\r\n          } else {\r\n            element.style.removeProperty(property);\r\n          }\r\n        });\r\n      });\r\n\r\n      mobileStyleBackup.clear();\r\n    }\r\n\r\n    function enableMobileFlow() {\r\n      const normalFlow = {\r\n        position: 'relative',\r\n        inset: 'auto',\r\n        height: 'auto',\r\n        'min-height': '0',\r\n        'max-height': 'none',\r\n        overflow: 'visible',\r\n        transform: 'none',\r\n        'touch-action': 'auto',\r\n        'scroll-snap-type': 'none',\r\n        'overscroll-behavior': 'auto'\r\n      };\r\n\r\n      \/\/ Sblocca lo scorrimento del documento.\r\n      forceMobileStyles(document.documentElement, {\r\n        ...normalFlow,\r\n        position: 'static',\r\n        'overflow-x': 'hidden',\r\n        'overflow-y': 'auto'\r\n      });\r\n\r\n      forceMobileStyles(document.body, {\r\n        ...normalFlow,\r\n        position: 'static'\r\n      });\r\n\r\n      \/*\r\n       * Sblocca anche gli antenati del wrapper.\r\n       * Un contenitore del tema alto 100vh con overflow hidden\r\n       * pu\u00f2 impedire di raggiungere le sezioni successive.\r\n       *\/\r\n      for (\r\n        let parent = wrapper.parentElement;\r\n        parent && parent !== document.body;\r\n        parent = parent.parentElement\r\n      ) {\r\n        forceMobileStyles(parent, {\r\n          ...normalFlow,\r\n          display: 'block',\r\n          contain: 'none',\r\n          'content-visibility': 'visible'\r\n        });\r\n      }\r\n\r\n      forceMobileStyles(wrapper, {\r\n        ...normalFlow,\r\n        display: 'block'\r\n      });\r\n\r\n      \/\/ Tutte le sezioni occupano spazio nel documento.\r\n      sections.forEach(section => {\r\n        forceMobileStyles(section, {\r\n          display: 'block',\r\n          position: 'relative',\r\n          inset: 'auto',\r\n          width: '100%',\r\n          height: 'auto',\r\n          'max-height': 'none',\r\n          flex: 'none',\r\n          float: 'none',\r\n          transform: 'none',\r\n          opacity: '1',\r\n          visibility: 'visible',\r\n          'touch-action': 'auto'\r\n        });\r\n\r\n        targets(section).forEach(item => {\r\n          item.classList.add('mp-mobile-reveal');\r\n        });\r\n      });\r\n\r\n      \/\/ Ripulisce eventuali contenitori di vecchi layout.\r\n      wrapper\r\n        .querySelectorAll(\r\n          '.fp-tableCell, .fp-overflow, .fp-scrollable, .fp-scroller'\r\n        )\r\n        .forEach(element => {\r\n          forceMobileStyles(element, {\r\n            ...normalFlow,\r\n            display: 'block'\r\n          });\r\n        });\r\n    }\r\n\r\n    \/* CONFIGURAZIONE DESKTOP \/ MOBILE *\/\r\n\r\n    function configure() {\r\n      const previous = sections[active];\r\n\r\n      stopMotion();\r\n      clearTimeout(settleTimer);\r\n\r\n      const mobile = mobileQuery.matches;\r\n\r\n      restoreMobileStyles();\r\n\r\n      desktopMode = !mobile;\r\n\r\n      document.documentElement.classList.toggle(\r\n        'mp-free-mobile',\r\n        mobile\r\n      );\r\n\r\n      document.documentElement.classList.add(\r\n        'mp-native-page'\r\n      );\r\n\r\n      document.documentElement.classList.toggle(\r\n        'mp-viewport-mode',\r\n        !mobile\r\n      );\r\n\r\n      document.body.classList.remove(\r\n        'mp-fullpage-ready'\r\n      );\r\n\r\n      document.body.classList.add(\r\n        'mp-native-ready'\r\n      );\r\n\r\n      document.body.classList.toggle(\r\n        'mp-mobile-layout',\r\n        mobile\r\n      );\r\n\r\n      document.body.classList.toggle(\r\n        'mp-native-desktop',\r\n        !mobile\r\n      );\r\n\r\n      \/\/ Desktop: contenitore a tutto schermo.\r\n      if (\r\n        !mobile &&\r\n        wrapper.parentNode !== document.body\r\n      ) {\r\n        document.body.append(wrapper);\r\n      }\r\n\r\n      \/\/ Mobile: ripristina la posizione originale nel documento.\r\n      if (\r\n        mobile &&\r\n        wrapper.parentNode !== originalParent\r\n      ) {\r\n        originalParent.insertBefore(\r\n          wrapper,\r\n          originalNext?.parentNode === originalParent\r\n            ? originalNext\r\n            : null\r\n        );\r\n      }\r\n\r\n      if (footer && !mobile) {\r\n        footer.classList.add(\r\n          'section',\r\n          'mp-footer-section'\r\n        );\r\n\r\n        if (footer.parentElement !== wrapper) {\r\n          wrapper.append(footer);\r\n        }\r\n      } else if (\r\n        footer &&\r\n        footerParent !== wrapper\r\n      ) {\r\n        footerParent.insertBefore(\r\n          footer,\r\n          footerNext?.parentNode === footerParent\r\n            ? footerNext\r\n            : null\r\n        );\r\n\r\n        footer.className = footerClasses;\r\n      }\r\n\r\n      sections = [...wrapper.children].filter(\r\n        element => element.matches('.section')\r\n      );\r\n\r\n      syncViewport();\r\n\r\n      mobileObserver.disconnect();\r\n\r\n      \/* MOBILE: NESSUNA NAVIGAZIONE FULLSCREEN *\/\r\n\r\n      if (mobile) {\r\n        sectionFadeObserver?.disconnect();\r\n        sectionFadeObserver = null;\r\n\r\n        nav?.remove();\r\n        nav = null;\r\n\r\n        sections.forEach(section => {\r\n          section.classList.remove('mp-mobile-fade');\r\n          section.classList.add('is-visible');\r\n\r\n          showSection(section, false);\r\n        });\r\n\r\n        \/\/ Applica il reset di altezze, overflow e visibilit\u00e0.\r\n        enableMobileFlow();\r\n\r\n        createButtons();\r\n\r\n        let mobileTarget = configured && previous\r\n          ? sections.indexOf(previous)\r\n          : detectSection();\r\n\r\n        if (mobileTarget < 0) {\r\n          mobileTarget = 0;\r\n        }\r\n\r\n        active = -1;\r\n\r\n        setActive(mobileTarget, false);\r\n\r\n        if (\r\n          configured &&\r\n          previous &&\r\n          sections.includes(previous)\r\n        ) {\r\n          writeScroll(topOf(previous));\r\n        }\r\n\r\n        configured = true;\r\n        wheelConsumed = false;\r\n        pointerActive = false;\r\n\r\n        return;\r\n      }\r\n\r\n      \/* DESKTOP *\/\r\n\r\n      sections.forEach(section => {\r\n        showSection(section, false);\r\n\r\n        section.classList.toggle(\r\n          'mp-mobile-fade',\r\n          mobile\r\n        );\r\n\r\n        if (mobile) {\r\n          mobileObserver.observe(section);\r\n        }\r\n      });\r\n\r\n      createButtons();\r\n      buildNav();\r\n\r\n      let target = configured && previous\r\n        ? sections.indexOf(previous)\r\n        : -1;\r\n\r\n      if (!configured && window.location.hash) {\r\n        try {\r\n          target = sections.findIndex(\r\n            section =>\r\n              section.id ===\r\n              decodeURIComponent(\r\n                window.location.hash.slice(1)\r\n              )\r\n          );\r\n        } catch (_) {\r\n          \/* Hash malformato: prima sezione. *\/\r\n        }\r\n      }\r\n\r\n      if (target < 0) {\r\n        target = mobile ? detectSection() : 0;\r\n      }\r\n\r\n      active = -1;\r\n\r\n      setActive(target, false);\r\n\r\n      if (desktopMode || configured) {\r\n        writeScroll(\r\n          topOf(sections[target])\r\n        );\r\n      }\r\n\r\n      configured = true;\r\n      wheelConsumed = false;\r\n      pointerActive = false;\r\n\r\n      window.mpFullscreen = {\r\n        version: '2.1',\r\n\r\n        moveTo: number => {\r\n          moveTo(Number(number) - 1, true);\r\n        },\r\n\r\n        refresh: syncViewport,\r\n\r\n        getState: () => ({\r\n          version: '2.1',\r\n          mode: desktopMode ? 'desktop' : 'mobile',\r\n          sections: sections.length,\r\n          activeSection: active + 1,\r\n          scrollTop: scrollY(),\r\n          viewportHeight: viewportHeight(),\r\n          moving\r\n        })\r\n      };\r\n\r\n      setupSectionFades();\r\n    }\r\n\r\n    mobileQuery.addEventListener(\r\n      'change',\r\n      configure\r\n    );\r\n\r\n    reducedQuery.addEventListener('change', () => {\r\n      stopMotion();\r\n\r\n      sections.forEach(section => {\r\n        showSection(section, false);\r\n      });\r\n\r\n      setupSectionFades();\r\n    });\r\n\r\n    window.addEventListener('resize', () => {\r\n      stopMotion();\r\n\r\n      clearTimeout(settleTimer);\r\n      clearTimeout(resizeTimer);\r\n\r\n      resizeTimer = setTimeout(() => {\r\n        syncViewport();\r\n\r\n        \/\/ Su mobile non riporta la pagina all'inizio della sezione.\r\n        if (desktopMode && sections[active]) {\r\n          writeScroll(\r\n            topOf(sections[active])\r\n          );\r\n        }\r\n\r\n        setActive(\r\n          detectSection(),\r\n          false\r\n        );\r\n      }, 150);\r\n    });\r\n\r\n    window.addEventListener(\r\n      'load',\r\n      () => {\r\n        syncViewport();\r\n\r\n        if (desktopMode && sections[active]) {\r\n          writeScroll(\r\n            topOf(sections[active])\r\n          );\r\n        }\r\n      },\r\n      { once: true }\r\n    );\r\n\r\n    window.addEventListener('hashchange', () => {\r\n      try {\r\n        const index = sections.findIndex(\r\n          section =>\r\n            section.id ===\r\n            decodeURIComponent(\r\n              window.location.hash.slice(1)\r\n            )\r\n        );\r\n\r\n        if (index >= 0) {\r\n          moveTo(index, true);\r\n        }\r\n      } catch (_) {\r\n        \/* Nessuna navigazione per un hash malformato. *\/\r\n      }\r\n    });\r\n\r\n    configure();\r\n\r\n    showSection(sections[active]);\r\n\r\n    initTabs();\r\n    initQuoteForm();\r\n    initNews();\r\n\r\n    \/* TAB SERVIZI *\/\r\n\r\n    function initTabs() {\r\n      const tabs = [\r\n        ...wrapper.querySelectorAll('.mp-tab')\r\n      ];\r\n\r\n      const panels = [\r\n        ...wrapper.querySelectorAll('.mp-tab-panel')\r\n      ];\r\n\r\n      tabs.forEach(tab => {\r\n        tab.addEventListener('click', event => {\r\n          event.preventDefault();\r\n\r\n          const panel = panels.find(\r\n            item => item.dataset.panel === tab.dataset.tab\r\n          );\r\n\r\n          if (!panel) return;\r\n\r\n          tabs.forEach(item => {\r\n            item.classList.toggle(\r\n              'is-active',\r\n              item === tab\r\n            );\r\n          });\r\n\r\n          panels.forEach(item => {\r\n            item.classList.toggle(\r\n              'is-active',\r\n              item === panel\r\n            );\r\n          });\r\n\r\n          if (\r\n            window.gsap &&\r\n            !reducedQuery.matches\r\n          ) {\r\n            window.gsap.fromTo(\r\n              panel,\r\n              {\r\n                autoAlpha: 0,\r\n                y: 8\r\n              },\r\n              {\r\n                autoAlpha: 1,\r\n                y: 0,\r\n                duration: 0.28,\r\n                ease: 'power3.out',\r\n                overwrite: true\r\n              }\r\n            );\r\n          }\r\n        });\r\n      });\r\n    }\r\n\r\n    \/* MODULO PREVENTIVO *\/\r\n\r\n    function initQuoteForm() {\r\n      const form = document.querySelector('#mpQuoteForm');\r\n      const status = document.querySelector('#mpFormStatus');\r\n\r\n      if (!form || !status) return;\r\n\r\n      const fileInput = form.querySelector('#mpFile');\r\n      const fileName = form.querySelector('#mpFileName');\r\n\r\n      const privacy = form.querySelector(\r\n        '#mpPrivacyAcceptance'\r\n      );\r\n\r\n      let submitting = false;\r\n\r\n      const ajaxUrl =\r\n        form.dataset.ajaxUrl ||\r\n        window.location.origin +\r\n          '\/wp-admin\/admin-ajax.php';\r\n\r\n      function setStatus(message, type) {\r\n        status.textContent = message;\r\n\r\n        status.className =\r\n          `mp-form-status is-visible is-${type}`;\r\n      }\r\n\r\n      function clearStatus() {\r\n        status.textContent = '';\r\n        status.className = 'mp-form-status';\r\n      }\r\n\r\n      function updateLabels() {\r\n        form.querySelectorAll('.mp-field').forEach(field => {\r\n          const input = field.querySelector(\r\n            'input, textarea, select'\r\n          );\r\n\r\n          if (\r\n            input &&\r\n            !['checkbox', 'file'].includes(input.type)\r\n          ) {\r\n            field.classList.toggle(\r\n              'is-filled',\r\n              input.value.trim() !== ''\r\n            );\r\n          }\r\n        });\r\n      }\r\n\r\n      function captchaId() {\r\n        const id = form.dataset.captchaWidgetId;\r\n\r\n        return id !== undefined && id !== ''\r\n          ? Number(id)\r\n          : undefined;\r\n      }\r\n\r\n      function resetCaptcha() {\r\n        try {\r\n          window.grecaptcha?.reset(\r\n            captchaId()\r\n          );\r\n        } catch (_) {\r\n          \/* Widget non pronto. *\/\r\n        }\r\n      }\r\n\r\n      form.addEventListener(\r\n        'input',\r\n        updateLabels\r\n      );\r\n\r\n      form.addEventListener(\r\n        'change',\r\n        updateLabels\r\n      );\r\n\r\n      updateLabels();\r\n\r\n      fileInput?.addEventListener('change', () => {\r\n        const file = fileInput.files[0];\r\n\r\n        if (\r\n          file &&\r\n          file.size > 10 * 1024 * 1024\r\n        ) {\r\n          fileInput.value = '';\r\n\r\n          if (fileName) {\r\n            fileName.textContent = '';\r\n          }\r\n\r\n          setStatus(\r\n            'Il file supera il limite massimo di 10 MB.',\r\n            'error'\r\n          );\r\n        } else {\r\n          if (fileName) {\r\n            fileName.textContent = file?.name || '';\r\n          }\r\n\r\n          clearStatus();\r\n        }\r\n      });\r\n\r\n      form.addEventListener('submit', async event => {\r\n        event.preventDefault();\r\n\r\n        if (submitting) return;\r\n\r\n        stopMotion();\r\n        clearStatus();\r\n\r\n        const submit = form.querySelector(\r\n          '.mp-submit-btn'\r\n        );\r\n\r\n        const text = submit?.querySelector('span');\r\n        const originalText = text?.textContent;\r\n\r\n        const empty = [\r\n          ...form.querySelectorAll(\r\n            'input[required], textarea[required]'\r\n          )\r\n        ].find(field => {\r\n          return (\r\n            !['checkbox', 'file', 'radio'].includes(\r\n              field.type\r\n            ) &&\r\n            !field.value.trim()\r\n          );\r\n        });\r\n\r\n        if (empty) {\r\n          setStatus(\r\n            'Compila tutti i campi obbligatori prima di inviare.',\r\n            'error'\r\n          );\r\n\r\n          empty.focus();\r\n          return;\r\n        }\r\n\r\n        if (privacy && !privacy.checked) {\r\n          setStatus(\r\n            'Per inviare il modulo devi dichiarare di aver letto l\u2019informativa privacy.',\r\n            'error'\r\n          );\r\n\r\n          privacy.focus();\r\n          return;\r\n        }\r\n\r\n        if (!form.checkValidity()) {\r\n          setStatus(\r\n            'Compila correttamente tutti i campi obbligatori prima di inviare.',\r\n            'error'\r\n          );\r\n\r\n          form.reportValidity();\r\n          return;\r\n        }\r\n\r\n        let token;\r\n\r\n        try {\r\n          if (!window.grecaptcha?.getResponse) {\r\n            throw new Error('Captcha non disponibile');\r\n          }\r\n\r\n          token = window.grecaptcha.getResponse(\r\n            captchaId()\r\n          );\r\n        } catch (_) {\r\n          setStatus(\r\n            'Il CAPTCHA non \u00e8 stato caricato correttamente. Ricarica la pagina e riprova.',\r\n            'error'\r\n          );\r\n\r\n          return;\r\n        }\r\n\r\n        if (!token) {\r\n          setStatus(\r\n            'Completa la verifica CAPTCHA prima di inviare il modulo.',\r\n            'error'\r\n          );\r\n\r\n          return;\r\n        }\r\n\r\n        const data = new FormData(form);\r\n\r\n        data.set(\r\n          'action',\r\n          'mp_send_quote_request'\r\n        );\r\n\r\n        data.set(\r\n          'g-recaptcha-response',\r\n          token\r\n        );\r\n\r\n        submitting = true;\r\n\r\n        if (submit) {\r\n          submit.disabled = true;\r\n        }\r\n\r\n        if (text) {\r\n          text.textContent = 'Invio in corso...';\r\n        }\r\n\r\n        try {\r\n          const response = await fetch(\r\n            ajaxUrl,\r\n            {\r\n              method: 'POST',\r\n              body: data,\r\n              credentials: 'same-origin'\r\n            }\r\n          );\r\n\r\n          const result = await response.json();\r\n\r\n          if (\r\n            !response.ok ||\r\n            !result?.success\r\n          ) {\r\n            setStatus(\r\n              result?.data?.message ||\r\n                'Si \u00e8 verificato un errore durante l\u2019invio. Riprova tra poco.',\r\n              'error'\r\n            );\r\n\r\n            resetCaptcha();\r\n            return;\r\n          }\r\n\r\n          setStatus(\r\n            'Messaggio inviato correttamente. Reindirizzamento in corso...',\r\n            'success'\r\n          );\r\n\r\n          form.reset();\r\n\r\n          if (fileName) {\r\n            fileName.textContent = '';\r\n          }\r\n\r\n          updateLabels();\r\n          resetCaptcha();\r\n\r\n          window.location.assign(\r\n            form.dataset.successUrl ||\r\n              result.data?.redirect_url ||\r\n              '\/grazie\/'\r\n          );\r\n        } catch (_) {\r\n          setStatus(\r\n            'Errore di connessione o risposta non valida. Riprova tra poco.',\r\n            'error'\r\n          );\r\n\r\n          resetCaptcha();\r\n        } finally {\r\n          submitting = false;\r\n\r\n          if (submit) {\r\n            submit.disabled = false;\r\n          }\r\n\r\n          if (text) {\r\n            text.textContent = originalText;\r\n          }\r\n        }\r\n      });\r\n    }\r\n\r\n    \/* NEWS WORDPRESS *\/\r\n\r\n    function initNews() {\r\n      const grid = document.querySelector('#mpNewsGrid');\r\n\r\n      if (!grid) return;\r\n\r\n      const fallbacks = [\r\n        'https:\/\/images.unsplash.com\/photo-1600607687920-4e2a09cf159d?auto=format&fit=crop&w=1200&q=85',\r\n        'https:\/\/images.unsplash.com\/photo-1600566752355-35792bedcfea?auto=format&fit=crop&w=1200&q=85',\r\n        'https:\/\/images.unsplash.com\/photo-1600566753190-17f0baa2a6c3?auto=format&fit=crop&w=1200&q=85'\r\n      ];\r\n\r\n      function plain(html) {\r\n        return new DOMParser()\r\n          .parseFromString(\r\n            html || '',\r\n            'text\/html'\r\n          )\r\n          .body.textContent || '';\r\n      }\r\n\r\n      function safeUrl(value, fallback) {\r\n        try {\r\n          const url = new URL(\r\n            value,\r\n            window.location.origin\r\n          );\r\n\r\n          return ['http:', 'https:'].includes(url.protocol)\r\n            ? url.href\r\n            : fallback;\r\n        } catch (_) {\r\n          return fallback;\r\n        }\r\n      }\r\n\r\n      function element(tag, className, text) {\r\n        const node = document.createElement(tag);\r\n\r\n        node.className = className;\r\n\r\n        if (text !== undefined) {\r\n          node.textContent = text;\r\n        }\r\n\r\n        return node;\r\n      }\r\n\r\n      function render(posts) {\r\n        grid.replaceChildren();\r\n\r\n        if (!posts.length) {\r\n          grid.append(\r\n            element(\r\n              'div',\r\n              'mp-news-empty',\r\n              'Al momento non ci sono notizie disponibili.'\r\n            )\r\n          );\r\n\r\n          return;\r\n        }\r\n\r\n        for (const [index, post] of posts.entries()) {\r\n          const title = plain(\r\n            post.title?.rendered\r\n          );\r\n\r\n          const excerpt = plain(\r\n            post.excerpt?.rendered\r\n          );\r\n\r\n          const media =\r\n            post._embedded?.['wp:featuredmedia']?.[0];\r\n\r\n          const sizes = media?.media_details?.sizes;\r\n\r\n          const imageUrl =\r\n            sizes?.large?.source_url ||\r\n            sizes?.medium_large?.source_url ||\r\n            sizes?.full?.source_url ||\r\n            media?.source_url;\r\n\r\n          const card = element(\r\n            'a',\r\n            'mp-news-card'\r\n          );\r\n\r\n          card.href = safeUrl(\r\n            post.link || '#',\r\n            '#'\r\n          );\r\n\r\n          card.setAttribute(\r\n            'aria-label',\r\n            `Leggi articolo: ${title}`\r\n          );\r\n\r\n          const cover = element(\r\n            'div',\r\n            'mp-news-image'\r\n          );\r\n\r\n          const img = document.createElement('img');\r\n\r\n          const fallback =\r\n            fallbacks[index % fallbacks.length];\r\n\r\n          img.src = safeUrl(\r\n            imageUrl || fallback,\r\n            fallback\r\n          );\r\n\r\n          img.alt = title;\r\n          img.loading = 'lazy';\r\n\r\n          cover.append(img);\r\n\r\n          const body = element(\r\n            'div',\r\n            'mp-news-body'\r\n          );\r\n\r\n          const date = new Date(post.date);\r\n\r\n          body.append(\r\n            element(\r\n              'span',\r\n              'mp-news-date',\r\n              Number.isNaN(date.getTime())\r\n                ? ''\r\n                : date.toLocaleDateString(\r\n                    'it-IT',\r\n                    {\r\n                      day: '2-digit',\r\n                      month: 'long',\r\n                      year: 'numeric'\r\n                    }\r\n                  )\r\n            ),\r\n\r\n            element(\r\n              'h3',\r\n              '',\r\n              title\r\n            ),\r\n\r\n            element(\r\n              'div',\r\n              'mp-news-divider'\r\n            ),\r\n\r\n            element(\r\n              'p',\r\n              '',\r\n              excerpt.length > 145\r\n                ? excerpt.substring(0, 145).trim() + ' [...]'\r\n                : excerpt\r\n            )\r\n          );\r\n\r\n          card.append(cover, body);\r\n          grid.append(card);\r\n        }\r\n      }\r\n\r\n      async function load() {\r\n        const endpoint = new URL(\r\n          grid.dataset.endpoint ||\r\n            '\/wp-json\/wp\/v2\/posts',\r\n          window.location.origin\r\n        );\r\n\r\n        endpoint.searchParams.set(\r\n          'per_page',\r\n          '3'\r\n        );\r\n\r\n        endpoint.searchParams.set(\r\n          '_embed',\r\n          '1'\r\n        );\r\n\r\n        if (grid.dataset.categoryId) {\r\n          endpoint.searchParams.set(\r\n            'categories',\r\n            grid.dataset.categoryId\r\n          );\r\n        }\r\n\r\n        try {\r\n          const response = await fetch(\r\n            endpoint,\r\n            {\r\n              credentials: 'same-origin'\r\n            }\r\n          );\r\n\r\n          if (!response.ok) {\r\n            throw new Error('News non disponibili');\r\n          }\r\n\r\n          const posts = await response.json();\r\n\r\n          if (!Array.isArray(posts)) {\r\n            throw new Error('Risposta non valida');\r\n          }\r\n\r\n          render(posts);\r\n        } catch (_) {\r\n          grid.replaceChildren(\r\n            element(\r\n              'div',\r\n              'mp-news-empty',\r\n              'Non \u00e8 stato possibile caricare le ultime notizie. Riprova pi\u00f9 tardi.'\r\n            )\r\n          );\r\n        }\r\n\r\n        requestAnimationFrame(onScroll);\r\n      }\r\n\r\n      load();\r\n    }\r\n  }\r\n\r\n  \/* AVVIO *\/\r\n\r\n  function start() {\r\n    if (\r\n      document.querySelector('#mp-fullpage-wrapper')\r\n    ) {\r\n      boot();\r\n      return;\r\n    }\r\n\r\n    const observer = new MutationObserver(() => {\r\n      if (\r\n        document.querySelector('#mp-fullpage-wrapper')\r\n      ) {\r\n        observer.disconnect();\r\n        boot();\r\n      }\r\n    });\r\n\r\n    observer.observe(\r\n      document.body,\r\n      {\r\n        childList: true,\r\n        subtree: true\r\n      }\r\n    );\r\n\r\n    setTimeout(() => {\r\n      observer.disconnect();\r\n    }, 15000);\r\n  }\r\n\r\n  if (document.readyState === 'loading') {\r\n    document.addEventListener(\r\n      'DOMContentLoaded',\r\n      start,\r\n      { once: true }\r\n    );\r\n  } else {\r\n    start();\r\n  }\r\n})();\r\n\r\n\/* FADE DEGLI ELEMENTI SU MOBILE \u2014 SCORRIMENTO NATIVO *\/\r\n\r\n(() => {\r\n  'use strict';\r\n\r\n  function initMobileFade() {\r\n    const wrapper = document.querySelector(\r\n      '#mp-fullpage-wrapper'\r\n    );\r\n\r\n    if (!wrapper) return;\r\n\r\n    if (\r\n      document.getElementById('mp-mobile-content-fade-style')\r\n    ) {\r\n      return;\r\n    }\r\n\r\n    const mobileQuery = window.matchMedia(\r\n      '(max-width: 1024px)'\r\n    );\r\n\r\n    const reducedQuery = window.matchMedia(\r\n      '(prefers-reduced-motion: reduce)'\r\n    );\r\n\r\n    const selector =\r\n      '.mp-kicker, .mp-content h1, .mp-content h2, ' +\r\n      '.mp-desc, .mp-btn, .mp-services-left, ' +\r\n      '.mp-services-image, .mp-quote-info, ' +\r\n      '.mp-quote-form-card, .mp-news-heading, .mp-news-card';\r\n\r\n    const style = document.createElement('style');\r\n\r\n    style.id = 'mp-mobile-content-fade-style';\r\n\r\n    style.textContent = `\r\n      html.mp-free-mobile body.mp-native-ready\r\n      #mp-fullpage-wrapper .mp-mobile-fade-item {\r\n        opacity: 1 !important;\r\n        visibility: visible !important;\r\n        transform: none !important;\r\n        animation: none !important;\r\n\r\n        transition:\r\n          opacity 800ms ease\r\n          var(--mp-mobile-fade-delay, 0ms) !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready\r\n      #mp-fullpage-wrapper\r\n      .mp-mobile-fade-item.mp-mobile-fade-hidden {\r\n        opacity: 0 !important;\r\n        transition: none !important;\r\n      }\r\n\r\n      html.mp-free-mobile body.mp-native-ready\r\n      #mp-fullpage-wrapper\r\n      .mp-mobile-fade-item.mp-mobile-fade-instant {\r\n        opacity: 1 !important;\r\n        transition: none !important;\r\n      }\r\n\r\n      @media (prefers-reduced-motion: reduce) {\r\n        html.mp-free-mobile body.mp-native-ready\r\n        #mp-fullpage-wrapper .mp-mobile-fade-item {\r\n          opacity: 1 !important;\r\n          transition: none !important;\r\n        }\r\n      }\r\n    `;\r\n\r\n    document.head.append(style);\r\n\r\n    const trackedItems = new Set();\r\n\r\n    let entryObserver = null;\r\n    let exitObserver = null;\r\n    let contentObserver = null;\r\n    let scanFrame = 0;\r\n\r\n    function reveal(item) {\r\n      item.classList.remove('mp-mobile-fade-hidden');\r\n    }\r\n\r\n    function resetItem(item) {\r\n      item.classList.remove(\r\n        'mp-mobile-fade-item',\r\n        'mp-mobile-fade-hidden',\r\n        'mp-mobile-fade-instant'\r\n      );\r\n\r\n      item.style.removeProperty(\r\n        '--mp-mobile-fade-delay'\r\n      );\r\n    }\r\n\r\n    function cleanup() {\r\n      entryObserver?.disconnect();\r\n      exitObserver?.disconnect();\r\n      contentObserver?.disconnect();\r\n\r\n      entryObserver = null;\r\n      exitObserver = null;\r\n      contentObserver = null;\r\n\r\n      cancelAnimationFrame(scanFrame);\r\n      scanFrame = 0;\r\n\r\n      trackedItems.forEach(resetItem);\r\n      trackedItems.clear();\r\n    }\r\n\r\n    function scanItems() {\r\n      scanFrame = 0;\r\n\r\n      if (!entryObserver || !exitObserver) return;\r\n\r\n      \/\/ Rimuove eventuali elementi sostituiti, ad esempio le news.\r\n      trackedItems.forEach(item => {\r\n        if (!wrapper.contains(item)) {\r\n          entryObserver.unobserve(item);\r\n          exitObserver.unobserve(item);\r\n\r\n          resetItem(item);\r\n          trackedItems.delete(item);\r\n        }\r\n      });\r\n\r\n      wrapper.querySelectorAll('.section').forEach(section => {\r\n        section.querySelectorAll(selector).forEach((item, index) => {\r\n          if (trackedItems.has(item)) return;\r\n\r\n          trackedItems.add(item);\r\n\r\n          item.classList.add('mp-mobile-fade-item');\r\n\r\n          item.style.setProperty(\r\n            '--mp-mobile-fade-delay',\r\n            `${Math.min(index, 3) * 45}ms`\r\n          );\r\n\r\n          const rect = item.getBoundingClientRect();\r\n\r\n          const alreadyVisible =\r\n            rect.bottom > 0 &&\r\n            rect.top < window.innerHeight;\r\n\r\n          \/*\r\n           * Non nasconde contenuti gi\u00e0 visibili quando\r\n           * lo script si avvia: evita il flash iniziale.\r\n           *\/\r\n          if (!alreadyVisible) {\r\n            item.classList.add('mp-mobile-fade-hidden');\r\n          }\r\n\r\n          entryObserver.observe(item);\r\n          exitObserver.observe(item);\r\n        });\r\n      });\r\n    }\r\n\r\n    function setup() {\r\n      cleanup();\r\n\r\n      if (\r\n        !mobileQuery.matches ||\r\n        reducedQuery.matches ||\r\n        !('IntersectionObserver' in window)\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      \/*\r\n       * Rivela gli elementi quando entrano nella\r\n       * parte visibile della finestra.\r\n       *\/\r\n      entryObserver = new IntersectionObserver(\r\n        entries => {\r\n          entries.forEach(entry => {\r\n            if (entry.isIntersecting) {\r\n              reveal(entry.target);\r\n            }\r\n          });\r\n        },\r\n        {\r\n          root: null,\r\n          threshold: 0,\r\n          rootMargin: '-6% 0px -8% 0px'\r\n        }\r\n      );\r\n\r\n      \/*\r\n       * Nasconde di nuovo un elemento solamente quando\r\n       * \u00e8 completamente fuori dallo schermo.\r\n       *\/\r\n      exitObserver = new IntersectionObserver(\r\n        entries => {\r\n          entries.forEach(entry => {\r\n            if (entry.isIntersecting) return;\r\n\r\n            const item = entry.target;\r\n            const rect = item.getBoundingClientRect();\r\n\r\n            const completelyOutside =\r\n              rect.bottom <= 0 ||\r\n              rect.top >= window.innerHeight;\r\n\r\n            if (\r\n              completelyOutside &&\r\n              !item.contains(document.activeElement)\r\n            ) {\r\n              item.classList.remove(\r\n                'mp-mobile-fade-instant'\r\n              );\r\n\r\n              item.classList.add(\r\n                'mp-mobile-fade-hidden'\r\n              );\r\n            }\r\n          });\r\n        },\r\n        {\r\n          root: null,\r\n          threshold: 0\r\n        }\r\n      );\r\n\r\n      scanItems();\r\n\r\n      \/\/ Include anche eventuali contenuti caricati successivamente.\r\n      contentObserver = new MutationObserver(() => {\r\n        if (!scanFrame) {\r\n          scanFrame = requestAnimationFrame(scanItems);\r\n        }\r\n      });\r\n\r\n      contentObserver.observe(wrapper, {\r\n        childList: true,\r\n        subtree: true\r\n      });\r\n    }\r\n\r\n    \/*\r\n     * Un elemento che riceve il focus deve essere\r\n     * immediatamente visibile, anche usando la tastiera.\r\n     *\/\r\n    wrapper.addEventListener('focusin', event => {\r\n      trackedItems.forEach(item => {\r\n        if (item.contains(event.target)) {\r\n          item.classList.add('mp-mobile-fade-instant');\r\n          reveal(item);\r\n        }\r\n      });\r\n    });\r\n\r\n    mobileQuery.addEventListener('change', setup);\r\n    reducedQuery.addEventListener('change', setup);\r\n\r\n    setup();\r\n  }\r\n\r\n  if (document.readyState === 'loading') {\r\n    document.addEventListener(\r\n      'DOMContentLoaded',\r\n      initMobileFade,\r\n      { once: true }\r\n    );\r\n  } else {\r\n    initMobileFade();\r\n  }\r\n})();<\/script><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>NOUS CONCEVONS ET FABRIQUONS ASCENSEURS, MONTE-CHARGES ET ESCALIERS M\u00c9CANIQUES, POUR UNE MOBILIT\u00c9 EFFICACE ET S\u00dbRE Nous analysons les besoins de chaque type de b\u00e2timent et garantissons la solution la plus adapt\u00e9e au client, de la conception \u00e0 l\u2019installation finale de l\u2019\u00e9quipement. ASCENSEURS Nous concevons et r\u00e9alisons des ascenseurs qui allient design, confort et grande fiabilit\u00e9. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-2098","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/millepiani.com\/fr\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"millepiani.com -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani\" \/>\n\t\t<meta property=\"og:description\" content=\"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/millepiani.com\/fr\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-05-13T20:09:45+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-09-15T22:12:01+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#listItem\",\"name\":\"Nouvelle page Ascenseurs\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#listItem\",\"position\":2,\"name\":\"Nouvelle page Ascenseurs\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#listItem\",\"name\":\"Home\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#organization\",\"name\":\"millepiani.com\",\"url\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#webpage\",\"url\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/\",\"name\":\"Ascenseurs, monte-charges et mobilit\\u00e9 verticale | Millepiani\",\"description\":\"Millepiani con\\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \\u00e9l\\u00e9vatrices, monte-escaliers et escaliers m\\u00e9caniques : des solutions s\\u00fbres, efficaces et sur mesure.\",\"inLanguage\":\"fr-FR\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#breadcrumblist\"},\"datePublished\":\"2026-05-13T20:09:45+00:00\",\"dateModified\":\"2026-09-15T22:12:01+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/\",\"name\":\"millepiani.com\",\"inLanguage\":\"fr-FR\",\"publisher\":{\"@id\":\"https:\\\/\\\/millepiani.com\\\/fr\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani","description":"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.","canonical_url":"https:\/\/millepiani.com\/fr\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/millepiani.com\/fr\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/millepiani.com\/fr\/#listItem","position":1,"name":"Home","item":"https:\/\/millepiani.com\/fr\/","nextItem":{"@type":"ListItem","@id":"https:\/\/millepiani.com\/fr\/#listItem","name":"Nouvelle page Ascenseurs"}},{"@type":"ListItem","@id":"https:\/\/millepiani.com\/fr\/#listItem","position":2,"name":"Nouvelle page Ascenseurs","previousItem":{"@type":"ListItem","@id":"https:\/\/millepiani.com\/fr\/#listItem","name":"Home"}}]},{"@type":"Organization","@id":"https:\/\/millepiani.com\/fr\/#organization","name":"millepiani.com","url":"https:\/\/millepiani.com\/fr\/"},{"@type":"WebPage","@id":"https:\/\/millepiani.com\/fr\/#webpage","url":"https:\/\/millepiani.com\/fr\/","name":"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani","description":"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.","inLanguage":"fr-FR","isPartOf":{"@id":"https:\/\/millepiani.com\/fr\/#website"},"breadcrumb":{"@id":"https:\/\/millepiani.com\/fr\/#breadcrumblist"},"datePublished":"2026-05-13T20:09:45+00:00","dateModified":"2026-09-15T22:12:01+00:00"},{"@type":"WebSite","@id":"https:\/\/millepiani.com\/fr\/#website","url":"https:\/\/millepiani.com\/fr\/","name":"millepiani.com","inLanguage":"fr-FR","publisher":{"@id":"https:\/\/millepiani.com\/fr\/#organization"}}]},"og:locale":"fr_FR","og:site_name":"millepiani.com -","og:type":"article","og:title":"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani","og:description":"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.","og:url":"https:\/\/millepiani.com\/fr\/","article:published_time":"2026-05-13T20:09:45+00:00","article:modified_time":"2026-09-15T22:12:01+00:00","twitter:card":"summary_large_image","twitter:title":"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani","twitter:description":"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure."},"aioseo_meta_data":{"post_id":"2098","title":"Ascenseurs, monte-charges et mobilit\u00e9 verticale | Millepiani","description":"Millepiani con\u00e7oit et fabrique des ascenseurs, monte-charges, plateformes \u00e9l\u00e9vatrices, monte-escaliers et escaliers m\u00e9caniques : des solutions s\u00fbres, efficaces et sur mesure.","keywords":null,"keyphrases":{"focus":{"keyphrase":"produttori ascensori","score":0,"analysis":[]},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_image_url":null,"twitter_title":null,"twitter_description":null,"schema_type":"default","schema_type_options":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"WebPage","isEnabled":true},"graphs":[]},"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"breadcrumb_settings":null,"seo_analyzer_scan_date":null,"created":"2026-09-10 10:57:34","updated":"2026-09-15 23:24:46","focus_keyword":"produttori ascensori","additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/millepiani.com\/fr\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tNouvelle page Ascenseurs\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/millepiani.com\/fr\/"},{"label":"Nouvelle page Ascenseurs","link":"https:\/\/millepiani.com\/fr\/"}],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/pages\/2098","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/comments?post=2098"}],"version-history":[{"count":18,"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/pages\/2098\/revisions"}],"predecessor-version":[{"id":2698,"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/pages\/2098\/revisions\/2698"}],"wp:attachment":[{"href":"https:\/\/millepiani.com\/fr\/wp-json\/wp\/v2\/media?parent=2098"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}