/* =====================================================================
   THE WISDOM OF SEDONA — retreat landing page
   Mobile-first. Designed at 375px, scaled up.
   No box shadows anywhere: depth comes from hairlines and background
   alternation. See BRIEF.md §3.
   ===================================================================== */

/* ── Tokens ────────────────────────────────────────────────────────── */

:root {
  /* Colour — WCAG-verified, see BRIEF.md §3 for the ratio table. */
  --bone:      #F4F1EA;
  --shell:     #FBF9F5;
  --hairline:  #E0D9CB;
  --sage:      #6E7458;
  --sage-deep: #464B38;
  --bronze:    #7E674E;
  --clay:      #B08968;
  --ink:       #2A2722;
  --muted:     #6B655C;
  --night:     #14130F;

  /* Channel forms of the palette above. Every translucent value on the page
     derives from these, so a palette change propagates instead of stranding
     hand-mixed literals — which is how the footer-credits contrast failure
     went unnoticed. Keep these in sync with the hex values. */
  --bone-rgb:      244 241 234;
  --shell-rgb:     251 249 245;
  --night-rgb:     20 19 15;
  --sage-deep-rgb: 70 75 56;
  --clay-rgb:      176 137 104;

  /* Type */
  --font-display: 'Prata', Georgia, 'Times New Roman', serif;
  --font-body: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --fs-h1: clamp(2.25rem, 7vw, 4.5rem);
  --fs-h2: clamp(1.75rem, 4vw, 2.75rem);
  --fs-h3: clamp(1.25rem, 2.5vw, 1.625rem);
  --fs-body: clamp(1rem, 1.6vw, 1.125rem);
  --fs-small: 0.875rem;
  --fs-eyebrow: 0.8125rem;

  --lh-body: 1.7;
  --lh-display: 1.1;
  --measure: 65ch;

  /* Layout */
  --maxw: 1200px;
  --gutter: 20px;
  --section-y: 56px;
  --radius: 8px;
  --radius-card: 12px;

  /* Motion */
  --dur-fast: 200ms;
  --dur-base: 500ms;
  --dur-reveal: 700ms;
  --dur-slow: 1000ms;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (min-width: 768px) {
  :root {
    --gutter: 32px;
    --section-y: 76px;
  }
}

@media (min-width: 1024px) {
  :root {
    --gutter: 48px;
    --section-y: 96px;
  }
}

/* ── Reset ─────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

/* Several components below set `display`, which would otherwise win over
   the `hidden` attribute they are toggled with. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 80px;
}

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
img { height: auto; }

/* Photos use <picture> for the AVIF → WebP fallback. `display: contents`
   removes the wrapper from layout so every existing rule that sizes the
   <img> (object-fit covers, height:100%) keeps working untouched. */
picture { display: contents; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: var(--bronze); }

/* ── Focus ─────────────────────────────────────────────────────────── */

:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
  border-radius: 2px;
}

.section--night :focus-visible,
.lightbox :focus-visible,
.hero :focus-visible,
.footer :focus-visible {
  outline-color: var(--shell);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--sage-deep);
  color: var(--bone);
  padding: 12px 20px;
  border-radius: 0 0 var(--radius) 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Primitives ────────────────────────────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--shell { background: var(--shell); }

/* Hard edge against the cream above — no gradient blend (BRIEF §5.8). */
.section--night {
  background: var(--night);
  color: var(--shell);
}
/* Not --clay: it is 2.81:1 and never permitted as text at any size. */
.section--night .eyebrow { color: rgb(var(--bone-rgb) / 0.78); }
.section--night .h2 { color: var(--shell); }

.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--muted);
  margin-bottom: 14px;
}

.h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: var(--lh-display);
  color: var(--sage-deep);
  margin-bottom: 28px;
}

.lead {
  max-width: var(--measure);
  margin-bottom: 20px;
}
.lead--wide { max-width: 60ch; margin-bottom: 36px; }

.link-out {
  color: var(--bronze);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid var(--clay);
  padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease);
}
.link-out:hover { border-bottom-color: var(--bronze); }

/* ── Buttons ───────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 14px 28px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform 120ms var(--ease);
}
.btn:active { transform: scale(0.98); }

/* The three CTAs that ask for the whole decision — hero, price card and the
   closing line. Set in caps here rather than typed in caps so the accessible
   name stays a normal sentence for screen readers. The sticky bar keeps
   sentence case on purpose: it is a persistent control, not a moment. */
.btn--shout {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.875rem;
}

/* Press feedback for the controls that aren't .btn. At 90% mobile traffic the
   hover states above are dead weight, so without this a tap gets no
   acknowledgement until the panel or lightbox catches up. Full-bleed rows use
   a gentler 0.99 — a row scaling as hard as a button reads wrong. */
/* .gallery__btn and .stickybar__tg declare their own transition further down
   and would win the cascade, so transform is added there instead. */
.practice__head,
.tl__head,
.faq__head,
.creds__head,
.nav__toggle,
.lightbox__close,
.lightbox__nav {
  transition: transform 140ms var(--ease);
}
.practice__head:active,
.tl__head:active,
.faq__head:active,
.creds__head:active { transform: scale(0.99); }
.gallery__btn:active,
.nav__toggle:active,
.lightbox__close:active,
.lightbox__nav:active,
.stickybar__tg:active { transform: scale(0.96); }

.btn--primary {
  background: var(--sage-deep);
  color: var(--bone);
}
.btn--primary:hover { background: var(--sage); }

.btn--ghost {
  border-color: rgb(var(--shell-rgb) / 0.55);
  color: var(--shell);
}
.btn--ghost:hover {
  border-color: var(--shell);
  background: rgb(var(--shell-rgb) / 0.1);
}

/* Secondary action on a light surface (.btn--ghost is for dark bands). */
.btn--quiet {
  border-color: var(--hairline);
  color: var(--sage-deep);
}
.btn--quiet:hover { border-color: var(--sage); background: rgb(var(--shell-rgb) / 0.5); }

.btn--light {
  background: var(--shell);
  color: var(--night);
}
.btn--light:hover { background: var(--bone); }

/* ── Callouts ──────────────────────────────────────────────────────── */

/* No left accent bar. A thick coloured border on one side of a card is the
   most recognizable tell of generated UI, and this page earns hierarchy from
   type and background alternation everywhere else — so it does so here too.
   The brief asked for "visually distinct from body copy", not for an accent. */
