/* ==========================================================================
   Majestic Dream Vacations
   Homepage prototype stylesheet

   Design direction
   ----------------
   The brand's own language is the canvas and the masterpiece ("Where Every
   Journey is a Masterpiece", "Your dream, our canvas"). So the page presents
   journeys the way a gallery presents work: each destination carries a
   museum-style placard with its location, dates, and length. The placard is
   the signature device. Everything around it stays quiet.

   Deep plum anchors the page. Mint white opens it up. Gold is rationed to
   calls to action and hairlines so it still reads as an accent by the footer.

   Structure
   ---------
   1. Tokens
   2. Reset and base
   3. Typography
   4. Layout primitives
   5. Components (buttons, placards, cards, media)
   6. Sections, in page order
   7. Motion
   8. Responsive
   ========================================================================== */

/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root {
  /* Brand palette. These five are the entire color system. */
  --plum: #29102d;
  --purple: #68266e;
  --magenta: #be5aa2;
  --gold: #f0b31d;
  --mint: #f0f7f0;

  /* Tints derived from the brand five. No new hues introduced. */
  --plum-deep: #1b0a1e;    /* darker plum for the footer floor */
  --plum-soft: #3d1c43;    /* hairlines and borders on dark ground */
  --mint-shade: #e2ece2;   /* hairlines and borders on light ground */
  --ink: #29102d;          /* body text on light ground, full strength plum */
  --ink-soft: #5a4560;     /* secondary text on light ground */
  --paper-soft: #faf7fa;   /* the lightest ground, warmer than pure white */

  /* Typography.
     Forum is the display face, from Google Fonts, as specified in the brand.
     Jost stands in for Avenir, which is a licensed Linotype face and cannot
     be self-hosted on WordPress without a purchased web license. Jost shares
     Avenir's geometric humanist construction and even x-height. Swap the
     first entry in --font-body once a license is in place. */
  --font-display: 'Forum', 'Cormorant Garamond', Georgia, serif;
  --font-body: 'Jost', 'Avenir Next', Avenir, system-ui, -apple-system, sans-serif;

  /* Type scale, fluid between the 375px and 1440px breakpoints. */
  --step--1: clamp(0.82rem, 0.79rem + 0.13vw, 0.89rem);
  --step-0: clamp(1rem, 0.96rem + 0.19vw, 1.11rem);
  --step-1: clamp(1.19rem, 1.12rem + 0.32vw, 1.39rem);
  --step-2: clamp(1.5rem, 1.36rem + 0.6vw, 1.94rem);
  --step-3: clamp(1.9rem, 1.66rem + 1.02vw, 2.7rem);
  --step-4: clamp(2.4rem, 1.99rem + 1.73vw, 3.75rem);
  --step-5: clamp(2.9rem, 2.19rem + 3.02vw, 5.2rem);

  /* Spacing */
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-s: 1.25rem;
  --space-m: 2rem;
  --space-l: 3.25rem;
  --space-xl: 5rem;
  --space-2xl: 7.5rem;

  /* Layout */
  --measure: 62ch;
  --wrap: 76rem;
  --wrap-narrow: 46rem;

  /* Detail */
  --radius: 2px;
  --rule: 1px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* Focus ring color.
     Gold measures only 1.77:1 against the light grounds, well under the 3:1
     WCAG requires for a focus indicator, so it cannot be the single global
     ring color. This inherits, so each dark ground below reassigns it to gold
     and everything on a light ground keeps plum at 16:1. */
  --focus: var(--plum);
}

/* ==========================================================================
   2. Reset and base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper-soft);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

/* Images that fail to load are hidden by mdv.js so the gradient ground
   underneath shows through rather than a broken-image icon and alt text. */
.is-missing {
  opacity: 0;
}

/* Focus. Color comes from --focus, which each ground reassigns, so the ring
   always clears 3:1 against whatever is behind it. Measured: plum on paper
   16.37:1, plum on mint 15.97:1, gold on plum 9.26:1, gold on plum-deep
   10.08:1. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.mdv-skip {
  position: absolute;
  left: var(--space-s);
  top: -100%;
  z-index: 200;
  padding: var(--space-xs) var(--space-s);
  background: var(--gold);
  color: var(--plum);
  font-weight: 500;
  text-decoration: none;
  transition: top 0.2s var(--ease);
}

.mdv-skip:focus {
  top: var(--space-s);
}

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

/* ==========================================================================
   3. Typography
   ========================================================================== */

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

/* The user-agent blockquote margin indents pull quotes out of alignment with
   the rule above them. */
blockquote,
figure,
dl,
dd {
  margin: 0;
}

/* The eyebrow and the placard share one typographic idea: small, letterspaced,
   uppercase Jost acting as gallery wall text against the Forum display. */
.mdv-eyebrow {
  display: block;
  margin-bottom: var(--space-s);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.mdv-lede {
  max-width: var(--measure);
  font-size: var(--step-1);
  line-height: 1.6;
}

.mdv-prose {
  max-width: var(--measure);
}

.mdv-prose > * + * {
  margin-top: var(--space-s);
}

/* ==========================================================================
   4. Layout primitives
   ========================================================================== */

.mdv-wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--space-s);
}

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

.mdv-section {
  padding-block: var(--space-2xl);
}

/* Ground modifiers. Kept to background and color only, never spacing, so
   they can be combined with any section without a specificity fight. */
.mdv-ground--light {
  background: var(--paper-soft);
  color: var(--ink);
}

.mdv-ground--mint {
  background: var(--mint);
  color: var(--ink);
}

/* Dark grounds switch the focus ring to gold. The property inherits, so every
   control inside these regions picks it up without needing its own rule. */
/* The header is deliberately absent from this list. It sits on a light ground,
   where gold measures 1.77:1 and would leave keyboard focus invisible. It
   keeps the plum default at 16:1. */
.mdv-ground--plum,
.mdv-hero,
.mdv-triphero,
.mdv-footer {
  --focus: var(--gold);
}

.mdv-ground--plum {
  background: var(--plum);
  color: var(--mint);
}

.mdv-ground--plum .mdv-eyebrow {
  color: var(--gold);
}

.mdv-ground--light .mdv-eyebrow,
.mdv-ground--mint .mdv-eyebrow {
  color: var(--purple);
}

.mdv-section__head {
  max-width: var(--wrap-narrow);
  margin-bottom: var(--space-xl);
}

/* A second heading within one section, where two related blocks share a
   ground (recently traveled and client testimonials, for instance). */
.mdv-section__head--repeat {
  margin-top: var(--space-2xl);
}

.mdv-section__title {
  font-size: var(--step-4);
}

.mdv-section__intro {
  margin-top: var(--space-s);
  max-width: var(--measure);
  font-size: var(--step-1);
  line-height: 1.6;
}

.mdv-ground--plum .mdv-section__intro {
  color: rgba(240, 247, 240, 0.82);
}

.mdv-ground--light .mdv-section__intro,
.mdv-ground--mint .mdv-section__intro {
  color: var(--ink-soft);
}

/* The hairline that separates major movements of the page. Gold at low
   opacity so it reads as a frame edge rather than a border. */
.mdv-rule {
  width: 100%;
  height: var(--rule);
  border: 0;
  margin: 0;
  background: linear-gradient(
    to right,
    transparent,
    rgba(240, 179, 29, 0.55) 20%,
    rgba(240, 179, 29, 0.55) 80%,
    transparent
  );
}

/* A section that opens with a rule drops its own top padding, otherwise the
   section padding and the rule's margin stack into a large dead band. */
.mdv-section--ruled {
  padding-top: 0;
}

.mdv-rule--spaced {
  margin-bottom: var(--space-2xl);
}

/* Inline call to action sitting at the end of a prose column. */
.mdv-cta-inline {
  margin-top: var(--space-m);
}

.mdv-section__intro--flush {
  margin-top: 0;
}

address {
  font-style: normal;
}

/* ==========================================================================
   5. Components
   ========================================================================== */

/* --- Buttons -------------------------------------------------------------
   Gold fill carries plum text, never white. Gold on mint or paper fails
   contrast for text, so gold is only ever a fill on light grounds. */

.mdv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: 3rem;
  padding: 0.9rem 1.9rem;
  border: var(--rule) solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), color 0.25s var(--ease),
    border-color 0.25s var(--ease), transform 0.25s var(--ease);
}

