/* ============ Tokens ============ */
:root {
  --navy-950: #000c18;
  --navy-900: #001a2f;
  --gold: #e8af69;
  --gold-light: #ffc261;
  --panel: #ebebeb;
  --card-blue-bg: rgba(28, 90, 141, 0.2);
  --card-blue-border: rgba(146, 146, 146, 0.35);
  --card-muted-bg: rgba(129, 148, 163, 0.3);
  --pill-menu-bg: rgba(217, 217, 217, 0.3);
  --pill-active-bg: rgba(0, 26, 47, 0.35);
  --text-dark: rgba(0, 26, 47, 0.88);

  --font-display: "Cormorant", serif;
  --font-display-alt: "Montserrat Alternates", sans-serif;
  --font-body: "Montserrat", sans-serif;

  --container-max: 1500px;
  --gutter: clamp(24px, 5vw, 82px);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--text-dark);
  background: #fff;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { text-decoration: none; color: inherit; }
h1, h2, p { margin: 0; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 34px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  white-space: nowrap;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.btn:hover { transform: translateY(-1px); opacity: 0.9; }
.btn--dark { background: #000; color: #fff; }
.btn--light { background: #fff; color: var(--text-dark); }

/* ============ Navbar ============ */
/* Fixed above everything: the journey panel (20) and the layout transition
   overlay (60) both sit under it, so the menu is never covered — including
   while the pull-back clip is playing over the page. */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 70;
  /* 3 equal-ish columns rather than space-between: the pill then sits dead
     centre in the viewport regardless of how wide the logo lockup or the
     CTA happen to be. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding: 22px var(--gutter);
  transition: background 0.35s ease, backdrop-filter 0.35s ease;
}
/* Over the light sections the white type would disappear, so drop in a
   dark translucent bar to keep it legible. */
.navbar.is-solid {
  background: rgba(0, 12, 24, 0.72);
  backdrop-filter: blur(12px);
}
/* On the light layout page the header stays transparent, so the type inverts
   rather than a bar dropping in behind it. main.js adds .is-dark once the
   header is no longer over the hero clip. */
.navbar.is-dark { background: transparent; }
.navbar.is-dark .navbar__logo { color: var(--navy-950); }
.navbar.is-dark .navbar__menu {
  background: rgba(0, 26, 47, 0.06);
  border: 1px solid rgba(0, 26, 47, 0.1);
}
.navbar.is-dark .navbar__menu a { color: var(--navy-950); opacity: 0.72; }
.navbar.is-dark .navbar__menu a:hover { opacity: 1; }
.navbar.is-dark .navbar__enquire {
  background: var(--navy-950);
  color: #fff;
}
.navbar.is-dark .navbar__toggle span { background: var(--navy-950); }
/* Same lockup as the journey brand beat: upright caps with the model
   name set small beneath it. */
.navbar__logo {
  font-family: var(--font-display);
  font-style: normal;
  font-size: clamp(15px, 1.6vw, 23px);
  color: #fff;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 0.34em;
}
.navbar__logo-name {
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.navbar__logo-sub {
  font-family: var(--font-body);
  font-size: 0.44em;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  opacity: 0.85;
}
.navbar__logo { justify-self: start; }
.navbar__menu {
  justify-self: center;
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.1vw, 30px);
  background: var(--pill-menu-bg);
  border-radius: 999px;
  padding: 11px clamp(18px, 2.2vw, 30px);
  backdrop-filter: blur(6px);
}
.navbar__menu a {
  color: #fff;
  font-size: 14px;
  font-weight: 400;
  opacity: 0.9;
}
.navbar__menu a:hover { opacity: 1; }
.navbar__enquire {
  justify-self: end;
  background: var(--pill-active-bg);
  color: #fff;
  border-radius: 999px;
  padding: 11px 26px;
  font-size: 14px;
  backdrop-filter: blur(6px);
}
.navbar__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 34px;
  height: 34px;
  background: none;
  border: none;
  cursor: pointer;
  z-index: 20;
}
.navbar__toggle span {
  display: block;
  width: 100%;
  height: 2px;
  background: #fff;
}

/* ============ Hero scroll track ============ */
/* 500vh of scrub + the 100vh the sticky hero occupies. */
.hero-scroll {
  position: relative;
  height: 600vh;
}
/* The same 289 frames over a shorter track: it scrubs faster rather than
   losing anything, and saves a screen and a half of thumb work. */
@media (max-width: 720px) {
  .hero-scroll { height: 450vh; }
}

/* ============ Hero ============ */
.hero {
  position: sticky;
  top: 0;
  height: 100vh;
  min-height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--navy-950);
}
.hero__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 30%;
  z-index: 0;
}
.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 12, 24, 0.25) 0%, rgba(0, 12, 24, 0.1) 40%, rgba(0, 12, 24, 0.65) 100%);
}
.hero__bottom {
  position: relative;
  z-index: 1;
  margin-top: auto;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--gutter) 48px;
}
.hero__content {
  display: flex;
  flex-direction: column;
}
.hero__heading {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(28px, 3.4vw, 40px);
  color: #fff;
  line-height: 1.15;
  text-align: right;
  max-width: 520px;
}
.hero__text {
  margin-top: 18px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(15px, 1.6vw, 20px);
  color: #fff;
  text-align: right;
  max-width: 490px;
  margin-left: auto;
  line-height: 1.5;
}

/* ============ Hero specs overlay (one fact at a time, cinematic reveal) ============ */
.hero__specs {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  text-align: center;
}
.hero__specs-value {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(56px, 10vw, 120px);
  line-height: 1;
  color: #fff;
  text-shadow: 0 4px 30px rgba(0, 0, 0, 0.35);
}
.hero__specs-rule {
  width: 48px;
  height: 1px;
  background: var(--gold-light);
  margin: 18px 0 14px;
}
.hero__specs-label {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.4vw, 18px);
  color: var(--gold-light);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ============ Feature strip (hero bottom cards) ============ */
.feature-strip {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 10px;
}
.feature-card {
  background: var(--card-blue-bg);
  border: 1px solid var(--card-blue-border);
  border-radius: 20px;
  padding: 8px;
  width: clamp(120px, 15vw, 220px);
  height: clamp(90px, 11.22vw, 165px);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
}
.feature-card img {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  object-fit: cover;
  border-radius: 14px;
}
.feature-card p {
  color: #fff;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 10.5px;
  line-height: 1.35;
  flex-shrink: 0;
}
.feature-card--cta .feature-card__cta-heading {
  font-weight: 400;
  font-size: 13px;
  margin-bottom: 2px;
}

/* ============ Gather showcase (scroll-driven 3-slot image carousel) ============ */
.gather-scroll {
  position: relative;
  height: 500vh;
  background: #fff;
}
.gather-showcase {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  background: #fff;
}
.gather-showcase__stage {
  position: relative;
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  /* Intrinsic columns + centred track group: leftover width splits evenly
     either side instead of pooling into a dead gap on the right. */
  grid-template-columns: auto auto auto;
  grid-template-rows: auto;
  justify-content: center;
  column-gap: clamp(20px, 3vw, 48px);
}
.gather-showcase__slot {
  visibility: hidden;
  aspect-ratio: 3 / 4;
  width: clamp(120px, 12vw, 170px);
}
/* All three share one grid row, whose height is set by the center image.
   The thumbs pin to that row's top/bottom edge via align-self, giving a
   deterministic diagonal: top-left -> center -> bottom-right. Spanning
   two auto rows instead let the browser split the height ambiguously,
   which is what pulled the bottom thumb up into the center image. */
.gather-showcase__slot--top { grid-column: 1; grid-row: 1; align-self: start; }
.gather-showcase__slot--center {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  /* Driven off viewport height so the 3/4 portrait can grow as wide as
     possible without clipping inside the 100vh sticky frame. */
  width: min(700px, 70vh);
}
.gather-showcase__side {
  grid-column: 3;
  grid-row: 1;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: clamp(170px, 17vw, 230px);
}
.gather-showcase__slot--bottom {
  flex: 0 0 auto;
  margin-top: 24px;
}
.gather-showcase__img {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 22px;
  border: 1px solid var(--card-blue-border);
  object-fit: cover;
  opacity: 0;
  will-change: transform, opacity;
  /* The FLIP math in main.js computes translate+scale against the box's
     top-left corner, so the origin must match — the default 50% 50%
     scales toward the centre and lands every thumb off its slot. */
  transform-origin: 0 0;
}
.gather-showcase__text {
  /* auto block margins centre the copy in whatever space is left above
     the bottom slot, instead of centring it over the slot. */
  margin: auto 0;
  max-width: 100%;
}
.gather-showcase__text h2 {
  font-family: var(--font-display-alt);
  font-size: clamp(13px, 1.3vw, 16px);
  font-weight: 400;
  line-height: 1.35;
  color: var(--text-dark);
}
.gather-showcase__text p {
  margin-top: 10px;
  font-size: 11px;
  line-height: 1.6;
  color: var(--text-dark);
  opacity: 0.85;
}
.gather-showcase__text .btn {
  margin-top: 16px;
  font-size: 11px;
  padding: 8px 20px;
}

/* ============ Journey (looping video, quick fill, one line per scroll) ============ */
/* Inert spacer — height is the scroll budget main.js reads progress
   against (COVER_VH + 3 * LINE_VH, kept in sync there). journey itself
   is fixed, so it contributes no height of its own. The negative margin
   pulls the budget back to start exactly where the hero stops being
   pinned, so there's no dead screen between the two. White, so the
   video section rides up over the hero.
   Pulled up exactly one viewport so this section starts entering while the
   hero still has its last stretch of scrub left — the two travel together,
   and the section lands in full view precisely as the hero finishes.
   height is a fallback; main.js sets the real value (one viewport for the
   ride up, plus a window per line). */
.journey-scroll {
  position: relative;
  z-index: 1;
  height: 450vh;
  margin-top: -100vh;
  background: var(--navy-950);
}
/* Sticky, not fixed: that's what lets it scroll up into view with the hero
   instead of appearing on top of it, then pin once it fills the screen —
   which is the point the text is allowed to start. */
.journey {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}
.journey__reveal {
  position: absolute;
  inset: 0;
  background: var(--navy-950);
}
.journey__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.journey__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.journey__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 12, 24, 0.4);
}
.journey__text {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--gutter);
}
.journey__line {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(20px, 2.8vw, 38px);
  line-height: 1.25;
  color: #fff;
  text-shadow: 0 4px 30px rgba(0, 0, 0, 0.35);
  opacity: 0;
}
/* Brand beat: same display face, but upright and capitalised rather than
   italic, with the model name set smaller beneath it. */
.journey__line--brand {
  font-style: normal;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5em;
}
.journey__brand {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1;
}
.journey__brand-sub {
  font-family: var(--font-body);
  font-size: 0.38em;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.26em;
  opacity: 0.85;
}

/* ============ Reel (accordion over the blurred loop) ============ */
/* An overlay inside the journey's sticky frame — NOT its own section. That
   is what lets the one video behind it blur in place; a separate section
   would have to slide in over the top and break the continuity.
   main.js fades this in once the blur has taken hold. */