.callout {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  padding: 24px 26px;
  background: transparent; /* each variant fills against its own section */
}
.callout p + p { margin-top: 10px; }

.callout__title {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.35;
  color: var(--sage-deep);
  margin-bottom: 10px;
}

.callout__note {
  font-size: var(--fs-small);
  color: var(--muted);
}

.callout--night {
  border-color: rgb(var(--bone-rgb) / 0.28);
  color: var(--shell);
  margin-top: 36px;
  font-size: 1.0625rem;
}

/* Sits on --bone, so the fill inverts. Full --bronze border rather than a side
   bar — the same move .pricecard makes with --sage-deep, and this is the one
   block on the page that must not read as decorative. */
.callout--health {
  background: var(--shell);
  border-color: var(--bronze);
  margin-bottom: 36px;
}
.callout--health .callout__title { color: var(--bronze); }
/* Real contraindication copy runs to several paragraphs, so it needs the same
   measure as body prose — the callout box itself stays full width. */
.callout--health p { max-width: var(--measure); }

/* The one callout that is the entire section rather than an aside inside one.
   It fills instead of outlining: at full width on --shell, an outlined box
   with nothing around it reads as an empty frame. */
.callout--wide {
  background: var(--bone);
  padding: 28px 26px;
}
.callout--wide .callout__title {
  font-size: var(--fs-h3);
  margin-bottom: 16px;
}
.callout--wide p { max-width: var(--measure); }
.callout--wide .callout__note {
  margin-top: 18px;
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.35;
  color: var(--sage-deep);
}

@media (min-width: 768px) {
  .callout--wide { padding: 44px 48px; }
}

/* Closing line under a section's content. */
.section__close {
  margin-top: 32px;
  max-width: var(--measure);
  color: var(--muted);
}

/* =====================================================================
   1 · Hero
   ===================================================================== */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-block: 120px 88px;
  overflow: hidden;
  isolation: isolate;
  background: var(--night);
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform-origin: center;
}

/* Scrim averages ~40%, weighted to the bottom where every piece of hero text
   sits and lifted slightly at the top so the nav stays readable. Tuned against
   the current sunset photo; a lighter hero image would need more. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top,
      rgb(var(--night-rgb) / 0.80) 0%,
      rgb(var(--night-rgb) / 0.60) 40%,
      rgb(var(--night-rgb) / 0.34) 70%,
      rgb(var(--night-rgb) / 0.46) 100%);
}

.hero__content { position: relative; }

.hero__eyebrow { color: rgb(var(--bone-rgb) / 0.82); }

.hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--shell);
  margin-bottom: 18px;
  max-width: 14ch;
}

.hero__title-mask { display: block; }

.hero__sub {
  font-size: clamp(1.0625rem, 2.2vw, 1.375rem);
  color: var(--bone);
  max-width: 32ch;
  margin-bottom: 32px;
}

.hero__micro {
  font-size: var(--fs-small);
  color: rgb(var(--bone-rgb) / 0.82);
  max-width: 40ch;
}

.hero__actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
}

.hero__cue {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  transition: opacity var(--dur-base) var(--ease);
}
.hero__cue-line {
  display: block;
  width: 1px;
  height: 46px;
  background: linear-gradient(to bottom, rgb(var(--bone-rgb) / 0), var(--clay));
  animation: cue-bob 2s var(--ease) infinite;
}
/* Stop the loop, don't just hide it — an invisible infinite animation keeps
   compositing for the rest of the session. */
.hero__cue.is-gone { opacity: 0; pointer-events: none; }
.hero__cue.is-gone .hero__cue-line { animation: none; }

@keyframes cue-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}

@media (min-width: 600px) {
  .hero__actions { flex-direction: row; flex-wrap: wrap; }
  .hero__actions .btn { min-width: 220px; }
}

/* Ken Burns — desktop only, not degraded on mobile (BRIEF §6).
   Deliberately `linear`, not --ease: this is ambient constant motion, not a UI
   transition. --ease is ~90% complete at a quarter of its duration, which over
   20s would zoom in the first 5s and then sit still for 15s. */
@media (min-width: 1024px) {
  .hero__img { animation: ken-burns 20s linear forwards; }
}
@keyframes ken-burns {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}

#hero-sentinel { height: 1px; margin-top: -1px; }

/* =====================================================================
   1b · Intro band
   The hero copy that does not fit in the hero. Sits on --shell so it reads
   as a continuation of the first screen rather than as the first section.
   ===================================================================== */

.intro {
  background: var(--shell);
  padding-block: calc(var(--section-y) * 0.8);
}
.intro__inner > .lead:last-child { margin-bottom: 0; }

/* Four steps, one row. Numbered because the order is the whole point — this
   is a path, not a list of themes. Stacks below 640px, where four columns
   would give each verb about eleven characters of width. */
.path {
  display: grid;
  gap: 14px;
  margin-block: 28px 32px;
  counter-reset: none;
}
.path__step {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-display);
  font-size: 1.0625rem;
  line-height: 1.3;
  color: var(--sage-deep);
}
.path__n {
  font-size: var(--fs-eyebrow);
  font-family: var(--font-body);
  letter-spacing: 0.12em;
  color: var(--clay);
  flex: 0 0 auto;
}

@media (min-width: 640px) {
  .path {
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
  }
  .path__step {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
  }
}

/* =====================================================================
   2 · Trust strip
   ===================================================================== */

.trust {
  background: var(--sage);
  color: var(--shell);
  padding-block: 22px;
}

.trust__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  text-align: left;
}

.trust__avatar {
  width: 54px;
  height: 54px;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgb(var(--shell-rgb) / 0.5);
}

.trust__line {
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--shell);
  max-width: 34ch;
}

.trust__count { font-variant-numeric: tabular-nums; font-weight: 600; }

/* BRIEF §6 row 2: the avatar scales from 0.94 rather than only sliding up. */
.js .trust__inner[data-reveal] .trust__avatar {
  transform: scale(0.94);
  transition: transform var(--dur-reveal) var(--ease);
}
.js .trust__inner[data-reveal].is-in .trust__avatar { transform: none; }

@media (min-width: 768px) {
  .trust__avatar { width: 64px; height: 64px; }
  .trust__line { font-size: 1.0625rem; max-width: none; }
}

