/* ============================================================
   APEX WRAPS — site stylesheet
   Concept build for the Black Oak Consulting portfolio.

   No framework, no CDN, no build step. Fonts below are the same
   variable woff2 files Google serves, split on Google's own
   unicode-ranges and served from assets/fonts/ instead, because
   the CSP on this domain permits no third-party origin.
   ============================================================ */

@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../fonts/archivo-var-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Archivo';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../fonts/archivo-var-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../fonts/inter-var-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Inter';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url('../fonts/inter-var-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================
   1. TOKENS
   ============================================================ */
:root{
  /* Surfaces run dark-to-light so elevation reads as "lit from above",
     matching the studio lighting in the photography. */
  --ink:#0a0a0b;
  --surface:#101012;
  --surface-2:#17171a;
  --surface-3:#1f1f23;
  --line:rgba(255,255,255,.10);
  --line-strong:rgba(255,255,255,.18);

  /* Acid green is the only chromatic color in the system. It is used
     for CTAs, focus rings and state — never for large fills, where it
     would overwhelm the photography it is meant to point at. */
  --acid:#c7f53d;
  --acid-dim:#a8d130;
  --acid-glow:rgba(199,245,61,.18);

  --text:#f4f4f2;      /* 18.4:1 on --ink */
  --text-2:#b6b6b2;    /* 9.1:1  on --ink */
  --text-3:#8a8a86;    /* 5.3:1  on --ink — smallest permitted body tone */
  --danger:#ff6b5e;    /* 5.6:1 on --surface */
  --ok:#7ee08a;

  --font-display:'Archivo',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-body:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;

  --sp-1:.25rem; --sp-2:.5rem;  --sp-3:.75rem; --sp-4:1rem;
  --sp-5:1.5rem; --sp-6:2rem;   --sp-7:3rem;   --sp-8:4rem;
  --sp-9:6rem;   --sp-10:8rem;

  --r-sm:6px; --r-md:10px; --r-lg:16px; --r-xl:24px;
  --wrap:1240px;
  --header-h:72px;

  --ease:cubic-bezier(.22,.61,.36,1);
  --dur-fast:140ms; --dur:240ms; --dur-slow:420ms;

  /* Layer scale. Nothing in this file may invent a z-index outside it. */
  --z-base:1; --z-sticky:20; --z-header:40; --z-overlay:60; --z-toast:80;
}

/* ============================================================
   2. RESET + BASE
   ============================================================ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body,h1,h2,h3,h4,p,figure,blockquote,dl,dd,ul,ol{margin:0}
ul[class],ol[class]{list-style:none;padding:0}

html{scroll-behavior:smooth}
body{
  background:var(--ink);
  color:var(--text);
  font-family:var(--font-body);
  font-size:1rem;
  line-height:1.65;
  font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img,video,svg{display:block;max-width:100%;height:auto}
button,input,select,textarea{font:inherit;color:inherit}

h1,h2,h3,h4,.display{
  font-family:var(--font-display);
  font-weight:800;
  line-height:1.04;
  letter-spacing:-.028em;
  text-wrap:balance;
}
h1{font-size:clamp(2.6rem,7.2vw,5.4rem)}
h2{font-size:clamp(2rem,4.6vw,3.4rem)}
h3{font-size:clamp(1.15rem,2vw,1.4rem);letter-spacing:-.018em}
p{text-wrap:pretty}

a{color:inherit;text-decoration-color:var(--line-strong);text-underline-offset:3px}
a:hover{text-decoration-color:var(--acid)}

/* Long tokens — URLs, VINs, plate numbers — reflow instead of
   forcing a horizontal scrollbar. Deliberately not break-all,
   which would also chop ordinary prose. */
.break-any{overflow-wrap:anywhere;min-width:0}

/* ============================================================
   3. ACCESSIBILITY PRIMITIVES
   ============================================================ */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:3px solid var(--acid);
  outline-offset:2px;
  border-radius:var(--r-sm);
}
.skip-link{
  position:absolute;left:var(--sp-4);top:calc(-1 * var(--sp-10));
  z-index:var(--z-toast);
  background:var(--acid);color:var(--ink);
  padding:var(--sp-3) var(--sp-5);
  border-radius:0 0 var(--r-md) var(--r-md);
  font-weight:700;text-decoration:none;
  transition:top var(--dur) var(--ease);
}
.skip-link:focus{top:0}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* ============================================================
   4. LAYOUT
   ============================================================ */
.wrap{width:100%;max-width:var(--wrap);margin-inline:auto;padding-inline:var(--sp-5)}
@media (min-width:768px){.wrap{padding-inline:var(--sp-6)}}
@media (min-width:1280px){.wrap{padding-inline:var(--sp-7)}}

.section{padding-block:clamp(var(--sp-8),11vw,var(--sp-10))}
.section--tight{padding-block:clamp(var(--sp-7),7vw,var(--sp-8))}
.section--line{border-top:1px solid var(--line)}

.eyebrow{
  font-family:var(--font-display);
  font-size:.75rem;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--acid);
  display:flex;align-items:center;gap:var(--sp-3);
  margin-bottom:var(--sp-4);
}
.eyebrow::before{
  content:"";width:28px;height:2px;background:var(--acid);flex:none;
}
.lede{
  font-size:clamp(1.05rem,1.6vw,1.2rem);
  color:var(--text-2);
  max-width:60ch;
}
.section-head{max-width:64ch;margin-bottom:var(--sp-7)}

