/* ==========================================================================
   RPEES MILLENNIUM STAY INN — DESIGN SYSTEM
   Load order: variables.css → style.css → responsive.css → animations.css
   This file contains NO page or section styles. Sections live with their page.
   ========================================================================== */

/* --------------------------------------------------------------------------
   01. RESET & BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;            /* Lenis owns scrolling. Never smooth here. */
}

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  font-weight: var(--fw-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }     /* mobile menu open */

img, picture, video, canvas, svg { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4, h5, h6, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; }

a { color: inherit; text-decoration: none; }

button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

::selection { background: var(--c-primary); color: var(--c-ivory); }
.u-mt-9 {
    margin-top: 40px;
}
/* Focus is always visible. Never remove this. */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius);
}
.on-dark :focus-visible,
.u-dark  :focus-visible { box-shadow: var(--focus-ring-dark); }

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

.skip-link {
  position: absolute; top: -100%; left: var(--gutter); z-index: var(--z-loader);
  background: var(--c-primary); color: var(--c-ivory);
  padding: var(--s-3) var(--s-5); font-family: var(--font-util);
  font-size: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase;
}
.skip-link:focus { top: var(--s-4); }


/* --------------------------------------------------------------------------
   02. LAYOUT
   -------------------------------------------------------------------------- */
.container       { width: 100%; max-width: var(--container);        margin-inline: auto; padding-inline: var(--gutter); }
.container--wide { max-width: var(--container-wide); }
.container--narrow { max-width: calc(var(--container-narrow) + var(--gutter) * 2); }
.container--flush { padding-inline: 0; }

.section        { padding-block: var(--section-y); position: relative; }
.section--wide  { padding-block: var(--section-y-wide); }
.section--flush { padding-block: 0; }
.section--full  { min-height: 100svh; display: flex; align-items: center; }

/* Surfaces. A section declares its surface; text colours follow automatically. */
.surface-light   { background: var(--bg-page);    color: var(--ink); }
.surface-raised  { background: var(--bg-raised);  color: var(--ink); }
.surface-mist    { background: var(--bg-mist);    color: var(--ink); }
.surface-forest  { background: var(--bg-dark);    color: var(--ink-on-dark); }
.surface-deep    { background: var(--bg-darkest); color: var(--ink-on-dark); }
.surface-brown   { background: var(--c-primary);  color: var(--ink-on-dark); }

.surface-forest, .surface-deep, .surface-brown { --line: var(--line-on-dark); --line-soft: var(--line-on-dark-soft); }

/* 12-column grid, used sparingly — most layouts are two asymmetric columns. */
.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--s-6); }

/* The asymmetric editorial pair the brief asks for instead of Bootstrap cards. */
.pair            { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 5vw, 88px); align-items: center; }
.pair--offset > :nth-child(2) { margin-top: clamp(32px, 8vw, 120px); }
.pair--weighted  { grid-template-columns: 6fr 6fr; }
.pair--weighted-r{ grid-template-columns: 7fr 5fr; }

.stack > * + * { margin-top: var(--s-5); }
.stack-lg > * + * { margin-top: var(--s-7); }


/* --------------------------------------------------------------------------
   03. TYPOGRAPHY
   -------------------------------------------------------------------------- */
.display-xl, .display-l, .display-m, .display-s {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 72px;
  text-wrap: balance;
}
.display-xl { font-size: var(--t-display-xl); }
.display-l  { font-size: var(--t-display-l); }
.display-m  { font-size: var(--t-display-m); line-height: var(--lh-heading); }
.display-s  { font-size: var(--t-display-s); line-height: var(--lh-heading); letter-spacing: 0; }

/* A statement runs two or three lines and breaks where the meaning breaks.
   Author the break with <br>, don't leave it to the viewport. */
.statement { max-width: 25ch; }
.statement--wide { max-width: 26ch; }

.lede {
  font-size: var(--t-lede);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  max-width: 62ch;
}
.surface-forest .lede, .surface-deep .lede, .surface-brown .lede { color: var(--ink-on-dark-mute); }

.prose { max-width: 68ch; }
.prose p + p { margin-top: var(--s-5); }

.text-small { font-size: var(--t-small); }
.text-muted { color: var(--ink-muted); }
.surface-forest .text-muted, .surface-deep .text-muted { color: var(--ink-on-dark-mute); }

/* Utility face: labels, numbering, data. Never used for reading text. */
.label {
  font-family: var(--font-util);
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}
.surface-forest .label, .surface-deep .label, .surface-brown .label { color: var(--c-sand); }


/* --------------------------------------------------------------------------
   04. SECTION LABEL — the signature device
   A hairline running the full container width, broken by a numbered label
   and marked with a single tick. It reads like a contour line on a survey
   sheet, which is the one visual idea the whole site is built on.
   -------------------------------------------------------------------------- */
.section-label {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: clamp(28px, 4vw, 56px);
}
.section-label__n {
  font-family: var(--font-util);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  color: var(--c-bronze);
  flex: 0 0 auto;
}
.section-label__t {
  font-family: var(--font-util);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  flex: 0 0 auto;
}
.surface-forest .section-label__t,
.surface-deep   .section-label__t,
.surface-brown  .section-label__t { color: var(--c-sand); }

.section-label__rule {
  flex: 1 1 auto;
  height: 1px;
  background: var(--c-bronze-soft);
  position: relative;
}
/* the tick */
.section-label__rule::before {
  content: "";
  position: absolute;
  left: 0; top: -3px;
  width: 1px; height: 7px;
  background: var(--c-bronze);
}
.section-label--center { justify-content: center; }
.section-label--center .section-label__rule { display: none; }


/* --------------------------------------------------------------------------
   05. DIVIDER
   -------------------------------------------------------------------------- */
.divider { height: 1px; background: var(--c-bronze-soft); border: 0; margin: 0; }
.divider--short { width: 64px; }
.divider--dot { position: relative; }
.divider--dot::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--c-bronze); transform: translate(-50%, -50%);
}


