/* ── Site layout & sections ─────────────────────────────────────────────────
   Every rule here is a direct translation of an inline style in the
   Claude Design source (`The Oven Cleaner Website.dc.html`). */

/* ── Layout primitives ──────────────────────────────────────────────────── */
.page{min-height:100vh;display:flex;flex-direction:column;background:var(--snow-50)}
main{flex:1}
.container{max-width:var(--content-max);margin:0 auto}
.container--narrow{max-width:840px;margin:0 auto}

.section{padding:92px 24px}
.section--sm{padding:88px 24px}
.section--page{background:var(--snow-50)}
.section--tint{background:var(--lavender-100)}
.section--dark{background:var(--purple-900)}

.section-head{max-width:760px;margin:0 auto 46px;text-align:center}
.section-head--wide{max-width:740px}
.section-title{font-size:clamp(32px,4.6vw,50px);font-weight:800;margin:0 0 16px;line-height:1.12}
.section-title--sm{font-size:clamp(30px,4.2vw,46px);line-height:1.14;margin:0}
.section-title:last-child{margin-bottom:0}
.section--dark .section-title{color:#fff}
.section-sub{font-size:17px;line-height:1.65;margin:0}
.section--dark .section-sub{color:rgba(255,255,255,.8)}

/* Stars */
.stars{display:inline-flex;gap:3px;flex:none}

/* ── Header ─────────────────────────────────────────────────────────────── */
/* Sits over the top of the hero and scrolls away with it; it does not stick.
   The one time it needs to hold still is while the full-screen mobile menu
   is open, so the burger stays in reach to close it: .is-solid then pins it
   and paints it white over the snow-coloured panel. */
.site-header{
  position:absolute;top:0;left:0;right:0;z-index:60;
  background:transparent;box-shadow:none;
}
.site-header.is-solid{position:fixed;background:#fff;box-shadow:0 6px 22px rgba(101,58,159,.13)}
.header-inner{
  position:relative;z-index:2;
  max-width:var(--content-max);margin:0 auto;padding:18px 24px;
  display:flex;align-items:center;gap:24px;
}
/* The nav leads from the left edge; the phone number and quote button take
   the right. Below 920px both give way to the burger and a quote button. */
.nav-desktop{display:flex;gap:34px;align-items:center}
.nav-mobile-cta{display:none}
.nav-link{
  font-weight:700;font-size:18px;color:var(--purple-900);text-decoration:none;
  transition:color .15s ease-out;
}
.nav-link:hover,.nav-link:focus-visible{color:var(--brand);text-decoration:none}
.nav-link[aria-current="page"]{
  color:var(--brand);text-decoration:underline;text-decoration-color:var(--lemon-400);
  text-decoration-thickness:3px;text-underline-offset:6px;
}

.has-dropdown{position:relative}
.dropdown-toggle{
  display:flex;align-items:center;gap:5px;
  background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--font-body);font-weight:700;font-size:18px;color:var(--purple-900);
  transition:color .15s ease-out;
}
.dropdown-toggle:hover{color:var(--brand)}
.dropdown-toggle svg{transition:transform .18s ease-out}
.has-dropdown.is-open .dropdown-toggle svg{transform:rotate(180deg)}
/* Current section, matching the underline on a current nav link. */
.has-dropdown.is-current .dropdown-toggle{
  color:var(--brand);text-decoration:underline;text-decoration-color:var(--lemon-400);
  text-decoration-thickness:3px;text-underline-offset:6px;
}
.dropdown{position:absolute;top:100%;left:-14px;padding-top:12px;min-width:220px;display:none}
.has-dropdown.is-open .dropdown{display:block}
.dropdown-inner{
  background:#fff;border:1px solid var(--border);border-radius:14px;
  box-shadow:0 12px 28px rgba(101,58,159,.16);padding:8px;
  display:flex;flex-direction:column;
}
.dropdown-inner a{
  padding:10px 14px;border-radius:10px;text-decoration:none;
  font-weight:700;font-size:15px;color:var(--purple-900);
}
.dropdown-inner a:hover{background:var(--lemon-400);color:var(--purple-900);text-decoration:none}

.nav-actions{display:flex;gap:14px;align-items:center;margin-left:auto}
.tel-link{
  display:flex;align-items:center;gap:7px;font-weight:800;font-size:15px;
  color:var(--purple-900);text-decoration:none;transition:color .15s ease-out;
}
.tel-link:hover{color:var(--brand);text-decoration:none}

.nav-burger{
  display:none;margin-left:auto;background:var(--lavender-100);
  border:1px solid var(--border-strong);border-radius:12px;
  width:44px;height:44px;align-items:center;justify-content:center;cursor:pointer;
  transition:background .15s ease-out,border-color .15s ease-out;
}
/* Stays a ghost button while the panel is open; the bars fold into a cross
   and the bar goes solid, which is signal enough. */
/* Three separate bars rather than one icon, so they can fold into a cross. */
.burger-bars{position:relative;display:block;width:22px;height:16px}
.burger-bars span{
  position:absolute;left:0;right:0;height:2.4px;border-radius:2px;
  background:var(--purple-900);
  transition:transform .24s cubic-bezier(.4,0,.2,1),opacity .12s linear,background-color .15s ease-out;
}
.burger-bars span:nth-child(1){top:0}
.burger-bars span:nth-child(2){top:6.8px}
.burger-bars span:nth-child(3){top:13.6px}
.nav-burger[aria-expanded="true"] .burger-bars span:nth-child(1){transform:translateY(6.8px) rotate(45deg)}
.nav-burger[aria-expanded="true"] .burger-bars span:nth-child(2){opacity:0}
.nav-burger[aria-expanded="true"] .burger-bars span:nth-child(3){transform:translateY(-6.8px) rotate(-45deg)}
@media (prefers-reduced-motion:reduce){.burger-bars span{transition:none}}

/* Full-screen panel rather than a strip under the bar. The header sits above
   it (see .header-inner) so the burger stays available to close it. */
.mobile-menu{
  /* z-index is relative to .site-header's stacking context, so 1 still
     covers the page while .header-inner stays on top of the panel. */
  position:fixed;inset:0;z-index:1;overflow-y:auto;
  padding:120px 26px calc(32px + env(safe-area-inset-bottom));
  display:flex;flex-direction:column;justify-content:center;gap:2px;
  background:var(--snow-50);
  animation:toc-menu-in .18s ease-out;
}
.mobile-menu[hidden]{display:none}
/* The badge above the links, on its own row with no rule beneath it. */
.mobile-menu a.mobile-menu__logo{
  align-self:center;padding:0;margin-bottom:22px;border-bottom:0;line-height:0;
}
.mobile-menu__logo img{width:112px;height:112px}
.mobile-menu a{
  padding:17px 8px;font-family:var(--font-display);font-weight:700;font-size:21px;
  text-align:center;text-decoration:none;color:var(--purple-900);
  border-bottom:1px solid var(--border);transition:color .15s ease-out;
}
.mobile-menu a:last-child{border-bottom:0}
.mobile-menu a:hover,.mobile-menu a[aria-current="page"]{color:var(--brand);text-decoration:none}
@keyframes toc-menu-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.mobile-menu{animation:none}}
/* The page behind must not scroll while the panel is open. */
html.menu-open,html.menu-open body{overflow:hidden}

