/* ==========================================================================
   STEWARD TRAVEL — Travel Well. Steward Generously.
   --------------------------------------------------------------------------
   The site is built around one idea: the commission was always in the price,
   and this business points it somewhere else. So the layout keeps returning
   to a redirect — a line that arrives, turns, and lands somewhere better.

   CSS ORDER — do not reorder, specificity depends on it:
     1. Tokens          6. Buttons
     2. Reset           7. Nav
     3. Layout bands    8. Components
     4. Type            9. Footer
     5. Rules/plates   10. Motion + responsive
   Section spacing lives ONLY on .band. Never add padding to a component that
   also sits inside a band — that is how selectors start fighting.
   ========================================================================== */

/* 1. TOKENS ============================================================== */

:root {
  /* Brand, exactly as specified */
  --slate: #2c3e6b;
  --terra: #c17a47;
  --gold: #c9a87c;
  --sand: #e8dcc8;
  --gray: #5a6070;

  /* Derived. Two of the five brand colours cannot carry text on a light
     ground — Terra lands at 2.52:1 on Sand and Gold at 1.65:1. Rather than
     drop them or ship failing text, each has an ink variant with the hue and
     saturation held and only lightness moved until it clears 4.5:1. The
     brand colour stays the brand colour wherever it is decorative. */
  --slate-deep: #1e2b4a;
  --slate-lift: #31406b;  /* gradient's lightest stop; gold labels need 4.5 here */
  --terra-ink: #8b552f;   /* Terra as text on light ground  — 4.51 */
  --terra-btn: #a86739;   /* Terra as button ground, white label — 4.50 */
  --gold-ink: #7b5c33;    /* Gold as text on light ground   — 4.53 */
  --terra-chip: #85512d;  /* Terra on a terra wash inside .note — 4.51 */

  /* Grounds */
  --paper: #f6f1e7;
  --sand-deep: #dccdb4;

  /* Text */
  --on-dark: #f4efe6;
  --on-dark-mute: #b8c1d2;
  --on-light: #23283a;
  --on-light-mute: #5a6070;

  /* Ground tokens. Every surface re-declares these three and components read
     them instead of naming a colour, so a component lands on the right side
     of the contrast line wherever it is placed and no `.band--slate .thing`
     override is ever needed. */
  --text: var(--on-light);
  --text-mute: var(--on-light-mute);
  --metal: var(--gold-ink);
  --accent: var(--terra-ink);

  /* Type */
  --display: "Cormorant Garamond", "Apple Garamond", Garamond, Georgia, serif;
  --body: "Lato", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* Scale — 1.25 major third */
  --t-xs: 0.75rem;
  --t-sm: 0.875rem;
  --t-base: 1.0625rem;
  --t-md: 1.1875rem;
  --t-lg: 1.5rem;
  --t-xl: 2rem;
  --t-2xl: 2.75rem;
  --t-3xl: 3.75rem;

  /* Space */
  --s-1: 0.5rem;
  --s-2: 1rem;
  --s-3: 1.5rem;
  --s-4: 2rem;
  --s-5: 3rem;
  --s-6: 4.5rem;
  --s-7: 7rem;

  --shell: 1160px;
  --shell-narrow: 720px;

  /* Height of the Travel Planning head. It is an ordinary section — the page
     is never pinned — so this is just how tall the heading band is. */
  --flyin-height: 62vh;

  /* Scroll length of the journey-map track. Lower it to shorten that
     section; the route still completes, just faster. */
  --jm-track: 240vh;

  /* Motion — weight, not bounce */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-soft: cubic-bezier(0.2, 0.9, 0.25, 1.06);

  --lift-1: 0 1px 2px rgba(20, 28, 48, 0.16);
  --lift-2: 0 8px 22px -8px rgba(20, 28, 48, 0.28);
  --lift-3: 0 20px 48px -16px rgba(20, 28, 48, 0.36);

  --rule: 1px solid rgba(122, 100, 70, 0.24);
  --rule-dark: 1px solid rgba(201, 168, 124, 0.26);
}

/* 2. RESET =============================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* The page always opens on a dark hero/pagehead and always closes on the
     dark footer, so the html background — the only thing visible during
     mobile rubber-band overscroll past either edge — should match those,
     not the light interior sections. Left as --paper here, it reads as an
     unexpected blank cream page bouncing in after the footer. */
  background: var(--slate-deep);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--on-light);
  font-family: var(--body);
  font-size: var(--t-base);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

button {
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
}

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

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

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--s-2);
  z-index: 200;
  padding: var(--s-2) var(--s-3);
  background: var(--terra-btn);
  color: #fff;
  font-size: var(--t-sm);
  font-weight: 700;
  text-decoration: none;
  transition: top 0.2s var(--ease-out);
}

.skip-link:focus {
  top: var(--s-2);
}

/* 3. LAYOUT BANDS ======================================================== */

.band {
  position: relative;
  padding: var(--s-7) var(--s-3);
}

.band--tight {
  padding-top: var(--s-4);
  padding-bottom: var(--s-4);
}

/* --- Light grounds --- */
.band--paper,
.band--sand,
.card,
.tier,
.faq {
  --text: var(--on-light);
  --text-mute: var(--on-light-mute);
  --metal: var(--gold-ink);
  --accent: var(--terra-ink);
  color: var(--text);
}

.band--paper {
  background: var(--paper);
}

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

/* --- Dark grounds --- */
.band--slate,
.band--deep,
.hero,
.pagehead,
.hero-video,
.flyin,
.foot,
.nav {
  --text: var(--on-dark);
  --text-mute: var(--on-dark-mute);
  --metal: var(--gold);
  --accent: var(--gold);
  color: var(--text);
}

.band--slate {
  background: var(--slate);
}

.band--deep {
  background: var(--slate-deep);
}

/* Closing CTA bands get a photo instead of flat color — one shared
   background-image per section via inline style, this class only supplies
   the cover/position mechanics and the dark scrim that keeps text
   readable over any photo. */
.band--cta-photo {
  position: relative;
  background-size: cover;
  background-position: center;
}

.band--cta-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(30, 43, 74, 0.9), rgba(30, 43, 74, 0.82));
}

.band--cta-photo::before {
  z-index: 1;
}

.band--cta-photo .shell {
  z-index: 2;
}

/* Very quiet ground texture — paper tooth on light, weave on dark */
.band--paper::before,
.band--sand::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: radial-gradient(circle at 20% 30%, rgba(90, 96, 112, 0.04) 0 1px, transparent 1px),
    radial-gradient(circle at 70% 60%, rgba(90, 96, 112, 0.03) 0 1px, transparent 1px);
  background-size: 13px 13px, 19px 19px;
}

.band--slate::before,
.band--deep::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: repeating-linear-gradient(102deg, rgba(255, 255, 255, 0.016) 0 2px, transparent 2px 5px);
}

.shell {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
}

.shell--narrow {
  max-width: var(--shell-narrow);
}

.grid {
  display: grid;
  gap: var(--s-4);
}

.grid--2 {
  grid-template-columns: repeat(2, 1fr);
}

.grid--3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid--split {
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--s-6);
  align-items: center;
}

.grid--split img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* 4. TYPE ================================================================ */

