/* ============================================================
   Carpe Diem Sailing — design system
   Palette: client-approved (Luxe & Elegant + Coastal Charm + Sani warmth)
   Type: Cormorant Garamond (display) + Jost (body)
   ============================================================ */

:root {
  --cream: #FAF7F2;
  --silk: #EEE5D9;
  --sand: #F2E8DE;
  --marble: #E8E4E0;
  --pearl: #FDFFFF;
  --navy: #222D52;
  --navy-deep: #1A2340;
  --ink: #2B2723;
  --ink-soft: #5C554E;
  --champagne: #D2B68A;
  --champagne-deep: #B99862;
  /* gold for TEXT on light surfaces — champagne-deep reads 2.5:1 on cream,
     this reads ~4.6:1. Navy-background golds keep the brighter tones. */
  --gold-ink: #77602F;
  --haven: #5A7D98;
  --aqua: #87B8BC;
  --mist: #BDD1D6;

  --font-display: "Cormorant Garamond", "Georgia", serif;
  --font-body: "Jost", "Segoe UI", system-ui, sans-serif;

  --container: 1360px;
  --radius: 12px;
  /* One horizontal gutter for the whole page. The header, the hero text and
     every section container all use it, so the left edge of the content never
     jogs as you scroll from the hero into the page. */
  --gutter: 24px;
  /* one vertical rhythm for every section, and one number for "how far below
     the fixed header should an anchor jump land" */
  --section-y: clamp(72px, 9vw, 108px);
  --section-y-tight: clamp(52px, 6.5vw, 76px);
  --header-h: 76px;
  --shadow-soft: 0 18px 45px -18px rgba(34, 45, 82, 0.28);
  --shadow-card: 0 10px 30px -12px rgba(34, 45, 82, 0.22);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- Reset & base ---------- */

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

html { scroll-behavior: smooth; overflow-x: clip; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.06rem;
  line-height: 1.7;
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img { max-width: 100%; display: block; }

a { color: var(--haven); text-decoration: none; transition: color 0.25s var(--ease); }
a:hover { color: var(--navy); }

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  color: var(--navy);
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.9rem, 6.6vw, 5.6rem); }
h2 { font-size: clamp(2.2rem, 4.4vw, 3.5rem); }
h3 { font-size: clamp(1.5rem, 2.4vw, 2rem); }

p { margin: 0 0 1.2em; }

em { font-family: var(--font-display); font-style: italic; font-size: 1.08em; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }
/* anchor jumps land clear of the fixed header — one rule, no per-id tuning */
main [id] { scroll-margin-top: calc(var(--header-h) + 6px); }
/* the last section eases into the footer instead of slamming against it */
main > section:last-child { padding-bottom: calc(var(--section-y) * 1.45); }

/* ---------- Kicker / section headings ---------- */

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 18px;
}

.kicker::before {
  content: "";
  width: 34px;
  height: 1px;
  background: var(--champagne);
}

.section-head { max-width: 720px; margin-bottom: 56px; }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .kicker::after { content: ""; width: 34px; height: 1px; background: var(--champagne); }
.section-head p { color: var(--ink-soft); }

/* centered banner kicker gets the matching right-hand dash — one-sided
   wings push the text visibly off-centre */
/* ---------- Header / nav ----------
   Fixed overlay: transparent over the hero, solid once scrolled.
   .site-header--solid forces the solid look on pages without a hero. */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.35s var(--ease), box-shadow 0.35s var(--ease),
    border-color 0.35s var(--ease), transform 0.4s var(--ease);
}
/* smart header: slides away scrolling down, returns scrolling up */
.site-header.is-hidden { transform: translateY(-105%); box-shadow: none; }
/* Frost on a pseudo-element: backdrop-filter on the header itself would make it
   the containing block for the fixed mobile nav panel. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  backdrop-filter: blur(0px);
  transition: backdrop-filter 0.35s var(--ease);
}
.site-header.is-scrolled,
.site-header--solid {
  background: rgba(250, 247, 242, 0.92);
  border-color: var(--marble);
  box-shadow: 0 8px 30px -18px rgba(34, 45, 82, 0.35);
}
.site-header.is-scrolled::before,
.site-header--solid::before { backdrop-filter: blur(12px); }

/* Over-hero (transparent) text colors */
.site-header .brand { color: var(--pearl); }
.site-header .brand__name { color: var(--pearl); }
.site-header .brand__tag { color: var(--champagne); }
.site-header .nav__link { color: rgba(253, 255, 255, 0.88); }
.site-header .nav__link:hover { color: var(--pearl); }
.site-header .nav__link[aria-current="page"],
.site-header .nav__link[data-section="current"] { color: var(--pearl); }
.site-header .nav-toggle { color: var(--pearl); }

/* Solid state text colors */
.site-header.is-scrolled .brand, .site-header--solid .brand,
.site-header.is-scrolled .brand__name, .site-header--solid .brand__name { color: var(--navy); }
.site-header.is-scrolled .brand__tag, .site-header--solid .brand__tag { color: var(--gold-ink); }
.site-header.is-scrolled .nav__link, .site-header--solid .nav__link { color: var(--ink); }
.site-header.is-scrolled .nav__link:hover, .site-header--solid .nav__link:hover,
.site-header.is-scrolled .nav__link[aria-current="page"], .site-header--solid .nav__link[aria-current="page"],
.site-header.is-scrolled .nav__link[data-section="current"], .site-header--solid .nav__link[data-section="current"] { color: var(--navy); }
.site-header.is-scrolled .nav-toggle, .site-header--solid .nav-toggle { color: var(--navy); }

.site-header__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 78px;
  transition: padding 0.35s var(--ease);
}
/* over the hero, sit clear of the inset frame line */
.site-header:not(.is-scrolled):not(.site-header--solid) .site-header__inner { padding-top: 22px; }

.brand { display: flex; align-items: center; gap: 12px; color: var(--navy); }
.brand svg { width: 40px; height: 26px; flex: none; }
.brand__text { display: flex; flex-direction: column; line-height: 1.05; }
.brand__name { font-family: var(--font-display); font-style: italic; font-weight: 700; font-size: 1.5rem; color: var(--navy); }
.brand__tag { font-size: 0.6rem; font-weight: 500; letter-spacing: 0.34em; text-transform: uppercase; color: var(--champagne-deep); margin-top: 3px; }

.nav { display: flex; align-items: center; }
/* the mobile menu's wash layers are injected on every page — they only
   exist below 860px, where the rules further down give them their box */
.nav__crest, .nav__sheet { display: none; }
.nav ul { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 6px; }

.nav__link {
  display: inline-block;
  /* above the open shelf's full-width hover bridge — without this, the bridge
     of an open dropdown sits on top of the neighbouring links and the pointer
     never really leaves the old menu (the stuck/flickering submenu bug) */
  position: relative;
  z-index: 2;
  padding: 8px 13px 6px;
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink);
}
.nav__link::after {
  content: "";
  display: block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--champagne);
  margin: 3px auto 0;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}
/* [aria-current] marks the page itself; [data-section] marks the parent of
   the group it lives in — both read as "you are here" */
.nav__link:hover,
.nav__link[aria-current="page"],
.nav__link[data-section="current"] { color: var(--navy); }
.nav__link[aria-current="page"]::after,
.nav__link[data-section="current"]::after { opacity: 1; }
.dropdown__menu a[aria-current="page"] { color: var(--champagne-deep); }

/* dropdowns (desktop: hover / focus-within, animated) */
.dropdown { position: relative; }
.dropdown__toggle { display: none; }
/* The submenu is a full-width shelf under the header: same width as the
   page, one card per option. */
.dropdown__menu {
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;
  z-index: 1;
  padding: 22px 0 28px;
  /* the same frosted cream the scrolled header wears, so the shelf reads as
     part of the chrome over the hero AND once the header goes solid */
  background: rgba(250, 247, 242, 0.93);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--marble);
  box-shadow: 0 40px 70px -40px rgba(34, 45, 82, 0.5);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.28s var(--ease), transform 0.28s var(--ease), visibility 0s 0.28s;
}
/* the pointer's path from the nav link down across the header's lower band */
.dropdown__menu::before {
  content: "";
  position: absolute;
  top: -34px;
  left: 0;
  right: 0;
  height: 34px;
}
.dropdown:hover .dropdown__menu,
.dropdown:focus-within .dropdown__menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.28s var(--ease), transform 0.28s var(--ease), visibility 0s;
}
.dropdown__head {
  margin: 0 0 14px;
  padding: 0 0 10px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-ink);
  border-bottom: 1px solid var(--silk);
}
.dropdown__cards { display: flex; gap: 16px; }
.dd-card { width: 224px; }
.dd-card img {
  width: 100%;
  aspect-ratio: 16 / 9.6;
  object-fit: cover;
  display: block;
  border-radius: 10px;
  transition: transform 0.45s var(--ease), box-shadow 0.3s var(--ease);
}
.dd-card:hover img { transform: translateY(-2px); box-shadow: var(--shadow-card); }
.dd-card__name { display: block; margin-top: 10px; font-size: 0.9rem; font-weight: 500; color: var(--ink); }
.dd-card:hover .dd-card__name { color: var(--navy); }
.dd-card__meta { display: block; margin-top: 2px; font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-ink); }
.dd-card[aria-current="page"] .dd-card__name { color: var(--gold-ink); }
.dd-card[aria-current="page"] img { outline: 2px solid var(--champagne); outline-offset: -2px; }
.nav__cta { margin-left: 14px; position: relative; z-index: 2; }
/* the header button matches the 40px brand/dial line instead of towering over it */
.nav__cta .btn { padding: 9px 20px; font-size: 0.7rem; }

