/* =============================================================================
   ONYX & OYSTER — SECTIONS
   Layout for each page component, in document order.
   ========================================================================== */


/* =============================================================================
   SHARED SECTION FURNITURE
   ========================================================================== */
.oo-section-head {
  display: flex;
  flex-direction: column;
  gap: var(--oo-space-md);
  max-width: 46rem;
  margin-block-end: var(--oo-space-2xl);
}
.oo-section-head__title { font-size: var(--oo-text-h2); }
.oo-section-head--center { margin-inline: auto; text-align: center; align-items: center; }

/* A short, centred passage of prose following a centred section head —
   used by the Partnerships introduction and the Founding Circle, both of
   which are quiet philosophy statements rather than a copy block beside a
   grid or a photograph. */
.oo-partnerships__intro { max-width: 42rem; margin-inline: auto; text-align: center; }

/* The emblem used as a quiet divider between editorial passages. */
.oo-divider {
  display: flex;
  align-items: center;
  gap: var(--oo-space-md);
  color: var(--ctx-rule);
}
.oo-divider::before,
.oo-divider::after {
  content: '';
  flex: 1;
  height: var(--oo-hairline);
  background-color: currentColor;
}
.oo-divider .oo-emblem { height: 1.125rem; }

/* Emblem set very large and very low-contrast behind a section. Decorative
   only, and hidden from assistive technology. */
.oo-watermark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: -6%;
  transform: translateY(-50%);
  width: min(46rem, 70%);
  height: auto;
  color: currentColor;
  opacity: 0.045;
  pointer-events: none;
  z-index: 0;
}


/* =============================================================================
   B. HERO
   ========================================================================== */
.oo-hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  background-color: var(--oo-onyx);
  color: var(--oo-ivory);
  --ctx-text: var(--oo-ivory);
  --ctx-muted: var(--oo-stone);
  --ctx-rule: var(--oo-rule-on-dark);
  --ctx-focus: var(--oo-focus-dark);
  --ctx-invert-bg: var(--oo-ivory);
  --ctx-invert-text: var(--oo-onyx);
}

/* --- Cinematic scroll reveal ----------------------------------------------
   The hero opens from an inset frame to full bleed as the reader scrolls, while
   the photograph zooms back to its natural crop.

   Every value below is a custom property with a resolved fallback, so the
   default state of this markup — no JavaScript, or reduced motion — is the plain
   full-bleed hero. The effect is additive; nothing depends on it running.

   scripts/hero-scroll.js writes:
     --oo-hero-inset / --oo-hero-inset-end   the frame
     --oo-hero-zoom                          the photograph
     --oo-hero-copy                          the headline block
     --oo-hero-cue                           the scroll indicator
   ------------------------------------------------------------------------- */
.oo-hero-track { position: relative; width: 100%; }

/* Pinned mode. The track is taller than the screen and the hero sticks to the
   top of it, so the frame opens against a stationary photograph rather than one
   already travelling up the page. */
.oo-hero-track.is-pinned { height: calc(100dvh + var(--oo-hero-scroll, 0px)); }
.oo-hero-track.is-pinned .oo-hero {
  position: sticky;
  top: 0;
  height: 100dvh;
  min-height: 0;
}

/* The frame clips the photograph and its scrim together, so the darkening never
   extends past the opening. */
/* The two axes are separate. Desktop insets both and reads as a frame; phones
   inset only the sides, because a vertical inset there would cut the bottom off
   the finder, which sits at the foot of a hero taller than the screen. */
.oo-hero__frame {
  position: absolute;
  inset: 0;
  clip-path: polygon(
    var(--oo-hero-inset-x, 0%)     var(--oo-hero-inset-y, 0%),
    var(--oo-hero-inset-x-end, 100%) var(--oo-hero-inset-y, 0%),
    var(--oo-hero-inset-x-end, 100%) var(--oo-hero-inset-y-end, 100%),
    var(--oo-hero-inset-x, 0%)     var(--oo-hero-inset-y-end, 100%)
  );
}

/* The photograph dims as the headline arrives, so the copy reads against a
   near-flat ground instead of competing with glassware and highlights. It fades
   toward the hero's own black, so no extra overlay is needed. */