.display-1,
.display-2,
.display-3 {
  font-family: var(--display);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.008em;
  margin: 0;
  text-wrap: balance;
}

.display-1 {
  font-size: clamp(2.5rem, 6vw, var(--t-3xl));
}

.display-2 {
  font-size: clamp(2rem, 4.4vw, var(--t-2xl));
}

.display-3 {
  font-size: clamp(1.45rem, 2.8vw, var(--t-xl));
  line-height: 1.2;
}

/* Section label with a rule drawn to its right. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0 0 var(--s-3);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--metal);
}

.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.4;
}

.eyebrow--center {
  justify-content: center;
}

.eyebrow--center::after {
  display: none;
}

.lede {
  margin: var(--s-3) 0 0;
  font-size: clamp(var(--t-md), 2vw, var(--t-lg));
  line-height: 1.55;
  color: var(--text-mute);
  max-width: 62ch;
}

/* Spacing lives on the elements themselves rather than on a `* + *` flow
   rule: `.prose p` outranks `.prose > * + *` on specificity, so a margin
   reset there silently wins and every paragraph closes up. */
.prose p {
  margin: 0 0 var(--s-3);
  max-width: 68ch;
}

.prose h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(1.7rem, 3.4vw, 2.35rem);
  line-height: 1.14;
  letter-spacing: -0.008em;
  margin: var(--s-6) 0 var(--s-3);
  color: var(--text);
  text-wrap: balance;
}

/* When an h2 opens a .prose block (no paragraph before it), its own
   margin-top stacks on top of the section's own padding-top, producing an
   inconsistent, larger gap than section-opening headings that got a
   hand-added `style="margin-top:0"`. Handling it here for every prose
   block, instead of on 40+ individual headings by hand, so it can't drift
   out of sync again. */
.prose > h2:first-child {
  margin-top: 0;
}

.prose h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.4rem;
  line-height: 1.25;
  margin: var(--s-5) 0 var(--s-2);
  color: var(--text);
}

.prose > :last-child {
  margin-bottom: 0;
}

.prose strong {
  font-weight: 700;
  color: var(--text);
}

.prose ul {
  margin: 0 0 var(--s-3);
  padding-left: 1.15rem;
  max-width: 66ch;
}

.prose li + li {
  margin-top: var(--s-1);
}

.prose li::marker {
  color: var(--metal);
}

.prose a:not(.btn) {
  color: var(--accent);
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 3px;
}

.prose a:not(.btn):hover {
  text-decoration-color: currentColor;
}

/* The line that turns. Used wherever the copy states the redirect. */
.turn {
  position: relative;
  margin: var(--s-5) 0;
  padding: var(--s-4) var(--s-4) var(--s-4) var(--s-5);
  background: color-mix(in srgb, var(--gold) 13%, transparent);
  border-left: 3px solid var(--terra);
  font-family: var(--display);
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
  line-height: 1.3;
  color: var(--text);
}

.turn p {
  margin: 0;
  max-width: none;
}

.turn p + p {
  margin-top: var(--s-2);
}

/* Side-by-side "book anywhere else" vs "book with us" contrast — deliberately
   plain HTML/CSS rather than an SVG diagram, since the whole point is that
   this reads instantly, at any width, with no custom artwork to misread. */
.impact-compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-4);
  max-width: 900px;
  margin: var(--s-5) auto 0;
}

.impact-icon-pair {
  display: block;
  width: auto;
  max-width: 100%;
  height: 46px;
  margin: 0 auto var(--s-3);
  color: var(--on-dark-mute);
}

.impact-compare__col--highlight .impact-icon-pair {
  color: var(--gold);
}

.impact-compare__col {
  padding: var(--s-4);
  border: 1px solid rgba(201, 168, 124, 0.22);
}

.impact-compare__col--highlight {
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}

.impact-compare__label {
  margin: 0 0 var(--s-2);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  color: var(--on-dark-mute);
}

.impact-compare__col--highlight .impact-compare__label {
  color: var(--gold);
}

.impact-compare__col p:last-child {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.6;
  text-align: left;
  color: var(--on-dark-mute);
}

.impact-compare__col--highlight p:last-child {
  color: var(--on-dark);
}

/* 5. RULES + PLATES ====================================================== */

.plate {
  position: relative;
  overflow: hidden;
  background: var(--slate-deep);
  border: var(--rule-dark);
}

.plate svg {
  width: 100%;
  height: auto;
}

.plate__cap {
  margin: var(--s-2) 0 0;
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
}

/* 6. BUTTONS ============================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-1);
  min-height: 48px;
  padding: 0.8rem var(--s-4);
  border: 1px solid transparent;
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.16s var(--ease-out), background-color 0.2s var(--ease-out),
    box-shadow 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}

.btn--primary {
  background: var(--terra-btn);
  color: #fff;
  box-shadow: var(--lift-1);
}

.btn--primary:hover {
  background: #96592f;
  box-shadow: var(--lift-2);
}

.btn--ghost {
  border-color: currentColor;
  color: var(--text);
  background: transparent;
}

.btn--ghost:hover {
  background: color-mix(in srgb, currentColor 10%, transparent);
}

/* A translucent navy backing (the previous fix here) still reads as
   invisible on a photo that's already scrimmed down to near-navy — cream
   text and a 1px cream border just don't hold a visible edge against a
   background close to the same color. Gold has enough contrast against the
   dark scrim regardless of what photo is behind it. */
.band--cta-photo .btn--ghost,
.hero-video .btn--ghost {
  border-color: var(--gold);
  color: var(--gold);
  background: rgba(0, 0, 0, 0.2);
}

.band--cta-photo .btn--ghost:hover,
.hero-video .btn--ghost:hover {
  background: var(--gold);
  color: var(--slate-deep);
}

.btn:active {
  transform: translateY(2px);
  box-shadow: none;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-4);
}

.btn-row--center {
  justify-content: center;
}

/* Text link with an arrow that steps forward on hover. */
.arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 700;
  font-size: var(--t-sm);
  letter-spacing: 0.04em;
  text-decoration: none;
  color: var(--accent);
}

.arrow::after {
  content: "\2192";
  transition: transform 0.2s var(--ease-out);
}

.arrow:hover::after {
  transform: translateX(4px);
}

/* 7. NAV ================================================================= */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--slate-deep);
  border-bottom: var(--rule-dark);
  transition: box-shadow 0.25s var(--ease-out);
}

.nav.is-condensed {
  box-shadow: var(--lift-2);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0.7rem var(--s-3);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  padding-block: 0.25rem;
}

/* 44px rather than 40 — the mark carries full coastlines here, matching the
   favicon, and the extra few pixels are what keep them reading as continents
   instead of texture. */
.brand__mark {
  width: 44px;
  height: 44px;
  flex: none;
}

.brand__name {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1;
  color: var(--on-dark);
}

.brand__tag {
  display: block;
  margin-top: 2px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--gold);
}

/* Persistent quick-access row — a second strip under the brand/trigger row,
   a handful of the most-wanted links stay on screen at every width;
   everything else (Destinations, Hot Deals, FAQ, the rest) lives in the
   full overlay behind the hamburger. Hidden below the breakpoint where it
   would crowd the brand mark — the overlay is the only way in there. */