.mdv-btn--primary {
  background: var(--gold);
  color: var(--plum);
  border-color: var(--gold);
}

.mdv-btn--primary:hover {
  background: #ffc63f;
  border-color: #ffc63f;
  transform: translateY(-2px);
}

/* Solid plum, for a call to action on a light ground.
   The gold primary cannot do this job in the header: gold against the light
   bar measures 1.77:1, so the button's own edge would be under the 3:1 a
   control boundary needs. Plum on paper measures 16.37:1, and mint on plum
   15.97:1 for the label. It also echoes the dark button on the live site. */
.mdv-btn--solid {
  background: var(--plum);
  color: var(--mint);
  border-color: var(--plum);
}

.mdv-btn--solid:hover {
  background: var(--purple);
  border-color: var(--purple);
  transform: translateY(-2px);
}

/* Secondary on a dark ground */
.mdv-btn--ghost {
  background: transparent;
  color: var(--mint);
  border-color: rgba(240, 247, 240, 0.45);
}

.mdv-btn--ghost:hover {
  border-color: var(--mint);
  background: rgba(240, 247, 240, 0.08);
  transform: translateY(-2px);
}

/* Secondary on a light ground */
/* Border alpha is 0.55, not a lighter value: a component boundary needs 3:1
   and 0.35 measured only 2.20:1 against the paper ground. 0.55 gives 3.89:1. */
.mdv-btn--outline {
  background: transparent;
  color: var(--plum);
  border-color: rgba(41, 16, 45, 0.55);
}

.mdv-btn--outline:hover {
  border-color: var(--plum);
  background: rgba(41, 16, 45, 0.05);
  transform: translateY(-2px);
}

/* Text link with a gold underline that draws in on hover. */
.mdv-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding-block: 0.35em;
  color: inherit;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  background-image: linear-gradient(var(--gold), var(--gold));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% var(--rule);
  transition: background-size 0.3s var(--ease);
}

.mdv-link:hover {
  background-size: 100% var(--rule);
}

.mdv-link__arrow {
  transition: transform 0.3s var(--ease);
}

.mdv-link:hover .mdv-link__arrow {
  transform: translateX(4px);
}

/* --- Media frame ---------------------------------------------------------
   Every image sits on a plum to purple gradient. When photography is dropped
   into images/ it covers the gradient. Until then, and if a file is ever
   missing, the gradient reads as an intentional ground. */

/* The placeholder gradient starts at royal purple rather than deep plum.
   Six image slots all rendering as near-black plum made the page read far
   heavier than the section grounds alone account for. This keeps the slots
   on brand while sitting distinctly lighter than the plum around them. */
.mdv-media {
  position: relative;
  overflow: hidden;
  background: linear-gradient(150deg, var(--purple) 0%, var(--magenta) 72%, #d9a2c6 125%);
  border-radius: var(--radius);
}

.mdv-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(27, 10, 30, 0.28), transparent 60%);
  pointer-events: none;
}

.mdv-media__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mdv-media--portrait {
  aspect-ratio: 4 / 5;
}

.mdv-media--landscape {
  aspect-ratio: 3 / 2;
}

/* --- Placard -------------------------------------------------------------
   The signature device. Museum wall text for a journey: where it goes, when
   it runs, how long it lasts. Order is fixed so the eye learns it once and
   then reads every card the same way. */

/* A two-column grid, not a wrapping flex row. Flex let a long value push the
   next label up onto the same line, so "Ghana" and "When" ran together and
   the pattern stopped being scannable. The grid keeps every label in column
   one and every value in column two, on every card, at every width. */
.mdv-placard {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.4rem 1.25rem;
  padding-top: var(--space-xs);
  border-top: var(--rule) solid rgba(240, 179, 29, 0.5);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  line-height: 1.4;
  text-transform: uppercase;
}

.mdv-placard__term {
  grid-column: 1;
  font-weight: 500;
  color: var(--gold);
}

.mdv-placard__value {
  grid-column: 2;
  color: rgba(240, 247, 240, 0.78);
}

/* Placard on a light ground. The default gold label measures 1.72:1 against
   mint, so it cannot carry text there. Purple gives 9.21:1 and the value
   colour 7.85:1. */
.mdv-placard--light {
  border-top-color: var(--mint-shade);
}

.mdv-placard--light .mdv-placard__term {
  color: var(--purple);
}

.mdv-placard--light .mdv-placard__value {
  color: var(--ink-soft);
}

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

.mdv-grid {
  display: grid;
  gap: var(--space-l);
}

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

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

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

/* Row alignment across cards.
   Card titles wrap to different line counts, which left every following row
   ragged. Subgrid hands the card's rows back to the parent grid so titles,
   placards, and descriptions line up across the whole row. Browsers without
   subgrid fall back to the ordinary stacked layout, which is untidy but not
   broken. */
@supports (grid-template-rows: subgrid) {
  .mdv-grid--services {
    grid-template-rows: auto auto;
  }

  .mdv-grid--services .mdv-service {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    gap: var(--space-xs);
  }

  .mdv-grid--journeys {
    grid-template-rows: auto auto auto auto;
  }

  .mdv-grid--journeys .mdv-journey {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
  }
}

/* --- Service card, with imagery ------------------------------------------
   Used on the homepage and the services index, where each service carries a
   photograph. The text-only .mdv-service below is a different thing: it is
   for qualification lists inside a page, where an image would be noise. */

.mdv-svc {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.mdv-svc__media {
  aspect-ratio: 3 / 2;
}

/* Square, to match the Canva covers in Drive, which are 800 x 800. */
.mdv-svc__media--square {
  aspect-ratio: 1 / 1;
}


/* Calendly's inline widget. Their script sets the height itself once it
   boots, so this is only a floor: it stops the space collapsing while the
   script loads, and leaves something sensible behind if the script is
   blocked entirely. Calendly draws its own card, so nothing is added here. */
.mdv-calendly {
  min-width: 320px;
  /* Both height and min-height on purpose. Calendly's embed is documented with
     a definite height and their script writes an inline one of its own; height
     gives it the definite box it expects, and min-height is the floor that
     inline value cannot shrink past. With neither, the box collapses and the
     calendar ends up scrolling inside a sliver. */
  height: 44rem;
  min-height: 44rem;
}

@media (max-width: 48rem) {
  .mdv-calendly {
    height: 58rem;
    min-height: 58rem;
  }
}

/* --- Deadline notice -----------------------------------------------------
   For a departure whose booking window is genuinely closing. Carries a
   worded label as well as the gold rule, so the urgency does not depend on
   colour alone. Use it sparingly: a banner on every trip stops being a
   signal and becomes decoration. */

.mdv-notice {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-m);
  align-items: baseline;
  padding: var(--space-s) var(--space-m);
  border-left: 3px solid var(--gold);
  background: rgba(240, 179, 29, 0.1);
  border-radius: var(--radius);
}

.mdv-ground--plum .mdv-notice {
  background: rgba(240, 179, 29, 0.14);
}

.mdv-notice__label {
  flex: none;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--purple);
}

.mdv-ground--plum .mdv-notice__label {
  color: var(--gold);
}

.mdv-notice__text {
  flex: 1 1 20rem;
  color: var(--ink-soft);
}

.mdv-ground--plum .mdv-notice__text {
  color: rgba(240, 247, 240, 0.85);
}

.mdv-svc__title {
  font-size: var(--step-2);
}

.mdv-svc__title a {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--purple), var(--purple));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% var(--rule);
  transition: background-size 0.3s var(--ease);
}

.mdv-svc__title a:hover {
  background-size: 100% var(--rule);
}

.mdv-svc__text {
  color: var(--ink-soft);
}

.mdv-ground--plum .mdv-svc__text {
  color: rgba(240, 247, 240, 0.78);
}

/* Row alignment across the grid, so media, titles, and blurbs line up even
   when the titles wrap to different line counts. */
/* The span must match the number of children in the card, or the extra child
   lands in a row already occupied and the two overlap. Three children (media,
   title, text) use --svc; four (media, title, placard, text) use --svc4. */