.oo-hero__media {
  position: absolute;
  inset: 0;
  opacity: var(--oo-hero-image, 1);
}
.oo-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Scaling the element is composited. Animating background-size, which is the
     usual way this effect is written, repaints the image every frame. */
  transform: scale(var(--oo-hero-zoom, 1));
  transform-origin: 50% 50%;
}

/* Promotion is applied only while the effect is running, then dropped — a
   permanently promoted full-screen layer costs memory for no benefit. */
.oo-hero-track.is-active .oo-hero__frame { will-change: clip-path; }
.oo-hero-track.is-active .oo-hero__media img { will-change: transform; }

/* The slow drift is the fallback for when the scroll effect is not running.
   Both write to the same transform, and an animation would win over the custom
   property, so they must never be active at once. */
@media (prefers-reduced-motion: no-preference) {
  .oo-hero-track:not(.is-active) .oo-hero__media img {
    animation: oo-hero-drift 26s var(--oo-ease-inout) forwards;
  }
}
@keyframes oo-hero-drift {
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}

/* The scrim eases back as the photograph dims. Holding it at full strength over
   an already-dimmed image would crush the foot of the hero — where the finder
   sits — to solid black. */
.oo-hero__scrim {
  position: absolute;
  inset: 0;
  background: var(--oo-scrim-hero);
  opacity: var(--oo-hero-scrim, 1);
}

.oo-hero__inner {
  position: relative;
  z-index: var(--oo-z-base);
  width: 100%;
  max-width: var(--oo-container-wide);
  margin-inline: auto;
  padding: calc(var(--oo-nav-height) + var(--oo-space-2xl)) var(--oo-gutter) var(--oo-space-2xl);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex: 1;
  /* Held back while the frame is still narrow, so the headline never sits on
     the black margin outside the opening. */
  opacity: var(--oo-hero-copy, 1);
}
.oo-hero-track.is-pinned .oo-hero__inner {
  transform: translateY(calc((1 - var(--oo-hero-copy, 1)) * 20px));
}

/* Unpinned mode keeps the copy visible throughout, so it has to sit inside the
   mat rather than straddling its edge. The padding is set once from the mat's
   starting width and then left alone — tying it to the animated value would
   re-wrap the headline on every frame of the scroll. */
.oo-hero-track:not(.is-pinned) .oo-hero__inner {
  padding-inline: calc(var(--oo-gutter) + var(--oo-hero-mat-x, 0px));
}

.oo-hero__copy { max-width: 44rem; margin-block-end: var(--oo-space-2xl); }

.oo-hero__title {
  /* The vh ceiling keeps the headline, the lede, the actions and the finder
     inside the first screen on short viewports, where the vw-based clamp alone
     would push the finder below the fold. */
  font-size: min(var(--oo-text-hero), 10vh);
  line-height: 1.04;
  letter-spacing: -0.02em;
  margin-block: var(--oo-space-md) var(--oo-space-lg);
  max-width: 21ch;
}

.oo-hero__lede {
  font-size: var(--oo-text-lead);
  line-height: var(--oo-leading-relaxed);
  color: var(--oo-oyster);
  max-width: 44ch;
}

.oo-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--oo-space-md) var(--oo-space-xl);
  margin-block-start: var(--oo-space-xl);
}

.oo-hero__finder { position: relative; z-index: var(--oo-z-raised); }

/* Scroll cue. A hairline that travels its own length, on a loop.
   Set against the right edge and vertically centred rather than along the
   bottom, where the finder panel occupies the full width. */
.oo-scroll-cue {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: calc(var(--oo-gutter) * 0.5);
  transform: translateY(-50%);
  z-index: var(--oo-z-raised);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--oo-space-md);
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  text-transform: uppercase;
  color: var(--oo-stone);
  /* Carries the reader through the reveal, then hands over to the headline. */
  opacity: var(--oo-hero-cue, 1);
  transition: opacity var(--oo-dur-base) var(--oo-ease);
}
.oo-scroll-cue > span:first-child {
  writing-mode: vertical-rl;
  text-orientation: mixed;
}
.oo-scroll-cue__rail {
  position: relative;
  display: block;
  width: 1px;
  height: 52px;
  background-color: var(--oo-rule-on-dark);
  overflow: hidden;
}
.oo-scroll-cue__rail::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  height: 18px;
  background-color: var(--oo-oyster);
}
@media (prefers-reduced-motion: no-preference) {
  .oo-scroll-cue__rail::after { animation: oo-cue 2.6s var(--oo-ease-inout) infinite; }
}
@keyframes oo-cue {
  0%   { transform: translateY(-20px); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateY(52px); opacity: 0; }
}


