/* =====================================================================
   Yacht Luxury Beds
   Built on the approved brand guide: Marine Navy #002C50, Warm Gold
   #B59048, Soft Ivory #FEFDF8, Cormorant Garamond + Manrope.
   ===================================================================== */

@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../assets/fonts/cormorant.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Manrope';
  src: url('../assets/fonts/manrope.woff2') format('woff2-variations');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- tokens ---------- */
:root {
  --navy: #002C50;
  --gold: #B59048;
  --ivory: #FEFDF8;
  --ivory-deep: #F5F0E4;
  --navy-70: rgba(0, 44, 80, 0.72);
  --navy-45: rgba(0, 44, 80, 0.45);
  --navy-16: rgba(0, 44, 80, 0.16);
  --ivory-72: rgba(254, 253, 248, 0.72);
  --ivory-60: rgba(254, 253, 248, 0.62);
  --ivory-40: rgba(254, 253, 248, 0.4);
  --alert: #F3C4AD;
  /* the brand gold darkened just enough to carry small text on ivory: 6.0:1 */
  --gold-ink: #7A5D22;

  --display: 'Cormorant Garamond', 'Times New Roman', serif;
  --body: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --gutter: clamp(20px, 5vw, 72px);
  --section: clamp(84px, 11vw, 168px);
  --header-h: 76px;
  --appbar-h: 0px;
  --hero-h: max(620px, calc(100svh - var(--header-h)));
  /* centre of the cabin window inside the scene, used as the zoom target */
  --window-x: 58.85%;
  --window-y: 30.9%;
  /* the statement's slot: how far back over the dive it reaches, and how long
     it holds once pinned */
  --stage-h: clamp(540px, 82svh, 900px);
  --arrival-reach: 128svh;
  --arrival-slot: 190svh;

  --ease: cubic-bezier(0.22, 0.61, 0.24, 1);
  --ui: 190ms var(--ease);
  --content: 560ms var(--ease);

  --measure: 34rem;
}

@media (max-width: 767.98px) {
  :root { --header-h: 58px; --appbar-h: calc(62px + env(safe-area-inset-bottom)); }
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 18px);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ivory);
  color: var(--navy);
  font-family: var(--body);
  font-size: clamp(1rem, 0.96rem + 0.18vw, 1.125rem);
  line-height: 1.58;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  padding-bottom: var(--appbar-h);
}

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

h1, h2, h3 { font-family: var(--display); font-weight: 400; line-height: 1.04; margin: 0; text-wrap: balance; }
p { margin: 0 0 1.15em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

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

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 1px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.skip-link {
  position: fixed;
  top: 10px; left: 50%;
  translate: -50% -180%;
  z-index: 100;
  background: var(--navy); color: var(--ivory);
  padding: 12px 20px;
  font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase;
  text-decoration: none;
  transition: translate var(--ui);
}
.skip-link:focus-visible { translate: -50% 0; }

/* ---------- shared type ---------- */
.eyebrow {
  display: block;
  font-size: clamp(0.66rem, 0.62rem + 0.12vw, 0.74rem);
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--navy-70);
  margin: 0 0 1.4em;
}
.eyebrow--on-dark { color: var(--gold); }

.display {
  font-size: clamp(2.1rem, 1.05rem + 3.6vw, 4rem);
  line-height: 1.08;
  letter-spacing: -0.005em;
}

.section-title {
  font-size: clamp(1.85rem, 1.1rem + 2.6vw, 3.15rem);
  line-height: 1.1;
}

.section-head { margin-bottom: clamp(40px, 6vw, 84px); }
.section-head--center { text-align: center; max-width: 46rem; margin-inline: auto; }
.section-head--center .section-intro {
  margin-top: 1.2em;
  color: var(--navy-70);
  font-size: 1rem;
}

.text-link {
  color: var(--navy);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  border-bottom: 1px solid var(--gold);
  padding-bottom: 3px;
  transition: color var(--ui), border-color var(--ui);
}
.text-link:hover { color: var(--gold); }

.rule {
  display: block;
  height: 1px;
  background: var(--gold);
  transform-origin: left center;
}
.rule--on-dark { background: var(--gold); }

/* ---------- buttons ---------- */
.button {
  --btn-bg: transparent;
  --btn-fg: var(--navy);
  --btn-line: var(--navy);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 30px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-line);
  border-radius: 0;
  font-family: var(--body);
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--ui), color var(--ui), border-color var(--ui), translate var(--ui);
}
.button--primary { --btn-bg: var(--navy); --btn-fg: var(--ivory); --btn-line: var(--navy); }
.button--primary:hover { --btn-bg: var(--gold); --btn-line: var(--gold); translate: 0 -2px; }
.button--quiet { --btn-bg: transparent; --btn-fg: var(--navy); --btn-line: var(--navy-45); }
.button--quiet:hover { --btn-line: var(--gold); --btn-fg: var(--gold); translate: 0 -2px; }
.button--gold { --btn-bg: var(--gold); --btn-fg: var(--navy); --btn-line: var(--gold); font-weight: 700; }
.button--gold:hover { --btn-bg: var(--ivory); --btn-line: var(--ivory); translate: 0 -2px; }
.button[disabled] { opacity: 0.6; cursor: progress; translate: none; }

/* =====================================================================
   HEADER
   ===================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  background: var(--ivory);
  border-bottom: 1px solid transparent;
  transition: border-color var(--ui), box-shadow var(--ui), translate 420ms var(--ease);
}
/* The bar gets out of the way on the way down and comes straight back the
   moment the visitor asks for it by scrolling up. It is translated rather than
   unstuck, so nothing below it moves and the scroll offsets still hold. */
.site-header.is-hidden { translate: 0 -100%; }
/* far enough to carry the crest hanging below it off the screen too */
@media (min-width: 1024px) and (min-height: 701px) {
  .site-header.is-hidden { translate: 0 calc(-1 * (var(--header-h) + 210px)); }
}
.site-header.is-stuck {
  border-bottom-color: var(--navy-16);
  box-shadow: 0 10px 30px -28px rgba(0, 44, 80, 0.8);
}

.site-nav {
  height: 100%;
  max-width: 1680px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(20px, 4vw, 64px);
}
.site-nav__group {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.6vw, 44px);
  margin: 0; padding: 0; list-style: none;
}
.site-nav__group--start { justify-content: flex-end; }
.site-nav__group--end { justify-content: flex-start; }
.site-nav a {
  position: relative;
  color: var(--navy);
  text-decoration: none;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 6px 0;
}
.site-nav a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--gold);
  scale: 0 1;
  transform-origin: left center;
  transition: scale 260ms var(--ease);
}
.site-nav a:hover::after,
.site-nav a.is-active::after { scale: 1 1; }

.site-nav__brand {
  position: relative;
  display: grid;
  place-items: center;
  height: 100%;
  font-size: clamp(0.7rem, 0.6rem + 0.3vw, 0.82rem);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  font-weight: 600;
}

/* The crest is square and cannot come below 318px without the simplified mark
   the brand guide asks for, so it hangs from the bar on its own ivory plate
   rather than being squeezed into it. Once the page is scrolled it gives way
   to the name in type and the bar stays slim. */
/* the bar reserves the mark's width, so the links never sit under it */
@media (min-width: 1024px) and (min-height: 701px) {
  .site-nav__brand { min-width: 210px; }
}

.site-nav__crest {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% 0;
  display: block;
  width: 200px;
  transition: opacity 320ms var(--ease), translate 320ms var(--ease);
}
/* The artwork is cut out, so instead of a panel it carries a soft ivory field
   of its own: it keeps the navy and gold legible over the photograph without
   a hard edge around the mark. */
.site-nav__crest::before {
  content: '';
  position: absolute;
  inset: -14% -18% -10%;
  background: radial-gradient(60% 56% at 50% 46%,
    rgba(254, 253, 248, 0.96) 0%,
    rgba(254, 253, 248, 0.9) 45%,
    rgba(254, 253, 248, 0.64) 68%,
    rgba(254, 253, 248, 0) 100%);
  z-index: -1;
}
.site-nav__crest img { display: block; width: 100%; height: auto; }
/* The crest sets the name in its own lettering, so while it is showing the bar
   does not repeat it. Once the page is scrolled the crest gives way to the
   simplified mark: the oval device on its own, without the lettering, which is
   the only form of the logo that survives a 76px bar. The full crest cannot go
   there, because the guide sets a 240px minimum for its visible artwork.

   This mark is cut from the approved crest (`assets/src/crest-symbol.png`) and
   is an interim: the guide asks for a separately prepared simplified mark, so
   it wants the designer's sign-off before launch. */
.site-nav__name { display: none; }

.site-nav__mark {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 58px;
  translate: -50% -50%;
  opacity: 0;
  scale: 0.9;
  pointer-events: none;
  transition: opacity 280ms var(--ease), scale 280ms var(--ease);
}
.site-nav__mark img { display: block; width: 100%; height: auto; }

/* The crest stays exactly as it is at the top of the page, in every state: it
   does not swap for anything when the page is scrolled, so the bar the visitor
   scrolls back up to is the bar they started with. Only the overhanging part
   is passed through to the page: the link's hit area is the bar itself, so the
   mark hanging over the content never swallows a click meant for it. */
.site-nav__crest { pointer-events: none; }

/* Where the crest cannot hang below the bar at all, the simplified mark carries it. */
/* the language switch sits at the end of the right-hand group */
.site-nav__lang a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border: 1px solid var(--navy-16);
  border-radius: 3px;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  transition: border-color var(--ui), color var(--ui);
}
.site-nav__lang a:hover { border-color: var(--gold); color: var(--gold-ink); }

@media (max-width: 1023.98px), (max-height: 700px) {
  .site-nav__crest { display: none; }
  .site-nav__mark { opacity: 1; scale: 1; width: 52px; }
}
.site-nav__brand::after { display: none; }


/* Between the breakpoint and about 1200px the links, the crest and the
   language switch are tight enough to push the right-hand group past the
   edge, so the spacing closes up before anything overflows. */
@media (min-width: 1024px) and (max-width: 1199.98px) {
  .site-nav { gap: clamp(12px, 2vw, 28px); padding-inline: clamp(16px, 3vw, 40px); }
  .site-nav__group { gap: clamp(12px, 1.8vw, 24px); }
  .site-nav a { font-size: 0.66rem; letter-spacing: 0.14em; }
  .site-nav__lang a { padding: 3px 6px; }
}

@media (max-width: 1023.98px) {
  .site-nav { grid-template-columns: 1fr; justify-items: center; }
  .site-nav__group { display: none; }
}

/* =====================================================================
   HERO
   ===================================================================== */
.hero-stage { position: relative; }
.dive-track { display: none; }

/* Section two opens with its statement. Where the dive runs, that statement
   sits over the open water; everywhere else it is a normal ivory opening.
   The crest always keeps the quiet ivory field the brand guide asks for. */
.intro__arrival {
  max-width: 1680px;
  margin-inline: auto;
  padding: clamp(64px, 10vw, 120px) var(--gutter) 0;
  background: var(--ivory);
}
.intro__arrival .display { max-width: 22ch; }
.arrival__rule { display: none; }
.arrival__foot { display: none; }
.arrival__word { opacity: 1; }
.intro__ground { background: var(--ivory); }
.eyebrow--on-water { color: var(--navy-70); }
.hero {
  --scene-w: max(100vw, calc(var(--hero-h) * 1.7684));
  position: relative;
  height: var(--hero-h);
  overflow: hidden;
  background: var(--ivory-deep);
  isolation: isolate;
}

.hero__media { position: absolute; inset: 0; overflow: hidden; }

.hero__scene {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: clamp(calc(100vw - var(--scene-w)), calc(50vw - var(--scene-w) * 0.6), 0px);
  width: var(--scene-w);
  aspect-ratio: 2688 / 1520;
  translate: var(--pan-match, 0px) -50%;
  transform-origin: var(--window-x) var(--window-y);
  scale: calc(1.045 * var(--dive-zoom, 1));
  will-change: transform;
}

