{"id":15563,"date":"2026-06-09T10:02:46","date_gmt":"2026-06-09T10:02:46","guid":{"rendered":"https:\/\/www.milleniumproperties.ch\/projets-immobiliers-neufs\/"},"modified":"2026-10-15T13:25:39","modified_gmt":"2026-10-15T13:25:39","slug":"geneva-new-build-properties","status":"publish","type":"page","link":"https:\/\/www.milleniumproperties.ch\/en\/geneva-new-build-properties\/","title":{"rendered":"Projets immobiliers neufs"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"15563\" class=\"elementor elementor-15563 elementor-3178\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2632101 e-con-full e-flex e-con e-parent\" data-id=\"2632101\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-39a481d e-con-full e-flex e-con e-child\" data-id=\"39a481d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0386373 elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"0386373\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">New build projects<\/p>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1b37be8 e-con-full e-flex e-con e-parent\" data-id=\"1b37be8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c77d1a8 elementor-widget elementor-widget-shortcode\" data-id=\"c77d1a8\" 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\">\n    <div id=\"carte-biens-filtres-overlay\"><\/div>\n\n    <div id=\"carte-biens-filtres\">\n        <button type=\"button\" id=\"btn-fermer-filtres-croix\" aria-label=\"Close\">\n            <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"5\" y1=\"5\" x2=\"19\" y2=\"19\"\/><line x1=\"19\" y1=\"5\" x2=\"5\" y2=\"19\"\/><\/svg>\n        <\/button>\n        <div class=\"filtre-champ\">\n            <label for=\"filtre-recherche\">Search<\/label>\n            <input type=\"text\" id=\"filtre-recherche\" placeholder=\"e.g. 1292, Chamb\u00e9sy or a reference\">\n        <\/div>\n                <div class=\"filtre-champ\">\n            <label for=\"filtre-type-bien\">Property type<\/label>\n            <select id=\"filtre-type-bien\">\n                <option value=\"\">All<\/option>\n                <option value=\"Appartement\">Apartment<\/option>\n                <option value=\"Maison\">House<\/option>\n                <option value=\"Commercial\">Commercial<\/option>\n            <\/select>\n        <\/div>\n        <div class=\"filtre-champ\">\n            <label for=\"filtre-pieces\">Rooms<\/label>\n            <select id=\"filtre-pieces\">\n                <option value=\"\">All<\/option>\n                <option value=\"1\">1<\/option>\n                <option value=\"2\">2<\/option>\n                <option value=\"3\">3<\/option>\n                <option value=\"4\">4<\/option>\n                <option value=\"5\">5<\/option>\n                <option value=\"6\">6+<\/option>\n            <\/select>\n        <\/div>\n        <div class=\"filtre-champ\">\n            <label for=\"filtre-prix-min\">Min price (CHF)<\/label>\n            <input type=\"number\" id=\"filtre-prix-min\" placeholder=\"0\" min=\"0\" step=\"10000\">\n        <\/div>\n        <div class=\"filtre-champ\">\n            <label for=\"filtre-prix-max\">Max price (CHF)<\/label>\n            <input type=\"number\" id=\"filtre-prix-max\" placeholder=\"No max\" min=\"0\" step=\"10000\">\n        <\/div>\n        <button type=\"button\" id=\"btn-fermer-filtres\">View results<\/button>\n        <button type=\"button\" id=\"btn-reset-filtres\">Reset search<\/button>\n    <\/div>\n\n    <div id=\"carte-biens-topbar\">\n        <button type=\"button\" id=\"btn-ouvrir-filtres\">\n            <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"4\" y1=\"6\" x2=\"20\" y2=\"6\"\/><circle cx=\"9\" cy=\"6\" r=\"2\" fill=\"currentColor\" stroke=\"none\"\/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"\/><circle cx=\"15\" cy=\"12\" r=\"2\" fill=\"currentColor\" stroke=\"none\"\/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"\/><circle cx=\"7\" cy=\"18\" r=\"2\" fill=\"currentColor\" stroke=\"none\"\/><\/svg>\n            Filters            <span id=\"badge-filtres-actifs\" class=\"filtres-badge\"><\/span>\n        <\/button>\n\n        <div id=\"carte-biens-ligne-resultats\">\n            <div id=\"carte-biens-compteur\"><\/div>\n            <button type=\"button\" id=\"btn-toggle-vue\">\n                <span id=\"icone-vue-carte\">\n                    <svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"currentColor\"><path d=\"M15 5.1L9 3 3 5.1v15.8l6-2.1 6 2.1 6-2.1V3l-6 2.1zM9 5.2l6-1.9v15.5l-6 1.9V5.2z\"\/><\/svg>\n                <\/span>\n                <span id=\"icone-vue-liste\">\n                    <svg viewBox=\"0 0 24 24\" width=\"15\" height=\"15\" fill=\"currentColor\"><rect x=\"3\" y=\"4\" width=\"4\" height=\"4\"\/><rect x=\"9\" y=\"4\" width=\"12\" height=\"4\"\/><rect x=\"3\" y=\"10\" width=\"4\" height=\"4\"\/><rect x=\"9\" y=\"10\" width=\"12\" height=\"4\"\/><rect x=\"3\" y=\"16\" width=\"4\" height=\"4\"\/><rect x=\"9\" y=\"16\" width=\"12\" height=\"4\"\/><\/svg>\n                <\/span>\n                <span id=\"btn-toggle-vue-texte\">Map<\/span>\n            <\/button>\n        <\/div>\n    <\/div>\n    <div id=\"carte-biens-topbar-spacer\"><\/div>\n\n    <div id=\"carte-biens-wrapper\">\n        <div id=\"liste-biens\"><\/div>\n\n        <div id=\"carte-biens-zone\">\n            <div id=\"carte-biens\"><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    window.biensData = [{\"titre\":\"Exceptional THPE villa 3 minutes from the lake \\u2013 Collonge-Bellerive\",\"lien\":\"https:\\\/\\\/www.milleniumproperties.ch\\\/en\\\/for-sale\\\/house\\\/collonge-bellerive\\\/sh2456\\\/\",\"lat\":46.255284262490555,\"lng\":6.1996039699359775,\"prix\":5640000,\"prix_affiche\":true,\"image\":\"https:\\\/\\\/www.immomigimg.ch\\\/s\\\/eb365\\\/1435\\\/pictures\\\/objects\\\/1435_6a3e61bc043927.15177009.jpg\",\"commune\":\"Collonge-Bellerive\",\"transaction\":\"vente\",\"type_bien\":\"maison\",\"reference\":\"SH2456\",\"npa\":\"1245\",\"surface\":\"274\",\"pieces\":7,\"chambres\":\"4\",\"nouveau\":false,\"statut_label\":\"\"},{\"titre\":\"VILLAS STIERLIN\",\"lien\":\"https:\\\/\\\/www.milleniumproperties.ch\\\/en\\\/for-sale\\\/house\\\/meyrin\\\/km-sh-2388\\\/\",\"lat\":46.24015844125153,\"lng\":6.090663942697419,\"prix\":1490000,\"prix_affiche\":true,\"image\":\"https:\\\/\\\/www.immomigimg.ch\\\/s\\\/dda57\\\/1435\\\/pictures\\\/objects\\\/1435_6a1ae35877ce26.46008256.jpg\",\"commune\":\"Meyrin\",\"transaction\":\"vente\",\"type_bien\":\"maison\",\"reference\":\"KM\\\/SH 2388\",\"npa\":\"1217\",\"surface\":\"150\",\"pieces\":5,\"chambres\":\"3\",\"nouveau\":false,\"statut_label\":\"\"}];\n    window.carteBiensCategorie = \"neuf\";\n    window.carteBiensI18n = {\"prixSurDemande\":\"Price on request\",\"surDemande\":\"On request\",\"parMois\":\" \\\/ month\",\"nouveau\":\"New\",\"aucunResultat\":\"No property matches these criteria.\",\"vueCarte\":\"Map\",\"vueListe\":\"List\",\"pieceUn\":\"room\",\"piecePlus\":\"rooms\",\"chambreUn\":\"bedroom\",\"chambrePlus\":\"bedrooms\",\"transactions\":{\"vente\":\"For sale\",\"location\":\"For rent\"},\"compteur\":{\"vente\":{\"un\":\"property for sale\",\"plus\":\"properties for sale\"},\"location\":{\"un\":\"property for rent\",\"plus\":\"properties for rent\"},\"international\":{\"un\":\"international property\",\"plus\":\"international properties\"},\"neuf\":{\"un\":\"new property\",\"plus\":\"new properties\"},\"vendus\":{\"un\":\"property sold\",\"plus\":\"properties sold\"},\"loues\":{\"un\":\"property rented\",\"plus\":\"properties rented\"},\"defaut\":{\"un\":\"property found\",\"plus\":\"properties found\"}}};\n\n    const STYLE_CARTE_CLAIR = [\n        { elementType: \"geometry\", stylers: [{ color: \"#f5f5f3\" }] },\n        { elementType: \"labels.icon\", stylers: [{ visibility: \"off\" }] },\n        { elementType: \"labels.text.fill\", stylers: [{ color: \"#6b7280\" }] },\n        { elementType: \"labels.text.stroke\", stylers: [{ color: \"#ffffff\" }] },\n        { featureType: \"administrative\", elementType: \"geometry\", stylers: [{ color: \"#dcdcd8\" }] },\n        { featureType: \"administrative.land_parcel\", stylers: [{ visibility: \"off\" }] },\n        { featureType: \"landscape\", elementType: \"geometry\", stylers: [{ color: \"#f5f5f3\" }] },\n        { featureType: \"poi\", stylers: [{ visibility: \"off\" }] },\n        { featureType: \"road\", elementType: \"geometry\", stylers: [{ color: \"#ffffff\" }] },\n        { featureType: \"road\", elementType: \"geometry.stroke\", stylers: [{ color: \"#e5e5e2\" }] },\n        { featureType: \"road.highway\", elementType: \"geometry\", stylers: [{ color: \"#f0ebe0\" }] },\n        { featureType: \"road.highway\", elementType: \"geometry.stroke\", stylers: [{ color: \"#e3dbc8\" }] },\n        { featureType: \"road.arterial\", elementType: \"labels\", stylers: [{ visibility: \"off\" }] },\n        { featureType: \"road.local\", elementType: \"labels\", stylers: [{ visibility: \"off\" }] },\n        { featureType: \"transit\", stylers: [{ visibility: \"off\" }] },\n        { featureType: \"water\", elementType: \"geometry\", stylers: [{ color: \"#cfe3ec\" }] },\n    ];\n\n    const ICONES = {\n        surface: '<svg viewBox=\"0 0 16 16\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M14.5.125h-13C.742.125.125.742.125 1.5v13c0 .758.617 1.375 1.375 1.375h13c.758 0 1.375-.617 1.375-1.375v-13c0-.758-.617-1.375-1.375-1.375zm.625 14.375c0 .345-.28.625-.625.625h-13a.626.626 0 0 1-.625-.625v-13c0-.345.28-.625.625-.625h13c.345 0 .625.28.625.625z\"\/><path d=\"M13.5 2.125h-3a.375.375 0 0 0 0 .75h2.094l-9.719 9.719V10.5a.375.375 0 0 0-.75 0v3c0 .207.168.375.375.375h3a.375.375 0 0 0 0-.75H3.406l9.719-9.719V5.5a.375.375 0 0 0 .75 0v-3a.375.375 0 0 0-.375-.375z\"\/><\/svg>',\n        pieces: '<svg viewBox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M511.55 497.93H.45V227.32L256 14.07l255.55 213.25zM38 460.34h436V244.91L256 63 38 244.91z\"\/><\/svg>',\n        chambres: '<svg viewBox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M440 188h-8v-64c-.026-22.08-17.92-39.974-40-40H120c-22.08.026-39.974 17.92-40 40v64h-8c-39.744.048-71.952 32.256-72 72v112h16v56h40v-56h400v56h40v-56h16V260c-.048-39.744-32.256-71.952-72-72zM96 124c0-13.255 10.745-24 24-24h272c13.255 0 24 10.745 24 24v64h-24v-32c0-13.255-10.745-24-24-24h-72c-13.255 0-24 10.745-24 24v32h-32v-32c0-13.255-10.745-24-24-24h-72c-13.255 0-24 10.745-24 24v32H96v-64zm280 32v32h-88v-32a8 8 0 0 1 8-8h72a8 8 0 0 1 8 8zm-152 0v32h-88v-32a8 8 0 0 1 8-8h72a8 8 0 0 1 8 8zM40 412h-8v-40h8v40zm440 0h-8v-40h8v40zm16-56H16v-40h480v40zm0-56H16v-40c.035-30.913 25.087-55.965 56-56h368c30.913.035 55.965 25.087 56 56v40z\"\/><\/svg>',\n    };\n\n    const T = window.carteBiensI18n;\n\n    function normaliser(texte) {\n        return (texte || '').toString().toLowerCase().normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '');\n    }\n\n    function formaterPrix(bien) {\n        if (!bien.prix || !bien.prix_affiche) return T.prixSurDemande;\n        const formatted = Math.round(bien.prix).toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\");\n        const estLocation = (bien.transaction || '').toLowerCase().includes('location');\n        return `CHF ${formatted}.-${estLocation ? T.parMois : ''}`;\n    }\n\n    function formaterPrixCourt(bien) {\n        if (!bien.prix || !bien.prix_affiche) return T.surDemande;\n        return Math.round(bien.prix).toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\") + '.-';\n    }\n\n    function libelleCompteur(compteur) {\n        const pluriel = compteur > 1;\n        const cle = T.compteur[window.carteBiensCategorie] ? window.carteBiensCategorie : 'defaut';\n        return pluriel ? T.compteur[cle].plus : T.compteur[cle].un;\n    }\n\n    \/\/ Libelle affiche pour une valeur de transaction, la valeur brute restant inchangee.\n    function libelleTransaction(valeur) {\n        const cle = (valeur || '').toString().toLowerCase();\n        return T.transactions[cle] || valeur;\n    }\n\n    function construireIconePrix(texte) {\n        const largeur = Math.max(56, texte.length * 7 + 24);\n        const hauteur = 26;\n        const svg = `<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"${largeur}\" height=\"${hauteur}\">\n            <rect x=\"1\" y=\"1\" width=\"${largeur - 2}\" height=\"${hauteur - 2}\" rx=\"${hauteur \/ 2}\" ry=\"${hauteur \/ 2}\"\n                  fill=\"#C7171B\" fill-opacity=\"0.6\" stroke=\"#C7171B\" stroke-width=\"2\" stroke-opacity=\"1\"\/>\n            <text x=\"50%\" y=\"52%\" dominant-baseline=\"central\" text-anchor=\"middle\" font-family=\"Arial, sans-serif\" font-size=\"12\" font-weight=\"400\" fill=\"#ffffff\">${texte}<\/text>\n        <\/svg>`;\n        return {\n            url: 'data:image\/svg+xml;charset=UTF-8,' + encodeURIComponent(svg),\n            scaledSize: new google.maps.Size(largeur, hauteur),\n            anchor: new google.maps.Point(largeur \/ 2, hauteur \/ 2),\n        };\n    }\n\n    function construireContenuBien(bien) {\n        const specs = [];\n        if (bien.surface) specs.push(`<li>${ICONES.surface}<span>${bien.surface} m\u00b2<\/span><\/li>`);\n        if (bien.pieces) specs.push(`<li>${ICONES.pieces}<span>${bien.pieces} ${bien.pieces > 1 ? T.piecePlus : T.pieceUn}<\/span><\/li>`);\n        if (bien.chambres) specs.push(`<li>${ICONES.chambres}<span>${bien.chambres} ${bien.chambres > 1 ? T.chambrePlus : T.chambreUn}<\/span><\/li>`);\n\n        \/\/ Sur les pages Vendus\/Lou\u00e9s, le badge indique le statut ; ailleurs, \"Nouveau\" si r\u00e9cent.\n        let badgeHtml = '';\n        if (bien.statut_label) {\n            badgeHtml = `<span class=\"carte-biens-badge carte-biens-badge-statut\">${bien.statut_label}<\/span>`;\n        } else if (bien.nouveau) {\n            badgeHtml = `<span class=\"carte-biens-badge\">${T.nouveau}<\/span>`;\n        }\n\n        return `\n            <div class=\"carte-biens-image-wrap\">\n                <img decoding=\"async\" src=\"${bien.image || ''}\" alt=\"\">\n                <div class=\"carte-biens-watermark\"><\/div>\n                ${badgeHtml}\n            <\/div>\n            <div class=\"carte-biens-body\">\n                <div class=\"carte-biens-meta-row\">\n                    ${bien.commune ? `<p class=\"carte-biens-commune\">${bien.commune}<\/p>` : '<span><\/span>'}\n                    <p class=\"carte-biens-prix\">${formaterPrix(bien)}<\/p>\n                <\/div>\n                <h4 class=\"carte-biens-titre\">${bien.titre}<\/h4>\n                ${specs.length ? `<ul class=\"carte-biens-specs\">${specs.join('')}<\/ul>` : ''}\n            <\/div>\n        `;\n    }\n\n    function creerCarteBien(bien) {\n        const card = document.createElement('div');\n        card.className = 'carte-biens-card';\n        card.innerHTML = construireContenuBien(bien);\n        card.addEventListener('click', () => { window.open(bien.lien, '_blank'); });\n        return card;\n    }\n\n    function largeurPopupSelonEcran() {\n        return window.innerWidth <= 480 ? Math.round(window.innerWidth * 0.9) : 320;\n    }\n\n    function hauteurHeaderFixe() {\n        let maxBas = 0;\n        document.querySelectorAll('body > *, header, #masthead, .site-header').forEach(el => {\n            if (el.id === 'carte-biens-topbar' || el.closest('#carte-biens-topbar')) return;\n            const cs = getComputedStyle(el);\n            if ((cs.position === 'fixed' || cs.position === 'sticky') && el.offsetHeight > 0) {\n                const rect = el.getBoundingClientRect();\n                if (rect.top <= 5 && rect.bottom > maxBas) maxBas = rect.bottom;\n            }\n        });\n        return Math.max(0, Math.round(maxBas));\n    }\n\n    function initCarteBiens() {\n        const data = window.biensData;\n        const listeEl = document.getElementById('liste-biens');\n        const compteurEl = document.getElementById('carte-biens-compteur');\n\n        const selTransaction = document.getElementById('filtre-transaction');\n        const selTypeBien   = document.getElementById('filtre-type-bien');\n        const selPieces     = document.getElementById('filtre-pieces');\n        const inputRecherche = document.getElementById('filtre-recherche');\n        const inputPrixMin  = document.getElementById('filtre-prix-min');\n        const inputPrixMax  = document.getElementById('filtre-prix-max');\n        const badgeFiltres  = document.getElementById('badge-filtres-actifs');\n\n        function remplirSelect(selectEl, valeurs) {\n            if (!selectEl) return;\n            [...new Set(valeurs)].filter(Boolean).sort().forEach(v => {\n                const opt = document.createElement('option');\n                opt.value = v;\n                opt.textContent = libelleTransaction(v);\n                selectEl.appendChild(opt);\n            });\n        }\n        remplirSelect(selTransaction, data.map(b => b.transaction));\n\n        const map = new google.maps.Map(document.getElementById('carte-biens'), {\n            zoom: 10,\n            center: { lat: 46.2044, lng: 6.1432 },\n            gestureHandling: 'greedy',\n            styles: STYLE_CARTE_CLAIR,\n        });\n\n        \/\/ autoPan d\u00e9sactiv\u00e9 : on g\u00e8re nous-m\u00eames le recentrage avant d'ouvrir le popup (voir plus bas),\n        \/\/ pour \u00e9viter le conflit avec notre CSS personnalis\u00e9 qui faisait dispara\u00eetre le popup au premier clic.\n        const popupPartage = new google.maps.InfoWindow({ disableAutoPan: true });\n\n        const markers = data.map(bien => {\n            const marker = new google.maps.Marker({\n                position: { lat: bien.lat, lng: bien.lng },\n                title: bien.titre,\n                icon: construireIconePrix(formaterPrixCourt(bien)),\n            });\n            marker.addListener('click', () => {\n                map.panTo(marker.getPosition());\n                google.maps.event.addListenerOnce(map, 'idle', () => {\n                    popupPartage.setOptions({ maxWidth: largeurPopupSelonEcran() });\n                    popupPartage.setContent(`<div class=\\\"carte-biens-card carte-biens-card-popup\\\" style=\\\"cursor:pointer;\\\" onclick=\\\"window.open('${bien.lien}', '_blank')\\\">${construireContenuBien(bien)}<\/div>`);\n                    popupPartage.open({ map, anchor: marker, shouldFocus: false });\n                });\n            });\n            return marker;\n        });\n\n        google.maps.event.addListener(popupPartage, 'domready', () => {\n            const btn = document.querySelector('.gm-ui-hover-effect');\n            if (btn) btn.style.display = 'none';\n        });\n\n        map.addListener('click', () => popupPartage.close());\n\n        const clusterer = new markerClusterer.MarkerClusterer({\n            map, markers,\n            renderer: {\n                render: ({ count, position }) => new google.maps.Marker({\n                    position,\n                    label: { text: String(count), color: '#ffffff', fontSize: '12px', fontWeight: '600' },\n                    icon: {\n                        path: google.maps.SymbolPath.CIRCLE,\n                        fillColor: '#C7171B',\n                        fillOpacity: 0.6,\n                        strokeColor: '#C7171B',\n                        strokeWeight: 2,\n                        scale: Math.min(18 + count \/ 3, 32),\n                    },\n                    zIndex: 1000 + count,\n                }),\n            },\n        });\n        clusterer.addListener('clusteringend', () => popupPartage.close());\n\n        function bienEstVisible(bien) {\n            if (selTransaction && selTransaction.value && bien.transaction !== selTransaction.value) return false;\n            if (selTypeBien.value && normaliser(bien.type_bien) !== normaliser(selTypeBien.value)) return false;\n\n            \/\/ Pi\u00e8ces : nombre exact, sauf pour \"6\" qui reste \"6 et plus\"\n            if (selPieces.value) {\n                const val = parseFloat(selPieces.value);\n                const piecesArrondi = Math.floor(bien.pieces);\n                if (val === 6) {\n                    if (piecesArrondi < 6) return false;\n                } else {\n                    if (piecesArrondi !== val) return false;\n                }\n            }\n\n            const recherche = normaliser(inputRecherche.value.trim());\n            if (recherche) {\n                const reference = normaliser(bien.reference);\n                const npa       = normaliser(bien.npa);\n                const commune   = normaliser(bien.commune);\n                if (!reference.includes(recherche) && !npa.includes(recherche) && !commune.includes(recherche)) return false;\n            }\n\n            const prixMin = parseFloat(inputPrixMin.value);\n            const prixMax = parseFloat(inputPrixMax.value);\n            if (!isNaN(prixMin) && bien.prix < prixMin) return false;\n            if (!isNaN(prixMax) && bien.prix > prixMax) return false;\n\n            return true;\n        }\n\n        function compterFiltresActifs() {\n            let n = 0;\n            if (selTransaction && selTransaction.value) n++;\n            if (selTypeBien.value) n++;\n            if (selPieces.value) n++;\n            if (inputRecherche.value.trim()) n++;\n            if (inputPrixMin.value) n++;\n            if (inputPrixMax.value) n++;\n            return n;\n        }\n\n        function appliquerFiltres() {\n            listeEl.innerHTML = '';\n            let compteur = 0;\n\n            markers.forEach((marker, i) => {\n                const bien = data[i];\n                const visible = bienEstVisible(bien);\n                marker.setVisible(visible);\n                if (visible) {\n                    compteur++;\n                    listeEl.appendChild(creerCarteBien(bien));\n                }\n            });\n\n            clusterer.clearMarkers();\n            clusterer.addMarkers(markers.filter(m => m.getVisible()));\n\n            compteurEl.innerHTML = `<span class=\"compteur-nombre\">${compteur}<\/span> ${libelleCompteur(compteur)}`;\n\n            const nbActifs = compterFiltresActifs();\n            if (nbActifs > 0) {\n                badgeFiltres.textContent = nbActifs;\n                badgeFiltres.style.display = 'inline-block';\n            } else {\n                badgeFiltres.style.display = 'none';\n            }\n\n            if (compteur === 0) {\n                listeEl.innerHTML = '<p style=\"padding:20px;\">' + T.aucunResultat + '<\/p>';\n            }\n        }\n\n        [selTransaction, selTypeBien, selPieces, inputPrixMin, inputPrixMax].forEach(el => {\n            if (el) el.addEventListener('change', appliquerFiltres);\n        });\n        inputPrixMin.addEventListener('input', appliquerFiltres);\n        inputPrixMax.addEventListener('input', appliquerFiltres);\n        inputRecherche.addEventListener('input', appliquerFiltres);\n\n        appliquerFiltres();\n\n        \/\/ --- R\u00e9initialiser la recherche ---\n        const btnReset = document.getElementById('btn-reset-filtres');\n        btnReset.addEventListener('click', () => {\n            if (selTransaction) selTransaction.value = '';\n            selTypeBien.value = '';\n            selPieces.value = '';\n            inputRecherche.value = '';\n            inputPrixMin.value = '';\n            inputPrixMax.value = '';\n            appliquerFiltres();\n        });\n\n        \/\/ --- Panel de filtres mobile (plein \u00e9cran) ---\n        const btnOuvrirFiltres = document.getElementById('btn-ouvrir-filtres');\n        const btnFermerFiltres = document.getElementById('btn-fermer-filtres');\n        const btnFermerFiltresCroix = document.getElementById('btn-fermer-filtres-croix');\n        const filtresPanel     = document.getElementById('carte-biens-filtres');\n        const filtresOverlay   = document.getElementById('carte-biens-filtres-overlay');\n\n        function ouvrirPanelFiltres() {\n            filtresPanel.classList.add('ouvert');\n            filtresOverlay.classList.add('ouvert');\n        }\n        function fermerPanelFiltres() {\n            filtresPanel.classList.remove('ouvert');\n            filtresOverlay.classList.remove('ouvert');\n        }\n        btnOuvrirFiltres.addEventListener('click', ouvrirPanelFiltres);\n        btnFermerFiltres.addEventListener('click', fermerPanelFiltres);\n        btnFermerFiltresCroix.addEventListener('click', fermerPanelFiltres);\n        filtresOverlay.addEventListener('click', fermerPanelFiltres);\n\n        \/\/ --- Bascule Liste \/ Carte mobile ---\n        const wrapperEl         = document.getElementById('carte-biens-wrapper');\n        const btnToggleVue      = document.getElementById('btn-toggle-vue');\n        const btnToggleVueTexte = document.getElementById('btn-toggle-vue-texte');\n\n        btnToggleVue.addEventListener('click', () => {\n            const enModeCarte = wrapperEl.classList.toggle('vue-carte');\n            btnToggleVueTexte.textContent = enModeCarte ? T.vueListe : T.vueCarte;\n            if (enModeCarte) {\n                setTimeout(() => {\n                    google.maps.event.trigger(map, 'resize');\n                    map.setCenter({ lat: 46.2044, lng: 6.1432 });\n                }, 50);\n            }\n        });\n\n        \/\/ --- Ancrage du bandeau (Filtres + compteur\/vue) en JS, sous le header sticky du th\u00e8me ---\n        const topbarEl = document.getElementById('carte-biens-topbar');\n        const spacerEl = document.getElementById('carte-biens-topbar-spacer');\n        let topbarOffset = null;\n\n        function calculerOffset() {\n            if (topbarEl.classList.contains('fixe-mobile')) return;\n            topbarOffset = topbarEl.getBoundingClientRect().top + window.scrollY;\n        }\n        calculerOffset();\n\n        window.addEventListener('resize', () => {\n            topbarEl.classList.remove('fixe-mobile');\n            spacerEl.style.display = 'none';\n            calculerOffset();\n        });\n\n        window.addEventListener('scroll', () => {\n            if (window.innerWidth > 768 || topbarOffset === null) return;\n            const decalageHeader = hauteurHeaderFixe();\n\n            if (window.scrollY >= topbarOffset - decalageHeader) {\n                if (!topbarEl.classList.contains('fixe-mobile')) {\n                    spacerEl.style.height = topbarEl.offsetHeight + 'px';\n                    spacerEl.style.display = 'block';\n                    topbarEl.classList.add('fixe-mobile');\n                }\n                topbarEl.style.top = decalageHeader + 'px';\n            } else {\n                topbarEl.classList.remove('fixe-mobile');\n                spacerEl.style.display = 'none';\n            }\n        }, { passive: true });\n    }\n    <\/script>\n    <script src=\"https:\/\/unpkg.com\/@googlemaps\/markerclusterer\/dist\/index.min.js\"><\/script>\n    <script async src=\"https:\/\/maps.googleapis.com\/maps\/api\/js?key=AIzaSyCU4OaRqNqpmK0sp_ziCROsnpSQByTskCc&callback=initCarteBiens\"><\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-48376fe e-con-full e-flex e-con e-parent\" data-id=\"48376fe\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-65ea150 e-con-full e-flex e-con e-child\" data-id=\"65ea150\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-315eb89 e-con-full e-flex e-con e-child\" data-id=\"315eb89\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ed2a3c elementor-widget elementor-widget-heading\" data-id=\"4ed2a3c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">New build property projects<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6833b1d elementor-widget elementor-widget-heading\" data-id=\"6833b1d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Land for sale in Geneva?<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-837c13a elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"837c13a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p dir=\"ltr\">Entrusting the sale of your land to Millenium Properties offers several advantages:<\/p>\n<ul dir=\"ltr\">\n<li>With our in-depth knowledge of the sector and our command of property prices, we can offer you a fair purchase price, often higher than those put forward by private buyers.<\/li>\n<li>You avoid the drawbacks of a private sale, such as preparing the listing and hosting viewings.<\/li>\n<li>Millenium Properties streamlines your sale, relieving you of lengthy procedures and administrative paperwork.<\/li>\n<\/ul>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-41daf54 e-con-full e-flex e-con e-parent\" data-id=\"41daf54\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-81c1191 e-con-full e-flex e-con e-child\" data-id=\"81c1191\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-a180ea0 e-con-full e-flex e-con e-child\" data-id=\"a180ea0\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d2c117c elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"d2c117c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">Address<\/p>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2841126 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"2841126\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>5 Boulevard du Th\u00e9\u00e2tre<br \/>1204 Geneva<\/p>\n<p>Monday \u2013 Friday<br \/>9:00 am \u2013 5:00 pm<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3cd7f48 e-con-full e-flex e-con e-child\" data-id=\"3cd7f48\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5b5fe43 elementor-widget__width-initial elementor-widget elementor-widget-heading\" data-id=\"5b5fe43\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">Contact<\/p>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d96dca6 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"d96dca6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"text-decoration: underline\"><a href=\"mailto:info@milleniumproperties.ch\">info@milleniumproperties.ch<\/a><\/span><\/p>\n<p><span style=\"text-decoration: underline\"><a href=\"tel:+41223424412\">+41 22 342 44 12<\/a><\/span><\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-70b8ba7 e-con-full e-flex e-con e-child\" data-id=\"70b8ba7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-832177c e-con-full e-flex e-con e-child\" data-id=\"832177c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-cb2bf65 elementor-widget elementor-widget-heading\" data-id=\"cb2bf65\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">Contact<\/p>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3aad8ba elementor-widget elementor-widget-heading\" data-id=\"3aad8ba\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<p class=\"elementor-heading-title elementor-size-default\">Let's talk about your project.<\/p>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c8628a3 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"c8628a3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Sales, rentals, property management or search: a single point of contact, from first conversation to signing.<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-beca742 elementor-widget__width-initial elementor-widget-mobile__width-inherit elementor-button-align-start elementor-widget elementor-widget-form\" data-id=\"beca742\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Next&quot;,&quot;step_previous_label&quot;:&quot;Previous&quot;,&quot;button_width&quot;:&quot;100&quot;,&quot;step_type&quot;:&quot;number_text&quot;,&quot;step_icon_shape&quot;:&quot;circle&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" name=\"Nouveau formulaire\" aria-label=\"Nouveau formulaire\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"15563\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"beca742\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-above\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-field_13a790e elementor-col-50 elementor-sm-50 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_13a790e\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tFirst name*\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[field_13a790e]\" id=\"form-field-field_13a790e\" class=\"elementor-field elementor-size-md  elementor-field-textual\" placeholder=\"Jean\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-name elementor-col-50 elementor-sm-50 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-name\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tLast name*\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[name]\" id=\"form-field-name\" class=\"elementor-field elementor-size-md  elementor-field-textual\" placeholder=\"Dupond\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-email elementor-field-group elementor-column elementor-field-group-email elementor-col-50 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-email\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tEmail*\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"email\" name=\"form_fields[email]\" id=\"form-field-email\" class=\"elementor-field elementor-size-md  elementor-field-textual\" placeholder=\"dupont@email.ch\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-tel elementor-field-group elementor-column elementor-field-group-field_141286d elementor-col-50 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-field_141286d\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tPhone*\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t<input size=\"1\" type=\"tel\" name=\"form_fields[field_141286d]\" id=\"form-field-field_141286d\" class=\"elementor-field elementor-size-md  elementor-field-textual\" placeholder=\"+41 00 000 00 00\" required=\"required\" pattern=\"[0-9()#&amp;+*-=.]+\" title=\"Only numbers and phone characters (#, -, *, etc) are accepted.\">\n\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-textarea elementor-field-group elementor-column elementor-field-group-message elementor-col-100 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-message\" class=\"elementor-field-label\">\n\t\t\t\t\t\t\t\tMessage\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<textarea class=\"elementor-field-textual elementor-field  elementor-size-md\" name=\"form_fields[message]\" id=\"form-field-message\" rows=\"4\" placeholder=\"Tell us about your project in a few lines (optional)...\" required=\"required\"><\/textarea>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-recaptcha_v3 elementor-field-group elementor-column elementor-field-group-field_5a6a405 elementor-col-100 recaptcha_v3-bottomleft\">\n\t\t\t\t\t<div class=\"elementor-field\" id=\"form-field-field_5a6a405\"><div class=\"elementor-g-recaptcha\" data-sitekey=\"6LdJOyQtAAAAAFZDDIhF5v_VznKZDJ_j9ryAMLCC\" data-type=\"v3\" data-action=\"Form\" data-badge=\"bottomleft\" data-size=\"invisible\"><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-sm\" type=\"submit\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Send my message<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type='hidden' name='lang' value='en-gb' \/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-956e171 elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"956e171\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Reply within 24 to 48 hours<\/p>\n\t\t\t\t\t\t\t\t<\/div>\n\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>New build projects New build property projects Land for sale in Geneva? Entrusting the sale of your land to Millenium Properties offers several advantages: With our in-depth knowledge of the sector and our command of property prices, we can offer you a fair purchase price, often higher than those put forward by private buyers. You [&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,"footnotes":""},"class_list":["post-15563","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/pages\/15563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/comments?post=15563"}],"version-history":[{"count":3,"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/pages\/15563\/revisions"}],"predecessor-version":[{"id":15566,"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/pages\/15563\/revisions\/15566"}],"wp:attachment":[{"href":"https:\/\/www.milleniumproperties.ch\/en\/wp-json\/wp\/v2\/media?parent=15563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}