.reel {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  /* Clears the fixed navbar. Without this the content centres in the full
     viewport, so the first row sits behind the header and — because the
     frame is overflow:hidden — the last row gets cut off the bottom. */
  /* No padding-bottom on purpose: centring inside [padding-top, bottom]
     already splits the leftover evenly, and adding one skewed the content
     down so it nearly touched the header. */
  padding-top: clamp(84px, 10vh, 112px);
  opacity: 0;
  pointer-events: none;
}
.reel__inner {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  /* Even halves — accordion and detail carry equal weight. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 3.5vw, 68px);
}
.reel__eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-light);
  margin-bottom: 14px;
}
.reel__list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 18px;
  backdrop-filter: blur(18px);
  overflow: hidden;
}
.reel__item + .reel__item {
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.reel__head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Rows and media are sized off viewport HEIGHT so five rows plus the open
     panel always fit the pinned frame — on a short laptop a fixed padding
     pushed the list past the bottom edge. Kept modest so the panel sits
     with air around it rather than filling the frame. */
  padding: clamp(11px, 1.5vh, 17px) clamp(16px, 1.5vw, 24px);
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: #fff;
  font-family: var(--font-body);
  font-size: clamp(14px, 1.25vw, 17px);
  font-weight: 400;
  transition: background 0.4s ease;
}
.reel__head:hover { background: rgba(255, 255, 255, 0.05); }
/* Montserrat SemiBold — 600 is in the loaded weight set. */
.reel__title {
  font-family: var(--font-body);
  font-weight: 600;
}
.reel__marker {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.35);
  transition: background 0.45s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__item.is-open .reel__marker {
  background: var(--gold-light);
  transform: scale(1.6);
}
/* grid-template-rows 0fr -> 1fr animates the panel open without needing a
   hardcoded max-height, so the media can be any size. */
.reel__panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  /* overflow:hidden is load-bearing, not cosmetic. The media keeps its full
     height (it has an explicit aspect-ratio), so a collapsed panel let a
     ~270px invisible box hang down over the headers below it and swallow
     their clicks — you couldn't click back to an earlier card. Clipping
     confines it to the collapsed row. */
  overflow: hidden;
  /* Spacing lives here rather than as a margin on the media so it collapses
     to nothing when closed; as a media margin it left ~16px of dead space
     under every closed row. */
  padding-bottom: 0;
  transition: grid-template-rows 0.72s cubic-bezier(0.22, 1, 0.36, 1),
    padding-bottom 0.72s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__item.is-open .reel__panel {
  grid-template-rows: 1fr;
  padding-bottom: clamp(13px, 1.8vh, 18px);
  opacity: 1;
}
.reel__panel > * { min-height: 0; }
/* Blurred backdrop that tracks the open card. Sits above the journey video
   (z 0) and below the accordion (z 2), so it crossfades over the deck loop
   as the accordion arrives. Scaled up because a large blur radius otherwise
   drags transparent edges in from outside the box. */
.reel__bg {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  pointer-events: none;
}
/* Two stacked layers; only the front one is opaque. main.js swaps which is
   which, so card-to-card changes dissolve instead of cutting. */
.reel__bg-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__bg-layer.is-front { opacity: 1; }
.reel__bg-layer > video,
.reel__bg-layer > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(26px) saturate(1.05);
  transform: scale(1.12);
  opacity: 0;
}
.reel__bg-layer > video.is-shown,
.reel__bg-layer > img.is-shown { opacity: 1; }
.reel__bg-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 12, 24, 0.5);
}

/* Inset from the panel edges with its own rounded corners. */
.reel__media {
  overflow: hidden;
  /* An explicit width is required rather than relying on the grid stretch:
     with an auto width, aspect-ratio + max-height shrinks the WIDTH to keep
     the ratio, leaving the media narrower than its inset. Setting the width
     from the inset makes height the only thing that clamps, so object-fit
     crops instead of the box shrinking. */
  width: calc(100% - 2 * clamp(16px, 1.4vw, 22px));
  /* No bottom margin — the panel's padding-bottom handles that gap so it
     can collapse to zero when the card closes. */
  margin: 0 auto;
  border-radius: 14px;
  aspect-ratio: 16 / 9;
  /* Modest cap so the open panel leaves air above and below it. */
  max-height: clamp(150px, 30vh, 340px);
}
/* Settles out of a slight zoom as it opens, which reads smoother than the
   height alone. Covers video as well as img — cards can use either. */
.reel__media img,
.reel__media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.07);
  transition: transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__item.is-open .reel__media img,
.reel__item.is-open .reel__media video { transform: scale(1); }

/* Right-hand detail; content swapped per item by main.js, which fades the
   whole block out and back so the swap isn't an instant cut. */
.reel__detail {
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__detail.is-swapping {
  opacity: 0;
  transform: translateY(10px);
}
.reel__detail-title {
  /* Same face as the scroll beats in the video section (.journey__line):
     Cormorant italic 500. Size stays at the accordion's own scale — only
     the typeface is shared, not the size. Negative tracking dropped with
     the Montserrat it was compensating for. */
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(20px, 1.9vw, 32px);
  line-height: 1.25;
  color: #fff;
  overflow-wrap: break-word;
}
.reel__detail-copy {
  margin-top: 14px;
  /* Held to a readable measure — the half-width column is wide enough that
     unconstrained lines would run too long to scan comfortably. */
  max-width: 46ch;
  font-size: 14px;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.82);
}
.reel__meta {
  margin: 24px 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, max-content));
  gap: 16px 36px;
  max-width: 46ch;
}
.reel__meta dt {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.reel__meta dd {
  margin: 5px 0 0;
  font-size: 15px;
  color: #fff;
}
/* Ticked list: for cards whose detail is a set of single-line inclusions
   rather than label/value pairs. */
.reel__points {
  list-style: none;
  margin: 24px 0 0;
  padding: 0;
  max-width: 46ch;
}
.reel__points li {
  position: relative;
  padding-left: 26px;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.85);
}
.reel__points li + li { margin-top: 13px; }
.reel__points li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  font-size: 12px;
  color: var(--gold-light);
}

/* Prose variant: some cards carry a sentence per label rather than a short
   spec value, which at the size above ran far past the column. Single
   column, smaller and muted so it reads as body copy. */
.reel__meta--notes {
  grid-template-columns: minmax(0, 1fr);
  gap: 15px;
  max-width: 52ch;
}
.reel__meta--notes dd {
  font-size: 13px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.78);
}
/* Bottom-centre pill, revealed on the last two items. Positioned against
   .reel (the full-frame overlay) rather than the grid, so it stays centred
   on the viewport regardless of the two columns. */
.reel__pill {
  position: absolute;
  left: 50%;
  bottom: clamp(22px, 4vh, 46px);
  transform: translate(-50%, 14px);
  display: inline-flex;
  align-items: center;
  background: var(--pill-active-bg);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
  color: #fff;
  border-radius: 999px;
  padding: 13px 30px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.reel__pill.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.reel__pill:hover { background: rgba(0, 26, 47, 0.6); }

/* ============ "View layout" hand-off ============
   The pill lifts the accordion's blur back off the journey video before
   cutting to the pull-back clip, so these all have to ease rather than snap.
   main.js stops writing the journey video's filter while .is-surfacing is on,
   otherwise the scrub would overwrite the unblur every frame. */
.journey__bg::after { transition: opacity 0.9s ease; }
.journey.is-surfacing .journey__bg::after { opacity: 0; }
.journey.is-surfacing .journey__video {
  transition: filter 0.9s ease, transform 0.9s ease;
}
.journey.is-surfacing .reel,
.journey.is-surfacing .reel__bg {
  transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

.layout-intro {
  position: fixed;
  inset: 0;
  z-index: 60; /* over the page, under the navbar at 70 */
  background: var(--navy-950);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s linear;
}
.layout-intro.is-active { opacity: 1; }
.layout-intro__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}


/* ============ Mosaic ============
   Geometry lifted from the reference: every tile is a full viewport box, and
   the rows are placed edge-to-edge by percentage rather than laid out in a
   grid. That is what lets a single scale() on the wrapper read as a camera
   pulling back — at scale 1 the centre tile is exactly the viewport, and the
   neighbours are parked just outside it. */
/* The grid lives inside the journey's pinned frame rather than a section of
   its own, because the centre tile IS the journey video — the clip that has
   been on screen since the text beats. Handing it to a separate section would
   mean a second copy of the same footage and a visible cut between them. */
.mosaic__grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  transform-origin: 50% 50%;
  will-change: transform;
}
/* Sized off the grid rather than the viewport: with a scrollbar present,
   100vw is wider than the stage, which would slide every row out of register
   with the centre tile by the scrollbar's width. */
.mosaic__row {
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
}
.mosaic__row--center { top: 0; }
/* Directly above and below the centre row, so the grid is continuous. */
.mosaic__row--top { bottom: 100%; }
.mosaic__row--bottom { top: 100%; }
/* The explicit width matters: a tile pinned by `right` with `left: auto` and
   no width shrink-to-fits, and since the video inside is absolute there is
   nothing to give it a size — every side tile would collapse to zero. */
/* .journey__bg is listed alongside because it is the centre tile — it takes
   the same gap and corner rounding as the pull-back opens up. */
.mosaic__tile,
.mosaic__row--center > .journey__bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--navy-900);
}
/* Half-tile offset: these two meet on the viewport's vertical centre line,
   while the centre row's joins sit on its edges. */
.mosaic__tile--midleft {
  right: 50%;
  left: auto;
}
.mosaic__tile--midright {
  left: 50%;
  right: auto;
}
.mosaic__tile--left {
  right: 100%;
  left: auto;
}
.mosaic__tile--right {
  left: 100%;
  right: auto;
}
.mosaic__tile video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform: translate(-50%, -50%);
  object-fit: cover;
}

.mosaic__center {
  position: absolute;
  z-index: 3;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(1000px, 74vw);
  text-align: center;
  pointer-events: none;
}
.mosaic__title {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(30px, 4.4vw, 70px);
  line-height: 1.16;
  color: #fff;
  text-shadow: 0 2px 40px rgba(0, 12, 24, 0.5);
  opacity: 0;
}
/* Split by main.js; each word fades and lifts on its own beat. */
.mosaic__word {
  display: inline-block;
  white-space: pre;
  will-change: opacity, transform;
}

.mosaic__toggle {
  position: absolute;
  z-index: 4;
  top: clamp(84px, 11vh, 122px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background: rgba(0, 26, 47, 0.34);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
}
.mosaic__toggle-opt {
  padding: 9px 22px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.66);
  white-space: nowrap;
  transition: background 0.45s ease, color 0.45s ease;
}
.mosaic__toggle-opt.is-active {
  background: rgba(255, 255, 255, 0.94);
  color: var(--navy-950);
}

@media (max-width: 720px) {
  .mosaic__toggle { top: clamp(70px, 9vh, 96px); }
  .mosaic__toggle-opt { padding: 8px 15px; font-size: 11px; }
}

/* ============ Anchorages ============
   Split panel pinned for one screen per destination. The left card is the
   index — an eyebrow, a wheel of names and a tab row — and the right panel is
   the picture. */
.anchor-scroll {
  position: relative;
  background: var(--navy-950);
}
.anchor {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  padding: 0 var(--gutter);
  overflow: hidden;
}
.anchor__stage {
  transform-origin: 50% 50%;
  will-change: transform;
  display: flex;
  gap: clamp(12px, 1.4vw, 22px);
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  height: min(80vh, 720px);
}
.anchor__info {
  position: relative;
  width: 42%;
  flex: 0 0 42%;
  border-radius: clamp(14px, 1.4vw, 22px);
  background: #efeae1;
  color: var(--text-dark);
  overflow: hidden;
}
.anchor__top {
  position: absolute;
  top: clamp(26px, 2.8vw, 53px);
  left: 50%;
  transform: translateX(-50%);
  width: min(84%, 440px);
  text-align: center;
}
.anchor__eyebrow {
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.7vw, 12px);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.55;
}
.anchor__intro {
  margin-top: 14px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(11.5px, 0.85vw, 14px);
  line-height: 1.6;
  opacity: 0.5;
}

/* Three rows tall with the middle one on the centre line, so the names above
   and below stay visible and the list reads as a wheel. */