/* =====================================================================
   3 · Sound familiar?
   ===================================================================== */

.resonance { padding-block: calc(var(--section-y) * 1.2); }

.resonance__eyebrow { margin-bottom: 40px; }

/* No max-width on mobile: a 22ch cap left roughly a third of the screen
   empty on the right and read as broken alignment rather than as a
   deliberate column. The lines fill the same width as every other block. */
.resonance__list {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* The copy here is prose with a single quoted line inside it, so the display
   face is reserved for that one line. Setting every line in Prata was right
   when all five were pull-quotes; applied to prose it turns the section into
   a wall of ornament and the quote stops landing. */
.resonance__line {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
  max-width: var(--measure);
}

.resonance__line--quote {
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 4.6vw, 2.25rem);
  font-weight: 400;
  line-height: 1.32;
  color: var(--sage-deep);
  text-wrap: balance;
  margin-block: 12px;
}

.resonance__close {
  margin-top: 52px;
  color: var(--bronze);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.04em;
}

/* Display type still needs a ceiling on wide screens, but NOT in ch:
   Prata's character box is only ~11.9px at 36px, so 34ch resolved to
   405px and filled a third of the 1200px wrap — which is what read as
   lopsided. 50rem fills roughly two thirds: clearly deliberate, still
   short enough that a quote stays comfortable to read. */
@media (min-width: 768px) {
  .resonance__list { gap: 24px; max-width: 50rem; }
  .resonance__line--quote { margin-block: 16px; }
}

/* =====================================================================
   5 · Sedona
   ===================================================================== */

.place__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 40px;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--hairline);
}
.place__stat dt {
  font-family: var(--font-display);
  font-size: 1.375rem;
  line-height: 1.2;
  color: var(--sage-deep);
}
.place__stat dd {
  font-size: var(--fs-small);
  color: var(--muted);
  margin-top: 4px;
}

.place__grid {
  display: grid;
  gap: 48px;
}

/* Offset collage — overlapping, differing vertical offsets. */
.collage {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.collage__item { border-radius: var(--radius-card); overflow: hidden; }
.collage__item img { width: 100%; height: 100%; object-fit: cover; }

.collage__item--1 { grid-column: 1; grid-row: 1 / span 2; }
.collage__item--2 { grid-column: 2; grid-row: 1; margin-top: 32px; }
.collage__item--3 { grid-column: 2; grid-row: 2; }

@media (min-width: 900px) {
  .place__grid {
    grid-template-columns: 1fr 1fr;
    gap: 64px;
    align-items: center;
  }
  .collage { gap: 18px; }
  .collage__item--2 { margin-top: 48px; }
}

/* =====================================================================
   8 · Leksa
   ===================================================================== */

.leksa__grid { display: grid; gap: 40px; }

.leksa__portrait {
  border-radius: var(--radius-card);
  overflow: hidden;
}
.leksa__portrait img { width: 100%; }


.leksa__creds {
  margin: 20px 0 28px;
  display: flex;
  flex-direction: column;
}

.creds__item {
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
}
.creds__item:first-child { border-top: 1px solid var(--hairline); }

/* 44px min-height: the row is the tap target now, not just the words in it. */
.creds__head {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 12px 0;
  text-align: left;
  color: var(--ink);
}
.creds__name { line-height: 1.4; }
.creds__text { color: var(--muted); max-width: var(--measure); }

@media (min-width: 900px) {
  .leksa__grid {
    grid-template-columns: 0.85fr 1fr;
    gap: 64px;
    align-items: start;
  }
}

/* =====================================================================
   11 · What you'll take with you
   ===================================================================== */

/* The six outcomes sit beside one photograph. Same split as .lodge__grid, and
   the figure is sticky so it stays with the list on a tall desktop column. */
.outcomes__grid {
  display: grid;
  gap: 32px;
  align-items: start;
}

.outcomes__figure img {
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
}
.outcomes__caption {
  margin-top: 12px;
  font-size: var(--fs-small);
  letter-spacing: 0.04em;
  color: var(--muted);
}

.outcomes__figures {
  display: grid;
  gap: 20px;
}

@media (min-width: 900px) {
  .outcomes__grid {
    grid-template-columns: 1.25fr 0.75fr;
    gap: 56px;
  }
}

.outcomes { margin-top: 8px; }

.outcome {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px 20px;
  padding-block: 28px;
  position: relative;
}

/* Divider drawn in via scaleX rather than a plain border. */
.outcome::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--hairline);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease) 120ms;
}
.outcome.is-in::after { transform: scaleX(1); }

/* --clay is permitted here only because these numerals stay ≥32px. */
.outcome__num {
  font-family: var(--font-display);
  font-size: 2.25rem;
  line-height: 1;
  color: var(--clay);
  min-width: 1.4ch;
}

.outcome__lead {
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
  margin-bottom: 6px;
}

.outcome__text {
  color: var(--muted);
  max-width: var(--measure);
}

@media (min-width: 768px) {
  .outcome {
    grid-template-columns: 88px 1fr;
    gap: 24px 32px;
    padding-block: 34px;
  }
  .outcome__num { font-size: 2.75rem; }
  .outcome__lead { font-size: 1.25rem; }
}

/* =====================================================================
   12 · Who it's for
   ===================================================================== */

.audience {
  display: grid;
  gap: 12px;
  margin-top: 8px;
}
.audience__card {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  background: var(--shell);
  padding: 24px 26px;
}
.audience__title {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--sage-deep);
  margin-bottom: 10px;
}
.audience__card p { color: var(--muted); }

/* 720px, not the usual 768: four cards of this length are readable two-up
   well before the tablet breakpoint, and one column of them runs very long. */
.audience__photo { margin-top: 12px; }
.audience__photo img {
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
}

@media (min-width: 720px) {
  .audience {
    grid-template-columns: repeat(2, 1fr);
    gap: 18px;
  }
  .audience__card { padding: 30px 32px; }
  .audience__photo { margin-top: 18px; }
}

/* =====================================================================
   9 · What we'll be doing
   ===================================================================== */

.practices__intro {
  display: grid;
  gap: 28px;
  margin-bottom: 32px;
}
.practices__photo img {
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
}
@media (min-width: 900px) {
  .practices__intro {
    grid-template-columns: 1fr 1fr;
    gap: 56px;
    align-items: center;
  }
}

