/* ==========================================================================
   Hammam Sables d’Or — Scroll-expand video hero

   The reference behaviour, in the house style: the still photograph is the
   ground, a small centred card of film sits on it, and as the visitor scrolls
   the card grows in BOTH axes while the two halves of the headline part and
   travel off the screen — until only the film is left.

   Driven by scroll POSITION, not intercepted wheel events. The page scrolls
   normally throughout, so keyboard, find-in-page, anchor links and scroll
   restoration all keep working. js/hero-video.js writes one custom property,
   --p (0 → 1); every value below is derived from it here in CSS.

   The booking call to action is not lost when the copy clears: RÉSERVER stays
   in the fixed header at every point of the animation.
   ========================================================================== */

.ht-vhero {
  position: relative;
  /* Fallback for no-JS and reduced motion: one screen, no runway. */
  height: 100svh;
  background: var(--ht-ground-deep);
}

/* The runway. Its height beyond one screen IS the scroll distance the
   expansion plays over. Only with scripting — without it there is nothing to
   animate and this would just be dead space. */
html.js .ht-vhero {
  /* 180svh: 0.8 of a screen of runway after the first sticky screen. At 260 the
     hero was 51% of the whole page and the expansion felt like the site. */
  height: 180svh;
}

/* WordPress only: the Elementor band that wraps the hero.

   The theme gives every parent container --ht-gutter of inline padding, which
   insets a full-bleed hero by 64px. Setting padding to 0 in the Elementor
   container settings did not cover the inline axis — the band still computed
   "0px 64px" — so it is cancelled here, where the specificity is explicit.
   Harmless on the static build, where no .ht-vhero-band element exists. */
.e-con.e-parent.ht-vhero-band {
  --padding-block-start: 0px;
  --padding-block-end: 0px;
  --padding-inline-start: 0px;
  --padding-inline-end: 0px;
}

.ht-vhero__stage {
  /* Sticky rather than fixed: the stage pins and releases itself, so there is
     no "am I still expanding?" state for a scroll handler to get stuck in. */
  position: sticky;
  inset-block-start: 0;
  height: 100svh;
  overflow: hidden;
  isolation: isolate;
  display: grid;
  place-items: center;

  /* Rests CLOSED, not open. Because the headline halves travel off-screen as
     --p approaches 1, resting at 1 would hand a visitor without JavaScript a
     hero with no headline and no buttons. At 0 everything is where it belongs
     and the film simply plays in its card. */
  --p: 0;
}

/* ---- The still, underneath ----------------------------------------------- */

.ht-vhero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* Never quite gone: it keeps a warm ground behind the film's darkest frames
     instead of letting them fall to flat black. */
  opacity: calc(1 - var(--p) * 0.85);
}

.ht-vhero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  /* The home hero's grade, not --ht-photo-filter: that token is tuned for
     photographs sitting beside text on the dark ground. A hero photograph
     carries text ON it and has to be pulled down much further. */
  filter: saturate(0.34) contrast(1.1) brightness(0.68) sepia(0.26);
}

.ht-vhero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
      180deg,
      rgb(11 10 8 / 0.58) 0%,
      rgb(11 10 8 / 0.16) 38%,
      rgb(11 10 8 / 0.62) 86%,
      rgb(18 16 14 / 0.92) 100%
    ),
    linear-gradient(90deg, rgb(11 10 8 / 0.5) 0%, rgb(11 10 8 / 0) 62%);
}

/* ---- The card of film -----------------------------------------------------
   Width and height are animated directly rather than with transform: scale.
   The card goes from 300x400 to roughly 1550x800 — 5.2x horizontally against
   2x vertically — so a single scale factor cannot produce it, and scaling
   would stretch the footage rather than reveal more of the frame.
   -------------------------------------------------------------------------- */

.ht-vhero__frame {
  /* Starts large enough to CONTAIN the copy, not to sit behind a corner of it.
     Measured at 1265px wide the copy block is 880 x 443 (eyebrow through
     buttons); a 300 x 400 card left the headline hanging outside its own frame
     on both sides, which is what made the closed state look broken.

     Ends at exactly the full screen — 100vw x 100svh, square corners, no
     shadow — so the film finishes edge to edge rather than as a large card
     floating on a dark margin. */
  /* Portrait at rest, like the reference — taller than the copy but NARROWER
     than the headline, so the headline crosses the window rather than sitting
     inside it. That crossing is what gives the composition depth: a deep
     vertical opening with type laid over it, instead of a landscape box with
     text tucked in. Sizing it to hug the text removed exactly that.

     Width is derived from height rather than set independently, so the 3:4
     portrait holds at every viewport instead of flattening on short screens. */
  --h-start: min(84svh, 46rem);
  --w-start: min(88vw, calc(var(--h-start) * 0.75));

  position: absolute;
  z-index: 1;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  transform: translate(-50%, -50%);

  width: calc(var(--w-start) + (100vw - var(--w-start)) * var(--p));
  height: calc(var(--h-start) + (100svh - var(--h-start)) * var(--p));

  border-radius: calc(var(--ht-radius-lg, 14px) * (1 - var(--p)));
  overflow: hidden;
  box-shadow: 0 0 3.125rem rgb(0 0 0 / calc(0.35 * (1 - var(--p))));
}

