/* ============================================================================
   THE WANDERBODY ALCHEMIST — traveling massage & bodywork
   Tokens live unlayered on :root so they beat the engine's @layer sw defaults.

   Two things separate this palette from a spa template, and both are load-
   bearing rather than decorative:

   1. CHARCOAL IS A SURFACE, not only ink. `.band--alt` is a dark ground, so
      the page alternates light and dark instead of running sand on sand from
      top to bottom.
   2. THE ACCENT EXISTS IN THREE WEIGHTS. One colour cannot be both a brand
      accent and readable small text. Every pair below is measured — run
      `python3 build/palettecheck.py` after touching any of them; it reads the
      values straight out of this file and needs no browser.
   ========================================================================== */

:root,
.sw-root {
  /* -- light surfaces ---------------------------------------------------- */
  --sand:#EDE6DA;
  --sand-deep:#E3D9C9;
  --cream:#F7F3EC;
  --clay:#E7DBCB;

  /* -- dark surfaces ----------------------------------------------------- */
  /* --ink stays the text charcoal it always was. --char is the same family
     promoted to a background, with --char-soft one step up for hover. */
  --char:#242220;
  --char-soft:#302C27;
  --cream-soft:#BFB8AC;      /* body text on a charcoal ground — 8.05:1 on --char */

  /* -- the accent, in three weights -------------------------------------- */
  /*  --gold       2.49:1 on sand — DECORATION ONLY. Strokes, borders, rules,
                   the mark, the spinner. Never small text on a light ground.
      --gold-ink   4.54:1 worst case across every light surface — the text
                   weight. Eyebrows, meta, captions.
      --gold-lift  5.79:1 worst case on charcoal — the same accent for text
                   sitting ON a dark ground, where it must go lighter rather
                   than darker.
     Gold is used sparingly by design: hairlines, one rule, the mark. It is
     never a fill. */
  --gold:#B08D57;
  --gold-ink:#7A5A22;
  --gold-lift:#C6A26A;

  --terra:#884924;
  --ink:#2A2724;
  --ink-soft:#625A50;
  --line:rgba(42,39,36,.14);
  --line-lift:rgba(247,243,236,.18);   /* the same hairline, on a dark ground */

  --serif:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,system-ui,sans-serif;

  /* engine overrides */
  --sw-bg:var(--sand);
  --sw-ink:var(--ink);
  --sw-ink-soft:var(--ink-soft);
  --sw-accent:var(--gold);
  --sw-font-display:var(--serif);
  --sw-font-body:var(--sans);
}

*,*::before,*::after{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{margin:0;background:var(--sand);color:var(--ink);font-family:var(--sans);
  font-weight:300;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden;}
img{max-width:100%;display:block;}
a{color:inherit;}

.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;}
.skip{position:absolute;left:-999px;top:0;z-index:200;background:var(--ink);color:var(--cream);
  padding:12px 20px;border-radius:0 0 6px 0;}
.skip:focus{left:0;}
/* The ink weight, not the decorative one: a focus ring at 2.49:1 is a focus
   ring you cannot find on a sand background. */
:focus-visible{outline:2px solid var(--gold-ink);outline-offset:3px;}

/* ---------------------------------------------------------------- shared -- */
.wrap{width:min(1180px,90vw);margin-inline:auto;}
.wrap--narrow{width:min(780px,90vw);}
.center{text-align:center;}
.center .lede{margin-inline:auto;}

.eyebrow{font-family:var(--sans);font-size:.72rem;font-weight:500;letter-spacing:.22em;
  text-transform:uppercase;color:var(--gold-ink);margin:0 0 18px;}

.h2{font-family:var(--serif);font-weight:300;font-size:clamp(2.1rem,4.6vw,3.6rem);
  line-height:1.08;letter-spacing:-.01em;margin:0;}

.lede{font-size:clamp(1.02rem,1.35vw,1.2rem);line-height:1.72;color:var(--ink-soft);
  max-width:62ch;margin:22px 0 0;}

.btn{display:inline-block;font-family:var(--sans);font-size:.86rem;font-weight:500;
  letter-spacing:.06em;text-decoration:none;padding:15px 32px;border-radius:999px;
  transition:transform .3s cubic-bezier(.2,.7,.3,1),background .3s,color .3s,border-color .3s;}
.btn--solid{background:var(--ink);color:var(--cream);border:1px solid var(--ink);}
.btn--solid:hover{background:var(--gold-ink);border-color:var(--gold-ink);transform:translateY(-2px);}
.btn--ghost{border:1px solid var(--line);color:var(--ink);}
.btn--ghost:hover{border-color:var(--ink);transform:translateY(-2px);}

.lnk{display:inline-block;margin-top:22px;font-size:.82rem;font-weight:500;letter-spacing:.06em;
  text-decoration:none;color:var(--ink);border-bottom:1px solid var(--gold);padding-bottom:3px;
  transition:color .3s,border-color .3s;}
.lnk:hover{color:var(--gold-ink);}

/* ---------------------------------------------------------------- header -- */
.hdr{position:fixed;inset:0 0 auto;z-index:70;display:flex;align-items:center;
  justify-content:space-between;gap:24px;padding:22px clamp(20px,5vw,58px);
  transition:background .45s,backdrop-filter .45s,padding .45s,box-shadow .45s;}
.hdr.is-stuck:not(.is-dark){background:color-mix(in srgb,var(--sand) 88%,transparent);
  backdrop-filter:blur(14px);padding-block:13px;box-shadow:0 1px 0 var(--line);}
.hdr.is-stuck{padding-block:13px;}

/* Over the film and the two ink-coloured sections the header must invert, or
   the wordmark sits invisible on top of a dark photograph. */