.hero__plane { position: absolute; inset: 0; will-change: transform; }
.hero__plane--interior { opacity: var(--dive-interior, 1); }
.hero__plane--sea { opacity: var(--dive-sea, 1); }
.hero__plane--sea {
  left: 19.42%;
  top: 16.447%;
  right: auto; bottom: auto;
  width: 78.906%;
  height: 29.079%;
}
.hero__plane--sea img { width: 100%; height: 100%; object-fit: cover; }
.hero__plane--interior img { width: 100%; height: auto; }

.hero__layer {
  position: absolute;
  inset: 0;
  transition: opacity 900ms var(--ease);
}
.hero__layer--evening { opacity: 0; }

.hero__caustics {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 19.737%;
  mix-blend-mode: screen;
  opacity: 0.85;
  transition: opacity 900ms var(--ease);
}
.hero__caustics img { width: 100%; height: 100%; object-fit: fill; }
.hero.is-animating:not([data-mode='evening']) .hero__caustics {
  animation: drift 13s ease-in-out infinite alternate;
}
@keyframes drift {
  from { translate: 0 0; opacity: 0.6; }
  to   { translate: 1.1% 0.6%; opacity: 0.95; }
}

.hero__mobile { display: none; position: absolute; inset: 0; }
.hero__mobile img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 58%; }