/* --------------------------------------------------------------------------
   06. BUTTONS
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg:     var(--c-primary);
  --btn-fg:     var(--c-ivory);
  --btn-bd:     var(--c-primary);
  --btn-bg-h:   var(--c-primary-deep);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: var(--btn-h);
  padding-inline: var(--btn-px);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--border-hair) solid var(--btn-bd);
  border-radius: var(--radius);
  font-family: var(--font-util);
  font-size: var(--t-label);
  letter-spacing: var(--ls-button);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--d-base) var(--e-out),
              color var(--d-base) var(--e-out),
              border-color var(--d-base) var(--e-out),
              transform var(--d-fast) var(--e-out);
}
.btn:hover  { background: var(--btn-bg-h); border-color: var(--btn-bg-h); }
.btn:active { transform: translateY(1px); }

.btn--sm { min-height: var(--btn-h-sm); padding-inline: var(--s-5); }
.btn--block { display: flex; width: 100%; }

/* Ghost — the secondary action everywhere on the site. */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--c-primary);
  --btn-bd: var(--c-primary-soft);
  --btn-bg-h: var(--c-primary);
}
.btn--ghost:hover { color: var(--c-ivory); }

/* On dark surfaces, both variants invert. */
.surface-forest .btn, .surface-deep .btn, .on-dark .btn {
  --btn-bg: var(--c-ivory); --btn-fg: var(--c-primary);
  --btn-bd: var(--c-ivory); --btn-bg-h: var(--c-white);
}
.surface-forest .btn--ghost, .surface-deep .btn--ghost, .on-dark .btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--c-ivory);
  --btn-bd: var(--line-on-dark); --btn-bg-h: var(--c-ivory);
}
.surface-forest .btn--ghost:hover, .surface-deep .btn--ghost:hover, .on-dark .btn--ghost:hover {
  color: var(--c-primary);
}

/* Accent — used once per page at most, for the live booking action. */
.btn--accent { --btn-bg: var(--c-accent); --btn-bd: var(--c-accent); --btn-fg: var(--c-forest-deep); --btn-bg-h: #338AB8; }

/* Text link with a rule that draws in from the left. */
.link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-button); text-transform: uppercase;
  padding-bottom: 6px; position: relative;
}
.link::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: currentColor; opacity: .3;
  transform: scaleX(1); transform-origin: right; transition: transform var(--d-base) var(--e-soft), opacity var(--d-base);
}
.link:hover::after { opacity: 1; transform-origin: left; }
.link__arrow { transition: transform var(--d-base) var(--e-soft); }
.link:hover .link__arrow { transform: translateX(5px); }


/* --------------------------------------------------------------------------
   07. IMAGE FRAME
   Every image on the site goes through this. It owns the aspect ratio, the
   clip-reveal hook, and the hover scale, so no section reinvents them.
   -------------------------------------------------------------------------- */
.frame {
  position: relative;
  overflow: hidden;

  border-radius: var(--radius);
}
.frame picture { display: block; width: 100%; height: 100%; }
.frame img { width: 100%; height: 100%; object-fit: cover; border-radius: 20px!important;}

.frame--portrait  { aspect-ratio: 3 / 4; }
.frame--square    { aspect-ratio: 1 / 1; }
.frame--landscape { aspect-ratio: 3 / 2; }
.frame--wide      { aspect-ratio: 16 / 9; }
.frame--cinema    { aspect-ratio: 21 / 9; }
.frame--tall      { aspect-ratio: 2 / 3; }
.frame--fill      { height: 100%; }

/* Hover zoom — applied on the link, not the image, so focus works too. */
.frame--zoom img { transition: transform 1.4s var(--e-soft); border-radius: 20px; }
a:hover .frame--zoom img,
a:focus-visible .frame--zoom img,
.frame--zoom:hover img { transform: scale(1.045); border-radius: 20px;}

/* Atmospheric treatments, from the brief. Reused, never re-authored. */
.frame--scrim::after   { content: ""; position: absolute; inset: 0; background: var(--scrim-bottom); pointer-events: none; }
.frame--scrim-full::after { content: ""; position: absolute; inset: 0; background: var(--scrim-full); pointer-events: none; }
.frame--vignette::before { content: ""; position: absolute; inset: 0; background: var(--vignette); pointer-events: none; z-index: 2; }

/* Film grain. One 140-byte inline SVG, no image request. */
.grain::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 3;
  opacity: .16; mix-blend-mode: overlay;
  /* background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); */
}

/* Caption sitting on a full-bleed image. */
.frame__caption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
  padding: clamp(20px, 4vw, 48px);
  color: var(--c-ivory);
}


/* --------------------------------------------------------------------------
   08. CARD
   Minimal by design. The room card is the only card with a defined shape.
   -------------------------------------------------------------------------- */
.card { display: block; position: relative; }
.card__body { padding-top: var(--s-5); }
.card__meta { margin-top: var(--s-3); display: flex; gap: var(--s-4); flex-wrap: wrap; }

.card-room .card__title { margin-top: var(--s-4); }
.card-room .card__foot  { margin-top: var(--s-4); display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }

/* Detail overlay that fades up over the image on hover / focus. */
.card__overlay {
  position: absolute; inset: auto 0 0 0; z-index: 4;
  padding: clamp(18px, 3vw, 32px);
  color: var(--c-ivory);
  background: var(--scrim-bottom);
  opacity: 0; transform: translateY(10px);
  transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-out);
}
.card:hover .card__overlay,
.card:focus-within .card__overlay { opacity: 1; transform: none; }

/* Badge — facts only, never a rating or a price we haven't been given. */
.badge {
  display: inline-block; padding: 5px 10px;
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--ink-muted);
}
.surface-forest .badge, .surface-deep .badge { border-color: var(--line-on-dark); color: var(--c-sand); }