/* =============================================================================
   C. BRAND INTRODUCTION
   ========================================================================== */
.oo-intro__grid {
  display: grid;
  grid-template-columns: 1fr 0.82fr;
  gap: clamp(2rem, 6vw, 6rem);
  align-items: center;
}
.oo-intro__copy { max-width: 34rem; }
.oo-intro__emblem { height: 2.75rem; color: var(--oo-evergreen); margin-block-end: var(--oo-space-lg); }
.oo-intro__title { margin-block: var(--oo-space-sm) var(--oo-space-lg); }
.oo-intro__media { align-self: stretch; }
.oo-intro__media .oo-media { height: 100%; min-height: 26rem; }


/* =============================================================================
   D. EXPERIENCE CATEGORIES
   ========================================================================== */
.oo-categories { position: relative; overflow: hidden; }
.oo-categories__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--oo-space-md);
  position: relative;
  z-index: var(--oo-z-base);
}


/* =============================================================================
   E. FEATURED EXPERIENCES
   ========================================================================== */
.oo-experiences__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--oo-space-xl);
  flex-wrap: wrap;
  margin-block-end: var(--oo-space-xl);
}
.oo-experiences__head .oo-section-head { margin-block-end: 0; }

.oo-experiences__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem) var(--oo-space-lg);
  margin-block-start: var(--oo-space-2xl);
}

/* The grid is a live region for the filter count, not for the cards themselves,
   so filtering is announced without reading six cards aloud each time. */
.oo-experiences__footnote {
  margin-block-start: var(--oo-space-2xl);
  padding-block-start: var(--oo-space-lg);
  border-block-start: var(--oo-hairline) solid var(--ctx-rule-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--oo-space-md);
  font-size: var(--oo-text-small);
  color: var(--ctx-muted);
}


/* =============================================================================
   F. THE DIFFERENCE — three principles
   ========================================================================== */
.oo-principles { position: relative; overflow: hidden; }
.oo-principles__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--oo-space-xl);
  position: relative;
  z-index: var(--oo-z-base);
}
.oo-principle { padding-block-start: var(--oo-space-lg); border-block-start: var(--oo-hairline) solid var(--ctx-rule); }
.oo-principle__index {
  display: block;
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  color: var(--ctx-accent);
  margin-block-end: var(--oo-space-md);
}
.oo-principle__title { font-size: var(--oo-text-h3); margin-block-end: var(--oo-space-sm); }
.oo-principle__body { color: var(--ctx-muted); font-size: var(--oo-text-small); line-height: var(--oo-leading-relaxed); }


/* =============================================================================
   PRIVATE CURATION — full-bleed photograph with a frosted panel
   ========================================================================== */
.oo-curation {
  position: relative;
  min-height: 40rem;
  display: flex;
  align-items: center;
  overflow: hidden;
  color: var(--oo-ivory);
  --ctx-text: var(--oo-ivory);
  --ctx-muted: var(--oo-stone);
  --ctx-rule: var(--oo-rule-on-dark);
  --ctx-focus: var(--oo-focus-dark);
  --ctx-accent: var(--oo-accent-on-dark);
  --ctx-invert-bg: var(--oo-ivory);
  --ctx-invert-text: var(--oo-onyx);
}
.oo-curation__media { position: absolute; inset: 0; }
.oo-curation__media img { width: 100%; height: 100%; object-fit: cover; }
.oo-curation__scrim { position: absolute; inset: 0; background: var(--oo-scrim-band); }

.oo-curation__inner {
  position: relative;
  z-index: var(--oo-z-base);
  width: 100%;
  max-width: var(--oo-container-wide);
  margin-inline: auto;
  padding-inline: var(--oo-gutter);
  padding-block: var(--oo-section-y);
}
.oo-curation__panel {
  max-width: 34rem;
  padding: clamp(1.75rem, 4vw, 3rem);
  background-color: var(--oo-glass-bg);
  border: var(--oo-hairline) solid var(--oo-glass-border);
  backdrop-filter: var(--oo-glass-blur);
  -webkit-backdrop-filter: var(--oo-glass-blur);
}
.oo-curation__title { margin-block: var(--oo-space-sm) var(--oo-space-md); }
.oo-curation__actions { margin-block-start: var(--oo-space-xl); display: flex; flex-wrap: wrap; gap: var(--oo-space-md) var(--oo-space-xl); align-items: center; }