/* ── Header over a dark hero ──────────────────────────────────────────────
   The purple hero runs up under a transparent bar, so the nav reverses to
   white. While the mobile menu is open the bar turns solid white and
   everything returns to purple. */
.site-header--over-dark .nav-link,
.site-header--over-dark .dropdown-toggle,
.site-header--over-dark .tel-link{color:#fff}
.site-header--over-dark .tel-link svg{stroke:#fff}
.site-header--over-dark .burger-bars span{background:#fff}
.site-header--over-dark .nav-burger:not([aria-expanded="true"]){
  background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.42);
}
.site-header--over-dark .nav-link:hover,
.site-header--over-dark .nav-link:focus-visible,
.site-header--over-dark .dropdown-toggle:hover,
.site-header--over-dark .tel-link:hover{color:var(--lemon-400)}
.site-header--over-dark .nav-link[aria-current="page"],
.site-header--over-dark .has-dropdown.is-current .dropdown-toggle{color:#fff}

.site-header--over-dark.is-solid .nav-link,
.site-header--over-dark.is-solid .dropdown-toggle,
.site-header--over-dark.is-solid .tel-link{color:var(--purple-900)}
.site-header--over-dark.is-solid .tel-link svg{stroke:#653A9F}
.site-header--over-dark.is-solid .burger-bars span{background:var(--purple-900)}
.site-header--over-dark.is-solid .nav-burger:not([aria-expanded="true"]){
  background:var(--lavender-100);border-color:var(--border-strong);
}
.site-header--over-dark.is-solid .nav-link:hover,
.site-header--over-dark.is-solid .nav-link:focus-visible,
.site-header--over-dark.is-solid .dropdown-toggle:hover,
.site-header--over-dark.is-solid .tel-link:hover{color:var(--brand)}
.site-header--over-dark.is-solid .nav-link[aria-current="page"],
.site-header--over-dark.is-solid .has-dropdown.is-current .dropdown-toggle{color:var(--brand)}

/* ── Call-to-action links ───────────────────────────────────────────────── */
.btn-call{
  display:inline-flex;align-items:center;gap:10px;
  background:var(--lemon-400);color:var(--purple-900);
  font-weight:800;font-size:18px;padding:16px 30px;
  border-radius:999px;text-decoration:none;
  transition:background .15s ease-out;
}
.btn-call:hover{background:var(--lemon-500);color:var(--purple-900);text-decoration:none}
.btn-call--sm{font-size:17px;padding:15px 28px}
.btn-call--md{font-size:16px;padding:14px 26px}

.btn-outline{
  display:inline-flex;align-items:center;gap:8px;
  border:2px solid rgba(255,255,255,.5);color:#fff;
  font-weight:800;font-size:17px;padding:13px 26px;
  border-radius:999px;text-decoration:none;
  transition:background .15s ease-out;
}
.btn-outline:hover{background:rgba(255,255,255,.12);color:#fff;text-decoration:none}
.hero .btn-outline{border-color:var(--purple-700);color:var(--purple-700)}
.hero .btn-outline:hover{background:rgba(101,58,159,.09);color:var(--purple-700)}

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero{position:relative;background:var(--snow-50)}
/* ── Bubble hero (home and location pages) ────────────────────────────────
   Purple with the same drifting bubbles as the call-to-action band. Alisdair
   sits in a soap bubble of his own and speaks from a speech bubble. */
.hero--bubbles{background:var(--purple-700);overflow:hidden}
.hero.hero--bubbles h1{color:#fff}
.hero--bubbles .hero-rating span:last-child{color:#fff}
.hero--bubbles .btn-outline{border-color:rgba(255,255,255,.55);color:#fff}
.hero--bubbles .btn-outline:hover{background:rgba(255,255,255,.14);color:#fff}

/* Speech bubble. The tail is a clipped square rather than a border trick, so
   it keeps the bubble's exact white and casts no seam. */
.hero-quote{
  position:relative;background:#fff;border-radius:26px;
  padding:26px 30px;margin:0 0 42px;max-width:56ch;
  box-shadow:0 18px 44px rgba(20,6,45,.28);
  transform:rotate(-1.5deg);
}
.hero-quote .hero-lede{margin:0;max-width:none;color:var(--text-body)}
/* Name then role, tight together, before he starts speaking. */
.hero-quote .hero-greeting{margin-bottom:1px}
.hero-quote .hero-brand{margin-bottom:14px}
.hero-quote::after{
  content:"";position:absolute;left:50%;margin-left:-16px;bottom:-15px;
  width:32px;height:17px;background:#fff;
  clip-path:polygon(0 0,100% 0,50% 100%);
}
/* Beside the portrait, the tail turns and points at him. */
@media (min-width:861px){
  .hero-quote::after{
    left:auto;right:-15px;bottom:auto;top:50%;margin:-17px 0 0;
    width:16px;height:34px;
    clip-path:polygon(0 0,100% 50%,0 100%);
  }
}

/* Alisdair in a bubble: a glassy skin over the photograph, with a highlight
   top-left and the purple of the band pooling at the foot. */
.hero--bubbles .hero-portrait{
  width:min(400px,84vw);
  animation:toc-float 14s ease-in-out infinite;
}
@media (min-width:861px){
  .hero--bubbles .hero-portrait{width:min(470px,40vw)}
}
.hero--bubbles .hero-portrait__frame{
  border:0;
  background:#fff;
  box-shadow:0 30px 70px rgba(20,6,45,.45),0 0 0 3px rgba(255,255,255,.4);
}
/* Just the ring. The bubble highlight and shading the other bubbles carry
   would sit on top of the photo and wash it out. */
.hero--bubbles .hero-portrait__frame::after{
  content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.75);
}
/* Purple on purple would vanish, so the badge takes the accent instead. */
/* A bubble of its own, matching the one Alisdair sits in: lit from the same
   direction, with the ring and the highlight doing the work. */
.hero--bubbles .hero-portrait__years{
  width:122px;height:122px;padding:0;border-radius:50%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  color:var(--purple-900);
  background:radial-gradient(circle at 30% 24%,#FFF275 0%,var(--lemon-400) 46%,var(--lemon-500) 100%);
  box-shadow:
    0 16px 34px rgba(20,6,45,.42),
    inset 0 0 0 2px rgba(255,255,255,.55),
    inset 0 12px 24px rgba(255,255,255,.5),
    inset 0 -16px 30px rgba(101,58,159,.16);
  /* Stacked, the portrait is nearly the full width, so the badge tucks inside
     its edge instead of hanging off it and being clipped by the section. */
  right:0;
}
.hero--bubbles .hero-portrait__years-n{font-size:32px}
.hero--bubbles .hero-portrait__years-l{font-size:9.5px;letter-spacing:.05em;line-height:1.2}
@media (min-width:861px){
  .hero--bubbles .hero-portrait__years{right:-6px}
}
.hero-inner{
  position:relative;max-width:var(--content-max);margin:0 auto;
  padding:140px 24px 110px;min-height:68vh;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(330px,100%),1fr));
  gap:48px;align-items:center;
}
.hero--bubbles .hero-inner{padding:124px 24px 110px;min-height:74vh}
/* The badge, above the rating and the heading. Its interior is white, so it
   reads on the purple as it is. Centred when the copy is; left beside the
   portrait. */
.hero-logo{display:block;width:150px;height:150px;margin:0 auto 26px}

/* Three areas, so the buttons and the response note can sit under the
   portrait on a phone while staying under the copy on a desktop.
   Stacked is the base; two columns arrive once there is room for both the
   portrait at full size and a sensible measure of text beside it. */
.hero--bubbles .hero-inner{
  grid-template-columns:1fr;
  grid-template-areas:"copy" "portrait" "cta";
  gap:34px 48px;
  justify-items:center;
  text-align:center;
}
.hero--no-cta .hero-inner{grid-template-areas:"copy" "portrait"}
.hero--bubbles .hero-copy{grid-area:copy}
.hero--bubbles .hero-portrait{grid-area:portrait}
.hero--bubbles .hero-cta{grid-area:cta}
.hero--bubbles .hero-quote{margin-bottom:0;margin-inline:auto}
.hero--bubbles .hero-actions{margin-bottom:0;justify-content:center}
/* A flex row, so text-align alone will not centre it. */
.hero--bubbles .hero-rating{justify-content:center}

@media (min-width:861px){
  .hero--bubbles .hero-inner{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"copy portrait" "cta portrait";
    gap:42px 52px;
    justify-items:start;
    text-align:left;
  }
  /* The portrait spans both rows and is taller than the text beside it, so the
     spare height was falling between the speech bubble and the buttons. Pin the
     two to the row boundary: the gap between them is now just the row gap, and
     the pair still reads as centred because the portrait centres across both. */
  .hero--bubbles .hero-copy{align-self:end}
  .hero--bubbles .hero-cta{align-self:start}
  /* Without buttons there is one row, and the copy centres on the portrait. */
  .hero--no-cta .hero-inner{grid-template-areas:"copy portrait"}
  .hero--no-cta .hero-copy{align-self:center}
  .hero--bubbles .hero-quote{margin-inline:0}
  .hero--bubbles .hero-actions{justify-content:flex-start}
  .hero--bubbles .hero-rating{justify-content:flex-start}
  .hero-logo{margin-inline:0}
}
.hero-rating{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:18px}
.hero-rating span:last-child{color:var(--purple-900);font-weight:800;font-size:16px}
.hero h1{font-size:clamp(36px,5.4vw,58px);line-height:1.06;font-weight:800;color:var(--text-heading);margin:0 0 20px;max-width:15ch}
.hero--bubbles h1{font-size:clamp(32px,4.8vw,52px);line-height:1.08;max-width:none}
.hero-lede{font-size:19px;line-height:1.6;color:var(--text-body);margin:0 0 30px;max-width:52ch}
.hero--bubbles .hero-lede{font-size:18px;line-height:1.65;max-width:54ch}
.hero-brand{
  display:block;font-family:var(--font-display);
  font-size:clamp(19px,2.1vw,24px);line-height:1.2;font-weight:800;
  color:var(--brand);margin-bottom:12px;
}
/* Location pages: Alisdair introduces himself, so the name label above the
   paragraph would say his name twice in two lines. The greeting carries the
   hierarchy instead. */
.hero-greeting{
  display:block;font-family:var(--font-display);
  font-size:clamp(22px,2.6vw,28px);line-height:1.2;font-weight:800;
  color:var(--purple-900);letter-spacing:-.01em;margin-bottom:10px;
}
.hero-actions{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-bottom:30px}
.eyebrow{
  display:inline-flex;align-items:center;gap:8px;
  background:rgba(101,58,159,.09);border:1px solid var(--border-strong);
  border-radius:999px;padding:7px 15px;font-size:13px;font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--purple-900);margin-bottom:22px;
}

/* Alisdair's portrait in the hero */
.hero-portrait{position:relative;margin:0;justify-self:center;width:min(360px,78vw)}
.hero-portrait__frame{
  position:relative;width:100%;aspect-ratio:1;border-radius:50%;overflow:hidden;
  background:#fff;
  border:7px solid var(--purple-700);
  box-shadow:0 22px 46px rgba(30,10,60,.20);
}
/* A 3:4 photo on white in a square circle: pinned to the top so the whole head
   is in, with the shoulders running out under the bottom edge. */
.hero-portrait__frame img{
  width:100%;height:100%;object-fit:cover;object-position:50% 0;
}
.hero-portrait__years{
  position:absolute;right:-6px;bottom:18px;
  background:var(--purple-700);color:#fff;border-radius:20px;padding:14px 20px;
  box-shadow:0 14px 30px rgba(101,58,159,.30);transform:rotate(-4deg);text-align:center;
}
.hero-portrait__years-n{display:block;font-family:var(--font-display);font-weight:800;font-size:30px;line-height:1}
.hero-portrait__years-l{display:block;font-weight:700;font-size:13px;letter-spacing:.04em;text-transform:uppercase}

/* Quote card in the hero */
.quote-card{background:#fff;border-radius:24px;box-shadow:0 24px 60px rgba(30,10,60,.35);padding:30px}
.quote-card h2{font-size:24px;margin:0 0 6px}
.quote-card .form-sub{font-size:14px;color:var(--text-muted);margin:0 0 20px}
.form-stack{display:flex;flex-direction:column;gap:14px}
.field-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(140px,100%),1fr));gap:14px}
.form-footnote{font-size:12.5px;color:var(--text-muted);margin:0;text-align:center}
.form-error{font-size:14px;font-weight:600;color:var(--danger);margin:0;text-align:center}
.form-error[hidden]{display:none}
.form-footnote a{font-weight:700}

/* Success panel shown after a form is sent */
.form-success{text-align:center;padding:26px 8px}
.form-success[hidden]{display:none}
.form-success .tick{
  width:64px;height:64px;border-radius:50%;background:var(--lavender-100);
  display:flex;align-items:center;justify-content:center;margin:0 auto 18px;
}
.form-success h2,.form-success h3{font-size:22px;margin:0 0 8px}
.form-success p{margin:0;font-size:15px;color:var(--text-body)}


/* ── About Alisdair ─────────────────────────────────────────────────────── */
.about-grid{
  max-width:var(--content-max);margin:0 auto;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));
  gap:56px;align-items:stretch;
}
.about-figure{position:relative;height:100%}
/* Three shots of equal height, stretched to match the text beside them. */
/* Taken out of flow so the row is sized by the text, then the three shots
   divide that height between them rather than setting it. */
.about-stack{position:absolute;inset:0;display:grid;grid-template-rows:repeat(2,minmax(0,1fr));gap:20px}
.about-shot{position:relative;min-height:150px;border-radius:20px;overflow:hidden;box-shadow:0 16px 36px rgba(30,10,60,.16)}
.about-shot picture{display:block;width:100%;height:100%}
.about-shot img{width:100%;height:100%;object-fit:cover}
.about-title{font-size:clamp(28px,4vw,40px);font-weight:800;margin:0 0 18px;line-height:1.15}
.about-body{font-size:17px;line-height:1.7;margin:0 0 16px}
.about-body:last-of-type{margin-bottom:26px}
.tick-list{display:grid;gap:12px;margin-bottom:30px;padding:0;list-style:none}
.tick-list li{display:flex;gap:12px;align-items:flex-start}
.tick-list svg{flex:none;margin-top:4px}
.tick-list span{font-size:16px;font-weight:600;color:var(--purple-900)}
.about-kicker{font-size:17px;font-weight:700;color:var(--purple-700);margin:0 0 22px}
.btn-row{display:flex;gap:12px;flex-wrap:wrap}

/* ── Service cards ──────────────────────────────────────────────────────── */
.card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:22px}
.svc-card{
  background:#fff;border:1px solid var(--border);border-radius:16px;
  box-shadow:0 6px 20px rgba(101,58,159,.08);padding:28px;
  transition:box-shadow .18s ease-out,transform .18s ease-out;
}
.svc-card:hover{box-shadow:0 16px 34px rgba(101,58,159,.16);transform:translateY(-2px)}
.svc-card svg{margin-bottom:18px}
.svc-card h3{font-size:20px;margin:0 0 8px}
.svc-card p{font-size:15px;line-height:1.6;margin:0}

/* ── Three steps ────────────────────────────────────────────────────────── */
.steps{position:relative}
.steps-line{position:absolute;left:18%;right:18%;top:44px;border-top:2px dashed var(--purple-200)}
.steps-grid{position:relative;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));gap:40px 30px}
.step{text-align:center;display:flex;flex-direction:column;align-items:center}
.step-num{
  width:88px;height:88px;border-radius:50%;background:var(--snow-50);
  display:flex;align-items:center;justify-content:center;margin-bottom:22px;
}
.step-num span{font-family:var(--font-display);font-weight:800;font-size:44px;color:var(--purple-700);line-height:1}
.step h3{font-size:21px;margin:0 0 10px}
.step p{font-size:15.5px;line-height:1.65;margin:0;max-width:34ch}