.nav__quicklinks {
  display: block;
  border-top: 1px solid rgba(201, 168, 124, 0.14);
}

.nav__quicklinks-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-5);
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0.5rem var(--s-3);
}

.nav__quicklink {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--on-dark);
  transition: color 0.18s var(--ease-out);
}

.nav__quicklink:hover,
.nav__quicklink:focus-visible {
  color: var(--gold);
}

.nav__quicklink[aria-current="page"] {
  color: var(--gold);
}

.nav__quicklink.is-section {
  color: color-mix(in srgb, var(--gold) 70%, var(--on-dark));
}

.nav__quicklink-item {
  position: relative;
}

.nav__quicklink-sub {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translate(-50%, -6px);
  min-width: 220px;
  margin: 0;
  padding: var(--s-1);
  list-style: none;
  background: var(--slate-deep);
  border: var(--rule-dark);
  box-shadow: var(--lift-3);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out), visibility 0.18s;
}

.nav__quicklink-item:hover .nav__quicklink-sub,
.nav__quicklink-item:focus-within .nav__quicklink-sub {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

.nav__quicklink-sub a {
  display: block;
  padding: 0.55rem 0.75rem;
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  text-decoration: none;
  color: var(--on-dark);
}

.nav__quicklink-sub a:hover {
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  color: var(--gold);
}

/* Trigger — a real hamburger now that it isn't the only way in; opens the
   full overlay for everything the quick-access row doesn't cover. */
.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.nav__social {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.nav__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  color: var(--on-dark);
  transition: color 0.2s var(--ease-out);
}

.nav__social-link svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.nav__social-link:hover,
.nav__social-link:focus-visible {
  color: var(--gold);
}

@media (max-width: 480px) {
  .nav__social {
    display: none;
  }
}

.nav__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--on-dark);
  cursor: pointer;
}

.nav__trigger-icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 22px;
  height: 16px;
}

.nav__trigger-icon span {
  display: block;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.25s var(--ease-out), opacity 0.2s var(--ease-out);
}

.nav__trigger:hover .nav__trigger-icon span,
.nav__trigger:focus-visible .nav__trigger-icon span {
  background: var(--gold);
}

.nav__trigger[aria-expanded="true"] .nav__trigger-icon span:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.nav__trigger[aria-expanded="true"] .nav__trigger-icon span:nth-child(2) {
  opacity: 0;
}

.nav__trigger[aria-expanded="true"] .nav__trigger-icon span:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* Full-screen menu — one implementation for every screen size. Travel
   Planning's sub-pages sit inline/indented rather than behind a second
   hover-triggered dropdown, since opening this is already a deliberate
   pause to choose where to go. */
.nav-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  flex-direction: column;
  justify-content: center;
  padding: var(--s-6) var(--s-3);
  background: var(--slate-deep);
  overflow: hidden auto;
}

.nav-overlay.is-open {
  display: flex;
}

/* Faint concentric-circle globe motif, echoing the brand mark, instead of
   flat color behind the link list — decoration only, never competes with
   text since it sits well under reading-contrast opacity. */
.nav-overlay__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.55;
  pointer-events: none;
}

.nav-overlay__nav {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: var(--s-6);
}

.nav-overlay__group {
  margin: 0 0 var(--s-2);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--gold);
}

.nav-overlay__links {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-overlay__links > li {
  border-bottom: 1px solid rgba(201, 168, 124, 0.14);
}

.nav-overlay__item {
  padding-bottom: 0.6rem;
}

.nav-overlay__link {
  display: block;
  padding: 0.65rem 0;
  font-family: var(--display);
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  font-weight: 500;
  text-decoration: none;
  color: var(--on-dark);
  transition: color 0.2s var(--ease-out);
}

.nav-overlay__link:hover,
.nav-overlay__link:focus-visible {
  color: var(--gold);
}

/* Same "here" vs "in here" distinction the old dropdown used — dimmed for
   a section ancestor, full gold for the exact page. */
.nav-overlay__link[aria-current="page"] {
  color: var(--gold);
}

.nav-overlay__link.is-section {
  color: color-mix(in srgb, var(--gold) 70%, var(--on-dark));
}

.nav-overlay__sub {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-overlay__sub a {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--on-dark-mute);
}

.nav-overlay__sub a:hover,
.nav-overlay__sub a:focus-visible {
  color: var(--gold);
}

.nav-overlay__sub a[aria-current="page"] {
  color: var(--gold);
}

.nav-overlay__tag {
  position: relative;
  z-index: 1;
  margin: var(--s-4) auto 0;
  max-width: var(--shell-narrow);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  text-align: center;
  color: var(--gold);
}

/* 8. COMPONENTS ========================================================== */

/* --- Hero --- */
.hero {
  position: relative;
  display: flex;
  align-items: flex-start;
  min-height: calc(100svh - 62px);
  padding: var(--s-6) var(--s-3) var(--s-7);
  background: radial-gradient(120% 90% at 50% 0%, var(--slate-lift) 0%, var(--slate) 45%, var(--slate-deep) 100%);
  overflow: hidden;
}

.hero__grid {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--shell-narrow);
  margin: auto;
  text-align: center;
}

.hero__globe {
  width: clamp(190px, 27vw, 300px);
  margin: 0 auto var(--s-5);
}

.hero__title {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(2.4rem, 5.6vw, 3.9rem);
  line-height: 1.06;
  letter-spacing: -0.012em;
  margin: 0;
  text-wrap: balance;
}

.hero__title em {
  font-style: italic;
  color: var(--gold);
}

.hero__lede {
  margin: var(--s-3) auto 0;
  max-width: 56ch;
  font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  line-height: 1.6;
  color: var(--on-dark-mute);
}

.hero__sig {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  margin: var(--s-4) 0 0;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--gold);
}

.hero__sig::before {
  content: "";
  width: 34px;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
  flex: none;
}

/* --- Page head (interior) --- */
.pagehead {
  position: relative;
  padding: var(--s-6) var(--s-3) var(--s-5);
  background: radial-gradient(120% 120% at 50% 0%, var(--slate-lift) 0%, var(--slate) 55%, var(--slate-deep) 100%);
  overflow: hidden;
}

/* A still photo instead of the flat gradient, for the pageheads that don't
   carry one of the traced icon marks — same cover/scrim mechanics as
   .band--cta-photo, just scoped to .pagehead so the eyebrow/h1/lede colors
   don't need to change. */
.pagehead--photo {
  background-size: cover;
  background-position: center;
}

.pagehead--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(30, 43, 74, 0.78), rgba(30, 43, 74, 0.88));
}

.pagehead__inner {
  position: relative;
  z-index: 1;
  max-width: var(--shell-narrow);
  margin-inline: auto;
  text-align: center;
}

/* The same turning mark as the home hero, at interior-page scale. It shares
   the `.mark` class, so the float, the entrance and the 48s rotation all come
   from the one set of rules. */
.pagehead__mark {
  width: clamp(88px, 11vw, 124px);
  margin: 0 auto var(--s-3);
}

/* The globe is square; the family is 440x264. Matched on HEIGHT rather than
   width, so it reads at the same weight in the head instead of as a short
   wide strip — 206px wide lands at 124px tall, the globe's own maximum. */