.hdr.is-dark{color:var(--cream);
  background:linear-gradient(180deg,rgba(22,19,16,.52),rgba(22,19,16,0));}
.hdr.is-dark .hdr__nav a{color:color-mix(in srgb,var(--cream) 76%,transparent);}
.hdr.is-dark .hdr__nav a:hover{color:var(--cream);}
.hdr.is-dark .mark{stroke:var(--cream);}
.hdr.is-dark .mark__core{fill:var(--cream);}
.hdr.is-dark .hdr__burger span{background:var(--cream);}
.hdr.is-dark .btn--solid{background:var(--cream);color:var(--ink);border-color:var(--cream);}
.hdr.is-dark .btn--solid:hover{background:var(--gold-ink);border-color:var(--gold-ink);color:var(--cream);}

.hdr__brand{display:flex;align-items:center;gap:11px;text-decoration:none;}
.mark{width:26px;height:26px;flex:none;fill:none;stroke:var(--gold);stroke-width:1.3;
  stroke-linecap:round;}
.mark__core{fill:var(--gold);stroke:none;}
/* Twenty-four uppercase characters where the previous brand had nine. The
   tracking and size below are what mobileqa.py measured as fitting inside a
   390px viewport that also has to hold the burger — the two-line lockup in the
   phone rules at the bottom of this file is the rest of that fix. Shortening
   the name is not an option; it is the brand. */
.hdr__word{font-family:var(--serif);font-size:1.06rem;font-weight:400;letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap;line-height:1.15;}

.hdr__nav{display:flex;gap:clamp(16px,2.2vw,32px);}
.hdr__nav a{position:relative;font-size:.8rem;font-weight:400;letter-spacing:.1em;
  text-transform:uppercase;text-decoration:none;color:var(--ink-soft);transition:color .3s;}
.hdr__nav a::after{content:"";position:absolute;left:0;right:0;bottom:-6px;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:0 50%;transition:transform .35s;}
.hdr__nav a:hover{color:var(--ink);} .hdr__nav a:hover::after{transform:scaleX(1);}
.hdr__cta{padding:11px 26px;font-size:.78rem;}

.hdr__burger{display:none;width:42px;height:42px;border:0;background:none;cursor:pointer;
  padding:0;place-items:center;gap:6px;flex-direction:column;}
.hdr__burger span{display:block;width:22px;height:1px;background:var(--ink);transition:transform .35s,opacity .3s;}
.hdr__burger[aria-expanded="true"] span:first-child{transform:translateY(3.5px) rotate(45deg);}
.hdr__burger[aria-expanded="true"] span:last-child{transform:translateY(-3.5px) rotate(-45deg);}

.mnav{position:fixed;inset:0;z-index:69;display:flex;flex-direction:column;justify-content:center;
  gap:6px;padding:0 12vw;background:var(--sand);}
.mnav[hidden]{display:none;}
.mnav a{font-family:var(--serif);font-size:2.1rem;font-weight:300;text-decoration:none;
  padding:12px 0;border-bottom:1px solid var(--line);}

/* ------------------------------------------------------- engine restyle --- */
#world{position:relative;z-index:1;}
.sw-topbar{display:none;}
.sw-copy__title{font-family:var(--serif);font-weight:300;letter-spacing:-.01em;
  font-size:clamp(2.3rem,5.2vw,4.2rem);line-height:1.04;text-shadow:none;}
.sw-copy__eyebrow{font-family:var(--sans);font-weight:500;font-size:.72rem;letter-spacing:.22em;color:var(--gold-ink);}
.sw-copy__num{color:color-mix(in srgb,var(--ink-soft) 70%,transparent);}
.sw-copy__body{font-weight:300;text-shadow:none;color:var(--ink-soft);}
.sw-copy__tags li{background:transparent;border:1px solid var(--line);color:var(--ink-soft);
  font-weight:400;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;border-radius:0;
  padding:8px 15px;}
/* `a{color:inherit}` above is unlayered, so it beats the engine's layered
   button colours — these buttons must therefore state their colour outright. */
.sw-copy__cta .sw-btn{font-family:var(--sans);font-size:.86rem;font-weight:500;letter-spacing:.06em;
  padding:15px 32px;}
.sw-copy__cta .sw-btn--primary{background:var(--ink);color:var(--cream);border:1px solid var(--ink);}
.sw-copy__cta .sw-btn--primary:hover{background:var(--gold-ink);border-color:var(--gold-ink);color:var(--cream);}
.sw-copy__cta .sw-btn--ghost{border:1px solid var(--line);color:var(--ink);}
.sw-copy__cta .sw-btn--ghost:hover{border-color:var(--ink);}

/* The engine writes an inline `transform` every frame, which would wipe out a
   CSS translateY(-50%). `translate` is a separate property, so the centring
   survives and the engine's parallax offset still composes on top. */
@media (min-width:861px){
  .sw-copy{translate:0 -50%;}
}

.sw-copylayer::before{width:min(64vw,860px);
  background:linear-gradient(90deg,var(--sand) 0%,color-mix(in srgb,var(--sand) 78%,transparent) 38%,
    color-mix(in srgb,var(--sand) 32%,transparent) 68%,transparent 100%);}
/* The hint sits over open picture, not over the copy scrim, so it carries its
   own halo rather than relying on whatever frame is behind it. */
.sw-hint{font-size:.68rem;letter-spacing:.24em;
  text-shadow:0 1px 10px color-mix(in srgb,var(--sand) 92%,transparent),
              0 0 22px color-mix(in srgb,var(--sand) 70%,transparent);}
.sw-scene__video,.sw-scene__still{object-position:center 40%;}

/* The engine's layers are fixed, so once the film is behind us they must stop
   painting over the rest of the page (and stop animating particles). */