/* ── Before / after slider ──────────────────────────────────────────────── */
.ba{
  position:relative;border-radius:24px;overflow:hidden;
  box-shadow:0 24px 60px rgba(0,0,0,.35);aspect-ratio:16/9;background:var(--purple-800);
  --pct:50%;
  user-select:none;-webkit-user-select:none;
}
.ba-layer{position:absolute;inset:0}
.ba-layer picture{display:block;width:100%;height:100%}
.ba-layer img{width:100%;height:100%;object-fit:cover}
.ba-after{clip-path:inset(0 0 0 var(--pct))}
.ba-line{position:absolute;top:0;bottom:0;width:3px;background:var(--lemon-400);left:var(--pct);pointer-events:none;box-shadow:0 0 14px rgba(0,0,0,.4)}
.ba-handle{
  position:absolute;top:50%;width:56px;height:56px;margin-left:-28px;margin-top:-28px;
  border-radius:50%;background:var(--lemon-400);
  display:flex;align-items:center;justify-content:center;left:var(--pct);
  pointer-events:none;box-shadow:0 6px 18px rgba(0,0,0,.3);
}
.ba-fade{
  position:absolute;left:0;right:0;bottom:0;height:84px;pointer-events:none;
  background:linear-gradient(to top,rgba(30,10,60,.45),rgba(30,10,60,0));
}
/* The whole comparison is the drag target, not just a strip along the bottom —
   the handle sits at the vertical centre and has to be grabbable where it looks
   grabbable. Kept as a native range input so keyboard and screen-reader support
   come for free; `pan-y` leaves vertical swipes to the page so mobile still
   scrolls normally over the image. */