/* evening state (CSS :has, with a JS-set data attribute as a fallback) */
.hero:has(#light-evening:checked) .hero__layer--evening,
.hero[data-mode='evening'] .hero__layer--evening { opacity: 1; }
.hero:has(#light-evening:checked) .hero__caustics,
.hero[data-mode='evening'] .hero__caustics { opacity: 0; }

/* open water, faded in as the scene passes through the glass */
.hero__ocean {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: var(--dive-ocean, 0);
  /* keeps drifting in through the held moment, so the frame is never static */
  scale: calc(var(--dive-ocean-scale, 1.06) * (1 + 0.05 * var(--arrival-hold, 0)));
  will-change: opacity, transform;
  pointer-events: none;
}
.hero__ocean img { width: 100%; height: 100%; object-fit: cover; }
/* real footage over the still, faded in only once it is actually playing */
.hero__footage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 900ms var(--ease);
  pointer-events: none;
}
.hero__footage.is-playing { opacity: 1; }

/* The cabin pan: real footage of the room, shown while the hero is at rest.
   It hands back to the layered stills as soon as the dive starts, because the
   dive needs those separate planes to fly through the window. */
.hero__pan {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  transform-origin: var(--window-x) var(--window-y);
  scale: var(--dive-zoom, 1);
  opacity: 0;
  pointer-events: none;
  transition: opacity 500ms var(--ease);
}
.hero__pan.is-live { opacity: clamp(0, calc(1 - var(--dive-pan-out, 0)), 1); }
.hero__pan-clip {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 900ms var(--ease);
}
.hero__pan-clip.hero__layer--evening { opacity: 0; }
.hero:has(#light-evening:checked) .hero__pan-clip.hero__layer--evening,
.hero[data-mode='evening'] .hero__pan-clip.hero__layer--evening { opacity: 1; }

@media (max-width: 1023.98px), (orientation: portrait) {
  .hero__pan { display: none; }
}

/* veil: keeps the headline legible over the image */
.hero__veil {
  position: absolute;
  inset: 0;
  /* above the pan footage, so the headline keeps its scrim */
  z-index: 3;
  opacity: var(--dive-content, 1);
  /* Enough weight to carry the headline and no more: measured against the
     darkest pixel under the text, this holds about 5:1. */
  background: linear-gradient(97deg,
    rgba(254, 253, 248, 0.62) 0%,
    rgba(254, 253, 248, 0.5) 22%,
    rgba(254, 253, 248, 0.24) 42%,
    rgba(254, 253, 248, 0) 58%);
  transition: background 900ms var(--ease);
}
.hero:has(#light-evening:checked) .hero__veil,
.hero[data-mode='evening'] .hero__veil {
  background: linear-gradient(97deg,
    rgba(0, 24, 44, 0.62) 0%,
    rgba(0, 24, 44, 0.5) 24%,
    rgba(0, 24, 44, 0.24) 44%,
    rgba(0, 24, 44, 0) 60%);
}

.hero__content {
  position: relative;
  z-index: 2;
  /* It is the full height of the hero so the copy can sit at the foot of the
     picture, which means most of it is empty space lying over the light
     control. Only its actual content takes the pointer. */
  pointer-events: none;
  opacity: var(--dive-content, 1);
  translate: 0 calc(-42px * (1 - var(--dive-content, 1)));
  height: 100%;
  max-width: 1680px;
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(76px, 12vh, 132px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  transition: color 900ms var(--ease);
}
.hero__content > * { pointer-events: auto; }
/* Corner mark. The crest itself cannot come down to this size: the brand guide
   sets a 240px minimum for the visible artwork and asks for a separately
   prepared simplified mark below that, which does not exist yet. So the name is
   set in type here, the way the guide's own digital study does it. */
.hero__mark { margin: 0 0 auto; }
.hero__mark-type { display: none; }
/* The crest, at the smallest size the brand guide allows: 318px on screen is
   the 240px of visible artwork it asks for. It keeps its own ivory field. */
.hero__mark-crest {
  display: none;
  /* its ivory field is part of the artwork, so it is framed deliberately
     rather than left to look like a pasted square */
  border-bottom: 2px solid var(--gold);
  box-shadow: 0 30px 60px -50px rgba(0, 24, 44, 0.8);
}
.hero__mark-crest img { width: 318px; height: auto; display: block; }

/* Only where the hero is tall enough to carry it without crowding the
   headline; everywhere else the name is set in type instead. */
@media (min-width: 1024px) and (min-height: 880px) and (orientation: landscape) {
  .hero__mark-crest { display: block; }
}
.hero__mark-rule {
  display: block;
  width: clamp(48px, 5vw, 78px);
  height: 1px;
  background: var(--gold);
}

.hero__title { margin: 0; font-size: 1rem; max-width: min(62rem, 64vw); }
.hero__eyebrow { color: var(--navy-70); transition: color 900ms var(--ease); }
.hero__headline {
  display: block;
  font-size: clamp(2.6rem, 0.9rem + 4.8vw, 6rem);
  line-height: 1.0;
  letter-spacing: -0.012em;
}
.hero__line {
  display: block;
  text-wrap: balance;
  padding-bottom: 0.08em;
  margin-bottom: -0.04em;
}
@media (min-width: 1024px) and (orientation: landscape) {
  .hero__line { overflow: hidden; }
  .hero__line > span { white-space: nowrap; }
}
.hero__lede {
  margin: clamp(20px, 2.6vh, 34px) 0 0;
  max-width: 24rem;
  font-size: clamp(1.05rem, 0.95rem + 0.45vw, 1.35rem);
  color: var(--navy-70);
  transition: color 900ms var(--ease);
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: clamp(26px, 3.4vh, 42px);
}

.hero:has(#light-evening:checked) .hero__content,
.hero[data-mode='evening'] .hero__content { color: var(--ivory); }
.hero:has(#light-evening:checked) .hero__eyebrow,
.hero:has(#light-evening:checked) .hero__lede,
.hero[data-mode='evening'] .hero__eyebrow,
.hero[data-mode='evening'] .hero__lede { color: var(--ivory-72); }

.hero:has(#light-evening:checked) .button--primary,
.hero[data-mode='evening'] .button--primary { --btn-bg: var(--ivory); --btn-fg: var(--navy); --btn-line: var(--ivory); }
.hero:has(#light-evening:checked) .button--quiet,
.hero[data-mode='evening'] .button--quiet { --btn-fg: var(--ivory); --btn-line: var(--ivory-40); }

/* day / evening control */
.hero__controls {
  position: absolute;
  z-index: 3;
  opacity: var(--dive-content, 1);
  right: var(--gutter);
  bottom: clamp(30px, 5vh, 56px);
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}
.light-toggle { margin: 0; padding: 0; border: 0; }
.light-toggle__legend {
  padding: 0 0 8px;
  margin-left: auto;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--navy-70);
  text-align: right;
  width: 100%;
}
.light-toggle__track {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: rgba(254, 253, 248, 0.92);
  border: 1px solid var(--navy-16);
  padding: 4px;
  box-shadow: 0 18px 40px -34px rgba(0, 44, 80, 0.9);
}
.light-toggle__input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: 0;
  pointer-events: none;
}
.light-toggle__option {
  position: relative;
  z-index: 2;
  min-width: 92px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy-70);
  cursor: pointer;
  transition: color 260ms var(--ease);
}
.light-toggle__thumb {
  position: absolute;
  z-index: 1;
  top: 4px; left: 4px; bottom: 4px;
  width: calc(50% - 4px);
  background: var(--navy);
  transition: translate 420ms var(--ease), background-color 420ms var(--ease);
}
.light-toggle__track:has(#light-day:checked) .light-toggle__option[for='light-day'],
.light-toggle__track:has(#light-evening:checked) .light-toggle__option[for='light-evening'] { color: var(--ivory); }
.light-toggle__track:has(#light-evening:checked) .light-toggle__thumb { translate: 100% 0; background: var(--gold); }
.light-toggle__input:focus-visible + .light-toggle__option { outline: 2px solid var(--gold); outline-offset: 2px; }

.hero__note {
  margin: 0;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy-45);
  transition: color 900ms var(--ease);
}
.hero:has(#light-evening:checked) .hero__note,
.hero[data-mode='evening'] .hero__note { color: var(--ivory-40); }

/* hero entrance (pure CSS so it also runs if the module fails) */
@media (prefers-reduced-motion: no-preference) {
  .hero__media { animation: heroMedia 1100ms var(--ease) both; }
  .hero__mark { animation: fadeUp 700ms var(--ease) 160ms both; }
  .hero__eyebrow { animation: fadeUp 700ms var(--ease) 220ms both; }
  .hero__line > span { display: block; animation: lineUp 900ms var(--ease) both; }
  .hero__line:nth-child(1) > span { animation-delay: 300ms; }
  .hero__line:nth-child(2) > span { animation-delay: 420ms; }
  .hero__lede { animation: fadeUp 700ms var(--ease) 640ms both; }
  .hero__actions { animation: fadeUp 700ms var(--ease) 760ms both; }
  .hero__controls > * { animation: fadeUp 700ms var(--ease) 900ms both; }
}
@keyframes heroMedia { from { opacity: 0; scale: 1.035; } to { opacity: 1; scale: 1; } }
@keyframes fadeUp { from { opacity: 0; translate: 0 14px; } to { opacity: 1; translate: 0 0; } }
@keyframes lineUp { from { translate: 0 108%; } to { translate: 0 0; } }

@media (min-width: 1024px) and (orientation: landscape) and (prefers-reduced-motion: no-preference) {
  /* The sticky hold and the dive's scroll only exist when scripting does. */
  .js .hero { position: sticky; top: var(--header-h); }
  .js .dive-track { display: block; height: 100svh; }

  /* The section is lifted over the sticky hero so its statement can scroll
     across the water. Its box therefore overhangs the hero, which would put an
     invisible sheet across the hero's buttons and the light control, so the
     section itself takes no pointer: its real content takes it back. */
  .intro {
    z-index: 2;
    pointer-events: none;
  }
  .intro > * { pointer-events: auto; }

  /* Over-water treatment, only while the dive is actually running. Without it
     (no scripting, reduced motion) the statement stays navy on ivory.

     The slot reaches back over the dive and is taller than the screen, so the
     statement is already pinned before it fades: it appears in place rather
     than travelling up into view. It releases and scrolls away at the end. */
  .is-dive .intro__slot {
    position: relative;
    height: var(--arrival-slot);
    margin-top: calc(-1 * var(--arrival-reach));
    /* It is pulled back over the hero, so for most of the dive it is an
       invisible sheet lying across the hero's buttons and the light control.
       The dive adds .is-arrived once the statement is actually on screen, and
       only then does it take the pointer, so the words stay selectable. */
    pointer-events: none;
  }
  .is-dive.is-arrived .intro__slot { pointer-events: auto; }
  .is-dive .intro__arrival {
    /* the opening beats: rule, then the label */
    --b1: clamp(0, calc((var(--arrival-in, 1) - 0.00) * 3), 1);
    --hold: var(--arrival-hold, 1);
    display: grid;
    grid-template-rows: auto 1fr auto;
    justify-items: center;
    text-align: center;
    align-content: stretch;
    position: sticky;
    top: var(--header-h);
    height: calc(100svh - var(--header-h));
    padding: clamp(34px, 6svh, 70px) var(--gutter) clamp(28px, 5svh, 56px);
    max-width: 1680px;
    margin-inline: auto;
    background: none;
    color: var(--ivory);
    /* The slot reaches back over the dive, so nothing of this section may show
       until the water has arrived: the whole block is held at zero until then,
       and the beats inside it work within that. */
    opacity: clamp(0, calc(var(--arrival-in, 1) * 1.15), 1);
  }

  /* A grade rather than a grey panel: light falls away behind the words while
     the open water stays bright. The block is capped at 1680px, the grade is
     not, so it bleeds to the full viewport and the edges never stay bright. */
  .is-dive .intro__arrival::before {
    content: '';
    position: absolute;
    /* Ending at the block's edge on a live alpha drew a hard line across the
       water, but reaching past the block to hide that edge washed a band over
       the header. So it stays inside its own box and both gradients run out to
       nothing at the top and bottom instead. */
    inset: 0 calc(50% - 50vw);
    background:
      radial-gradient(78% 52% at 50% 50%,
        rgba(0, 24, 44, 0.74) 0%,
        rgba(0, 24, 44, 0.66) 32%,
        rgba(0, 24, 44, 0.44) 60%,
        rgba(0, 24, 44, 0.18) 82%,
        rgba(0, 24, 44, 0) 100%),
      linear-gradient(to bottom,
        rgba(0, 24, 44, 0) 0%,
        rgba(0, 24, 44, 0.3) 14%,
        rgba(0, 24, 44, 0.04) 34%,
        rgba(0, 24, 44, 0.04) 66%,
        rgba(0, 24, 44, 0.36) 86%,
        rgba(0, 24, 44, 0) 100%);
    pointer-events: none;
    z-index: -1;
  }

  .is-dive .arrival__head {
    display: grid;
    justify-items: center;
    gap: clamp(14px, 2vw, 22px);
    opacity: var(--b1);
  }
  .is-dive .arrival__rule {
    display: block;
    width: clamp(64px, 7vw, 110px);
    height: 1px;
    background: var(--gold);
    transform-origin: center;
    scale: var(--b1) 1;
  }
  .is-dive .intro__arrival .eyebrow--on-water { color: var(--ivory); margin: 0; }

  /* the statement is the frame: centred, and as large as the screen allows */
  .is-dive .intro__arrival .display {
    align-self: center;
    justify-self: stretch;
    /* fills the content width: the sentence reaches both edges of the block */
    max-width: none;
    width: 100%;
    /* width-driven, but capped against the viewport height so a wide, short
       screen cannot push the closing row off the bottom */
    font-size: clamp(2.5rem, min(0.6rem + 6.6vw, 15svh), 8.5rem);
    line-height: 1.02;
    letter-spacing: -0.015em;
    color: var(--ivory);
    text-shadow: 0 1px 34px rgba(0, 24, 44, 0.55);
  }
  .is-dive .intro__arrival .display > span { display: block; text-wrap: pretty; }

  /* each word lights up as the held moment is scrolled through */
  .is-dive .arrival__word {
    /* The sweep runs over the first third of the hold, so the whole sentence is
       lit while it is still being read, and stays lit from there on. */
    opacity: clamp(0.28, calc((var(--hold) * 3.3 * (var(--n, 16) + 6) - var(--i)) * 0.6), 1);
    transition: opacity 120ms linear;
  }

  /* the closing line, arriving once the sentence has landed */
  .is-dive .arrival__foot {
    display: grid;
    gap: clamp(12px, 1.6vw, 20px);
    opacity: clamp(0, calc((var(--hold) - 0.34) * 4.5), 1);
  }
  .is-dive .arrival__foot { justify-items: center; width: min(100%, 60rem); }
  .is-dive .arrival__foot-rule {
    display: block;
    width: min(100%, 28rem);
    height: 1px;
    background: linear-gradient(to right,
      rgba(181, 144, 72, 0), var(--gold) 50%, rgba(181, 144, 72, 0));
    transform-origin: center;
    scale: clamp(0, calc((var(--hold) - 0.34) * 3.4), 1) 1;
  }
  .is-dive .arrival__foot-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 10px clamp(20px, 3vw, 44px);
  }
  .is-dive .arrival__aside {
    margin: 0;
    font-family: var(--display);
    font-style: italic;
    font-size: clamp(1.05rem, 0.9rem + 0.6vw, 1.5rem);
    color: var(--ivory);
  }
  .is-dive .arrival__who {
    margin: 0;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ivory-72);
  }
  .is-dive .arrival__who span { color: var(--gold); margin: 0 4px; }

  .intro__ground { position: relative; }
}

/* =====================================================================
   INTRODUCTION
   ===================================================================== */
.intro { position: relative; }
.intro__ground {
  max-width: 1680px;
  margin-inline: auto;
}
/* The brand signature: an aerial of a yacht under way, running edge to edge,
   with the crest on the quiet ivory panel the brand guide asks for. The scene
   drifts in as the section is scrolled through. */
.signature {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  min-height: clamp(640px, 96svh, 1000px);
  display: grid;
  /* the choice sits along the bottom, so the hull and its wake stay clear */
  align-items: end;
  justify-items: center;
  overflow: hidden;
  /* transparent by default: the open water behind it shows through while the
     aerial fades in, so one sea dissolves into the other */
  background: transparent;
}
/* It used to fade to ivory because an ivory section followed it. What follows
   now is the sea, so there is nothing to hand over to: water meets water. */
.signature__scene {
  position: absolute;
  inset: 0;
  /* The plate is framed for this section rather than cropped into it. The
     aerial was re-cut from its source: 300px taken off the top so the hull
     rides high, the same amount added back at the foot as a vertically
     mirrored band of its own water (which falls behind the cards anyway), and
     the whole frame flipped so the hull runs to the right of the heading. The
     video was cut the same way from the same footage, so the two match. */
  /* starts at full width so the bow is not clipped, then drifts in */
  scale: calc(1 + 0.06 * var(--sig, 0));
  /* Its foot dissolves into the sea the page carries, so the two plates meet
     as one body of water rather than at a line. */
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, rgba(0, 0, 0, 0) 100%);
          mask-image: linear-gradient(to bottom, #000 58%, rgba(0, 0, 0, 0) 100%);
  opacity: var(--sig-fade, 1);
  will-change: transform, opacity;
}
.signature__scene img,
.signature__footage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.signature__footage { opacity: 0; transition: opacity 900ms var(--ease); }
.signature__footage.is-playing { opacity: 1; }

.signature__pick {
  position: relative;
  z-index: 1;
  width: min(1680px, 100% - 2 * var(--gutter));
  padding-bottom: clamp(28px, 4vw, 64px);
}
/* The heading is not washed over the water: it is given a field of its own, in
   the same ivory and gold as the cards below it, so it reads as the first of
   the row rather than as type fighting the wake. Navy on ivory is about 13:1
   whatever the aerial happens to be doing behind it, and the picture is left
   completely alone. */
.signature__intro {
  width: min(100%, 46ch);
  margin-bottom: clamp(12px, 1.4vw, 22px);
  padding: clamp(22px, 2.2vw, 36px) clamp(22px, 2.2vw, 36px) clamp(24px, 2.4vw, 38px);
  background: var(--ivory);
  border-top: 2px solid var(--gold);
  box-shadow: 0 40px 90px -60px rgba(0, 24, 44, 0.9);
  translate: 0 calc(26px * (1 - var(--sig-in, 1)));
  opacity: var(--sig-in, 1);
}
.signature__intro .eyebrow { color: var(--gold-ink); margin-bottom: 1em; }
.signature__title {
  font-family: var(--display);
  font-size: clamp(1.7rem, 1.15rem + 1.9vw, 2.6rem);
  line-height: 1.1;
  color: var(--navy);
  margin: 0;
  max-width: 17ch;
}
.signature__lead {
  margin: 0.7em 0 0;
  color: var(--navy-70);
  font-size: clamp(0.92rem, 0.88rem + 0.18vw, 1rem);
}

.pick-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(12px, 1.4vw, 22px);
}
/* Each card slides in from the left as the section is scrolled through, one
   after the next. The travel is written per card by the script as --card-in,
   so it is the scroll position that drives it: stop and it stops, scroll back
   and it goes back. Both properties fall back to the settled state, so with no
   scripting, or under reduced motion, the cards are simply there. */
.pick-card {
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--ivory);
  color: var(--navy);
  text-decoration: none;
  border-top: 2px solid var(--gold);
  box-shadow: 0 40px 90px -60px rgba(0, 24, 44, 0.9);
  overflow: hidden;
  translate: calc(-1 * var(--card-travel, 140px) * (1 - var(--card-in, 1))) 0;
  opacity: var(--card-in, 1);
  /* hover moves the card with `transform`, which composes after `translate`,
     so the two never overwrite one another and the scroll-driven value is not
     fighting a transition every frame */
  transition: transform var(--content), box-shadow var(--content);
}
.pick-card__figure { display: block; overflow: hidden; }
.pick-card__figure picture { display: block; }
.pick-card__figure img {
  display: block;
  width: 100%;
  height: clamp(130px, 13vw, 200px);
  object-fit: cover;
  transition: scale 900ms var(--ease);
}
.pick-card__body {
  display: grid;
  align-content: start;
  gap: 8px;
  padding: clamp(16px, 1.5vw, 24px) clamp(16px, 1.5vw, 24px) clamp(18px, 1.7vw, 26px);
}
.pick-card__name {
  font-family: var(--display);
  font-size: clamp(1.15rem, 0.95rem + 0.7vw, 1.6rem);
  line-height: 1.15;
}
.pick-card__line {
  color: var(--navy-70);
  font-size: 0.88rem;
  line-height: 1.5;
}
.pick-card__go {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.pick-card__go svg { transition: translate var(--content); }

@media (hover: hover) and (pointer: fine) {
  .pick-card:hover { transform: translateY(-6px); box-shadow: 0 50px 90px -52px rgba(0, 24, 44, 0.95); }
  .pick-card:hover .pick-card__figure img { scale: 1.06; }
  .pick-card:hover .pick-card__go svg { translate: 4px 0; }
}
.pick-card:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

@media (max-width: 1099.98px) {
  .pick-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 767.98px) {
  .signature { min-height: clamp(560px, 86svh, 760px); }
  .pick-grid { grid-template-columns: 1fr; gap: 10px; }
  /* less room to travel across, so a shorter run */
  .pick-card { --card-travel: 56px; }
  .pick-card { grid-template-columns: 38% 1fr; grid-template-rows: auto; }
  .pick-card__figure img { height: 100%; min-height: 104px; }
  .pick-card__line { display: none; }
}

/* =====================================================================
   THE SPECIALISM — laid out as a drawing sheet
   A bordered sheet over a faint two-scale grid. The title block doubles as
   the display: the panels all occupy one grid cell, so the block is as tall
   as its tallest panel and nothing jumps when they swap. The row of cells
   beneath shows only a numeral and a name; hovering, focusing or clicking one
   brings its principle and its photograph up into the block.

   Without scripting every panel renders stacked and visible, so the whole
   section still reads (js/components/sheet.js).
   ===================================================================== */
.sheet {
  position: relative;
  /* full bleed: the cabin is the background of the section, not a picture
     mounted inside it, so it runs to both edges of the screen */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding: clamp(48px, 7vw, 110px) max(var(--gutter), calc(50% - 840px))
           clamp(40px, 6vw, 90px);
  overflow: hidden;
}
/* static as well: with the mount's border gone, the only thing its position
   still did was hold the photograph inside the section's padding */
.sheet__frame {
  position: static;
  border: 0;
  padding: 0;
}
/* the mount is gone, so its corner ticks have nothing to sit on */
.sheet__tick { display: none; }
.sheet__tick--tl { top: -1px; left: -1px; border-width: 1px 0 0 1px; }
.sheet__tick--tr { top: -1px; right: -1px; border-width: 1px 1px 0 0; }
.sheet__tick--bl { bottom: -1px; left: -1px; border-width: 0 0 1px 1px; }
.sheet__tick--br { bottom: -1px; right: -1px; border-width: 0 1px 1px 0; }

/* ---- the title block, which is also the display --------------------- */
/* static, so the photograph behind it measures itself against the whole
   section rather than against this block */
.sheet__block {
  position: static;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 15rem);
  gap: clamp(20px, 3vw, 56px);
  align-items: start;
  padding: clamp(20px, 2.4vw, 40px);
}
.sheet__media { position: absolute; inset: 0; }
.sheet__shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 150ms var(--ease);
}
.sheet__shot.is-shown { opacity: 1; transition: opacity 340ms var(--ease) 120ms; }
.sheet__shot picture { display: block; height: 100%; }
.sheet__shot img { width: 100%; height: 100%; object-fit: cover; }
/* The block is a wide, shallow band, so the aerial is cropped hard top and
   bottom. Centred, the hull rides off the top edge; held near the top of the
   plate it sits low in the band, clear of the heading above it. */
.sheet__shot--aerial img { object-position: 50% 8%; }
/* washed toward the text side so the copy keeps its contrast whatever the
   photograph is doing: measured, navy holds about 11:1 at the thinnest point */
.sheet__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Measured against the brightest pixels of all five photographs: the
     headings hold about 12:1 and the lede about 5.4:1 even where the wash is
     thinnest under the copy, so this is as light as it can go and still be
     comfortably readable. */
  background: linear-gradient(
    to right,
    rgba(254, 253, 248, 0.78) 0%,
    rgba(254, 253, 248, 0.66) 40%,
    rgba(254, 253, 248, 0.36) 70%,
    rgba(254, 253, 248, 0.22) 100%
  );
}

.sheet__display { position: relative; display: grid; }
.sheet__panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  /* out before the next one arrives, or the two read as a double exposure */
  transition: opacity 150ms var(--ease), visibility 0s linear 150ms;
}
.sheet__panel.is-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity 340ms var(--ease) 120ms, visibility 0s;
}
.sheet__label {
  margin: 0 0 0.9em;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.sheet__heading {
  font-family: var(--display);
  font-size: clamp(1.4rem, 1.05rem + 1.2vw, 2.1rem);
  line-height: 1.16;
  margin: 0;
  color: var(--navy);
  max-width: 24ch;
}
/* a wider measure than the principles above: 78 characters over two lines */
.sheet__heading--lead {
  font-size: clamp(1.45rem, 1rem + 1.5vw, 2.35rem);
  max-width: 41ch;
}
.sheet__lede {
  margin: 0.9em 0 0;
  max-width: 60ch;
  color: var(--navy-70);
}

.sheet__meta {
  position: relative;
  margin: 0;
  display: grid;
  gap: 0;
  align-content: start;
  /* it sits where the wash is thinnest, so it carries a field of its own:
     the labels hold about 7:1 and the values about 13:1 over any of the four
     photographs */
  padding: clamp(10px, 1vw, 16px) clamp(12px, 1.1vw, 18px);
  background: rgba(254, 253, 248, 0.93);
  border-top: 1px solid var(--navy-16);
}
.sheet__meta-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--navy-16);
}
.sheet__meta dt {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--navy-45);
}
.sheet__meta dd {
  margin: 0;
  font-size: 0.78rem;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ---- the live conductor --------------------------------------------- */
.sheet__conductor {
  position: relative;
  height: 1px;
  margin: clamp(22px, 3vw, 44px) 0 0;
  background: var(--navy-16);
  overflow: hidden;
}
.sheet__charge {
  position: absolute;
  inset: 0 auto 0 0;
  width: 22%;
  background: linear-gradient(to right, transparent, var(--gold), transparent);
  animation: sheet-charge 4.2s linear infinite;
}
@keyframes sheet-charge {
  from { translate: -120% 0; }
  to { translate: 560% 0; }
}

/* ---- the trigger cells ---------------------------------------------- */
/* a 1px gap over a tinted bed, so every divider is drawn by the grid itself
   whatever the column count is */
.sheet__cells {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--navy-16);
  border-bottom: 1px solid var(--navy-16);
}
.sheet__cell {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: clamp(12px, 1.2vw, 20px);
  width: 100%;
  min-height: clamp(108px, 11vw, 148px);
  margin: 0;
  padding: clamp(18px, 1.8vw, 28px) clamp(14px, 1.4vw, 22px);
  border: 0;
  background: var(--ivory-deep);
  text-align: left;
  cursor: pointer;
  transition: background var(--ui);
}
.sheet__cell::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: var(--navy);
  scale: 0 1;
  transform-origin: left center;
  transition: scale 420ms var(--ease);
}
.sheet__numeral {
  font-family: var(--display);
  font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.5rem);
  line-height: 0.9;
  color: var(--navy-16);
  transition: color var(--ui), -webkit-text-stroke-color var(--ui);
}
@supports (-webkit-text-stroke: 1px currentColor) {
  .sheet__numeral {
    color: transparent;
    -webkit-text-stroke: 1px var(--navy-45);
  }
}
.sheet__name {
  font-family: var(--display);
  font-size: clamp(0.98rem, 0.9rem + 0.4vw, 1.2rem);
  line-height: 1.22;
  color: var(--navy);
}
.sheet__cell.is-on { background: var(--ivory); }
.sheet__cell.is-on::before { scale: 1 1; }
.sheet__cell.is-on .sheet__numeral { color: var(--navy); -webkit-text-stroke-color: var(--navy); }
.sheet__cell:focus-visible { outline: 3px solid var(--gold); outline-offset: -3px; }
/* held in place by a click, which is also how touch reaches it */
.sheet__cell[aria-pressed='true'] { background: var(--ivory); }
.sheet__cell[aria-pressed='true']::before { background: var(--gold); scale: 1 1; }