@supports (grid-template-rows: subgrid) {
  .mdv-grid--svc {
    grid-template-rows: auto auto auto;
  }

  .mdv-grid--svc .mdv-svc {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
    gap: var(--space-s);
  }

  .mdv-grid--svc4 {
    grid-template-rows: auto auto auto auto;
  }

  .mdv-grid--svc4 .mdv-svc {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    gap: var(--space-s);
  }

  .mdv-grid--svc5 {
    grid-template-rows: auto auto auto auto auto;
  }

  .mdv-grid--svc5 .mdv-svc {
    display: grid;
    grid-row: span 5;
    grid-template-rows: subgrid;
    gap: var(--space-s);
  }
}

/* Service card. No icons: the brand brief rules out generic travel icons,
   so the hierarchy is carried by a rule and type alone. */
.mdv-service {
  padding-top: var(--space-s);
  border-top: var(--rule) solid var(--mint-shade);
}

.mdv-service__title {
  font-size: var(--step-2);
  margin-bottom: var(--space-xs);
}

.mdv-service__text {
  color: var(--ink-soft);
}

/* Journey card */
.mdv-journey {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.mdv-journey__media {
  aspect-ratio: 4 / 5;
}

.mdv-journey__title {
  font-size: var(--step-2);
}

.mdv-journey__title a {
  color: inherit;
  text-decoration: none;
}

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

/* Full body size, not the small step. At 375px the small step lands near
   13px, which is under the readable floor for running text. */
.mdv-journey__text {
  color: rgba(240, 247, 240, 0.75);
  font-size: var(--step-0);
  line-height: 1.6;
}

/* --- Featured journey ----------------------------------------------------
   The next departure gets a wide card instead of a place in the grid. When a
   trip is weeks rather than months away, it should not have to compete with
   three others for attention. */

/* Stack for more than one open departure. */
.mdv-features {
  display: grid;
  gap: var(--space-2xl);
}

.mdv-feature {
  display: grid;
  grid-template-columns: 6fr 5fr;
  gap: var(--space-xl);
  align-items: center;
}

/* Alternates the image to the other side, so two feature cards in a row read
   as a rhythm rather than as the same block printed twice. */
.mdv-feature--flip {
  grid-template-columns: 5fr 6fr;
}

.mdv-feature--flip .mdv-feature__media {
  order: 2;
}

/* Square, matching the Canva covers. The covers carry the trip name and dates
   inside the artwork, so the box has to match the file exactly or the design
   gets sliced. Every cover is 1:1, so every slot is 1:1 and nothing crops. */
.mdv-feature__media {
  aspect-ratio: 1 / 1;
}

.mdv-feature__title {
  margin-block: var(--space-xs) var(--space-s);
  font-size: var(--step-4);
}

.mdv-feature__text {
  margin-bottom: var(--space-m);
  color: rgba(240, 247, 240, 0.82);
  font-size: var(--step-1);
  line-height: 1.6;
}

.mdv-feature__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-m);
}

/* Status line. Carries a text label as well as a color, because color alone
   must never be the only thing communicating meaning. */
.mdv-status {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
}

.mdv-status__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--gold);
  flex: none;
}

/* --- Recently traveled ---------------------------------------------------
   Completed journeys are evidence, not inventory. They stay on the page as
   proof of where MDV has actually taken people, deliberately quiet: no
   images, no calls to action, nothing that competes with a departure a
   visitor can still book. */

.mdv-recent {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-m) var(--space-l);
}

.mdv-recent__item {
  padding-top: var(--space-xs);
  border-top: var(--rule) solid var(--mint-shade);
}

.mdv-recent__title {
  font-size: var(--step-1);
  margin-bottom: 0.35rem;
}

.mdv-recent__meta {
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Reason column in the difference section.
   This section sits on a light ground so that the two long dark blocks either
   side of it, the group experiences above and the closing call to action
   below, do not run together into one unbroken stretch of plum. */
.mdv-reason {
  padding-top: var(--space-s);
  border-top: var(--rule) solid var(--mint-shade);
}

.mdv-reason__title {
  margin-bottom: var(--space-xs);
  font-size: var(--step-2);
}

.mdv-reason__text {
  color: var(--ink-soft);
}

/* --- Process steps -------------------------------------------------------
   Numbered because this genuinely is a sequence: the order is the
   information. A traveler cannot reach a proposal before a consultation. */

.mdv-steps {
  display: grid;
  gap: 0;
  counter-reset: step;
}

.mdv-step {
  display: grid;
  grid-template-columns: 5rem 1fr;
  gap: var(--space-m);
  align-items: start;
  padding-block: var(--space-m);
  border-top: var(--rule) solid var(--mint-shade);
}

.mdv-step:last-child {
  border-bottom: var(--rule) solid var(--mint-shade);
}

.mdv-step__num {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1;
  color: var(--magenta);
}

.mdv-step__title {
  margin-bottom: var(--space-2xs);
  font-size: var(--step-2);
}

.mdv-step__text {
  max-width: 54ch;
  color: var(--ink-soft);
}

/* --- Testimonials -------------------------------------------------------- */

.mdv-quote {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding-top: var(--space-s);
  border-top: var(--rule) solid var(--mint-shade);
  margin: 0;
}

.mdv-quote__text {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.35;
}

/* The quote takes the slack so the three attributions sit on one line across
   the row, however unequal the quotes above them are. Doing it here rather
   than with margin-top:auto on the caption keeps the gap between quote and
   attribution identical in every card. */
.mdv-quote__text {
  flex: 1;
}

.mdv-quote__by {
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}


/* --- Form ---------------------------------------------------------------- */

.mdv-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-m);
}

.mdv-field {
  flex: 1 1 18rem;
}

/* Holds the submit control level with the bottom of the input beside it. */
.mdv-field--action {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
}

.mdv-field__label {
  display: block;
  margin-bottom: var(--space-2xs);
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}

.mdv-field__input {
  width: 100%;
  min-height: 3rem;
  padding: 0.85rem 1rem;
  background: rgba(240, 247, 240, 0.06);
  border: var(--rule) solid rgba(240, 247, 240, 0.35);
  border-radius: var(--radius);
  color: var(--mint);
  font-family: var(--font-body);
  font-size: var(--step-0);
}

.mdv-field__input::placeholder {
  color: rgba(240, 247, 240, 0.5);
}

.mdv-field__input:focus {
  border-color: var(--gold);
}

.mdv-form__note {
  flex: 1 1 100%;
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: rgba(240, 247, 240, 0.62);
}

/* ==========================================================================
   6. Sections
   ========================================================================== */

/* --- Header --------------------------------------------------------------
   One row: three navigation items, the logo, three more, and the call to
   action at the right.

   The two halves are separate lists either side of a fixed spacer, each
   flexing to the same width. That is what keeps the logo optically centered:
   the left half ("About Services Experiences") and the right half
   ("Destinations Blog Plan With Us") are different lengths, so centering a
   single list would have pushed the middle off center by about 18px. Equal
   flex columns put the spacer exactly on the centerline, and the logo is
   absolutely positioned to that same line.

   Social links are not in this row. They are in the footer and in the mobile
   panel. A header is for moving people further into the site, and there was
   no room for them without crowding the navigation.
   ========================================================================== */

.mdv-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(250, 247, 250, 0.94);
  backdrop-filter: blur(10px);
  border-bottom: var(--rule) solid var(--mint-shade);
  color: var(--ink);
}

.mdv-header__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  /* The logo is out of flow, so the row needs its own height to hold it. */
  min-height: 7rem;
  transition: min-height 0.3s var(--ease);
}

/* --- Brand lockup --------------------------------------------------------
   Pinned to the centerline of the header rather than placed in the flow, so
   nothing either side of it can shift it off center.

   The CSS fallback lockup below only appears if the logo file is missing.
   Its wordmark uses royal purple rather than the gold of the printed logo:
   gold measures 1.77:1 against this light bar, under the 4.5:1 live text
   requires. An uploaded logo image is exempt under the WCAG logotype
   exception, so the real file keeps its gold. */

.mdv-brand {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  color: var(--plum);
  text-decoration: none;
  text-align: center;
}

.mdv-brand__logo {
  display: none;
  max-height: 6.25rem;
  width: auto;
  transition: max-height 0.3s var(--ease);
}

.mdv-brand.has-logo .mdv-brand__logo {
  display: block;
}

.mdv-brand.has-logo .mdv-brand__lockup {
  display: none;
}