/* ============================================================
   5. BUTTONS
   ============================================================ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  min-height:48px;padding:var(--sp-3) var(--sp-5);
  font-family:var(--font-display);font-weight:700;font-size:.94rem;
  letter-spacing:.01em;
  border:1px solid transparent;border-radius:var(--r-md);
  text-decoration:none;cursor:pointer;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease),
             transform var(--dur-fast) var(--ease);
  touch-action:manipulation;
}
/* Scale only — never a size or margin change, which would reflow
   neighbouring content on press. */
.btn:active{transform:scale(.975)}

.btn--primary{background:var(--acid);color:var(--ink)}
.btn--primary:hover{background:#d3ff52}
.btn--ghost{background:transparent;color:var(--text);border-color:var(--line-strong)}
.btn--ghost:hover{border-color:var(--acid);color:var(--acid)}
.btn--lg{min-height:56px;padding:var(--sp-4) var(--sp-6);font-size:1.02rem}
.btn--block{display:flex;width:100%}

.btn[disabled],.btn[aria-disabled="true"]{
  opacity:.45;cursor:not-allowed;transform:none;
}

.btn svg{flex:none}

/* ============================================================
   6. UTILITY BAR + HEADER
   ============================================================ */
.utility{
  background:var(--surface-2);
  border-bottom:1px solid var(--line);
  font-size:.8rem;color:var(--text-3);
}
.utility .wrap{
  display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-5);
  align-items:center;justify-content:space-between;
  min-height:38px;padding-block:var(--sp-2);
}
.utility a{color:var(--text-2)}
.utility a:hover{color:var(--acid)}
.utility-left{display:flex;align-items:center;gap:var(--sp-2)}
.dot{width:7px;height:7px;border-radius:50%;background:var(--acid);flex:none}
@media (max-width:600px){.utility .wrap>span:last-child{display:none}}

.site-header{
  position:sticky;top:0;z-index:var(--z-header);
  background:rgba(10,10,11,.86);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
.site-header .wrap{
  display:flex;align-items:center;gap:var(--sp-5);
  min-height:var(--header-h);
}
.brand{
  display:flex;align-items:center;gap:var(--sp-3);
  text-decoration:none;color:var(--text);margin-right:auto;
}
.brand svg{width:30px;height:30px;color:var(--text);flex:none}
.brand-name b{
  display:block;font-family:var(--font-display);font-weight:800;
  font-size:1.02rem;letter-spacing:.06em;text-transform:uppercase;line-height:1.1;
}
.brand-name span{
  display:block;font-size:.68rem;letter-spacing:.19em;
  text-transform:uppercase;color:var(--text-3);
}

.nav{display:none;gap:var(--sp-5)}

/* Three-zone header: brand left, nav optically centered in the header, CTA
   right. The side columns are both 1fr, so the nav sits centered on the header
   regardless of how much wider the brand is than the button — which a plain
   flex row with margin-right:auto cannot do. min-width:0 lets the side columns
   shrink instead of shoving the centre off-axis at narrow desktop widths. */
@media (min-width:1024px){
  .site-header .wrap{
    display:grid;
    grid-template-columns:1fr auto 1fr;
    align-items:center;
  }
  .site-header .wrap>*{min-width:0}
  .brand{margin-right:0;justify-self:start}
  .nav{display:flex;justify-self:center}
}
.nav a{
  position:relative;text-decoration:none;font-size:.92rem;
  color:var(--text-2);padding-block:var(--sp-2);
  transition:color var(--dur-fast) var(--ease);
}
.nav a:hover{color:var(--text)}
.nav a[aria-current]{color:var(--text)}
/* Current page is marked by an underline AND aria-current, so the
   state does not depend on color alone. */
.nav a[aria-current]::after{
  content:"";position:absolute;left:0;right:0;bottom:0;
  height:2px;background:var(--acid);
}
.header-cta{display:none}
@media (min-width:1024px){.header-cta{display:inline-flex;justify-self:end}}

.nav-toggle{
  display:inline-flex;align-items:center;gap:var(--sp-2);
  min-height:44px;min-width:44px;padding:var(--sp-2) var(--sp-3);
  background:transparent;border:1px solid var(--line-strong);
  border-radius:var(--r-md);cursor:pointer;
  font-size:.86rem;
}
@media (min-width:1024px){.nav-toggle{display:none}}

.mobile-nav{display:none;border-top:1px solid var(--line);background:var(--surface)}
.mobile-nav.open{display:block}
@media (min-width:1024px){.mobile-nav,.mobile-nav.open{display:none}}
.mobile-nav ul{padding:var(--sp-3) var(--sp-5) var(--sp-5)}
.mobile-nav li+li{border-top:1px solid var(--line)}
.mobile-nav a:not(.btn){
  display:block;padding:var(--sp-4) 0;text-decoration:none;font-size:1.02rem;
}
.mobile-nav a[aria-current]{color:var(--acid)}
.mobile-nav .btn{margin-top:var(--sp-4)}

/* ============================================================
   7. HERO — scroll-scrubbed transformation
   The section is tall; a sticky stage inside it holds the frame
   stack. Scroll progress through the tall section maps to which
   frame is opaque. Frames are stacked, not swapped in the DOM,
   so there is no decode flash between steps.
   ============================================================ */
.hero{position:relative;height:340vh}
@media (max-width:767px){.hero{height:300vh}}

.hero__stage{
  position:sticky;top:0;
  height:100svh;
  display:grid;grid-template-rows:1fr auto;
  overflow:hidden;
  background:
    radial-gradient(120% 80% at 50% 30%, #1a1a1e 0%, var(--ink) 72%);
}

@media (min-height:620px){
  .hero__stage{min-height:560px}
}

.hero__frames{
  position:absolute;inset:0;
  display:grid;place-items:center;
}
.hero__frames img{
  grid-area:1/1;
  width:100%;height:100%;
  object-fit:cover;
  opacity:0;
  will-change:opacity;
}
/* Frame 1 carries the LCP and is the visible state before JS runs, so the
   hero is never blank. */
.hero__frames img:first-child{opacity:1}

/* Once the scrubber takes over, .is-active is the ONLY thing that shows a
   frame. Without this, the :first-child rule above stays live underneath the
   whole stack, and any frame that has not decoded yet renders transparent and
   lets the white opening frame show through — the scrub reads 100% while the
   car is still factory white. */
.hero__frames.is-live img{opacity:0}
.hero__frames.is-live img.is-active{opacity:1}

.hero__scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(10,10,11,.80) 0%,rgba(10,10,11,.12) 34%,
                    rgba(10,10,11,.42) 72%,var(--ink) 100%),
    linear-gradient(100deg,rgba(10,10,11,.86) 0%,rgba(10,10,11,.52) 28%,
                    rgba(10,10,11,.10) 52%,transparent 68%);
}

