<?phpuse Twig\Environment;use Twig\Error\LoaderError;use Twig\Error\RuntimeError;use Twig\Extension\CoreExtension;use Twig\Extension\SandboxExtension;use Twig\Markup;use Twig\Sandbox\SecurityError;use Twig\Sandbox\SecurityNotAllowedTagError;use Twig\Sandbox\SecurityNotAllowedFilterError;use Twig\Sandbox\SecurityNotAllowedFunctionError;use Twig\Source;use Twig\Template;use Twig\TemplateWrapper;/* vitrine/en/homepage.html.twig */class __TwigTemplate_44de184e5eb1317f89ee043904cd3b74 extends Template{ private Source $source; /** * @var array<string, Template> */ private array $macros = []; public function __construct(Environment $env) { parent::__construct($env); $this->source = $this->getSourceContext(); $this->blocks = [ 'title' => [$this, 'block_title'], 'description' => [$this, 'block_description'], 'robots' => [$this, 'block_robots'], 'canonical' => [$this, 'block_canonical'], 'body' => [$this, 'block_body'], 'footerjs' => [$this, 'block_footerjs'], 'css' => [$this, 'block_css'], ]; } protected function doGetParent(array $context): bool|string|Template|TemplateWrapper { // line 1 return "vitrine/en/layout.html.twig"; } protected function doDisplay(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "vitrine/en/homepage.html.twig")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template", "vitrine/en/homepage.html.twig")); $this->parent = $this->load("vitrine/en/layout.html.twig", 1); yield from $this->parent->unwrap()->yield($context, array_merge($this->blocks, $blocks)); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); } // line 3 /** * @return iterable<null|scalar|\Stringable> */ public function block_title(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "title")); yield "Cathedral Heritage Suite - 8-Guest Rental Strasbourg Center"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 4 /** * @return iterable<null|scalar|\Stringable> */ public function block_description(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "description")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "description")); yield "Rent our 83mΒ² suite in the heart of Strasbourg. 3 bedrooms, sleeps 8, 100m from Cathedral. Kitchen fully furnished, 2 bathrooms. Book your stay today!"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 5 /** * @return iterable<null|scalar|\Stringable> */ public function block_robots(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "robots")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "robots")); yield "index,follow"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 7 /** * @return iterable<null|scalar|\Stringable> */ public function block_canonical(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "canonical")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "canonical")); // line 8 yield " <link rel=\"canonical\" href=\"https://cathedraleheritage.com\" /> <link rel=\"alternate\" hreflang=\"fr\" href=\"https://cathedraleheritage.com/fr\" /> <link rel=\"alternate\" hreflang=\"en\" href=\"https://cathedraleheritage.com\" /> <link rel=\"alternate\" hreflang=\"x-default\" href=\"https://cathedraleheritage.com\" />"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 14 /** * @return iterable<null|scalar|\Stringable> */ public function block_body(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "body")); // line 15 yield " <section id=\"hero\" class=\"text-light no-top no-bottom relative overflow-hidden z-1000\"> <div class=\"abs w-100 abs-centered z-2\"> <div class=\"container\"> <div class=\"spacer-double\"></div> <div class=\"row g-4 align-items-center justify-content-center\"> <div class=\"col-md-8 text-center\"> <h1 class=\"mb-2\" style=\"color:white;\">Welcome to Cathedral Heritage Suite</h1> <p class=\"lead mb-3\" style=\"color:white; font-size:22px;\">Beautifully appointed apartment accommodating up to 8 guests in Strasbourg's prestigious historical city center</p> <a class=\"btn-main btn-line bg-blur fx-slide\" href=\"#about\" style=\"color:white;\"><span>Find out more</span></a> </div> </div> </div> </div> <div class=\"vertical-center\"> <div class=\"swiper\"> <div class=\"swiper-wrapper\"> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/salon2.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/chambre2.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/noel.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> </div> </div> </div> <div class=\"abs w-100 bottom-0 z-2 pb-4 sm-hide\"> <div class=\"container\"> <div class=\"row\"> <div class=\"col-lg-12\"> <div class=\"d-flex justify-content-between\"> <div><h6 style=\"color:white;\">Cathedral 100m away</h6></div> <div><h6 style=\"color:white;\">Museums 200m away</h6></div> <div><h6 style=\"color:white;\">Petite France 300m away</h6></div> </div> </div> </div> </div> </div> <div class=\"gradient-edge-bottom op-8\"></div> </section> <section id=\"about\"> <div class=\"container\"> <div class=\"row g-4 align-items-end justify-content-between\"> <div class=\"col-lg-5\"> <div class=\"subtitle\">About the apartment</div> <h2>Modern suite in the heart of Strasbourg's Grande Γle</h2> </div> <div class=\"col-lg-4\"> <p class=\"mb-4\" style=\"color:#212121;\"> Spacious fully equipped appartement ideal for families and groups up to 8 people : 1 master bedroom with en-suite bathroom, one double bedroom, one bedroom with two double bunk beds (sleeps 4), maximum weight of 100kg for upper bunks. </p> <p class=\"mb-4\" style=\"color:#212121;\"> Kitchen fully furnished and cozy living-dining room to share great moments together. </p> <p class=\"mb-4\" style=\"color:#212121;\"> Amenities: hairdryer, dishwasher, washer-dryer, microwave, oven, ironing board with iron, Nespresso coffee machine, kettle, TV, Wi-Fi and USB outlets for charging your devices. </p> </div> </div> <div class=\"spacer-single\"></div> <div class=\"row g-4\"> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Size</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:6px;\"> <img src=\"/images/home.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">83 mΒ²</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Bedrooms</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:4px;\"> <img src=\"/images/bed.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">3</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Living Room</h5> <div class=\"d-flex justify-content-start align-items-center\"> <img src=\"/images/sofa.png\" width=\"50\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">Included</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Kitchen</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:6px;\"> <img src=\"/images/cooking.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">Included</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Bathrooms</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:4px;\"> <img src=\"/images/bathroom.png\" width=\"40\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">2</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Guests</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:5px;\"> <img src=\"/images/user.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">8</div> </div> </div> </div> </div> </div> </section> <section id=\"rooms\" class=\"p-0 overflow-hidden\"> <div class=\"container-fluid\"> <div class=\"row\"> <div class=\"col-lg-12\"> <div class=\"owl-custom-nav menu-float\" data-target=\"#room-carousel\"> <a class=\"btn-next\"></a> <a class=\"btn-prev\"></a> <div id=\"room-carousel\" class=\"owl-2-cols-center owl-carousel owl-theme\"> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-0 z-2 p-4\"> <h3 style=\"color:white;\">Living Room</h3> </div> <img src=\"/images/salon2.jpeg\" class=\"w-100\" alt=\"Living Room\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-1 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 1</h3> </div> <img src=\"/images/chambre1.jpeg\" class=\"w-100\" alt=\"Bedroom 1\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-2 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 2</h3> </div> <img src=\"/images/chambre2.jpeg\" class=\"w-100\" alt=\"Bedroom 2\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-3 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 3</h3> </div> <img src=\"/images/chambre3.jpeg\" class=\"w-100\" alt=\"Bedroom 3\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-4 z-2 p-4\"> <h3 style=\"color:white;\">Kitchen</h3> </div> <img src=\"/images/cuisine.jpeg\" class=\"w-100\" alt=\"Kitchen\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-5 z-2 p-4\"> <h3 style=\"color:white;\">Bathroom</h3> </div> <img src=\"/images/salledebain.jpeg\" class=\"w-100\" alt=\"Bathroom 1\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-6 z-2 p-4\"> <h3 style=\"color:white;\">Bathroom 2</h3> </div> <img src=\"/images/salledebain2.jpeg\" class=\"w-100\" alt=\"Bathroom 2\"> </div> </div> </div> </div> </div> </div> </div> </div> </section> <section id=\"services\" class=\"overlay-dark-1\"> <div class=\"container\"> <div class=\"row g-4 justify-content-between\"> <div class=\"col-lg-5 relative z-3\"> <div class=\"me-lg-3\"> <div class=\"subtitle wow fadeInUp\" data-wow-delay=\".0s\">Your stay in Strasbourg</div> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Rates and services</h2> <p style=\"color:#212121; font-size:18px;\">An exceptional suite in the heart of Strasbourg, with optionnal dedicated concierge service to assist you throughout your stay.</p> <p style=\"color:#212121; font-size:18px;\">Minimum booking of two nights.</p> <a href=\"#reservation\" class=\"btn-main\" style=\"color:white;\">Booking</a> </div> </div> <div class=\"col-lg-6\" style=\"color:black;\"> <div class=\"spacer-single spacer-double\"></div> <div class=\"row\"> <div class=\"col-md-6 wow fadeInUp\" data-wow-delay=\".2s\"> "; // line 282 yield " <ul class=\"ul-check fs-500\"> <li>from β¬350 per night</li> <li>10% discount for bookings of 7 nights and up</li> </ul> </div> <div class=\"col-md-6 wow fadeInUp\" data-wow-delay=\".4s\"> <h5 class=\"mb-3\">Optional services</h5> <ul class=\"ul-check fs-500\"> <li>One parking space: β¬24/day or β¬150/week</li> <li>Extra cleaning during your stay : 60 euros</li> <li>Other Extras : Children's workshop, baby amenities, dog policy on request (other pets are unfortunately not allowed in the appartement), Decoration for special occasions, breakfast, Alsatian delicacies, etc</li> </ul> <div class=\"mt-4\"> <p class=\"fs-500\"> <strong>On site assistance</strong> <br /> <small>Tuesday to Saturday β’ 10am-6:45pm</small> </p> <p class=\"fs-500\"> <strong>Private concierge subject to availability</strong><br> <small>Quotation on request</small> </p> </div> </div> </div> </div> </div> </div> </section> <section id=\"section-gallery\" class=\"relative\"> <div class=\"container relative z-2\" id=\"photos\"> <div class=\"row g-4 gx-5 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Apartment Gallery</h2> <p class=\"wow fadeInUp\" data-wow-delay=\".3s\" style=\"color:#212121;\">Explore our curated images to discover the residence's various spaces β from the bedrooms and living area to the kitchen, bathroom, and outdoor surroundings.</p> </div> </div> <div class=\"row\"> <div class=\"col-md-12 text-center\"> <ul id=\"filters\" class=\"wow fadeInUp\" data-wow-delay=\"0s\"> <li><a href=\"#\" data-filter=\"*\" class=\"selected\" style=\"color:#212121;\">Show All</a></li> <li><a href=\"#\" data-filter=\".chambre\" style=\"color:#212121;\">Bedrooms</a></li> <li><a href=\"#\" data-filter=\".salon\" style=\"color:#212121;\">Living Room</a></li> <li><a href=\"#\" data-filter=\".cuisine\" style=\"color:#212121;\">Kitchen</a></li> <li><a href=\"#\" data-filter=\".salledebain\" style=\"color:#212121;\">Bathroom</a></li> <li><a href=\"#\" data-filter=\".exterieur\" style=\"color:#212121;\">Outdoor surroundings</a></li> </ul> </div> </div> <div id=\"gallery\" class=\"row g-3 wow fadeInUp\" data-wow-delay=\".3s\"> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre1.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre1.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre3.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre3.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom 3\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon3.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon3.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 3\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon4.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon4.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 4\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon5.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon5.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 5\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item cuisine\"> <a href=\"images/cuisine.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/cuisine.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Kitchen\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salledebain\"> <a href=\"images/salledebain.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salledebain.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bathroom\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salledebain\"> <a href=\"images/salledebain2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salledebain2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bathroom 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item exterieur\"> <a href=\"images/exterieur.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/exterieur.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Exterior\"> </div> </a> </div> </div> </div> </section> "; // line 453 yield " "; // line 454 yield " "; // line 455 yield " <section id=\"reservation\" class=\"text-light\"> <div class=\"container\"> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Book your stay</h2> </div> </div> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-8\"> <div class=\"booking-card\"> "; // line 466 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderBlock((isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 466, $this->source); })()), 'form_start'); yield " "; // line 469 yield " <div class=\"calendar-container\" style=\"height:300px;\"> <input type=\"text\" id=\"date_range_picker\"> </div> "; // line 474 yield " <div class=\"row g-3 mt-2 dates-recap\"> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Arrival</div> <div class=\"recap-value\" id=\"info-start\">-</div> </div> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Departure</div> <div class=\"recap-value\" id=\"info-end\">-</div> </div> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Nights</div> <div class=\"recap-value\" id=\"info-nights\">-</div> </div> </div> <hr class=\"booking-divider\"> "; // line 492 yield " <h4 class=\"booking-title\">Select rooms and guests</h4> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Bedrooms</div> <div class=\"counter-sub\">Set by guest count</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"rooms\">β</button> <span class=\"counter-value\" id=\"cnt-rooms\">1</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"rooms\">+</button> </div> </div> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Adults</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"adults\">β</button> <span class=\"counter-value\" id=\"cnt-adults\">2</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"adults\">+</button> </div> </div> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Children</div> <div class=\"counter-sub\">1 - 17 years</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"children\">β</button> <span class=\"counter-value\" id=\"cnt-children\">0</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"children\">+</button> </div> </div> <div id=\"capacity-warning\" class=\"capacity-warning\" style=\"display:none;\"></div> "; // line 532 yield " <div id=\"results\" class=\"mt-3\"></div> <hr class=\"booking-divider\"> "; // line 537 yield " <div class=\"row g-3\"> <div class=\"col-md-6\"> <label class=\"booking-label\">Last name</label> "; // line 540 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 540, $this->source); })()), "lastname", [], "any", false, false, false, 540), 'widget'); yield " </div> <div class=\"col-md-6\"> <label class=\"booking-label\">First name</label> "; // line 544 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 544, $this->source); })()), "name", [], "any", false, false, false, 544), 'widget'); yield " </div> <div class=\"col-md-12\"> <label class=\"booking-label\">Email address</label> "; // line 548 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 548, $this->source); })()), "email", [], "any", false, false, false, 548), 'widget'); yield " </div> <div class=\"col-md-12\"> <label class=\"booking-label\">Message</label> "; // line 552 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 552, $this->source); })()), "message", [], "any", false, false, false, 552), 'widget'); yield " </div> </div> "; // line 557 yield " <div class=\"text-center mt-4 cgv-block\"> <input type=\"checkbox\" id=\"acceptCGV\" /> I accept the <a href=\"/terms\" target=\"_blank\" style=\"color:#212121; text-decoration:underline;\">terms and conditions of sale</a> </div> <div class=\"text-center mt-3\"> <button type=\"submit\" name=\"submit\" value=\"1\" class=\"btn-main\" style=\"color:white;\">Send booking request</button> </div> "; // line 565 yield " "; yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 565, $this->source); })()), "start", [], "any", false, false, false, 565), 'widget'); yield " "; // line 566 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 566, $this->source); })()), "end", [], "any", false, false, false, 566), 'widget'); yield " "; // line 567 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 567, $this->source); })()), "rooms", [], "any", false, false, false, 567), 'widget'); yield " "; // line 568 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 568, $this->source); })()), "adults", [], "any", false, false, false, 568), 'widget'); yield " "; // line 569 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 569, $this->source); })()), "children", [], "any", false, false, false, 569), 'widget'); yield " "; // line 570 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(CoreExtension::getAttribute($this->env, $this->source, (isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 570, $this->source); })()), "persons", [], "any", false, false, false, 570), 'widget'); yield " "; // line 572 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock((isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 572, $this->source); })()), 'rest'); yield " "; // line 573 yield $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderBlock((isset($context["form"]) || array_key_exists("form", $context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.', 573, $this->source); })()), 'form_end'); yield " </div> </div> </div> </div> </section> <section id=\"faq\" class=\"text-light\"> <div class=\"container\"> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">FAQ</h2> </div> </div> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-left\" style=\"color:black !important;\"> <h3 style=\"margin-top:7px;\">How can I book the accommodation?</h3> <div>You can book directly on our website and soon via partner platforms. Secure payment immediately confirms your reservation.</div> <h3 style=\"margin-top:7px;\">What are the check-in and check-out times?</h3> <div> <ul> <li>Check-in: from 3:00 PM</li> <li>Check-out: before 11:00 AM</li> </ul> </div> <h3 style=\"margin-top:7px;\">Is the accommodation fully equipped?</h3> <div> Yes, the apartment is fully furnished and equipped: kitchen, bedding, towels, appliances, Wi-Fi, and more.</div> <h3 style=\"margin-top:7px;\">Is parking available?</h3> <div>Yes, private parking is available as an option at β¬24 per 24 hours or β¬150 per week (7 nights).</div> <h3 style=\"margin-top:7px;\">Is the accommodation suitable for children?</h3> <div>Yes, we offer some baby amenities (baby cot, high chair, child-friendly tableware) upon request.</div> <h3 style=\"margin-top:7px;\"> Are pets allowed?</h3> <div> Please contact us before booking if you wish to bring a pet. Only dogs are accepted, and prior approval is required.</div> <h3 style=\"margin-top:7px;\">Can I cancel or modify my reservation?</h3> <div>Yes, our cancellation policy is provided at the time of booking: <ul> <li>85% refund if canceled more than 1 month before arrival</li> <li>50% refund if canceled between 1 month and 15 days before arrival</li> <li>No refund if canceled less than 15 days before arrival</li> </ul> </div> <h3 style=\"margin-top:7px;\">Is the accommodation accessible by public transport?</h3> <div>Yes, major transport options are nearby. The tram station \"Langstross, Grand'rue\" is less than 100 meters from the apartment, and Strasbourg train station is a 10-minute walk.</div> <h3 style=\"margin-top:7px;\">Are there shops or restaurants nearby?</h3> <div>Yes, you'll find supermarkets, cafΓ©s, restaurants, and tourist activities right at the foot of the building.</div> <h3 style=\"margin-top:7px;\"> What should I do if there's a problem during my stay?</h3> <div> We are available 24/7 by email for emergencies or questions about the apartment. You can also call us from 9:00 AM to 8:00 PM at +33 7 61 05 82 43, and we are available on-site on the ground floor of the building from Tuesday to Saturday, 10:00 AM to 6:45 PM. </div> </div> </div> </div> </section>"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 642 /** * @return iterable<null|scalar|\Stringable> */ public function block_footerjs(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "footerjs")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "footerjs")); // line 643 yield " <script src=\"https://cdn.jsdelivr.net/npm/flatpickr\"></script> "; // line 646 yield " <script> window.PRICING_MATRIX = "; // line 647 yield json_encode((isset($context["pricingMatrix"]) || array_key_exists("pricingMatrix", $context) ? $context["pricingMatrix"] : (function () { throw new RuntimeError('Variable "pricingMatrix" does not exist.', 647, $this->source); })())); yield "; window.SIMULATION_URL = \""; // line 648 yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("simulation_pricing"); yield "\"; console.log('π Off-peak pricing matrix loaded:', window.PRICING_MATRIX); console.log('π Simulation URL:', window.SIMULATION_URL); </script> <script> // =========================================================== // Bedrooms / adults / children logic // // Physical layout: // - Bedroom A: double bed β 2 people // - Bedroom B: double bed β 2 people // - Bedroom C: bunk beds β 4 people (adults/children mix) // // The number of bedrooms is DETERMINED automatically (no choice): // // WITHOUT CHILDREN: // 1-2 ad β 1 br // 3-4 ad β 2 br // 5-8 ad β 3 br // // WITH CHILDREN: // 1-2 ad β 2 br (bedroom A + bunk room) // 3+ ad β 3 br (A + B + bunk room) // // Constraints: adults + children β€ 8, children β€ 4, adults β₯ 1 // =========================================================== function roomsForCombo(adults, children) { if (children > 0) { return adults <= 2 ? 2 : 3; } if (adults <= 2) return 1; if (adults <= 4) return 2; return 3; } function canAddAdult(state) { if (state.adults >= 8) return false; return (state.adults + 1 + state.children) <= 8; } function canAddChild(state) { if (state.children >= 4) return false; return (state.adults + state.children + 1) <= 8; } const state = { rooms: 1, adults: 2, children: 0 }; function updateDisplay() { // Bedrooms count is recalculated automatically on each update state.rooms = roomsForCombo(state.adults, state.children); \$('#cnt-rooms').text(state.rooms); \$('#cnt-adults').text(state.adults); \$('#cnt-children').text(state.children); \$('#reservation_form_rooms').val(state.rooms); \$('#reservation_form_adults').val(state.adults); \$('#reservation_form_children').val(state.children); \$('#reservation_form_persons').val(state.adults + state.children); \$('.counter-btn').each(function() { const target = \$(this).data('target'); const action = \$(this).data('action'); let disabled = false; if (target === 'rooms') { // Bedrooms = always locked (set by adults/children) disabled = true; } if (target === 'adults') { if (action === 'dec' && state.adults <= 1) disabled = true; if (action === 'inc' && !canAddAdult(state)) disabled = true; } if (target === 'children') { if (action === 'dec' && state.children <= 0) disabled = true; if (action === 'inc' && !canAddChild(state)) disabled = true; } \$(this).prop('disabled', disabled).toggleClass('disabled', disabled); }); \$('#capacity-warning').hide(); } \$(document).on('click', '.counter-btn', function() { if (\$(this).prop('disabled')) return; const target = \$(this).data('target'); const action = \$(this).data('action'); // No action on \"rooms\" (always disabled) if (target === 'adults') { if (action === 'inc' && canAddAdult(state)) state.adults++; if (action === 'dec' && state.adults > 1) state.adults--; } if (target === 'children') { if (action === 'inc' && canAddChild(state)) state.children++; if (action === 'dec' && state.children > 0) state.children--; } updateDisplay(); updateSimulation(); }); function updateSimulation() { const start = \$(\"#reservation_form_start\").val(); const end = \$(\"#reservation_form_end\").val(); const persons = state.adults + state.children; console.log('π updateSimulation', { start, end, rooms: state.rooms, adults: state.adults, children: state.children }); if (!start || !end || persons < 1) { \$(\"#results\").html(''); return; } \$(\"#results\").html('<div class=\"loading\" style=\"color:#212121;\">Calculating...</div>'); \$.post( window.SIMULATION_URL, { start: start, end: end, rooms: state.rooms, adults: state.adults, children: state.children } ) .done(function(data) { console.log('β
Simulation OK'); \$(\"#results\").html(data); }) .fail(function(xhr) { console.error('β Simulation KO', xhr.status, xhr.responseText); \$(\"#results\").html('<div class=\"error\" style=\"color:#a00;\">Error calculating price (' + xhr.status + ')</div>'); }); } \$(document).ready(function() { updateDisplay(); \$('button[type=\"submit\"]').prop('disabled', true); \$('#acceptCGV').change(function() { \$('button[type=\"submit\"]').prop('disabled', !\$(this).is(':checked')); }); }); </script> <script> // =========================================================== // Flatpickr calendar // =========================================================== \$(document).ready(function() { let bookedRanges = []; \$.ajax({ url: '"; // line 802 yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['App\Twig\CoreExtension']->getEnvironmentVariable("WEBHOOK_CALENDAR_AVAILABILITY"), "html", null, true); yield "', method: 'POST', contentType: 'application/json', data: '' }) .done(function(data) { bookedRanges = data.bookings || []; initDatePicker(); }) .fail(function() { initDatePicker(); }); function parseLocalDate(dateStr) { const [year, month, day] = dateStr.split('-').map(Number); return new Date(year, month - 1, day); } const isMobile = window.innerWidth <= 900; function initDatePicker() { flatpickr(\"#date_range_picker\", { inline: true, mode: \"range\", minDate: new Date(new Date().setDate(new Date().getDate() + 1)), dateFormat: \"Y-m-d\", showMonths: isMobile ? 1 : 2, disable: [ function(date) { const checkDate = new Date(date); checkDate.setHours(0, 0, 0, 0); return bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return checkDate >= start && checkDate <= end; }); } ], onChange: function(selectedDates, dateStr, instance) { if (selectedDates.length === 2) { const start = selectedDates[0]; const end = selectedDates[1]; if (isRangeAvailable(start, end)) { \$('#reservation_form_start').val(formatDate(start)).trigger('change'); \$('#reservation_form_end').val(formatDate(end)).trigger('change'); updateSelectedInfo(start, end); updateSimulation(); } else { alert('β οΈ This period contains already booked dates.'); instance.clear(); clearSymfonyFields(); hideSelectedInfo(); \$(\"#results\").html(''); } } else { clearSymfonyFields(); hideSelectedInfo(); \$(\"#results\").html(''); } }, onDayCreate: function(dObj, dStr, fp, dayElem) { const date = new Date(dayElem.dateObj); date.setHours(0, 0, 0, 0); const isBooked = bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return date >= start && date <= end; }); if (isBooked) { dayElem.classList.add('booked'); dayElem.title = 'Unavailable date (booked)'; } else if (date >= new Date()) { dayElem.classList.add('available'); } } }); } function isRangeAvailable(startDate, endDate) { let currentDate = new Date(startDate); currentDate.setHours(0, 0, 0, 0); const endCheck = new Date(endDate); endCheck.setHours(0, 0, 0, 0); while (currentDate <= endCheck) { const isBooked = bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return currentDate >= start && currentDate <= end; }); if (isBooked) return false; currentDate.setDate(currentDate.getDate() + 1); } return true; } function updateSelectedInfo(start, end) { const nights = Math.ceil((end - start) / (1000 * 60 * 60 * 24)); \$('#info-start').text(start.toLocaleDateString('en-GB')); \$('#info-end').text(end.toLocaleDateString('en-GB')); \$('#info-nights').text(nights + ' night' + (nights > 1 ? 's' : '')); } function hideSelectedInfo() { \$('#info-start').text('-'); \$('#info-end').text('-'); \$('#info-nights').text('-'); } function clearSymfonyFields() { \$('#reservation_form_start').val(''); \$('#reservation_form_end').val(''); } function formatDate(date) { return date.getFullYear() + '-' + String(date.getMonth() + 1).padStart(2, '0') + '-' + String(date.getDate()).padStart(2, '0'); } }); </script>"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } // line 926 /** * @return iterable<null|scalar|\Stringable> */ public function block_css(array $context, array $blocks = []): iterable { $macros = $this->macros; $__internal_5a27a8ba21ca79b61932376b2fa922d2 = $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"]; $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "css")); $__internal_6f47bbe9983af81f1e7450e9a3e3768f = $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"]; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block", "css")); // line 927 yield " <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css\"> <style> /* =========================================================== Booking card (white border, transparent bg, black text) =========================================================== */ .booking-card { background: transparent; border: 2px solid white; border-radius: 12px; padding: 32px; color: #212121; } .booking-title { color: #212121; font-weight: 700; margin-bottom: 24px; } .booking-divider { border-top: 1px solid rgba(0,0,0,0.15); margin: 28px 0; } .booking-label { color: #212121; font-weight: 500; margin-bottom: 6px; display: block; } .booking-card input.form-control, .booking-card textarea.form-control { background: rgba(255,255,255,0.85) !important; border: 1px solid rgba(0,0,0,0.2) !important; color: #212121 !important; } .booking-card input.form-control::placeholder, .booking-card textarea.form-control::placeholder { color: rgba(0,0,0,0.4) !important; } .booking-card input.form-control:focus, .booking-card textarea.form-control:focus { border-color: #212121 !important; box-shadow: 0 0 0 0.2rem rgba(0,0,0,0.08) !important; } .cgv-block { color: #212121; } .cgv-block a { color: #212121; text-decoration: underline; } .dates-recap { color: #212121; } .recap-label { font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.7; } .recap-value { font-size: 18px; font-weight: 600; margin-top: 4px; } .counter-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid rgba(0,0,0,0.1); } .counter-row:last-of-type { border-bottom: none; } .counter-title { font-size: 16px; font-weight: 500; color: #212121; } .counter-sub { font-size: 12px; color: rgba(0,0,0,0.6); margin-top: 2px; } .counter-controls { display: flex; align-items: center; gap: 12px; } .counter-btn { width: 40px; height: 40px; border-radius: 8px; border: 1.5px solid #212121; background: transparent; color: #212121; font-size: 20px; font-weight: 600; line-height: 1; cursor: pointer; transition: all 0.15s; } .counter-btn:hover:not(.disabled) { background: rgba(0,0,0,0.06); } .counter-btn.disabled, .counter-btn:disabled { border-color: rgba(0,0,0,0.2); color: rgba(0,0,0,0.25); cursor: not-allowed; background: transparent; } .counter-value { min-width: 28px; text-align: center; font-size: 16px; font-weight: 500; color: #212121; } .capacity-warning { margin-top: 12px; padding: 10px 14px; background: rgba(255,180,0,0.18); border: 1px solid rgba(180,120,0,0.5); border-radius: 6px; color: #8a4500; font-size: 14px; } .calendar-container { margin: 0 0 8px 0; width: 100%; display: flex; justify-content: center; } #date_range_picker { display: none; } .flatpickr-calendar.inline { box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 8px; } .flatpickr-day.booked { background-color: #ff4444 !important; color: white !important; cursor: not-allowed !important; position: relative; } .flatpickr-day.booked::after { content: \"β\"; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 20px; font-weight: bold; } .flatpickr-day.booked:hover { background-color: #ff0000 !important; } .flatpickr-day.available:hover { background-color: #28a745; color: white; } @media (max-width: 768px) { .booking-card { padding: 20px; } .calendar-container { margin: 0 0 8px 0; padding: 0; } .flatpickr-calendar.inline { width: 100% !important; max-width: 100% !important; } .flatpickr-months { padding: 8px 10px; } .flatpickr-days { width: 100% !important; } .dayContainer { width: 100% !important; min-width: 100% !important; max-width: 100% !important; } .flatpickr-day { height: 40px !important; line-height: 40px !important; flex-basis: 14.2857% !important; max-width: 14.2857% !important; } } </style>"; $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof); $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof); yield from []; } /** * @codeCoverageIgnore */ public function getTemplateName(): string { return "vitrine/en/homepage.html.twig"; } /** * @codeCoverageIgnore */ public function isTraitable(): bool { return false; } /** * @codeCoverageIgnore */ public function getDebugInfo(): array { return array ( 1183 => 927, 1170 => 926, 1036 => 802, 879 => 648, 875 => 647, 872 => 646, 868 => 643, 855 => 642, 776 => 573, 772 => 572, 767 => 570, 763 => 569, 759 => 568, 755 => 567, 751 => 566, 746 => 565, 737 => 557, 730 => 552, 723 => 548, 716 => 544, 709 => 540, 704 => 537, 698 => 532, 657 => 492, 638 => 474, 632 => 469, 627 => 466, 614 => 455, 612 => 454, 610 => 453, 438 => 282, 179 => 15, 166 => 14, 151 => 8, 138 => 7, 115 => 5, 92 => 4, 69 => 3, 46 => 1,); } public function getSourceContext(): Source { return new Source("{% extends 'vitrine/en/layout.html.twig' %}{% block title %}Cathedral Heritage Suite - 8-Guest Rental Strasbourg Center{% endblock title %}{% block description %}Rent our 83mΒ² suite in the heart of Strasbourg. 3 bedrooms, sleeps 8, 100m from Cathedral. Kitchen fully furnished, 2 bathrooms. Book your stay today!{% endblock description %}{% block robots %}index,follow{% endblock robots %}{% block canonical %} <link rel=\"canonical\" href=\"https://cathedraleheritage.com\" /> <link rel=\"alternate\" hreflang=\"fr\" href=\"https://cathedraleheritage.com/fr\" /> <link rel=\"alternate\" hreflang=\"en\" href=\"https://cathedraleheritage.com\" /> <link rel=\"alternate\" hreflang=\"x-default\" href=\"https://cathedraleheritage.com\" />{% endblock canonical %}{% block body %} <section id=\"hero\" class=\"text-light no-top no-bottom relative overflow-hidden z-1000\"> <div class=\"abs w-100 abs-centered z-2\"> <div class=\"container\"> <div class=\"spacer-double\"></div> <div class=\"row g-4 align-items-center justify-content-center\"> <div class=\"col-md-8 text-center\"> <h1 class=\"mb-2\" style=\"color:white;\">Welcome to Cathedral Heritage Suite</h1> <p class=\"lead mb-3\" style=\"color:white; font-size:22px;\">Beautifully appointed apartment accommodating up to 8 guests in Strasbourg's prestigious historical city center</p> <a class=\"btn-main btn-line bg-blur fx-slide\" href=\"#about\" style=\"color:white;\"><span>Find out more</span></a> </div> </div> </div> </div> <div class=\"vertical-center\"> <div class=\"swiper\"> <div class=\"swiper-wrapper\"> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/salon2.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/chambre2.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> <div class=\"swiper-slide\"> <div class=\"swiper-inner\" data-bgimage=\"url(/images/noel.jpeg)\"> <div class=\"sw-overlay op-5\"></div> </div> </div> </div> </div> </div> <div class=\"abs w-100 bottom-0 z-2 pb-4 sm-hide\"> <div class=\"container\"> <div class=\"row\"> <div class=\"col-lg-12\"> <div class=\"d-flex justify-content-between\"> <div><h6 style=\"color:white;\">Cathedral 100m away</h6></div> <div><h6 style=\"color:white;\">Museums 200m away</h6></div> <div><h6 style=\"color:white;\">Petite France 300m away</h6></div> </div> </div> </div> </div> </div> <div class=\"gradient-edge-bottom op-8\"></div> </section> <section id=\"about\"> <div class=\"container\"> <div class=\"row g-4 align-items-end justify-content-between\"> <div class=\"col-lg-5\"> <div class=\"subtitle\">About the apartment</div> <h2>Modern suite in the heart of Strasbourg's Grande Γle</h2> </div> <div class=\"col-lg-4\"> <p class=\"mb-4\" style=\"color:#212121;\"> Spacious fully equipped appartement ideal for families and groups up to 8 people : 1 master bedroom with en-suite bathroom, one double bedroom, one bedroom with two double bunk beds (sleeps 4), maximum weight of 100kg for upper bunks. </p> <p class=\"mb-4\" style=\"color:#212121;\"> Kitchen fully furnished and cozy living-dining room to share great moments together. </p> <p class=\"mb-4\" style=\"color:#212121;\"> Amenities: hairdryer, dishwasher, washer-dryer, microwave, oven, ironing board with iron, Nespresso coffee machine, kettle, TV, Wi-Fi and USB outlets for charging your devices. </p> </div> </div> <div class=\"spacer-single\"></div> <div class=\"row g-4\"> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Size</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:6px;\"> <img src=\"/images/home.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">83 mΒ²</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Bedrooms</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:4px;\"> <img src=\"/images/bed.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">3</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Living Room</h5> <div class=\"d-flex justify-content-start align-items-center\"> <img src=\"/images/sofa.png\" width=\"50\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">Included</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Kitchen</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:6px;\"> <img src=\"/images/cooking.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">Included</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Bathrooms</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:4px;\"> <img src=\"/images/bathroom.png\" width=\"40\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">2</div> </div> </div> </div> <div class=\"col-md-2\"> <div class=\"relative\"> <h5>Guests</h5> <div class=\"d-flex justify-content-start align-items-center\" style=\"padding-top:5px;\"> <img src=\"/images/user.png\" width=\"37\" class=\"me-3\" alt=\"\"> <div class=\"fs-20 fw-600\" style=\"color:#212121;\">8</div> </div> </div> </div> </div> </div> </section> <section id=\"rooms\" class=\"p-0 overflow-hidden\"> <div class=\"container-fluid\"> <div class=\"row\"> <div class=\"col-lg-12\"> <div class=\"owl-custom-nav menu-float\" data-target=\"#room-carousel\"> <a class=\"btn-next\"></a> <a class=\"btn-prev\"></a> <div id=\"room-carousel\" class=\"owl-2-cols-center owl-carousel owl-theme\"> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-0 z-2 p-4\"> <h3 style=\"color:white;\">Living Room</h3> </div> <img src=\"/images/salon2.jpeg\" class=\"w-100\" alt=\"Living Room\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-1 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 1</h3> </div> <img src=\"/images/chambre1.jpeg\" class=\"w-100\" alt=\"Bedroom 1\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-2 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 2</h3> </div> <img src=\"/images/chambre2.jpeg\" class=\"w-100\" alt=\"Bedroom 2\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-3 z-2 p-4\"> <h3 style=\"color:white;\">Bedroom 3</h3> </div> <img src=\"/images/chambre3.jpeg\" class=\"w-100\" alt=\"Bedroom 3\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-4 z-2 p-4\"> <h3 style=\"color:white;\">Kitchen</h3> </div> <img src=\"/images/cuisine.jpeg\" class=\"w-100\" alt=\"Kitchen\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-5 z-2 p-4\"> <h3 style=\"color:white;\">Bathroom</h3> </div> <img src=\"/images/salledebain.jpeg\" class=\"w-100\" alt=\"Bathroom 1\"> </div> </div> </div> <div class=\"item\"> <div class=\"relative\"> <div class=\"overflow-hidden text-light\"> <div class=\"abs h-100 start-6 z-2 p-4\"> <h3 style=\"color:white;\">Bathroom 2</h3> </div> <img src=\"/images/salledebain2.jpeg\" class=\"w-100\" alt=\"Bathroom 2\"> </div> </div> </div> </div> </div> </div> </div> </div> </section> <section id=\"services\" class=\"overlay-dark-1\"> <div class=\"container\"> <div class=\"row g-4 justify-content-between\"> <div class=\"col-lg-5 relative z-3\"> <div class=\"me-lg-3\"> <div class=\"subtitle wow fadeInUp\" data-wow-delay=\".0s\">Your stay in Strasbourg</div> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Rates and services</h2> <p style=\"color:#212121; font-size:18px;\">An exceptional suite in the heart of Strasbourg, with optionnal dedicated concierge service to assist you throughout your stay.</p> <p style=\"color:#212121; font-size:18px;\">Minimum booking of two nights.</p> <a href=\"#reservation\" class=\"btn-main\" style=\"color:white;\">Booking</a> </div> </div> <div class=\"col-lg-6\" style=\"color:black;\"> <div class=\"spacer-single spacer-double\"></div> <div class=\"row\"> <div class=\"col-md-6 wow fadeInUp\" data-wow-delay=\".2s\"> {# <h5 class=\" mb-3\">Peak Season</h5> <p class=\"fs-500\"><small>June 1st to September 30th β’ November 25th to January 5th</small></p> <ul class=\"ul-check fs-500\"> <li>β¬960 per night</li> <li>10% discount for bookings of 7 nights and up</li> </ul> <h5 class=\"mb-3 mt-4\">Off-peak Season</h5> #} <ul class=\"ul-check fs-500\"> <li>from β¬350 per night</li> <li>10% discount for bookings of 7 nights and up</li> </ul> </div> <div class=\"col-md-6 wow fadeInUp\" data-wow-delay=\".4s\"> <h5 class=\"mb-3\">Optional services</h5> <ul class=\"ul-check fs-500\"> <li>One parking space: β¬24/day or β¬150/week</li> <li>Extra cleaning during your stay : 60 euros</li> <li>Other Extras : Children's workshop, baby amenities, dog policy on request (other pets are unfortunately not allowed in the appartement), Decoration for special occasions, breakfast, Alsatian delicacies, etc</li> </ul> <div class=\"mt-4\"> <p class=\"fs-500\"> <strong>On site assistance</strong> <br /> <small>Tuesday to Saturday β’ 10am-6:45pm</small> </p> <p class=\"fs-500\"> <strong>Private concierge subject to availability</strong><br> <small>Quotation on request</small> </p> </div> </div> </div> </div> </div> </div> </section> <section id=\"section-gallery\" class=\"relative\"> <div class=\"container relative z-2\" id=\"photos\"> <div class=\"row g-4 gx-5 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Apartment Gallery</h2> <p class=\"wow fadeInUp\" data-wow-delay=\".3s\" style=\"color:#212121;\">Explore our curated images to discover the residence's various spaces β from the bedrooms and living area to the kitchen, bathroom, and outdoor surroundings.</p> </div> </div> <div class=\"row\"> <div class=\"col-md-12 text-center\"> <ul id=\"filters\" class=\"wow fadeInUp\" data-wow-delay=\"0s\"> <li><a href=\"#\" data-filter=\"*\" class=\"selected\" style=\"color:#212121;\">Show All</a></li> <li><a href=\"#\" data-filter=\".chambre\" style=\"color:#212121;\">Bedrooms</a></li> <li><a href=\"#\" data-filter=\".salon\" style=\"color:#212121;\">Living Room</a></li> <li><a href=\"#\" data-filter=\".cuisine\" style=\"color:#212121;\">Kitchen</a></li> <li><a href=\"#\" data-filter=\".salledebain\" style=\"color:#212121;\">Bathroom</a></li> <li><a href=\"#\" data-filter=\".exterieur\" style=\"color:#212121;\">Outdoor surroundings</a></li> </ul> </div> </div> <div id=\"gallery\" class=\"row g-3 wow fadeInUp\" data-wow-delay=\".3s\"> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre1.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre1.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item chambre\"> <a href=\"images/chambre3.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/chambre3.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bedroom 3\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon3.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon3.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 3\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon4.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon4.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 4\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salon\"> <a href=\"images/salon5.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salon5.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Living Room 5\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item cuisine\"> <a href=\"images/cuisine.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/cuisine.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Kitchen\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salledebain\"> <a href=\"images/salledebain.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salledebain.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bathroom\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item salledebain\"> <a href=\"images/salledebain2.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/salledebain2.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Bathroom 2\"> </div> </a> </div> <div class=\"col-md-3 col-sm-6 col-12 item exterieur\"> <a href=\"images/exterieur.jpeg\" class=\"image-popup d-block hover\"> <div class=\"relative overflow-hidden\"> <div class=\"absolute start-0 w-100 hover-op-1 p-5 abs-middle z-2 text-center text-white z-3\">View</div> <div class=\"absolute start-0 w-100 h-100 overlay-dark-7 hover-op-1 z-2\"></div> <img src=\"images/exterieur.jpeg\" class=\"w-100 hover-scale-1-2\" alt=\"Exterior\"> </div> </a> </div> </div> </div> </section> {# =================================================== #} {# ============ BOOKING SECTION (refactored) ========= #} {# =================================================== #} <section id=\"reservation\" class=\"text-light\"> <div class=\"container\"> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">Book your stay</h2> </div> </div> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-8\"> <div class=\"booking-card\"> {{ form_start(form) }} {# ----- CALENDAR ----- #} <div class=\"calendar-container\" style=\"height:300px;\"> <input type=\"text\" id=\"date_range_picker\"> </div> {# ----- DATES RECAP (just below the calendar) ----- #} <div class=\"row g-3 mt-2 dates-recap\"> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Arrival</div> <div class=\"recap-value\" id=\"info-start\">-</div> </div> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Departure</div> <div class=\"recap-value\" id=\"info-end\">-</div> </div> <div class=\"col-4 text-center\"> <div class=\"recap-label\">Nights</div> <div class=\"recap-value\" id=\"info-nights\">-</div> </div> </div> <hr class=\"booking-divider\"> {# ----- COUNTERS ----- #} <h4 class=\"booking-title\">Select rooms and guests</h4> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Bedrooms</div> <div class=\"counter-sub\">Set by guest count</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"rooms\">β</button> <span class=\"counter-value\" id=\"cnt-rooms\">1</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"rooms\">+</button> </div> </div> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Adults</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"adults\">β</button> <span class=\"counter-value\" id=\"cnt-adults\">2</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"adults\">+</button> </div> </div> <div class=\"counter-row\"> <div class=\"counter-label\"> <div class=\"counter-title\">Children</div> <div class=\"counter-sub\">1 - 17 years</div> </div> <div class=\"counter-controls\"> <button type=\"button\" class=\"counter-btn\" data-action=\"dec\" data-target=\"children\">β</button> <span class=\"counter-value\" id=\"cnt-children\">0</span> <button type=\"button\" class=\"counter-btn\" data-action=\"inc\" data-target=\"children\">+</button> </div> </div> <div id=\"capacity-warning\" class=\"capacity-warning\" style=\"display:none;\"></div> {# ----- PRICE RESULT ----- #} <div id=\"results\" class=\"mt-3\"></div> <hr class=\"booking-divider\"> {# ----- PERSONAL INFO ----- #} <div class=\"row g-3\"> <div class=\"col-md-6\"> <label class=\"booking-label\">Last name</label> {{ form_widget(form.lastname) }} </div> <div class=\"col-md-6\"> <label class=\"booking-label\">First name</label> {{ form_widget(form.name) }} </div> <div class=\"col-md-12\"> <label class=\"booking-label\">Email address</label> {{ form_widget(form.email) }} </div> <div class=\"col-md-12\"> <label class=\"booking-label\">Message</label> {{ form_widget(form.message) }} </div> </div> {# ----- T&C + SUBMIT ----- #} <div class=\"text-center mt-4 cgv-block\"> <input type=\"checkbox\" id=\"acceptCGV\" /> I accept the <a href=\"/terms\" target=\"_blank\" style=\"color:#212121; text-decoration:underline;\">terms and conditions of sale</a> </div> <div class=\"text-center mt-3\"> <button type=\"submit\" name=\"submit\" value=\"1\" class=\"btn-main\" style=\"color:white;\">Send booking request</button> </div> {# Hidden fields #} {{ form_widget(form.start) }} {{ form_widget(form.end) }} {{ form_widget(form.rooms) }} {{ form_widget(form.adults) }} {{ form_widget(form.children) }} {{ form_widget(form.persons) }} {{ form_rest(form) }} {{ form_end(form) }} </div> </div> </div> </div> </section> <section id=\"faq\" class=\"text-light\"> <div class=\"container\"> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-center\"> <h2 class=\"wow fadeInUp\" data-wow-delay=\".2s\">FAQ</h2> </div> </div> <div class=\"row g-4 justify-content-center\"> <div class=\"col-lg-6 text-left\" style=\"color:black !important;\"> <h3 style=\"margin-top:7px;\">How can I book the accommodation?</h3> <div>You can book directly on our website and soon via partner platforms. Secure payment immediately confirms your reservation.</div> <h3 style=\"margin-top:7px;\">What are the check-in and check-out times?</h3> <div> <ul> <li>Check-in: from 3:00 PM</li> <li>Check-out: before 11:00 AM</li> </ul> </div> <h3 style=\"margin-top:7px;\">Is the accommodation fully equipped?</h3> <div> Yes, the apartment is fully furnished and equipped: kitchen, bedding, towels, appliances, Wi-Fi, and more.</div> <h3 style=\"margin-top:7px;\">Is parking available?</h3> <div>Yes, private parking is available as an option at β¬24 per 24 hours or β¬150 per week (7 nights).</div> <h3 style=\"margin-top:7px;\">Is the accommodation suitable for children?</h3> <div>Yes, we offer some baby amenities (baby cot, high chair, child-friendly tableware) upon request.</div> <h3 style=\"margin-top:7px;\"> Are pets allowed?</h3> <div> Please contact us before booking if you wish to bring a pet. Only dogs are accepted, and prior approval is required.</div> <h3 style=\"margin-top:7px;\">Can I cancel or modify my reservation?</h3> <div>Yes, our cancellation policy is provided at the time of booking: <ul> <li>85% refund if canceled more than 1 month before arrival</li> <li>50% refund if canceled between 1 month and 15 days before arrival</li> <li>No refund if canceled less than 15 days before arrival</li> </ul> </div> <h3 style=\"margin-top:7px;\">Is the accommodation accessible by public transport?</h3> <div>Yes, major transport options are nearby. The tram station \"Langstross, Grand'rue\" is less than 100 meters from the apartment, and Strasbourg train station is a 10-minute walk.</div> <h3 style=\"margin-top:7px;\">Are there shops or restaurants nearby?</h3> <div>Yes, you'll find supermarkets, cafΓ©s, restaurants, and tourist activities right at the foot of the building.</div> <h3 style=\"margin-top:7px;\"> What should I do if there's a problem during my stay?</h3> <div> We are available 24/7 by email for emergencies or questions about the apartment. You can also call us from 9:00 AM to 8:00 PM at +33 7 61 05 82 43, and we are available on-site on the ground floor of the building from Tuesday to Saturday, 10:00 AM to 6:45 PM. </div> </div> </div> </div> </section>{% endblock body %}{% block footerjs %} <script src=\"https://cdn.jsdelivr.net/npm/flatpickr\"></script> {# Pricing matrix + simulation URL exposed to JS #} <script> window.PRICING_MATRIX = {{ pricingMatrix|json_encode|raw }}; window.SIMULATION_URL = \"{{ path('simulation_pricing') }}\"; console.log('π Off-peak pricing matrix loaded:', window.PRICING_MATRIX); console.log('π Simulation URL:', window.SIMULATION_URL); </script> <script> // =========================================================== // Bedrooms / adults / children logic // // Physical layout: // - Bedroom A: double bed β 2 people // - Bedroom B: double bed β 2 people // - Bedroom C: bunk beds β 4 people (adults/children mix) // // The number of bedrooms is DETERMINED automatically (no choice): // // WITHOUT CHILDREN: // 1-2 ad β 1 br // 3-4 ad β 2 br // 5-8 ad β 3 br // // WITH CHILDREN: // 1-2 ad β 2 br (bedroom A + bunk room) // 3+ ad β 3 br (A + B + bunk room) // // Constraints: adults + children β€ 8, children β€ 4, adults β₯ 1 // =========================================================== function roomsForCombo(adults, children) { if (children > 0) { return adults <= 2 ? 2 : 3; } if (adults <= 2) return 1; if (adults <= 4) return 2; return 3; } function canAddAdult(state) { if (state.adults >= 8) return false; return (state.adults + 1 + state.children) <= 8; } function canAddChild(state) { if (state.children >= 4) return false; return (state.adults + state.children + 1) <= 8; } const state = { rooms: 1, adults: 2, children: 0 }; function updateDisplay() { // Bedrooms count is recalculated automatically on each update state.rooms = roomsForCombo(state.adults, state.children); \$('#cnt-rooms').text(state.rooms); \$('#cnt-adults').text(state.adults); \$('#cnt-children').text(state.children); \$('#reservation_form_rooms').val(state.rooms); \$('#reservation_form_adults').val(state.adults); \$('#reservation_form_children').val(state.children); \$('#reservation_form_persons').val(state.adults + state.children); \$('.counter-btn').each(function() { const target = \$(this).data('target'); const action = \$(this).data('action'); let disabled = false; if (target === 'rooms') { // Bedrooms = always locked (set by adults/children) disabled = true; } if (target === 'adults') { if (action === 'dec' && state.adults <= 1) disabled = true; if (action === 'inc' && !canAddAdult(state)) disabled = true; } if (target === 'children') { if (action === 'dec' && state.children <= 0) disabled = true; if (action === 'inc' && !canAddChild(state)) disabled = true; } \$(this).prop('disabled', disabled).toggleClass('disabled', disabled); }); \$('#capacity-warning').hide(); } \$(document).on('click', '.counter-btn', function() { if (\$(this).prop('disabled')) return; const target = \$(this).data('target'); const action = \$(this).data('action'); // No action on \"rooms\" (always disabled) if (target === 'adults') { if (action === 'inc' && canAddAdult(state)) state.adults++; if (action === 'dec' && state.adults > 1) state.adults--; } if (target === 'children') { if (action === 'inc' && canAddChild(state)) state.children++; if (action === 'dec' && state.children > 0) state.children--; } updateDisplay(); updateSimulation(); }); function updateSimulation() { const start = \$(\"#reservation_form_start\").val(); const end = \$(\"#reservation_form_end\").val(); const persons = state.adults + state.children; console.log('π updateSimulation', { start, end, rooms: state.rooms, adults: state.adults, children: state.children }); if (!start || !end || persons < 1) { \$(\"#results\").html(''); return; } \$(\"#results\").html('<div class=\"loading\" style=\"color:#212121;\">Calculating...</div>'); \$.post( window.SIMULATION_URL, { start: start, end: end, rooms: state.rooms, adults: state.adults, children: state.children } ) .done(function(data) { console.log('β
Simulation OK'); \$(\"#results\").html(data); }) .fail(function(xhr) { console.error('β Simulation KO', xhr.status, xhr.responseText); \$(\"#results\").html('<div class=\"error\" style=\"color:#a00;\">Error calculating price (' + xhr.status + ')</div>'); }); } \$(document).ready(function() { updateDisplay(); \$('button[type=\"submit\"]').prop('disabled', true); \$('#acceptCGV').change(function() { \$('button[type=\"submit\"]').prop('disabled', !\$(this).is(':checked')); }); }); </script> <script> // =========================================================== // Flatpickr calendar // =========================================================== \$(document).ready(function() { let bookedRanges = []; \$.ajax({ url: '{{ env('WEBHOOK_CALENDAR_AVAILABILITY') }}', method: 'POST', contentType: 'application/json', data: '' }) .done(function(data) { bookedRanges = data.bookings || []; initDatePicker(); }) .fail(function() { initDatePicker(); }); function parseLocalDate(dateStr) { const [year, month, day] = dateStr.split('-').map(Number); return new Date(year, month - 1, day); } const isMobile = window.innerWidth <= 900; function initDatePicker() { flatpickr(\"#date_range_picker\", { inline: true, mode: \"range\", minDate: new Date(new Date().setDate(new Date().getDate() + 1)), dateFormat: \"Y-m-d\", showMonths: isMobile ? 1 : 2, disable: [ function(date) { const checkDate = new Date(date); checkDate.setHours(0, 0, 0, 0); return bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return checkDate >= start && checkDate <= end; }); } ], onChange: function(selectedDates, dateStr, instance) { if (selectedDates.length === 2) { const start = selectedDates[0]; const end = selectedDates[1]; if (isRangeAvailable(start, end)) { \$('#reservation_form_start').val(formatDate(start)).trigger('change'); \$('#reservation_form_end').val(formatDate(end)).trigger('change'); updateSelectedInfo(start, end); updateSimulation(); } else { alert('β οΈ This period contains already booked dates.'); instance.clear(); clearSymfonyFields(); hideSelectedInfo(); \$(\"#results\").html(''); } } else { clearSymfonyFields(); hideSelectedInfo(); \$(\"#results\").html(''); } }, onDayCreate: function(dObj, dStr, fp, dayElem) { const date = new Date(dayElem.dateObj); date.setHours(0, 0, 0, 0); const isBooked = bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return date >= start && date <= end; }); if (isBooked) { dayElem.classList.add('booked'); dayElem.title = 'Unavailable date (booked)'; } else if (date >= new Date()) { dayElem.classList.add('available'); } } }); } function isRangeAvailable(startDate, endDate) { let currentDate = new Date(startDate); currentDate.setHours(0, 0, 0, 0); const endCheck = new Date(endDate); endCheck.setHours(0, 0, 0, 0); while (currentDate <= endCheck) { const isBooked = bookedRanges.some(range => { const start = parseLocalDate(range.start_date); const end = parseLocalDate(range.end_date); return currentDate >= start && currentDate <= end; }); if (isBooked) return false; currentDate.setDate(currentDate.getDate() + 1); } return true; } function updateSelectedInfo(start, end) { const nights = Math.ceil((end - start) / (1000 * 60 * 60 * 24)); \$('#info-start').text(start.toLocaleDateString('en-GB')); \$('#info-end').text(end.toLocaleDateString('en-GB')); \$('#info-nights').text(nights + ' night' + (nights > 1 ? 's' : '')); } function hideSelectedInfo() { \$('#info-start').text('-'); \$('#info-end').text('-'); \$('#info-nights').text('-'); } function clearSymfonyFields() { \$('#reservation_form_start').val(''); \$('#reservation_form_end').val(''); } function formatDate(date) { return date.getFullYear() + '-' + String(date.getMonth() + 1).padStart(2, '0') + '-' + String(date.getDate()).padStart(2, '0'); } }); </script>{% endblock footerjs %}{% block css %} <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css\"> <style> /* =========================================================== Booking card (white border, transparent bg, black text) =========================================================== */ .booking-card { background: transparent; border: 2px solid white; border-radius: 12px; padding: 32px; color: #212121; } .booking-title { color: #212121; font-weight: 700; margin-bottom: 24px; } .booking-divider { border-top: 1px solid rgba(0,0,0,0.15); margin: 28px 0; } .booking-label { color: #212121; font-weight: 500; margin-bottom: 6px; display: block; } .booking-card input.form-control, .booking-card textarea.form-control { background: rgba(255,255,255,0.85) !important; border: 1px solid rgba(0,0,0,0.2) !important; color: #212121 !important; } .booking-card input.form-control::placeholder, .booking-card textarea.form-control::placeholder { color: rgba(0,0,0,0.4) !important; } .booking-card input.form-control:focus, .booking-card textarea.form-control:focus { border-color: #212121 !important; box-shadow: 0 0 0 0.2rem rgba(0,0,0,0.08) !important; } .cgv-block { color: #212121; } .cgv-block a { color: #212121; text-decoration: underline; } .dates-recap { color: #212121; } .recap-label { font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.7; } .recap-value { font-size: 18px; font-weight: 600; margin-top: 4px; } .counter-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid rgba(0,0,0,0.1); } .counter-row:last-of-type { border-bottom: none; } .counter-title { font-size: 16px; font-weight: 500; color: #212121; } .counter-sub { font-size: 12px; color: rgba(0,0,0,0.6); margin-top: 2px; } .counter-controls { display: flex; align-items: center; gap: 12px; } .counter-btn { width: 40px; height: 40px; border-radius: 8px; border: 1.5px solid #212121; background: transparent; color: #212121; font-size: 20px; font-weight: 600; line-height: 1; cursor: pointer; transition: all 0.15s; } .counter-btn:hover:not(.disabled) { background: rgba(0,0,0,0.06); } .counter-btn.disabled, .counter-btn:disabled { border-color: rgba(0,0,0,0.2); color: rgba(0,0,0,0.25); cursor: not-allowed; background: transparent; } .counter-value { min-width: 28px; text-align: center; font-size: 16px; font-weight: 500; color: #212121; } .capacity-warning { margin-top: 12px; padding: 10px 14px; background: rgba(255,180,0,0.18); border: 1px solid rgba(180,120,0,0.5); border-radius: 6px; color: #8a4500; font-size: 14px; } .calendar-container { margin: 0 0 8px 0; width: 100%; display: flex; justify-content: center; } #date_range_picker { display: none; } .flatpickr-calendar.inline { box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 8px; } .flatpickr-day.booked { background-color: #ff4444 !important; color: white !important; cursor: not-allowed !important; position: relative; } .flatpickr-day.booked::after { content: \"β\"; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 20px; font-weight: bold; } .flatpickr-day.booked:hover { background-color: #ff0000 !important; } .flatpickr-day.available:hover { background-color: #28a745; color: white; } @media (max-width: 768px) { .booking-card { padding: 20px; } .calendar-container { margin: 0 0 8px 0; padding: 0; } .flatpickr-calendar.inline { width: 100% !important; max-width: 100% !important; } .flatpickr-months { padding: 8px 10px; } .flatpickr-days { width: 100% !important; } .dayContainer { width: 100% !important; min-width: 100% !important; max-width: 100% !important; } .flatpickr-day { height: 40px !important; line-height: 40px !important; flex-basis: 14.2857% !important; max-width: 14.2857% !important; } } </style>{% endblock css %}", "vitrine/en/homepage.html.twig", "/var/www/vhosts/mirtillostudio.com/ch.mirtillostudio.com/templates/vitrine/en/homepage.html.twig"); }}