/* =============================================================================
   G / H. PARTNER SECTIONS — shared split layout
   ========================================================================== */

/* Hotel Partnerships' Evergreen-on-Evergreen hover defect no longer needs a
   scoped fix here: .oo-theme-evergreen (base.css) sets
   --ctx-hover-bg/--ctx-hover-text to Onyx/Oyster, and the shared
   .oo-btn--primary:hover (components.css) reads those instead of a fixed
   Evergreen fill. Verified byte-identical computed styles with the old
   #hotel-partners override removed before deleting it. */
.oo-partner__grid {
  display: grid;
  /* DOM order is intro → media → value (story, visual, value, action) so
     the stacked/mobile layout below needs no reordering at all — it's
     already the right reading order. Desktop places the three blocks into
     an explicit two-column arrangement instead: media (1fr) deliberately
     wider than the copy column (0.92fr) so the photograph reads as the
     more cinematic element, with intro/value stacked in the other column.
     The reversed variant below mirrors these same two track sizes rather
     than swapping order, so media stays the larger column regardless of
     which visual side it appears on. */
  grid-template-columns: 0.92fr 1fr;
  grid-template-areas:
    "intro media"
    "value media";
  gap: clamp(1.75rem, 5vw, 5rem);
  align-items: center;
}
.oo-partner__grid--reverse {
  grid-template-columns: 1fr 0.92fr;
  grid-template-areas:
    "media intro"
    "media value";
}
.oo-partner__intro { grid-area: intro; }
.oo-partner__value { grid-area: value; }
.oo-partner__media { grid-area: media; }

.oo-partner__intro,
.oo-partner__value { max-width: 34rem; }
.oo-partner__title { margin-block: var(--oo-space-sm) var(--oo-space-lg); }

/* Local Partnerships' approved headline ("For a limited collection of
   businesses that define a destination.") is longer than Hotel's ("By
   invitation and application.") and wraps much taller than Hotel's headline
   at the shared copy-column width despite both using the same h2 styling.
   Scoped to #local-partners only via its own section id, so
   .oo-partner__grid/__intro/__title themselves (and therefore Hotel
   Partnerships, which uses the exact same classes) are completely
   unaffected. Two modest adjustments, split rather than concentrated in
   one dimension: the copy column gets a little more of the grid (media
   stays comfortably within the ~44-48% cinematic-width target, just not at
   its very widest), and the heading's own clamp ceiling comes down slightly
   — together these hold the approved wording to three lines instead of
   four at both desktop and the tablet cusp just above 1024px. */
#local-partners .oo-partner__grid { grid-template-columns: 0.82fr 1fr; }
#local-partners .oo-partner__title { font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.75rem); }
#local-partners .oo-partner__intro { max-width: 39rem; }
#local-partners .oo-partner__value { max-width: 34rem; }

.oo-partner__benefits {
  display: flex;
  flex-direction: column;
  /* Space below the list, before the note — the gap above (against the
     photo, or the intro on mobile) now comes from the grid's own gap
     instead of a duplicate top margin, since __value's first child is the
     benefit list itself. */
  margin-block-end: calc(var(--oo-space-xl) * 0.8);
}
.oo-partner__benefit {
  display: flex;
  align-items: flex-start;
  gap: var(--oo-space-md);
  /* ~30% tighter than the shared md padding, carried over from the six-row
     layout — three taller (title + description) rows still read as a
     materially shorter list than six single-line ones. */
  padding-block: calc(var(--oo-space-md) * 0.7);
  border-block-start: var(--oo-hairline) solid var(--ctx-rule);
}
.oo-partner__benefit:last-child { border-block-end: var(--oo-hairline) solid var(--ctx-rule); }
.oo-partner__benefit-index {
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  color: var(--ctx-accent);
  flex: none;
  /* Optical alignment against the title's cap-height rather than its own
     line box. */
  padding-block-start: 0.3em;
}
.oo-partner__benefit-content {
  display: flex;
  flex-direction: column;
  gap: var(--oo-space-3xs);
}
/* Small and sans (body font, not display) so the grouped-benefit title
   never competes with the serif section heading above it. */