.ba-range{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:0;margin:0;cursor:ew-resize;touch-action:pan-y;
}
.ba-range:focus-visible{outline:3px solid var(--lemon-400);outline-offset:-3px;border-radius:24px}
.ba-tags{position:absolute;top:16px;left:16px;right:16px;display:flex;justify-content:space-between;pointer-events:none}
.ba-tag{
  background:rgba(30,10,60,.62);color:#fff;font-weight:800;font-size:12px;
  letter-spacing:.08em;text-transform:uppercase;padding:6px 12px;border-radius:999px;
}

/* ── Review cards ───────────────────────────────────────────────────────── */
.review-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:22px}
.review-grid--loc{grid-template-columns:repeat(auto-fit,minmax(min(290px,100%),1fr));gap:20px}
.review-card{
  background:#fff;border:1px solid var(--border);border-radius:16px;
  box-shadow:0 6px 20px rgba(101,58,159,.08);padding:28px;
  display:flex;flex-direction:column;gap:14px;
}
.review-grid--loc .review-card{padding:26px;gap:13px}
.review-card blockquote{font-size:16px;line-height:1.65;margin:0;color:var(--purple-900);font-weight:600}
.review-grid--loc .review-card blockquote{font-size:15.5px}
.review-foot{margin-top:auto;padding-top:6px;border-top:1px solid var(--border)}
.review-name{font-weight:800;color:var(--purple-900);font-size:15px;margin-top:12px}
.review-place{font-size:13px;color:var(--text-muted)}