.practices {
  display: grid;
  gap: 12px;
}

.practice {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  background: var(--shell);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}

.practice__head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px;
  text-align: left;
}

.practice__name {
  font-family: var(--font-display);
  font-size: 1.125rem;
  line-height: 1.3;
  color: var(--sage-deep);
}

.practice__text { color: var(--muted); max-width: var(--measure); }

/* Three of the eight practices have no description written yet. They sit in
   the same grid but carry no button and no icon — an accordion that opens on
   nothing is worse than a plain row, and it lies about there being more. */
.practice--flat {
  display: flex;
  align-items: center;
  padding: 20px 22px;
}

/* Plus → minus, drawn from two rules. */
.practice__icon,
.faq__icon,
.creds__icon,
.tl__icon {
  position: relative;
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}
.practice__icon::before, .practice__icon::after,
.faq__icon::before, .faq__icon::after,
.creds__icon::before, .creds__icon::after,
.tl__icon::before, .tl__icon::after {
  content: '';
  position: absolute;
  background: var(--sage);
  transition: transform var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
}
.practice__icon::before, .faq__icon::before, .creds__icon::before, .tl__icon::before {
  top: 50%; left: 0; right: 0; height: 1.5px; margin-top: -0.75px;
}
.practice__icon::after, .faq__icon::after, .creds__icon::after, .tl__icon::after {
  left: 50%; top: 0; bottom: 0; width: 1.5px; margin-left: -0.75px;
}
[aria-expanded="true"] .practice__icon::after,
[aria-expanded="true"] .faq__icon::after,
[aria-expanded="true"] .creds__icon::after,
[aria-expanded="true"] .tl__icon::after {
  transform: scaleY(0);
}

@media (min-width: 768px) {
  .practices { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .practices { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) {
  .practice:hover {
    border-color: var(--sage);
    transform: translateY(-2px);
  }
}

/* Shared accordion panel: animates grid-template-rows, never height. */
.panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 400ms var(--ease);
}
.panel.is-open { grid-template-rows: 1fr; }
.panel > .panel__inner {
  overflow: hidden;
  min-height: 0;
}
.panel > .panel__inner > * { margin-bottom: 12px; }
.panel > .panel__inner > *:first-child { padding-top: 2px; }
.panel > .panel__inner > *:last-child { margin-bottom: 22px; }

.practice .panel__inner { padding-inline: 22px; }

/* =====================================================================
   6 · Places of power
   ===================================================================== */

.vortex {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-bottom: 40px;
  max-width: var(--measure);
}
/* Meaning always under the name on a phone. Letting it sit inline "where it
   fits" made the column ragged: short names kept their meaning on the same
   line, long ones pushed it below, so no two rows aligned. One row per line
   from 768px up, where every pair fits. */
.vortex__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 0;
  border-bottom: 1px solid rgb(var(--bone-rgb) / 0.16);
}
.vortex__item:first-child { border-top: 1px solid rgb(var(--bone-rgb) / 0.16); }
.vortex dt {
  font-family: var(--font-display);
  font-size: 1.125rem;
  line-height: 1.3;
  color: var(--bone);
}
.vortex dd {
  font-size: var(--fs-small);
  color: rgb(var(--bone-rgb) / 0.72);
}

.places__gallery {
  display: grid;
  gap: 12px;
}
.places__fig {
  border-radius: var(--radius-card);
  overflow: hidden;
}
.places__fig img { width: 100%; transform-origin: center; }

@media (min-width: 768px) {
  .vortex { max-width: none; }
  .vortex__item { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 2px 18px; }
  .places__gallery { grid-template-columns: repeat(3, 1fr); gap: 18px; }
  .places__fig img { aspect-ratio: 4 / 3; object-fit: cover; height: auto; }
}

/* =====================================================================
   9b · Sweat Lodge
   ===================================================================== */

.lodge__grid {
  display: grid;
  gap: 32px;
  align-items: start;
  margin-block: 36px;
}

.lodge__copy p { max-width: var(--measure); }
.lodge__copy p + p { margin-top: 16px; }

/* The radius goes on the image, not a clipping wrapper — the caption has to
   sit outside the rounded box, and overflow:hidden on the figure would eat it. */
.lodge__portrait img {
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
}
.lodge__caption {
  margin-top: 12px;
  font-size: var(--fs-small);
  letter-spacing: 0.04em;
  color: rgb(var(--bone-rgb) / 0.72);
}

.lodge__close {
  margin-top: 28px;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3vw, 1.625rem);
  line-height: 1.35;
  color: var(--shell);
  max-width: 38ch;
}

/* 900px, matching the collage: the portrait needs real width before it earns
   a column of its own, and below that it reads better full-bleed under the copy. */
@media (min-width: 900px) {
  .lodge__grid {
    grid-template-columns: 1.25fr 0.75fr;
    gap: 56px;
  }
}

/* =====================================================================
   10 · Four days
   ===================================================================== */

.timeline {
  position: relative;
  padding-left: 26px;
}

/* Vertical rail. */
.timeline::before {
  content: '';
  position: absolute;
  left: 5px;
  top: 12px;
  bottom: 12px;
  width: 1px;
  background: var(--hairline);
}

.tl { position: relative; }

.tl__dot {
  position: absolute;
  left: -26px;
  top: 24px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bone);
  border: 1.5px solid var(--clay);
}

.tl__head {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 16px;
  align-items: start;
  padding: 18px 0;
  text-align: left;
  border-bottom: 1px solid var(--hairline);
}
.tl:first-child .tl__head { border-top: 1px solid var(--hairline); }

/* Day names are words ("Grounding and strength"), and the date beside them is
   "Day 1" — at 375px the longest pair must be free to break onto two lines. */
.tl__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  grid-column: 1;
}
.tl__day {
  font-family: var(--font-display);
  font-size: 1.125rem;
  color: var(--sage-deep);
}
.tl__date {
  font-size: var(--fs-small);
  color: var(--muted);
}

.tl__summary {
  grid-column: 1;
  font-size: var(--fs-small);
  color: var(--muted);
  line-height: 1.5;
  max-width: 46ch;
}

.tl__icon { grid-column: 2; grid-row: 1 / span 2; align-self: center; }

.tl .panel__inner > p { color: var(--muted); max-width: var(--measure); }
.tl .panel__inner > p + p { margin-top: 12px; }

