/* =========================================================
   Light House Surf Camp — Bali Luxury Retreat Theme
   Ivory · teak · jungle · clay · brass — editorial & refined

   Breakpoints
     1180px  nav collapses to the drawer (9 links need 1195px to sit flat)
      980px  tablet — multi-column grids halve
      760px  large phone — everything single column, CTAs go full width
      560px  phone — masonry/footer/photo band tighten
   ========================================================= */
:root{
  /* surfaces */
  --ivory:#f7f1e6;
  --ivory-2:#f1e8d8;
  --sand:#e8dcc4;
  --linen:#efe6d4;
  --paper:#fffdf8;
  /* ink */
  --ink:#272019;
  --ink-soft:#5a5044;
  --stone:#8a7c68;
  /* accents */
  --clay:#b3623d;
  --clay-dk:#9a4f2e;
  --brass:#a98a4e;
  --brass-dk:#8f7340;
  --jungle:#33402e;
  --jungle-2:#3f4f37;
  --espresso:#221b14;
  /* misc */
  --line:rgba(39,32,25,.14);
  --line-soft:rgba(39,32,25,.08);
  --line-dk:rgba(247,241,230,.18);
  --shadow:0 30px 70px -34px rgba(34,27,20,.5);
  --shadow-soft:0 18px 44px -28px rgba(34,27,20,.32);
  --r:8px;
  --ri:4px;
  --maxw:1280px;
  --display:"Fraunces",Georgia,serif;
  --body:"Manrope",system-ui,sans-serif;
  /* legacy aliases */
  --deep:#272019;
  --gold:#a98a4e;
  --sunset:#b3623d;
  /* ---- ocean: the water register --------------------------------
     Desaturated and green-cast on purpose so the blues sit beside the
     warm sand base instead of fighting it. The ramp is deliberately deep:
     the dark surfaces carry ivory text at reduced alpha (.75-.88) for
     hierarchy, and every one of those alphas must still clear 4.5:1
     against the LIGHTEST end of the gradient, --ocean-2. Measured:
       ivory on --ocean-2   6.82:1     ivory @.75 on --ocean-2  4.64:1
       ivory on --ocean     9.25:1     --sand on --ocean-2      5.64:1
       ink   on --foam     12.68:1     white on --ocean        10.40:1
     --lagoon is the one exception: 2.58:1 on ivory and 2.64:1 on
     --ocean-2, so it is for accents, borders and large display type
     ONLY. Never set body copy in it. ---------------------------- */
  --foam:#dbe7e5;      /* palest wash: tinted surfaces, hairlines */
  --lagoon:#57a3ad;    /* shallow water: accents + large text only */
  --lagoon-dk:#3d8a95;
  --ocean-2:#1a5b68;   /* light end of every ocean gradient */
  --ocean:#134650;     /* the workhorse blue */
  --ocean-dk:#0d333b;  /* pressed / hover state */
  --abyss:#08222a;     /* deepest water */
  /* layout metrics */
  --nav-h:90px;
  --gutter:clamp(22px,4.8vw,40px);
  --tap:44px;
  --safe-b:env(safe-area-inset-bottom,0px);
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--nav-h) + 14px);-webkit-text-size-adjust:100%}
body{
  font-family:var(--body);
  background:var(--ivory);
  color:var(--ink);
  line-height:1.75;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
/* iOS-safe scroll lock while the mobile drawer is open (JS restores scrollY) */
body.nav-open{position:fixed;left:0;right:0;width:100%;overflow:hidden}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}

/* Visible keyboard focus — there was none before */
:focus-visible{outline:2px solid var(--brass);outline-offset:3px}