/* Masonry review wall (reviews page) */
.reviews-masonry{max-width:var(--content-max);margin:0 auto;columns:340px;column-gap:22px}
/* display:block (not inline-block) — inside a multicol container an inline-block
   picks up the inter-element whitespace and overflows the column. */
.review-tile{
  break-inside:avoid;background:#fff;border:1px solid var(--border);border-radius:16px;
  box-shadow:0 6px 20px rgba(101,58,159,.08);padding:26px;margin:0 0 22px;
  display:block;width:100%;
}
.review-tile__top{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px}
.review-tile__date{font-size:12.5px;color:var(--text-muted);font-weight:700}
.review-tile h3{font-size:17px;margin:0 0 10px}
.review-tile blockquote{font-size:15.5px;line-height:1.65;margin:0 0 16px;color:var(--text-body)}
.review-tile__foot{padding-top:14px;border-top:1px solid var(--border);display:flex;align-items:center;gap:12px}
.avatar{
  width:38px;height:38px;border-radius:50%;background:var(--lavender-100);color:var(--purple-700);
  font-family:var(--font-display);font-weight:800;font-size:15px;
  display:flex;align-items:center;justify-content:center;flex:none;
}

/* ── Areas we cover list ────────────────────────────────────────────────── */
.area-list{display:flex;flex-direction:column}
.area-row{
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:24px;
  text-decoration:none;padding:26px 22px;border-top:1px solid var(--border-strong);
  transition:background .18s ease-out;
}
.area-row:last-child{border-bottom:1px solid var(--border-strong)}
.area-row:hover{background:#fff;text-decoration:none}
.area-row h3{
  font-family:var(--font-display);font-weight:800;font-size:clamp(24px,3vw,34px);
  color:var(--purple-900);margin:0 0 6px;line-height:1.15;
}
.area-row p{font-size:15.5px;line-height:1.55;margin:0;color:var(--text-body)}
.area-arrow{
  flex:none;width:58px;height:58px;border-radius:50%;background:var(--lemon-400);
  display:flex;align-items:center;justify-content:center;color:var(--purple-900);
}
/* A little nudge in the direction of travel when the row is hovered. */
.area-arrow svg{transition:transform .2s ease-out}
.area-row:hover .area-arrow svg,
.area-row:focus-visible .area-arrow svg{animation:toc-arrow-bounce .6s cubic-bezier(.34,1.56,.64,1)}
@keyframes toc-arrow-bounce{
  0%{transform:translateX(0)}
  35%{transform:translateX(7px)}
  70%{transform:translateX(-2px)}
  100%{transform:translateX(0)}
}
@media (prefers-reduced-motion:reduce){.area-row:hover .area-arrow svg,.area-row:focus-visible .area-arrow svg{animation:none}}

/* ── Benefit bar ──────────────────────────────────────────────────────────
   One shape, not three: the hero already carries the drifting bubbles, the
   portrait and the 17+ badge, and three more circles made it all read the
   same. A single card astride the join keeps the benefits prominent without
   adding another round thing. It is a sibling of both sections, since the
   hero clips its own bubbles. */
.benefits-wrap{
  position:relative;z-index:3;
  max-width:var(--content-max);margin:0 auto;padding:0 18px;
}
.benefits{
  --bar:78px;
  min-height:var(--bar);margin:calc(var(--bar) / -2) auto 0;
  max-width:780px;
  background:#fff;border-radius:var(--radius-xl);
  box-shadow:0 18px 40px rgba(20,6,45,.24);
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  list-style:none;padding:0;overflow:hidden;
}
.benefit{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:7px;padding:16px 8px;text-align:center;
  border-left:1px solid var(--border);
}
.benefit:first-child{border-left:0}
.benefit svg{flex:none}
.benefit__label{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(12px,2.1vw,16px);line-height:1.15;color:var(--purple-900);
}
/* Wide enough for the icon to sit beside the words rather than above them. */
@media (min-width:620px){
  .benefits{--bar:84px}
  .benefit{flex-direction:row;gap:12px;padding:20px 16px}
}
/* The bar brings its own breathing room, so the section needs less. */
.section--after-benefits{padding-top:56px}

/* ── Location page pieces ───────────────────────────────────────────────── */

/* Its own colour, a step deeper than the standard tint, so this band reads as
   the local part of the page and separates cleanly from the snow sections
   above and below it. */
.section--local{background:var(--purple-200)}

/* Copy, photograph and the places card as one interlocking block. Stacked, the
   explanation leads; side by side, the picture and the places sit under each
   other with the copy running the full height beside them. */
.loc-intro{
  max-width:var(--content-max);margin:0 auto;
  display:grid;grid-template-columns:1fr;
  grid-template-areas:"copy" "media" "places";
  gap:30px;
}
.loc-copy{grid-area:copy}
.loc-figure{grid-area:media}
.loc-places{grid-area:places}
.loc-copy__cta{margin-top:26px}

@media (min-width:861px){
  .loc-intro{
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:"media copy" "places copy";
    gap:30px 52px;
    align-items:start;
  }
}
.loc-figure{
  margin:0;border-radius:var(--radius-xl);overflow:hidden;
  box-shadow:0 18px 44px rgba(67,38,110,.20);
}
.loc-figure picture{display:block}
.loc-figure img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:3/2}

