Qualité dyal tswirat : 7/10 · m9iyma b IA
Ghandi, Casablanca
45 000 MAD/mois
72 MAD/m²
Positionnement dyal taman
−36% t7t l'wasat dyal l'7ouma
L'wasat Ghandi : 113 MAD/m² · 76 annonces m7allila
Chouf l'as3ar dyal l'7oumaCaractéristiques
Surface
Annonces mchabhin
45 000 MAD/mois
72 MAD/m²
622 m²
Biout
4
Description
à louer – Villa de standing entièrement rénovée avec piscine au cœur de l’Oasis Située dans le quartier très prisé de l’Oasis, cette somptueuse villa rénovée allie élégance, confort et prestations haut de gamme. édifiée sur trois niveaux et offrant une superficie généreuse de 622 m², elle constitue un cadre de vie idéal pour une famille ou une résidence de fonction. Dès l’entrée, vous serez séduit par ses volumes spacieux et sa luminosité naturelle. La villa dispose de trois salons distincts, parfaitement agencés pour répondre à tous les styles de réception : un salon européen raffiné avec cheminée, un salon marocain authentique sublimé par un plafond en bois sculpté, ainsi qu’un troisième salon ouvert sur une agréable terrasse avec espace barbecue. L’espace nuit comprend quatre chambres confortables, dont une suite parentale avec balcon privatif et dressing, accompagnées de deux salles de bains. La villa est également dotée de deux toilettes invités, assurant un confort optimal pour vos réceptions. La cuisine, fonctionnelle et bien équipée, dispose d’un garde-manger ainsi que d’une chambre froide, idéale pour un usage quotidien ou professionnel. Pensée pour le bien-être, la propriété propose également un hammam beldi traditionnel, offrant un espace de détente unique à domicile. Les prestations annexes viennent compléter ce bien d’exception : • Chambre de personnel avec logement indépendant pour gardien • Garage pour deux véhicules avec ouverture électrique • Système de chauffage au gaz et climatisation • Finitions de qualité avec sols en marbre • Interphone pour plus de sécurité à l’extérieur, vous profiterez d’un cadre agréable avec piscine et espaces de vie extérieurs propices à la détente et aux moments en famille. document.addEventListener(`DOMContentLoaded`,function(){let e=document.getElementById(`voir-plus`),t=document.querySelector(`.label`);e.addEventListener(`change`,function(){e.checked||t.scrollIntoView({behavior:`smooth`})})}); proposée par : Cantarel Immobilier Agence immobilière à Casablanca Information financières --> --> Annonces Similaires Il y a 4 mois 30 000 DH / mois 4 Ch 4 sdb 478 m² Villa à louer Casablanca -Franceville Annonce par : Cantarel Immobilier (function(){const id = ""; const similarLen = 1; document.addEventListener("DOMContentLoaded", function () { const carousel = document.getElementById(`Cards-Container${id}`); const arrows = document.getElementById(`arrowsId${id}`); const indicators = document.getElementById(`indicators${id}`); // const prevStroke = document.getElementById(`prev-stroke${id}`); const nextButtons = document.querySelectorAll(`.next-btn${id}`); const prevButtons = document.querySelectorAll(`.prev-btn${id}`); if (!carousel) return; /* Card #4103 — measure the real card "step" (card width + gap) * by reading the two first children's offsetLeft. Falls back to * the first child's offsetWidth if there's only one card. This is * what makes the arrow navigation actually land on card edges * instead of being off by the gap. */ let currentIndex = 0; const firstCard = carousel.firstElementChild; const cardWidth = firstCard instanceof HTMLElement ? firstCard.offsetWidth || 320 : 320; const measureStep = () => { const first = carousel.children[0]; const second = carousel.children[1]; if (!first || !(first instanceof HTMLElement)) return cardWidth; if (second && second instanceof HTMLElement) { const delta = second.offsetLeft - first.offsetLeft; if (delta > 0) return delta; } return first.offsetWidth || cardWidth; }; let step = measureStep(); /* maxScroll is the true end of the scroll container. The card- * counted maxIndex is derived from it so the last "next" click * lands at scrollLeft = maxScroll and the final card sits fully * inside the viewport, no partial visibility. */ const getMaxScroll = () => Math.max(0, carousel.scrollWidth - carousel.clientWidth); let maxScroll = getMaxScroll(); let maxIndex = step > 0 ? Math.ceil(maxScroll / step) : 0; const maxDots = 5; const isRTL = getComputedStyle(carousel).direction === "rtl"; const recompute = () => { step = measureStep(); maxScroll = getMaxScroll(); maxIndex = step > 0 ? Math.ceil(maxScroll / step) : 0; }; const updateArrowsVisibility = () => { if (!arrows || !carousel) return; arrows.style.visibility = maxScroll > 0 ? "visible" : "hidden"; }; /* Dots window over the VALID scroll positions [0, maxIndex], * not over similarLen. Showing more dots than reachable positions * was the source of the "active dot stuck on an earlier position" * bug for cards = N where N - visibleCards maxDots and there's more content beyond an edge, * the dots closest to that edge shrink (1.0 → 0.7 → 0.5) so the * user gets a visual "there's more in this direction" cue without * the dot strip itself growing. */ const updateIndicators = () => { if (!indicators) return; const dots = indicators.querySelectorAll(".dot-indicator"); const pageCount = maxIndex + 1; // number of valid scroll positions let startDot = 0; if (pageCount > maxDots) { const half = Math.floor(maxDots / 2); if (currentIndex = pageCount - half - 1) { startDot = pageCount - maxDots; } else { startDot = currentIndex - half; } } const endDot = startDot + maxDots - 1; const overflowsAtStart = pageCount > maxDots && startDot > 0; const overflowsAtEnd = pageCount > maxDots && endDot { const actualIndex = startDot + dotPosition; const isVisible = actualIndex { if (!carousel) return; recompute(); currentIndex = Math.max(0, Math.min(index, maxIndex)); /* The container has `scroll-snap-type: x mandatory` and the cards * default to start-aligned snap. If we just scrollTo(maxScroll) * the browser snaps back to the PREVIOUS card's left edge when * maxScroll isn't an exact multiple of `step` — that's what * leaves the last card partially hidden behind the gap. * * For the final index, pin the LAST card's inline-end edge to * the container's inline-end edge via scrollIntoView. That * overrides snap proximity and guarantees full visibility of * the last card, no matter the gap or padding-right. */ if ( currentIndex >= maxIndex && maxIndex > 0 && carousel.children.length > 0 ) { const lastCard = carousel.children[carousel.children.length - 1]; if (lastCard instanceof HTMLElement) { lastCard.scrollIntoView({ inline: isRTL ? "start" : "end", block: "nearest", behavior: smooth ? "smooth" : "auto", }); } else { carousel.scrollTo({ left: maxScroll, behavior: smooth ? "smooth" : "auto", }); } } else { const scrollLeft = Math.min(currentIndex * step, maxScroll); carousel.scrollTo({ left: scrollLeft, behavior: smooth ? "smooth" : "auto", }); } updateIndicators(); prevButtons.forEach((btn) => { btn.style.display = currentIndex > 0 ? 'flex' : 'none'; }); // Hide next button when there are no more cards to scroll to. nextButtons.forEach((btn) => { btn.style.display = currentIndex { if (!carousel) return; // In RTL, browsers report scrollLeft as a negative value (or inverted), // so take the absolute distance from the start edge. const scrollPosition = Math.abs(carousel.scrollLeft); /* If the user dragged all the way to maxScroll, snap the index * to maxIndex even if scrollPosition / step rounds short. */ if (maxScroll > 0 && scrollPosition >= maxScroll - 1) { currentIndex = maxIndex; } else { currentIndex = step > 0 ? Math.round(scrollPosition / step) : 0; } currentIndex = Math.max(0, Math.min(currentIndex, maxIndex)); updateIndicators(); prevButtons.forEach((btn) => { btn.style.display = currentIndex > 0 ? 'flex' : 'none'; }); // Hide next button when there are no more cards to scroll to. nextButtons.forEach((btn) => { btn.style.display = currentIndex { if (resizeRaf) return; resizeRaf = requestAnimationFrame(() => { resizeRaf = 0; recompute(); updateArrowsVisibility(); updateIndicators(); if (currentIndex > maxIndex) { scrollToIndex(maxIndex, false); } else { // Re-evaluate next/prev visibility against the fresh maxIndex. prevButtons.forEach((btn) =>
Localisation
Position ta9ribiya
32 000 MAD/mois
Villa · 450 m² · 4 biout
CIL, Casablancahadi kter mn 3am