.sheet__index {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  padding: 12px 2px 0;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy-45);
}
.sheet__index ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
}
.sheet__index p { margin: 0; }

.sheet__who {
  position: relative;
  margin: clamp(26px, 3vw, 44px) 0 0;
  /* it now sits on the photograph, so it carries a field of its own */
  padding: clamp(14px, 1.6vw, 22px) clamp(16px, 1.8vw, 26px);
  background: rgba(254, 253, 248, 0.93);
  font-size: 0.95rem;
  color: var(--navy-70);
}

/* Without scripting the panels cannot share a cell, so they stack and the
   whole section reads as one page of copy. */
html:not(.js) .sheet__panel {
  grid-area: auto;
  opacity: 1;
  visibility: visible;
  margin-bottom: clamp(20px, 3vw, 36px);
}
html:not(.js) .sheet__cells,
html:not(.js) .sheet__conductor { display: none; }

@media (max-width: 1099.98px) {
  .sheet__cells { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 899.98px) {
  .sheet__block { grid-template-columns: minmax(0, 1fr); }
  .sheet__meta { margin-top: clamp(18px, 4vw, 28px); }
  .sheet__media::after {
    background: linear-gradient(to bottom, rgba(254, 253, 248, 0.95), rgba(254, 253, 248, 0.9));
  }
}
@media (prefers-reduced-motion: reduce) {
  .sheet__charge { animation: none; opacity: 0.5; }
}

/* =====================================================================
   DESIGN DETAILS
   ===================================================================== */
/* Top left, because the reading panel sits on the right: centred, the title
   ran underneath it. */
.details__head {
  position: absolute;
  /* The grade covers the whole stage. Held to a box the size of the words, a
     linear gradient still had alpha left at the box's right and bottom edges,
     and those edges read as two straight lines ruled across the photograph.
     A radial anchored at the top corner has no edge to show: it reaches zero
     before it reaches anything. */
  inset: 0;
  z-index: 2;
  width: 100%;
  padding: clamp(26px, 5vh, 62px) var(--gutter) clamp(40px, 6vh, 80px);
  color: var(--ivory);
  /* No grade behind it: the cabin stays clean. The type carries itself with a
     shadow instead, the same way the heading over the water does. */
  background: none;
  pointer-events: none;
}
.details__head .section-title {
  color: var(--ivory);
  max-width: 22ch;
  /* No grade behind the words, so the type has to carry itself. The tight
     layers draw an edge round each glyph, which is what holds it where the
     bedding behind runs white on white; the wide ones only lift it. */
  text-shadow:
    0 1px 2px rgba(0, 24, 44, 0.95),
    0 0 7px rgba(0, 24, 44, 0.9),
    0 0 20px rgba(0, 24, 44, 0.78),
    0 0 48px rgba(0, 24, 44, 0.6);
}
.details__intro {
  margin: 0.9em 0 0;
  max-width: 40ch;
  /* full ivory rather than 72%: with no grade under it the softer tone was the
     first thing the photograph swallowed */
  color: var(--ivory);
  text-shadow:
    0 1px 2px rgba(0, 24, 44, 0.95),
    0 0 6px rgba(0, 24, 44, 0.9),
    0 0 16px rgba(0, 24, 44, 0.8);
  font-size: 0.98rem;
}

.details .section-title {
  font-size: clamp(2.2rem, 1.25rem + 3.4vw, 4.2rem);
  line-height: 1.06;
}
.details {
  background: var(--ivory-deep);
  padding: 0;
}
/* The stage runs edge to edge: the cabin is the section, with the reading
   panel laid over it and the tour bar along the bottom. */
/* The stage is pinned for the length of the tour, so while this section is
   what you are looking at it fills the screen and nothing else shows above or
   below it. The track supplies that scroll length — one screen per detail —
   which is also what drives the tour: without a track taller than the stage,
   `trackProgress()` has nothing to measure and the view never advances. */
.details__track { position: relative; }
.details__stage {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  /* full screen: on this section the cabin is all there is to look at */
  height: 100svh;
  overflow: hidden;
  background: var(--navy);
}
.details__camera {
  position: absolute;
  inset: 0;
  will-change: transform;
  transform: scale(var(--cam-s, 1)) translate(var(--cam-x, 0%), var(--cam-y, 0%));
}
.details__camera picture,
.details__camera img { display: block; width: 100%; height: 100%; object-fit: cover; }

.details__spotlight {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--spot, 0);
  background: radial-gradient(circle at var(--sx, 50%) var(--sy, 50%),
    rgba(0, 24, 44, 0) 0%,
    rgba(0, 24, 44, 0) 12%,
    rgba(0, 24, 44, 0.3) 44%,
    rgba(0, 24, 44, 0.62) 100%);
  transition: opacity 600ms var(--ease);
}

/* the reading panel, sitting over the image */
.details__panel {
  position: absolute;
  z-index: 3;
  right: clamp(18px, 4vw, 76px);
  top: 50%;
  translate: 0 -50%;
  width: min(30rem, 40vw);
  padding: clamp(28px, 2.6vw, 44px);
  background: rgba(0, 28, 52, 0.9);
  color: var(--ivory);
  border-top: 2px solid var(--gold);
}
.details__panel h3 { color: var(--ivory); font-size: clamp(1.5rem, 1.1rem + 1vw, 2.15rem); margin-bottom: 0.6em; }
.details__panel p { color: var(--ivory-72); }
.details__cta { display: inline-block; margin-top: 1.8em; }
.text-link--on-dark { color: var(--ivory); }
.text-link--on-dark:hover { color: var(--gold); }