h1,h2,h3,h4{font-family:var(--display);font-weight:400;line-height:1.06;letter-spacing:-.015em;color:var(--ink);text-wrap:balance;overflow-wrap:break-word}
h1{font-size:clamp(2.4rem,7.2vw,6.2rem)}
h2{font-size:clamp(1.85rem,4.6vw,3.9rem)}
h3{font-size:clamp(1.25rem,2.4vw,1.95rem)}
.eyebrow{
  font-family:var(--body);font-weight:700;text-transform:uppercase;
  letter-spacing:.34em;font-size:.7rem;color:var(--brass);
  display:inline-flex;align-items:center;gap:12px;margin-bottom:20px;
}
.eyebrow::before{content:"";width:34px;height:1px;background:var(--brass);flex:none}
.lead{font-size:clamp(1rem,1.55vw,1.28rem);color:var(--ink-soft);max-width:62ch;font-weight:400;text-wrap:pretty}
p{color:var(--ink-soft);text-wrap:pretty}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:11px;
  padding:16px clamp(20px,3.2vw,34px);border-radius:2px;font-weight:700;min-height:52px;
  font-size:.82rem;letter-spacing:.12em;text-transform:uppercase;cursor:pointer;border:none;
  text-align:center;line-height:1.25;
  transition:transform .4s cubic-bezier(.2,.8,.2,1),box-shadow .4s,background .35s,color .35s,border-color .35s;
}
.btn-primary{background:var(--clay);color:#fff}
.btn-primary:hover{background:var(--clay-dk);transform:translateY(-2px);box-shadow:0 16px 34px -14px rgba(154,79,46,.65)}
.btn-ghost{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.55)}
.btn-ghost:hover{background:#fff;color:var(--ink);border-color:#fff;transform:translateY(-2px)}
.btn-gold{background:var(--brass);color:#fff}
.btn-gold:hover{background:var(--brass-dk);transform:translateY(-2px)}
.btn-ocean{background:var(--ocean);color:#fff}
.btn-ocean:hover{background:var(--ocean-dk);transform:translateY(-2px)}
.btn .arrow{transition:transform .4s;flex:none}
.btn:hover .arrow{transform:translateX(5px)}

/* Outline button for light surfaces. `.btn-ghost` used to go white-on-white
   whenever a pale card sat inside a dark section (packages.html) — the ancestor
   list below repairs that automatically wherever the surface is light. */
.btn-line,
.bg-paper .btn-ghost,.bg-cream .btn-ghost,
.card .btn-ghost,.price:not(.feat) .btn-ghost,
.form-card .btn-ghost,.quote .btn-ghost,.contact-strip .btn-ghost{
  background:transparent;color:var(--ink);border:1px solid var(--line)
}
.btn-line:hover,
.bg-paper .btn-ghost:hover,.bg-cream .btn-ghost:hover,
.card .btn-ghost:hover,.price:not(.feat) .btn-ghost:hover,
.form-card .btn-ghost:hover,.quote .btn-ghost:hover,.contact-strip .btn-ghost:hover{
  background:var(--ink);color:#fff;border-color:var(--ink)
}
/* …but a dark card inside a light section must keep the white ghost treatment */
.bg-paper .price.feat .btn-ghost,.bg-cream .price.feat .btn-ghost,
.bg-paper .mcard .btn-ghost,.bg-cream .mcard .btn-ghost{
  color:#fff;border-color:rgba(255,255,255,.55)
}
.bg-paper .price.feat .btn-ghost:hover,.bg-cream .price.feat .btn-ghost:hover{
  background:#fff;color:var(--ink);border-color:#fff
}

/* ---------- Nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;gap:22px;flex-wrap:nowrap;
  padding:24px var(--gutter);transition:background .5s,padding .5s,box-shadow .5s;
}
.nav.scrolled{background:rgba(247,241,230,.92);backdrop-filter:blur(16px);padding:14px var(--gutter);box-shadow:0 1px 0 var(--line-soft)}
.brand{display:flex;align-items:center;gap:13px;font-family:var(--display);font-size:1.3rem;color:#fff;transition:color .5s;flex:none;white-space:nowrap}
.nav.scrolled .brand{color:var(--ink)}
.brand .mark{
  width:42px;height:42px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:transparent;border:1px solid rgba(255,255,255,.5);font-size:1.05rem;transition:border-color .5s;
}
.nav.scrolled .brand .mark{border-color:var(--brass)}
.brand b{font-weight:600;letter-spacing:.1em;text-transform:uppercase;background:linear-gradient(100deg,var(--brass),var(--clay) 75%);-webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 1px 5px rgba(0,0,0,.35))}
.nav.scrolled .brand b,.footer .brand b{filter:none}
/* The wordmark paints a gradient through the letterforms, which needs
   color:transparent — so if background-clip:text is ever unsupported the
   brand name renders as nothing at all rather than degrading. Repaint it in
   solid brass in that case; no browser that supports the clip sees this. */
@supports not ((background-clip:text) or (-webkit-background-clip:text)){
  .brand b{background:none;color:var(--brass)}
}
.brand .mark svg{width:23px;height:23px;display:block}
.brand small{display:block;font-family:var(--body);font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;color:rgba(255,255,255,.75);margin-top:2px;white-space:nowrap}
.nav.scrolled .brand small{color:var(--brass)}
.nav-links{display:flex;align-items:center;gap:clamp(18px,2.1vw,30px);list-style:none;min-width:0}
/* ---- language switcher: disclosure dropdown ----------------------
   A <button aria-expanded> sitting over a <ul> of real <a href> links to
   the static /de/ /fr/ /ru/ … pages. It reads as a select and behaves as
   one, but it is not a <select>: a native select cannot contain an
   anchor, so its nine options would be invisible to crawlers, impossible
   to open in a new tab and dead with JS off — which is the entire reason
   these pages have their own URLs in the first place.

   Two copies exist in the markup — .lang-bar in the nav rail and
   .lang-drawer inside the slide-in menu — because at 375px the bar has
   exactly 0px of slack once the logo, Book Now and the burger are placed
   (measured: 306px used of 316px available). Each copy is hidden at the
   breakpoint where the other shows, so only one is ever focusable. */
.lang{position:relative;flex:none;margin-right:2px}

/* The trigger. Sized to the 36px the nav rail can spare beside a 46px
   button; the drawer copy grows it to the full 44px tap target below. */
.lang-toggle{
  display:flex;align-items:center;gap:7px;
  height:36px;padding:0 9px 0 11px;
  font-family:var(--body);font-size:.68rem;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;
  color:rgba(255,255,255,.82);
  background:rgba(255,255,255,.1);
  border:1px solid rgba(255,255,255,.2);border-radius:100px;
  cursor:pointer;white-space:nowrap;
  text-shadow:0 1px 10px rgba(34,27,20,.35);
  transition:color .3s,background .3s,border-color .3s
}
.lang-toggle:hover{color:#fff;background:rgba(255,255,255,.2)}
.lang-toggle[aria-expanded="true"]{color:#fff;background:rgba(255,255,255,.22)}

/* Flags are DRAWN, not typed. Naming the colour-emoji families ahead of the
   UI font was the right fix for the wrong problem: Segoe UI Emoji — the font
   every Chrome and Edge on Windows falls back to — deliberately ships no
   glyph for a regional-indicator pair, so there was nothing to fall back TO
   and the switcher rendered the bare letters "GB", "DE", "IT" for the
   largest single slice of this site's traffic. Each flag is now a <use> of
   a <symbol> in the per-page sprite; see FLAG_SPRITE in tools/i18n-build.js.

   One 4:3 box for all nine, so a nine-row menu has a single column edge
   rather than nine ragged ones — real flag ratios run from 1:1 (Switzerland)
   to 2:1 (the UK) and would look like a mistake stacked on top of each
   other. */
.lang-flag{
  display:block;flex:none;width:21px;height:15.75px;
  border-radius:2.5px;overflow:hidden;
  /* Japan, Israel and the top band of Russia are white to the edge, so
     without a hairline they dissolve into the pale dropdown. */
  box-shadow:0 0 0 1px rgba(11,26,38,.18)
}
/* On the photograph the ring has to flip, for exactly the same reason in
   reverse — and flip back once the nav turns to paper on scroll. */
.lang-toggle .lang-flag{box-shadow:0 0 0 1px rgba(255,255,255,.42)}
.nav.scrolled .lang-toggle .lang-flag{box-shadow:0 0 0 1px rgba(11,26,38,.18)}
/* The drawer is dark at every scroll position, so its flags keep the light
   ring; (0,3,0) to match .nav.scrolled .lang-toggle .lang-flag above. */
.lang-drawer .lang-flag,
.nav.scrolled .lang-drawer .lang-flag{box-shadow:0 0 0 1px rgba(247,241,230,.34)}

/* The sprite itself: nine <symbol> definitions at the top of <body> that
   never paint. The width/height attributes keep it out of layout and
   position takes it out of flow, so it cannot open the page with a stray
   empty line box. */
.flag-sprite{position:absolute;width:0;height:0;overflow:hidden}
.lang-code{line-height:1}
.lang-caret{width:9px;height:6px;flex:none;opacity:.75;transition:transform .35s cubic-bezier(.2,.8,.2,1)}
.lang-toggle[aria-expanded="true"] .lang-caret{transform:rotate(180deg)}

/* The panel. Anchored to the trigger's right edge so a nine-row list
   opens inward from the nav rail instead of off the side of the page. */
.lang-menu{
  position:absolute;top:calc(100% + 11px);inset-inline-end:0;z-index:130;
  min-width:196px;padding:7px;list-style:none;
  background:var(--paper);border:1px solid var(--line-soft);border-radius:14px;
  box-shadow:0 24px 54px -22px rgba(8,34,42,.42);
  /* Animated with opacity/transform rather than display, so the open and
     close both have a transition to run. visibility rides along as a 0s
     step — delayed on close so the panel stays painted through the fade,
     immediate on open because the JS may focus a link in the same tick
     and a still-hidden element silently refuses focus. */
  opacity:0;visibility:hidden;transform:translateY(-8px) scale(.97);transform-origin:top right;
  transition:opacity .26s ease,transform .26s cubic-bezier(.2,.8,.2,1),visibility 0s .26s
}
.lang-toggle[aria-expanded="true"]+.lang-menu{
  opacity:1;visibility:visible;transform:none;transition-delay:0s,0s,0s
}
.lang-menu a{
  display:flex;align-items:center;gap:11px;
  min-height:38px;padding:7px 11px;border-radius:9px;
  font-family:var(--body);font-size:.87rem;font-weight:500;letter-spacing:0;
  text-transform:none;text-shadow:none;white-space:nowrap;
  color:var(--ink-soft);transition:color .22s,background .22s
}
.lang-menu a:hover,.lang-menu a:focus-visible{background:var(--foam);color:var(--ocean)}
.lang-menu a.on{background:var(--foam);color:var(--ocean);font-weight:700}
/* The current language earns a tick rather than colour alone — colour is
   the one signal a colour-blind visitor may not receive, and this menu
   has no other way to say "you are here". */
.lang-menu a.on::after{content:"✓";margin-inline-start:auto;font-size:.8rem;opacity:.85}

/* Scrolled: the nav turns to paper, so the trigger has to follow it off
   the photograph and onto a light surface. */
.nav.scrolled .lang-toggle{
  color:var(--ink-soft);background:var(--foam);border-color:var(--line-soft);text-shadow:none
}
.nav.scrolled .lang-toggle:hover,.nav.scrolled .lang-toggle[aria-expanded="true"]{
  color:var(--ocean);background:var(--sand)
}

.lang-drawer{display:none}
.lang-li{margin-top:6px}
.nav-links a{display:inline-block;font-size:.78rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.9);position:relative;transition:color .3s;text-shadow:0 1px 10px rgba(34,27,20,.35);white-space:nowrap}
.nav.scrolled .nav-links a{color:var(--ink-soft);text-shadow:none}
/* The underline is laid out at full width and revealed with scaleX rather
   than grown from width:0. Visually identical for a solid 1px bar, but a
   width transition relayouts the link on every frame of the 350ms sweep,
   while a transform is handed to the compositor and costs nothing. */
.nav-links a::after{content:"";position:absolute;inset-inline-start:0;bottom:-7px;width:100%;height:1px;background:var(--brass);transform:scaleX(0);transform-origin:inline-start;transition:transform .35s}
.nav-links a:hover,.nav-links a.active{color:#fff}
.nav.scrolled .nav-links a:hover,.nav.scrolled .nav-links a.active{color:var(--clay)}
.nav-links a:hover::after,.nav-links a.active::after{transform:scaleX(1)}
.nav-cta{display:flex;gap:14px;align-items:center;flex:none}
.nav-cta .btn{white-space:nowrap;min-height:46px;padding:13px clamp(18px,2.4vw,28px)}
/* Drawer-only "Book Now" — injected by main.js, hidden on desktop */
.nav-drawer-cta{display:none;width:100%;margin-top:8px}
.nav-drawer-cta .btn{width:100%}
/* Scrim behind the drawer — injected by main.js */
.nav-scrim{position:fixed;inset:0;z-index:99;background:rgba(26,20,14,.55);backdrop-filter:blur(2px);opacity:0;visibility:hidden;transition:opacity .4s,visibility 0s .4s}
.nav-scrim.on{opacity:1;visibility:visible;transition:opacity .4s,visibility 0s}

.burger{
  display:none;width:var(--tap);height:var(--tap);padding:0;flex:none;
  flex-direction:column;align-items:center;justify-content:center;gap:5px;
  background:none;border:none;cursor:pointer;
}
.burger span{width:26px;height:1.5px;background:#fff;display:block;transition:transform .38s cubic-bezier(.2,.8,.2,1),opacity .25s,background .3s}
.nav.scrolled .burger span{background:var(--ink)}
/* X state — bar gap is 5px and bars are 1.5px, so centre-to-centre is 6.5px */
.burger[aria-expanded="true"] span{background:var(--ivory)}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0;transform:scaleX(.2)}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* ---------- Hero ---------- */
/* svh keeps the hero clear of the mobile URL bar; vh is the fallback */
.hero{position:relative;min-height:100vh;min-height:100svh;display:flex;align-items:flex-end;overflow:hidden}
/* THE HERO STACKING LADDER — media 0 · scrim 1 · cue 2 · copy 3 · dots 4.
   These used to be -2 and -1, painting the media and its wash BEHIND the
   header's own box. That works until something inside the media gets its own
   compositing layer — which is exactly what a playing <video> is. Measured in
   Chrome at a phone viewport: adding .hero-video promoted .hero-media, the
   promoted negative layer went behind the opaque page background, and the
   hero photograph disappeared entirely, leaving the gradient over white.

   A non-negative ladder gives the identical picture with no reliance on
   negative painting order at all: .hero-media still opens its own stacking
   context, so the film and the slides inside it remain trapped underneath
   the scrim above them, which is what keeps the headline readable. */
.hero-media{position:absolute;inset:0;z-index:0;overflow:hidden}
.hero-media>img{width:100%;height:100%;object-fit:cover;animation:slowzoom 20s ease-out forwards}
@keyframes slowzoom{from{transform:scale(1.14)}to{transform:scale(1)}}
/* slideshow */
.hero-media.slideshow .slide{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;opacity:0;transition:opacity 1.7s ease-in-out;animation:none}
.hero-media.slideshow .slide.active{opacity:1;animation:kenburns 7s ease-out forwards}
@keyframes kenburns{from{transform:scale(1.1)}to{transform:scale(1)}}

/* ---------- Hero background video ----------
   The film lives INSIDE .hero-media, which is positioned and therefore opens
   a stacking context of its own. Nothing in here can climb above the
   .hero::after scrim one rung up the ladder — which is the whole point:
   the video is graded by exactly the same gradient wash that makes the
   headline readable over the photographs, so nothing about .hero-inner,
   the type, or the layout has to change to accommodate it.

   It ships invisible. main.js reveals it only once frames are genuinely
   playing, so a phone in Low Power Mode — which silently refuses to
   autoplay even muted inline video — simply keeps the slideshow instead of
   showing a black rectangle. The espresso ground behind it covers the
   split second between the poster and the first frame. */
.hero-video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center;
  background:var(--espresso);
  opacity:0;transition:opacity 1.2s ease;pointer-events:none}
.hero.has-video .hero-video{opacity:1}
/* With the film running the photographs behind it are only its poster
   frame: stop the Ken Burns pass nobody can see, and take away dots that
   would offer to page through a slideshow that is no longer moving. */
.hero.has-video .hero-media .slide{animation:none}
.hero.has-video .hero-dots{display:none}
@media(prefers-reduced-motion:reduce){
  /* A moving full-bleed background is precisely what this preference is
     asking us not to serve. main.js never even attaches a src; this is the
     belt to that braces, in case the film is hard-coded in the markup. */
  .hero-video{display:none}
}

.hero-dots{position:absolute;bottom:24px;inset-inline-end:calc(var(--gutter) + 2px);z-index:4;display:flex;gap:4px}
.hero-dots button{
  width:34px;height:var(--tap);padding:0;border:none;background:none;cursor:pointer;
  display:grid;place-items:center;
}
.hero-dots button::after{
  content:"";width:9px;height:9px;border-radius:50%;
  border:1px solid rgba(255,255,255,.75);background:transparent;
  transition:width .35s,background .35s,border-radius .35s;
}
.hero-dots button.on::after{background:#fff;width:28px;border-radius:6px}
.hero::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(34,27,20,.4) 0%,rgba(34,27,20,.12) 38%,rgba(34,27,20,.45) 72%,rgba(34,27,20,.92) 100%)}
/* position + z-index so the copy still sits above the scrim now that the
   scrim is a positive layer rather than a negative one. */
.hero-inner{position:relative;z-index:3;padding-top:calc(var(--nav-h) + 24px);padding-bottom:9vh;max-width:940px}
.hero h1{margin:18px 0 24px;color:#fff;font-weight:300;text-shadow:0 4px 40px rgba(0,0,0,.4)}
.hero h1 .glow{color:var(--sand);font-style:italic}
.hero .lead{color:rgba(255,255,255,.92);text-shadow:0 2px 20px rgba(0,0,0,.5)}
.hero .eyebrow{color:rgba(255,255,255,.92)}.hero .eyebrow::before{background:var(--sand)}
.hero-meta{display:flex;flex-wrap:wrap;gap:16px;margin-top:38px;align-items:center}
.hero-stats{display:flex;gap:36px;margin-inline-start:auto;flex-wrap:wrap}
.stat b{font-family:var(--display);font-size:clamp(1.65rem,5.2vw,2rem);color:#fff;display:block;line-height:1;font-weight:300}
.stat span{font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--sand)}
.scroll-cue{position:absolute;bottom:26px;left:50%;transform:translateX(-50%);z-index:2;
  font-size:.64rem;letter-spacing:.3em;text-transform:uppercase;color:rgba(255,255,255,.8);
  display:flex;flex-direction:column;align-items:center;gap:9px;pointer-events:none}
.scroll-cue i{width:1px;height:46px;background:linear-gradient(var(--sand),transparent);animation:cue 2.2s infinite}
@keyframes cue{0%,100%{opacity:.3;transform:scaleY(.6)}50%{opacity:1;transform:scaleY(1)}}

/* ---------- Sections ---------- */
section{position:relative}
.section{padding:clamp(78px,11.5vw,170px) 0}
.section-head{max-width:720px;margin-bottom:clamp(42px,5.6vw,74px)}
.section-head.center{margin:0 auto clamp(34px,5vw,60px);text-align:center}
.section-head.center .eyebrow{justify-content:center}

.bg-paper,.bg-cream{background:var(--ivory);color:var(--ink)}
.bg-cream{background:var(--ivory-2)}
.bg-paper h1,.bg-paper h2,.bg-paper h3,.bg-cream h1,.bg-cream h2,.bg-cream h3{color:var(--ink)}
.bg-paper p,.bg-cream p{color:var(--ink-soft)}

.bg-deep{background:linear-gradient(165deg,var(--ocean-dk),var(--abyss));color:var(--ivory)}
.bg-deep h1,.bg-deep h2,.bg-deep h3{color:var(--ivory)}
.bg-deep p,.bg-deep .lead{color:rgba(247,241,230,.78)}
.bg-deep .eyebrow{color:var(--sand)}.bg-deep .eyebrow::before{background:var(--brass)}

.bg-teal{background:linear-gradient(160deg,var(--ocean-2),var(--ocean));color:var(--ivory)}
.bg-teal h1,.bg-teal h2,.bg-teal h3{color:var(--ivory)}
.bg-teal p,.bg-teal .lead{color:rgba(247,241,230,.82)}
.bg-teal .eyebrow{color:var(--sand)}.bg-teal .eyebrow::before{background:var(--sand)}

/* A pale card nested in a dark section still needs dark type inside it */
.bg-deep .price:not(.feat) h3,.bg-teal .price:not(.feat) h3,
.bg-deep .price:not(.feat) .amt,.bg-teal .price:not(.feat) .amt{color:var(--ink)}
.bg-deep .price:not(.feat) ul li,.bg-teal .price:not(.feat) ul li,
.bg-deep .price:not(.feat) p,.bg-teal .price:not(.feat) p{color:var(--ink-soft)}
.bg-deep .price:not(.feat) .per,.bg-teal .price:not(.feat) .per{color:var(--stone)}

/* ---------- Marquee strip ---------- */
/* The gap used to live on .track, so translateX(-50%) landed 46px short and the
   loop visibly jumped. Spacing now lives inside each half, so -50% is seamless. */
.strip{background:var(--jungle);color:var(--ivory);padding:18px 0;overflow:hidden;white-space:nowrap;border-top:1px solid var(--line-dk);border-bottom:1px solid var(--line-dk)}
.strip .track{display:inline-flex;gap:0;animation:marq 30s linear infinite;font-family:var(--display);font-size:clamp(1rem,3vw,1.25rem);font-style:italic;font-weight:300;will-change:transform}
.strip span{display:inline-flex;align-items:center;gap:46px;padding-inline-end:46px;color:var(--sand)}
@keyframes marq{to{transform:translateX(-50%)}}

/* ---------- Feature grid ---------- */
.grid{display:grid;gap:clamp(20px,2.8vw,34px)}
.g-3{grid-template-columns:repeat(3,1fr)}
.g-2{grid-template-columns:repeat(2,1fr)}
.g-4{grid-template-columns:repeat(4,1fr)}
.card{
  background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);
  padding:clamp(26px,3.4vw,38px) clamp(22px,3vw,34px);transition:transform .45s,border-color .45s,box-shadow .45s;
}
.card h3{color:var(--ink)}.card p{color:var(--ink-soft)}
.card:hover{transform:translateY(-6px);border-color:var(--brass);box-shadow:var(--shadow-soft)}
.card .ico{font-size:1.5rem;margin-bottom:18px;display:grid;place-items:center;width:54px;height:54px;border-radius:50%;
  background:transparent;border:1px solid var(--brass);color:var(--clay)}
.card h3{margin-bottom:11px;font-weight:400}
.card p{font-size:.96rem}
.bg-deep .card,.bg-teal .card{background:rgba(247,241,230,.06);border-color:var(--line-dk);backdrop-filter:blur(3px)}
.bg-deep .card h3,.bg-teal .card h3{color:var(--ivory)}
.bg-deep .card p,.bg-teal .card p{color:rgba(247,241,230,.8)}
.bg-deep .card .ico,.bg-teal .card .ico{border-color:var(--sand);color:var(--sand)}
.bg-deep .checklist li,.bg-teal .checklist li{color:rgba(247,241,230,.88)}

/* ---------- Media cards ---------- */
.mcard{position:relative;border-radius:var(--ri);overflow:hidden;min-height:clamp(300px,50vw,360px);display:flex;align-items:flex-end;box-shadow:var(--shadow-soft)}
.mcard img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform 1s cubic-bezier(.2,.8,.2,1)}
.mcard:hover img{transform:scale(1.06)}
.mcard::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 30%,rgba(26,20,14,.86))}
.mcard .body{position:relative;z-index:2;padding:clamp(22px,3vw,30px)}
.mcard .tag{display:inline-block;font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ivory);border:1px solid rgba(247,241,230,.6);padding:5px 13px;border-radius:2px;margin-bottom:13px;font-weight:600}
.mcard h3{color:#fff;margin-bottom:7px;font-weight:400}
.mcard p{color:rgba(247,241,230,.85);font-size:.92rem}

/* ---------- Split feature ---------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(46px,5.6vw,88px);align-items:center}
/* `direction:rtl` used to flip these, which also flipped punctuation and
   scrollbars in nested content. Flex/grid order does the same job cleanly. */
.split.rev>*:first-child{order:2}
.split.rev>*:last-child{order:1}
/* Stacked room/feature blocks — replaces a repeated inline margin-bottom:80px
   (one block on stay.html was missing it) and scales down on small screens */
.split-stack{margin-bottom:clamp(48px,7vw,80px)}
/* Room headings on stay.html carried this as an identical inline style 7 times. */
.room-title{font-size:clamp(1.7rem,3vw,2.4rem);margin-bottom:14px}
.split-media{border-radius:var(--ri);overflow:hidden;box-shadow:var(--shadow);position:relative;aspect-ratio:4/5}
.split-media img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s}
.split-media:hover img{transform:scale(1.05)}
.split-media.wide{aspect-ratio:4/3}
.checklist{list-style:none;margin-top:28px;display:grid;gap:15px}
.checklist li{display:flex;gap:15px;align-items:flex-start;font-size:1rem;color:var(--ink-soft)}
.checklist .tick{flex:none;width:26px;height:26px;border-radius:50%;background:transparent;border:1px solid var(--brass);color:var(--clay);display:grid;place-items:center;font-size:.72rem;font-weight:700}