/* JS-injected mobile menu foot — only exists visually inside the panel */
.nav__foot { display: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  padding: 10px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--navy);
  -webkit-tap-highlight-color: transparent;
}
.nav-toggle__bar {
  display: block;
  width: 24px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.42s var(--ease), opacity 0.28s var(--ease), width 0.3s var(--ease);
}
.nav-toggle__bar:nth-child(2) { width: 16px; }
/* open: the bars fold into a close cross */
body.nav-open .nav-toggle__bar:nth-child(1) { transform: translateY(8px) rotate(45deg); }
body.nav-open .nav-toggle__bar:nth-child(2) { opacity: 0; transform: translateX(10px); }
body.nav-open .nav-toggle__bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* ---------- Buttons ---------- */

.btn {
  display: inline-block;
  padding: 13px 30px;
  border: 1px solid var(--champagne);
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy);
  background: transparent;
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease), transform 0.3s var(--ease);
}
.btn:hover { background: var(--champagne); color: var(--navy); transform: translateY(-1px); }

.btn--solid { background: var(--champagne); }
.btn--solid:hover { background: var(--champagne-deep); }

.btn--ghost { border-color: rgba(253, 255, 255, 0.55); color: var(--pearl); }
.btn--ghost:hover { background: var(--pearl); color: var(--navy); border-color: var(--pearl); }
/* outline button for LIGHT surfaces — ghost is pearl-on-photo and vanishes on cream */
.btn--line { border-color: rgba(34, 45, 82, 0.45); color: var(--navy); }
.btn--line:hover { background: var(--navy); color: var(--pearl); border-color: var(--navy); }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  /* editorial: the content sits low in the frame, not adrift in the middle */
  align-items: flex-end;
  isolation: isolate;
  overflow: hidden;
}
.hero__media, .hero__media img { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__media img { object-fit: cover; animation: hero-drift 9s var(--ease) forwards; }
@keyframes hero-drift { from { transform: scale(1.07); } to { transform: scale(1); } }

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(ellipse 120% 90% at 50% 108%, rgba(26, 35, 64, 0.55), transparent 55%),
    linear-gradient(180deg, rgba(26, 35, 64, 0.52) 0%, rgba(26, 35, 64, 0.18) 32%, rgba(26, 35, 64, 0.26) 64%, rgba(26, 35, 64, 0.6) 100%);
}

/* inset hairline frame — the printed-chart look */
.hero__frame {
  position: absolute;
  inset: 18px;
  z-index: 2;
  border: 1px solid rgba(253, 255, 255, 0.3);
  border-radius: 3px;
  pointer-events: none;
}

.hero__content {
  position: relative;
  z-index: 2;
  max-width: var(--container);
  margin: 0 auto;
  padding: 130px var(--gutter) 128px;
  width: 100%;
  color: var(--pearl);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}
/* keep the home hero inside one screen on shorter viewports */
@media (max-height: 820px) {
  .hero__content { padding: 96px var(--gutter) 116px; }
  .hero__content h1 { font-size: clamp(3.1rem, 6.4vw, 5.3rem); }
  .hero__lead { font-size: 1.02rem; }
  .hero__actions { margin-top: 22px; }
  .hero__facts { bottom: 30px; }
}
.hero__content .kicker { color: var(--champagne); text-shadow: 0 1px 14px rgba(26, 35, 64, 0.65); }
.hero__content h1 { color: var(--pearl); max-width: 17ch; font-weight: 700; text-shadow: 0 2px 34px rgba(26, 35, 64, 0.5); }
.hero__content h1 em { color: var(--champagne); }
.hero__lead { max-width: 620px; font-size: 1.13rem; font-weight: 300; color: rgba(253, 255, 255, 0.94); }
.hero__actions { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 14px; margin-top: 30px; }

.hero__facts {
  position: absolute;
  bottom: 38px;
  left: 0;
  right: 0;
  margin: 0 auto;
  max-width: var(--container);
  padding: 0 var(--gutter);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 20px;
  white-space: nowrap;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(253, 255, 255, 0.82);
}
.hero__facts span { display: inline-flex; align-items: center; gap: 7px; }
.hero__facts span svg { width: 13px; height: 13px; color: var(--champagne); flex: none; }
.hero__facts span[aria-hidden] { color: var(--champagne); }

/* Home: one monumental centered statement. Subpages stay editorial-left. */
.hero--center { align-items: center; }
.hero--center .hero__content { align-items: center; text-align: center; padding-bottom: 132px; }
.hero--center .hero__actions { margin-top: 24px; }
.hero--center .hero__content h1 { font-size: clamp(3.6rem, 8vw, 6.6rem); letter-spacing: -0.015em; line-height: 1.02; }
.hero--center .hero__content .kicker::after { content: ""; width: 34px; height: 1px; background: var(--champagne); }
.hero--center .hero__actions { justify-content: center; }
.hero--center .hero__facts { justify-content: center; }

/* cruise heroes carry their facts strip along the bottom edge */
.hero--facts .hero__content { padding-bottom: 128px; }
.hero--page.hero--facts { min-height: 66vh; min-height: 66svh; }

.hero--page { min-height: 60vh; min-height: 60svh; }
.hero--page .hero__content { padding-bottom: 64px; }


/* ---------- Sections ---------- */

.section { padding: var(--section-y) 0; }
.section--tight { padding: var(--section-y-tight) 0; }
/* the cross-sell strip at the foot of each cruise page needs more air above it
   so it reads as a new offer rather than a continuation of the page's own content */
.section--more { padding-top: calc(var(--section-y) * 1.45); }
.section--silk { background: var(--silk); }
.section--sand { background: var(--sand); }
.section--navy { background: var(--navy); color: var(--mist); }
.section--navy h2, .section--navy h3 { color: var(--pearl); }
.section--navy p { color: var(--mist); }
.section--navy .kicker { color: var(--champagne); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; }

/* ---------- Feature props ---------- */

.prop { text-align: center; padding: 0 10px; }
.prop__icon {
  width: 62px; height: 62px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: var(--sand);
  color: var(--haven);
  display: flex; align-items: center; justify-content: center;
}
.prop__icon svg { width: 30px; height: 30px; }
.prop h3 { margin-bottom: 10px; }
.prop p { color: var(--ink-soft); font-size: 0.99rem; }

/* ---------- Cards ---------- */

.card {
  background: var(--pearl);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.card:hover { transform: translateY(-6px); box-shadow: var(--shadow-soft); }

.card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease); }
.card:hover .card__media img { transform: scale(1.05); }
.card__tag {
  position: absolute;
  top: 14px; left: 14px;
  background: rgba(34, 45, 82, 0.82);
  color: var(--champagne);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
}
.card__body { padding: 26px 26px 30px; display: flex; flex-direction: column; flex: 1; }
.card__body h3 { margin-bottom: 8px; }
.card__meta { font-size: 0.78rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-ink); margin-bottom: 12px; }
.card__body p { color: var(--ink-soft); font-size: 0.98rem; flex: 1; }
.card__link { font-size: 0.8rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--haven); }
.card__link::after { content: " →"; }
.card__link:hover { color: var(--navy); }

/* ---------- Tour card (compact, whole card is the anchor) ---------- */

.tour-card {
  position: relative;
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
  aspect-ratio: 4 / 4.6;
  box-shadow: var(--shadow-card);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.tour-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-soft); }
.tour-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease);
}
.tour-card:hover img { transform: scale(1.06); }
.tour-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(26, 35, 64, 0.08) 30%, rgba(26, 35, 64, 0.42) 62%, rgba(26, 35, 64, 0.86) 100%);
  z-index: 1;
}
.tour-card__tag {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 2;
  background: rgba(26, 35, 64, 0.72);
  color: var(--champagne);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
}
.tour-card__arrow {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(253, 255, 255, 0.5);
  color: var(--pearl);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), background 0.3s var(--ease);
}
.tour-card:hover .tour-card__arrow { opacity: 1; transform: none; background: rgba(210, 182, 138, 0.35); }
.tour-card__body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 22px 22px 20px;
}
.tour-card__meta {
  margin: 0 0 4px;
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--champagne);
}
.tour-card__body h3 {
  margin: 0;
  color: var(--pearl);
  font-size: clamp(1.4rem, 1.8vw, 1.7rem);
  line-height: 1.15;
}
/* The body is bottom-anchored, so opening this track lifts the title by exactly the
   blurb's rendered height and the blurb lands where the title was. Both this and the
   old max-height animate layout every frame — the win is precision, not frame cost:
   the track resolves to the real height instead of a guessed 90px.
   padding-top (not margin) so the gap is clipped with the text when collapsed. */
