/* ============================================================================
   Nokian Experiences — public site

   Design direction: modern luxury hospitality, branded around the Nokian
   logo's mountain blues. Warm ivory and white carry the page; deep charcoal
   is used deliberately for contrast bands, imagery and the footer; blue
   appears as the brand accent — eyebrows, active states, buttons, hairline
   dividers, hover details.

   Three ideas carry the design:

   1. Typography is set LIGHT and LARGE. Cormorant at 300 across 3-7rem reads
      as expensive; the same face at 500/2rem reads as a template.
   2. Geometry is squared, not pill-shaped. Small radii and hairline rules read
      as architecture and editorial print — the vocabulary of the category —
      where large pills and soft blobs read as generic SaaS.
   3. Until real photography arrives, empty image slots render as layered mesh
      gradients with film grain, so the page looks art-directed rather than
      like a grid of missing assets.
   ========================================================================= */

:root {
  /* --- Core palette ----------------------------------------------------- */
  --char-900: #141414;   /* deepest, for the footer floor          */
  --char-800: #1C1C1C;   /* deep charcoal — primary dark surface   */
  --char-700: #2A2A2A;   /* secondary dark — raised dark surface   */
  --char-600: #3A3A3A;   /* dark surface hover / borders on dark   */

  --ivory: #F7F5F2;      /* warm ivory — the page's default ground */
  --ivory-deep: #EFEBE4;  /* a half-step down, for banded sections  */
  --white: #FFFFFF;

  --text: #1A1A1A;       /* primary text                           */
  --text-soft: #4E4E4E;  /* secondary text                         */
  --text-faint: #7D7870; /* meta, captions, disabled               */

  --blue: #2C6FA8;        /* the single accent — matches the logo   */
  --blue-bright: #5FA8DB; /* lighter, for on-dark / hover states    */
  --blue-soft: #CFE6F5;   /* pale tint, for soft backgrounds        */
  --blue-deep: #17456B;   /* darker, for gradients and active/hover */

  --line: #E5E0D8;                        /* standard hairline    */
  --line-soft: rgba(34, 34, 34, 0.07);    /* barely-there divider */
  --line-light: rgba(247, 245, 242, 0.16); /* hairline on dark     */

  /* --- Aliases ---------------------------------------------------------- */
  /* Kept so existing markup that reaches for a token inline keeps working;
     every one of these resolves into the palette above. */
  --ink-900: var(--char-900);
  --ink-800: var(--char-800);
  --ink-700: var(--char-700);
  --ink: var(--text);
  --green-600: var(--char-700);
  --green-500: var(--char-800);
  --green-400: var(--text-soft);
  --green-deep: var(--text);
  --sage-300: var(--text-faint);
  --sage-200: var(--line);
  --cream: var(--ivory);
  --sand: var(--ivory-deep);
  --beige: var(--ivory-deep);
  --beige-deep: var(--line);
  --stone: var(--text-soft);
  --stone-light: var(--text-faint);
  --bronze: var(--blue); /* legacy alias name, still referenced inline in a few Blade views */

  /* --- Type ------------------------------------------------------------- */
  --display: "Playfair Display", "Times New Roman", serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --serif: var(--display);

  /* --- Motion — one slow, confident curve used everywhere ---------------- */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --dur: 0.7s;
  --dur-slow: 1.1s;

  /* --- Geometry — deliberately restrained -------------------------------- */
  --radius: 15px;
  --radius-lg: 15px;

  --shadow-sm: 0 1px 2px rgba(20, 20, 20, 0.04), 0 2px 12px rgba(20, 20, 20, 0.03);
  --shadow: 0 2px 6px rgba(20, 20, 20, 0.04), 0 16px 40px rgba(20, 20, 20, 0.07);
  --shadow-lg: 0 4px 12px rgba(20, 20, 20, 0.05), 0 32px 70px rgba(20, 20, 20, 0.13);

  --gutter: clamp(1.25rem, 4vw, 4rem);
  /* Fixed up to a large desktop, then scales with the viewport instead of
     staying capped — otherwise a 4K/TV-class screen sees the same column as a
     laptop, with hundreds of empty pixels either side. */
  --max: min(1680px, 94vw);
}

@media (min-width: 1800px) { :root { --max: min(2200px, 94vw); } }
@media (min-width: 2600px) { :root { --max: min(3000px, 94vw); --gutter: clamp(2rem, 5vw, 7rem); } }
@media (min-width: 3600px) { :root { --max: 94vw; --gutter: clamp(3rem, 5vw, 9rem); } }

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  /* Every size in this stylesheet is set in rem, which is relative to this
     root size - bumping it here nudges everything (including the small
     uppercase labels/meta text) up a little for readability, without
     hand-editing dozens of individual font-size rules. */
  font-size: 106.25%;
}

body {
  margin: 0;
  background: var(--ivory);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.75;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--char-800); color: var(--ivory); }

:focus-visible {
  outline: 1px solid var(--blue);
  outline-offset: 4px;
  border-radius: 1px;
}

/* ---------------------------------------------------------------- typography */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 300;
  color: var(--text);
  line-height: 1.06;
  letter-spacing: -0.012em;
  text-wrap: balance;
  margin: 0 0 0.45em;
}

h1 { font-size: clamp(2.85rem, 8vw, 6.5rem); }
h2 { font-size: clamp(2.25rem, 5vw, 4.15rem); }
h3 { font-size: clamp(1.45rem, 2.5vw, 2rem); font-weight: 400; }
h4 { font-size: clamp(1.1rem, 1.7vw, 1.35rem); font-weight: 400; }

p { margin: 0 0 1.1rem; color: var(--text-soft); }

em { font-style: italic; color: var(--blue); }

.lede {
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  line-height: 1.75;
  color: var(--text-soft);
  max-width: 56ch;
}

/* The small letterspaced label that opens a section. The rule before it is
   the one place gold appears on almost every screen — keep it thin. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 1.5rem;
}
.eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}
.eyebrow.centered { justify-content: center; }
/* An eyebrow bound to an admin-editable subtitle that's been cleared still
   renders the tag (and its decorative line) with nothing next to it -
   without this, that line reads as a stray floating dash. Hide the whole
   label, margin included, when there's truly no text in it. */
.eyebrow:empty { display: none; }
.eyebrow.on-dark { color: var(--blue-bright); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5); }

#hero-heading, #hero-subtitle, #hero-explore-link { transition: opacity 0.35s var(--ease); }

/* ------------------------------------------------------------------- layout */

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
.wrap-narrow { width: 100%; max-width: 860px; margin: 0 auto; padding: 0 var(--gutter); }
.wrap-wide { width: 100%; max-width: calc(var(--max) + 160px); margin: 0 auto; padding: 0 var(--gutter); }

/* The homepage intro sits two sentences deep in a narrow column; the default
   h2 scale would wrap each sentence, turning 2 intended lines into 4. */
.wrap-narrow .reveal-lines { font-size: clamp(1.6rem, 3.6vw, 2.6rem); }
.wrap-narrow .lede { max-width: 76ch; font-size: clamp(1rem, 1.2vw, 1.1rem); }

section { padding: clamp(5rem, 11vw, 10rem) 0; position: relative; }
section.tight { padding: clamp(3.5rem, 7vw, 6rem) 0; }