/* ---------- Photo band ---------- */
.photoband{display:grid;grid-template-columns:repeat(4,1fr);gap:4px}
.photoband .ph{position:relative;aspect-ratio:3/4;overflow:hidden}
.photoband .ph img{width:100%;height:100%;object-fit:cover;transition:transform 1s}
.photoband .ph:hover img{transform:scale(1.06)}
.photoband .ph::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 50%,rgba(26,20,14,.6));opacity:.5;transition:opacity .4s}
.photoband .ph:hover::after{opacity:.85}
.photoband .cap{position:absolute;inset-inline-start:18px;bottom:16px;z-index:2;color:#fff;font-family:var(--display);font-style:italic;font-size:clamp(.95rem,2.6vw,1.1rem);letter-spacing:.01em}

/* ---------- Pricing ---------- */
.price-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,28px);align-items:stretch}
.price{display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);padding:clamp(28px,3.6vw,42px) clamp(22px,3vw,34px);position:relative;transition:transform .45s,box-shadow .45s,border-color .45s}
.price h3{color:var(--ink);font-weight:400;padding-inline-end:96px}
.price:hover{transform:translateY(-6px);box-shadow:var(--shadow-soft);border-color:var(--brass)}
.price.feat{background:linear-gradient(165deg,var(--ocean-2),var(--ocean));border-color:transparent;box-shadow:var(--shadow);color:var(--ivory)}
.price.feat h3{color:var(--ivory)}
.price .ribbon{position:absolute;top:24px;right:24px;background:var(--brass);color:#fff;font-size:.6rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:5px 13px;border-radius:2px;white-space:nowrap}
.price .amt{font-family:var(--display);font-size:clamp(2.4rem,6vw,3.1rem);color:var(--ink);line-height:1;margin:16px 0 5px;font-weight:300}
.price.feat .amt{color:var(--ivory)}
.price .amt small{font-size:1rem;color:var(--clay);font-family:var(--body);font-weight:700}
.price.feat .amt small{color:var(--sand)}
.price .per{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--stone)}
.price.feat .per{color:rgba(247,241,230,.75)}
.price ul{list-style:none;margin:26px 0 32px;display:grid;gap:13px}
.price ul li{display:flex;gap:11px;font-size:.94rem;color:var(--ink-soft)}
.price.feat ul li{color:rgba(247,241,230,.88)}
.price ul li::before{content:"—";color:var(--brass);flex:none}
.price.feat ul li::before{color:var(--sand)}
.price .btn{margin-top:auto;justify-content:center;width:100%}

/* ---------- Reviews ---------- */
.quote{background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);padding:clamp(26px,3.4vw,38px) clamp(22px,3vw,34px);display:flex;flex-direction:column;gap:18px}
.quote .stars{color:var(--brass);letter-spacing:4px;font-size:.9rem}
.quote p{font-family:var(--display);font-style:italic;font-size:clamp(1.05rem,2.2vw,1.18rem);color:var(--ink);line-height:1.55;font-weight:300}
.quote .who{display:flex;align-items:center;gap:13px;margin-top:auto}
.quote .av{width:44px;height:44px;flex:none;border-radius:50%;background:var(--clay);display:grid;place-items:center;color:#fff;font-weight:600;font-family:var(--display)}
/* Name over meta, not beside it. As inline siblings inside the wrapper
   these rendered as one run-on string — "Lena M.Germany · Beginner
   Course" — which then wrapped mid-phrase on narrow screens. */
.quote .who>div{display:flex;flex-direction:column;gap:2px;min-width:0}
.quote .who b{color:var(--ink);font-family:var(--body);font-weight:700}
/* Scoped to the inner wrapper. Written as `.quote .who span` this also
   matched .av — at (0,2,1) against the .quote .av rule's (0,2,0) — so it
   repainted the avatar initial brass on its clay disc (1.37:1 contrast)
   and shrank it to .8rem. */
.quote .who>div>span{font-size:.8rem;color:var(--brass);letter-spacing:.04em}
.bg-deep .quote,.bg-teal .quote{background:rgba(247,241,230,.06);border-color:var(--line-dk);backdrop-filter:blur(3px)}
.bg-deep .quote p,.bg-teal .quote p{color:var(--ivory)}
.bg-deep .quote .who b,.bg-teal .quote .who b{color:var(--ivory)}
.bg-deep .quote .who>div>span,.bg-teal .quote .who>div>span{color:var(--sand)}

/* ---------- Gallery masonry ---------- */
.masonry{columns:3;column-gap:14px}
.masonry img{width:100%;border-radius:var(--ri);margin-bottom:14px;transition:transform .6s,filter .6s;cursor:pointer;filter:saturate(.96)}
.masonry img:hover{transform:scale(1.015);filter:saturate(1.08)}

/* ---------- CTA band ---------- */
.cta-band{position:relative;border-radius:var(--ri);overflow:hidden;padding:clamp(44px,8vw,100px) clamp(24px,6vw,100px);text-align:center;box-shadow:var(--shadow)}
.cta-band img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2}
.cta-band::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,rgba(13,51,59,.48),rgba(8,34,42,.84))}
.cta-band h2{color:#fff;margin-bottom:20px;font-weight:300}
.cta-band .lead{color:rgba(255,255,255,.9);margin:0 auto}
.cta-band .eyebrow{color:rgba(255,255,255,.9);justify-content:center}.cta-band .eyebrow::before{background:var(--sand)}
.cta-band .btns{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-top:34px}

/* ---------- Footer ---------- */
.footer{background:var(--espresso);color:var(--ivory);padding:clamp(56px,8vw,80px) 0 calc(32px + var(--safe-b))}
.footer .brand{color:var(--ivory)}
.footer .brand .mark{border-color:var(--brass)}
.foot-grid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1.2fr;gap:clamp(30px,4vw,44px);margin-bottom:clamp(34px,4.5vw,54px)}
.footer h4{font-family:var(--body);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brass);margin-bottom:20px}
.footer a{display:block;color:rgba(247,241,230,.7);font-size:.92rem;margin-bottom:11px;transition:color .3s}
.footer a:hover{color:var(--sand)}
.footer address{font-style:normal;color:rgba(247,241,230,.7);font-size:.92rem}
.foot-brand p{font-size:.94rem;margin:18px 0 22px;max-width:36ch;color:rgba(247,241,230,.72)}
.socials{display:flex;gap:12px}
.socials a{width:var(--tap);height:var(--tap);border:1px solid var(--line-dk);border-radius:50%;display:grid;place-items:center;color:var(--ivory);font-size:.95rem;margin:0}
.socials a:hover{background:var(--clay);color:#fff;border-color:var(--clay)}
.foot-bottom{border-top:1px solid var(--line-dk);padding-top:26px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;font-size:.8rem;color:rgba(247,241,230,.5)}

/* ---------- Page hero (inner) ---------- */
.phero{position:relative;padding:calc(var(--nav-h) + clamp(56px,9vw,98px)) 0 clamp(64px,8vw,100px);overflow:hidden}
.phero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2}
.phero::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,rgba(34,27,20,.5),rgba(34,27,20,.35) 45%,rgba(26,20,14,.9))}
.phero h1{color:#fff;font-weight:300;text-shadow:0 4px 34px rgba(0,0,0,.4)}
.phero .lead{margin-top:18px;color:rgba(255,255,255,.92)}
.phero .eyebrow{color:rgba(255,255,255,.9)}.phero .eyebrow::before{background:var(--sand)}
/* thank-you.html's full-screen confirmation panel. It carried a raw inline
   min-height:100vh, which the mobile URL bar clips; svh measures the small
   viewport instead. Padding flexes so short screens don't overflow. */
.phero-full{min-height:100vh;min-height:100svh;display:flex;align-items:center;
  padding:clamp(96px,13vh,120px) 0 calc(clamp(96px,13vh,120px) + var(--safe-b))}
.crumb{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--sand);margin-bottom:16px;font-weight:600}
.crumb a:hover{color:#fff}

/* ---------- Booking ---------- */
.book-grid{display:grid;grid-template-columns:1.4fr .9fr;gap:clamp(28px,3.6vw,44px);align-items:start}
.form-card{background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);padding:clamp(22px,4.2vw,42px);box-shadow:var(--shadow-soft)}
/* #book is .bg-deep, and line 369's .bg-deep h1,h2,h3{color:var(--ivory)}
   is meant for text sitting directly on the dark section. But .form-card is a
   light cream card INSIDE that section, so the section rule bled through and
   painted its headings ivory-on-cream - invisible. h3 and p were patched for
   this here long ago; h2 was missed, which is exactly what .step-h uses, so
   every step heading (Build your trip / Your details / Confirm) rendered as a
   faint ghost. Covering the whole h1-h4 range closes the hole for good.
   (0,1,1) - the same specificity as the .bg-deep rule, but later in the
   sheet, so it wins on order and needs no !important. */
.form-card h1,.form-card h2,.form-card h3,.form-card h4{color:var(--ink)}
.form-card h3{font-weight:400}
.form-card p{color:var(--ink-soft)}
/* The step rail lives in its own block further down (search "BOOKING —
   step rail"). A legacy 3px progress-bar version used to sit here and was
   never deleted when the circle-marker design replaced it. Its base rule was
   harmless — the later .steps .s re-declares height/background at equal
   specificity and wins on order — but .steps .s.on{background:var(--clay)}
   is (0,3,0) against the newer rule's (0,2,0), so it outranked the reset and
   painted every completed <li> solid terracotta: one stretched orange slab
   across steps 1-2, with .s-lab labels rendered terracotta-on-terracotta and
   therefore invisible. book.html is the only page carrying .steps markup, so
   removing it outright is safe. */
.field{margin-bottom:22px}
.field label{display:block;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--brass);margin-bottom:9px;font-weight:700}
.field input,.field select,.field textarea{
  width:100%;padding:15px 16px;background:var(--ivory);border:1px solid var(--line);
  border-radius:3px;color:var(--ink);font-family:var(--body);font-size:1rem;transition:border-color .3s,background .3s
}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--clay);background:var(--paper);box-shadow:0 0 0 3px rgba(179,98,61,.14)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.pkg-opts{display:grid;gap:12px}
.pkg-opt{display:flex;align-items:center;gap:14px;padding:17px;border:1px solid var(--line);border-radius:4px;cursor:pointer;transition:border-color .3s,background .3s}
.pkg-opt:hover{border-color:var(--brass)}
.pkg-opt input{width:auto;flex:none;accent-color:var(--clay)}
.pkg-opt.sel{border-color:var(--clay);background:rgba(179,98,61,.06)}
.pkg-opt .meta{flex:1;min-width:0}
.pkg-opt b{color:var(--ink);font-weight:700}
.pkg-opt .pp{font-family:var(--display);color:var(--clay);font-size:1.35rem;font-weight:300;white-space:nowrap}
.summary{background:linear-gradient(165deg,var(--ocean-2),var(--ocean));color:var(--ivory);border-radius:var(--r);padding:clamp(24px,3.2vw,36px);position:sticky;top:calc(var(--nav-h) + 14px);box-shadow:var(--shadow)}
.summary h3{margin-bottom:20px;color:var(--ivory);font-weight:400}
.sum-row{display:flex;justify-content:space-between;gap:14px;padding:13px 0;border-bottom:1px solid var(--line-dk);font-size:.94rem;color:rgba(247,241,230,.86)}
.sum-row.total{border:none;font-family:var(--display);font-size:1.55rem;color:var(--sand);padding-top:20px;font-weight:300}
.pay-note{font-size:.8rem;color:rgba(247,241,230,.72);margin-top:18px;display:flex;gap:8px;align-items:flex-start}
.pay-badges{display:flex;gap:10px;align-items:center;margin-top:20px;flex-wrap:wrap}
.pay-badges span{font-size:.68rem;padding:6px 11px;border:1px solid var(--line-dk);border-radius:3px;letter-spacing:.06em;color:var(--ivory)}
.hidden{display:none}
.contact-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:32px}
.contact-strip a{display:flex;gap:15px;align-items:center;padding:22px;background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);transition:border-color .3s,transform .3s;min-width:0}
.contact-strip a:hover{border-color:var(--clay);transform:translateY(-3px)}
.contact-strip .ci{font-size:1.4rem;color:var(--clay);flex:none}
.contact-strip b{display:block;color:var(--ink);font-weight:700}
.contact-strip span{font-size:.84rem;color:var(--ink-soft);overflow-wrap:anywhere}