.hero__copy{
  position:relative;z-index:var(--z-base);
  align-self:center;
  padding-block:var(--sp-8);
}
.hero__copy h1{max-width:16ch}
.hero__copy .lede{margin-top:var(--sp-5);max-width:48ch}
.hero__actions{
  display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-6);
}

/* The two words that swap as the car changes. Both are always in the
   DOM and readable to a screen reader; only the visual emphasis moves. */
.hero__state{
  display:inline-grid;
  font-family:var(--font-display);
}
.hero__state span{
  grid-area:1/1;
  transition:opacity var(--dur-slow) var(--ease);
}
.hero__state span[data-state="to"]{color:var(--acid);opacity:0}
.hero.is-wrapped .hero__state span[data-state="from"]{opacity:0}
.hero.is-wrapped .hero__state span[data-state="to"]{opacity:1}

/* Progress rail — gives the scrub a visible, non-color-only readout. */
.hero__rail{
  position:relative;z-index:var(--z-base);
  display:flex;align-items:center;gap:var(--sp-4);
  padding-block:var(--sp-5);
  border-top:1px solid var(--line);
  font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-3);font-family:var(--font-display);font-weight:600;
}
.hero__track{
  position:relative;flex:1;height:2px;background:var(--line-strong);
  border-radius:2px;overflow:hidden;
}
.hero__fill{
  position:absolute;inset:0;transform-origin:left center;
  transform:scaleX(0);background:var(--acid);
}
.hero__pct{font-variant-numeric:tabular-nums;color:var(--text-2);min-width:4ch;text-align:right}

@media (max-width:600px){
  .hero__rail span:first-child,.hero__rail span:nth-child(3){display:none}
}

/* Reduced motion: no scrubbing. The visitor gets the
   finished car immediately and the tall scroll section collapses,
   because a 340vh section of nothing is its own accessibility problem. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .hero{height:auto}
  .hero__stage{position:relative;height:auto;min-height:0}
  .hero__frames{position:relative;height:min(72svh,560px)}
  .hero__frames img{opacity:0}
  .hero__frames img:last-child{opacity:1}
  .hero__frames img:first-child{opacity:0}
  .hero__rail{display:none}
}

/* ============================================================
   8. REVEAL ON SCROLL
   Opt-in via .reveal. The .js class is set by an inline script in
   <head>, so with JS off nothing is ever left hidden.
   ============================================================ */
.js .reveal{opacity:0;transform:translateY(18px)}
.js .reveal.is-in{
  opacity:1;transform:none;
  transition:opacity 620ms var(--ease),transform 620ms var(--ease);
}
@media (prefers-reduced-motion:reduce){
  .js .reveal{opacity:1;transform:none;transition:none}
}

/* ============================================================
   9. CARDS + GRIDS
   ============================================================ */
.grid{display:grid;gap:var(--sp-5)}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}

.card{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  padding:var(--sp-6);
  display:flex;flex-direction:column;gap:var(--sp-3);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.card:hover{border-color:var(--line-strong);background:var(--surface-2)}
.card__icon{
  width:44px;height:44px;display:grid;place-items:center;
  border-radius:var(--r-md);
  background:var(--acid-glow);color:var(--acid);
  margin-bottom:var(--sp-2);
}
.card p{color:var(--text-2);font-size:.96rem}
.card__meta{
  margin-top:auto;padding-top:var(--sp-4);
  border-top:1px solid var(--line);
  font-family:var(--font-display);font-weight:700;
  font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-3);
}
.card__meta b{color:var(--acid);font-weight:700}