.mdv-brand__lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.mdv-brand__mark {
  display: grid;
  place-items: center;
  width: 2.85rem;
  height: 2.85rem;
  border-radius: 50%;
  background: var(--plum);
  color: var(--gold);
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: 0.06em;
  line-height: 1;
}

.mdv-brand__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.mdv-brand__sub {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  color: var(--purple);
  line-height: 1;
}

/* --- Navigation ---------------------------------------------------------- */

.mdv-nav {
  display: flex;
  align-items: center;
  width: 100%;
  /* Reserves room for the call to action on the right, and the same amount on
     the left so the centerline does not move. */
  padding-inline: 10rem;
}

.mdv-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin: 0;
  padding: 0;
  list-style: none;
  flex: 1;
  min-width: 0;
}

.mdv-nav__list--start {
  justify-content: flex-end;
}

.mdv-nav__list--end {
  justify-content: flex-start;
}

/* The gap the logo sits in. The logo's wordmark is about 164px wide, so this
   leaves roughly 30px of air either side of it. */
.mdv-nav__well {
  flex: none;
  width: 14rem;
}

.mdv-nav__link {
  display: block;
  padding-block: 0.65rem;
  color: var(--ink);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-decoration: none;
  white-space: nowrap;
  background-image: linear-gradient(var(--purple), var(--purple));
  background-repeat: no-repeat;
  background-position: 50% calc(100% - 0.35rem);
  background-size: 0% var(--rule);
  transition: background-size 0.3s var(--ease), color 0.25s var(--ease);
}

.mdv-nav__link:hover {
  background-size: 100% var(--rule);
}

/* Current page marked with an underline, as on the live site, and with
   aria-current in the markup so it is not signalled by styling alone. */
.mdv-nav__link[aria-current='page'] {
  background-size: 100% var(--rule);
  color: var(--plum);
}

.mdv-nav__cta {
  position: absolute;
  /* Matches the wrap's own gutter. At right:0 the button sat flush against
     the viewport edge, since absolute offsets resolve to the padding box. */
  right: var(--space-s);
  top: 50%;
  transform: translateY(-50%);
  min-height: 2.75rem;
  padding: 0.65rem 1.35rem;
  white-space: nowrap;
}

/* The call to action and social links are repeated inside the drop panel for
   small screens. On a wide screen the panel copies stay hidden. */
.mdv-nav .mdv-nav__cta,
.mdv-nav .mdv-social {
  display: none;
}

/* --- Social --------------------------------------------------------------
   Footer and mobile panel only. Each control is a 44px square so it clears
   the tap target minimum even though the glyph inside is small. */

.mdv-social {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mdv-social a {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: var(--ink);
  transition: color 0.25s var(--ease), background-color 0.25s var(--ease);
}

.mdv-social a:hover {
  color: var(--purple);
  background: rgba(104, 38, 110, 0.09);
}

.mdv-social svg {
  width: 1.2rem;
  height: 1.2rem;
}

/* --- Compact state -------------------------------------------------------
   The row tightens once the page scrolls, so a tall centered lockup does not
   hold the top of the viewport for the whole visit. */

.mdv-header.is-compact .mdv-header__inner {
  min-height: 5.25rem;
}

.mdv-header.is-compact .mdv-brand__logo {
  max-height: 4.25rem;
}

.mdv-header.is-compact .mdv-brand__mark {
  width: 2.1rem;
  height: 2.1rem;
  font-size: 0.85rem;
}

.mdv-header.is-compact .mdv-brand__sub {
  display: none;
}

/* --- Burger --------------------------------------------------------------- */

.mdv-burger {
  display: none;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: transparent;
  /* 0.55, not lighter: this is the only visible boundary of the control and
     needs 3:1. At 0.30 it measured 1.93:1 against the light bar. */
  border: var(--rule) solid rgba(41, 16, 45, 0.55);
  border-radius: var(--radius);
  cursor: pointer;
}

.mdv-burger__bar {
  display: block;
  width: 1.15rem;
  height: 1.5px;
  margin-inline: auto;
  background: var(--plum);
  transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}

.mdv-burger[aria-expanded='true'] .mdv-burger__bar:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.mdv-burger[aria-expanded='true'] .mdv-burger__bar:nth-child(2) {
  opacity: 0;
}

.mdv-burger[aria-expanded='true'] .mdv-burger__bar:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* --- Hero ----------------------------------------------------------------
   The thesis of the page. One statement, one primary action, and the placard
   introduced immediately so the gallery logic is established before the
   visitor reaches the journeys. */

.mdv-hero {
  position: relative;
  display: flex;
  align-items: flex-start;
  min-height: min(92vh, 54rem);
  padding-block: var(--space-l) var(--space-xl);
  background: var(--plum);
  color: var(--mint);
  overflow: hidden;
}

/* The gradient only shows if the photograph is missing. */
.mdv-hero__bg {
  position: absolute;
  inset: 0;
  background: linear-gradient(155deg, var(--plum-deep) 0%, var(--purple) 68%, var(--magenta) 125%);
}

/* Scrim, shaped rather than flat.
   A wash dark enough for the type, applied across the whole frame, dulls the
   photograph everywhere including the parts carrying no text. So the darkness
   is pooled where the words actually are and the rest of the image is left
   close to untouched.

   Layer one is a large, heavily feathered ellipse centered on the text block.
   It reads as light falloff rather than a panel because it never presents an
   edge. Layer two is a faint wash along the bottom so the lower edge of the
   frame does not compete with the buttons.

   The values are measured, not judged by eye. See the figures recorded in
   docs/homepage-copy.md; the binding constraint is the gold eyebrow, which
   needs 4.5:1 like any other text. */
.mdv-hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      56% 46% at 76% 20%,
      rgba(27, 10, 30, 0.92) 0%,
      rgba(27, 10, 30, 0.84) 38%,
      rgba(27, 10, 30, 0.54) 66%,
      rgba(27, 10, 30, 0.18) 87%,
      rgba(27, 10, 30, 0) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(27, 10, 30, 0.24) 0%,
      rgba(27, 10, 30, 0.08) 30%,
      rgba(27, 10, 30, 0) 55%
    );
}

/* Focal point favors the vehicle and the travelers in it. On a phone the crop
   is severe, and people are what the brand brief asks the imagery to carry. */
.mdv-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 42% 55%;
  /* Norman asked for a brighter hero, August 5, 2026. Most of the gain came
     from moving the paragraph and buttons off the image so the scrim could
     shrink; this is the remaining lift, kept small so the savannah does not
     go chalky. Contrast was re-measured after both changes. */
  filter: brightness(1.1) saturate(1.04);
}

.mdv-hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
}

/* Headline right, per Norman, August 5, 2026. A max-width rather than a grid
   column so the block keeps a sensible measure at any viewport, and margin-left
   auto rather than text-align so the type stays left-aligned within itself. */
.mdv-hero__block {
  max-width: 30rem;
  margin-left: auto;
}

/* White, not the gold used on the flat dark grounds elsewhere.
   Gold has a high relative luminance, so over a photograph it needs a much
   darker backdrop than white does to clear 4.5:1. Keeping it gold here meant
   dimming the whole image to serve one small line of type. White lifts that
   constraint and lets the photograph stay bright, which is the point of using
   it. The gold still carries the primary button directly below. */
.mdv-hero .mdv-eyebrow {
  color: rgba(240, 247, 240, 0.92);
  /* Fits one line on desktop. On a phone it has to wrap, and without this it
     drops "masterpiece" onto a line by itself; balancing evens the two lines
     instead. No max-width, so the wrap is driven by the viewport alone. */
  text-wrap: balance;
}

/* Two lines at different scales. The live site sets "Experiences" in a script
   face; that is held back here because the brand brief rules out adding more
   typefaces, so the contrast is carried by size instead. Both lines stay in
   Forum. See docs/homepage-copy.md for the script alternative. */
.mdv-hero__title {
  max-width: 20ch;
  font-size: var(--step-5);
  line-height: 1.02;
}

.mdv-hero__title-lead {
  display: block;
  font-size: 0.46em;
  letter-spacing: 0.01em;
  color: rgba(240, 247, 240, 0.9);
}

