/* ==========================================================================
   Hero — la photo s'ouvre au fil du scroll
   Le scroll reste natif : une piste haute, une scène collée, une variable
   --p (0 → 1) écrite par le JS. Aucun événement molette intercepté.

   Séparation des deux images : le paysage est délavé vers le crème, flouté
   et désaturé dès le départ ; la photo du couple est nette, cadrée d'un
   liseré clair et posée sur une ombre. L'une est un fond, l'autre un sujet.
   ========================================================================== */

.hero {
  --p: 0;
  /* Au repos, la photo est un carré : format de portrait, pas de bandeau. */
  --card-min: min(78vw, 62dvh, 420px);
  --card-w-min: var(--card-min);
  --card-h-min: var(--card-min);
  --card-h-max: 100dvh;
  position: relative;
  background: var(--cream);
}

/* Sur un écran étroit, une photo de paysage ne peut pas remplir un format
   portrait sans couper l'un des deux visages : l'ouverture s'arrête donc à
   une bande pleine largeur qui garde le cadrage d'origine. */
@media (max-width: 720px) {
  .hero {
    --card-min: min(84vw, 46dvh, 360px);
    --card-h-max: 64dvh;
  }
}

.hero__track {
  height: 340dvh;
}

.hero__stage {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--cream);
}

/* --- Image de fond : le paysage ------------------------------------------ */

.hero__bg {
  position: absolute;
  inset: -5%;
  z-index: var(--z-base);
  opacity: clamp(0, calc(1 - var(--p) * 1.05), 1);
  transform: scale(calc(1 + var(--p) * 0.12));
  filter: blur(calc(7px + var(--p) * 16px));
  will-change: transform, opacity, filter;
}

.hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
  filter: saturate(0.18) brightness(1.12) contrast(0.9);
}

/* Voile crème plat : le paysage passe dans la charte, sans dégradé. */
.hero__wash {
  position: absolute;
  inset: -5%;
  z-index: 1;
  background: var(--cream);
  opacity: clamp(0, calc(0.5 - var(--p) * 0.5), 1);
}

/* --- La carte : photo du couple ------------------------------------------ */

.hero__card {
  position: relative;
  z-index: var(--z-hero-media);
  width: calc(var(--card-w-min) + (100vw - var(--card-w-min)) * var(--p));
  height: calc(
    var(--card-h-min) + (var(--card-h-max) - var(--card-h-min)) * var(--p)
  );
  border-radius: calc(var(--r-xl) * (1 - var(--p) * 0.94));
  overflow: hidden;
  box-shadow: var(--shadow-hero);
  will-change: width, height;
}

.hero__card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Le cadrage remonte au fil de l'ouverture, de 46 % à 18 %. Sans ce
     déplacement, un écran large recadre une bande centrale et coupe les
     têtes ; aller jusqu'à 0 % les coupe par le haut. Le premier nombre règle
     le carré au repos, le second l'amplitude de la remontée. */
  object-position: 50% calc(46% - var(--p) * 28%);
}

/* Au repos la photo est éclaircie pour que le titre passe dessus ; elle
   retrouve ses couleurs à mesure qu'elle devient le sujet. */
.hero__card-veil {
  position: absolute;
  inset: 0;
  background: var(--white);
  opacity: clamp(0, calc(0.34 - var(--p) * 1), 1);
}

/* Liseré clair : c'est lui qui détache la carte du paysage flouté. */
.hero__card-rim {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.7);
  opacity: clamp(0, calc(1 - var(--p) * 1.6), 1);
}

/* --- Titre ---------------------------------------------------------------
   Les deux prénoms s'écartent, l'esperluette reste au centre : le geste du
   composant d'origine, transposé à deux noms qui se séparent puis cèdent la
   place à la photo.
   -------------------------------------------------------------------- */