/* the tour bar */
.details__tabs {
  position: absolute;
  z-index: 3;
  left: 0; right: 0; bottom: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: rgba(0, 24, 44, 0.68);
  backdrop-filter: blur(2px);
}
.details__tab {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: clamp(16px, 1.8vw, 24px) clamp(16px, 2.4vw, 34px);
  background: none;
  border: 0;
  border-top: 1px solid rgba(254, 253, 248, 0.16);
  font-family: var(--body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ivory-60);
  text-align: left;
  cursor: pointer;
  transition: color var(--ui), background-color var(--ui);
}
.details__tab:hover { color: var(--ivory); background: rgba(0, 24, 44, 0.4); }
.details__tab[aria-selected='true'] { color: var(--ivory); }
.details__num { font-family: var(--display); font-size: 1.05rem; color: var(--gold); }
.details__tab-label { flex: 1 1 auto; }
/* how long this detail has left before the view moves on */
.details__progress {
  position: absolute;
  left: 0; top: -1px;
  height: 2px;
  width: calc(var(--p, 0) * 100%);
  background: var(--gold);
}

.details__readout {
  position: absolute;
  z-index: 3;
  left: clamp(18px, 4vw, 76px);
  bottom: clamp(88px, 11vh, 120px);
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--display);
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.3rem);
  letter-spacing: 0.1em;
  color: var(--ivory);
  text-shadow: 0 1px 18px rgba(0, 24, 44, 0.8);
}
.details__readout-sep { color: var(--gold); }

.details__panels { position: relative; }
.is-ready .details__copy[hidden] { display: none; }
.is-ready .details__copy > * { animation: panelIn 520ms var(--ease) both; }
.is-ready .details__copy > *:nth-child(1) { animation-delay: 40ms; }
.is-ready .details__copy > *:nth-child(2) { animation-delay: 120ms; }
.is-ready .details__copy > *:nth-child(3) { animation-delay: 200ms; }
@keyframes panelIn { from { opacity: 0; translate: 0 10px; } to { opacity: 1; translate: 0 0; } }
.details__copy + .details__copy { margin-top: 2.4em; }

@media (min-width: 900px) {
  /* one screen of scroll per detail */
  .details__track { height: 300svh; }
  /* Pinned to the very top, not below the header: at --header-h it left a
     76px gap above the stage and the page's sea showed through it. The heading
     inside the stage takes the header's height as padding instead. */
  .details__stage { position: sticky; top: 0; }
  .details__head { padding-top: calc(var(--header-h) + clamp(18px, 3vh, 44px)); }
  /* The grade now spans the stage, so it no longer doubles as the measure the
     title wrapped to. From here up the reading panel sits on the right, and
     these keep the words on the free side of it. */
  .details__head .section-title { max-width: min(22ch, 48vw); }
  .details__intro { max-width: min(40ch, 44vw); }
}

@media (max-width: 899.98px) {
  .details__stage { height: auto; }
  .details__camera {
    position: relative;
    height: clamp(300px, 58vw, 460px);
    /* no camera push at this size: the crop would fall outside the frame and
       the markers are hidden anyway */
    transform: none;
  }
  .details__panel {
    position: static;
    translate: none;
    width: auto;
    background: var(--navy);
  }
  .details__tabs { position: static; grid-template-columns: 1fr; background: var(--navy); }
  .details__readout { bottom: auto; top: clamp(12px, 3vw, 20px); }
  .details__spotlight { height: clamp(300px, 58vw, 460px); inset: 0 0 auto; }
  .hotspot { display: none; }
}

/* =====================================================================
   LIFE ONBOARD
   ===================================================================== */
.onboard {
  /* no veil over the section: the sea is the background. Only the heading
     carries a grade of its own, below. */
  background: transparent;
  color: var(--ivory);
  padding: var(--section) var(--gutter);
  overflow: hidden;
}
.onboard__head {
  /* an explicit width, not max-width with auto margins: as a grid item that
     shrinks to fit and the heading drifts out of line with the row below */
  width: min(1680px, 100%);
  margin: 0 auto clamp(46px, 7vw, 92px);
  text-align: center;
}

/* Where there is a landscape screen to do it on, the whole section is sized to
   one screen: heading, the row of cabins and the note, with the row taking
   whatever height is left over. Nothing is cropped, and there is no half-seen
   panel at the fold. */
@media (min-width: 768px) and (min-height: 560px) {
  .onboard {
    min-height: 100svh;
    /* the header is sticky, so the heading has to start below where it lands */
    padding: calc(var(--header-h) + clamp(18px, 3vh, 46px)) var(--gutter) clamp(24px, 4vh, 56px);
    display: grid;
    /* The single column has to be told to fill the section. Left to size
       itself, a grid column takes its items' max-content width, and the row of
       cabins is a flex row whose panels all start from a zero basis: before
       their pictures have loaded its max-content is about 56px, which is what
       the whole row then collapsed to. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    row-gap: clamp(16px, 3vh, 46px);
  }
  .onboard__head { margin-bottom: 0; }
  .onboard .accordion { height: 100%; min-height: 0; }
}
.onboard__head .section-title {
  color: var(--ivory);
  /* No grade behind it: the water stays clean. The type carries itself with a
     soft shadow instead. Over the water's typical tone it runs about 14:1; the
     shadow is what holds it where a foam streak passes behind. */
  text-shadow: 0 1px 18px rgba(0, 24, 44, 0.75), 0 0 36px rgba(0, 24, 44, 0.5);
  font-size: clamp(2rem, 1.1rem + 3.4vw, 4.3rem);
}
@media (min-width: 1024px) {
  /* one line, sized so the 46 characters always fit the content width
     (a Cormorant character averages about 0.465em, so 21.5em holds it) */
  .onboard__head .section-title {
    white-space: nowrap;
    font-size: min(4.3rem, calc(min(100vw - 2 * var(--gutter), 1680px) / 21.5));
  }
}

/* ---- the horizontal accordion ---------------------------------------
   A row of cabins where one panel is open and the rest are collapsed to a
   numbered strip. Hover, tap or keyboard focus opens a different one. With
   no JavaScript the panels share the row evenly and every caption is
   readable, so nothing is hidden behind an interaction. */
.accordion {
  list-style: none;
  /* an explicit width, not max-width with auto margins: as a grid item that
     would shrink to fit its contents rather than fill the column */
  width: min(1680px, 100%);
  margin-inline: auto;
  padding: 0;
  display: flex;
  gap: clamp(6px, 0.7vw, 12px);
  height: clamp(460px, 72svh, 780px);
}
.apanel {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  background: #04203A;
  transition: flex-grow 720ms var(--ease);
}
/* the open one takes most of the row */
.js .apanel { flex-grow: 1; }
.js .apanel.is-open { flex-grow: 4.6; }

.apanel__hit {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--ivory);
  text-align: left;
}
.apanel__hit picture { display: block; height: 100%; }
.apanel__hit img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the collapsed strips sit back so the open one leads, and the label on
     them has to stay readable: measured on the pale cabins, about 8:1 */
  filter: saturate(0.76) brightness(0.52);
  scale: 1.04;
  transition: filter 720ms var(--ease), scale 900ms var(--ease);
}
.apanel.is-open .apanel__hit img { filter: none; scale: 1; }
.apanel__hit::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 24, 44, 0.86) 0%, rgba(0, 24, 44, 0.24) 46%, rgba(0, 24, 44, 0.1) 100%);
}

/* the collapsed label, set on its side */
.apanel__tag {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(18px, 2vw, 30px);
  display: grid;
  justify-items: center;
  gap: 14px;
  opacity: 1;
  transition: opacity 340ms var(--ease);
}
.apanel.is-open .apanel__tag { opacity: 0; pointer-events: none; }
.apanel__n {
  font-family: var(--display);
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  color: var(--gold);
}
.apanel__label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ivory);
  white-space: nowrap;
  text-shadow: 0 1px 16px rgba(0, 24, 44, 0.95), 0 0 3px rgba(0, 24, 44, 0.7);
}

/* the open caption, over the foot of the picture */
.apanel__open {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  padding: clamp(22px, 2.4vw, 42px);
  color: var(--ivory);
  opacity: 0;
  translate: 0 14px;
  pointer-events: none;
  transition: opacity 420ms var(--ease) 140ms, translate 520ms var(--ease) 140ms;
}
.apanel.is-open .apanel__open { opacity: 1; translate: 0 0; pointer-events: auto; }
.apanel__n--open { margin: 0 0 0.5em; }
.apanel__title {
  font-family: var(--display);
  font-size: clamp(1.5rem, 1.1rem + 1.3vw, 2.4rem);
  line-height: 1.12;
  margin: 0;
  white-space: nowrap;
}
.apanel__text {
  margin: 0.6em 0 0;
  max-width: 40ch;
  color: var(--ivory-72);
  font-size: clamp(0.9rem, 0.86rem + 0.2vw, 1rem);
}
.apanel__go {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: clamp(14px, 1.6vw, 22px);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--gold);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ivory);
  text-decoration: none;
  transition: color var(--ui);
}
.apanel__go:hover { color: var(--gold); }
.apanel__go svg { transition: translate var(--ui); }
.apanel__go:hover svg { translate: 4px 0; }
.apanel__hit:focus-visible,
.apanel__go:focus-visible { outline: 3px solid var(--gold); outline-offset: -4px; }

/* Without JavaScript every panel is simply open. */
html:not(.js) .apanel__tag { display: none; }
html:not(.js) .apanel__open { opacity: 1; translate: 0; position: static; }
html:not(.js) .apanel__title { white-space: normal; }
html:not(.js) .accordion { flex-wrap: wrap; height: auto; }
html:not(.js) .apanel { flex: 1 1 320px; min-height: 420px; }

@media (max-width: 1099.98px) {
  .accordion { height: clamp(420px, 62svh, 620px); }
  .js .apanel.is-open { flex-grow: 5.4; }
}

/* On a phone the row becomes a column and the panels open downwards. */
@media (max-width: 767.98px) {
  .accordion {
    flex-direction: column;
    height: auto;
    gap: 8px;
  }
  .apanel {
    flex: 0 0 auto;
    height: 86px;
    transition: height 620ms var(--ease);
  }
  .js .apanel.is-open { height: min(78svh, 520px); }
  .apanel__tag {
    inset: 0 auto 0 0;
    bottom: auto;
    width: 100%;
    height: 100%;
    align-content: center;
    justify-items: start;
    grid-auto-flow: column;
    justify-content: start;
    align-items: center;
    gap: 16px;
    padding: 0 18px;
  }
  .apanel__label { writing-mode: horizontal-tb; transform: none; }
  .apanel__title { white-space: normal; }
}

/* =====================================================================
   YOUR PROJECT
   ===================================================================== */
/* A band, so the white cards of the sequence have something to sit on. */
.project {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--ivory-deep);
  padding: var(--section) var(--gutter);
}
.project > * { max-width: 72rem; margin-inline: auto; }

.steps__head { text-align: center; margin-bottom: clamp(32px, 4vw, 56px); }
.steps__head .eyebrow { margin-bottom: 1.1em; }
.steps__lede {
  margin: 1.2em auto 0;
  max-width: 46rem;
  color: var(--navy-70);
}
.steps__rule {
  display: block;
  width: 4.5rem;
  height: 4px;
  margin: clamp(22px, 2.6vw, 34px) auto 0;
  border-radius: 2px;
  background: var(--gold);
}

/* ---- the stacking sequence -------------------------------------------
   Each card pins under the header and the next one slides up over it,
   leaving a stepped edge of 14px per card, so the stack visibly builds.

   The sticky offset comes from --i, written per card by the script
   (js/components/steps.js). It cannot be :nth-child(): the chevrons are
   inserted between the cards, which shifts every index. */