.anchor__wheel {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: calc(3 * var(--anchor-row));
  overflow: hidden;
  --anchor-row: clamp(42px, 3.6vw, 62px);
}
.anchor__names {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Offset by one row so item 0 starts on the centre line. */
  transform: translateY(var(--anchor-row));
  transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.anchor__name {
  height: var(--anchor-row);
  line-height: var(--anchor-row);
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(24px, 2.5vw, 40px);
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
.anchor__name.is-near { opacity: 0.22; }
.anchor__name.is-active { opacity: 1; }

.anchor__tabs {
  position: absolute;
  bottom: clamp(16px, 1.7vw, 32px);
  left: clamp(16px, 1.7vw, 32px);
  width: calc(100% - 2 * clamp(16px, 1.7vw, 32px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.anchor__tab {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: clamp(8px, 0.62vw, 11px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-dark);
  opacity: 0.4;
  transition: opacity 0.45s ease;
}
.anchor__tab:hover { opacity: 0.75; }
.anchor__tab.is-active { opacity: 1; }

.anchor__content {
  position: relative;
  width: 58%;
  flex: 0 0 58%;
  border-radius: clamp(14px, 1.4vw, 22px);
  background: var(--navy-900);
  overflow: hidden;
}
.anchor__images {
  position: absolute;
  inset: 0;
}
/* Each image sits on top of the last and is wiped up into view, so moving
   through the list reads as a reveal rather than a dissolve. */
.anchor__image {
  position: absolute;
  inset: 0;
  clip-path: inset(100% 0 0 0);
  transition: clip-path 0.95s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: clip-path;
}
.anchor__image.is-shown { clip-path: inset(0 0 0 0); }
.anchor__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: translateY(8%);
  transition: transform 0.95s cubic-bezier(0.16, 1, 0.3, 1);
}
.anchor__image.is-shown img { transform: translateY(0); }

.anchor__boxes {
  position: absolute;
  right: clamp(16px, 1.7vw, 32px);
  bottom: clamp(16px, 1.7vw, 32px);
  width: min(340px, 46%);
  min-height: clamp(150px, 15vw, 210px);
}
.anchor__box {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 18px;
  padding: clamp(16px, 1.5vw, 26px);
  border-radius: clamp(12px, 1.1vw, 18px);
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(18px);
  color: #fff;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.anchor__box.is-active {
  opacity: 1;
  transform: translateY(0);
}
.anchor__box-icon {
  width: clamp(20px, 1.7vw, 26px);
  height: clamp(20px, 1.7vw, 26px);
  fill: none;
  stroke: #fff;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.anchor__box p {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(12px, 0.95vw, 15px);
  line-height: 1.55;
}

/* Stacks below the split: the wheel needs height the portrait viewport does
   not have, so the name becomes a plain heading over the picture. */
@media (max-width: 860px) {
  .anchor__stage {
    flex-direction: column;
    height: auto;
    gap: 10px;
  }
  .anchor__info,
  .anchor__content {
    width: 100%;
    flex: 0 0 auto;
  }
  /* The cream panel was taking the larger half and leaving the photograph a
     shallow strip, so the split is reversed on a phone: the picture is the
     thing worth the room here. */
  .anchor__info { height: clamp(250px, 34vh, 300px); }
  .anchor__content { height: clamp(300px, 44vh, 400px); }
  /* The frosted card sits over that photograph. At 70% wide and 150px tall it
     covered about half the yacht; pulled back to a caption-sized panel in the
     corner it says the same thing without hiding the subject. */
  .anchor__boxes {
    width: min(210px, 52%);
    /* Enough for the icon and two lines and no more. Dropping this to 0 let the
       absolutely positioned card inside collapse to 28px and clip its own copy.
       26px padding + an 18px icon + a 10px gap + two 12px lines = 106. */
    min-height: 108px;
    right: 14px;
    bottom: 14px;
  }
  .anchor__box {
    gap: 10px;
    padding: 13px 15px;
    border-radius: 12px;
  }
  .anchor__box p { font-size: 12px; line-height: 1.45; }
  .anchor__box-icon { width: 18px; height: 18px; }
  .anchor__tabs { justify-content: flex-start; overflow-x: auto; }
  /* These were 10px tall and effectively unhittable. */
  .anchor__tab { padding: 11px 2px; min-height: 44px; font-size: 13px; }
}

/* ============ Closing call to action ============ */
/* A layer inside the pinned anchor frame, not a section of its own: the two
   panels shrink away and this rises from the bottom edge to replace them.
   The origin is the bottom, not the centre, so it climbs into frame with the
   scroll rather than blooming in the middle of the page. Scaling a full-frame
   box down is what makes it a grow rather than a reveal — the video is always
   framed for its finished size, just seen smaller. */
.cta {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--navy-950);
  text-align: center;
  transform-origin: 50% 100%;
  transform: scale(0.3);
  opacity: 0;
  pointer-events: none;
  will-change: transform, border-radius;
}
.cta.is-open { pointer-events: auto; }

/* On the layout page it is an ordinary section rather than something the
   scroll grows into frame, so everything the transition drives has to be
   handed back: the shrink, the clip, and the opacities the copy stagger
   starts from. */
.cta--static {
  position: relative;
  inset: auto;
  z-index: auto;
  height: 100vh;
  min-height: 560px;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  clip-path: none;
  border-radius: 0;
  will-change: auto;
}
.cta--static .cta__bg { transform: none; }
.cta--static .cta__scrim,
.cta--static .cta__inner,
.cta--static .cta__inner > * {
  opacity: 1;
  transform: none;
}
.cta__scrim { opacity: 0; }
/* Each line carries its own beat, staggered by main.js. */
.cta__inner > * { opacity: 0; }
.cta__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.cta__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Heavier through the middle band, where the copy sits, and lighter at the
   edges so the water keeps its colour. */
.cta__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      to bottom,
      rgba(0, 12, 24, 0.62) 0%,
      rgba(0, 12, 24, 0.48) 40%,
      rgba(0, 12, 24, 0.4) 60%,
      rgba(0, 12, 24, 0.66) 100%
    );
}
.cta__inner {
  position: relative;
  z-index: 2;
  width: min(760px, calc(100% - 2 * var(--gutter)));
  color: #fff;
}
.cta__eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.72vw, 12px);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}
.cta__eyebrow::before,
.cta__eyebrow::after {
  content: "";
  width: clamp(28px, 4vw, 62px);
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}
.cta__heading {
  margin-top: clamp(18px, 2.4vh, 30px);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(32px, 4.6vw, 68px);
  line-height: 1.1;
}
.cta__heading em {
  font-style: italic;
  color: var(--gold-light);
}
.cta__text {
  margin: clamp(14px, 2vh, 22px) auto 0;
  max-width: 560px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1.05vw, 17px);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.76);
}
.cta__btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(24px, 3.4vh, 42px);
  background: var(--pill-active-bg);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
  color: #fff;
  border-radius: 999px;
  padding: clamp(13px, 1.5vh, 16px) clamp(26px, 2.6vw, 34px);
  font-family: var(--font-body);
  font-size: clamp(12px, 0.85vw, 14px);
  font-weight: 500;
  letter-spacing: 0.06em;
  white-space: nowrap;
  transition: background 0.4s ease;
}
.cta__btn:hover { background: rgba(0, 26, 47, 0.62); }

/* ============ Panel wrapper ============ */
.panel {
  background: var(--panel);
  border-radius: 20px;
  margin: 0 clamp(0px, 1vw, 16px);
  padding: clamp(40px, 6vw, 90px) var(--gutter) 0;
  display: flex;
  flex-direction: column;
  gap: clamp(60px, 8vw, 110px);
}

/* ============ Yacht banner / stats ============ */
.yacht-banner {
  position: relative;
  border-radius: 40px;
  overflow: hidden;
}
.yacht-banner__img {
  width: 100%;
  height: clamp(360px, 52vw, 700px);
  object-fit: cover;
}
.yacht-banner__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 28px clamp(20px, 4vw, 56px) 40px;
}
.yacht-banner__cta {
  align-self: flex-end;
  margin-bottom: 24px;
}
.yacht-banner__stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  max-width: 900px;
}
.stat {
  background: var(--card-blue-bg);
  border: 1px solid var(--card-blue-border);
  border-radius: 20px;
  padding: 22px 12px;
  text-align: center;
  backdrop-filter: blur(4px);
}
.stat__value {
  font-family: var(--font-body);
  font-size: clamp(24px, 3vw, 40px);
  color: #fff;
  font-weight: 400;
}
.stat__label {
  font-size: clamp(11px, 1.1vw, 15px);
  color: #fff;
  letter-spacing: 0.03em;
  margin-top: 8px;
  text-transform: uppercase;
}

/* ============ Life on board ============ */
.eyebrow {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 20px;
}
.life-onboard__heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.life-onboard__heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(34px, 5.5vw, 70px);
  color: var(--gold);
  line-height: 1.05;
  max-width: 900px;
}
.life-onboard__heading em {
  font-style: italic;
}
.life-onboard__intro {
  margin-top: 24px;
  font-size: clamp(16px, 1.6vw, 20px);
  max-width: 490px;
  line-height: 1.55;
}
.life-onboard__grid {
  margin-top: clamp(40px, 5vw, 70px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3vw, 40px);
}
.feature__icon {
  width: 44px;
  height: 44px;
  object-fit: contain;
  margin-bottom: 20px;
}
.feature__title {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 20px;
  margin-bottom: 12px;
}
.feature__desc {
  font-size: 15px;
  line-height: 1.6;
  opacity: 0.85;
}

/* ============ Experience CTA ============ */
.experience {
  position: relative;
  border-radius: 60px 60px 0 0;
  overflow: hidden;
  margin: 0 calc(-1 * var(--gutter));
}
.experience__img {
  width: 100%;
  height: clamp(420px, 55vw, 780px);
  object-fit: cover;
}
.experience__overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 40px;
  text-align: center;
  padding: 40px;
}
.experience__overlay h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  font-size: clamp(32px, 7vw, 90px);
  color: #fff;
  max-width: 1100px;
}

/* ============ Footer ============ */
/* No negative top margin any more: it existed to tuck the footer under the
   rounded bottom corners of .panel, and that wrapper is no longer on any page.
   Left in, it pulled the footer up over whatever now precedes it — over the
   step rail on the enquire page, over the closing image on about. */
.footer {
  background: var(--navy-950);
  color: #fff;
  padding: 70px var(--gutter) 30px;
}
.footer__top {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 50px;
}
.footer__logo {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 40px;
}
.footer__tagline {
  margin-top: 24px;
  font-weight: 300;
  font-size: 14px;
  line-height: 1.6;
  max-width: 280px;
  opacity: 0.9;
}
.footer__spec {
  margin-top: 16px;
  font-size: 13px;
  color: var(--gold-light);
}
.footer__col {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.footer__col-heading {
  font-weight: 500;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
  opacity: 0.7;
}
.footer__col a,
.footer__col p {
  font-weight: 300;
  font-size: 14px;
  opacity: 0.9;
}
.footer__col a:hover { text-decoration: underline; }
.footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding-top: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 13px;
  opacity: 0.75;
}
.footer__legal {
  display: flex;
  gap: 28px;
}
.footer__legal a:hover { text-decoration: underline; }