/* ---- Process: a numbered rail ---- */
.steps{counter-reset:step;display:grid;gap:var(--sp-5)}
@media (min-width:900px){.steps{grid-template-columns:repeat(4,1fr)}}
.step{
  counter-increment:step;
  padding-top:var(--sp-5);
  border-top:2px solid var(--line);
  transition:border-color var(--dur) var(--ease);
}
.step:hover{border-top-color:var(--acid)}
.step::before{
  content:counter(step,decimal-leading-zero);
  display:block;
  font-family:var(--font-display);font-weight:800;
  font-size:2.4rem;line-height:1;color:var(--surface-3);
  margin-bottom:var(--sp-3);
  font-variant-numeric:tabular-nums;
}
.step h3{margin-bottom:var(--sp-2)}
.step p{color:var(--text-2);font-size:.94rem}

/* ---- Stats ---- */
.stats{
  display:grid;gap:var(--sp-5);
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
}
.stat b{
  display:block;font-family:var(--font-display);font-weight:800;
  font-size:clamp(2rem,3.6vw,2.8rem);line-height:1;
  font-variant-numeric:tabular-nums;
}
.stat span{
  display:block;margin-top:var(--sp-2);
  font-size:.82rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--text-3);
}

/* ---- Media figure ---- */
.figure{
  position:relative;border-radius:var(--r-lg);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line);
}
.figure img,.figure video{width:100%;display:block}
.figure figcaption{
  padding:var(--sp-4) var(--sp-5);
  font-size:.86rem;color:var(--text-3);
  border-top:1px solid var(--line);
}

/* ---- Testimonials ---- */
.quote{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:var(--sp-6);
  display:flex;flex-direction:column;gap:var(--sp-4);
}
.quote blockquote{font-size:1.04rem;color:var(--text);line-height:1.6}
.quote figcaption{
  display:flex;align-items:center;gap:var(--sp-3);
  margin-top:auto;padding-top:var(--sp-4);border-top:1px solid var(--line);
  font-size:.88rem;color:var(--text-3);
}
.quote figcaption b{color:var(--text-2);font-weight:600}
.avatar{
  width:36px;height:36px;border-radius:50%;flex:none;
  display:grid;place-items:center;
  background:var(--surface-3);color:var(--text-3);
  font-family:var(--font-display);font-weight:700;font-size:.8rem;
}
/* Sample content flag. These names are placeholders and the site says so
   rather than implying real customers. */
.sample-note{
  margin-top:var(--sp-5);font-size:.82rem;color:var(--text-3);
  display:flex;gap:var(--sp-2);align-items:flex-start;
}

/* ============================================================
   10. BOOKING — calendar + form
   ============================================================ */
.booking{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-xl);
  overflow:hidden;
}
.booking__grid{display:grid}
/* Grid children default to min-width:auto, so a column whose contents have a
   larger intrinsic minimum silently overflows the rounded container and gets
   clipped by its overflow:hidden. This is what cut the Saturday column off the
   calendar on a 375px screen. */
.booking__grid>*{min-width:0}
@media (min-width:1000px){.booking__grid{grid-template-columns:minmax(0,420px) minmax(0,1fr)}}

.booking__cal{
  padding:var(--sp-6);
  border-bottom:1px solid var(--line);
  background:var(--surface-2);
}
@media (min-width:1000px){
  .booking__cal{border-bottom:0;border-right:1px solid var(--line)}
}
.booking__form{padding:var(--sp-6)}
@media (min-width:768px){
  .booking__cal,.booking__form{padding:var(--sp-7)}
}

/* ---- Month header ---- */
.cal__head{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--sp-3);margin-bottom:var(--sp-5);
}
.cal__month{
  font-family:var(--font-display);font-weight:700;font-size:1.06rem;
  letter-spacing:.01em;
}
.cal__nav{display:flex;gap:var(--sp-2)}
.cal__nav button{
  width:40px;height:40px;display:grid;place-items:center;
  background:transparent;border:1px solid var(--line-strong);
  border-radius:var(--r-md);cursor:pointer;color:var(--text-2);
  transition:border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.cal__nav button:hover:not([disabled]){border-color:var(--acid);color:var(--acid)}
.cal__nav button[disabled]{opacity:.35;cursor:not-allowed}

/* ---- Day grid ---- */
.cal__dow{
  display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sp-1);
  margin-bottom:var(--sp-2);
}
.cal__dow span{
  text-align:center;font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3);padding-block:var(--sp-2);
}
.cal__grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--sp-1)}
.cal__day{
  position:relative;
  aspect-ratio:1;min-height:44px;min-width:0;
  display:grid;place-items:center;
  background:transparent;border:1px solid transparent;
  border-radius:var(--r-md);
  font-size:.94rem;font-variant-numeric:tabular-nums;
  color:var(--text);cursor:pointer;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease);
}
.cal__day:hover:not([disabled]){background:var(--surface-3);border-color:var(--line-strong)}
.cal__day[disabled]{color:var(--text-3);opacity:.4;cursor:not-allowed}
.cal__day[aria-pressed="true"]{
  background:var(--acid);color:var(--ink);font-weight:700;border-color:var(--acid);
}
/* Today gets a dot as well as a tint — never color alone. */
.cal__day.is-today::after{
  content:"";position:absolute;bottom:5px;left:50%;translate:-50% 0;
  width:4px;height:4px;border-radius:50%;background:var(--acid);
}
.cal__day[aria-pressed="true"].is-today::after{background:var(--ink)}
.cal__empty{aspect-ratio:1;min-height:44px}

