/* ==============================================================
   RANTHAMBORE REGENCY - SHARED SITE STYLESHEET
   Every inner page links this file. It holds the design tokens, the
   sticky bar, the overlay menu, the footer and the inner-page system
   described in DESIGN-SYSTEM.md.

   The chrome below is lifted from index.html unchanged, so the bar,
   the menu and the footer are the same component on every page. The
   home page still carries its own inline copy: it was left alone by
   decision, so the two are duplicated for now. Reconcile by pointing
   index.html at this file once the inner pages have settled - a fix
   made here does NOT reach the home page until that happens.
   ============================================================== */
/* ══════════════════════════════════════════════════════════════
   TOKENS
   ══════════════════════════════════════════════════════════════ */
:root{
  /* ══════════════════════════════════════════════════════════════
     DESIGN SYSTEM
     Every colour, size, weight and gap on the page resolves through a
     token below. Nothing sets a raw value — that is what keeps it
     consistent when a section is added later.
     ══════════════════════════════════════════════════════════════ */

  /* ── colour ─────────────────────────────────────────────────── */
  /* TWO greens with two jobs. Pine is the brand green: the deep grounds
     (experiences band, footer), the filled buttons and the eyebrows.
     Olive and forest are the TEXT greens — headings, the italic accent,
     body copy — warmer, so type on ivory reads as ink rather than as
     paint. They were briefly all one value; the type went back. */
  --olive:      #50582F;   /* headings, the italic accent           */
  --olive-mark: #444B23;   /* the logo artwork's own green          */
  --forest:     #343B21;   /* body copy                             */
  --pine-deep:  #1B4A3E;   /* the pine, pressed: button hovers      */
  --pine:       #245D4E;   /* the deep green grounds: experiences,
                              footer. Cooler and further from olive
                              than --forest, so a full-bleed panel in
                              it reads as its own ground rather than
                              as body-copy green stretched wide.     */
  --ivory:      #F5F1E7;   /* page ground                           */
  --cream:      #EDE8D8;
  /* The brand band's ground. A token because three things must hold the
     same value: the band's background, the hairline stroke under its
     wordmark (invisible only while it matches the ground exactly), and
     the hero's foot directly above it — which was showing page ivory
     against this cream and reading as a seam. */
  --brand-ground: var(--cream);   /* panel ground                          */
  --sage:       #E3E7D6;   /* alternate panel ground                */
  --beige:      #D8CFBA;   /* rules, hairlines                      */
  --charcoal:   #25271F;   /* deepest ground                        */

  /* ── ink ────────────────────────────────────────────────────────
     Type on light grounds is ink, not green. Deliberately separate
     tokens rather than a retarget of --forest or --olive: those two
     also drive the burger bars, the botanical fills, the star and dot
     marks, the rail progress bar and the icon strokes, all of which
     stay green. Pointing them at grey would have turned the
     illustrations grey along with the text. */
  --ink-head:   #393939;   /* headings and display type             */
  --ink-body:   #272727;   /* body paragraphs                       */
  --white:      #FFFFFF;

  /* ── families ───────────────────────────────────────────────── */
  --font-head: "Cormorant Garamond", Georgia, serif;
  --font-body: "Manrope", "Helvetica Neue", Helvetica, Arial, sans-serif;
  /* the written eyebrow — the same hand the drawn marks came from */
  --font-hand: "Allura", "Segoe Script", cursive;
  /* aliases — existing rules reference these */
  --display: var(--font-head);
  --ui: var(--font-body);

  /* ── weights ────────────────────────────────────────────────── */
  --fw-head:  300;   /* Cormorant regular                          */
  --fw-body:  200;   /* Manrope ExtraLight — copy, buttons, links  */
  --fw-label: 300;   /* tracked caps need a touch more to hold      */

  /* ── one filled button ──────────────────────────────────────────
     Every solid button on the page resolves through these three, so
     Book Now and the section CTAs cannot drift apart again. They were
     10.56/20.24 at radius 0 and 16.8/35.2 at radius 2 — the same
     control in two shapes. */
  --btn-pad-y:  .66rem;
  --btn-pad-x:  1.265rem;
  --btn-radius: 0;

  /* ── type scale ─────────────────────────────────────────────── */
  --fs-h1:    clamp(2.25rem, 5vw, 3.5rem);    /* 36 → 56 */
  --fs-h2:    clamp(1.75rem, 3.6vw, 2.5rem);  /* 28 → 40 */
  --fs-h3:    clamp(1.25rem, 2vw, 1.5rem);    /* 20 → 24 */
  --fs-body:  1.125rem;                        /* 18 */
  --fs-copy:  1rem;                            /* 16 — copy inside panels */
  --fs-small: 1rem;                            /* 16 */
  --fs-label: .8125rem;                        /* 13 */
  --fs-micro: .75rem;                          /* 12 */
  --lh-head:  1.16;
  --lh-body:  1.7;

  /* ── spacing ────────────────────────────────────────────────── */
  --sp-head-para: 26px;    /* heading  → paragraph            */
  --sp-para-cta:  30px;    /* paragraph → button or link      */
  --sp-cta-next:  40px;    /* button   → cards / next block   */
  --sp-section: 100px;   /* 50 bottom + 50 top between sections */    /* section  → section, TOTAL       */
  /* Every section pays HALF the section rhythm at each edge, so any two
     adjacent sections add up to exactly --sp-section between their
     content. Applying the full 120px top and bottom — which is what the
     page used to do — stacked to 240px wherever two sections met. */
  --sp-edge: calc(var(--sp-section) / 2);

  /* ── geometry ───────────────────────────────────────────────── */
  --curtain-size: 94vw;
  --gut: clamp(1.5rem, 4vw, 4rem);
  --ease: cubic-bezier(.4,0,.2,1);
}

/* ══════════════════════════════════════════════════════════════
   THE HEADING RULE
   Half roman, half italic — and the italic carries the green. One
   rule, so every section heading gets it without being told.
   ══════════════════════════════════════════════════════════════ */
h1,h2,h3{ font-family:var(--font-head); font-weight:var(--fw-head); line-height:var(--lh-head); }

/* Key facts called out in body copy (75 rooms, safari timings, distances).
   600 is loaded with the font so the browser never fakes the bold. */
strong{ font-weight:600; color:inherit; }

h1{ font-size:var(--fs-h1); }

h2{ font-size:var(--fs-h2); }

h3{ font-size:var(--fs-h3); }

h1 .accent, h2 .accent, h3 .accent, h1 em, h2 em, h3 em{
  font-weight:var(--fw-head);
  color:var(--olive);
}

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

/* CLIP, not hidden. The curtain overshoots when scaled and must never
   scroll sideways — but overflow-x:hidden turns <body> into a scroll
   CONTAINER, and position:sticky inside a scroll container resolves
   against that container's scrollport instead of the viewport. That
   silently killed the sticky pin in #conservation: the pane never
   stuck, its whole travel was spent scrolling the picture away, and
   the rest of the section rendered as an empty band before
   #testimonials. overflow:clip clips identically WITHOUT creating a
   scroll container, so sticky keeps working. */
html,body{ overflow-x:clip; }

/* ── ONE type scale ──────────────────────────────────────────────
   Body copy was running at eight different sizes across the page —
   13px here, 15px there, 17px somewhere else — because body set no
   font-size at all and every component invented its own. There is
   now a single paragraph size, and everything else is a label.

   The floor is 11px. Four rules were at 8-9px, which is below what
   is comfortably legible even for tracked uppercase, so those were
   raised rather than kept for the look.                            */


/* ══════════════════════════════════════════════════════════════
   THE HEADING RULE
   Half roman, half italic — and the italic carries the green. One
   rule, so every section heading gets it without being told.
   ══════════════════════════════════════════════════════════════ */
h1,h2,h3{ font-family:var(--font-head); font-weight:var(--fw-head); line-height:var(--lh-head); }

h1{ font-size:var(--fs-h1); }

h2{ font-size:var(--fs-h2); }

h3{ font-size:var(--fs-h3); }

h1 .accent, h2 .accent, h3 .accent, h1 em, h2 em, h3 em{
  font-weight:var(--fw-head);
  color:var(--olive);
}

body{
  background:var(--ivory);
  color:var(--forest);
  font-family:var(--ui);
  font-weight:300;
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
}

/* Available to assistive tech, absent from the layout. Used for the
   section headings the visual design carries as artwork, so the
   document outline is complete without changing what is drawn. */
.eyebrow{
  font-size:var(--fs-micro); font-weight:400;
  letter-spacing:.28em; text-transform:uppercase;
  color:var(--pine); line-height:1.6;   /* the brand green, not the text green */
}

/* ── the written eyebrow, SET rather than drawn ────────────────
   Same hand as the four marks above (Allura), as live text instead of
   outlines. No mask, so no stroke-by-stroke reveal — for the sections
   where the word should simply already be written.

   The three resets are the whole point: .eyebrow uppercases the word
   and opens .28em of tracking, both of which are correct for a small
   sans label and ruinous for a script — capitals break the joins and
   tracking pulls the letters apart at exactly the points where they
   are meant to connect. */
.eyebrow--hand{
  font-family:var(--font-hand);
  text-transform:none;
  letter-spacing:0;
  /* Sized against .rr-hw svg, not against .eyebrow. The SVG's height
     is the word's whole bounding box, ascenders and descenders in; an
     em box the same number renders smaller than that, so this runs a
     little larger to land at the same optical size. */
  font-size:clamp(2.2rem,3.8vw,3.3rem);
  line-height:1;
  /* Allura sits high in its em box, so the default half-leading reads as
     a gap above the word — hence the negative top. The BOTTOM stays
     positive: the descenders here are long and looped, and pulling the
     heading up into them was closing the two lines onto each other. */
  margin-block:-.12em .1em;
}

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

/* ── HeroNavigation ──────────────────────────────────────────── */
/* Three columns, not space-between. The logo has to sit on the PAGE's
   centre line, and space-between only puts it there if the burger and
   the Book button happen to be the same width — which they are not, and
   which would change again the first time either label is edited. A
   1fr auto 1fr track centres the middle cell on the bar regardless of
   what the two sides weigh. */
