{"id":543,"date":"2025-10-27T14:38:23","date_gmt":"2025-10-27T14:38:23","guid":{"rendered":"https:\/\/www.ggrouproma.it\/?page_id=543"},"modified":"2026-02-04T10:14:42","modified_gmt":"2026-02-04T10:14:42","slug":"progetti-2","status":"publish","type":"page","link":"https:\/\/www.ggrouproma.it\/en\/progetti-2\/","title":{"rendered":"Projects"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"543\" class=\"elementor elementor-543\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bfc04ee e-flex e-con-boxed e-con e-parent\" data-id=\"bfc04ee\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b9b9099 elementor-widget elementor-widget-heading\" data-id=\"b9b9099\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">I nostri progetti<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-047236c e-flex e-con-boxed e-con e-parent\" data-id=\"047236c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-302e64e elementor-widget elementor-widget-text-editor\" data-id=\"302e64e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>I nostri progetti raccontano l\u2019impegno, la competenza e la qualit\u00e0 che mettiamo in ogni cantiere. Attraverso la mappa interattiva puoi esplorare alcune delle diverse opere realizzate e scoprire quelle di tuo interesse.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e830dd8 e-flex e-con-boxed e-con e-parent\" data-id=\"e830dd8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8840aea elementor-widget elementor-widget-html\" data-id=\"8840aea\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!-- ====== Leaflet & MarkerCluster ====== -->\r\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\" integrity=\"sha256-p4NxAoJBhIIN+hmNHrzRCf9tD\/miZyoHS5obTRR9BMY=\" crossorigin=\"\"\/>\r\n<script src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\" integrity=\"sha256-20nQCchB9co0qIjJZRGuk2\/Z9VM+kNiyxNV1lvTlZBo=\" crossorigin=\"\"><\/script>\r\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.5.3\/dist\/MarkerCluster.css\"\/>\r\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.5.3\/dist\/MarkerCluster.Default.css\"\/>\r\n<script src=\"https:\/\/unpkg.com\/leaflet.markercluster@1.5.3\/dist\/leaflet.markercluster.js\"><\/script>\r\n\r\n<style>\r\n  :root{--bg:#0f172a;--panel:#111827;--muted:#94a3b8;--text:#e5e7eb;--accent:#22c55e;--done:#9ca3af;--link:#60a5fa;--ring:rgba(96,165,250,.4)}\r\n  .projwrap{background:var(--bg);color:var(--text);font-family:system-ui,-apple-system,Segoe UI,Roboto,Inter;border-radius:12px;overflow:hidden}\r\n  .projwrap header{padding:16px 20px;border-bottom:1px solid #1f2937;display:flex;gap:16px;align-items:center;flex-wrap:wrap;background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0))}\r\n  .projwrap header h1{font-size:20px;margin:0}\r\n  .filters{display:flex;gap:8px;align-items:center}\r\n  .filters .btn{appearance:none;border:1px solid #1f2937;background:#0b1220;color:var(--text);padding:8px 12px;border-radius:999px;cursor:pointer;font-weight:600;font-size:14px}\r\n  .filters .btn[aria-pressed=\"true\"]{outline:2px solid var(--ring);background:#0d1b2a}\r\n  .legend{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:14px}\r\n  .dot{width:10px;height:10px;border-radius:999px;display:inline-block}.dot.ongoing{background:var(--accent)}.dot.completed{background:var(--done)}\r\n  .layout{display:grid;grid-template-columns:360px 1fr;height:560px}\r\n  @media (max-width:980px){.layout{grid-template-columns:1fr;grid-template-rows:320px 1fr;height:760px}}\r\n  aside{border-right:1px solid #1f2937;background:var(--panel);overflow:hidden;display:grid;grid-template-rows:auto 1fr}\r\n  .searchbar{padding:12px;display:flex;gap:8px}\r\n  .searchbar input{flex:1;padding:10px 12px;border-radius:10px;border:1px solid #1f2937;background:#0b1220;color:var(--text)}\r\n  .list{overflow:auto}\r\n  .card{padding:12px;border-bottom:1px solid #1f2937;cursor:pointer;display:grid;grid-template-columns:56px 1fr;gap:12px;align-items:center}\r\n  .card:hover{background:rgba(255,255,255,.02)}\r\n  .badge{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;padding:4px 8px;border-radius:999px;display:inline-flex;align-items:center;gap:6px;border:1px solid #1f2937}\r\n  .badge.ongoing{color:var(--accent)}.badge.completed{color:var(--done)}\r\n  .thumb{width:56px;height:56px;background:#0b1220;border:1px solid #1f2937;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--muted);overflow:hidden}\r\n  .thumb img{width:100%;height:100%;object-fit:cover;display:block}\r\n  .title{font-weight:700;margin:0;font-size:15px}\r\n  .meta{color:var(--muted);font-size:13px}\r\n  #map{width:100%;height:100%}\r\n  .leaflet-popup-content-wrapper{background:#0b1220;color:var(--text);border:1px solid #1f2937;border-radius:12px}\r\n  .leaflet-popup-tip{background:#0b1220}\r\n  .popup-title{font-weight:800;margin:0 0 6px;font-size:16px}\r\n  .popup-meta{color:var(--muted);font-size:13px;margin-bottom:6px}\r\n  .popup-actions a{color:var(--link);text-decoration:none;font-weight:600}\r\n  .poi{background:#0b1220;color:#e5e7eb;border:1px solid #1f2937;border-radius:999px;padding:6px 9px;font-size:12px;font-weight:800;box-shadow:0 6px 16px rgba(0,0,0,.35);display:inline-flex;align-items:center;gap:6px}\r\n  .poi .dot{width:8px;height:8px}\r\n  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\r\n<\/style>\r\n\r\n<div class=\"projwrap\">\r\n  <header>\r\n    <h1>Progetti<\/h1>\r\n    <nav class=\"filters\" aria-label=\"Filtri stato progetti\">\r\n      <button class=\"btn\" data-filter=\"all\" aria-pressed=\"true\">Tutti<\/button>\r\n      <button class=\"btn\" data-filter=\"ongoing\" aria-pressed=\"false\">In corso<\/button>\r\n      <button class=\"btn\" data-filter=\"completed\" aria-pressed=\"false\">Conclusi<\/button>\r\n    <\/nav>\r\n    <div class=\"legend\" aria-hidden=\"true\">\r\n      <span class=\"dot ongoing\"><\/span> In corso\r\n      <span class=\"dot completed\" style=\"margin-left:12px;\"><\/span> Conclusi\r\n    <\/div>\r\n  <\/header>\r\n\r\n  <div class=\"layout\">\r\n    <aside>\r\n      <div class=\"searchbar\">\r\n        <label for=\"q\" class=\"sr-only\">Cerca progetti<\/label>\r\n        <input id=\"q\" type=\"search\" placeholder=\"Cerca per titolo, citt\u00e0, regione\u2026\" autocomplete=\"off\" \/>\r\n      <\/div>\r\n      <div id=\"list\" class=\"list\" role=\"list\"><\/div>\r\n    <\/aside>\r\n    <main id=\"map\" aria-label=\"Mappa dei progetti\"><\/main>\r\n  <\/div>\r\n<\/div>\r\n\r\n<!-- QUI imposto l'URL del JSON (con cache-buster) -->\r\n<script>\r\n  window.PROGETTI_DATA_URL = \"https:\/\/www.ggrouproma.it\/wp-content\/uploads\/2026\/02\/progetti3.json\";\r\n<\/script>\r\n\r\n<script>\r\n  const ITALY_CENTER = [45.0, 10.5]; \/\/ vicino al Garda\r\n  const ITALY_ZOOM = 8;\r\n\r\n  const DATA_URL = (window.PROGETTI_DATA_URL) || 'progetti.json';\r\n\r\n  const FALLBACK = []; \/\/ niente fallback: cos\u00ec noti subito se il JSON non carica\r\n\r\n  async function loadData() {\r\n    try {\r\n      const res = await fetch(DATA_URL, { cache: 'no-store' });\r\n      if (!res.ok) throw new Error('HTTP ' + res.status);\r\n      const items = await res.json();\r\n      if (!Array.isArray(items)) throw new Error('Il JSON DEVE essere un array []');\r\n      return items;\r\n    } catch (e) {\r\n      console.error('Errore caricamento dati:', e.message);\r\n\r\n      \/\/ Mostra errore anche a schermo (utile quando sul sito pubblico la cache\/CORS blocca tutto)\r\n      const listEl = document.getElementById('list');\r\n      if (listEl) {\r\n        listEl.innerHTML = `<div style=\"padding:12px;color:#e5e7eb;\">\r\n          <strong>Errore caricamento progetti<\/strong><br>\r\n          <small>${DATA_URL}<br>${e.message}<\/small>\r\n        <\/div>`;\r\n      }\r\n\r\n      return FALLBACK;\r\n    }\r\n  }\r\n\r\n  function markerIcon(stato) {\r\n    return L.divIcon({\r\n      className: 'poi-icon',\r\n      html: `<span class=\"poi\"><span class=\"dot ${stato}\"><\/span>${stato === 'ongoing' ? 'In corso' : 'Concluso'}<\/span>`,\r\n      iconSize: [82, 26],\r\n      iconAnchor: [41, 13],\r\n      popupAnchor: [0, -10]\r\n    });\r\n  }\r\n\r\n  function projectCard(p) {\r\n    const badgeClass = p.stato === 'ongoing' ? 'ongoing' : 'completed';\r\n    const periodo = p.fine ? `${p.inizio}\u2013${p.fine}` : `${p.inizio}\u2013oggi`;\r\n    return `\r\n      <div class=\"card\" role=\"listitem\" data-id=\"${p.id}\">\r\n        <div class=\"thumb\">${p.immagine ? `<img decoding=\"async\" src=\"${p.immagine}\" alt=\"\">` : '\u2014'}<\/div>\r\n        <div>\r\n          <div class=\"badge ${badgeClass}\">${p.stato === 'ongoing' ? 'In corso' : 'Concluso'}<\/div>\r\n          <p class=\"title\">${p.titolo}<\/p>\r\n          <p class=\"meta\">${p.citta || ''}${p.citta ? ', ' : ''}${p.regione || ''} \u2022 ${periodo}<\/p>\r\n        <\/div>\r\n      <\/div>`;\r\n  }\r\n\r\n  function euro(n) {\r\n    try { return new Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR' }).format(n); }\r\n    catch { return (typeof n==='number') ? n.toLocaleString('it-IT') : n; }\r\n  }\r\n\r\n  function projectPopup(p) {\r\n    const periodo = p.fine ? `${p.inizio}\u2013${p.fine}` : `${p.inizio}\u2013oggi`;\r\n    const comm = p.committente ? `<div class=\"popup-meta\">Committente: <strong>${p.committente}<\/strong><\/div>` : '';\r\n    const imp = (p.importo_eur || p.importo) ? `<div class=\"popup-meta\">Importo: <strong>${p.importo_eur || euro(p.importo)}<\/strong><\/div>` : '';\r\n    const link = p.url ? `<div class=\"popup-actions\"><a href=\"${p.url}\" target=\"_blank\" rel=\"noopener\">Dettagli progetto \u2197<\/a><\/div>` : '';\r\n    return `\r\n      <div class=\"popup\">\r\n        <p class=\"popup-title\">${p.titolo}<\/p>\r\n        <p class=\"popup-meta\">${p.citta || ''}${p.citta ? ', ' : ''}${p.regione || ''} \u2022 ${periodo} \u2022 ${p.stato === 'ongoing' ? 'In corso' : 'Concluso'}<\/p>\r\n        ${comm}${imp}${link}\r\n      <\/div>`;\r\n  }\r\n\r\n  (async function init() {\r\n    const data = await loadData();\r\n    window.__PROGETTI_DATA = data; \/\/ esponi dati per la griglia\r\n\r\n    const map = L.map('map', { zoomControl: true, scrollWheelZoom: true }).setView(ITALY_CENTER, ITALY_ZOOM);\r\n    window.map = map;\r\n\r\n    L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', { attribution: '&copy; OpenStreetMap', maxZoom: 18 }).addTo(map);\r\n\r\n    const clusters = L.markerClusterGroup({ chunkedLoading: true, showCoverageOnHover: false, maxClusterRadius: 40 });\r\n\r\n    const markersById = new Map();\r\n    window.__MARKERS_BY_ID = markersById;\r\n\r\n    function addMarker(p) {\r\n      const m = L.marker([p.lat, p.lng], { icon: markerIcon(p.stato) }).bindPopup(projectPopup(p));\r\n      m.on('click', () => highlightListItem(p.id));\r\n      markersById.set(p.id, m);\r\n      clusters.addLayer(m);\r\n    }\r\n    data.forEach(addMarker);\r\n    map.addLayer(clusters);\r\n\r\n    if (data.length > 0) {\r\n      if (data.length === 1) {\r\n        const only = data[0];\r\n        map.setView([only.lat, only.lng], 12);\r\n        markersById.get(only.id)?.openPopup();\r\n      } else {\r\n        const group = new L.featureGroup(Array.from(markersById.values()));\r\n        map.fitBounds(group.getBounds().pad(0.2));\r\n      }\r\n    }\r\n\r\n    const listEl = document.getElementById('list');\r\n    function renderList(items) { listEl.innerHTML = items.map(projectCard).join(''); }\r\n    renderList(data);\r\n\r\n    listEl.addEventListener('click', (e) => {\r\n      const card = e.target.closest('.card'); if (!card) return;\r\n      const id = card.getAttribute('data-id'); const marker = markersById.get(id);\r\n      if (marker) {\r\n        map.setView(marker.getLatLng(), Math.max(map.getZoom(), 12), { animate: true });\r\n        marker.openPopup();\r\n        listEl.querySelectorAll('.card').forEach(el => el.style.background = '');\r\n        card.style.background = 'rgba(255,255,255,.04)';\r\n      }\r\n    });\r\n\r\n    function highlightListItem(id) {\r\n      const target = listEl.querySelector(`.card[data-id=\"${id}\"]`); if (!target) return;\r\n      listEl.querySelectorAll('.card').forEach(el => el.style.background = '');\r\n      target.style.background = 'rgba(255,255,255,.04)';\r\n      target.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n    }\r\n\r\n    const buttons = Array.from(document.querySelectorAll('.filters .btn'));\r\n    function setFilter(filter) {\r\n      buttons.forEach(b => b.setAttribute('aria-pressed', String(b.dataset.filter === filter)));\r\n      clusters.clearLayers(); markersById.clear();\r\n      const filtered = data.filter(p => filter === 'all' ? true : p.stato === filter);\r\n      filtered.forEach(addMarker); map.addLayer(clusters);\r\n      if (filtered.length > 0) {\r\n        if (filtered.length === 1) map.setView([filtered[0].lat, filtered[0].lng], 12);\r\n        else {\r\n          const group = new L.featureGroup(Array.from(markersById.values()));\r\n          map.fitBounds(group.getBounds().pad(0.2));\r\n        }\r\n      }\r\n      renderList(filtered);\r\n      window.__PROGETTI_DATA_FILTERED = filtered;\r\n    }\r\n    buttons.forEach(b => b.addEventListener('click', () => setFilter(b.dataset.filter)));\r\n\r\n    const q = document.getElementById('q');\r\n    q.addEventListener('input', () => {\r\n      const term = q.value.trim().toLowerCase();\r\n      const filtered = data.filter(p => `${p.titolo} ${p.citta||''} ${p.regione||''}`.toLowerCase().includes(term));\r\n      renderList(filtered);\r\n      clusters.clearLayers(); markersById.clear();\r\n      filtered.forEach(addMarker);\r\n      map.addLayer(clusters);\r\n      window.__PROGETTI_DATA_FILTERED = filtered;\r\n    });\r\n  })();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-accdbc1 e-flex e-con-boxed e-con e-parent\" data-id=\"accdbc1\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3c7edd5 elementor-widget elementor-widget-html\" data-id=\"3c7edd5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<section id=\"grid-progetti\" style=\"margin-top:28px\">\r\n  <h2 style=\"margin:0 0 12px;font:700 22px\/1.3 system-ui,-apple-system,Segoe UI,Roboto\">Elenco dei cantieri <\/h2>\r\n  <div id=\"grid-progetti-wrap\" class=\"grid-progetti\"><\/div>\r\n<\/section>\r\n\r\n<style>\r\n  .grid-progetti{\r\n    display:grid;\r\n    grid-template-columns:repeat(auto-fill,minmax(260px,1fr));\r\n    gap:14px\r\n  }\r\n\r\n  .gp-card{\r\n    border:1px solid rgba(0,0,0,.12);\r\n    border-radius:12px;\r\n    padding:12px;\r\n    background:rgba(255,255,255,.02);\r\n    display:flex;\r\n    flex-direction:column;\r\n    gap:8px;\r\n    height:100%\r\n  }\r\n\r\n  .gp-thumb{\r\n    width:100%;\r\n    height:160px;\r\n    border-radius:10px;\r\n    overflow:hidden;\r\n    border:1px solid rgba(0,0,0,.08);\r\n    background:#0b1220;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center\r\n  }\r\n\r\n  .gp-thumb img{\r\n    width:100%;\r\n    height:100%;\r\n    object-fit:cover;\r\n    display:block\r\n  }\r\n\r\n  .gp-title{\r\n    font-weight:800;\r\n    font-size:16px;\r\n    margin:0\r\n  }\r\n\r\n  .gp-meta{\r\n    font-size:13px;\r\n    color:#64748b\r\n  }\r\n\r\n  .gp-badge{\r\n    display:inline-block;\r\n    font-size:11px;\r\n    font-weight:800;\r\n    text-transform:uppercase;\r\n    letter-spacing:.4px;\r\n    border:1px solid rgba(0,0,0,.12);\r\n    border-radius:999px;\r\n    padding:3px 8px\r\n  }\r\n  .gp-badge.ongoing{color:#22c55e}\r\n  .gp-badge.completed{color:#9ca3af}\r\n\r\n  .gp-actions{\r\n    margin-top:auto;\r\n    display:flex;\r\n    gap:8px;\r\n    flex-wrap:wrap\r\n  }\r\n\r\n  \/* \ud83d\udd35 NUOVO STILE PULSANTE \u2013 COME RICHIESTO *\/\r\n  .gp-btn{\r\n    appearance:none;\r\n    border:1px solid rgba(0,0,0,.12);\r\n    background:#ffffff !important;        \/* sfondo bianco *\/\r\n    border-radius:10px;\r\n    padding:8px 10px;\r\n    cursor:pointer;\r\n    font-weight:700;\r\n    text-decoration:none;\r\n    color:#1d4ed8 !important;             \/* blu scuro *\/\r\n    transition:background .2s, color .2s;\r\n  }\r\n\r\n  \/* Hover \u2192 blu scuro + testo bianco *\/\r\n  .gp-btn:hover{\r\n    background:#1d4ed8 !important;\r\n    color:#ffffff !important;\r\n  }\r\n\r\n  \/* Click \u2192 blu pi\u00f9 scuro *\/\r\n  .gp-btn:active{\r\n    background:#1e40af !important;\r\n    color:#ffffff !important;\r\n  }\r\n<\/style>\r\n\r\n<script>\r\n(async function(){\r\n  const DATA_URL = window.PROGETTI_DATA_URL || 'progetti.json';\r\n\r\n  let items = (Array.isArray(window.__PROGETTI_DATA) && window.__PROGETTI_DATA.length)\r\n    ? window.__PROGETTI_DATA\r\n    : null;\r\n\r\n  if(!items){\r\n    try{\r\n      const r = await fetch(DATA_URL,{cache:'no-store'});\r\n      if(r.ok) items = await r.json();\r\n    }catch(e){\r\n      console.warn(\"Errore caricamento dati:\", e);\r\n    }\r\n  }\r\n\r\n  if(!Array.isArray(items)){\r\n    console.warn('Dataset non disponibile');\r\n    return;\r\n  }\r\n\r\n  \/\/ Ordina per importo DESC\r\n  const sorted = items.slice().sort((a,b)=> (b.importo||0) - (a.importo||0));\r\n\r\n  const wrap = document.getElementById('grid-progetti-wrap');\r\n\r\n  const eur = n =>\r\n    (typeof n==='number')\r\n      ? new Intl.NumberFormat('it-IT',{style:'currency',currency:'EUR'}).format(n)\r\n      : (n||'');\r\n\r\n  const card = p => {\r\n    const hasImg = p.immagine && String(p.immagine).trim() !== '';\r\n    const badge = p.stato === 'ongoing' ? 'ongoing' : 'completed';\r\n    const metaCity = [p.citta, p.regione].filter(Boolean).join(', ');\r\n    const periodo = p.fine ? `${p.inizio||''}\u2013${p.fine}` : (p.inizio?`${p.inizio}\u2013oggi`:'' );\r\n    const linkDett = p.url\r\n      ? `<a class=\"gp-btn\" href=\"${p.url}\" target=\"_blank\" rel=\"noopener\">Dettagli progetto \u2197<\/a>`\r\n      : '';\r\n    const comm = p.committente ? `<div class=\"gp-meta\">Committente: <strong>${p.committente}<\/strong><\/div>` : '';\r\n    const imp = (p.importo_eur || p.importo)\r\n      ? `<div class=\"gp-meta\">Importo: <strong>${p.importo_eur || eur(p.importo)}<\/strong><\/div>`\r\n      : '';\r\n\r\n    return `\r\n      <article class=\"gp-card\" data-id=\"${p.id}\">\r\n        <span class=\"gp-badge ${badge}\">${p.stato==='ongoing'?'In corso':'Concluso'}<\/span>\r\n        ${hasImg ? `<div class=\"gp-thumb\"><img decoding=\"async\" src=\"${p.immagine}\" alt=\"\"><\/div>` : ''}\r\n        <h3 class=\"gp-title\">${p.titolo}<\/h3>\r\n        <div class=\"gp-meta\">${metaCity}${metaCity && periodo ? ' \u2022 ' : ''}${periodo}<\/div>\r\n        ${comm}${imp}\r\n        <div class=\"gp-actions\">\r\n          <button type=\"button\" class=\"gp-btn\" data-action=\"focus-map\">Mostra su mappa<\/button>\r\n          ${linkDett}\r\n        <\/div>\r\n      <\/article>\r\n    `;\r\n  };\r\n\r\n  wrap.innerHTML = sorted.map(card).join('');\r\n\r\n  \/\/ Funzione \"Mostra su mappa\"\r\n  const markers = window.__MARKERS_BY_ID || window.markersById || null;\r\n  const map = window.map || null;\r\n\r\n  wrap.addEventListener('click', (e)=>{\r\n    const btn = e.target.closest('button[data-action=\"focus-map\"]');\r\n    if(!btn) return;\r\n\r\n    const card = e.target.closest('.gp-card');\r\n    const id = card && card.getAttribute('data-id');\r\n    if(!id) return;\r\n\r\n    if(markers && map){\r\n      const marker = markers.get ? markers.get(id) : markers[id];\r\n      if(marker && marker.getLatLng){\r\n        map.setView(marker.getLatLng(), 12, {animate:true});\r\n        marker.openPopup();\r\n      }\r\n    } else {\r\n      const mapEl = document.getElementById('map');\r\n      if(mapEl && mapEl.scrollIntoView){\r\n        mapEl.scrollIntoView({behavior:'smooth', block:'start'});\r\n      }\r\n    }\r\n  });\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>I nostri progetti I nostri progetti raccontano l\u2019impegno, la competenza e la qualit\u00e0 che mettiamo in ogni cantiere. Attraverso la [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_templately_pack_id":"","_templately_imported_at":"","_templately_source":"","_templately_import_session_id":"","site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-543","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Progetti - G.Group srl<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.ggrouproma.it\/en\/progetti-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Progetti - G.Group srl\" \/>\n<meta property=\"og:description\" content=\"I nostri progetti I nostri progetti raccontano l\u2019impegno, la competenza e la qualit\u00e0 che mettiamo in ogni cantiere. Attraverso la [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.ggrouproma.it\/en\/progetti-2\/\" \/>\n<meta property=\"og:site_name\" content=\"G.Group srl\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-04T10:14:42+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/progetti-2\\\/\",\"url\":\"https:\\\/\\\/www.ggrouproma.it\\\/progetti-2\\\/\",\"name\":\"Progetti - G.Group srl\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#website\"},\"datePublished\":\"2025-10-27T14:38:23+00:00\",\"dateModified\":\"2026-02-04T10:14:42+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/progetti-2\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.ggrouproma.it\\\/progetti-2\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/progetti-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.ggrouproma.it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Progetti\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#website\",\"url\":\"https:\\\/\\\/www.ggrouproma.it\\\/\",\"name\":\"G.Group srl\",\"description\":\"Infrastrutture e Fabbricati civili ed industriali\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.ggrouproma.it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#organization\",\"name\":\"G.Group srl\",\"url\":\"https:\\\/\\\/www.ggrouproma.it\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.ggrouproma.it\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/Logo-new-G-Group-scaled.png\",\"contentUrl\":\"https:\\\/\\\/www.ggrouproma.it\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/Logo-new-G-Group-scaled.png\",\"width\":2560,\"height\":702,\"caption\":\"G.Group srl\"},\"image\":{\"@id\":\"https:\\\/\\\/www.ggrouproma.it\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Progetti - G.Group srl","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.ggrouproma.it\/en\/progetti-2\/","og_locale":"en_GB","og_type":"article","og_title":"Progetti - G.Group srl","og_description":"I nostri progetti I nostri progetti raccontano l\u2019impegno, la competenza e la qualit\u00e0 che mettiamo in ogni cantiere. Attraverso la [&hellip;]","og_url":"https:\/\/www.ggrouproma.it\/en\/progetti-2\/","og_site_name":"G.Group srl","article_modified_time":"2026-02-04T10:14:42+00:00","twitter_card":"summary_large_image","twitter_misc":{"Estimated reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.ggrouproma.it\/progetti-2\/","url":"https:\/\/www.ggrouproma.it\/progetti-2\/","name":"Progetti - G.Group srl","isPartOf":{"@id":"https:\/\/www.ggrouproma.it\/#website"},"datePublished":"2025-10-27T14:38:23+00:00","dateModified":"2026-02-04T10:14:42+00:00","breadcrumb":{"@id":"https:\/\/www.ggrouproma.it\/progetti-2\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.ggrouproma.it\/progetti-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.ggrouproma.it\/progetti-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.ggrouproma.it\/"},{"@type":"ListItem","position":2,"name":"Progetti"}]},{"@type":"WebSite","@id":"https:\/\/www.ggrouproma.it\/#website","url":"https:\/\/www.ggrouproma.it\/","name":"G.Group srl","description":"Infrastrutture e Fabbricati civili ed industriali","publisher":{"@id":"https:\/\/www.ggrouproma.it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.ggrouproma.it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/www.ggrouproma.it\/#organization","name":"G.Group srl","url":"https:\/\/www.ggrouproma.it\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.ggrouproma.it\/#\/schema\/logo\/image\/","url":"https:\/\/www.ggrouproma.it\/wp-content\/uploads\/2025\/02\/Logo-new-G-Group-scaled.png","contentUrl":"https:\/\/www.ggrouproma.it\/wp-content\/uploads\/2025\/02\/Logo-new-G-Group-scaled.png","width":2560,"height":702,"caption":"G.Group srl"},"image":{"@id":"https:\/\/www.ggrouproma.it\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/pages\/543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/comments?post=543"}],"version-history":[{"count":68,"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/pages\/543\/revisions"}],"predecessor-version":[{"id":1291,"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/pages\/543\/revisions\/1291"}],"wp:attachment":[{"href":"https:\/\/www.ggrouproma.it\/en\/wp-json\/wp\/v2\/media?parent=543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}