.mdv-hero__title-main {
  display: block;
  margin-top: 0.06em;
  /* Optical alignment: the opening quotation mark on the line above hangs
     left of the text, so this nudges across to line the two up by eye. */
  margin-left: 0.06em;
}

.mdv-hero__text {
  margin-top: var(--space-m);
  max-width: 52ch;
  font-size: var(--step-1);
  line-height: 1.6;
  color: rgba(240, 247, 240, 0.86);
}

.mdv-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-l);
}

/* --- Intro ---------------------------------------------------------------
   Two columns: the statement on the left, the plain explanation on the right.
   The split is the point, aspiration and practicality sitting side by side. */

.mdv-intro__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xl);
  align-items: start;
}

.mdv-intro__title {
  font-size: var(--step-4);
  max-width: 16ch;
}

.mdv-intro__body > * + * {
  margin-top: var(--space-s);
}

.mdv-intro__body {
  color: var(--ink-soft);
  font-size: var(--step-1);
  line-height: 1.6;
}

.mdv-ground--plum .mdv-intro__body {
  color: rgba(240, 247, 240, 0.86);
}

.mdv-ground--plum .mdv-intro__body a {
  color: var(--mint);
  text-decoration-color: var(--gold);
  text-underline-offset: 0.2em;
}

.mdv-intro__cta {
  margin-top: var(--space-m);
}

/* --- Journeys ------------------------------------------------------------ */

.mdv-journeys__foot {
  margin-top: var(--space-xl);
  text-align: center;
}

/* --- Founder ------------------------------------------------------------- */

.mdv-founder__grid {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: var(--space-xl);
  align-items: center;
}

.mdv-founder__body > * + * {
  margin-top: var(--space-s);
}

.mdv-founder__quote {
  margin: var(--space-m) 0 0;
  padding-left: var(--space-s);
  border-left: 2px solid var(--gold);
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.35;
}

/* The bio around the quote is third person and the quote is first person, so
   the attribution is doing real work: it marks who is suddenly speaking. */
.mdv-founder__cite {
  margin-top: var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-style: normal;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

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

/* Three columns, the middle one sticky. As the page scrolls the outer columns
   travel while the centre holds, which is the entire effect. It is ordinary
   position:sticky: no library, no scroll hijacking, nothing to load.

   Deliberately not smooth-scrolled. A smooth-scroll library overrides the
   scroll physics people already know, and on a site aiming for calm that is a
   cost with no matching benefit. */
.mdv-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-xs);
  align-items: start;
}

.mdv-gallery__col {
  display: grid;
  gap: var(--space-xs);
}

.mdv-gallery__col--sticky {
  position: sticky;
  top: var(--space-xs);
  height: calc(100vh - var(--space-m));
  grid-template-rows: repeat(3, 1fr);
}

.mdv-gallery__item {
  margin: 0;
  overflow: hidden;
  background: linear-gradient(150deg, var(--purple), var(--magenta));
}

.mdv-gallery__img {
  display: block;
  width: 100%;
  height: 27rem;
  object-fit: cover;
}

/* The sticky column's three images share the viewport height between them
   rather than taking a fixed height like the scrolling columns. */
.mdv-gallery__col--sticky .mdv-gallery__item {
  height: 100%;
}

.mdv-gallery__col--sticky .mdv-gallery__img {
  height: 100%;
}

/* Below 60rem the sticky column has nothing useful to hold against, so the
   effect is dropped. All three columns become display:contents so that every
   figure is promoted to a direct grid item and the photographs run as one
   plain mosaic. Flattening only the middle column, which was the first
   attempt, leaves two column containers and three loose figures fighting for
   the same two tracks. */
@media (max-width: 60rem) {
  .mdv-gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  .mdv-gallery__col,
  .mdv-gallery__col--sticky {
    display: contents;
  }

  .mdv-gallery__col--sticky {
    position: static;
  }

  .mdv-gallery__img,
  .mdv-gallery__col--sticky .mdv-gallery__img {
    height: 20rem;
  }

  .mdv-gallery__col--sticky .mdv-gallery__item {
    height: auto;
  }
}

@media (max-width: 34rem) {
  .mdv-gallery {
    grid-template-columns: 1fr;
  }

  .mdv-gallery__img,
  .mdv-gallery__col--sticky .mdv-gallery__img {
    height: 15rem;
  }
}

/* The thumbnail is a real button so it is reachable by keyboard and announced
   as something you can act on. Stripped back to look exactly like the image
   it wraps. */
.mdv-gallery__open {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  color: inherit;
  font: inherit;
}

.mdv-gallery__open:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: -4px;
}

/* --- Lightbox ------------------------------------------------------------ */

.mdv-lightbox {
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgba(15, 5, 17, 0.94);
  color: var(--mint);
  --focus: var(--gold);
}

.mdv-lightbox::backdrop {
  background: rgba(15, 5, 17, 0.8);
}

.mdv-lightbox[open] {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-m);
}

.mdv-lightbox__frame {
  margin: 0;
  display: grid;
  gap: var(--space-s);
  justify-items: center;
  min-width: 0;
}

.mdv-lightbox__img {
  display: block;
  max-width: 100%;
  /* Room for the caption and the padding, so a tall picture never pushes the
     caption off the bottom of the screen. */
  max-height: calc(100dvh - 9rem);
  object-fit: contain;
  transition: opacity 0.25s var(--ease);
}

.mdv-lightbox.is-loading .mdv-lightbox__img {
  opacity: 0.55;
}

.mdv-lightbox__caption {
  max-width: 60ch;
  text-align: center;
  font-size: var(--step--1);
  line-height: 1.5;
  color: rgba(240, 247, 240, 0.78);
}

.mdv-lightbox__nav,
.mdv-lightbox__close {
  display: grid;
  place-content: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1px solid rgba(240, 247, 240, 0.28);
  border-radius: 50%;
  background: rgba(15, 5, 17, 0.5);
  color: var(--mint);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.mdv-lightbox__nav:hover,
.mdv-lightbox__close:hover {
  background: rgba(240, 247, 240, 0.14);
  border-color: rgba(240, 247, 240, 0.5);
}

.mdv-lightbox__close {
  position: absolute;
  top: var(--space-s);
  right: var(--space-s);
  z-index: 1;
}

@media (max-width: 40rem) {
  .mdv-lightbox[open] {
    padding: var(--space-s);
    gap: var(--space-2xs);
  }

  .mdv-lightbox__nav,
  .mdv-lightbox__close {
    width: 2.75rem;
    height: 2.75rem;
  }

  .mdv-lightbox__img {
    max-height: calc(100dvh - 11rem);
  }
}

/* --- Community and final call ------------------------------------------- */

.mdv-community__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xl);
  align-items: center;
}

.mdv-final {
  text-align: center;
}

.mdv-final__title {
  margin-inline: auto;
  max-width: 14ch;
  font-size: var(--step-5);
}

.mdv-final__text {
  margin: var(--space-m) auto 0;
  max-width: 46ch;
  font-size: var(--step-1);
  color: rgba(240, 247, 240, 0.82);
}

.mdv-final__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  justify-content: center;
  margin-top: var(--space-l);
}

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

.mdv-footer {
  padding-block: var(--space-xl) var(--space-m);
  background: var(--plum-deep);
  color: rgba(240, 247, 240, 0.75);
}

.mdv-footer__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--space-l);
}

.mdv-footer__title {
  margin-bottom: var(--space-s);
  font-size: var(--step--1);
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

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

.mdv-footer a {
  color: inherit;
  text-decoration: none;
  border-bottom: var(--rule) solid transparent;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}

/* Footer links measured 20 to 24px tall, at or under the 24px minimum, and
   sat close enough together to mis-tap on a phone. Padding lifts each target
   to roughly 40px without changing how the columns look. */
.mdv-footer__list a,
.mdv-footer__legal a {
  display: inline-block;
  padding-block: 0.45rem;
}

.mdv-footer a:hover {
  color: var(--mint);
  border-bottom-color: var(--gold);
}

.mdv-footer__brand {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--mint);
  margin-bottom: var(--space-xs);
}

.mdv-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-m);
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-xl);
  padding-top: var(--space-s);
  border-top: var(--rule) solid var(--plum-soft);
  font-size: var(--step--1);
}

.mdv-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ==========================================================================
   6b. Group trip landing page
   Components used only by the trip pages. Kept with the rest of the system so
   there is one stylesheet and one set of tokens.
   ========================================================================== */

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