.section-head { max-width: 720px; margin-bottom: clamp(2.75rem, 5.5vw, 4.5rem); }
.section-head.centered { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 { margin-bottom: 1rem; }
.section-head p { font-size: 1.04rem; color: var(--text-soft); margin: 0; }

/* A hairline that draws itself as the section enters */
.rule {
  height: 1px;
  background: var(--line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.4s var(--ease);
}
.reveal.visible .rule, .rule.visible { transform: scaleX(1); }

/* ------------------------------------------------------- placeholder scenery */

/*
   Image slots without a photograph yet. Each variant is a distinct layered
   mesh gradient, so a grid of cards reads as art direction rather than as
   missing assets. `.has-image` switches these off entirely.
*/
.scene {
  position: relative;
  overflow: hidden;
  background: var(--char-800);
  isolation: isolate;
}

.scene::before {
  content: "";
  position: absolute;
  inset: -10%;
  z-index: 0;
  background:
    radial-gradient(58% 48% at 22% 18%, rgba(44, 111, 168, 0.30), transparent 62%),
    radial-gradient(52% 60% at 84% 30%, rgba(58, 58, 58, 0.85), transparent 66%),
    radial-gradient(70% 62% at 50% 96%, rgba(20, 20, 20, 0.94), transparent 70%),
    linear-gradient(152deg, #3A3A3A 0%, var(--char-900) 78%);
  transition: transform 1.6s var(--ease);
}

/* Film grain keeps the flat gradients from looking synthetic */
.scene::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.30;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

.scene > * { position: relative; z-index: 3; }

.scene.v2::before {
  background:
    radial-gradient(56% 50% at 78% 20%, rgba(95, 168, 219, 0.36), transparent 64%),
    radial-gradient(60% 56% at 16% 44%, rgba(42, 42, 42, 0.9), transparent 68%),
    radial-gradient(74% 60% at 54% 98%, rgba(20, 20, 20, 0.92), transparent 72%),
    linear-gradient(200deg, #2E5573 0%, var(--char-900) 76%);
}
.scene.v3::before {
  background:
    radial-gradient(50% 46% at 30% 78%, rgba(226, 210, 182, 0.26), transparent 62%),
    radial-gradient(58% 58% at 76% 26%, rgba(42, 42, 42, 0.92), transparent 68%),
    radial-gradient(80% 60% at 48% 100%, rgba(20, 20, 20, 0.9), transparent 70%),
    linear-gradient(168deg, #34495A 0%, var(--char-900) 78%);
}
.scene.v4::before {
  background:
    radial-gradient(54% 46% at 68% 76%, rgba(44, 111, 168, 0.32), transparent 62%),
    radial-gradient(56% 54% at 24% 22%, rgba(58, 58, 58, 0.9), transparent 66%),
    radial-gradient(76% 64% at 52% 98%, rgba(20, 20, 20, 0.92), transparent 70%),
    linear-gradient(196deg, #3D6E93 0%, var(--char-800) 80%);
}

/* Real photography replaces the gradient entirely */
.scene.has-image::before { display: none; }
.scene.has-image::after { opacity: 0.10; }
.scene > img.scene-img {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.8s var(--ease), filter 1s var(--ease);
}

/* Legibility wash under any text laid over a scene. Strengthened from the
   original tuning — the old mid-stop (0.20 at 55%) let a bright patch right
   behind the heading peek through on some real photos. */
.scene .veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(to top, rgba(20, 20, 20, 0.9) 0%, rgba(20, 20, 20, 0.34) 55%, transparent 100%);
  pointer-events: none;
}

/* Photos flagged bright at upload (ImageBrightness, sampled from the bottom
   third — exactly where this text sits) get a materially darker wash on top
   of the baseline above, rather than the whole site being tuned for the
   worst-case photo. Computed once per image, not guessed. */
.scene.is-bright .veil {
  background: linear-gradient(to top, rgba(20, 20, 20, 0.96) 0%, rgba(20, 20, 20, 0.62) 45%, rgba(20, 20, 20, 0.15) 80%, transparent 100%);
}

/* -------------------------------------------------------------------- header */

.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 200;
  padding: 0.6rem 0 1.6rem;
  transition: padding 0.55s var(--ease), background 0.55s var(--ease),
              box-shadow 0.55s var(--ease), backdrop-filter 0.55s var(--ease);
}

/* Thin locator strip above the main nav row */
.header-topline {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ivory);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.55);
  opacity: 0.95;
  padding-bottom: 0.7rem;
  margin-bottom: 0.7rem;
  border-bottom: 1px solid rgba(247, 245, 242, 0.28);
  transition: opacity 0.4s var(--ease), max-height 0.4s var(--ease), margin 0.4s var(--ease), padding 0.4s var(--ease);
}
.site-header.stuck .header-topline,
.site-header.solid .header-topline {
  color: var(--blue-deep);
  text-shadow: none;
  border-bottom-color: var(--line);
}
.site-header.stuck { padding-top: 0.5rem; }
.site-header.stuck .header-topline {
  max-height: 0;
  opacity: 0;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
}
.site-header .wrap-wide {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

/* Over the hero the header is transparent with light type */
.site-header .brand,
.site-header .nav > a { color: var(--ivory); }

.site-header.stuck {
  padding: 0.8rem 0;
  background: rgba(247, 245, 242, 0.88);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow: 0 1px 0 var(--line), 0 10px 34px rgba(20, 20, 20, 0.05);
}
.site-header.stuck .brand,
.site-header.stuck .nav > a:not(.btn) { color: var(--text); }
.site-header.stuck .brand .dot { color: var(--blue); }
/* The Enquire button keeps its own solid-fill colour (white text on the
   blue gradient) in every header state - without this it inherited the
   plain nav-link colour above, turning the text near-black on its own
   dark/blue fill and making it unreadable once the header goes solid. */
.site-header.stuck .nav > a.btn,
.site-header.solid .nav > a.btn { color: var(--white); }

/* Pages without a full-bleed hero start in the solid state */
.site-header.solid {
  background: rgba(247, 245, 242, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--line);
}
.site-header.solid .brand,
.site-header.solid .nav > a:not(.btn) { color: var(--text); }

.brand {
  position: relative;
  z-index: 195;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  /* Never shrink the logo mark below its own content size - if the header
     row runs tight, the nav links are what should compress/wrap instead. */
  flex-shrink: 0;
  font-family: var(--display);
  font-size: 1.7rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  line-height: 1;
  transition: color 0.5s var(--ease);
}
.brand-logo {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  box-shadow: 0 2px 10px rgba(23, 69, 107, 0.25);
}
/* The wordmark is the client's own logotype image, not styled text - kept
   solid white by default (readable over the transparent/dark header on a
   hero image) and swapped to its own original blue once the header goes
   solid/light, via a plain colour-swap filter rather than shipping two
   separate image files. */
.brand-word-img {
  height: 1.05em;
  display: block;
  filter: brightness(0) invert(1);
  transition: filter 0.5s var(--ease);
}
.site-header.stuck .brand-word-img,
.site-header.solid .brand-word-img { filter: none; }
.brand .dot { color: var(--blue); }

.nav { display: flex; align-items: center; gap: clamp(1.1rem, 1.8vw, 2.3rem); }
/* :not(.btn) keeps these plain-link rules off the CTA button that also lives
   inside .nav — without it, its padding and font-size get clobbered by these
   (same specificity, later in the file), squashing the label into its edges. */
.nav > a:not(.btn) {
  position: relative;
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: clamp(0.08em, 0.6vw, 0.18em);
  text-transform: uppercase;
  padding: 0.4rem 0;
  white-space: nowrap;
  transition: color 0.5s var(--ease), opacity 0.35s var(--ease);
}
.nav > a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.55s var(--ease);
}
.nav > a:not(.btn):hover::after, .nav > a.active::after { transform: scaleX(1); transform-origin: left; }
.nav > a.active { color: var(--blue-bright); }
.site-header.stuck .nav > a.active,
.site-header.solid .nav > a.active { color: var(--blue); }

.nav-toggle {
  display: none;
  position: relative;
  z-index: 195;
  width: 42px; height: 42px;
  background: none;
  border: 1px solid currentColor;
  border-radius: var(--radius);
  color: inherit;
  cursor: pointer;
  padding: 0;
}
.nav-toggle span {
  position: absolute;
  left: 12px;
  width: 18px; height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease);
}
.nav-toggle span:nth-child(1) { top: 17px; }
.nav-toggle span:nth-child(2) { top: 24px; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

@media (max-width: 1000px) {
  .nav-toggle { display: block; color: var(--ivory); }
  .site-header.stuck .nav-toggle, .site-header.solid .nav-toggle { color: var(--text); }

  .nav {
    position: fixed;
    inset: 0;
    background: var(--char-800);
    flex-direction: column;
    justify-content: center;
    gap: 0;
    padding: 6rem 2rem 3rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.5s var(--ease), visibility 0.5s;
    z-index: 190;
  }
  .nav.open { opacity: 1; visibility: visible; }
  .nav > a:not(.btn) {
    color: var(--ivory) !important;
    font-family: var(--display);
    font-size: 2rem;
    font-weight: 300;
    letter-spacing: 0.02em;
    text-transform: none;
    padding: 0.7rem 0;
  }
  .nav > a { opacity: 0; transform: translateY(18px); }
  .nav.open > a {
    opacity: 1;
    transform: none;
    transition: opacity 0.6s var(--ease) calc(var(--i, 0) * 60ms),
                transform 0.6s var(--ease) calc(var(--i, 0) * 60ms);
  }
  .nav > a::after { display: none; }
  .nav .btn { margin-top: 1.75rem; }
}

/* ------------------------------------------------------------------- buttons */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 1.05rem 2.3rem;
  border: 1px solid transparent;
  border-radius: 40px;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease),
              transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
}

/* A wash that sweeps up from the bottom on hover */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  transform: translateY(101%);
  transition: transform 0.6s var(--ease);
}
.btn:hover::before { transform: translateY(0); }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn-primary { background: var(--char-800); color: var(--ivory); }
.btn-primary::before { background: linear-gradient(135deg, var(--blue-bright), var(--blue) 55%, var(--blue-deep)); }
.btn-primary:hover { color: var(--white); box-shadow: var(--shadow); }

/* The single most prominent CTA on any screen. */
.btn-bronze { background: linear-gradient(135deg, var(--blue-bright), var(--blue) 55%, var(--blue-deep)); color: var(--white); border-color: transparent; }
.btn-bronze::before { background: var(--char-800); }
.btn-bronze:hover { color: var(--ivory); box-shadow: var(--shadow); }

.btn-outline { background: transparent; border-color: var(--line); color: var(--text); }
.btn-outline::before { background: linear-gradient(135deg, var(--blue-bright), var(--blue) 55%, var(--blue-deep)); }
.btn-outline:hover { color: var(--white); border-color: var(--blue); }

.btn-ghost {
  background: rgba(247, 245, 242, 0.06);
  border-color: rgba(247, 245, 242, 0.4);
  color: var(--ivory);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.btn-ghost::before { background: linear-gradient(135deg, var(--blue-bright), var(--blue) 55%, var(--blue-deep)); }
.btn-ghost:hover { color: var(--white); border-color: var(--blue-bright); }

/* Solid light button, for use on a charcoal band */
.btn-light { background: var(--ivory); color: var(--char-800); border-color: var(--ivory); }
.btn-light::before { background: linear-gradient(135deg, var(--blue-bright), var(--blue) 55%, var(--blue-deep)); }
.btn-light:hover { color: var(--white); border-color: var(--blue); }

.btn-sm { padding: 0.78rem 1.6rem; font-size: 0.64rem; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }
.btn:disabled::before { display: none; }

/* Text link with an arrow that slides */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue);
  padding-bottom: 0.3rem;
  position: relative;
}
.link-arrow::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease);
}
.link-arrow:hover::after { transform: scaleX(1); transform-origin: left; }
.link-arrow .arw { transition: transform 0.5s var(--ease); }
.link-arrow:hover .arw { transform: translateX(5px); }