/* --------------------------------------------------------------------------
   09. NAVIGATION
   Two independent axes:
     data-nav-tone  = ivory | ink   → set by the hero's frame luminance
     data-nav-state = float | solid → set by scroll position
   navigation.js writes both. CSS never guesses.
   -------------------------------------------------------------------------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-nav);
  height: var(--nav-h);
  display: flex; align-items: center;
  transition: background var(--d-base) var(--e-out),
              height var(--d-base) var(--e-out),
              box-shadow var(--d-base) var(--e-out);
}
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--s-6); width: 100%; }

.nav__logo { display: flex; align-items: center; flex: 0 0 auto; }
.nav__logo img {
    height: clamp(34px, 3.4vw, 46px);
    width: auto;
    transition: opacity var(--d-base);
    width: 150px;
    height: auto;
    margin-top: 5px;
}
.nav__logo .logo--ivory, .nav__logo .logo--ink { transition: opacity var(--d-base) var(--e-out); }

.nav__menu { display: flex; align-items: center; gap: clamp(20px, 2.2vw, 40px); }
.nav__link {
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  position: relative; padding-block: 6px;
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: currentColor; transform: scaleX(0); transform-origin: right;
  transition: transform var(--d-base) var(--e-soft);
}
.nav__link:hover::after, .nav__link[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }

.nav__actions { display: flex; align-items: center; gap: var(--s-4); flex: 0 0 auto; }

/* --- tone: over a dark frame --- */
.nav[data-nav-tone="ivory"] { color: var(--c-ivory); }
.nav[data-nav-tone="ivory"] .logo--ink   { display: none; }
/* --- tone: over the white mist frames, or any light page --- */
.nav[data-nav-tone="ink"]   { color: var(--c-primary); }
.nav[data-nav-tone="ink"]   .logo--ivory { display: none; }

/* --- state: floating over the hero --- */
.nav[data-nav-state="float"] { background: transparent; }
.nav[data-nav-state="float"][data-nav-tone="ivory"] { text-shadow: 0 1px 14px rgba(4,22,8,.45); }

/* --- state: past the hero --- */
.nav[data-nav-state="solid"] {
  height: 80px;
  background: rgba(0, 46, 7, .90);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  backdrop-filter: saturate(150%) blur(14px);
  color: var(--c-ivory);
  box-shadow: 0 1px 0 var(--line-on-dark-soft);
}
.nav[data-nav-state="solid"] .logo--ink { display: none; }
.nav[data-nav-state="solid"] .logo--ivory { display: block; }
.nav[data-nav-state="solid"] .btn { --btn-bg: var(--c-ivory); --btn-fg: var(--c-primary); --btn-bd: var(--c-ivory); --btn-bg-h: var(--c-white); }

/* --- state: hidden on scroll-down, revealed on scroll-up --- */
.nav[data-nav-hidden="true"] { transform: translateY(-100%); transition: transform var(--d-base) var(--e-out); }

/* Burger */
.nav__burger { display: none; width: 44px; height: 44px; align-items: center; justify-content: center; }
.nav__burger span { display: block; width: 24px; height: 1px; background: currentColor; position: relative; transition: background var(--d-fast); }
.nav__burger span::before, .nav__burger span::after {
  content: ""; position: absolute; left: 0; width: 24px; height: 1px; background: currentColor;
  transition: transform var(--d-base) var(--e-soft), top var(--d-base) var(--e-soft);
}
.nav__burger span::before { top: -7px; }
.nav__burger span::after  { top:  7px; }
[data-menu-open="true"] .nav__burger span { background: transparent; }
[data-menu-open="true"] .nav__burger span::before { top: 0; transform: rotate(45deg); }
[data-menu-open="true"] .nav__burger span::after  { top: 0; transform: rotate(-45deg); }


/* --------------------------------------------------------------------------
   10. MOBILE MENU — full screen, forest floor
   -------------------------------------------------------------------------- */
.menu {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--c-secondary); color: var(--c-ivory);
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(var(--nav-h-sm) + var(--s-7)) var(--gutter) var(--s-8);
  visibility: hidden; opacity: 0;
  transition: opacity var(--d-base) var(--e-out), visibility var(--d-base);
}
[data-menu-open="true"] .menu { visibility: visible; opacity: 1; }

.menu__list { list-style: none; }
.menu__item { overflow: hidden; }
.menu__link {
  display: flex; align-items: baseline; gap: var(--s-4);
  font-family: var(--font-display); font-weight: var(--fw-display);
  font-size: clamp(2.1rem, 8vw, 3.4rem); line-height: 1.28;
  padding-block: 4px;
}
.menu__n { font-family: var(--font-util); font-size: var(--t-label); letter-spacing: var(--ls-label); color: var(--c-bronze); }
.menu__foot { margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--line-on-dark-soft); }


/* --------------------------------------------------------------------------
   11. STICKY MOBILE CTA
   -------------------------------------------------------------------------- */
.cta-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-sticky);
  display: none; align-items: stretch;
  background: rgba(4, 22, 8, .94);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-top: 1px solid var(--line-on-dark-soft);
  padding-bottom: env(safe-area-inset-bottom);
}
.cta-bar__item {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 58px; color: var(--c-ivory);
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-button); text-transform: uppercase;
}
.cta-bar__item + .cta-bar__item { border-left: 1px solid var(--line-on-dark-soft); }
.cta-bar__item--primary { background: var(--c-primary); }


/* --------------------------------------------------------------------------
   12. FORMS
   -------------------------------------------------------------------------- */