.steps {
  list-style: none;
  /* auto, not 0: this rule comes after .project > * and would otherwise undo
     the centring that every other block in the section gets */
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
/* the last card needs something to scroll against, or the stack never closes */
.steps::after { content: ''; display: block; height: 4vh; }

.steps__card {
  position: sticky;
  top: calc(var(--header-h) + 1.4rem + (var(--i, 0) * 14px));
  /* above the chevrons: they animate opacity, and anything under 1 paints in
     the same layer as positioned elements, so a later chevron would otherwise
     render over a pinned card */
  z-index: 2;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(16px, 2vw, 28px);
  align-items: start;
  padding: clamp(1.4rem, 3vw, 2.3rem);
  background: var(--ivory);
  border: 1.5px solid var(--navy-16);
  border-radius: 14px;
  box-shadow: 0 22px 48px -30px rgba(0, 44, 80, 0.55);
}
.steps__badge {
  display: grid;
  place-items: center;
  width: clamp(52px, 5vw, 66px);
  height: clamp(52px, 5vw, 66px);
  border-radius: 10px;
  background: var(--navy);
  color: var(--ivory);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 0.95rem + 0.5vw, 1.45rem);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.steps__body h3 {
  font-size: clamp(1.2rem, 1rem + 0.8vw, 1.6rem);
  margin: 0 0 0.5em;
}
.steps__body p { margin: 0; color: var(--navy-70); }

.steps__chevron {
  z-index: 1;
  display: grid;
  place-items: center;
  height: clamp(26px, 3vw, 38px);
  color: var(--gold);
  opacity: 0;
  transition: opacity 520ms var(--ease);
}
.steps__chevron.is-in { opacity: 1; }
.steps__chevron svg { animation: steps-bob 1.9s ease-in-out infinite; }
@keyframes steps-bob {
  0%, 100% { translate: 0 -22%; }
  50% { translate: 0 22%; }
}

/* A plain vertical list that reads identically. */
@media (prefers-reduced-motion: reduce) {
  .steps__card { position: relative; top: auto; }
  .steps__chevron { opacity: 1; }
  .steps__chevron svg { animation: none; }
}
.steps.is-still .steps__card { position: relative; top: auto; }
.steps.is-still .steps__chevron { opacity: 1; }
.steps.is-still .steps__chevron svg { animation: none; }

/* ---- the course ------------------------------------------------------
   The three steps are laid out as a passage: a rail running down beside
   them, drawn from the top as the section is scrolled through, with a marker
   riding the head of it and each waypoint lighting as the line reaches it.
   Driven entirely by scroll position (js/components/course.js).

   --course falls back to 1, so with no scripting the line is simply drawn and
   every waypoint is lit. */
.course {
  --node-col: clamp(46px, 5vw, 72px);
  --node: 13px;
  position: relative;
}
.course__rail {
  position: absolute;
  top: calc(var(--node) * 1.6);
  bottom: calc(var(--node) * 1.6);
  left: calc(var(--node-col) / 2);
  width: 1px;
  background: var(--navy-16);
}
.course__drawn {
  position: absolute;
  inset: 0;
  background: var(--gold);
  transform-origin: top center;
  scale: 1 var(--course, 1);
}
.course__marker {
  position: absolute;
  left: 50%;
  top: calc(var(--course, 1) * 100%);
  width: 7px;
  height: 7px;
  translate: -50% -50%;
  rotate: 45deg;
  background: var(--gold);
  opacity: clamp(0, calc(var(--course, 1) * 12), 1);
}

.course__list { list-style: none; margin: 0; padding: 0; }
.course__stop {
  position: relative;
  display: grid;
  grid-template-columns: var(--node-col) minmax(0, 1fr);
  align-items: start;
  padding: clamp(10px, 1.2vw, 16px) 0;
}
.course__node {
  position: relative;
  z-index: 1;
  justify-self: center;
  width: var(--node);
  height: var(--node);
  margin-top: 1.5em;
  rotate: 45deg;
  background: var(--ivory);
  border: 1px solid var(--navy-45);
  transition: background var(--content), border-color var(--content), scale var(--content);
}
.course__body {
  padding: clamp(20px, 2.2vw, 30px) clamp(20px, 2.4vw, 34px);
  background: var(--ivory-deep);
  border-left: 2px solid transparent;
  transition: border-color var(--content), background var(--content), translate var(--content),
    opacity var(--content), box-shadow var(--content);
}
.course__num {
  margin: 0 0 0.35em;
  font-family: var(--display);
  font-size: clamp(1.5rem, 1.1rem + 1.1vw, 2.2rem);
  line-height: 1;
  color: var(--navy-16);
  transition: color var(--content);
}
.course__body h3 {
  font-size: clamp(1.25rem, 1rem + 0.9vw, 1.75rem);
  margin: 0 0 0.5em;
}
.course__text { color: var(--navy-70); margin: 0; }

/* set back until the line reaches it, so the lighting is what you notice */
.course__stop:not(.is-reached) .course__body { opacity: 0.58; }
.course__stop:not(.is-reached) .course__body h3,
.course__stop:not(.is-reached) .course__text { color: var(--navy-70); }

/* lit as the line reaches it */
.course__stop.is-reached .course__node {
  background: var(--gold);
  border-color: var(--gold);
  scale: 1.1;
}
.course__stop.is-reached .course__body {
  border-left-color: var(--gold);
  background: var(--ivory);
  box-shadow: 0 26px 54px -42px rgba(0, 24, 44, 0.75);
  opacity: 1;
  translate: 3px 0;
}
.course__stop.is-reached .course__num { color: var(--gold-ink); }

@media (max-width: 599.98px) {
  .course { --node-col: 34px; }
  .course__body { padding: 18px 16px; }
}

.callout {
  margin-top: clamp(40px, 5vw, 64px);
  padding: clamp(26px, 3vw, 38px) clamp(24px, 3vw, 40px);
  background: var(--ivory-deep);
  border-left: 2px solid var(--gold);
}
.callout__label {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--navy-70);
  margin-bottom: 1.2em;
}
.callout ul { margin: 1.1em 0 0; padding-left: 1.1em; color: var(--navy-70); }
.callout li { margin-bottom: 0.55em; }
.callout li::marker { color: var(--gold); }

.compare { margin-top: clamp(44px, 5vw, 72px); }
.compare__title { font-size: clamp(1.3rem, 1.05rem + 0.8vw, 1.7rem); margin-bottom: 1em; }
.compare__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  text-align: left;
}
.compare__table th,
.compare__table td {
  padding: 16px 18px 16px 0;
  border-bottom: 1px solid var(--navy-16);
  vertical-align: top;
}
.compare__table thead th {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy-70);
  border-bottom-color: var(--gold);
  padding-bottom: 12px;
}
.compare__table tbody th {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 400;
  width: 26%;
  padding-right: 24px;
}
.compare__table td { color: var(--navy-70); width: 37%; }
.compare__note { margin-top: 1.4em; font-size: 0.9rem; color: var(--navy-70); }

@media (max-width: 639.98px) {
  .compare__table, .compare__table tbody, .compare__table tr, .compare__table td, .compare__table th { display: block; width: auto; }
  .compare__table thead { display: none; }
  .compare__table tr { padding: 6px 0 14px; border-bottom: 1px solid var(--navy-16); }
  .compare__table tbody th { border: 0; padding: 12px 0 4px; }
  .compare__table td { border: 0; padding: 4px 0 4px 0; }
  .compare__table td::before {
    content: attr(data-label);
    display: block;
    font-family: var(--body);
    font-size: 0.64rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 3px;
  }
}

.faq { margin-top: clamp(48px, 6vw, 80px); }
.faq__title {
  font-size: clamp(1.3rem, 1.05rem + 0.8vw, 1.7rem);
  margin-bottom: 0.9em;
}
.faq__item { border-top: 1px solid var(--navy-16); }
.faq__item:last-of-type { border-bottom: 1px solid var(--navy-16); }
.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 56px;
  padding: 16px 0;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  list-style: none;
  transition: color var(--ui);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: '';
  flex: none;
  width: 13px; height: 13px;
  background:
    linear-gradient(var(--gold), var(--gold)) center / 100% 1px no-repeat,
    linear-gradient(var(--gold), var(--gold)) center / 1px 100% no-repeat;
  transition: rotate 300ms var(--ease);
}
.faq__item[open] summary::after { rotate: 45deg; }
.faq__item summary:hover { color: var(--gold); }
.faq__answer { padding: 0 0 22px; max-width: 46rem; color: var(--navy-70); }

@media (max-width: 899.98px) {
  .project { display: block; }
  .faq, .callout, .compare { grid-column: auto; }
  .project__intro { position: static; margin-bottom: 40px; }
}

/* =====================================================================
   ENQUIRY
   ===================================================================== */
.enquire {
  background: var(--navy);
  color: var(--ivory);
  padding: var(--section) var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: clamp(36px, 5vw, 110px);
  align-items: start;
  max-width: 1680px;
  margin-inline: auto;
}
.enquire__aside { position: sticky; top: calc(var(--header-h) + 48px); }
.enquire__aside .section-title { color: var(--ivory); }
.enquire__aside p { color: var(--ivory-72); margin-top: 1.4em; max-width: 26rem; }
.enquire__aside .rule { margin-top: 2.4em; width: 120px; }

.enquiry-form { display: grid; gap: clamp(22px, 2.6vw, 34px); }

/* steps: three short passes instead of one long wall of fields */
.step {
  display: grid;
  gap: clamp(22px, 2.6vw, 34px);
  margin: 0;
  padding: 0;
  border: 0;
}
.step__legend {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 0 0 clamp(6px, 1vw, 12px);
  font-family: var(--display);
  font-size: clamp(1.25rem, 1rem + 0.8vw, 1.7rem);
  color: var(--ivory);
}
.step__num { font-size: 0.78em; color: var(--gold); letter-spacing: 0.08em; }
.is-ready .step[hidden] { display: none; }
.is-ready .step { animation: stepIn 520ms var(--ease) both; }
@keyframes stepIn { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: 0 0; } }

/* completion meter */
.meter {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: clamp(28px, 4vw, 44px);
}
.meter[hidden] { display: none; }
.meter__ring { width: 62px; height: 62px; flex: none; rotate: -90deg; }
.meter__ring circle {
  fill: none;
  stroke-width: 2;
  cx: 48px;
  cy: 48px;
}
.meter__track { stroke: rgba(254, 253, 248, 0.18); }
.meter__value {
  stroke: var(--gold);
  stroke-linecap: round;
  stroke-dasharray: 270;
  stroke-dashoffset: calc(270 - 270 * var(--done, 0));
  transition: stroke-dashoffset 560ms var(--ease);
}
.meter__text { display: grid; gap: 3px; }
.meter__step {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ivory);
}
.meter__hint { font-size: 0.88rem; color: var(--ivory-60); }

/* what has been answered so far */
.enquire__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}
.enquire__chips li {
  padding: 7px 13px;
  border: 1px solid rgba(254, 253, 248, 0.22);
  font-size: 0.78rem;
  color: var(--ivory-72);
  animation: stepIn 420ms var(--ease) both;
}
.enquire__chips li b { font-weight: 600; color: var(--ivory); }