@media (max-width:480px){
  .booking__cal,.booking__form{padding:var(--sp-4)}
  .cal__day,.cal__empty{aspect-ratio:auto;height:46px}
}

.cal__legend{
  display:flex;flex-wrap:wrap;gap:var(--sp-4);
  margin-top:var(--sp-5);padding-top:var(--sp-4);
  border-top:1px solid var(--line);
  font-size:.78rem;color:var(--text-3);
}
.cal__legend span{display:flex;align-items:center;gap:var(--sp-2)}
.swatch{width:10px;height:10px;border-radius:3px;flex:none}
.swatch--open{background:var(--acid)}
.swatch--closed{background:var(--surface-3);border:1px solid var(--line-strong)}

/* ---- Time slots ---- */
.slots{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-4)}
.slot{
  min-height:44px;padding:var(--sp-2) var(--sp-4);
  background:transparent;border:1px solid var(--line-strong);
  border-radius:var(--r-md);cursor:pointer;
  font-size:.9rem;font-variant-numeric:tabular-nums;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease);
}
.slot:hover:not([disabled]){border-color:var(--acid);color:var(--acid)}
.slot[aria-pressed="true"]{background:var(--acid);color:var(--ink);border-color:var(--acid);font-weight:700}
.slot[disabled]{opacity:.35;cursor:not-allowed;text-decoration:line-through}

.slots-empty{
  margin-top:var(--sp-4);padding:var(--sp-5);
  border:1px dashed var(--line-strong);border-radius:var(--r-md);
  color:var(--text-3);font-size:.9rem;text-align:center;
}

/* ---- Fields ---- */
.field{margin-bottom:var(--sp-5)}
.field>label,.fieldset>legend{
  display:block;margin-bottom:var(--sp-2);
  font-size:.86rem;font-weight:600;letter-spacing:.02em;
}
.req{color:var(--acid);margin-left:2px}
.hint{display:block;margin-top:var(--sp-2);font-size:.8rem;color:var(--text-3)}

.input,.select,.textarea{
  width:100%;min-height:48px;
  padding:var(--sp-3) var(--sp-4);
  background:var(--ink);
  border:1px solid var(--line-strong);
  border-radius:var(--r-md);
  transition:border-color var(--dur-fast) var(--ease),background var(--dur-fast) var(--ease);
}
.textarea{min-height:112px;resize:vertical;line-height:1.6}
.select{
  appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a8a86' 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 var(--sp-4) center;
  padding-right:var(--sp-8);
}
.input:hover,.select:hover,.textarea:hover{border-color:var(--line-strong)}
.input:focus,.select:focus,.textarea:focus{border-color:var(--acid)}
.input::placeholder,.textarea::placeholder{color:var(--text-3)}

/* Invalid state carries a border color, an icon and a message — never
   color on its own. */
.field[data-invalid] .input,
.field[data-invalid] .textarea{
  border-color:var(--danger);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23ff6b5e' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v6M12 16.5v.01'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right var(--sp-4) center;
  padding-right:var(--sp-8);
}
.field[data-invalid] .select{border-color:var(--danger)}
.error{
  display:none;align-items:center;gap:var(--sp-2);
  margin-top:var(--sp-2);font-size:.84rem;color:var(--danger);
}
.field[data-invalid] .error{display:flex}

.fieldset{border:0;padding:0;margin:0 0 var(--sp-5)}
.choices{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.choice{position:relative}
.choice input{
  position:absolute;inset:0;opacity:0;width:100%;height:100%;
  margin:0;cursor:pointer;
}
.choice span{
  display:block;min-height:44px;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  font-size:.9rem;
  transition:border-color var(--dur-fast) var(--ease),
             background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.choice input:hover+span{border-color:var(--acid)}
.choice input:focus-visible+span{outline:3px solid var(--acid);outline-offset:2px}
.choice input:checked+span{background:var(--acid);color:var(--ink);border-color:var(--acid);font-weight:600}

/* ---- Error summary ---- */
.summary{
  display:none;
  margin-bottom:var(--sp-5);padding:var(--sp-5);
  background:rgba(255,107,94,.09);
  border:1px solid var(--danger);border-radius:var(--r-md);
}
.summary.is-on{display:block}
.summary h3{font-size:1rem;margin-bottom:var(--sp-3);color:var(--danger)}
.summary ul{list-style:none;padding:0;display:grid;gap:var(--sp-2)}
.summary a{color:var(--text);font-size:.9rem}

/* ---- Review + success ---- */
.review{
  margin-bottom:var(--sp-5);padding:var(--sp-5);
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-md);
}
.review dl{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-2) var(--sp-5);font-size:.9rem}
.review dt{color:var(--text-3)}
.review dd{margin:0;font-weight:600}