.film-done .sw-stage,.film-done .sw-copylayer,.film-done .sw-route,
.film-done .sw-hint,.film-done .sw-sky,.film-done .sw-scrollbar{
  opacity:0;visibility:hidden;transition:opacity .45s,visibility .45s;}

/* ------------------------------------------------------------------ page -- */
.page{position:relative;z-index:30;background:var(--sand);}
.band{padding:clamp(88px,13vh,150px) 0;}
.band--cream{background:var(--cream);}
.band--clay{background:var(--clay);}
.band__head{margin-bottom:clamp(44px,6vw,72px);}

/* ---------------------------------------------------- the charcoal ground -- */
/* Everything below re-weights a component that was written for a light band.
   The colour is set on the container so plain prose inherits it; only the
   components that hard-code a colour of their own need naming. */
.band--alt{background:var(--char);color:var(--cream-soft);}
.band--alt .h2,.band--alt h3,.band--alt strong{color:var(--cream);}
.band--alt .eyebrow{color:var(--gold-lift);}
.band--alt .lede{color:var(--cream-soft);}
.band--alt .pillars h3{border-top-color:var(--line-lift);}
.band--alt .pillars p{color:var(--cream-soft);}
.band--alt .chips li{color:var(--cream-soft);border-color:var(--line-lift);}
.band--alt .creds li{color:var(--cream-soft);border-top-color:var(--line-lift);}
.band--alt .flow li{border-top-color:var(--line-lift);}
.band--alt .flow li::after{background:var(--gold-lift);}
.band--alt .flow span{color:var(--gold-lift);}
.band--alt .flow p{color:var(--cream-soft);}
.band--alt .split__media figcaption{color:var(--cream-soft);}
.band--alt .lnk{color:var(--cream);border-bottom-color:var(--gold-lift);}
.band--alt .lnk:hover{color:var(--gold-lift);}
.band--alt .btn--solid{background:var(--cream);color:var(--char);border-color:var(--cream);}
.band--alt .btn--solid:hover{background:var(--gold-lift);border-color:var(--gold-lift);color:var(--char);}
.band--alt .btn--ghost{border-color:var(--line-lift);color:var(--cream);}
.band--alt .btn--ghost:hover{border-color:var(--cream);}
.band--alt :focus-visible{outline-color:var(--gold-lift);}

/* ------------------------------------------------------- the introduction -- */
.intro{padding:clamp(110px,18vh,200px) 0;}
.intro__line{font-family:var(--serif);font-weight:300;line-height:1.32;
  font-size:clamp(1.45rem,3.4vw,2.5rem);margin:0 0 16px;color:var(--cream);}
.intro__line--last{color:var(--gold-lift);}
/* The one large typographic moment on the page. Set in the accent's lift
   weight, which clears 5.79:1 on charcoal — it is enormous, but it is still
   text and still has to be readable. */
.intro__big{font-family:var(--serif);font-weight:300;text-transform:uppercase;
  font-size:clamp(3rem,15vw,10rem);line-height:1;letter-spacing:.08em;
  margin:clamp(46px,8vw,96px) 0;color:var(--gold-lift);}
.intro__deny{font-family:var(--serif);font-weight:300;line-height:1.55;
  font-size:clamp(1.35rem,3vw,2.1rem);margin:0;color:var(--cream);}

/* ----------------------------------------------------------- the journey --- */
/* A single line down the page with seven moments along it. The line is drawn
   by site.js at real pixel dimensions (so the stroke never distorts); until it
   does, and whenever JS is unavailable, the ::before hairline stands in. The
   seven words are ordinary markup and never depend on either. */
.road{position:relative;background:var(--sand);
  padding:clamp(100px,15vh,170px) 0;overflow:hidden;}
.road__line{position:absolute;inset:0;pointer-events:none;}
.road__line::before{content:"";position:absolute;left:50%;top:8%;bottom:8%;width:1px;
  background:var(--gold);opacity:.55;transition:opacity .5s;}
.road__line svg{position:absolute;inset:0;width:100%;height:100%;opacity:0;
  transition:opacity .5s;}
.road.is-drawn .road__line::before{opacity:0;}
.road.is-drawn .road__line svg{opacity:1;}
.road__path{fill:none;stroke:var(--gold);stroke-width:1.3;stroke-linecap:round;}

.road__head{position:relative;z-index:2;text-align:center;
  margin:0 0 clamp(54px,9vw,100px);}
.road__steps{list-style:none;margin:0;padding:0;position:relative;z-index:2;
  display:grid;gap:clamp(44px,8vh,104px);}
.road__step{display:flex;}
.road__step:nth-child(even){justify-content:flex-end;}
/* The word knocks a hole in the line rather than sitting on top of it. */
.road__step span{font-family:var(--serif);font-weight:300;letter-spacing:-.01em;
  font-size:clamp(2rem,6.2vw,4rem);line-height:1;background:var(--sand);
  padding:8px 20px;}

/* --------------------------------------------------------- the story band -- */
.story__verse{font-family:var(--serif);font-weight:300;font-style:italic;
  font-size:clamp(1.5rem,3.4vw,2.5rem);line-height:1.45;margin:0 0 30px;color:var(--ink);}

/* ------------------------------------------------------------- the pillars -- */
.pillars{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:clamp(28px,4vw,54px);margin:clamp(48px,7vw,80px) 0 0;padding:0;text-align:left;}
.pillars h3{font-family:var(--serif);font-weight:400;font-size:1.5rem;margin:0 0 10px;
  padding-top:20px;border-top:1px solid var(--line);}
.pillars p{margin:0;color:var(--ink-soft);font-size:.96rem;}

/* --------------------------------------------------- services as chapters -- */
/* Three chapters across, then the fourth full width. The fourth is not a
   fourth product — it is the condition the other three are delivered under —
   so it carries no ladder and no CTA, and the layout says so. */