/* Booking wizard — lifted out of the inline <style> block in book.html */
.bk-toggle{display:flex;gap:6px;margin:0 0 18px;background:var(--ivory);border:1px solid var(--line-soft);border-radius:100px;padding:5px}
.bk-mode{flex:1;border:none;background:transparent;padding:11px 14px;border-radius:100px;font-family:var(--body);font-weight:700;font-size:.8rem;letter-spacing:.03em;color:var(--ink-soft);cursor:pointer;transition:.3s;min-height:44px}
.bk-mode.on{background:var(--clay);color:#fff}
.opt-head{font-family:var(--display);font-size:1.08rem;color:var(--ink);margin:18px 0 8px;padding-bottom:6px;border-bottom:1px solid var(--line-soft)}
#grp-custom .opt-head:first-child,#grp-packages .opt-head{margin-top:2px}
.addrow{display:flex;gap:12px;align-items:flex-end;margin-top:18px;padding-top:18px;border-top:1px solid var(--line-soft);flex-wrap:wrap}
.addrow .qtybox{width:100px;flex:none}
.addrow .qtybox label{display:block;font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);margin-bottom:6px;font-weight:700}
.addrow .qtybox input{width:100%;padding:13px 10px;background:var(--ivory);border:1px solid var(--line);border-radius:8px;color:var(--ink);font-family:var(--body);font-size:1rem;text-align:center;min-height:50px}
.addrow .btn{flex:1 1 170px;justify-content:center}
.cart-item{display:flex;align-items:center;gap:8px;padding:11px 0;border-bottom:1px solid var(--line-dk)}
.cart-item .ci-main{flex:1;min-width:0}
.cart-item .ci-main b{display:block;color:#fff;font-size:.9rem;font-weight:600;line-height:1.25}
.cart-item .ci-main em{font-style:normal;font-size:.76rem;color:rgba(247,241,230,.7)}
.cart-item .ci-qty{display:flex;align-items:center;gap:7px;flex:none}
.cart-item .ci-qty button{width:26px;height:26px;border-radius:50%;border:1px solid var(--line-dk);background:transparent;color:#fff;cursor:pointer;font-size:.85rem;line-height:1;display:grid;place-items:center;flex:none}
.cart-item .ci-price{width:56px;flex:none;text-align:end;color:var(--sand);font-size:.88rem}
.cart-item .ci-x{background:none;border:none;color:rgba(247,241,230,.5);cursor:pointer;font-size:1.05rem;padding:0 2px;flex:none}
.cart-empty{color:rgba(247,241,230,.6);font-size:.9rem;padding:12px 0}
/* "— or —" and "Edit details" were set in near-white on the pale form card */
/* --stone lands at 3.9:1 on paper — under AA for text this size. */
.or-rule{text-align:center;margin:16px 0;font-size:.85rem;color:var(--ink-soft);letter-spacing:.14em;text-transform:uppercase}
.link-back{background:none;border:none;color:var(--ink-soft);font-size:.84rem;font-weight:600;cursor:pointer;padding:10px 4px;min-height:44px;letter-spacing:.04em}
.link-back:hover{color:var(--clay)}
/* buildReview() injects white/sand text, so this panel must be genuinely dark.
   It used to be rgba(8,18,15,.4) over the paper form card, which composites to
   a mid-grey (#9c9f9b) — white text on it measured ~2.3:1. */
.review-box{background:linear-gradient(165deg,var(--ocean-2),var(--ocean));border:1px solid transparent;border-radius:var(--r);padding:clamp(18px,3.4vw,24px);color:rgba(247,241,230,.86);font-size:.92rem;box-shadow:var(--shadow-soft);overflow-wrap:anywhere}
.review-box b{color:var(--ivory)}

/* ---------- Reveal ---------- */
.js .reveal{opacity:0;transform:translateY(42px);filter:blur(6px);
  transition:opacity 1.15s cubic-bezier(.16,1,.3,1),transform 1.35s cubic-bezier(.16,1,.3,1),filter 1.15s cubic-bezier(.16,1,.3,1)}
.js .reveal.in{opacity:1;transform:none;filter:none}

/* =========================================================
   Responsive
   ========================================================= */

/* --- Nav drawer: 9 uppercase links + brand + CTA need 1195px to sit flat,
       so the bar was wrapping into three rows anywhere under ~1300px. --- */
@media(max-width:1180px){
  .nav-links{
    position:fixed;inset:0 0 0 auto;width:min(84vw,380px);
    background:linear-gradient(170deg,var(--ocean-dk),var(--abyss));
    flex-direction:column;align-items:flex-start;
    justify-content:center;justify-content:safe center;
    /* Tightened from clamp(16px,3vh,26px) to pay for the taller links below —
       the per-item pitch is unchanged, so the drawer still fits without scrolling. */
    gap:clamp(12px,2.3vh,21px);
    transform:translateX(100%);visibility:hidden;pointer-events:none;
    /* visibility flips as a 0s step, delayed on close so the panel stays painted
       through the slide-out. Opening it must be instant and undelayed: the JS
       focuses the first link in the same tick, and a still-hidden element
       silently refuses focus. */
    transition:transform .45s cubic-bezier(.2,.8,.2,1),visibility 0s .45s;
    padding:calc(var(--nav-h) + 20px) 40px calc(40px + var(--safe-b));
    overflow-y:auto;overscroll-behavior:contain;
    box-shadow:-30px 0 70px -30px rgba(0,0,0,.6);z-index:120;
  }
  .nav-links.open{transform:none;visibility:visible;pointer-events:auto;
    transition:transform .45s cubic-bezier(.2,.8,.2,1),visibility 0s}
  .nav-links li{width:100%}
  /* padding:6px 0 left these at 40px — under the 44px thumb target */
  .nav-links a{font-size:1.02rem;letter-spacing:.1em;color:var(--ivory);text-shadow:none;
    width:100%;display:flex;align-items:center;min-height:var(--tap);padding:4px 0}
  .nav.scrolled .nav-links a{color:var(--ivory)}
  .nav-links a:hover,.nav-links a.active,
  .nav.scrolled .nav-links a:hover,.nav.scrolled .nav-links a.active{color:var(--sand)}
  .nav-links a::after{bottom:0}
  /* Measured at 375px: brand 163 + nav-cta 143 = 306 of the 316 available,
     and the 10px flex gap takes the rest. There is exactly 0px of slack, so
     the bar copy is retired here and the drawer copy takes over — full
     width, 44px targets, and a panel that expands DOWNWARD in the flow
     rather than floating over the links beneath it. */
  .lang-bar{display:none}
  .lang-drawer{display:block;width:100%;margin:10px 0 0;padding-top:16px;
    border-top:1px solid rgba(247,241,230,.16)}
  .lang-drawer .lang-toggle{width:100%;height:var(--tap);gap:11px;
    padding:0 14px;border-radius:12px;font-size:.78rem;letter-spacing:.1em;
    color:var(--ivory);background:rgba(247,241,230,.08);
    border-color:rgba(247,241,230,.2);text-shadow:none}
  /* Pushes the caret to the far edge of the full-width trigger. Logical, so
     it lands on the left in the Hebrew build without a second rule. */
  .lang-drawer .lang-caret{margin-inline-start:auto;width:11px;height:7px}
  /* .nav.scrolled .lang-toggle is (0,3,0) and would otherwise repaint the
     drawer trigger for the light nav — but the drawer is dark at every
     scroll position, so it needs matching specificity to hold its own. */
  .nav.scrolled .lang-drawer .lang-toggle{color:var(--ivory);
    background:rgba(247,241,230,.08);border-color:rgba(247,241,230,.2)}
  .lang-drawer .lang-toggle:hover,
  .lang-drawer .lang-toggle[aria-expanded="true"],
  .nav.scrolled .lang-drawer .lang-toggle:hover,
  .nav.scrolled .lang-drawer .lang-toggle[aria-expanded="true"]{
    color:var(--ivory);background:rgba(247,241,230,.16)}

  /* In the drawer the panel is part of the document flow, not a popover:
     it pushes the rest of the menu down, which is what "downward-expanding"
     should feel like on a phone. The drawer itself is overflow-y:auto, so a
     nine-row list that outgrows the viewport simply scrolls.

     Collapsed with max-height rather than display:none so both directions
     animate, and with visibility so the nine links inside are not still
     reachable by Tab while the panel is shut — a max-height:0 container
     hides its content visually but keeps it in the focus order. */
  .lang-drawer .lang-menu{position:static;min-width:0;padding:0;margin:0;
    background:none;border:0;border-radius:0;box-shadow:none;
    opacity:1;transform:none;overflow:hidden;
    max-height:0;visibility:hidden;
    transition:max-height .4s cubic-bezier(.2,.8,.2,1),margin-top .4s,visibility 0s .4s}
  .lang-drawer .lang-toggle[aria-expanded="true"]+.lang-menu{
    max-height:560px;margin-top:8px;visibility:visible;transition-delay:0s,0s,0s}
  .lang-drawer .lang-menu li+li{margin-top:4px}
  .lang-drawer .lang-menu a{min-height:var(--tap);padding:8px 14px;border-radius:11px;
    font-size:.92rem;color:rgba(247,241,230,.82);background:rgba(247,241,230,.05)}
  .lang-drawer .lang-menu a:hover,.lang-drawer .lang-menu a:focus-visible{
    color:var(--ivory);background:rgba(247,241,230,.14)}
  .lang-drawer .lang-menu a.on{color:var(--abyss);background:var(--sand);font-weight:700}
  .nav-drawer-cta{display:block}
  .burger{display:flex}
  .nav-cta .btn-ghost{display:none}
}

/* --- Tablet --- */
@media(max-width:980px){
  .g-4{grid-template-columns:repeat(2,1fr)}
  .g-3{grid-template-columns:repeat(2,1fr)}
  .price-grid{grid-template-columns:repeat(2,1fr)}
  .book-grid,.g-2,.split{grid-template-columns:1fr}
  .split.rev>*:first-child,.split.rev>*:last-child{order:0}
  .split-media{aspect-ratio:16/10;max-height:60vh}
  .foot-grid{grid-template-columns:1fr 1fr}
  .foot-brand{grid-column:1/-1}
  .summary{position:static}
  .photoband{grid-template-columns:repeat(2,1fr)}
  .masonry{columns:2}
  /* the stats block and the scroll cue were landing on top of each other */
  .hero-stats{margin-inline-start:0}
  .scroll-cue{display:none}
}

/* --- Large phone: single column, thumb-friendly CTAs --- */
@media(max-width:760px){
  .g-3,.g-4,.price-grid,.field-row,.contact-strip{grid-template-columns:1fr}
  /* Footer links were 15px tall — the margin became padding so the target grows
     without spreading the columns as far as a full 44px would. */
  .footer a{display:flex;align-items:center;min-height:40px;margin-bottom:0}
  .price h3{padding-inline-end:0}
  .price .ribbon{position:static;display:inline-block;margin-bottom:12px}
  .hero-inner{padding-bottom:calc(66px + var(--safe-b))}
  .hero h1{margin:14px 0 18px}
  /* Full-width, stacked, easy to reach with one thumb */
  .hero-meta{flex-direction:column;align-items:stretch;gap:12px;margin-top:28px}
  .hero-meta>.btn{width:100%}
  .hero-stats{
    margin:16px 0 0;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:0;
    border-top:1px solid rgba(255,255,255,.22);padding-top:18px
  }
  .hero-stats .stat{padding-inline-end:16px}
  .hero-stats .stat+.stat{padding-inline-start:20px;border-inline-start:1px solid rgba(255,255,255,.22)}
  .hero-dots{inset-inline-start:var(--gutter);inset-inline-end:auto;bottom:calc(10px + var(--safe-b))}
  .cta-band .btns{flex-direction:column;align-items:stretch;gap:12px}
  .cta-band .btns>.btn{width:100%}
  .checklist li{font-size:.95rem;gap:12px}
}

/* --- Phone --- */
@media(max-width:560px){
  /* Width budget on a 390px screen: 350px of content has to hold brand + Book Now
     + burger. At full size that totals ~395px and pushed the burger off-canvas,
     so the lockup tightens here (wordmark and tagline both stay). */
  .nav{gap:12px;padding:18px var(--gutter)}
  .nav.scrolled{padding:12px var(--gutter)}
  .brand{font-size:.98rem;gap:9px;min-width:0}
  .brand .mark{width:34px;height:34px}
  .brand .mark svg{width:19px;height:19px}
  .brand small{font-size:.6rem;letter-spacing:.1em}
  .brand>span:last-child{min-width:0;overflow:hidden;text-overflow:ellipsis}
  .nav-cta{gap:8px}
  .nav-cta .btn{font-size:.68rem;letter-spacing:.1em;padding:12px 14px;min-height:42px}

  .masonry{columns:1}
  .foot-bottom{flex-direction:column;text-align:center;align-items:center}
  .foot-grid{grid-template-columns:1fr}
  .split-media{aspect-ratio:4/3}
  .strip{padding:14px 0}
  .btn{font-size:.76rem;letter-spacing:.1em}
  .steps{margin-bottom:24px}
  .addrow .qtybox{width:88px}
  .pkg-opt{padding:14px;gap:11px}
  .pkg-opt .pp{font-size:1.15rem}
}

/* --- Small phone (360px Android is the common floor) --- */
@media(max-width:400px){
  /* At 360px only 320px of content is available and the lockup above needs 331px,
     so the burger crept 12px past the gutter. The tagline's .15em tracking is the
     widest single contributor, so tracking (not size) gives the px back. */
  .nav{gap:10px}
  .brand{flex:0 1 auto;gap:8px}
  .brand .mark{width:30px;height:30px}
  .brand .mark svg{width:17px;height:17px}
  .brand small{font-size:.56rem;letter-spacing:.05em;overflow:hidden;text-overflow:ellipsis}
  .nav-cta .btn{padding:12px}
  /* Below ~330px there is nothing left to give: let the tagline ellipsize rather
     than push the menu button off-canvas. */
  .brand>span:last-child{flex:0 1 auto}
}

/* --- Touch devices: hover lifts read as stuck states on tap --- */
@media(hover:none){
  .btn:hover,.card:hover,.price:hover,.contact-strip a:hover{transform:none;box-shadow:none}
  .card:hover{box-shadow:none;border-color:var(--line-soft)}
  .price:hover{box-shadow:none;border-color:var(--line-soft)}
  .mcard:hover img,.split-media:hover img,.photoband .ph:hover img,.masonry img:hover{transform:none}
  .btn:hover .arrow{transform:none}
  .nav-links a:hover::after{transform:scaleX(0)}
  .nav-links a.active::after{transform:scaleX(1)}
}

/* --- Reduced motion --- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important
  }
  html{scroll-behavior:auto}
  .strip .track{animation:none}
  .hero-media>img,.hero-media.slideshow .slide.active{animation:none;transform:none}
  .js .reveal{opacity:1;transform:none;filter:none}
}

/* =========================================================
   PREMIUM LAYER — booking engine, mobile-first patterns,
   always-on CTAs. Appended after the reduced-motion block,
   so this section carries its own guard at the very end.
   ========================================================= */

/* --- Skip link (keyboard users land on the content on every page) --- */
/* Hidden by clipping, not by left:-9999px. A physical -9999px offset is
   inline-END overflow once dir="rtl" is set, and the root element does not
   clip it — body{overflow-x:hidden} cannot help because it is <html> that
   scrolls. Measured on he/index.html at 1280px: documentElement.scrollWidth
   was 11264 instead of 1280, i.e. the whole Hebrew site panned sideways.
   Clipping occupies zero space in either writing direction. */
.skip-link{position:absolute;top:0;inset-inline-start:0;z-index:200;
  width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;
  background:var(--espresso);color:var(--ivory);
  padding:14px 22px;border-radius:0 0 var(--r) 0;font-size:.85rem;font-weight:700;letter-spacing:.06em}
.skip-link:focus{width:auto;height:auto;overflow:visible;clip-path:none}

/* --- Trust row under a page hero --- */
.trust-row{list-style:none;display:flex;flex-wrap:wrap;gap:10px 26px;margin-top:26px}
.trust-row li{display:flex;align-items:center;gap:9px;font-size:.86rem;color:rgba(255,255,255,.9);
  text-shadow:0 1px 14px rgba(0,0,0,.5)}
.trust-row li span{color:var(--sand);font-size:1rem}

.phero-book{padding:calc(var(--nav-h) + clamp(52px,8vw,88px)) 0 clamp(56px,7vw,88px)}

/* =========================================================
   BOOKING — step rail
   ========================================================= */
.steps{display:flex;gap:0;margin-bottom:clamp(26px,3.6vw,38px);list-style:none}
.steps .s{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px;position:relative;
  padding-top:2px;color:var(--stone);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;
  font-weight:700;height:auto;background:none;border-radius:0}
/* the connecting rail sits behind the numbers */
.steps .s::before{content:"";position:absolute;top:17px;inset-inline-start:-50%;width:100%;height:2px;background:var(--line);z-index:0}
.steps .s:first-child::before{display:none}
.steps .s.on::before{background:var(--clay)}
.steps .s-num{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;position:relative;z-index:1;
  background:var(--ivory);border:2px solid var(--line);color:var(--stone);font-family:var(--display);
  font-size:.95rem;transition:background .35s,border-color .35s,color .35s,transform .35s}
.steps .s.on .s-num{background:var(--clay);border-color:var(--clay);color:#fff}
.steps .s.current .s-num{transform:scale(1.1);box-shadow:0 0 0 5px rgba(179,98,61,.15)}
/* background:none is belt-and-braces: it pins the reset at the same (0,3,0)
   specificity as the deleted legacy rule, so the fill cannot come back if a
   .on background is ever reintroduced above this block. */
.steps .s.on{color:var(--clay);background:none}
.steps .s-lab{line-height:1.3;text-align:center}
/* completed steps are clickable shortcuts back */
.steps .s.on:not(.current){cursor:pointer}
.steps .s.on:not(.current):hover .s-num{transform:scale(1.06)}

.step-h{font-family:var(--display);font-weight:300;font-size:clamp(1.5rem,3.2vw,2rem);color:var(--ink);
  margin-bottom:6px;line-height:1.15;outline:none}
.step-h:focus-visible{outline:2px solid var(--clay);outline-offset:5px;border-radius:3px}
.step-sub{font-size:.94rem;color:var(--ink-soft);margin-bottom:22px;max-width:56ch}
.step-nav{display:flex;justify-content:space-between;gap:12px;margin-top:28px;flex-wrap:wrap}
.step-nav-end{justify-content:flex-end}
.step-nav-center{justify-content:center;margin-top:14px}

/* =========================================================
   BOOKING — option cards (image-forward)
   ========================================================= */
.bk-options{margin-top:4px}
.bk-loading{display:flex;flex-direction:column;align-items:center;gap:14px;padding:56px 0;color:var(--stone)}
.bk-loading .spin{width:26px;height:26px;border:2px solid var(--line);border-top-color:var(--clay);
  border-radius:50%;animation:bkspin .8s linear infinite}
@keyframes bkspin{to{transform:rotate(360deg)}}

.opt-grid{display:grid;gap:14px}
.opt-grid-lg{gap:clamp(16px,2.2vw,22px)}

.opt{display:grid;grid-template-columns:96px 1fr auto;align-items:center;gap:16px;
  background:var(--paper);border:1px solid var(--line-soft);border-radius:var(--r);overflow:hidden;
  transition:border-color .35s,box-shadow .35s,transform .35s}
.opt:hover{border-color:var(--brass);box-shadow:var(--shadow-soft);transform:translateY(-2px)}
.opt.in-cart{border-color:var(--clay);box-shadow:0 0 0 1px var(--clay) inset}
.opt-img{width:96px;object-fit:cover;display:block;align-self:stretch;height:100%}
.opt-body{padding:14px 0;min-width:0}
.opt-body h4{font-family:var(--display);font-weight:400;font-size:1.06rem;color:var(--ink);line-height:1.25}
.opt-meta{font-size:.82rem;color:var(--stone);margin-top:3px}
.opt-price{margin-top:7px;display:flex;align-items:baseline;gap:7px}
.opt-price b{font-family:var(--display);font-weight:300;font-size:1.3rem;color:var(--clay)}
.opt-price em{font-style:normal;font-size:.74rem;color:var(--stone);letter-spacing:.04em}
.opt-add{padding-inline-end:16px;display:flex;flex-direction:column;align-items:center;gap:5px;flex:none}
.opt-unitword{font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--stone);font-weight:700}
.opt-btn{padding:11px 20px;font-size:.76rem;min-height:var(--tap)}

/* Large package cards — photography leads */
.opt-lg{display:block}
.opt-lg .opt-img{width:100%;height:clamp(190px,26vw,250px)}
.opt-lg .opt-body{padding:clamp(18px,2.4vw,24px) clamp(18px,2.4vw,24px) 0}
.opt-lg .opt-body h4{font-size:clamp(1.3rem,2.4vw,1.7rem)}
.opt-blurb{font-size:.9rem;color:var(--ink-soft);margin-top:10px;line-height:1.65}
.opt-inc{list-style:none;margin:14px 0 0;display:grid;gap:6px}
.opt-inc li{font-size:.85rem;color:var(--ink-soft);padding-inline-start:22px;position:relative}
.opt-inc li::before{content:"\2713";position:absolute;inset-inline-start:0;top:0;color:var(--brass);font-weight:700}
.opt-lg .opt-add{padding:18px clamp(18px,2.4vw,24px) clamp(18px,2.4vw,24px);flex-direction:row;
  align-items:center;justify-content:space-between;width:100%;gap:12px}
.opt-lg .opt-btn{flex:1;justify-content:center}

/* Quantity stepper — 44px targets, integers only (the number input
   that happily accepted "2.5" is gone entirely) */
.stepper{display:flex;align-items:center;gap:4px;background:var(--ivory);border:1px solid var(--line);
  border-radius:100px;padding:3px}
.stepper button{width:38px;height:38px;border-radius:50%;border:none;background:var(--paper);color:var(--clay);
  font-size:1.15rem;line-height:1;cursor:pointer;display:grid;place-items:center;
  transition:background .25s,color .25s;font-weight:600}
.stepper button:hover{background:var(--clay);color:#fff}
.stepper button:focus-visible{outline:2px solid var(--clay);outline-offset:2px}
.stepper-n{min-width:26px;text-align:center;font-family:var(--display);font-size:1.05rem;color:var(--ink)}

/* Category chips replace the 1,826px flat list */
.cat-chips{display:flex;gap:8px;overflow-x:auto;padding:2px 2px 12px;margin:0 -2px 4px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.cat-chips::-webkit-scrollbar{display:none}
.chip{flex:none;display:inline-flex;align-items:center;gap:7px;padding:10px 18px;min-height:var(--tap);
  border:1px solid var(--line);border-radius:100px;background:var(--paper);color:var(--ink-soft);
  font-family:var(--body);font-weight:700;font-size:.8rem;letter-spacing:.03em;cursor:pointer;
  transition:background .3s,color .3s,border-color .3s;white-space:nowrap}
.chip:hover{border-color:var(--brass)}
.chip.on{background:var(--ocean);border-color:var(--ocean);color:var(--ivory)}
.chip-n{background:var(--clay);color:#fff;border-radius:100px;min-width:20px;height:20px;
  display:grid;place-items:center;font-size:.68rem;padding:0 6px}
/* The category note repeats what every card in the grid already states in its
   own unit line ("per night", "per session"), so as a standalone uppercase
   heading it read as a second, competing label above the same information.
   Hidden rather than deleted: booking.js still builds the node from
   content/experiences.json, so the owner's `note` field keeps working the day
   we want it back, and display:none also keeps it out of the a11y tree — a
   screen reader hears the unit once, like everyone else. */
.cat-note{display:none}

.bk-fallback{text-align:center;padding:36px 20px;border:1px dashed var(--line);border-radius:var(--r)}
.bk-fallback h4{font-family:var(--display);font-weight:400;font-size:1.2rem;color:var(--ink);margin-bottom:8px}
.bk-fallback p{font-size:.9rem;color:var(--ink-soft);margin-bottom:18px}

/* =========================================================
   BOOKING — cart, review, validation
   ========================================================= */
.cart-count{display:inline-grid;place-items:center;min-width:24px;height:24px;padding:0 7px;border-radius:100px;
  background:var(--clay);color:#fff;font-family:var(--body);font-size:.74rem;font-weight:700;
  vertical-align:middle;margin-left:8px}
.summary h3{display:flex;align-items:center}

.review-box{display:grid;gap:2px}
.rv-line{display:flex;justify-content:space-between;gap:16px;padding:9px 0;border-bottom:1px solid var(--line-dk)}
.rv-line span{color:rgba(247,241,230,.9)}
.rv-line b{color:var(--sand);white-space:nowrap;font-weight:600}
.rv-total{display:flex;justify-content:space-between;gap:16px;padding:9px 0;font-size:.92rem}
.rv-total b{color:var(--sand);white-space:nowrap}
.rv-strong{font-family:var(--display);font-size:1.3rem;font-weight:300;padding:12px 0;
  border-top:1px solid var(--line-dk);margin-top:6px}
.rv-strong b{color:var(--sand)}
.rv-who{margin-top:14px;padding-top:14px;border-top:1px solid var(--line-dk);
  font-size:.82rem;color:rgba(247,241,230,.7)}

.pay-copy{font-size:.9rem;color:var(--ink-soft);margin:22px 0 18px}
.pay-copy b{color:var(--clay-dk)}
.pay-fine{font-size:.78rem;color:var(--stone);text-align:center;margin-top:12px}
.btn-block{width:100%;justify-content:center}
.btn-xl{font-size:1rem;padding:18px 20px}
.btn.is-loading{opacity:.6;pointer-events:none}

.field label i{font-style:normal;color:var(--clay)}
.lab-hint{text-transform:none;letter-spacing:0;font-weight:400;color:var(--stone);font-size:.72rem;margin-inline-start:6px}
.field-err{display:block;margin-top:7px;font-size:.78rem;color:var(--clay-dk);font-weight:600}
.field.has-err input,.field.has-err select,.field.has-err textarea{
  border-color:var(--clay);box-shadow:0 0 0 3px rgba(179,98,61,.12)}

/* =========================================================
   Sticky mobile summary bar + toast
   ========================================================= */
.bk-bar{position:fixed;left:0;right:0;bottom:0;z-index:95;transform:translateY(110%);
  transition:transform .4s cubic-bezier(.2,.8,.2,1);
  background:rgba(34,27,20,.97);backdrop-filter:blur(10px);border-top:1px solid var(--line-dk);
  padding:12px var(--gutter) calc(12px + var(--safe-b))}
.bk-bar.on{transform:none}
.bk-bar-in{display:flex;align-items:center;gap:14px;max-width:var(--maxw);margin:0 auto}
.bk-bar-sum{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25}
.bk-bar-sum b{font-family:var(--display);font-weight:300;font-size:1.4rem;color:var(--sand)}
.bk-bar-sum span{font-size:.74rem;letter-spacing:.08em;text-transform:uppercase;color:rgba(247,241,230,.65)}
.bk-bar .btn{flex:none;min-height:var(--tap)}
@media(min-width:981px){.bk-bar{display:none}}

.bk-toast{position:fixed;left:50%;bottom:calc(96px + var(--safe-b));transform:translate(-50%,20px);
  z-index:130;background:var(--ocean);color:var(--ivory);padding:14px 22px;border-radius:100px;
  font-size:.86rem;font-weight:600;box-shadow:var(--shadow);opacity:0;pointer-events:none;
  transition:opacity .3s,transform .3s;max-width:calc(100vw - 32px);text-align:center}
.bk-toast.show{opacity:1;transform:translate(-50%,0)}
.bk-toast.warn{background:var(--clay-dk)}

/* =========================================================
   Site-wide: sticky mobile CTA for the marketing pages
   ========================================================= */
.mobile-cta{position:fixed;left:0;right:0;bottom:0;z-index:94;display:none;gap:10px;
  padding:10px var(--gutter) calc(10px + var(--safe-b));
  background:rgba(34,27,20,.96);backdrop-filter:blur(10px);border-top:1px solid var(--line-dk);
  transform:translateY(110%);transition:transform .4s cubic-bezier(.2,.8,.2,1)}
.mobile-cta.on{transform:none}
.mobile-cta .btn{flex:1;justify-content:center;min-height:var(--tap);font-size:.76rem;padding:13px 14px}
@media(max-width:980px){
  .mobile-cta{display:flex}
  /* keep the footer clear of the bar */
  .footer{padding-bottom:calc(38px + var(--tap) + var(--safe-b))}
}

/* =========================================================
   Mobile content patterns — accordions & "read more"
   Text-heavy prose collapses on phones so photography leads.
   ========================================================= */
.acc{border-top:1px solid var(--line)}
.acc-item{border-bottom:1px solid var(--line)}
.acc-head{width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;
  background:none;border:none;padding:20px 2px;cursor:pointer;text-align:start;
  font-family:var(--display);font-size:1.08rem;font-weight:400;color:var(--ink);min-height:var(--tap)}
.acc-head:focus-visible{outline:2px solid var(--clay);outline-offset:-2px}
.acc-ico{flex:none;width:26px;height:26px;border-radius:50%;border:1px solid var(--line);
  display:grid;place-items:center;color:var(--clay);font-size:1rem;line-height:1;
  transition:transform .35s,background .35s,color .35s}
.acc-head[aria-expanded="true"] .acc-ico{transform:rotate(45deg);background:var(--clay);color:#fff;
  border-color:var(--clay)}
.acc-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .4s cubic-bezier(.2,.8,.2,1)}
.acc-panel>div{overflow:hidden}
.acc-item.open .acc-panel{grid-template-rows:1fr}
.acc-panel p{padding-bottom:20px;font-size:.93rem;color:var(--ink-soft)}
.acc-panel p+p{padding-top:0}

/* "Read more" — clamps prose to a few lines on phones only */
.readmore-btn{display:none;background:none;border:none;color:var(--clay);font-family:var(--body);
  font-weight:700;font-size:.82rem;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;
  padding:10px 2px;min-height:var(--tap)}
.readmore-btn::after{content:" \2193"}
.readmore.open .readmore-btn::after{content:" \2191"}
@media(max-width:760px){
  .readmore-btn{display:inline-block}
  .readmore .readmore-body{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}
  .readmore.open .readmore-body{display:block;-webkit-line-clamp:unset}
}

/* =========================================================
   Refined scroll choreography
   ========================================================= */
.js .reveal[data-delay="1"]{transition-delay:.09s}
.js .reveal[data-delay="2"]{transition-delay:.18s}
.js .reveal[data-delay="3"]{transition-delay:.27s}
.js .reveal[data-delay="4"]{transition-delay:.36s}

/* =========================================================
   Booking responsive
   ========================================================= */
@media(max-width:980px){
  .book-grid{grid-template-columns:1fr}
  /* On a phone the cart sits ~1,300px below the options, so it stops
     pretending to be a live panel and becomes a review block; the
     sticky bar carries the running total instead. */
  .summary{position:static;order:2}
  /* leave room for the sticky bar so the last control is never buried */
  #book{padding-bottom:calc(clamp(64px,8vw,110px) + 74px)}
}
@media(max-width:760px){
  .steps .s-lab{font-size:.6rem;letter-spacing:.06em}
  .steps .s-num{width:30px;height:30px;font-size:.85rem}
  .steps .s::before{top:15px}
  /* Photo left, text right, control underneath. Every measurement here is
     tuned to keep a 7-item category under ~1.3 screens instead of the
     1,826px wall the flat list used to produce. */
  .opt{grid-template-columns:96px 1fr;grid-template-rows:auto auto;gap:0 13px}
  .opt-img{width:96px;grid-row:1/3}
  .opt-body{padding:11px 13px 0 0}
  .opt-body h4{font-size:.96rem;line-height:1.25}
  .opt-meta{font-size:.76rem;margin-top:2px}
  .opt-price{margin-top:5px}
  .opt-price b{font-size:1.08rem}
  .opt-add{grid-column:2;padding:6px 13px 11px 0;flex-direction:row;justify-content:flex-start;
    align-items:center;gap:10px}
  /* the price line already says "per night" — the unit word is noise here */
  .opt-unitword{display:none}
  .opt-lg .opt-img{grid-row:auto;width:100%}
  .opt-lg .opt-add{grid-column:auto}
  /* full 44px targets on touch */
  .stepper button{width:var(--tap);height:var(--tap);font-size:1.3rem}
  .stepper-n{min-width:34px;font-size:1.15rem}
  .cart-item .ci-qty button{width:36px;height:36px;font-size:1rem}
  .cart-item .ci-x{min-width:36px;min-height:36px;padding:0;display:grid;place-items:center}
  .step-nav .btn{flex:1 1 100%;justify-content:center}
  .contact-strip{grid-template-columns:1fr}
}
@media(max-width:560px){
  .trust-row{gap:8px 16px}
  .trust-row li{font-size:.78rem;flex:1 1 100%}
  .opt-price b{font-size:1.15rem}
  .bk-bar-sum b{font-size:1.2rem}
}

/* --- Reduced motion for everything added above --- */
@media(prefers-reduced-motion:reduce){
  .bk-loading .spin{animation:none}
  .bk-bar,.mobile-cta,.bk-toast,.acc-panel,.steps .s-num{transition:none}
  .opt:hover{transform:none}
}

/* =========================================================
   MARKETING LAYER — package cards, FAQ, closing CTA
   The booking engine already owns .opt/.opt-lg; these are the
   equivalents for the storefront pages, where the job is to
   show a price early rather than to collect a quantity.
   ========================================================= */
.wrap-narrow{max-width:860px}

/* stretch, not start: equal-height cards land every "Reserve" button on
   the same baseline, which is what makes a price grid read as premium. */
.pkg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,28px);align-items:stretch}

.pkg-card{position:relative;display:flex;flex-direction:column;background:var(--paper);
  border:1px solid var(--line-soft);border-radius:var(--r);overflow:hidden;
  transition:transform .5s cubic-bezier(.2,.8,.2,1),box-shadow .5s,border-color .5s}
.pkg-card:hover{transform:translateY(-6px);box-shadow:var(--shadow-soft);border-color:var(--brass)}
.pkg-card>img{width:100%;height:clamp(190px,20vw,240px);object-fit:cover;display:block}

/* The one the camp wants sold sits slightly forward of the others. */
.pkg-card.featured{border-color:var(--brass);box-shadow:var(--shadow-soft)}
.pkg-card.featured>img{height:clamp(210px,23vw,268px)}
.pkg-badge{position:absolute;top:16px;inset-inline-start:16px;z-index:2;background:var(--clay);color:#fff;
  font-size:.66rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  padding:8px 14px;border-radius:100px;box-shadow:0 6px 18px -8px rgba(34,27,20,.7)}

.pkg-body{padding:clamp(20px,2.4vw,28px);display:flex;flex-direction:column;flex:1}
.pkg-body h3{font-family:var(--display);font-weight:400;font-size:clamp(1.2rem,2vw,1.45rem);
  color:var(--ink);line-height:1.2}
.pkg-tag{font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--stone);
  font-weight:700;margin-top:7px}