.tour-card__reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s var(--ease);
}
.tour-card__blurb {
  margin: 0;
  padding-top: 8px;
  min-height: 0;
  overflow: hidden;
  color: rgba(253, 255, 255, 0.85);
  font-size: 0.9rem;
  line-height: 1.5;
  opacity: 0;
  transition: opacity 0.3s var(--ease) 0.05s;
}
.tour-card:hover .tour-card__reveal,
.tour-card:focus-visible .tour-card__reveal { grid-template-rows: 1fr; }
.tour-card:hover .tour-card__blurb,
.tour-card:focus-visible .tour-card__blurb { opacity: 1; }
.tour-card--wide { aspect-ratio: 16 / 8.4; }
/* Event cards that are not links. The photo zoom and the subtext reveal stay —
   they reward attention — but the lift is dropped, since a card that rises to
   meet the pointer promises somewhere to go. */
.tour-card--static { cursor: default; }
.tour-card--static:hover { transform: none; box-shadow: var(--shadow-card); }

/* ---------- Photo duo (main image + overlapping small one) ---------- */

.photo-duo { position: relative; --duo-frame: var(--cream); padding: 0 0 64px 0; }
.photo-duo img:first-child {
  width: 88%;
  margin-left: auto;
  display: block;
  aspect-ratio: 4 / 3.4;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}
.photo-duo img:last-child {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 46%;
  aspect-ratio: 5 / 4;
  object-fit: cover;
  border-radius: var(--radius);
  border: 6px solid var(--duo-frame);
  box-shadow: var(--shadow-soft);
}
.section--navy .photo-duo { --duo-frame: var(--navy); }

/* ---------- Weather chips ---------- */

/* Weather lives inside the chart, like a legend box in its corner */
.wx {
  position: absolute;
  top: 17px;
  left: 17px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 9px;
  padding: 11px 13px 12px;
  border: 1px solid rgba(210, 182, 138, 0.35);
  border-radius: 10px;
  background: rgba(26, 35, 64, 0.55);
  backdrop-filter: blur(2px);
}
/* the eyebrow row: what this is, and where it is measured */
.wx__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin: 0;
}
.wx__place {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(189, 209, 214, 0.72);
}
/* the readings: equal columns split by champagne hairlines. Auto columns,
   not repeat(3) — the wave chip only exists when the marine API answers. */
.wx__grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}
.wx__grid .wx__item + .wx__item {
  border-left: 1px solid rgba(210, 182, 138, 0.22);
  padding-left: 13px;
  margin-left: 13px;
}
.wx__read { display: grid; gap: 1px; min-width: 0; }
.wx__live {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--aqua);
}
.wx__live::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--aqua);
  box-shadow: 0 0 0 0 rgba(135, 184, 188, 0.65);
  animation: wx-pulse 2.4s var(--ease) infinite;
}
@keyframes wx-pulse {
  0% { box-shadow: 0 0 0 0 rgba(135, 184, 188, 0.65); }
  70% { box-shadow: 0 0 0 9px rgba(135, 184, 188, 0); }
  100% { box-shadow: 0 0 0 0 rgba(135, 184, 188, 0); }
}
.wx__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--pearl);
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0.06em;
}
.wx__item svg { width: 16px; height: 16px; color: var(--champagne); flex: none; }
.wx__item b { font-weight: 400; font-size: 0.95rem; line-height: 1.1; }
.wx__item small {
  color: var(--mist);
  font-size: 0.63rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1.2;
}

/* ---------- Route map (signature): interactive nautical chart ---------- */

.route-map { position: relative; }

/* Hosts the frame and the weather strip. On desktop .wx is absolutely positioned
   against this instead of the frame; below 700px it drops out of flow-position and
   sits beneath the chart. */
.route-map__stage { position: relative; }

.route-map__frame {
  position: relative;
  border: 1px solid rgba(210, 182, 138, 0.35);
  border-radius: var(--radius);
  padding: clamp(8px, 1.6vw, 22px);
  background:
    radial-gradient(ellipse 90% 70% at 50% 30%, rgba(90, 125, 152, 0.16), transparent 70%),
    linear-gradient(180deg, #1D2747, var(--navy-deep));
  overflow: hidden;
}
/* the chart svg only — .wx / note icons inside the frame size themselves */
.route-map__frame > svg, .route-map__world > svg { display: block; width: 100%; height: auto; }

/* the chart sits in a pannable "world" layer (moves only on small screens) */
.route-map__world { transform-origin: 0 0; }

/* mobile nudge: fades once the visitor starts exploring */
.route-map__drag {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 4;
  display: none;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(210, 182, 138, 0.4);
  background: rgba(26, 35, 64, 0.72);
  color: var(--mist);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 0.5s var(--ease);
}
.route-map__drag.is-gone { opacity: 0; }

.route-map__hint {
  text-align: center;
  margin: 18px 0 0;
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(189, 209, 214, 0.6);
}

/* hover: floating photos fanning out beside the stop */
.map-pop {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  display: none;
  width: 0;
  height: 0;
}
.map-pop.is-open { display: block; }
.map-pop img {
  position: absolute;
  width: 168px;
  max-width: none; /* the pop anchor is 0×0 — the base img max-width:100% would collapse these */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
  border: 4px solid var(--pearl);
  box-shadow: 0 22px 50px -12px rgba(0, 0, 0, 0.55);
  opacity: 0;
}
.map-pop.is-open img:first-child {
  bottom: 14px;
  left: 16px;
  animation: pop-a 0.45s var(--ease) forwards;
}
.map-pop.is-open img:last-child {
  bottom: 34px;
  left: 120px;
  animation: pop-b 0.5s var(--ease) 0.08s forwards;
}
@keyframes pop-a {
  from { opacity: 0; transform: rotate(-10deg) translateY(18px) scale(0.82); }
  to { opacity: 1; transform: rotate(-6deg) translateY(0) scale(1); }
}
@keyframes pop-b {
  from { opacity: 0; transform: rotate(9deg) translateY(20px) scale(0.82); }
  to { opacity: 1; transform: rotate(5deg) translateY(0) scale(1); }
}

/* click: a pinned note card, floating beside the stop like the hover fan */
.map-note {
  position: absolute;
  z-index: 6;
  width: 314px;
  background: var(--pearl);
  border: 4px solid var(--pearl);
  border-radius: 10px;
  box-shadow: 0 26px 60px -14px rgba(0, 0, 0, 0.6);
  /* grows out of its stop: js/main.js sets transform-origin to where the dot
     sits relative to the card, so the card unfolds from the marker rather
     than appearing beside it */
  animation: note-pop 0.34s var(--ease);
}
@keyframes note-pop {
  from { opacity: 0; transform: scale(0.72); }
  to { opacity: 1; transform: none; }
}
/* the hairline that ties the card back to its dot. --stem-y is the dot's
   height within the card, set alongside the origin; the side comes from
   which way the card was flipped to stay inside the frame. */
.map-note::before {
  content: "";
  position: absolute;
  top: var(--stem-y, 50%);
  width: var(--stem-w, 22px);
  height: 2px;
  background: var(--champagne);
  transform: translateY(-50%);
  pointer-events: none;
}
.map-note[data-stem="left"]::before { right: 100%; }
.map-note[data-stem="right"]::before { left: 100%; }
.map-note[data-stem="none"]::before { display: none; }
/* the author display values below must never beat the hidden attribute */
.map-note[hidden] { display: none; }

.map-note__media { position: relative; margin: 0; }
.map-note img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 6px 6px 0 0; }
.map-note__body { padding: 14px 17px 14px; }

/* gallery paging inside the card */
.map-note__pic {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  background: rgba(26, 35, 64, 0.55);
  color: var(--pearl);
  font-size: 1.1rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.25s var(--ease), background 0.25s var(--ease);
}
.map-note__media:hover .map-note__pic, .map-note__pic:focus-visible { opacity: 1; }
@media (hover: none) { .map-note__pic { opacity: 1; } }
.map-note__pic:hover { background: rgba(210, 182, 138, 0.8); }
.map-note__pic--prev { left: 8px; }
.map-note__pic--next { right: 8px; }
.map-note__dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  display: flex;
  justify-content: center;
  gap: 5px;
  pointer-events: none;
}
.map-note__dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(253, 255, 255, 0.45);
  transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}
.map-note__dots i.is-on { background: var(--champagne); transform: scale(1.2); }