.chapters{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);
  gap:1px;margin:0;padding:0;background:var(--line-lift);
  border-block:1px solid var(--line-lift);}
.chapter{background:var(--char);padding:clamp(30px,3.2vw,46px);
  display:flex;flex-direction:column;align-items:flex-start;transition:background .45s;}
.chapter:hover{background:var(--char-soft);}
.chapter--wide{grid-column:1 / -1;}
.chapter__n{font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--gold-lift);margin:0;}
.chapter__name{font-family:var(--serif);font-weight:400;line-height:1.12;
  font-size:clamp(1.7rem,2.6vw,2.3rem);margin:14px 0 10px;}
.chapter__head{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:1.15rem;line-height:1.4;margin:0 0 16px;color:var(--gold-lift);}
.chapter p{margin:0;font-size:.96rem;color:var(--cream-soft);}
.chapter__where{margin-top:20px !important;font-size:.74rem !important;letter-spacing:.12em;
  text-transform:uppercase;color:var(--cream-soft);}
.chapter .lnk{margin-top:auto;padding-top:26px;}
.chapter__pull{font-family:var(--serif);font-style:italic;font-weight:300;
  font-size:clamp(1.4rem,3vw,2.1rem) !important;line-height:1.4;
  margin-top:28px !important;color:var(--cream) !important;}

.ladder{list-style:none;margin:24px 0 0;padding:0;width:100%;}
.ladder li{display:grid;grid-template-columns:auto 1fr auto;gap:2px 16px;align-items:baseline;
  padding:11px 0;border-top:1px solid var(--line-lift);}
.ladder__d{font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cream);white-space:nowrap;}
.ladder__w{font-size:.9rem;color:var(--cream-soft);}
/* The price slot: built, styled, and deliberately empty until real numbers
   exist. An empty one takes no space at all rather than leaving a gap. */
.ladder__p{font-size:.82rem;color:var(--gold-lift);white-space:nowrap;}
.ladder__p:empty{display:none;}

/* ------------------------------------------------------ the alchemy of touch -- */
.touch__big{font-family:var(--serif);font-weight:300;text-transform:uppercase;
  font-size:clamp(3.4rem,16vw,11rem);line-height:1;letter-spacing:.06em;
  margin:0 0 clamp(30px,5vw,54px);color:var(--ink);}
.touch__parts{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;
  gap:10px 0;margin:0;padding:0;}
.touch__parts li{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.25rem,2.8vw,1.9rem);line-height:1.3;padding:0 clamp(14px,2.2vw,26px);
  border-right:1px solid var(--line);}
.touch__parts li:last-child{border-right:0;}

/* ---------------------------------------------------------- split blocks -- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(36px,6vw,88px);align-items:center;}
.split--rev .split__media{order:-1;}
.split__media{margin:0;position:relative;}
.split__media img{width:100%;height:100%;object-fit:cover;aspect-ratio:4/3;}
.split__media figcaption{margin-top:12px;font-size:.75rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);}
.split__copy .btn{margin-top:34px;}
.portrait img{aspect-ratio:3/4;object-position:center 30%;}

.chips{list-style:none;display:flex;flex-wrap:wrap;gap:9px;margin:30px 0 0;padding:0;}
.chips li{font-size:.75rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);
  border:1px solid var(--line);padding:8px 15px;}

/* event flow: SETUP -> ARRIVAL -> MASSAGE -> RESET -> RETURN */
.flow{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:clamp(24px,3vw,40px);margin:clamp(60px,9vw,110px) 0 0;padding:0;}
.flow li{position:relative;padding-top:26px;border-top:1px solid var(--line);}
.flow li::after{content:"";position:absolute;top:-4px;left:0;width:7px;height:7px;
  border-radius:50%;background:var(--gold);}
.flow span{font-size:.72rem;letter-spacing:.2em;color:var(--gold-ink);}
.flow h3{font-family:var(--serif);font-weight:400;font-size:1.35rem;margin:8px 0 8px;}
.flow p{margin:0;font-size:.9rem;color:var(--ink-soft);}

/* ------------------------------------------------------ no permanent walls -- */
/* An abstract route, not a map. A map reads as a logistics company with a
   coverage area; a route reads as a journey. */
.route{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:clamp(14px,3vw,30px);margin:clamp(40px,6vw,66px) 0 0;padding:0;}
.route li{position:relative;font-family:var(--serif);font-weight:300;
  font-size:clamp(1.4rem,3.4vw,2.4rem);line-height:1.2;}
.route li+li::before{content:"→";display:inline-block;margin-right:clamp(14px,3vw,30px);
  color:var(--gold-ink);font-family:var(--sans);font-size:.55em;vertical-align:middle;}
.walls__now{margin:clamp(44px,6vw,70px) 0 0;font-size:.96rem;color:var(--ink-soft);}
.walls__where{margin:8px 0 0;font-family:var(--sans);font-size:.78rem;font-weight:500;
  letter-spacing:.2em;text-transform:uppercase;color:var(--gold-ink);}

/* ---------------------------------------------------------------- gallery -- */
.gallery{list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:clamp(18px,2.5vw,34px);margin:0;padding:0;}
.gallery li{position:relative;overflow:hidden;}
.gallery img{width:100%;aspect-ratio:16/10;object-fit:cover;transition:transform 1.1s cubic-bezier(.2,.7,.3,1);}
.gallery li:hover img{transform:scale(1.04);}
.gallery span{position:absolute;left:18px;bottom:16px;color:var(--cream);font-size:.74rem;
  letter-spacing:.2em;text-transform:uppercase;text-shadow:0 1px 12px rgba(0,0,0,.6);}