.pagehead__mark--family {
  width: clamp(147px, 18.3vw, 206px);
}

/* Traced artwork, cropped to its own bounds (aspect 0.944). Matched on
   height like the family mark, so all three page-head symbols carry the same
   visual weight: 117px wide lands at 124px tall. */
.pagehead__mark--gift {
  width: clamp(83px, 10.4vw, 117px);
}

/* Traced artwork, aspect 1.088 — 135px wide lands at 124px tall. */
.pagehead__mark--map {
  width: clamp(96px, 12vw, 135px);
}

/* Traced artwork, aspect 0.654 — the tallest of the marks, so it is the
   narrowest: 81px wide lands at the same 124px tall. */
.pagehead__mark--cross {
  width: clamp(58px, 7.2vw, 81px);
}

/* Traced artwork, aspect 0.837 — 104px wide lands at 124px tall. */
.pagehead__mark--church {
  width: clamp(74px, 9.2vw, 104px);
}

/* The beach mark needs no modifier: its traced bounds are square (293x293),
   so the base .pagehead__mark width already lands it at the same 124px tall.
   It carries no `.mark` class, so it stays still like the other traced marks. */

.pagehead .eyebrow {
  justify-content: center;
}

.pagehead .eyebrow::after {
  display: none;
}

.pagehead .lede {
  margin-inline: auto;
}

/* --- Scroll fly-in -----------------------------------------------------
   An ordinary page head that happens to have an aircraft crossing it. The
   page scrolls normally the whole time — nothing is pinned, so the reader is
   never held in place waiting for an animation to finish. The aircraft's
   position is a function of how far this section has scrolled, so it moves
   with the reader rather than instead of them. */

.flyin {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: var(--flyin-height);
  padding: var(--s-6) var(--s-3);
  overflow: hidden;
  background: radial-gradient(120% 110% at 50% 15%, var(--slate-lift) 0%, var(--slate) 55%, var(--slate-deep) 100%);
}

.flyin__text {
  position: relative;
  z-index: 10;
  max-width: var(--shell-narrow);
  margin-bottom: var(--s-5);
  text-align: center;
}

/* A dedicated lane below the text, so the two can never share a pixel of
   vertical space no matter how many lines the heading wraps to on a phone.
   The aircraft translates well past both viewport edges, so `.flyin` must
   keep `overflow: hidden` — without it those off-screen positions widen the
   document and the whole page scrolls sideways. */
.flyin__lane {
  position: relative;
  width: 100%;
  height: clamp(112px, 16vw, 216px);
}

.flyin__craft {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  pointer-events: none;
  will-change: transform, opacity;
  opacity: 0;
}

.flyin__craft svg {
  width: clamp(230px, 34vw, 460px);
  height: auto;
  flex: none;
}

/* Without JS there is no flight, so the lane collapses and the aircraft is
   simply not drawn — the heading still reads and no space is wasted holding
   a gap open for an animation that will never run. */
.flyin:not(.is-live) .flyin__lane {
  display: none;
}

/* --- Journey map --------------------------------------------------------
   The specialties as a route rather than a grid of cards.

   The DEFAULT state below is the fallback: a drawn route with the cards in an
   ordinary grid underneath. That is what renders with JS off or under reduced
   motion. `.is-live`, added by the script, is what turns on the pinned,
   scrubbed version — so the readable version is never dependent on the
   animation arriving. */

.jm {
  position: relative;
  --text: var(--on-dark);
  --text-mute: var(--on-dark-mute);
  --metal: var(--gold);
  --accent: var(--gold);
  color: var(--text);
  background: radial-gradient(120% 90% at 50% 6%, var(--slate-lift) 0%, var(--slate) 52%, var(--slate-deep) 100%);
}

.jm__screen {
  padding: var(--s-7) var(--s-3);
}

.jm__head {
  max-width: var(--shell-narrow);
  margin: 0 auto var(--s-5);
  text-align: center;
}

.jm__stage {
  position: relative;
  max-width: var(--shell);
  margin-inline: auto;
  transform-origin: 50% 55%;
}

.jm__map {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.jm__grid line { stroke: rgba(201, 168, 124, 0.09); stroke-width: 1; }
.jm__land   { fill: rgba(255, 255, 255, 0.035); }
.jm__land--2 { fill: rgba(255, 255, 255, 0.022); }

.jm__route-base {
  fill: none;
  stroke: rgba(201, 168, 124, 0.22);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 2 12;
}

/* DrawSVG is a paid GSAP plugin; this is the dash-offset technique instead. */
.jm__route {
  fill: none;
  stroke: var(--terra);
  stroke-width: 4;
  stroke-linecap: round;
}

.jm__pin-halo { fill: var(--terra); opacity: 0.18; }
.jm__pin-dot  { fill: var(--sand); stroke: var(--terra); stroke-width: 3; }

.jm__pin-num {
  fill: var(--slate-deep);
  font-family: var(--body);
  font-weight: 900;
  font-size: 15px;
  text-anchor: middle;
  dominant-baseline: central;
}

.jm__craft-body { fill: var(--gold); stroke: var(--slate-deep); stroke-width: 1.5; stroke-linejoin: round; }
.jm__craft-ring { fill: none; stroke: var(--gold); stroke-width: 2; opacity: 0.35; }

/* The craft only means anything while the route is being travelled. */
.jm:not(.is-live) .jm__craft { display: none; }

.jm__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: var(--s-3);
  margin-top: var(--s-5);
}

.jm__card {
  padding: var(--s-3);
  background: var(--sand);
  color: var(--on-light);
  border-left: 3px solid var(--terra);
  box-shadow: var(--lift-2);
}

.jm__card-n {
  margin: 0 0 0.35rem;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--terra-ink);
}

.jm__card-h {
  margin: 0 0 0.35rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.2rem;
  line-height: 1.15;
}

.jm__card-p {
  margin: 0 0 0.6rem;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--on-light-mute);
}

.jm__card .arrow { color: var(--terra-ink); }

/* --- Live: pinned and scrubbed ----------------------------------------- */

.jm.is-live {
  height: var(--jm-track);
}

.jm.is-live .jm__screen {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100svh;
  padding: var(--s-5) var(--s-3);
  overflow: hidden;
}

.jm.is-live .jm__head { flex: none; margin-bottom: var(--s-3); }

.jm.is-live .jm__stage {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  will-change: transform;
}

.jm.is-live .jm__map {
  position: absolute;
  inset: 0;
  height: 100%;
}

.jm.is-live .jm__cards {
  position: absolute;
  inset: 0;
  display: block;
  margin: 0;
  pointer-events: none;
}

/* Positioned onto its own marker. The custom properties are set in JS so a
   media query can relocate the card without fighting an inline style. */
.jm.is-live .jm__card {
  position: absolute;
  left: var(--jm-x);
  top: var(--jm-y);
  width: min(255px, 33vw);
  padding: 0.85rem 0.95rem;
  border-radius: 3px;
  pointer-events: auto;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.86);
  transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-soft);
}