/* ---------------------------------------------------------------------- hero */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding: 8rem 0 clamp(2.5rem, 6vh, 4rem);
  overflow: hidden;
  background: var(--char-900);
}

.hero-bg {
  position: absolute;
  inset: -8% 0 -8% 0;
  z-index: 0;
  will-change: transform;
}

.hero-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(60% 50% at 74% 16%, rgba(44, 111, 168, 0.30), transparent 62%),
    radial-gradient(56% 56% at 14% 74%, rgba(110, 88, 54, 0.28), transparent 66%),
    radial-gradient(90% 70% at 50% 108%, rgba(20, 20, 20, 0.96), transparent 74%),
    linear-gradient(158deg, #1C2B38 0%, var(--char-900) 82%);
  /* A very slow drift keeps the hero alive without distracting */
  animation: drift 28s var(--ease-soft) infinite alternate;
}
@keyframes drift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.08) translate3d(-1.5%, -1.5%, 0); }
}

.hero-bg img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Same full-coverage legibility wash the hero slideshow carries (see
   .hero-slideshow::after) — every page using .hero-bg (home's own
   fallback path, property/facility pages, destination & private weddings)
   now reads with the same dimming as the home hero, instead of the old
   bottom-only fade that left the top two-thirds untouched.

   This MUST be ::after, not ::before: a ::before is inserted as the first
   child, so with a real <img> tag also inside .hero-bg (added after it in
   the DOM), the img painted on top and hid the ::before wash completely —
   it was having zero visible effect despite computing correctly. ::after
   paints last/on top, same as .hero-slideshow::after already does. */
.hero-bg.has-image::before { content: none; }
.hero-bg.has-image::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(200deg, rgba(20, 20, 20, 0.6) 0%, rgba(20, 20, 20, 0.74) 55%, rgba(20, 20, 20, 0.92) 100%),
    linear-gradient(to top, rgba(20, 20, 20, 0.7) 0%, transparent 48%);
}
.hero-bg.has-image.is-bright::after {
  background:
    linear-gradient(200deg, rgba(20, 20, 20, 0.72) 0%, rgba(20, 20, 20, 0.84) 55%, rgba(20, 20, 20, 0.96) 100%),
    linear-gradient(to top, rgba(20, 20, 20, 0.86) 0%, transparent 42%);
}

.hero-grain {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.24;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

.hero .wrap { position: relative; z-index: 3; }

.hero h1 {
  color: var(--ivory);
  max-width: 15ch;
  margin-bottom: 1.75rem;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.5);
}

/* Each line rises into place on load */
.hero-line { display: block; overflow: hidden; }
.hero-line > span {
  display: block;
  transform: translateY(105%);
  transition: transform 1.25s var(--ease) calc(var(--i, 0) * 130ms);
}
.loaded .hero-line > span { transform: translateY(0); }

.hero-sub {
  font-size: clamp(1rem, 1.5vw, 1.18rem);
  color: rgba(247, 245, 242, 0.74);
  max-width: 46ch;
  margin-bottom: 2.25rem;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}

.hero-fade {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 1s var(--ease) calc(0.5s + var(--i, 0) * 110ms),
              transform 1s var(--ease) calc(0.5s + var(--i, 0) * 110ms);
}
.loaded .hero-fade { opacity: 1; transform: none; }

.hero-actions { display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* Glass strip of destination facts along the hero foot */
.hero-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  margin-top: clamp(2rem, 4.5vh, 3.25rem);
  background: var(--line-light);
  border: 1px solid var(--line-light);
  border-radius: var(--radius);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.hero-strip > div {
  position: relative;
  background: rgba(247, 245, 242, 0.94);
  padding: 1.15rem 1.4rem;
  transition: background 0.45s var(--ease), transform 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
.hero-strip > div:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.hero-strip > div:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.hero-strip > div:hover {
  background: #E2DCD1;
  transform: scale(1.07);
  box-shadow: 0 18px 32px -14px rgba(23, 69, 107, 0.35);
  z-index: 2;
  border-radius: var(--radius);
}
.hero-strip strong {
  display: block;
  font-family: var(--display);
  font-size: 1.8rem;
  font-weight: 300;
  color: var(--blue-deep);
  line-height: 1;
  margin-bottom: 0.3rem;
  text-shadow: none;
}
.hero-strip > div > span {
  display: block;
  font-size: 0.63rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--blue);
}
/* The counter sits inside <strong> and must keep the display size. */
.hero-strip strong span { font-size: inherit; letter-spacing: inherit; text-transform: none; color: inherit; }

/* Editorial stat row - a plain divided line of figures rather than a card
   grid, to sit quietly on a content page (About) instead of the glassy
   hero-strip look that only makes sense floating over a photo. */
.stat-row {
  display: flex;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.stat-col {
  flex: 1 1 160px;
  text-align: center;
  padding: 2.25rem 1rem;
  border-left: 1px solid var(--line);
}
.stat-col:first-child { border-left: none; }
.stat-col strong {
  display: block;
  font-family: var(--display);
  font-size: clamp(2rem, 4vw, 2.6rem);
  font-weight: 300;
  color: var(--blue);
  line-height: 1;
  margin-bottom: 0.5rem;
}
.stat-col strong span { font-size: inherit; letter-spacing: inherit; color: inherit; }
.stat-col > span {
  display: block;
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-soft);
}
@media (max-width: 640px) {
  .stat-col { flex: 1 1 50%; border-left: none; border-top: 1px solid var(--line); }
  .stat-col:nth-child(-n+2) { border-top: none; }
}

/* ---------------------------------------------------------- hero slideshow */

/*
   A stack of full-bleed photos, one crossfading in over the last. Each slide
   is its own layer so the transition is a pure opacity fade — no layout shift,
   no flash of the wrong image. The active slide also drifts very slowly (a
   restrained Ken Burns) so a still photograph still feels cinematic.
*/
.hero-slideshow {
  position: absolute;
  inset: -8% 0 -8% 0;
  z-index: 0;
  overflow: hidden;
}

.hero-slide-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 2s var(--ease-soft), transform 2s var(--ease-soft);
  will-change: opacity, transform;
}
.hero-slide-bg.is-active {
  opacity: 1;
  transform: scale(1);
  transition: opacity 2s var(--ease-soft), transform 9s linear;
}

/* Same legibility wash the static hero-bg carries, so the slideshow and the
   placeholder-gradient hero read as one consistent treatment. Strengthened
   (was 0.58/0.68/0.88) for the same reason as .scene .veil above. */
.hero-slideshow::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(200deg, rgba(20,20,20,0.6) 0%, rgba(20,20,20,0.74) 55%, rgba(20,20,20,0.92) 100%),
    linear-gradient(to top, rgba(20,20,20,0.7) 0%, transparent 48%);
  pointer-events: none;
  transition: opacity 0.6s var(--ease);
}

/* The active slide's own ImageBrightness flag darkens the shared wash
   further — :has() lets one overlay element react to whichever slide is
   currently on top, since each slide can be a different photo entirely. */
.hero-slideshow:has(.hero-slide-bg.is-active.is-bright)::after {
  background:
    linear-gradient(200deg, rgba(20,20,20,0.72) 0%, rgba(20,20,20,0.84) 55%, rgba(20,20,20,0.96) 100%),
    linear-gradient(to top, rgba(20,20,20,0.86) 0%, transparent 42%);
}

/* Slide indicators: a column of thin rules rather than dots — quieter, and
   the active one reads as a measured progress mark. */
.hero-dots {
  position: absolute;
  right: clamp(1.5rem, 4vw, var(--gutter));
  bottom: clamp(5rem, 10vh, 7rem);
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.9rem;
}
.hero-dot {
  width: 22px; height: 1px;
  border: none;
  padding: 0;
  background: rgba(247, 245, 242, 0.45);
  cursor: pointer;
  transition: width 0.6s var(--ease), background 0.6s var(--ease);
}
.hero-dot:hover { background: var(--ivory); width: 30px; }
.hero-dot.is-active { background: var(--blue-bright); width: 46px; }

@media (max-width: 700px) { .hero-dots { display: none; } }

.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 10.5rem;
  transform: translateX(-50%);
  z-index: 4;
  display: grid;
  justify-items: center;
  gap: 0.7rem;
  font-size: 0.58rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(247, 245, 242, 0.5);
}
.scroll-cue i {
  width: 1px; height: 46px;
  background: linear-gradient(to bottom, rgba(247,245,242,0.45), transparent);
  position: relative;
  overflow: hidden;
}
.scroll-cue i::after {
  content: "";
  position: absolute;
  top: -46px; left: 0;
  width: 1px; height: 46px;
  background: var(--blue-bright);
  animation: cue 2.4s var(--ease-soft) infinite;
}
@keyframes cue {
  0% { top: -46px; }
  60%, 100% { top: 46px; }
}

@media (max-width: 700px) { .scroll-cue { display: none; } }

/* --------------------------------------------------------------- page header */

.page-hero {
  position: relative;
  min-height: 58vh;
  display: flex;
  align-items: flex-end;
  padding: 11rem 0 clamp(3rem, 6vw, 5rem);
  overflow: hidden;
  background: var(--char-900);
}
.page-hero .wrap { position: relative; z-index: 3; }
.page-hero h1 { color: var(--ivory); max-width: 16ch; text-shadow: 0 2px 16px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.5); }
.page-hero p { color: rgba(247, 245, 242, 0.74); max-width: 56ch; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.4); }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 245, 242, 0.5);
  margin-bottom: 1.5rem;
}
.breadcrumb a { transition: color 0.4s var(--ease); }
.breadcrumb a:hover { color: var(--blue-bright); }