/* sail on to the previous / next stop without leaving the card */
.map-note__steps { display: flex; border-top: 1px solid var(--marble); }
.map-note__step {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 12px;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color 0.2s var(--ease), background 0.2s var(--ease);
}
.map-note__step em { font-style: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Cap-height SVG chevrons. The old ‹ › glyphs centred on their own em box,
   which does not agree with a 0.66rem uppercase label — they sat visibly
   low. A drawn chevron sized to the label aligns by construction. */
.map-note__step svg { width: 7px; height: 11px; flex: none; color: var(--gold-ink); }
.map-note__step--next { justify-content: flex-end; text-align: right; border-left: 1px solid var(--marble); }
/* The card is 10px round with a 4px border, so its inner corner is 6px. A
   square hover fill punched straight through that curve. */
.map-note__step:hover { color: var(--navy); background: var(--sand); }
.map-note__step--prev:hover { border-radius: 0 0 0 6px; }
.map-note__step--next:hover { border-radius: 0 0 6px 0; }
.map-note__meta {
  margin: 0 0 3px;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.map-note__body h3 { margin: 0 0 7px; color: var(--navy); font-size: 1.38rem; }
.map-note__text { margin: 0; color: var(--ink); font-size: 0.9rem; line-height: 1.55; }
/* The stop card is a pearl island inside a navy section: the section's
   light-on-dark text rules (.section--navy p at 0,1,1) beat the card's own
   class colors (0,1,0) and painted its copy mist-on-pearl — near invisible.
   These win on specificity, not luck. */
.section--navy .map-note__meta { color: var(--gold-ink); }
.section--navy .map-note__body h3 { color: var(--navy); }
.section--navy .map-note__text { color: var(--ink); }

.map-note__close {
  position: absolute;
  top: -12px;
  right: -12px;
  /* above the gallery image and its paging arrows, always */
  z-index: 4;
  width: 33px;
  height: 33px;
  border-radius: 50%;
  border: none;
  background: var(--pearl);
  color: var(--ink);
  font-size: 0.85rem;
  cursor: pointer;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
  transition: background 0.25s var(--ease);
}
.map-note__close:hover { background: var(--champagne); color: var(--pearl); }
@media (max-width: 700px) {
  /* A phone gets a bottom sheet across the full width of the chart, not a
     floating card. It used to be pinned 10px off the left with a fixed
     272px width, which left a third of the screen empty beside it. */
  .map-note {
    left: 0 !important;
    right: 0;
    top: auto !important;
    bottom: 0;
    width: auto;
    border-width: 0;
    border-radius: 14px 14px 0 0;
    padding: 13px 15px 0;
    display: grid;
    grid-template-columns: 132px 1fr;
    grid-template-areas: "media body" "steps steps";
    gap: 0 14px;
    box-shadow: 0 -16px 44px -12px rgba(0, 0, 0, 0.55);
    /* a sheet rises from the edge; only the desktop card grows from a dot */
    transform-origin: 50% 100% !important;
    animation: note-rise 0.32s var(--ease);
  }
  /* the dot keeps its pearl ring instead — a stem to a card pinned at the
     bottom edge would cross half the chart */
  .map-note::before { display: none; }
  .map-note__media { grid-area: media; }
  .map-note img { width: 100%; height: 100%; min-height: 112px; aspect-ratio: auto; border-radius: 8px; }
  .map-note__body { grid-area: body; padding: 1px 0 0; }
  .map-note__body h3 { font-size: 1.24rem; margin-bottom: 5px; }
  .map-note__text { font-size: 0.8rem; line-height: 1.5; }
  .map-note__steps { grid-area: steps; margin: 12px -15px 0; }
  .map-note__step { padding: 11px 15px; }
  .map-note__step--prev:hover, .map-note__step--next:hover { border-radius: 0; }
  /* clear of the sheet's rounded top-right corner, still fully on screen */
  .map-note__close { top: -14px; right: 14px; }
  /* the thumbnail is too small for arrows — tap it to page the gallery */
  .map-note__pic { display: none; }
  .map-note__media { cursor: pointer; }
  .map-note__dots { bottom: 5px; gap: 4px; }
  .map-note__dots i { width: 5px; height: 5px; box-shadow: 0 0 3px rgba(26, 35, 64, 0.7); }
}
@keyframes note-rise {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: none; }
}

.route-map .island {
  fill: #2A3560;
  stroke: rgba(210, 182, 138, 0.75);
  stroke-width: 1.6;
  stroke-linejoin: round;
}
.route-map .islet { fill: #2A3560; stroke: rgba(210, 182, 138, 0.55); stroke-width: 1.2; stroke-linejoin: round; }
.route-map .graticule { stroke: rgba(189, 209, 214, 0.07); stroke-width: 1; }
.route-map .sea-label {
  font-family: var(--font-display);
  font-style: italic;
  fill: rgba(189, 209, 214, 0.4);
  letter-spacing: 0.2em;
}
/* island names ride a gentle arc along each island's spine */
.route-map .island-label {
  font-family: var(--font-display);
  font-weight: 600;
  fill: rgba(210, 182, 138, 0.5);
  letter-spacing: 0.5em;
}
.route-map .islet-label {
  font-family: var(--font-display);
  font-style: italic;
  fill: rgba(189, 209, 214, 0.5);
}
.route-map .osm-credit {
  font-family: var(--font-body);
  font-size: 8.5px;
  letter-spacing: 0.08em;
  fill: rgba(189, 209, 214, 0.28);
}
.route-map .compass { stroke: rgba(210, 182, 138, 0.55); fill: rgba(210, 182, 138, 0.55); }
.route-map .wave { stroke: rgba(189, 209, 214, 0.18); stroke-width: 1.4; fill: none; stroke-linecap: round; }

.route-map .route-line {
  fill: none;
  stroke: var(--champagne);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 1 12;
}
/* per-leg reveal strokes: narrow, so a leg being drawn can't uncover a
   crossing leg early (each leg has its own mask) */
.route-map .leg-reveal {
  fill: none;
  stroke: #fff;
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.route-map .geo-ticks text {
  font-family: var(--font-body);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  fill: rgba(189, 209, 214, 0.32);
}

/* opacity-only reveal — a CSS transform here would override the SVG
   transform attribute that positions each waypoint. .is-on is applied by
   main.js exactly when the course line reaches the stop. */
.route-map .wp { opacity: 0; transition: opacity 0.5s var(--ease); }
.route-map .wp.is-on { opacity: 1; }
.route-map .wp { cursor: pointer; outline: none; }
.route-map .wp__hit { fill: transparent; stroke: none; }
.route-map .wp__dot { fill: var(--champagne); transition: fill 0.25s var(--ease); }
.route-map .wp__ring {
  fill: none;
  stroke: rgba(210, 182, 138, 0.55);
  stroke-width: 1.4;
  transform-origin: center;
  transform-box: fill-box;
}
.route-map .wp.is-on .wp__ring { animation: wp-pulse 3.4s var(--ease) 0.4s infinite; }
.route-map .wp.is-active .wp__ring { animation: none; stroke: var(--pearl); opacity: 1; transform: none; }
.route-map .wp.is-active .wp__dot { fill: var(--pearl); }
.route-map .wp.is-active .wp__label { fill: var(--champagne); }
/* keyboard focus: stop the pulse (it fades the ring to nothing for much of
   its cycle) and hold a solid halo, since .wp suppresses the page outline */
.route-map .wp:focus-visible .wp__ring {
  animation: none;
  stroke: var(--pearl);
  stroke-width: 2.4;
  opacity: 1;
  transform: none;
}
.route-map .wp:focus-visible .wp__halo { opacity: 1; }
.route-map .wp__halo {
  fill: none;
  stroke: var(--champagne);
  stroke-width: 1.6;
  stroke-dasharray: 3 4;
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}
@keyframes wp-pulse {
  0% { transform: scale(0.55); opacity: 1; }
  60% { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}
.route-map .wp__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 21px;
  fill: var(--pearl);
  paint-order: stroke;
  stroke: rgba(26, 35, 64, 0.65);
  stroke-width: 4px;
  stroke-linejoin: round;
  transition: fill 0.25s var(--ease);
}
.route-map .wp__meta {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  fill: var(--champagne);
  paint-order: stroke;
  stroke: rgba(26, 35, 64, 0.65);
  stroke-width: 3px;
}
.route-map .island-label { font-size: 17px; }
.route-map .islet-label { font-size: 13px; }
.route-map .sea-label { font-size: 22px; }
.route-map .compass text {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.2em;
  fill: rgba(210, 182, 138, 0.8);
  stroke: none;
}

/* ---------- Booking calendar ---------- */

/* One card, not two: calendar and summary share a single shell, and the
   calendar is capped so day cells stop reading as coasters. */
.book__layout {
  max-width: 1020px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.06fr 0.94fr;
  align-items: stretch;
  background: var(--pearl);
  border: 1px solid var(--marble);
  border-radius: 16px;
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.book__left { display: flex; flex-direction: column; }
.cal { flex: 1; display: block; padding: 28px 32px 24px; }
/* the picked day's forecast — it fills what used to be dead white space */
.book__wx {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 32px 28px;
  padding: 14px 18px;
  background: var(--sand);
  border-radius: 11px;
  color: var(--ink-soft);
}
.book__wx-icon { line-height: 0; flex: none; color: var(--gold-ink); }
.book__wx-icon svg { width: 21px; height: 21px; }
.book__wx p { margin: 0; font-size: 0.86rem; line-height: 1.45; }
.cal__month { background: none; border: none; border-radius: 0; padding: 0; box-shadow: none; }
.cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; min-height: 34px; }
.cal__title { font-family: var(--font-display); font-size: 1.2rem; font-weight: 600; color: var(--navy); margin: 0 auto; }
.cal__btn {
  width: 34px; height: 34px;
  border: 1px solid var(--marble);
  border-radius: 50%;
  background: none;
  color: var(--navy);
  font-size: 1.1rem;
  cursor: pointer;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.cal__btn:hover:not(:disabled) { background: var(--sand); border-color: var(--champagne); }
.cal__btn:disabled { opacity: 0.35; cursor: default; }
.cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px 3px; }
.cal__dow {
  text-align: center;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-ink);
  padding: 6px 0;
}
.cal__day {
  height: 38px;
  border: none;
  border-radius: 9px;
  background: none;
  font-family: var(--font-body);
  font-size: 0.84rem;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.cal__day:hover:not(:disabled) { background: var(--sand); }
.cal__day:disabled { color: var(--marble); cursor: default; }
.cal__day.is-today { box-shadow: inset 0 0 0 1px var(--mist); }
.cal__day.is-selected { background: var(--navy); color: var(--pearl); box-shadow: 0 0 0 3px var(--champagne); }

.book__panel {
  background: var(--navy);
  padding: 30px 34px;
  color: var(--mist);
}
.book__panel h3 { color: var(--pearl); margin-bottom: 20px; }
.book__row { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid rgba(210, 182, 138, 0.25); }
.book__row dt { font-size: 0.7rem; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: var(--champagne); }
.book__row dd { margin: 0; font-family: var(--font-display); font-size: 1.15rem; font-weight: 600; color: var(--pearl); text-align: right; }
.book__select {
  background: rgba(253, 255, 255, 0.06);
  border: 1px solid rgba(210, 182, 138, 0.4);
  border-radius: 8px;
  color: var(--pearl);
  font-family: var(--font-body);
  font-size: 0.92rem;
  padding: 9px 12px;
  cursor: pointer;
}
.book__select option { color: var(--ink); background: var(--pearl); }
.book__step {
  width: 32px; height: 32px;
  border: 1px solid rgba(210, 182, 138, 0.4);
  border-radius: 50%;
  background: none;
  color: var(--pearl);
  font-size: 1rem;
  cursor: pointer;
  transition: background 0.2s var(--ease);
}
.book__step:hover { background: rgba(210, 182, 138, 0.25); }
.book__guests { display: inline-flex; align-items: center; gap: 14px; }
.book__hint { font-size: 0.9rem; color: var(--mist); margin: 18px 0; min-height: 2.6em; }
.book__panel .btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.book__panel .btn { width: 100%; text-align: center; }
.book__note { font-size: 0.78rem; color: rgba(189, 209, 214, 0.65); margin-top: 14px; }
.book__note a { color: var(--champagne); }
.book__note a:hover { color: var(--pearl); }

/* Two buttons share the row deliberately. `.book__panel .btn` still matches both
   with width:100%, so without `flex: 1 1 0` they would only fit by flex-shrink
   accident and break the moment anyone sets flex-shrink: 0 or flex-wrap. */
.book__actions { display: flex; gap: 12px; }
.book__actions .btn { flex: 1 1 0; width: auto; }
@media (max-width: 560px) { .book__actions { flex-direction: column; } }

/* itinerary timeline (daily cruise) */
.itinerary { list-style: none; margin: 0; padding: 0; position: relative; }
.itinerary::before {
  content: "";
  position: absolute;
  left: 19px; top: 14px; bottom: 14px;
  border-left: 2px dashed var(--champagne);
}
.itinerary li { position: relative; padding: 0 0 42px 64px; }
.itinerary li:last-child { padding-bottom: 0; }
.itinerary__dot {
  position: absolute;
  left: 8px; top: 4px;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--cream);
  border: 2px solid var(--champagne);
  display: flex; align-items: center; justify-content: center;
}
.itinerary__dot::after { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--navy); }
.itinerary__time {
  display: inline-block;
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--champagne-deep);
  margin-bottom: 6px;
}
.itinerary h3 { margin-bottom: 6px; }
.itinerary p { color: var(--ink-soft); max-width: 640px; margin-bottom: 0; }