.loc-body{font-size:17px;line-height:1.7;margin:0 0 16px}
.loc-body:last-of-type{margin-bottom:0}
/* A place list, not a row of buttons: pill shapes here invited clicks that
   went nowhere. Two columns of pinned rows, sharing the rule-between-items
   look of the FAQ and the areas list. */
.village-list{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));
  gap:0 28px;margin:0;padding:0;list-style:none;
}
.village-list li{
  display:flex;align-items:center;gap:9px;
  padding:10px 2px;border-bottom:1px solid var(--border-strong);
  font-size:15.5px;font-weight:600;color:var(--purple-900);line-height:1.35;
}
.village-list svg{flex:none;color:var(--purple-500)}
.loc-card{
  background:#fff;border:1px solid var(--border);border-radius:24px;
  box-shadow:0 6px 20px rgba(101,58,159,.08);padding:30px 32px;
}
.loc-card h2{font-size:21px;margin:0 0 18px}

/* ── Page banner (reviews / contact) ────────────────────────────────────── */
.page-banner{background:var(--lavender-100);padding:100px 24px 72px;border-bottom:1px solid var(--border)}
.page-banner h1{font-size:clamp(32px,4.6vw,50px);font-weight:800;color:var(--text-heading);margin:0 0 18px;line-height:1.1}
.page-banner p{font-size:18px;line-height:1.65;color:var(--text-body);margin:0 0 26px;max-width:60ch}
.page-banner p:last-child{margin-bottom:0}
/* Purple with the drifting bubbles, for pages that want the hero's colour
   without its portrait and speech bubble. */