/* ---------------------------------------------------------------- experience */

.exp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.exp-item {
  background: var(--ivory);
  padding: clamp(2rem, 3.5vw, 3rem);
  transition: background 0.6s var(--ease);
  position: relative;
  overflow: hidden;
}
.exp-item::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease);
}
.exp-item:hover { background: var(--white); }
.exp-item:hover::before { transform: scaleX(1); }
.exp-num {
  font-family: var(--display);
  font-size: 0.9rem;
  color: var(--blue);
  letter-spacing: 0.1em;
  display: block;
  margin-bottom: 1.5rem;
}
.exp-item h3 { margin-bottom: 0.7rem; }
.exp-item p { font-size: 0.93rem; margin: 0; }

/* --------------------------------------------------------- the Nokian idea */
/* 3-up / 2-row grid of image-left, text-right cards, uniform size. */

.idea-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
  gap: 1.5rem;
}
.idea-card {
  position: relative;
  display: flex;
  min-height: 300px;
  background: var(--ivory);
  border: 1px solid var(--line);
  border-radius: 15px;
  overflow: hidden;
  isolation: isolate;
  box-shadow: 0 2px 6px rgba(23, 69, 107, 0.06), 0 14px 30px -18px rgba(23, 69, 107, 0.22);
  transition: box-shadow 0.55s var(--ease), transform 0.55s var(--ease), border-color 0.55s var(--ease), background 0.55s var(--ease);
}
.idea-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  box-shadow: 0 0 0 1px var(--blue), 0 24px 34px -14px rgba(23, 69, 107, 0.4), 0 48px 80px -24px rgba(23, 69, 107, 0.55);
  opacity: 0;
  transition: opacity 0.55s var(--ease);
  pointer-events: none;
}
/* A thin accent bar that grows down the seam between image and text */
.idea-card::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--blue-bright), var(--blue-deep));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.6s var(--ease);
  z-index: 2;
}
.idea-card:hover {
  transform: translateY(-9px) scale(1.02);
  border-color: transparent;
}
.idea-card:hover::after { opacity: 1; }
.idea-card:hover::before { transform: scaleY(1); }

/* A light sweeping sheen across the image, instead of a flat colour wash */
.idea-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.28) 48%, transparent 66%);
  transform: translateX(-120%);
  pointer-events: none;
}
.idea-card:hover .idea-media::before {
  transform: translateX(120%);
  transition: transform 1.1s var(--ease);
}

.idea-media {
  position: relative;
  width: 50%;
  flex-shrink: 0;
  background: var(--char-800);
  overflow: hidden;
}
.idea-media:not(.has-image) {
  background: linear-gradient(160deg, var(--blue-deep), var(--blue) 65%, var(--blue-bright));
}
.idea-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(200deg, rgba(23, 69, 107, 0.35), rgba(23, 69, 107, 0) 60%);
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.idea-card:hover .idea-media::after { opacity: 1; }
.idea-card:hover .idea-media .scene-img { transform: scale(1.12); }
.idea-media .scene-img { transition: transform 1s var(--ease); }

.idea-body {
  flex: 1;
  min-width: 0;
  padding: clamp(1.25rem, 2.2vw, 1.75rem);
  display: flex;
  flex-direction: column;
  transition: transform 0.55s var(--ease);
}
.idea-card:hover .idea-body { transform: translateX(4px); }
.idea-num {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--blue);
  letter-spacing: 0.03em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.7rem;
  height: 2.7rem;
  border-radius: 50%;
  border: 1px solid var(--blue-soft);
  margin-bottom: 1rem;
  transition: background 0.5s var(--ease), color 0.5s var(--ease), border-color 0.5s var(--ease), transform 0.5s var(--ease);
}
.idea-card:hover .idea-num {
  background: var(--blue);
  color: var(--white);
  border-color: var(--blue);
  transform: scale(1.1);
}
.idea-body h3 { margin-bottom: 0.6rem; font-size: clamp(1.4rem, 1.9vw, 1.75rem); line-height: 1.15; transition: color 0.4s var(--ease); }
.idea-card:hover .idea-body h3 { color: var(--blue-deep); }
.idea-desc {
  font-size: 0.9rem;
  color: var(--text-soft);
  margin: 0;
  overflow: hidden;
}
.idea-desc.is-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
}
.idea-readmore {
  margin-top: 0.6rem;
  align-self: flex-start;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue);
  cursor: pointer;
  transition: color 0.3s var(--ease);
}
.idea-readmore:hover { color: var(--blue-deep); }

@media (max-width: 980px) {
  .idea-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .idea-grid { grid-template-columns: 1fr; }
  .idea-card { flex-direction: column; min-height: 0; }
  .idea-media { width: 100%; aspect-ratio: 16/9; }
  .idea-card::before { left: 0; right: 0; top: auto; bottom: calc(100% - 1px); height: 3px; width: auto; transform: scaleX(0); }
  .idea-card:hover::before { transform: scaleX(1); }
  .idea-card:hover .idea-body { transform: none; }
}

/* ----------------------------------------------------------- destination cards */

.dest-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.dest {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--char-800);
  aspect-ratio: 4 / 5;
  isolation: isolate;
}
.dest .scene { position: absolute; inset: 0; }
.dest:hover .scene::before,
.dest:hover .scene-img { transform: scale(1.07); }

/* .scene relies on an absolutely-positioned ancestor to give it a height —
   without this, a bare .scene inside .split-media collapses to 0px tall
   (its only child, the img, is itself position:absolute and so contributes
   no height), rendering as a blank box despite the image loading fine.
   Previously patched per-instance with an inline style; fixed generally
   here so every future .split-media/.scene pairing works without it. */
.split-media .scene, .split-media .inset .scene { position: absolute; inset: 0; }

.dest-body {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 4;
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  color: var(--ivory);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
}
/* A gradient wash that rises to fill just the text block (not the whole
   card) on hover, so copy stays readable over any image the admin uploads. */
.dest-body::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(23, 69, 107, 0.94) 0%, rgba(44, 111, 168, 0.62) 55%, rgba(44, 111, 168, 0) 100%);
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.dest:hover .dest-body::before { opacity: 1; }

/* Golden label deliberately kept off the blue system: it needs to read
   clearly against a small blue-glass chip rather than blend into the brand
   blue used everywhere else on the card. */
.dest-loc {
  font-size: 0.62rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #F0C568;
  margin-bottom: 0.8rem;
  display: inline-block;
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  background: rgba(44, 111, 168, 0.38);
  border: 1px solid rgba(95, 168, 219, 0.4);
  backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
}
.dest-body h3 {
  color: var(--ivory);
  font-size: clamp(1.55rem, 2.5vw, 2.1rem);
  margin-bottom: 0.5rem;
}
.dest-body p {
  color: rgba(247, 245, 242, 0.74);
  font-size: 0.91rem;
  margin: 0 0 1.1rem;
  max-width: 40ch;
  /* Copy is held back until hover so the image leads */
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.7s var(--ease), opacity 0.5s var(--ease), margin 0.7s var(--ease);
}
.dest:hover .dest-body p { max-height: 8rem; opacity: 1; }

.dest-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-light);
}
.dest-foot .link-arrow { color: var(--ivory); }

.dest-badge {
  position: absolute;
  top: 1.25rem; left: 1.25rem;
  z-index: 5;
}
/* Status badge and property-type tag on destination cards pick up the same
   blue-glass treatment as the location chip, instead of the generic neutral
   glass/outline styling used elsewhere. */
.dest-badge .pill.glass {
  background: rgba(44, 111, 168, 0.4);
  border-color: rgba(95, 168, 219, 0.45);
  color: var(--ivory);
}
.dest-foot .tag.on-dark {
  background: rgba(44, 111, 168, 0.34);
  border-color: rgba(95, 168, 219, 0.4);
  color: var(--ivory);
  backdrop-filter: blur(8px) saturate(150%);
  -webkit-backdrop-filter: blur(8px) saturate(150%);
}
.dest-foot .tag.on-dark:hover { background: rgba(44, 111, 168, 0.55); border-color: var(--blue-bright); color: var(--ivory); }

/* Wrapper used purely as the stagger/reveal target around a card */
.dest-wrap, .stay-wrap, .exp-wrap { display: block; }