/* ---------- Amenities ---------- */

.amenities { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 18px 34px; }
.amenities li { display: flex; gap: 14px; align-items: flex-start; }
.amenities li svg { flex: none; width: 22px; height: 22px; color: var(--aqua); margin-top: 5px; }
.amenities li span { color: var(--ink-soft); }
.section--navy .amenities li span { color: var(--mist); }

/* ---------- Guest reviews (About) ---------- */
/* One featured pull-quote carries the section; the two longer reviews sit
   quietly beneath it, and a Tripadvisor owl closes with the link out. */
.stars { display: inline-flex; gap: 5px; color: var(--champagne-deep); line-height: 0; }
.stars svg { width: 18px; height: 18px; }

.reviews__featured { max-width: 860px; margin: 0 auto 58px; text-align: center; }
.reviews__featured .stars svg { width: 21px; height: 21px; }
.reviews__quote {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  color: var(--ink);
  font-size: clamp(1.5rem, 1rem + 2.1vw, 2.1rem);
  line-height: 1.34;
  margin: 22px 0 20px;
  text-wrap: balance;
}
.reviews__cite,
.review-card__cite {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

.reviews__grid { align-items: stretch; }
.review-card {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: var(--pearl);
  border-top: 2px solid var(--champagne);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 34px 34px 30px;
}
.review-card .stars svg { width: 17px; height: 17px; }
.review-card__quote {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.14rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 15px 0 22px;
}
.review-card__cite { margin-top: auto; }

.reviews__more {
  margin-top: 62px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
}
.reviews__owl { color: var(--navy); line-height: 0; }
.reviews__owl svg { width: 48px; height: 48px; }

@media (max-width: 640px) {
  .review-card { padding: 26px 22px 24px; }
  .reviews__featured { margin-bottom: 44px; }
}

/* ---------- Facts strip (cruise pages) ---------- */
/* ---------- Content photo (reserves space to avoid layout shift) ---------- */

.ph {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}

/* ---------- Media band ---------- */

.band { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.band img { border-radius: var(--radius); width: 100%; height: 300px; object-fit: cover; box-shadow: var(--shadow-card); }

/* ---------- Mosaic (home gallery teaser) ---------- */

.mosaic { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 210px; gap: 16px; }
.mosaic a { position: relative; border-radius: var(--radius); overflow: hidden; display: block; }
.mosaic img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease); }
.mosaic a:hover img { transform: scale(1.06); }
.mosaic a:nth-child(1) { grid-row: span 2; }
.mosaic a:nth-child(4) { grid-column: span 2; }
.mosaic a:nth-child(6) { grid-column: span 2; }

/* ---------- Quote ---------- */

.quote {
  max-width: 780px;
  margin: 0 auto;
  text-align: center;
}
.quote blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  line-height: 1.4;
  color: var(--navy);
}
.quote figcaption { margin-top: 18px; font-size: 0.78rem; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: var(--champagne-deep); }

/* ---------- CTA banner ---------- */

/* ---------- Footer ---------- */

.site-footer { background: var(--navy-deep); color: var(--mist); padding: 90px 0 36px; }

.site-footer__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 24px;
  padding-bottom: 54px;
}
.site-footer p.site-footer__line {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(2.2rem, 4.5vw, 3.6rem);
  line-height: 1.1;
  color: var(--pearl);
}
.site-footer__line strong { color: var(--champagne); font-weight: 600; }

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.35fr 1fr 1fr 1.1fr;
  gap: 44px;
  padding: 54px 0 46px;
  border-top: 1px dashed rgba(210, 182, 138, 0.4);
  border-bottom: 1px solid rgba(210, 182, 138, 0.18);
}
.site-footer .brand__name { color: var(--pearl); }
.site-footer .brand__tag { color: var(--champagne); }
.site-footer p { color: var(--mist); font-size: 0.95rem; }
.site-footer h4 { color: var(--pearl); font-family: var(--font-body); font-size: 0.78rem; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase; margin-bottom: 16px; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.site-footer a { color: var(--mist); font-size: 0.95rem; }
.site-footer a:hover { color: var(--champagne); }
.site-footer__base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 26px; padding-top: 26px; font-size: 0.82rem; letter-spacing: 0.08em; color: rgba(189, 209, 214, 0.75); }
.site-footer__base a { color: var(--champagne); }
/* the chart's live-conditions chips, retold quietly under the footer blurb */
/* the same glass card the chart wears, so the two readings of the same data
   look like one component in two places. Only the positioning differs: on
   the chart it is pinned into a corner, here it sits in the footer column. */