.field__foot { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.field__count { margin: 0; font-size: 0.74rem; color: var(--ivory-40); font-variant-numeric: tabular-nums; }
.field__count.is-close { color: var(--gold); }
.field.is-filled label::after {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--gold);
  align-self: center;
}
.button--ghost { --btn-bg: transparent; --btn-fg: var(--ivory); --btn-line: rgba(254, 253, 248, 0.4); }
.button--ghost:hover { --btn-line: var(--ivory); translate: 0 -2px; }
.button[hidden] { display: none; }
.field-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(22px, 2.6vw, 34px);
}
.field { display: grid; gap: 8px; align-content: start; }
.field label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ivory-72);
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.field__req, .field__opt {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  color: var(--gold);
}
.field__opt { color: var(--ivory-60); }
.field input,
.field textarea,
.field select {
  width: 100%;
  min-height: 52px;
  padding: 12px 2px;
  background: transparent;
  color: var(--ivory);
  border: 0;
  border-bottom: 1px solid var(--ivory-40);
  border-radius: 0;
  font-family: var(--body);
  font-size: 1.02rem;
  transition: border-color var(--ui), background-color var(--ui);
}
.field textarea { resize: vertical; min-height: 140px; line-height: 1.55; }
.field input:hover, .field textarea:hover, .field select:hover { border-bottom-color: var(--ivory); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-bottom-color: var(--gold);
  border-bottom-width: 2px;
  padding-bottom: 11px;
}
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
}
.select { position: relative; }
.select::after {
  content: '';
  position: absolute;
  right: 6px; top: 50%;
  width: 9px; height: 9px;
  border-right: 1px solid var(--gold);
  border-bottom: 1px solid var(--gold);
  rotate: 45deg;
  translate: 0 -70%;
  pointer-events: none;
}
.field select { appearance: none; padding-right: 30px; cursor: pointer; }
.field select option { color: var(--navy); }
.field__hint { margin: 0; font-size: 0.82rem; color: var(--ivory-60); }
.field__error { margin: 0; font-size: 0.85rem; color: var(--alert); display: none; }
.field.has-error .field__error { display: flex; gap: 8px; align-items: baseline; }
.field.has-error .field__error::before { content: '!'; font-weight: 700; }
.field.has-error input,
.field.has-error textarea,
.field.has-error select { border-bottom-color: var(--alert); }
.field--trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-summary {
  border: 1px solid var(--alert);
  padding: 18px 22px;
  color: var(--alert);
  font-size: 0.95rem;
}
.form-summary ul { margin: 10px 0 0; padding-left: 18px; }
.form-summary a { color: var(--alert); }

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px 26px;
  margin-top: 6px;
}
.form-status { margin: 0; font-size: 0.92rem; color: var(--ivory-72); max-width: 32rem; }
.form-status.is-error { color: var(--alert); }
.form-status.is-success { color: var(--gold); }

.form-done {
  border: 1px solid var(--gold);
  padding: clamp(26px, 4vw, 44px);
}
.form-done h3 { font-size: clamp(1.5rem, 1.2rem + 1vw, 2.1rem); color: var(--ivory); margin-bottom: 0.5em; }
.form-done p { color: var(--ivory-72); }

@media (max-width: 899.98px) {
  .enquire { display: block; }
  .enquire__aside { position: static; margin-bottom: 40px; }
  .field-row { grid-template-columns: 1fr; }
}

/* =====================================================================
   FOOTER
   ===================================================================== */
/* The close of the page, not a sign-off line: the crest on its quiet field,
   the two ways through the site, and the one thing we want asked. */
.site-footer {
  background: var(--ivory);
  border-top: 1px solid var(--gold);
  /* the deep foot clears the accessibility button, which is fixed to the
     bottom-left corner and otherwise sits on top of the legal line */
  padding: clamp(54px, 7vw, 96px) var(--gutter) clamp(94px, 8vw, 112px);
}
.site-footer__inner {
  width: min(1680px, 100%);
  margin-inline: auto;
  display: grid;
  gap: clamp(34px, 4vw, 64px);
  align-items: start;
}
.site-footer__crest img {
  /* the brand guide's floor for the crest; capped so it cannot overrun a
     narrow phone, where 320px plus gutters does not fit */
  width: 320px;
  max-width: 100%;
  height: auto;
}
.site-footer__line {
  margin: clamp(20px, 2.4vw, 30px) 0 0;
  max-width: 34ch;
  font-size: 0.95rem;
  color: var(--navy-70);
}
.site-footer__heading {
  margin: 0 0 1.5em;
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.site-footer__col ul {
  margin: 0; padding: 0; list-style: none;
  display: grid;
  gap: 0.95em;
}
.site-footer__col a {
  color: var(--navy);
  text-decoration: none;
  font-size: 0.92rem;
  border-bottom: 1px solid transparent;
  transition: border-color var(--ui), color var(--ui);
}
.site-footer__col a:hover { color: var(--gold-ink); border-bottom-color: var(--gold); }
.site-footer__note {
  margin: 0 0 1.8em;
  max-width: 34ch;
  font-size: 0.92rem;
  color: var(--navy-70);
}
.site-footer__base {
  width: min(1680px, 100%);
  margin: clamp(38px, 5vw, 66px) auto 0;
  padding-top: clamp(18px, 2vw, 26px);
  border-top: 1px solid var(--navy-16);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 28px;
}
.site-footer__legal { margin: 0; font-size: 0.78rem; color: var(--navy-45); }

/* two up once there is room for a column beside the crest, four across when
   the crest can keep its full width and still leave the lists their measure */
@media (min-width: 620px) {
  .site-footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1100px) {
  .site-footer__inner {
    grid-template-columns:
      minmax(0, 1.45fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1.1fr);
  }
}

/* =====================================================================
   MOBILE APP BAR
   ===================================================================== */
.app-bar { display: none; }
.app-sheet { display: none; }

@media (max-width: 767.98px) {
  .app-bar {
    position: fixed;
    z-index: 60;
    left: 0; right: 0; bottom: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    background: var(--ivory);
    border-top: 1px solid var(--navy-16);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .app-bar__item {
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 4px;
    min-height: 62px;
    padding: 6px 4px;
    background: none;
    border: 0;
    color: var(--navy);
    font-family: var(--body);
    font-size: 0.64rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
  }
  .app-bar__item--primary { color: var(--gold); }
  .app-bar__item:active { background: var(--ivory-deep); }

  .app-sheet {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: grid;
    align-items: end;
    background: rgba(0, 28, 52, 0.42);
    opacity: 0;
    transition: opacity 260ms var(--ease);
  }
  .app-sheet.is-open { opacity: 1; }
  .app-sheet[hidden] { display: none; }
  .app-sheet__panel {
    background: var(--ivory);
    padding: 28px var(--gutter) calc(30px + env(safe-area-inset-bottom));
    translate: 0 16px;
    transition: translate 320ms var(--ease);
  }
  .app-sheet.is-open .app-sheet__panel { translate: 0 0; }
  .app-sheet__brand {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--navy-45);
    margin-bottom: 18px;
  }
  .app-sheet ul { list-style: none; margin: 0 0 22px; padding: 0; }
  .app-sheet li + li { border-top: 1px solid var(--navy-16); }
  .app-sheet a {
    display: block;
    padding: 16px 0;
    font-family: var(--display);
    font-size: 1.6rem;
    color: var(--navy);
    text-decoration: none;
  }
  .app-sheet__close {
    width: 100%;
    min-height: 50px;
    background: none;
    border: 1px solid var(--navy-16);
    font-family: var(--body);
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--navy);
    cursor: pointer;
  }
  body.sheet-open { overflow: hidden; }
}

/* =====================================================================
   HERO: TABLET AND MOBILE LAYOUT (image above, content below)
   ===================================================================== */