.rr-nav{
  position:absolute; inset:0 0 auto 0; z-index:40;
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
  /* Top padding pulled well in. The nav sits over a photograph, so
     the image itself supplies the breathing room — the padding only
     needs to keep the logo off the very edge, not open a band above
     it. Horizontal gutter is untouched. */
  gap:2rem; padding:clamp(.75rem,1.1vw,1.15rem) var(--gut);
  color:var(--white);
}

.rr-logo{ display:block; }

.rr-logo img{
  width:clamp(112px,10vw,152px); height:auto;
  filter:drop-shadow(0 1px 10px rgba(37,39,31,.42));
}

/* ── actions: BOOK and burger, nothing else ──────────────────────
   The BOOK button is the only filled element on the hero, which is
   what makes it the obvious action without needing size or colour
   noise competing beside it. */
/* Placement only — the two controls are direct grid children now, so
   there is no wrapper left to lay them out. Shared by both bars. */
.rr-nav .rr-burger,
.rr-sticky .rr-burger{ justify-self:start; }

.rr-logo,
.rr-sticky__logo{ justify-self:center; }

.rr-nav .rr-book,
.rr-sticky .rr-book{ justify-self:end; }

/* the one filled control */
/* The body family, but at 400 rather than the --fw-body 200: a button is
   a target, not copy, and ExtraLight caps at 12px were too faint to read
   as one. */
.rr-book{ font-family:var(--font-body); font-weight:400;
  /* Sized against the burger beside it, not against the header. The
     block was 20px taller than the burger and nearly six times its
     width, which is what read as heavy. Tighter tracking too — .24em
     was pushing the four letters into a much wider box than they
     need. */
  /* Solid white ground, forest text. Both places this button lives are
     dark (a translucent charcoal bar, and photography under a scrim),
     so the light face is what carries it at distance; an outline alone
     was reading as a faint box. Hover slides the olive up and the text
     goes ivory, which is the same motion as before, just the other way
     round. */
  background:var(--white); color:var(--forest) !important;
  border:1px solid var(--white);
  /* 10% up on the whole block — the padding and the label together, so
     it grows in proportion rather than just gaining a wider box */
  padding:var(--btn-pad-y) var(--btn-pad-x); border-radius:var(--btn-radius);
  /* Caps, like every other label on the page — the .14em tracking above
     was already set for them, and tracking that wide under lowercase is
     what made the word look loosely spelled rather than lettered. */
  text-transform:uppercase;
  letter-spacing:.14em !important;
  font-size:calc(var(--fs-micro) * 1.1);
  /* two words, one line — at phone width the pill was breaking to two */
  white-space:nowrap;
  position:relative; overflow:hidden;
  transition:color .45s var(--ease), border-color .45s var(--ease);
}

.rr-book span{ position:relative; z-index:1; }

.rr-book::before{
  content:""; position:absolute; inset:0; background:var(--pine);
  transform:translateY(101%); transition:transform .45s var(--ease);
}

.rr-book:hover{ color:var(--ivory) !important; opacity:1 !important; border-color:var(--olive); }

.rr-book:hover::before{ transform:translateY(0); }

/* ── burger ───────────────────────────────────────────────────────
   Two-stage morph rather than a straight rotate. The bars first
   collapse to the middle, then the outer two rotate into the cross —
   the delay on the rotate is what separates the stages. Middle bar
   fades on the way in so nothing is left over inside the X.
   Reversing the same transitions gives the close its animation for
   free, and the bars fan back out.                                */
/* 26 x 16, down from 34 x 20 at the user's request; the bars keep their
   2px weight and close up from 9px to 7px apart */
.rr-burger{
  width:26px; height:16px; position:relative; flex:0 0 auto;
  display:block;
}

.rr-burger span{
  position:absolute; left:0; width:100%; height:2px; background:var(--white);
  /* the hero bars sit on photography — a hairline alone disappears
     into a pale sky, so each carries its own shadow */
  filter:drop-shadow(0 1px 3px rgba(37,39,31,.45));
  transition:top .3s var(--ease), opacity .25s var(--ease),
             transform .4s var(--ease) .22s, width .4s var(--ease);
}

.rr-burger span:nth-child(1){ top:0; }

.rr-burger span:nth-child(2){ top:7px; }

.rr-burger span:nth-child(3){ top:14px; }

.rr-burger:hover span:nth-child(2){ width:70%; }

.rr-burger[aria-expanded="true"] span{ background:var(--forest); filter:none; }

.rr-burger[aria-expanded="true"] span:nth-child(1){ top:7px; transform:rotate(45deg); }

.rr-burger[aria-expanded="true"] span:nth-child(2){ opacity:0; width:100%; transition-delay:0s; }

.rr-burger[aria-expanded="true"] span:nth-child(3){ top:7px; transform:rotate(-45deg); }

@media (max-width:34rem){
/* The body family, but at 400 rather than the --fw-body 200: a button is
   a target, not copy, and ExtraLight caps at 12px were too faint to read
   as one. */
  /* Sized to FIT its 1fr track, not just forbidden from wrapping: the
     pill is overflow:hidden, so the grid never grows the track for it,
     and at 360px a 108px pill in a 68px track was sitting on the logo.
     Tighter gap, a lower floor on the mark, and a smaller pill together
     clear it down to 360. */
  .rr-nav, .rr-sticky{ gap:1rem; }
.rr-logo img{ width:clamp(92px,10vw,152px); }
.rr-book{ font-family:var(--font-body); font-weight:400; font-size:var(--fs-micro); padding:.45rem .7rem; letter-spacing:.06em !important; }
}

@media (max-width:22rem){
/* the 320px floor: the pill was still touching the mark */
  .rr-nav, .rr-sticky{ gap:.75rem; }
.rr-logo img{ width:84px; }
}

/* ══════════════════════════════════════════════════════════════
   STICKY NAVBAR
   Arrives only once the pinned hero has been left behind entirely,
   sliding down from above rather than fading in — a fade would read
   as an overlay, a slide reads as a bar that was always up there.

   Glassmorphism: a translucent ground plus backdrop-filter, so the
   page tinted behind it stays legible through the bar. saturate()
   alongside the blur is what stops the colour behind going muddy —
   blur alone desaturates and the whole thing turns grey.
   ══════════════════════════════════════════════════════════════ */
.rr-sticky{
  position:fixed; top:0; left:0; right:0; z-index:70;
  /* One fluid ramp instead of a desktop value plus a phone override.
     The logo is what sets the floor here: sized by width it rendered
     86px tall, so a 120px bar was mostly logo with 17px of air. */
  height:clamp(64px,6.5vw,88px);
  /* same three-column track as the hero bar, so the mark sits on the
     page centre line in both and does not shift as the sticky takes over */
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
  gap:2rem; padding-inline:var(--gut);
  /* Light ground, so the mark can be shown in its own colour. On the old
     translucent charcoal the bar took its tone from whatever was behind
     it: over the ivory sections the olive logo cleared 3.3:1, but over
     the forest experiences band the bar composited to #2E3320 and the
     logo fell to 1.4:1 — invisible. An ivory ground is the same
     everywhere, so the mark reads on every section. */
  /* .70, not .88. The blur was already declared below but could not be
     seen through an almost-opaque ground — glass you cannot see through
     is just a panel. .70 is as far down as this can go before the note
     above starts to bite again: composited over the forest band it
     resolves near #BBBAAC, which still holds the olive mark at ~3.8:1
     and the forest burger at ~5.9:1. Lower looks better and reads worse. */
  /* Solid, at the user's request: the frosted .70 ground let whatever
     scrolled underneath smear through behind the logo, so the bar read
     as a tinted pane rather than a header. Opaque ivory, a firm rule and
     a soft shadow make it a bar the page passes under. */
  background:var(--ivory);
  /* a hair brighter along the top edge — the one cue that reads as a
     pane of glass catching light rather than a flat translucent fill */
  box-shadow:0 6px 18px rgba(37,39,31,.07);
  border-bottom:1px solid rgba(52,59,33,.16);
  transform:translateY(-100%);
  transition:transform .75s var(--ease);
  will-change:transform;
}

.rr-sticky.show{ transform:translateY(0); }

/* stand down while the overlay owns the screen — the menu carries its
   own close control, so two competing bars would just fight */
.rr-sticky.stand-down{ transform:translateY(-100%); }

/* Constrained by HEIGHT, not width — the bar's height is the scarce
   dimension, and a 1.54 aspect mark sized by width overruns it. */
/* +20% on all three stops, not just the ceiling — scaling only the max
   would leave the bar's logo unchanged on every screen below the point
   where the clamp is already pinned, which is most laptops. */
.rr-sticky__logo img{ height:clamp(50px,5.5vw,74px); width:auto; }

/* The bar is light now, so its two controls invert. Scoped to .rr-sticky
   only — the hero nav sits on photography and keeps its light-on-dark
   treatment. Without this the ivory Book block and the white burger bars
   would both disappear into the ground. */
/* Filled here, always: an olive block with an ivory label on the ivory
   bar, and hovering deepens the olive to forest rather than inverting
   to a light panel.

   Inverting was the bug: the ::before slid IVORY up over an ivory bar,
   so on hover the button lost its edge against the ground and became a
   patch of grey text floating in the bar. Going darker keeps the shape
   readable and makes hover feel like pressure rather than erasure. */
.rr-sticky .rr-book{ background:var(--pine); color:var(--ivory) !important; border:1px solid var(--pine); }

.rr-sticky .rr-book::before{ background:var(--pine-deep); }

.rr-sticky .rr-book:hover{ color:var(--ivory) !important; border-color:var(--pine-deep); }

.rr-sticky .rr-burger span{ background:var(--forest); filter:none; }

@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
.rr-sticky{ background:var(--ivory); }
}

/* ══════════════════════════════════════════════════════════════
   OVERLAY MENU
   Sits outside the pinned stage so it is never affected by the pin.
   Ivory ground, so it reads as the same world the curve reveals.
   ══════════════════════════════════════════════════════════════ */