.jm.is-live .jm__card.is-on {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.jm.is-live .jm__card-p { font-size: 0.8rem; margin-bottom: 0.5rem; }

.jm.is-live .jm__pin,
.jm.is-live .jm__craft { opacity: 0; transition: opacity 0.3s var(--ease-out); }

.jm.is-live .jm__pin.is-on,
.jm.is-live .jm__craft.is-on { opacity: 1; }

/* Narrow screens: the map keeps the upper half and the cards share one slot
   in the band beneath it, one at a time. A 1200x620 map in a narrow column
   letterboxes to a strip with dead bands, and cards pinned to their markers
   run off both edges — this is a different layout, not the desktop one
   squeezed. */
@media (max-width: 860px) {
  .jm.is-live .jm__stage { flex: none; height: 52svh; }

  /* The card slot is the band under the map, not the map itself: a 1200x620
     map in a narrow column letterboxes to a strip, and a card centred on its
     marker would sit on top of the route. */
  .jm.is-live .jm__cards { inset: auto 0 0 0; height: 42%; }

  .jm.is-live .jm__card {
    left: 50%;
    top: auto;
    bottom: 0;
    width: min(340px, 88vw);
    transform: translate(-50%, 0) scale(0.9);
  }

  .jm.is-live .jm__card.is-on { transform: translate(-50%, 0) scale(1); }
}

/* --- Cards --- */
.card {
  display: flex;
  flex-direction: column;
  padding: var(--s-4);
  background: var(--paper);
  border: var(--rule);
  border-top: 3px solid var(--terra);
  box-shadow: var(--lift-1);
  text-decoration: none;
  transition: transform 0.28s var(--ease-soft), box-shadow 0.28s var(--ease-out);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-2);
}

.card__h {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.15;
  margin: 0 0 var(--s-2);
  color: var(--text);
}

.card p {
  margin: 0 0 var(--s-3);
  color: var(--text-mute);
  font-size: var(--t-base);
}

.card .arrow {
  margin-top: auto;
}

.card--plain {
  border-top-color: var(--gold);
}

/* --- Numbered steps. Numbered because the order is real. --- */
.steps {
  counter-reset: step;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-4);
}

.step {
  position: relative;
  padding-left: 4.6rem;
  counter-increment: step;
}

.step::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: -0.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--metal);
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--metal);
  background: transparent;
  transition: background-color 0.25s var(--ease-out), color 0.25s var(--ease-out), border-color 0.25s var(--ease-out);
}

.step:hover::before {
  background: var(--slate);
  border-color: var(--slate);
  color: var(--on-dark);
}

.step__h {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.35rem;
  line-height: 1.2;
  margin: 0 0 var(--s-1);
  color: var(--text);
}

.step p {
  margin: 0;
  color: var(--text-mute);
}

/* --- Gratitude tier table --- */
.tier {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--s-4);
  background: var(--paper);
  border: var(--rule);
  font-variant-numeric: tabular-nums;
}

.tier caption {
  caption-side: top;
  text-align: left;
  padding-bottom: var(--s-2);
  font-size: var(--t-sm);
  color: var(--text-mute);
}

.tier th,
.tier td {
  padding: 0.85rem var(--s-3);
  text-align: left;
  border-bottom: var(--rule);
}

.tier thead th {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--metal);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
}

.tier tbody tr:last-child th,
.tier tbody tr:last-child td {
  border-bottom: 0;
}

.tier td:last-child {
  font-weight: 700;
  color: var(--terra-ink);
}

/* --- FAQ --- */
.faq {
  border-top: var(--rule);
}

.faq__item {
  border-bottom: var(--rule);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-3) 0;
  background: none;
  border: 0;
  text-align: left;
  font-family: var(--display);
  font-size: 1.22rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  cursor: pointer;
}

.faq__q::after {
  content: "+";
  flex: none;
  font-family: var(--body);
  font-size: 1.3rem;
  font-weight: 400;
  color: var(--metal);
  transition: transform 0.24s var(--ease-out);
}

.faq__item.is-open .faq__q::after {
  transform: rotate(45deg);
}

.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s var(--ease-out);
}

.faq__item.is-open .faq__a {
  grid-template-rows: 1fr;
}

.faq__a > div {
  overflow: hidden;
}

.faq__a p,
.faq__a ul {
  margin: 0 0 var(--s-3);
  max-width: 68ch;
  color: var(--text-mute);
}

.faq__group {
  margin: var(--s-6) 0 var(--s-2);
}

/* --- Lead magnet --- */
.magnet {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  background: var(--slate-deep);
  border-left: 4px solid var(--terra);
  color: var(--on-dark);
}

.magnet__h {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.4rem;
  line-height: 1.2;
  margin: 0 0 0.35rem;
}

.magnet p {
  margin: 0;
  color: var(--on-dark-mute);
  font-size: var(--t-sm);
}

.magnet__icon {
  width: 46px;
  height: 46px;
  color: var(--gold);
  flex: none;
}

/* --- Contact --- */
.contact-line {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  padding: var(--s-2) 0;
  border-bottom: var(--rule);
}

.contact-line dt {
  flex: none;
  width: 5.5rem;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--metal);
}

.contact-line dd {
  margin: 0;
  font-size: var(--t-md);
}

.contact-line a {
  color: var(--accent);
  text-underline-offset: 3px;
}

.embed {
  width: 100%;
  margin-top: var(--s-5);
  border: 0;
  background: var(--paper);
}

/* --- Notes / testimonial --- */
.note {
  padding: var(--s-4);
  background: color-mix(in srgb, var(--gold) 14%, transparent);
  border-left: 3px solid var(--gold);
}

.note p {
  margin: 0;
  font-family: var(--display);
  font-size: 1.3rem;
  line-height: 1.35;
}

.note cite {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--body);
  font-size: var(--t-xs);
  font-style: normal;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
}

.placeholder {
  display: inline-block;
  margin-top: var(--s-2);
  padding: 0.15rem 0.5rem;
  background: color-mix(in srgb, var(--terra) 18%, transparent);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--terra-chip);
}

/* Certification badge and the supplier wall under it. Every third-party mark
   is served from /assets/partners/ — nothing here is hotlinked to a supplier's
   own server, so the strip cannot break when they reorganise their CDN. */
.credential {
  margin: var(--s-5) 0 0;
  text-align: center;
}

.credential__badge {
  display: block;
  width: clamp(112px, 14vw, 150px);
  height: auto;
  margin-inline: auto;
}

.credential__note {
  margin: var(--s-2) auto 0;
  max-width: 56ch;
  font-style: italic;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--text-mute);
}

/* Outranks `.prose p`, which would otherwise reset the eyebrow's size and
   margins — same specificity trap the comment above `.prose p` describes. */
.prose .suppliers__label {
  margin: var(--s-6) 0 var(--s-4);
  max-width: none;
}

/* Breaks the wall out of the 720px reading column. Six wordmarks will not sit
   on one line inside it, and wrapping 3/2/1 strands Uniworld on a row of its
   own. The translate lives here rather than on the [data-reveal] list, because
   that animates `transform` and would wipe the centring. */
.suppliers-wall {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  width: min(var(--shell), calc(100vw - 4rem));
}

/* Prefixed with .prose to clear `.prose ul`, which otherwise caps this at
   66ch and re-adds the bullet indent. */
