Boutique Hotel Website HTML Template — Free Snippet
Boutique Hotel Website template · 13 website sections · Plain HTML, CSS & JS · Customise it in the Website Builder
Copy & paste
Source Code
<section class="st st-navbar-simple" data-uid="smvw6s7vi6ut7">
<header class="st-wrap nb">
<a class="st-brand" href="#">
<span class="st-brand-mark"><span class="st-brand-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" /><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /></svg></span><span>Casa Mar</span></span>
</a>
<nav class="nb-nav" data-menu aria-label="Main">
<ul class="nb-links">
<li data-menu-item><a class="nb-link" href="#work"><span>Rooms</span></a></li>
<li data-menu-item><a class="nb-link" href="#highlights"><span>Experience</span></a></li>
<li data-menu-item><a class="nb-link" href="#customers"><span>Reviews</span></a></li>
<li data-menu-item><a class="nb-link" href="#contact"><span>Location</span></a></li>
</ul>
<div class="nb-actions" data-menu-item>
<a class="st-btn nb-cta" href="#contact"><span>Book a stay</span></a>
</div>
</nav>
<button type="button" class="st-burger" data-menu-toggle aria-expanded="false" aria-label="Open menu"><span></span><span></span><span></span></button>
</header>
<i hidden data-sticky-flag></i>
</section>
<section class="st st-image-background-hero" data-uid="smvw6s7vi29he">
<div class="ib-bg" role="img" aria-label="Background photo" style="background-image:url('https://webdevpuneet.com/images/section-templates/tpl-hotel.jpg')"></div>
<div class="ib-shade" aria-hidden="true"></div>
<div class="ib st-wrap">
<div class="ib-copy">
<span class="st-eyebrow ib-eyebrow" data-anim="item">Boutique hotel · Algarve coast</span>
<h1 class="ib-title" data-anim="item" data-anim-text>Slow mornings, <span class="hl">salt-water days</span></h1>
<p class="st-lead ib-lead" data-anim="item">Twenty-four rooms, a pool among the palms and the beach two minutes away. Breakfast is served until noon.</p>
<div class="st-btns" data-anim="item">
<a class="st-btn" href="#contact"><span>Book a stay</span></a>
<a class="st-btn st-btn--ghost ib-ghost" href="#work"><span>See the rooms</span></a>
</div>
</div>
<div class="ib-stats" data-anim="media">
<div><strong>24</strong><span>rooms and suites</span></div>
<div><strong>2 min</strong><span>to the beach</span></div>
<div><strong>9.4</strong><span>guest rating</span></div>
</div>
</div>
</section>
<section id="work" class="st st-scroll-gallery" data-uid="smvw6s7vi0mh5">
<div class="st-wrap hs-head">
<div class="hs-titles">
<p class="st-eyebrow" data-anim="item">Rooms & suites</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Find <span class="hl">your room</span></h2>
</div>
<p class="st-lead hs-lead" data-anim="item">Every room has linen sheets, a rain shower and a balcony or garden terrace. Keep scrolling to see them all.</p>
</div>
<div class="hs-row" data-hscroll>
<a class="hs-card" href="#contact">
<img class="hs-img" width="900" height="1100" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-1.jpg" alt="Garden room with a double bed">
<span class="hs-tag">From €160 / night</span>
<span class="hs-title">Garden Room</span>
<span class="hs-text">A quiet double opening onto the orange grove.</span>
</a>
<a class="hs-card" href="#contact">
<img class="hs-img" width="900" height="1100" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-2.jpg" alt="Green-toned room with a large window">
<span class="hs-tag">From €190 / night</span>
<span class="hs-title">Palm Room</span>
<span class="hs-text">Big windows over the palms and the pool.</span>
</a>
<a class="hs-card" href="#contact">
<img class="hs-img" width="900" height="1100" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-3.jpg" alt="Dark suite with a sunset window">
<span class="hs-tag">From €260 / night</span>
<span class="hs-title">Sea View Suite</span>
<span class="hs-text">Sunsets over the bay from a private balcony.</span>
</a>
<a class="hs-card" href="#contact">
<img class="hs-img" width="900" height="1100" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-4.jpg" alt="Pink-toned loft room">
<span class="hs-tag">From €240 / night</span>
<span class="hs-title">Rose Loft</span>
<span class="hs-text">A split-level loft with a reading nook.</span>
</a>
</div>
</section>
<section id="highlights" class="st st-scroll-stack" data-uid="smvw6s7vijqty">
<div class="st-art" aria-hidden="true" style="color:var(--st-brand);opacity:0.15" data-art-anim="float"><svg viewBox="0 0 1200 800" preserveAspectRatio="xMidYMid slice"><defs><radialGradient id="art-glow-smvw6s7vijqty"><stop offset="0" stop-color="currentColor"/><stop offset="1" stop-color="currentColor" stop-opacity="0"/></radialGradient></defs><ellipse data-float cx="600" cy="80" rx="620" ry="380" fill="url(#art-glow-smvw6s7vijqty)"/><ellipse data-float cx="1100" cy="760" rx="420" ry="300" fill="url(#art-glow-smvw6s7vijqty)"/></svg></div>
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">The experience</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Everything for <span class="hl">a slow stay</span></h2>
<p class="st-lead" data-anim="item">Scroll on for the little things guests remember.</p>
</header>
<div class="sk-list" data-stack>
<article class="sk-card">
<div class="sk-inner">
<div class="sk-copy">
<span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 2v2" /><path d="M14 2v2" /><path d="M16 8a1 1 0 0 1 1 1v8a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1h14a4 4 0 1 1 0 8h-1" /><path d="M6 2v2" /></svg></span>
<span class="sk-label">Mornings</span>
<h3 class="sk-title">Breakfast until noon</h3>
<p class="sk-text">Fresh bread, fruit from the garden and eggs any way you like, served on the terrace.</p>
</div>
</div>
</article>
<article class="sk-card">
<div class="sk-inner">
<div class="sk-copy">
<span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z" /><path d="M20 3v4" /><path d="M22 5h-4" /><path d="M4 17v2" /><path d="M5 18H3" /></svg></span>
<span class="sk-label">Afternoons</span>
<h3 class="sk-title">Pool, spa and shade</h3>
<p class="sk-text">A heated salt-water pool among the palms, a small spa and plenty of loungers.</p>
</div>
</div>
</article>
<article class="sk-card">
<div class="sk-inner">
<div class="sk-copy">
<span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" /></svg></span>
<span class="sk-label">Days out</span>
<h3 class="sk-title">Coves, vineyards and boats</h3>
<p class="sk-text">We book boat trips, wine tastings and the best hidden beaches for you.</p>
</div>
</div>
</article>
<article class="sk-card">
<div class="sk-inner">
<div class="sk-copy">
<span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" /></svg></span>
<span class="sk-label">Evenings</span>
<h3 class="sk-title">Dinner under the stars</h3>
<p class="sk-text">Grilled fish and local wine in the courtyard, three nights a week.</p>
</div>
</div>
</article>
</div>
</div>
</section>
<section id="gallery" class="st st-gallery-grid" data-uid="smvw6s7vi1fo2">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">Gallery</p>
<h2 class="st-h2" data-anim="item" data-anim-text>A look around <span class="hl">Casa Mar</span></h2>
<p class="st-lead" data-anim="item">Rooms, the pool and the evenings on the terrace. Tap any photo to see it larger.</p>
</header>
<div class="gg-filters" data-gallery-filters role="group" aria-label="Filter photos" hidden data-all="All"></div>
<ul class="gg-grid" data-gallery>
<li class="gg-item" data-anim="item" data-tag="Rooms">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-1.jpg" alt="A bright double room with tall windows">
<p class="gg-cap"><strong class="gg-title">Garden room</strong><span class="gg-text">Morning light and a quiet view</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Outdoors">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-hotel.jpg" alt="The hotel at dusk beside the pool">
<p class="gg-cap"><strong class="gg-title">The pool at dusk</strong><span class="gg-text">Open until ten every evening</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Dining">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-restaurant.jpg" alt="Plates of food on a wooden table">
<p class="gg-cap"><strong class="gg-title">Breakfast on the terrace</strong><span class="gg-text">Served from 8 until 11</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Rooms">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/room-3.jpg" alt="A dark suite with gold details">
<p class="gg-cap"><strong class="gg-title">Night suite</strong><span class="gg-text">Our largest room, with a terrace</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Outdoors">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-nature.jpg" alt="Green hills at sunrise">
<p class="gg-cap"><strong class="gg-title">The coast path</strong><span class="gg-text">Two minutes from the door</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Dining">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/wed-dinner.jpg" alt="A long table set with candles">
<p class="gg-cap"><strong class="gg-title">Dinner by candlelight</strong><span class="gg-text">Long tables on summer evenings</span></p>
</li>
</ul>
</div>
</section>
<section id="customers" class="st st-testimonials-carousel" data-uid="smvw6s7vinrdl">
<div class="st-wrap">
<div class="tc-top">
<header class="st-head st-head--left tc-head">
<p class="st-eyebrow" data-anim="item">Guest reviews</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Guests <span class="hl">come back</span></h2>
<p class="st-lead" data-anim="item">9.4 from 820 verified reviews</p>
</header>
<div class="tc-arrows" data-anim="item">
<button type="button" class="tc-arrow" data-carousel-prev><span class="tc-sr">Previous testimonials</span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg></button>
<button type="button" class="tc-arrow" data-carousel-next><span class="tc-sr">Next testimonials</span><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg></button>
</div>
</div>
<div class="tc-track" data-carousel tabindex="0" role="region" aria-label="Testimonials">
<figure class="tc-card" data-anim="item">
<p class="st-stars" role="img" aria-label="Rated 5 out of 5"><span aria-hidden="true">★★★★★</span></p>
<blockquote class="tc-quote"><p>The calmest week we have had in years. Breakfast on the terrace was the highlight of every day.</p></blockquote>
<figcaption><div class="st-person">
<img class="st-avatar" width="96" height="96" loading="lazy" src="https://webdevpuneet.com/images/section-templates/avatar-3.jpg" alt="">
<div><p class="st-person-name">Hannah & Tom</p><p class="st-person-role">Stayed in the Garden Room</p></div>
</div></figcaption>
</figure>
<figure class="tc-card" data-anim="item">
<p class="st-stars" role="img" aria-label="Rated 5 out of 5"><span aria-hidden="true">★★★★★</span></p>
<blockquote class="tc-quote"><p>Thoughtful, warm staff who booked us the perfect boat trip. The Sea View Suite is worth every euro.</p></blockquote>
<figcaption><div class="st-person">
<img class="st-avatar" width="96" height="96" loading="lazy" src="https://webdevpuneet.com/images/section-templates/avatar-4.jpg" alt="">
<div><p class="st-person-name">Rafael M.</p><p class="st-person-role">Stayed in the Sea View Suite</p></div>
</div></figcaption>
</figure>
<figure class="tc-card" data-anim="item">
<p class="st-stars" role="img" aria-label="Rated 5 out of 5"><span aria-hidden="true">★★★★★</span></p>
<blockquote class="tc-quote"><p>Small enough to feel personal, beautiful enough to never want to leave. Already planning our return.</p></blockquote>
<figcaption><div class="st-person">
<img class="st-avatar" width="96" height="96" loading="lazy" src="https://webdevpuneet.com/images/section-templates/avatar-2.jpg" alt="">
<div><p class="st-person-name">Elena K.</p><p class="st-person-role">Stayed in the Rose Loft</p></div>
</div></figcaption>
</figure>
</div>
</div>
</section>
<section id="faq" class="st st-faq-accordion" data-uid="smvw6s7vivi51">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">FAQ</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Before you <span class="hl">arrive</span></h2>
<p class="st-lead" data-anim="item">Check-in, breakfast, children and getting here from the airport.</p>
</header>
<div class="fq-list" data-accordion="single first">
<details class="st-acc" data-anim="item">
<summary class="st-acc-q"><span>What time is check-in?</span><span class="st-acc-icon" aria-hidden="true"></span></summary>
<div class="st-acc-a"><p>From 3 pm, and check-out is until 11 am. We store luggage before and after your stay.</p></div>
</details>
<details class="st-acc" data-anim="item">
<summary class="st-acc-q"><span>Is breakfast included?</span><span class="st-acc-icon" aria-hidden="true"></span></summary>
<div class="st-acc-a"><p>Yes, breakfast is included in every rate and served until noon.</p></div>
</details>
<details class="st-acc" data-anim="item">
<summary class="st-acc-q"><span>Do you allow children?</span><span class="st-acc-icon" aria-hidden="true"></span></summary>
<div class="st-acc-a"><p>Children over 12 are welcome; the hotel is designed as a quiet retreat.</p></div>
</details>
<details class="st-acc" data-anim="item">
<summary class="st-acc-q"><span>Can you arrange airport transfers?</span><span class="st-acc-icon" aria-hidden="true"></span></summary>
<div class="st-acc-a"><p>Yes. Faro airport is 45 minutes away and we can book a private transfer for you.</p></div>
</details>
</div>
</div>
</section>
<section id="contact" class="st st-booking-form" data-uid="smvw6s7vi5d3n">
<div class="st-wrap bk">
<div class="bk-info">
<header class="st-head st-head--left bk-head">
<p class="st-eyebrow" data-anim="item">Book a stay</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Request <span class="hl">your stay</span></h2>
<p class="st-lead" data-anim="item">Tell us the room, the day you arrive and roughly when. We reply within a few hours with availability and the best rate.</p>
</header>
<div class="bk-block" data-anim="item">
<h3 class="bk-sub">Reception</h3>
<dl class="bk-hours">
<div class="bk-row"><dt>Reception</dt><dd>7:00 am – 11:00 pm</dd></div>
<div class="bk-row"><dt>Check-in</dt><dd>from 3:00 pm</dd></div>
<div class="bk-row"><dt>Check-out</dt><dd>until 11:00 am</dd></div>
</dl>
</div>
<div class="bk-block" data-anim="item">
<h3 class="bk-sub">Good to know</h3>
<ul class="st-checks"><li>Check-in from 3 pm, check-out until 11 am</li><li>Breakfast included in every rate</li><li>Free cancellation up to 7 days before arrival</li></ul>
</div>
</div>
<div class="bk-card" data-anim="media">
<form class="st-form" method="post" data-form action="https://formspree.io/f/your-form-id">
<div class="st-form-fields" data-form-fields>
<div class="st-form-row">
<label class="st-field"><span>Your name</span><input name="name" type="text" required autocomplete="name"></label>
<label class="st-field"><span>Email</span><input name="email" type="email" required autocomplete="email"></label>
</div>
<label class="st-field"><span>Phone</span><input name="phone" type="tel" autocomplete="tel"></label>
<label class="st-field"><span>Room</span><select name="service" required>
<option value="Garden room">Garden room</option>
<option value="Sea room">Sea room</option>
<option value="Night suite">Night suite</option>
<option value="Family suite">Family suite</option>
</select></label>
<div class="st-form-row">
<label class="st-field"><span>Arrival date</span><input name="date" type="date" required data-booking-date></label>
<label class="st-field"><span>Expected arrival</span><select name="time" required>
<option value="Before 2 pm">Before 2 pm</option>
<option value="Afternoon (2 pm – 6 pm)">Afternoon (2 pm – 6 pm)</option>
<option value="Evening (6 pm – 9 pm)">Evening (6 pm – 9 pm)</option>
<option value="Late (after 9 pm)">Late (after 9 pm)</option>
</select></label>
</div>
<label class="st-field"><span>Anything we should know?</span><textarea name="notes" rows="3"></textarea></label>
<input class="st-hp" type="text" name="_gotcha" tabindex="-1" autocomplete="off" aria-hidden="true">
<button class="st-btn st-form-btn" type="submit"><span>Request this stay</span></button>
<p class="st-form-note">This is a request, not a confirmed booking. We reply with availability.</p>
<p class="st-form-error" data-form-error hidden role="alert">Sorry, something went wrong. Please try again or call us directly.</p>
</div>
<div class="st-form-success" data-form-success hidden tabindex="-1" role="status">
<span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg></span>
<h3>Request received</h3>
<p>Thank you. We will email you availability and the rate shortly.</p>
</div>
</form>
</div>
</div>
</section>
<section id="contact-2" class="st st-opening-hours" data-uid="smvw6s7vio6ex">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">Find us</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Two minutes <span class="hl">from the sea</span></h2>
<p class="st-lead" data-anim="item">On a quiet lane above Praia da Luz, 45 minutes from Faro airport.</p>
</header>
<div class="oh" data-opennow data-tz="Europe/Lisbon" data-open-label="Open now" data-closes-label="closes at" data-shut-label="Closed now" data-opens-label="opens">
<div class="oh-card oh-hours" data-anim="item">
<div class="oh-top">
<h3 class="oh-title">Reception hours</h3>
<p class="oh-badge" data-open-badge role="status" hidden><span class="oh-dot" aria-hidden="true"></span><span class="oh-badge-text"></span></p>
</div>
<ol class="oh-list">
<li class="oh-row" data-hours-row data-day="Monday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Monday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Tuesday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Tuesday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Wednesday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Wednesday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Thursday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Thursday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Friday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Friday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Saturday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Saturday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
<li class="oh-row" data-hours-row data-day="Sunday" data-open="07:00" data-close="23:00" data-closed="">
<span class="oh-day">Sunday</span>
<span class="oh-time"><time>07:00</time> <span aria-hidden="true">–</span> <time>23:00</time></span>
</li>
</ol>
<p class="oh-special">Check-in from 15:00, check-out until 11:00. Arriving late? Tell us and we will leave your key.</p>
</div>
<div class="oh-side">
<div class="oh-map" data-anim="media">
<iframe class="oh-frame" loading="lazy" referrerpolicy="no-referrer-when-downgrade" src="https://www.openstreetmap.org/export/embed.html?bbox=-8.738900000000001%2C37.0842%2C-8.7289%2C37.0892&layer=mapnik&marker=37.0867%2C-8.7339" title="Map showing Casa Mar in Luz"></iframe>
</div>
<div class="oh-card oh-contact" data-anim="item">
<ul class="oh-info">
<li class="oh-item"><span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" /></svg></span>
<address class="oh-addr">
<span class="oh-line oh-name">Casa Mar</span>
<span class="oh-line">Rua da Praia 12</span>
<span class="oh-line"><span>8600-160</span> <span>Luz, Algarve</span></span>
<span class="oh-line">Portugal</span>
</address>
</li>
<li class="oh-item"><span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" /></svg></span><a class="oh-link" href="tel:+351282000123">+351 282 000 123</a></li>
<li class="oh-item"><span class="st-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2" /><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" /></svg></span><a class="oh-link" href="mailto:[email protected]">[email protected]</a></li>
</ul>
<div class="st-btns">
<a class="st-btn" href="https://www.google.com/maps/search/?api=1&query=Rua%20da%20Praia%2012%2C%208600-160%20Luz%2C%20Portugal"><span>Get directions</span></a>
<a class="st-btn st-btn--ghost" href="tel:+351282000123"><span>Call reception</span></a>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="st st-popup-modal" data-uid="smvw6s7vi8k4y">
<div class="pu" data-pu data-trigger="delay" data-delay="15" data-scroll="50" data-days="7" data-pos="bottom-center" data-layout="left" data-autoplay="0" data-pu-id="ncmalq">
<div class="pu-backdrop" data-pu-close hidden></div>
<div class="pu-dialog" role="dialog" aria-modal="true" aria-labelledby="pu-heading" tabindex="-1" hidden>
<button type="button" class="pu-x" data-pu-close aria-label="Close popup"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
<div class="pu-media">
<img class="pu-img" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-hotel.jpg" alt="The terrace at Casa Mar">
</div>
<div class="pu-body">
<p class="st-eyebrow">Book direct</p>
<h2 class="pu-h" id="pu-heading">Save <span class="hl">10%</span> when you book direct</h2>
<p class="pu-lead">Best price guaranteed, free breakfast and a late checkout on stays of two nights or more.</p>
<div class="pu-ctas">
<a class="st-btn pu-cta" href="#contact"><span>Check dates</span></a>
</div>
<button type="button" class="pu-no" data-pu-close><span>No thanks</span></button>
</div>
</div>
</div>
</section>
<section class="st st-footer-minimal" data-uid="smvw6s7vid2he">
<footer class="st-wrap fm">
<div class="fm-row" data-anim="item">
<a class="st-brand" href="#">
<span class="st-brand-mark"><span class="st-brand-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" /><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /></svg></span><span>Casa Mar</span></span>
</a>
<nav aria-label="Footer"><ul class="fm-links"><li><a href="#work">Rooms</a></li><li><a href="#highlights">Experience</a></li><li><a href="#customers">Reviews</a></li><li><a href="#contact">Location</a></li></ul></nav>
<div><ul class="st-socials">
<li><a class="st-social" href="https://x.com/" aria-label="X (Twitter)"><span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" /></svg></span></a></li>
<li><a class="st-social" href="https://www.linkedin.com/" aria-label="LinkedIn"><span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z" /><rect width="4" height="12" x="2" y="9" /><circle cx="4" cy="4" r="2" /></svg></span></a></li>
<li><a class="st-social" href="https://github.com/" aria-label="GitHub"><span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" /><path d="M9 18c-4.51 2-5-2-7-2" /></svg></span></a></li>
</ul></div>
</div>
<p class="fm-copy">© 2026 Casa Mar Boutique Hotel</p>
</footer>
</section>
<section class="st st-back-to-top" data-uid="smvw6s7vi14g7">
<div class="btt" data-btt data-enabled="on" data-distance="500" data-pos="right" data-appear="fade" data-speed="0.8" data-mobile="on" data-shadow="on" style="--btt-size:52px;--btt-off:24px;--btt-radius:50%;--btt-speed:0.8s">
<div class="btt-demo" aria-hidden="true">
<span class="btt-bar btt-bar--lg"></span><span class="btt-bar"></span><span class="btt-bar btt-bar--md"></span><span class="btt-bar"></span><span class="btt-bar btt-bar--sm"></span>
<span class="btt-note">The button appears here once the page has scrolled</span>
</div><!--/btt-demo-->
<button type="button" class="btt-btn" aria-label="Back to top" title="Back to top"><svg class="btt-svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2.400" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 19V5M5 12l7-7 7 7"/></svg></button>
</div>
</section>
<section class="st st-accessibility-toolbar" data-uid="smvw6s7vi3ncf">
<div class="a11y" data-a11y data-pos="left" data-remember="on">
<button type="button" class="a11y-fab" aria-expanded="false" data-a11y-open aria-label="Open accessibility tools">
<svg viewBox="0 0 24 24" width="30" height="30" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="7.500" r="1.200" fill="currentColor"/><path d="M7 10.500l5 1 5-1M12 11.500v3.500M9.500 19l2.500-4 2.500 4"/></svg>
</button>
<div class="a11y-panel" role="dialog" tabindex="-1" hidden aria-label="Accessibility">
<div class="a11y-head">
<h2 class="a11y-title">Accessibility</h2>
<button type="button" class="a11y-icon" data-a11y-reset aria-label="Reset all settings" title="Reset all settings"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.700L3 8"/><path d="M3 3v5h5"/></svg></button>
<button type="button" class="a11y-icon" data-a11y-close aria-label="Close accessibility tools" title="Close accessibility tools"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.400" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
</div>
<div class="a11y-body">
<div class="a11y-sec">
<h3 class="a11y-h">Text</h3>
<div class="a11y-grid">
<button type="button" class="a11y-tile" data-feature="text" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 7V5h10v2M9 5v12M6 17h6"/><path d="M15 12h6M18 12v6"/></svg><span class="a11y-lab">Bigger text</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="lineheight" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M8 6h13M8 12h13M8 18h13"/><path d="M3 8l2-2 2 2M3 16l2 2 2-2"/></svg><span class="a11y-lab">Line height</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="align" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 6h16M4 12h10M4 18h14"/></svg><span class="a11y-lab">Text align</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="font" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M4 19 10 5l6 14M6.5 14h7"/><path d="M17 11h4M19 11v8"/></svg><span class="a11y-lab">Readable font</span><span class="a11y-pips" aria-hidden="true"></span></button>
</div>
</div>
<div class="a11y-sec">
<h3 class="a11y-h">Visual</h3>
<div class="a11y-grid">
<button type="button" class="a11y-tile" data-feature="contrast" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M12 3v18" /><path d="M12 3a9 9 0 0 1 0 18z" fill="currentColor"/></svg><span class="a11y-lab">Contrast</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="gray" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 3s6 6.2 6 10.5A6 6 0 0 1 6 13.500C6 9.200 12 3 12 3z"/><path d="M12 3v16.500" /></svg><span class="a11y-lab">Grayscale</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="images" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="9" cy="10" r="1.500"/><path d="m21 16-5-5-9 8M3 3l18 18"/></svg><span class="a11y-lab">Hide images</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="motion" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M10 9v6M14 9v6"/></svg><span class="a11y-lab">Pause animations</span><span class="a11y-pips" aria-hidden="true"></span></button>
</div>
</div>
<div class="a11y-sec">
<h3 class="a11y-h">Orientation</h3>
<div class="a11y-grid">
<button type="button" class="a11y-tile" data-feature="links" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 14a4.500 4.500 0 0 0 6.400 0l3-3a4.500 4.500 0 0 0-6.400-6.400l-1 1"/><path d="M14 10a4.500 4.500 0 0 0-6.400 0l-3 3a4.500 4.500 0 0 0 6.400 6.400l1-1"/></svg><span class="a11y-lab">Highlight links</span><span class="a11y-pips" aria-hidden="true"></span></button>
<button type="button" class="a11y-tile" data-feature="mask" aria-pressed="false"><svg class="a11y-ic" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 9h18M3 15h18"/></svg><span class="a11y-lab">Reading mask</span><span class="a11y-pips" aria-hidden="true"></span></button>
</div>
</div>
<p class="a11y-note">Your choices are saved on this device only.</p>
</div>
</div>
</div>
</section>@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700;800;900&family=DM+Sans:wght@400;500;600;700;800;900&display=swap');
body{margin:0;background:#fbf8f3}
html{scroll-behavior:smooth}section[id]{scroll-margin-top:84px}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
.st{--st-brand:#0f766e;--st-btn-text:#ffffff;--st-bg:#fbf8f3;--st-surface:#f1ebe1;--st-text:#1f2a24;--st-muted:#5c665f;--st-radius:14;--st-max:1200;--st-font-heading:"Playfair Display", serif;--st-font-body:"DM Sans", sans-serif}
.st{--st-pad:clamp(20px,5cqi,56px);container:st/inline-size;position:relative;overflow:hidden;background:var(--st-bg);color:var(--st-text);font-family:var(--st-font-body);font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased}
:where(.st) *,:where(.st) *::before,:where(.st) *::after{box-sizing:border-box;margin:0;padding:0}
:where(.st img){display:block;max-width:100%;height:auto}
:where(.st a){color:inherit}
:where(.st h1,.st h2,.st h3){font-family:var(--st-font-heading);line-height:1.08;letter-spacing:-.025em;font-weight:800;color:var(--st-text)}
.st .hl{color:var(--st-brand)}
.st [data-edit]:empty,.st [data-i-edit]:empty{display:none}
.st-wrap{width:100%;max-width:calc(var(--st-max) * 1px);margin:0 auto;padding-left:var(--st-pad);padding-right:var(--st-pad)}
.st-eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--st-brand)}
.st-pill{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;background:color-mix(in srgb,var(--st-brand) 12%,transparent);color:var(--st-brand);font-size:13.5px;font-weight:700}
.st-btns{display:flex;flex-wrap:wrap;gap:12px}
.st-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:50px;padding:0 26px;border-radius:calc(var(--st-radius) * 1px);border:2px solid var(--st-brand);background:var(--st-brand);color:var(--st-btn-text);font:700 16px/1 var(--st-font-body);text-decoration:none;transition:transform .15s ease,box-shadow .15s ease,background .15s ease}
.st-btn:hover{transform:translateY(-1px);box-shadow:0 8px 24px color-mix(in srgb,var(--st-brand) 35%,transparent)}
.st-btn:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:3px}
.st-btn--ghost{background:transparent;color:var(--st-text);border-color:color-mix(in srgb,var(--st-text) 22%,transparent)}
.st-btn--ghost:hover{box-shadow:none;border-color:var(--st-text)}
.st-lead{font-size:clamp(17px,1.2cqi + 12px,20px);line-height:1.65;color:var(--st-muted)}
.st-head{display:flex;flex-direction:column;align-items:center;gap:14px;max-width:46em;margin:0 auto clamp(36px,5cqi,64px);text-align:center}
.st-head--left{align-items:flex-start;margin-left:0;text-align:left}
.st-h2{font-size:clamp(30px,2.6cqi + 16px,48px)}
.st-icon{display:inline-grid;place-items:center;flex:none;width:48px;height:48px;border-radius:calc(var(--st-radius) * .85px);background:color-mix(in srgb,var(--st-brand) 12%,transparent);color:var(--st-brand)}
.st-icon svg{width:24px;height:24px}
.st-icon:empty{display:none}
.st-checks{list-style:none;display:flex;flex-direction:column;gap:11px}
.st-checks li{position:relative;padding-left:30px;font-size:15.5px;line-height:1.5}
.st-checks li::before{content:"";position:absolute;left:0;top:.12em;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--st-brand) 15%,transparent)}
.st-checks li::after{content:"";position:absolute;left:5px;top:calc(.12em + 5px);width:10px;height:10px;background:var(--st-brand);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat}
@media (prefers-reduced-motion:reduce){.st *{transition:none!important;animation:none!important}}
/* Simple Sticky Navbar */
.st-navbar-simple{overflow:visible;background:color-mix(in srgb,var(--st-bg) 88%,transparent);-webkit-backdrop-filter:saturate(1.6) blur(14px);backdrop-filter:saturate(1.6) blur(14px);border-bottom:1px solid color-mix(in srgb,var(--st-text) 8%,transparent)}
.st-brand{display:inline-flex;align-items:center;gap:10px;flex:none;text-decoration:none;color:var(--st-text)}
.st-brand-img{height:32px;width:auto;max-width:180px;object-fit:contain}
.st-brand-mark{display:inline-flex;align-items:center;gap:10px;font:800 21px/1 var(--st-font-heading);letter-spacing:-.03em}
.st-brand-icon{display:grid;place-items:center;width:34px;height:34px;border-radius:calc(var(--st-radius) * .7px);background:var(--st-brand);color:var(--st-btn-text)}
.st-brand-icon svg{width:19px;height:19px}
.st:has([data-sticky-flag]){position:sticky;top:0;z-index:50;transition:box-shadow .3s ease}
.st.is-scrolled{box-shadow:0 10px 30px -18px rgba(15,23,42,.35)}
.st-burger{display:none;position:relative;flex:none;width:44px;height:44px;border:0;border-radius:calc(var(--st-radius) * .7px);background:color-mix(in srgb,var(--st-text) 7%,transparent);color:var(--st-text);cursor:pointer}
.st-burger span{position:absolute;left:12px;right:12px;height:2px;border-radius:2px;background:currentColor;transition:transform .3s ease,opacity .2s ease}
.st-burger span:nth-child(1){top:15px}.st-burger span:nth-child(2){top:21px}.st-burger span:nth-child(3){top:27px}
.st-burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.st-burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.st-burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
.st-burger:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:2px}
.nb{position:relative;display:flex;align-items:center;gap:clamp(20px,3cqi,40px);min-height:72px}
.nb-nav{flex:1;display:flex;align-items:center;justify-content:space-between;gap:24px}
.nb-links{list-style:none;display:flex;align-items:center;gap:4px;margin:0 auto}
.nb-link{display:block;padding:8px 14px;border-radius:calc(var(--st-radius) * .7px);color:var(--st-muted);font-weight:600;font-size:15.5px;text-decoration:none;transition:color .2s ease,background .2s ease}
.nb-link:hover{color:var(--st-text);background:color-mix(in srgb,var(--st-text) 6%,transparent)}
.nb-link[aria-current="page"]{color:var(--st-brand);background:color-mix(in srgb,var(--st-brand) 11%,transparent)}
.nb-actions{display:flex;align-items:center;gap:18px}
.nb-login{color:var(--st-text);font-weight:600;font-size:15.5px;text-decoration:none}
.nb-login:hover{color:var(--st-brand)}
.nb .nb-cta{min-height:44px;padding:0 20px;font-size:15px}
@container st (max-width:900px){
.nb .st-burger{display:inline-block;margin-left:auto}
.nb-nav{position:absolute;left:var(--st-pad);right:var(--st-pad);top:calc(100% + 8px);flex-direction:column;align-items:stretch;gap:8px;padding:10px;border-radius:calc(var(--st-radius) * 1.2px);background:var(--st-bg);border:1px solid color-mix(in srgb,var(--st-text) 9%,transparent);box-shadow:0 24px 60px -24px rgba(15,23,42,.35)}
.nb-links{flex-direction:column;align-items:stretch;gap:2px;margin:0}
.nb-link{padding:12px 14px;font-size:16.5px;color:var(--st-text)}
.nb-actions{flex-direction:column;align-items:stretch;gap:10px;padding:12px 4px 4px;border-top:1px solid color-mix(in srgb,var(--st-text) 8%,transparent)}
.nb-login{padding:8px 10px}
.nb .nb-cta{width:100%;min-height:48px}
.has-menu:not(.menu-open) .nb-nav{display:none}
.st:not(.has-menu) .nb{flex-wrap:wrap;padding-top:12px;padding-bottom:12px}
.st:not(.has-menu) .nb-nav{position:static;flex-basis:100%;box-shadow:none}
.st:not(.has-menu) .st-burger{display:none}
}
/* Image Background Hero */
.st-image-background-hero{min-height:min(88vh,760px);display:flex;align-items:stretch;background:var(--st-bg)}
.ib-bg{position:absolute;inset:0;background-size:cover;background-position:center}
.ib-shade{position:absolute;inset:0;background:linear-gradient(90deg,color-mix(in srgb,var(--st-bg) 88%,transparent) 0%,color-mix(in srgb,var(--st-bg) 55%,transparent) 55%,color-mix(in srgb,var(--st-bg) 15%,transparent) 100%),linear-gradient(0deg,color-mix(in srgb,var(--st-bg) 70%,transparent),transparent 45%)}
.ib{position:relative;display:flex;flex-direction:column;justify-content:space-between;gap:48px;padding-top:clamp(72px,10cqi,140px);padding-bottom:clamp(32px,4cqi,48px)}
.ib-copy{display:flex;flex-direction:column;align-items:flex-start;gap:22px;max-width:640px}
.ib-eyebrow{color:var(--st-brand)}
.ib-title{font-size:clamp(42px,5.6cqi + 10px,80px);line-height:1.02}
.ib-lead{color:var(--st-muted);max-width:32em}
.ib-ghost{color:var(--st-text);border-color:color-mix(in srgb,var(--st-text) 55%,transparent);backdrop-filter:blur(6px)}
.ib-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;padding-top:24px;border-top:1px solid color-mix(in srgb,var(--st-text) 22%,transparent)}
.ib-stats div{display:flex;flex-direction:column;gap:2px}
.ib-stats strong{font-family:var(--st-font-heading);font-size:clamp(26px,2.6cqi + 8px,38px);line-height:1.1;color:var(--st-text)}
.ib-stats span{font-size:14px;color:var(--st-muted)}
@container st (max-width:640px){.ib-stats{grid-template-columns:1fr}.ib-shade{background:color-mix(in srgb,var(--st-bg) 72%,transparent)}}
/* Horizontal Scroll Gallery */
.st-scroll-gallery{padding:clamp(64px,8cqi,112px) 0}
.hs-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px 48px;margin-bottom:clamp(28px,4cqi,48px)}
.hs-titles{display:flex;flex-direction:column;gap:12px;max-width:40em}
.hs-lead{max-width:28em}
.hs-row{display:flex;gap:clamp(16px,2cqi,28px);overflow-x:auto;scroll-snap-type:x mandatory;--hs-in:max(var(--st-pad),calc((100% - var(--st-max) * 1px) / 2 + var(--st-pad)));padding:4px var(--hs-in) 18px;scroll-padding-inline:var(--hs-in);scrollbar-width:thin}
.st-scroll-gallery.is-hscroll .hs-row{overflow:visible;scroll-snap-type:none}
.hs-card{flex:none;width:clamp(240px,28cqi,380px);scroll-snap-align:start;display:flex;flex-direction:column;gap:6px;color:inherit;text-decoration:none}
.hs-img{width:100%;aspect-ratio:4/5;object-fit:cover;margin-bottom:10px;border-radius:calc(var(--st-radius) * 1px);background:var(--st-surface);transition:transform .5s cubic-bezier(.2,.7,.2,1)}
.hs-card:hover .hs-img{transform:translateY(-6px)}
.hs-card:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 50%,transparent);outline-offset:6px;border-radius:calc(var(--st-radius) * 1px)}
.hs-tag{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--st-brand)}
.hs-title{font:700 clamp(19px,.8cqi + 14px,22px)/1.25 var(--st-font-heading)}
.hs-text{color:var(--st-muted);font-size:15px;line-height:1.5}
@container st (max-width:720px){.hs-head{flex-direction:column;align-items:flex-start}}
/* Stacking Cards */
.st-scroll-stack{padding:clamp(64px,8cqi,112px) 0}
.sk-list{display:flex;flex-direction:column;gap:clamp(20px,3cqi,32px);max-width:1040px;margin:0 auto}
.sk-inner{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(20px,3cqi,44px);align-items:center;min-height:min(62vh,500px);padding:clamp(24px,3.5cqi,52px);border-radius:calc(var(--st-radius) * 1.3px);background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 9%,transparent);box-shadow:0 40px 70px -48px rgba(0,0,0,.45);transform-origin:50% 0}
.sk-card:nth-child(3n+2) .sk-inner{background:color-mix(in srgb,var(--st-brand) 9%,var(--st-surface))}
.sk-card:nth-child(3n) .sk-inner{background:color-mix(in srgb,var(--st-text) 92%,var(--st-brand));color:var(--st-bg)}
.sk-card:nth-child(3n) .sk-title{color:var(--st-bg)}
.sk-card:nth-child(3n) .sk-text{color:color-mix(in srgb,var(--st-bg) 72%,transparent)}
.sk-copy{display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.sk-label{font-size:13px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--st-brand)}
.sk-title{font-size:clamp(24px,1.6cqi + 14px,36px);line-height:1.1}
.sk-text{color:var(--st-muted);font-size:17px;max-width:30em}
.sk-img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:calc(var(--st-radius) * .8px);background:color-mix(in srgb,var(--st-text) 6%,transparent)}
.sk-inner:not(:has(.sk-img)){grid-template-columns:1fr;min-height:0}
@container st (max-width:760px){.sk-inner{grid-template-columns:1fr;min-height:0}}
/* Filterable Image Gallery */
.st-gallery-grid{padding:clamp(56px,7cqi,104px) 0}
.gg-filters{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-bottom:clamp(24px,3cqi,36px)}
.gg-filters:empty{display:none}
.gg-chip{min-height:40px;padding:0 18px;border:1px solid color-mix(in srgb,var(--st-text) 14%,transparent);border-radius:999px;background:transparent;color:var(--st-text);font:600 14.5px/1 var(--st-font-body);cursor:pointer;transition:background .2s ease,color .2s ease,border-color .2s ease}
.gg-chip:hover{border-color:var(--st-brand);color:var(--st-brand)}
.gg-chip[aria-pressed="true"]{background:var(--st-brand);border-color:var(--st-brand);color:var(--st-btn-text)}
.gg-chip:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:2px}
.gg-grid{list-style:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,260px),1fr));gap:clamp(12px,1.6cqi,20px)}
.gg-item{position:relative;overflow:hidden;border-radius:calc(var(--st-radius) * 1px);background:var(--st-surface);aspect-ratio:4/3}
.gg-item[hidden]{display:none}
.gg-item[role="button"]{cursor:zoom-in}
.gg-item:focus-visible{outline:3px solid var(--st-brand);outline-offset:3px}
.gg-img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.2,.8,.2,1)}
.gg-item:hover .gg-img{transform:scale(1.07)}
.gg-cap{position:absolute;inset:auto 0 0;display:flex;flex-direction:column;gap:2px;padding:44px 16px 14px;color:#fff;background:linear-gradient(to top,rgba(10,12,20,.78),transparent);opacity:0;transform:translateY(8px);transition:opacity .3s ease,transform .3s ease}
.gg-item:hover .gg-cap,.gg-item:focus-visible .gg-cap{opacity:1;transform:none}
.gg-title{font-size:16px;line-height:1.3}
.gg-text{font-size:13.5px;opacity:.85}
@media (hover:none){.gg-cap{opacity:1;transform:none}}
.stg-lb{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;padding:clamp(16px,4vw,48px);background:rgba(8,10,16,.92);animation:stg-fade .2s ease}
.stg-lb[hidden]{display:none}
.stg-lb-fig{display:flex;flex-direction:column;align-items:center;gap:14px;max-width:min(1100px,100%);max-height:100%;margin:0}
.stg-lb-img{display:block;max-width:100%;max-height:calc(var(--lb-h,100vh) - 150px);border-radius:10px;object-fit:contain;background:#111}
.stg-lb-cap{color:#e5e7eb;font:500 15px/1.5 system-ui,sans-serif;text-align:center}
.stg-lb-cap:empty{display:none}
.stg-lb-close,.stg-lb-nav{position:absolute;display:grid;place-items:center;width:48px;height:48px;border:0;border-radius:50%;background:rgba(255,255,255,.12);color:#fff;font:400 30px/1 system-ui,sans-serif;cursor:pointer;transition:background .2s ease}
.stg-lb-close svg,.stg-lb-nav svg{display:block;width:22px;height:22px;pointer-events:none}
.stg-lb-close:hover,.stg-lb-nav:hover{background:rgba(255,255,255,.24)}
.stg-lb-close:focus-visible,.stg-lb-nav:focus-visible{outline:3px solid #fff;outline-offset:2px}
.stg-lb-close{top:16px;right:16px}
.stg-lb-prev{left:16px;top:50%;margin-top:-24px}
.stg-lb-next{right:16px;top:50%;margin-top:-24px}
.stg-lb.is-single .stg-lb-nav{display:none}
.stg-lb-count{position:absolute;bottom:14px;left:0;right:0;margin:0;color:#9ca3af;font:500 13px/1 system-ui,sans-serif;text-align:center}
html.stg-open{overflow:hidden}
@keyframes stg-fade{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.stg-lb{animation:none}.gg-img,.gg-cap{transition:none}}
@container st (max-width:520px){.gg-grid{grid-template-columns:1fr 1fr}.gg-cap{display:none}}
/* Testimonial Carousel */
.st-testimonials-carousel{padding:clamp(64px,8cqi,112px) 0}
.st-stars{color:#f59e0b;font-size:16px;letter-spacing:2px;line-height:1}
.st-person{display:flex;align-items:center;gap:12px}
.st-avatar{width:44px;height:44px;flex:none;border-radius:50%;object-fit:cover;background:var(--st-surface)}
.st-person-name{font-weight:700;font-size:15.5px;line-height:1.3}
.st-person-role{color:var(--st-muted);font-size:14px;line-height:1.4}
.st-person-role:empty{display:none}
.tc-top{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;margin-bottom:clamp(28px,3.4cqi,44px)}
.tc-head{margin:0}
.tc-arrows{display:flex;gap:10px;flex:none}
.tc-arrow{position:relative;display:grid;place-items:center;width:48px;height:48px;border-radius:50%;border:1px solid color-mix(in srgb,var(--st-text) 16%,transparent);background:var(--st-bg);color:var(--st-text);cursor:pointer;transition:background .2s ease,color .2s ease,opacity .2s ease}
.tc-arrow:hover:not(:disabled){background:var(--st-brand);border-color:var(--st-brand);color:var(--st-btn-text)}
.tc-arrow:disabled{opacity:.35;cursor:default}
.tc-arrow:focus-visible,.tc-track:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:3px}
.tc-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tc-track{display:flex;gap:clamp(14px,1.8cqi,22px);overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;padding:4px 2px 16px;margin:0 -2px;overscroll-behavior-x:contain}
.tc-track::-webkit-scrollbar{display:none}
.tc-track.is-draggable{scroll-snap-type:none;cursor:grab}
.tc-track.is-draggable:active{cursor:grabbing}
.tc-card{flex:0 0 clamp(280px,32%,400px);scroll-snap-align:start;display:flex;flex-direction:column;gap:16px;margin:0;padding:clamp(24px,2.6cqi,32px);border-radius:calc(var(--st-radius) * 1px);background:var(--st-surface);user-select:none}
.tc-quote{flex:1;font-size:17px;line-height:1.65}
@container st (max-width:700px){.tc-top{flex-direction:column;align-items:flex-start}.tc-card{flex-basis:85%}}
/* FAQ Accordion */
.st-faq-accordion{padding:clamp(64px,8cqi,112px) 0}
.st-acc{border-bottom:1px solid color-mix(in srgb,var(--st-text) 11%,transparent)}
.st-acc-q{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:22px 2px;cursor:pointer;list-style:none;font:700 clamp(17px,.6cqi + 14px,19px)/1.4 var(--st-font-heading);letter-spacing:-.01em}
.st-acc-q::-webkit-details-marker{display:none}
.st-acc-q:hover{color:var(--st-brand)}
.st-acc-q:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:2px;border-radius:6px}
.st-acc-icon{position:relative;flex:none;width:28px;height:28px;border-radius:50%;background:color-mix(in srgb,var(--st-brand) 11%,transparent);transition:transform .3s ease,background .3s ease}
.st-acc-icon::before,.st-acc-icon::after{content:"";position:absolute;left:50%;top:50%;width:12px;height:2px;border-radius:2px;background:var(--st-brand);transform:translate(-50%,-50%)}
.st-acc-icon::after{transform:translate(-50%,-50%) rotate(90deg);transition:transform .3s ease}
.st-acc[open]:not(.is-closing) .st-acc-icon{transform:rotate(180deg);background:var(--st-brand)}
.st-acc[open]:not(.is-closing) .st-acc-icon::before,.st-acc[open]:not(.is-closing) .st-acc-icon::after{background:var(--st-btn-text)}
.st-acc[open]:not(.is-closing) .st-acc-icon::after{transform:translate(-50%,-50%) rotate(0deg)}
.st-acc-a{overflow:hidden}
.st-acc-a p{padding:0 48px 24px 2px;color:var(--st-muted);font-size:16.5px;line-height:1.7}
.fq-list{max-width:820px;margin:0 auto;border-top:1px solid color-mix(in srgb,var(--st-text) 11%,transparent)}
.fq-contact{max-width:820px;margin:clamp(32px,4cqi,48px) auto 0;padding:20px 24px;border-radius:calc(var(--st-radius) * 1px);background:var(--st-surface);text-align:center;color:var(--st-muted)}
.fq-contact a{color:var(--st-brand);font-weight:700;text-decoration:none}
.fq-contact a:hover{text-decoration:underline}
/* Booking Request Form */
.st-booking-form{padding:clamp(64px,8cqi,112px) 0}
.st-form{display:block}
.st-form-fields{display:flex;flex-direction:column;gap:16px}
.st-form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.st-field{display:flex;flex-direction:column;gap:7px;font-size:14.5px;font-weight:600;color:var(--st-text)}
.st-field input,.st-field textarea{width:100%;padding:13px 15px;border-radius:calc(var(--st-radius) * .8px);border:1px solid color-mix(in srgb,var(--st-text) 16%,transparent);background:var(--st-bg);color:var(--st-text);font:400 16px/1.5 var(--st-font-body);outline:none;transition:border-color .2s ease,box-shadow .2s ease;resize:vertical}
.st-field input:focus,.st-field textarea:focus{border-color:var(--st-brand);box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 18%,transparent)}
.st-hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.st-form-btn{align-self:flex-start;min-width:180px}
.st-form-btn[aria-busy="true"]{opacity:.7;cursor:progress}
.st-form-note{font-size:13.5px;color:var(--st-muted)}
.st-form-error{padding:12px 14px;border-radius:calc(var(--st-radius) * .8px);background:#fef2f2;color:#b91c1c;font-size:14.5px}
.st-form-success{display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:8px 0;outline:none}
.st-form-success[hidden],.st-form-error[hidden]{display:none}
.st-form-success h3{font-size:22px}
.st-form-success p{color:var(--st-muted)}
@container st (max-width:560px){.st-form-row{grid-template-columns:1fr}.st-form-btn{width:100%}}
.st-field select{width:100%;padding:13px 44px 13px 15px;-webkit-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 16px center;background-size:16px;cursor:pointer;border-radius:calc(var(--st-radius) * .8px);border:1px solid color-mix(in srgb,var(--st-text) 16%,transparent);background-color:var(--st-bg);color:var(--st-text);font:400 16px/1.5 var(--st-font-body);outline:none;transition:border-color .2s ease,box-shadow .2s ease}
.st-field select:focus,.st-field input[type="date"]:focus{border-color:var(--st-brand);box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 18%,transparent)}
.st-field input[type="date"]{min-height:51px}
.bk{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);align-items:start;gap:clamp(36px,5cqi,80px)}
.bk-info{display:flex;flex-direction:column;gap:30px}
.bk-head{margin:0}
.bk-sub{margin-bottom:12px;font-size:17px;letter-spacing:-.01em}
.bk-hours{display:flex;flex-direction:column;border-top:1px solid color-mix(in srgb,var(--st-text) 10%,transparent)}
.bk-row{display:flex;justify-content:space-between;gap:16px;padding:11px 0;border-bottom:1px solid color-mix(in srgb,var(--st-text) 10%,transparent);font-size:15.5px}
.bk-row dt{font-weight:600}
.bk-row dd{color:var(--st-muted);font-variant-numeric:tabular-nums}
.bk-card{padding:clamp(24px,3.4cqi,40px);border-radius:calc(var(--st-radius) * 1.3px);background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 7%,transparent);box-shadow:0 30px 70px -40px color-mix(in srgb,var(--st-text) 45%,transparent)}
@container st (max-width:860px){.bk{grid-template-columns:1fr}}
/* Opening Hours & Location */
.st-opening-hours{padding:clamp(64px,8cqi,112px) 0}
.oh{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:clamp(18px,2.6cqi,32px);align-items:stretch}
.oh-card{padding:clamp(22px,2.8cqi,34px);border-radius:calc(var(--st-radius) * 1.1px);background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 9%,transparent);box-shadow:0 24px 60px -44px color-mix(in srgb,var(--st-text) 55%,transparent)}
.oh-top{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px;margin-bottom:6px}
.oh-title{font-size:clamp(21px,2.3cqi,26px)}
.oh-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 13px;border-radius:999px;background:color-mix(in srgb,var(--st-text) 7%,transparent);color:var(--st-text);font-size:13.5px;font-weight:700}
.oh-badge[hidden]{display:none}
.oh-dot{width:9px;height:9px;border-radius:50%;background:#94a3b8}
.oh-badge.is-open{background:rgba(34,197,94,.15);color:color-mix(in srgb,#16a34a 78%,var(--st-text))}
.oh-badge.is-open .oh-dot{background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.25)}
.oh-badge.is-shut{background:rgba(239,68,68,.12);color:color-mix(in srgb,#dc2626 78%,var(--st-text))}
.oh-badge.is-shut .oh-dot{background:#ef4444}
.oh-list{list-style:none;margin:0;padding:0}
.oh-row{display:grid;grid-template-columns:minmax(96px,auto) 1fr;gap:3px 16px;align-items:baseline;padding:13px 12px;margin:0 -12px;border-bottom:1px dashed color-mix(in srgb,var(--st-text) 14%,transparent);font-size:16px}
.oh-row:last-child{border-bottom:0}
.oh-day{font-weight:700}
.oh-time,.oh-shut{justify-self:end;font-variant-numeric:tabular-nums}
.oh-shut{color:var(--st-muted)}
.oh-note{grid-column:1 / -1;justify-self:end;color:var(--st-muted);font-size:13.5px}
.oh-row.is-today{background:color-mix(in srgb,var(--st-brand) 10%,transparent);border-radius:10px;border-bottom-color:transparent}
.oh-row.is-today .oh-day{color:var(--st-brand)}
.oh-row.is-today .oh-day::before{content:"";display:inline-block;width:8px;height:8px;margin-right:9px;border-radius:50%;background:var(--st-brand)}
.oh-special{margin-top:14px;padding-top:14px;border-top:1px solid color-mix(in srgb,var(--st-text) 9%,transparent);color:var(--st-muted);font-size:14.5px}
.oh-side{display:flex;flex-direction:column;gap:clamp(14px,2cqi,20px);min-width:0}
.oh-map{flex:1;min-height:280px;overflow:hidden;border-radius:calc(var(--st-radius) * 1.1px);background:var(--st-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 420' preserveAspectRatio='xMidYMid slice'%3E%3Crect width='600' height='420' fill='%23e9eef0'/%3E%3Cpath d='M0 90H600M0 250H600M0 350H600M110 0V420M300 0V420M470 0V420' stroke='%23ffffff' stroke-width='16'/%3E%3Cpath d='M0 190L600 150M200 0L330 420' stroke='%23ffffff' stroke-width='10'/%3E%3Crect x='330' y='110' width='110' height='80' rx='8' fill='%23d9e6dc'/%3E%3Cpath d='M300 150c-28 0-50 22-50 50 0 36 50 82 50 82s50-46 50-82c0-28-22-50-50-50z' fill='%23ef4444'/%3E%3Ccircle cx='300' cy='200' r='17' fill='%23ffffff'/%3E%3C/svg%3E") center/cover no-repeat;border:1px solid color-mix(in srgb,var(--st-text) 9%,transparent)}
.oh-frame{display:block;width:100%;height:100%;min-height:280px;border:0}
.oh-info{list-style:none;margin:0 0 18px;padding:0;display:grid;gap:14px}
.oh-item{display:flex;align-items:flex-start;gap:14px}
.oh-item .st-icon{width:42px;height:42px;background:color-mix(in srgb,var(--st-brand) 14%,transparent)}
.oh-item .st-icon svg{width:20px;height:20px}
.oh-addr{display:flex;flex-direction:column;font-style:normal;font-size:16px;line-height:1.5;padding-top:2px}
.oh-name{font-weight:700}
.oh-link{align-self:center;color:var(--st-text);font-size:16.5px;font-weight:600;text-decoration:none;word-break:break-word}
.oh-link:hover{color:var(--st-brand);text-decoration:underline}
.oh-contact .st-btns{display:flex;flex-wrap:wrap;gap:12px}
@container st (max-width:860px){.oh{grid-template-columns:1fr}.oh-map,.oh-frame{min-height:260px}}
@media (prefers-reduced-motion:reduce){.oh-dot{box-shadow:none!important}}
/* Popup & Promo Modal */
.st-popup-modal{overflow:visible;container-type:normal;height:0;min-height:0;background:transparent}
.st-popup-modal:has(.pu.is-preview){height:auto;padding:clamp(24px,4vw,48px) var(--st-pad);background:color-mix(in srgb,var(--st-text) 8%,var(--st-bg))}
.pu-backdrop{position:fixed;inset:0;z-index:1000;background:rgba(15,23,42,.58);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity .3s ease}
.pu-backdrop[hidden],.pu-dialog[hidden]{display:none}
.pu-dialog{position:fixed;z-index:1001;display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);--pu-wd:780px;width:min(var(--pu-w,var(--pu-wd)),calc(100vw - 32px));height:var(--pu-h,auto);max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);overflow:auto;border-radius:calc(var(--st-radius) * 1.2px);background:var(--st-bg);color:var(--st-text);box-shadow:0 40px 90px -20px rgba(15,23,42,.55);font-family:var(--st-font-body);opacity:0;transition:opacity .3s ease,transform .35s cubic-bezier(.2,.8,.2,1)}
.pu[data-pos=center] .pu-dialog{top:50%;left:50%;transform:translate(-50%,-46%) scale(.97)}
.pu:not([data-pos=center]) .pu-dialog{--pu-wd:400px;grid-template-columns:1fr;box-shadow:0 24px 60px -16px rgba(15,23,42,.5),0 0 0 1px color-mix(in srgb,var(--st-text) 8%,transparent)}
.pu:not([data-pos=center]) .pu-backdrop{display:none}
.pu[data-pos^=bottom] .pu-dialog{bottom:20px;transform:translateY(24px)}
.pu[data-pos^=top] .pu-dialog{top:20px;transform:translateY(-24px)}
.pu[data-pos$=right] .pu-dialog{right:20px}
.pu[data-pos$=left] .pu-dialog{left:20px}
.pu[data-pos=bottom-center] .pu-dialog{left:50%;--pu-wd:460px;transform:translate(-50%,24px)}
.pu.is-open .pu-backdrop{opacity:1}
.pu.is-open .pu-dialog{opacity:1}
.pu[data-pos=center].is-open .pu-dialog{transform:translate(-50%,-50%)}
.pu[data-pos=bottom-center].is-open .pu-dialog{transform:translateX(-50%)}
.pu:not([data-pos=center]):not([data-pos=bottom-center]).is-open .pu-dialog{transform:none}
.pu-media{position:relative;min-height:220px;background:var(--st-surface)}
.pu-media:not(:has(.pu-img,.pu-car,.pu-video)){display:none}
.pu-dialog:not(:has(.pu-img,.pu-car,.pu-video)){grid-template-columns:1fr}
.pu-body:not(:has(.st-eyebrow:not(:empty),.pu-h:not(:empty),.pu-lead:not(:empty),.pu-form,.pu-ctas,.pu-html-wrap,.pu-no span:not(:empty))){display:none}
.pu-dialog:not(:has(.st-eyebrow:not(:empty),.pu-h:not(:empty),.pu-lead:not(:empty),.pu-form,.pu-ctas,.pu-html-wrap,.pu-no span:not(:empty))){grid-template-columns:1fr}
.pu-dialog:not(:has(.st-eyebrow:not(:empty),.pu-h:not(:empty),.pu-lead:not(:empty),.pu-form,.pu-ctas,.pu-html-wrap,.pu-no span:not(:empty))) .pu-media{min-height:clamp(240px,40vw,380px)}
.pu[data-pos=center][data-layout=right] .pu-dialog{grid-template-columns:minmax(0,6fr) minmax(0,5fr)}
.pu[data-pos=center][data-layout=right] .pu-media{order:2}
.pu[data-pos=center][data-layout=top] .pu-dialog{grid-template-columns:1fr;--pu-wd:520px}
.pu[data-pos=center][data-layout=top] .pu-media{min-height:0;aspect-ratio:16/9}
.pu[data-pos=center][data-layout=bottom] .pu-dialog{grid-template-columns:1fr;--pu-wd:520px}
.pu[data-pos=center][data-layout=bottom] .pu-media{min-height:0;aspect-ratio:16/9}
.pu[data-layout=bottom] .pu-media{order:2}
.pu:not([data-pos=center]) .pu-media{min-height:150px;aspect-ratio:16/9}
.pu-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pu-car{position:absolute;inset:0}
.pu-video{position:absolute;inset:0;z-index:1;background:#0b1020;overflow:hidden}
.pu-video .vs-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pu-video .vs-play{position:absolute;inset:0;display:grid;place-items:center;background:linear-gradient(to top,rgba(8,10,20,.55),rgba(8,10,20,.08) 65%);color:#fff;text-decoration:none}
.pu-video .vs-btn{display:grid;place-items:center;width:64px;height:64px;border-radius:50%;background:var(--st-brand);color:var(--st-btn-text);box-shadow:0 8px 24px rgba(0,0,0,.35);transition:transform .2s ease}
.pu-video .vs-btn svg{margin-left:3px}
.pu-video .vs-play:hover .vs-btn{transform:scale(1.08)}
.pu-video .vs-play:focus-visible{outline:4px solid var(--st-brand);outline-offset:-4px}
.pu-video .vs-embed{position:absolute;inset:0;width:100%;height:100%;border:0;background:#000}
.pu-video.is-playing .vs-poster,.pu-video.is-playing .vs-play{display:none}
.pu-html-wrap{width:100%;min-width:0}
.pu-html{min-width:0;color:var(--st-text);font-size:15px;line-height:1.6}
.pu-html iframe,.pu-html img,.pu-html video{max-width:100%}
.pu-track{display:flex;height:100%;margin:0;padding:0;list-style:none;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.pu-track::-webkit-scrollbar{display:none}
.pu-slide{position:relative;flex:0 0 100%;height:100%;scroll-snap-align:center}
.pu-slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pu-slide-link{position:absolute;inset:0}
.pu-cap{position:absolute;left:0;right:0;bottom:0;padding:34px 16px 38px;background:linear-gradient(to top,rgba(8,10,20,.72),transparent);color:#fff;font-weight:700;font-size:15px;line-height:1.3;pointer-events:none}
.pu-cap:empty{display:none}
.pu-nav{position:absolute;top:50%;z-index:2;display:grid;place-items:center;width:34px;height:34px;margin-top:-17px;border:0;border-radius:50%;background:rgba(255,255,255,.9);color:#0f172a;cursor:pointer;box-shadow:0 2px 8px rgba(15,23,42,.3)}
.pu-nav:hover{background:#fff}
.pu-prev{left:10px}
.pu-next{right:10px}
.pu-dots{position:absolute;left:0;right:0;bottom:12px;z-index:2;display:flex;justify-content:center;gap:7px}
.pu-dot{width:9px;height:9px;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.55);cursor:pointer;transition:background .2s ease,transform .2s ease}
.pu-dot[aria-current=true]{background:#fff;transform:scale(1.25)}
.pu-car.is-single .pu-nav,.pu-car.is-single .pu-dots{display:none}
.pu-body{display:flex;flex-direction:column;align-items:flex-start;gap:12px;justify-content:safe center;padding:clamp(24px,4vw,40px)}
.pu:not([data-pos=center]) .pu-body{padding:20px 22px 22px;gap:10px}
.pu-h{font-size:clamp(24px,2vw + 14px,34px)}
.pu:not([data-pos=center]) .pu-h{font-size:clamp(20px,1vw + 14px,26px)}
.pu-lead{color:var(--st-muted);font-size:16px}
.pu:not([data-pos=center]) .pu-lead{font-size:14.5px}
.pu-form{width:100%}
.pu-row{display:flex;flex-direction:column;gap:10px}
.pu-input{width:100%;min-height:50px;padding:0 16px;border:1.5px solid color-mix(in srgb,var(--st-text) 18%,transparent);border-radius:calc(var(--st-radius) * .7px);background:var(--st-bg);color:var(--st-text);font:500 16px/1 var(--st-font-body);outline:none}
.pu-input:focus{border-color:var(--st-brand);box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 18%,transparent)}
.pu-btn{width:100%}
.pu-ctas{display:flex;flex-wrap:wrap;gap:10px;width:100%}
.pu-ctas .pu-cta{flex:1 1 auto}
.pu-note{margin-top:8px;font-size:13px;color:var(--st-muted)}
.pu-note:empty,.pu-ok:empty,.pu-err:empty{display:none}
.pu-ok{padding:12px 14px;border-radius:calc(var(--st-radius) * .6px);background:color-mix(in srgb,#16a34a 14%,transparent);color:var(--st-text);font-weight:600}
.pu-err{margin-top:8px;color:#b91c1c;font-size:14px;font-weight:600}
.pu-no{align-self:center;padding:6px 10px;border:0;background:none;color:var(--st-muted);font:600 14px/1 var(--st-font-body);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.pu-no:hover{color:var(--st-text)}
.pu-no:has(span:empty){display:none}
.pu-x{position:absolute;top:12px;right:12px;z-index:3;display:grid;place-items:center;width:36px;height:36px;border:0;border-radius:50%;background:color-mix(in srgb,var(--st-bg) 88%,transparent);color:var(--st-text);cursor:pointer;box-shadow:0 2px 8px rgba(15,23,42,.18);transition:background .2s ease,transform .2s ease}
.pu-x:hover{background:var(--st-bg);transform:scale(1.06)}
.pu-x:focus-visible,.pu-no:focus-visible,.pu-input:focus-visible,.pu-nav:focus-visible,.pu-dot:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 55%,transparent);outline-offset:2px}
.pu.is-preview .pu-backdrop{display:none}
.pu.is-preview .pu-dialog{position:relative;inset:auto;transform:none;margin:0 auto;opacity:1;max-height:none}
@media (max-width:640px){
.pu[data-pos=center] .pu-dialog,.pu[data-pos=center][data-layout=right] .pu-dialog{grid-template-columns:1fr}
.pu[data-pos=center][data-layout=right] .pu-media{order:0}
.pu-media{min-height:150px;max-height:220px}
.pu:not([data-pos=center]) .pu-dialog{left:12px;right:12px;width:auto}
.pu[data-pos=bottom-center] .pu-dialog,.pu[data-pos=bottom-center].is-open .pu-dialog{left:12px;transform:none}
.pu[data-pos^=bottom] .pu-dialog{bottom:12px}
.pu[data-pos^=top] .pu-dialog{top:12px}
.pu-body{padding:22px}
}
@media print{.pu{display:none}}
/* Minimal Footer */
.st-footer-minimal{padding:36px 0 28px;border-top:1px solid color-mix(in srgb,var(--st-text) 8%,transparent)}
.st-brand{display:inline-flex;align-items:center;gap:10px;flex:none;text-decoration:none;color:var(--st-text)}
.st-brand-img{height:32px;width:auto;max-width:180px;object-fit:contain}
.st-brand-mark{display:inline-flex;align-items:center;gap:10px;font:800 21px/1 var(--st-font-heading);letter-spacing:-.03em}
.st-brand-icon{display:grid;place-items:center;width:34px;height:34px;border-radius:calc(var(--st-radius) * .7px);background:var(--st-brand);color:var(--st-btn-text)}
.st-brand-icon svg{width:19px;height:19px}
.st-socials{list-style:none;display:flex;flex-wrap:wrap;gap:8px}
.st-social{display:grid;place-items:center;width:40px;height:40px;border-radius:calc(var(--st-radius) * .7px);color:var(--st-muted);background:color-mix(in srgb,var(--st-text) 6%,transparent);transition:color .2s ease,background .2s ease,transform .2s ease}
.st-social:hover{color:var(--st-btn-text);background:var(--st-brand);transform:translateY(-2px)}
.st-social > span{display:block;line-height:0}
.st-social svg{display:block;width:19px;height:19px}
.fm .st-brand-mark{font-size:19px}
.fm .st-brand-icon{width:30px;height:30px}
.fm-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:20px 32px;padding-bottom:24px;border-bottom:1px solid color-mix(in srgb,var(--st-text) 8%,transparent)}
.fm-links{list-style:none;display:flex;flex-wrap:wrap;gap:8px 26px}
.fm-links a{color:var(--st-muted);font-size:15px;font-weight:500;text-decoration:none}
.fm-links a:hover{color:var(--st-brand)}
.fm .st-social{width:36px;height:36px;background:none}
.fm .st-social:hover{background:color-mix(in srgb,var(--st-brand) 12%,transparent);color:var(--st-brand)}
.fm-copy{padding-top:20px;color:var(--st-muted);font-size:14px;text-align:center}
@container st (max-width:760px){.fm-row{flex-direction:column;text-align:center}.fm-links{justify-content:center}.fm .st-socials{justify-content:center}}
/* Back to Top Button */
.st-back-to-top{overflow:visible;container-type:normal;height:0;min-height:0;padding:0;background:transparent}
.st-back-to-top:has(.btt.is-preview){height:auto;padding:clamp(20px,3vw,40px) var(--st-pad);background:color-mix(in srgb,var(--st-text) 6%,var(--st-bg))}
.btt{--btt-size:52px;--btt-off:24px;--btt-radius:50%;--btt-speed:.8s;--btt-bg:var(--st-brand);--btt-fg:var(--st-btn-text)}
.btt-btn{position:fixed;bottom:var(--btt-off);z-index:2147482500;display:grid;place-items:center;width:var(--btt-size);height:var(--btt-size);padding:0;border:0;border-radius:var(--btt-radius);background:var(--btt-bg);color:var(--btt-fg);cursor:pointer;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .3s ease,transform .3s ease,visibility 0s .3s,box-shadow .2s ease,background .2s ease}
.btt[data-pos=right] .btt-btn{right:var(--btt-off)}
.btt[data-pos=left] .btt-btn{left:var(--btt-off)}
.btt[data-appear=slide] .btt-btn{transform:translateY(28px)}
.btt[data-appear=zoom] .btt-btn{transform:scale(.5)}
.btt[data-shadow=on] .btt-btn{box-shadow:0 12px 28px -8px rgba(15,23,42,.45)}
.btt.is-visible .btt-btn{opacity:1;visibility:visible;pointer-events:auto;transform:none;transition:opacity .3s ease,transform .3s ease,visibility 0s,box-shadow .2s ease,background .2s ease}
.btt.is-visible .btt-btn:hover{transform:translateY(-3px)}
.btt.is-visible .btt-btn:active{transform:translateY(0) scale(.96)}
.btt-btn:focus-visible{outline:3px solid color-mix(in srgb,var(--btt-bg) 55%,#fff);outline-offset:3px}
.btt-svg{width:calc(var(--btt-size) * .46);height:calc(var(--btt-size) * .46)}
@media (max-width:899px){.btt[data-mobile=off] .btt-btn{display:none}}
.btt[data-enabled=off] .btt-btn{display:none}
.btt-demo{display:none}
.btt.is-preview .btt-demo{position:relative;display:flex;flex-direction:column;gap:14px;min-height:320px;padding:34px 30px;border-radius:calc(var(--st-radius) * 1.2px);background:var(--st-bg);box-shadow:0 20px 50px -24px color-mix(in srgb,var(--st-text) 40%,transparent)}
.btt-bar{display:block;height:14px;width:100%;border-radius:7px;background:color-mix(in srgb,var(--st-text) 12%,transparent)}
.btt-bar--lg{height:22px;width:62%;background:color-mix(in srgb,var(--st-text) 22%,transparent)}
.btt-bar--md{width:84%}.btt-bar--sm{width:46%}
.btt-note{margin-top:auto;font-size:13px;color:var(--st-muted)}
.btt.is-preview .btt-btn{position:absolute;right:calc(var(--st-pad) + 18px);bottom:calc(clamp(20px,3vw,40px) + 18px);opacity:1;visibility:visible;pointer-events:auto;transform:none}
.btt.is-preview[data-pos=left] .btt-btn{right:auto;left:calc(var(--st-pad) + 18px)}
@media (prefers-reduced-motion:reduce){.btt-btn{transition:none}}
@media print{.btt{display:none}}
/* Accessibility Toolbar Widget */
.st-accessibility-toolbar{overflow:visible;container-type:normal;height:0;min-height:0;background:transparent}
.st-accessibility-toolbar:has(.a11y.is-preview){height:auto;min-height:680px;padding:clamp(16px,2vw,24px) var(--st-pad);background:color-mix(in srgb,var(--st-text) 8%,var(--st-bg))}
.a11y{--a11y-w:380px}
.a11y-fab{position:fixed;bottom:20px;z-index:2147483000;display:grid;place-items:center;width:58px;height:58px;padding:0;border:3px solid #fff;border-radius:50%;background:var(--st-brand);color:var(--st-btn-text);cursor:pointer;box-shadow:0 10px 28px -6px rgba(15,23,42,.5);transition:transform .2s ease,box-shadow .2s ease}
.a11y[data-pos=right] .a11y-fab{right:20px}
.a11y[data-pos=left] .a11y-fab{left:20px}
.a11y-fab:hover{transform:scale(1.06)}
.a11y-fab:focus-visible,.a11y-tile:focus-visible,.a11y-icon:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 60%,#fff);outline-offset:3px}
.a11y.is-open .a11y-fab{box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 30%,transparent),0 10px 28px -6px rgba(15,23,42,.5)}
.a11y-panel{position:fixed;bottom:92px;z-index:2147483001;display:flex;flex-direction:column;width:min(var(--a11y-w),calc(100vw - 24px));max-height:calc(100vh - 116px);max-height:calc(100dvh - 116px);overflow:hidden;border-radius:calc(var(--st-radius) * 1.3px);background:var(--st-bg);color:var(--st-text);font-family:var(--st-font-body);font-size:15px;line-height:1.4;box-shadow:0 30px 70px -18px rgba(15,23,42,.55),0 0 0 1px color-mix(in srgb,var(--st-text) 8%,transparent);opacity:0;transform:translateY(12px) scale(.98);transition:opacity .2s ease,transform .2s ease}
.a11y-panel[hidden]{display:none}
.a11y[data-pos=right] .a11y-panel{right:20px}
.a11y[data-pos=left] .a11y-panel{left:20px}
.a11y.is-open .a11y-panel{opacity:1;transform:none}
.a11y-head{display:flex;align-items:center;gap:6px;padding:13px 18px;background:linear-gradient(135deg,var(--st-brand),color-mix(in srgb,var(--st-brand) 70%,#000));color:var(--st-btn-text)}
.a11y-title{flex:1;margin:0;font-family:var(--st-font-heading);font-size:21px;font-weight:800;letter-spacing:-.01em;color:inherit}
.a11y-icon{display:grid;place-items:center;width:34px;height:34px;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.16);color:inherit;cursor:pointer;transition:background .15s ease}
.a11y-icon:hover{background:rgba(255,255,255,.3)}
.a11y-body{overflow-y:auto;padding:12px 14px 14px;background:var(--st-surface);overscroll-behavior:contain}
.a11y-sec{margin-bottom:10px;padding:12px;border-radius:calc(var(--st-radius) * 1px);background:var(--st-bg)}
.a11y-sec:not(:has(.a11y-tile)){display:none}
.a11y-h{margin:0 0 8px;font-size:14px;font-weight:700;color:var(--st-text)}
.a11y-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.a11y-tile{position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:space-between;gap:8px;min-height:70px;padding:10px 12px;border:2px solid transparent;border-radius:calc(var(--st-radius) * .75px);background:var(--st-surface);color:var(--st-text);font:600 14px/1.25 var(--st-font-body);text-align:left;cursor:pointer;transition:background .15s ease,border-color .15s ease,color .15s ease}
.a11y-tile:hover{border-color:color-mix(in srgb,var(--st-brand) 35%,transparent)}
.a11y-tile[aria-pressed=true]{border-color:var(--st-brand);background:color-mix(in srgb,var(--st-brand) 12%,var(--st-bg));color:var(--st-brand)}
.a11y-ic{flex:none}
.a11y-lab{display:block}
.a11y-pips{display:flex;gap:4px;min-height:6px}
.a11y-pip{width:16px;height:5px;border-radius:3px;background:color-mix(in srgb,var(--st-text) 18%,transparent)}
.a11y-pip.on{background:var(--st-brand)}
.a11y-note{margin:4px 2px 0;font-size:12.5px;color:var(--st-muted);text-align:center}
.a11y-note:empty{display:none}
.a11y.is-preview .a11y-fab{position:absolute}
.a11y.is-preview .a11y-panel{position:relative;inset:auto;margin:0 auto;opacity:1;transform:none;max-height:none}
.a11y-mask{position:fixed;left:0;right:0;z-index:2147482000;background:rgba(0,0,0,.78);pointer-events:none}
@media (max-width:480px){.a11y-grid{gap:8px}.a11y-tile{min-height:76px;padding:10px}}
@media (prefers-reduced-motion:reduce){.a11y-fab,.a11y-panel{transition:none}}
@media print{.a11y,.a11y-mask{display:none}}
.st:has(>.st-art){isolation:isolate}
.st-art{position:absolute;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
.st-art>svg{position:absolute;top:0;left:0;display:block;width:100%;height:100%}
.st-art--bottom>svg{top:auto;bottom:-1px;height:var(--st-art-h,80px)}
.st-art--top>svg{top:-1px;bottom:auto;height:var(--st-art-h,80px);transform:scaleY(-1)}
.st-art--corner>svg{top:-12%;right:-8%;left:auto;width:min(58%,620px);height:auto}
.st-art--corners>svg{top:0;right:0;left:auto;width:clamp(140px,22cqi,300px);height:auto}
.st-art--corners>svg+svg{top:auto;right:auto;bottom:0;left:0;transform:rotate(180deg)}
.st-art[data-pos=top]{inset:0 0 50% 0}
.st-art[data-pos=bottom]{inset:50% 0 0 0}
.st-art[data-pos=left]{inset:0 50% 0 0}
.st-art[data-pos=right]{inset:0 0 0 50%}
.st-art--corner[data-pos=c]>svg{top:var(--art-y,50%);left:var(--art-x,50%);right:auto;bottom:auto;translate:-50% -50%}
.st-art--corner[data-pos=tl]>svg{right:auto;left:-8%}
.st-art--corner[data-pos=br]>svg{top:auto;bottom:-12%}
.st-art--corner[data-pos=bl]>svg{top:auto;right:auto;bottom:-12%;left:-8%}
.st-art--corners[data-pos=tl]>svg{right:auto;left:0;transform:scaleX(-1)}
.st-art--corners[data-pos=tl]>svg+svg{left:auto;right:0;transform:scaleY(-1)}
(function () {
var G = window.gsap;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var anim = G && !reduce;
document.querySelectorAll('.st').forEach(function (sec) {
var btn = sec.querySelector('[data-menu-toggle]');
var panel = sec.querySelector('[data-menu]');
if (btn && panel) {
sec.classList.add('has-menu');
var isOpen = false;
var mobile = function () { return getComputedStyle(btn).display !== 'none'; };
// The toggle and the panel's controls, in document order (the toggle may come after the panel)
var focusables = function () {
return Array.prototype.filter.call(sec.querySelectorAll('a[href], button'), function (el) { return el === btn || panel.contains(el); });
};
var open = function () {
isOpen = true;
sec.classList.add('menu-open');
btn.setAttribute('aria-expanded', 'true');
if (anim) {
G.fromTo(panel, { opacity: 0, y: -12 }, { opacity: 1, y: 0, duration: 0.35, ease: 'power3.out', clearProps: 'transform,opacity' });
G.fromTo(panel.querySelectorAll('[data-menu-item]'), { opacity: 0, y: -8 }, { opacity: 1, y: 0, duration: 0.3, stagger: 0.04, delay: 0.05, ease: 'power2.out', clearProps: 'transform,opacity' });
}
var first = panel.querySelector('a[href], button');
if (first) first.focus();
};
var close = function (returnFocus) {
if (!isOpen) return;
isOpen = false;
btn.setAttribute('aria-expanded', 'false');
var done = function () { sec.classList.remove('menu-open'); };
if (anim) G.to(panel, { opacity: 0, y: -8, duration: 0.2, ease: 'power2.in', onComplete: function () { done(); G.set(panel, { clearProps: 'transform,opacity' }); } });
else done();
if (returnFocus) btn.focus();
};
btn.addEventListener('click', function () { if (isOpen) close(false); else open(); });
document.addEventListener('keydown', function (e) {
if (!isOpen) return;
if (e.key === 'Escape') { close(true); return; }
if (e.key === 'Tab') {
var f = focusables(), first = f[0], last = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
});
document.addEventListener('click', function (e) { if (isOpen && !sec.contains(e.target)) close(false); });
panel.addEventListener('click', function (e) { if (e.target.closest('a')) close(false); });
window.addEventListener('resize', function () { if (isOpen && !mobile()) close(false); });
}
sec.querySelectorAll('[data-dismiss]').forEach(function (x) {
x.addEventListener('click', function () {
var box = x.closest('[data-dismissable]');
if (!box) return;
if (anim) G.to(box, { height: 0, opacity: 0, paddingTop: 0, paddingBottom: 0, duration: 0.35, ease: 'power2.inOut', onComplete: function () { box.remove(); } });
else box.remove();
});
});
if (sec.querySelector('[data-sticky-flag]')) {
var hideOn = !!sec.querySelector('[data-hide-flag]');
var last = window.scrollY, hidden = false;
var onScroll = function () {
var y = window.scrollY;
sec.classList.toggle('is-scrolled', y > 8);
if (hideOn && !sec.classList.contains('menu-open')) {
var down = y > last && y > 120;
if (down !== hidden) {
hidden = down;
if (anim) G.to(sec, { yPercent: down ? -100 : 0, duration: 0.35, ease: 'power2.out' });
else sec.style.transform = down ? 'translateY(-100%)' : '';
}
}
last = y;
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
}
});
})();
(function () {
var G = window.gsap, reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!G || !window.ScrollTrigger || reduce || (window.ST_STILL && !window.ST_SCROLL_FX)) return;
G.registerPlugin(ScrollTrigger);
G.matchMedia().add('(min-width: 768px)', function () {
var made = [];
document.querySelectorAll('.st [data-hscroll]').forEach(function (row) {
var sec = row.closest('.st');
sec.classList.add('is-hscroll');
var dist = function () { return Math.max(0, row.scrollWidth - row.clientWidth); };
// A sticky header stays on screen, so the section pins just below it instead of under it
var head = function () { var h = 0; document.querySelectorAll('.st').forEach(function (n) { if (n !== sec && n.querySelector('[data-sticky-flag]')) h = Math.max(h, n.offsetHeight); }); return h; };
var tw = G.to(row, { x: function () { return -dist(); }, ease: 'none', scrollTrigger: { trigger: sec, start: function () { return 'top ' + head(); }, end: function () { return '+=' + dist(); }, pin: true, scrub: 0.6, anticipatePin: 1, invalidateOnRefresh: true } });
made.push(function () { if (tw.scrollTrigger) tw.scrollTrigger.kill(); tw.kill(); G.set(row, { clearProps: 'transform' }); sec.classList.remove('is-hscroll'); });
});
return function () { made.forEach(function (f) { f(); }); };
});
})();
(function () {
var G = window.gsap, reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!G || !window.ScrollTrigger || reduce || (window.ST_STILL && !window.ST_SCROLL_FX)) return;
G.registerPlugin(ScrollTrigger);
G.matchMedia().add('(min-width: 768px)', function () {
var made = [];
document.querySelectorAll('.st [data-stack]').forEach(function (list) {
var cards = Array.prototype.slice.call(list.children);
if (cards.length < 2) return;
var last = cards[cards.length - 1];
cards.forEach(function (card, i) {
var top = 90 + i * 22;
var pin = ScrollTrigger.create({ trigger: card, start: 'top ' + top, endTrigger: last, end: 'top ' + (90 + (cards.length - 1) * 22), pin: true, pinSpacing: false });
made.push(function () { pin.kill(); });
if (card === last) return;
// Scale the card's inner wrapper: the card itself is positioned by its pin
var inner = card.firstElementChild || card;
// fromTo: GSAP can't tween a filter from "none" (it would start at brightness 0)
var tw = G.fromTo(inner, { scale: 1, filter: 'brightness(1)' }, { scale: 1 - (cards.length - 1 - i) * 0.04, filter: 'brightness(.82)', ease: 'none', scrollTrigger: { trigger: cards[i + 1], start: 'top bottom', end: 'top ' + top, scrub: true } });
made.push(function () { if (tw.scrollTrigger) tw.scrollTrigger.kill(); tw.kill(); G.set(inner, { clearProps: 'transform,filter' }); });
});
});
return function () { made.forEach(function (f) { f(); }); };
});
})();
(function () {
var viewer, imgEl, capEl, countEl, items = [], index = 0, opener = null;
function build() {
if (viewer) return;
viewer = document.createElement('div');
viewer.className = 'stg-lb';
viewer.setAttribute('role', 'dialog');
viewer.setAttribute('aria-modal', 'true');
viewer.setAttribute('aria-label', 'Image viewer');
viewer.hidden = true;
viewer.innerHTML = '<button type="button" class="stg-lb-close" aria-label="Close"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button>' +
'<button type="button" class="stg-lb-nav stg-lb-prev" aria-label="Previous image"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 5-7 7 7 7"/></svg></button>' +
'<figure class="stg-lb-fig"><img class="stg-lb-img" alt=""><figcaption class="stg-lb-cap"></figcaption></figure>' +
'<button type="button" class="stg-lb-nav stg-lb-next" aria-label="Next image"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 5 7 7-7 7"/></svg></button>' +
'<p class="stg-lb-count" aria-live="polite"></p>';
document.body.appendChild(viewer);
imgEl = viewer.querySelector('.stg-lb-img');
capEl = viewer.querySelector('.stg-lb-cap');
countEl = viewer.querySelector('.stg-lb-count');
viewer.addEventListener('click', function (e) {
if (e.target === viewer || e.target.classList.contains('stg-lb-fig')) close();
});
viewer.querySelector('.stg-lb-close').addEventListener('click', close);
viewer.querySelector('.stg-lb-prev').addEventListener('click', function () { show(index - 1); });
viewer.querySelector('.stg-lb-next').addEventListener('click', function () { show(index + 1); });
document.addEventListener('keydown', function (e) {
if (viewer.hidden) return;
if (e.key === 'Escape') close();
else if (e.key === 'ArrowLeft') show(index - 1);
else if (e.key === 'ArrowRight') show(index + 1);
else if (e.key === 'Tab') {
var f = viewer.querySelectorAll('button');
var first = f[0], last = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
});
}
function show(i) {
if (!items.length) return;
index = (i + items.length) % items.length;
var fig = items[index], img = fig.querySelector('img');
imgEl.src = img.currentSrc || img.src;
imgEl.alt = img.alt || '';
var cap = fig.querySelector('.gg-cap');
var parts = cap ? [].slice.call(cap.children).map(function (c) { return c.textContent.trim(); }).filter(Boolean) : [];
capEl.textContent = parts.join(' — ');
countEl.textContent = (index + 1) + ' / ' + items.length;
viewer.classList.toggle('is-single', items.length < 2);
}
// In the editor the preview is a tall frame inside a scrolling panel: centre the viewer in the
// part of the frame you can actually see (a normal page uses the whole window)
// The part of this frame you can see when it sits inside a scrolling panel of the editor
// (null on a normal page): { top, bottom } in the frame's own pixels
function seenRange() {
var fe = null, pw = null;
try { fe = window.frameElement; pw = window.parent; } catch (err) { return null; }
if (!fe || !pw || pw === window) return null;
try {
var r = fe.getBoundingClientRect(), k = r.width / (window.innerWidth || r.width) || 1;
var top = 0, bottom = pw.innerHeight;
for (var n = fe.parentElement; n; n = n.parentElement) {
if (/(auto|scroll|hidden|clip)/.test(pw.getComputedStyle(n).overflowY)) {
var nr = n.getBoundingClientRect();
top = Math.max(top, nr.top); bottom = Math.min(bottom, nr.bottom);
}
}
return { top: Math.max(0, top - r.top) / k, bottom: (Math.min(bottom, r.bottom) - r.top) / k };
} catch (err) { return null; }
}
function fit() {
if (!viewer) return;
var range = window.ST_STILL || window.ST_PREVIEW ? seenRange() : null;
if (!range || range.bottom - range.top < 120) { viewer.style.top = ''; viewer.style.bottom = ''; viewer.style.removeProperty('--lb-h'); return; }
viewer.style.top = range.top + 'px';
viewer.style.bottom = Math.max(0, window.innerHeight - range.bottom) + 'px';
viewer.style.setProperty('--lb-h', (range.bottom - range.top) + 'px');
}
function watch(on) {
try { var w = window.parent; if (!w || w === window) return; var f = on ? 'addEventListener' : 'removeEventListener'; w[f]('scroll', fit, true); w[f]('resize', fit); } catch (err) { /* cross-origin parent */ }
}
function open(list, i, from) {
build();
items = list; opener = from;
show(i);
viewer.hidden = false;
fit(); watch(true);
document.documentElement.classList.add('stg-open');
viewer.querySelector('.stg-lb-close').focus();
}
function close() {
viewer.hidden = true;
watch(false);
document.documentElement.classList.remove('stg-open');
if (opener) opener.focus();
}
document.querySelectorAll('.st').forEach(function (sec) {
var grid = sec.querySelector('[data-gallery]');
if (!grid) return;
var all = [].slice.call(grid.querySelectorAll('.gg-item'));
var bar = sec.querySelector('[data-gallery-filters]');
if (bar && !window.ST_STILL) {
var tags = [];
all.forEach(function (it) { var t = (it.getAttribute('data-tag') || '').trim(); if (t && tags.indexOf(t) < 0) tags.push(t); });
if (tags.length > 1) {
var label = bar.getAttribute('data-all') || 'All';
var buttons = [];
[''].concat(tags).forEach(function (t) {
var b = document.createElement('button');
b.type = 'button';
b.className = 'gg-chip';
b.textContent = t || label;
b.setAttribute('aria-pressed', t ? 'false' : 'true');
b.addEventListener('click', function () {
buttons.forEach(function (x) { x.setAttribute('aria-pressed', String(x === b)); });
all.forEach(function (it) { it.hidden = !!t && (it.getAttribute('data-tag') || '').trim() !== t; });
});
buttons.push(b);
bar.appendChild(b);
});
bar.hidden = false;
}
}
var editing = window.ST_STILL || window.ST_PREVIEW;
all.forEach(function (it) {
var img = it.querySelector('img');
if (!img) return;
function go() {
var visible = all.filter(function (x) { return !x.hidden; });
open(visible, visible.indexOf(it), it);
}
if (editing) {
// In the editor the click also selects the photo in the panel (the editor handles that),
// and the viewer opens on top so you can check it
it.style.cursor = 'zoom-in';
it.addEventListener('click', go);
return;
}
it.setAttribute('tabindex', '0');
it.setAttribute('role', 'button');
it.setAttribute('aria-label', 'View larger: ' + (img.alt || 'image'));
it.addEventListener('click', go);
it.addEventListener('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); go(); } });
});
});
})();
(function () {
var G = window.gsap;
if (G && window.Draggable) G.registerPlugin(Draggable);
if (G && window.InertiaPlugin) G.registerPlugin(InertiaPlugin);
if (G && window.ScrollToPlugin) G.registerPlugin(ScrollToPlugin);
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var fine = window.matchMedia && window.matchMedia('(pointer: fine)').matches;
document.querySelectorAll('.st').forEach(function (sec) {
var track = sec.querySelector('[data-carousel]');
if (!track) return;
var prev = sec.querySelector('[data-carousel-prev]');
var next = sec.querySelector('[data-carousel-next]');
var max = function () { return Math.max(0, track.scrollWidth - track.clientWidth); };
var points = function () {
var first = track.children[0];
if (!first) return [0];
return Array.prototype.map.call(track.children, function (c) { return Math.min(max(), c.offsetLeft - first.offsetLeft); });
};
var nearest = function (x) { return points().reduce(function (a, p) { return Math.abs(p - x) < Math.abs(a - x) ? p : a; }, 0); };
var update = function () {
var x = track.scrollLeft;
if (prev) prev.disabled = x <= 2;
if (next) next.disabled = x >= max() - 2;
};
var go = function (dir) {
var ps = points(), x = track.scrollLeft, target = x;
if (dir > 0) { for (var i = 0; i < ps.length; i++) if (ps[i] > x + 4) { target = ps[i]; break; } }
else { for (var j = ps.length - 1; j >= 0; j--) if (ps[j] < x - 4) { target = ps[j]; break; } }
if (G && window.ScrollToPlugin && !reduce) G.to(track, { scrollTo: { x: target }, duration: 0.6, ease: 'power3.out', onUpdate: update });
else track.scrollTo({ left: target, behavior: reduce ? 'auto' : 'smooth' });
};
if (prev) prev.addEventListener('click', function () { go(-1); });
if (next) next.addEventListener('click', function () { go(1); });
track.addEventListener('scroll', update, { passive: true });
window.addEventListener('resize', update);
update();
// Mouse drag with momentum on desktop; touch keeps native scrolling and snap.
// An invisible proxy is dragged and its x is mapped onto the track's native scrollLeft,
// so the slides' markup and layout never change.
if (G && window.Draggable && fine) {
track.classList.add('is-draggable');
var proxy = document.createElement('div');
var start = 0;
var apply = function () { track.scrollLeft = start - this.x; update(); };
Draggable.create(proxy, {
type: 'x',
trigger: track,
inertia: !!window.InertiaPlugin && !reduce,
dragClickables: false,
onPress: function () { G.killTweensOf(track); start = track.scrollLeft; G.set(proxy, { x: 0 }); this.update(); },
onDrag: apply,
onThrowUpdate: apply,
snap: { x: function (v) { return start - nearest(Math.max(0, Math.min(max(), start - v))); } },
onRelease: function () { if (!this.tween) { G.to(track, { scrollTo: window.ScrollToPlugin ? { x: nearest(track.scrollLeft) } : undefined, duration: 0.4, ease: 'power3.out', onUpdate: update }); } }
});
}
});
})();
(function () {
var G = window.gsap;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var anim = G && !reduce;
document.querySelectorAll('.st [data-accordion]').forEach(function (list) {
var mode = list.getAttribute('data-accordion') || '';
var items = Array.prototype.slice.call(list.querySelectorAll('details'));
var body = function (d) { return d.querySelector('.st-acc-a'); };
var close = function (d) {
if (!d.open || d.classList.contains('is-closing')) return;
if (!anim) { d.open = false; return; }
d.classList.add('is-closing');
G.to(body(d), { height: 0, duration: 0.32, ease: 'power2.inOut', onComplete: function () {
d.open = false; d.classList.remove('is-closing'); G.set(body(d), { clearProps: 'height' });
} });
};
var open = function (d) {
d.open = true;
if (!anim) return;
var b = body(d);
G.fromTo(b, { height: 0 }, { height: 'auto', duration: 0.4, ease: 'power2.out', clearProps: 'height' });
G.fromTo(b.children, { y: -8, opacity: 0 }, { y: 0, opacity: 1, duration: 0.35, delay: 0.06, ease: 'power2.out', clearProps: 'transform,opacity' });
};
items.forEach(function (d) {
d.querySelector('summary').addEventListener('click', function (e) {
e.preventDefault();
if (d.open && !d.classList.contains('is-closing')) { close(d); return; }
if (/single/.test(mode)) items.forEach(function (o) { if (o !== d) close(o); });
open(d);
});
});
if (/first/.test(mode) && items[0]) items[0].open = true;
});
})();
(function () {
var G = window.gsap;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
document.querySelectorAll('.st form[data-form]').forEach(function (form) {
var ok = form.querySelector('[data-form-success]');
var bad = form.querySelector('[data-form-error]');
var btn = form.querySelector('[type="submit"]');
var done = function () {
var fields = form.querySelectorAll('[data-form-fields]');
var show = function () {
Array.prototype.forEach.call(fields, function (f) { f.hidden = true; });
if (ok) { ok.hidden = false; ok.focus && ok.focus(); if (G && !reduce) G.from(ok, { y: 16, opacity: 0, duration: 0.5, ease: 'power3.out', clearProps: 'transform,opacity' }); }
};
if (G && !reduce && fields.length) G.to(fields, { opacity: 0, y: -10, duration: 0.25, onComplete: show }); else show();
};
form.addEventListener('submit', function (e) {
if (!window.fetch) return;
e.preventDefault();
if (bad) bad.hidden = true;
if (btn) { btn.disabled = true; btn.setAttribute('aria-busy', 'true'); }
var finish = function () { if (btn) { btn.disabled = false; btn.removeAttribute('aria-busy'); } };
if (window.ST_PREVIEW) { setTimeout(function () { finish(); done(); }, 600); return; }
fetch(form.action, { method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' } })
.then(function (r) { finish(); if (r.ok) done(); else if (bad) bad.hidden = false; })
.catch(function () { finish(); if (bad) bad.hidden = false; });
});
});
})();
(function () {
var d = new Date();
var pad = function (n) { return (n < 10 ? '0' : '') + n; };
var today = d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
document.querySelectorAll('.st [data-booking-date]').forEach(function (input) { input.min = today; });
})();
(function () {
var KEYS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
function mins(v) {
var m = String(v || '').trim().toLowerCase().match(/^(\d{1,2})(?::(\d{2}))?\s*(am|pm)?$/);
if (!m) return null;
var h = +m[1], mi = +(m[2] || 0);
if (m[3] === 'pm' && h < 12) h += 12;
if (m[3] === 'am' && h === 12) h = 0;
return h > 24 || mi > 59 ? null : h * 60 + mi;
}
function clock(total) {
var h = Math.floor(total / 60) % 24, mi = total % 60;
return (h < 10 ? '0' : '') + h + ':' + (mi < 10 ? '0' : '') + mi;
}
function nowIn(tz) {
var o = { weekday: 'short', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' };
if (tz) o.timeZone = tz;
var parts;
try { parts = new Intl.DateTimeFormat('en-GB', o).formatToParts(new Date()); }
catch (e) { delete o.timeZone; parts = new Intl.DateTimeFormat('en-GB', o).formatToParts(new Date()); }
var p = {};
parts.forEach(function (x) { p[x.type] = x.value; });
return { day: KEYS.indexOf(String(p.weekday).slice(0, 3).toLowerCase()), min: (parseInt(p.hour, 10) % 24) * 60 + parseInt(p.minute, 10) };
}
document.querySelectorAll('.st').forEach(function (sec) {
var root = sec.querySelector('[data-opennow]');
if (!root) return;
var badge = root.querySelector('[data-open-badge]');
var text = badge && badge.querySelector('.oh-badge-text');
var rows = Array.prototype.map.call(root.querySelectorAll('[data-hours-row]'), function (r) {
var d = KEYS.indexOf(String(r.getAttribute('data-day') || '').slice(0, 3).toLowerCase());
var o = mins(r.getAttribute('data-open')), c = mins(r.getAttribute('data-close'));
var label = r.querySelector('.oh-day');
return { el: r, day: d, open: o, close: c, shut: r.getAttribute('data-closed') === 'closed' || o === null || c === null, name: label ? label.textContent : '' };
});
if (!rows.length) return;
var tz = root.getAttribute('data-tz') || '';
function attr(n, d) { return root.getAttribute(n) || d; }
function update() {
var n = nowIn(tz), prev = (n.day + 6) % 7, open = null;
rows.forEach(function (r) {
r.el.classList.toggle('is-today', r.day === n.day);
if (r.day === n.day) r.el.setAttribute('aria-current', 'date'); else r.el.removeAttribute('aria-current');
if (r.shut) return;
var over = r.close <= r.open;
if (r.day === n.day && n.min >= r.open && (over || n.min < r.close)) open = open || r;
if (r.day === prev && over && n.min < r.close) open = open || r;
});
if (!badge || !text) return;
badge.hidden = false;
badge.classList.toggle('is-open', !!open);
badge.classList.toggle('is-shut', !open);
if (open) { text.textContent = attr('data-open-label', 'Open now') + ' \u00b7 ' + attr('data-closes-label', 'closes at') + ' ' + clock(open.close); return; }
var next = null;
for (var i = 0; i < 8 && !next; i++) {
var dd = (n.day + i) % 7;
rows.forEach(function (r) {
if (r.shut || r.day !== dd || (i === 0 && r.open <= n.min)) return;
if (!next || r.open < next.open) next = r;
});
if (next) next.when = i === 0 ? '' : next.name + ' ';
}
text.textContent = attr('data-shut-label', 'Closed now') + (next ? ' \u00b7 ' + attr('data-opens-label', 'opens') + ' ' + next.when + clock(next.open) : '');
}
update();
setInterval(update, 60000);
});
})();
(function () {
var inline = window.ST_STILL || window.ST_PREVIEW || window.ST_POPUP_INLINE;
document.querySelectorAll('.st [data-pu]').forEach(function (root) {
var dlg = root.querySelector('.pu-dialog');
var back = root.querySelector('.pu-backdrop');
if (!dlg || root.getAttribute('data-pu-ready')) return;
root.setAttribute('data-pu-ready', '1');
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
root.querySelectorAll('[data-pu-carousel]').forEach(function (car) {
var track = car.querySelector('.pu-track');
if (!track) return;
var slides = track.children, n = slides.length;
if (n < 2) { car.classList.add('is-single'); return; }
var mk = function (cls, label, svg) { var b = document.createElement('button'); b.type = 'button'; b.className = cls; b.setAttribute('aria-label', label); if (svg) b.innerHTML = svg; return b; };
var arrow = function (d) { return '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="' + d + '"/></svg>'; };
var prev = mk('pu-nav pu-prev', 'Previous slide', arrow('m15 18-6-6 6-6'));
var next = mk('pu-nav pu-next', 'Next slide', arrow('m9 18 6-6-6-6'));
var dots = document.createElement('div'); dots.className = 'pu-dots';
var dotEls = [];
for (var i = 0; i < n; i++) { (function (k) { var d = mk('pu-dot', 'Go to slide ' + (k + 1)); d.addEventListener('click', function () { go(k); stop(); }); dots.appendChild(d); dotEls.push(d); })(i); }
car.appendChild(prev); car.appendChild(next); car.appendChild(dots);
var idx = function () { return Math.round(track.scrollLeft / Math.max(1, track.clientWidth)); };
var mark = function () { var c = idx(); dotEls.forEach(function (d, k) { d.setAttribute('aria-current', k === c ? 'true' : 'false'); }); };
var go = function (k) { k = (k + n) % n; track.scrollTo({ left: k * track.clientWidth, behavior: reduce ? 'auto' : 'smooth' }); };
var ticking = false;
track.addEventListener('scroll', function () { if (ticking) return; ticking = true; requestAnimationFrame(function () { ticking = false; mark(); }); }, { passive: true });
prev.addEventListener('click', function () { go(idx() - 1); stop(); });
next.addEventListener('click', function () { go(idx() + 1); stop(); });
mark();
var secs = parseFloat(root.getAttribute('data-autoplay')) || 0;
var timer = 0, paused = false;
var stop = function () { clearInterval(timer); timer = 0; };
if (secs > 0 && !reduce) {
car.addEventListener('mouseenter', function () { paused = true; });
car.addEventListener('mouseleave', function () { paused = false; });
car.addEventListener('focusin', function () { paused = true; });
car.addEventListener('focusout', function () { paused = false; });
timer = setInterval(function () { var d = root.querySelector('.pu-dialog'); if (!paused && d && !d.hidden && !document.hidden) go(idx() + 1); }, secs * 1000);
}
});
var btnMode = !!window.ST_POPUP_BUTTON; // Website Builder preview: a floating button opens the popup instead of showing it inline
if (inline && !btnMode) {
root.classList.add('is-preview');
dlg.hidden = false;
if (back) back.hidden = true;
root.querySelectorAll('[data-pu-close]').forEach(function (b) { b.addEventListener('click', function (e) { e.preventDefault(); }); });
return;
}
var trigger = root.getAttribute('data-trigger') || 'delay';
var delay = Math.max(0, parseFloat(root.getAttribute('data-delay')) || 0);
var pct = Math.min(100, Math.max(1, parseFloat(root.getAttribute('data-scroll')) || 50));
var days = parseFloat(root.getAttribute('data-days')) || 0;
var KEY = 'pu-' + (root.getAttribute('data-pu-id') || 'x');
try {
var seen = parseInt(localStorage.getItem(KEY), 10);
if (!btnMode && days > 0 && seen && Date.now() - seen < days * 86400000) return;
} catch (e) {}
var modal = (root.getAttribute('data-pos') || 'center') === 'center'; // only the centre popup dims the page and traps focus
dlg.setAttribute('aria-modal', modal ? 'true' : 'false');
var shown = false, last = null, undo = [], quiet = btnMode; // in the builder preview the popup never pulls focus out of the side panel
var setOpenFlag = function (v) { if (!btnMode) return; try { if (v) window.parent.__wbPuOpen = KEY; else if (window.parent.__wbPuOpen === KEY) window.parent.__wbPuOpen = ''; } catch (e) {} };
var focusables = function () { return Array.prototype.filter.call(dlg.querySelectorAll('a[href],button:not([disabled]),input,select,textarea,[tabindex]:not([tabindex="-1"])'), function (el) { return el.offsetParent !== null; }); };
var onKey = function (e) {
if (e.key === 'Escape') { e.preventDefault(); hide(); return; }
if (e.key !== 'Tab' || !modal) return;
var f = focusables();
if (!f.length) return;
var first = f[0], end = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); end.focus(); }
else if (!e.shiftKey && document.activeElement === end) { e.preventDefault(); first.focus(); }
};
function show() {
if (shown) return;
shown = true;
undo.forEach(function (fn) { fn(); });
last = document.activeElement;
dlg.hidden = false;
if (back) back.hidden = false;
void dlg.offsetWidth;
root.classList.add('is-open');
setOpenFlag(true);
if (modal && !quiet) {
var f = focusables();
var target = dlg.querySelector('input') || f[1] || f[0] || dlg;
try { target.focus({ preventScroll: true }); } catch (e) {}
}
document.addEventListener('keydown', onKey);
try { if (days > 0 && !btnMode) localStorage.setItem(KEY, String(Date.now())); } catch (e) {}
}
function hide() {
setOpenFlag(false);
root.classList.remove('is-open');
root.querySelectorAll('.vs-embed').forEach(function (v) { var box = v.parentNode; v.remove(); if (box) box.classList.remove('is-playing'); });
document.removeEventListener('keydown', onKey);
setTimeout(function () { dlg.hidden = true; if (back) back.hidden = true; }, 320);
if (last && last.focus) { try { last.focus({ preventScroll: true }); } catch (e) {} }
}
root.querySelectorAll('[data-pu-close]').forEach(function (b) { b.addEventListener('click', hide); });
var on = function (target, ev, fn, opts) { target.addEventListener(ev, fn, opts); undo.push(function () { target.removeEventListener(ev, fn, opts); }); };
var started = Date.now();
if (btnMode) {
// The popup follows its own trigger (delay, exit intent, scroll) exactly like the published page; a floating
// button also opens and closes it on demand, and it stays open across preview reloads while it is being edited
var btn = document.createElement('button');
btn.type = 'button';
btn.className = 'wb-pu-btn';
btn.textContent = 'Popup preview';
btn.setAttribute('aria-label', 'Open the popup');
btn.style.cssText = 'position:fixed;left:16px;bottom:' + (16 + document.querySelectorAll('.wb-pu-btn').length * 48) + 'px;z-index:999;padding:0 16px;height:38px;border:0;border-radius:999px;background:#4f46e5;color:#fff;font:700 13px/1 system-ui,sans-serif;box-shadow:0 8px 22px rgba(15,23,42,.35);cursor:pointer';
btn.addEventListener('click', function () { if (root.classList.contains('is-open')) hide(); else { shown = false; show(); } });
document.body.appendChild(btn);
try { if (window.parent.__wbPuOpen === KEY) show(); } catch (e) {}
}
if (trigger === 'scroll') {
var check = function () {
var h = document.documentElement.scrollHeight - window.innerHeight;
var p = h > 0 ? (window.scrollY / h) * 100 : 100;
if (p >= pct) show();
};
on(window, 'scroll', check, { passive: true });
} else if (trigger === 'exit' && window.matchMedia && window.matchMedia('(pointer: fine)').matches) {
on(document, 'mouseout', function (e) { if (!e.relatedTarget && e.clientY <= 0 && Date.now() - started > 2000) show(); });
} else {
var timer = setTimeout(show, Math.max(delay, trigger === 'exit' ? 10 : 0) * 1000);
undo.push(function () { clearTimeout(timer); });
}
});
})();
(function () {
var editing = window.ST_STILL || window.ST_PREVIEW;
function embed(url) {
var m;
// Character classes instead of backslashes: this code lives inside a template literal
if ((m = url.match(/(?:youtube[.]com[/](?:watch[?](?:.*&)?v=|embed[/]|shorts[/])|youtu[.]be[/])([A-Za-z0-9_-]{11})/))) return { type: 'iframe', src: 'https://www.youtube-nocookie.com/embed/' + m[1] + '?autoplay=1&rel=0' };
if ((m = url.match(/vimeo[.]com[/](?:video[/])?([0-9]+)/))) return { type: 'iframe', src: 'https://player.vimeo.com/video/' + m[1] + '?autoplay=1&dnt=1' };
if (/[.](mp4|webm|ogg)([?].*)?$/i.test(url)) return { type: 'video', src: url };
return null;
}
document.querySelectorAll('.st [data-video-box]').forEach(function (box) {
var btn = box.querySelector('[data-video]');
if (!btn) return;
function start(e) {
var info = embed(btn.getAttribute('data-video') || '');
if (!info) return;
e.preventDefault();
// In the editor the click also selects the section, so the editor still gets it
if (!editing) e.stopPropagation();
var title = box.getAttribute('data-title') || 'Video';
var el;
if (info.type === 'iframe') {
el = document.createElement('iframe');
el.src = info.src;
el.title = title;
el.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; fullscreen';
el.allowFullscreen = true;
el.referrerPolicy = 'strict-origin-when-cross-origin';
} else {
el = document.createElement('video');
el.src = info.src;
el.controls = true;
el.autoplay = true;
el.setAttribute('playsinline', '');
el.setAttribute('aria-label', title);
}
el.className = 'vs-embed';
box.appendChild(el);
box.classList.add('is-playing');
if (el.focus) el.focus();
}
btn.addEventListener('click', start);
});
})();
(function () {
var inline = window.ST_STILL || window.ST_PREVIEW || window.ST_POPUP_INLINE;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
document.querySelectorAll('.st [data-btt]').forEach(function (root) {
if (root.getAttribute('data-btt-ready')) return;
root.setAttribute('data-btt-ready', '1');
var btn = root.querySelector('.btt-btn');
var demo = root.querySelector('.btt-demo');
if (!btn || root.getAttribute('data-enabled') === 'off') { if (demo && !inline) demo.parentNode.removeChild(demo); return; }
if (!inline && demo) demo.parentNode.removeChild(demo);
if (inline) {
root.classList.add('is-preview', 'is-visible');
btn.addEventListener('click', function (e) { e.preventDefault(); });
return;
}
var dist = parseFloat(root.getAttribute('data-distance')) || 0;
var secs = parseFloat(root.getAttribute('data-speed'));
if (isNaN(secs)) secs = 0.8;
var ticking = false;
function check() { ticking = false; root.classList.toggle('is-visible', (window.pageYOffset || document.documentElement.scrollTop) > dist); }
window.addEventListener('scroll', function () { if (!ticking) { ticking = true; requestAnimationFrame(check); } }, { passive: true });
check();
var stopped = false;
['wheel', 'touchstart', 'keydown'].forEach(function (ev) { window.addEventListener(ev, function () { stopped = true; }, { passive: true }); });
btn.addEventListener('click', function () {
var from = window.pageYOffset || document.documentElement.scrollTop;
if (reduce || secs <= 0 || from < 2) { window.scrollTo({ top: 0, left: 0, behavior: 'instant' }); return; }
stopped = false;
var t0 = performance.now(), dur = secs * 1000;
(function step(t) {
var p = Math.min(1, (t - t0) / dur);
var e = p < 0.5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2;
window.scrollTo({ top: from * (1 - e), left: 0, behavior: 'instant' });
if (p < 1 && !stopped) requestAnimationFrame(step);
})(t0);
});
});
})();
(function () {
var inline = window.ST_STILL || window.ST_PREVIEW || window.ST_POPUP_INLINE;
var btnMode = !!window.ST_POPUP_BUTTON;
var LEVELS = { text: 3, lineheight: 2, align: 3, font: 1, contrast: 2, gray: 1, images: 1, motion: 1, links: 1, mask: 1 };
var SIZES = [1, 1.15, 1.3, 1.5];
var ALIGNS = ['', 'left', 'center', 'right'];
var KEY = 'st-a11y';
var CSS = [
'html[data-a11y-lh="1"] body *:not(.a11y *){line-height:1.7!important}',
'html[data-a11y-lh="2"] body *:not(.a11y *){line-height:2.1!important}',
'html[data-a11y-font] body *:not(.a11y *){font-family:Verdana,Tahoma,Arial,sans-serif!important;letter-spacing:.02em!important}',
'html[data-a11y-align] body *:not(.a11y *){text-align:var(--a11y-align)!important}',
'html[data-a11y-img] body :is(img,picture,video,canvas):not(.a11y *){visibility:hidden!important}',
'html[data-a11y-img] body *:not(.a11y *){background-image:none!important}',
'html[data-a11y-motion] body *:not(.a11y *),html[data-a11y-motion] body *::before,html[data-a11y-motion] body *::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}',
'html[data-a11y-links] body a:not(.a11y a){text-decoration:underline!important;text-underline-offset:3px!important;background:#ffe14d!important;color:#111!important;outline:2px solid #111!important;outline-offset:1px!important}',
'.a11y-fx{filter:var(--a11y-filter,none)}',
'html[data-a11y-contrast="2"] .a11y-fx :is(img,video,picture){filter:invert(1) hue-rotate(180deg)}'
].join('\n');
var textBase = new Map();
function load(remember) {
if (!remember) return {};
try { return JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } catch (e) { return {}; }
}
function save(state, remember) {
if (!remember) return;
try {
var any = Object.keys(LEVELS).some(function (k) { return state[k]; });
if (any) localStorage.setItem(KEY, JSON.stringify(state)); else localStorage.removeItem(KEY);
} catch (e) {}
}
document.querySelectorAll('.st [data-a11y]').forEach(function (root) {
if (root.getAttribute('data-a11y-ready')) return;
root.setAttribute('data-a11y-ready', '1');
var fab = root.querySelector('.a11y-fab');
var panel = root.querySelector('.a11y-panel');
if (!fab || !panel) return;
var remember = root.getAttribute('data-remember') !== 'off';
var tiles = root.querySelectorAll('[data-feature]');
var state = {};
Object.keys(LEVELS).forEach(function (k) { state[k] = 0; });
function paint() {
tiles.forEach(function (t) {
var f = t.getAttribute('data-feature');
var lvl = state[f] || 0, max = LEVELS[f] || 1;
t.setAttribute('aria-pressed', lvl > 0 ? 'true' : 'false');
var pips = t.querySelector('.a11y-pips');
if (pips) {
pips.innerHTML = '';
if (max > 1) for (var i = 1; i <= max; i++) { var p = document.createElement('span'); p.className = 'a11y-pip' + (i <= lvl ? ' on' : ''); pips.appendChild(p); }
}
});
}
root.querySelectorAll('[data-a11y-close]').forEach(function (b) { b.addEventListener('click', function (e) { if (inline && !btnMode) { e.preventDefault(); panel.hidden = true; fab.setAttribute('aria-expanded', 'false'); return; } close(true); }); });
if (inline && !btnMode) {
root.classList.add('is-preview');
panel.hidden = false;
fab.setAttribute('aria-expanded', 'true');
fab.addEventListener('click', function () { panel.hidden = !panel.hidden; fab.setAttribute('aria-expanded', String(!panel.hidden)); });
tiles.forEach(function (t) {
t.addEventListener('click', function () { var f = t.getAttribute('data-feature'); state[f] = ((state[f] || 0) + 1) % ((LEVELS[f] || 1) + 1); paint(); });
});
var rs = root.querySelector('[data-a11y-reset]');
if (rs) rs.addEventListener('click', function () { Object.keys(LEVELS).forEach(function (k) { state[k] = 0; }); paint(); });
state.text = 1; state.contrast = 0; state.font = 1; // a sample of switched-on options for the preview
paint();
return;
}
/* ---------- real page ---------- */
var styleEl = document.createElement('style');
styleEl.setAttribute('data-a11y-css', '');
styleEl.textContent = CSS;
document.head.appendChild(styleEl);
var html = document.documentElement;
var maskTop = null, maskBottom = null, maskY = 140;
function markFx() {
(function walk(node) {
Array.prototype.forEach.call(node.children, function (c) {
if (c === root) return;
if (c.contains(root)) { walk(c); return; }
if (/^(SCRIPT|STYLE|LINK|META|NOSCRIPT|TEMPLATE)$/.test(c.tagName) || c.hasAttribute('data-a11y-css')) return;
c.classList.add('a11y-fx');
});
})(document.body);
}
function applyText(level) {
var els = [];
document.body.querySelectorAll('*').forEach(function (el) {
if (el.closest('.a11y') || /^(SCRIPT|STYLE|NOSCRIPT|SVG|PATH|BR|HR|IMG|VIDEO|CANVAS)$/i.test(el.tagName)) return;
for (var n = el.firstChild; n; n = n.nextSibling) { if (n.nodeType === 3 && n.nodeValue.trim()) { els.push(el); break; } }
});
if (level === 0) {
textBase.forEach(function (info, el) { if (info.inline) el.style.setProperty('font-size', info.inline); else el.style.removeProperty('font-size'); });
textBase.clear();
return;
}
els.forEach(function (el) { if (!textBase.has(el)) textBase.set(el, { inline: el.style.getPropertyValue('font-size'), px: parseFloat(getComputedStyle(el).fontSize) || 16 }); });
els.forEach(function (el) { var info = textBase.get(el); el.style.setProperty('font-size', (info.px * SIZES[level]).toFixed(2) + 'px', 'important'); });
}
function setMask(on) {
if (!on) {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('touchmove', onTouch);
document.removeEventListener('focusin', onFocus);
if (maskTop) { maskTop.remove(); maskBottom.remove(); maskTop = maskBottom = null; }
return;
}
if (maskTop) return;
maskTop = document.createElement('div'); maskTop.className = 'a11y-mask'; maskTop.style.top = '0';
maskBottom = document.createElement('div'); maskBottom.className = 'a11y-mask'; maskBottom.style.bottom = '0';
document.body.appendChild(maskTop); document.body.appendChild(maskBottom);
place(maskY);
document.addEventListener('mousemove', onMove);
document.addEventListener('touchmove', onTouch, { passive: true });
document.addEventListener('focusin', onFocus);
}
function place(y) {
maskY = y;
var half = 55;
maskTop.style.height = Math.max(0, y - half) + 'px';
maskBottom.style.height = Math.max(0, window.innerHeight - y - half) + 'px';
}
function onMove(e) { place(e.clientY); }
function onTouch(e) { if (e.touches[0]) place(e.touches[0].clientY); }
function onFocus(e) { if (e.target && e.target.getBoundingClientRect && !root.contains(e.target)) { var r = e.target.getBoundingClientRect(); place(r.top + r.height / 2); } }
function apply() {
var s = state;
function flag(name, on, val) { if (on) html.setAttribute(name, val === undefined ? '' : val); else html.removeAttribute(name); }
flag('data-a11y-lh', s.lineheight > 0, String(s.lineheight));
flag('data-a11y-font', s.font > 0);
flag('data-a11y-align', s.align > 0);
if (s.align > 0) html.style.setProperty('--a11y-align', ALIGNS[s.align]); else html.style.removeProperty('--a11y-align');
flag('data-a11y-img', s.images > 0);
flag('data-a11y-motion', s.motion > 0);
flag('data-a11y-links', s.links > 0);
flag('data-a11y-contrast', s.contrast > 0, String(s.contrast));
var filters = [];
if (s.contrast === 1) filters.push('contrast(1.5)');
if (s.contrast === 2) filters.push('invert(1) hue-rotate(180deg)');
if (s.gray) filters.push('grayscale(1)');
if (filters.length) { markFx(); html.style.setProperty('--a11y-filter', filters.join(' ')); } else html.style.removeProperty('--a11y-filter');
applyText(s.text);
if (s.motion) {
document.querySelectorAll('video').forEach(function (v) { try { v.pause(); } catch (e) {} });
if (window.gsap && gsap.globalTimeline) gsap.globalTimeline.pause();
} else if (window.gsap && gsap.globalTimeline) gsap.globalTimeline.resume();
setMask(s.mask > 0);
paint();
save(s, remember);
}
tiles.forEach(function (t) {
t.addEventListener('click', function () { var f = t.getAttribute('data-feature'); state[f] = ((state[f] || 0) + 1) % ((LEVELS[f] || 1) + 1); apply(); });
});
var reset = root.querySelector('[data-a11y-reset]');
if (reset) reset.addEventListener('click', function () { Object.keys(LEVELS).forEach(function (k) { state[k] = 0; }); apply(); });
function open() {
panel.hidden = false;
requestAnimationFrame(function () { root.classList.add('is-open'); });
fab.setAttribute('aria-expanded', 'true');
panel.focus();
}
function close(refocus) {
root.classList.remove('is-open');
fab.setAttribute('aria-expanded', 'false');
setTimeout(function () { if (!root.classList.contains('is-open')) panel.hidden = true; }, 220);
if (refocus) fab.focus();
}
fab.addEventListener('click', function () { if (root.classList.contains('is-open')) close(true); else open(); });
root.addEventListener('keydown', function (e) { if (e.key === 'Escape' && root.classList.contains('is-open')) { e.stopPropagation(); close(true); } });
document.addEventListener('mousedown', function (e) { if (root.classList.contains('is-open') && !root.contains(e.target)) close(false); });
var saved = load(remember);
var any = false;
Object.keys(LEVELS).forEach(function (k) { var v = parseInt(saved[k], 10); if (v > 0 && v <= LEVELS[k]) { state[k] = v; any = true; } });
paint();
// Restore after the page has finished loading, so text added below this script is found too
if (any) { if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', apply); else apply(); }
});
})();
(function () {
if (!window.gsap) return;
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
if (window.ScrollTrigger) gsap.registerPlugin(ScrollTrigger);
var TEXT = window.SplitText ? {"split":"words","part":"words","mask":"words","vars":{"yPercent":110,"stagger":0.06,"duration":0.8}} : null;
if (TEXT) gsap.registerPlugin(SplitText);
function run() {
document.querySelectorAll('.st:not([data-scroll])').forEach(function (section) {
var heads = TEXT ? section.querySelectorAll('[data-anim-text]') : [];
var items = section.querySelectorAll(heads.length ? '[data-anim="item"]:not([data-anim-text])' : '[data-anim="item"]');
var media = section.querySelectorAll('[data-anim="media"]');
var tl = gsap.timeline({
defaults: { ease: 'power3.out', duration: 0.80 },
scrollTrigger: window.ScrollTrigger ? (window.ST_PREVIEW ? { trigger: section, start: 'top 80%', end: function () { var pin = ScrollTrigger.getAll().filter(function (t) { return t.pin === section; })[0]; return pin ? pin.end + section.offsetHeight : 'bottom top'; }, toggleActions: 'play reset play reset' } : { trigger: section, start: 'top 80%', once: true }) : undefined
});
Array.prototype.forEach.call(heads, function (el, i) {
var opts = { type: TEXT.split };
if (TEXT.mask) opts.mask = TEXT.mask;
var parts = SplitText.create(el, opts)[TEXT.part];
// The mask clips each line or word to its line box, which cuts off descenders (g, y, p):
// give the mask a little room below and take it back with a negative margin
if (TEXT.mask) Array.prototype.forEach.call(parts, function (p) { var m = p.parentElement; if (m && m !== el) { m.style.paddingBottom = '.22em'; m.style.marginBottom = '-.22em'; } });
tl.from(parts, Object.assign({}, TEXT.vars), i ? '<0.1' : 0);
});
if (items.length) tl.from(items, {"y":28,"opacity":0,"stagger":0.09,"clearProps":"transform,opacity"}, heads.length ? '<0.2' : 0);
if (media.length) tl.from(media, {"y":40,"opacity":0,"duration":1.1,"clearProps":"transform,opacity"}, items.length || heads.length ? '<0.15' : 0);
});
}
// Split text only after the fonts load, so lines break where they finally will
if (TEXT && document.fonts && document.fonts.ready) document.fonts.ready.then(run); else run();
})();
(function () {
var G = window.gsap, reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!G || reduce || window.ST_STILL) return;
if (window.ScrollTrigger) G.registerPlugin(ScrollTrigger);
document.querySelectorAll('.st-art[data-art-anim]').forEach(function (layer) {
var mode = layer.getAttribute('data-art-anim'), sec = layer.closest('.st'), svg = layer.querySelector('svg');
if (mode === 'float') layer.querySelectorAll('[data-float]').forEach(function (el, i) {
G.to(el, { x: (i % 3 - 1) * 24, y: (i % 2 ? -1 : 1) * 22, duration: 5 + (i % 3), ease: 'sine.inOut', yoyo: true, repeat: -1, delay: i * 0.4 });
});
if (mode === 'spin') layer.querySelectorAll('[data-spin]').forEach(function (el, i) {
G.to(el, { rotation: i % 2 ? -360 : 360, duration: 60 + i * 8, ease: 'none', repeat: -1, transformOrigin: '50% 50%' });
});
// window.ST_ART_PLAY (the section editor's preview): draw and parallax play once by themselves,
// so picking them shows the effect without scrolling. Exports and pages keep the scroll-driven version.
if (mode === 'draw' && (window.ScrollTrigger || window.ST_ART_PLAY)) layer.querySelectorAll('[data-draw]').forEach(function (p, i) {
var len = p.getTotalLength ? p.getTotalLength() : 0;
if (!len) return;
if (window.ST_ART_PLAY) G.fromTo(p, { strokeDasharray: len, strokeDashoffset: len }, { strokeDashoffset: 0, duration: 2.4, delay: i * 0.12, ease: 'power2.out' });
else G.fromTo(p, { strokeDasharray: len, strokeDashoffset: len }, { strokeDashoffset: 0, ease: 'none', scrollTrigger: { trigger: sec, start: 'top 90%', end: 'bottom 40%', scrub: 0.6 } });
});
if (mode === 'parallax' && svg && (window.ScrollTrigger || window.ST_ART_PLAY)) {
G.set(svg, { scale: 1.15 });
if (window.ST_ART_PLAY) G.fromTo(svg, { yPercent: -6 }, { yPercent: 6, duration: 2.4, ease: 'sine.inOut', yoyo: true, repeat: 1 });
else G.fromTo(svg, { yPercent: -6 }, { yPercent: 6, ease: 'none', scrollTrigger: { trigger: sec, start: 'top bottom', end: 'bottom top', scrub: true } });
}
});
})();
Extend with AI
Take This Template Further With AI
Give this prompt to an AI assistant to generate your own version of the Boutique Hotel Website template: swap in your business name, services and tone, add or remove sections, translate it, or turn the page into a Next.js project or a WordPress theme. Use the template above as the visual reference, so you and the AI start from a design that already works.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a complete boutique hotel website for “Casa Mar” as clean HTML, CSS and a little JavaScript.
Page structure, top to bottom:
1. Simple Sticky Navbar
2. Image Background Hero: “Slow mornings, salt-water days”
3. Horizontal Scroll Gallery: “Find your room”
4. Stacking Cards: “Everything for a slow stay”
5. Filterable Image Gallery: “A look around Casa Mar”
6. Testimonial Carousel: “Guests come back”
7. FAQ Accordion: “Before you arrive”
8. Booking Request Form: “Request your stay”
9. Opening Hours & Location: “Two minutes from the sea”
10. Popup & Promo Modal
11. Minimal Footer
12. Back to Top Button
13. Accessibility Toolbar Widget
Look and feel:
- Colours as CSS custom properties: brand #0f766e, page background #fbf8f3, cards #f1ebe1, text #1f2a24, muted text #5c665f. Corner radius 14px, content width 1200px.
- Headings in Playfair Display, body text in DM Sans (load both from Google Fonts with display=swap).
- Mobile first. Sections use CSS grid or flexbox and stack cleanly below 700px.
Content:
- Write real, believable travel & hospitality copy for every section instead of lorem ipsum: specific offers, numbers, names and calls to action.
- One clear primary action in the hero and again near the end.
Quality:
- Semantic HTML (header, main, section, footer) with exactly one h1, the hero headline, and one h2 per section.
- Accessible: alt text on every image, visible focus states, labelled form fields, buttons and links with clear text, and prefers-reduced-motion respected.
- SEO: title “Casa Mar: Boutique Hotel Two Minutes From the Algarve Sea”, a meta description of 150 to 160 characters, Open Graph tags and JSON-LD that suits a travel & hospitality business.
- Optional: a subtle GSAP ScrollTrigger fade-up on section headings, with content visible without JavaScript.
Also create these pages with the same navbar, footer and theme, and link them from the menu:
- Rooms (rooms.html)
- Experience (experience.html)
- Book (book.html)
- Privacy (privacy.html)Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
What's included
Features
About this UI Snippet
A Boutique Hotel Website That Sells the Stay: Rooms, Experience and Direct Booking

Small hotels and B&Bs compete with booking platforms that take a commission, so the site's job is to make a direct booking feel better. The dusk hero sets the mood and states the essentials (location, price from, availability), and the rooms scroll sideways as the guest scrolls down, a horizontal gallery that gives each room space to be looked at, which a grid of thumbnails cannot.
The experience is told in stacking cards, one idea at a time (breakfast, the garden, the walks nearby), so guests picture the stay rather than comparing room specifications. Reviews from past guests, a FAQ on check-in, parking and pets, and a booking request form with a map complete the page, with a popup available for a seasonal offer such as "stay three nights, pay for two".
Use your own photography, because in hospitality the images are the product. It is the layout of the Boutique Hotel Website template, which also comes as a multi-page site with Rooms, Experience and Book pages; open it in the Website Builder to edit and export.
Interactive extras built in
Beyond the core sections, this template adds reception hours with a live Open now badge, the address, a map and a call button; a floating back to top button that appears after the visitor scrolls, so a long page is easy to leave and return; and a floating accessibility toolbar where visitors can enlarge text, raise contrast, hide images and pause animations. Each one has its own page in the Website Section Templates library (Opening Hours & Location, Back to Top Button, Accessibility Toolbar Widget), where you can try its settings on their own, and you can edit, move or remove any of them in the Website Builder.
Built from website section templates
The 13 Sections Behind This Boutique Hotel Website Page
This page is not one big block of code: it is stacked from ready-made sections in the free Website Section Templates library, in this order. Open any of them to edit it on its own, or start with the whole page.
- Simple Sticky Navbara sticky bar with a Book direct button, the action that saves you the platform commission
- Image Background Heroa dusk photograph with the location, a "from" price and a booking button
- Horizontal Scroll Galleryrooms that scroll sideways as the guest scrolls down, giving each one room to be looked at
- Stacking Cardsthe experience told in stacking cards: breakfast, the garden, the walks nearby
- Filterable Image Gallerya filterable gallery by room, dining and surroundings
- Testimonial Carouselreviews from past guests, which a booking platform would normally keep for itself
- FAQ Accordioncheck-in times, parking, pets and cancellation, answered before the enquiry
- Booking Request Forma booking request form with dates, guests and room preference
- Opening Hours & Locationreception hours with a live Open now badge, the address, a map and a call button
- Popup & Promo Modala popup for a seasonal offer such as three nights for the price of two
- Minimal Footera minimal footer with contact details, registration and legal links
- Back to Top Buttona floating back to top button that appears after the visitor scrolls, so a long page is easy to leave and return
- Accessibility Toolbar Widgeta floating accessibility toolbar where visitors can enlarge text, raise contrast, hide images and pause animations
Step by step
How to Use
- 1Open the template in the Website BuilderPress "Start using this template" to open the Boutique Hotel Website in the Website Builder. Everything is edited with forms in a side panel; no code is needed.
- 2Describe each room honestly with real photosAdd one slide per room with its name, size, bed type and a "from" price, using your own photography taken in good light.
- 3Write the experience cards about the stay, not the buildingUse the stacking cards for moments a guest will remember (the breakfast, the view, the evening drink) rather than a list of facilities.
- 4Offer a reason to book directUse the popup and booking form to offer something a platform does not, such as a welcome drink, free late checkout or a best-rate guarantee.
- 5Export and publishDownload one HTML file or a ZIP (or one HTML file per page for the multi-page version) and upload it to Netlify, Vercel, Cloudflare Pages, GitHub Pages or your own host. Or copy the code from this page and export it to React, Vue, Angular or Tailwind with the buttons above the editor.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Rooms with photos and prices, what makes the stay special, reviews, practical answers, a way to book direct and a map.
The form sends booking requests to your email. For live availability, link the booking button to your property management or booking engine.
A horizontal gallery gives each room the full width of the screen, so photographs read bigger and guests look at each room properly.
It adds an opening hours section with a live Open now badge, a floating back to top button and an accessibility toolbar. Each is a section you can edit, move or remove in the Website Builder, and each has its own page in the Website Section Templates library.
It is assembled from 13 templates in the free Website Section Templates library: Simple Sticky Navbar, Image Background Hero, Horizontal Scroll Gallery, Stacking Cards, Filterable Image Gallery, Testimonial Carousel, FAQ Accordion, Booking Request Form, Opening Hours & Location, Popup & Promo Modal, Minimal Footer, Back to Top Button, Accessibility Toolbar Widget. Each one has its own page where you can edit it separately.
It is the same page. Here you read and edit the HTML, CSS and JavaScript directly with a live preview; in the Website Builder you edit it with forms, change the theme once for the whole page, add pages and export a finished site.