.field { display: block; margin-bottom: var(--s-5); }
.field__label { display: block; margin-bottom: var(--s-2); }
.field__input, .field__select, .field__textarea {
  width: 100%; min-height: var(--btn-h);
  padding: var(--s-3) var(--s-4);
  background: transparent;
  border: 0; border-bottom: var(--border-hair) solid var(--line);
  border-radius: 0;
  font-family: var(--font-body); font-size: var(--t-body); color: inherit;
  transition: border-color var(--d-base) var(--e-out);
}
.field__textarea { min-height: 140px; resize: vertical; padding-top: var(--s-4); }
.field__input:hover, .field__select:hover, .field__textarea:hover { border-bottom-color: var(--c-bronze); }
.field__input:focus, .field__select:focus, .field__textarea:focus {
  outline: none; border-bottom-color: var(--c-accent); box-shadow: 0 1px 0 0 var(--c-accent);
}
.field__input::placeholder, .field__textarea::placeholder { color: var(--ink-muted); opacity: .6; }
.field__error { display: block; margin-top: var(--s-2); color: #B4553C; }
.field[data-invalid="true"] .field__input { border-bottom-color: #B4553C; }

.surface-forest .field__input, .surface-deep .field__input,
.surface-forest .field__textarea, .surface-deep .field__textarea,
.surface-forest .field__select, .surface-deep .field__select { border-bottom-color: var(--line-on-dark); }


/* --------------------------------------------------------------------------
   13. FOOTER
   -------------------------------------------------------------------------- */
.footer { background: var(--c-secondary); color: var(--ink-on-dark); padding-block: var(--section-y) var(--s-7); }
.footer__top { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: clamp(28px, 4vw, 72px); }
.footer__logo img {
    height: auto;
    width: 160px;
}
.footer__list { list-style: none; }
.footer__list li + li { margin-top: var(--s-3); }
.footer__link { font-size: var(--t-small); color: var(--ink-on-dark-mute); transition: color var(--d-fast); }
.footer__link:hover { color: var(--c-ivory); }
.footer__bottom {
  margin-top: var(--s-8); padding-top: var(--s-5);
  border-top: 1px solid var(--line-on-dark-soft);
  display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap;
}


/* --------------------------------------------------------------------------
   14. UTILITIES — a deliberately short list
   -------------------------------------------------------------------------- */
.u-center     { text-align: center; }
.u-right      { text-align: right; }
.u-relative   { position: relative; }
.u-full-bleed { width: 100vw; margin-left: 50%; transform: translateX(-50%); }
.u-mt-0 { margin-top: 0; }
.u-mt-4 { margin-top: var(--s-4); }
.u-mt-5 { margin-top: var(--s-5); }
.u-mt-6 { margin-top: var(--s-6); }
.u-mt-7 { margin-top: var(--s-7); }
.u-row  { display: flex; gap: var(--s-4); flex-wrap: wrap; align-items: center; }


/* --------------------------------------------------------------------------
   14b. TEXT PLATE
   A directional scrim behind copy on full-bleed sections. A uniform overlay
   either washes out the photograph or leaves the text unreadable over sky;
   this darkens only the side the text sits on.
   -------------------------------------------------------------------------- */
.plate::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  
}
/* .plate--center::before {
  background: radial-gradient(72% 58% at 50% 50%, rgba(4,22,8,.78), rgba(4,22,8,.30) 70%, transparent 100%);
} */

/* --------------------------------------------------------------------------
   15. LAYERED PARALLAX
   Three planes inside one section. Each layer is oversized and inset so the
   parallax drift never exposes an edge. Depth comes from how much each moves,
   which is set on the markup, not here.
   -------------------------------------------------------------------------- */
.layers { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.layer  { position: absolute; left: -5%; width: 110%; }
.layer img { display: block; width: 100%; height: 100%; object-fit: cover; }

.layer--sky  { top: -14%;      height: 86%;  z-index: 1; }
.layer--mid  { top:   6%;      height: 84%;  z-index: 2; }
.layer--fore { bottom: -16%;   height: 68%;  z-index: 3; }

/* The foreground is a keyed cutout — it must not pick up the scrim. */
.layer--fore > img { object-position: center top; }


/* --------------------------------------------------------------------------
   16. HORIZONTAL RAIL
   Pinned and translated on desktop by [data-hscroll]; a native snap-scroller
   on phones, where pinning a horizontal track fights the browser's own
   gesture handling and always loses.
   -------------------------------------------------------------------------- */
.hscroll { position: relative; overflow: hidden; }
.hrail {
  display: flex; align-items: center;
  gap: clamp(20px, 4vw, 72px);
  padding-inline: var(--gutter);
  height: 100svh;
}
.hrail__panel { flex: 0 0 auto; height: min(74svh, 720px); }
/* Explicit widths, not intrinsic. Deriving panel width from a decoded image
   means scrollWidth is 0 at first measure, which gives the pin a span of 0 and
   the whole section collapses. */
.hrail__panel--wide { width: min(96vw, 1180px); }
.hrail__panel--med  { width: min(62vw,  760px); }
.hrail__panel--text { height: auto; width: min(46ch, 78vw); }
.hrail__panel .frame { height: 100%; width: 100%; }
.hrail__panel .frame picture { width: 100%; height: 100%; }
.hrail__panel .frame img { height: 100%; width: 100%; object-fit: cover; }

@media (max-width: 640px) {
  .hscroll { overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
  .hrail { transform: none !important; height: auto; padding-block: var(--s-8); }
  .hrail__panel { scroll-snap-align: center; height: 58svh; }
  .hrail__panel--wide, .hrail__panel--med { width: 86vw; }
  .hrail__panel--text { height: auto; width: 82vw; }
}


/* --------------------------------------------------------------------------
   17. CROSSFADE PAIR
   Two stacked plates; the second is faded in on scrub by [data-crossfade].
   -------------------------------------------------------------------------- */
.xfade { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.xfade__plate { position: absolute; inset: 0; }
.xfade__plate img { width: 100%; height: 100%; object-fit: cover; }
.xfade__plate--to { opacity: 0; }

.xfade-labels { display: flex; gap: var(--s-5); align-items: center; }
.xfade-labels span { transition: opacity var(--d-base) var(--e-out); }
.xfade-labels [data-xfade-label="to"] { opacity: .34; }


/* --------------------------------------------------------------------------
   18. FRAME SCENE
   An inline scroll-driven canvas sequence. The poster sits underneath and
   fades out once enough frames have decoded, so the section is never empty
   and never flashes.
   -------------------------------------------------------------------------- */
.scene { position: relative; height: 100svh; overflow: hidden; background: var(--c-forest-deep); }
.scene__canvas,
.scene__poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; object-fit: cover;
}
.scene__poster { z-index: 1; transition: opacity 1.2s var(--e-soft); }
.scene__canvas { z-index: 2; }
.scene__overlay { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.scene__content { position: relative; z-index: 5; }

/* --------------------------------------------------------------------------
   19. CONTOUR OVERLAY
   Generated by tools/make-contours.py from the terrain itself.
   -------------------------------------------------------------------------- */
.contours { position: absolute; inset: 0; width: 100%; height: 100%; }
.contour  { fill: none; }

/* --------------------------------------------------------------------------
   20. SILENCE LINES
   Three statements that arrive one at a time and do not leave. Spaced far
   enough apart that the reader has to sit with each one.
   -------------------------------------------------------------------------- */
.silence { display: flex; flex-direction: column; gap: clamp(20px, 5vh, 56px); }
.silence__line { opacity: 0; }
.silence__line:nth-child(even) { align-self: flex-end; text-align: right; }

.readout {
  position: absolute; left: var(--gutter); bottom: clamp(24px, 5vh, 56px); z-index: 6;
  display: flex; gap: var(--s-5); align-items: baseline;
}
.readout__v { font-family: var(--font-util); font-size: var(--t-label); letter-spacing: var(--ls-label); color: var(--c-sand); }

@media (max-width: 640px) {
  .silence__line:nth-child(even) { align-self: flex-start; text-align: left; }
  .readout { position: static; margin-top: var(--s-7); }
}


/* --------------------------------------------------------------------------
   21. MAP SCENE
   -------------------------------------------------------------------------- */
.mapscene { position: relative; height: 100svh; overflow: hidden; background: var(--c-forest-deep); }
.mapscene__canvas,
.mapscene__poster {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover;
}
.mapscene__poster { z-index: 1; opacity: 1; transition: opacity 1.4s var(--e-soft); }
.mapscene__canvas { z-index: 2; }
.mapscene__content { position: relative; z-index: 4; }
.mapscene__scrim { position: absolute; inset: 0; z-index: 3; pointer-events: none;
                   background: linear-gradient(to right, rgba(4,22,8,.86) 0%, rgba(4,22,8,.35) 46%, transparent 72%); }
.mapscene__credit { position: absolute; right: var(--gutter); bottom: 16px; z-index: 5; }

/* --------------------------------------------------------------------------
   22. ADDRESS CARD + MAP EMBED
   -------------------------------------------------------------------------- */
.mapembed { position: relative; aspect-ratio: 16 / 16; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.mapembed iframe { width: 100%; height: 100%; border: 0; display: block; filter: saturate(.85); }

.facilities { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--s-4) var(--s-5); }
.facilities li { list-style: none; display: flex; gap: var(--s-3); align-items: baseline; font-size: var(--t-small); }
.facilities li::before { content: ""; flex: 0 0 auto; width: 14px; height: 1px; background: var(--c-bronze); transform: translateY(-4px); }

/* --------------------------------------------------------------------------
   23. REELS RAIL
   -------------------------------------------------------------------------- */
.reels { display: flex; gap: clamp(14px, 2vw, 12px); overflow-x: auto; scroll-snap-type: x mandatory!important;
         padding-block: var(--s-4); -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.reels::-webkit-scrollbar { display: none; }
.reel { flex: 0 0 auto; width: clamp(200px, 23vw, 300px); scroll-snap-align: center; position: relative; }
.reel .frame { aspect-ratio: 9 / 16; }
.reel__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-top: var(--s-3); }
.reel__play {
  position: absolute; inset: 0; z-index: 4; display: flex; align-items: center; justify-content: center;
  color: var(--c-ivory); pointer-events: none;
}
.reel__play span {
  width: 54px; height: 54px; border-radius: 50%; border: 1px solid rgba(247,243,234,.6);
  display: flex; align-items: center; justify-content: center;
  background: rgba(4,22,8,.34); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: transform var(--d-base) var(--e-soft);
}
.reel:hover .reel__play span { transform: scale(1.09); }

.placeholder-badge {
  position: absolute; top: 12px; left: 12px; z-index: 5;
  background: var(--c-bronze); color: var(--c-forest-deep);
  font-family: var(--font-util); font-size: 9px; letter-spacing: .18em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 2px;
}


/* --------------------------------------------------------------------------
   24. WHATSAPP FLOAT
   Sits above the sticky mobile bar, and never over the footer CTA.
   -------------------------------------------------------------------------- */
.wa-float {
  position: fixed; right: clamp(16px, 3vw, 32px); bottom: clamp(16px, 3vw, 32px);
  z-index: var(--z-sticky);
  display: inline-flex; align-items: center; gap: 0;
  height: 56px; padding: 0 15px;
  background: var(--c-secondary); color: var(--c-ivory);
  border: 1px solid rgba(247, 243, 234, .18); border-radius: var(--radius-pill);
  box-shadow: 0 10px 30px rgba(4, 22, 8, .32);
  transition: gap var(--d-base) var(--e-soft), padding var(--d-base) var(--e-soft),
              background var(--d-base) var(--e-out), transform var(--d-base) var(--e-soft);
}
.wa-float__label {
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-button); text-transform: uppercase;
  max-width: 0; overflow: hidden; white-space: nowrap; opacity: 0;
  transition: max-width var(--d-base) var(--e-soft), opacity var(--d-base) var(--e-out);
}
.wa-float:hover, .wa-float:focus-visible {
  gap: 10px; padding-right: 22px; background: var(--c-primary); transform: translateY(-2px);
}
.wa-float:hover .wa-float__label, .wa-float:focus-visible .wa-float__label {
  max-width: 120px; opacity: 1;
}
@media (max-width: 640px) {
  .wa-float { bottom: calc(58px + 14px); height: 50px; padding: 0 13px; }
  .wa-float:hover, .wa-float:focus-visible { padding-right: 13px; gap: 0; }
  .wa-float__label { display: none; }
}

/* --------------------------------------------------------------------------
   25. CHANNELS — the three ways to reach the property
   -------------------------------------------------------------------------- */
.channels { display: grid; gap: 0; border-top: 1px solid var(--line); }
.channel {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--s-5); padding: clamp(20px, 3vw, 30px) 0;
  border-bottom: 1px solid var(--line);
  transition: padding-inline var(--d-base) var(--e-soft), color var(--d-base);
}
.channel:hover, .channel:focus-visible { padding-inline: var(--s-4); color: var(--c-accent); }
.channel__n { font-family: var(--font-util); font-size: var(--t-label); letter-spacing: var(--ls-label); color: var(--c-bronze); }
.channel__body { display: block; }
.channel__t { display: block; font-family: var(--font-display); font-size: var(--t-display-s); line-height: 1.2; }
.channel__d { display: block; font-size: var(--t-small); color: var(--ink-muted); margin-top: 4px; }
.surface-forest .channel__d, .surface-deep .channel__d { color: var(--ink-on-dark-mute); }
.channel__arrow { font-size: 1.2rem; transition: transform var(--d-base) var(--e-soft); }
.channel:hover .channel__arrow { transform: translateX(6px); }

.enquiry { max-width: 760px; }

/* --------------------------------------------------------------------------
   26. VIDEO WALKTHROUGH
   Portrait source, so the frame is portrait on phones and a letterboxed
   plate on desktop rather than a stretched crop.
   -------------------------------------------------------------------------- */
.walk { position: relative; }
.walk__stage {
  position: relative; overflow: hidden; border-radius: var(--radius);
  background: var(--c-forest-deep); aspect-ratio: 9 / 16;
  max-height: 78svh; margin-inline: auto; width: auto;
}
.walk__stage video, .walk__stage img { width: 100%; height: 100%; object-fit: cover; display: block; }
.walk__poster { position: absolute; inset: 0; z-index: 2; transition: opacity var(--d-slow) var(--e-soft); }
.walk[data-playing="true"] .walk__poster { opacity: 0; pointer-events: none; }

.walk__controls { position: absolute; inset: auto 0 0 0; z-index: 4; display: flex; gap: var(--s-3);
                  padding: clamp(14px, 3vw, 24px); justify-content: space-between; align-items: center; }
.walk__btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 42px; padding: 0 16px; color: var(--c-ivory);
  background: rgba(4, 22, 8, .5); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid rgba(247, 243, 234, .26); border-radius: var(--radius-pill);
  font-family: var(--font-util); font-size: var(--t-label); letter-spacing: var(--ls-button); text-transform: uppercase;
}
.walk__btn:hover { background: rgba(4, 22, 8, .74); }

/* --------------------------------------------------------------------------
   27. ATTRACTIONS
   Alternating full-bleed plates. Each one pins its own caption while the
   image behind it drifts and scales.
   -------------------------------------------------------------------------- */
.spot { position: relative; min-height: 92svh; display: flex; align-items: flex-end; overflow: hidden; }
.spot__bg { position: absolute; inset: -8% 0; z-index: 0; }
.spot__bg img { width: 100%; height: 100%; object-fit: cover; }
.spot__scrim { position: absolute; inset: 0; z-index: 1; background: var(--scrim-bottom); }
.spot__body { position: relative; z-index: 3; padding-block: clamp(36px, 7vh, 88px); max-width: 52ch; }
.spot:nth-child(even) .spot__body { margin-left: auto; text-align: right; }
.spot__meta { display: flex; gap: var(--s-4); align-items: center; }
.spot:nth-child(even) .spot__meta { justify-content: flex-end; }

@media (max-width: 640px) {
  .spot { min-height: 78svh; }
  .spot:nth-child(even) .spot__body { margin-left: 0; text-align: left; }
  .spot:nth-child(even) .spot__meta { justify-content: flex-start; }
}


/* --------------------------------------------------------------------------
   28. BACK TO TOP
   Opposite corner to the WhatsApp float so the two never fight, and above the
   sticky bar on phones.
   -------------------------------------------------------------------------- */
.to-top {
  position: fixed; left: clamp(16px, 3vw, 32px); bottom: clamp(16px, 3vw, 32px);
  z-index: var(--z-sticky);
  display: inline-flex; align-items: center; gap: 8px;
  height: 46px; padding: 0 16px;
  background: rgba(4, 22, 8, .72); color: var(--c-ivory);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--line-on-dark); border-radius: var(--radius-pill);
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-button); text-transform: uppercase;
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-soft),
              background var(--d-base) var(--e-out);
}
.to-top[data-visible="true"] { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { background: var(--c-primary); }
.to-top[hidden] { display: none; }
@media (max-width: 640px) {
  .to-top { bottom: calc(58px + 14px); height: 42px; padding: 0 12px; }
  .to-top__label { display: none; }
}

/* --------------------------------------------------------------------------
   29. STACKED PLATES
   Sticky cards that layer over one another as you scroll.
   -------------------------------------------------------------------------- */
.stack-deck { position: relative; }
.stack-deck .spot {
  position: sticky; top: 0;
  height: 100svh; min-height: 0;
}
.spot__inner {
  position: absolute; inset: 0;
  display: flex; align-items: flex-end;
  overflow: hidden; border-radius: var(--radius);
  transform-origin: 50% 30%;
  will-change: transform, opacity;
}
.stack-deck .spot__bg  { inset: -8% 0; }
/* Dimming the outgoing card with OPACITY makes it translucent, so every
   heading behind it shows through and the deck reads as a smear. An opaque
   plate on top darkens it without making it see-through. */
.spot__dim {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  /* background: var(--c-forest-deep); opacity: 0; */
}
.stack-deck .spot__body { padding-bottom: clamp(48px, 9vh, 120px); }

@media (max-width: 640px) {
  .stack-deck .spot { height: 82svh; }
}

/* --------------------------------------------------------------------------
   30. FACILITIES
   -------------------------------------------------------------------------- */
.facility {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s-4);
  align-items: start; padding: var(--s-5) 0;
  border-bottom: 1px solid var(--line);
}
.facility__n { font-family: var(--font-util); font-size: var(--t-label);
               letter-spacing: var(--ls-label); color: var(--c-bronze); padding-top: 5px; }