/* Closes the timeline: the programme is deliberately not minute-by-minute. */
.timeline + .callout { margin-top: 40px; }
.timeline + .callout p { color: var(--muted); max-width: var(--measure); }

@media (min-width: 768px) {
  .timeline { padding-left: 40px; }
  .timeline::before { left: 6px; }
  .tl__dot { left: -40px; width: 13px; height: 13px; }
  .tl__head { padding: 24px 0; }
  .tl__day { font-size: 1.25rem; }
  .tl__summary { font-size: 1rem; }
}

/* =====================================================================
   13 · Accommodation
   ===================================================================== */

/* Provisional content. Dashed and desaturated on purpose: a section that says
   "to be confirmed" must not be able to pass for finished copy, the same
   reasoning behind .legal-todo on the policy pages. */
.statblocks {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin-bottom: 36px;
  border-top: 1px solid var(--hairline);
}
.statblock {
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
}
.statblock dt {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.2;
  color: var(--sage-deep);
}
.statblock dd {
  font-size: var(--fs-small);
  color: var(--muted);
  margin-top: 4px;
}

@media (min-width: 768px) {
  .statblocks { grid-template-columns: repeat(3, 1fr); gap: 32px; }
}

/* Room options: name over detail on a phone, one row each from 768px. */
.rooms__title {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 8px 0 12px;
}
.rooms { margin-bottom: 36px; }
.rooms__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline);
}
.rooms__item:first-child { border-top: 1px solid var(--hairline); }
.rooms__name {
  font-family: var(--font-display);
  font-size: 1.125rem;
  line-height: 1.3;
  color: var(--ink);
}
.rooms__detail { font-size: var(--fs-small); color: var(--muted); }


@media (min-width: 768px) {
  .rooms__item { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 24px; }
}

.pending {
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-card);
  padding: 24px 26px;
  max-width: var(--measure);
  color: var(--muted);
}
.pending__lead {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--sage-deep);
  margin-bottom: 14px;
}
.pending__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}
.pending__list li {
  position: relative;
  padding-left: 20px;
  font-size: 0.9375rem;
}
.pending__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 8px;
  height: 1px;
  background: var(--clay);
}

@media (min-width: 768px) {
  .pending { padding: 32px 34px; }
}

.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.gallery__btn {
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: transform 140ms var(--ease);
}
.gallery__btn img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

@media (min-width: 768px) {
  .gallery { grid-template-columns: repeat(3, 1fr); gap: 18px; }
  /* Offset grid — second column drops. */
  .gallery__item:nth-child(3n + 2) { margin-top: 32px; }
}
/* Width alone isn't a proxy for a mouse — an iPad is 768px+ and fires a
   false hover on tap, leaving the lift stuck until the next interaction. */
@media (min-width: 768px) and (hover: hover) and (pointer: fine) {
  .gallery__btn:hover { transform: translateY(-2px); }
}

/* =====================================================================
   14 · How it has been
   ===================================================================== */

.testimonials {
  display: grid;
  gap: 16px;
}
.testimonial {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  background: var(--shell);
  padding: 26px 24px;
}
.testimonial blockquote {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--sage-deep);
  margin-bottom: 16px;
}
.testimonial__by {
  display: flex;
  gap: 10px;
  font-size: var(--fs-small);
}
.testimonial__name { font-weight: 600; }
.testimonial__city { color: var(--muted); }

/* Archive fallback — horizontal snap strip, autoplay off by design. */
.archive__strip {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 78%;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 4px;
  /* Bleed to the viewport edge so the strip reads as scrollable. */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
}
.archive__strip::-webkit-scrollbar { display: none; }

.archive__item { scroll-snap-align: start; }
.archive__item figure { position: relative; }
/* The caption used to lean on its text-shadow alone, which held up over the
   dark-bottomed landscapes but not over a bright interior. A scrim keeps it
   legible whatever photo gets swapped in — same move the hero makes. */
.archive__item figure::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  background: linear-gradient(to top,
    rgb(var(--night-rgb) / 0.72) 0%,
    rgb(var(--night-rgb) / 0.34) 55%,
    rgb(var(--night-rgb) / 0) 100%);
  pointer-events: none;
}
.archive__item figcaption { z-index: 1; }
.archive__item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-card);
}
.archive__item figcaption {
  position: absolute;
  left: 16px;
  bottom: 14px;
  display: flex;
  gap: 10px;
  align-items: baseline;
  color: var(--shell);
  font-size: var(--fs-small);
  text-shadow: 0 1px 12px rgb(var(--night-rgb) / 0.75);
}
.archive__place { font-weight: 600; }
.archive__year { color: rgb(var(--shell-rgb) / 0.85); }

.archive__dots {
  display: flex;
  justify-content: center;
  gap: 4px;
  margin-top: 16px;
}

/* The dot stays 7px; the *target* is 24×24 with a 4px gap, so adjacent hit
   areas don't overlap. WCAG 2.2 SC 2.5.8 Target Size (Minimum), AA. */
.archive__dot {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: none;
  transition: transform 140ms var(--ease);
}
.archive__dot::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--hairline);
  transition: background-color var(--dur-fast) var(--ease);
}
.archive__dot:active { transform: scale(0.9); }
.archive__dot[aria-selected="true"]::before { background: var(--sage); }

@media (min-width: 768px) {
  .testimonials { grid-template-columns: repeat(3, 1fr); }
  .archive__strip { grid-auto-columns: 42%; gap: 18px; }
}
@media (min-width: 1024px) {
  .archive__strip { grid-auto-columns: 1fr; overflow-x: visible; margin-inline: 0; padding-inline: 0; }
  .archive__dots { display: none; }
}

/* =====================================================================
   15 · Price
   ===================================================================== */

.booking {
  background: var(--sage);
  padding-block: var(--section-y);
}

.pricecard {
  background: var(--shell);
  border: 1px solid var(--sage-deep);
  border-radius: var(--radius-card);
  padding: 32px 24px;
  max-width: 760px;
  margin-inline: auto;
}

.pricecard__eyebrow { margin-bottom: 8px; }

.pricecard__price {
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 9vw, 4rem);
  font-weight: 400;
  line-height: 1;
  color: var(--sage-deep);
}
.pricecard__per {
  font-size: var(--fs-small);
  color: var(--muted);
  margin-top: 8px;
  margin-bottom: 30px;
}