/* Glass pill used over imagery */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.5em 1em;
  border-radius: var(--radius);
  background: var(--ivory-deep);
  color: var(--text);
}
.pill.glass {
  background: rgba(247, 245, 242, 0.12);
  border: 1px solid rgba(247, 245, 242, 0.3);
  color: var(--ivory);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.pill.live { background: rgba(44, 111, 168, 0.16); color: #17456B; }
.pill.soon { background: rgba(34, 34, 34, 0.07); color: var(--text-soft); }
.pill.muted { background: var(--ivory-deep); color: var(--text-soft); }

.tag-row { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.tag {
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  padding: 0.4em 0.95em;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text-soft);
  transition: border-color 0.4s var(--ease), color 0.4s var(--ease), background 0.4s var(--ease);
}
.tag:hover { border-color: var(--blue); color: var(--blue); }
.tag.on-dark { border-color: var(--line-light); color: rgba(247, 245, 242, 0.82); }
.tag.on-dark:hover { border-color: var(--blue-bright); color: var(--blue-bright); }

/* ------------------------------------------------------------- editorial split */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: clamp(2rem, 6vw, 6rem);
  align-items: center;
}
.split.reverse > *:first-child { order: 2; }
@media (max-width: 780px) { .split.reverse > *:first-child { order: 0; } }
.split.align-top { align-items: start; }

.split-media {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.split-media.tall { aspect-ratio: 3 / 4; }

/* A smaller frame that overlaps the main one, for depth */
.split-media .inset {
  position: absolute;
  right: -12%;
  bottom: -8%;
  width: 46%;
  aspect-ratio: 1;
  border-radius: var(--radius-lg);
  border: 10px solid var(--ivory);
  overflow: hidden;
  z-index: 5;
  box-shadow: var(--shadow);
}
@media (max-width: 640px) { .split-media .inset { display: none; } }

.split-body h2 { margin-bottom: 1.25rem; }
.property-logo { max-height: 56px; max-width: 220px; object-fit: contain; margin-bottom: 1.5rem; }

/* --------------------------------------------------------------- stay cards */

.stay-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(1.25rem, 2.2vw, 1.85rem);
}

.stay {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform 0.7s var(--ease), box-shadow 0.7s var(--ease), border-color 0.7s var(--ease);
}
.stay::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 1px var(--blue-soft);
  opacity: 0;
  transition: opacity 0.5s var(--ease);
  pointer-events: none;
}
.stay:hover {
  transform: translateY(-7px);
  box-shadow: 0 30px 55px -22px rgba(23, 69, 107, 0.4);
  border-color: transparent;
}
.stay:hover::after { opacity: 1; }
.stay-media { aspect-ratio: 16 / 11; position: relative; overflow: hidden; }
.stay-media .scene { position: absolute; inset: 0; }
.stay-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(23, 69, 107, 0.28), transparent 55%);
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.stay:hover .stay-media::after { opacity: 1; }
.stay:hover .stay-media .scene::before,
.stay:hover .stay-media .scene-img { transform: scale(1.08); }

.stay-body { padding: 1.65rem 1.65rem 0; flex: 1; }
.stay-body h3 { transition: color 0.4s var(--ease); }
.stay:hover .stay-body h3 { color: var(--blue-deep); }
.stay-loc {
  font-size: 0.61rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text-faint);
  display: block;
  margin-bottom: 0.5rem;
}
.stay-body h3 { font-size: 1.38rem; margin-bottom: 0.5rem; }
.stay-body p { font-size: 0.91rem; margin-bottom: 1rem; }

/* Plain text line - no boxed pills for occupancy / extra-bed / unit count */
.stay-meta {
  font-size: 0.8rem;
  color: var(--text-faint);
  margin: -0.4rem 0 1rem;
}

.stay-foot {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.1rem 1.65rem 1.5rem;
  margin-top: auto;
  border-top: 1px solid var(--line);
}
.stay-foot .price { justify-content: flex-start; }
.stay-cta { width: 100%; }

.price {
  font-family: var(--sans);
  font-size: 1.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  line-height: 1;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}
.price small {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* A single, consistent way to set a rupee figure wherever one appears
   inline (rate lists, additional services, extra-bed cost) rather than
   every spot inheriting plain body text — same family/weight as the card
   .price above, at text scale, so every price on the site reads as one
   deliberate style instead of several ad-hoc ones. */
.price-tag {
  font-family: var(--sans);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
}
.price-tag .basis {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-left: 0.3rem;
}
.band-dark .price-tag, .band-green .price-tag { color: var(--ivory); }
.band-dark .price-tag .basis, .band-green .price-tag .basis { color: rgba(247, 245, 242, 0.6); }

/* --------------------------------------------------------------- venue rows */

.venue-list { display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }

.venue-row {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr) auto;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  background: var(--ivory);
  padding: clamp(1.75rem, 3.5vw, 2.6rem) 0;
  transition: background 0.6s var(--ease), padding-inline 0.6s var(--ease);
}
.venue-row:hover { background: var(--white); padding-inline: clamp(0rem, 1.5vw, 1.5rem); }
@media (max-width: 860px) {
  .venue-row { grid-template-columns: 1fr; gap: 1rem; }
  .venue-row:hover { padding-inline: 0; }
}

.venue-title { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.venue-title h3 { margin: 0; }
.venue-cap {
  font-family: var(--display);
  font-size: 1.5rem;
  color: var(--blue);
  white-space: nowrap;
}
.venue-cap small {
  font-family: var(--sans);
  font-size: 0.58rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-left: 0.35rem;
}

/* ------------------------------------------------------------------- bands */

.band-sand { background: var(--ivory-deep); }
.band-beige { background: var(--ivory-deep); }

.band-dark, .band-green {
  background: linear-gradient(155deg, var(--char-900) 0%, var(--char-800) 45%, var(--blue-deep) 130%);
  color: var(--ivory);
  position: relative;
  overflow: hidden;
}
.band-dark::before, .band-green::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(55% 55% at 84% 8%, rgba(95, 168, 219, 0.32), transparent 62%),
    radial-gradient(50% 58% at 8% 94%, rgba(44, 111, 168, 0.28), transparent 68%);
  pointer-events: none;
}
.band-dark > *, .band-green > * { position: relative; z-index: 2; }

/* Optional admin-uploaded video/image behind a CTA band (see
   PageSection::ctaMediaFor()) — sits under the decorative gradient above,
   which becomes a plain dark scrim instead so the text stays readable over
   a photo/video the same way it already reads over the plain gradient. */
.band-dark.has-cta-media, .band-green.has-cta-media { background: var(--char-900); }
.band-dark.has-cta-media::before, .band-green.has-cta-media::before {
  background: linear-gradient(155deg, rgba(20, 20, 20, 0.78) 0%, rgba(20, 20, 20, 0.5) 55%, rgba(23, 69, 107, 0.72) 100%);
}
.cta-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.cta-media video, .cta-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.band-dark h2, .band-dark h3, .band-dark h4,
.band-green h2, .band-green h3, .band-green h4 { color: var(--ivory); }
.band-dark p, .band-green p { color: rgba(247, 245, 242, 0.70); }
.band-dark .lede, .band-green .lede { color: rgba(247, 245, 242, 0.78); }

/* --------------------------------------------------------------- amenities */

.amenity-set { display: grid; gap: 2.25rem; }
.amenity-group h4 {
  font-family: var(--sans);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 1rem;
}
.amenity-list {
  list-style: none;
  padding: 0; margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.65rem 1.5rem;
}
.amenity-list li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding-left: 0;
  font-size: 0.92rem;
  color: var(--text-soft);
}
/* When the amenity/complimentary has an icon set in admin, .ico renders it;
   otherwise fall back to a plain dot so the list still reads cleanly. */
.amenity-list li .ico {
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
  color: var(--blue);
  transition: color 0.4s var(--ease);
}
.amenity-list li:not(:has(.ico)) { padding-left: 1.5rem; }
.amenity-list li:not(:has(.ico))::before {
  content: "";
  position: absolute;
  left: 0; top: 0.66em;
  width: 6px; height: 6px;
  border: 1px solid var(--blue);
  transition: background 0.4s var(--ease);
}
.amenity-list li:hover .ico { color: var(--blue-deep); }
.amenity-list li:hover::before { background: var(--blue); }
.band-dark .amenity-list li, .band-green .amenity-list li { color: rgba(247, 245, 242, 0.82); }
.band-dark .amenity-list li .ico, .band-green .amenity-list li .ico { color: var(--blue-bright); }
.band-dark .amenity-group h4, .band-green .amenity-group h4 { color: var(--blue-bright); }

/* Card-grid variant - a light, editorial alternative to dropping the
   amenity list straight onto a dark/blue band. Each category becomes its
   own bordered card in a responsive grid rather than a two-column split. */
.amenity-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.25rem;
}
.amenity-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.75rem;
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease), transform 0.4s var(--ease);
}
.amenity-card:hover {
  border-color: var(--blue-soft);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}
.amenity-card .amenity-group h4 { margin-bottom: 1.1rem; }
.amenity-card .amenity-list {
  grid-template-columns: 1fr;
  gap: 0.65rem;
}

/* Plain point list for a property's headline facts (e.g. "700+ Seat
   Convention Hall") - reused inside the About section's left column, so it
   takes only that column's width rather than spanning as full-width cards. */
.feature-points {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.1rem;
}
.feature-points li {
  padding-left: 1.4rem;
  position: relative;
}
.feature-points li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 6px; height: 6px;
  border: 1px solid var(--blue);
}
.feature-points strong {
  display: block;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
  margin-bottom: 0.15rem;
}
.feature-points span { font-size: 0.88rem; color: var(--text-soft); }

/* ---------------------------------------------------------------- gallery */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem;
}
.gallery-grid figure {
  margin: 0;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
  background: var(--char-800);
}
/* Every sixth tile spans two columns, breaking the grid's regularity so the
   page reads as a curated layout rather than a uniform contact sheet. */
.gallery-grid figure:nth-child(6n + 1) { grid-column: span 2; aspect-ratio: 16 / 10; }
@media (max-width: 700px) { .gallery-grid figure:nth-child(6n + 1) { grid-column: span 1; aspect-ratio: 4 / 3; } }
.gallery-grid img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.gallery-grid figure:hover img { transform: scale(1.06); }
.gallery-grid figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 1.75rem 1.25rem 1rem;
  background: linear-gradient(to top, rgba(15, 30, 43, 0.85), transparent);
  color: var(--ivory);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
  pointer-events: none;
}
.gallery-grid figure:hover figcaption { opacity: 1; transform: translateY(0); }