.facility__t { font-family: var(--font-display); font-size: var(--t-display-s); line-height: 1.2; }
.facility__d { font-size: var(--t-small); color: var(--ink-muted); margin-top: 3px; }
.surface-forest .facility__d, .surface-deep .facility__d { color: var(--ink-on-dark-mute); }
.facility-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 clamp(28px, 5vw, 80px);
    margin-top: 40px;
}
@media (max-width: 760px) { .facility-grid { grid-template-columns: 1fr; } }




/* --------------------------------------------------------------------------
   31. BACKGROUND VIDEO
   The poster sits under the video and fades out only once playback has
   actually started, so a blocked autoplay leaves a photograph rather than
   a black rectangle.
   -------------------------------------------------------------------------- */
.bgvideo { position: absolute; inset: 0; z-index: 0; overflow: hidden; }

.bgvideo__poster,
.bgvideo__el {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.bgvideo__poster { z-index: 1; transition: opacity 1s var(--e-soft); }
.bgvideo__el {
  z-index: 2; opacity: 0; transition: opacity 1s var(--e-soft);
  /* Own compositor layer. Without this the video texture is re-rasterised
     with the rest of the section on every scroll tick. */
  transform: translateZ(0);
  backface-visibility: hidden;
  will-change: transform;
}

.bgvideo[data-playing="true"] .bgvideo__poster { opacity: 0; }
.bgvideo[data-playing="true"] .bgvideo__el     { opacity: 1; }

.bgvideo__scrim { position: absolute; inset: 0; z-index: 3; background: var(--scrim-full); pointer-events: none; }
.bgvideo__grain { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

/* --------------------------------------------------------------------------
   While a background video is PLAYING, drop the layers that force the whole
   section to re-composite on every painted frame. Each of these is cheap over
   a static image and expensive over 30 live frames a second:

     .mist          filter: blur(14px) on a full-bleed, permanently animated
                    element — a blurred layer is repainted, not composited
     .grain         mix-blend-mode: overlay across the full viewport — a blend
                    pulls the stack off the GPU fast path entirely

   The video supplies its own movement, so neither is missed.
   -------------------------------------------------------------------------- */
[data-video-playing="true"] .mist { display: none; }


/* No video at all in these states — the poster is the section. */
[data-motion="reduced"] .bgvideo__el,
.bgvideo[data-video-off="true"] .bgvideo__el { display: none; }



/* --------------------------------------------------------------------------
   32. REELS — video cards
   Vertical 9:16, playing straight from assets/video/reels/. Only the card
   nearest the centre of the rail plays; see animations.js for why.
   -------------------------------------------------------------------------- */
.reel__stage {
  position: relative; overflow: hidden; border-radius: var(--radius);
  aspect-ratio: 9 / 16; background: var(--c-forest-deep);
}
.reel__stage .frame { position: absolute; inset: 0; aspect-ratio: auto; height: 100%; }

.reel__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Own compositor layer — the rail is translated on scroll and the video
     would otherwise be re-rasterised with it every tick. */
  transform: translateZ(0);
  backface-visibility: hidden;
}
.reel__scrim {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: var(--scrim-bottom);
}

/* Playing card lifts slightly out of the row. */
.reel { transition: transform var(--d-base) var(--e-soft); }
.reel[data-playing="true"] { transform: translateY(-6px); }

.reel__sound {
    position: absolute;
    right: 40%;
    top: 40%;
    z-index: 4;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--c-ivory);
    border-radius: 50%;
    background: rgba(4, 22, 8, .48);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid rgba(247, 243, 234, .28);
    transition: background var(--d-fast) var(--e-out);
}
.reel__sound:hover { background: rgba(179, 92, 10, 0.78); }
.reel__sound .reel__wave { opacity: 0; }
.reel__sound .reel__mute { opacity: 1; }
.reel__sound[aria-pressed="true"] .reel__wave { opacity: 1; }
.reel__sound[aria-pressed="true"] .reel__mute { opacity: 0; }