.pricecard__cols {
  display: grid;
  gap: 26px;
  padding-block: 26px;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.pricecard__coltitle {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

.ticklist { display: flex; flex-direction: column; gap: 10px; }
.ticklist li {
  position: relative;
  padding-left: 26px;
  font-size: 0.9375rem;
  line-height: 1.5;
}
.ticklist li::before {
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 600;
}
.ticklist--in li::before { content: '+'; color: var(--sage); }
.ticklist--out li::before { content: '–'; color: var(--muted); }
.ticklist--out li { color: var(--muted); }

.pricecard__actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
}

.pricecard__note {
  margin-top: 22px;
  font-size: var(--fs-small);
  color: var(--muted);
}

.pricecard__terms {
  margin-top: 10px;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--muted);
}


@media (min-width: 640px) {
  .pricecard { padding: 44px 40px; }
  .pricecard__cols { grid-template-columns: 1.2fr 1fr; gap: 40px; }
  .pricecard__actions { flex-direction: row; }
  .pricecard__actions .btn { flex: 1; }
}

/* =====================================================================
   13 · FAQ
   ===================================================================== */

.faq__item { border-bottom: 1px solid var(--hairline); }
.faq__item:first-child { border-top: 1px solid var(--hairline); }

.faq__head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 0;
  text-align: left;
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink);
}

.faq .panel__inner > p { color: var(--muted); max-width: var(--measure); }

/* =====================================================================
   14 · Telegram
   ===================================================================== */

.tg {
  background: var(--shell);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  padding-block: 32px;
}
.tg__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}
.tg__text { font-size: var(--fs-small); color: var(--muted); }
.tg__link {
  color: var(--bronze);
  font-size: var(--fs-small);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px solid var(--clay);
  padding-bottom: 2px;
}

@media (min-width: 640px) {
  .tg__inner { flex-direction: row; justify-content: center; gap: 12px; }
}

/* =====================================================================
   18 · Closing
   ===================================================================== */

.final { text-align: center; }

.final__lines {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 30ch;
  margin-inline: auto;
}
.final__lines p {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3.4vw, 1.875rem);
  line-height: 1.35;
  color: var(--shell);
  text-wrap: balance;
}

/* 30ch is right for the short lines but strangles the long one: the closing
   paragraph is a single 40-word sentence, and at 30ch it stacks into an
   eight-line tower. Widen the block once there is room — in rem, not ch,
   because Prata's character box is far narrower than the number suggests. */
@media (min-width: 600px) {
  .final__lines { max-width: 38rem; }
}

/* Three across doesn't fit at 320px once the labels are letter-spaced,
   so narrow screens get stacked label/value rows instead. */
.final__recap {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 52px;
  padding-top: 28px;
  border-top: 1px solid rgb(var(--bone-rgb) / 0.18);
  text-align: left;
}
.final__recap > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.final__recap dt {
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgb(var(--bone-rgb) / 0.7);
  margin-bottom: 4px;
}
.final__recap dd {
  font-size: 0.9375rem;
  color: var(--bone);
  text-align: right;
}

/* The headline said once more, in the page's own voice, right before the only
   thing left to do. */
.final__echo {
  margin-top: 44px;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 5.2vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--shell);
}

.final__cta { margin-top: 28px; }

@media (min-width: 560px) {
  .final__recap {
    grid-template-columns: repeat(2, auto);
    justify-content: center;
    gap: 12px 40px;
    text-align: center;
  }
  .final__recap > div { display: block; }
  .final__recap dd { text-align: center; }
}

/* =====================================================================
   Footer
   ===================================================================== */