.pkg-price{display:flex;align-items:baseline;gap:8px;margin:16px 0 4px;
  padding-bottom:16px;border-bottom:1px solid var(--line-soft)}
.pkg-price b{font-family:var(--display);font-weight:300;font-size:clamp(1.9rem,3.4vw,2.4rem);
  color:var(--clay);line-height:1}
.pkg-price em{font-style:normal;font-size:.78rem;letter-spacing:.06em;color:var(--stone)}
.pkg-inc{list-style:none;margin:18px 0 24px;display:grid;gap:9px;flex:1}
.pkg-inc li{font-size:.88rem;color:var(--ink-soft);padding-inline-start:24px;position:relative;line-height:1.5}
.pkg-inc li::before{content:"\2713";position:absolute;inset-inline-start:0;top:0;color:var(--brass);font-weight:700}
.pkg-foot{text-align:center;margin-top:clamp(30px,4vw,44px);font-size:.94rem;color:var(--ink-soft)}
.pkg-foot b{color:var(--clay);font-weight:700}
.pkg-foot a{color:var(--clay-dk);font-weight:700;border-bottom:1px solid rgba(179,98,61,.35)}
.pkg-foot a:hover{border-bottom-color:var(--clay)}

.cta-fine{margin-top:22px;font-size:.78rem;letter-spacing:.06em;color:rgba(255,255,255,.62)}