.mdv-triphero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: min(80vh, 44rem);
  padding-block: var(--space-2xl) var(--space-xl);
  background: var(--plum);
  color: var(--mint);
  overflow: hidden;
}

.mdv-triphero__bg {
  position: absolute;
  inset: 0;
  background: linear-gradient(155deg, var(--plum-deep) 0%, var(--purple) 65%, var(--magenta) 125%);
}

/* The strongest part of the scrim stays behind the copy on the left, then
   falls away quickly so the moving footage remains vivid across the rest of
   the hero. A small text shadow below carries contrast through bright frames. */
.mdv-triphero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      100deg,
      rgba(27, 10, 30, 0.78) 0%,
      rgba(27, 10, 30, 0.66) 45%,
      rgba(27, 10, 30, 0.34) 72%,
      rgba(27, 10, 30, 0.16) 100%
    ),
    linear-gradient(to top, rgba(27, 10, 30, 0.32) 0%, rgba(27, 10, 30, 0.05) 60%);
}

.mdv-triphero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- Background video ----------------------------------------------------
   A YouTube embed behind the hero, muted and looping. The poster image sits
   underneath and carries the section on its own whenever the video does not
   run: reduced motion, a blocked embed, or a slow connection.

   The scaling is not the usual 16:9 cover. The source video is 3:2, so
   YouTube pillarboxes it inside a 16:9 player with bars taking 7.7% of the
   width on each side. A normal cover fit would put those black bars across
   the hero. Scaling past cover by 1.19 pushes them outside the frame.
   Measured from the poster frame: content spans 1082px of a 1280px player. */

.mdv-triphero__video {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
}

.mdv-triphero__video.is-playing {
  opacity: 1;
}

.mdv-triphero__video iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100vw;
  height: 56.25vw;
  min-width: 177.78vh;
  min-height: 100%;
  border: 0;
  transform: translate(-50%, -50%) scale(1.19);
  /* Clicks belong to the page, not to YouTube's player chrome. */
  pointer-events: none;
}

/* Auto-playing content that loops needs a way to stop it. */
.mdv-triphero__toggle {
  position: absolute;
  right: var(--space-s);
  bottom: var(--space-s);
  z-index: 3;
  display: none;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: var(--rule) solid rgba(240, 247, 240, 0.5);
  border-radius: 50%;
  background: rgba(27, 10, 30, 0.6);
  color: var(--mint);
  cursor: pointer;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.mdv-triphero__sound {
  position: absolute;
  right: calc(var(--space-s) + 3.5rem);
  bottom: var(--space-s);
  z-index: 3;
  display: none;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  padding: 0.6rem 0.85rem;
  border: var(--rule) solid rgba(240, 247, 240, 0.5);
  border-radius: 999px;
  background: rgba(27, 10, 30, 0.6);
  color: var(--mint);
  font: inherit;
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.mdv-triphero__sound.is-available {
  display: flex;
}

.mdv-triphero__sound:hover {
  background: rgba(27, 10, 30, 0.85);
  border-color: var(--mint);
}

.mdv-triphero__sound svg {
  width: 1.15rem;
  height: 1.15rem;
}

.mdv-triphero__sound .mdv-sound-waves {
  display: none;
}

.mdv-triphero__sound[aria-pressed='true'] .mdv-sound-waves {
  display: block;
}

.mdv-triphero__sound[aria-pressed='true'] .mdv-sound-muted {
  display: none;
}

.mdv-triphero__toggle.is-available {
  display: grid;
}

.mdv-triphero__toggle:hover {
  background: rgba(27, 10, 30, 0.85);
  border-color: var(--mint);
}

.mdv-triphero__toggle svg {
  width: 1rem;
  height: 1rem;
}

.mdv-triphero__toggle .mdv-icon-play {
  display: none;
}

.mdv-triphero__toggle[aria-pressed='true'] .mdv-icon-play {
  display: block;
}

.mdv-triphero__toggle[aria-pressed='true'] .mdv-icon-pause {
  display: none;
}

.mdv-triphero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
}

.mdv-triphero__title,
.mdv-triphero__placard,
.mdv-triphero .mdv-eyebrow {
  text-shadow: 0 2px 14px rgba(27, 10, 30, 0.5);
}

.mdv-triphero .mdv-eyebrow {
  color: var(--gold);
}

/* Over moving footage, the small informational type uses near-white rather
   than gold so it remains legible as the frame brightness changes. Gold still
   carries the primary button on its own solid fill. */
.mdv-triphero--video .mdv-eyebrow,
.mdv-triphero--video .mdv-placard__term {
  color: rgba(240, 247, 240, 0.92);
}

.mdv-triphero--video .mdv-placard {
  border-top-color: rgba(240, 247, 240, 0.4);
}

.mdv-triphero__title {
  max-width: 20ch;
  font-size: var(--step-5);
}

.mdv-triphero__placard {
  margin-top: var(--space-l);
  max-width: 34rem;
}

/* --- Route fork ----------------------------------------------------------
   Where an itinerary splits into two routes that rejoin later. Presented as
   two equal cards rather than tabs: both options need to be readable at once,
   because the visitor is choosing between them, not navigating. */

.mdv-fork {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-l);
}

.mdv-fork__option {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-top: var(--space-s);
  border-top: 2px solid var(--purple);
}

.mdv-fork__label {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--purple);
}

.mdv-fork__title {
  font-size: var(--step-2);
}

.mdv-fork__dates {
  font-size: var(--step--1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Price sits on the fork because that is where the decision is made. Reading
   the two routes and then hunting for the difference in a table below is work
   the page can do for the visitor instead. */
.mdv-fork__price {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.mdv-fork__text {
  color: var(--ink-soft);
}

/* --- Itinerary -----------------------------------------------------------
   Reuses the numbered step pattern from the homepage process section. Days
   are a genuine sequence, so numbering carries real information here. */

.mdv-day__num {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--purple);
  line-height: 1.6;
}

/* --- Inclusions ----------------------------------------------------------
   Two lists side by side. Each carries a heading in words, never a bare green
   tick against a red cross, so the distinction survives without color. */

.mdv-incl__title {
  margin-bottom: var(--space-s);
  padding-bottom: var(--space-xs);
  border-bottom: var(--rule) solid var(--mint-shade);
  font-size: var(--step-2);
}

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

.mdv-incl__list li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: var(--space-xs);
  color: var(--ink-soft);
}

.mdv-incl__list li::before {
  position: absolute;
  left: 0;
  font-weight: 500;
}

.mdv-incl__list--yes li::before {
  content: '+';
  color: var(--purple);
}

.mdv-incl__list--no li::before {
  content: '\2013';
  color: var(--ink-soft);
}

/* --- Pricing -------------------------------------------------------------
   A definition list rather than a table, because this is a set of labelled
   values, not a grid of data. It also reflows to one column on a phone
   without the horizontal scrolling a table would need. */

.mdv-price {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--space-xl);
  margin-top: var(--space-m);
}

/* Label above value, not label and value pushed to opposite ends of the row.
   With space-between across two narrow columns, a long value in the left
   column ended up sitting flush against the right column's label and the two
   read as one line. Stacking removes the collision at every width. */
.mdv-price__row {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding-block: var(--space-s);
  border-bottom: var(--rule) solid rgba(240, 247, 240, 0.18);
}

.mdv-price__label {
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}

.mdv-price__value {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.2;
}

.mdv-price__note {
  margin-top: var(--space-m);
  max-width: var(--measure);
  font-size: var(--step--1);
  color: rgba(240, 247, 240, 0.7);
}

/* --- FAQ -----------------------------------------------------------------
   Native details and summary: keyboard operable and expandable without any
   JavaScript. */

.mdv-faq {
  border-top: var(--rule) solid var(--mint-shade);
}

.mdv-faq__item {
  border-bottom: var(--rule) solid var(--mint-shade);
}

.mdv-faq__q {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-s);
  padding-block: var(--space-s);
  font-family: var(--font-display);
  font-size: var(--step-2);
  cursor: pointer;
  list-style: none;
}

.mdv-faq__q::-webkit-details-marker {
  display: none;
}