/* ============ Responsive ============ */
@media (max-width: 1000px) {
  .feature-strip { flex-wrap: wrap; }
  .life-onboard__grid { grid-template-columns: repeat(2, 1fr); }
  .footer__top { grid-template-columns: 1fr; }
  /* Detail stacks above the list so the open panel stays reachable. */
  .reel__inner { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .reel__detail { order: -1; }
  .reel__detail-copy { max-width: none; }
  .reel__meta { margin-top: 18px; gap: 12px 24px; }
  .gather-showcase__stage {
    grid-template-columns: 90px minmax(0, 1fr);
    grid-template-rows: auto auto;
    justify-content: stretch;
  }
  .gather-showcase__slot--top,
  .gather-showcase__slot--bottom { width: 90px; }
  .gather-showcase__slot--top { grid-column: 1; grid-row: 1; }
  .gather-showcase__slot--center { grid-column: 2; grid-row: 1; width: 100%; }
  /* Copy drops below the image, thumb stays bottom-right of the group. */
  .gather-showcase__side {
    grid-column: 1 / 3;
    grid-row: 2;
    width: auto;
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px;
    margin-top: 24px;
  }
  .gather-showcase__text { margin: 0; }
  .gather-showcase__slot--bottom { margin-top: 0; }
}

@media (max-width: 720px) {
  .navbar__menu {
    position: absolute;
    top: 74px;
    left: var(--gutter);
    right: var(--gutter);
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    background: rgba(0, 12, 24, 0.85);
    display: none;
  }
  .navbar__menu.is-open { display: flex; }
  .navbar.is-dark .navbar__menu {
    background: rgba(255, 255, 255, 0.94);
    border-color: rgba(0, 26, 47, 0.1);
    backdrop-filter: blur(12px);
  }
  /* Absolute menu + hidden CTA leaves logo and toggle in the grid, so pin
     the toggle to the last column to keep it hard right. */
  .navbar__toggle { display: flex; grid-column: 3; justify-self: end; }
  .navbar__enquire { display: none; }
  .hero__bottom { flex-direction: column; align-items: center; gap: 32px; }
  .hero__content { align-items: center; text-align: center; }
  .hero__heading, .hero__text { text-align: center; margin-left: 0; }
  .hero__specs { flex-wrap: wrap; justify-content: center; max-width: 80%; gap: 10px; }
  .hero__spec { padding: 10px 14px; min-width: 72px; }
  .yacht-banner__stats { grid-template-columns: 1fr; }
  .life-onboard__grid { grid-template-columns: 1fr; }
  .life-onboard__heading-row { flex-direction: column; align-items: flex-start; }
  .gather-showcase__stage { grid-template-columns: 70px 1fr; }
  .gather-showcase__slot--top,
  .gather-showcase__slot--bottom { width: 70px; }
}

/* ============ About page ============
   A reveal-on-enter language rather than the pinned scrubbing the home page
   uses: blocks rest offset and settle as they come into view, figures drift
   against the scroll, and the cabin cards straighten out of a slight tilt. */
.page--about {
  background: var(--navy-950);
  color: #fff;
}
.about {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(120px, 16vh, 190px) var(--gutter) 0;
  display: flex;
  flex-direction: column;
  gap: clamp(72px, 12vh, 150px);
}

/* --- shared type --- */
.about__eyebrow {
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.72vw, 12px);
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: clamp(14px, 1.8vh, 22px);
}
.about h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(46px, 8vw, 118px);
  line-height: 0.98;
}
.about h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(28px, 3.6vw, 54px);
  line-height: 1.1;
}
.about h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(20px, 1.9vw, 28px);
  line-height: 1.2;
}
.about__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.72);
}
.about__copy .about__body + .about__body { margin-top: 1.1em; }
.about__copy h2 + .about__body { margin-top: clamp(18px, 2.4vh, 30px); }

.about__intro { max-width: 20ch; }
.about__crumb {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  margin-bottom: clamp(20px, 3vh, 38px);
}
.about__crumb span { margin: 0 8px; opacity: 0.5; }
.about__lede {
  max-width: 34ch;
  margin-top: clamp(20px, 3vh, 34px);
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(17px, 1.6vw, 25px);
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.8);
}

/* --- figures + parallax ---
   The inner element is deliberately taller than its frame so it has somewhere
   to travel: shifting a flush-fitting image would drag an empty edge into
   view. main.js moves the inner, the frame clips it. */
.about__figure {
  position: relative;
  overflow: hidden;
  border-radius: clamp(10px, 1vw, 18px);
  background: var(--navy-900);
}
.about__figure-inner {
  position: absolute;
  top: -9%;
  left: 0;
  width: 100%;
  height: 118%;
  will-change: transform;
}
.about__figure-inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.about__figure--wide { aspect-ratio: 16 / 8.4; }
.about__figure--tall { aspect-ratio: 3 / 4; }

/* --- two-column blocks --- */
.about__split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 96px);
}
.about__split--reverse .about__copy { order: 2; }
.about__copy { max-width: 46ch; }

.about__list {
  list-style: none;
  margin: clamp(22px, 3vh, 34px) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.about__list li {
  position: relative;
  padding: clamp(11px, 1.5vh, 15px) 0 clamp(11px, 1.5vh, 15px) 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 0.95vw, 15.5px);
  color: rgba(255, 255, 255, 0.78);
}
.about__list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  transform: translateY(-50%);
}

/* --- specification: the one pinned moment --- */
.about__specs {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 96px);
  align-items: start;
}
.about__specs-head {
  position: sticky;
  top: clamp(110px, 16vh, 170px);
}
.about__link,
.about__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(22px, 3vh, 34px);
  background: var(--pill-active-bg);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
  color: #fff;
  border-radius: 999px;
  padding: 13px 28px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.06em;
  white-space: nowrap;
  transition: background 0.4s ease;
}
.about__link:hover,
.about__cta:hover { background: rgba(0, 26, 47, 0.62); }

.about__spec-list { margin: 0; }
.about__spec {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  gap: 18px;
  align-items: baseline;
  padding: clamp(14px, 2vh, 20px) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.about__spec:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.14); }
.about__spec dt {
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.7vw, 11.5px);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.about__spec dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(17px, 1.5vw, 24px);
  line-height: 1.25;
}

/* --- cabins --- */
.about__section-head { max-width: 46ch; margin-bottom: clamp(34px, 5vh, 62px); }
.about__cabin-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 2.6vw, 40px);
}
.about__cabin-media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: clamp(10px, 1vw, 18px);
  margin-bottom: clamp(18px, 2.4vh, 28px);
  background: var(--navy-900);
}
.about__cabin-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}
.about__cabin:hover .about__cabin-media img { transform: scale(1.04); }
.about__cabin h3 { margin-bottom: 12px; }

/* --- living spaces figure cluster --- */
.about__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 22px);
}
.about__pair .about__figure { aspect-ratio: 1 / 1; }
.about__figure--span {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 7 !important;
}

/* --- closing --- */
.about__closing {
  position: relative;
  margin: 0 calc(-1 * var(--gutter));
  min-height: min(88vh, 780px);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  text-align: center;
}
.about__closing-bg { position: absolute; }
.about__closing-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0, 12, 24, 0.6) 0%,
    rgba(0, 12, 24, 0.42) 45%,
    rgba(0, 12, 24, 0.72) 100%
  );
}
.about__closing-copy {
  position: relative;
  z-index: 1;
  width: min(640px, calc(100% - 2 * var(--gutter)));
}
.about__closing-copy p {
  margin: clamp(14px, 2vh, 22px) auto 0;
  max-width: 46ch;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1.05vw, 16px);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.76);
}

/* --- the reveal itself ---
   Held at an offset until main.js marks it in. The delay comes from --d on the
   element, which is what staggers a group without needing a class per step. */
[data-reveal] {
  opacity: 0;
  transform: translateY(38px);
  transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms),
    transform 0.9s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms),
    rotate 1.1s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms);
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}
/* Sits slightly off-square and straightens on arrival. Kept separate from the
   transform above so the two never overwrite each other. */
[data-tilt] { rotate: -1.8deg; }
[data-tilt].is-in { rotate: 0deg; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  [data-tilt] { rotate: 0deg; }
  .about__figure-inner { transform: none !important; }
}

@media (max-width: 900px) {
  .about { gap: clamp(56px, 9vh, 96px); }
  .about__split,
  .about__specs {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(26px, 4vh, 44px);
  }
  .about__split--reverse .about__copy { order: 0; }
  .about__specs-head { position: static; }
  .about__cabin-grid { grid-template-columns: minmax(0, 1fr); }
  .about__intro { max-width: none; }
}

/* ============ About hero ============
   Shaped after the reference: full-bleed video, everything centred, and a
   headline that changes face part-way through. Sits outside .about's container
   so it can go edge to edge. */
.about-hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  text-align: center;
  background: var(--navy-950);
}
.about-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.about-hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Weighted to the top and bottom so the centred stack sits on the darkest
   part while the middle of the frame keeps its light. */
.about-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      to bottom,
      rgba(0, 12, 24, 0.7) 0%,
      rgba(0, 12, 24, 0.4) 34%,
      rgba(0, 12, 24, 0.44) 62%,
      rgba(0, 12, 24, 0.78) 100%
    );
}
.about-hero__inner {
  position: relative;
  z-index: 2;
  width: min(900px, calc(100% - 2 * var(--gutter)));
  padding: clamp(96px, 14vh, 150px) 0 clamp(48px, 8vh, 90px);
  color: #fff;
}
.about-hero__kicker {
  font-family: var(--font-body);
  font-size: clamp(10px, 0.75vw, 12.5px);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: clamp(20px, 3vh, 34px);
}
/* Two lines, second in the display serif — the face change is what gives the
   headline its shape, so the lines are separate blocks rather than one wrap. */
.about-hero__title {
  margin: 0;
  font-weight: 500;
  font-size: clamp(30px, 4.9vw, 68px);
  line-height: 1.06;
}
.about-hero__line {
  display: block;
  font-family: var(--font-body);
  font-weight: 300;
  letter-spacing: -0.01em;
}
.about-hero__line--serif {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0;
}
.about-hero__sub {
  margin: clamp(20px, 3vh, 32px) auto 0;
  max-width: 34ch;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 0.95vw, 15.5px);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.78);
}
.about-hero__meta {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(12px, 2vw, 28px);
  margin-top: clamp(22px, 3vh, 34px);
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.7vw, 11.5px);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
/* Separated by a rule rather than a bullet, so it reads as a spec line. */
.about-hero__meta span + span::before {
  content: "";
  display: inline-block;
  width: clamp(16px, 2vw, 30px);
  height: 1px;
  margin-right: clamp(12px, 2vw, 28px);
  vertical-align: middle;
  background: currentColor;
  opacity: 0.5;
}
.about-hero__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(28px, 4vh, 48px);
  background: var(--pill-active-bg);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
  color: #fff;
  border-radius: 999px;
  padding: 14px 30px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.06em;
  transition: background 0.4s ease;
}
.about-hero__cta:hover { background: rgba(0, 26, 47, 0.62); }

/* Word-by-word arrival. main.js wraps each word in a .w-word and stamps its
   own delay, so a line cascades without a class per word. */
.w-word {
  display: inline-block;
  white-space: pre;
  opacity: 0;
  transform: translateY(0.5em);
  transition: opacity 0.85s cubic-bezier(0.22, 1, 0.36, 1) var(--wd, 0ms),
    transform 0.85s cubic-bezier(0.22, 1, 0.36, 1) var(--wd, 0ms);
}
.w-word.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .w-word {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* The hero is full-bleed, so pull the container's own top padding off — the
   hero supplies its own. */
.page--about .about { padding-top: clamp(72px, 11vh, 130px); }

@media (max-width: 900px) {
  .about-hero__inner { padding-top: clamp(104px, 16vh, 150px); }
  .about-hero__meta { flex-direction: column; gap: 10px; }
  .about-hero__meta span + span::before { display: none; }
}

/* ============ Enquire ============
   Reference layout: one clip full-bleed behind everything, the headline over it
   on the left, the form in a tall card on the right, and a step rail along the
   bottom. The card is the only light surface on the page, so it carries dark
   type while everything outside it stays white on video. */
.page--enquire {
  background: var(--navy-950);
  color: #fff;
}
.enquire {
  position: relative;
  /* A definite height, not just a minimum: the card is told to scroll its own
     contents, and "max-height: 100%" can only resolve against a row that has a
     size of its own. Left as a minimum, the page simply grew to fit the form
     and pushed the step rail off the bottom of the screen. */
  min-height: 100vh;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: clamp(96px, 13vh, 132px) var(--gutter) clamp(20px, 3vh, 32px);
}
.enquire__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.enquire__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Darkest on the left where the headline sits; the right stays lighter because
   the card covers it anyway. */
.enquire__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to right, rgba(0, 12, 24, 0.78) 0%, rgba(0, 12, 24, 0.52) 46%, rgba(0, 12, 24, 0.64) 100%),
    linear-gradient(to bottom, rgba(0, 12, 24, 0.5) 0%, rgba(0, 12, 24, 0.1) 40%, rgba(0, 12, 24, 0.55) 100%);
}
.enquire__grid {
  position: relative;
  z-index: 2;
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) min(460px, 40vw);
  gap: clamp(24px, 4vw, 72px);
  align-items: center;
  min-height: 0;
}