/* ----------------------------------------------------------- testimonials -- */
/* One at a time, large, like a line copied out of a travel journal. A second
   one is one more <figure>; nothing here counts them. */
.testi__one{margin:clamp(30px,5vw,54px) auto 0;max-width:60ch;}
.testi__one blockquote{font-family:var(--serif);font-weight:300;font-style:italic;
  font-size:clamp(1.6rem,4vw,2.8rem);line-height:1.32;margin:0;letter-spacing:-.01em;}
.testi__one figcaption{margin-top:24px;font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);}
/* Emoji and the closing quote mark travel together, or the line breaks leave a
   single glyph stranded on a line of its own under a centred pull-quote. */
.testi__emo{white-space:nowrap;}

/* ------------------------------------------------------------ credentials -- */
.creds{list-style:none;margin:34px 0 0;padding:0;}
.creds li{padding:14px 0;border-top:1px solid var(--line);font-size:.9rem;color:var(--ink-soft);}
.creds strong{font-weight:500;color:var(--ink);}

/* --------------------------------------------------------------- the kit -- */
.kit__list{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:0 clamp(30px,5vw,64px);}
.kit__list li{display:flex;flex-direction:column;gap:6px;
  padding:22px 0;border-top:1px solid var(--line);}
.kit__t{font-family:var(--serif);font-weight:400;font-size:1.4rem;line-height:1.2;}
.kit__d{font-size:.92rem;color:var(--ink-soft);}

/* ------------------------------------------------------------------ form -- */
.direct{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;
  margin:0 0 clamp(48px,6vw,72px);}
.direct .btn[hidden],.foot__links li[hidden]{display:none;}

/* booking tabs */
.tabs{display:flex;justify-content:center;gap:6px;margin:0 0 clamp(30px,4vw,44px);
  padding:5px;border:1px solid var(--line);border-radius:999px;width:fit-content;
  margin-inline:auto;background:color-mix(in srgb,var(--cream) 55%,transparent);}
.tabs__t{font:inherit;font-size:.8rem;font-weight:500;letter-spacing:.06em;color:var(--ink-soft);
  border:0;background:transparent;cursor:pointer;padding:11px 22px;border-radius:999px;
  transition:color .3s,background .3s;white-space:nowrap;}
.tabs__t:hover{color:var(--ink);}
.tabs__t[aria-selected="true"]{background:var(--ink);color:var(--cream);}
.tabs__t[hidden]{display:none;}

.panel[hidden]{display:none;}
.cal{border:1px solid var(--line);background:var(--cream);overflow:hidden;min-height:120px;}
.cal iframe{display:block;width:100%;height:min(760px,86vh);border:0;}
.cal__note{margin:16px 0 0;text-align:center;font-size:.82rem;color:var(--ink-soft);}
.cal__note:empty{display:none;}

.form__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:8px clamp(20px,3vw,38px);}
.f{margin:0 0 22px;display:flex;flex-direction:column;gap:7px;}
.f--wide{margin-top:8px;}
.f label{font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);}
.f input,.f select,.f textarea{font:inherit;font-size:.98rem;color:var(--ink);background:transparent;
  border:0;border-bottom:1px solid var(--line);padding:10px 2px;border-radius:0;
  transition:border-color .3s;-webkit-appearance:none;appearance:none;}
.f select{background-image:linear-gradient(45deg,transparent 50%,var(--ink-soft) 50%),
  linear-gradient(135deg,var(--ink-soft) 50%,transparent 50%);
  background-position:calc(100% - 12px) 50%,calc(100% - 7px) 50%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:28px;}
.f textarea{resize:vertical;min-height:96px;}
.f input:focus,.f select:focus,.f textarea:focus{outline:0;border-bottom-color:var(--gold-ink);}
.f input[aria-invalid="true"],.f textarea[aria-invalid="true"]{border-bottom-color:var(--terra);}

.form__event{border:0;border-top:1px solid var(--line);margin:10px 0 6px;padding:26px 0 0;}
.form__event legend{padding:0 14px 0 0;font-size:.72rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gold-ink);}
.form__foot{display:flex;flex-wrap:wrap;align-items:center;gap:18px;margin-top:14px;}
.form__note{margin:0;font-size:.78rem;color:var(--ink-soft);max-width:44ch;}
.form__status{margin:18px 0 0;font-size:.9rem;color:var(--gold-ink);min-height:1.4em;}

/* ------------------------------------------------------- breath + footer -- */
.breath{background:var(--ink);color:var(--cream);padding:clamp(120px,22vh,240px) 0;}
.breath__big{font-family:var(--serif);font-weight:300;font-size:clamp(3rem,10vw,8rem);
  line-height:1;margin:0 0 34px;letter-spacing:-.02em;}
.breath__sub{font-family:var(--serif);font-weight:300;
  font-size:clamp(1.4rem,3vw,2.2rem);line-height:1.5;margin:0 0 14px;color:var(--cream);}
.breath__last{font-size:clamp(1rem,1.6vw,1.2rem);line-height:1.8;margin:0 0 46px;
  color:var(--cream-soft);}
.breath .btn--solid{background:var(--cream);color:var(--ink);border-color:var(--cream);}
.breath .btn--solid:hover{background:var(--gold-lift);border-color:var(--gold-lift);color:var(--ink);}
/* The mark comes back last, on its own, after the final call to action. */
.breath__mark{width:34px;height:34px;margin:clamp(56px,8vw,90px) auto 0;stroke:var(--gold-lift);
  transition:opacity 1.6s ease,transform 1.6s cubic-bezier(.2,.7,.3,1);}
.breath__mark .mark__core{fill:var(--gold-lift);}

.foot{background:var(--ink);color:var(--cream-soft);
  padding:44px 0;border-top:1px solid rgba(247,243,236,.14);}