.prose .suppliers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-4) var(--s-5);
  margin: 0;
  padding: 0;
  max-width: none;
  list-style: none;
}

.prose .suppliers li {
  margin: 0;
  display: flex;
}

/* Fitted to a box rather than to one axis. These wordmarks run from 6:1
   (Scenic) to 3:2 (Viking): capping height alone lets the long thin ones run
   to full natural width, capping width alone shrinks the stacked ones to
   nothing. Whichever limit binds first wins, which is what evens the row.

   A bare px max-width, not `min(150px, 100%)`: a percentage there is indefinite
   during intrinsic sizing, so the flex item kept sizing to Scenic's full 293px
   natural width and pushed the row to wrap. */
.suppliers img {
  display: block;
  width: auto;
  max-width: 150px;
  max-height: 52px;
  opacity: 0.9;
}

/* Viking and Emerald carry a stacked lockup, so they read small at a shared
   cap height — a little extra room evens the row out optically. */
.suppliers img[data-tall] {
  max-height: 66px;
}

/* 9. FOOTER ============================================================== */

.foot {
  background: var(--slate-deep);
  padding: var(--s-6) var(--s-3) var(--s-4);
}

.foot__grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: var(--s-5);
  max-width: var(--shell);
  margin-inline: auto;
}

.foot__h {
  margin: 0 0 var(--s-2);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.foot__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot__list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--on-dark-mute);
}

.foot__list a:hover {
  color: var(--gold);
}

.foot__list a.foot__contact,
.foot__legal a.foot__contact {
  color: var(--on-dark);
  font-weight: 700;
}

.foot__rule {
  max-width: var(--shell);
  height: 1px;
  margin: var(--s-5) auto 0;
  background: linear-gradient(90deg, var(--gold), color-mix(in srgb, var(--gold) 20%, transparent));
  transform: scaleX(0);
  transform-origin: left center;
}

.foot__legal {
  max-width: var(--shell);
  margin: 0 auto 0;
  padding-top: var(--s-3);
  font-size: 0.76rem;
  line-height: 1.7;
  color: var(--on-dark-mute);
}

@media (prefers-reduced-motion: reduce) {
  .foot__rule {
    transform: scaleX(1);
  }
}

.foot__legal a {
  color: var(--on-dark-mute);
  text-underline-offset: 3px;
}

.foot__legal a:hover {
  color: var(--gold);
}

/* 10. MOTION ============================================================= */

/* Not one uniform fade-up applied to everything. Each kind of element
   arrives the way its counterpart would: a label settles its tracking, a
   printed line is laid down from the top, a card is set on the table.
   Travel is short throughout — the page should read as composed on arrival,
   not assembled in front of the reader. */

[data-reveal] {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.55s var(--ease-out), transform 0.55s var(--ease-out);
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

.eyebrow[data-reveal] {
  transform: none;
  letter-spacing: 0.32em;
  transition: opacity 0.45s var(--ease-out), letter-spacing 0.75s var(--ease-out);
}

.eyebrow[data-reveal].is-in {
  letter-spacing: 0.2em;
}

.lede[data-reveal] {
  transform: none;
  clip-path: inset(0 0 102% 0);
  transition: opacity 0.4s var(--ease-out), clip-path 0.85s var(--ease-out);
}

.lede[data-reveal].is-in {
  clip-path: inset(0 0 -2% 0);
}

.card[data-reveal],
.note[data-reveal],
.turn[data-reveal] {
  transform: translateY(14px) scale(0.992);
  transition: opacity 0.5s var(--ease-out), transform 0.6s var(--ease-soft);
}

/* Same specificity as [data-reveal].is-in above, but declared later here —
   without this, the un-revealed translateY/scale above never actually
   clears once revealed, and the card sits permanently offset until
   something else (like a hover rule resetting transform) snaps it into
   place, which reads as an unwanted jump on hover. */
.card[data-reveal].is-in,
.note[data-reveal].is-in,
.turn[data-reveal].is-in {
  transform: none;
}

.steps[data-reveal] .step {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s var(--ease-out), transform 0.55s var(--ease-out);
}

.steps[data-reveal].is-in .step {
  opacity: 1;
  transform: none;
}

.steps[data-reveal].is-in .step:nth-child(2) { transition-delay: 0.09s; }
.steps[data-reveal].is-in .step:nth-child(3) { transition-delay: 0.18s; }
.steps[data-reveal].is-in .step:nth-child(4) { transition-delay: 0.27s; }

/* --- Line-reveal headline mask ------------------------------------------ */
/* The wrapper itself never fades — only the printed line inside it slides
   up from behind the mask, the way a line rises off a press. Wrap one
   hand-chosen line per span (same convention as hero__title's hand-placed
   <br>s); a multi-line headline nests several with staggered
   data-reveal-delay values. */

.line-reveal {
  display: block;
  overflow: hidden;
}

.line-reveal[data-reveal] {
  opacity: 1;
  transform: none;
  transition: none;
}

.line-reveal__row {
  display: block;
  line-height: 1.25;
  transform: translateY(100%);
  transition: transform 0.7s var(--ease-out);
}

.line-reveal[data-reveal].is-in .line-reveal__row {
  transform: translateY(0);
}

/* --- Transition plane ------------------------------------------------------ */
/* The old .flyin pagehead's aircraft, demoted from "main event" to a small,
   quiet recurring motif: it flies across wherever a section seam needs a
   little life, not a whole dedicated lane. Zero layout height of its own —
   sits on the seam between the two sections around it. Same GSAP-scrub
   technique as the dividers (initTransitionPlanes() in motion.js). */
/* The lane sits between two sections' own top/bottom padding, so left
   alone it stacks a full two section-paddings' worth of blank space
   (var(--s-7) top + var(--s-7) bottom) with nothing to visually break it
   up when both sides share the same background — reads as one long empty
   stretch with a small icon floating in it. Pulling the lane in by half of
   that on each side halves the total gap to one section-padding's worth,
   at any breakpoint, since it's computed from the same token. */
.transition-plane-lane {
  position: relative;
  z-index: 3;
  height: 0;
  overflow: visible;
  margin-block: calc(var(--s-7) * -0.5);
}

.transition-plane {
  position: absolute;
  top: -30px;
  left: -8%;
  width: 130px;
  opacity: 0.85;
  pointer-events: none;
}

.transition-plane[data-direction="rtl"] {
  left: 104%;
}

.transition-plane svg {
  display: block;
  width: 100%;
  height: auto;
}

/* The mark is the client's own logo, so the artwork is never distorted.
   Motion is a staged entrance, a slow float, and the globe's rotation. */
.mark__float,
.mark__globe,
.mark__swoosh,
.mark__hands {
  transform-box: fill-box;
  transform-origin: center;
}

.mark__float {
  animation: mark-float 7s ease-in-out infinite;
}

.mark__land {
  animation: mark-spin 48s linear infinite;
}

@keyframes mark-spin {
  from { transform: translateX(0); }
  to { transform: translateX(-200.8px); }
}

@keyframes mark-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

.mark__hands {
  animation: mark-rise 1s var(--ease-out) both;
}

.mark__globe {
  animation: mark-in 1.1s var(--ease-out) 0.15s both;
}

.mark__swoosh {
  animation: mark-sweep 1.2s var(--ease-out) 0.3s both;
}

@keyframes mark-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

@keyframes mark-in {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: none; }
}