.hero__title {
  position: absolute;
  z-index: var(--z-hero-text);
  inset-inline: 0;
  top: 50%;
  translate: 0 -50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
  padding: 0 var(--gutter);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--t-hero);
  line-height: 1;
  color: var(--accent);
  /* Halo discret : juste assez pour décoller le rouge de la photo, pas assez
     pour se voir comme un contour. Le voile clair sur la carte au repos fait
     déjà l'essentiel du travail de contraste. */
  text-shadow: 0 0 16px rgba(255, 255, 255, 0.5),
    0 1px 2px rgba(255, 255, 255, 0.4);
  opacity: clamp(0, calc(1.06 - var(--p) * 1.9), 1);
  transform: scale(calc(1 - var(--p) * 0.06));
  transform-origin: center;
  will-change: opacity, transform;
  pointer-events: none;
}

/* Les prénoms ne partent pas sur les côtés : ils s'effacent sur place, en
   reculant très légèrement, pendant que la photo prend toute la place. */
.hero__name {
  display: block;
  white-space: nowrap;
}

.hero__amp {
  display: block;
  font-size: 0.52em;
  color: var(--accent-hover);
}

/* --- Plaque finale : apparaît quand la photo occupe l'écran -------------- */

.hero__plate {
  position: absolute;
  z-index: var(--z-hero-text);
  left: 50%;
  bottom: clamp(1.5rem, 6vh, 4rem);
  translate: -50% 0;
  width: min(92vw, 34rem);
  padding: var(--s-5) var(--s-6);
  border-radius: var(--r-lg);
  text-align: center;
  color: var(--ink);
  /* Le verre est ici plus opaque que la primitive : il passe devant une zone
     de photo quelconque, le contraste ne peut pas dépendre du cadrage. */
  background: rgba(255, 255, 255, 0.78);
  opacity: clamp(0, calc((var(--p) - 0.68) / 0.24), 1);
  transform: translateY(calc((1 - clamp(0, (var(--p) - 0.68) / 0.24, 1)) * 18px));
  pointer-events: none;
}

.hero__plate[data-active="true"] {
  pointer-events: auto;
}

.hero__date {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-lg);
  color: var(--accent);
}

.hero__place {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--t-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.hero__rule {
  width: 3.5rem;
  height: 1px;
  margin: var(--s-4) auto;
  background: var(--accent);
  opacity: 0.5;
}

/* --- Invite à défiler ---------------------------------------------------- */

.hero__cue {
  position: absolute;
  z-index: var(--z-hero-text);
  left: 50%;
  bottom: clamp(1.25rem, 4vh, 2.5rem);
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: clamp(0, calc(1 - var(--p) * 3.4), 1);
  pointer-events: none;
}

.hero__cue-line {
  width: 1px;
  height: 2.5rem;
  background: var(--accent);
  transform-origin: top;
  animation: cue 2.4s var(--ease-in-out) infinite;
}

@keyframes cue {
  0%,
  100% {
    transform: scaleY(0.3);
    opacity: 0.3;
  }
  50% {
    transform: scaleY(1);
    opacity: 0.75;
  }
}

/* --- Repli sans animation ------------------------------------------------
   Mouvement réduit ou JS absent : pas d'épinglage, la photo est simplement
   grande et le titre lisible. Rien n'est masqué par défaut.
   -------------------------------------------------------------------- */

.hero.is-static .hero__track {
  height: auto;
}

.hero.is-static .hero__stage {
  position: relative;
  height: auto;
  padding: var(--s-8) var(--gutter);
  gap: var(--s-6);
  grid-auto-flow: row;
}

.hero.is-static .hero__bg,
.hero.is-static .hero__wash {
  opacity: 1;
  transform: none;
}

.hero.is-static .hero__bg {
  filter: blur(7px);
}

.hero.is-static .hero__card {
  width: var(--card-min);
  height: var(--card-min);
  border-radius: var(--r-xl);
}

.hero.is-static .hero__card-veil {
  opacity: 0;
}

.hero.is-static .hero__title {
  position: static;
  translate: none;
  transform: none;
  opacity: 1;
  order: -1;
}

.hero.is-static .hero__plate {
  position: static;
  translate: none;
  transform: none;
  opacity: 1;
  margin-inline: auto;
}

.hero.is-static .hero__cue {
  display: none;
}