/* --- left: headline, lede, contact details --- */
.enquire__intro { max-width: 34ch; }
.enquire__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(38px, 6vw, 86px);
  line-height: 0.96;
  letter-spacing: -0.01em;
}
.enquire__title-line { display: block; }
.enquire__lede {
  margin-top: clamp(20px, 3vh, 32px);
  max-width: 44ch;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1.02vw, 16px);
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.74);
}
.enquire__contact {
  margin: clamp(26px, 4vh, 44px) 0 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 2.4vh, 26px) clamp(20px, 3vw, 44px);
  max-width: 460px;
}
.enquire__contact dt {
  font-family: var(--font-body);
  font-size: clamp(8.5px, 0.62vw, 10.5px);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 7px;
}
.enquire__contact dd {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(12.5px, 0.95vw, 15px);
  color: rgba(255, 255, 255, 0.85);
}
.enquire__contact a { border-bottom: 1px solid rgba(255, 255, 255, 0.28); }
.enquire__contact a:hover { border-bottom-color: var(--gold); }

/* --- right: the form card --- */
.enquire__card {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  /* Frosted on the same values as the accordion's .reel__list, so the two
     surfaces read as the same material. Being translucent, every bit of type
     inside it flips from navy to white. */
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(18px);
  color: #fff;
  border-radius: clamp(14px, 1.4vw, 24px);
  padding: clamp(22px, 2.4vw, 40px);
  /* The form is taller than the card on short screens, so it scrolls inside
     rather than pushing the rail off the bottom of the page. */
  overflow-y: auto;
  max-height: 100%;
  min-height: 0;
}
.enquire__badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.72vw, 12px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.enquire__badge-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  font-size: 10.5px;
  letter-spacing: 0.04em;
}
.enquire__card-title {
  margin: clamp(18px, 2.4vh, 28px) 0 clamp(20px, 3vh, 32px);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(28px, 2.9vw, 44px);
  line-height: 1.05;
  color: #fff;
}
.enquire__form {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.2vh, 24px);
}

/* --- fields: label above, ruled underneath --- */
.field { display: flex; flex-direction: column; }
.field__label {
  font-family: var(--font-body);
  font-size: clamp(8.5px, 0.62vw, 10.5px);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: 8px;
}
.field__input {
  width: 100%;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.26);
  border-radius: 0;
  background: none;
  padding: 6px 0 9px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(14px, 1.05vw, 16px);
  color: #fff;
  transition: border-color 0.3s ease;
}
.field__input::placeholder { color: rgba(255, 255, 255, 0.34); }
.field__input:focus {
  outline: none;
  border-bottom-color: #fff;
}
.field__input--area {
  resize: vertical;
  min-height: 62px;
  line-height: 1.5;
}

.field-group { margin: 0; padding: 0; border: 0; }
.field-group__legend {
  padding: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(17px, 1.5vw, 22px);
  color: #fff;
  margin-bottom: clamp(12px, 1.6vh, 18px);
}
.field-group__row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 22px);
}

.enquire__actions {
  margin-top: auto;
  padding-top: clamp(18px, 2.6vh, 30px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.enquire__back {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.7);
  transition: color 0.3s ease;
}
.enquire__back:hover { color: #fff; }
.enquire__submit {
  border: 0;
  cursor: pointer;
  background: #fff;
  color: var(--navy-950);
  border-radius: 999px;
  padding: 15px 34px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.06em;
  transition: background 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.enquire__submit:hover {
  background: rgba(255, 255, 255, 0.86);
  transform: translateY(-1px);
}
.enquire__note {
  margin: 4px 0 0;
  font-family: var(--font-body);
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.74);
}

/* --- bottom step rail --- */
.enquire__rail {
  position: relative;
  z-index: 2;
  list-style: none;
  margin: clamp(18px, 3vh, 34px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 2vw, 30px);
}
.enquire__step {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-top: clamp(10px, 1.4vh, 15px);
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.72vw, 12px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  transition: color 0.4s ease, border-color 0.4s ease;
}
.enquire__step-no { font-weight: 500; }
.enquire__step.is-active {
  color: #fff;
  border-top-color: #fff;
}

@media (max-width: 1000px) {
  .enquire {
    height: auto;
    padding-top: clamp(104px, 15vh, 140px);
  }
  .enquire__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(28px, 4vh, 44px);
    align-items: start;
  }
  .enquire__card {
    align-self: auto;
    max-height: none;
    overflow-y: visible;
  }
  .enquire__intro { max-width: none; }
  .enquire__rail { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}
@media (max-width: 560px) {
  .enquire__contact { grid-template-columns: minmax(0, 1fr); }
  .enquire__rail { grid-template-columns: minmax(0, 1fr); }
  .enquire__step:not(.is-active) { display: none; }
  .enquire__actions { flex-direction: column-reverse; align-items: stretch; }
  .enquire__submit { width: 100%; }
  .enquire__back { justify-content: center; }
}

/* ============ Gallery ============ */
.page--gallery {
  background: var(--navy-950);
  color: #fff;
}
/* No wrapper padding or max-width: the panel runs edge to edge and fills the
   screen on its own, so there is only ever one frame on the page. */
.gallery { padding: 0; }

/* --- the bit above the panel --- */
.gallery__intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(20px, 4vw, 70px);
  align-items: end;
  margin-bottom: clamp(30px, 5vh, 62px);
}
.gallery__lead {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(34px, 4.6vw, 68px);
  line-height: 1.02;
}
.gallery__blurb {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1.02vw, 16.5px);
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.7);
  max-width: 46ch;
}

/* --- the dark panel, ruled like the reference --- */
.gallery__panel {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: #0a0a0b;
  /* Top padding clears the fixed navbar now that the panel starts at y=0. */
  padding: clamp(104px, 14vh, 150px) 0 clamp(34px, 5vh, 68px);
  overflow: hidden;
}
.gallery__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
/* Blur is baked into the file; the scale only pulls the softened edges out of
   frame, the way the journey video does. */
.gallery__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.08);
}
.gallery__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to bottom, rgba(6, 8, 10, 0.82) 0%, rgba(6, 8, 10, 0.68) 45%, rgba(6, 8, 10, 0.86) 100%);
}
/* Everything else in the panel rides above the clip. */
.gallery__head,
.gallery__filters,
.marquee,
.gallery__grid,
.gallery__empty {
  position: relative;
  z-index: 2;
}
.gallery__head {
  padding: 0 var(--gutter);
  margin-bottom: clamp(22px, 3.4vh, 40px);
}
.gallery__note {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(11px, 0.82vw, 13.5px);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.6);
  max-width: 34ch;
}

/* --- frosted filter pills, on the accordion's values --- */
.gallery__filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 var(--gutter);
  margin-bottom: clamp(24px, 3.6vh, 44px);
}
.pill {
  cursor: pointer;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(18px);
  color: rgba(255, 255, 255, 0.72);
  border-radius: 999px;
  padding: 10px 20px;
  font-family: var(--font-body);
  font-size: clamp(11px, 0.78vw, 13px);
  font-weight: 500;
  letter-spacing: 0.06em;
  white-space: nowrap;
  transition: background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}
.pill:hover {
  background: rgba(255, 255, 255, 0.13);
  color: #fff;
}
.pill.is-active {
  background: rgba(255, 255, 255, 0.92);
  border-color: transparent;
  color: var(--navy-950);
}

/* --- the running row --- */
.marquee {
  overflow: hidden;
  /* Fades the row into the panel edges instead of cutting it off square. */
  mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.marquee__track {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.6vw, 26px);
  width: max-content;
  will-change: transform;
  padding: clamp(20px, 3vh, 40px) var(--gutter);
}

/* --- a frame, in either view --- */
.shot {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  cursor: pointer;
  background: var(--navy-900);
  border-radius: clamp(10px, 1vw, 16px);
  overflow: hidden;
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.shot img {
  display: block;
  width: 100%;
  height: auto;
}
.shot__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: clamp(28px, 5vh, 54px) clamp(12px, 1.2vw, 20px) clamp(12px, 1.4vh, 18px);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(10.5px, 0.78vw, 13px);
  letter-spacing: 0.04em;
  color: #fff;
  text-align: left;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0) 100%);
  pointer-events: none;
}

/* In the row the frames are sized by height so portrait and landscape both
   keep their own proportions, and they sit at alternating angles. */
.marquee .shot {
  flex: 0 0 auto;
  height: clamp(240px, 40vh, 420px);
  width: auto;
}
.marquee .shot img {
  height: 100%;
  width: auto;
  max-width: none;
}
/* No tilt: the frames run straight, so the row reads as one continuous strip. */
.marquee .shot:hover {
  transform: scale(1.03);
  box-shadow: 0 26px 60px rgba(0, 0, 0, 0.5);
  z-index: 1;
}


/* --- category view: a column flow, so frames keep their own heights --- */
.gallery__grid {
  padding: 0 var(--gutter);
  columns: 4;
  column-gap: clamp(12px, 1.4vw, 22px);
}
.gallery__grid .shot {
  width: 100%;
  break-inside: avoid;
  margin-bottom: clamp(12px, 1.4vw, 22px);
}
.gallery__grid .shot:hover {
  transform: scale(1.015);
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.45);
}
.gallery__grid .shot[hidden] { display: none; }
.gallery__empty {
  padding: clamp(30px, 6vh, 70px) var(--gutter);
  text-align: center;
  font-family: var(--font-body);
  font-weight: 300;
  color: rgba(255, 255, 255, 0.55);
}

/* --- expanded view --- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 90; /* over the navbar at 70 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(20px, 5vh, 64px) clamp(20px, 5vw, 80px);
}
.lightbox[hidden] { display: none; }
/* Blurs the page behind rather than just darkening it, so the frame in front
   is the only sharp thing on screen. */
.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 8, 16, 0.62);
  backdrop-filter: blur(22px);
  opacity: 0;
  transition: opacity 0.5s ease;
  cursor: zoom-out;
}
.lightbox.is-open .lightbox__backdrop { opacity: 1; }
.lightbox__figure {
  position: relative;
  z-index: 1;
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
}
.lightbox__figure img {
  display: block;
  max-width: 100%;
  /* Room left under it for the caption. */
  /* Width and height are set by main.js so the box matches the picture and
     does not depend on which file is currently loaded. */
  max-height: calc(100% - 46px);
  object-fit: contain;
  border-radius: clamp(8px, 0.8vw, 14px);
  transform-origin: 50% 50%;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.5);
}
.lightbox__figure figcaption {
  margin-top: 16px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(12px, 0.9vw, 15px);
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.8);
  opacity: 0;
  transition: opacity 0.4s ease 0.25s;
}
.lightbox.is-open .lightbox__figure figcaption { opacity: 1; }
.lightbox__close {
  position: absolute;
  top: clamp(16px, 3vh, 34px);
  right: clamp(16px, 3vw, 40px);
  z-index: 2;
  cursor: pointer;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.24);
  backdrop-filter: blur(18px);
  color: #fff;
  font-size: 22px;
  line-height: 1;
  opacity: 0;
  transition: opacity 0.4s ease 0.2s, background 0.3s ease;
}
.lightbox.is-open .lightbox__close { opacity: 1; }
.lightbox__close:hover { background: rgba(255, 255, 255, 0.2); }

