Repository Public
1<!DOCTYPE html><html lang="fr"> <head><!-- GTM + Google Ads — chargés uniquement sur le domaine de prod (anti-pollution staging/preview/local) --><script>2 window.dataLayer = window.dataLayer || [];3 function gtag(){dataLayer.push(arguments);}4 (function () {5 // Consentement D68 (opt-out, chat-gi Phase 1) : un refus explicite stocké coupe les tags6 // Google pour ce navigateur — effet au chargement de page. Source : lib/consent-client.ts.7 try {8 var consent = JSON.parse(localStorage.getItem('locator:consent:v1') || 'null');9 if (consent && consent.choice === 'refused') return;10 } catch (e) { /* storage bloqué : comportement par défaut (opt-out) */ }11 var h = location.hostname;12 if (h !== 'locationdi.com' && !h.endsWith('.locationdi.com')) return;13 // Google Tag Manager14 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':15 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],16 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=17 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);18 })(window,document,'script','dataLayer','GTM-N23V72B2');19 // Google Ads (gtag.js) — suivi de conversion20 var ad=document.createElement('script');ad.async=true;21 ad.src='https://www.googletagmanager.com/gtag/js?id=AW-18179616586';22 document.head.appendChild(ad);23 gtag('js', new Date());24 gtag('config', 'AW-18179616586');25 })();26 </script><!-- End GTM + Google Ads --><meta charset="utf-8"><link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="shortcut icon" href="/favicon.ico"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><meta name="apple-mobile-web-app-title" content="Location DI"><link rel="manifest" href="/site.webmanifest"><meta name="theme-color" content="#2F5D2E"><link rel="canonical" href="https://locationdi.com/logements/region/lanaudiere/saint-charles-borromee"><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content"><meta name="description" content="Logements à louer à Saint-Charles-Borromée (Lanaudière) : 3½, 4½, 5½ gérés par Location DI. Prix, disponibilités et photos à jour."><title>Logements à louer à Saint-Charles-Borromée | Location DI</title><meta property="og:type" content="website"><meta property="og:url" content="https://locationdi.com/logements/region/lanaudiere/saint-charles-borromee"><meta property="og:title" content="Logements à louer à Saint-Charles-Borromée | Location DI"><meta property="og:description" content="Logements à louer à Saint-Charles-Borromée (Lanaudière) : 3½, 4½, 5½ gérés par Location DI. Prix, disponibilités et photos à jour."><meta property="og:image" content="https://locationdi.com/og-image.jpg"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="og:image:alt" content="Location DI — Gestionnaire d'immeubles au Québec. Bien logé. Bien accompagné."><meta property="og:locale" content="fr_CA"><meta property="og:site_name" content="Location DI"><meta property="fb:app_id" content="966242223397117"><!-- Verification de propriete du domaine locationdi.com (Meta Business Suite > Brand safety > Domaines) --><meta name="facebook-domain-verification" content="v1ucjmyd65qg1q7ehlgt2zu4gi4ocj"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://locationdi.com/logements/region/lanaudiere/saint-charles-borromee"><meta name="twitter:title" content="Logements à louer à Saint-Charles-Borromée | Location DI"><meta name="twitter:description" content="Logements à louer à Saint-Charles-Borromée (Lanaudière) : 3½, 4½, 5½ gérés par Location DI. Prix, disponibilités et photos à jour."><meta name="twitter:image" content="https://locationdi.com/og-image.jpg"><meta name="twitter:image:alt" content="Location DI — Gestionnaire d'immeubles au Québec. Bien logé. Bien accompagné."> <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Logements","item":"https://locationdi.com/logements"},{"@type":"ListItem","position":2,"name":"Lanaudière","item":"https://locationdi.com/logements/region/lanaudiere"},{"@type":"ListItem","position":3,"name":"Saint-Charles-Borromée","item":"https://locationdi.com/logements/region/lanaudiere/saint-charles-borromee"}]}</script> <script type="application/ld+json">{"@context":"https://schema.org","@type":"CollectionPage","name":"Logements à louer à Saint-Charles-Borromée","description":"Logements à louer à Saint-Charles-Borromée (Lanaudière) : 3½, 4½, 5½ gérés par Location DI. Prix, disponibilités et photos à jour.","url":"https://locationdi.com/logements/region/lanaudiere/saint-charles-borromee","mainEntity":{"@type":"ItemList","numberOfItems":26,"itemListElement":[{"@type":"ListItem","position":1,"name":"4½ à louer — 2064 Rue de la Visitation, app. 204","url":"https://locationdi.com/logements/4-2064-rue-de-la-visitation-204-831861"},{"@type":"ListItem","position":2,"name":"4½ à louer — 2062 Rue de la Visitation, app. 104","url":"https://locationdi.com/logements/4-2062-rue-de-la-visitation-104-816474"},{"@type":"ListItem","position":3,"name":"4½ à louer — 1041 Rue de la Visitation, app. 204","url":"https://locationdi.com/logements/4-1041-rue-de-la-visitation-204-406704"},{"@type":"ListItem","position":4,"name":"4½ à louer — 1039 Rue de la Visitation, app. 304","url":"https://locationdi.com/logements/4-1039-quebec-343-304-406739"},{"@type":"ListItem","position":5,"name":"4½ à louer — 1 Rue Vaudreuil, app. 3","url":"https://locationdi.com/logements/4-1-rue-vaudreuil-003-624608"},{"@type":"ListItem","position":6,"name":"4½ à louer — 2060 Rue de la Visitation, app. 102","url":"https://locationdi.com/logements/4-2060-rue-de-la-visitation-102-729962"},{"@type":"ListItem","position":7,"name":"3½ à louer — 3 Rue Vaudreuil, app. 101","url":"https://locationdi.com/logements/3-saint-charles-borromee-680615"},{"@type":"ListItem","position":8,"name":"3½ à louer — 43 Rang de la Petite Noraie, app. 104","url":"https://locationdi.com/logements/3-saint-charles-borromee-504057"},{"@type":"ListItem","position":9,"name":"4½ à louer — 2064 Rue de la Visitation, app. 205","url":"https://locationdi.com/logements/4-2064-rue-de-la-visitation-205-831862"}]}}</script> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script><link rel="stylesheet" href="/_astro/Layout.Bk6kjvn7.css?dpl=6a770c5aa9d6f6000809ad95">27<style>.villes-scroll[data-astro-cid-zqhg2sfa]{scrollbar-width:none;-ms-overflow-style:none;cursor:grab;-webkit-user-select:none;user-select:none}.villes-scroll[data-astro-cid-zqhg2sfa]::-webkit-scrollbar{display:none}.villes-scroll[data-astro-cid-zqhg2sfa].is-dragging{cursor:grabbing;user-select:none;scroll-behavior:auto}28.ville-intro-summary[data-astro-cid-scz7trl6]{list-style:none}.ville-intro-summary[data-astro-cid-scz7trl6]::-webkit-details-marker{display:none}.ville-intro-details[data-astro-cid-scz7trl6]:not([open]) .show-when-open[data-astro-cid-scz7trl6]{display:none}.ville-intro-details[data-astro-cid-scz7trl6][open] .show-when-closed[data-astro-cid-scz7trl6]{display:none}29</style></head> <body class="min-h-screen bg-cream font-sans text-warm-900 antialiased"> <!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N23V72B2" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) --> <div class="sticky top-0 z-50"> <aside id="site-promo" data-dismiss-key="promo-dismissed:mois-gratuit-ete-2026+electros-75-2026" class="relative overflow-hidden bg-gradient-to-r from-accent-800 via-accent-700 to-accent-800 text-white" aria-label="Promotions en cours"><div class="absolute inset-x-0 bottom-0 h-px bg-white/15" aria-hidden="true"></div><div class="mx-auto flex max-w-[1800px] items-center gap-x-4 px-4 py-2.5 sm:px-8"><div class="relative min-w-0 flex-1"><div data-promo-slide class="flex w-full items-center gap-x-4 transition-opacity duration-500 motion-reduce:transition-none"><p class="flex min-w-0 flex-1 items-center justify-center gap-3 sm:justify-start"><span class="hidden shrink-0 items-center rounded-full border border-white/25 bg-white/10 px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-white/90 sm:inline-flex">30Offre31</span><span class="min-w-0 truncate"><strong class="font-serif text-[15px] font-semibold tracking-tight">1 mois gratuit</strong><span class="text-sm text-white/70"> · jusqu'au 21 septembre 2026</span></span></p><button type="button" data-promo-cta class="group shrink-0 inline-flex items-center gap-1.5 rounded-full bg-white px-4 py-1.5 text-xs font-semibold text-accent-800 shadow-sm transition hover:bg-cream">J'en profite<svg class="h-3.5 w-3.5 transition-transform duration-200 group-hover:translate-x-0.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5-5 5M6 12h12"></path></svg></button></div><div data-promo-slide class="flex w-full items-center gap-x-4 transition-opacity duration-500 motion-reduce:transition-none pointer-events-none absolute inset-0 opacity-0" aria-hidden="true" inert><p class="flex min-w-0 flex-1 items-center justify-center gap-3 sm:justify-start"><span class="hidden shrink-0 items-center rounded-full border border-white/25 bg-white/10 px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-white/90 sm:inline-flex">32Offre33</span><span class="min-w-0 truncate"><strong class="font-serif text-[15px] font-semibold tracking-tight">5 électroménagers à 100$/mois</strong><span class="text-sm text-white/70"> · jusqu'au 1er décembre 2026</span></span></p><button type="button" data-promo-cta class="group shrink-0 inline-flex items-center gap-1.5 rounded-full bg-white px-4 py-1.5 text-xs font-semibold text-accent-800 shadow-sm transition hover:bg-cream">J'en profite<svg class="h-3.5 w-3.5 transition-transform duration-200 group-hover:translate-x-0.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5-5 5M6 12h12"></path></svg></button></div></div><button type="button" id="site-promo-dismiss" class="shrink-0 rounded-full p-1 text-white/70 transition hover:bg-white/15 hover:text-white" aria-label="Fermer les promotions"><svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg></button></div></aside><script type="module">const e=document.getElementById("site-promo");if(e){const r=e.dataset.dismissKey||"promo-dismissed";if(sessionStorage.getItem(r))e.remove();else{document.getElementById("site-promo-dismiss")?.addEventListener("click",()=>{sessionStorage.setItem(r,"1"),e.remove()}),e.addEventListener("click",s=>{s.target.closest("[data-promo-cta]")&&window.dispatchEvent(new CustomEvent("open-chat"))});const t=Array.from(e.querySelectorAll("[data-promo-slide]"));if(t.length>1){const s=["pointer-events-none","absolute","inset-0","opacity-0"];let i=0;setInterval(()=>{const o=t[i];i=(i+1)%t.length;const n=t[i];o.classList.add(...s),o.setAttribute("aria-hidden","true"),o.setAttribute("inert",""),n.classList.remove(...s),n.removeAttribute("aria-hidden"),n.removeAttribute("inert")},7e3)}}}</script> <header id="site-header" class="border-b border-warm-200/60 bg-cream/95 backdrop-blur-sm transition-shadow"> <nav class="mx-auto flex max-w-[1800px] items-center gap-4 px-4 py-4 sm:gap-8 sm:px-8"> <!-- Logo à gauche --> <a href="/" class="shrink-0" aria-label="Location DI - logements à louer"> <img src="/logo-location-di.png" alt="Location DI - logements à louer" class="block h-auto w-44 max-w-full lg:w-52"> </a> <!-- Nav links centrés dans l'espace disponible --> <div class="hidden flex-1 items-center justify-center gap-14 md:flex"> <a href="/" class="text-xl transition-colors border-b-2 pb-1 pt-[6px] font-medium text-warm-600 border-transparent hover:text-accent-600"> Accueil </a><div class="group relative"> <a href="/logements" class="inline-flex items-center gap-1 text-xl transition-colors border-b-2 pb-1 pt-[6px] font-semibold text-warm-900 border-accent-500">34Logements35<svg class="h-4 w-4 transition-transform group-hover:rotate-180" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path> </svg> </a> <!-- Méga-menu (CSS hover ; le pt-4 garde le survol continu entre le lien et le panneau) --> <div class="invisible absolute left-1/2 top-full z-50 -translate-x-1/2 pt-4 opacity-0 transition-all duration-150 group-hover:visible group-hover:opacity-100"> <div class="w-[min(92vw,720px)] rounded-2xl border border-warm-200 bg-white p-6 shadow-xl shadow-warm-300/40"> <a href="/logements" class="inline-flex items-center gap-1 text-sm font-semibold text-accent-700 transition hover:text-accent-800">36Voir tous les logements37<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg> </a> <div class="mt-4 grid grid-cols-3 gap-6 border-t border-warm-100 pt-4"> <div> <a href="/logements/region/lanaudiere" class="block text-sm font-semibold text-warm-900 transition hover:text-accent-600">Lanaudière</a> <ul class="mt-2 space-y-1.5"> <li> <a href="/logements/region/lanaudiere/berthierville" class="block text-sm text-warm-600 transition hover:text-accent-600">Berthierville</a> </li><li> <a href="/logements/region/lanaudiere/saint-ambroise-de-kildare" class="block text-sm text-warm-600 transition hover:text-accent-600">Saint-Ambroise-de-Kildare</a> </li><li> <a href="/logements/region/lanaudiere/saint-charles-borromee" class="block text-sm text-warm-600 transition hover:text-accent-600">Saint-Charles-Borromée</a> </li><li> <a href="/logements/region/lanaudiere/saint-felix-de-valois" class="block text-sm text-warm-600 transition hover:text-accent-600">Saint-Félix-de-Valois</a> </li><li> <a href="/logements/region/lanaudiere/saint-gabriel-de-brandon" class="block text-sm text-warm-600 transition hover:text-accent-600">Saint-Gabriel-de-Brandon</a> </li><li class="js-ville-extra hidden"> <a href="/logements/region/lanaudiere/saint-jean-de-matha" class="block text-sm text-warm-600 transition hover:text-accent-600">Saint-Jean-de-Matha</a> </li><li class="js-ville-extra hidden"> <a href="/logements/region/lanaudiere/sainte-elisabeth" class="block text-sm text-warm-600 transition hover:text-accent-600">Sainte-Élisabeth</a> </li> <li> <button type="button" class="js-villes-toggle inline-flex items-center gap-1 text-sm font-medium text-accent-700 transition hover:text-accent-800" aria-expanded="false" data-count="2"> <span class="js-villes-toggle-label">+ 2 autres</span> <svg class="js-villes-toggle-chevron h-3.5 w-3.5 transition-transform" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path></svg> </button> </li> </ul> </div><div> <a href="/logements/region/laurentides" class="block text-sm font-semibold text-warm-900 transition hover:text-accent-600">Laurentides</a> <ul class="mt-2 space-y-1.5"> <li> <a href="/logements/region/laurentides/lachute" class="block text-sm text-warm-600 transition hover:text-accent-600">Lachute</a> </li> </ul> </div><div> <a href="/logements/region/mauricie" class="block text-sm font-semibold text-warm-900 transition hover:text-accent-600">Mauricie</a> <ul class="mt-2 space-y-1.5"> <li> <a href="/logements/region/mauricie/becancour" class="block text-sm text-warm-600 transition hover:text-accent-600">Bécancour</a> </li><li> <a href="/logements/region/mauricie/trois-rivieres" class="block text-sm text-warm-600 transition hover:text-accent-600">Trois-Rivières</a> </li> </ul> </div><div> <a href="/logements/region/montreal" class="block text-sm font-semibold text-warm-900 transition hover:text-accent-600">Montréal</a> <ul class="mt-2 space-y-1.5"> </ul> </div> </div> </div> </div> </div><a href="/notre-entreprise" class="text-xl transition-colors border-b-2 pb-1 pt-[6px] font-medium text-warm-600 border-transparent hover:text-accent-600"> Notre entreprise </a><a href="/contact" class="text-xl transition-colors border-b-2 pb-1 pt-[6px] font-medium text-warm-600 border-transparent hover:text-accent-600"> Contact </a> </div> <!-- CTA à droite --> <div class="hidden shrink-0 items-end gap-4 md:flex"> <a href="/logements" class="rounded-xl bg-accent-500 px-6 py-3 text-base font-semibold text-white shadow-sm transition hover:bg-accent-400 hover:shadow-md hover:-translate-y-0.5">38Trouve ton logement ici39</a> <a href="/contact?mode=proprietaire" class="text-sm text-warm-500 transition-colors hover:text-warm-700">40Propriétaires?41</a> </div> <button id="mobile-menu-btn-e" class="flex h-11 w-11 items-center justify-center rounded-lg text-warm-700 transition hover:bg-warm-100 md:hidden" aria-label="Menu" aria-expanded="false"> <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16"></path> </svg> </button> </nav> <div id="mobile-menu-e" class="hidden border-t border-warm-200/60 bg-cream px-4 pb-4 md:hidden"> <a href="/" class="block py-3 text-sm font-medium transition-colors hover:text-accent-600 text-warm-600"> Accueil </a><div class="border-b border-warm-200/60"> <button id="mobile-logements-toggle" class="flex w-full items-center justify-between py-3 text-sm font-medium text-warm-600 transition hover:text-accent-600" aria-expanded="false" aria-controls="mobile-logements-sub">42Logements43<svg id="mobile-logements-chevron" class="h-4 w-4 transition-transform" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path> </svg> </button> <div id="mobile-logements-sub" class="hidden pb-2"> <a href="/logements" class="block py-2 text-sm font-semibold text-accent-700">Voir tous les logements</a> <div class="mt-1"> <a href="/logements/region/lanaudiere" class="block py-1.5 text-sm font-semibold text-warm-800 hover:text-accent-600">Lanaudière</a> <a href="/logements/region/lanaudiere/berthierville" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Berthierville</a><a href="/logements/region/lanaudiere/saint-ambroise-de-kildare" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Saint-Ambroise-de-Kildare</a><a href="/logements/region/lanaudiere/saint-charles-borromee" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Saint-Charles-Borromée</a><a href="/logements/region/lanaudiere/saint-felix-de-valois" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Saint-Félix-de-Valois</a><a href="/logements/region/lanaudiere/saint-gabriel-de-brandon" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Saint-Gabriel-de-Brandon</a><a href="/logements/region/lanaudiere/saint-jean-de-matha" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Saint-Jean-de-Matha</a><a href="/logements/region/lanaudiere/sainte-elisabeth" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Sainte-Élisabeth</a> </div><div class="mt-1"> <a href="/logements/region/laurentides" class="block py-1.5 text-sm font-semibold text-warm-800 hover:text-accent-600">Laurentides</a> <a href="/logements/region/laurentides/lachute" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Lachute</a> </div><div class="mt-1"> <a href="/logements/region/mauricie" class="block py-1.5 text-sm font-semibold text-warm-800 hover:text-accent-600">Mauricie</a> <a href="/logements/region/mauricie/becancour" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Bécancour</a><a href="/logements/region/mauricie/trois-rivieres" class="block py-1 pl-3 text-sm text-warm-500 hover:text-accent-600">Trois-Rivières</a> </div><div class="mt-1"> <a href="/logements/region/montreal" class="block py-1.5 text-sm font-semibold text-warm-800 hover:text-accent-600">Montréal</a> </div> </div> </div><a href="/notre-entreprise" class="block py-3 text-sm font-medium transition-colors hover:text-accent-600 text-warm-600"> Notre entreprise </a><a href="/contact" class="block py-3 text-sm font-medium transition-colors hover:text-accent-600 text-warm-600"> Contact </a> <div class="mt-3 flex flex-col gap-3 border-t border-warm-200 pt-4"> <a href="/contact?mode=proprietaire" class="text-sm text-warm-500 transition-colors hover:text-warm-700">44Propriétaires?45</a> <a href="/logements" class="rounded-xl bg-accent-500 px-5 py-3 text-center text-sm font-semibold text-white shadow-sm transition hover:bg-accent-400 hover:shadow-md">46Trouve ton logement ici47</a> </div> </div> </header> <script type="module">const s=document.getElementById("mobile-menu-btn-e"),n=document.getElementById("mobile-menu-e");s&&n&&s.addEventListener("click",()=>{const e=!n.classList.contains("hidden");n.classList.toggle("hidden"),s.setAttribute("aria-expanded",String(!e))});const l=document.getElementById("mobile-logements-toggle"),o=document.getElementById("mobile-logements-sub"),a=document.getElementById("mobile-logements-chevron");l&&o&&l.addEventListener("click",()=>{const e=!o.classList.contains("hidden");o.classList.toggle("hidden"),l.setAttribute("aria-expanded",String(!e)),a?.classList.toggle("rotate-180",!e)});const i=document.getElementById("site-header");if(i){const e=()=>{window.scrollY>4?i.classList.add("is-scrolled"):i.classList.remove("is-scrolled")};window.addEventListener("scroll",e,{passive:!0}),e()}document.querySelectorAll(".js-villes-toggle").forEach(e=>{e.addEventListener("click",()=>{const c=e.closest("ul");if(!c)return;const t=e.getAttribute("aria-expanded")==="true";c.querySelectorAll(".js-ville-extra").forEach(r=>r.classList.toggle("hidden",t)),e.setAttribute("aria-expanded",String(!t));const d=e.querySelector(".js-villes-toggle-label");d&&(d.textContent=t?`+ ${e.getAttribute("data-count")} autres`:"voir moins"),e.querySelector(".js-villes-toggle-chevron")?.classList.toggle("rotate-180",!t)})});</script> </div> <main class="pb-16 md:pb-0"> <section class="py-8" data-astro-cid-scz7trl6> <div class="mx-auto max-w-7xl px-4 sm:px-6" data-astro-cid-scz7trl6> <nav class="mb-6 text-sm text-warm-500" data-astro-cid-scz7trl6> <a href="/logements" class="inline-block py-3 -my-3 hover:text-accent-600" data-astro-cid-scz7trl6>Logements</a> <span class="mx-2" data-astro-cid-scz7trl6>›</span> <a href="/logements/region/lanaudiere" class="hover:text-accent-600" data-astro-cid-scz7trl6>Lanaudière</a> <span class="mx-2" data-astro-cid-scz7trl6>›</span> <span class="text-warm-900" data-astro-cid-scz7trl6>Saint-Charles-Borromée</span> </nav> <p class="flex items-center gap-2 text-sm font-semibold uppercase tracking-wider text-warm-500" data-astro-cid-scz7trl6> <span class="h-0.5 w-6 rounded bg-accent-500" aria-hidden="true" data-astro-cid-scz7trl6></span>48Logements à louer49</p> <h1 class="mt-3 tracking-tight text-warm-900" data-astro-cid-scz7trl6> <span class="block font-sans text-3xl font-extrabold text-accent-700 sm:text-4xl" data-astro-cid-scz7trl6>Moderne et Abordable</span> <span class="block font-serif font-bold mt-2 text-2xl sm:text-3xl" data-astro-cid-scz7trl6>Trouvez votre chez-vous à Saint-Charles-Borromée.</span> </h1> <article class="mt-6 max-w-3xl space-y-5 text-base leading-relaxed text-warm-700" data-astro-cid-scz7trl6> <p data-astro-cid-scz7trl6>Découvrez un milieu de vie où la tranquillité de la nature côtoie l'effervescence de la ville. Située au cœur de Lanaudière, Saint-Charles-Borromée (affectueusement appelée « SCB » par les résidents) est une municipalité de choix.</p> <section data-astro-cid-scz7trl6> <h2 class="text-lg font-semibold text-warm-900" data-astro-cid-scz7trl6>L'effervescence de la rue de la Visitation</h2> <p class="mt-2" data-astro-cid-scz7trl6>En choisissant un logement dans ce secteur, vous vous installez au cœur du dynamisme local. La rue de la Visitation est une artère vivante et en pleine revitalisation qui regroupe tout ce dont vous avez besoin au quotidien : épiceries, pharmacies, boutiques et cafés. C'est un quartier où la commodité est reine.</p> </section> <details class="ville-intro-details" data-astro-cid-scz7trl6> <summary class="ville-intro-summary cursor-pointer text-sm font-semibold text-accent-700 transition hover:text-accent-800 select-none" data-astro-cid-scz7trl6> <span class="show-when-closed inline-flex items-center gap-1" data-astro-cid-scz7trl6>50Lire la suite51<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" data-astro-cid-scz7trl6> <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" data-astro-cid-scz7trl6></path> </svg> </span> <span class="show-when-open inline-flex items-center gap-1" data-astro-cid-scz7trl6>52Réduire53<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" data-astro-cid-scz7trl6> <path stroke-linecap="round" stroke-linejoin="round" d="M5 15l7-7 7 7" data-astro-cid-scz7trl6></path> </svg> </span> </summary> <div class="mt-4 space-y-5" data-astro-cid-scz7trl6> <section data-astro-cid-scz7trl6> <h2 class="text-lg font-semibold text-warm-900" data-astro-cid-scz7trl6>Un emplacement stratégique pour les professionnels et étudiants</h2> <p class="mt-2" data-astro-cid-scz7trl6>Saint-Charles-Borromée est un véritable pôle d'emploi et de services. La municipalité abrite notamment le <strong>Centre hospitalier régional de Lanaudière (CHRDL)</strong>, ce qui en fait un secteur de prédilection, très recherché par les travailleurs de la santé qui souhaitent vivre près de leur lieu de travail. De plus, grâce à sa frontière immédiate avec le centre-ville de Joliette, vous vous trouvez à seulement quelques minutes de route ou de transport en commun d'institutions majeures telles que le <strong>Cégep à Joliette</strong> et le <strong>Palais de justice</strong>.</p> </section><section data-astro-cid-scz7trl6> <h2 class="text-lg font-semibold text-warm-900" data-astro-cid-scz7trl6>L'ADN de SCB : la douceur de vivre au bord de l'eau</h2> <p class="mt-2" data-astro-cid-scz7trl6>Qu'est-ce qui rend Saint-Charles-Borromée si unique ? C'est assurément son lien privilégié avec la rivière L'Assomption et ses grands espaces verts qui donnent un air de vacances à la routine.</p> </section> <section data-astro-cid-scz7trl6> <p class="mb-2" data-astro-cid-scz7trl6>Vivre ici, c'est avoir accès à :</p> <ul class="ml-5 list-disc space-y-2 text-warm-700 marker:text-accent-500" data-astro-cid-scz7trl6> <li data-astro-cid-scz7trl6><strong data-astro-cid-scz7trl6>La nature :</strong> le célèbre parc Saint-Jean-Bosco et ses superbes plages pour le kayak l'été ou les glissades l'hiver.</li><li data-astro-cid-scz7trl6><strong data-astro-cid-scz7trl6>La culture :</strong> le patrimoine local, magnifiquement représenté par la Maison et jardins Antoine-Lacombe, véritable joyau pour les amateurs d'horticulture et de culture.</li><li data-astro-cid-scz7trl6><strong data-astro-cid-scz7trl6>L'action :</strong> un vaste réseau cyclable enchanteur qui relie les différents attraits du Grand Joliette.</li> </ul> </section> </div> </details> <a href="/contact?tab=candidature&mode=logement&intent=visite&source=ville-saint-charles-borromee" class="mt-2 inline-flex items-center gap-2 rounded-xl bg-accent-500 px-6 py-3 text-sm font-semibold text-white shadow-md shadow-accent-500/20 transition hover:bg-accent-400" data-astro-cid-scz7trl6>54Réservez votre visite en ligne55<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" data-astro-cid-scz7trl6> <path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" data-astro-cid-scz7trl6></path> </svg> </a> </article> <section class="mt-8" data-astro-cid-scz7trl6> <div class="max-w-3xl" data-astro-cid-scz7trl6> <h2 class="text-lg font-semibold text-warm-900" data-astro-cid-scz7trl6>Les villes que nous couvrons dans Lanaudière</h2> <p class="mt-1 text-sm text-warm-500" data-astro-cid-scz7trl6>Change de ville, ou reviens à toute la région.</p> </div> <div class="villes-scroll flex gap-2 overflow-x-auto py-3 mt-3" data-villes-scroll data-astro-cid-zqhg2sfa> <a href="/logements/region/lanaudiere" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border border-warm-300 bg-white px-4 py-1.5 text-sm text-warm-700 transition hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6>56Toute la région57</a> <a href="/logements/region/lanaudiere/berthierville" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Berthierville </a><a href="/logements/region/lanaudiere/saint-ambroise-de-kildare" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Saint-Ambroise-de-Kildare </a><a href="/logements/region/lanaudiere/saint-charles-borromee" aria-current="page" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-accent-400 bg-accent-50 font-semibold text-accent-700" data-astro-cid-scz7trl6> Saint-Charles-Borromée </a><a href="/logements/region/lanaudiere/saint-felix-de-valois" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Saint-Félix-de-Valois </a><a href="/logements/region/lanaudiere/saint-gabriel-de-brandon" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Saint-Gabriel-de-Brandon </a><a href="/logements/region/lanaudiere/saint-jean-de-matha" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Saint-Jean-de-Matha </a><a href="/logements/region/lanaudiere/sainte-elisabeth" class="inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full border px-4 py-1.5 text-sm transition border-warm-300 bg-white text-warm-700 hover:border-accent-400 hover:text-accent-600" data-astro-cid-scz7trl6> Sainte-Élisabeth </a> </div> <script>58 (function () {59 document.querySelectorAll('[data-villes-scroll]').forEach(function (track) {60 // Empêche le drag natif des liens / images : sans ça, mousedown + déplacement61 // sur un chip <a> lance un glisser-déposer natif et le clic-glisser ne défile pas.62 track.addEventListener('dragstart', function (e) {63 e.preventDefault()64 })6566 // --- Molette verticale -> défilement horizontal ---67 track.addEventListener(68 'wheel',69 function (e) {70 if (!e.deltaY) return71 if (track.scrollWidth <= track.clientWidth) return72 var atStart = track.scrollLeft <= 073 var atEnd = track.scrollLeft + track.clientWidth >= track.scrollWidth - 174 // Laisse la page défiler verticalement quand on est déjà au bout.75 if ((e.deltaY < 0 && atStart) || (e.deltaY > 0 && atEnd)) return76 e.preventDefault()77 // Normalise deltaMode (certaines souris Windows envoient des « lignes », pas des px).78 var step = e.deltaMode === 1 ? e.deltaY * 16 : e.deltaMode === 2 ? e.deltaY * track.clientWidth : e.deltaY79 track.scrollLeft += step80 },81 { passive: false },82 )8384 // --- Clic-glisser (souris uniquement ; touch/pen restent natifs) ---85 // move/up écoutés au niveau window (et PAS de setPointerCapture) : le drag86 // continue même si le curseur sort de la bande, et on évite les blocages de87 // capture de pointeur sur un conteneur scrollable (cause du drag mort).88 var down = false,89 startX = 0,90 startLeft = 0,91 moved = 092 track.addEventListener('pointerdown', function (e) {93 if (e.pointerType !== 'mouse' || e.button !== 0) return94 down = true95 moved = 096 startX = e.clientX97 startLeft = track.scrollLeft98 track.classList.add('is-dragging')99 e.preventDefault() // coupe la sélection / le drag natif dès le mousedown100 })101 window.addEventListener('pointermove', function (e) {102 if (!down) return103 var dx = e.clientX - startX104 if (Math.abs(dx) > moved) moved = Math.abs(dx)105 track.scrollLeft = startLeft - dx106 })107 function endDrag() {108 if (!down) return109 down = false110 track.classList.remove('is-dragging')111 }112 window.addEventListener('pointerup', endDrag)113 window.addEventListener('pointercancel', endDrag)114 // Un vrai glissé ne doit pas déclencher la navigation du chip cliqué.115 track.addEventListener(116 'click',117 function (e) {118 if (moved > 6) {119 e.preventDefault()120 e.stopPropagation()121 }122 },123 true,124 )125 })126 })()127</script> </section> <p id="disponibilites" class="mt-8 scroll-mt-24 text-sm text-warm-500" data-results-count data-results-suffix="à Saint-Charles-Borromée" data-astro-cid-scz7trl6> 26 logements disponibles à Saint-Charles-Borromée. </p> <script type="module">function p(){document.querySelectorAll(".logement-card").forEach(v=>{const c=v.querySelector(".carousel-container");if(!c)return;const a=c.querySelectorAll(".carousel-slide");if(a.length<=1)return;const y=c.querySelectorAll(".carousel-dot"),i=c.querySelector(".carousel-prev"),d=c.querySelector(".carousel-next");let n=0;const s=a.length;function r(t){a.forEach((e,o)=>{e.style.opacity=o===t?"1":"0"}),y.forEach((e,o)=>{e.style.opacity=o===t?"1":"0.5",e.style.transform=o===t?"scale(1.25)":"scale(1)"}),n=t}function f(t){t.preventDefault(),t.stopPropagation()}i&&i.addEventListener("click",t=>{f(t),r((n-1+s)%s)}),d&&d.addEventListener("click",t=>{f(t),r((n+1)%s)});let l=0,h=0,u=!1;c.addEventListener("touchstart",t=>{l=t.touches[0].clientX,h=t.touches[0].clientY,u=!1},{passive:!0}),c.addEventListener("touchmove",t=>{const e=t.touches[0].clientX-l,o=t.touches[0].clientY-h;Math.abs(e)>Math.abs(o)&&Math.abs(e)>10&&(u=!0,t.preventDefault())},{passive:!1}),c.addEventListener("touchend",t=>{const e=t.changedTouches[0].clientX-l;u&&Math.abs(e)>50&&(e<0?r((n+1)%s):r((n-1+s)%s),t.preventDefault())})})}p();document.addEventListener("astro:after-swap",p);</script><div class="mt-8 rounded-2xl border border-warm-200 bg-white px-4 py-3 shadow-sm" data-filterbar> <div class="flex flex-wrap items-end gap-3"> <span class="flex h-[42px] shrink-0 items-center text-warm-400" title="Filtrer les logements"> <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M2.628 1.601C5.028 1.206 7.49 1 10 1s4.973.206 7.372.601a.75.75 0 01.628.74v2.288a2.25 2.25 0 01-.659 1.59l-4.682 4.683a2.25 2.25 0 00-.659 1.59v3.037c0 .684-.31 1.33-.844 1.757l-1.937 1.55A.75.75 0 018 18.25v-5.757a2.25 2.25 0 00-.659-1.591L2.659 6.22A2.25 2.25 0 012 4.629V2.34a.75.75 0 01.628-.74z" clip-rule="evenodd"></path></svg> <span class="sr-only">Filtrer les logements</span> </span> <label class="flex shrink-0 flex-col gap-1"> <span class="text-[11px] font-semibold uppercase tracking-wide text-warm-500">Type</span> <div class="flex h-[42px] items-center gap-1.5" data-type-chips> <button type="button" data-type-chip="3½" aria-disabled="false" class="h-[42px] rounded-xl border px-3.5 text-sm font-medium transition border-warm-200 bg-white text-warm-600 hover:border-accent-400"> 3½ </button><button type="button" data-type-chip="4½" aria-disabled="false" class="h-[42px] rounded-xl border px-3.5 text-sm font-medium transition border-warm-200 bg-white text-warm-600 hover:border-accent-400"> 4½ </button><button type="button" data-type-chip="5½" aria-disabled="false" class="h-[42px] rounded-xl border px-3.5 text-sm font-medium transition border-warm-200 bg-white text-warm-600 hover:border-accent-400"> 5½ </button> </div> <select data-filter-type style="display: none" aria-hidden="true" tabindex="-1"> <option value="">Tous les types</option> <option value="3½">3½</option><option value="4½">4½</option><option value="5½">5½</option> </select> </label> <label class="flex min-w-[130px] flex-1 flex-col gap-1"> <span class="text-[11px] font-semibold uppercase tracking-wide text-warm-500">Étage</span> <select data-filter-etage class="h-[42px] w-full rounded-xl border border-warm-200 bg-white px-4 text-sm text-warm-700 transition focus:border-accent-400 focus:outline-none focus:ring-2 focus:ring-accent-400/30"> <option value="">Tous les étages</option> <option value="1er Étage">1er Étage</option><option value="2e Étage">2e Étage</option><option value="3e Étage">3e Étage</option><option value="Demi sous-sol">Demi sous-sol</option><option value="RDC">RDC</option> </select> </label> <label class="flex min-w-[120px] flex-1 flex-col gap-1"> <span class="text-[11px] font-semibold uppercase tracking-wide text-warm-500">Prix max</span> <input type="number" min="0" step="50" inputmode="numeric" placeholder="$" data-filter-prixmax class="h-[42px] w-full rounded-xl border border-warm-200 bg-white px-4 text-sm text-warm-700 transition focus:border-accent-400 focus:outline-none focus:ring-2 focus:ring-accent-400/30 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"> </label> <label class="flex min-w-[130px] flex-1 flex-col gap-1"> <span class="text-[11px] font-semibold uppercase tracking-wide text-warm-500">Trier</span> <select data-filter-tri class="h-[42px] w-full rounded-xl border border-warm-200 bg-white px-4 text-sm text-warm-700 transition focus:border-accent-400 focus:outline-none focus:ring-2 focus:ring-accent-400/30"> <option value="">Trier par</option> <option value="prix-asc">Prix (croissant)</option> <option value="prix-desc">Prix (décroissant)</option> <option value="dispo-now">Disponible maintenant</option> <option value="dispo-date">Disponibilité + tard</option> </select> </label> <button type="button" data-filter-reset class="flex h-[42px] w-[42px] shrink-0 items-center justify-center rounded-xl text-warm-400 transition hover:bg-warm-50 hover:text-accent-600" title="Réinitialiser les filtres" aria-label="Réinitialiser les filtres"> <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 6L18 18M6 18L18 6"></path></svg> </button> </div> </div> <script>128 (function () {129 const bar = document.querySelector('[data-filterbar]');130 if (!bar) return;131 const typeSel = bar.querySelector('[data-filter-type]');132 const etageSel = bar.querySelector('[data-filter-etage]');133 const prixMax = bar.querySelector('[data-filter-prixmax]');134 const triSel = bar.querySelector('[data-filter-tri]');135 const resetBtn = bar.querySelector('[data-filter-reset]');136137 // Chips type : pilotent le <select> caché (sélection unique, re-clic = désélection),138 // miroir de la barre /logements. Le pipeline existant lit le select et écoute 'change'.139 const typeChipsWrap = bar.querySelector('[data-type-chips]');140 const typeChips = typeChipsWrap ? Array.from(typeChipsWrap.querySelectorAll('[data-type-chip]')) : [];141 const CHIP_ON = ['border-accent-500', 'bg-accent-50', 'text-accent-700'];142 const CHIP_OFF = ['border-warm-200', 'bg-white', 'text-warm-600'];143 function renderChips() {144 const val = typeSel ? typeSel.value : '';145 typeChips.forEach(function (c) {146 const active = c.getAttribute('data-type-chip') === val;147 CHIP_ON.forEach(function (cls) { c.classList.toggle(cls, active); });148 CHIP_OFF.forEach(function (cls) { c.classList.toggle(cls, !active); });149 });150 }151 typeChips.forEach(function (c) {152 c.addEventListener('click', function () {153 const t = c.getAttribute('data-type-chip');154 if (typeSel) {155 typeSel.value = typeSel.value === t ? '' : t;156 typeSel.dispatchEvent(new Event('change', { bubbles: true }));157 }158 renderChips();159 });160 });161162 function emit() {163 document.dispatchEvent(164 new CustomEvent('logements:filter', {165 detail: {166 type: typeSel ? typeSel.value : '',167 etage: etageSel ? etageSel.value : '',168 prixMin: '',169 prixMax: prixMax ? prixMax.value : '',170 tri: triSel ? triSel.value : '',171 },172 }),173 );174 }175176 let t;177 function emitDebounced() {178 clearTimeout(t);179 t = setTimeout(emit, 350);180 }181182 [typeSel, etageSel, triSel].forEach((el) => el && el.addEventListener('change', emit));183 if (prixMax) prixMax.addEventListener('input', emitDebounced);184185 if (resetBtn) {186 resetBtn.addEventListener('click', function () {187 if (typeSel) typeSel.value = '';188 if (etageSel) etageSel.value = '';189 if (prixMax) prixMax.value = '';190 if (triSel) triSel.value = '';191 renderChips();192 emit();193 });194 }195196 renderChips();197 })();198</script><div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3" data-paginated-grid data-api-base="/api/logements-cards?size=9&hrefBase=%2Flogements&region=Lanaudi%C3%A8re&ville=Saint-Charles-Borrom%C3%A9e" data-page-size="9" data-total="26"> <a href="/logements/4-2064-rue-de-la-visitation-204-831861" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/da7590154f749a136760cd295d44183bc60d4cc7-2000x1333.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/8dd8a18047e70bef63fcc695d17e948d2cec4334-967x687.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/c74a90f791ed0073e51e27ff1922cd10bb5a8fd4-2000x1333.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 16 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>1993D200</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-blue-600/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Neuf</span> <span class="hidden sm:inline">Construction neuve</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> <span class="block text-xs font-medium uppercase tracking-wide text-warm-500">À partir de</span> 1 150$201<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 825 pi² · 2e Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">2064 Rue de la Visitation, app. 204</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-2062-rue-de-la-visitation-104-816474" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/da7590154f749a136760cd295d44183bc60d4cc7-2000x1333.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/8dd8a18047e70bef63fcc695d17e948d2cec4334-967x687.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/c74a90f791ed0073e51e27ff1922cd10bb5a8fd4-2000x1333.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 16 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2023D203</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-sky-500/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Récent</span> <span class="hidden sm:inline">Immeuble récent</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> <span class="block text-xs font-medium uppercase tracking-wide text-warm-500">À partir de</span> 1 150$204<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 875 pi² · 1er Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">2062 Rue de la Visitation, app. 104</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-1041-rue-de-la-visitation-204-406704" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/8c4c808d9c05e022051b829818b9bb8f9dc3caec-1496x1000.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/478a65ca53f479605f905f7c1d98c73bfb928175-1103x656.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/b79adf60dd7f02266c08a1d26ea45c7688fd3c05-945x615.png" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 25 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2053D206</span> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> 1 150$207<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 860 pi² · 1er Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">1041 Rue de la Visitation, app. 204</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-1039-quebec-343-304-406739" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/8c4c808d9c05e022051b829818b9bb8f9dc3caec-1496x1000.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/64bd2d34dbe48f1bcfcc36220182e9d487b467b2-836x579.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/786697c05c7cf5bfd10388996e600e1bf14d2c66-1496x1000.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 23 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2083D209</span> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> <span class="block text-xs font-medium uppercase tracking-wide text-warm-500">À partir de</span> 1 150$210<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full bg-amber-50 px-2.5 py-0.5 text-xs font-semibold text-amber-700"> <span class="h-1.5 w-1.5 rounded-full bg-amber-500"></span>211Réservé212</span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 860 pi² · 2e Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">1039 Rue de la Visitation, app. 304</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-1-rue-vaudreuil-003-624608" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/614ebb8db9da65e216d3252d7e02caaf58a1ddee-1500x1000.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/857c5e788ba62000d154b7fbb2aa098633a09a5d-1031x627.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/fdcf3d912774bdcfca629c1c260ce71eccbae646-1500x1000.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 17 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2133D214</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-sky-500/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Récent</span> <span class="hidden sm:inline">Immeuble récent</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> 1 150$215<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 928 pi² · Demi sous-sol</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">1 Rue Vaudreuil, app. 3</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-2060-rue-de-la-visitation-102-729962" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/c3faec29a54f5c0d9e0e601c98889318c01dd5a1-1500x1000.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/b2e21504d46ea3c615b8fc313793101cbde09c67-802x699.png" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/088e72fa29ab6434b4675a368ea1550273737a5b-1500x1000.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 17 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2163D217</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-sky-500/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Récent</span> <span class="hidden sm:inline">Immeuble récent</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> 1 150$218<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 825 pi² · 1er Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">2060 Rue de la Visitation, app. 102</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/3-saint-charles-borromee-680615" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/b435df67cc15d16e950329c6512e062e94e2bfdc-2000x1333.jpg" alt="3½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/ac9cd5c89043692d307ab678c8825cb6b28c8bfa-2000x1333.jpg" alt="3½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/cd51d7c2e236d11ff30fe99320baf32744cee637-2000x1333.jpg" alt="3½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 17 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2193D220</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-sky-500/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Récent</span> <span class="hidden sm:inline">Immeuble récent</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> 1 125$221<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">3½</span> <span> · 825 pi² · RDC</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">3 Rue Vaudreuil, app. 101</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/3-saint-charles-borromee-504057" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/df240375317c57f2778078ff26f6e9a9ffd22cbb-1500x1000.jpg" alt="3½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/c72f725af965d8279b96e3fbe94d11f79c4dc24b-773x502.png" alt="3½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/3306ba9a512b902dc4b3efb4ac8fa1fee1cdbed0-1500x1000.jpg" alt="3½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 25 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2223D223</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-sky-500/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Récent</span> <span class="hidden sm:inline">Immeuble récent</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> 1 100$224<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-amber-50 text-amber-700"> <span class="h-1.5 w-1.5 rounded-full bg-amber-500"></span> Dispo oct. 2026 </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">3½</span> <span> · 790 pi² · 1er Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">43 Rang de la Petite Noraie, app. 104</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> <a href="/logements/4-2064-rue-de-la-visitation-205-831862" class="logement-card group block overflow-hidden rounded-2xl border border-warm-200 bg-white transition-all duration-300 hover:scale-[1.02] hover:shadow-xl hover:shadow-warm-300/40"> <div class="relative aspect-[4/3] overflow-hidden bg-warm-100"> <div class="carousel-container relative h-full w-full"> <img src="https://cdn.sanity.io/images/4ae0mkdu/production/b6dd95cac818b21fe04ae09b39ce4cb96bb43895-1500x1000.jpg" alt="4½ – photo 1" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-100" data-slide="0" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/4cb46596cddd95b378ae1362c19b20636ce66912-1500x1000.jpg" alt="4½ – photo 2" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="1" loading="lazy"><img src="https://cdn.sanity.io/images/4ae0mkdu/production/fdf566825dd407d30097534ca4e988de901dba5e-1500x1000.jpg" alt="4½ – photo 3" class="carousel-slide absolute inset-0 h-full w-full object-cover transition-all duration-500 group-hover:scale-105 opacity-0" data-slide="2" loading="lazy"> <button type="button" class="carousel-prev absolute left-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo précédente"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path></svg> </button> <button type="button" class="carousel-next absolute right-2 top-1/2 z-10 hidden -translate-y-1/2 rounded-full bg-white/80 p-1.5 text-warm-700 shadow backdrop-blur-sm transition hover:bg-white group-hover:md:block" aria-label="Photo suivante"> <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"></path></svg> </button> <div class="absolute bottom-2 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5 md:hidden md:group-hover:flex"> <span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white scale-125" data-dot="0"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="1"></span><span class="carousel-dot pointer-events-none block h-1.5 w-1.5 rounded-full transition-all duration-300 bg-white/50" data-dot="2"></span> </div> </div> <span class="absolute bottom-2.5 right-2.5 z-10 flex items-center gap-1 rounded-full bg-warm-900/70 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7h2l2-3h10l2 3h2a1 1 0 011 1v10a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1z"></path><circle cx="12" cy="13" r="4"></circle></svg> 11 </span> <span class="absolute bottom-2.5 left-2.5 z-10 flex items-center gap-1 rounded-full bg-accent-600/90 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur-sm"> <svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l9-9 9 9M4 11v8a1 1 0 001 1h4v-5h6v5h4a1 1 0 001-1v-8"></path></svg>2253D226</span> <div class="absolute left-3 right-3 top-3 z-10 flex flex-wrap items-start gap-1.5"> <span class="rounded-full bg-blue-600/90 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur-sm sm:px-2.5 sm:py-1 sm:text-xs"> <span class="sm:hidden">Neuf</span> <span class="hidden sm:inline">Construction neuve</span> </span> </div> </div> <div class="p-3 sm:p-5"> <div class="flex items-center gap-3"> <p class="text-xl sm:text-2xl font-bold text-accent-600"> <span class="block text-xs font-medium uppercase tracking-wide text-warm-500">À partir de</span> 1 150$227<span class="text-sm font-normal text-warm-500"> / mois</span> </p> <span class="inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-semibold bg-[#D9F5DC] text-[#2E6E1F] ring-1 ring-[#7BCB67]"> <span class="h-1.5 w-1.5 rounded-full bg-[#00C776]"></span> Disponible dès maintenant </span> </div> <p class="mt-2 text-sm text-warm-600"> <span class="text-base font-semibold text-warm-800">4½</span> <span> · 740 pi² · 2e Étage</span> </p> <div class="mt-2"> <p class="text-xs text-warm-400">2064 Rue de la Visitation, app. 205</p> <p class="text-sm text-warm-500">Saint-Charles-Borromée</p> </div> </div> </a> </div> <div class="mt-8 flex flex-col items-center gap-2" data-paginated-grid-more> <button type="button" data-paginated-grid-load-more data-api-base="/api/logements-cards?size=9&hrefBase=%2Flogements&region=Lanaudi%C3%A8re&ville=Saint-Charles-Borrom%C3%A9e" data-page-size="9" data-total="26" data-more-label="Afficher plus de logements à Saint-Charles-Borromée" class="rounded-xl border border-warm-300 bg-white px-6 py-3 text-sm font-semibold text-warm-700 transition hover:border-accent-400 hover:text-accent-600 disabled:cursor-wait disabled:opacity-60"> Afficher plus de logements à Saint-Charles-Borromée </button> <p class="text-xs text-warm-500" data-paginated-grid-counter data-lieu-suffixe="à Saint-Charles-Borromée"> 9 / 26 affichés à Saint-Charles-Borromée </p> </div> <script>228 (function () {229 const grid = document.querySelector('[data-paginated-grid]');230 if (!grid) return;231 const baseApi = grid.dataset.apiBase || '';232 const pageSize = parseInt(grid.dataset.pageSize || '9', 10);233 let total = parseInt(grid.dataset.total || '0', 10);234235 const more = document.querySelector('[data-paginated-grid-more]');236 const btn = document.querySelector('[data-paginated-grid-load-more]');237 const counter = document.querySelector('[data-paginated-grid-counter]');238 const moreLabel = (btn && btn.getAttribute('data-more-label')) || 'Afficher plus de logements';239 const counterSuffixe = (counter && counter.getAttribute('data-lieu-suffixe')) || '';240241 let activeApi = baseApi; // base + filtres actifs242 let currentPage = 1;243 let shown = Math.min(pageSize, total);244 let inflight = false;245246 function updateMoreUI() {247 if (more) more.style.display = shown < total ? '' : 'none';248 if (btn) {249 btn.disabled = false;250 btn.textContent = moreLabel;251 }252 if (counter) counter.textContent = shown + ' / ' + total + ' affichés' + (counterSuffixe ? ' ' + counterSuffixe : '');253 }254255 async function loadMore() {256 if (inflight || shown >= total) return;257 inflight = true;258 if (btn) { btn.disabled = true; btn.textContent = 'Chargement…'; }259 try {260 const nextPage = currentPage + 1;261 const r = await fetch(activeApi + '&page=' + nextPage);262 if (!r.ok) throw new Error('HTTP ' + r.status);263 const html = await r.text();264 grid.insertAdjacentHTML('beforeend', html);265 currentPage = nextPage;266 shown = Math.min(shown + pageSize, total);267 updateMoreUI();268 } catch (e) {269 if (btn) { btn.disabled = false; btn.textContent = 'Réessayer'; }270 console.warn('Echec chargement batch:', e);271 } finally {272 inflight = false;273 }274 }275276 // Filtrage sur place : refetch page 1 avec les filtres et remplace la grille.277 async function applyFilters(detail) {278 const params = new URLSearchParams();279 if (detail.type) params.set('type', detail.type);280 if (detail.etage) params.set('etage', detail.etage);281 if (detail.prixMin) params.set('prixMin', detail.prixMin);282 if (detail.prixMax) params.set('prixMax', detail.prixMax);283 if (detail.tri) params.set('tri', detail.tri);284 const qs = params.toString();285 activeApi = baseApi + (qs ? '&' + qs : '');286 if (inflight) return;287 inflight = true;288 grid.setAttribute('aria-busy', 'true');289 try {290 const r = await fetch(activeApi + '&page=1');291 if (!r.ok) throw new Error('HTTP ' + r.status);292 total = parseInt(r.headers.get('X-Total-Count') || '0', 10);293 // Compteur réactif du template (« X logements disponibles … »).294 const countEl = document.querySelector('[data-results-count]');295 if (countEl) {296 const suffix = countEl.getAttribute('data-results-suffix') || '';297 const plural = total > 1 ? 's' : '';298 countEl.textContent =299 total === 0300 ? 'Aucun logement disponible ' + suffix + ' pour le moment.'301 : total + ' logement' + plural + ' disponible' + plural + ' ' + suffix + '.';302 }303 const html = await r.text();304 currentPage = 1;305 shown = Math.min(pageSize, total);306 if (total === 0) {307 grid.innerHTML = '<p class="col-span-full rounded-2xl border border-warm-200 bg-warm-50 p-8 text-center text-sm text-warm-600">Aucun logement ne correspond à ces filtres. Essaie d\'élargir tes critères.</p>';308 } else {309 grid.innerHTML = html;310 }311 updateMoreUI();312 } catch (e) {313 console.warn('Echec filtrage:', e);314 } finally {315 inflight = false;316 grid.removeAttribute('aria-busy');317 }318 }319320 if (btn) btn.addEventListener('click', loadMore);321 document.addEventListener('logements:filter', function (e) {322 applyFilters((e && e.detail) || {});323 });324 })();325</script> <nav class="mt-10 -mx-4 overflow-x-auto px-4 sm:mx-0 sm:overflow-x-visible sm:px-0" aria-label="Voir aussi"><div class="flex flex-nowrap items-center gap-2 text-sm sm:flex-wrap sm:gap-3"><span class="shrink-0 text-xs font-semibold uppercase tracking-wider text-warm-500">Voir aussi</span><a href="/logements/region/lanaudiere" class="shrink-0 rounded-full border border-warm-300 bg-white px-4 py-1.5 text-warm-700 transition hover:border-accent-400 hover:text-accent-600">Logements dans Lanaudière</a><a href="/logements/region/lanaudiere/saint-felix-de-valois" class="shrink-0 rounded-full border border-warm-300 bg-white px-4 py-1.5 text-warm-700 transition hover:border-accent-400 hover:text-accent-600">Saint-Félix-de-Valois</a><a href="/logements/region/lanaudiere/mrc-joliette" class="shrink-0 rounded-full border border-warm-300 bg-white px-4 py-1.5 text-warm-700 transition hover:border-accent-400 hover:text-accent-600">MRC de Joliette</a><a href="/logements/region/lanaudiere/saint-gabriel-de-brandon" class="shrink-0 rounded-full border border-warm-300 bg-white px-4 py-1.5 text-warm-700 transition hover:border-accent-400 hover:text-accent-600">Saint-Gabriel-de-Brandon</a></div></nav> </div> </section> <section class="relative overflow-hidden"> <img src="/images/bg-studio-2500.webp" srcset="/images/bg-studio-640.webp 640w, /images/bg-studio-1280.webp 1280w, /images/bg-studio-2500.webp 2500w" sizes="100vw" alt="" class="absolute inset-0 h-full w-full object-cover object-bottom" loading="lazy"> <div class="absolute inset-x-0 top-0 h-1/3 bg-gradient-to-b from-cream to-transparent"></div> <div class="absolute inset-0 bg-warm-900/50"></div> <div class="relative px-4 py-20 sm:px-6"> <div class="mx-auto max-w-2xl text-center"> <h2 class="text-3xl font-bold text-white sm:text-4xl">Le logement que tu cherches est ici.</h2> <p class="mt-4 text-lg leading-relaxed text-warm-200">Notre équipe est là pour te guider</p> <div class="mt-8 flex flex-col justify-center gap-4 sm:flex-row"> <a href="/logements" class="group flex h-14 w-56 items-center justify-center gap-2 rounded-xl bg-accent-500 text-base font-bold text-white shadow-lg shadow-accent-900/30 transition hover:scale-105 hover:bg-accent-400 hover:shadow-xl">Trouver mon logement <span class="inline-block transition-transform group-hover:translate-x-1">→</span></a> <a href="/contact#chat-humain" class="flex h-14 w-56 flex-col items-center justify-center rounded-xl border border-white/30 bg-white/20 text-white backdrop-blur-sm transition hover:bg-white/30"> <span class="text-base font-bold">Clavarde</span><span class="text-xs font-medium">avec nous</span> </a> </div> </div> </div> </section> </main> <footer class="border-t border-warm-200 bg-warm-100"> <div class="mx-auto max-w-7xl px-4 py-12 sm:px-6"> <div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-4"> <!-- Col 1 : Logo + tagline --> <div> <img src="/logo-location-di.png" alt="Location DI" class="h-12"> <p class="mt-3 text-sm font-semibold text-warm-800">Bien logé, bien accompagné.</p> <p class="mt-2 max-w-xs text-sm leading-relaxed text-warm-600">326Une équipe locative à échelle humaine pour t'accompagner.327</p> </div> <!-- Col 2 : Coordonnées + Confiance --> <div> <p class="text-sm font-semibold text-warm-900">Coordonnées</p> <div class="mt-2 space-y-1 text-sm text-warm-600"> <p>544 Rue Notre-Dame</p><p>Repentigny, QC J6A 2T8</p><p>Local 101</p> <p class="mt-2"> <a href="tel:4388123694" class="hover:text-accent-600">438-812-3694</a> </p> <p> <a href="mailto:location@spheredi.com" class="hover:text-accent-600">location@spheredi.com</a> </p> </div> <div class="mt-5"> <p class="text-sm font-semibold text-warm-900">Confiance</p> <div class="mt-2 space-y-1.5 text-sm text-warm-600"> <p class="flex gap-2"> <span class="text-accent-600">✓</span> <span>Plus de 750 logements à louer à travers le Québec</span> </p><p class="flex gap-2"> <span class="text-accent-600">✓</span> <span>Moderne et abordable</span> </p><p class="flex gap-2"> <span class="text-accent-600">✓</span> <a href="https://spheredi.com" target="_blank" rel="noopener noreferrer" class="hover:text-accent-600"> Groupe Sphère DI – Promoteur immobilier d'expérience </a> </p> </div> </div> </div> <!-- Col 3 : Disponibilités + Sociaux + CTA --> <div> <p class="text-sm font-semibold text-warm-900">Disponibilités</p> <div class="mt-2 space-y-1 text-sm text-warm-600"> <p>Lun-ven 8h à 16h</p> <p class="text-warm-500">Soirs et fins de semaine couverts</p> </div> <div class="mt-5"> <p class="text-sm font-semibold text-warm-900">Suis-nous</p> <div class="mt-2 flex gap-3"> <a href="https://www.facebook.com/1018488254690464" target="_blank" rel="noopener noreferrer" aria-label="Page Facebook Location DI - Gestionnaire d'immeubles" class="flex h-8 w-8 items-center justify-center rounded-full border border-warm-300 text-warm-400 transition hover:border-accent-400 hover:text-accent-600"> <svg class="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"></path></svg> </a> </div> </div> <a href="/logements" class="mt-5 inline-flex items-center justify-center rounded-xl bg-accent-500 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-accent-400">328Voir les logements329</a> </div> <!-- Col 4 : Navigation --> <div> <p class="text-sm font-semibold text-warm-900">Navigation</p> <div class="mt-2 space-y-1 text-sm"> <a href="/" class="block text-warm-600 hover:text-accent-600">Accueil</a> <a href="/logements" class="block text-warm-600 hover:text-accent-600">Logements</a> <a href="/notre-entreprise" class="block text-warm-600 hover:text-accent-600">Notre entreprise</a> <a href="/contact" class="block text-warm-600 hover:text-accent-600">Contact</a> <a href="/contact?mode=proprietaire" class="block text-warm-500 hover:text-warm-700">Propriétaires?</a> </div> <div class="mt-5"> <p class="text-sm font-semibold text-warm-900">Régions</p> <div class="mt-2 space-y-1 text-sm"> <a href="/logements/region/lanaudiere" class="block text-warm-600 hover:text-accent-600"> Lanaudière </a><a href="/logements/region/laurentides" class="block text-warm-600 hover:text-accent-600"> Laurentides </a><a href="/logements/region/mauricie" class="block text-warm-600 hover:text-accent-600"> Mauricie </a><a href="/logements/region/montreal" class="block text-warm-600 hover:text-accent-600"> Montréal </a> </div> </div> </div> </div> <div class="mt-10 flex flex-col items-center justify-between gap-4 border-t border-warm-200 pt-6 sm:flex-row"> <div class="flex flex-wrap justify-center gap-x-4 gap-y-2 text-sm text-warm-500 sm:justify-start"> <a href="/politique-confidentialite" class="hover:text-warm-700">Politique de confidentialité</a> <span>·</span> <a href="/conditions-utilisation" class="hover:text-warm-700">Conditions d'utilisation</a> <span>·</span> <a href="/suppression-donnees" class="hover:text-warm-700">Suppression des données</a> <span>·</span> <a href="#" data-consent-manage class="hover:text-warm-700">Gérer mes préférences</a> <span>·</span> <a href="https://spheredi.com" target="_blank" rel="noopener noreferrer" class="hover:text-warm-700">330Groupe Sphère DI ↗331</a> </div> <p class="text-sm text-warm-400">© 2026 Location DI - Tous droits réservés</p> </div> </div> </footer> <nav class="fixed inset-x-0 bottom-0 z-40 flex border-t border-warm-200/60 bg-cream/95 shadow-[0_-2px_8px_rgba(0,0,0,0.04)] backdrop-blur-sm md:hidden" style="padding-bottom: env(safe-area-inset-bottom);" aria-label="Navigation mobile principale"> <a href="/logements" class="flex flex-1 flex-col items-center justify-center gap-1 py-3 text-xs font-semibold text-warm-700 transition hover:text-accent-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-500"> <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-4.35-4.35M17 11a6 6 0 11-12 0 6 6 0 0112 0z"></path> </svg> <span>Trouve ton logement</span> </a> <a href="/contact" class="flex flex-1 flex-col items-center justify-center gap-1 border-l border-warm-200/60 py-3 text-xs font-semibold text-warm-700 transition hover:text-accent-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-500"> <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-hidden="true"> <path stroke-linecap="round" stroke-linejoin="round" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path> </svg> <span>Contact</span> </a> </nav> <!-- Floating chat button + panel --><div id="chat-humain" class="fixed right-4 z-50 bottom-[calc(5rem+env(safe-area-inset-bottom))] flex flex-col items-end gap-3 sm:bottom-6 sm:right-6" data-messenger-page-id="1018488254690464" data-astro-cid-ryytxnzt> <!-- Panel (hidden by default) --> <div id="chat-panel" class="hidden flex flex-col bg-white fixed inset-x-0 z-50 w-full h-[var(--vv-h,100dvh)] top-[var(--vv-offset-top,0px)] bottom-auto sm:relative sm:inset-auto sm:top-auto sm:bottom-auto sm:w-[400px] sm:h-auto sm:max-h-[580px] sm:rounded-2xl sm:border sm:border-warm-200 sm:shadow-xl" role="dialog" aria-modal="true" aria-label="Clavardage avec Lea" data-astro-cid-ryytxnzt> <!-- Header (sticky en haut, safe area iOS top, swipe-to-close mobile) --> <div id="chat-header" class="shrink-0 z-10 border-b border-warm-100 bg-accent-50 px-5 py-4 touch-none" style="padding-top: max(1rem, env(safe-area-inset-top));" data-astro-cid-ryytxnzt> <!-- Handle bar mobile only (visual cue swipe-to-close pattern Messenger natif) --> <div id="chat-header-handle" class="mx-auto mb-2 h-1.5 w-12 rounded-full bg-warm-300 sm:hidden" data-astro-cid-ryytxnzt></div> <div class="flex items-center justify-between gap-2" data-astro-cid-ryytxnzt> <h3 class="font-serif text-lg font-bold text-warm-900" data-astro-cid-ryytxnzt>Chat avec nous</h3> <div class="flex items-center gap-1" data-astro-cid-ryytxnzt> <!-- Mutation 2b#2 (Codex) : Porte de sortie humaine persistante.332 Bouton compact "Équipe" dans le header, mobile = icône seule (économie d'espace),333 desktop = icône + label. Same handler que chat-trigger-team-contact welcome. --> <button id="chat-header-team" class="flex h-11 items-center justify-center gap-1.5 rounded-full px-3 text-xs font-semibold text-accent-700 transition hover:bg-accent-100 sm:h-8" aria-label="Texter l'équipe (SMS)" data-astro-cid-ryytxnzt> <svg class="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 9.75h4.5m-4.5 3H12m6.75-6.75c1.243 0 2.25 1.007 2.25 2.25v6c0 1.243-1.007 2.25-2.25 2.25h-2.69l-3.31 2.48V15.75H5.25A2.25 2.25 0 013 13.5v-6c0-1.243 1.007-2.25 2.25-2.25h13.5z" data-astro-cid-ryytxnzt></path> </svg> <span class="hidden sm:inline" data-astro-cid-ryytxnzt>Texter</span> </button> <button id="chat-close" class="flex h-11 w-11 items-center justify-center rounded-full text-warm-400 transition hover:bg-warm-100 hover:text-warm-600 sm:h-7 sm:w-7" aria-label="Fermer le chat" data-astro-cid-ryytxnzt> <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" data-astro-cid-ryytxnzt></path> </svg> </button> </div> </div> <div id="chat-header-meta" class="mt-1.5 flex items-center gap-2" data-astro-cid-ryytxnzt> <!-- Badge (C''' non-retour) : « Assistant IA » par défaut, remplacé définitivement par334 « Équipe Location DI » (même style) dès l'état HUMAIN (setHeaderHumain) — le laisser335 dire « IA » contredirait le point de non-retour. Jamais reversé (aller simple). --> <span id="chat-header-ia-badge" class="inline-flex items-center gap-1 rounded-full bg-accent-100 px-2.5 py-0.5 text-xs font-semibold text-accent-700" data-astro-cid-ryytxnzt> <span class="h-1.5 w-1.5 rounded-full bg-accent-500" data-astro-cid-ryytxnzt></span> <span id="chat-header-ia-badge-label" data-astro-cid-ryytxnzt>Assistant IA</span> </span> <!-- Porte-état (D69) : « Équipe en ligne » seulement quand la présence GI est PROUVÉE336 (gi_disponible, maj par maybeUpdateWelcomeForEtat) ; « Vous êtes avec l'équipe »337 (générique, C''') en état HUMAIN — défaut/repli honnête ci-dessous sinon. --> <span id="chat-header-status" class="text-xs text-warm-500" data-astro-cid-ryytxnzt>Assistante virtuelle 24/7</span> </div> </div> <!-- Messages area --> <div id="chat-messages" class="flex-1 overflow-y-auto [overflow-anchor:auto] px-4 py-4 space-y-3 min-h-0 sm:min-h-[200px] sm:max-h-[320px]" data-astro-cid-ryytxnzt> <!-- Welcome message (2 bulles aerees - T03d ajustement esthetique) --> <div id="chat-welcome" data-astro-cid-ryytxnzt> <div id="chat-welcome-intro" class="mb-2 rounded-xl bg-warm-50 px-3.5 py-2.5 text-sm text-warm-700 max-w-[80%]" data-astro-cid-ryytxnzt>338Bonjour! Je suis Léa, l'assistante virtuelle de Location DI.339</div> <div id="chat-welcome-role" class="mb-3 rounded-xl bg-warm-50 px-3.5 py-2.5 text-sm text-warm-700 max-w-[80%]" data-astro-cid-ryytxnzt>340Je prépare votre demande pour notre équipe humaine.341</div> <!-- Action rapide texto (G2-express, D74 amendée : le texto précède la voix). Masquée342 quand la présence d'équipe est PROUVÉE (vibe ACCUEIL : écrire ici EST la ligne343 directe — setVibeEquipeEnLigne).344 Rétrogradation 2026-07-11 (finding « widget vs texté », SCOPE MOBILE) : sur mobile,345 « Texter l'équipe » ouvre l'app SMS → deux canaux en parallèle avec le champ. On346 rétrograde donc le CTA en LIEN DISCRET sur mobile (le champ = le geste), tout en347 gardant le BOUTON visible sur desktop (`sm:`), où le clic n'ouvre pas d'app SMS (repli348 numéro/formulaire) → aucune confusion. Icône bulle de texto sur les deux. La ligne349 d'invite est retirée (le placeholder « Posez votre question » la rendait redondante).350 Ids conservés (JS : toggle hidden + handler). --> <div id="chat-welcome-team-cta" class="flex flex-col mb-3 w-full sm:max-w-[80%]" data-astro-cid-ryytxnzt> <button id="chat-trigger-team-contact" class="chat-quick-action inline-flex items-center gap-1.5 self-start text-xs font-medium text-accent-600 transition hover:text-accent-700 hover:underline sm:gap-2.5 sm:rounded-xl sm:border sm:border-accent-200 sm:bg-accent-50 sm:px-3 sm:py-2 sm:text-sm sm:text-accent-700 sm:no-underline sm:hover:border-accent-300 sm:hover:bg-accent-100 sm:hover:no-underline" aria-label="Texter l'équipe (SMS)" data-astro-cid-ryytxnzt> <svg class="h-4 w-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 9.75h4.5m-4.5 3H12m6.75-6.75c1.243 0 2.25 1.007 2.25 2.25v6c0 1.243-1.007 2.25-2.25 2.25h-2.69l-3.31 2.48V15.75H5.25A2.25 2.25 0 013 13.5v-6c0-1.243 1.007-2.25 2.25-2.25h13.5z" data-astro-cid-ryytxnzt></path> </svg>351Ou texter l'équipe352</button> </div> </div> </div> <!-- Typing indicator (hidden) --> <div id="chat-typing" class="hidden px-4 pb-2" data-astro-cid-ryytxnzt> <div class="flex items-center gap-1.5 rounded-xl bg-warm-50 px-3.5 py-2.5 max-w-[80%]" data-astro-cid-ryytxnzt> <span class="h-2 w-2 rounded-full bg-warm-400 animate-bounce" style="animation-delay: 0ms" data-astro-cid-ryytxnzt></span> <span class="h-2 w-2 rounded-full bg-warm-400 animate-bounce" style="animation-delay: 150ms" data-astro-cid-ryytxnzt></span> <span class="h-2 w-2 rounded-full bg-warm-400 animate-bounce" style="animation-delay: 300ms" data-astro-cid-ryytxnzt></span> </div> </div> <!-- Input area (sticky bas, safe area iOS bottom) --> <div class="shrink-0 border-t border-warm-100 bg-white px-4 py-3" style="padding-bottom: max(0.75rem, env(safe-area-inset-bottom));" data-astro-cid-ryytxnzt> <!-- Bandeau « Répondre à » (reply-to, D65) : visible seulement quand une bulle GI a été353 choisie via le bouton « Répondre » ; annulable via le X. --> <div id="chat-reply-banner" class="hidden mb-2 items-start gap-2 rounded-lg bg-warm-50 px-3 py-2" data-astro-cid-ryytxnzt> <div class="min-w-0 flex-1" data-astro-cid-ryytxnzt> <p class="text-[10px] font-bold uppercase tracking-wider text-accent-600" data-astro-cid-ryytxnzt>Réponse à</p> <p id="chat-reply-banner-text" class="truncate text-xs text-warm-600" data-astro-cid-ryytxnzt></p> </div> <button id="chat-reply-banner-cancel" type="button" class="shrink-0 text-warm-400 hover:text-warm-600" aria-label="Annuler la réponse" data-astro-cid-ryytxnzt> <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" data-astro-cid-ryytxnzt></path> </svg> </button> </div> <!-- Ancrage Turnstile (fix conversion 2026-07-06, trace validation-2026-07-06) : quand354 Cloudflare exige une interaction, la case se rend ICI, collée au champ de saisie —355 l'ancien conteneur position:fixed bas-GAUCHE sur <body> la rendait invisible du chat356 (suspect n° 1 du trou 75 % ouvre→écrit). Vide = zéro hauteur (empty:hidden). --> <div id="chat-turnstile-anchor" class="empty:hidden mb-2 flex justify-center" data-astro-cid-ryytxnzt></div> <form id="chat-form" class="flex items-center gap-2" data-astro-cid-ryytxnzt> <!-- Honeypot anti-bot (garde adaptative « B+ », 2026-07-14) : champ leurre invisible et hors357 tabulation. Un humain ne le voit jamais (hors écran, aria-hidden, tabindex -1) ; un bot qui358 remplit les champs le remplit -> la route /tour le lit comme signal de risque. --> <input id="chat-hp" type="text" name="website" tabindex="-1" autocomplete="off" aria-hidden="true" class="absolute left-[-9999px] top-0 h-0 w-0 opacity-0" data-astro-cid-ryytxnzt> <input id="chat-input" type="text" placeholder="Posez votre question..." maxlength="2000" autocomplete="off" autocorrect="on" spellcheck="true" enterkeyhint="send" class="flex-1 rounded-xl border border-warm-200 bg-warm-50 px-3.5 py-2.5 text-base sm:text-sm text-warm-800 placeholder:text-warm-400 outline-none transition focus:border-accent-300 focus:ring-2 focus:ring-accent-100" data-astro-cid-ryytxnzt> <button id="chat-send" type="submit" class="flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-accent-500 text-white transition hover:bg-accent-400 disabled:opacity-50 disabled:cursor-not-allowed sm:h-10 sm:w-10" aria-label="Envoyer" data-astro-cid-ryytxnzt> <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5" data-astro-cid-ryytxnzt></path> </svg> </button> </form> </div> </div> <!-- Floating trigger button --> <button id="chat-toggle" class="relative flex h-14 w-14 items-center justify-center rounded-full bg-accent-500 text-white shadow-lg transition hover:bg-accent-400 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-accent-300 focus:ring-offset-2 sm:flex" aria-label="Clavardez avec nous" data-astro-cid-ryytxnzt> <!-- Chat icon (default) --> <svg id="chat-icon-open" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" data-astro-cid-ryytxnzt></path> </svg> <!-- Close icon (when open) --> <svg id="chat-icon-close" class="hidden h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ryytxnzt> <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" data-astro-cid-ryytxnzt></path> </svg> <!-- Badge non-lu (E3, tranche E P5-T22) : COMPTE des réponses GI arrivées panneau fermé OU359 onglet caché (SSE et polling passent par le même entonnoir public) ; « 9+ » au360 delà de 9 ; remis à zéro à l'ouverture du panneau. Le « 1 » ci-dessous n'est qu'un361 contenu initial : updateUnreadBadge() pose toujours le vrai compte AVANT d'afficher. --> <span id="chat-unread-badge" class="hidden absolute -top-1 -right-1 h-5 min-w-[1.25rem] items-center justify-center rounded-full bg-red-500 px-1 text-[11px] font-bold text-white" aria-hidden="true" data-astro-cid-ryytxnzt>1</span> </button> </div> <script type="module" src="/_astro/ChatWidget.astro_astro_type_script_index_0_lang.C0_536Sr.js?dpl=6a770c5aa9d6f6000809ad95"></script> <aside id="consent-banner" class="fixed inset-x-0 bottom-0 z-[60] hidden" role="region" aria-label="Préférences de confidentialité"> <div class="mx-auto max-w-[1800px] px-4 pb-4 sm:px-8"> <div class="rounded-2xl border border-warm-200 bg-white/95 px-4 py-3 shadow-lg backdrop-blur sm:px-6 sm:py-4"> <div class="flex flex-col gap-3 sm:flex-row sm:items-center"> <p class="min-w-0 flex-1 text-sm leading-relaxed text-warm-700">362Nous utilisons des témoins (cookies) pour la mesure d'audience et un signal de présence363 pour vous offrir le service en direct avec notre équipe.364<a href="/politique-confidentialite" class="whitespace-nowrap text-accent-600 hover:underline">365Politique de confidentialité366</a> </p> <div class="flex shrink-0 items-center gap-2"> <button type="button" id="consent-refuse" class="rounded-full border border-warm-300 px-4 py-1.5 text-xs font-semibold text-warm-700 transition hover:bg-warm-100">367Refuser368</button> <button type="button" id="consent-accept" class="rounded-full bg-accent-700 px-5 py-1.5 text-xs font-semibold text-white shadow-sm transition hover:bg-accent-800">369OK370</button> </div> </div> </div> </div> </aside> <script type="module" src="/_astro/ConsentBanner.astro_astro_type_script_index_0_lang.DnUHoAqY.js?dpl=6a770c5aa9d6f6000809ad95"></script> </body></html>