.mdv-faq__q::after {
  content: '+';
  font-family: var(--font-body);
  font-size: var(--step-1);
  color: var(--purple);
  flex: none;
}

.mdv-faq__item[open] .mdv-faq__q::after {
  content: '\2013';
}

.mdv-faq__a {
  max-width: var(--measure);
  padding-bottom: var(--space-m);
  color: var(--ink-soft);
}

.mdv-faq__a > * + * {
  margin-top: var(--space-s);
}

/* Lists inside an answer. The privacy policy sets out your rights as a list;
   without this they take the user agent's 40px indent and 1em margins, which
   sit oddly against the surrounding prose. */
.mdv-faq__a ul {
  margin: 0;
  padding-left: 1.15em;
  list-style: disc;
}

.mdv-faq__a li + li {
  margin-top: var(--space-2xs);
}

/* --- Fine print ---------------------------------------------------------- */

.mdv-terms {
  max-width: var(--measure);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

.mdv-terms > * + * {
  margin-top: var(--space-xs);
}

/* ==========================================================================
   6c. Form page
   A compact page head and a third party form embed.
   ========================================================================== */

/* Not a hero. The visitor came to fill in a form, so this band states where
   they are and gets out of the way. */
.mdv-pagehead {
  padding-block: var(--space-xl);
  background: var(--plum);
  color: var(--mint);
}

/* Experiences carries a photograph behind its page head. Only the eyebrow and
   the headline sit on it; the standing paragraph moved to .mdv-lede below, so
   the picture is covered by one line of type rather than six. That is what
   lets the scrim be a shallow foot wash instead of a pool over half the frame,
   which is the whole point: the faces are the reason to use this photograph. */
.mdv-pagehead--image {
  position: relative;
  display: flex;
  align-items: flex-start;
  min-height: min(92vh, 54rem);
  padding-block: var(--space-l) var(--space-2xl);
  overflow: hidden;
}

.mdv-pagehead__bg {
  position: absolute;
  inset: 0;
  background: var(--plum);
}

/* Weighted to the foot of the frame, where the words are, and clear of the
   faces above. Tuned by measuring the rendered pixels behind the type. */
.mdv-pagehead__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to bottom,
      rgba(27, 10, 30, 0.86) 0%,
      rgba(27, 10, 30, 0.76) 14%,
      rgba(27, 10, 30, 0.5) 28%,
      rgba(27, 10, 30, 0.2) 42%,
      rgba(27, 10, 30, 0) 58%
    );
}

.mdv-pagehead__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Centred on the group. They sit a little below the middle of the frame, and
     this keeps every face in shot as the viewport narrows. */
  object-position: 50% 56%;
}

.mdv-pagehead__inner {
  position: relative;
}

/* Centred above the group, per Norman, August 5, 2026. A measure rather than
   full bleed so the line breaks somewhere sensible on a narrow screen instead
   of running the full width of a desktop monitor. */
.mdv-pagehead--image .mdv-pagehead__title {
  max-width: 22ch;
  margin-inline: auto;
  text-align: center;
}

/* Left aligned variant, for heroes whose photograph is open on the left. The
   centred treatment above suits Experiences, where the group fills the frame;
   here the couple sits right and the rooftops give the type somewhere to go. */
.mdv-pagehead--start .mdv-pagehead__title {
  max-width: none;
  margin-inline: 0;
  text-align: left;
}

.mdv-pagehead--start .mdv-pagehead__block {
  max-width: 34rem;
}

/* Wash from the left rather than the top, following the type. */
.mdv-pagehead--start .mdv-pagehead__bg::after {
  background:
    radial-gradient(
      68% 108% at 16% 58%,
      rgba(27, 10, 30, 0.9) 0%,
      rgba(27, 10, 30, 0.8) 34%,
      rgba(27, 10, 30, 0.5) 62%,
      rgba(27, 10, 30, 0.16) 85%,
      rgba(27, 10, 30, 0) 100%
    ),
    linear-gradient(
      to right,
      rgba(27, 10, 30, 0.5) 0%,
      rgba(27, 10, 30, 0.2) 36%,
      rgba(27, 10, 30, 0) 60%
    );
}

.mdv-pagehead--start .mdv-pagehead__img {
  /* Favours the right of the frame so the couple survives the side crop. */
  object-position: 56% 50%;
}

/* Foot anchored variant. Some photographs are open at the bottom rather than
   the top; this one has a hundred guests filling the upper half and clean
   grass in the foreground, so the type belongs low. */
.mdv-pagehead--end {
  align-items: flex-end;
  padding-block: var(--space-2xl) var(--space-l);
}

.mdv-pagehead--end .mdv-pagehead__title {
  max-width: none;
  margin-inline: 0;
  text-align: left;
}

.mdv-pagehead--end .mdv-pagehead__block {
  max-width: 36rem;
}

/* Wash pooled at the foot, following the type, leaving the ceremony clear. */
.mdv-pagehead--end .mdv-pagehead__bg::after {
  background:
    radial-gradient(
      74% 90% at 20% 88%,
      rgba(27, 10, 30, 0.92) 0%,
      rgba(27, 10, 30, 0.84) 32%,
      rgba(27, 10, 30, 0.54) 60%,
      rgba(27, 10, 30, 0.18) 84%,
      rgba(27, 10, 30, 0) 100%
    ),
    linear-gradient(
      to top,
      rgba(27, 10, 30, 0.62) 0%,
      rgba(27, 10, 30, 0.3) 26%,
      rgba(27, 10, 30, 0) 52%
    );
}

@media (max-width: 87.49rem) {
  .mdv-pagehead--end .mdv-pagehead__block {
    max-width: none;
  }

  .mdv-pagehead--end .mdv-pagehead__bg::after {
    background: linear-gradient(
      to top,
      rgba(27, 10, 30, 0.86) 0%,
      rgba(27, 10, 30, 0.78) 44%,
      rgba(27, 10, 30, 0.5) 72%,
      rgba(27, 10, 30, 0.2) 100%
    );
  }
}

/* Below 87.5rem the pooled wash stops working, and the reason is the crop
   rather than the text. This photograph is 2:1 in a box that is roughly 1.2:1
   at 1024px, so the sides are cut hard and the open rooftops on the left are
   gone entirely; the type then sits on the bright terrace. Measured failures
   before this rule: 1.13:1 at 390px and 2.89:1 at 1024px.

   So the pool is reserved for viewports wide enough to still show the left of
   the frame, and everything narrower gets a full width wash from the top,
   which is where this hero's type sits. */
@media (max-width: 87.49rem) {
  .mdv-pagehead--start .mdv-pagehead__block {
    max-width: none;
  }

  .mdv-pagehead--start .mdv-pagehead__bg::after {
    background: linear-gradient(
      to bottom,
      rgba(27, 10, 30, 0.84) 0%,
      rgba(27, 10, 30, 0.76) 46%,
      rgba(27, 10, 30, 0.5) 74%,
      rgba(27, 10, 30, 0.22) 100%
    );
  }
}

/* The paragraph the headline used to sit on top of. Royal purple rather than
   deep plum, echoing the band on the live site without adding another heavy
   dark block to a page that already opens on one.

   Named standfirst, not lede: .mdv-lede already exists further up as a
   max-width typography utility, and reusing the name silently capped this
   band at 62ch instead of letting it span the viewport. */
.mdv-standfirst {
  padding-block: var(--space-l);
  background: var(--purple);
  color: var(--mint);
}

.mdv-standfirst__text {
  margin: 0;
  font-size: var(--step-1);
  line-height: 1.6;
}

/* The source is 4:3 rather than a wide band, so a portrait viewport can be
   covered properly and the picture stays a backdrop at every width, exactly as
   the homepage hero does it. */
@media (max-width: 47.99rem) {
  .mdv-pagehead--image {
    min-height: min(88vh, 44rem);
  }

  .mdv-pagehead--image .mdv-pagehead__title,
  .mdv-pagehead--image .mdv-pagehead__text {
    max-width: none;
  }
}

.mdv-pagehead .mdv-eyebrow {
  color: var(--gold);
}

/* Breadcrumb back to the services index, sitting in the eyebrow slot so it
   does not need a row of its own. Gold on plum measures 9.26:1.

   Padded to clear the 24px minimum tap target: at the eyebrow's size the link
   measured 79x22. The underline is drawn as a background rather than a border
   so the padding grows the hit area without pushing the rule away from the
   text. */
