Band Website HTML Template — Free Music Artist Page
Music Artist & Band Website template · 13 website sections · Plain HTML, CSS & JS · Customise it in the Website Builder
What's included
Features
About this UI Snippet
Anatomy of a Band Website: Why Each Section Sits Where It Does

A band website has three jobs: get people to press play, get them to a show and get them on your list. This page is ordered around those jobs. The stage hero names the band and offers the music and the tour in two buttons, the New Release Spotlight counts down to the album, and the Audio Player lets a visitor hear the new songs without leaving the page, because a song heard is worth ten described.
Tour dates come next because that is the second thing a fan looks for, and they are a list with a clear status (Tickets, Few left, Sold out) rather than a poster image, so search engines can read them. The Discography Grid follows for the visitor who wants the back catalogue, then a live video and a photo gallery for atmosphere, press quotes for proof, merch for the fans who want something physical, and a booking and press form for promoters and journalists. A newsletter closes the page so the people who do not buy today can still hear about the next release.
To make it yours, keep the order and replace the content: use a stage photo with space on the left for the hero, write the release date and time into the countdown, paste links to your own MP3 previews into the player and add the date of every show so the tour list can describe itself to search engines. This is the same page as the Music Artist & Band website template, which also opens as a six-page site with Music, Tour, Videos, Merch, About and Contact pages.
Built from website section templates
The 13 Sections Behind This Music Artist & Band 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.
- Floating Pill Navbara floating bar that keeps "Listen now" one click away while the visitor scrolls the whole page
- Music Artist Heroa stage photo, the band name in huge type and two buttons, one for the music and one for the tour
- New Release Spotlighta countdown to the new album that turns into "Out now" by itself on release day
- Audio Player & Track Listthe fastest way to convince a visitor: press play on the new songs right on the page
- Tour Dates & Ticketsa calendar-style list of shows with colour-coded status and ticket buttons, readable by search engines
- Discography Gridthe back catalogue as cover art with filter chips, for visitors who want older records
- Video Section with Postera live session poster frame that adds atmosphere and shows the band at work
- Filterable Image Galleryphotos from stage, studio and crowd, filterable by category
- Testimonial Carouselpress quotes that carry proof from outside the band
- Product Gridvinyl, cassettes and posters for the fans who want something physical
- Booking Request Forma booking and press form so promoters, journalists and licensing enquiries have a clear route
- Newsletter Signup CTAa newsletter sign-up so visitors who do not buy today still hear about the next release
- Minimal Footera minimal footer with links to every section and the social profiles
Step by step
How to Use
- 1Open the template in the Website BuilderPress "Start using this template" to open the Music Artist & Band Website in the Website Builder. Everything is edited with forms in a side panel; no code is needed.
- 2Set the release and the showsType your release date and time into the New Release Spotlight, then add every show to the tour list with its city, venue, status and ticket link. Add each show's date in year-month-day form so the list can describe itself to search engines.
- 3Add your own songsPaste a link to an MP3 or WAV preview for each track in the Audio Player, add the cover art, and put your Spotify or Bandcamp link in the stream field so a good preview leads straight to the full song.
- 4Swap in your photos and linksReplace the stage photo, covers, gallery pictures and press quotes with your own, and point the booking form at your own email or form service. Check that every image has a short description for screen readers.
- 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
Paste a direct link to an MP3 or WAV file into each track. Short previews of 30 to 60 seconds load fastest, and each track can carry a stream or buy link so the full song is one click away.
Yes. When the release time passes, the countdown hides, an "Out now" message appears and the main button changes to "Listen now", in each visitor's browser, with no reload.
Yes. Change the names, photos and links: a DJ can use the tour list as a booking calendar, and a label can use the discography grid as a roster, with the artist name as the type for the filter chips.
It is assembled from 13 templates in the free Website Section Templates library: Floating Pill Navbar, Music Artist Hero, New Release Spotlight, Audio Player & Track List, Tour Dates & Tickets, Discography Grid, Video Section with Poster, Filterable Image Gallery, Testimonial Carousel, Product Grid, Booking Request Form, Newsletter Signup CTA, Minimal Footer. 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.
Source Code
<section class="st st-navbar-floating" data-uid="smvrrymllamn4">
<div class="st-wrap">
<header class="nf">
<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="M3 14h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-7a9 9 0 0 1 18 0v7a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3" /></svg></span><span>Velvet Static</span></span>
</a>
<nav class="nf-nav" data-menu aria-label="Main">
<ul class="nf-links">
<li data-menu-item><a class="nf-link" href="#music"><span>Music</span></a></li>
<li data-menu-item><a class="nf-link" href="#tour"><span>Tour</span></a></li>
<li data-menu-item><a class="nf-link" href="#videos"><span>Videos</span></a></li>
<li data-menu-item><a class="nf-link" href="#merch"><span>Merch</span></a></li>
<li data-menu-item><a class="nf-link" href="#contact"><span>Contact</span></a></li>
</ul>
<a class="st-btn nf-cta" data-menu-item href="#listen"><span>Listen now</span></a>
</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>
</div>
<i hidden data-sticky-flag></i>
</section>
<section class="st st-music-hero" data-uid="smvrrymllfyy4">
<div class="mh-bg" role="img" style="background-image:url('https://webdevpuneet.com/images/section-templates/tpl-music.jpg')" aria-label="The singer at the microphone under cyan and pink stage lights"></div>
<div class="mh-shade" aria-hidden="true"></div>
<div class="mh st-wrap">
<span class="mh-pill" data-anim="item"><i class="mh-dot" aria-hidden="true"></i><span>New album · Out 14 November</span></span>
<h1 class="mh-name" data-anim="item" data-anim-text>Velvet<br><span class="hl">Static</span></h1>
<p class="st-lead mh-tag" data-anim="item">Dream-pop from Lisbon with big drums, late-night synths and songs made to be sung back.</p>
<div class="st-btns" data-anim="item">
<a class="st-btn" href="#listen"><span>Listen now</span></a>
<a class="st-btn st-btn--ghost mh-ghost" href="#tour"><span>Tour dates</span></a>
</div>
<ul class="mh-links" data-anim="item" aria-label="Listen on">
<li><a class="mh-link" href="#"><span>Spotify</span></a></li>
<li><a class="mh-link" href="#"><span>Apple Music</span></a></li>
<li><a class="mh-link" href="#"><span>YouTube</span></a></li>
<li><a class="mh-link" href="#"><span>Bandcamp</span></a></li>
</ul>
</div>
<div class="mh-eq" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</section>
<section id="new-release" class="st st-release-spotlight" data-uid="smvrrymllq9i1">
<div class="st-wrap rs">
<div class="rs-art" data-anim="media">
<span class="rs-disc" aria-hidden="true"></span>
<img class="rs-cover" width="1200" height="1200" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-1.jpg" alt="Album cover with a pink sun rising over dark water">
</div>
<div class="rs-copy">
<p class="st-eyebrow" data-anim="item">New album</p>
<h2 class="rs-title" data-anim="item" data-anim-text>Static <span class="hl">Hearts</span></h2>
<p class="st-lead rs-text" data-anim="item">Eleven songs about leaving, arriving and everything in between, recorded live to tape in a converted church in Porto.</p>
<div class="rs-count" data-anim="item" data-countdown role="timer" data-at="2026-11-14T00:00" data-out="Out now. Listen everywhere." data-cta-out="Listen now">
<div class="rs-cell"><b data-u="d">--</b><span>Days</span></div>
<div class="rs-cell"><b data-u="h">--</b><span>Hours</span></div>
<div class="rs-cell"><b data-u="m">--</b><span>Minutes</span></div>
<div class="rs-cell"><b data-u="s">--</b><span>Seconds</span></div>
</div>
<p class="rs-out" data-out hidden></p>
<ol class="rs-tracks" data-anim="item"><li>Lights Out in Lisbon</li><li>Slow Fire</li><li>Night Tram</li><li>Paper Skies</li><li>Static Hearts</li><li>The Last Train Home</li></ol>
<div class="st-btns" data-anim="item">
<a class="st-btn" data-cta-main href="#"><span>Pre-save the album</span></a>
<a class="st-btn st-btn--ghost rs-ghost" href="#videos"><span>Watch the teaser</span></a>
</div>
</div>
</div>
</section>
<section id="listen" class="st st-audio-player" data-uid="smvrrymlle02l">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">Listen</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Press play on <span class="hl">the new songs</span></h2>
<p class="st-lead" data-anim="item">Short previews of the new album. Tap a track to play it, or stream the full song with the link beside it.</p>
</header>
<div class="ap" data-player data-anim="media">
<div class="ap-now">
<div class="ap-art"><img class="ap-cover" data-ap-cover alt="" width="600" height="600"></div>
<div class="ap-info"><span class="ap-tag">Now playing</span><strong class="ap-title" data-ap-title></strong><span class="ap-meta" data-ap-meta></span></div>
<div class="ap-bar"><span class="ap-t" data-ap-cur>0:00</span><input class="ap-seek" type="range" min="0" max="1000" value="0" step="1" aria-label="Seek" data-ap-seek><span class="ap-t" data-ap-dur>0:00</span></div>
<div class="ap-ctl">
<button class="ap-btn" type="button" aria-label="Previous track" data-ap-prev><svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" aria-hidden="true"><path d="M6 5h2v14H6zM20 5v14L9 12z"/></svg></button>
<button class="ap-btn ap-play" type="button" aria-label="Play" data-ap-play><svg class="ap-i-play" viewBox="0 0 24 24" width="26" height="26" fill="currentColor" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg><svg class="ap-i-pause" viewBox="0 0 24 24" width="26" height="26" fill="currentColor" aria-hidden="true"><path d="M7 5h4v14H7zM13 5h4v14h-4z"/></svg></button>
<button class="ap-btn" type="button" aria-label="Next track" data-ap-next><svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" aria-hidden="true"><path d="M16 5h2v14h-2zM4 5l11 7-11 7z"/></svg></button>
</div>
<p class="ap-msg" data-ap-msg role="status"></p>
</div>
<ol class="ap-list">
<li class="ap-track" data-src="https://webdevpuneet.com/audio/demo-1.wav">
<button class="ap-row" type="button" data-ap-row>
<span class="ap-n" aria-hidden="true"></span>
<img class="ap-thumb" width="120" height="120" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-1.jpg" alt="Cover art for Lights Out in Lisbon, a pink sun over dark water">
<span class="ap-names"><b class="ap-name">Lights Out in Lisbon</b><small class="ap-by">Velvet Static · Static Hearts</small></span>
<span class="ap-eq" aria-hidden="true"><i></i><i></i><i></i></span>
<span class="ap-len">0:08</span>
</button>
<a class="ap-link" href="#"><span>Stream</span></a>
</li>
<li class="ap-track" data-src="https://webdevpuneet.com/audio/demo-2.wav">
<button class="ap-row" type="button" data-ap-row>
<span class="ap-n" aria-hidden="true"></span>
<img class="ap-thumb" width="120" height="120" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-2.jpg" alt="Cover art for Slow Fire, a glowing cyan circle on black">
<span class="ap-names"><b class="ap-name">Slow Fire</b><small class="ap-by">Velvet Static · Single</small></span>
<span class="ap-eq" aria-hidden="true"><i></i><i></i><i></i></span>
<span class="ap-len">0:08</span>
</button>
<a class="ap-link" href="#"><span>Stream</span></a>
</li>
<li class="ap-track" data-src="https://webdevpuneet.com/audio/demo-3.wav">
<button class="ap-row" type="button" data-ap-row>
<span class="ap-n" aria-hidden="true"></span>
<img class="ap-thumb" width="120" height="120" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-3.jpg" alt="Cover art for Night Tram, violet and orange waves">
<span class="ap-names"><b class="ap-name">Night Tram</b><small class="ap-by">Velvet Static · Night Tram EP</small></span>
<span class="ap-eq" aria-hidden="true"><i></i><i></i><i></i></span>
<span class="ap-len">0:08</span>
</button>
<a class="ap-link" href="#"><span>Stream</span></a>
</li>
<li class="ap-track" data-src="">
<button class="ap-row" type="button" data-ap-row>
<span class="ap-n" aria-hidden="true"></span>
<img class="ap-thumb" width="120" height="120" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-4.jpg" alt="Cover art for Paper Skies, golden dots on deep blue">
<span class="ap-names"><b class="ap-name">Paper Skies</b><small class="ap-by">Velvet Static · Paper Skies</small></span>
<span class="ap-eq" aria-hidden="true"><i></i><i></i><i></i></span>
<span class="ap-len">3:51</span>
</button>
<a class="ap-link" href="#"><span>Stream</span></a>
</li>
</ol>
</div>
</div>
</section>
<section id="tour" class="st st-tour-dates" data-uid="smvrrymllt3s9">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">On tour</p>
<h2 class="st-h2" data-anim="item" data-anim-text>See us <span class="hl">live</span></h2>
<p class="st-lead" data-anim="item">The Static Hearts tour: eleven shows across Europe this winter. Tickets go fast, so grab yours early.</p>
</header>
<ul class="td-list">
<li class="td-row" data-anim="item" data-status="Sold out">
<div class="td-date" aria-hidden="false"><span class="td-month">NOV</span><strong class="td-day">14</strong></div>
<div class="td-where"><strong class="td-city">Lisbon, PT</strong><span class="td-venue">LX Factory</span></div>
<span class="td-status" data-status="Sold out">Sold out</span>
<a class="td-btn" href="#"><span>Sold out</span></a>
</li>
<li class="td-row" data-anim="item" data-status="Few left">
<div class="td-date" aria-hidden="false"><span class="td-month">NOV</span><strong class="td-day">16</strong></div>
<div class="td-where"><strong class="td-city">Madrid, ES</strong><span class="td-venue">Sala Mon</span></div>
<span class="td-status" data-status="Few left">Few left</span>
<a class="td-btn" href="#"><span>Get tickets</span></a>
</li>
<li class="td-row" data-anim="item" data-status="Tickets">
<div class="td-date" aria-hidden="false"><span class="td-month">NOV</span><strong class="td-day">19</strong></div>
<div class="td-where"><strong class="td-city">Barcelona, ES</strong><span class="td-venue">Razzmatazz 2</span></div>
<span class="td-status" data-status="Tickets">Tickets</span>
<a class="td-btn" href="#"><span>Get tickets</span></a>
</li>
<li class="td-row" data-anim="item" data-status="Tickets">
<div class="td-date" aria-hidden="false"><span class="td-month">NOV</span><strong class="td-day">22</strong></div>
<div class="td-where"><strong class="td-city">Paris, FR</strong><span class="td-venue">La Maroquinerie</span></div>
<span class="td-status" data-status="Tickets">Tickets</span>
<a class="td-btn" href="#"><span>Get tickets</span></a>
</li>
<li class="td-row" data-anim="item" data-status="Tickets">
<div class="td-date" aria-hidden="false"><span class="td-month">NOV</span><strong class="td-day">27</strong></div>
<div class="td-where"><strong class="td-city">Berlin, DE</strong><span class="td-venue">Lido</span></div>
<span class="td-status" data-status="Tickets">Tickets</span>
<a class="td-btn" href="#"><span>Get tickets</span></a>
</li>
<li class="td-row" data-anim="item" data-status="Free">
<div class="td-date" aria-hidden="false"><span class="td-month">DEC</span><strong class="td-day">03</strong></div>
<div class="td-where"><strong class="td-city">London, UK</strong><span class="td-venue">Electric Ballroom</span></div>
<span class="td-status" data-status="Free">Free</span>
<a class="td-btn" href="#"><span>RSVP free</span></a>
</li>
</ul>
<div class="td-foot">
<p class="td-note">Doors open one hour before the show. Under-16s must be with an adult. Not seeing your city? Ask us to play there.</p>
<a class="st-btn st-btn--ghost td-cta" href="#contact"><span>Request a show in your city</span></a>
</div>
</div>
</section>
<section id="music" class="st st-discography" data-uid="smvrrymlleoi1">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">Discography</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Albums, EPs <span class="hl">and singles</span></h2>
<p class="st-lead" data-anim="item">Everything we have released so far, newest first. Pick a type or tap any cover to listen.</p>
</header>
<div class="dg-chips" data-chips-bar role="group" aria-label="Filter releases" hidden data-all="All"></div>
<ul class="dg-grid" data-chips>
<li class="dg-item" data-anim="item" data-tag="Album">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-1.jpg" alt="Album cover with a pink sun rising over dark water"></span>
<span class="dg-meta"><span class="dg-type">Album</span><strong class="dg-title">Static Hearts</strong><span class="dg-sub"><span>2026</span><span class="dg-info">11 tracks</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
<li class="dg-item" data-anim="item" data-tag="Single">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-2.jpg" alt="Single cover with a glowing cyan circle on black"></span>
<span class="dg-meta"><span class="dg-type">Single</span><strong class="dg-title">Lights Out in Lisbon</strong><span class="dg-sub"><span>2026</span><span class="dg-info">3:42</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
<li class="dg-item" data-anim="item" data-tag="EP">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-3.jpg" alt="EP cover with overlapping violet and orange waves"></span>
<span class="dg-meta"><span class="dg-type">EP</span><strong class="dg-title">Night Tram</strong><span class="dg-sub"><span>2025</span><span class="dg-info">5 tracks</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
<li class="dg-item" data-anim="item" data-tag="Album">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-4.jpg" alt="Album cover with a grid of golden dots on deep blue"></span>
<span class="dg-meta"><span class="dg-type">Album</span><strong class="dg-title">Paper Skies</strong><span class="dg-sub"><span>2024</span><span class="dg-info">10 tracks</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
<li class="dg-item" data-anim="item" data-tag="Live">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-5.jpg" alt="Live album cover with stage lights above a crowd silhouette"></span>
<span class="dg-meta"><span class="dg-type">Live</span><strong class="dg-title">Live at Coliseu</strong><span class="dg-sub"><span>2023</span><span class="dg-info">14 tracks</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
<li class="dg-item" data-anim="item" data-tag="Single">
<a class="dg-link" href="#">
<span class="dg-art"><span class="dg-disc" aria-hidden="true"></span><img class="dg-cover" width="1000" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-3.jpg" alt="Single cover with overlapping violet and orange waves"></span>
<span class="dg-meta"><span class="dg-type">Single</span><strong class="dg-title">Slow Fire</strong><span class="dg-sub"><span>2023</span><span class="dg-info">3:18</span></span><span class="dg-go">Listen</span></span>
</a>
</li>
</ul>
</div>
</section>
<section id="videos" class="st st-video-section" data-uid="smvrrymll97nc">
<div class="st-wrap">
<header class="st-head">
<p class="st-eyebrow" data-anim="item">Live session</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Lights Out in Lisbon, <span class="hl">live in the church</span></h2>
<p class="st-lead" data-anim="item">Recorded in one take with the whole band in the converted church where the album was made.</p>
</header>
<div class="vs-box" data-anim="media" data-video-box data-title="Velvet Static: Lights Out in Lisbon (live session)">
<img class="vs-poster" width="1280" height="720" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-crowd.jpg" alt="A crowd with hands in the air in front of coloured stage lights">
<a class="vs-play" target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=aqz-KE-bpKQ" data-video="https://www.youtube.com/watch?v=aqz-KE-bpKQ" aria-label="Play the live session">
<span class="vs-btn" aria-hidden="true"><svg viewBox="0 0 24 24" width="30" height="30" fill="currentColor"><path d="M8 5.5v13a1 1 0 0 0 1.5.86l10.5-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z"/></svg></span>
<span class="vs-meta"><span class="vs-label">Play the live session</span><span class="vs-dur">4:12</span></span>
</a>
</div>
<ul class="vs-points">
<li class="vs-point" data-anim="item">
<h3 class="vs-point-title">One take</h3>
<p class="vs-point-text">No overdubs and no click track, just five people in a room.</p>
</li>
<li class="vs-point" data-anim="item">
<h3 class="vs-point-title">Shot on film</h3>
<p class="vs-point-text">Filmed on 16mm by Marta Leal in a single afternoon.</p>
</li>
<li class="vs-point" data-anim="item">
<h3 class="vs-point-title">Full album live</h3>
<p class="vs-point-text">Watch all eleven songs from Static Hearts on our channel.</p>
</li>
</ul>
</div>
</section>
<section id="gallery" class="st st-gallery-grid" data-uid="smvrrymllcd7z">
<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>On stage <span class="hl">and in the studio</span></h2>
<p class="st-lead" data-anim="item">Shows, rehearsals and the church where we recorded the album. Pick a category or tap a 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="Live">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-music.jpg" alt="The singer at the microphone under cyan and pink stage lights">
<p class="gg-cap"><strong class="gg-title">Coliseu dos Recreios</strong><span class="gg-text">The last night of the Paper Skies tour</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Crowd">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-crowd.jpg" alt="A crowd with hands raised in front of coloured lights">
<p class="gg-cap"><strong class="gg-title">Lisbon, sold out</strong><span class="gg-text">Two thousand voices on the last chorus</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Band">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-band.jpg" alt="The four band members as silhouettes against a glowing backdrop">
<p class="gg-cap"><strong class="gg-title">The band</strong><span class="gg-text">Before the sound check in Madrid</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Studio">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-studio.jpg" alt="A mixing desk with glowing faders under a warm lamp">
<p class="gg-cap"><strong class="gg-title">The church studio</strong><span class="gg-text">Where Static Hearts was recorded to tape</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Live">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/tpl-event.jpg" alt="A stage lit by spotlights in front of an audience">
<p class="gg-cap"><strong class="gg-title">Festival main stage</strong><span class="gg-text">Sunset set, Vilar de Mouros</span></p>
</li>
<li class="gg-item" data-anim="item" data-tag="Crowd">
<img class="gg-img" width="1200" height="900" loading="lazy" src="https://webdevpuneet.com/images/section-templates/wed-party.jpg" alt="String lights over a dance floor at night">
<p class="gg-cap"><strong class="gg-title">After the show</strong><span class="gg-text">Meeting fans at the merch table</span></p>
</li>
</ul>
</div>
</section>
<section id="customers" class="st st-testimonials-carousel" data-uid="smvrrymllo35y">
<div class="st-wrap">
<div class="tc-top">
<header class="st-head st-head--left tc-head">
<p class="st-eyebrow" data-anim="item">In the press</p>
<h2 class="st-h2" data-anim="item" data-anim-text>What they are <span class="hl">saying</span></h2>
<p class="st-lead" data-anim="item">Reviews of Static Hearts and the live show.</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>Big drums, shimmering synths and choruses you will be humming all week. Static Hearts is the best dream-pop record of the year.</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="Portrait of a reviewer">
<div><p class="st-person-name">The Wire Report</p><p class="st-person-role">Album review, 5 stars</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>Seeing Velvet Static live is a reminder of why we go to gigs. Two thousand people sang every word.</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-5.jpg" alt="Portrait of a writer">
<div><p class="st-person-name">Lisbon Nights</p><p class="st-person-role">Live review</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>A band that sounds enormous and intimate at the same time. One to watch.</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="Portrait of a critic">
<div><p class="st-person-name">Indie Radar</p><p class="st-person-role">Artists to watch 2027</p></div>
</div></figcaption>
</figure>
</div>
</div>
</section>
<section id="merch" class="st st-product-grid" data-uid="smvrrymll6nlx">
<div class="st-wrap">
<div class="pg-top">
<header class="st-head st-head--left pg-head">
<p class="st-eyebrow" data-anim="item">Merch</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Take <span class="hl">the music home</span></h2>
</header>
<a class="pg-all" data-anim="item" href="#merch"><span>See everything</span> <span aria-hidden="true">→</span></a>
</div>
<ul class="pg-grid">
<li class="pg-card" data-anim="item">
<a class="pg-media" tabindex="-1" aria-hidden="true" href="#">
<img class="pg-img" width="800" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-1.jpg" alt="Static Hearts on vinyl">
<span class="pg-badge">New</span>
</a>
<div class="pg-body">
<h3 class="pg-name"><a href="#"><span>Static Hearts, vinyl LP</span></a></h3>
<p class="pg-text">180 g, gatefold, with a download code</p>
<p class="pg-rating"><span aria-hidden="true">★</span> <span>5.0</span><span class="pg-reviews">(<span>112</span>)</span></p>
<p class="pg-price"><strong>€28</strong></p>
<a class="st-btn pg-btn" href="#"><span>Add to cart</span></a>
</div>
</li>
<li class="pg-card" data-anim="item">
<a class="pg-media" tabindex="-1" aria-hidden="true" href="#">
<img class="pg-img" width="800" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-3.jpg" alt="Night Tram cassette">
</a>
<div class="pg-body">
<h3 class="pg-name"><a href="#"><span>Night Tram, cassette</span></a></h3>
<p class="pg-text">Limited run of 300, numbered</p>
<p class="pg-rating"><span aria-hidden="true">★</span> <span>4.9</span><span class="pg-reviews">(<span>41</span>)</span></p>
<p class="pg-price"><strong>€12</strong></p>
<a class="st-btn pg-btn" href="#"><span>Add to cart</span></a>
</div>
</li>
<li class="pg-card" data-anim="item">
<a class="pg-media" tabindex="-1" aria-hidden="true" href="#">
<img class="pg-img" width="800" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-5.jpg" alt="Tour poster with stage lights">
<span class="pg-badge">Tour</span>
</a>
<div class="pg-body">
<h3 class="pg-name"><a href="#"><span>Static Hearts tour poster</span></a></h3>
<p class="pg-text">A2 print, signed by the band</p>
<p class="pg-rating"><span aria-hidden="true">★</span> <span>4.8</span><span class="pg-reviews">(<span>58</span>)</span></p>
<p class="pg-price"><strong>€15</strong></p>
<a class="st-btn pg-btn" href="#"><span>Add to cart</span></a>
</div>
</li>
<li class="pg-card" data-anim="item">
<a class="pg-media" tabindex="-1" aria-hidden="true" href="#">
<img class="pg-img" width="800" height="1000" loading="lazy" src="https://webdevpuneet.com/images/section-templates/mus-cover-4.jpg" alt="Paper Skies compact disc">
</a>
<div class="pg-body">
<h3 class="pg-name"><a href="#"><span>Paper Skies, signed CD</span></a></h3>
<p class="pg-text">Digipak with a 12-page booklet</p>
<p class="pg-rating"><span aria-hidden="true">★</span> <span>4.9</span><span class="pg-reviews">(<span>73</span>)</span></p>
<p class="pg-price"><strong>€14</strong><s class="pg-old">€18</s></p>
<a class="st-btn pg-btn" href="#"><span>Add to cart</span></a>
</div>
</li>
</ul>
</div>
</section>
<section id="contact" class="st st-booking-form" data-uid="smvrrymllrido">
<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">Get in touch</p>
<h2 class="st-h2" data-anim="item" data-anim-text>Bookings, <span class="hl">press and licensing</span></h2>
<p class="st-lead" data-anim="item">Tell us what you have in mind: a show, an interview or a song for your film. Our manager replies within two working days.</p>
</header>
<div class="bk-block" data-anim="item">
<h3 class="bk-sub">Contacts</h3>
<dl class="bk-hours">
<div class="bk-row"><dt>Bookings</dt><dd>bookings@velvetstatic.example</dd></div>
<div class="bk-row"><dt>Press</dt><dd>press@velvetstatic.example</dd></div>
<div class="bk-row"><dt>Licensing</dt><dd>sync@velvetstatic.example</dd></div>
</dl>
</div>
<div class="bk-block" data-anim="item">
<h3 class="bk-sub">Good to know</h3>
<ul class="st-checks"><li>Festival and club bookings go through our agent</li><li>Press kit with photos and logos is free to download</li><li>We license songs for film, TV and advertising</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>What is this about?</span><select name="service" required>
<option value="Booking a show">Booking a show</option>
<option value="Press and interviews">Press and interviews</option>
<option value="Licensing a song">Licensing a song</option>
<option value="Something else">Something else</option>
</select></label>
<div class="st-form-row">
<label class="st-field"><span>Date (if it is for a show)</span><input name="date" type="date" required data-booking-date></label>
<label class="st-field"><span>Best time to reach you</span><select name="time" required>
<option value="Morning">Morning</option>
<option value="Afternoon">Afternoon</option>
<option value="Evening">Evening</option>
</select></label>
</div>
<label class="st-field"><span>Tell us more</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>Send the message</span></button>
<p class="st-form-note">We reply within two working days.</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>Message received</h3>
<p>Thank you. Our manager will be in touch shortly.</p>
</div>
</form>
</div>
</div>
</section>
<section id="get-started" class="st st-cta-newsletter" data-uid="smvrrymllw7ke">
<div class="st-wrap">
<div class="cn" data-anim="media">
<span class="st-icon cn-icon" data-anim="item"><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>
<h2 class="st-h2 cn-title" data-anim="item" data-anim-text>Be first to <span class="hl">hear what is next</span></h2>
<p class="st-lead cn-lead" data-anim="item">New songs, tour dates and presales a day before everyone else, once or twice a month.</p>
<form class="cn-form" data-anim="item" method="post" action="https://webdevpuneet.com/subscribe">
<input class="cn-input" type="email" required autocomplete="email" name="email" placeholder="you@example.com" aria-label="you@example.com">
<button class="st-btn cn-btn" type="submit"><span>Sign me up</span></button>
</form>
<p class="cn-meta" data-anim="item"><span class="cn-proof">Join 24,000 fans</span><span class="cn-note">No spam. Unsubscribe any time.</span></p>
</div>
</div>
</section>
<section class="st st-footer-minimal" data-uid="smvrrymlljzy0">
<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="M3 14h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-7a9 9 0 0 1 18 0v7a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3" /></svg></span><span>Velvet Static</span></span>
</a>
<nav aria-label="Footer"><ul class="fm-links"><li><a href="#music">Music</a></li><li><a href="#tour">Tour</a></li><li><a href="#videos">Videos</a></li><li><a href="#merch">Merch</a></li><li><a href="#contact">Contact</a></li></ul></nav>
<div><ul class="st-socials">
<li><a class="st-social" href="https://www.instagram.com/" aria-label="Instagram"><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"><rect width="20" height="20" x="2" y="2" rx="5" ry="5" /><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" /><line x1="17.5" x2="17.51" y1="6.5" y2="6.5" /></svg></span></a></li>
<li><a class="st-social" href="https://www.youtube.com/" aria-label="YouTube"><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="M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17" /><path d="m10 15 5-3-5-3z" /></svg></span></a></li>
<li><a class="st-social" href="https://www.facebook.com/" aria-label="Facebook"><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="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" /></svg></span></a></li>
<li><a class="st-social" href="https://x.com/" aria-label="X"><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>
</ul></div>
</div>
<p class="fm-copy">© 2026 Velvet Static</p>
</footer>
</section>@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600;700;800;900&display=swap');
body{margin:0;background:#07090f}
html{scroll-behavior:smooth}section[id]{scroll-margin-top:84px}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
.st{--st-brand:#22d3ee;--st-btn-text:#04121a;--st-bg:#07090f;--st-surface:#111522;--st-text:#f4f7fb;--st-muted:#a3adc2;--st-radius:14;--st-max:1200;--st-font-heading:"Space Grotesk", sans-serif;--st-font-body:"Inter", 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}}
/* Floating Pill Navbar */
.st-navbar-floating{overflow:visible;background:transparent;padding:14px 0}
.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}
.nf{position:relative;display:flex;align-items:center;gap:24px;max-width:1040px;margin:0 auto;padding:8px 8px 8px 18px;border-radius:999px;background:color-mix(in srgb,var(--st-surface) 82%,transparent);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border:1px solid color-mix(in srgb,var(--st-text) 12%,transparent);box-shadow:0 20px 50px -24px rgba(0,0,0,.6)}
.nf .st-brand{color:var(--st-text)}
.nf .st-brand-mark{font-size:19px}
.nf .st-brand-icon{width:30px;height:30px}
.nf-nav{flex:1;display:flex;align-items:center;justify-content:space-between;gap:16px}
.nf-links{list-style:none;display:flex;gap:2px;margin:0 auto}
.nf-link{display:block;padding:9px 16px;border-radius:999px;color:var(--st-muted);font-weight:600;font-size:15px;text-decoration:none;transition:color .2s ease,background .2s ease}
.nf-link:hover{color:var(--st-text);background:color-mix(in srgb,var(--st-text) 9%,transparent)}
.nf-link[aria-current="page"]{color:var(--st-brand);background:color-mix(in srgb,var(--st-brand) 13%,transparent)}
.nf .nf-cta{min-height:44px;padding:0 22px;border-radius:999px;font-size:15px}
.nf .st-burger{color:var(--st-text);background:color-mix(in srgb,var(--st-text) 10%,transparent);border-radius:999px}
@container st (max-width:860px){
.nf .st-burger{display:inline-block;margin-left:auto;position:relative;z-index:2}
.nf .st-brand{position:relative;z-index:2}
.nf-nav{position:fixed;inset:0;z-index:1;flex-direction:column;justify-content:center;align-items:flex-start;gap:28px;padding:96px var(--st-pad) 48px;background:color-mix(in srgb,var(--st-surface) 97%,transparent);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}
.nf-links{flex-direction:column;align-items:flex-start;gap:6px;margin:0}
.nf-link{padding:6px 0;font:800 clamp(30px,8cqi,44px)/1.15 var(--st-font-heading);letter-spacing:-.03em;color:var(--st-text);background:none!important}
.nf-link:hover{color:var(--st-brand)}
.nf .nf-cta{min-height:54px;padding:0 30px;font-size:17px}
.has-menu:not(.menu-open) .nf-nav{display:none}
.menu-open .nf{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--st-surface)}
.st:not(.has-menu) .nf{flex-wrap:wrap;border-radius:calc(var(--st-radius) * 1.4px)}
.st:not(.has-menu) .nf-nav{position:static;flex-basis:100%;padding:8px;background:none}
.st:not(.has-menu) .nf-link{font-size:18px}
.st:not(.has-menu) .st-burger{display:none}
}
/* Music Artist Hero */
.st-music-hero{min-height:min(92vh,820px);display:flex;align-items:stretch;background:var(--st-bg);overflow:hidden}
.mh-bg{position:absolute;inset:0;background-size:cover;background-position:center}
.mh-shade{position:absolute;inset:0;background:linear-gradient(90deg,color-mix(in srgb,var(--st-bg) 92%,transparent) 0%,color-mix(in srgb,var(--st-bg) 60%,transparent) 55%,color-mix(in srgb,var(--st-bg) 20%,transparent) 100%),linear-gradient(0deg,var(--st-bg),transparent 55%)}
.mh{position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-end;gap:22px;padding-top:clamp(96px,12cqi,160px);padding-bottom:clamp(64px,9cqi,120px)}
.mh-pill{display:inline-flex;align-items:center;gap:10px;padding:7px 16px 7px 12px;border-radius:999px;border:1px solid color-mix(in srgb,var(--st-brand) 55%,transparent);background:color-mix(in srgb,var(--st-bg) 55%,transparent);backdrop-filter:blur(8px);font-size:13.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--st-brand)}
.mh-dot{width:8px;height:8px;border-radius:50%;background:var(--st-brand);box-shadow:0 0 0 0 color-mix(in srgb,var(--st-brand) 70%,transparent);animation:mh-pulse 2s infinite}
@keyframes mh-pulse{70%{box-shadow:0 0 0 10px transparent}100%{box-shadow:0 0 0 0 transparent}}
.mh-name{font-size:clamp(64px,11cqi + 8px,168px);line-height:.88;letter-spacing:-.03em;text-transform:uppercase}
.mh-tag{color:var(--st-muted);max-width:30em}
.mh-ghost{color:var(--st-text);border-color:color-mix(in srgb,var(--st-text) 50%,transparent);backdrop-filter:blur(6px)}
.mh-links{list-style:none;display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:8px}
.mh-link{font-size:14.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--st-muted);text-decoration:none;border-bottom:2px solid transparent;padding-bottom:2px;transition:color .2s,border-color .2s}
.mh-link:hover,.mh-link:focus-visible{color:var(--st-brand);border-color:var(--st-brand);outline:none}
.mh-eq{position:absolute;left:0;right:0;bottom:0;height:clamp(40px,6cqi,72px);display:flex;align-items:flex-end;gap:clamp(3px,.6cqi,8px);padding:0 clamp(12px,2cqi,28px);opacity:.55;pointer-events:none}
.mh-eq i{flex:1;height:100%;border-radius:3px 3px 0 0;background:linear-gradient(0deg,var(--st-brand),transparent);transform-origin:50% 100%;animation:mh-eq 1.6s ease-in-out infinite}
.mh-eq i:nth-child(3n+1){animation-duration:1.2s;animation-delay:-.3s}
.mh-eq i:nth-child(3n+2){animation-duration:1.9s;animation-delay:-.9s}
.mh-eq i:nth-child(5n){animation-duration:1.4s;animation-delay:-.6s}
@keyframes mh-eq{0%,100%{transform:scaleY(.18)}50%{transform:scaleY(1)}}
@media (prefers-reduced-motion:reduce){.mh-eq i{animation:none;transform:scaleY(.4)}.mh-dot{animation:none}}
@container st (max-width:640px){.mh-shade{background:linear-gradient(0deg,var(--st-bg) 8%,color-mix(in srgb,var(--st-bg) 55%,transparent))}}
/* New Release Spotlight */
.st-release-spotlight{padding:clamp(64px,8cqi,120px) 0;background:radial-gradient(ellipse 60% 70% at 25% 50%,color-mix(in srgb,var(--st-brand) 16%,var(--st-bg)),var(--st-bg) 70%)}
.rs{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);align-items:center;gap:clamp(32px,6cqi,96px)}
.rs-art{position:relative;aspect-ratio:1;margin-right:26%}
.rs-cover{position:relative;z-index:2;width:100%;height:100%;object-fit:cover;border-radius:6px;background:var(--st-surface);box-shadow:0 40px 80px -30px rgba(0,0,0,.8),0 0 0 1px color-mix(in srgb,var(--st-text) 8%,transparent)}
.rs-disc{position:absolute;z-index:1;top:3%;left:32%;width:94%;aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,var(--st-brand) 0 10%,#0b0b10 10.5% 18%,transparent 18.5%),repeating-radial-gradient(circle,#232634 0 2px,#10121a 2px 4px);box-shadow:0 20px 50px -20px rgba(0,0,0,.9),0 0 0 2px color-mix(in srgb,var(--st-brand) 28%,transparent);animation:rs-spin 9s linear infinite}
@keyframes rs-spin{to{transform:rotate(360deg)}}
.rs-copy{display:flex;flex-direction:column;align-items:flex-start;gap:18px}
.rs-title{font-size:clamp(44px,5.4cqi + 10px,88px);line-height:.95;letter-spacing:-.02em;text-transform:uppercase}
.rs-text{color:var(--st-muted);max-width:32em}
.rs-count{display:flex;gap:clamp(8px,1.4cqi,16px)}
.rs-cell{min-width:clamp(62px,7cqi,88px);display:flex;flex-direction:column;align-items:center;gap:2px;padding:12px 8px;border-radius:14px;background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 10%,transparent)}
.rs-cell b{font:700 clamp(26px,2.6cqi + 10px,40px)/1 var(--st-font-heading);font-variant-numeric:tabular-nums;color:var(--st-brand)}
.rs-cell span{font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--st-muted)}
.rs-out{font:700 clamp(20px,1cqi + 14px,28px)/1.2 var(--st-font-heading);color:var(--st-brand)}
.rs-tracks{list-style:none;counter-reset:t;columns:2;column-gap:32px;color:var(--st-muted);font-size:15.5px;max-width:34em}
.rs-tracks:empty{display:none}
.rs-tracks li{counter-increment:t;break-inside:avoid;padding:3px 0}
.rs-tracks li::before{content:counter(t,decimal-leading-zero);margin-right:12px;font-weight:700;font-size:12.5px;letter-spacing:.06em;color:var(--st-brand)}
.rs-ghost{color:var(--st-text);border-color:color-mix(in srgb,var(--st-text) 40%,transparent)}
@media (prefers-reduced-motion:reduce){.rs-disc{animation:none}}
@container st (max-width:820px){.rs{grid-template-columns:1fr}.rs-art{max-width:360px;width:100%;margin:0 auto 14%}.rs-copy{align-items:center;text-align:center}.rs-tracks{text-align:left}}
@container st (max-width:520px){.rs-tracks{columns:1}}
/* Audio Player & Track List */
.st-audio-player{padding:clamp(56px,7cqi,104px) 0}
.ap{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(18px,2.6cqi,36px);align-items:start}
.ap-now{position:relative;display:flex;flex-direction:column;gap:16px;padding:clamp(18px,2.2cqi,28px);border-radius:calc(var(--st-radius) * 1.2px);background:linear-gradient(160deg,color-mix(in srgb,var(--st-brand) 14%,var(--st-surface)),var(--st-surface));border:1px solid color-mix(in srgb,var(--st-text) 10%,transparent)}
.ap-art{aspect-ratio:1;max-width:340px;margin:0 auto;width:100%}
.ap-cover{width:100%;height:100%;object-fit:cover;border-radius:calc(var(--st-radius) * .7px);background:color-mix(in srgb,var(--st-text) 8%,transparent);box-shadow:0 24px 50px -24px rgba(0,0,0,.8)}
.ap-info{display:flex;flex-direction:column;gap:3px}
.ap-tag{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--st-brand)}
.ap-title{font:700 clamp(20px,1cqi + 15px,28px)/1.2 var(--st-font-heading)}
.ap-meta{color:var(--st-muted);font-size:15px}
.ap-bar{display:flex;align-items:center;gap:12px}
.ap-t{font-size:13px;font-variant-numeric:tabular-nums;color:var(--st-muted);min-width:2.6em}
.ap-seek{--p:0%;flex:1;height:22px;margin:0;background:transparent;-webkit-appearance:none;appearance:none;cursor:pointer}
.ap-seek::-webkit-slider-runnable-track{height:5px;border-radius:5px;background:linear-gradient(90deg,var(--st-brand) var(--p),color-mix(in srgb,var(--st-text) 18%,transparent) var(--p))}
.ap-seek::-moz-range-track{height:5px;border-radius:5px;background:color-mix(in srgb,var(--st-text) 18%,transparent)}
.ap-seek::-moz-range-progress{height:5px;border-radius:5px;background:var(--st-brand)}
.ap-seek::-webkit-slider-thumb{-webkit-appearance:none;width:15px;height:15px;margin-top:-5px;border-radius:50%;border:0;background:var(--st-text);box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 30%,transparent)}
.ap-seek::-moz-range-thumb{width:15px;height:15px;border-radius:50%;border:0;background:var(--st-text)}
.ap-seek:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 50%,transparent);outline-offset:3px;border-radius:6px}
.ap-ctl{display:flex;align-items:center;justify-content:center;gap:18px}
.ap-btn{display:grid;place-items:center;width:46px;height:46px;border-radius:50%;border:1px solid color-mix(in srgb,var(--st-text) 18%,transparent);background:transparent;color:var(--st-text);cursor:pointer;transition:background .2s,color .2s,transform .2s}
.ap-btn:hover{background:color-mix(in srgb,var(--st-text) 10%,transparent)}
.ap-btn:focus-visible{outline:3px solid var(--st-brand);outline-offset:3px}
.ap-play{width:62px;height:62px;border:0;background:var(--st-brand);color:var(--st-btn-text)}
.ap-play:hover{background:var(--st-brand);transform:scale(1.06)}
.ap-i-pause{display:none}
.ap.is-playing .ap-i-play{display:none}.ap.is-playing .ap-i-pause{display:block}
.ap-msg{min-height:1.4em;text-align:center;font-size:13.5px;color:var(--st-muted)}
.ap-list{list-style:none;display:flex;flex-direction:column;gap:6px;counter-reset:n}
.ap-track{display:flex;align-items:center;gap:8px;border-radius:calc(var(--st-radius) * .7px);border:1px solid transparent;transition:background .2s,border-color .2s}
.ap-track:hover{background:color-mix(in srgb,var(--st-text) 5%,transparent)}
.ap-track.is-current{background:color-mix(in srgb,var(--st-brand) 12%,transparent);border-color:color-mix(in srgb,var(--st-brand) 45%,transparent)}
.ap-row{flex:1;min-width:0;display:flex;align-items:center;gap:14px;padding:10px 12px;border:0;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer;border-radius:inherit}
.ap-row:focus-visible{outline:3px solid var(--st-brand);outline-offset:-3px}
.ap-n{counter-increment:n;width:1.6em;text-align:center;font-size:14px;font-weight:700;color:var(--st-muted)}
.ap-n::before{content:counter(n)}
.ap-thumb{width:52px;height:52px;border-radius:calc(var(--st-radius) * .35px);object-fit:cover;flex:none;background:color-mix(in srgb,var(--st-text) 8%,transparent)}
.ap-names{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.ap-name{font-size:16.5px;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ap-by{color:var(--st-muted);font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ap-len{font-size:13.5px;font-variant-numeric:tabular-nums;color:var(--st-muted)}
.ap-eq{display:none;align-items:flex-end;gap:2px;height:16px}
.ap-eq i{width:3px;height:100%;background:var(--st-brand);border-radius:2px;transform-origin:50% 100%;animation:ap-eq 1s ease-in-out infinite}
.ap-eq i:nth-child(2){animation-delay:-.3s}.ap-eq i:nth-child(3){animation-delay:-.6s}
@keyframes ap-eq{0%,100%{transform:scaleY(.25)}50%{transform:scaleY(1)}}
.ap-track.is-current.is-playing .ap-eq{display:flex}
.ap-track.is-current.is-playing .ap-n{visibility:hidden}
.ap-link{flex:none;margin-right:12px;font-size:13.5px;font-weight:700;color:var(--st-brand);text-decoration:none;border-bottom:2px solid transparent}
.ap-link:hover,.ap-link:focus-visible{border-color:var(--st-brand);outline:none}
@media (prefers-reduced-motion:reduce){.ap-eq i{animation:none;transform:scaleY(.6)}}
@container st (max-width:820px){.ap{grid-template-columns:1fr}.ap-art{max-width:260px}}
@container st (max-width:480px){.ap-thumb{display:none}}
/* Tour Dates & Tickets */
.st-tour-dates{padding:clamp(56px,7cqi,104px) 0}
.td-list{list-style:none;display:flex;flex-direction:column;border-top:1px solid color-mix(in srgb,var(--st-text) 12%,transparent)}
.td-row{display:grid;grid-template-columns:92px minmax(0,1fr) auto auto;align-items:center;gap:clamp(14px,2.4cqi,32px);padding:clamp(16px,2cqi,24px) clamp(4px,1cqi,16px);border-bottom:1px solid color-mix(in srgb,var(--st-text) 12%,transparent);transition:background .25s ease,padding .25s ease}
.td-row:hover{background:color-mix(in srgb,var(--st-brand) 7%,transparent)}
.td-date{display:flex;flex-direction:column;align-items:center;line-height:1;gap:4px;padding:10px 0;border-radius:calc(var(--st-radius) * .8px);background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 10%,transparent)}
.td-month{font-size:12px;font-weight:800;letter-spacing:.14em;color:var(--st-brand)}
.td-day{font:700 34px/1 var(--st-font-heading)}
.td-where{display:flex;flex-direction:column;gap:3px;min-width:0}
.td-city{font:700 clamp(19px,.9cqi + 14px,26px)/1.2 var(--st-font-heading)}
.td-venue{color:var(--st-muted);font-size:15.5px}
.td-status{font-size:12.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:6px 12px;border-radius:999px;color:var(--st-muted);border:1px solid color-mix(in srgb,var(--st-text) 18%,transparent);white-space:nowrap}
.td-status[data-status="Few left"]{color:#fbbf24;border-color:color-mix(in srgb,#fbbf24 55%,transparent)}
.td-status[data-status="Free"]{color:#4ade80;border-color:color-mix(in srgb,#4ade80 55%,transparent)}
.td-status[data-status="Sold out"]{color:#f87171;border-color:color-mix(in srgb,#f87171 50%,transparent)}
.td-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 22px;border-radius:999px;background:var(--st-brand);color:var(--st-btn-text);font-weight:700;font-size:15px;text-decoration:none;white-space:nowrap;transition:transform .2s ease,box-shadow .2s ease}
.td-btn:hover,.td-btn:focus-visible{transform:translateY(-2px);box-shadow:0 10px 24px -10px var(--st-brand);outline:none}
.td-row[data-status="Sold out"] .td-where,.td-row[data-status="Sold out"] .td-date{opacity:.55}
.td-row[data-status="Sold out"] .td-btn{background:transparent;color:var(--st-muted);border:1px solid color-mix(in srgb,var(--st-text) 20%,transparent);pointer-events:none}
.td-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px 32px;margin-top:clamp(20px,2.6cqi,32px)}
.td-note{color:var(--st-muted);font-size:15px;max-width:44em}
@container st (max-width:720px){.td-row{grid-template-columns:76px minmax(0,1fr);grid-template-areas:"date where" "status btn"}.td-date{grid-area:date}.td-where{grid-area:where}.td-status{grid-area:status;justify-self:start}.td-btn{grid-area:btn;justify-self:end}}
/* Discography Grid */
.st-discography{padding:clamp(56px,7cqi,104px) 0}
.dg-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-bottom:clamp(24px,3cqi,40px)}
.dg-chips:empty{display:none}
.dg-chip{min-height:40px;padding:0 18px;border:1px solid color-mix(in srgb,var(--st-text) 16%,transparent);border-radius:999px;background:transparent;color:var(--st-text);font:600 14.5px/1 var(--st-font-body);cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.dg-chip:hover{border-color:var(--st-brand);color:var(--st-brand)}
.dg-chip[aria-pressed="true"]{background:var(--st-brand);border-color:var(--st-brand);color:var(--st-btn-text)}
.dg-chip:focus-visible{outline:3px solid color-mix(in srgb,var(--st-brand) 45%,transparent);outline-offset:2px}
.dg-grid{list-style:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,230px),1fr));gap:clamp(22px,3cqi,40px) clamp(16px,2cqi,28px)}
.dg-item[hidden]{display:none}
.dg-link{display:flex;flex-direction:column;gap:16px;color:inherit;text-decoration:none}
.dg-art{position:relative;display:block;aspect-ratio:1;margin-right:14%}
.dg-cover{position:relative;z-index:2;width:100%;height:100%;object-fit:cover;border-radius:calc(var(--st-radius) * .5px);background:var(--st-surface);box-shadow:0 18px 40px -18px rgba(0,0,0,.7);transition:transform .45s cubic-bezier(.2,.8,.2,1)}
.dg-disc{position:absolute;z-index:1;top:3%;left:6%;width:94%;aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,var(--st-brand) 0 9%,#0b0b10 9.5% 17%,transparent 17.5%),repeating-radial-gradient(circle,#232634 0 2px,#10121a 2px 4px);box-shadow:0 12px 28px -12px rgba(0,0,0,.8),0 0 0 2px color-mix(in srgb,var(--st-brand) 25%,transparent);transition:transform .55s cubic-bezier(.2,.8,.2,1)}
.dg-item:hover .dg-disc,.dg-link:focus-visible .dg-disc{transform:translateX(24%) rotate(160deg)}
.dg-item:hover .dg-cover,.dg-link:focus-visible .dg-cover{transform:translateX(-4%)}
.dg-link:focus-visible{outline:3px solid var(--st-brand);outline-offset:6px;border-radius:calc(var(--st-radius) * 1px)}
.dg-meta{display:flex;flex-direction:column;gap:4px}
.dg-type{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--st-brand)}
.dg-title{font:700 clamp(18px,.8cqi + 14px,22px)/1.25 var(--st-font-heading)}
.dg-sub{display:flex;gap:10px;color:var(--st-muted);font-size:14.5px}
.dg-info::before{content:"\00b7";margin-right:10px}
.dg-go{margin-top:6px;font-weight:700;font-size:14.5px;color:var(--st-text);border-bottom:2px solid var(--st-brand);align-self:flex-start;padding-bottom:2px}
@media (hover:none){.dg-disc{transform:translateX(18%)}.dg-cover{transform:translateX(-3%)}}
@media (prefers-reduced-motion:reduce){.dg-disc,.dg-cover{transition:none}}
/* Video Section with Poster */
.st-video-section{padding:clamp(56px,7cqi,104px) 0}
.vs-box{position:relative;overflow:hidden;aspect-ratio:16/9;border-radius:calc(var(--st-radius) * 1.3px);background:#0b1020;box-shadow:0 40px 80px -40px color-mix(in srgb,var(--st-text) 55%,transparent)}
.vs-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .8s cubic-bezier(.2,.8,.2,1)}
.vs-box:hover .vs-poster{transform:scale(1.03)}
.vs-play{position:absolute;inset:0;display:flex;align-items:flex-end;gap:16px;padding:clamp(16px,3cqi,32px);color:#fff;text-decoration:none;background:linear-gradient(to top,rgba(8,10,20,.65),rgba(8,10,20,.05) 55%);cursor:pointer}
.vs-btn{position:absolute;left:50%;top:50%;display:grid;place-items:center;width:clamp(64px,9cqi,92px);height:clamp(64px,9cqi,92px);margin:calc(clamp(64px,9cqi,92px) / -2) 0 0 calc(clamp(64px,9cqi,92px) / -2);border-radius:50%;background:var(--st-brand);color:var(--st-btn-text);box-shadow:0 0 0 0 color-mix(in srgb,var(--st-brand) 55%,transparent);transition:transform .25s ease}
.vs-btn svg{margin-left:4px}
.vs-play:hover .vs-btn{transform:scale(1.08)}
.vs-play:focus-visible{outline:4px solid var(--st-brand);outline-offset:-4px}
.vs-meta{display:flex;align-items:center;gap:10px;font-weight:700;font-size:15px}
.vs-dur{padding:3px 9px;border-radius:999px;background:rgba(255,255,255,.2);font-size:13px;font-variant-numeric:tabular-nums}
.vs-dur:empty{display:none}
.vs-embed{position:absolute;inset:0;width:100%;height:100%;border:0;background:#000}
.vs-box.is-playing .vs-poster,.vs-box.is-playing .vs-play{display:none}
.vs-points{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:clamp(20px,2.6cqi,36px);margin-top:clamp(28px,3.4cqi,48px)}
.vs-point{padding-top:18px;border-top:2px solid color-mix(in srgb,var(--st-brand) 70%,transparent)}
.vs-point-title{margin-bottom:6px;font-size:18px;line-height:1.3;letter-spacing:-.01em}
.vs-point-text{color:var(--st-muted);font-size:15.5px}
@media (prefers-reduced-motion:no-preference){.vs-btn{animation:vs-pulse 2.6s ease-out infinite}}
@keyframes vs-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--st-brand) 55%,transparent)}70%,100%{box-shadow:0 0 0 22px transparent}}
@container st (max-width:560px){.vs-meta{font-size:13.5px}}
/* 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%}}
/* Product Grid */
.st-product-grid{padding:clamp(56px,7cqi,104px) 0}
.pg-top{display:flex;align-items:flex-end;justify-content:space-between;flex-wrap:wrap;gap:16px;margin-bottom:clamp(24px,3cqi,40px)}
.pg-head{margin:0}
.pg-all{color:var(--st-brand);font-weight:700;text-decoration:none;white-space:nowrap}
.pg-all:hover{text-decoration:underline}
.pg-grid{list-style:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(16px,2cqi,28px)}
.pg-card{display:flex;flex-direction:column;overflow:hidden;border-radius:calc(var(--st-radius) * 1.1px);background:var(--st-surface);border:1px solid color-mix(in srgb,var(--st-text) 6%,transparent);transition:transform .3s ease,box-shadow .3s ease}
.pg-card:hover{transform:translateY(-4px);box-shadow:0 24px 44px -28px color-mix(in srgb,var(--st-text) 55%,transparent)}
.pg-media{position:relative;display:block;aspect-ratio:4/5;overflow:hidden;background:color-mix(in srgb,var(--st-brand) 8%,var(--st-surface))}
.pg-img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.pg-card:hover .pg-img{transform:scale(1.05)}
.pg-badge{position:absolute;top:12px;left:12px;padding:5px 11px;border-radius:999px;background:var(--st-text);color:var(--st-bg);font:800 12px/1 var(--st-font-body);letter-spacing:.03em}
.pg-body{display:flex;flex-direction:column;gap:6px;padding:16px 18px 18px;flex:1}
.pg-name{font-size:17px;line-height:1.3;letter-spacing:-.01em}
.pg-name a{color:inherit;text-decoration:none}
.pg-name a:hover{color:var(--st-brand)}
.pg-text{color:var(--st-muted);font-size:14.5px;line-height:1.45}
.pg-rating{display:flex;align-items:center;gap:5px;color:#b45309;font-size:13.5px;font-weight:700}
.pg-reviews{color:var(--st-muted);font-weight:500}
.pg-price{display:flex;align-items:baseline;gap:8px;margin-top:auto;padding-top:6px}
.pg-price strong{font:800 20px/1 var(--st-font-heading);letter-spacing:-.02em}
.pg-old{color:var(--st-muted);font-size:14.5px}
.pg-old:empty{display:none}
.pg-btn{margin-top:8px;min-height:42px;padding:0 16px;font-size:14.5px}
@container st (max-width:1000px){.pg-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@container st (max-width:720px){.pg-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@container st (max-width:420px){.pg-grid{grid-template-columns:1fr}}
/* 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}}
/* Newsletter Signup CTA */
.st-cta-newsletter{padding:clamp(56px,7cqi,104px) 0}
.cn{max-width:760px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:16px;padding:clamp(36px,5cqi,60px) clamp(22px,5cqi,60px);text-align:center;border-radius:calc(var(--st-radius) * 1.4px);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-brand) 50%,transparent)}
.cn-icon{width:56px;height:56px;margin-bottom:6px}
.cn-icon svg{width:28px;height:28px}
.cn .cn-title{font-size:clamp(28px,2.4cqi + 14px,42px)}
.cn-form{display:flex;gap:10px;width:100%;max-width:520px;margin-top:10px;padding:6px;border-radius:calc(var(--st-radius) * 1px + 6px);background:var(--st-bg);border:1px solid color-mix(in srgb,var(--st-text) 12%,transparent)}
.cn-form:focus-within{border-color:var(--st-brand);box-shadow:0 0 0 4px color-mix(in srgb,var(--st-brand) 18%,transparent)}
.cn-input{flex:1;min-width:0;padding:0 14px;border:0;background:none;color:var(--st-text);font:500 16px/1 var(--st-font-body);outline:none}
.cn-input::placeholder{color:color-mix(in srgb,var(--st-muted) 75%,transparent)}
.cn-btn{flex:none}
.cn-meta{display:flex;flex-wrap:wrap;justify-content:center;gap:4px 14px;font-size:14px;color:var(--st-muted)}
.cn-proof{font-weight:700;color:var(--st-text)}
.cn-proof:empty,.cn-note:empty{display:none}
@container st (max-width:520px){.cn-form{flex-direction:column;background:none;border:0;padding:0}.cn-form:focus-within{box-shadow:none}.cn-input{min-height:52px;border-radius:calc(var(--st-radius) * 1px);border:1px solid color-mix(in srgb,var(--st-text) 15%,transparent);background:var(--st-bg)}.cn-btn{width:100%}}
/* 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}}
(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 () {
document.querySelectorAll('.st [data-countdown]').forEach(function (box) {
var at = Date.parse(box.getAttribute('data-at') || '');
if (isNaN(at)) return;
var sec = box.closest('.st'), out = sec.querySelector('[data-out]'), main = sec.querySelector('[data-cta-main]'), cells = {}, timer;
box.querySelectorAll('[data-u]').forEach(function (b) { cells[b.getAttribute('data-u')] = b; });
var pad = function (n) { return n < 10 ? '0' + n : String(n); };
var finish = function () {
box.hidden = true;
if (out) { out.textContent = box.getAttribute('data-out') || ''; out.hidden = !out.textContent; }
var o = box.getAttribute('data-cta-out'), sp = main && main.querySelector('span');
if (sp && o) sp.textContent = o;
};
var tick = function () {
var ms = at - Date.now();
if (ms <= 0) { finish(); clearInterval(timer); return; }
var s = Math.floor(ms / 1000);
cells.d.textContent = pad(Math.floor(s / 86400)); cells.h.textContent = pad(Math.floor(s % 86400 / 3600));
cells.m.textContent = pad(Math.floor(s % 3600 / 60)); cells.s.textContent = pad(s % 60);
};
tick(); timer = setInterval(tick, 1000);
});
})();
(function () {
var current = null;
var fmt = function (s) { if (!isFinite(s) || s < 0) s = 0; var m = Math.floor(s / 60), r = Math.floor(s % 60); return m + ':' + (r < 10 ? '0' : '') + r; };
document.querySelectorAll('.st [data-player]').forEach(function (box) {
var rows = Array.prototype.slice.call(box.querySelectorAll('.ap-track'));
if (!rows.length) return;
var q = function (a) { return box.querySelector('[' + a + ']'); };
var cover = q('data-ap-cover'), title = q('data-ap-title'), meta = q('data-ap-meta'), cur = q('data-ap-cur'), dur = q('data-ap-dur');
var seek = q('data-ap-seek'), play = q('data-ap-play'), prev = q('data-ap-prev'), next = q('data-ap-next'), msg = q('data-ap-msg');
var audio = new Audio();
audio.preload = 'none';
var idx = -1, loaded = -1, tried = false;
var setSeek = function (p) { seek.value = String(Math.round(p * 1000)); seek.style.setProperty('--p', (p * 100) + '%'); };
var mark = function () {
rows.forEach(function (r, i) { r.classList.toggle('is-current', i === idx); r.classList.toggle('is-playing', i === idx && !audio.paused); });
box.classList.toggle('is-playing', !audio.paused);
play.setAttribute('aria-label', audio.paused ? 'Play' : 'Pause');
};
var show = function (i) {
idx = i;
var r = rows[i], img = r.querySelector('.ap-thumb'), by = r.querySelector('.ap-by'), len = r.querySelector('.ap-len');
title.textContent = r.querySelector('.ap-name').textContent;
meta.textContent = by ? by.textContent : '';
if (img && img.getAttribute('src')) { cover.src = img.getAttribute('src'); cover.style.visibility = ''; } else { cover.removeAttribute('src'); cover.style.visibility = 'hidden'; }
cur.textContent = '0:00'; dur.textContent = len && len.textContent ? len.textContent : '0:00'; setSeek(0);
msg.textContent = r.getAttribute('data-src') ? '' : 'No audio file for this track yet. Use its stream link.';
mark();
};
var select = function (i) {
if (i === loaded) return;
audio.pause();
show(i);
var src = rows[i].getAttribute('data-src') || '';
if (src) audio.src = src; else audio.removeAttribute('src');
audio.load();
loaded = i;
};
var playAt = function (i) {
select(i);
if (!rows[i].getAttribute('data-src')) { mark(); return; }
tried = true;
if (current && current !== audio) current.pause();
current = audio;
var p = audio.play();
if (p && p.catch) p.catch(function () { msg.textContent = 'This audio file could not be played.'; mark(); });
};
var go = function (t) { t = Math.max(0, Math.min(rows.length - 1, t)); if (!audio.paused) playAt(t); else select(t); };
rows.forEach(function (r, i) {
r.querySelector('[data-ap-row]').addEventListener('click', function () {
if (i === idx && rows[i].getAttribute('data-src')) { if (audio.paused) playAt(i); else audio.pause(); } else playAt(i);
});
});
play.addEventListener('click', function () { if (idx < 0) select(0); if (audio.paused) playAt(idx); else audio.pause(); });
prev.addEventListener('click', function () { if (audio.currentTime > 3) audio.currentTime = 0; else go(idx - 1); });
next.addEventListener('click', function () { go(idx + 1); });
seek.addEventListener('input', function () { var p = seek.value / 1000; seek.style.setProperty('--p', (p * 100) + '%'); if (isFinite(audio.duration) && audio.duration > 0) audio.currentTime = p * audio.duration; });
audio.addEventListener('play', mark); audio.addEventListener('pause', mark);
audio.addEventListener('timeupdate', function () { cur.textContent = fmt(audio.currentTime); if (isFinite(audio.duration) && audio.duration > 0) setSeek(audio.currentTime / audio.duration); });
audio.addEventListener('loadedmetadata', function () {
dur.textContent = fmt(audio.duration);
var len = rows[idx] && rows[idx].querySelector('.ap-len');
if (len && isFinite(audio.duration)) len.textContent = fmt(audio.duration);
});
audio.addEventListener('ended', function () { if (idx < rows.length - 1) playAt(idx + 1); else { setSeek(0); cur.textContent = '0:00'; mark(); } });
audio.addEventListener('error', function () { if (tried && audio.getAttribute('src')) { msg.textContent = 'This audio file could not be loaded.'; mark(); } });
select(0);
});
})();
(function () {
document.querySelectorAll('.st [data-chips]').forEach(function (grid) {
var bar = grid.parentNode.querySelector('[data-chips-bar]');
if (!bar) return;
var items = Array.prototype.slice.call(grid.children), tags = [];
items.forEach(function (it) { var t = (it.getAttribute('data-tag') || '').trim(); if (t && tags.indexOf(t) < 0) tags.push(t); });
if (tags.length < 2) return;
var all = bar.getAttribute('data-all') || 'All';
bar.textContent = '';
[''].concat(tags).forEach(function (t) {
var b = document.createElement('button');
b.type = 'button'; b.className = 'dg-chip'; b.textContent = t || all; b.setAttribute('aria-pressed', t ? 'false' : 'true');
b.addEventListener('click', function () {
Array.prototype.forEach.call(bar.children, function (c) { c.setAttribute('aria-pressed', c === b ? 'true' : 'false'); });
items.forEach(function (it) { it.hidden = !!t && (it.getAttribute('data-tag') || '').trim() !== t; });
});
bar.appendChild(b);
});
bar.hidden = false;
});
})();
(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 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;
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 () {
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%', 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();
})();