.success{
  display:none;text-align:center;padding:var(--sp-7) var(--sp-5);
}
.success.is-on{display:block}
.success__mark{
  width:64px;height:64px;margin:0 auto var(--sp-5);
  display:grid;place-items:center;border-radius:50%;
  background:var(--acid-glow);color:var(--acid);
}
.success h3{margin-bottom:var(--sp-3)}
.success p{color:var(--text-2);max-width:44ch;margin-inline:auto}
.success .review{margin-top:var(--sp-6);text-align:left}

/* ============================================================
   11. GALLERY
   ============================================================ */
.filters{
  display:flex;flex-wrap:wrap;gap:var(--sp-2);
  margin-bottom:var(--sp-6);
}
.filter{
  min-height:44px;padding:var(--sp-2) var(--sp-4);
  background:transparent;border:1px solid var(--line-strong);
  border-radius:999px;cursor:pointer;font-size:.88rem;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.filter:hover{border-color:var(--acid);color:var(--acid)}
.filter[aria-pressed="true"]{background:var(--acid);color:var(--ink);border-color:var(--acid);font-weight:600}

.gallery{
  display:grid;gap:var(--sp-4);
  grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
}
.shot{
  position:relative;overflow:hidden;
  border-radius:var(--r-lg);border:1px solid var(--line);
  background:var(--surface-2);
}
.shot img{
  width:100%;aspect-ratio:4/3;object-fit:cover;
  transition:transform 620ms var(--ease);
}
.shot:hover img,.shot:focus-within img{transform:scale(1.035)}
.shot figcaption{
  position:absolute;inset:auto 0 0 0;
  padding:var(--sp-6) var(--sp-5) var(--sp-4);
  background:linear-gradient(180deg,transparent,rgba(10,10,11,.92) 62%);
}
.shot h3{font-size:1.02rem}
.shot p{font-size:.84rem;color:var(--text-2);margin-top:2px}
.shot .tag{
  display:inline-block;margin-bottom:var(--sp-2);
  padding:3px 9px;border-radius:999px;
  background:var(--acid);color:var(--ink);
  font-family:var(--font-display);font-weight:700;
  font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
}
.shot[hidden]{display:none}
@media (prefers-reduced-motion:reduce){
  .shot img{transition:none}
  .shot:hover img,.shot:focus-within img{transform:none}
}

.gallery-empty{
  padding:var(--sp-8) var(--sp-5);text-align:center;
  color:var(--text-3);border:1px dashed var(--line-strong);
  border-radius:var(--r-lg);
}

/* ============================================================
   12. CONTACT
   ============================================================ */
.contact-hero{position:relative;overflow:hidden;isolation:isolate}
.contact-hero__media{position:absolute;inset:0;z-index:-2}
.contact-hero__media img,
.contact-hero__media video{
  width:100%;height:100%;object-fit:cover;
}
.contact-hero__media video{position:absolute;inset:0}
.contact-hero::after{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg,rgba(10,10,11,.72),rgba(10,10,11,.94));
}
.contact-hero .wrap{padding-block:clamp(var(--sp-8),12vw,var(--sp-10))}

.contact-list{display:grid;gap:var(--sp-5)}
.contact-item{
  display:flex;gap:var(--sp-4);align-items:flex-start;
  padding-block:var(--sp-4);border-top:1px solid var(--line);
}
.contact-item .card__icon{margin-bottom:0}
.contact-item h3{font-size:.82rem;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);font-weight:700}
.contact-item p,.contact-item a{margin-top:var(--sp-1);font-size:1.02rem;color:var(--text)}
.contact-item .sub{font-size:.86rem;color:var(--text-3);margin-top:2px}

.hours{width:100%;border-collapse:collapse;font-size:.94rem}
.hours th,.hours td{padding:var(--sp-3) 0;text-align:left;border-bottom:1px solid var(--line)}
.hours th{font-weight:500;color:var(--text-2)}
.hours td{text-align:right;font-variant-numeric:tabular-nums;color:var(--text)}
.hours tr:last-child th,.hours tr:last-child td{border-bottom:0}
.hours .closed{color:var(--text-3)}

/* ============================================================
   13. FOOTER
   ============================================================ */
.site-footer{
  border-top:1px solid var(--line);
  background:var(--surface);
  padding-block:var(--sp-8) var(--sp-6);
  margin-top:var(--sp-4);
}
.footer-grid{
  display:grid;gap:var(--sp-7);
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  margin-bottom:var(--sp-7);
}
.footer-grid h3{
  font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-3);margin-bottom:var(--sp-4);font-weight:700;
}
.footer-grid ul{display:grid;gap:var(--sp-3)}
.footer-grid a{font-size:.94rem;color:var(--text-2);text-decoration:none}
.footer-grid a:hover{color:var(--acid)}
.footer-bar{
  display:flex;flex-wrap:wrap;gap:var(--sp-3) var(--sp-5);
  align-items:center;justify-content:space-between;
  padding-top:var(--sp-5);border-top:1px solid var(--line);
  font-size:.82rem;color:var(--text-3);
}
.footer-bar a{color:var(--text-2)}
.footer-note{
  margin-top:var(--sp-4);font-size:.78rem;color:var(--text-3);
  max-width:80ch;line-height:1.6;
}