.mdv-pagehead__back {
  display: inline-block;
  padding-block: 0.35rem;
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(rgba(240, 179, 29, 0.5), rgba(240, 179, 29, 0.5));
  background-repeat: no-repeat;
  background-position: 0 calc(100% - 0.3rem);
  background-size: 100% var(--rule);
  transition: background-image 0.25s var(--ease);
}

.mdv-pagehead__back:hover {
  background-image: linear-gradient(var(--gold), var(--gold));
}

.mdv-pagehead__title {
  font-size: var(--step-4);
}

.mdv-pagehead__text {
  margin-top: var(--space-s);
  max-width: var(--measure);
  font-size: var(--step-1);
  line-height: 1.6;
  color: rgba(240, 247, 240, 0.85);
}

/* --- Embedded form -------------------------------------------------------
   The frame holds a page from another domain, so this stylesheet cannot
   reach inside it and its appearance is controlled by PlanItEasy. The
   container gives it a quiet, neutral surround rather than trying to compete
   with it.

   Height is set rather than fitted, because a cross-origin frame cannot be
   measured from here. Narrow screens get more height, not less: the fields
   stack, so the form grows taller as the viewport narrows. mdv.js will fit
   the frame exactly if PlanItEasy ever posts its height. */

.mdv-embed__frame-wrap {
  background: #fff;
  border: var(--rule) solid var(--mint-shade);
  border-radius: var(--radius);
  overflow: hidden;
}

/* Measured, not guessed. Rendering the PlanItEasy form on its own at this
   container width put its Submit button at about 3400px. The live site's
   embed is fixed at 2000px, which cuts off the Budget section, both
   agreement checkboxes, and the Submit button itself, leaving visitors to
   discover they must scroll inside the frame to finish. The extra height
   here trades a longer page for a form that is never truncated. */
.mdv-embed__frame {
  display: block;
  width: 100%;
  height: 3500px;
  border: 0;
}

.mdv-embed__fallback {
  margin-top: var(--space-s);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

/* Taller on a phone, not shorter: the fields stack, so the form grows as the
   viewport narrows. Measured at about 4400px at 390px wide. */
@media (max-width: 48rem) {
  .mdv-embed__frame {
    height: 4600px;
  }
}

/* ==========================================================================
   7. Motion
   Scroll reveals are additive: without JavaScript, or with reduced motion
   requested, content is simply visible.
   ========================================================================== */

.js .mdv-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

.js .mdv-reveal.is-visible {
  opacity: 1;
  transform: none;
}

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

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

  .js .mdv-reveal {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   8. Responsive
   ========================================================================== */

@media (max-width: 74rem) {
  :root {
    --space-2xl: 5rem;
    --space-xl: 3.5rem;
  }

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

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

  .mdv-intro__grid,
  .mdv-founder__grid,
  .mdv-community__grid,
  .mdv-feature,
  .mdv-feature--flip,
  .mdv-fork {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }

  /* Reset the alternation once stacked, so the image leads on both. */
  .mdv-feature--flip .mdv-feature__media {
    order: 0;
  }

  .mdv-features {
    gap: var(--space-xl);
  }

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

  .mdv-footer__grid {
    grid-template-columns: 1fr 1fr;
  }

  /* Six items plus the logo plus a button will not fit one row much below
     1150px, so the navigation collapses into a drop panel here. The burger
     takes the left, the logo stays centered, and the row keeps its height. */
  .mdv-burger {
    display: flex;
  }

  /* The top row copy of the call to action. The panel keeps its own. */
  .mdv-header__inner > .mdv-nav__cta {
    display: none;
  }

  .mdv-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-xs) var(--space-s) var(--space-s);
    background: var(--paper-soft);
    border-top: var(--rule) solid var(--mint-shade);
    border-bottom: var(--rule) solid var(--mint-shade);
    box-shadow: 0 12px 24px rgba(41, 16, 45, 0.08);
  }

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

  .mdv-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    flex: none;
  }

  /* No logo sits between the halves once they are stacked. */
  .mdv-nav__well {
    display: none;
  }

  .mdv-nav__link {
    padding-block: var(--space-xs);
    border-bottom: var(--rule) solid var(--mint-shade);
    background-image: none;
    text-align: left;
  }

  .mdv-nav__link[aria-current='page'] {
    color: var(--purple);
    font-weight: 500;
  }

  /* Both return inside the panel, where there is room for them. The call to
     action has to shed the absolute positioning it uses in the top row. */
  .mdv-nav .mdv-nav__cta {
    display: inline-flex;
    position: static;
    transform: none;
    width: 100%;
    margin-top: var(--space-s);
  }

  .mdv-nav .mdv-social {
    display: flex;
    justify-content: center;
    margin-top: var(--space-s);
  }
}

/* The hero scrim has to change shape, not just strength, on a narrow screen.
   The pooled ellipse works on desktop because the type occupies the left third
   and the photograph keeps the rest. On a phone the type spans the full width,
   so a pool centered at 15% leaves the right-hand end of every line sitting on
   bare photograph. Measured there: 2.19:1, against a 4.5:1 requirement.

   So below this width the scrim becomes a vertical wash instead: even across
   the full width where the words are, easing off toward the top so the sky and
   the horizon still read. The image is necessarily less visible here than on
   desktop, because on a phone the text covers most of it. */
@media (max-width: 63.99rem) {
  .mdv-hero__bg::after {
    background: linear-gradient(
      to bottom,
      rgba(27, 10, 30, 0.74) 0%,
      rgba(27, 10, 30, 0.66) 58%,
      rgba(27, 10, 30, 0.4) 86%,
      rgba(27, 10, 30, 0.2) 100%
    );
  }

  /* Full width once stacked; there is no right hand column on a phone. */
  .mdv-hero__block {
    max-width: none;
    margin-left: 0;
  }
}

@media (max-width: 40rem) {
  /* Text links retain the editorial look while meeting a dependable 44px
     touch target on phones. The footer also protects short labels such as
     "Shop" and "About" with a minimum inline target. */
  .mdv-link,
  .mdv-svc__title a,
  .mdv-footer__list a,
  .mdv-footer__legal a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
  }

  .mdv-footer__list a,
  .mdv-footer__legal a {
    min-width: 2.75rem;
  }

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

  .mdv-footer__grid,
  .mdv-recent,
  .mdv-price {
    grid-template-columns: 1fr;
  }

  .mdv-step {
    grid-template-columns: 1fr;
    gap: var(--space-2xs);
  }

  .mdv-hero {
    min-height: 88vh;
  }

  .mdv-hero__title {
    max-width: 100%;
  }

  .mdv-btn {
    width: 100%;
  }

  .mdv-hero__actions .mdv-btn,
  .mdv-final__actions .mdv-btn {
    width: 100%;
  }

  /* Stack the email field and its submit control. */
  .mdv-field--action {
    flex: 1 1 100%;
  }
}
/* Shop catalog */
.mdv-shop-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.mdv-product {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  background: #fff;
  border: 1px solid rgba(41, 16, 45, .14);
  box-shadow: 0 18px 45px rgba(41, 16, 45, .08);
}

.mdv-product__image-link {
  display: block;
  overflow: hidden;
  background: #f5f2f0;
  aspect-ratio: 1;
}

.mdv-product__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .45s ease;
}

.mdv-product__image-link:hover .mdv-product__image,
.mdv-product__image-link:focus-visible .mdv-product__image {
  transform: scale(1.025);
}

.mdv-product__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}

.mdv-product__type {
  margin: 0 0 .45rem;
  color: var(--gold);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.mdv-product__title {
  margin: 0;
  color: var(--plum);
  font-family: var(--font-display);
  font-size: clamp(1.55rem, 2.2vw, 2rem);
  font-weight: 400;
  line-height: 1.05;
}

.mdv-product__price {
  margin: .8rem 0 0;
  color: var(--plum);
  font-size: .9rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.mdv-product__text {
  margin: .75rem 0 1.25rem;
  color: var(--ink-soft);
}

.mdv-product__button {
  width: 100%;
  margin-top: auto;
  justify-content: center;
}

@media (max-width: 880px) {
  .mdv-shop-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .mdv-shop-grid { grid-template-columns: 1fr; }
}