.oo-partner__benefit-title {
  font-family: var(--oo-font-body);
  font-size: var(--oo-text-body);
  font-weight: 500;
  color: var(--ctx-text);
}
.oo-partner__benefit-desc {
  font-size: var(--oo-text-small);
  color: var(--ctx-muted);
  line-height: var(--oo-leading-relaxed);
}

/* The action block: CTA first, then the qualification note directly beneath
   it — deliberately a pair rather than two independent elements, so the
   note reads as a quiet footnote to the button rather than an interruption
   between the benefits and the action. Centered under the button (rather
   than left-aligned with the rest of the column) because a full-width
   sentence sitting flush left under an auto-width button read as
   disconnected from it on review; centering ties the two together and
   matches how the button is visually the focal point here. */
.oo-partner__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--oo-space-sm);
}

/* Annual partnership / "investment shared after qualification" —
   deliberately quiet, not another benefit row and not styled as a price or
   a disclaimer. Constrained narrower than the surrounding copy measure so
   it reads as belonging to the button above it rather than spanning the
   full column; wraps to two lines rather than stretching wide. */
.oo-partner__note {
  max-width: 20rem;
  text-align: center;
  font-size: var(--oo-text-caption);
  line-height: var(--oo-leading-normal);
  color: var(--ctx-muted);
}

/* A deliberate ratio box rather than a stretch-to-copy-height fill — the
   image's height no longer depends on how tall the benefit list happens to
   be, which is what made this column read as an elongated portrait strip.
   6:7 reads as a wider, more cinematic frame than the source photographs'
   native 4:5 while still cropping only a small margin off the top/bottom
   (object-fit handles it; focalPoint in data/site-images.js keeps the
   subject seated correctly). Unwound to 4:5 on mobile/tablet in
   responsive.css, close to the source ratio so nothing meaningful is lost
   at full width. */
.oo-partner__media .oo-media { aspect-ratio: 6 / 7; }


/* =============================================================================
   I. BRAND STORY — one large frame, two supporting
   ========================================================================== */
.oo-story { position: relative; overflow: hidden; }
.oo-story__grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
  position: relative;
  z-index: var(--oo-z-base);
}
.oo-story__copy { max-width: 34rem; }
.oo-story__title { margin-block: var(--oo-space-sm) var(--oo-space-lg); max-width: 16ch; }

.oo-story__collage {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--oo-space-md);
}
.oo-story__collage .oo-story__frame--primary { grid-column: 1 / -1; }
/* The supporting frames sit inset from the primary, so the group reads as a
   considered arrangement rather than a three-up grid. */
.oo-story__frame--support:first-of-type { margin-inline-start: clamp(0rem, 4vw, 3rem); }
.oo-story__frame--support:last-of-type  { margin-block-start: clamp(1rem, 3vw, 2.5rem); }


/* =============================================================================
   J. TESTIMONIAL
   ========================================================================== */
.oo-testimonial { text-align: center; }
.oo-testimonial__inner {
  max-width: 52rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--oo-space-lg);
}
.oo-testimonial__emblem { height: 2rem; color: var(--ctx-rule); }
.oo-testimonial__quote {
  font-family: var(--oo-font-display);
  font-size: clamp(1.375rem, 0.95rem + 1.9vw, 2.25rem);
  line-height: 1.36;
  letter-spacing: var(--oo-tracking-tight);
  text-wrap: balance;
}
.oo-testimonial__attribution {
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  text-transform: uppercase;
  color: var(--ctx-muted);
}

/* Reserved for partner marks, press and further testimonials. Left as an
   explicit, labelled placeholder rather than filled with invented logos. */
.oo-proof {
  margin-block-start: var(--oo-space-3xl);
  padding-block-start: var(--oo-space-xl);
  border-block-start: var(--oo-hairline) solid var(--ctx-rule-soft);
}
.oo-proof__label { text-align: center; margin-block-end: var(--oo-space-lg); }
.oo-proof__row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--oo-space-md);
}
.oo-proof__slot {
  aspect-ratio: 5 / 2;
  border: var(--oo-hairline) dashed var(--ctx-rule-soft);
  display: grid;
  place-items: center;
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  text-transform: uppercase;
  color: var(--ctx-rule);
}