@keyframes mark-sweep {
  from { opacity: 0; transform: rotate(-16deg); }
  to { opacity: 1; transform: none; }
}

/* 11. RESPONSIVE ========================================================= */

@media (max-width: 1000px) {
  .foot__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-4);
  }

  .grid--3 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 860px) {
  :root {
    --s-7: 4.5rem;
    --s-6: 3rem;
  }

  /* Below this width the quicklink row won't fit without wrapping or
     crowding the brand mark — the hamburger overlay is the only way in. */
  .nav__quicklinks {
    display: none;
  }

  /* The two-column nav-overlay grid needs to fall back to one column
     before there's room for two comfortably. */
  .nav-overlay__nav {
    grid-template-columns: 1fr;
    gap: var(--s-4);
  }

  .impact-compare {
    grid-template-columns: 1fr;
  }

  .grid--2,
  .grid--3,
  .grid--split {
    grid-template-columns: 1fr;
  }

  .hero {
    min-height: 0;
  }

  .magnet {
    grid-template-columns: 1fr;
    text-align: left;
  }
}

@media (max-width: 560px) {
  :root {
    --s-7: 3.5rem;
  }

  .band {
    padding-left: var(--s-2);
    padding-right: var(--s-2);
  }

  /* Smaller marks and a tighter gutter so the supplier wall wraps to an even
     two-up. At full size the widest marks only fit one per row on a phone,
     which strands four of the six on lines of their own. */
  .suppliers img {
    max-width: 120px;
    max-height: 44px;
  }

  .suppliers img[data-tall] {
    max-height: 56px;
  }

  .prose .suppliers {
    gap: var(--s-3) var(--s-4);
  }

  /* On a phone the hero stops being a centred poster and becomes a title
     page — ranged left. Centred is fine for two lines of headline and poor
     for five lines of body: every line start lands somewhere new and the
     eye has to hunt for it. This is the one place the phone layout
     deliberately disagrees with the desktop one rather than reflowing it. */
  .hero__grid,
  .hero__title,
  .hero__lede,
  .hero__sig,
  .pagehead__inner {
    text-align: left;
  }

  .hero__sig {
    justify-content: flex-start;
    align-items: flex-start;
  }

  .hero__sig::before {
    margin-top: 0.62em;
  }

  .pagehead .eyebrow {
    justify-content: flex-start;
  }

  .pagehead .lede {
    margin-inline: 0;
  }

  .foot__grid {
    grid-template-columns: 1fr;
  }

  .btn {
    width: 100%;
  }

  .step {
    padding-left: 3.6rem;
  }

  .step::before {
    width: 38px;
    height: 38px;
  }

  .magnet {
    padding: var(--s-3);
  }

  /* Standalone controls come up to the 44px touch minimum. Links inside a
     sentence are deliberately left alone: WCAG 2.5.8 exempts targets in a
     block of text, and padding them out would wreck the paragraph's
     line spacing for everyone. */
  .arrow {
    min-height: 44px;
  }

  .contact-line dd a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* A tier table cannot usefully shrink, so it scrolls in its own box
     rather than forcing the page sideways. */
  .tier-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .tier {
    min-width: 420px;
  }
}

/* 12. REDUCED MOTION ===================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

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

  [data-reveal],
  .steps[data-reveal] .step {
    opacity: 1;
    transform: none;
  }

  .lede[data-reveal] {
    clip-path: none;
  }

  .flyin__craft {
    display: none;
  }

  /* The journey map stays in its static fallback: route drawn, cards in a
     grid, nothing pinned and nothing to scrub. */
  .jm.is-live { height: auto; }

  .jm.is-live .jm__screen {
    position: static;
    height: auto;
    padding: var(--s-7) var(--s-3);
    overflow: visible;
  }

  .jm.is-live .jm__stage { flex: none; height: auto; transform: none !important; }

  .jm.is-live .jm__map { position: relative; inset: auto; height: auto; }

  .jm.is-live .jm__cards {
    position: static;
    display: grid;
    margin-top: var(--s-5);
    height: auto;
  }

  .jm.is-live .jm__card {
    position: static;
    width: auto;
    opacity: 1;
    transform: none;
  }

  .jm.is-live .jm__craft { display: none; }

  .eyebrow[data-reveal] {
    letter-spacing: 0.2em;
  }

  .line-reveal__row {
    transform: none;
  }

  .transition-plane-lane {
    display: none;
  }
}

/* 13. PRINT ============================================================== */

@media print {
  .nav,
  .foot,
  .magnet,
  .hero__globe,
  .btn-row,
  .skip-link {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  .band,
  .hero,
  .pagehead {
    padding: 0 0 1.5rem;
    background: #fff !important;
    color: #000 !important;
  }

  .faq__a {
    grid-template-rows: 1fr !important;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
  }
}

/* --- Blog --- */
/* Column, not row-with-wrap: the category set spans "Holy Land" (short)
   to "Faith-Based Group Travel" (long), and at card width the long ones
   wrapped to a second line while short ones stayed on one — same markup,
   inconsistent look purely from label length. Stacking unconditionally
   makes every card look identical regardless of which category lands in
   it, now or with any category added later. */
.blog-meta {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  margin: 0 0 var(--s-4);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--metal);
}

.blog-hero {
  margin: 0 0 var(--s-5);
  border: var(--rule);
}

.blog-hero img {
  width: 100%;
  height: auto;
}

.toc {
  padding: var(--s-4);
  margin: var(--s-4) 0 var(--s-5);
  background: var(--paper);
  border: var(--rule);
  border-left: 3px solid var(--gold);
}

.toc h4 {
  margin: 0 0 var(--s-2);
  font-family: var(--body);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--metal);
}

.toc ul {
  margin: 0;
  padding-left: 1.15rem;
}

.toc li + li {
  margin-top: 0.35rem;
}

.toc a {
  text-decoration: none;
  color: var(--text);
}

.toc a:hover {
  color: var(--terra-ink);
  text-decoration: underline;
}

.blog-cta {
  padding: var(--s-4);
  margin: var(--s-5) 0;
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  border-top: 3px solid var(--terra);
}

.blog-cta p {
  max-width: none;
}

.blog-cta__h {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.3rem;
  margin: 0 0 var(--s-2);
  color: var(--text);
}

.blog-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
}

.blog-card {
  padding: 0;
  overflow: hidden;
}

.blog-card__img {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
}

.blog-card__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}

.blog-card:hover .blog-card__img img {
  transform: scale(1.08);
}

/* Dark wash + "View" badge, both fade/scale in on hover — same affordance
   nelson.travel uses on its destination cards. */
.blog-card__img::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: color-mix(in srgb, var(--slate-deep) 30%, transparent);
  opacity: 0;
  transition: opacity 0.35s var(--ease-out);
}

.blog-card:hover .blog-card__img::before {
  opacity: 1;
}