/* ============================================================
   14. COOKIE BANNER
   ============================================================ */
.cookie{
  position:fixed;inset:auto var(--sp-4) var(--sp-4) var(--sp-4);
  z-index:var(--z-overlay);
  max-width:460px;margin-inline:auto;
  background:var(--surface-2);
  border:1px solid var(--line-strong);
  border-radius:var(--r-lg);
  padding:var(--sp-5);
  box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.cookie[hidden]{display:none}
.cookie h2{font-size:1.02rem;margin-bottom:var(--sp-3)}
.cookie p{font-size:.88rem;color:var(--text-2);margin-bottom:var(--sp-4)}
/* Accept and decline carry equal visual weight. Nothing here is
   pre-selected and neither choice is hidden or de-emphasised. */
.cookie__actions{display:flex;flex-wrap:wrap;gap:var(--sp-3)}
.cookie__actions .btn{flex:1 1 140px}
@media (min-width:900px){
  .cookie{left:auto;right:var(--sp-5);bottom:var(--sp-5);margin-inline:0}
}

/* ============================================================
   15. LEGAL / PROSE PAGES
   ============================================================ */
.prose{max-width:72ch}
.prose h2{font-size:clamp(1.35rem,2.4vw,1.7rem);margin-top:var(--sp-7);margin-bottom:var(--sp-4)}
.prose h3{margin-top:var(--sp-5);margin-bottom:var(--sp-3)}
.prose p,.prose li{color:var(--text-2)}
.prose p+p{margin-top:var(--sp-4)}
.prose ul{list-style:disc;padding-left:1.3em;margin-top:var(--sp-4);display:grid;gap:var(--sp-2)}
.prose a{color:var(--acid)}
.prose .updated{font-size:.86rem;color:var(--text-3)}

.callout{
  margin-top:var(--sp-5);padding:var(--sp-5);
  border:1px solid var(--line-strong);border-left:3px solid var(--acid);
  border-radius:var(--r-md);background:var(--surface);
}
.callout p{color:var(--text-2);font-size:.92rem}

/* ============================================================
   16. BREADCRUMB
   ============================================================ */
.crumbs{font-size:.84rem;color:var(--text-3);margin-bottom:var(--sp-5)}
.crumbs ol{display:flex;flex-wrap:wrap;gap:var(--sp-2);list-style:none;padding:0}
.crumbs li+li::before{content:"/";margin-right:var(--sp-2);color:var(--line-strong)}
.crumbs a{color:var(--text-2);text-decoration:none}
.crumbs a:hover{color:var(--acid)}

/* ============================================================
   17. NO-JS FALLBACK
   Without JS the hero cannot scrub, so a 340vh section would be
   three screens of a single motionless frame. Collapse it to the
   same static presentation reduced-motion users get.
   ============================================================ */
html:not(.js) .hero{height:auto}
html:not(.js) .hero__stage{position:relative;height:auto;min-height:0}
html:not(.js) .hero__frames{position:relative;height:min(72svh,560px)}
html:not(.js) .hero__frames img{opacity:0}
html:not(.js) .hero__frames img:last-child{opacity:1}
html:not(.js) .hero__frames img:first-child{opacity:0}
html:not(.js) .hero__rail{display:none}
/* The calendar is script-driven; say so rather than showing an empty grid. */
html:not(.js) [data-booking] .booking__cal::after{
  content:"The date picker needs JavaScript. Call or email us and we will book you in directly.";
  display:block;margin-top:var(--sp-4);color:var(--text-2);font-size:.92rem;
}

/* ============================================================
   18. SECTION WITH VIDEO BACKGROUND
   Used by the Process section. The media sits on its own layer
   below the content, and the section paints a scrim over it that
   runs to solid --ink at the top and bottom edges, so the video
   dissolves into the page instead of ending on a hard seam.
   ============================================================ */
.section--media{position:relative;isolation:isolate;overflow:hidden}

.section-bg{position:absolute;inset:0;z-index:-2}
.section-bg img,
.section-bg video{
  width:100%;height:100%;
  object-fit:cover;
}
.section-bg video{position:absolute;inset:0}

/* The scrim is set from measurement, not by eye. The brightest pixel in the
   clip is 236/255; --text-2 (the step paragraphs) needs 4.5:1 against the
   composite of that pixel and this overlay, which puts the hard floor at
   alpha .735. .76 is used in the middle, giving 5.08:1 with margin to spare,
   and .82 at the edges where the fade to solid --ink begins. Do not raise the
   video's visibility past this without re-checking the ratio. */
.section--media::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(180deg,
      var(--ink) 0%,
      rgba(10,10,11,.82) 12%,
      rgba(10,10,11,.76) 50%,
      rgba(10,10,11,.82) 88%,
      var(--ink) 100%);
}

/* A decorative background video has no pause control, so anyone who has
   asked the system for less motion gets the still poster instead. The
   poster is a real <img> underneath, so nothing goes blank. */
@media (prefers-reduced-motion:reduce){
  .section-bg video,
  .contact-hero__media video{display:none}
}