.site-footer .wx {
  position: static;
  margin: 18px 0 0;
  /* Restated, not inherited: the ≤700px block turns .wx into a full-bleed
     band with square corners and no side borders so it reads as the chart's
     caption. That is a bare `.wx`, so it would reach this card too — these
     hold the card shape at every width. */
  padding: 11px 13px 12px;
  border-width: 1px;
  border-radius: 10px;
  /* the chart's tint is navy-on-navy against this footer — lift it off the
     background with a light film instead of a darker one */
  background: rgba(253, 255, 255, 0.045);
}
.site-footer__base a:hover { color: var(--pearl); }
/* buttons keep their own ink — don't let footer link colors wash them out */
.site-footer a.btn { color: var(--navy); }
.site-footer a.btn:hover { color: var(--navy); }

/* ---------- Gallery ---------- */

.gallery-grid { columns: 3 320px; column-gap: 18px; }
.gallery-grid figure { margin: 0 0 18px; break-inside: avoid; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-card); }
.gallery-grid img { width: 100%; cursor: zoom-in; transition: transform 0.5s var(--ease); }
.gallery-grid figure:hover img { transform: scale(1.04); }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(26, 35, 64, 0.94);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 4vh 4vw;
}
.lightbox.is-open { display: flex; }
.lightbox img { max-width: 92vw; max-height: 84vh; border-radius: 6px; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5); }
.lightbox__caption { position: absolute; bottom: 3vh; left: 50%; transform: translateX(-50%); color: var(--mist); font-size: 0.85rem; letter-spacing: 0.12em; text-transform: uppercase; }
.lightbox button {
  position: absolute;
  background: rgba(253, 255, 255, 0.08);
  border: 1px solid rgba(253, 255, 255, 0.3);
  color: var(--pearl);
  width: 48px; height: 48px;
  border-radius: 50%;
  font-size: 1.15rem;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.lightbox button:hover { background: rgba(210, 182, 138, 0.35); }
.lightbox__close { top: 3vh; right: 3vw; }
.lightbox__prev { left: 3vw; top: 50%; transform: translateY(-50%); }
.lightbox__next { right: 3vw; top: 50%; transform: translateY(-50%); }

/* ---------- Reveal ---------- */

.reveal { opacity: 0; transform: translateY(26px); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); }
.reveal--visible { opacity: 1; transform: none; }

/* ---------- Contact details, socials, map embed ---------- */

.contact-lines { margin: 26px 0 0; display: flex; flex-direction: column; gap: 12px; }
.contact-lines div { display: flex; align-items: baseline; gap: 18px; border-bottom: 1px solid var(--marble); padding-bottom: 12px; }
.contact-lines dt {
  flex: none;
  width: 64px;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
.contact-lines dd { margin: 0; font-family: var(--font-display); font-size: 1.25rem; font-weight: 600; color: var(--navy); }
.contact-lines dd a { color: var(--navy); }
.contact-lines dd a:hover { color: var(--haven); }

/* ---------- FAQ (contact page) ----------
   Numbered open text. Round 11's facts-card cleanup accidentally swallowed the
   previous FAQ rules with it, so the section rendered bare — which is what
   "the FAQ looks awful" was. These are its real clothes. */
.faq-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 44px 64px; counter-reset: faq; }
.faq-item {
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 4px 18px;
  border-top: 1px solid var(--marble);
  padding-top: 26px;
}
.faq-item::before {
  counter-increment: faq;
  content: "0" counter(faq);
  grid-row: 1 / 3;
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 600;
  line-height: 1;
  color: var(--champagne);
}
.faq-item h3 { font-size: 1.45rem; margin: 0; }
.faq-item p { margin: 0; color: var(--ink-soft); max-width: 46ch; }
@media (max-width: 700px) {
  .faq-grid { grid-template-columns: 1fr; gap: 28px; }
  .faq-item { grid-template-columns: 40px 1fr; padding-top: 22px; }
  .faq-item::before { font-size: 1.7rem; }
}

/* ---------- Last-minute booking ---------- */
/* The wave menu washes over the page with some translucency mid-animation, so
   hide the button explicitly rather than relying on stacking order. The
   lightbox needs no rule: it is inset:0 at z-index 100 and covers this. */
/* ---------- Last-minute booking ---------- */

/* A fixed circular dial with a caption that introduces itself once on load,
   reappears on hover, and otherwise stays out of the way. The whole thing
   steps aside when the footer's credit line is on screen. */
.fab {
  position: fixed;
  right: clamp(16px, 3vw, 30px);
  bottom: clamp(16px, 3vw, 30px);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 12px;
  transition: opacity 0.3s var(--ease), visibility 0s;
}
.fab__btn {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--champagne);
  color: var(--navy);
  box-shadow: 0 14px 32px -10px rgba(26, 35, 64, 0.55);
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.fab__btn svg { width: 22px; height: 22px; }
.fab__btn:hover { background: var(--champagne-deep); transform: translateY(-2px); }
.fab__hint {
  position: relative;
  max-width: 200px;
  padding: 10px 15px;
  background: var(--navy);
  color: var(--pearl);
  font-size: 0.78rem;
  line-height: 1.4;
  border-radius: 11px;
  box-shadow: 0 16px 36px -16px rgba(26, 35, 64, 0.6);
  opacity: 0;
  visibility: hidden;
  transform: translateX(8px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), visibility 0s 0.35s;
}
.fab__hint::after {
  content: "";
  position: absolute;
  right: -5px;
  top: 50%;
  width: 10px;
  height: 10px;
  background: var(--navy);
  transform: translateY(-50%) rotate(45deg);
}
.fab.hint-on .fab__hint,
.fab:hover .fab__hint,
.fab:focus-within .fab__hint {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), visibility 0s;
}
body.nav-open .fab, .fab.is-docked { opacity: 0; visibility: hidden; transition: opacity 0.25s var(--ease), visibility 0s 0.25s; }

.socials { display: flex; gap: 10px; margin-top: 22px; }
/* "Find us here" — labels the social row on the contact page and in every footer.
   Qualified with `p` on purpose: `.site-footer p` (0,1,1) sets BOTH color and
   font-size, so a bare `.socials__label` (0,1,0) loses to it and the nine footer
   labels render mist grey at body size. `p.socials__label` ties at (0,1,1) and
   wins on order, being ~70 lines further down the sheet.
   margin-bottom MUST stay 0: as a <p> this element would otherwise inherit the
   global paragraph bottom margin, which collapses against and beats the 10px below. */
p.socials__label {
  margin: 22px 0 0;
  /* Light-context default: champagne on cream is only 1.82:1, unreadable at this
     size. champagne-deep is the house convention for small-caps labels on light
     backgrounds (.kicker, .card__meta, .brand__tag) at 2.54:1. The footer
     override below restores champagne, which is 6.9:1 on navy. */
  color: var(--gold-ink);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.socials__label + .socials { margin-top: 10px; }
/* On the navy footer, champagne reads at 6.9:1 — use the brighter tone there. */
.site-footer p.socials__label { color: var(--champagne); }
.socials a {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--marble);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease), transform 0.25s var(--ease);
}
.socials a:hover { border-color: var(--champagne); color: var(--navy); transform: translateY(-2px); }
.socials svg { width: 20px; height: 20px; }
.site-footer .socials a { border-color: rgba(210, 182, 138, 0.35); color: var(--mist); }
.site-footer .socials a:hover { border-color: var(--champagne); color: var(--champagne); }

.map-embed {
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  border: 1px solid var(--marble);
}
.map-embed iframe { display: block; width: 100%; height: 400px; border: 0; }

/* ---------- Draft banner (internal preview page) ---------- */

.draft-banner {
  position: sticky;
  top: 0;
  z-index: 200;
  background: #8C2F2F;
  color: #fff;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 12px 16px;
}

/* ---------- Responsive ---------- */

@media (max-width: 1440px) {
  .nav ul { gap: 0; }
  .nav__link { padding: 10px 9px; font-size: 0.78rem; letter-spacing: 0.1em; }
  .nav__cta { margin-left: 8px; }
  .nav__cta .btn { padding: 11px 20px; }
  .brand__name { font-size: 1.3rem; }
}

@media (max-width: 1080px) {
  .book__layout { grid-template-columns: 1fr; }
  .book__panel { position: static; }
}