/* =============================================================================
   K. BEGIN IN HUDSON
   ========================================================================== */
.oo-hudson {
  position: relative;
  overflow: hidden;
  color: var(--oo-ivory);
  --ctx-text: var(--oo-ivory);
  --ctx-muted: var(--oo-stone);
  --ctx-rule: var(--oo-rule-on-dark);
  --ctx-rule-soft: var(--oo-rule-on-dark-soft);
  --ctx-accent: var(--oo-accent-on-dark);
  --ctx-focus: var(--oo-focus-dark);
  --ctx-invert-bg: var(--oo-ivory);
  --ctx-invert-text: var(--oo-onyx);
  /* Completes the context so .oo-btn--ghost:hover's --ctx-bg read resolves
     instead of guaranteed-invalid — was rendering "Plan Your Visit" as
     Ivory-on-Ivory (invisible) on hover. */
  --ctx-bg: var(--oo-onyx);
  background-color: var(--oo-onyx);
}
.oo-hudson__media { position: absolute; inset: 0; }
.oo-hudson__media img { width: 100%; height: 100%; object-fit: cover; }
/* Two layers. The horizontal one carries the copy column, which sits over the
   brightest part of a lit street; the vertical one seats the band against the
   sections above and below it. */
.oo-hudson__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(0,0,0,0.90) 0%, rgba(0,0,0,0.72) 42%, rgba(0,0,0,0.42) 100%),
    linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.30) 45%, rgba(0,0,0,0.80) 100%);
}
.oo-hudson__inner { position: relative; z-index: var(--oo-z-base); }

.oo-hudson__grid {
  display: grid;
  grid-template-columns: 1fr 0.7fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
}
.oo-hudson__copy { max-width: 34rem; }
.oo-hudson__place {
  display: flex;
  align-items: center;
  gap: var(--oo-space-sm);
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  text-transform: uppercase;
  color: var(--oo-oyster);
}
.oo-hudson__place svg { width: 14px; height: 14px; }
.oo-hudson__title { margin-block: var(--oo-space-md) var(--oo-space-lg); }
.oo-hudson__actions { display: flex; flex-wrap: wrap; gap: var(--oo-space-md); margin-block-start: var(--oo-space-xl); }

.oo-hudson__aside {
  border: var(--oo-hairline) solid var(--oo-rule-on-dark);
  background-color: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.oo-hudson__aside .oo-media { aspect-ratio: 4 / 3; }
.oo-hudson__aside-body { padding: var(--oo-space-lg); }
.oo-hudson__aside-note {
  margin-block-start: var(--oo-space-md);
  padding-block-start: var(--oo-space-md);
  border-block-start: var(--oo-hairline) solid var(--oo-rule-on-dark-soft);
  font-size: var(--oo-text-caption);
  color: var(--oo-stone);
}


/* =============================================================================
   L. FINAL CALL TO ACTION
   ========================================================================== */
.oo-closing {
  position: relative;
  overflow: hidden;
  text-align: center;
  background-image: linear-gradient(180deg, var(--oo-evergreen) 0%, var(--oo-evergreen-deep) 100%);
}
.oo-closing__inner {
  position: relative;
  z-index: var(--oo-z-base);
  max-width: 48rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--oo-space-lg);
}
.oo-closing__emblem { height: 2.5rem; color: var(--oo-oyster); opacity: 0.85; }
.oo-closing__title { font-size: var(--oo-text-h1); max-width: 18ch; }
.oo-closing__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--oo-space-md) var(--oo-space-xl);
  margin-block-start: var(--oo-space-md);
}

/* Closing's Evergreen-on-Evergreen hover defect no longer needs a scoped
   fix either, for the same reason as Hotel Partnerships above (both are
   .oo-theme-evergreen). Verified byte-identical computed styles with the
   old #closing override removed before deleting it. */


/* =============================================================================
   M. FOOTER
   ========================================================================== */