/* Natural-aspect gallery variant (destination/private wedding pages) - a
   true masonry: every photo keeps its own shot aspect ratio (portrait stays
   portrait, landscape stays landscape - no cropping), but each also gets a
   genuinely different on-page size, not just "full column width, height
   varies". public/js/site.js measures each photo once its natural size is
   known and sets --gspan (row-span) here; occasional tiles are also given
   extra column width below, so the whole thing reads as a curated, mixed
   collage rather than a uniform contact sheet. */
.gallery-grid-natural {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  grid-auto-rows: 10px;
  grid-auto-flow: dense;
  gap: 1rem;
}
.gallery-grid-natural figure {
  margin: 0;
  grid-row-end: span var(--gspan, 40);
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
  background: var(--char-800);
}
/* A rotating minority of tiles run wider, so photos don't all read at the
   same visual weight - still never cropped, just given more width to
   render their own (now taller-looking) natural shape at. */
.gallery-grid-natural figure:nth-of-type(5n+1) { grid-column: span 2; }
.gallery-grid-natural img {
  display: block;
  width: 100%;
  height: 100%;
  /* The JS sizes each tile to match its photo's own ratio, so cover has
     nothing real to crop - it only ever trims the sub-pixel rounding slack
     from snapping to the row-unit grid, which is imperceptible. Using cover
     rather than contain avoids the visible dark letterbox bar that shows
     up whenever that rounding gap isn't perfectly zero. */
  object-fit: cover;
  transition: transform 1.2s var(--ease);
}
.gallery-grid-natural figure:hover img { transform: scale(1.04); }
@media (max-width: 700px) {
  .gallery-grid-natural { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
  .gallery-grid-natural figure:nth-of-type(5n+1) { grid-column: span 2; }
}

/* Both grid variants are click-to-preview - see the shared #lightbox below,
   wired generically in site.js against any .gallery-grid/.gallery-grid-natural
   figure on the page, no per-page JS needed. */
.gallery-grid figure, .gallery-grid-natural figure { cursor: zoom-in; }

/* ------------------------------------------------------------- lightbox */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 15, 15, 0.94);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease);
  padding: clamp(1.5rem, 5vw, 4rem);
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: var(--shadow-lg);
  user-select: none;
}
.lightbox-close,
.lightbox-nav {
  position: absolute;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--line-light);
  color: var(--ivory);
  cursor: pointer;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
}
.lightbox-close:hover,
.lightbox-nav:hover { background: rgba(255, 255, 255, 0.18); border-color: rgba(255, 255, 255, 0.4); }
.lightbox-close {
  top: clamp(0.75rem, 3vw, 1.75rem);
  right: clamp(0.75rem, 3vw, 1.75rem);
  width: 44px; height: 44px;
  border-radius: 50%;
  font-size: 1.6rem;
  line-height: 1;
}
.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 52px; height: 52px;
  border-radius: 50%;
  font-size: 2rem;
  line-height: 1;
}
.lightbox-prev { left: clamp(0.5rem, 3vw, 2rem); }
.lightbox-next { right: clamp(0.5rem, 3vw, 2rem); }
.lightbox-count {
  position: absolute;
  bottom: clamp(0.75rem, 3vw, 1.75rem);
  left: 50%;
  transform: translateX(-50%);
  color: rgba(247, 245, 242, 0.75);
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
}
@media (max-width: 640px) {
  .lightbox-nav { width: 42px; height: 42px; font-size: 1.6rem; }
}

.tag.is-active { background: var(--blue); border-color: var(--blue); color: var(--white); }
.tag.on-dark.is-active { background: var(--blue-bright); border-color: var(--blue-bright); color: var(--char-900); }

/* -------------------------------------------------------------- cards / grid */

.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* Plain content card — the light counterpart to .dest */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform 0.7s var(--ease), box-shadow 0.7s var(--ease), border-color 0.7s var(--ease);
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: transparent; }
.card-body { padding: clamp(1.5rem, 2.5vw, 2rem); flex: 1; }
.card-body h3 { margin-bottom: 0.6rem; }
.card-body p:last-child { margin-bottom: 0; }
.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem clamp(1.5rem, 2.5vw, 2rem) clamp(1.5rem, 2.5vw, 2rem);
  border-top: 1px solid var(--line);
  margin-top: auto;
}
.card-loc {
  font-size: 0.61rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 0.5rem;
}

/* ---------------------------------------------------------- feature list */
/* An editorial, non-boxed alternative to a grid of cards — numbered rows
   separated by hairlines, for text-led content (advantages, steps, types)
   that doesn't need a photo. Used on the wedding pages in place of what
   used to be several stacked card grids. */

.feature-list {
  border-top: 1px solid var(--line);
}
.feature-list.cols-2 {
  columns: 2;
  column-gap: clamp(2rem, 4vw, 4rem);
}
@media (max-width: 780px) {
  .feature-list.cols-2 { columns: 1; }
}

.feature-row {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  align-items: baseline;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding: clamp(1.5rem, 3vw, 2.25rem) 0;
  border-bottom: 1px solid var(--line);
  break-inside: avoid;
  transition: padding-left 0.5s var(--ease);
}
.feature-row:hover { padding-left: 0.6rem; }
/* Kept in case a numbered variant is wanted again later - unused now that
   every .feature-row list dropped its 01/02 step numbers. */
.feature-num {
  font-family: var(--display);
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  font-weight: 300;
  line-height: 1;
  color: var(--line);
  transition: color 0.5s var(--ease);
}
.feature-row:hover .feature-num { color: var(--blue); }
.feature-row h3 {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  margin-bottom: 0.4rem;
}
.feature-row p { color: var(--text-soft); font-size: 0.92rem; margin: 0; max-width: 52ch; }
.band-dark .feature-row, .band-green .feature-row { border-bottom-color: var(--line-light); }
.band-dark .feature-num, .band-green .feature-num { color: rgba(247, 245, 242, 0.28); }
.band-dark .feature-row:hover .feature-num, .band-green .feature-row:hover .feature-num { color: var(--blue-bright); }
.band-dark .feature-row p, .band-green .feature-row p { color: rgba(247, 245, 242, 0.68); }

/* Photographic variant for a name + location + note list (guest stays) —
   a real rectangular photo rather than a bare text row, but still a single
   flowing list rather than a grid of separate boxed cards. */
.feature-row.with-thumb {
  grid-template-columns: clamp(6rem, 14vw, 9rem) 1fr;
  align-items: center;
}
.feature-thumb {
  position: relative;
  width: clamp(6rem, 14vw, 9rem);
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--char-800);
}
.feature-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.feature-row.with-thumb:hover .feature-thumb img { transform: scale(1.08); }

/* A tall photo alongside a feature-list, for the advantage-point sections
   that don't have a natural per-item image (why choose / what makes it
   special) but still deserve a strong visual anchor. */