.reels__foot { justify-content: space-between; align-items: center; }
@media (max-width: 640px) {
  .reels__foot { flex-direction: column-reverse; align-items: stretch; gap: var(--s-4); }
  .reels__foot .btn { width: 100%; }
}


/* --------------------------------------------------------------------------
   33. PAGE HERO — every internal page opens the same way
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative; overflow: hidden;
  min-height: min(72svh, 720px);
  display: flex; align-items: flex-end;
  padding-block: calc(var(--nav-h) + var(--s-8)) clamp(48px, 8vh, 110px);
}
.page-hero__bg { position: absolute; inset: -6% 0; z-index: 0; }
.page-hero__bg .frame,
.page-hero__bg img { width: 100%; height: 100%; object-fit: cover; }
.page-hero__body { position: relative; z-index: 4; }

/* --------------------------------------------------------------------------
   34. GALLERY — masonry with category filtering
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   34. GALLERY — true masonry with category filtering
   -------------------------------------------------------------------------- */

.gal {
  column-count: 4;
  column-gap: clamp(10px, 1.4vw, 20px);
}

.gal__item {
  position: relative;
  display: inline-block;
  width: 100%;
  margin: 0 0 clamp(10px, 1.4vw, 20px);
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
}

/* Masonry does not need row/column spanning */
.gal__item--wide,
.gal__item--tall {
  grid-column: auto;
  grid-row: auto;
}