@media (max-width: 700px) {
  /* kickers: the leading dash indents the text 46px past the heading
     beneath it and reads as misalignment on a phone — drop it for
     left-aligned kickers, keep short symmetric wings on centered ones */
  .kicker { gap: 9px; }
  .kicker::before { display: none; }
  .section-head--center .kicker::before,
  .hero--center .hero__content .kicker::before { display: block; width: 18px; }
  .section-head--center .kicker::after,
  .hero--center .hero__content .kicker::after { width: 18px; }

  /* the chart goes full-bleed and behaves like a real map: the world
     layer is drawn wider than the phone and pans/pinches inside the
     frame, so nothing is cropped away — it's all there to explore */
  .route-map__frame {
    margin: 0 -24px;
    border-radius: 0;
    border-left: none;
    border-right: none;
    padding: 0;
    height: min(122vw, 500px);
    /* pan-y, not none: a vertical swipe still scrolls the page, so the
       chart can't trap the reader on more than half the screen */
    touch-action: pan-y;
    cursor: grab;
  }
  .route-map__world {
    position: absolute;
    top: 0;
    left: 0;
    width: 235vw;
    will-change: transform;
  }
  .route-map__world svg { width: 100%; height: auto; }
  .route-map__drag { display: block; }
  .route-map__hint { font-size: 0.66rem; }

  /* Drawn at near-desktop density, so labels stay as they are. The hit
     radius must stay under half the 33-unit gap between the closest pair
     of stops (Panormos/Kastani) or the nearer marker becomes untappable;
     pinch-zoom is what opens up the tight cluster. */
  .route-map .wp__hit { r: 16; }
  /* NO .map-note width here. This block sits AFTER the ≤700px one, so any
     width set at this breakpoint wins on source order and overrode the
     phone's full-bleed sheet — that is what made the card half-width. */

  /* Weather goes below the chart, out of the way of a pannable map — and
     full-bleed like the chart above it. As a bordered box it read as a card
     floating on the navy section rather than the chart's own caption. */
  .wx {
    position: static;
    top: auto; left: auto; right: auto;
    margin: 0 -24px;
    gap: 8px;
    padding: 12px 24px 13px;
    border-width: 1px 0;
    border-radius: 0;
    background: rgba(26, 35, 64, 0.4);
  }
  .wx__grid .wx__item + .wx__item { padding-left: 11px; margin-left: 11px; }
  .wx__item { font-size: 0.78rem; gap: 7px; }
  .wx__item svg { width: 15px; height: 15px; }
  .wx__item b { font-size: 0.9rem; }
  .wx__item small { font-size: 0.58rem; letter-spacing: 0.1em; }

  .site-footer__cta { justify-content: center; text-align: center; }

  /* ---- the last-minute dial stretches into a pill over the hero ----
  /* hero must truly fit one phone screen */
  .hero__content { padding: 88px var(--gutter) 92px; }
  .hero__content h1 { font-size: clamp(2.6rem, 11.5vw, 3.35rem); }
  .hero--center .hero__content { padding-bottom: 132px; }
  .hero--center .hero__content h1 { font-size: clamp(2.9rem, 13.5vw, 3.9rem); }
  .hero--facts .hero__content { padding-bottom: 116px; }
  .cal { padding: 20px 16px 18px; }
  .book__wx { margin: 0 16px 20px; }
  .book__panel { padding: 26px 20px; }
  .cal__day { height: 40px; }
  .hero__lead { font-size: 0.95rem; }
  .hero__actions { margin-top: 20px; gap: 10px; }
  .hero__actions .btn { padding: 11px 22px; font-size: 0.74rem; }
  .hero__facts {
    bottom: 24px;
    white-space: normal;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 6px 12px;
    font-size: 0.6rem;
    letter-spacing: 0.18em;
  }
}

/* touch devices: content that appears on hover is simply visible */
@media (hover: none) {
  .tour-card__reveal { grid-template-rows: 1fr; }
  .tour-card__blurb { opacity: 1; }
  .tour-card__arrow { opacity: 1; transform: none; }
}

@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: 1fr 1fr; }
  .band { grid-template-columns: 1fr 1fr; }
  .band img:last-child { grid-column: span 2; height: 340px; }
}