.footer {
  background: var(--night);
  color: var(--bone);
  padding-block: 40px 100px;
  border-top: 1px solid rgb(var(--bone-rgb) / 0.12);
}
.footer__inner {
  display: flex;
  flex-direction: column;
  gap: 22px;
  align-items: center;
  text-align: center;
}
.footer__social {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.footer__social a {
  color: var(--bone);
  font-size: var(--fs-small);
  text-decoration: none;
  border-bottom: 1px solid rgb(var(--clay-rgb) / 0.7);
  padding-bottom: 2px;
}


.footer__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
}
.footer__legal a {
  color: rgb(var(--bone-rgb) / 0.75);
  font-size: var(--fs-small);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.footer__legal a:hover { border-bottom-color: var(--clay); }

/* 0.45 measured 4.16:1 — below AA. This block carries the CC BY-SA attribution
   the licences require to be legible, so it has to clear the floor. 0.62 at
   12px measures 6.7:1. */
.footer__credits {
  font-size: 0.75rem;
  line-height: 1.6;
  color: rgb(var(--bone-rgb) / 0.62);
  max-width: 62ch;
}
.footer__credits a {
  color: rgb(var(--bone-rgb) / 0.6);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer__copy {
  font-size: 0.75rem;
  color: rgb(var(--bone-rgb) / 0.5);
}

@media (min-width: 768px) {
  .footer { padding-bottom: 48px; }
  .footer__social { flex-direction: row; gap: 24px; }
}

/* =====================================================================
   Persistent UI
   ===================================================================== */

/* ── Anchor nav ────────────────────────────────────────────────────── */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 90;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.nav.is-solid {
  background: var(--bone);
  border-bottom-color: var(--hairline);
}

.nav__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: 14px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.nav__brand {
  font-family: var(--font-display);
  font-size: 0.9375rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--shell);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.nav.is-solid .nav__brand { color: var(--sage-deep); }

.nav__links {
  display: none;
  gap: 26px;
}
.nav__links a {
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--bone);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.nav.is-solid .nav__links a { color: var(--ink); }
.nav__links a:hover { border-bottom-color: var(--clay); }

.nav__toggle {
  display: grid;
  gap: 5px;
  width: 44px;
  height: 44px;
  place-content: center;
  margin-right: -11px; /* keeps the bars optically flush with the gutter */
}
.nav__toggle-bar {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--shell);
  transition: transform var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.nav.is-solid .nav__toggle-bar { background: var(--ink); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:first-child { transform: translateY(3.25px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bar:last-child { transform: translateY(-3.25px) rotate(-45deg); }

/* Mobile drawer. */
@media (max-width: 767.98px) {
  .nav__links.is-open {
    display: flex;
    flex-direction: column;
    gap: 0;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    background: var(--bone);
    border-bottom: 1px solid var(--hairline);
    padding: 8px var(--gutter) 16px;

    /* allow-discrete lets `display` participate so the panel can fade in
       instead of popping. Engines without it get today's instant open. */
    opacity: 1;
    transform: translateY(0);
    transition: opacity var(--dur-fast) var(--ease),
                transform var(--dur-fast) var(--ease),
                display var(--dur-fast) allow-discrete;
  }
  @starting-style {
    .nav__links.is-open {
      opacity: 0;
      transform: translateY(-8px);
    }
  }
  .nav__links.is-open a {
    color: var(--ink);
    padding: 14px 0;
    border-bottom: 1px solid var(--hairline);
  }
  .nav__links.is-open a:last-child { border-bottom: 0; }
}

@media (min-width: 768px) {
  .nav__links { display: flex; }
  .nav__toggle { display: none; }
}

/* ── Sticky mobile bar ─────────────────────────────────────────────── */
/* Stays put once shown — it's the primary conversion path (BRIEF §7). */

.stickybar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 95;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px var(--gutter);
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--shell);
  border-top: 1px solid var(--hairline);
  transform: translateY(100%);
  transition: transform 300ms var(--ease);
}
.stickybar.is-visible { transform: translateY(0); }

/* nowrap + flex-shrink:0 because a wrapping date pushed the whole bar from
   65px to 91px tall. The CTA absorbs the remaining width instead. The date
   line is longer than the price it replaced, hence the smaller display size —
   at 320px "October 25–30, 2026" at 1rem does not leave room for a button. */
.stickybar__meta {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  line-height: 1.2;
  white-space: nowrap;
}
.stickybar__meta strong {
  font-family: var(--font-display);
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--sage-deep);
}
.stickybar__meta span {
  font-size: 0.6875rem;
  color: var(--muted);
}

.stickybar__tg {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  margin-left: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  color: var(--sage);
  transition: border-color var(--dur-fast) var(--ease),
              transform 140ms var(--ease);
}
.stickybar__tg:hover { border-color: var(--sage); }

/* Shrinks to keep the row inside the gutter at 320px, where price + Telegram
   + button are ~20px wider than the available space. */
.stickybar__cta {
  min-height: 44px;
  padding: 12px 16px;
  font-size: 0.875rem;
  flex-shrink: 1;
  min-width: 0;
}

@media (min-width: 768px) {
  .stickybar { display: none; }
}

/* ── Messenger bubble (desktop only) ───────────────────────────────── */

.bubble {
  display: none;
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 92;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}

.bubble__menu {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  background: var(--shell);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);

  /* Grows from the button that spawned it, not from nowhere. The trigger sits
     below-right, so that corner is the origin. Never scale(0) — 0.96. */
  transform-origin: bottom right;
  opacity: 1;
  transform: scale(1);
  transition: opacity var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              display var(--dur-fast) allow-discrete;
}
@starting-style {
  .bubble__menu {
    opacity: 0;
    transform: scale(0.96);
  }
}
.bubble__item {
  padding: 8px 16px;
  border-radius: var(--radius);
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease);
}
.bubble__item:hover { background: var(--bone); }

.bubble__btn {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--sage-deep);
  color: var(--bone);
  transition: background-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.bubble__btn:hover { background: var(--sage); }
.bubble__btn:active { transform: scale(0.96); }

@media (min-width: 768px) {
  .bubble { display: flex; }
}

/* ── Lightbox ──────────────────────────────────────────────────────── */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 16px;
  background: rgb(var(--night-rgb) / 0.94);
  opacity: 0;
  transition: opacity 250ms var(--ease);
}
.lightbox.is-open { opacity: 1; }
.lightbox[hidden] { display: none; }

.lightbox__figure {
  grid-column: 2;
  display: grid;
  place-items: center;
  max-height: 100%;
  min-width: 0;
}
.lightbox__figure img {
  max-width: 100%;
  max-height: calc(100svh - 32px);
  width: auto;
  border-radius: var(--radius-card);
  transform: scale(0.96);
  transition: transform 250ms var(--ease),
              opacity 150ms var(--ease);
}
.lightbox.is-open .lightbox__figure img { transform: scale(1); }

/* Held while the next photo decodes, so prev/next crossfades instead of
   hard-cutting. A transition, not keyframes — rapid arrow presses retarget. */
.lightbox__figure img.is-swapping { opacity: 0.4; }

.lightbox__close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--shell);
  background: rgb(var(--bone-rgb) / 0.1);
}

.lightbox__nav {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--shell);
  background: rgb(var(--bone-rgb) / 0.1);
}
.lightbox__nav--prev { grid-column: 1; }
.lightbox__nav--next { grid-column: 3; }
.lightbox__close:hover, .lightbox__nav:hover { background: rgb(var(--bone-rgb) / 0.2); }

body.is-locked { overflow: hidden; }

/* =====================================================================
   Motion
   One easing curve. Transform and opacity only. Reveal once.
   ===================================================================== */

/* Every hidden-until-revealed state is gated behind `.js`, which main.js
   adds to <html> immediately. If the script fails to load or run, the page
   renders fully visible instead of blank. */
.js [data-reveal],
.js [data-stagger],
.js [data-resonance],
.js [data-final] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--dur-reveal) var(--ease),
              transform var(--dur-reveal) var(--ease);
  transition-delay: var(--delay, 0ms);
}

.js [data-reveal] { transform: translateY(24px); }

[data-reveal].is-in,
[data-stagger].is-in,
[data-resonance].is-in,
[data-final].is-in {
  opacity: 1;
  transform: none;
}

/* §3 lines settle at 0.35 first, then brighten (see JS scroll-linked mode). */
[data-resonance].is-in { transition-duration: 800ms; }

/* §5 portrait: clip-path inset from the bottom.

   The clip goes on the child, never on the observed element itself. A
   clip-path of inset(0 0 100%) collapses the element's own intersection
   rectangle to zero height, so IntersectionObserver reports isIntersecting
   false however far it scrolls into view — the reveal that would remove the
   clip can never fire, and the portrait stays invisible forever. Clipping the
   inner <picture> keeps the figure itself measurable. */
.js [data-reveal-clip] > * {
  display: block;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 900ms var(--ease);
}
.js [data-reveal-clip].is-in > * { clip-path: inset(0 0 0 0); }