body.is-locked { overflow: hidden; }

@media (max-width: 1100px) {
  .gallery__grid { columns: 3; }
}
@media (max-width: 780px) {
  .gallery__intro { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .gallery__grid { columns: 2; }
  .marquee .shot { height: clamp(200px, 32vh, 280px); }
}
@media (max-width: 480px) {
  .gallery__grid { columns: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .shot,
  .lightbox__figure img,
  .lightbox__backdrop { transition: none; }
}

/* Kept in the document for structure and screen readers while the visible
   title is gone. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============ Gallery entrance ============
   The page assembles rather than arriving all at once: the clip settles out of
   a slight push-in, then the note, then the pills, then the row. main.js adds
   .is-ready once the first frame is up, and every delay below hangs off that
   one class so the whole sequence is legible in one place. */
.page--gallery {
  --ent: cubic-bezier(0.22, 1, 0.36, 1);
}

/* The clip eases out of a push-in. The 1.08 scale it settles on is the one
   that keeps the baked-in blur's soft edges off screen. */
.gallery__bg {
  opacity: 0;
  transform: scale(1.05);
  transition: opacity 1.5s ease, transform 2s var(--ent);
}
.gallery__panel.is-ready .gallery__bg {
  opacity: 1;
  transform: scale(1);
}
.gallery__scrim {
  opacity: 0;
  transition: opacity 1.3s ease 0.15s;
}
.gallery__panel.is-ready .gallery__scrim { opacity: 1; }

.gallery__head {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ent) 0.32s, transform 0.9s var(--ent) 0.32s;
}
.gallery__panel.is-ready .gallery__head {
  opacity: 1;
  transform: none;
}

/* The pills come in left to right. Six of them, so the delays are written out
   rather than computed — it is less machinery than a custom property. */
.gallery__filters .pill {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.6s var(--ent), transform 0.6s var(--ent),
    background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}
.gallery__panel.is-ready .gallery__filters .pill {
  opacity: 1;
  transform: none;
}
.gallery__filters .pill:nth-child(1) { transition-delay: 0.46s, 0.46s, 0s, 0s, 0s; }
.gallery__filters .pill:nth-child(2) { transition-delay: 0.52s, 0.52s, 0s, 0s, 0s; }
.gallery__filters .pill:nth-child(3) { transition-delay: 0.58s, 0.58s, 0s, 0s, 0s; }
.gallery__filters .pill:nth-child(4) { transition-delay: 0.64s, 0.64s, 0s, 0s, 0s; }
.gallery__filters .pill:nth-child(5) { transition-delay: 0.70s, 0.70s, 0s, 0s, 0s; }
.gallery__filters .pill:nth-child(6) { transition-delay: 0.76s, 0.76s, 0s, 0s, 0s; }

/* The row's frames rise in sequence. --i is stamped on each frame in the
   markup; capped so the ones already off screen do not push the tail of the
   sequence out to several seconds. */
.marquee .shot {
  opacity: 0;
  transform: translateY(34px);
  transition: opacity 0.85s var(--ent) calc(0.6s + min(var(--i, 0), 9) * 0.06s),
    transform 0.85s var(--ent) calc(0.6s + min(var(--i, 0), 9) * 0.06s),
    box-shadow 0.7s var(--ent);
}
.gallery__panel.is-ready .marquee .shot {
  opacity: 1;
  transform: none;
}
/* Hover has to win over the entrance's resting transform once it is in. */
.gallery__panel.is-ready .marquee .shot:hover {
  transform: scale(1.03);
}

/* Category views get the same treatment when a pill is picked, so switching
   set does not feel abrupt next to the entrance. main.js stamps the delay. */
.gallery__grid .shot {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.6s var(--ent), transform 0.6s var(--ent),
    box-shadow 0.7s var(--ent);
}
.gallery__grid .shot.is-in {
  opacity: 1;
  transform: none;
}
.gallery__grid .shot.is-in:hover { transform: scale(1.015); }

@media (prefers-reduced-motion: reduce) {
  .gallery__bg,
  .gallery__scrim,
  .gallery__head,
  .gallery__filters .pill,
  .marquee .shot,
  .gallery__grid .shot {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============ Page entrance ============
   Shared mechanism: any page whose body carries data-entrance gets .is-ready
   added by main.js, and the rules below hang every delay off that one class so
   a page's whole sequence stays readable in one place.

   Everything here starts at opacity 0, which means a page that never gets the
   class is blank rather than merely unanimated — main.js therefore adds it on a
   timer as well as on a frame. */
[data-entrance] {
  --ent: cubic-bezier(0.22, 1, 0.36, 1);
}

/* The navbar arrives on every entrance page, just after the backdrop. */
[data-entrance] .navbar {
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 0.8s var(--ent) 0.2s, transform 0.8s var(--ent) 0.2s,
    background 0.35s ease, backdrop-filter 0.35s ease;
}
[data-entrance].is-ready .navbar {
  opacity: 1;
  transform: none;
}

/* ---------- Home ---------- */
/* The hero settles out of a push-in. Its opacity is safe to animate: the scroll
   scrub writes to the canvas pixels and to the overlays, never to this box. */
.page--home .hero__bg {
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 1.5s ease, transform 2.2s var(--ent);
}
.page--home.is-ready .hero__bg {
  opacity: 1;
  transform: none;
}
.page--home .hero__content {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 1s var(--ent) 0.55s, transform 1s var(--ent) 0.55s;
}
.page--home.is-ready .hero__content {
  opacity: 1;
  transform: none;
}
/* The cards animate, not the strip around them: the scroll scrub owns the
   strip's own opacity and would overwrite anything set on it. */
.page--home .feature-card {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.85s var(--ent), transform 0.85s var(--ent);
}
.page--home.is-ready .feature-card {
  opacity: 1;
  transform: none;
}
.page--home .feature-card:nth-child(1) { transition-delay: 0.7s; }
.page--home .feature-card:nth-child(2) { transition-delay: 0.82s; }
.page--home .feature-card:nth-child(3) { transition-delay: 0.94s; }

/* ---------- Enquire ---------- */
.page--enquire .enquire__bg {
  opacity: 0;
  transform: scale(1.05);
  transition: opacity 1.5s ease, transform 2.2s var(--ent);
}
.page--enquire.is-ready .enquire__bg {
  opacity: 1;
  transform: none;
}
.page--enquire .enquire__scrim {
  opacity: 0;
  transition: opacity 1.2s ease 0.1s;
}
.page--enquire.is-ready .enquire__scrim { opacity: 1; }

/* Two lines, one after the other. */
.page--enquire .enquire__title-line {
  display: block;
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.9s var(--ent), transform 0.9s var(--ent);
}
.page--enquire.is-ready .enquire__title-line {
  opacity: 1;
  transform: none;
}
.page--enquire .enquire__title-line:nth-child(1) { transition-delay: 0.34s; }
.page--enquire .enquire__title-line:nth-child(2) { transition-delay: 0.46s; }

.page--enquire .enquire__lede {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ent) 0.6s, transform 0.9s var(--ent) 0.6s;
}
.page--enquire.is-ready .enquire__lede {
  opacity: 1;
  transform: none;
}

/* Contact rows come in as a group of four, left to right then down. */
.page--enquire .enquire__contact > div {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.7s var(--ent), transform 0.7s var(--ent);
}
.page--enquire.is-ready .enquire__contact > div {
  opacity: 1;
  transform: none;
}
.page--enquire .enquire__contact > div:nth-child(1) { transition-delay: 0.76s; }
.page--enquire .enquire__contact > div:nth-child(2) { transition-delay: 0.84s; }
.page--enquire .enquire__contact > div:nth-child(3) { transition-delay: 0.92s; }
.page--enquire .enquire__contact > div:nth-child(4) { transition-delay: 1s; }

/* The card slides in from its own side, which reads as it arriving rather than
   simply appearing where it already was. */
.page--enquire .enquire__card {
  opacity: 0;
  transform: translateX(46px);
  transition: opacity 1.1s var(--ent) 0.42s, transform 1.1s var(--ent) 0.42s;
}
.page--enquire.is-ready .enquire__card {
  opacity: 1;
  transform: none;
}

.page--enquire .enquire__step {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.7s var(--ent), transform 0.7s var(--ent),
    color 0.4s ease, border-color 0.4s ease;
}
.page--enquire.is-ready .enquire__step {
  opacity: 1;
  transform: none;
}
.page--enquire .enquire__step:nth-child(1) { transition-delay: 0.9s, 0.9s, 0s, 0s; }
.page--enquire .enquire__step:nth-child(2) { transition-delay: 0.98s, 0.98s, 0s, 0s; }
.page--enquire .enquire__step:nth-child(3) { transition-delay: 1.06s, 1.06s, 0s, 0s; }
.page--enquire .enquire__step:nth-child(4) { transition-delay: 1.14s, 1.14s, 0s, 0s; }

@media (prefers-reduced-motion: reduce) {
  [data-entrance] .navbar,
  .page--home .hero__bg,
  .page--home .hero__content,
  .page--home .feature-card,
  .page--enquire .enquire__bg,
  .page--enquire .enquire__scrim,
  .page--enquire .enquire__title-line,
  .page--enquire .enquire__lede,
  .page--enquire .enquire__contact > div,
  .page--enquire .enquire__card,
  .page--enquire .enquire__step {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============ About: light band ============
   Specification and accommodation sit on a light ground, so the page breaks
   rather than running as one long dark scroll.

   The band has to reach the screen edges from inside a max-width container.
   box-shadow spreads the fill sideways and clip-path trims it back vertically,
   which costs no layout — 100vw would have been simpler but it counts the
   scrollbar, so the band would sit ~15px wider than the content and put a
   horizontal scrollbar on the page. */
.about__light {
  display: flex;
  flex-direction: column;
  gap: clamp(72px, 12vh, 150px);
  padding: clamp(64px, 10vh, 120px) 0;
  background: #f2efe8;
  color: var(--text-dark);
  box-shadow: 0 0 0 100vmax #f2efe8;
  clip-path: inset(0 -100vmax);
}

/* --- type flips to dark on the band --- */
.about__light .about__eyebrow {
  /* The site gold is too light to read on this ground, so a deeper cut of it
     keeps the accent without dropping the contrast. */
  color: #96692a;
}
.about__light h2,
.about__light h3 { color: var(--navy-950); }
.about__light .about__body { color: rgba(0, 26, 47, 0.7); }

.about__light .about__spec {
  border-top-color: rgba(0, 26, 47, 0.16);
}
.about__light .about__spec:last-child {
  border-bottom-color: rgba(0, 26, 47, 0.16);
}
.about__light .about__spec dt { color: rgba(0, 26, 47, 0.52); }
.about__light .about__spec dd { color: var(--navy-950); }

.about__light .about__cabin-media { background: #e4dfd4; }

/* The pill is built for dark ground — translucent white would vanish here, so
   it inverts to solid navy. */
.about__light .about__link {
  background: var(--navy-950);
  border-color: transparent;
  backdrop-filter: none;
  color: #fff;
}
.about__light .about__link:hover { background: var(--navy-900); }

/* ============ Layout page ============
   Light ground, white tiles, soft shadows — the language of the reference.
   This is the one page on the site that runs light, so it defines its own
   surface tokens rather than borrowing the dark ones. */
.page--deck {
  --ink: #0d1620;
  --ink-soft: rgba(13, 22, 32, 0.62);
  --ink-faint: rgba(13, 22, 32, 0.42);
  --ground: #e9e7e2;
  --tile: #ffffff;
  --tile-2: #f4f2ee;
  --lift: 0 18px 40px rgba(13, 22, 32, 0.08);
  --lift-lg: 0 30px 70px rgba(13, 22, 32, 0.13);
  background: var(--ground);
  color: var(--ink);
}
.deck {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(96px, 13vh, 130px) var(--gutter) clamp(60px, 9vh, 110px);
  display: flex;
  flex-direction: column;
  gap: clamp(56px, 9vh, 118px);
}

/* --- hero card --- */
.deck__badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--tile);
  border: 1px solid rgba(13, 22, 32, 0.08);
  box-shadow: var(--lift);
  border-radius: 999px;
  padding: 8px 16px 8px 10px;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.72vw, 12px);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.deck__badge span {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--ink);
}
.deck__title {
  margin: clamp(20px, 3vh, 34px) 0 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(34px, 5.2vw, 76px);
  line-height: 1.04;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.deck__title em {
  font-style: italic;
  color: #96692a;
}
.deck__lede {
  margin: clamp(16px, 2.4vh, 26px) auto 0;
  max-width: 52ch;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1vw, 16px);
  line-height: 1.7;
  color: var(--ink-soft);
}


/* --- sections --- */
.deck__section--tight { margin-top: calc(-1 * clamp(16px, 3vh, 40px)); }
.deck__head {
  max-width: 46ch;
  margin-bottom: clamp(26px, 4vh, 48px);
}
.deck__eyebrow {
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.68vw, 11.5px);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #96692a;
  margin-bottom: 14px;
}
.deck__section h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(26px, 3.2vw, 46px);
  line-height: 1.1;
  color: var(--ink);
}
.deck__note {
  margin-top: clamp(12px, 1.8vh, 20px);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 0.98vw, 15.5px);
  line-height: 1.65;
  color: var(--ink-soft);
}