.foot__in{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:20px;}
.foot .hdr__word{color:var(--cream);}
.foot__by{margin:0;font-size:.82rem;}
.foot__links{list-style:none;display:flex;gap:22px;margin:0;padding:0;}
.foot__links a{font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;
  text-decoration:none;transition:color .3s;}
.foot__links a:hover{color:var(--gold-lift);}

.stickycta{display:none;position:fixed;left:14px;right:14px;
  bottom:calc(14px + env(safe-area-inset-bottom));z-index:65;text-align:center;
  padding:16px;background:var(--ink);color:var(--cream);text-decoration:none;border-radius:999px;
  font-size:.86rem;font-weight:500;letter-spacing:.06em;box-shadow:0 8px 30px rgba(42,39,36,.3);
  transform:translateY(140%);transition:transform .45s cubic-bezier(.2,.7,.3,1);}
.stickycta.is-on{transform:none;}

/* ---------------------------------------------------------------- reveal -- */
.reveal{opacity:0;transform:translateY(20px);
  transition:opacity .9s ease,transform 1s cubic-bezier(.2,.7,.3,1);}
.reveal.is-in{opacity:1;transform:none;}

/* ----------------------------------------------------------- legal pages -- */
/* Privacy and Terms are plain documents: no film, no engine, no reveals. They
   share the tokens and the footer so they still read as the same site. */
.hdr--plain{position:static;background:var(--sand);border-bottom:1px solid var(--line);
  padding:20px 0;}
.hdr--plain .wrap{display:flex;align-items:center;justify-content:space-between;gap:20px;}
.hdr--plain .hdr__brand{position:static;}

.legal{padding:clamp(56px,8vh,96px) 0 clamp(70px,10vh,120px);}
.legal h1{font-family:var(--serif);font-weight:300;font-size:clamp(2.4rem,5vw,3.8rem);
  line-height:1.06;letter-spacing:-.01em;margin:0 0 14px;}
.legal__meta{margin:0 0 clamp(38px,5vw,58px);font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--gold-ink);}
.legal h2{font-family:var(--serif);font-weight:400;font-size:clamp(1.5rem,2.6vw,2rem);
  line-height:1.2;margin:clamp(44px,5vw,64px) 0 16px;padding-top:22px;
  border-top:1px solid var(--line);}
.legal h3{font-family:var(--sans);font-size:.95rem;font-weight:600;letter-spacing:.01em;
  margin:30px 0 8px;}
.legal p,.legal li{font-size:.98rem;line-height:1.78;color:var(--ink-soft);}
.legal p{margin:0 0 16px;}
.legal strong{color:var(--ink);font-weight:500;}
.legal ul{margin:0 0 18px;padding-left:22px;}
.legal li{margin-bottom:9px;}
/* Prose links only. Without the exclusions this rule also repaints every
   button inside a document page — `.legal a` outranks `.btn--solid`, which
   put terracotta text on the ink button at 2.93:1. */
.legal a:not(.btn):not(.lnk):not(.stickycta):not(.hdr__brand){
  color:var(--terra);text-underline-offset:3px;}
.legal__lead{font-size:clamp(1.02rem,1.35vw,1.16rem);color:var(--ink);}

/* A field that has to be filled by a human before publication. Loud on
   purpose — an unfilled one is a defect, not a stylistic choice. */
/* Fixed tint rather than a mix of --terra: deriving it meant darkening the
   accent also darkened the background behind it, and the pair stayed stuck
   just under 4.5:1 however far the text was pushed. */
.legal mark.todo{background:#F1E6DA;
  color:var(--terra);padding:1px 6px;border-radius:3px;font-weight:500;
  border:1px dashed var(--terra);}

/* A value that HAS been written, but written by me rather than by Marco. It is
   readable as finished prose, because it is finished prose — the mark only says
   "nobody has confirmed this number is the one you actually enforce".
   Deliberately quieter than .todo: a page of equally loud marks trains you to
   skim all of them, and these two need different actions. .todo blocks
   publication; .draft blocks nothing and needs one read-through. */
.legal mark.draft{background:transparent;color:inherit;padding:0 2px;
  border-bottom:1px solid var(--gold);}
.legal mark.draft::after{content:"\00a0\25B4";color:var(--gold-ink);
  font-size:.7em;vertical-align:super;line-height:0;}

.legal .note{border-left:2px solid var(--gold);padding:2px 0 2px 20px;margin:0 0 22px;}
.legal .note p:last-child{margin-bottom:0;}

.legal__toc{list-style:none;margin:0 0 10px;padding:0;columns:2;column-gap:34px;}
.legal__toc li{margin-bottom:7px;break-inside:avoid;}
.legal__toc a{color:var(--ink-soft);text-decoration:none;font-size:.88rem;}
.legal__toc a:hover{color:var(--terra);text-decoration:underline;}

/* --------------------------------------------------- 404 + thank-you doc -- */
.notfound__nav{display:grid;gap:2px;margin-top:clamp(44px,6vw,66px);
  border-top:1px solid var(--line);}
.notfound__nav a{display:block;padding:20px 4px;border-bottom:1px solid var(--line);
  text-decoration:none;transition:padding-left .3s,color .3s;}
.notfound__nav a:hover{padding-left:12px;color:var(--terra);}
.notfound__nav strong{display:block;font-family:var(--serif);font-weight:400;
  font-size:1.25rem;color:var(--ink);}
.notfound__nav span{display:block;margin-top:3px;font-size:.9rem;color:var(--ink-soft);}

.thanks__mark{width:64px;height:64px;margin:0 0 26px;}
.thanks__mark svg{width:100%;height:100%;fill:none;stroke:var(--gold);
  stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;}