/* §15 pacing decelerates at the end. */
[data-final] {
  transition-duration: var(--dur-slow);
}

/* §1 hero: text stagger, H1 via a clip-path line mask rather than a fade. */
.js [data-hero] {
  opacity: 0;
  transform: translateY(24px);
}
.hero.is-ready [data-hero] {
  animation: hero-in var(--dur-reveal) var(--ease) forwards;
}
.hero.is-ready [data-hero="1"] { animation-delay: 100ms; }
.hero.is-ready [data-hero="2"] { animation-delay: 240ms; }
.hero.is-ready [data-hero="3"] { animation-delay: 520ms; }
.hero.is-ready [data-hero="4"] { animation-delay: 660ms; }
.hero.is-ready [data-hero="5"] { animation-delay: 800ms; }

@keyframes hero-in {
  to { opacity: 1; transform: none; }
}

.hero__title { opacity: 1 !important; transform: none !important; animation: none !important; }
.js .hero__title-mask {
  clip-path: inset(0 0 110% 0);
  transform: translateY(12px);
  transition: clip-path 900ms var(--ease) 240ms,
              transform 900ms var(--ease) 240ms;
}
.hero.is-ready .hero__title-mask {
  clip-path: inset(-10% -5% -10% -5%);
  transform: none;
}

/* §4 collage parallax and §8 reverse Ken Burns.
   Driven by scroll-linked animations where supported — no scroll listeners.
   Desktop only; on smaller screens these are disabled, not degraded. */
@media (min-width: 1024px) {
  @supports (animation-timeline: view()) {
    [data-parallax] {
      animation: parallax linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    [data-parallax="8"]  { --parallax-dist: 8px; }
    [data-parallax="16"] { --parallax-dist: 16px; }
    [data-parallax="24"] { --parallax-dist: 24px; }

    @keyframes parallax {
      from { transform: translateY(var(--parallax-dist)); }
      to   { transform: translateY(calc(var(--parallax-dist) * -1)); }
    }

    /* Images start at 1.08 and settle to 1.0 — it feels like arriving. */
    [data-kenburns] img {
      animation: kenburns-reverse linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 60%;
    }
    @keyframes kenburns-reverse {
      from { transform: scale(1.08); }
      to   { transform: scale(1); }
    }
  }
}

/* §3 stronger option: opacity tied to scroll position, each line
   brightening 0.35 → 1 as it crosses the viewport centre. */
@supports (animation-timeline: view()) {
  [data-resonance].is-in {
    animation: resonance-brighten linear both;
    animation-timeline: view();
    animation-range: entry 20% cover 55%;
  }
  @keyframes resonance-brighten {
    from { opacity: 0.35; }
    to   { opacity: 1; }
  }
}

/* ── Reduced motion ────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 150ms !important;
    transition-delay: 0ms !important;
  }

  /* Every reveal collapses to a 150ms opacity fade. */
  [data-reveal],
  [data-stagger],
  [data-resonance],
  [data-final],
  [data-hero] {
    transform: none !important;
    transition: opacity 150ms linear !important;
  }
  .js [data-hero] { opacity: 1 !important; }

  [data-reveal-clip], [data-reveal-clip] > * { clip-path: none !important; }
  .hero__title-mask { clip-path: none !important; transform: none !important; }

  .outcome::after { transform: scaleX(1) !important; transition: none !important; }
  .hero__cue-line { animation: none !important; }
  .hero__img { animation: none !important; }

  [data-parallax], [data-kenburns] img {
    animation: none !important;
    transform: none !important;
  }
  [data-resonance].is-in { animation: none !important; opacity: 1 !important; }

  .archive__strip { scroll-behavior: auto; }
}

/* ── Legal pages ───────────────────────────────────────────────────────
   Shared by privacy.html, offer.html and cookies.html. Long-form reading,
   so the measure is tighter than the landing page and nothing animates:
   a policy must render fully with JS off and be printable.
   ────────────────────────────────────────────────────────────────────── */

.legal {
  padding: calc(var(--section-y) + 64px) 0 var(--section-y);
  background: var(--shell);
}

.legal__wrap {
  max-width: 760px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.legal__back {
  display: inline-block;
  margin-bottom: 32px;
  font-size: var(--fs-small);
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 2px;
}
.legal__back:hover { color: var(--ink); border-bottom-color: var(--ink); }

.legal h1 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-display);
  color: var(--ink);
  margin: 0 0 12px;
}

.legal__updated {
  font-size: var(--fs-small);
  color: var(--muted);
  margin: 0 0 40px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}

.legal h2 {
  font-family: var(--font-body);
  font-size: var(--fs-h3);
  font-weight: 600;
  color: var(--ink);
  margin: 40px 0 12px;
}

.legal h3 {
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--ink);
  margin: 28px 0 8px;
}

.legal p,
.legal li {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
}

.legal p { margin: 0 0 16px; }

.legal ul, .legal ol { margin: 0 0 16px; padding-left: 24px; }
.legal li { margin-bottom: 8px; }

.legal a { color: var(--bronze); }

.legal table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 24px;
  font-size: var(--fs-small);
}
.legal th, .legal td {
  text-align: left;
  padding: 12px 10px;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  color: var(--ink);
  /* An email address is one unbreakable word. Without this it sets the table's
     min-content width and pushes the identity tables past a 320px screen. */
  overflow-wrap: anywhere;
}
.legal th { font-weight: 600; }

/* Wide tables must scroll inside their own box, never the page body. */
.legal__scroll { overflow-x: auto; margin: 0 0 24px; }
.legal__scroll table { margin: 0; min-width: 460px; }

/* Unfilled legal facts. Deliberately loud: these MUST NOT reach production.
   Grep for "legal-todo" to find every remaining one. */
.legal-todo {
  background: #FDF3D7;
  border-bottom: 2px solid var(--clay);
  padding: 1px 5px;
  font-weight: 600;
  color: #5A4420;
}

.legal__note {
  background: var(--bone);
  border-left: 3px solid var(--sage);
  padding: 16px 20px;
  margin: 0 0 24px;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.legal__note p:last-child { margin-bottom: 0; }

@media print {
  .legal { padding: 0; background: #fff; }
  .legal__back, .nav, .footer__social { display: none; }
  .legal-todo { background: none; border-bottom: 1px solid #000; }
}