/* --- stat tiles --- */
.deck__stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 20px);
}
.deck__stat {
  background: var(--tile);
  border-radius: clamp(12px, 1.2vw, 20px);
  padding: clamp(18px, 2vw, 30px);
  box-shadow: var(--lift);
}
.deck__stat-value {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(28px, 2.8vw, 44px);
  line-height: 1;
  color: var(--ink);
}
.deck__stat-value span {
  margin-left: 5px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.32em;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}
.deck__stat-label {
  margin-top: 12px;
  font-family: var(--font-body);
  font-size: clamp(9px, 0.66vw, 11px);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

@media (max-width: 1000px) {
  .deck__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .deck__stats { grid-template-columns: minmax(0, 1fr); }
}

/* ============ Layout hero ============
   The blurred yacht clip is the ground again, so the pull-back film still has
   a full-bleed frame to arrive on. Dark hero, light tiles below it. */
.deck__hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(104px, 14vh, 150px) clamp(16px, 3vw, 40px) 0;
  overflow: hidden;
  border-radius: 0;
  background: var(--navy-950);
  color: #fff;
  text-align: center;
}
.deck__hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.deck__hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Enough to sit back behind the copy, not so much that she stops reading as
     a yacht. Scaled so the blur's soft edges stay off screen. */
  filter: blur(7px) saturate(1.04);
  transform: scale(1.05);
}
.deck__hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to bottom,
    rgba(0, 12, 24, 0.62) 0%,
    rgba(0, 12, 24, 0.4) 34%,
    rgba(0, 12, 24, 0.52) 100%
  );
}
.deck__hero-copy {
  position: relative;
  z-index: 2;
  width: min(760px, 100%);
}

/* Copy on the dark ground rather than the light tile it was built for. */
.deck__hero .deck__badge {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px);
  box-shadow: none;
  color: rgba(255, 255, 255, 0.78);
}
.deck__hero .deck__badge span { background: var(--gold); }
.deck__hero .deck__title { color: #fff; }
.deck__hero .deck__title em { color: var(--gold-light); }
.deck__hero .deck__lede { color: rgba(255, 255, 255, 0.74); }

/* --- the arc --- */
/* Three frames fanned along a curve. The arc has a definite height and every
   card is anchored to its bottom edge and rotated about its inner bottom
   corner, so the outer two can only ever swing upward — the arc cannot spill
   past the hero however short the viewport gets. */
.deck__arc {
  position: relative;
  z-index: 2;
  --arc-h: min(36vh, 320px);
  margin-top: clamp(18px, 3vh, 44px);
  /* Rotating the outer frames about their inner bottom corner swings their
     outer corner below the box, so that drop is reserved below the arc.
     0.15 covers it: the swing is width x sin(13deg) and width tracks height. */
  margin-bottom: calc(var(--arc-h) * 0.15);
  width: min(940px, 100%);
  height: var(--arc-h);
}
.deck__arc-card {
  position: absolute;
  bottom: 0;
  margin: 0;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: clamp(10px, 1vw, 16px);
  background: var(--navy-900);
  box-shadow: 0 26px 60px rgba(0, 6, 14, 0.5);
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.deck__arc-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.deck__arc-card--mid {
  left: 50%;
  height: 100%;
  z-index: 1;
  transform: translateX(-50%);
}
.deck__arc-card--left {
  right: 55%;
  height: 78%;
  transform-origin: 100% 100%;
  transform: rotate(-13deg);
}
.deck__arc-card--right {
  left: 55%;
  height: 78%;
  transform-origin: 0 100%;
  transform: rotate(13deg);
}
.deck__arc-card--left:hover { transform: rotate(-13deg) translateY(-8px); }
.deck__arc-card--right:hover { transform: rotate(13deg) translateY(-8px); }
.deck__arc-card--mid:hover { transform: translateX(-50%) translateY(-8px); }

@media (max-width: 700px) {
  .deck__arc { --arc-h: min(28vh, 210px); }
  .deck__arc-card--left { right: 52%; transform: rotate(-10deg); }
  .deck__arc-card--right { left: 52%; transform: rotate(10deg); }
}
@media (prefers-reduced-motion: reduce) {
  .deck__arc-card { transition: none; }
}

/* --- entrance --- */
.page--deck .deck__hero-bg {
  opacity: 0;
  transform: scale(1.05);
  transition: opacity 1.5s ease, transform 2.2s var(--ent);
}
.page--deck.is-ready .deck__hero-bg {
  opacity: 1;
  transform: none;
}
.page--deck .deck__hero-scrim {
  opacity: 0;
  transition: opacity 1.2s ease 0.1s;
}
.page--deck.is-ready .deck__hero-scrim { opacity: 1; }

.page--deck .deck__hero-copy > * {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.9s var(--ent), transform 0.9s var(--ent);
}
.page--deck.is-ready .deck__hero-copy > * {
  opacity: 1;
  transform: none;
}
.page--deck .deck__hero-copy > *:nth-child(1) { transition-delay: 0.3s; }
.page--deck .deck__hero-copy > *:nth-child(2) { transition-delay: 0.42s; }
.page--deck .deck__hero-copy > *:nth-child(3) { transition-delay: 0.54s; }

/* The frames rise into the arc, outer ones after the middle. */
.page--deck .deck__arc-card {
  opacity: 0;
}
.page--deck.is-ready .deck__arc-card { opacity: 1; }
.page--deck .deck__arc-card--mid {
  transform: translateX(-50%) translateY(64px);
  transition: opacity 0.9s var(--ent) 0.62s, transform 1.1s var(--ent) 0.62s;
}
.page--deck.is-ready .deck__arc-card--mid { transform: translateX(-50%); }
/* The outer two rise flat and settle into their angle, so the fan opens. */
.page--deck .deck__arc-card--left {
  transform: rotate(0deg) translateY(88px);
  transition: opacity 0.9s var(--ent) 0.74s, transform 1.1s var(--ent) 0.74s;
}
.page--deck.is-ready .deck__arc-card--left { transform: rotate(-13deg); }
.page--deck .deck__arc-card--right {
  transform: rotate(0deg) translateY(88px);
  transition: opacity 0.9s var(--ent) 0.86s, transform 1.1s var(--ent) 0.86s;
}
.page--deck.is-ready .deck__arc-card--right { transform: rotate(13deg); }

/* The staggered entrance delays live on rules that keep matching after the
   entrance, so hover would inherit a 0.86s wait. Reset it for hover only. */
.page--deck .deck__arc-card:hover {
  transition-delay: 0s;
  transition-duration: 0.5s;
}

@media (prefers-reduced-motion: reduce) {
  .page--deck .deck__hero-bg,
  .page--deck .deck__hero-scrim,
  .page--deck .deck__hero-copy > *,
  .page--deck .deck__arc-card {
    opacity: 1;
    transition: none;
  }
  .page--deck .deck__arc-card--mid { transform: translateX(-50%); }
  .page--deck .deck__arc-card--left { transform: rotate(-13deg); }
  .page--deck .deck__arc-card--right { transform: rotate(13deg); }
}

/* ============ Deck showcase ============
   The reference's top-half panel, inverted for this page: a deep card on the
   light ground rather than a light card on a dark one, so the contrast
   relationship survives the page running light. */
.expo {
  --card-pad: clamp(22px, 3.4vw, 58px);
}
.expo__card {
  position: relative;
  background: var(--navy-900);
  border-radius: clamp(16px, 1.8vw, 30px);
  padding: var(--card-pad);
  /* The rail runs past the card's right edge and is cropped by it, which is
     what gives the reference its sense of a strip continuing off-frame. */
  overflow: hidden;
  color: #fff;
}

/* --- heading row --- */
.expo__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: clamp(24px, 4vw, 72px);
}
.expo__index {
  margin: 0;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.72vw, 12px);
  color: rgba(255, 255, 255, 0.4);
}
.expo__label {
  margin: 4px 0 0;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.72vw, 12px);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.9);
}
.expo__title {
  margin: clamp(16px, 2.4vh, 30px) 0 0;
  max-width: 22ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(24px, 2.9vw, 44px);
  line-height: 1.14;
  letter-spacing: -0.01em;
  color: #fff;
}

/* --- deck filter --- */
/* The reference fades the list downward. Fading by distance from the active
   item keeps that look while still reading as a control. */
.expo__filters {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: clamp(6px, 1vh, 12px);
  text-align: right;
}
.expo__filter {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: clamp(13px, 1.1vw, 18px);
  font-weight: 400;
  line-height: 1.3;
  color: #fff;
  opacity: 0.34;
  transition: opacity 0.4s ease;
}
.expo__filter.is-active {
  opacity: 1;
  font-weight: 500;
}
/* Set by JS as distance from the active item, so the list always trails off
   away from whatever is selected. */
.expo__filter[data-fade="1"] { opacity: 0.5; }
.expo__filter[data-fade="2"] { opacity: 0.32; }
.expo__filter[data-fade="3"] { opacity: 0.2; }
.expo__filter[data-fade="4"] { opacity: 0.12; }
.expo__filter:hover { opacity: 0.85; }
.expo__filter.is-active:hover { opacity: 1; }

/* --- stage --- */
.expo__stage {
  margin-top: clamp(26px, 4.5vh, 58px);
  display: grid;
  grid-template-columns: minmax(120px, 0.85fr) minmax(0, 3fr);
  gap: clamp(18px, 2.6vw, 44px);
  align-items: end;
}
.expo__aside {
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 2vh, 22px);
  padding-bottom: clamp(4px, 1vh, 12px);
}
.expo__blurb-name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(17px, 1.5vw, 24px);
  line-height: 1.15;
  color: #fff;
}
.expo__blurb-text {
  margin: 8px 0 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(11px, 0.82vw, 13.5px);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.6);
}
.expo__nav {
  display: flex;
  gap: 10px;
}
.expo__arrow {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: none;
  color: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.3s ease, border-color 0.3s ease, opacity 0.3s ease;
}
.expo__arrow:hover { background: rgba(255, 255, 255, 0.14); }
/* The forward arrow is the filled one in the reference — it is the move the
   panel expects you to make. */