/* ============================================================
   19. STICKY-HEADER ANCHOR OFFSET
   The header is sticky, so anything scrolled to by an in-page
   link or by scrollIntoView() would otherwise come to rest
   underneath it. Applied to every element carrying an id, which
   deliberately includes form fields: when the booking error
   summary sends focus to an invalid input, that input must not
   land behind the header either (WCAG 2.2 "focus not obscured").
   ============================================================ */
[id]{scroll-margin-top:calc(var(--header-h) + var(--sp-5))}

/* ============================================================
   20. INTERACTION STATES
   Every control gets both a hover and a pressed state.

   Hover styling sits behind @media (hover:hover) so a touch
   device does not leave a "hovered" look stuck on whatever was
   tapped last — on a phone :hover latches until you tap
   elsewhere, which reads as a selection that isn't there.

   Pressed states change color AND scale. The scale is a
   transform, so it never reflows neighbouring content under a
   finger, and it is dropped entirely under reduced-motion at
   the end of this block while the color change stays — so the
   feedback survives without the movement.
   ============================================================ */

/* ---- Buttons ---- */
.btn--primary:active{background:var(--acid-dim)}
.btn--ghost:active{
  background:rgba(255,255,255,.06);
  border-color:var(--acid);color:var(--acid);
}

/* ---- Header: menu toggle ---- */
@media (hover:hover){
  .nav-toggle:hover{border-color:var(--acid);color:var(--acid)}
}
.nav-toggle{transition:background var(--dur-fast) var(--ease),
                       border-color var(--dur-fast) var(--ease),
                       color var(--dur-fast) var(--ease),
                       transform var(--dur-fast) var(--ease)}
.nav-toggle:active{
  background:rgba(255,255,255,.07);
  border-color:var(--acid);color:var(--acid);
  transform:scale(.97);
}

/* ---- Navigation links ---- */
.nav a:active{color:var(--acid)}
@media (hover:hover){
  .mobile-nav a:not(.btn):hover{color:var(--acid)}
}
.mobile-nav a:not(.btn){transition:color var(--dur-fast) var(--ease),
                                   background var(--dur-fast) var(--ease)}
.mobile-nav a:not(.btn):active{color:var(--acid);background:rgba(255,255,255,.05)}

/* ---- Calendar ---- */
.cal__nav button{transition:border-color var(--dur-fast) var(--ease),
                            color var(--dur-fast) var(--ease),
                            background var(--dur-fast) var(--ease),
                            transform var(--dur-fast) var(--ease)}
.cal__nav button:active:not([disabled]){
  background:var(--acid-glow);border-color:var(--acid);color:var(--acid);
  transform:scale(.94);
}
.cal__day{transition:background var(--dur-fast) var(--ease),
                     border-color var(--dur-fast) var(--ease),
                     color var(--dur-fast) var(--ease),
                     transform var(--dur-fast) var(--ease)}
.cal__day:active:not([disabled]){
  background:var(--acid-glow);border-color:var(--acid);
  transform:scale(.92);
}

/* ---- Time slots and filters ---- */
.slot{transition:background var(--dur-fast) var(--ease),
                 border-color var(--dur-fast) var(--ease),
                 color var(--dur-fast) var(--ease),
                 transform var(--dur-fast) var(--ease)}
.slot:active:not([disabled]){
  background:var(--acid-glow);border-color:var(--acid);color:var(--acid);
  transform:scale(.96);
}
.filter{transition:background var(--dur-fast) var(--ease),
                   border-color var(--dur-fast) var(--ease),
                   color var(--dur-fast) var(--ease),
                   transform var(--dur-fast) var(--ease)}
.filter:active{
  background:var(--acid-glow);border-color:var(--acid);color:var(--acid);
  transform:scale(.96);
}

/* ---- Radio chips ---- */
.choice span{transition:border-color var(--dur-fast) var(--ease),
                        background var(--dur-fast) var(--ease),
                        color var(--dur-fast) var(--ease),
                        transform var(--dur-fast) var(--ease)}
.choice input:active + span{
  background:var(--acid-glow);border-color:var(--acid);
  transform:scale(.97);
}

/* ---- Text links ---- */
@media (hover:hover){
  .prose a:hover,
  .contact-item a:hover{color:var(--acid)}
}
.prose a,.contact-item a{transition:color var(--dur-fast) var(--ease)}
.footer-grid a:active,
.utility a:active,
.crumbs a:active,
.prose a:active,
.contact-item a:active{color:var(--acid-dim)}

/* ---- Card used as a link (404 page) ---- */
.card{transition:border-color var(--dur) var(--ease),
                 background var(--dur) var(--ease),
                 transform var(--dur-fast) var(--ease)}
a.card:active{
  border-color:var(--acid);background:var(--surface-3);
  transform:scale(.99);
}

/* ---- Skip link ---- */
@media (hover:hover){
  .skip-link:hover{background:#d3ff52}
}
.skip-link:active{background:var(--acid-dim)}

/* ---- Motion opt-out ----
   Color feedback is kept; only the movement is removed. */
@media (prefers-reduced-motion:reduce){
  .btn:active,
  .nav-toggle:active,
  .cal__nav button:active:not([disabled]),
  .cal__day:active:not([disabled]),
  .slot:active:not([disabled]),
  .filter:active,
  .choice input:active + span,
  a.card:active{transform:none}
}