@media (max-width: 860px) {
  /* ---- Full-screen menu, revealed by a wave rolling from the toggle corner:
     a sea-glass crest sweeps in first, the navy panel floods in just behind
     it; closing pulls the navy back so the crest glints once more on the
     way out. ---- */
  .nav {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: block;
    visibility: hidden;
    pointer-events: none;
    /* Must outlast the slowest exit: the sheet leaves at 0.16s + 0.6s = 0.76s.
       Cutting visibility before that beheads the close animation. */
    transition: visibility 0s 0.8s;
  }
  body.nav-open .nav { visibility: visible; pointer-events: auto; transition: visibility 0s; }

  /* Each layer is a full-height sheet with a wavy leading edge that hangs
     off its left side, so the menu doesn't slide in — it washes in. The
     pale crest runs ahead; the navy body follows and settles. */
  .nav__crest, .nav__mid, .nav__sheet {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: -2px;
    /* The wave hangs up to max(26vw, 96px) off each sheet's LEFT edge, so
       102% alone leaves a strip of wave poking into the viewport whenever the
       nav is visible — the flash at the right edge on resize, and the wave
       that "vanished" at the end of the close animation (it had never left;
       the delayed visibility flip was cutting it off mid-screen). Park far
       enough that the wave clears too. */
    transform: translateX(calc(102% + max(26vw, 96px)));
  }
  /* Each sheet's gradient runs straight down, and its wave SVG carries the
     identical ramp (built in js/main.js). Vertical is the whole point: a
     diagonal ramp cannot be matched by a wave whose left edge moves, so the
     join showed as a hard vertical seam — the "line" between the layers.
     Each layer's stops start where the layer in front ends, so the three
     crests read as one body of water deepening toward the navy. */
  .nav__crest {
    z-index: 1;
    background: linear-gradient(to bottom, #C9DDE0, #93C2C6 50%, #63A0A9);
    transition: transform 0.62s cubic-bezier(0.4, 0.02, 0.2, 1) 0.02s;
  }
  .nav__mid {
    z-index: 2;
    background: linear-gradient(to bottom, #63A0A9, #3E6B77 50%, #2B4E5F);
    transition: transform 0.61s cubic-bezier(0.4, 0.02, 0.2, 1) 0.1s;
  }
  .nav__sheet {
    z-index: 3;
    background:
      radial-gradient(ellipse 130% 70% at 88% -8%, rgba(90, 125, 152, 0.32), transparent 62%),
      linear-gradient(to bottom, #1D2747, var(--navy-deep));
    transition: transform 0.6s cubic-bezier(0.4, 0.02, 0.2, 1) 0.18s;
  }
  body.nav-open .nav__crest { transform: none; transition: transform 0.66s cubic-bezier(0.22, 0.68, 0.24, 1) 0s; }
  body.nav-open .nav__mid { transform: none; transition: transform 0.68s cubic-bezier(0.22, 0.68, 0.24, 1) 0.1s; }
  body.nav-open .nav__sheet { transform: none; transition: transform 0.7s cubic-bezier(0.22, 0.68, 0.24, 1) 0.2s; }

  /* the swell itself: a curved edge riding just ahead of each sheet */
  .nav__wave {
    position: absolute;
    /* Flush 0/100%, not -2%/104%: the wave's gradient is in objectBoundingBox
       units, so its ramp only lines up with the sheet's when the two boxes
       span the same extent. Overhang here reintroduces the seam. */
    top: 0;
    height: 100%;
    /* tucked 3px UNDER its sheet, not abutting it — at exactly 100% the
       antialiased seam between wave and sheet showed the pale crest through
       as a hairline once the panel settled */
    right: calc(100% - 3px);
    width: 26vw;
    min-width: 96px;
    /* grow from the tucked edge, so the 3px overlap never opens up */
    transform-origin: 100% 50%;
  }
  /* The swell breathes sideways only. The old keyframe also bobbed on Y,
     which slid the wave's gradient out of register with its sheet's and put
     the colour seam back — scaleX from the tucked edge keeps every row of
     pixels at the same height as the body it joins. */
  body.nav-open .nav__wave { animation: wave-swell 4.5s ease-in-out 0.7s infinite alternate; }
  /* the three crests drift against each other instead of moving in lockstep */
  body.nav-open .nav__mid .nav__wave { animation-duration: 5.2s; animation-delay: 0.85s; }
  body.nav-open .nav__sheet .nav__wave { animation-duration: 6.1s; animation-delay: 1s; }
  @keyframes wave-swell {
    from { transform: scaleX(1); }
    to { transform: scaleX(1.09); }
  }

  /* the page must not scroll behind the open menu */
  html.nav-lock, html.nav-lock body { overflow: hidden; }

  /* Brand and toggle keep watch above the flood. These must out-specify
     .site-header.is-scrolled's dark text (0,3,0) — the menu covers the
     header, so its own solid background is never what you see. */
  body.nav-open .site-header .brand { position: relative; z-index: 80; color: var(--pearl); }
  body.nav-open .site-header .brand__name { color: var(--pearl); }
  body.nav-open .site-header .brand__tag { color: var(--champagne); }
  body.nav-open .site-header .nav-toggle { color: var(--pearl); }
  /* the header must never become a containing block for the fixed menu */
  body.nav-open .site-header { transform: none; }

  /* panel content: scrolls if it must, but never shows a scrollbar.
     z-index must stay above the deepest wave layer (.nav__sheet is 3). */
  .nav ul {
    position: relative;
    z-index: 4;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: max(92px, 12svh) clamp(26px, 7vw, 44px) max(16px, env(safe-area-inset-bottom, 0px) + 14px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
  }
  .nav ul::-webkit-scrollbar { display: none; }

  /* items surface once the wave has passed */
  .nav li { opacity: 0; transform: translateY(20px); transition: opacity 0.4s var(--ease), transform 0.4s var(--ease); }
  body.nav-open .nav li { opacity: 1; transform: none; }
  body.nav-open .nav li:nth-child(1) { transition-delay: 0.32s; }
  body.nav-open .nav li:nth-child(2) { transition-delay: 0.37s; }
  body.nav-open .nav li:nth-child(3) { transition-delay: 0.42s; }
  body.nav-open .nav li:nth-child(4) { transition-delay: 0.47s; }
  body.nav-open .nav li:nth-child(5) { transition-delay: 0.52s; }
  body.nav-open .nav li:nth-child(6) { transition-delay: 0.57s; }
  body.nav-open .nav li:nth-child(7) { transition-delay: 0.62s; }
  body.nav-open .nav li:nth-child(8) { transition-delay: 0.67s; }

  /* links: display serif over the navy, champagne for the current page */
  .nav__link {
    display: block;
    padding: clamp(9px, 1.6svh, 15px) 4px;
    font-family: var(--font-display);
    font-size: clamp(1.4rem, 3.2svh, 1.85rem);
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: none;
    border-bottom: 1px solid rgba(210, 182, 138, 0.16);
  }
  .site-header .nav .nav__link { color: var(--pearl); }
  .site-header .nav .nav__link:hover { color: var(--champagne); }
  .site-header .nav .nav__link[aria-current="page"],
  .site-header .nav .nav__link[data-section="current"] { color: var(--champagne); }
  .nav .nav__link::after { display: none; }

  /* submenu groups collapse; the chevron toggles them (one at a time) */
  .dropdown { display: grid; grid-template-columns: 1fr auto; align-items: center; border-bottom: 1px solid rgba(210, 182, 138, 0.16); }
  .dropdown .nav__link { border-bottom: none; }
  .dropdown__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    background: none;
    border: none;
    color: var(--champagne);
    cursor: pointer;
  }
  .dropdown__toggle svg { width: 15px; height: 9px; transition: transform 0.35s var(--ease); }
  .dropdown.is-open .dropdown__toggle svg { transform: rotate(180deg); }
  /* Collapses on max-height, measured by JS into --submenu-h (see main.js).
     A HARD-CODED max-height was the original bug: it has to exceed the
     content, so closing spent its first frames travelling from 240px down
     to the real 171px with nothing moving, then dumped the rest — a snap.
     grid-template-rows: 0fr/1fr fixes that but only interpolates on newer
     engines, and silently snaps on the rest. The measured value animates
     the true height everywhere, which is what this needs to be. */
  .dropdown__menu {
    grid-column: 1 / -1;
    position: static;
    min-width: 0;
    border: none;
    box-shadow: none;
    background: transparent;
    border-radius: 0;
    padding: 0;
    transform: none;
    opacity: 1;
    max-height: 0;
    overflow: hidden;
    /* collapsed means gone: visibility keeps the links out of the tab order
       and the accessibility tree while the group is shut */
    visibility: hidden;
    transition: max-height 0.4s var(--ease), visibility 0s 0.4s;
  }
  .dropdown.is-open .dropdown__menu {
    max-height: var(--submenu-h, 400px);
    visibility: visible;
    transition: max-height 0.4s var(--ease), visibility 0s;
  }
  .dropdown__menu::before { display: none; }
  /* The base .container centres itself with `margin: 0 auto` inside a
     max-width — inherited here it pushed the sub-links into the middle of
     the panel. They belong on the same left edge as the nav links above. */
  .dropdown__menu .container {
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0 0 6px 16px;
    opacity: 0;
    transition: opacity 0.26s var(--ease);
  }
  .dropdown.is-open .dropdown__menu .container { opacity: 1; transition: opacity 0.3s var(--ease) 0.08s; }
  .dropdown__head { display: none; }
  .dropdown__cards { display: block; }
  .dd-card { width: auto; display: block; padding: 7px 4px; }
  .dd-card img, .dd-card__meta { display: none; }
  .dd-card__name { margin: 0; font-size: 1rem; font-weight: 400; color: var(--mist); }
  .dropdown__menu a {
    padding: 7px 4px;
    font-size: 0.78rem;
    font-weight: 400;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--mist);
  }
  .dropdown__menu a::before { left: 0; background: var(--champagne); }
  .dropdown__menu a:hover { background: none; color: var(--champagne); padding-left: 20px; }

  .nav ul { flex-direction: column; }
  .nav__cta { margin: max(16px, 2.4svh) 0 0; text-align: center; border-bottom: none; }
  .nav__cta .btn { display: block; }

  /* The panel foot: last-minute on the left, house line over the socials on
     the right. Three children in one row gave each about 90px of a 335px
     line and both numbers wrapped onto three lines apiece — hence nowrap on
     every number here. Bottom-aligned so the left block's baseline settles
     onto the socials row. */
  .nav__foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 10px 16px;
    margin-top: auto;
    padding-top: max(15px, 2svh);
    border-top: 1px solid rgba(210, 182, 138, 0.18);
  }
  .nav__foot-last {
    display: grid;
    gap: 3px;
    margin: 0;
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--champagne);
  }
  .nav__foot-last a {
    color: var(--pearl);
    font-size: 1.02rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: none;
    white-space: nowrap;
  }
  .nav__foot-last a:hover { color: var(--champagne); }
  .nav__foot-contact { display: grid; justify-items: end; gap: 9px; }
  .nav__foot-tel {
    font-size: 0.8rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    color: var(--mist);
    white-space: nowrap;
  }
  .nav__foot-tel:hover { color: var(--champagne); }
  .nav__foot .socials { margin: 0; }
  .nav__foot .socials a { width: 38px; height: 38px; border-color: rgba(210, 182, 138, 0.35); color: var(--mist); }
  .nav__foot .socials a:hover { border-color: var(--champagne); color: var(--champagne); }

  .nav-toggle { display: flex; position: relative; z-index: 80; margin-left: auto; }

  /* ---- page layout stacks at this width (not only on short screens) ---- */
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .grid-2 { gap: 30px; }
  .mosaic { grid-template-columns: 1fr 1fr; grid-auto-rows: 180px; }
  .mosaic a:nth-child(4) { grid-column: span 1; }
  .amenities { grid-template-columns: 1fr; }
  .hero { min-height: 100vh; min-height: 100svh; }
  .hero--page { min-height: 56vh; min-height: 56svh; }
  .site-footer__grid { grid-template-columns: 1fr; gap: 30px; }
}

/* Short screens (or a phone in landscape): tighten the menu's rhythm so an
   open submenu still leaves the Book Now button and the foot on screen.
   Menu-only — page layout rules belong in the width query above. */
@media (max-width: 860px) and (max-height: 720px) {
  .nav ul { padding-top: max(74px, 11svh); padding-bottom: max(14px, env(safe-area-inset-bottom, 0px) + 12px); }
  .nav__link { padding: clamp(6px, 1.1svh, 12px) 4px; font-size: clamp(1.15rem, 2.7svh, 1.5rem); }
  .dropdown__toggle { height: 38px; }
  .dropdown__menu a { padding: 6px 4px; font-size: 0.74rem; }
  .nav__cta { margin-top: max(12px, 2svh); }
  .nav__cta .btn { padding: 11px 24px; }
  .nav__foot { padding-top: max(12px, 2svh); }
  .nav__foot .socials a { width: 34px; height: 34px; }
  .nav__foot .socials svg { width: 17px; height: 17px; }
}

/* Landscape phones and the smallest handsets: navigation earns the space,
   so the contact foot steps aside and the type tightens again. */
@media (max-width: 860px) and (max-height: 600px) {
  .nav ul { padding-top: max(62px, 9svh); }
  .nav__link { padding: clamp(5px, 0.9svh, 10px) 4px; font-size: clamp(1rem, 2.4svh, 1.3rem); }
  .dropdown__toggle { height: 32px; }
  .nav__foot { display: none; }
}

@media (max-width: 520px) {
  .grid-4 { grid-template-columns: 1fr; }
  .band { grid-template-columns: 1fr; }
  .band img, .band img:last-child { grid-column: span 1; height: 240px; }
  .strip__route .leg { width: 34px; }
  .hero__content { padding: 90px var(--gutter) 60px; }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero__media img { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .card, .card__media img, .mosaic img { transition: none; }
  .tour-card, .tour-card img, .tour-card__reveal, .tour-card__blurb, .tour-card__arrow { transition: none; }
  .route-map .leg-reveal { stroke-dashoffset: 0; }
  .route-map .wp { opacity: 1; transition: none; }
  .route-map .wp.is-on .wp__ring { animation: none; }
  .wx__live::before { animation: none; }
  /* the call caption appears in place rather than sliding */
  .fab__hint { transition: opacity 0.01s; transform: none; }
  .map-pop.is-open img, .map-note { animation: none; opacity: 1; }
  /* the wave menu: layers arrive instantly, and the swell stops swelling */
  .nav__crest, .nav__mid, .nav__sheet, .nav li, .nav-toggle__bar,
  .dropdown__menu, .dropdown__menu .container, .dropdown__toggle svg { transition: none; }
  .nav__wave, body.nav-open .nav__wave { animation: none; }
  .route-map__world { transition: none !important; }
}