.expo__arrow--next {
  background: #fff;
  border-color: #fff;
  color: var(--navy-950);
}
.expo__arrow--next:hover { background: rgba(255, 255, 255, 0.85); }
.expo__arrow:disabled {
  opacity: 0.3;
  cursor: default;
}
.expo__arrow:disabled:hover { background: none; }
.expo__arrow--next:disabled:hover { background: #fff; }
.expo__all {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: clamp(11px, 0.8vw, 13px);
  color: rgba(255, 255, 255, 0.75);
  transition: color 0.3s ease, gap 0.3s ease;
}
.expo__all:hover { color: #fff; gap: 16px; }
.expo__all span { color: rgba(255, 255, 255, 0.45); }

/* --- the rail --- */
.expo__viewport {
  /* Runs to the card's edge and past it, so the next slide is cropped. */
  margin-right: calc(-1 * var(--card-pad));
  overflow: hidden;
}
.expo__rail {
  display: flex;
  gap: clamp(10px, 1.2vw, 20px);
  transition: transform 0.75s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.expo__slide {
  position: relative;
  flex: 0 0 auto;
  margin: 0;
  width: clamp(230px, 30vw, 460px);
  aspect-ratio: 4 / 3;
  border-radius: clamp(10px, 1vw, 16px);
  overflow: hidden;
  background: var(--navy-950);
}
.expo__slide[hidden] { display: none; }
.expo__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.expo__slide:hover img { transform: scale(1.04); }
/* The title sits in the image, per the brief — the scrim is what keeps it
   readable over whatever the photograph happens to be doing down there. */
.expo__caption {
  position: absolute;
  inset: auto 0 0 0;
  padding: clamp(30px, 4vw, 52px) clamp(14px, 1.6vw, 24px) clamp(13px, 1.6vw, 20px);
  background: linear-gradient(
    to top,
    rgba(0, 12, 24, 0.82) 0%,
    rgba(0, 12, 24, 0.45) 45%,
    rgba(0, 12, 24, 0) 100%
  );
}
.expo__caption h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(16px, 1.5vw, 24px);
  line-height: 1.15;
  color: #fff;
}
.expo__caption p {
  margin: 5px 0 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(10.5px, 0.76vw, 12.5px);
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.66);
}

@media (max-width: 900px) {
  .expo__top {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(20px, 4vh, 34px);
  }
  .expo__filters {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    gap: 8px 18px;
  }
  .expo__stage {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(16px, 3vh, 26px);
  }
  /* Controls move below the rail once the columns stack, so the rail still
     starts at the card edge rather than under a column of buttons. */
  .expo__aside {
    order: 2;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
  }
  .expo__viewport { order: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .expo__rail,
  .expo__slide img,
  .expo__filter,
  .expo__all { transition: none; }
}

/* ============ Loading curtain ============
   Sits above everything, including the lightbox at 90 and the page transition
   overlay at 60, and lifts off the top to hand over to the page entrance.

   These rules have to work before main.js has run a line: the curtain is
   opaque by default and only ever moves once a class is added, so a page whose
   script fails to load shows the lockup rather than a half-animated mess. */
.loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: var(--navy-950);
  transform: translateY(0);
  transition: transform 1.15s cubic-bezier(0.76, 0, 0.24, 1);
}
/* A very faint wash so the panel is not a flat black rectangle. */
.loader::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    120% 90% at 50% 108%,
    rgba(232, 175, 105, 0.16) 0%,
    rgba(232, 175, 105, 0) 62%
  );
  pointer-events: none;
}
.loader.is-done { transform: translateY(-100%); }
.loader.is-gone { display: none; }

.loader__inner {
  position: relative;
  z-index: 1;
  width: min(460px, 100%);
  text-align: center;
  transition: opacity 0.42s ease, transform 0.42s ease;
}
/* The lockup leaves before the panel does, so the curtain is empty as it
   lifts rather than dragging the wordmark up the screen with it. */
.loader.is-done .loader__inner {
  opacity: 0;
  transform: translateY(-14px);
}

.loader__mark {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  color: #fff;
}
.loader__name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(30px, 5vw, 62px);
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* Letter-spacing puts a trailing gap after the last character, which reads
     as the wordmark sitting left of centre. */
  text-indent: 0.1em;
}
.loader__sub {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(8.5px, 0.72vw, 10.5px);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  text-indent: 0.3em;
}

.loader__track {
  position: relative;
  height: 1px;
  margin: clamp(28px, 4.5vh, 46px) 0 0;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
}
.loader__fill {
  display: block;
  height: 100%;
  background: linear-gradient(to right, var(--gold), var(--gold-light));
  transform: scaleX(0.02);
  transform-origin: 0 50%;
  /* Short, so the bar tracks the counter instead of gliding behind it. */
  transition: transform 0.35s ease-out;
}
.loader__count {
  margin: 14px 0 0;
  font-family: var(--font-body);
  font-size: clamp(9.5px, 0.7vw, 11px);
  font-weight: 400;
  letter-spacing: 0.22em;
  color: rgba(255, 255, 255, 0.42);
}

/* The between-pages version: no counting, just a short wipe. There is nothing
   to report progress on when the page is already cached, and a bar that flashes
   full reads worse than no bar. */
.loader--brief {
  transition-duration: 0.5s;
}
.loader--brief .loader__inner {
  transition-duration: 0.2s;
}
.loader--brief .loader__track,
.loader--brief .loader__count { display: none; }

/* The wordmark settles in rather than being there from frame one — the only
   entrance on the site that cannot wait for the gate, since it is the gate. */
@keyframes loaderMark {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.loader:not(.loader--brief) .loader__mark {
  animation: loaderMark 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.loader:not(.loader--brief) .loader__track,
.loader:not(.loader--brief) .loader__count {
  animation: loaderMark 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.28s both;
}

@media (prefers-reduced-motion: reduce) {
  .loader,
  .loader__inner,
  .loader__fill { transition-duration: 0.25s; }
  .loader .loader__mark,
  .loader .loader__track,
  .loader .loader__count { animation: none; }
  .loader__count { display: none; }
}

/* ============ Cursor hint ============
   Follows the pointer over the first screen until the user starts scrolling.
   pointer-events: none matters more than it looks — it passes over the navbar
   and the hero's links, and must never be what receives the click. */
.cursor-hint {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 150; /* over the navbar at 70, under the curtain at 200 */
  margin: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 17px;
  border-radius: 999px;
  /* The house frosted surface — same values as the accordion list. */
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(18px);
  font-family: var(--font-body);
  font-size: clamp(10px, 0.74vw, 12.5px);
  font-weight: 400;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.88);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
  will-change: transform;
}
/* Added once the pointer has reported a position, so it never fades in at the
   top-left corner before it knows where to be. */
.cursor-hint.is-visible { opacity: 1; }

.cursor-hint__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  flex: 0 0 auto;
  animation: hintPulse 2.4s ease-in-out infinite;
}
@keyframes hintPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.7); }
}

/* No pointer to follow on touch, so it sits the whole thing out rather than
   parking a label in the corner. JS bails on the same query. */
@media (hover: none), (pointer: coarse) {
  .cursor-hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .cursor-hint__dot { animation: none; }
}

/* ============ Mobile fixes ============ */
@media (max-width: 720px) {
  /* The menu is a pill on desktop. As a tall column that same 999px radius
     produces lozenge ends that curve in across the first and last link, which
     is what made the text look cut off. */
  /* A standard mobile menu: a full-width panel dropping from the header, edge
     to edge, no radius. The pill shape belongs to the desktop bar. */
  .navbar__menu {
    left: 0;
    right: 0;
    top: 100%;
    width: 100%;
    border-radius: 0;
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding: 6px var(--gutter) 14px;
    gap: 0;
    background: rgba(0, 12, 24, 0.94);
    backdrop-filter: blur(18px);
  }
  /* A divider per row, the way a native list reads. */
  .navbar__menu a + a { border-top: 1px solid rgba(255, 255, 255, 0.08); }
  /* Links carry their own height so each row is a real tap target rather than
     a line of text with the gap standing in for one. */
  .navbar__menu a {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 44px;
    font-size: 16px;
    opacity: 0.92;
  }

  /* The hero cards are a desktop flourish: on a phone they crowd the frame the
     scrub is the point of, and they were the last thing left above the fold. */
  .feature-strip { display: none; }
  .hero__bottom { gap: 0; }

  /* --- accordion --- */
  /* It was landing in the bottom half of the screen as a 397px block of 42px
     rows — legible in principle, unreadable in practice. Rows get real height
     and the type comes up to a size worth setting on a phone. */
  .reel__head {
    padding: 15px 18px;
    min-height: 52px;
  }
  .reel__title {
    font-size: 16px;
    letter-spacing: 0.01em;
  }
  .reel__item.is-open .reel__panel { padding-bottom: 14px; }
  .reel__media { border-radius: 10px; }
}

/* The smallest phones cannot afford the same generosity, so the rows keep
   their height but the type steps back down rather than wrapping. */
@media (max-width: 380px) {
  .reel__title { font-size: 15px; }
  .reel__head { padding: 14px 15px; }
}

/* ============ Accordion section: fitting a phone frame ============
   Pinned, this section gets ~760px under the navbar and its richest card
   (Life on board, with four sub-sections) wants ~1108px. The 348px difference
   was being cut off at both ends. Everything below buys that space back.

   Space comes from spacing and from the decorative clip before it comes from
   type, because the copy is the reason the section exists. */
@media (max-width: 720px) {
  .reel { padding-top: clamp(70px, 8.4vh, 88px); }
  .reel__inner { gap: 14px; }

  .reel__detail-title { font-size: 18px; line-height: 1.2; }
  .reel__detail-copy { font-size: 13px; line-height: 1.45; }
  .reel__meta { margin-top: 12px; gap: 9px 18px; }
  .reel__meta dt { font-size: 9.5px; }
  /* line-height was `normal`; naming it lets the four paragraphs tighten
     without dropping the type size as far. */
  .reel__meta dd { font-size: 12.5px; line-height: 1.4; }

  /* The rows keep a 44px touch target while giving back the extra height. */
  .reel__head { padding: 9px 16px; min-height: 42px; }
  .reel__title { font-size: 15px; }

  /* The clip stays in the card, where it belongs. Hiding it was the wrong
     trade: the rule only ever hid the OPEN card's video - the one being
     looked at - while every collapsed card kept its own. */
  .reel__item.is-open .reel__media { max-height: 150px; }
  .reel__item.is-open .reel__panel { padding-bottom: 10px; }

  /* What gives way instead is the four sub-sections. A pinned phone frame
     cannot hold the clip and ~340px of detail copy at once, and the same
     ground is covered on the About page. Eyebrow, headline and the intro
     line still carry the card. */
  .reel__meta { display: none; }

  /* Backdrop steps back now that the card carries its own clip, though not
     all the way to the 26px that made it a flat wash. */
  .reel__bg-layer > video,
  .reel__bg-layer > img {
    filter: blur(16px) saturate(1.05);
    transform: scale(1.09);
  }
  .reel__bg-scrim { background: rgba(0, 12, 24, 0.55); }

  /* Last of the space comes from the four paragraphs, tightened rather than
     shrunk much further - they are what the section is for. */
}

/* Shorter phones (a 360x740 Android is the common case) have ~100px less to
   work with, so the same content needs another pass. */
@media (max-width: 720px) and (max-height: 800px) {
  .reel { padding-top: clamp(62px, 7.8vh, 78px); }
  .reel__inner { gap: 10px; }
  .reel__detail-title { font-size: 16.5px; }
  .reel__detail-copy { font-size: 12px; }
  .reel__head { padding: 8px 14px; min-height: 40px; }
  .reel__title { font-size: 14px; }
}

/* Centring splits any remaining overflow between top and bottom, which is what
   put the opening line under the header. `safe` centres while it fits and falls
   back to the start edge when it does not, so the copy always begins where it
   can be read and only the tail of the list can ever be trimmed. */
@media (max-width: 720px) {
  .reel { align-items: safe center; }
}