.thanks__mark circle{opacity:.35;}
.thanks__actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(36px,5vw,52px);}

/* ------------------------------------------------- loading + error states -- */
/* Every async thing on this site says which of the three states it is in:
   working, done, or failed with a way out. An empty box is not a state. */
.cal{position:relative;}
.cal[data-state="loading"]{min-height:min(760px,86vh);}
.cal__msg{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;text-align:center;
  padding:clamp(24px,5vw,48px);background:var(--cream);}
.cal__msg p{margin:0;font-size:.95rem;color:var(--ink-soft);max-width:46ch;line-height:1.7;}
.cal__msg strong{color:var(--ink);font-weight:500;}
.cal__msg--error{position:static;min-height:min(420px,60vh);}
.cal__acts{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;}

.cal__spin{width:26px;height:26px;border-radius:50%;
  border:2px solid color-mix(in srgb,var(--gold) 30%,transparent);
  border-top-color:var(--gold);animation:wb-spin .9s linear infinite;}
@keyframes wb-spin{to{transform:rotate(360deg);}}

.form.is-busy{opacity:.72;}
.form.is-busy .f input,.form.is-busy .f select,.form.is-busy .f textarea{
  pointer-events:none;}
.btn[disabled],.btn:disabled{cursor:progress;opacity:.75;transform:none;}

.form__status[data-kind="error"]{color:var(--terra);font-weight:500;}
.form__status[data-kind="error"]::before{content:"";display:inline-block;
  width:7px;height:7px;border-radius:50%;background:var(--terra);
  margin-right:9px;vertical-align:middle;}

/* ----------------------------------------------------------- cookie bar --- */
.consent{position:fixed;left:14px;right:14px;bottom:14px;z-index:90;
  background:var(--ink);color:var(--cream-soft);
  border-radius:14px;padding:clamp(20px,2.6vw,26px);
  box-shadow:0 14px 46px rgba(42,39,36,.34);
  display:flex;align-items:center;gap:clamp(18px,3vw,40px);
  max-width:1100px;margin-inline:auto;}
.consent[hidden]{display:none;}
.consent__txt{margin:0;font-size:.86rem;line-height:1.65;}
.consent__txt strong{color:var(--cream);font-weight:500;}
.consent__txt a{color:var(--gold-lift);}
.consent__btns{display:flex;gap:10px;flex-shrink:0;}
/* Both choices carry the same weight. A reject button styled as an
   afterthought is the dark pattern regulators actually look for. */
.consent__b{font:inherit;font-size:.82rem;font-weight:500;letter-spacing:.06em;
  padding:13px 26px;border-radius:999px;cursor:pointer;white-space:nowrap;
  border:1px solid var(--cream);background:transparent;color:var(--cream);
  transition:background .3s,color .3s;}
.consent__b--yes{background:var(--cream);color:var(--ink);}
.consent__b:hover{background:var(--gold-lift);border-color:var(--gold-lift);color:var(--ink);}

/* ------------------------------------------------------------ responsive -- */
@media (max-width:1000px){
  .hdr__nav,.hdr__cta{display:none;}
  .hdr__burger{display:flex;}
  .split{grid-template-columns:1fr;}
  .split--rev .split__media{order:0;}
  .chapters{grid-template-columns:1fr;}
  .chapter--wide{grid-column:auto;}
}
@media (max-width:640px){
  .legal__toc{columns:1;}
  .ladder li{grid-template-columns:1fr;gap:2px;}
  .touch__parts li{border-right:0;padding:0 12px;}
}
@media (max-width:720px){
  .consent{flex-direction:column;align-items:stretch;gap:16px;}
  .consent__btns{flex-direction:column;}
  .consent__b{width:100%;}
}
@media (max-width:860px){
  .stickycta{display:block;}
  .foot__in{flex-direction:column;align-items:flex-start;}
  .page{padding-bottom:86px;}
  /* The line runs straight down the middle on a phone and every word sits on
     it — the alternating left/right rhythm needs width that is not there. */
  .road__step,.road__step:nth-child(even){justify-content:center;}
  /* Restore the engine's full-width bottom scrim — the desktop rule above is
     unlayered and would otherwise keep its 64vw width on a phone, leaving a
     hard vertical edge down the middle of the picture. */
  .sw-copylayer::before{inset:auto 0 0 0;width:100%;height:72%;
    background:linear-gradient(0deg,var(--sand) 6%,
    color-mix(in srgb,var(--sand) 72%,transparent) 46%,transparent 100%);}
}
/* ------------------------------------------------------------ thumb size -- */
/* Phone rules, measured at 390px with build/mobileqa.py. Two floors:
   nothing carrying a sentence drops below 16px, and nothing you tap is
   smaller than 44px. Decorative micro-labels (eyebrows, chapter numbers,
   captions, chips) keep their size — a letterspaced uppercase eyebrow set at
   16px is a worse page, not a more accessible one, and WCAG 2.5.8 exempts
   links sitting inline in a sentence from the 44px floor for the same reason. */