@media(max-width:980px){
  .pkg-grid{grid-template-columns:repeat(2,1fr)}
  .pkg-card.featured{order:-1;grid-column:1/-1}
  .pkg-card.featured>img{height:clamp(200px,26vw,280px)}
}
@media(max-width:760px){
  /* A swipeable rail beats a 2,000px stack of cards: the photography
     stays large, and the whole offer is one thumb-flick wide. */
  .pkg-grid{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:82%;
    overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    margin-inline:calc(var(--gutter) * -1);padding:4px var(--gutter) 16px;
    scrollbar-width:none}
  .pkg-grid::-webkit-scrollbar{display:none}
  .pkg-card{scroll-snap-align:center}
  .pkg-card.featured{order:0;grid-column:auto}
  .pkg-card>img,.pkg-card.featured>img{height:210px}
  /* Cards sitting off to the right would otherwise stay faded out until
     swiped; on a rail the reveal animation is noise, so drop it. */
  .js .pkg-grid .reveal{opacity:1;transform:none;transition:none}
  .pkg-card:hover{transform:none;box-shadow:none}
}

/* =========================================================
   MOBILE CLARITY LAYER
   On a phone the job is the opposite of desktop: photography
   should hold the screen and prose should get out of the way.
   Nothing here fires above 760px, so the desktop composition
   built above is untouched.
   ========================================================= */
/* The swipe hint is meaningless on a grid, so it is hidden by default and
   only switched on inside the phone block below. Declared first: an equal
   specificity rule placed after the media query would win everywhere. */
.rail-hint{display:none}

@media(max-width:760px){

  /* ---- Feature cards: stacked box → compact media row ----
     Eight full-width boxes is 3,000px of scrolling. Laying the
     icon beside the text roughly halves each card and turns the
     set into something that reads as one list.

     Gated on :has(.ico), because the media row assumes an icon holds
     column 1. A card without one — the big stat numbers on
     reviews.html — dropped its first child into the 46px icon
     column, where a 93px string spilled straight across the heading
     beside it. Those keep the stacked form. */
  .grid.g-3 .card:has(.ico),.grid.g-4 .card:has(.ico){
    display:grid;grid-template-columns:46px 1fr;grid-template-rows:auto auto;
    column-gap:15px;align-items:start;
    padding:18px 18px 19px
  }
  .grid.g-3 .card:has(.ico) .ico,.grid.g-4 .card:has(.ico) .ico{
    width:46px;height:46px;font-size:1.15rem;margin:0;grid-row:1/3
  }
  /* Everything that is not the icon belongs in the text column.
     Placing only h3 and p left any further child — a "Learn more →"
     link, a .checklist — auto-placed back into the 46px icon column,
     overflowing it by up to 83px and painting over the copy beside it.
     min-width:0 lets those items shrink; a grid item defaults to
     min-width:auto, which refuses to go below its min-content width. */
  .grid.g-3 .card:has(.ico)>*:not(.ico),
  .grid.g-4 .card:has(.ico)>*:not(.ico){grid-column:2;min-width:0}
  .grid.g-3 .card:has(.ico) h3,.grid.g-4 .card:has(.ico) h3{
    margin:0 0 5px;font-size:1.02rem;line-height:1.35;align-self:center
  }
  .grid.g-3 .card:has(.ico) p,.grid.g-4 .card:has(.ico) p{
    font-size:.9rem;line-height:1.6;margin:0
  }
  /* A card carrying a button keeps the stacked form — the CTA
     needs the full width to stay a comfortable tap target. Kept at the
     same specificity as the media row above so source order still
     decides between them. */
  .grid.g-3 .card:has(.btn),.grid.g-4 .card:has(.btn){grid-template-columns:1fr;padding:24px 22px}
  .grid.g-3 .card:has(.btn) .ico,.grid.g-4 .card:has(.btn) .ico{grid-row:auto;margin-bottom:14px}
  .grid.g-3 .card:has(.btn)>*:not(.ico),
  .grid.g-4 .card:has(.btn)>*:not(.ico){grid-column:1}
  .card:hover{transform:none;box-shadow:none}

  /* ---- Price cards: swipe rail ----
     Same reasoning as the package grid on the homepage — one
     thumb-flick beats a 2,000px column of near-identical cards. */
  .price-grid{
    grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:84%;
    overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    margin-inline:calc(var(--gutter) * -1);padding:4px var(--gutter) 18px;
    scrollbar-width:none
  }
  .price-grid::-webkit-scrollbar{display:none}
  .price{scroll-snap-align:center;height:100%}
  .js .price-grid .reveal{opacity:1;transform:none;transition:none}
  /* The rail is only obvious if the next card peeks in — this hint
     tells a first-time visitor there is more to the right. */
  .rail-hint{
    display:block;font-size:.74rem;letter-spacing:.12em;text-transform:uppercase;
    color:var(--stone);margin:-4px 0 14px;opacity:.8
  }
  .bg-deep .rail-hint,.bg-teal .rail-hint{color:rgba(247,241,230,.7)}

  /* ---- Long prose: clamp behind Read more ----
     Applies to the wrappers injected into the storytelling
     sections; see .readmore in the premium layer. */
  .split-media{margin-bottom:4px}
  .split .checklist{margin-top:16px}
}

@media(max-width:560px){
  /* Two lines of heading is a headline; four is a paragraph. */
  .phero h1{font-size:clamp(1.9rem,8.4vw,2.5rem);line-height:1.12}
  .phero .lead{font-size:.96rem;line-height:1.6}
  .price-grid{grid-auto-columns:88%}
}

/* ============================================================
   MOBILE READING LAYER  (375px – 560px)
   Placed last on purpose. The values it overrides live in blocks
   further down the sheet than the phone breakpoint above
   (.steps .s-lab at ~918, .rail-hint at ~1096, .acc-head at ~870),
   and at equal specificity source order decides — so a rule added
   up there would simply lose. Everything here is a readability
   floor, not a restyle.
   ============================================================ */
@media(max-width:560px){

  /* Display headings ship at line-height 1.06. That is correct for a
     6.2rem desktop h1 set on one line, but once a heading wraps at
     29-38px the descenders of one line touch the caps of the next.
     Loosen as the type gets smaller. */
  h1{line-height:1.14}
  h2{line-height:1.18}
  h3,h4{line-height:1.3}
  .room-title{line-height:1.2}
  .lead{line-height:1.62}

  /* Small caps labels were 9.6px–11.5px with .14em–.34em tracking.
     At these sizes wide tracking costs more legibility than the point
     size does, so each label gains size and gives back tracking. */
  .eyebrow{font-size:.76rem;letter-spacing:.18em;margin-bottom:16px;gap:9px}
  .eyebrow::before{width:22px}
  .mcard .tag{font-size:.72rem;letter-spacing:.11em;padding:5px 11px}
  .crumb{font-size:.76rem;letter-spacing:.09em}
  .steps .s-lab{font-size:.68rem;letter-spacing:.04em;line-height:1.35}
  .rail-hint{font-size:.78rem;letter-spacing:.08em}
  .checklist li{line-height:1.6}

  /* The 3-5px of reported overflow here was never the label: .acc-ico is
     a 26px square that rotates 45deg when its item is open, and a rotated
     square reports a bounding box of 26*sqrt(2) = 36.8px. The corners, not
     the text, crossed the edge. 6px of side padding clears the 5.4px each
     corner needs. The gap and size below are for reading comfort. */
  .acc-head{gap:12px;padding:18px 6px;font-size:1.02rem;line-height:1.4}
}

/* ============================================================
   MOBILE RHYTHM LAYER  (375px – 480px)   ← THE OVERLAP FIX
   Placed after the reading layer above and before the script
   support below, so the Hebrew/Japanese leading overrides that
   follow still win for those two languages.

   ROOT CAUSE of the reported "lines rendering on top of each
   other": the reset at the top of this sheet is
   `*{box-sizing:border-box;margin:0;padding:0}` — and nothing
   ever put a margin back for prose. Measured on a 375px viewport:
   8 sibling pairs render at a 0-5px gap, including four H2 -> P
   pairs at exactly 0px. A display serif's descenders extend past
   its line box, so at a 0px gap an <h2> literally draws into the
   cap height of the <p> beneath it. That is the overlap. It is a
   missing margin, not a broken layout.
   ============================================================ */
@media(max-width:480px){

  /* --- 1. Re-establish vertical rhythm (the actual fix) ---
     Specificity is (0,0,2) via the adjacent combinator, which clears
     the (0,0,0) universal reset without !important. */
  h1+p,h2+p,h3+p,h4+p,
  h1+ul,h2+ul,h3+ul,h4+ul,
  h1+ol,h2+ol,h3+ol,h4+ol{margin-top:16px}
  p+p,p+ul,p+ol,ul+p,ol+p{margin-top:1.05em}
  p+h2,p+h3,p+h4,ul+h2,ul+h3,ul+h4{margin-top:30px}

  /* Containers that already space their own children with flex/grid
     `gap` must not receive the margin as well, or the two stack and
     the block grows by ~17px per pair. */
  .quote>*+*,.hero-meta>*+*,.grid>*+*,.acc-panel>*+*,
  .foot-grid>*+*,.cart-item>*+*,.opt-body>*+*{margin-top:0}

  /* --- 2. Leading: real descender clearance ---
     Headings ship at line-height 1.06, correct for a 6.2rem desktop
     h1 on one line. At 29-38px wrapped over 2-3 lines the descender
     of one line reaches the cap of the next. The reading layer above
     raised these to 1.14/1.18; Fraunces' descenders need a little
     more than that at phone sizes. */
  h1{line-height:1.18}
  h2{line-height:1.22}
  h3{line-height:1.3}
  h4{line-height:1.34}

  /* Negative tracking closes the very gaps that keep 38px glyphs
     apart. Neutral at phone sizes, unchanged on every larger screen. */
  h1,h2,h3,h4{letter-spacing:0}

  /* --- 3. Crushed single-line values ---
     line-height:1 gives a display numeral zero room; the digits sat
     on the label below. */
  .stat b{line-height:1.08;margin-bottom:3px}
  .stat span{line-height:1.45}
  .price .amt{line-height:1.06;margin:14px 0 6px}

  /* --- 4. Hero spacing at 375px --- */
  .hero h1{margin:12px 0 20px}
  .hero .lead{line-height:1.65}
  .hero-meta{margin-top:26px}

  /* --- 5. Section rhythm: 78px of dead band top and bottom is a lot
     of scrolling on a 812px-tall screen. --- */
  .section{padding:66px 0}
  .section-head{margin-bottom:32px}

  /* --- 6. Body copy floor. 1rem/1.75 is comfortable; the lists were
     inheriting the tighter component values. --- */
  .lead{font-size:1rem;line-height:1.68}
  .checklist li{line-height:1.62;gap:12px}
  .checklist li+li{margin-top:10px}

  /* --- 7. Specificity escalation ---
     Two component rules outrank the (0,0,2) adjacent-sibling rules in
     part 1 and were still holding their headings flush:
       .grid.g-3 .card:has(.ico) p{margin:0}   -> (0,4,2)
       .pkg-tag{margin-top:7px}                -> (0,1,0)
     Matched here at equal-or-higher weight rather than with
     !important, so a later component override is still possible. */
  .grid.g-3 .card:has(.ico) h3+p,
  .grid.g-4 .card:has(.ico) h3+p{margin-top:13px}
  .card h3{margin-bottom:0}
  .pkg-body h3+.pkg-tag,.pkg-body h3+p{margin-top:12px}
  .price h3+p,.price h3+.amt{margin-top:12px}

  /* --- 8. Script guard ---
     Hebrew and Japanese have taller glyph bodies than Latin lower-case
     and are set at 1.32 further down this sheet. Re-stated here so this
     whole block can be pasted at ANY point in the file without the
     paste position deciding whether Hebrew keeps its leading. */
  [lang="he"] h1,[lang="he"] h2,[lang="he"] h3,[lang="he"] h4,
  [lang="ja"] h1,[lang="ja"] h2,[lang="ja"] h3,[lang="ja"] h4{
    line-height:1.32;letter-spacing:0}
}