.ht-vhero__frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Lighter than the stills: those are graded down hard so amateur source
     reads as deliberate, but the film has to stay alive. */
  filter: saturate(0.42) contrast(1.06) brightness(0.88) sepia(0.2);
  transition: opacity 0.4s linear;
}

/* Set by hero-video.js for the last 0.4s of the clip. The trimmed loop ends on
   a lit interior and restarts on a candle in near-darkness, so a hard cut
   reads as a glitch; dipping through the card lets it dissolve. */
.ht-vhero__frame video.is-wrapping {
  opacity: 0;
}

/* Legibility scrim over the film, strongest while the headline is still on it.
   It eases off as the copy clears, because by then there is nothing left to
   protect and the film should be seen. */
.ht-vhero__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: rgb(11 10 8 / 0.42);
  opacity: calc(1 - var(--p) * 0.55);
}

/* ---- Copy -----------------------------------------------------------------
   Centred over the card, and cleared sideways as it opens. Padded clear of the
   fixed bar for the same reason .ht-hero__inner is.
   -------------------------------------------------------------------------- */

.ht-vhero__copy {
  position: relative;
  z-index: 2;
  width: 100%;
  /* Carries its own gutter. This block used to be .ht-wrap; recentring it
     dropped that class, and with it the horizontal padding — which put the
     stacked buttons edge to edge at 375px wide. */
  padding-inline: var(--ht-gutter);
  padding-block-start: var(--ht-header-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ht-s-2);
  text-align: center;
  pointer-events: none;
}

/* The buttons still have to be clickable inside a block that ignores pointers. */
.ht-vhero__copy a,
.ht-vhero__copy button {
  pointer-events: auto;
}

.ht-vhero__eyebrow {
  opacity: calc(1 - var(--p) * 2.2);
}

.ht-vhero__title {
  font-size: var(--ht-t-3xl);
  line-height: 1.04;
  max-width: none;
}

/* The signature move. The halves travel far enough to leave the screen
   entirely by full expansion — at a smaller amplitude it reads as two lines
   that failed to align rather than as a deliberate parting. */
.ht-vhero__line {
  display: block;
  will-change: transform;
}

/* 100vw, not 82: at 82 the halves still showed ~23px at each edge when fully
   expanded, which reads as text stuck against the frame rather than gone.
   Overshooting costs nothing — .ht-vhero__stage clips, so no overflow — and it
   keeps them clear on wider headlines and narrower viewports alike. */
.ht-vhero__line--a {
  transform: translateX(calc(var(--p) * -100vw));
}

.ht-vhero__line--b {
  transform: translateX(calc(var(--p) * 100vw));
}

.ht-vhero__lead {
  font-size: var(--ht-t-md);
  color: var(--ht-steam);
  max-width: 46ch;
  line-height: 1.6;
  /* Gone by 55%, before the card is wide enough to sit behind it awkwardly. */
  opacity: calc(1 - var(--p) * 1.8);
}

.ht-vhero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--ht-s-2);
  margin-block-start: var(--ht-s-3);
  opacity: calc(1 - var(--p) * 1.8);
}

/* ---- Scroll cue -----------------------------------------------------------
   Only meaningful while something is still closed. Gone by the halfway point.
   -------------------------------------------------------------------------- */

.ht-vhero__cue {
  position: absolute;
  z-index: 2;
  inset-block-end: var(--ht-s-3);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--ht-s-2);
  font-size: var(--ht-t-xs);
  letter-spacing: var(--ht-track-eyebrow);
  text-transform: uppercase;
  color: var(--ht-muted);
  white-space: nowrap;
  opacity: calc(1 - var(--p) * 2);
  pointer-events: none;
}

.ht-vhero__cue::after {
  content: "";
  width: 3rem;
  height: 1px;
  background: currentColor;
}

/* ---- Narrow screens -------------------------------------------------------
   A card that grows 5x horizontally has nowhere to go on a phone, so it opens
   mostly vertically instead — same reference values as the original component.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  /* Same portrait proportion, a little narrower: a phone is already portrait,
     so the card only has to stay clear of the gutters to read as a window. */
  .ht-vhero__frame {
    --h-start: min(78svh, 40rem);
    --w-start: min(84vw, calc(var(--h-start) * 0.72));
  }

  .ht-vhero__title {
    font-size: var(--ht-t-2xl);
  }

  /* Less width to clear, and the lines are longer relative to it. */
  .ht-vhero__line--a {
    transform: translateX(calc(var(--p) * -140vw));
  }

  .ht-vhero__line--b {
    transform: translateX(calc(var(--p) * 140vw));
  }

  .ht-vhero__actions {
    width: 100%;
  }

  .ht-vhero__actions .ht-btn {
    flex: 1 1 100%;
  }

  .ht-vhero__cue {
    display: none;
  }
}

/* ---- Reduced motion -------------------------------------------------------
   No runway and no expansion: the film is simply already open, the copy is
   simply already where it lands. Nothing moves, nothing is left invisible.
   js/hero-video.js also pauses playback here.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html.js .ht-vhero {
    height: 100svh;
  }

  html.js .ht-vhero__stage {
    --p: 0;
  }

  .ht-vhero__line {
    transform: none;
  }
}