@media (max-width: 1199.98px) and (orientation: portrait), (max-width: 767.98px) {
  .hero__line { overflow: visible; }
  .hero__line > span { white-space: normal; }
  .hero {
    --hero-h: auto;
    height: auto;
    display: grid;
    background: var(--ivory);
  }
  .hero__media {
    position: relative;
    height: clamp(340px, 56svh, 118vw);
  }
  .hero__scene { left: 50%; translate: -50% -50%; width: max(100vw, calc(56svh * 1.7684)); }
  .hero__veil { background: linear-gradient(0deg, rgba(254, 253, 248, 0.5) 0%, rgba(254, 253, 248, 0) 34%); }
  .hero:has(#light-evening:checked) .hero__veil,
  .hero[data-mode='evening'] .hero__veil {
    background: linear-gradient(0deg, rgba(0, 24, 44, 0.45) 0%, rgba(0, 24, 44, 0) 34%);
  }
  .hero__content {
    height: auto;
    padding: clamp(28px, 6vw, 48px) var(--gutter) clamp(36px, 7vw, 56px);
    color: var(--navy);
  }
  .hero:has(#light-evening:checked) .hero__content,
  .hero[data-mode='evening'] .hero__content { color: var(--navy); }
  .hero:has(#light-evening:checked) .hero__eyebrow,
  .hero:has(#light-evening:checked) .hero__lede,
  .hero[data-mode='evening'] .hero__eyebrow,
  .hero[data-mode='evening'] .hero__lede { color: var(--navy-70); }
  .hero:has(#light-evening:checked) .button--primary,
  .hero[data-mode='evening'] .button--primary { --btn-bg: var(--navy); --btn-fg: var(--ivory); --btn-line: var(--navy); }
  .hero:has(#light-evening:checked) .button--quiet,
  .hero[data-mode='evening'] .button--quiet { --btn-fg: var(--navy); --btn-line: var(--navy-45); }
  .hero__mark { margin-bottom: clamp(20px, 4vw, 34px); }
  /* the header keeps the name at this size, so the hero does not repeat it */
  .hero__mark { display: none; }

  .hero__title { max-width: min(100%, 33rem); }
  .hero__headline { font-size: clamp(2.05rem, 1.1rem + 4.6vw, 3.2rem); }
  .hero__actions .button { flex: 1 1 auto; }
  .hero__controls {
    right: auto;
    left: var(--gutter);
    bottom: clamp(16px, 4vw, 26px);
    align-items: flex-start;
  }
  .light-toggle__legend {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    clip-path: inset(50%);
    overflow: hidden; white-space: nowrap;
  }
  .hero__note { display: none; }
}

@media (max-width: 767.98px) {
  .hero__plane, .hero__caustics { display: none; }
  .hero__mobile { display: block; }
  .hero__scene { left: 0; top: 0; translate: none; scale: 1; width: 100%; height: 100%; aspect-ratio: auto; }
  .hero__media { height: clamp(360px, 52svh, 112vw); }
  .light-toggle__option { min-width: 78px; }
}

/* =====================================================================
   SCROLL REVEALS (only applied once the module is ready)
   ===================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .is-ready .reveal-lines,
  .is-ready .reveal-media,
  .is-ready .rule--draw { will-change: transform, opacity; }

  .is-ready .reveal-lines { opacity: 0; translate: 0 18px; transition: opacity var(--content), translate var(--content); }
  .is-ready .reveal-lines.is-in { opacity: 1; translate: 0 0; }

  .is-ready .reveal-media { clip-path: inset(0 0 12% 0); opacity: 0; transition: clip-path 900ms var(--ease), opacity 700ms var(--ease); }
  .is-ready .reveal-media.is-in { clip-path: inset(0 0 0 0); opacity: 1; }

  .is-ready .rule--draw { scale: 0 1; transition: scale 760ms var(--ease); }
  .is-ready .rule--draw.is-in { scale: 1 1; }

  .is-ready .pathway__step { opacity: 0; translate: 0 16px; transition: opacity var(--content), translate var(--content); }
  .is-ready .pathway__step.is-in { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =====================================================================
   ACCESSIBILITY CONTROLS
   Built in the site's own language rather than dropped in as a widget.
   These are conveniences: the site also follows the visitor's own system
   settings, and no claim is made about certification.
   ===================================================================== */
.a11y-toggle {
  position: fixed;
  z-index: 80;
  left: clamp(14px, 2vw, 26px);
  bottom: clamp(14px, 2vw, 26px);
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 46px;
  padding: 0 16px;
  background: var(--navy);
  color: var(--ivory);
  border: 1px solid var(--navy);
  font-family: var(--body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 18px 40px -28px rgba(0, 24, 44, 0.9);
  transition: background-color var(--ui), color var(--ui);
}
.a11y-toggle:hover { background: var(--gold); border-color: var(--gold); color: var(--navy); }

.a11y-panel {
  position: fixed;
  z-index: 81;
  left: clamp(14px, 2vw, 26px);
  bottom: calc(clamp(14px, 2vw, 26px) + 58px);
  width: min(340px, calc(100vw - 28px));
  max-height: min(78svh, 640px);
  overflow-y: auto;
  padding: clamp(20px, 2.4vw, 28px);
  background: var(--ivory);
  border-top: 2px solid var(--gold);
  box-shadow: 0 40px 90px -50px rgba(0, 24, 44, 0.85);
}
.a11y-panel[hidden] { display: none; }
.a11y-panel__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.a11y-panel h2 { font-size: 1.25rem; }
.a11y-panel__close {
  background: none;
  border: 0;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--navy-70);
  cursor: pointer;
  padding: 4px 6px;
}
.a11y-panel__close:hover { color: var(--gold); }

.a11y-group { margin: 22px 0 0; padding: 0; border: 0; }
.a11y-group legend {
  padding: 0 0 10px;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--navy-70);
}
.a11y-choice { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.a11y-choice button {
  min-height: 44px;
  padding: 0 6px;
  background: none;
  border: 1px solid var(--navy-16);
  font-family: var(--body);
  font-size: 0.76rem;
  color: var(--navy-70);
  cursor: pointer;
  transition: border-color var(--ui), color var(--ui), background-color var(--ui);
}
.a11y-choice button[aria-pressed='true'] {
  border-color: var(--navy);
  background: var(--navy);
  color: var(--ivory);
}
.a11y-switch {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  font-size: 0.92rem;
  color: var(--navy);
  cursor: pointer;
}
.a11y-switch input { width: 20px; height: 20px; accent-color: var(--navy); }

.a11y-reset {
  margin-top: 22px;
  width: 100%;
  min-height: 44px;
  background: none;
  border: 1px solid var(--navy-45);
  font-family: var(--body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy);
  cursor: pointer;
}
.a11y-reset:hover { border-color: var(--gold); color: var(--gold); }
.a11y-note { margin: 16px 0 0; font-size: 0.78rem; color: var(--navy-70); }

@media (max-width: 767.98px) {
  .a11y-toggle { bottom: calc(var(--appbar-h) + 12px); }
  .a11y-toggle span { display: none; }
  .a11y-toggle { padding: 0 13px; }
  .a11y-panel { bottom: calc(var(--appbar-h) + 70px); }
}

/* ---- what the settings actually change ---- */
:root[data-a11y-text='115'] { font-size: 115%; }
:root[data-a11y-text='130'] { font-size: 130%; }

:root[data-a11y-contrast='on'] {
  --navy-70: rgba(0, 44, 80, 0.94);
  --navy-45: rgba(0, 44, 80, 0.72);
  --navy-16: rgba(0, 44, 80, 0.4);
  --ivory-72: rgba(254, 253, 248, 0.96);
  --ivory-60: rgba(254, 253, 248, 0.9);
  --ivory-40: rgba(254, 253, 248, 0.78);
}
:root[data-a11y-contrast='on'] .hero__veil,
:root[data-a11y-contrast='on'] .details__spotlight { opacity: 1; }
:root[data-a11y-contrast='on'] .site-header { border-bottom-color: var(--navy); }

:root[data-a11y-links='on'] a:not(.button):not(.site-nav__brand) { text-decoration: underline; text-underline-offset: 3px; }

:root[data-a11y-motion='reduced'] *,
:root[data-a11y-motion='reduced'] *::before,
:root[data-a11y-motion='reduced'] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* =====================================================================
   Cabin pages (/beds/…)
   Sub-pages for each cabin the bed is being planned for. They reuse the
   header, footer, app bar and accessibility panel, so only the page body
   needs styling.
   ===================================================================== */
.page-cabin { background: var(--ivory); }

.cabin-hero {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  min-height: clamp(460px, 74svh, 760px);
  display: grid;
  align-items: end;
  overflow: hidden;
}
.cabin-hero__media { position: absolute; inset: 0; }
.cabin-hero__media picture { display: block; height: 100%; }
.cabin-hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* the type needs its own weight: the cabins are bright and pale */
.cabin-hero::after {
  content: '';
  position: absolute;
  inset: 25% 0 0;
  background: linear-gradient(to bottom, rgba(0, 24, 44, 0), rgba(0, 24, 44, 0.68) 55%, rgba(0, 24, 44, 0.84));
}
.cabin-hero__text {
  position: relative;
  z-index: 1;
  width: min(1680px, 100% - 2 * var(--gutter));
  margin-inline: auto;
  padding-bottom: clamp(34px, 5vw, 76px);
  color: var(--ivory);
}
.cabin-hero__text .display { margin: 0.1em 0 0; color: var(--ivory); max-width: 16ch; }
.cabin-hero__lead {
  margin: 0.7em 0 0;
  max-width: 44ch;
  color: var(--ivory-72);
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.2rem);
}

.crumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ivory-60);
}
.crumbs li + li::before { content: '/'; margin-right: 8px; color: var(--ivory-40); }
.crumbs a { color: var(--ivory-72); text-decoration: none; }
.crumbs a:hover { color: var(--gold); }

.cabin-intro {
  max-width: 1680px;
  margin-inline: auto;
  padding: clamp(56px, 8vw, 120px) var(--gutter) 0;
}
.cabin-intro__text {
  margin: 0;
  max-width: 34ch;
  margin-left: auto;
  font-family: var(--display);
  font-size: clamp(1.4rem, 1rem + 1.5vw, 2.3rem);
  line-height: 1.24;
  color: var(--navy);
}

.cabin-points {
  max-width: 1680px;
  margin-inline: auto;
  padding: clamp(56px, 8vw, 120px) var(--gutter);
}
.cabin-points__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0;
}
.cabin-points__list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(18px, 3vw, 56px);
  padding: clamp(22px, 2.6vw, 38px) 0;
  border-top: 1px solid var(--navy-16);
}
.cabin-points__list li:last-child { border-bottom: 1px solid var(--navy-16); }
.cabin-points__n {
  font-family: var(--display);
  font-size: clamp(1.1rem, 0.9rem + 0.6vw, 1.5rem);
  color: var(--gold-ink);
}
.cabin-points__list h3 {
  font-family: var(--display);
  font-size: clamp(1.25rem, 1rem + 0.9vw, 1.85rem);
  line-height: 1.16;
  margin: 0 0 0.45em;
}
.cabin-points__list p { margin: 0; max-width: 62ch; color: var(--navy-70); }
/* wide enough to set the heading against its own explanation, the way the
   ruled lists elsewhere on the site read */
@media (min-width: 1100px) {
  .cabin-points__list li > div {
    display: grid;
    grid-template-columns: minmax(0, 26ch) minmax(0, 62ch);
    gap: clamp(28px, 3.4vw, 72px);
    align-items: start;
  }
  .cabin-points__list h3 { margin-bottom: 0; }
}

.cabin-useful {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--navy);
  color: var(--ivory);
  padding: clamp(56px, 8vw, 120px) var(--gutter);
}
.cabin-useful__inner { max-width: 1680px; margin-inline: auto; }
.cabin-useful h2 { color: var(--ivory); }
.cabin-useful p { margin: 1em 0 0; max-width: 56ch; color: var(--ivory-72); }
.cabin-useful ul {
  list-style: none;
  margin: clamp(26px, 3vw, 44px) 0 clamp(30px, 3.4vw, 48px);
  padding: 0;
  columns: 2;
  column-gap: clamp(24px, 4vw, 72px);
}
.cabin-useful li {
  break-inside: avoid;
  padding: 13px 0;
  border-top: 1px solid rgba(254, 253, 248, 0.16);
  color: var(--ivory);
  font-size: 0.96rem;
}

.cabin-more {
  max-width: 1680px;
  margin-inline: auto;
  padding: clamp(56px, 8vw, 120px) var(--gutter) 0;
}
.more-grid {
  margin-top: clamp(26px, 3vw, 44px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.4vw, 22px);
}
.more-card {
  display: grid;
  align-content: start;
  gap: 10px;
  padding: clamp(20px, 2vw, 32px);
  background: var(--ivory-deep);
  border-top: 2px solid var(--gold);
  color: var(--navy);
  text-decoration: none;
  transition: translate var(--ui), background var(--ui);
}
.more-card:hover { translate: 0 -4px; background: #EFE8D8; }
.more-card__name { font-family: var(--display); font-size: clamp(1.15rem, 1rem + 0.5vw, 1.45rem); }
.more-card__line { color: var(--navy-70); font-size: 0.88rem; line-height: 1.5; }

.cabin-note {
  max-width: 1680px;
  margin: clamp(56px, 8vw, 120px) auto 0;
  padding: 0 var(--gutter) clamp(56px, 8vw, 110px);
  font-size: 0.78rem;
  color: var(--navy-45);
  max-width: 70ch;
}

@media (max-width: 900px) {
  .cabin-intro__text { margin-left: 0; }
  .cabin-useful ul { columns: 1; }
  .more-grid { grid-template-columns: 1fr; }
}


/* =====================================================================
   THE SEA BEHIND THE PAGE
   One fixed layer of moving water, held behind everything. The hero covers
   it with its own imagery; from the beds section down the sections go
   transparent and their copy sits on translucent paper, so the water runs
   the whole way to the footer and keeps moving as the page scrolls.
   ===================================================================== */
.seabed {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: #0A2A47;
  pointer-events: none;
}
.seabed picture { display: block; height: 100%; }
.seabed img,
.seabed__footage {
  /* measured: the backdrop ran 2.8x brighter than the aerial it meets, which
     is what made them read as two different seas */
  filter: brightness(0.78) saturate(1.06);
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.seabed__footage { opacity: 0; transition: opacity 900ms var(--ease); }
.seabed__footage.is-playing { opacity: 1; }

/* the sections that now float on it */
.details,
.project { background: transparent; }

/* The specialism is the one light section in the run: the sheet sits on its
   own ground rather than on the water. The top edge fades in from the sea
   above it so the change is a transition and not a line. */
.intro__ground {
  position: relative;
  /* fades in from the sea above and back out to it below, so the one light
     section in the run arrives and leaves as a transition rather than an edge */
  --ground-fade: clamp(90px, 14vh, 190px);
  background: linear-gradient(
    to bottom,
    rgba(254, 253, 248, 0) 0,
    var(--ivory) var(--ground-fade),
    var(--ivory) calc(100% - var(--ground-fade)),
    rgba(254, 253, 248, 0) 100%
  );
}

/* paper: enough to carry navy type over any part of the water, and still
   let the sea show at the gutters and between the blocks */
.project > .steps__head,
.project > .callout,
.project > .compare,
.project > .faq {
  background: rgba(254, 253, 248, 0.95);
  backdrop-filter: blur(2px);
}
/* the photograph is the background now, so the mount carries nothing */
.sheet__frame { padding: 0; background: none; }
.project > .steps__head,
.project > .callout,
.project > .compare,
.project > .faq {
  padding: clamp(24px, 3vw, 44px);
  border-radius: 14px;
  box-shadow: 0 22px 48px -30px rgba(0, 44, 80, 0.55);
}
.project > * + * { margin-top: clamp(20px, 2.6vw, 36px); }

/* the drawing sheet is a sheet of paper laid on the water */
.sheet__who {
  margin-top: clamp(20px, 2.4vw, 32px);
  padding: clamp(16px, 1.8vw, 24px) 0 0;
}

/* The last two bands let the water through rather than sealing it off, so the
   sea really does run to the foot of the page. Both are dark enough for ivory
   type: measured over the brightest foam, about 11:1. */
.enquire { background: rgba(0, 44, 80, 0.93); }
/* It had a 1680px cap, so above that width it stopped short of both edges and
   left a sliver of water down each side. The band is full bleed now, and the
   columns are held to the content measure by the padding rather than by a cap
   on the children — capping those fought the grid and left a dead gap. */
.enquire {
  max-width: none;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  padding-inline: max(var(--gutter), calc(50% - 840px));
}

/* the footer is ivory with navy type, so it stays ivory — just translucent */
.site-footer { background: rgba(254, 253, 248, 0.95); }

/* Phones and reduced motion keep the still: a background video is not worth
   their bandwidth, and nothing here depends on it moving. */
@media (max-width: 767.98px), (prefers-reduced-motion: reduce) {
  .seabed__footage { display: none; }
}