.page-banner--purple{
  position:relative;overflow:hidden;
  background:var(--purple-700);border-bottom:0;
  padding-top:150px;padding-bottom:84px;
}
.page-banner--purple .container{position:relative}
.page-banner--purple h1{color:#fff}
.page-banner--purple p{color:rgba(255,255,255,.9)}
.banner-stats{display:flex;gap:26px;flex-wrap:wrap;align-items:center}
.score{display:flex;align-items:center;gap:12px}
.score__n{font-family:var(--font-display);font-weight:800;font-size:44px;color:var(--brand);line-height:1}
.score__c{color:var(--text-muted);font-size:14px;margin-top:4px}
.page-banner--purple .score__n{color:var(--lemon-400)}
.page-banner--purple .score__c{color:rgba(255,255,255,.82)}

/* ── Contact page ───────────────────────────────────────────────────────── */
.contact-grid{
  max-width:var(--content-max);margin:0 auto;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));
  gap:36px;align-items:start;
}
.form-card{
  background:#fff;border:1px solid var(--border);border-radius:24px;
  box-shadow:0 10px 34px rgba(101,58,159,.10);padding:34px;
}
.form-card h2{font-size:26px;margin:0 0 8px}
.form-card .form-sub{font-size:15px;color:var(--text-muted);margin:0 0 24px}
.form-card .form-stack{gap:16px}
.form-card .field-row{grid-template-columns:repeat(auto-fit,minmax(min(190px,100%),1fr));gap:16px}
.form-card .form-success{padding:40px 8px}
.form-card .form-success .tick{width:72px;height:72px;margin-bottom:20px}
.form-card .form-success h2{font-size:26px;margin:0 0 10px}
.form-card .form-success p{font-size:16px;line-height:1.65;margin:0 0 22px}

.dropzone-label{font-size:14px;font-weight:700;color:var(--purple-900);margin-bottom:8px}
.dropzone{
  border:2px dashed var(--border-strong);border-radius:16px;background:var(--lavender-100);
  padding:28px 20px;text-align:center;cursor:pointer;width:100%;
  font-family:var(--font-body);
  transition:border-color .15s ease-out,background .15s ease-out;
}
.dropzone:hover,.dropzone.is-dragging{border-color:var(--purple-700);background:var(--purple-200)}
.dropzone svg{margin:0 auto 10px}
.dropzone__title{font-weight:800;color:var(--purple-900);font-size:15.5px;margin-bottom:4px}
.dropzone__hint{font-size:13.5px;color:var(--text-muted)}
.file-list{
  margin-top:12px;display:flex;align-items:center;gap:10px;
  background:var(--surface-card);border:1px solid var(--border);
  border-radius:12px;padding:12px 14px;
}
.file-list[hidden]{display:none}
.file-list span{font-size:14px;font-weight:700;color:var(--purple-900)}