.blog-card__img::after {
  content: "View";
  position: absolute;
  left: var(--s-3);
  bottom: var(--s-3);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 74px;
  height: 74px;
  border: 1px dashed rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: var(--slate-deep);
  color: #fff;
  font-family: var(--body);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0;
  transform: scale(0.55);
  transition: opacity 0.35s var(--ease-out), transform 0.35s var(--ease-out), color 0.35s var(--ease-out);
  pointer-events: none;
}

.blog-card:hover .blog-card__img::after,
.blog-card:focus-visible .blog-card__img::after {
  opacity: 1;
  transform: scale(1);
  color: var(--gold);
}

.blog-card:hover,
.blog-card:focus-visible {
  transform: none;
}

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

  .blog-card:hover .blog-card__img img {
    transform: none;
  }
}

/* --- Dot card ------------------------------------------------------------ */
/* A second card affordance, distinct from .blog-card's zoom+View badge —
   used for travel-planning's own "destinations you might love" pointers
   rather than the Destinations section's real browsing grid, so the two
   contexts read as different kinds of link at a glance. A dotted ring sits
   over the name and spins up on hover instead of the photo zooming. */
.dot-card {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  text-decoration: none;
  color: var(--on-dark);
}

.dot-card__img {
  position: absolute;
  inset: 0;
}

.dot-card__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.82);
  transition: filter 0.35s var(--ease-out);
}

.dot-card:hover .dot-card__img img,
.dot-card:focus-visible .dot-card__img img {
  filter: brightness(0.68);
}

.dot-card__ring {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 62%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
}

.dot-card__ring svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.dot-card__ring circle {
  transform-origin: center;
  animation: dot-card-spin 14s linear infinite;
  animation-play-state: paused;
}

.dot-card:hover .dot-card__ring circle,
.dot-card:focus-visible .dot-card__ring circle {
  animation-play-state: running;
}

.dot-card__label {
  position: relative;
  z-index: 1;
  padding: 0 var(--s-2);
  font-family: var(--display);
  font-size: clamp(1.15rem, 2.2vw, 1.6rem);
  line-height: 1.15;
  text-align: center;
  opacity: 0.8;
  transition: opacity 0.35s var(--ease-out), transform 0.35s var(--ease-out);
}

.dot-card:hover .dot-card__label,
.dot-card:focus-visible .dot-card__label {
  opacity: 1;
  transform: scale(1.06);
}

@keyframes dot-card-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .dot-card__ring circle {
    animation: none;
  }

  .dot-card__label {
    opacity: 1;
    transform: none;
  }
}

.blog-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--s-4);
}

/* Deal cards carry a real CTA button (blog/destination teaser cards use a
   plain .arrow instead) — pin it to the card's bottom edge so "Get Details
   & Book" lands at the same height across a row regardless of how long an
   individual deal's description runs. */
.blog-card__body > .btn {
  margin-top: auto;
}

.blog-meta a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.blog-meta a:hover {
  color: var(--terra-ink);
}

.blog-byline {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0 0 var(--s-4);
  font-size: var(--t-sm);
  color: var(--text-mute);
}

.blog-byline img {
  border-radius: 50%;
  flex: none;
  object-fit: cover;
}

.blog-byline a {
  color: var(--text);
  font-weight: 700;
  text-decoration: none;
}

.blog-byline a:hover {
  color: var(--terra-ink);
  text-decoration: underline;
}

@media (max-width: 860px) {
  .blog-grid {
    grid-template-columns: 1fr;
  }
}

/* --- Destinations --- */
.badge {
  display: inline-flex;
  padding: 0.3rem 0.85rem;
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
  border-radius: 999px;
  color: var(--terra-ink);
  text-decoration: none;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: var(--t-xs);
}

.badge:hover {
  background: color-mix(in srgb, var(--gold) 26%, transparent);
}

.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
}

.filter-pill {
  padding: 0.6rem 1.2rem;
  border: 1px solid var(--metal);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  text-decoration: none;
  font-size: var(--t-sm);
  font-weight: 700;
  transition: background-color 0.2s var(--ease-out), color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}

.filter-pill:hover {
  border-color: var(--terra);
}

.filter-pill.is-active {
  background: var(--terra-btn);
  border-color: var(--terra-btn);
  color: #fff;
}

.destination-card {
  transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}

.destination-card.is-hidden {
  display: none;
}

/* --- Video hero --- */
.hero-video {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100svh - 62px);
  padding: var(--s-6) var(--s-3) var(--s-7);
  overflow: hidden;
  background: var(--slate) center/cover no-repeat;
}

/* Interior pages get a banner, not a second homepage — same media/scrim/
   content structure, just shorter, matching the old .flyin pagehead's
   footprint (62vh) instead of the homepage's near-full-viewport height. */
.hero-video--interior {
  min-height: var(--flyin-height);
  padding: var(--s-5) var(--s-3);
}

.hero-video__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.hero-video__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--slate-deep) 78%, transparent) 0%,
    color-mix(in srgb, var(--slate-deep) 88%, transparent) 100%);
}

.hero-video__content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--shell-narrow);
  margin: auto;
  text-align: center;
  text-shadow: 0 2px 16px rgba(10, 16, 32, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .hero-video__media {
    display: none;
  }
}

/* --- Carousels (Swiper) --- */
.carousel-section {
  position: relative;
}

.carousel-section .swiper {
  overflow: visible;
  padding-bottom: var(--s-3);
}

.carousel-section .swiper-slide {
  height: auto;
  display: flex;
}

.carousel-section .swiper-slide .card {
  width: 100%;
}

.carousel-nav {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
}

.carousel-nav button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--metal);
  border-radius: 50%;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}

.carousel-nav button:hover {
  border-color: var(--terra);
  background: color-mix(in srgb, var(--terra) 10%, transparent);
}

.carousel-nav button.swiper-button-disabled {
  opacity: 0.35;
  cursor: default;
}

.carousel-nav svg {
  width: 20px;
  height: 20px;
}

/* --- Portrait (About page) --- */
.portrait {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0 0 var(--s-5);
}

.portrait img {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--gold);
}

.portrait figcaption {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--text);
}

/* --- Trip planner search form --- */
.trip-form {
  padding: var(--s-5);
  margin-bottom: var(--s-4);
  background: var(--paper);
  border: var(--rule);
  border-top: 3px solid var(--terra);
  box-shadow: var(--lift-1);
}

.trip-form__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-4);
  margin-bottom: var(--s-4);
}

.trip-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.trip-form__field--wide {
  grid-column: 1 / -1;
  margin-bottom: var(--s-4);
}

.trip-form__field span {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--metal);
}

.trip-form__field input,
.trip-form__field select,
.trip-form__field textarea {
  padding: 0.75rem 1rem;
  border: 1px solid var(--metal);
  background: #fff;
  color: var(--text);
  font-family: var(--body);
  font-size: var(--t-base);
  min-height: 48px;
}

.trip-form__field textarea {
  min-height: 88px;
  resize: vertical;
}

.trip-form__field input:focus,
.trip-form__field select:focus,
.trip-form__field textarea:focus {
  outline: 2px solid var(--terra);
  outline-offset: 1px;
  border-color: var(--terra);
}

@media (max-width: 640px) {
  .trip-form__grid {
    grid-template-columns: 1fr;
  }
}