/* Split panel: photography holds the left, the ivory panel carries the
   navigation on the right. The two halves are animated separately —
   the panel slides, the image resolves — so the menu arrives as two
   related moves rather than one flat fade. */
/* The overlay carries its own ground, which it did not before. The panel
   and the photograph together cover the viewport only once BOTH have
   finished arriving; until then the uncovered middle showed the live page
   straight through. That was the real defect. The clip-path version made
   it read as a seam because the page behind is the same ivory as the
   panel, and swapping the clip for a slide did not fix it — it only
   changed what leaked through.

   Set as background-color rather than a ::before, because a pseudo-element
   on a flex container becomes a flex item and would sit in the row beside
   the panel. It fades in faster than the halves travel, so the page is
   covered before anything is far enough in to expose it. */
.rr-menu{
  position:fixed; inset:0; z-index:90;
  display:flex; visibility:hidden;
  background-color:rgba(37,39,31,0);
  transition:visibility .8s, background-color .8s var(--ease);
}

/* Fast in, slow out. The gap between the two halves is open from the
   very first frame — at rest the panel is at -100% and the photograph
   at +100%, so nothing covers the middle — which means the ground has
   to be opaque before either starts travelling, not .45s later. On the
   way out the base rule's .8s applies instead, so the ground holds
   until the halves have left rather than uncovering the page early. */
.rr-menu.open{
  visibility:visible;
  background-color:rgba(37,39,31,1);
  transition:visibility 0s, background-color .2s var(--ease);
}

/* Panel left, photograph right. Ordered in CSS rather than by moving the
   markup: the visual half holds nothing focusable, so source order and
   visual order can differ here without disturbing the tab sequence —
   which is exactly why the nav bar's controls were reordered in the
   MARKUP instead, where every item is a tab stop. */
.rr-menu__panel{  order:0; }

.rr-menu__visual{ order:1; }

/* ── right: the image, one per destination ────────────────────── */
.rr-menu__visual{
  position:relative; flex:1 1 auto; overflow:hidden; background:var(--charcoal);
  /* Slides in from the right rather than being wiped open by a clip.
     The clip left the unrevealed area TRANSPARENT, so the page showed
     through it mid-animation — and the page is the same ivory as the
     panel, which read as the panel being arbitrarily too wide with a
     hard edge where the photograph began, rather than as a reveal.

     A transform keeps the element opaque for the whole move, so there
     is nothing to see through. It also shares the panel's duration and
     easing below, so the two halves arrive together instead of the
     photograph trailing the panel by 100ms. */
  transform:translateX(100%);
  transition:transform .8s var(--ease);
}

.rr-menu.open .rr-menu__visual{ transform:translateX(0); }

.rr-menu__visual img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transform:scale(1.06);
  transition:opacity .8s var(--ease), transform 1.4s var(--ease);
}

.rr-menu__visual img.is-on{ opacity:1; transform:scale(1); }

/* a whisper of the brand over the photograph keeps the two halves
   reading as one surface rather than a pasted-in picture */
.rr-menu__visual::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  /* 270deg, not 90: the vignette belongs on the photograph's OUTER edge,
     which is now the right-hand one. Left at 90deg it would darken the
     side that meets the panel and read as a seam between the halves. */
  background:linear-gradient(270deg, rgba(37,39,31,.34), rgba(37,39,31,0) 55%);
}

/* ── left: the panel ──────────────────────────────────────────── */
.rr-menu__panel{
  flex:0 0 clamp(360px, 36vw, 560px);
  background:var(--ivory); color:var(--forest);
  display:flex; flex-direction:column; align-items:center;
  padding:clamp(1.5rem,3vh,2.5rem) clamp(1.5rem,3vw,3rem) clamp(2rem,5vh,3.5rem);
  transform:translateX(-100%);      /* enters from the left edge it now sits on */
  transition:transform .8s var(--ease);
  overflow-y:auto;
}

.rr-menu.open .rr-menu__panel{ transform:translateX(0); }

.rr-menu__top{
  width:100%; display:flex; align-items:center; justify-content:flex-start;
  gap:1rem; margin-bottom:clamp(1.5rem,4vh,3rem);
}

.rr-menu__top a{
  font-size:var(--fs-micro); letter-spacing:.22em; text-transform:uppercase;
  color:var(--forest); opacity:.75; transition:opacity .3s var(--ease);
}

.rr-menu__top a:hover{ opacity:1; }

/* close — rotates and scales in, so it arrives rather than appears */
.rr-menu__close{ width:32px; height:32px; position:relative; flex:0 0 auto; }

.rr-menu__close span{
  position:absolute; top:50%; left:0; width:100%; height:1.25px;
  background:var(--forest); transition:background .3s var(--ease);
}

.rr-menu__close span:nth-child(1){ transform:rotate(45deg); }

.rr-menu__close span:nth-child(2){ transform:rotate(-45deg); }

.rr-menu__close:hover span{ background:var(--olive); }

.rr-menu__close{
  opacity:0; transform:rotate(-90deg) scale(.5);
  transition:opacity .5s var(--ease) .35s, transform .6s var(--ease) .35s;
}

.rr-menu.open .rr-menu__close{ opacity:1; transform:rotate(0) scale(1); }

.rr-menu__emblem{
  width:clamp(120px,11vw,168px); height:auto;
  margin-bottom:clamp(1.5rem,4vh,3rem);
  opacity:0; transform:translateY(14px);
  transition:opacity .6s var(--ease) .3s, transform .6s var(--ease) .3s;
}

.rr-menu.open .rr-menu__emblem{ opacity:1; transform:none; }

.rr-menu nav{
  display:flex; flex-direction:column; align-items:center;
  gap:clamp(.5rem,1.8vh,1.15rem); width:100%;
}
/* The emblem above the list and the address below it are gone (the
   user's call), so the list centres itself in the panel. On a screen too
   short for all ten items the auto margins fall to zero and the panel's
   own overflow-y scrolls instead. */
.rr-menu nav{ margin-block:auto; }
/* Ten items run past a landscape phone (844x390 was 44px over, 740x360
   74px). Below 544px tall the type, gaps and panel padding tighten so all
   ten fit; 16px caps stays above the 14px floor. Taller screens untouched.
   Measured and proposed by ranthambore-regency-45. */
@media (max-height:34rem){
  /* #menuNav, not nav: the base .rr-menu nav a rule comes later in this
     file and would win a tie */
  .rr-menu #menuNav a{ font-size:clamp(1rem,3.4vh,1.25rem); }
  /* .15rem floor, not .25: with Jungle Safari the menu is eleven items,
     and at 740x360 the .25 floor overflowed the panel by 8px */
  .rr-menu nav{ gap:clamp(.15rem,1.2vh,.6rem); }
  .rr-menu__panel{ padding-block:clamp(.6rem,2vh,1rem); }
}

.rr-menu nav a{ font-family:var(--font-body); font-weight:var(--fw-body);
  font-family:var(--display); font-weight:500;
  font-size:clamp(1.25rem,2vw,1.85rem); line-height:1.25;
  letter-spacing:.03em; text-transform:uppercase; color:var(--olive);
  opacity:0; transform:translateY(18px);
  transition:opacity .6s var(--ease), transform .6s var(--ease), color .3s var(--ease);
  transition-delay:calc(.34s + var(--i) * 55ms);
}

.rr-menu.open nav a{ opacity:1; transform:none; }

.rr-menu nav a:hover, .rr-menu nav a.is-active{ color:var(--forest); }

.rr-menu__foot{
  margin-top:auto; padding-top:clamp(1.5rem,4vh,2.5rem);
  display:flex; flex-direction:column; align-items:center; gap:.5rem;
  font-size:var(--fs-micro); letter-spacing:.22em; text-transform:uppercase;
  color:rgba(52,59,33,.6); text-align:center;
  opacity:0; transition:opacity .6s var(--ease) .6s;
}

.rr-menu.open .rr-menu__foot{ opacity:1; }

@media (max-width:52rem){
.rr-menu__visual{ display:none; }
.rr-menu__panel{ flex:1 1 100%; }
}

/* Everything real is lifted over the watermark layer. Scoped to direct
   children so it cannot disturb the stacking inside the slider grid. */

/* Grid stacking rather than absolute positioning: every slide shares
   one cell, so the section is always as tall as its tallest slide and
   nothing shifts when the slide changes. */
/* ══════════════════════════════════════════════════════════════
   SECTION HEADER — one component, used by every section
   Four slots in a fixed order: eyebrow, heading, paragraph, CTA.

   The heading is split into a plain part and an ACCENT part, which
   is the convention the reference is built on — its template renders
   every section heading as {title}

.rr-shead p:not(.eyebrow){ color:var(--ink-body); max-width:46rem; }

.rr-shead--light .eyebrow{ color:var(--beige); }

.rr-shead--light p:not(.eyebrow){ color:rgba(245,241,231,.76); }

.rr-split__panel p:not(.eyebrow){ font-size:var(--fs-body); line-height:1.75;
  color:var(--ink-body); max-width:34rem; margin-top:1.1rem;
 margin-bottom:var(--sp-para-cta); }

.rr-grow__copy .eyebrow{ color:var(--beige); }

/* ══════════════════════════════════════════════════════════════
   FOOTER — redesigned 5 Oct after the client's reference footer
   A treeline standing on the page ground, then one pine band: three
   labelled columns (address, contact, follow), a centred row of every
   page, and the colophon. The trees are the logo's own banyan,
   recoloured to pine (assets/emblem-pine.png), on a tiled strip of
   grass (assets/footer-grass.svg) whose ground is the band's top edge.
   Replaced the two-panel footer (link columns beside a brand panel on
   a photograph), which the client did not like.
   ══════════════════════════════════════════════════════════════ */
.rr-ft{ position:relative; color:var(--ivory); font-size:15px; }
.rr-ft a{ color:inherit; transition:color .3s var(--ease), opacity .3s var(--ease); }
.rr-ft a:focus-visible{ outline:2px solid var(--ivory); outline-offset:3px; }