.oo-footer {
  background-color: var(--oo-onyx);
  color: var(--oo-ivory);
  --ctx-text: var(--oo-ivory);
  --ctx-muted: var(--oo-stone);
  --ctx-rule: var(--oo-rule-on-dark);
  --ctx-rule-soft: var(--oo-rule-on-dark-soft);
  --ctx-focus: var(--oo-focus-dark);
  --ctx-invert-bg: var(--oo-ivory);
  --ctx-invert-text: var(--oo-onyx);
  /* Completes the context so .oo-btn--ghost:hover's --ctx-bg read resolves
     instead of guaranteed-invalid — was rendering "Join the List" as
     Ivory-on-Ivory (invisible) on hover. */
  --ctx-bg: var(--oo-onyx);
  padding-block: var(--oo-section-y-tight) var(--oo-space-xl);
}

/* --- Newsletter ------------------------------------------------------------ */
.oo-footer__signup {
  display: grid;
  grid-template-columns: 1fr 0.9fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  padding-block-end: var(--oo-space-3xl);
  border-block-end: var(--oo-hairline) solid var(--oo-rule-on-dark-soft);
}
.oo-footer__signup-title { font-size: var(--oo-text-h3); margin-block: var(--oo-space-2xs) var(--oo-space-sm); }
.oo-footer__signup-body { color: var(--oo-stone); font-size: var(--oo-text-small); max-width: 42ch; }

/* --- Brand & columns -------------------------------------------------------- */
.oo-footer__main {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  padding-block: var(--oo-space-3xl);
}
.oo-footer__brand { max-width: 26rem; }
.oo-footer__lockup { display: flex; align-items: center; gap: var(--oo-space-sm); margin-block-end: var(--oo-space-md); }
.oo-footer__lockup .oo-emblem { height: 1.5rem; }
.oo-footer__lockup .oo-wordmark { font-size: 1rem; }
.oo-footer__description { color: var(--oo-stone); font-size: var(--oo-text-small); }
.oo-footer__statement {
  margin-block-start: var(--oo-space-lg);
  font-family: var(--oo-font-display);
  font-size: var(--oo-text-h4);
  line-height: 1.42;
  color: var(--oo-oyster);
  max-width: 22ch;
}

.oo-footer__col-heading {
  margin-block-end: var(--oo-space-md);
  color: var(--oo-stone);
}
.oo-footer__col li + li { margin-block-start: var(--oo-space-2xs); }
.oo-footer__link {
  display: inline-flex;
  align-items: center;
  gap: var(--oo-space-3xs);
  min-height: 34px;
  font-size: var(--oo-text-small);
  color: var(--oo-ivory);
  opacity: 0.82;
  transition: opacity var(--oo-dur-fast) var(--oo-ease);
}
.oo-footer__link:hover { opacity: 1; text-decoration: underline; text-underline-offset: 0.28em; }
.oo-footer__link svg { width: 11px; height: 11px; opacity: 0.6; }

/* --- Legal bar --------------------------------------------------------------- */
.oo-footer__legal {
  padding-block-start: var(--oo-space-lg);
  border-block-start: var(--oo-hairline) solid var(--oo-rule-on-dark-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--oo-space-md);
  font-size: var(--oo-text-caption);
  color: var(--oo-stone);
}
.oo-footer__legal-links { display: flex; flex-wrap: wrap; gap: var(--oo-space-lg); }


/* =============================================================================
   404
   ========================================================================== */
.oo-notfound {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  text-align: center;
  background-color: var(--oo-onyx);
  color: var(--oo-ivory);
  --ctx-text: var(--oo-ivory);
  --ctx-muted: var(--oo-stone);
  --ctx-rule: var(--oo-rule-on-dark);
  --ctx-focus: var(--oo-focus-dark);
  --ctx-invert-bg: var(--oo-ivory);
  --ctx-invert-text: var(--oo-onyx);
  padding: var(--oo-space-2xl) var(--oo-gutter);
}
.oo-notfound__inner { display: flex; flex-direction: column; align-items: center; gap: var(--oo-space-lg); max-width: 34rem; }
.oo-notfound__emblem { height: 3rem; color: var(--oo-oyster); opacity: 0.7; }
.oo-notfound__code {
  font-size: var(--oo-text-label);
  letter-spacing: var(--oo-tracking-label);
  text-transform: uppercase;
  color: var(--oo-stone);
}
.oo-notfound__title { font-size: var(--oo-text-h1); }