@media (max-width:860px){
  /* -- the wordmark ------------------------------------------------------ */
  /* Twenty-four characters do not fit on one line beside a burger at 390px.
     Two lines and tighter tracking, never a shorter name.
     11ch delivered THREE lines, not two — "THE WANDERBODY" is 14 characters,
     so it broke after "THE" and the mark stood ~48px tall in a fixed header,
     colliding with the film copy scrolling under it.
     `ch` is the wrong unit for the job: it is the width of a "0", and this is
     letterspaced uppercase, so 15ch measured ~105px against the 143px the
     words actually need. Measured at 390px: "THE WANDERBODY" = 143px,
     "ALCHEMIST" = 89px, and there is ~240px of room before the burger.
     150px breaks it where the comment always said it should:
     THE WANDERBODY / ALCHEMIST. */
  .hdr__word{white-space:normal;font-size:.86rem;letter-spacing:.1em;
    max-width:150px;}

  /* -- 16px floor on anything that is read ------------------------------- */
  .legal p,.legal li{font-size:1rem;}
  .legal__lead{font-size:1.08rem;}
  .lnk{font-size:1rem;}
  .btn{font-size:1rem;}
  .consent__b{font-size:1rem;}
  .consent__txt{font-size:1rem;}
  .tabs__t{font-size:1rem;}
  .foot__by{font-size:1rem;}
  .stickycta{font-size:1rem;}
  .pillars p{font-size:1rem;}
  .chapter p{font-size:1rem;}
  .ladder__w{font-size:1rem;}
  .kit__d{font-size:1rem;}
  .walls__now{font-size:1rem;}
  .flow p{font-size:1rem;}
  .creds li{font-size:1rem;}
  .legal h3{font-size:1rem;}
  .notfound__nav span{font-size:1rem;}

  /* These four used to sit on build/mobileqa.py's DECORATIVE exemption list,
     which is why the audit read "0 issues" while they shipped at 11.8-13.1px.
     None of them is decorative:
       .foot__links a   the footer NAVIGATION — Email, Instagram, Privacy,
                        Terms, Cookie settings. Tapped to get somewhere.
       .cal__note       a sentence ("Pick a time that suits you…")
       .form__note      a sentence, under the enquiry form
       .chapter__where  where a service is delivered — decision information
     Uppercase at .12em tracking gets wide fast at 16px, so the footer links
     drop to .08em; the block already wraps at this width. .chapter__where
     needs !important only because the desktop rule at the top of this file
     carries one, and a media query adds no specificity of its own. */
  .foot__links a{font-size:1rem;letter-spacing:.08em;}
  .cal__note{font-size:1rem;}
  .form__note{font-size:1rem;}
  .chapter__where{font-size:1rem !important;letter-spacing:.08em;}
  /* Engine copy lives in @layer sw, so these unlayered rules win outright.
     The CTA needs the two-class selector: the desktop override above is
     `.sw-copy__cta .sw-btn`, and a media query adds no specificity — a bare
     `.sw-btn` here loses to it and silently does nothing. */
  .sw-copy__body{font-size:clamp(1rem,3.6vw,1.1rem);}
  .sw-copy__cta .sw-btn{font-size:1rem;}

  /* 16px on form controls is not a nicety: below it, iOS Safari zooms the
     whole page in the moment the field takes focus, and never zooms back. */
  .f input,.f select,.f textarea{font-size:1rem;}
  .f label{font-size:.8rem;}

  /* -- 44px floor on anything that is tapped ----------------------------- */
  .hdr__brand{min-height:44px;}
  .hdr__burger{width:48px;height:48px;}
  .tabs__t{min-height:48px;}
  .btn{padding:16px 32px;}
  .lnk{display:inline-flex;align-items:center;min-height:44px;padding-bottom:0;}
  .chapter .lnk{padding-top:20px;}
  .consent__b{min-height:48px;}
  .stickycta{min-height:48px;}

  .foot__links{gap:0 22px;flex-wrap:wrap;}
  .foot__links a{display:inline-flex;align-items:center;justify-content:center;
    min-height:44px;min-width:44px;}

  /* The booking tabs sat 6px past the right edge once their labels reached
     16px. Full width and equal halves instead of shrink-to-fit. */
  .tabs{width:100%;}
  .tabs__t{flex:1;padding:11px 10px;}

  /* ...except `flex:1` alone did NOT make them equal, and the pills burst out
     of the pill-shaped container on both sides — measured at 390px, the
     container ran 19.5→370.5 while the tabs ran 4.5→385.5.
     Two defaults did it together:
       white-space:nowrap  (base rule) — the label cannot break, so its
                           intrinsic width is the whole sentence
       min-width:auto      (flex default) — a flex item never shrinks below
                           that intrinsic width, so `flex-shrink` is ignored
     `flex:1` therefore distributed nothing and each tab kept its text width:
     158.8px and 216.2px, summing past the container.
     This stayed invisible to build/mobileqa.py because its overflow test asks
     whether an element passes the VIEWPORT edge, and 385.5 < 390 — it cleared
     the check by four and a half pixels while plainly looking broken. */
  .tabs__t{min-width:0;white-space:normal;line-height:1.25;}

  .legal__toc{columns:1;}
  .legal__toc li{margin-bottom:0;}
  .legal__toc a{display:flex;align-items:center;min-height:44px;font-size:1rem;
    border-bottom:1px solid var(--line);}

  /* The film's scene dots: the hit area grows to 44px, the painted dot
     inside stays 9px, so nothing looks heavier than before. */
  .sw-route__dot{width:44px;height:44px;}

  /* -- the sticky CTA and the cookie bar must not stack on top of each
        other. While a decision is pending, the bar has the bottom. -------- */
  .consent-open .stickycta{transform:translateY(140%);pointer-events:none;}

  /* Room under the last element so the CTA never covers the footer. */
  body.doc{padding-bottom:96px;}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  .reveal{opacity:1;transform:none;transition:none;}
  .gallery img,.btn,.stickycta{transition:none;}
  .stickycta{transform:none;}
  /* The journey line is drawn once, complete, and never scrubs. The seven
     words are markup either way — the line has never carried meaning on its
     own. */
  .road__line svg,.road__line::before,.road__path,.breath__mark{transition:none;}
  /* A spinner is still the clearest "working" signal, so it stays — it just
     steps instead of sweeping. */
  .cal__spin{animation-duration:2.4s;animation-timing-function:steps(8,end);}
  .notfound__nav a{transition:none;}
}