/* ── the treeline, on its own ivory ground ──────────────────────
   Grass drawn as an illustration in two layers (the client found the
   earlier spiky strip "too artificial", 5 Oct):
     ::before  tall wild grass and seed heads, lighter, behind
     ::after   short grass in front, on the solid ground line
   ONE banyan, at the left: the client asked for the right-hand tree and
   its animals to go and for the other to stay (5 Oct). It stands in front
   of the grass, and the front blades are cleared round the walking
   leopard at its foot, where grass in the same green swallowed its outline.
   Tiles are seamless and of different widths (1600 / 1200), so the repeat
   never lines up; they are generated, so change them as a set. */
.rr-ft__tree{
  --tree-h:clamp(72px,9vw,140px);
  --tree-x:clamp(.5rem,5vw,7rem);
  --grass-h:clamp(32px,2.8vw,42px);
  --grass-back-h:clamp(52px,5vw,78px);
  position:relative; height:var(--tree-h); pointer-events:none;
  /* its own ivory ground, not transparent: on the home page the pinned
     hero sits behind everything and would show through */
  background:var(--ivory);
}
.rr-ft__tree::before{
  content:""; position:absolute; left:0; right:0; bottom:-1px;
  height:var(--grass-back-h);
  background:url(footer-grass-back.svg) repeat-x left bottom / auto 100%;
  opacity:.42;
}
.rr-ft__tree::after{
  content:""; position:absolute; left:0; right:0; bottom:-2px;
  height:var(--grass-h);
  background:url(footer-grass.svg) repeat-x left bottom / auto 100%;
  /* the clearing round the leopard: .24-.48 of the banyan's width (it is
     1.92 x its height wide) in from its left edge, so it tracks the tree
     at every width. Layer two keeps the bottom 5px, so the ground stays
     whole and only the blades go. Edges fade over 10px. */
  --cl-a:calc(var(--tree-x) + var(--tree-h) * .46);
  --cl-b:calc(var(--tree-x) + var(--tree-h) * .92);

  /* One clearing per tree, because each banyan carries its own leopard at
     its foot and the front grass is the same pine, so the blades swallow
     the outline even with the tree drawn in front of them.

     The band is .46-.92 of a tree's OWN height in from its own left edge,
     and each tree is 1.92x its height wide. Worked per tree, not from
     --tree-h, because these two stand shorter than the first:

     middle, 46% tall and FLIPPED, so the band is measured from its right
     edge instead: right edge sits at 55% + 1.92 * .46h = 55% + .883h,
     and the band runs .212h to .423h back from there.
     right, 62% tall and unflipped: .46-.92 of .62h = .285h to .570h. */
  --cl-m-a:calc(55% + var(--tree-h) * .460);
  --cl-m-b:calc(55% + var(--tree-h) * .672);
  --cl-r-a:calc(81% + var(--tree-h) * .285);
  --cl-r-b:calc(81% + var(--tree-h) * .570);

  -webkit-mask-image:
    linear-gradient(90deg, #000 0, #000 calc(var(--cl-a) - 10px), transparent var(--cl-a),
      transparent var(--cl-b), #000 calc(var(--cl-b) + 10px), #000 100%),
    linear-gradient(to top, #000 5px, transparent 5px);
          mask-image:
    linear-gradient(90deg, #000 0, #000 calc(var(--cl-a) - 10px), transparent var(--cl-a),
      transparent var(--cl-b), #000 calc(var(--cl-b) + 10px), #000 100%),
    linear-gradient(to top, #000 5px, transparent 5px);
}
/* A hidden tree must take its clearing with it, or the grass keeps a gap
   where no tree stands. Collapsing the band to zero width is enough. */
@media (max-width:60rem){
  .rr-ft__tree::after{
    --cl-m-a:calc(58% + var(--tree-h) * .440);
    --cl-m-b:calc(58% + var(--tree-h) * .642);
    --cl-r-a:100%; --cl-r-b:100%;
  }
}
@media (max-width:40rem){
  .rr-ft__tree::after{ --cl-m-a:100%; --cl-m-b:100%; }
}
/* in FRONT of the grass and standing on its ground line, so the animals
   keep their whole outline against the ivory and the pale back grass */
.rr-ft__banyan{
  position:absolute; z-index:1; bottom:0;
  height:100%; width:auto; display:block;
}
.rr-ft__banyan--l{ left:var(--tree-x); }

/* Two more banyans across the strip. Placed by percentage rather than by
   the --tree-x ramp the left one uses: that value is an edge inset, which
   is the right idea for a tree anchored to the margin and the wrong one
   for trees standing out in the open, where they should hold their
   position in the scene as the viewport changes.

   Neither is a straight copy of the first. Both stand well short of the
   first: the middle is flipped and small, the right medium, so the three read as three
   trees rather than one stamped three times. Heights are percentages of
   the strip, so they scale with --tree-h like the original. */
.rr-ft__banyan--m{
  left:55%; height:46%; transform:scaleX(-1); transform-origin:center;
  }
.rr-ft__banyan--r{ left:81%; height:62%; }

/* Below this the strip is short and the three would crowd each other, so
   the open-ground pair steps back to two, then to the original one. */
@media (max-width:60rem){
  .rr-ft__banyan--m{ left:58%; height:44%; }
  .rr-ft__banyan--r{ display:none; }
}
@media (max-width:40rem){
  .rr-ft__banyan--m{ display:none; }
}

/* ── the band ───────────────────────────────────────────────────── */
.rr-ft__body{
  position:relative; background:var(--pine);
  padding:clamp(1.75rem,3.2vw,2.75rem) var(--gut) clamp(1.1rem,2.2vw,1.6rem);
}
.rr-ft__info, .rr-ft__links, .rr-ft__base{ max-width:66rem; margin-inline:auto; }
/* One centred stack, after the client's second footer reference, kept
   compact: name and address, the phones on one line and the email on the
   next, then Follow Us beside its buttons. Marks are ivory line drawings and
   the buttons outlines: the solid ivory tiles read as heavy white boxes
   (the user's call). */
.rr-ft__info{ text-align:center; }
.rr-ft__name{
  margin:0; font-family:var(--display); font-weight:500;
  font-size:clamp(1.5rem,2vw,1.85rem); line-height:1.2; letter-spacing:.01em; color:var(--ivory);
}
.rr-ft__addr{ margin:.3rem 0 0; font-size:15px; font-weight:300; line-height:1.6; color:var(--ivory); }
.rr-ft__addr a:hover{ text-decoration:underline; text-underline-offset:4px; }

.rr-ft__contact{
  list-style:none; margin:.15rem 0 0; padding:0;
  display:flex; flex-wrap:wrap; justify-content:center; gap:.15rem 2.25rem;
}
.rr-ft__contact--first{ margin-top:clamp(.85rem,1.6vw,1.15rem); }
.rr-ft__contact li{
  display:inline-flex; align-items:center; gap:.55rem;
  font-size:15px; font-weight:300; color:var(--ivory); padding-block:.25rem;
}
.rr-ft__contact a{ padding-block:.3rem; }
.rr-ft__contact a:hover{ text-decoration:underline; text-underline-offset:4px; }
.rr-ft__contact b{ font-weight:500; }
.rr-ft__sep{ color:#7FA197; }   /* solid: the divider tone on pine */
.rr-ft__ico{
  flex:none; width:18px; height:18px; display:block;
  fill:none; stroke:var(--ivory); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}

/* Follow Us on the same line as its buttons: one row, not two */
.rr-ft__follow{
  margin-top:clamp(.9rem,1.8vw,1.25rem);
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:.6rem 1.1rem;
}
/* a label, not a heading: the footer should not add to every page's outline */
.rr-ft__h{
  margin:0; font-family:var(--display); font-weight:500;
  font-size:clamp(1.2rem,1.5vw,1.4rem); line-height:1.2; color:var(--ivory);
}
/* Smaller boxes and icons at the client's request (5 October 2026). The
   ::after keeps the tap target at 44px round the 34px box; the 10px gap
   keeps neighbouring targets from overlapping. */
.rr-ft__social{ list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; justify-content:center; gap:.625rem; }
.rr-ft__social a{
  position:relative; width:34px; height:34px; display:grid; place-items:center;
  border:1px solid var(--ivory);
  transition:background .3s var(--ease);
}
.rr-ft__social a::after{ content:""; position:absolute; inset:-5px; }
.rr-ft__social svg{ width:14px; height:14px; fill:var(--ivory); transition:fill .3s var(--ease); }
/* the owl is wide and short, so at 14px it reads smaller than the rest */
.rr-ft__social a[aria-label="TripAdvisor"] svg{ width:16px; height:16px; }
.rr-ft__social a:hover{ background:var(--ivory); }
.rr-ft__social a:hover svg{ fill:var(--pine); }

/* every page, in one centred row that wraps */
.rr-ft__links{
  margin-top:clamp(1.25rem,2.4vw,1.75rem); padding-top:clamp(.75rem,1.6vw,1.1rem);
  border-top:1px solid #4E7B6D;   /* solid: ivory at 20% over pine, flattened */
  display:flex; flex-wrap:wrap; justify-content:center; gap:0 1.5rem;
}
.rr-ft__links a{
  font-size:14px; letter-spacing:.05em; font-weight:300;
  color:var(--ivory); padding-block:.4rem;
}
.rr-ft__links a:hover{ color:var(--ivory); text-decoration:underline; text-underline-offset:4px; }

.rr-ft__base{
  margin-top:clamp(.35rem,1vw,.6rem);
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:.3rem .9rem;
  font-size:14px; font-weight:300; color:var(--ivory);
}
.rr-ft__base span{ color:#7FA197; }   /* the divider, solid */
.rr-ft__base a{ padding-block:.35rem; }
.rr-ft__base a:hover{ color:var(--ivory); }

.rr-ft__top{
  position:absolute; right:clamp(1rem,2.5vw,2.25rem); bottom:clamp(1rem,2.5vw,2.25rem);
  width:44px; height:44px; display:grid; place-items:center; border-radius:50%;
  border:1px solid var(--ivory);
  transition:background .3s var(--ease), border-color .3s var(--ease);
}
.rr-ft__top:hover{ background:var(--ivory); border-color:var(--ivory); }
.rr-ft__top svg{ width:17px; height:17px; fill:none; stroke:var(--ivory); stroke-width:1.4; transition:stroke .3s var(--ease); }
.rr-ft__top:hover svg{ stroke:var(--pine); }

@media (max-width:47.9375rem){
  /* one contact item per line, still centred */
  .rr-ft__contact{ flex-direction:column; align-items:center; gap:0; }
  .rr-ft__links{ gap:0 1.25rem; }
  /* under the colophon on a phone, rather than sitting on top of it */
  .rr-ft__top{ position:static; margin:1.1rem auto 0; }
  /* Sitemap over the credit, with no dangling separator between them */
  .rr-ft__base{ flex-direction:column; gap:0; }
  .rr-ft__base span{ display:none; }
}
/* copyright line: a span like the divider, but text - keep it visible and ivory at every width */
.rr-ft__base .rr-ft__copy{ display:inline; color:inherit; padding-block:.35rem; }

.rr-burger::after{ content:""; position:absolute; inset:-14px -9px; }   /* 44 x 44 around the 26 x 16 mark */

.rr-menu__close::after{ content:""; position:absolute; inset:-6px; }

/* stacked link lists — 20px line boxes become ~40px hit boxes */
.rr-menu nav a{ padding-block:.5rem; margin-block:-.5rem; }



@media (hover:none){
/* thumbs, not cursors: the underline CTAs sit at 29px, which clears the
     WCAG minimum but not comfort. .rr-grow__cta came off this list when
     it became a pill — it already carries 1rem of vertical padding, and
     the bump here would have stretched the pill out of shape. */
  .rr-shead__cta, .rr-rs__link, .rr-split__cta, .rr-ft__cta{
    padding-block:.45rem; margin-block:-.45rem;
  }
}

/* ══════════════════════════════════════════════════════════════
   NAVBAR — a link cluster beside the burger
   The reference carries three standing links next to the menu button,
   the mark on the page centre line, and one filled pill on the right.
   The grid is still 1fr auto 1fr, so the mark stays centred on the BAR
   no matter what the two sides come to weigh.
   ══════════════════════════════════════════════════════════════ */
.rr-nav__left, .rr-sticky__left{
  justify-self:start;
  display:flex; align-items:center; gap:clamp(1rem,2.4vw,2.4rem);
}

.rr-nav__links, .rr-sticky__links{
  display:flex; align-items:center; gap:clamp(.9rem,2vw,2rem);
}

.rr-nav__links a, .rr-sticky__links a{
  font-family:var(--font-body); font-weight:400;
  font-size:var(--fs-label); letter-spacing:.18em; text-transform:uppercase;
  white-space:nowrap; transition:opacity .3s var(--ease);
}

.rr-nav__links a{ color:var(--white); text-shadow:0 1px 8px rgba(37,39,31,.45); }

.rr-sticky__links a{ color:var(--forest); }

.rr-nav__links a:hover, .rr-sticky__links a:hover{ opacity:.65; }

/* Filled, square-cornered, one per bar. It was a 999px pill for a while;
   the site's edges are sharp everywhere else, so the button follows the
   --btn-radius it started with (0). */
.rr-book{ border-radius:var(--btn-radius); }

@media (max-width:68rem){
/* below this the three links crowd the mark, and the burger already
     carries the whole navigation */
  .rr-nav__links, .rr-sticky__links{ display:none; }
}

/* Everything after the pinned hero rides over it. The stage is excluded
   because this rule would otherwise replace its sticky with relative and
   the pull-up would quietly stop happening. */
body > section:not(.rr-stage),
body > footer{ position:relative; z-index:1; }

/* the written "Welcome" is a <p> too, so the copy colour above was
   landing on it; the eyebrow keeps the brand green like every other */
.rr-about__head .eyebrow{ color:var(--pine); }

/* Filled in the hero as well, at every width — one pill, one treatment:
   solid white, forest label, matching the booking bar beneath it. White
   rather than the sticky bar's olive, because this one sits on
   photography and a mid-green fill would sink into the canopy. The
   fill, edge and olive hover are all .rr-book's; this only pins them so
   a later override cannot hollow the pill out again. */
.rr-nav .rr-book{ background:var(--white); border:1px solid var(--white); }

.eyebrow--hand{
  --hw:1;
  /* the trailing 1.1em is the wet edge — a hard stop reads as a wipe */
  -webkit-mask-image:linear-gradient(90deg,
    #000 0,
    #000 calc(var(--hw) * (100% + 1.1em) - 1.1em),
    transparent calc(var(--hw) * (100% + 1.1em)));
          mask-image:linear-gradient(90deg,
    #000 0,
    #000 calc(var(--hw) * (100% + 1.1em) - 1.1em),
    transparent calc(var(--hw) * (100% + 1.1em)));
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
}

/* armed by script, one frame before it is asked to write */
.eyebrow--hand.hw-arm{ --hw:0; }

.eyebrow--hand.hw-arm.is-written{
  --hw:1;
  transition:--hw calc(var(--hw-dur,1.7s) * var(--hw-speed,.62)) cubic-bezier(.5,0,.25,1);
}

@media (prefers-reduced-motion:reduce){
.eyebrow--hand.hw-arm{ --hw:1; }
.eyebrow--hand.hw-arm.is-written{ transition:none; }
}

/* ══════════════════════════════════════════════════════════════
   INNER PAGES
   Everything above this line is the site chrome, lifted unchanged from
   the home page so the bar, the overlay menu and the footer are the
   same component everywhere. Everything below is the inner-page system
   described in DESIGN-SYSTEM.md.

   The home page keeps its own fluid type and its own gaps by decision;
   these tokens are scoped to .page so they cannot reach it.
   ══════════════════════════════════════════════════════════════ */
.page{
  /* ── type: exact pixels at two widths, not a ramp ──────────────
     The spec names 48/58 at desktop and 32/40 at mobile. A clamp()
     between them would land on neither, so there are two sets and one
     breakpoint. Tablet keeps the desktop scale and adapts the grid,
     which is what holds the hierarchy steady across sizes. */
  --fs-h1:48px;  --lh-h1:58px;
  --fs-h2:40px;  --lh-h2:48px;
  --fs-h3:32px;  --lh-h3:40px;
  --fs-h4:26px;  --lh-h4:34px;
  --fs-h5:22px;  --lh-h5:30px;
  --fs-h6:18px;  --lh-h6:26px;
  /* 14, down from the spec's 16: the running copy read too large on a
     wide measure. The leading comes down with it so the ratio stays
     near 1.7 rather than the lines drifting apart as the type shrinks. */
  --fs-p:14px;   --lh-p:24px;
  --fs-sm:14px;  --lh-sm:22px;
  --fs-btn:16px; --lh-btn:24px;
  --fs-crumb:14px; --lh-crumb:20px;

  /* ── spacing ─────────────────────────────────────────────────── */
  --sp-nav-crumb:24px;
  --sp-crumb-head:16px;
  --sp-head-p:16px;
  --sp-p-p:12px;
  --sp-p-cta:24px;
  --sp-head-grid:32px;
  --sp-cta-grid:32px;
  --sp-card:24px;
  --sp-img-content:32px;
  --sp-content:40px;
  --sp-sec:100px;

  --container:76rem;
  --hairline:1px solid rgba(52,59,33,.16);
}
@media (max-width:47.9375rem){
  .page{
    --fs-h1:32px;  --lh-h1:40px;
    --fs-h2:28px;  --lh-h2:36px;
    --fs-h3:24px;  --lh-h3:32px;
    --fs-h4:22px;  --lh-h4:30px;
    --fs-h5:20px;  --lh-h5:28px;
    --fs-p:14px;   --lh-p:22px;
    --fs-sm:14px;  --lh-sm:20px;
    --fs-crumb:13px;
    --sp-nav-crumb:16px;
    --sp-crumb-head:12px;
    --sp-head-p:12px;
    --sp-p-cta:20px;
    --sp-head-grid:24px;
    --sp-cta-grid:24px;
    --sp-card:16px;
    --sp-img-content:24px;
    --sp-content:24px;
    --sp-sec:60px;
  }
}

/* ── the page shell ─────────────────────────────────────────────
   The bar is position:fixed, so the page owes it that much room at the
   top or the breadcrumb starts underneath it. One value, read from the
   bar's own height ramp rather than guessed. */
.page{
  --bar-h:clamp(64px,6.5vw,88px);
  padding-top:var(--bar-h);
  background:var(--ivory);
  color:var(--ink-body);
  font-family:var(--font-body); font-weight:var(--fw-body);
  font-size:var(--fs-p); line-height:var(--lh-p);
}
.wrap{
  max-width:var(--container); margin-inline:auto;
  padding-inline:var(--gut);
}
/* Every section pays half the rhythm at each edge, so any two adjacent
   sections add up to exactly --sp-sec between their content. The first
   pays only the navbar gap at the top, because the bar is not a section
   and the spec gives that boundary its own smaller value. The last pays
   the full rhythm at the foot, which is the last-section-to-footer gap. */
.page section{ padding-block:calc(var(--sp-sec) / 2); }
.page section:first-of-type{ padding-top:var(--sp-nav-crumb); }
.page section:last-of-type{ padding-bottom:var(--sp-sec); }


/* ── headings ───────────────────────────────────────────────────
   Cormorant at 300, and the one <em> inside carries the olive. The
   accent is the site's heading signature and is applied here once so
   no page has to remember it. */
.page h1,.page h2,.page h3,.page h4,.page h5,.page h6{
  font-family:var(--font-head); font-weight:var(--fw-head);
  color:var(--ink-head); text-wrap:balance;
}
.page h1{ font-size:var(--fs-h1); line-height:var(--lh-h1); }
.page h2{ font-size:var(--fs-h2); line-height:var(--lh-h2); }
.page h3{ font-size:var(--fs-h3); line-height:var(--lh-h3); }
.page h4{ font-size:var(--fs-h4); line-height:var(--lh-h4); }
.page h5{ font-size:var(--fs-h5); line-height:var(--lh-h5); }
.page h6{ font-size:var(--fs-h6); line-height:var(--lh-h6); }
.page h1 em,.page h2 em,.page h3 em,.page h4 em,.page h5 em,.page h6 em{
  font-style:italic; color:var(--olive); font-weight:var(--fw-head);
}
.page p{ font-size:var(--fs-p); line-height:var(--lh-p); color:var(--ink-body); }
.page p + p{ margin-top:var(--sp-p-p); }

/* ── breadcrumb ─────────────────────────────────────────────────
   An ordered list, because the trail IS a sequence and a screen reader
   should be able to say which step of it you are on. The last item is
   the current page and carries no link. */
/* Weight 400, not the page's inherited 200: at 14px the ExtraLight
   strokes all but disappeared on the ivory ground (the user flagged it).
   The current page sits at 80% ink, clearly readable but still a step
   quieter than the link before it. */
.crumb{
  font-size:var(--fs-crumb); line-height:var(--lh-crumb);
  font-weight:400; letter-spacing:.02em;
}
.crumb ol{ display:flex; flex-wrap:wrap; align-items:center; gap:.5rem; list-style:none; }
.crumb a{
  color:var(--pine); text-decoration:none;
  border-bottom:1px solid rgba(36,93,78,.5);
  padding-bottom:1px; transition:border-color .3s var(--ease);
}
.crumb a:hover{ border-bottom-color:var(--pine); }
.crumb li[aria-current]{ color:rgba(39,39,39,.8); }
/* The separator is generated, so the markup carries only the trail.
   Written as an escape rather than the literal character: this file is
   assembled from several sources and a single mis-read encoding
   anywhere in that chain turns a literal › into mojibake. */
.crumb li + li::before{
  content:"\203A"; margin-right:.5rem;
  color:rgba(39,39,39,.68);   /* ~4.6:1 on ivory, still lighter than the current item */
}

/* ── page header ────────────────────────────────────────────────
   Breadcrumb, H1, intro. The gaps are the spec's, named rather than
   typed, so a change to the system moves every page at once. */
.phead{ text-align:center; }
.phead .crumb{ text-align:left; }
.phead h1{ margin-top:var(--sp-crumb-head); }
.phead__intro{
  margin-top:var(--sp-head-p);
  max-width:52rem; margin-inline:auto;
}

/* ── buttons ────────────────────────────────────────────────────
   One component. Geometry, label and transition are Book Now's, which
   is what keeps the bar's button and the page's buttons reading as the
   same control. Only the ground changes per context. */
.btn{
  display:inline-flex; align-items:center; gap:.7rem;
  font-family:var(--font-body); font-weight:400;
  font-size:calc(var(--fs-micro) * 1.1); letter-spacing:.14em;
  text-transform:uppercase; white-space:nowrap; text-decoration:none;
  padding:var(--btn-pad-y) var(--btn-pad-x);
  border-radius:var(--btn-radius); border:1px solid transparent;
  cursor:pointer;
  transition:background .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease);
}
.btn i{ font-style:normal; transition:transform .4s var(--ease); }
.btn:hover i{ transform:translateX(5px); }
.btn--outline{ background:none; color:var(--pine); border-color:var(--pine); }
.btn--outline:hover{ background:var(--pine); border-color:var(--pine); color:var(--ivory); }
.btn--fill{ background:var(--pine); color:var(--ivory); border-color:var(--pine); }
.btn--fill:hover{ background:var(--pine-deep); border-color:var(--pine-deep); }

/* ── cards ──────────────────────────────────────────────────────
   Square, hairline edge, ivory ground. Three per row for a three-column
   section, two for a two-column one, one on a phone. The gap is the
   token, so the card rhythm cannot drift from the page rhythm. */
.cards{
  display:grid; gap:var(--sp-card);
  margin-top:var(--sp-head-grid);
}
.cards--3{ grid-template-columns:repeat(3,minmax(0,1fr)); }
.cards--2{ grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (max-width:63.9375rem){
  .cards--3{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:47.9375rem){
  .cards--3,.cards--2{ grid-template-columns:1fr; }
}
.card{
  border:var(--hairline); background:var(--ivory);
  padding:clamp(1.5rem,2.6vw,2.25rem);
  display:flex; flex-direction:column;
}
.card h3,.card h4,.card h5{ margin-bottom:var(--sp-head-p); }
/* Card copy takes the same ink as every other paragraph on the page
   (--ink-body via .page p). It was a paler 82% tint, which read as a
   second, lighter paragraph style beside the intro above it. */
.card p{ color:var(--ink-body); }
/* A card inside a centred header keeps its own left edge. Centring is
   the header's business and should not reach into the components it
   contains, or every card on the site inherits the alignment of
   whatever happens to wrap it. */
.phead .cards{ text-align:left; }

/* ══════════════════════════════════════════════════════════════
   BASE ELEMENT RESETS
   These came from the home page and were missed when the chrome was
   pulled across, because they are named by element and the extraction
   matched on class. Their absence is what put a native button border
   and ground around the burger and the menu's close control: with no
   reset, a <button> is drawn by the operating system.
   ══════════════════════════════════════════════════════════════ */
img{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{
  -webkit-appearance:none; appearance:none;
  background:transparent; border:0; border-radius:0;
  font:inherit; color:inherit; line-height:inherit; text-align:inherit;
  cursor:pointer;
}

/* ══════════════════════════════════════════════════════════════
   LINKS IN RUNNING COPY
   The base reset makes every <a> inherit its colour and drop its
   underline, which is right for navigation, buttons and cards — those
   announce themselves by position. It is wrong inside a sentence: a
   link in a paragraph was rendering as plain body ink with no mark on
   it at all, so nothing said it could be clicked.

   Pine against the ivory ground is 6.8:1, comfortably past AA for body
   text, and it is the same green the breadcrumb already uses, so the
   two read as one idea rather than two link styles.

   Colour is never the only signal — the rule underneath carries it for
   anyone who cannot separate the two hues. It sits at 30% so the line
   reads as a mark under the words rather than a strikethrough through
   their descenders, and comes to full strength on hover.
   ══════════════════════════════════════════════════════════════ */
/* Scoped to running copy only. A blanket `.page li a` would have caught
   the breadcrumb, which styles itself, and `:not(.btn)` keeps it off
   the buttons — the closing Book button sits inside a <p>, and giving
   it a border-bottom here would have fought the border the button
   already draws. */
.page p a:not(.btn),
.page dd a:not(.btn),
.page .incl li a:not(.btn),
.page .fineprint li a:not(.btn){
  color:var(--pine);
  border-bottom:1px solid rgba(36,93,78,.3);
  padding-bottom:.08em;
  transition:color .3s var(--ease), border-color .3s var(--ease);
}
.page p a:not(.btn):hover,
.page dd a:not(.btn):hover,
.page .incl li a:not(.btn):hover,
.page .fineprint li a:not(.btn):hover{
  color:var(--pine-deep);
  border-bottom-color:var(--pine-deep);
}

/* ── keyboard focus ─────────────────────────────────────────────
   One visible ring for everything that takes focus. Without this the
   reset's outline:none inheritance leaves a keyboard user with no idea
   where they are. offset keeps it clear of the glyphs. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--pine);
  outline-offset:3px;
}

/* ══════════════════════════════════════════════════════════════
   SPLIT ROW — a picture beside its writing, sides alternating
   Used by the dining summary, where each outlet gets a row and the
   picture changes side down the page so the eye zig-zags instead of
   running down one rail.

   The alternation is done with `order` on the media, not by reversing
   the grid direction: reversing a grid also reverses the DOM order a
   screen reader and the keyboard follow, so the heading would be read
   after its own photograph on every second row.
   ══════════════════════════════════════════════════════════════ */
.split{
  display:grid; align-items:center;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1.75rem,5vw,4rem);
}
.split + .split{
  margin-top:var(--sp-block,50px);
  padding-top:var(--sp-block,50px);
  border-top:var(--hairline);
}
.split__media{ margin:0; }
.split__media img{
  width:100%; height:100%; object-fit:cover; display:block;
  aspect-ratio:4/3;
}
/* every even row puts its picture on the right */
.split:nth-of-type(even) .split__media{ order:2; }
.split__body h2{ margin-bottom:var(--sp-head-p); }
.split__body .btn{ margin-top:var(--sp-p-cta); }

/* One column on a tablet and below. The order reset matters: without
   it the even rows would stack text-then-picture while the odd ones
   stack picture-then-text, and the page would read inconsistently. */
@media (max-width:63.9375rem){
  .split{ grid-template-columns:1fr; gap:var(--sp-img-content); }
  .split:nth-of-type(even) .split__media{ order:0; }
}

/* ══════════════════════════════════════════════════════════════
   GALLERY — filter tabs over a masonry grid
   The grid is CSS columns, not a JS masonry library. Columns give the
   staggered look for free, reflow by themselves when the filter hides
   half the pictures, and cost nothing to maintain. The trade is
   reading order: columns fill top-to-bottom, so picture two sits below
   picture one rather than beside it. For a gallery, where no photograph
   depends on the one before it, that is not a cost worth paying script
   to avoid.
   ══════════════════════════════════════════════════════════════ */
.galfilter{
  margin-top:var(--sp-block,50px);
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:.5rem clamp(1rem,3vw,2.25rem);
}
/* .7rem of block padding takes the 22px line to a 44px target */
.galfilter button{
  padding-block:.7rem;
  font-family:var(--font-body); font-weight:var(--fw-label);
  font-size:var(--fs-sm); line-height:var(--lh-sm);
  letter-spacing:.12em; text-transform:uppercase;
  color:rgba(39,39,39,.6);
  border-bottom:1px solid transparent;
  transition:color .3s var(--ease), border-color .3s var(--ease);
}
.galfilter button:hover{ color:var(--ink-body); }
/* aria-pressed is the state, and the styling hangs off it, so what is
   shown and what a screen reader announces cannot drift apart */
.galfilter button[aria-pressed="true"]{
  color:var(--pine); border-bottom-color:var(--pine);
}

.gallery{
  margin-top:var(--sp-block,50px);
  columns:3; column-gap:var(--sp-card);
}
.gallery figure{
  break-inside:avoid; margin:0 0 var(--sp-card);
  overflow:hidden; background:var(--cream);
}
.gallery img{
  width:100%; height:auto; display:block;
  transition:transform 1.2s var(--ease);
}
.gallery figure:hover img{ transform:scale(1.04); }
/* the count under the grid, so a filtered view says how much it holds */
.galcount{
  margin-top:var(--sp-p-p);
  text-align:center; font-size:var(--fs-sm); line-height:var(--lh-sm);
  color:rgba(39,39,39,.6);
}
@media (max-width:63.9375rem){ .gallery{ columns:2; } }
@media (max-width:47.9375rem){ .gallery{ columns:1; } }

/* ══════════════════════════════════════════════════════════════
   FAQ — questions grouped, answers open
   A description list, because that is what a question and its answer
   are: <dt> the term, <dd> the description. Not an accordion. With
   around thirty answers that are each a sentence or two, hiding them
   behind a click costs a reader more than it saves — and an open page
   can be searched with the browser's own find.
   ══════════════════════════════════════════════════════════════ */
.faqjump{
  margin-top:var(--sp-block,50px);
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:.5rem clamp(1rem,2.5vw,2rem);
}
/* .7rem of block padding takes the 22px line to a 44px target */
.faqjump a{
  padding-block:.7rem;
  font-size:var(--fs-sm); line-height:var(--lh-sm);
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--pine);
  border-bottom:1px solid rgba(36,93,78,.3);
  transition:border-color .3s var(--ease);
}
.faqjump a:hover{ border-bottom-color:var(--pine); }

.faqset{ margin-top:var(--sp-block,50px); }
/* scroll-margin so a jump link does not park the heading under the
   fixed bar — the bar is 88px at its tallest, plus a little air */
.faqset h2{
  scroll-margin-top:calc(clamp(64px,6.5vw,88px) + 1.5rem);
  padding-bottom:var(--sp-head-p);
  border-bottom:var(--hairline);
}
.faqset dl{ margin-top:var(--sp-head-p); }
.faqset dt{
  font-family:var(--font-head); font-weight:var(--fw-head);
  font-size:var(--fs-h6); line-height:var(--lh-h6);
  color:var(--ink-head);
}
.faqset dd{
  margin:.35rem 0 0;
  font-size:var(--fs-p); line-height:var(--lh-p);
  color:var(--ink-body);
  max-width:60rem;
}
.faqset dd + dt{ margin-top:clamp(1.1rem,2.2vw,1.6rem); }

/* ── still stuck ────────────────────────────────────────────────
   The way out of the page, for the question nobody wrote down. */
.faqhelp{
  margin-top:var(--sp-block,50px);
  padding:clamp(1.5rem,3vw,2.25rem);
  background:var(--cream); text-align:center;
}
.page .faqhelp h2{ font-size:var(--fs-h5); line-height:var(--lh-h5); }
.faqhelp p{ margin-top:var(--sp-head-p); }
.faqhelp .acts{ margin-top:var(--sp-p-cta); }

/* ── you are here ───────────────────────────────────────────────
   The menu item for the current page. Marked with aria-current in the
   markup, so the styling hangs off the same attribute a screen reader
   announces rather than a second class that could fall out of step. */
/* Forest, not ivory: the menu panel IS ivory, so an ivory item vanished
   and left a blank row where the current page should be. */
#menuNav a[aria-current="page"]{ color:var(--forest); }
#menuNav a[aria-current="page"]::after{
  content:""; display:block; height:1px; margin-top:.25em;
  background:currentColor; opacity:.5;
}

/* ══════════════════════════════════════════════════════════════
   ROOMS
   The summary page (rooms.html) and the two room pages. Shared here
   rather than in a page <style> because both room pages carry the same
   switcher, gallery, amenity grid and pager, and two copies of one
   component is how they drift.
   ══════════════════════════════════════════════════════════════ */

/* Without this, any component that sets its own display (the gallery's
   arrows are grid, its thumb strip is grid) overrides the hidden
   attribute and paints controls that have no script behind them yet. */
[hidden]{ display:none !important; }

/* Links inside the page intro. Scoped to the intro on purpose: a rule
   on every "p a" would also reach a button sitting inside a paragraph
   and repaint it as a text link. */
.page .phead__intro a{
  color:var(--pine);
  border-bottom:1px solid rgba(36,93,78,.35);
  transition:border-color .3s var(--ease);
}
.page .phead__intro a:hover{ border-bottom-color:var(--pine); }

.center{ text-align:center; }

/* ── room switcher ──────────────────────────────────────────────
   The strip under the bar on a room page: every room, one line, the
   current one marked by the same attribute a screen reader announces. */
.roomnav{ border-bottom:var(--hairline); }
.roomnav ul{
  list-style:none; display:flex; flex-wrap:wrap; justify-content:center;
  column-gap:clamp(1.5rem,4vw,3rem);
  max-width:var(--container); margin-inline:auto; padding-inline:var(--gut);
}
/* .8rem of block padding takes the 22px line to a 48px target */
.roomnav a{
  display:block; padding-block:.8rem; margin-bottom:-1px;
  font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label);
  color:rgba(39,39,39,.72);
  border-bottom:1px solid transparent;
  transition:color .3s var(--ease), border-color .3s var(--ease);
}
.roomnav a:hover{ color:var(--ink-body); border-bottom-color:rgba(36,93,78,.35); }
.roomnav a[aria-current="page"]{ color:var(--pine); border-bottom-color:var(--pine); }

/* ── room header additions ──────────────────────────────────────
   .page p sets the paragraph size at (0,1,1), so the lead has to be
   named at (0,2,0) or it silently renders as body copy. */
.page .room-lead{
  margin-top:var(--sp-head-p);
  font-family:var(--font-head); font-weight:var(--fw-head);
  font-size:var(--fs-h5); line-height:var(--lh-h5);
  color:var(--ink-head);
}
.page .room-lead + .phead__intro{ margin-top:var(--sp-head-p); }
.room-book{ margin-top:var(--sp-p-cta); }

/* ── spec list: the room's facts as icon + label ────────────────
   A list because it is one: size, beds, occupancy. Centred under the
   header on a room page, flush left inside a card. */
.specs{
  list-style:none; display:flex; flex-wrap:wrap; justify-content:center;
  gap:.75rem clamp(1.25rem,3vw,2.25rem);
  margin-top:var(--sp-p-cta);
}
.specs li{
  display:inline-flex; align-items:center; gap:.55rem;
  font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label);
  color:var(--ink-body);
}
.specs svg,.amen svg{
  flex:none; fill:none; stroke:var(--olive); stroke-width:1.3;
  stroke-linecap:round; stroke-linejoin:round;
}
.specs svg{ width:24px; height:24px; }
.specs--card{ justify-content:flex-start; gap:.5rem 1.25rem; margin:0 0 var(--sp-p-p); }
.specs--card svg{ width:20px; height:20px; }

/* ── card with a photograph ─────────────────────────────────────
   The one card, with its padding moved off the frame and onto the body
   so the picture runs to the hairline. One ratio for the whole grid,
   so every card's text starts on the same line. */
.card--media{ padding:0; }
.card__media{ display:block; aspect-ratio:4/3; overflow:hidden; background:var(--cream); }
.card__media img{ width:100%; height:100%; object-fit:cover; transition:transform 1.2s var(--ease); }
.card--media:hover .card__media img{ transform:scale(1.04); }
.card__body{ flex:1; display:flex; flex-direction:column; padding:clamp(1.5rem,2.6vw,2.25rem); }
.page .card__title{ font-size:var(--fs-h4); line-height:var(--lh-h4); margin-bottom:var(--sp-head-p); }
.card__cta{ margin-top:auto; padding-top:var(--sp-p-cta); }

/* ── room gallery ───────────────────────────────────────────────
   One stage and a strip of thumbnails. Not a carousel: every thumbnail
   fits, so nothing scrolls, and the stage swaps its picture in place.
   The arrows, the counter and the strip ship hidden and the script
   reveals them, so with no script the page shows one honest photograph
   rather than controls that do nothing.
   2:1, not 16:9: at 16:9 the stage filled almost the whole laptop
   viewport under the bar, and the thumbnails fell below the fold. */
/* The pictures are the room the header just described, not a new part
   of the page, so the gap above them is the header's half-rhythm alone:
   50px, 30 on a phone. A full 100 left the Book Now button stranded. */
.page .room-gal{ padding-top:0; }
.gal__stage{ position:relative; aspect-ratio:2/1; overflow:hidden; background:var(--cream); }
/* Stage and thumbnails fit in one screen under the bar. The stage is
   2:1 while the window is tall enough for that, and gives up height on
   a shorter one, never below 320px, so the whole gallery is in view at
   once. cqi resolves against .gal, the gallery's own width; the thumb
   height is the strip's real one: six across, five .5rem gaps, 3:2.
   The 2rem is breathing room so the strip does not sit on the edge. */
@supports (height:1cqi) and (height:1svh){
  @media (min-width:48rem){
    .gal{ container-type:inline-size; }
    .gal__stage{
      --thumb-h:calc((100cqi - 2.5rem) / 6 * 2 / 3);
      aspect-ratio:auto;
      height:min(50cqi, max(320px, calc(100svh - var(--bar-h) - var(--thumb-h) - .5rem - 2rem)));
    }
  }
}
.gal__img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transition:opacity .35s var(--ease);
}
.gal.is-swapping .gal__img{ opacity:.4; }
.gal__arrow{
  position:absolute; top:50%; transform:translateY(-50%);
  width:48px; height:48px; display:grid; place-items:center;
  background:rgba(245,241,231,.9); color:var(--forest);
  border:1px solid rgba(52,59,33,.16);
  transition:background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.gal__arrow--prev{ left:clamp(.75rem,2vw,1.5rem); }
.gal__arrow--next{ right:clamp(.75rem,2vw,1.5rem); }
.gal__arrow:hover{ background:var(--pine); border-color:var(--pine); color:var(--ivory); }
.gal__arrow svg{
  width:18px; height:18px; fill:none; stroke:currentColor;
  stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
/* The ring lands on a photograph, which can be any colour at all, so
   it carries an ivory halo and reads on dark and light ground alike. */
.gal__arrow:focus-visible,.gal__thumb:focus-visible{
  outline:2px solid var(--pine); outline-offset:2px;
  box-shadow:0 0 0 6px var(--ivory);
}
.page .gal__count{
  position:absolute; right:0; bottom:0; margin:0;
  padding:.35rem .8rem;
  background:rgba(37,39,31,.78); color:var(--ivory);
  font-size:var(--fs-sm); line-height:var(--lh-sm); letter-spacing:.08em;
}
.gal__count b{ font-weight:500; }
.gal__thumbs{
  list-style:none; display:grid; grid-template-columns:repeat(6,minmax(0,1fr));
  gap:.5rem; margin-top:.5rem;
}
.gal__thumb{
  position:relative; display:block; width:100%; aspect-ratio:3/2; overflow:hidden;
  opacity:.55; transition:opacity .3s var(--ease);
}
.gal__thumb img{ width:100%; height:100%; object-fit:cover; }
.gal__thumb:hover{ opacity:.85; }
.gal__thumb[aria-current="true"]{ opacity:1; }
.gal__thumb[aria-current="true"]::after{
  content:""; position:absolute; inset:auto 0 0 0; height:3px; background:var(--pine);
}
@media (prefers-reduced-motion:reduce){
  .gal__img,.gal__thumb{ transition:none; }
}
@media (max-width:47.9375rem){
  .gal__stage{ aspect-ratio:16/10; }
  .gal__thumbs{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .gal__arrow{ width:44px; height:44px; }
}

/* ── amenity grid ───────────────────────────────────────────────
   Tiles on hairlines: the grid's 1px gap shows the rule colour through.
   Twenty items, so five, four and two across all come out even and no
   row is left with a grey hole in it. */
.amen{
  list-style:none; margin-top:var(--sp-head-grid);
  display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:1px;
  background:rgba(52,59,33,.14); border:1px solid rgba(52,59,33,.14);
}
.amen li{
  background:var(--ivory);
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:.5rem; padding:clamp(1.25rem,2.2vw,1.75rem) .75rem;
}
.amen svg{ width:30px; height:30px; margin-bottom:.25rem; }
.amen__name{ font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label); color:var(--ink-body); }
/* .68 of the ink still clears 4.5:1 on ivory; the reference's paler
   grey for this line did not */
.amen__note{ margin-top:-.4rem; font-size:var(--fs-sm); line-height:var(--lh-sm); color:rgba(39,39,39,.68); }
@media (max-width:63.9375rem){ .amen{ grid-template-columns:repeat(4,minmax(0,1fr)); } }
@media (max-width:47.9375rem){ .amen{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* ── room pager ─────────────────────────────────────────────────
   The next or previous room. With two rooms each page has only one
   neighbour, so a single link sits on its own side. */
.pager{ display:flex; justify-content:space-between; gap:var(--sp-card); }
/* The pager closes the amenity grid rather than opening a new part of
   the page, so its section pays no top half of the rhythm: 50px under
   the grid instead of 100 (30 instead of 60 on a phone). */
.page section.pager-sec{ padding-top:0; }
.pager__link{ display:flex; flex-direction:column; gap:.35rem; }
.pager__link--next{ margin-left:auto; align-items:flex-end; text-align:right; }
.pager__dir{
  font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label);
  letter-spacing:.14em; text-transform:uppercase; color:var(--pine);
}
.pager__dir i{ font-style:normal; display:inline-block; transition:transform .4s var(--ease); }
.pager__name{
  font-family:var(--font-head); font-weight:var(--fw-head);
  font-size:var(--fs-h4); line-height:var(--lh-h4); color:var(--ink-head);
  transition:color .3s var(--ease);
}
.pager__link:hover .pager__name{ color:var(--olive); }
.pager__link--next:hover .pager__dir i{ transform:translateX(5px); }
.pager__link--prev:hover .pager__dir i{ transform:translateX(-5px); }

/* ══════════════════════════════════════════════════════════════
   COLLAGE — seven photographs, two of them tall
   Moved here from about.html once the spa page needed the same grid.
   A page sets --sp-block for the gap above it; without one it takes
   the spec's content-to-content value.

   Named areas, not spans with auto-placement. Auto-placement decides
   where a tile lands by scanning for the first hole that fits, so a
   tall tile two columns over silently reshuffles the rest and leaves
   a gap somewhere else. Naming every cell makes the arrangement a
   fact rather than an outcome. Tiles a and d are the tall ones and
   should take PORTRAIT files.
   ══════════════════════════════════════════════════════════════ */
.collage{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  grid-template-areas:
    "a b c"
    "a d e"
    "f d g";
  grid-auto-rows:clamp(130px,15.5vw,215px);
  gap:var(--sp-card);
  margin-top:var(--sp-block, var(--sp-content));
}
.collage figure{ position:relative; overflow:hidden; margin:0; }
.collage img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform 1.2s var(--ease);
}
.collage figure:hover img{ transform:scale(1.04); }
.collage .t-a{ grid-area:a; } .collage .t-b{ grid-area:b; }
.collage .t-c{ grid-area:c; } .collage .t-d{ grid-area:d; }
.collage .t-e{ grid-area:e; } .collage .t-f{ grid-area:f; }
.collage .t-g{ grid-area:g; }

/* Two columns on a tablet. The arrangement is re-named rather than
   left to reflow, for the same reason it was named in the first place. */
@media (max-width:63.9375rem){
  .collage{
    grid-template-columns:repeat(2,minmax(0,1fr));
    grid-template-areas:
      "a b"
      "a c"
      "d e"
      "d f"
      "g g";
  }
}
/* One column on a phone, every tile the same height, nothing tall. */
@media (max-width:47.9375rem){
  .collage{
    grid-template-columns:1fr;
    grid-template-areas:"a" "b" "c" "d" "e" "f" "g";
    grid-auto-rows:clamp(200px,52vw,280px);
  }
}

/* ══════════════════════════════════════════════════════════════
   OFFER DETAIL (offer.html)
   After the client's reference: switcher, breadcrumb, centred name and
   intro, ONE photograph, a second paragraph, the terms as a three-row
   table, Book Now, then the previous and next offer. Here rather than in
   the page because offer.html is a template meant to be copied once per
   offer, and copies of a page <style> drift.
   ══════════════════════════════════════════════════════════════ */
.offer__media{
  max-width:56rem; margin:var(--sp-content) auto 0;
  aspect-ratio:16/9; overflow:hidden; background:var(--cream);
}
.offer__media img{ width:100%; height:100%; object-fit:cover; }
.page .offer__body{
  max-width:52rem; margin:var(--sp-content) auto 0; text-align:center;
}

/* ── the terms ──────────────────────────────────────────────────
   A definition list, because each row IS a term and its value. Label
   in tracked caps on the left, value on the right, a hairline under
   every row. .68 of the ink keeps the small caps above 4.5:1. */
.terms{
  max-width:29rem; margin:var(--sp-content) auto 0;
  border-top:var(--hairline);
}
.terms div{
  display:flex; justify-content:space-between; align-items:baseline;
  gap:var(--sp-card); padding-block:.85rem;
  border-bottom:var(--hairline);
}
.terms dt{
  font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label);
  letter-spacing:.14em; text-transform:uppercase; color:rgba(39,39,39,.68);
}
.terms dd{
  font-size:var(--fs-p); line-height:var(--lh-p); color:var(--ink-body);
  text-align:right;
}
.offer__book{ margin-top:var(--sp-content); text-align:center; }

/* ══════════════════════════════════════════════════════════════
   FACILITIES (facilities.html)
   After the client's reference: one card per facility, picture above,
   name below, an optional note line (Complimentary, Chargeable, hours).
   Three across, two on a tablet, one on a phone. A facility the library
   has no photograph of gets a sage panel with the site's own seedling
   mark rather than a stock picture, per the content rules.
   ══════════════════════════════════════════════════════════════ */
.fac{
  list-style:none; margin-top:var(--sp-head-grid);
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--sp-card);
}
.fac > li{ border:var(--hairline); background:var(--ivory); display:flex; flex-direction:column; }
.fac__media{ position:relative; aspect-ratio:3/2; overflow:hidden; background:var(--sage); }
.fac__media img{ width:100%; height:100%; object-fit:cover; transition:transform 1.2s var(--ease); }
.fac > li:hover .fac__media img{ transform:scale(1.04); }
/* The mark is a mask, so it takes --olive like every other botanical
   on the site instead of the file's own fill. */
.fac__media--blank::before{
  content:""; position:absolute; inset:0; margin:auto;
  width:30%; aspect-ratio:149/131;
  background:var(--olive); opacity:.38;
  -webkit-mask:url("r1c5-seedling.svg") center/contain no-repeat;
          mask:url("r1c5-seedling.svg") center/contain no-repeat;
}
.fac__body{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.2rem; padding:clamp(1rem,2vw,1.4rem) 1rem; text-align:center;
}
.page .fac__name{ font-size:var(--fs-h5); line-height:var(--lh-h5); }
/* .68 of the ink keeps tracked small caps above 4.5:1 on ivory */
.page .fac__note{
  font-size:var(--fs-sm); line-height:var(--lh-sm); font-weight:var(--fw-label);
  letter-spacing:.14em; text-transform:uppercase; color:rgba(39,39,39,.68);
}
.fac-cta{ margin-top:var(--sp-content); text-align:center; }
@media (max-width:63.9375rem){ .fac{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:47.9375rem){ .fac{ grid-template-columns:1fr; } }