.side-stack{display:flex;flex-direction:column;gap:20px}
.side-card--brand{background:var(--purple-700);color:#fff;border-radius:24px;padding:32px}
.side-card--brand h2{font-size:22px;color:#fff;margin:0 0 10px}
.side-card--brand p{font-size:15.5px;line-height:1.6;margin:0 0 20px;color:rgba(255,255,255,.85)}
.side-card--brand .btn-call{font-size:19px;padding:15px 28px}
.side-card{
  background:#fff;border:1px solid var(--border);border-radius:24px;
  box-shadow:0 6px 20px rgba(101,58,159,.08);padding:32px;
}
.side-card h2{font-size:20px;margin:0 0 16px}
.area-pills{display:grid;gap:12px}
.area-pills a{
  display:flex;justify-content:space-between;align-items:center;gap:10px;
  text-decoration:none;font-weight:700;font-size:15.5px;color:var(--purple-900);
  padding:13px 16px;border-radius:999px;background:var(--lemon-400);
  transition:background .15s ease-out;
}
.area-pills a:hover{background:var(--lemon-500);color:var(--purple-900);text-decoration:none}
.area-pills span{color:var(--purple-700)}
.side-note{font-size:14px;line-height:1.6;color:var(--text-muted);margin:18px 0 0}

/* ── CTA band ───────────────────────────────────────────────────────────── */
.cta-band{background:var(--purple-700);padding:76px 24px;position:relative;overflow:hidden}
.bubble{
  position:absolute;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.62),rgba(255,255,255,.16) 42%,rgba(255,255,255,.05) 72%);
  box-shadow:inset 0 0 22px rgba(255,255,255,.30);
  animation:toc-float 11s ease-in-out infinite;
}
@keyframes toc-float{
  0%{transform:translate3d(0,0,0)}
  50%{transform:translate3d(10px,-26px,0)}
  100%{transform:translate3d(0,0,0)}
}
.cta-inner{
  position:relative;max-width:var(--content-max);margin:0 auto;
  display:flex;flex-wrap:wrap;gap:32px;align-items:center;justify-content:space-between;
}
.cta-copy{max-width:620px}
.cta-copy h2{font-size:clamp(26px,3.6vw,38px);font-weight:800;color:#fff;margin:0 0 12px;line-height:1.15}
.cta-copy p{font-size:17.5px;line-height:1.6;color:rgba(255,255,255,.85);margin:0}
.cta-actions{display:flex;gap:14px;flex-wrap:wrap}
.cta-actions .btn-outline{border-color:rgba(255,255,255,.55)}

/* ── Footer ─────────────────────────────────────────────────────────────── */
.site-footer{background:var(--lavender-100);color:var(--text-body);padding:56px 24px 26px;border-top:1px solid var(--border)}
.footer-grid{
  max-width:var(--content-max);margin:0 auto;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:34px;
}
.footer-brand{display:flex;flex-direction:column;align-items:flex-start;gap:10px;margin-bottom:14px}
.footer-logo{display:block;width:76px;height:76px;flex:none}
.footer-brand span{font-family:var(--font-display);font-weight:800;font-size:24px;line-height:1.1;letter-spacing:-.01em;color:var(--purple-900)}
.footer-blurb{font-size:14.5px;line-height:1.6;color:var(--text-muted);max-width:270px;margin:0}
.footer-col{display:flex;flex-direction:column;gap:9px;font-size:14.5px}
.footer-col h2{font-family:var(--font-display);font-size:15.5px;color:var(--purple-900);margin:0;font-weight:700}
.footer-col a,.footer-col span{color:var(--text-body);text-decoration:none;transition:color .15s ease-out}
.footer-col a{display:flex;gap:9px;align-items:center}
.footer-col a:hover{color:var(--brand);text-decoration:none}
.footer-col span{display:flex;gap:9px;align-items:center}
.footer-bottom{
  max-width:var(--content-max);margin:30px auto 0;padding-top:18px;
  border-top:1px solid var(--border);font-size:12.5px;color:var(--text-muted);
  display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;
}
.footer-bottom a{color:var(--text-muted)}
.footer-bottom a:hover{color:var(--brand)}

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width:920px){
  .nav-desktop{display:none}
  .nav-mobile-cta{display:inline-flex}
  .nav-burger{display:inline-flex}
}
@media (max-width:860px){
  .steps-line{display:none}
  .steps-grid{grid-template-columns:1fr;gap:44px}
}
@media (max-width:720px){
  .section,.section--sm{padding:64px 18px}
  .page-banner{padding:96px 18px 56px}
  .header-inner,.footer-grid,.footer-bottom,.site-footer,.cta-band{padding-left:18px;padding-right:18px}
  .footer-grid,.footer-bottom{padding-left:0;padding-right:0}
  .hero-inner{padding:120px 18px 84px;gap:36px}
  .hero--bubbles .hero-inner{padding:110px 18px 90px}
  .hero-logo{width:120px;height:120px;margin-bottom:22px}
  .about-grid,.loc-intro{gap:36px}
  .about-figure{order:2}
  .about-stack{position:static;gap:14px}
  .about-shot{aspect-ratio:3/2;min-height:0}

  /* Centred copy reads better in a narrow column; lists and cards stay left
     so their icons and edges still line up. */
  .hero-inner > div:first-child,
  .about-grid > div:last-child,
  .loc-copy,
  .page-banner .container,
  .cta-copy{text-align:center}
  .hero h1,.hero-lede,.about-body,.about-kicker,.loc-body,
  .cta-copy p,.page-banner p{margin-left:auto;margin-right:auto}
  .hero-rating,.hero-actions,.btn-row,
  .cta-actions,.banner-stats{justify-content:center}
  .loc-copy__cta{display:inline-flex}
  .cta-inner{justify-content:center}
  .tick-list,.village-list li{text-align:left}
  .quote-card,.form-card{padding:24px}
  .hero-quote{padding:22px 24px}
}

/* ── Scroll reveals ─────────────────────────────────────────────────────────
   Gated behind `.js` on <html>, set by an inline script in <head> before first
   paint. With JavaScript off the class is never added, these rules never match,
   and every section renders plainly visible. */

.js [data-reveal],
.js [data-reveal-group] > *{
  opacity:0;
  transform:translate3d(0,22px,0);
  transition:opacity .6s cubic-bezier(.22,.61,.36,1),
             transform .6s cubic-bezier(.22,.61,.36,1);
}
.js [data-reveal].is-in,
.js [data-reveal-group].is-in > *{opacity:1;transform:none}

/* The figure in the About block comes in from the side instead. */
.js [data-reveal="left"]{transform:translate3d(-26px,0,0)}

/* Staggered entrances, capped so a long list never crawls in. */
.js [data-reveal-group].is-in > *:nth-child(1){transition-delay:0s}
.js [data-reveal-group].is-in > *:nth-child(2){transition-delay:.06s}
.js [data-reveal-group].is-in > *:nth-child(3){transition-delay:.12s}
.js [data-reveal-group].is-in > *:nth-child(4){transition-delay:.18s}
.js [data-reveal-group].is-in > *:nth-child(5){transition-delay:.24s}
.js [data-reveal-group].is-in > *:nth-child(6){transition-delay:.3s}
.js [data-reveal-group].is-in > *:nth-child(7){transition-delay:.36s}
.js [data-reveal-group].is-in > *:nth-child(n+8){transition-delay:.42s}

@media (prefers-reduced-motion:reduce){
  .js [data-reveal],
  .js [data-reveal-group] > *{opacity:1;transform:none;transition:none}
}

/* Preview mode: an <a> with no href loses the pointer cursor, so put it back —
   the page should still look and feel exactly like the finished site. */
a[data-link-disabled]{cursor:pointer}