.gal__item .frame {
  width: 100%;
  height: auto;
  aspect-ratio: auto;
  overflow: hidden;
}

.gal__item--wide .frame,
.gal__item--tall .frame {
  aspect-ratio: auto;
}

.gal__item .frame img {
  display: block;
  width: 100%;
  height: auto;
}

.gal__item[hidden] {
  display: none;
}

.gal__btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  text-align: left;
  cursor: zoom-in;
}

.filters { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.filter {
  font-family: var(--font-util); font-size: var(--t-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  padding: 9px 16px; border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink-muted); transition: .18s;
}
.filter:hover { border-color: var(--c-bronze); color: var(--ink); }
.filter[aria-pressed="true"] { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-ivory); }

/* Lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: var(--z-menu);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(16px, 4vw, 56px);
  background: rgba(4, 22, 8, .95);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; visibility: hidden; transition: opacity var(--d-base) var(--e-out), visibility var(--d-base);
}
.lightbox[data-open="true"] { opacity: 1; visibility: visible; }
.lightbox__img { max-width: 100%; max-height: 82svh; object-fit: contain; border-radius: var(--radius); }
.lightbox__cap { position: absolute; left: 0; right: 0; bottom: clamp(14px, 3vh, 30px); text-align: center; color: var(--c-sand); }
.lightbox__close, .lightbox__nav {
  position: absolute; z-index: 2; width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  color: var(--c-ivory); border: 1px solid var(--line-on-dark); border-radius: 50%;
  background: rgba(4, 22, 8, .5); transition: background var(--d-fast);
}
.lightbox__close:hover, .lightbox__nav:hover { background: var(--c-primary); }
.lightbox__close { top: clamp(14px, 3vh, 28px); right: clamp(14px, 3vw, 28px); }
.lightbox__nav--prev { left: clamp(10px, 2vw, 26px); top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: clamp(10px, 2vw, 26px); top: 50%; transform: translateY(-50%); }

@media (max-width: 900px) { .gal { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
  .gal { grid-template-columns: 1fr; }
  .gal__item--wide, .gal__item--tall { grid-column: auto; grid-row: auto; }
}

/* --------------------------------------------------------------------------
   35. SIMPLE EDITORIAL RUNS — about / experiences
   -------------------------------------------------------------------------- */