/* --- 428px (iPhone Pro Max): same rhythm, a little more air --- */
@media(min-width:429px) and (max-width:560px){
  h1+p,h2+p,h3+p,h4+p{margin-top:18px}
  p+p{margin-top:1.1em}
}


/* ============================================================
   SCRIPT SUPPORT  —  Hebrew (RTL) and Japanese
   Keyed off the lang/dir attributes that tools/i18n-build.js stamps on
   <html>, so nothing here needs a per-page class.

   Almost all of the layout above is flexbox and grid, which mirror
   themselves once dir="rtl" is set, and the handful of genuinely
   direction-bearing declarations were converted to logical properties
   (padding-inline-start, inset-inline-end, text-align:start) in place
   rather than re-stated here. What remains below is only what logical
   properties cannot express: physical viewport pinning, a rotation
   origin, and an animation that runs along an axis.
   ============================================================ */

/* ---- Type: neither Fraunces nor Manrope covers Hebrew or Japanese ----
   Both would silently fall back per-glyph, mixing a serif Latin numeral
   into a sans Hebrew line. Name the system faces instead of loading more
   webfonts: every target OS ships a good Hebrew and a good Japanese
   family, and a CJK webfont is a multi-megabyte download that would undo
   the LCP work on the very pages it is meant to serve. */
:root:lang(he),:root[lang="he"]{
  --display:"Noto Serif Hebrew","David Libre","Frank Ruehl CLM",Georgia,serif;
  --body:"Assistant","Heebo","Noto Sans Hebrew","Arial Hebrew",Arial,sans-serif
}
:root:lang(ja),:root[lang="ja"]{
  --display:"Hiragino Mincho ProN","Yu Mincho","Noto Serif JP",serif;
  --body:"Hiragino Sans","Yu Gothic","Noto Sans JP","Meiryo",sans-serif
}

/* Wide tracking and uppercasing are Latin typographic devices. Hebrew has
   no case at all, so text-transform:uppercase is a no-op that only
   confuses, and letter-spacing on a connected-feeling script reads as
   damage rather than emphasis. Japanese behaves the same way: tracking
   applied to kana and kanji breaks the even rhythm the script depends on.
   Line-height goes UP in both, because both have taller glyph bodies than
   Latin lower-case. */
[lang="he"] .eyebrow,[lang="he"] .crumb,[lang="he"] .btn,[lang="he"] .tag,
[lang="he"] .nav-links a,[lang="he"] .mcard .tag,[lang="he"] .s-lab,
[lang="ja"] .eyebrow,[lang="ja"] .crumb,[lang="ja"] .btn,[lang="ja"] .tag,
[lang="ja"] .nav-links a,[lang="ja"] .mcard .tag,[lang="ja"] .s-lab{
  letter-spacing:0;text-transform:none
}
[lang="he"] body,[lang="ja"] body{line-height:1.85}
[lang="he"] h1,[lang="he"] h2,[lang="he"] h3,[lang="he"] h4,
[lang="ja"] h1,[lang="ja"] h2,[lang="ja"] h3,[lang="ja"] h4{line-height:1.32}
/* Fraunces' optical-size and italic axes do not exist in the fallback
   families, so an italic pull-quote would be synthesised — slanted, not
   drawn. Upright reads better than a fake oblique. */
[lang="he"] .quote p,[lang="ja"] .quote p,
[lang="he"] .photoband .cap,[lang="ja"] .photoband .cap{font-style:normal}

/* ---- RTL: what mirroring cannot do on its own ---- */

/* The slide-in drawer is pinned to a physical edge and animated along a
   physical axis, so neither the inset nor the transform mirrors itself.
   It has to come from the left in Hebrew, or it slides in over the burger
   that opened it. */
@media(max-width:1180px){
  [dir="rtl"] .nav-links{
    inset:0 auto 0 0;
    transform:translateX(-100%);
    box-shadow:30px 0 70px -30px rgba(0,0,0,.6)
  }
  [dir="rtl"] .nav-links.open{transform:none}
}

/* transform-origin takes physical keywords only; the panel must still
   grow out of the corner it is anchored to. */
[dir="rtl"] .lang-menu{transform-origin:top left}
[dir="rtl"] .lang-menu{transform:translateY(-8px) scale(.97)}
[dir="rtl"] .lang-toggle[aria-expanded="true"]+.lang-menu{transform:none}
/* The trigger's asymmetric padding (11px lead, 9px trail) was set for a
   flag-then-code reading order; mirrored, the two swap roles. */
[dir="rtl"] .lang-toggle{padding:0 11px 0 9px}
[dir="rtl"] .lang{margin-right:0;margin-left:2px}

/* A marquee travels along an axis, and translateX(-50%) travels left
   whatever the writing direction. Hebrew reads right-to-left, so the
   ticker has to run the other way or it scrolls into the text instead of
   out of it. */
@keyframes marq-rtl{to{transform:translateX(50%)}}
[dir="rtl"] .strip span{animation-name:marq-rtl}

/* The tick after the current language sits at the far end of the row;
   margin-inline-start already flips it, but the glyph itself must not be
   pulled into the bidi run of the Hebrew label beside it. */
[dir="rtl"] .lang-menu a.on::after{direction:ltr;unicode-bidi:isolate}

/* Prices, dates and phone numbers are LTR runs inside RTL sentences. The
   bidi algorithm gets the digits right on its own but not the currency
   symbol or the surrounding punctuation, which is how "$190" becomes
   "190$" in the middle of a Hebrew line. Isolating the run fixes it
   without touching the copy. */
[dir="rtl"] .price .amt,[dir="rtl"] .pkg-price,[dir="rtl"] .stat b,
[dir="rtl"] time,[dir="rtl"] .ci-price{direction:ltr;unicode-bidi:isolate}

/* =====================================================================
   RELEASE 24 — SEVEN REPORTED DEFECTS
   Appended last on purpose: every rule below is written at the SAME
   specificity as the declaration it replaces, so source order — not
   !important — is what makes it win. Nothing here uses !important.
   ===================================================================== */

/* ---------------------------------------------------------------------
   [1] BRAND — wavy, ocean-lit wordmark
   The wordmark keeps the exact palette (brass -> clay) and the exact
   words. What changes is the FORM: a wider optical tracking, a slow
   tidal gradient sweep through the letterforms, a hand-drawn swell rule
   between the two lines, and a badge that reads as a porthole rather
   than a plain circle.
   --------------------------------------------------------------------- */
.brand{gap:clamp(11px,1.15vw,15px);align-items:center}

/* The badge: a porthole. The inner radial is the sky-glow behind the
   lantern; the ring shadow gives it a machined edge at every scroll
   position without needing a second border. */
.brand .mark{
  width:clamp(38px,3.4vw,47px);height:clamp(38px,3.4vw,47px);
  border:1px solid rgba(255,255,255,.44);
  background:radial-gradient(125% 118% at 50% 4%,rgba(255,255,255,.17),rgba(255,255,255,0) 64%);
  box-shadow:0 0 0 4px rgba(255,255,255,.045),inset 0 1px 0 rgba(255,255,255,.24);
  overflow:hidden;position:relative;
  transition:border-color .5s,box-shadow .5s,transform .5s cubic-bezier(.2,.8,.2,1);
}
.nav.scrolled .brand .mark{
  border-color:rgba(169,138,78,.55);
  background:radial-gradient(125% 118% at 50% 4%,rgba(169,138,78,.16),rgba(169,138,78,0) 64%);
  box-shadow:0 0 0 4px rgba(169,138,78,.09),inset 0 1px 0 rgba(255,255,255,.5);
}
.brand:hover .mark{transform:translateY(-1px) rotate(-2deg)}
.brand .mark svg{width:66%;height:66%;display:block;overflow:visible}

/* The two sea lines drift under the tower — a slow swell, not a loop
   that draws attention to itself. */
.brand .mark .mark-sea{animation:mark-swell 6.5s ease-in-out infinite}
@keyframes mark-swell{
  0%,100%{transform:translateX(0)}
  50%    {transform:translateX(-2.6px)}
}
.brand .mark .mark-beam{animation:mark-beam 5.5s ease-in-out infinite}
@keyframes mark-beam{0%,100%{opacity:.28}45%{opacity:.72}}

/* The wordmark. font-optical-sizing plus a lifted weight give Fraunces
   its display cut at this size; the tracking is what makes it read
   premium. background-size:230% is the runway the tidal sweep travels. */
.brand b{
  display:block;
  font-family:var(--display);
  font-weight:500;
  font-size:clamp(1.1rem,1.35vw,1.38rem);
  line-height:1;
  letter-spacing:.155em;
  text-transform:uppercase;
  font-optical-sizing:auto;
  background:linear-gradient(96deg,#f0e3c8 0%,var(--brass) 34%,var(--clay) 62%,#e9d3a4 100%);
  background-size:230% 100%;
  background-position:0% 50%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 1px 6px rgba(0,0,0,.38));
  animation:brand-tide 11s ease-in-out infinite;
}
@keyframes brand-tide{
  0%,100%{background-position:0% 50%}
  50%    {background-position:100% 50%}
}
.nav.scrolled .brand b,.footer .brand b{filter:none}

/* The swell rule. A 22px tile carrying exactly two full periods, so the
   22px scroll loops seamlessly. It sits in the gap between the two
   lines and is the single element doing the "wavy" work — the type
   itself stays legible and on-brand. */
.brand small{
  position:relative;
  display:block;
  font-family:var(--body);
  font-size:.6rem;
  font-weight:600;
  letter-spacing:.235em;
  text-transform:uppercase;
  color:rgba(255,255,255,.78);
  margin-top:9px;padding-top:8px;
  white-space:nowrap;
}
.brand small::before{
  content:"";position:absolute;top:0;inset-inline-start:0;
  width:100%;max-width:132px;height:5px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='5' viewBox='0 0 22 5'%3E%3Cpath d='M0 2.5q2.75-1.55 5.5 0t5.5 0 5.5 0 5.5 0' fill='none' stroke='%23a98a4e' stroke-width='1.05' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x 0 center;
  opacity:.8;
  animation:brand-swell 9s linear infinite;
}
@keyframes brand-swell{from{background-position:0 center}to{background-position:22px center}}
.nav.scrolled .brand small{color:var(--brass)}

/* Motion is decoration here, never information. */
@media(prefers-reduced-motion:reduce){
  .brand b,.brand small::before,
  .brand .mark .mark-sea,.brand .mark .mark-beam{animation:none}
  .brand b{background-position:18% 50%}
}

/* ---------------------------------------------------------------------
   [2] DESKTOP LANGUAGE DROPDOWN — make the trigger unmissable
   The panel is position:absolute inside .nav-cta. Three things can kill
   it on desktop and all three are closed here:
     a) a click landing on the flag/label SPAN instead of the BUTTON,
     b) an ancestor clipping or out-stacking the panel,
     c) the panel staying pointer-transparent after it fades in.
   The .is-open class is a belt-and-braces duplicate of the
   [aria-expanded="true"] + sibling selector: if the markup ever gains a
   node between button and list, the attribute selector breaks silently —
   the class cannot.
   --------------------------------------------------------------------- */
.nav,.nav-cta,.nav .wrap{overflow:visible}
.nav-cta{position:relative;z-index:60}
.lang{position:relative;z-index:61}

/* Every child of the trigger is inert, so e.target is ALWAYS the button.
   This is what makes the outside-click closer in main.js reliable. */
.lang-toggle{position:relative;z-index:2;cursor:pointer;-webkit-tap-highlight-color:transparent}
.lang-toggle>*{pointer-events:none}

.lang-menu{pointer-events:none}
.lang-toggle[aria-expanded="true"]+.lang-menu,
.lang.is-open>.lang-menu{
  opacity:1;visibility:visible;transform:none;pointer-events:auto;
  transition-delay:0s,0s,0s;
}
/* The drawer copy keeps its own collapsed-height animation. */
@media(max-width:1180px){
  .lang-drawer .lang-toggle[aria-expanded="true"]+.lang-menu,
  .lang-drawer.is-open>.lang-menu{
    max-height:640px;margin-top:10px;visibility:visible;pointer-events:auto;
    transition-delay:0s,0s,0s;
  }
}

/* ---------------------------------------------------------------------
   [3] + [4] MOBILE READING — breathable, and structurally unable to overlap
   Root cause of the overlap: the universal reset near the top of this
   file sets margin:0 on EVERY element, and nothing ever restored prose
   margins. A <p> following a <p> therefore renders at a literal 0px gap,
   and a display serif's descenders draw straight into the next line's
   cap height — which is what "printing on top of each other" looks like.
   The rules below restore that rhythm at (0,0,2) so ordinary prose gets
   it everywhere, then escalate for the component selectors that
   deliberately zero it out.
   --------------------------------------------------------------------- */

/* Global floor. No specificity games: a bare p+p is (0,0,2), so any
   component rule that genuinely wants flush paragraphs still outranks it. */
p+p{margin-top:1.05em}

/* Nothing may ever push a line past its own box. */
p,li,dd,blockquote,figcaption,.lead,h1,h2,h3,h4,h5,h6{
  overflow-wrap:break-word;
  min-width:0;
}