.feature-split {
  display: grid;
  grid-template-columns: minmax(280px, 0.85fr) 1.15fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.feature-split-media {
  position: sticky;
  top: 6.5rem;
  aspect-ratio: 5 / 6;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.feature-split .feature-list { flex: 1; }
@media (max-width: 900px) {
  .feature-split { grid-template-columns: 1fr; }
  .feature-split-media { position: static; }
}

/* ------------------------------------------------------- journey (image rows) */
/* Alternating photo/text rows for a step-by-step journey — each step gets
   its own image where the admin has set one, falling back to a plain text
   row (no broken box) when it hasn't. */

.journey-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.journey-row.reverse > *:first-child { order: 2; }
@media (max-width: 780px) { .journey-row.reverse > *:first-child { order: 0; } }
.journey-row:not(:last-child) { margin-bottom: clamp(3rem, 7vw, 5.5rem); }
.journey-media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.journey-media .scene-img { transition: transform 1.1s var(--ease); }
.journey-row:hover .journey-media .scene-img { transform: scale(1.05); }
.journey-num {
  font-family: var(--display);
  font-size: 0.9rem;
  color: var(--blue);
  letter-spacing: 0.1em;
  display: block;
  margin-bottom: 0.6rem;
}
.journey-body h3 { font-size: clamp(1.5rem, 2.6vw, 2rem); margin-bottom: 0.6rem; }
.journey-body p { color: var(--text-soft); max-width: 46ch; }

/* Text-only step, when no image is set for that item yet */
.journey-row.no-media { grid-template-columns: 1fr; }
.journey-row.no-media .journey-body { max-width: 60ch; }

/* ------------------------------------------------------------------- forms */

.panel {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.panel + .panel { margin-top: 1.25rem; }
.panel h3 { font-size: 1.3rem; margin-bottom: 1.25rem; }

.field { margin-bottom: 1.3rem; }
.field label {
  display: block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: 0.55rem;
}
.field label .req { color: var(--blue); }

.field input, .field select, .field textarea {
  width: 100%;
  padding: 0.9rem 0;
  border: none;
  border-bottom: 1px solid var(--line);
  background: transparent;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--text);
  border-radius: 0;
  transition: border-color 0.45s var(--ease);
}
.field select {
  padding-right: 1.5rem;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-soft) 50%),
                    linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
  background-position: calc(100% - 12px) 55%, calc(100% - 7px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--blue);
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-faint); }
.field textarea { resize: vertical; min-height: 92px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }
.field-error { color: #9A3434; font-size: 0.8rem; margin-top: 0.4rem; }

/* ------------------------------------------------------------ booking calendar */

.booking-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}
@media (max-width: 980px) { .booking-layout { grid-template-columns: 1fr; } }

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}
.cal-title { font-family: var(--display); font-size: 1.5rem; font-weight: 400; color: var(--text); }
.cal-nav { display: flex; gap: 0.5rem; }
.cal-nav button {
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.cal-nav button:hover:not(:disabled) { background: var(--char-800); color: var(--ivory); border-color: var(--char-800); }
.cal-nav button:disabled { opacity: 0.3; cursor: not-allowed; }

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow {
  text-align: center;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-bottom: 0.5rem;
}
.cal-day {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  overflow: hidden;
  border: 1px solid transparent;
  /* A day cell is only ~37-40px across, so the site-wide 15px radius reads
     as a near-circle here and the two-line (date + rate) content doesn't
     sit well inside it. Kept deliberately smaller than var(--radius). */
  border-radius: 6px;
  background: var(--ivory-deep);
  color: var(--text);
  font-family: var(--sans);
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.cal-day .rate { font-size: 0.58rem; color: var(--text-faint); }
.cal-day:hover:not(:disabled) { background: var(--white); border-color: var(--blue); transform: scale(1.06); z-index: 2; }
.cal-day.empty { background: transparent; cursor: default; }
.cal-day:disabled {
  background: transparent;
  color: var(--text-faint);
  text-decoration: line-through;
  cursor: not-allowed;
  opacity: 0.55;
}
.cal-day:disabled .rate { display: none; }
.cal-day.selected { background: var(--char-800); border-color: var(--char-800); color: var(--ivory); font-weight: 600; }
.cal-day.selected .rate { color: rgba(247, 245, 242, 0.7); }
.cal-day.in-range { background: var(--blue-soft); }
.cal-day.range-end { background: var(--blue); border-color: var(--blue); color: var(--white); }
.cal-day.range-end .rate { color: rgba(255, 255, 255, 0.78); }

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 1.25rem;
  font-size: 0.72rem;
  color: var(--text-soft);
}
.cal-legend span { display: flex; align-items: center; gap: 0.5rem; }
.swatch { width: 13px; height: 13px; border-radius: 2px; display: inline-block; }
.swatch.free { background: var(--ivory-deep); }
.swatch.sel { background: var(--char-800); }
.swatch.gone { border: 1px solid var(--line); }

.pay-options { display: grid; gap: 0.8rem; }
.pay-option {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem;
  align-items: start;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.4s var(--ease), background 0.4s var(--ease);
}
.pay-option:hover { border-color: var(--blue); background: var(--ivory); }
.pay-option input { margin-top: 0.3rem; accent-color: var(--blue); }
.pay-option strong { display: block; font-size: 0.94rem; color: var(--text); margin-bottom: 0.15rem; }
.pay-option span { font-size: 0.85rem; color: var(--text-soft); }
.pay-option.is-disabled { opacity: 0.5; cursor: not-allowed; background: var(--ivory-deep); }

.summary { position: sticky; top: 100px; }
.summary-rows { margin: 1.25rem 0; }
.summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  font-size: 0.9rem;
  color: var(--text-soft);
}
.summary-row span:last-child { font-variant-numeric: tabular-nums; color: var(--text); }
/* Longer free-text values (e.g. a postal address) read better left-aligned
   and wrapping under their own width than squeezed flush-right next to a
   short label like the numeric rows above it. */
.summary-row-wrap { align-items: flex-start; }
.summary-row-wrap span:last-child { text-align: left; max-width: 62%; }
.summary-row.total {
  border-top: 1px solid var(--line);
  margin-top: 0.5rem;
  padding-top: 1rem;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--text);
}
.summary-row.total span:last-child { color: var(--text); }
.summary-empty { color: var(--text-faint); font-size: 0.91rem; padding: 1.25rem 0; }

.notice {
  padding: 0.95rem 1.2rem;
  border-radius: var(--radius);
  font-size: 0.9rem;
  margin-bottom: 1.25rem;
  border-left: 2px solid currentColor;
}
.notice-info { background: var(--ivory-deep); color: var(--text-soft); }
.notice-warn { background: #FBF4E8; color: #8A6A32; }
.notice-error { background: #FBEAEA; color: #9A3434; }
.notice-ok { background: #EDF3EE; color: #3B6B3F; }

/* ------------------------------------------------------------ floating actions */

.quick-actions {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 150;
  display: grid;
  gap: 0.6rem;
}
.qa-btn {
  position: relative;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--char-800);
  color: var(--ivory);
  font-size: 1.05rem;
  box-shadow: var(--shadow);
  transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
.qa-btn:hover { transform: translateY(-3px) scale(1.05); box-shadow: var(--shadow-lg); }
.qa-btn.wa { background: #25D366; }
.qa-btn.bronze { background: var(--blue); }

.qa-btn::after {
  content: attr(data-label);
  position: absolute;
  right: calc(100% + 0.6rem);
  top: 50%;
  transform: translateY(-50%) translateX(6px);
  white-space: nowrap;
  background: var(--char-800);
  color: var(--ivory);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.45em 0.8em;
  border-radius: var(--radius);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.qa-btn:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }

@media (max-width: 600px) {
  .quick-actions { right: 0.9rem; bottom: 0.9rem; }
  .qa-btn { width: 42px; height: 42px; }
  .qa-btn::after { display: none; }
}

/* ------------------------------------------------------------------- footer */

.site-footer {
  background: linear-gradient(165deg, var(--char-900) 0%, var(--char-900) 55%, var(--blue-deep) 145%);
  color: var(--ivory);
  padding: clamp(4rem, 8vw, 7rem) 0 2rem;
  position: relative;
  overflow: hidden;
}
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(60% 60% at 12% 0%, rgba(44, 111, 168, 0.24), transparent 62%),
    radial-gradient(55% 55% at 95% 100%, rgba(95, 168, 219, 0.18), transparent 65%);
  pointer-events: none;
}
.site-footer .wrap { position: relative; z-index: 2; }

.footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--line-light);
}
@media (max-width: 900px) { .footer-top { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-top { grid-template-columns: 1fr; } }

.footer-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--display);
  font-size: 2rem;
  font-weight: 400;
  letter-spacing: 0.06em;
  color: var(--ivory);
  margin-bottom: 1rem;
}
/* The footer floor is always dark, so the wordmark stays white here
   unconditionally - no stuck/solid header state to react to. */
.footer-word-img { height: 0.85em; filter: brightness(0) invert(1); }
.footer-brand .dot { color: var(--blue); }

.site-footer h4 {
  font-family: var(--sans);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 1.25rem;
}
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: 0.7rem; font-size: 0.92rem; color: rgba(247, 245, 242, 0.7); }
.site-footer a { transition: color 0.4s var(--ease), padding-left 0.4s var(--ease); }
.site-footer a:hover { color: var(--blue-bright); }
.site-footer ul a:hover { padding-left: 0.35rem; }

.newsletter { display: flex; gap: 0.6rem; margin-top: 1rem; max-width: 360px; }
.newsletter input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line-light);
  color: var(--ivory);
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.6rem 0;
}
.newsletter input::placeholder { color: rgba(247, 245, 242, 0.35); }
.newsletter input:focus { outline: none; border-bottom-color: var(--blue); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 2rem;
  font-size: 0.78rem;
  color: rgba(247, 245, 242, 0.42);
}

/* --------------------------------------------------------------- animation */

/*
   Every reveal is opt-in via a class and driven by IntersectionObserver in
   site.js. `--i` on an element staggers it within its group.
*/
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.9s var(--ease) calc(var(--i, 0) * 90ms),
              transform 0.9s var(--ease) calc(var(--i, 0) * 90ms);
}
.reveal.visible { opacity: 1; transform: none; }

.reveal-fade {
  opacity: 0;
  transition: opacity 1.1s var(--ease) calc(var(--i, 0) * 90ms);
}
.reveal-fade.visible { opacity: 1; }

.reveal-lines .line { display: block; overflow: hidden; }
.reveal-lines .line > span {
  display: block;
  transform: translateY(104%);
  transition: transform 1.1s var(--ease) calc(var(--i, 0) * 110ms);
}
.reveal-lines.visible .line > span { transform: translateY(0); }

/* Image mask-reveal: an ivory curtain wipes up off the photo while it settles
   back from a slight scale — together they read as a camera move rather than
   a fade. Applied to any element wrapping an image.

   The curtain is a pseudo-element, not clip-path on the observed box itself:
   clipping the target's own box down to zero height also zeroes its measured
   intersection ratio, so IntersectionObserver can never report it as visible
   and it stays hidden forever. A sibling curtain keeps the box's real
   geometry intact for the observer while still producing the wipe visually. */
.reveal-mask { position: relative; overflow: hidden; }
.reveal-mask::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 6;
  background: var(--ivory);
  transform-origin: top;
  transition: transform 1.15s var(--ease) calc(var(--i, 0) * 100ms);
}
.reveal-mask.visible::before { transform: scaleY(0); }
.reveal-mask img, .reveal-mask .scene-img {
  transform: scale(1.14);
  transition: transform 1.8s var(--ease) calc(var(--i, 0) * 100ms);
}
.reveal-mask.visible img, .reveal-mask.visible .scene-img { transform: scale(1); }

.parallax { will-change: transform; }

/* -------------------------------------------------------------------- prose */

.prose { max-width: 68ch; }
.prose p { font-size: 1.02rem; line-height: 1.85; }
.prose h2, .prose h3 { margin-top: 2.5rem; }
.prose > *:first-child { margin-top: 0; }

/* ---------------------------------------------------------------- utilities */

.stack { display: grid; gap: 1.25rem; }
.center { text-align: center; }
.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.muted { color: var(--text-faint); }
.mb-0 { margin-bottom: 0 !important; }
.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }

/* --------------------------------------------------------- reduced motion */

/*
   Anything that moves is switched off wholesale here, and every reveal is
   forced to its resting state so no content can be left invisible.
*/
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .reveal, .reveal-fade { opacity: 1; transform: none; }
  .reveal-mask::before { transform: scaleY(0); }
  .reveal-mask img, .reveal-mask .scene-img { transform: none; }
  .reveal-lines .line > span, .hero-line > span { transform: none; }
  .hero-fade { opacity: 1; transform: none; }
  .hero-slide-bg.is-active { transform: none; }
  .parallax { transform: none !important; }
}

/* ----------------------------------------------------------- search widget */

/*
   A compact booking.com-style search bar: date range + guest counts in one
   row, with the calendar living in a small dropdown instead of taking up
   half the page. Sits just under the hero on a facility's booking page.
*/
.search-widget {
  position: relative;
  z-index: 20;
  margin-top: -3.25rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
}
@media (max-width: 900px) { .search-widget { margin-top: -2rem; } }

.search-field {
  position: relative;
  flex: 1 1 150px;
  min-width: 130px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-right: 1px solid var(--line);
}
.search-field:last-of-type { border-right: none; }
.search-field > label.search-field-label { padding: 0.95rem 1.25rem 0 1.25rem; }

.search-field-btn {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.2rem;
  padding: 0.95rem 1.25rem;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--sans);
  transition: background 0.3s var(--ease);
}
.search-field-btn:hover { background: var(--ivory); }
.search-field-label {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.search-field-value {
  font-size: 0.94rem;
  color: var(--text);
  font-weight: 500;
}
.search-field-value.is-placeholder { color: var(--text-faint); font-weight: 400; }

.search-field select {
  width: 100%;
  padding: 0.3rem 1.25rem 0.95rem 1.25rem;
  border: none;
  background: transparent;
  font-family: var(--sans);
  font-size: 0.94rem;
  color: var(--text);
  cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-soft) 50%),
                    linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
  background-position: calc(100% - 20px) 58%, calc(100% - 15px) 58%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.search-field select:hover { background-color: var(--ivory); }
.search-field select:focus { outline: none; }

.search-cta {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 0.6rem;
}
.search-cta .btn { width: 100%; white-space: nowrap; }

@media (max-width: 760px) {
  .search-widget { flex-direction: column; }
  .search-field { border-right: none; border-bottom: 1px solid var(--line); }
  .search-cta { padding: 0.85rem; }
}

/* The calendar dropdown itself — a small popover anchored under the date
   field, reusing the .cal-* primitives at a fraction of their original
   width so the grid cells shrink to match. */
.cal-popover {
  position: absolute;
  top: calc(100% + 0.6rem);
  left: 0;
  z-index: 60;
  width: min(320px, 92vw);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 1.1rem 1.15rem 1.25rem;
  opacity: 0;
  transform: translateY(-8px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
}
.cal-popover.is-open {
  opacity: 1;
  transform: none;
  visibility: visible;
  pointer-events: auto;
}
.cal-popover .cal-title { font-size: 1.05rem; }
.cal-popover .cal-nav button { width: 30px; height: 30px; font-size: 0.9rem; }
.cal-popover .cal-day { font-size: 0.76rem; }
.cal-popover .cal-day .rate { font-size: 0.5rem; }
.cal-popover .cal-legend { font-size: 0.64rem; gap: 0.85rem; margin-top: 1rem; }
.cal-popover .swatch { width: 10px; height: 10px; }

/* A brief inline price readout inside the widget once both dates are picked */
.search-price {
  font-size: 0.78rem;
  color: var(--text-soft);
  margin-top: 0.15rem;
}
.search-price strong { color: var(--blue); font-weight: 600; }

/* -------------------------------------------------------------- full video */

/*
   A full-viewport-height video break — muted, looping, autoplaying,
   controls-free. Used sparingly (a property's page, at most) as a cinematic
   pause between content sections rather than a hero replacement.
*/
.full-video {
  position: relative;
  height: 100vh;
  overflow: hidden;
  background: var(--char-900);
}
/* Ultimate fallback when a section has neither a video nor an image set -
   a plain brand-blue gradient instead of a blank/broken box. */
.full-video.no-media {
  background: linear-gradient(160deg, var(--blue-deep), var(--blue) 60%, var(--blue-bright));
}
.full-video video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.full-video::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(20, 20, 20, 0.72) 0%, rgba(20, 20, 20, 0.15) 40%, transparent 60%);
  pointer-events: none;
}
.full-video-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: clamp(2rem, 5vw, 3.5rem) 0;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.45);
}
.full-video-caption p { color: rgba(247, 245, 242, 0.8); margin: 0; max-width: 46ch; }

.full-video-sound {
  position: absolute;
  right: clamp(1.25rem, 3vw, var(--gutter));
  bottom: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 3;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.4);
  border: 1px solid rgba(247, 245, 242, 0.35);
  color: var(--ivory);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
  font-size: 1rem;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}
.full-video-sound:hover { background: rgba(20, 20, 20, 0.6); border-color: var(--blue); }

@media (max-width: 700px) { .full-video { height: 70vh; } }

/* --------------------------------------------------------------- home film */
/* Admin-manageable cinematic strip after "Our Destinations". Falls back to
   a plain image (or a brand-blue gradient, if even that is unset) so the
   section never renders as a blank box before anyone has uploaded media. */

.film-band {
  padding: clamp(3rem, 6vw, 5rem) 0;
}
.film-section {
  position: relative;
  height: 82vh;
  min-height: 480px;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--blue-deep), var(--blue) 60%, var(--blue-bright));
  isolation: isolate;
}
.film-section video,
.film-section .film-fallback-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.film-section::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, rgba(15, 30, 43, 0.82) 0%, rgba(15, 30, 43, 0.35) 45%, rgba(15, 30, 43, 0.55) 100%);
  pointer-events: none;
}
.film-content {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
}
.film-play {
  position: absolute;
  right: clamp(1.25rem, 3vw, var(--gutter));
  bottom: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 3;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.4);
  border: 1px solid rgba(247, 245, 242, 0.35);
  color: var(--ivory);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
  font-size: 1rem;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}
.film-play:hover { background: rgba(44, 111, 168, 0.55); border-color: var(--blue-bright); }
.film-eyebrow {
  font-size: 0.68rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--blue-bright);
  margin-bottom: 1rem;
}
.film-heading { color: var(--ivory); max-width: 22ch; margin-bottom: 0.9rem; }
.film-sub { color: rgba(247, 245, 242, 0.78); max-width: 52ch; margin: 0; }

@media (max-width: 700px) { .film-section { height: 78vh; } }

/* ----------------------------------------------------------- enquiry modal */

/*
   A split modal — dark image panel on the left with a short brand line,
   the real enquiry form on the right. Same field set as the standalone
   /enquiry page (the modal is a presentation change, not a content one).
*/
.enquiry-modal {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.enquiry-modal[hidden] { display: none; }
.enquiry-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.62);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}

.enquiry-modal-box {
  position: relative;
  width: min(920px, 100%);
  max-height: 90vh;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  /* An implicit auto-height row sizes to its tallest child's full content
     height regardless of the container's max-height — max-height only ever
     clips the rendered box afterwards, it doesn't feed back into track
     sizing. minmax(0, 1fr) tells the row "shrink to 0 if needed, but never
     grow past whatever height max-height actually settled on" — which is
     what makes .enquiry-modal-form's overflow-y:auto engage for a long
     form instead of the submit button being pushed below the visible
     modal. */
  grid-template-rows: minmax(0, 1fr);
  overflow: hidden;
}
@media (max-width: 760px) {
  .enquiry-modal-box { grid-template-columns: 1fr; max-height: 92vh; overflow-y: auto; }
}

.enquiry-modal-close {
  position: absolute;
  top: 1rem; right: 1rem;
  z-index: 5;
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.35);
  color: var(--ivory);
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.3s var(--ease);
}
.enquiry-modal-close:hover { background: var(--char-800); }
@media (max-width: 760px) {
  .enquiry-modal-close { background: rgba(20, 20, 20, 0.55); }
}

.enquiry-modal-image {
  position: relative;
  overflow: hidden;
  min-height: 220px;
  background: var(--char-800);
}
.enquiry-modal-image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.enquiry-modal-image-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(200deg, rgba(20,20,20,0.35) 0%, rgba(20,20,20,0.55) 55%, rgba(20,20,20,0.88) 100%);
}
.enquiry-modal-image-copy {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.enquiry-modal-image-copy h3 { color: var(--ivory); font-size: clamp(1.5rem, 2.6vw, 2rem); margin: 0.5rem 0 0.6rem; }
.enquiry-modal-image-copy p { color: rgba(247, 245, 242, 0.72); font-size: 0.86rem; }

.enquiry-modal-form {
  padding: clamp(1.75rem, 3vw, 2.5rem);
  overflow-y: auto;
  /* .enquiry-modal-box sets max-height, not height — so the implicit grid
     row still sized itself to this column's full content (auto), and
     min-height:0 alone changes nothing without an explicit height for the
     item to actually shrink into. Explicit height:100% makes this column
     match whatever height the box's max-height settled on, which is what
     finally makes overflow-y:auto engage instead of the form just growing
     past the modal and pushing the submit button off the bottom. */
  height: 100%;
  min-height: 0;
}
.enquiry-modal-form h3 { font-size: 1.5rem; }
.enquiry-modal-form .field { margin-bottom: 1.05rem; }
.enquiry-modal-form .field-row { gap: 1rem; }