.run { display: grid; gap: clamp(48px, 9vh, 120px); }
.run__item { display: grid; grid-template-columns: 5fr 7fr; gap: clamp(24px, 5vw, 80px); align-items: center; }
.run__item:nth-child(even) { grid-template-columns: 7fr 5fr; }
.run__item:nth-child(even) .run__text { order: 2; }
@media (max-width: 900px) {
  .run__item, .run__item:nth-child(even) { grid-template-columns: 1fr; }
  .run__item:nth-child(even) .run__text { order: 0; }
}

/* --------------------------------------------------------------------------
   36. 404
   -------------------------------------------------------------------------- */
.notfound { min-height: 78svh; display: flex; align-items: center; text-align: center; }
.notfound .container > * { margin-inline: auto; }

/* Unnumbered variant — the tick carries the left edge on its own. */
.section-label--plain .section-label__t { color: var(--c-bronze); }
.surface-forest .section-label--plain .section-label__t,
.surface-deep .section-label--plain .section-label__t,
.surface-brown .section-label--plain .section-label__t { color: var(--c-sand); }

/* Hero title: one <h1> reading "RPEES Millennium Stay Inn", two visual sizes. */
.hero__title { margin: 0; }
.hero__title > span { display: block; }


/* --------------------------------------------------------------------------
   37. ROOM SLIDER
   One crossfade between stacked figures. No carousel library — the whole
   behaviour is 40 lines and this keeps it off the critical path.
   -------------------------------------------------------------------------- */
.rslider { position: relative; }
.rslider__stage {
  position: relative; overflow: hidden; border-radius: var(--radius);
  aspect-ratio: 3 / 2; background: var(--c-mist);
}
.rslider__slide {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; visibility: hidden;
  transition: opacity .9s var(--e-soft), visibility .9s;
}
.rslider__slide.is-active { opacity: 1; visibility: visible; }
.rslider__slide picture, .rslider__slide img { width: 100%; height: 100%; display: block; }
.rslider__slide img { object-fit: cover; }

.rslider__dots {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 3; display: flex; gap: 8px;
}
.rslider__dot {
  width: 26px; height: 3px; border-radius: 2px; border: 0; padding: 0;
  background: rgba(247, 243, 234, .45); cursor: pointer; transition: background .25s;
}
.rslider__dot.is-active { background: var(--c-sand); }
.rslider__dot:focus-visible { box-shadow: var(--focus-ring-dark); }

.rslider__nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  color: var(--c-ivory); border-radius: 50%;
  background: rgba(4, 22, 8, .42);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(247, 243, 234, .26);
  opacity: 0; transition: opacity .25s, background .25s;
}
.rslider:hover .rslider__nav, .rslider__nav:focus-visible { opacity: 1; }
.rslider__nav:hover { background: var(--c-primary); }
.rslider__nav--prev { left: 12px; }
.rslider__nav--next { right: 12px; }
@media (hover: none) { .rslider__nav { opacity: 1; } }

/* --------------------------------------------------------------------------
   38. RATE
   -------------------------------------------------------------------------- */
.rate { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding-block: var(--s-5); }
.rate__main { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.rate__amount { font-family: var(--font-display); font-size: clamp(2.1rem, 4vw, 3rem); line-height: 1; color: var(--c-primary); }
.surface-forest .rate__amount, .surface-deep .rate__amount { color: var(--c-sand); }
.rate__unit { font-family: var(--font-util); font-size: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--ink-muted); }
.surface-forest .rate__unit, .surface-deep .rate__unit { color: var(--ink-on-dark-mute); }
.rate__meta { list-style: none; padding: 0; margin: var(--s-4) 0 0; display: flex; gap: var(--s-5); flex-wrap: wrap; }
.rate__meta li { font-size: var(--t-small); color: var(--ink-muted); display: flex; gap: 8px; align-items: baseline; }
.rate__meta li::before { content: ""; width: 12px; height: 1px; background: var(--c-bronze); flex: 0 0 auto; }
.surface-forest .rate__meta li, .surface-deep .rate__meta li { color: var(--ink-on-dark-mute); }
.rate--compact { border: 0; padding-block: 0; }


/* --------------------------------------------------------------------------
   39. PAINT BUDGET
   Sections below the fold are skipped by layout and paint until they are
   near the viewport. contain-intrinsic-size supplies a placeholder height so
   the scrollbar does not jump as they are realised — without it this causes
   layout shift, which is worse than the problem it solves.

   The hero and the pinned sections are excluded: content-visibility on a
   position:sticky or pinned ancestor breaks the pin.
   -------------------------------------------------------------------------- */
/* REVERTED on the homepage. content-visibility estimates a section's height
   until it is realised, and ScrollTrigger measures pin offsets against those
   estimates — measured drift of 24-51px on the four pinned sections, which
   shows up as a small jump when a pin engages. The real payload win came from
   the media pass (17.3 MB -> 2.8 MB), so this was buying very little.

   Kept only where there are no pins to disturb. */
.gal__item {
  content-visibility: auto;
  contain-intrinsic-size: auto 320px;
}

/* Images must never cause reflow. Everything that can be sized, is. */
img { max-width: 100%; height: auto; }

@media (prefers-reduced-motion: reduce) {
  .rslider__slide { transition: none; }
}


/* --------------------------------------------------------------------------
   40. HERO LOADER — the first three seconds
   Covers the hero while band one decodes. Sits above the beats, so nothing
   shows over an empty stage.
   -------------------------------------------------------------------------- */
.hero-loader__mark { height: 40px; width: auto; opacity: .9; margin-bottom: var(--s-2); }
.hero-loader__text { animation: loader-breathe 2.4s var(--e-in-out) infinite; }
@keyframes loader-breathe { 0%,100% { opacity: .62; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .hero-loader__text { animation: none; } }