@media(max-width:760px){
  /* --- vertical rhythm --------------------------------------------- */
  h1+p,h2+p,h3+p,h4+p,
  h1+ul,h2+ul,h3+ul,h4+ul,
  h1+ol,h2+ol,h3+ol,h4+ol,
  h1+.readmore,h2+.readmore,h3+.readmore,h4+.readmore{margin-top:18px}
  p+p,p+ul,p+ol,ul+p,ol+p{margin-top:1.15em}
  p+h2,p+h3,p+h4,ul+h2,ul+h3,ul+h4,.readmore+ul,.readmore+p{margin-top:30px}

  /* --- leading: the other half of "no overlap" --------------------- */
  h1{line-height:1.2;letter-spacing:-.005em}
  h2{line-height:1.24;letter-spacing:-.005em}
  h3{line-height:1.32;letter-spacing:0}
  h4{line-height:1.36;letter-spacing:0}

  /* --- density: lighter, larger, further apart --------------------- */
  body{line-height:1.8}
  p,.lead,li{font-weight:350}
  p{font-size:1.02rem;line-height:1.8;color:var(--ink-soft)}
  .lead{font-size:1.06rem;line-height:1.74;font-weight:350}
  .section{padding:72px 0}
  .section-head{margin-bottom:34px}
  .eyebrow{margin-bottom:18px}
  .checklist li{line-height:1.7;gap:13px;font-weight:350}
  .checklist li+li{margin-top:14px}
  .card p,.pkg-body p{line-height:1.75;font-weight:350}

  /* --- component selectors that zero the rhythm out ---------------- */
  .grid.g-3 .card:has(.ico) h3+p,
  .grid.g-4 .card:has(.ico) h3+p{margin-top:14px}
  .card h3{margin-bottom:0}
  .pkg-body h3+.pkg-tag,.pkg-body h3+p{margin-top:13px}
  .price h3+p,.price h3+.amt{margin-top:13px}
  .stat b{line-height:1.08;margin-bottom:4px}
  .stat span{line-height:1.5}

  /* --- [4] THE RETREAT: retire -webkit-line-clamp ------------------
     -webkit-line-clamp is only defined for a container of INLINE
     content. ".readmore-body" holds two block-level <p>s, and clamping
     a multi-child block is undefined behaviour: WebKit/Blink size the
     box from the CONTAINER's line-height while each child lays out on
     its own, which is exactly how two paragraphs end up drawn over one
     another. Measured at 375px: container 112px tall, first <p> also
     112px, second <p> starting at +128px with no margin between them.

     A plain max-height clamp is deterministic instead: real block
     layout, so margins are honoured, a soft mask instead of a hard
     ellipsis, and it animates in both directions. It is structurally
     incapable of stacking two lines. --------------------------------- */
  .readmore .readmore-body{
    display:block;
    -webkit-line-clamp:none;
    -webkit-box-orient:initial;
    max-height:9.4em;
    overflow:hidden;
    -webkit-mask-image:linear-gradient(180deg,#000 58%,rgba(0,0,0,.15) 92%,transparent 100%);
    mask-image:linear-gradient(180deg,#000 58%,rgba(0,0,0,.15) 92%,transparent 100%);
    transition:max-height .5s cubic-bezier(.2,.8,.2,1);
  }
  .readmore.open .readmore-body{
    max-height:240em;
    -webkit-mask-image:none;mask-image:none;
  }
  .readmore-btn{display:inline-flex;align-items:center;margin-top:6px}

  /* --- [5] PHOTOS: stop cropping the subject out ------------------
     .split-media forces 4/3 below 760px. The sources are 956x1700
     portraits, so a 4/3 box discards roughly 70% of the frame from the
     centre out — which takes the surfers with it. Dropping the fixed
     ratio lets the image keep its own; max-height only engages for
     extreme panoramas, and then it crops from --focal, not dead centre. */
  .split-media{aspect-ratio:auto;max-height:none}
  .split-media img{
    width:100%;height:auto;max-height:76vh;
    object-fit:cover;object-position:var(--focal,50% 38%);
    display:block;
  }
  .pkg-card>img{
    height:auto;aspect-ratio:4/3;
    object-fit:cover;object-position:var(--focal,50% 42%);
  }
  .mcard img,.photoband .ph img,.cta-band img,.phero img{
    object-position:var(--focal,50% 38%);
  }
  .photoband .ph{aspect-ratio:4/5}
}

/* Two paragraphs of Hebrew or Japanese need more leading, not more
   tracking — the rhythm rules above are script-neutral, this is not. */
@media(max-width:760px){
  [lang="he"] p,[lang="ja"] p{line-height:1.95}
  [lang="he"] h1,[lang="he"] h2,[lang="he"] h3,[lang="he"] h4,
  [lang="ja"] h1,[lang="ja"] h2,[lang="ja"] h3,[lang="ja"] h4{
    line-height:1.4;letter-spacing:0;
  }
}

/* ---------------------------------------------------------------------
   [6] MOBILE MENU — language first, and a slide that feels designed
   Two changes: the switcher is pinned to the top of the panel (order:-1
   backs up the DOM move in tools/i18n-build.js, so it is first even on
   a page that has not been rebuilt yet), and the panel now opens from
   the top rather than centring its contents, with the links arriving on
   a short stagger behind the panel edge.
   --------------------------------------------------------------------- */
@media(max-width:1180px){
  .nav-links{
    width:min(88vw,392px);
    justify-content:flex-start;
    gap:1px;
    padding:calc(var(--nav-h) + 16px) 30px calc(34px + var(--safe-b));
    background:linear-gradient(168deg,#10404b 0%,var(--ocean-dk) 44%,var(--abyss) 100%);
    box-shadow:-34px 0 80px -34px rgba(0,0,0,.72);
    /* .52s on a spring-ish curve reads as weight; the old .45s ease
       read as a panel being switched on. */
    transition:transform .52s cubic-bezier(.16,1,.3,1),visibility 0s .52s;
  }
  .nav-links.open{
    transition:transform .52s cubic-bezier(.16,1,.3,1),visibility 0s;
  }

  /* Language switcher: first thing in the panel, under the header. */
  .nav-links .lang-li{
    order:-1;width:100%;
    margin:0 0 20px;padding:0 0 20px;
    border-bottom:1px solid rgba(247,241,230,.15);
    border-top:0;
  }
  .lang-drawer{margin:0;padding-top:0;border-top:0}
  .lang-drawer .lang-toggle{
    height:50px;border-radius:14px;font-size:.8rem;
    background:rgba(247,241,230,.09);border-color:rgba(247,241,230,.22);
  }

  /* Staggered entrance. transform on the row, never on the panel, so
     the drawer's own slide stays one compositor-friendly move. */
  .nav-links>li{
    opacity:0;transform:translateX(26px);
    transition:opacity .38s ease,transform .5s cubic-bezier(.16,1,.3,1);
  }
  .nav-links.open>li{opacity:1;transform:none}
  .nav-links.open>li:nth-child(1) {transition-delay:.10s}
  .nav-links.open>li:nth-child(2) {transition-delay:.14s}
  .nav-links.open>li:nth-child(3) {transition-delay:.18s}
  .nav-links.open>li:nth-child(4) {transition-delay:.22s}
  .nav-links.open>li:nth-child(5) {transition-delay:.26s}
  .nav-links.open>li:nth-child(6) {transition-delay:.30s}
  .nav-links.open>li:nth-child(7) {transition-delay:.34s}
  .nav-links.open>li:nth-child(8) {transition-delay:.38s}
  .nav-links.open>li:nth-child(9) {transition-delay:.42s}
  .nav-links.open>li:nth-child(10){transition-delay:.46s}
  .nav-links.open>li:nth-child(11){transition-delay:.50s}
  /* order:-1 moves it visually; this delay follows it so the switcher is
     the first row to arrive, not the tenth. */
  .nav-links.open>li.lang-li{transition-delay:.06s}

  .nav-links a{font-size:1.06rem;letter-spacing:.085em;padding:6px 0}
  .nav-drawer-cta{margin-top:22px}
  .nav-drawer-cta .btn{width:100%;justify-content:center}

  /* Deeper scrim so the page behind reads as dismissed, not just dimmed. */
  .nav-scrim{background:rgba(8,34,42,.58);backdrop-filter:blur(4px) saturate(.9)}
}
@media(max-width:1180px) and (prefers-reduced-motion:reduce){
  .nav-links>li{opacity:1;transform:none;transition:none}
  .nav-links{transition:transform .01s,visibility 0s .01s}
}

/* [1b] Brand at phone widths. The header has exactly three tenants —
   mark, wordmark, and a 143px CTA cluster — and at 375px the wordmark
   gets what is left, which is about 128px. The display sizes above are
   tuned for the desktop rail and clip here, so they are re-tuned rather
   than left to text-overflow. Same treatment, smaller stone. */
@media(max-width:760px){
  .brand{gap:10px}
  .brand .mark{width:36px;height:36px}
  .brand b{font-size:1rem;letter-spacing:.1em}
  .brand small{font-size:.58rem;letter-spacing:.11em;margin-top:6px;padding-top:5px;
    overflow:visible;text-overflow:clip}
  .brand small::before{max-width:100%;height:4px}
}
@media(max-width:400px){
  .brand b{font-size:.95rem;letter-spacing:.07em}
  .brand small{font-size:.53rem;letter-spacing:.085em}
}

/* =====================================================================
   RELEASE 25 — MINIMAL MOBILE HEADER + REDUCED TEXT DENSITY
   Appended last, same-specificity-wins, no !important.
   ===================================================================== */

/* ---------------------------------------------------------------------
   [A] MOBILE HEADER — logo left, flag right, burger far right
   Release 24 put the switcher at the top of the slide-in drawer. This
   brings it back out into the bar itself, flag-only, so the language is
   visible without opening anything — the Island Route pattern.

   The drawer copy is retired rather than kept. Two visible switchers
   would be two tab stops and eighteen focusable links for one decision,
   and the ARIA relationship (aria-controls -> lang-menu-*) would point
   at two panels claiming the same role. One switcher, one panel.
   To put the drawer copy back, delete the .lang-li rule below.
   --------------------------------------------------------------------- */
@media(max-width:1180px){
  .lang-bar{display:block}
  .nav-links .lang-li{display:none}

  /* Flag + caret only. The button keeps its aria-label ("Language:
     English"), which is what carries the meaning once the "EN" text is
     gone — a flag is decoration to a screen reader, never a label. */
  .lang-bar .lang-code{display:none}
  .lang-bar .lang-toggle{
    height:40px;gap:5px;padding:0 8px 0 10px;border-radius:100px;
  }
  /* Scoped to the trigger: the nine options inside the panel keep the
     standard 21px so the list stays one column. */
  .lang-bar .lang-toggle .lang-flag{width:23px;height:17.25px}
  .lang-bar .lang-caret{width:9px;height:6px;opacity:.8}

  /* The panel is anchored to the trigger's right edge. min-width:196px
     would push it off-canvas on a 320px phone, so it is capped to the
     viewport minus the two gutters. */
  .lang-bar .lang-menu{min-width:min(206px,calc(100vw - 36px))}

  .nav-cta{gap:10px}
}

/* Book Now leaves the bar below 760px. It is not lost: the hero carries
   "Reserve Your Escape", the drawer carries .nav-drawer-cta, and the
   sticky .mobile-cta appears as soon as the hero scrolls past. Scoped
   with > so the drawer's own primary button is untouched. */
@media(max-width:760px){
  .nav-cta>.btn-primary{display:none}

  /* The bar now holds three tenants instead of four, so the wordmark
     gets the reclaimed width back. */
  .brand{gap:11px}
  .brand .mark{width:38px;height:38px}
  .brand b{font-size:1.06rem;letter-spacing:.12em}
  .brand small{font-size:.6rem;letter-spacing:.13em}
}
@media(max-width:400px){
  .brand b{font-size:1rem;letter-spacing:.095em}
  .brand small{font-size:.55rem;letter-spacing:.1em}
}

/* ---------------------------------------------------------------------
   [B] MOBILE TEXT DENSITY — let the photography talk
   .m-hide marks prose that is deliberately desktop-only. It stays in the
   HTML rather than being deleted, so the crawler, the RSS-style scrapers
   and anyone with CSS disabled still get the full copy; only the phone
   layout drops it. That is a standard responsive pattern, not cloaking —
   the text is identical, only its display differs by viewport.

   It is deliberately usable on an inline span as well as a block. The hero
   lead is ONE paragraph whose tail sentences are wrapped: the phone keeps
   the opening line — "A boutique surf and eco retreat on Sri Lanka's wild
   east coast." — and drops the rest. Hiding the whole paragraph would have
   left the strongest above-the-fold keyword line invisible to a
   mobile-first crawler, which reads the phone layout first and discounts
   what that layout hides. A near-duplicate second paragraph would have
   fixed the visibility and put two versions of the same sentence in the
   DOM. Splitting one paragraph does neither.
   --------------------------------------------------------------------- */
@media(max-width:760px){
  .m-hide{display:none}

  /* The Retreat now has a single paragraph, so the clamp and its
     "Read more" button have nothing left to reveal. :has() scopes this
     to the one block whose secondary text is mobile-hidden — the other
     read-more sections on the page keep their clamp, which is what is
     holding their text down in the first place. */
  .readmore:has(.m-hide) .readmore-body{
    max-height:none;overflow:visible;
    -webkit-mask-image:none;mask-image:none;
  }
  .readmore:has(.m-hide) .readmore-btn{display:none}
}

/* One pill width for every language, so swapping the flag — or falling
   back to its two-letter code on a platform with no flag glyphs — never
   nudges the burger sideways. */
@media(max-width:1180px){
  .lang-bar .lang-toggle{min-width:54px;justify-content:center}
}

/* ---------------------------------------------------------------------
   [C] HERO FOOTER CLEARANCE — the trust row vs the scroll cue
   The 980px block above already hides .scroll-cue because it and the
   stats were landing on top of each other. The same collision survives
   ABOVE that breakpoint, where the cue is still drawn: it is 73px tall
   and sits 26px off the hero floor, so it claims 99px of the hero''s
   bottom edge, while .hero-inner only reserves 9vh of padding — 81px on
   a 1440x900 laptop, the single most common desktop viewport there is.
   Measured on this build: the trust row wrapped to a second line and
   overlapped the cue by 19px vertically and 78px horizontally, in every
   language.

   max() rather than a flat value so tall monitors keep the airier 9vh
   the design asks for; the floor only engages on short viewports, which
   is exactly where the padding was running out. Scoped to min-width:981
   so it cannot add dead space at the widths where the cue is hidden and
   the shorter padding is correct. */
@media(min-width:981px){
  .hero-inner{padding-bottom:max(9vh, 116px)}
}


/* ---------------------------------------------------------------------
   [D] BOOKING CRUMB CLEARANCE — the brand lockup vs "HOME / BOOK NOW"
   .phero-book reserves calc(var(--nav-h) + clamp(52px,8vw,88px)) at the
   top, but --nav-h is a static 80px while the bar itself is content-sized
   and grows with the brand lockup: measured on this build it is 81px at
   480-600px wide and 87px at 768px. The crumb's breathing room is therefore
   whatever the clamp has left AFTER the bar has taken what it needs, and on
   a phone the clamp is already bottomed out at its 52px minimum — so the
   gap shrinks silently the moment the lockup grows (a longer locale, a
   larger default font size, a user zoom).

   Budget the clearance explicitly instead of inheriting the leftovers. The
   crumb carries the visitor's place in the booking flow, so it stays
   visible; it is the spacing that gives way, not the content. */
@media(max-width:760px){
  .phero-book{padding-top:calc(var(--nav-h) + 76px)}
}
