/* ============================================================
   Lightworker Collective — Composants (components.css)
   Nav, footer, logo, boutons, cartes, badges, placeholders.
   Toutes les couleurs et polices viennent de brand.css.
   ============================================================ */

/* Décalage d'ancre sous la nav sticky */
[id] { scroll-margin-top: 96px; }

/* ------------------------------------------------------------
   Navigation (sticky, translucide avec blur léger)
   ------------------------------------------------------------ */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  /* Transparent au-dessus du hero; le fond translucide apparaît
     PROGRESSIVEMENT au scroll (--nav-op piloté par main.js). */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s var(--ease-soft);
  /* La nav vit sur fond clair partout */
  --ink: var(--charcoal);
  --btn-bg: var(--charcoal);
  --btn-ink: var(--cream);
  --focus-ring: var(--teal-deep);
  --hairline: color-mix(in srgb, var(--charcoal) 12%, transparent);
}

/* Couche de fond translucide + blur, révélée graduellement au scroll. */
.site-nav::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--white) 82%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  opacity: var(--nav-op, 0);
  transition: opacity 0.25s var(--ease-soft);
  pointer-events: none;
}

.site-nav.is-scrolled { border-bottom-color: var(--hairline); }

.nav-inner {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.4rem);
  padding-block: 0.85rem;
  /* Header PLEINE LARGEUR : logo près du bord gauche, menu+bouton près du bord
     droit. .container impose `width: min(1180px, …)` -> on l'annule ici. */
  width: 100%;
  max-width: none;
  padding-inline: clamp(1.25rem, 3.5vw, 3rem);
}

/* Le logo reste à GAUCHE et pousse tout le reste (menu + bouton) à DROITE.
   Le petit margin-left le décale légèrement vers la droite (le bouton, lui,
   garde sa distance au bord droit). */
.nav-inner .logo { margin-right: auto; margin-left: clamp(0.5rem, 1.3vw, 1.4rem); }

.nav-links {
  display: none; /* mobile : dans le panneau burger */
}

.nav-links a {
  font-family: var(--font-display);   /* Royal */
  font-weight: 500;
  font-size: 0.88rem;
  text-transform: uppercase;          /* Royal majuscule (demande cliente) */
  color: color-mix(in srgb, var(--charcoal) 86%, var(--white));
  text-decoration: none;
  position: relative;
  padding-block: 0.3em;
}

.nav-links a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s var(--ease-soft);
}

.nav-links a:hover::after,
.nav-links a:focus-visible::after { transform: scaleX(1); }

.nav-cta {
  margin-left: 0;                       /* le push est géré par .logo (margin-right:auto) */
  white-space: nowrap;
  --btn-bg: #4B6D77;                    /* même bleu que le tag de date du hero */
  --btn-ink: var(--cream);
  transition: transform 0.35s var(--ease-soft), box-shadow 0.35s var(--ease-soft), background-color 0.35s var(--ease-soft);
}
.nav-cta:hover,
.nav-cta:focus-visible { --btn-bg: var(--color-celestial-light); }
/* Nouvelle flèche : icône SVG fine (au lieu du « → » texte). */
.nav-cta .btn-arrow { display: inline-flex; align-items: center; }
.nav-cta .btn-arrow svg { width: 1.05em; height: 1.05em; display: block; }

/* Burger minimaliste */
.nav-burger {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
}

.burger-lines,
.burger-lines::before,
.burger-lines::after {
  content: '';
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: var(--charcoal);
  transition: transform 0.35s var(--ease-soft), opacity 0.35s;
}

.burger-lines { position: relative; }
.burger-lines::before { position: absolute; top: -7px; }
.burger-lines::after  { position: absolute; top: 7px; }

.site-nav.is-open .burger-lines { background: transparent; }
.site-nav.is-open .burger-lines::before { transform: translateY(7px) rotate(45deg); }
.site-nav.is-open .burger-lines::after  { transform: translateY(-7px) rotate(-45deg); }

/* Panneau mobile */
.site-nav.is-open .nav-links {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  position: absolute;
  top: 100%;
  left: 0; right: 0;
  padding: 1.2rem clamp(1.25rem, 4vw, 2.5rem) 1.8rem;
  background: color-mix(in srgb, var(--white) 94%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hairline);
}

.site-nav.is-open .nav-links a { font-size: 1.05rem; padding-block: 0.5em; }

@media (min-width: 1024px) {
  .nav-links { display: flex; gap: 1.9rem; }
  .nav-burger { display: none; }
  .nav-cta { margin-left: 0; }
}

/* ------------------------------------------------------------
   Logo temporaire (logotype typographique — voir section 7)
   Une seule couleur, héritée du fond via --ink.
   ------------------------------------------------------------ */

.logo {
  display: inline-block;
  text-decoration: none;
  color: var(--ink, var(--charcoal));
  line-height: 1;
  white-space: nowrap;
}

/* Logo IMAGE du header (remplace le logotype texte ici ; le footer, sur fond
   foncé, garde le logotype texte car ce fichier-ci est noir). */
.logo-img {
  display: block;
  height: clamp(20px, 1.8vw, 26px);
  width: auto;
}

/* Logo du FOOTER : bloc de marque -> plus généreux que le header. Ce fichier est
   un lockup compact (ratio ~1.57), pas un wordmark large : on le monte en hauteur. */
.logo-img--footer { height: clamp(84px, 8.6vw, 122px); }

/* LOGOTYPE LIGHTWORKER — GELÉ. Le client a demandé de le garder tel quel :
   on épingle ses polices historiques (Cormorant + Poppins), conservées
   chargées uniquement pour lui. Il ne passe donc PAS en Royal/Open Sans. */
.logo-light {
  font-family: var(--font-logo-serif);
  font-style: italic;
  font-weight: 600;
  font-size: 1.5rem;
}

.logo-worker {
  font-family: var(--font-logo-sans);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: 0.18em;
  margin-left: 0.1em;
}

.logo-collective {
  display: block;
  font-family: var(--font-logo-sans);
  font-weight: 500;
  font-size: 0.52rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  opacity: 0.72;
  margin-top: 0.38em;
}

/* ------------------------------------------------------------
   Boutons — texte en Georgia italique (accent éditorial),
   pleinement arrondis.
   ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-display);   /* Royal */
  font-style: normal;
  font-weight: 700;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 1.7px;
  line-height: 1;
  text-decoration: none;
  padding: 0.78em 1.75em;
  border-radius: var(--radius-btn);
  background: var(--btn-bg, var(--charcoal));
  color: var(--btn-ink, var(--cream));
  transition: transform 0.35s var(--ease-soft), box-shadow 0.35s var(--ease-soft);
}

.btn-arrow { display: inline-block; transition: transform 0.35s var(--ease-soft); }

.btn:hover,
.btn:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px color-mix(in srgb, var(--powder-blue) 45%, transparent);
}

.btn:hover .btn-arrow,
.btn:focus-visible .btn-arrow { transform: translateX(3px); }

.btn--sm { padding: 0.62em 1.4em; }   /* hérite du 13px de base, padding resserré */

.btn--ghost {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--hairline);
}

/* Bouton « appel » — variante douce (fond clair, texte bleu, flèche cerclée),
   d'après la maquette « JE RESSENS L'APPEL ». Utilisée UNIQUEMENT sous les
   témoignages (voir index.html .testi-foot). */
.btn--call {
  position: relative;
  z-index: 0;
  overflow: hidden;        /* le remplissage reste dans la pilule */
  margin-top: 0.7rem;      /* plus d'air au-dessus (séparation des puces) */
  padding-block: 1.05em;   /* bouton plus généreux verticalement */
  background: color-mix(in srgb, var(--color-celestial-tides) 9%, var(--white));   /* teinte douce, presque blanc (maquette d'origine) */
  color: var(--color-celestial-tides);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--color-celestial-tides) 28%, transparent);   /* fin liseré bleu */
  transition: color 0.35s var(--ease-soft), transform 0.35s var(--ease-soft), box-shadow 0.35s var(--ease-soft);
}
/* Survol : un fond plein (couleur ACTUELLE du texte) balaye de GAUCHE -> DROITE
   derrière le texte, et la police passe au blanc. */
.btn--call::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-celestial-tides);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease-soft);
}
.btn--call .btn-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;          /* jamais compressé : cercle parfait */
  width: 1.7em;
  height: 1.7em;
  border-radius: 50%;
  background: var(--color-celestial-tides);
  color: var(--white);
  font-size: 0.82em;
  line-height: 1;
  transition: background-color 0.35s var(--ease-soft), color 0.35s var(--ease-soft);
}
.btn--call .btn-arrow svg { width: 0.95em; height: 0.95em; display: block; }
.btn--call:hover,
.btn--call:focus-visible {
  color: #fff;                                   /* police blanche au survol */
  box-shadow: inset 0 0 0 1.5px transparent;
}
.btn--call:hover::before,
.btn--call:focus-visible::before {
  transform: scaleX(1);                          /* le fond se remplit G->D */
}
/* La flèche s'inverse (cercle blanc, flèche bleue) pour rester visible sur le plein */
.btn--call:hover .btn-arrow,
.btn--call:focus-visible .btn-arrow {
  background: #fff;
  color: var(--color-celestial-tides);
}

/* ------------------------------------------------------------
   Têtes de section
   ------------------------------------------------------------ */

.section-head { max-width: 46rem; margin-bottom: clamp(2.8rem, 6vw, 4.5rem); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head .lead { margin-top: 1.3rem; font-size: 1.14rem; color: var(--ink-soft); }

/* ------------------------------------------------------------
   Surbrillance animée « highlight-sweep » (CSS fourni par la cliente).
   Barre sombre qui balaye G->D, puis fond #1E1E1E qui se remplit et
   reste, texte qui vire au bleu. Les 3 animations sont ARMÉES par la
   classe .is-swept (ajoutée par JS quand le mot APPARAÎT) : dans le
   titre des piliers, le déclenchement suit la révélation mot-à-mot
   (initWordIntros) ; ailleurs, l'entrée dans le viewport
   (initHighlightSweep). Usage : <span class="highlight-sweep">mot</span>.
   ------------------------------------------------------------ */
.highlight-sweep{
  position: relative;
  display: inline-block;
  font-family: royal;
  font-weight: 600;
  padding: 0 .25em;                 /* plus de padding latéral */
  color: inherit;                   /* couleur du thème au départ */
  z-index: 0;
  line-height: 1.2;
}

/* BARRE fine qui balaye de GAUCHE -> DROITE derrière le texte */
.highlight-sweep::before{
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 50%;
  background: #1E1E1E;
  border-radius: 6px;               /* coins arrondis */
  transform: translateX(-100%);
  z-index: -1;
  will-change: transform;
}

/* FOND qui se REMPLIT de DROITE -> GAUCHE et RESTE en place */
.highlight-sweep::after{
  content: "";
  position: absolute;
  inset: 0;
  background: #1E1E1E;
  border-radius: 6px;               /* coins arrondis */
  transform-origin: right center;
  transform: scaleX(0);
  z-index: -1;
  will-change: transform;
}

/* Déclenchement : .is-swept lance les 3 animations (rejouable). */
.highlight-sweep.is-swept          { animation: hs-text 800ms ease 600ms forwards; }
.highlight-sweep.is-swept::before  { animation: hs-sweep 500ms cubic-bezier(.35,.01,.21,1) 0ms forwards; }
.highlight-sweep.is-swept::after   { animation: hs-fill 800ms cubic-bezier(.35,.01,.21,1) 300ms forwards; }

/* Animations */
@keyframes hs-sweep{
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(102%); }
}
@keyframes hs-fill{
  0%   { transform: scaleX(0); }
  100% { transform: scaleX(1); }
}
@keyframes hs-text{
  0%   { color: inherit; }
  100% { color: #4B6D77; }
}

/* Repli sans animation : état final (fond plein + texte bleu) une fois armé. */
@media (prefers-reduced-motion: reduce) {
  .highlight-sweep.is-swept { animation: none; color: #4B6D77; }
  .highlight-sweep.is-swept::before { animation: none; transform: translateX(102%); }
  .highlight-sweep.is-swept::after  { animation: none; transform: scaleX(1); }
}

/* ------------------------------------------------------------
   Badges (petites étiquettes)
   ------------------------------------------------------------ */

.badge-row { display: flex; flex-wrap: wrap; gap: 0.65rem 0.8rem; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.76rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  padding: 0.6em 1.15em;
  border-radius: var(--radius-btn);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--white) 45%, transparent);
}

/* ------------------------------------------------------------
   Placeholders texte — visibles, impossibles à manquer
   ------------------------------------------------------------ */

.placeholder {
  display: inline-block;
  padding: 0.1em 0.55em;
  border-radius: 8px;
  background: color-mix(in srgb, var(--tan) 30%, transparent);
  border: 1.5px dashed var(--burnt-orange);
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.88em;
  font-style: normal;
  letter-spacing: 0.01em;
  text-transform: none;
}

/* ------------------------------------------------------------
   Médias + placeholders d'images
   Le HTML référence les vrais fichiers; tant qu'ils n'existent
   pas, onerror bascule sur .img-placeholder (voir main.js /
   lwImgFallback dans loading.js).
   ------------------------------------------------------------ */

.media {
  position: relative;
  border-radius: var(--radius-soft);
  overflow: hidden;
  background: color-mix(in srgb, var(--sage) 20%, var(--cream));
}

.media img,
.media video { width: 100%; height: 100%; object-fit: cover; }

/* Vidéo scrubée (galerie zoom) : masquée si le fichier est absent,
   le placeholder prend le relais. */
.zoom-video { display: block; background: color-mix(in srgb, var(--sage) 20%, var(--cream)); }
.media.is-missing video { opacity: 0; }

.img-placeholder {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1rem;
  border-radius: inherit;
  border: 1.5px dashed var(--cream);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--sage) 36%, var(--cream)),
    color-mix(in srgb, var(--teal) 28%, var(--cream))
  );
}

.img-placeholder > span {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--charcoal) 78%, var(--cream));
  padding: 0.9em 1.3em;
  border-radius: 12px;
  background: color-mix(in srgb, var(--white) 38%, transparent);
}

/* opacity (et non visibility) : l'img et son alt restent exposés à
   l'arbre d'accessibilité; le placeholder visuel est aria-hidden. */
.media.is-missing img { opacity: 0; }
.media.is-missing .img-placeholder { display: flex; }

/* Ratios réservés (zéro CLS) */
.ratio-45  { aspect-ratio: 4 / 5; }
.ratio-43  { aspect-ratio: 4 / 3; }
.ratio-34  { aspect-ratio: 3 / 4; }
.ratio-11  { aspect-ratio: 1 / 1; }

/* ------------------------------------------------------------
   Hero
   ------------------------------------------------------------ */

.hero { padding-block: clamp(70px, 9vw, 130px) var(--section-y); }

/* Fond photo du hero (groupe de la dernière retraite) + voile NOIR dégradé
   (voir .hero-bg) : plus dense à gauche (sous le texte) pour garder le texte
   CLAIR lisible, plus transparent à droite pour laisser respirer la photo. La
   photo s'estompe avec le hero (reveal sticky). Repli sombre : .hero.hero--dark. */
.hero.theme-white { background-color: var(--cream); }

/* La photo vit dans une COUCHE dédiée (comme .gift-bg / .invest-bg) et non dans
   le background de la section : on peut ainsi l'ÉPINGLER sur mobile pour qu'elle
   ne s'étire pas quand le hero s'allonge. Sur desktop elle couvre la section
   (absolute inset:0) — rendu strictement identique à avant, puisque .section est
   déjà position:relative et .section > .container déjà z-index:1. */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* Filtre NOIR dégradé (remplace l'ancien voile crème) : dense à gauche sous le
     texte pour la lisibilité, plus léger à droite pour laisser voir la photo. */
  background-image:
    linear-gradient(100deg,
      color-mix(in srgb, var(--charcoal) 72%, transparent) 0%,
      color-mix(in srgb, var(--charcoal) 52%, transparent) 50%,
      color-mix(in srgb, var(--charcoal) 34%, transparent) 100%),
    url('../img/nouveauhero.webp?v=301043df');
  background-size: cover;
  background-position: center 28%;
  background-repeat: no-repeat;
}

/* Hero « filtre noir » : le texte passe en clair pour rester lisible sur le
   voile sombre ; les puces deviennent un verre clair et le bouton passe en
   crème pour ressortir. Overrides ciblés sur le hero uniquement. */
.hero.hero--dark { background-color: var(--charcoal); }   /* repli si l'image manque */
.hero--dark .eyebrow { color: var(--color-celestial-light); }
.hero--dark h1 { color: var(--cream); }
.hero--dark .accent { color: var(--color-celestial-light); }
.hero--dark .hero-sub { color: color-mix(in srgb, var(--cream) 82%, transparent); }
.hero--dark .badge {
  color: color-mix(in srgb, var(--cream) 90%, transparent);
  background: color-mix(in srgb, var(--white) 12%, transparent);
  border-color: color-mix(in srgb, var(--white) 22%, transparent);
}
.hero--dark .btn {
  background: var(--cream);
  color: var(--charcoal);
}
/* Bouton FANTÔME clair (Découvrir) sur le hero sombre — placé APRÈS .hero--dark
   .btn pour reprendre le fond transparent + un contour clair. */
.hero--dark .btn--ghost {
  background: transparent;
  color: var(--cream);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cream) 45%, transparent);
}
.hero--dark .btn--ghost:hover,
.hero--dark .btn--ghost:focus-visible {
  box-shadow: inset 0 0 0 1.5px var(--cream);
}

/* ------------------------------------------------------------
   HERO CENTRÉ (logo au milieu) : tag dates (haut) · logo · tagline
   Royal MAJUSCULE · boutons · tag places restantes. Voir index.html.
   ------------------------------------------------------------ */
.hero-copy--center {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(1.05rem, 2.4vw, 1.7rem);
  max-width: 62rem;
  margin-inline: auto;
}

/* Tag DATES — pilule bleue translucide, au-dessus du logo */
.hero-copy--center .hero-dates {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin: 0;
  padding: 0.5em 1.15em;
  border-radius: 14px;   /* un peu moins rond (au lieu de la pilule 999px) */
  background: #4B6D77;   /* bleu demandé, 100% opaque */
  color: var(--cream);
  font-family: var(--font-title);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
/* Mobile : pas d'icône calendrier dans le tag de date (demande client).
   `display: none` plutôt qu'un retrait du HTML : elle reste sur desktop. Le
   conteneur étant un flex, l'élément retiré emporte son `gap` avec lui — aucun
   espace résiduel à gauche du texte. L'icône est aria-hidden : rien à perdre
   côté lecteurs d'écran. */
@media (max-width: 899px) {
  .hero-copy--center .hero-dates > span[aria-hidden="true"] { display: none; }
}

/* LOGO au centre (+ repli texte tant que l'image n'existe pas) */
.hero-logo { width: min(720px, 90vw); line-height: 0; }
.hero-logo-img { display: block; width: 100%; height: auto; }
.hero-logo.is-missing .hero-logo-img { display: none; }
.hero-logo-fallback { display: none; }
.hero-logo.is-missing .hero-logo-fallback {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 8vw, 5.5rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--cream);
}
.hero-logo.is-missing .logo-light { font-weight: 400; }
.hero-logo.is-missing .logo-worker { font-weight: 700; }

/* TAGLINE Royal MAJUSCULE sous le logo (H1) — spécificité > .hero h1 */
.hero-copy--center .hero-tagline {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: clamp(0.72rem, 1.3vw, 0.9rem);   /* un peu plus petit */
  line-height: 1.5;
  color: color-mix(in srgb, var(--cream) 88%, transparent);
}
/* Encadrement « – … – » (tirets décoratifs, hors texte lu par le SEO) */
.hero-copy--center .hero-tagline::before { content: "–"; margin-right: 0.55em; }
.hero-copy--center .hero-tagline::after  { content: "–"; margin-left: 0.55em; }
/* « équilibre » : même police Royal que le reste (on annule l'override global
   em.accent = Georgia italique), juste teinté en bleu. */
.hero-copy--center .hero-tagline .accent {
  font-family: inherit;
  font-style: normal;
  font-weight: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  color: var(--color-celestial-light);
}

/* BOUTONS */
.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(0.8rem, 1.6vw, 1.1rem);
  margin-top: 0.4rem;
}
/* Boutons du hero un peu moins ronds — UNIQUEMENT ici (le token global
   --radius-btn = 999px reste inchangé pour la nav, les prix, etc.). */
.hero-cta-row .btn { border-radius: 14px; }

/* TAG places restantes, en dessous */
.hero-copy--center .hero-places {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin: 0;
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--cream) 80%, transparent);
}
.hero-copy--center .hero-places > span[aria-hidden] { color: var(--color-celestial-light); }

.hero-grid {
  display: grid;
  gap: clamp(3rem, 6vw, 4.5rem);
  align-items: center;
}

@media (min-width: 1024px) {
  .hero-grid { grid-template-columns: 55fr 45fr; }
}

/* Variante « solo » : la vidéo de bienvenue a migré vers sa propre section
   (voir .video-feature). Le hero garde une seule colonne (texte) ; la photo de
   fond respire à droite, dans la continuité du dégradé (dense à gauche). */
.hero-grid--solo { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) {
  .hero-grid--solo { grid-template-columns: minmax(0, 60ch); }
}

.hero .h1-line { display: block; }

.hero-sub {
  margin-top: 1.5rem;
  font-size: 1.18rem;
  color: var(--ink-soft);
  max-width: 34rem;
}

.hero-info { margin: 1.9rem 0 2.4rem; }

/* Bloc vidéo de bienvenue */
.video-shell { position: relative; }

.video-frame {
  position: relative;
  border-radius: var(--radius-soft);
  overflow: hidden;
  aspect-ratio: 9 / 16;   /* la vidéo de Kiki est un « reel » 9/16 — aucun recadrage */
  background: color-mix(in srgb, var(--sage) 20%, var(--cream));
  box-shadow: 0 32px 80px color-mix(in srgb, var(--charcoal) 16%, transparent);
}

.video-frame video { width: 100%; height: 100%; object-fit: cover; }

/* En plein écran, la vidéo occupe un écran PAYSAGE. Chrome/Edge respectent
   object-fit même en plein écran : `cover` recadrerait alors le portrait 9/16
   (haut et bas coupés, cf. capture). On repasse en `contain` pour voir toute
   l'image, bandes noires sur les côtés — le rendu normal d'une vidéo verticale.
   (Sur la page, le cadre est déjà en 9/16 : `cover` y remplit sans rien couper.)
   Règles séparées : un préfixe inconnu invaliderait une liste de sélecteurs. */
.video-frame video:fullscreen { object-fit: contain; }
.video-frame video:-webkit-full-screen { object-fit: contain; }

.video-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 86px;
  height: 86px;
  border-radius: 50%;
  background: var(--cream);
  display: grid;
  place-items: center;
  box-shadow: 0 14px 40px color-mix(in srgb, var(--charcoal) 30%, transparent);
  transition: transform 0.35s var(--ease-soft), box-shadow 0.35s var(--ease-soft);
}

.video-play svg { width: 26px; height: 26px; color: var(--charcoal); margin-left: 4px; }

.video-play:hover,
.video-play:focus-visible {
  transform: scale(1.06);
  box-shadow: 0 18px 48px color-mix(in srgb, var(--powder-blue) 55%, transparent);
}

.video-frame.is-playing .video-play,
.video-frame.is-missing .video-play { display: none; }

.video-frame.is-missing video { visibility: hidden; }
.video-frame.is-missing .img-placeholder { display: flex; }

/* Motif « boule de lumière » en orbite, au coin du bloc vidéo */
.video-shell .lw-orb {
  position: absolute;
  width: 220px;
  right: -48px;
  top: -44px;
  z-index: 1;
}

/* ------------------------------------------------------------
   Mot de bienvenue — section vidéo (gauche) + texte (droite).
   « Riser » de la scène reveal (voir .hero-reveal.is-reveal plus bas et
   main.js / initHeroReveal). En flux normal (mobile / reduced-motion) elle
   s'empile : vidéo puis texte.
   ------------------------------------------------------------ */
/* Même fond que la section témoignages (qui est transparente -> montre le body
   blanc #fff). On aligne donc la section vidéo sur ce blanc. */
.video-feature { background-color: var(--white); }

.video-feature-grid {
  display: grid;
  gap: clamp(2.4rem, 5vw, 4.5rem);
  align-items: center;
}

@media (min-width: 900px) {
  .video-feature-grid { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}

/* La vidéo (portrait 9/16, un « reel ») garde une taille élégante, centrée dans
   sa colonne sur mobile. */
.video-feature-media { width: 100%; max-width: 360px; margin-inline: auto; }
@media (min-width: 900px) {
  /* Desktop : la section vit dans le stage ÉPINGLÉ (reveal, cf. plus bas). Elle
     DOIT tenir dans la hauteur de l'écran, même sur un laptop bas (1366x660).
     On dimensionne donc la vidéo par la HAUTEUR du viewport (svh = l'état le plus
     petit) ; la largeur suit le ratio 9/16 — jamais de débordement du stage. */
  .video-feature-media { max-width: none; margin-inline: 0; }
  .video-feature-media .video-frame {
    height: min(72svh, 680px);
    width: auto;
    margin-inline: auto;   /* centrée dans sa colonne */
  }
}

.video-feature-copy { max-width: 40rem; }
.video-feature-copy .eyebrow { margin-bottom: 0.9rem; }
.video-feature-copy h2 { margin-bottom: 1.1rem; }
.video-feature-copy p { color: var(--ink-soft); font-size: 1.1rem; }

/* Variante « texte seul » : vidéo retirée en attendant le fichier final.
   Le mot de bienvenue occupe alors une colonne unique, centrée au milieu
   de la page (la section est déjà centrée verticalement par le stage épinglé). */
.video-feature-grid--solo { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
@media (min-width: 900px) {
  .video-feature-grid--solo { grid-template-columns: minmax(0, 1fr); }
}
.video-feature-grid--solo .video-feature-copy { max-width: 46rem; margin-inline: auto; }

/* ------------------------------------------------------------
   Témoignages — carrousel horizontal piloté par le scroll
   Base (mobile / no-JS / reduced-motion) : carrousel à balayage
   tactile avec scroll-snap. Enrichi en mode « épinglé » (.is-pinned,
   posé par main.js sur grand écran) : la section devient haute, le
   contenu se fige et la piste glisse de droite à gauche au scroll.
   ------------------------------------------------------------ */

.quote-name {
  display: block;
  margin-top: 1.5rem;
  font-family: var(--font-title);
  font-style: normal;
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--eyebrow-ink);
}

/* Inversion demandée : la couleur crème passe sur les CARTES; la
   section devient transparente (on voit le hero derrière pendant le
   fondu, puis le fond de page). */
.testi.theme-cream { background: transparent; }

.testi { padding-bottom: clamp(3rem, 6vw, 4.5rem); }

/* ------------------------------------------------------------
   Scène « reveal » : le hero reste épinglé et s'estompe, la section
   témoignages monte par-dessus en fondu (opacités pilotées par JS).
   Actif sur grand écran + mouvement (classe .is-reveal posée par JS).
   ------------------------------------------------------------ */
/* La nav est sticky : elle occupe sa hauteur dans le flux, et le hero
   commençait juste EN DESSOUS -> derrière la nav transparente on ne voyait que
   le blanc du body. On remonte le hero de la hauteur exacte de la nav
   (--nav-h, mesurée par main.js) : la photo passe sous la nav, qui devient
   réellement transparente. Sans JS : --nav-h vaut 0, la nav garde sa bande. */
.hero-reveal { position: relative; margin-top: calc(-1 * var(--nav-h, 0px)); }

/* Piste de scroll qui donne la DISTANCE du cross-fade (desktop reveal
   uniquement) : le stage reste épinglé pendant qu'on la traverse. Hauteur nulle
   hors reveal (mobile / no-JS). */
.hero-runway { height: 0; }
.hero-reveal.is-reveal .hero-runway { height: 240vh; height: 240svh; }
/* SOLO (D7, mobile) : la piste ne sert plus qu'au fondu du hero — la vidéo est
   sortie du stage par le JS et arrive en flux normal après. ~150svh = la part
   que le hero occupait déjà sur desktop (0 -> 0.62 de 240svh), ce qui reste
   dans l'esprit du recalibrage mobile D1 (~73 % des durées desktop).
   Même spécificité que la règle ci-dessus : elle doit rester APRÈS pour gagner. */
.hero-reveal.is-solo .hero-runway { height: 150vh; height: 150svh; }

/* Stage ÉPINGLÉ : le hero et la section vidéo occupent le MÊME emplacement,
   superposés en absolu ; leurs opacités se croisent au scroll (voir main.js /
   initHeroReveal). Desktop reveal uniquement — sur mobile, .hero-stage est un
   simple conteneur en flux (hero puis section, empilés). */
.hero-reveal.is-reveal .hero-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  z-index: 1;
}
.hero-reveal.is-reveal .hero-stage > .hero,
.hero-reveal.is-reveal .hero-stage > .video-feature {
  position: absolute;
  inset: 0;
  min-height: 0;
  margin: 0;
  padding-block: 0;          /* centrage vertical EXACT (pas de padding de section) */
  display: flex;
  align-items: center;
  will-change: opacity;
}
.hero-reveal.is-reveal .hero-stage > .hero { z-index: 1; }
.hero-reveal.is-reveal .hero-stage > .video-feature { z-index: 2; }

.testi-stage { position: relative; }

/* Le titre vit DANS la zone épinglée, juste au-dessus des cartes, pour
   qu'il reste collé au groupe (pas relégué en haut de section). */
.testi-pin {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.2rem, 2.4vw, 2rem);
}

.testi-eyebrow { flex: none; }
.testi-eyebrow .eyebrow { margin-bottom: 0; }

/* Piste — carrousel natif par défaut */
.testi-track {
  display: flex;
  gap: clamp(1.2rem, 3vw, 2rem);
  list-style: none;
  margin: 0;
  padding: 0.6rem clamp(1.25rem, 8vw, 5rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.testi-track::-webkit-scrollbar { display: none; }

.testi-card {
  flex: 0 0 min(560px, 84vw);
  scroll-snap-align: center;
  display: flex;
}

.testi-card figure {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  background: var(--cream);
  border-radius: var(--radius-soft);
  padding: clamp(1.8rem, 3.4vw, 2.6rem);
  box-shadow: 0 26px 65px color-mix(in srgb, var(--charcoal) 13%, transparent);
  transition: transform 0.4s var(--ease-soft), box-shadow 0.4s var(--ease-soft), opacity 0.5s var(--ease-soft);
}

.testi-card figure:hover {
  transform: translateY(-4px);
  box-shadow: 0 30px 70px color-mix(in srgb, var(--charcoal) 11%, transparent);
}

/* En mode épinglé, la carte centrée est mise en avant; les voisines
   s'estompent doucement (effet « focus »). */
.testi.is-pinned .testi-card figure { opacity: 0.45; }
.testi.is-pinned .testi-card.is-focus figure { opacity: 1; }

/* Cartes à fond photo : une vraie <img> en couverture + un voile charcoal
   (plus dense vers le bas) pour que le texte clair reste bien lisible. */
.testi-card--photo figure {
  position: relative;
  overflow: hidden;
  background: var(--charcoal);   /* repli si l'image manque */
  color: var(--cream);
}

.testi-card-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Cadrage vers le haut (visage) — réglable par carte via --obj */
  object-position: var(--obj, center 18%);
  z-index: 0;
  /* On assombrit l'image directement (uniforme) pour la lisibilité */
  filter: brightness(0.62) saturate(0.9);
}

/* Voile charcoal supplémentaire, un peu plus dense vers le bas */
.testi-card--photo figure::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--charcoal) 42%, transparent),
    color-mix(in srgb, var(--charcoal) 62%, transparent));
}

/* Contenu au-dessus de l'image et du voile */
.testi-card--photo figure > blockquote,
.testi-card--photo figure > figcaption { position: relative; z-index: 2; }

.testi-card--photo figure blockquote p { color: var(--cream); }
.testi-card--photo figure .quote-name { color: var(--color-celestial-light); }

.testi-photo {
  width: 78px;
  height: 78px;
  border-radius: 50%;
  margin-bottom: 1.4rem;
}

.testi-card blockquote { margin: 0; }

.testi-card blockquote p {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1rem, 1.35vw, 1.16rem);
  line-height: 1.5;
  color: var(--ink);
}

.testi-card .quote-name { margin-top: auto; padding-top: 1.5rem; }

/* Puces de progression */
.testi-dots {
  display: flex;
  justify-content: center;
  gap: 0.55rem;
  margin-bottom: 1.3rem;
}

.testi-dot {
  width: 6px;
  height: 6px;
  padding: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--charcoal) 22%, transparent);
  transition: transform 0.35s var(--ease-soft), background-color 0.35s var(--ease-soft);
}

.testi-dot.is-active {
  background: var(--teal);
  transform: scale(1.4);
}

/* Navigation par flèches — MOBILE uniquement (affichée par .testi.is-swipe dans le
   bloc @media). Masquée par défaut : aucun impact sur le rendu grand écran, où le
   scroll pilote déjà le carrousel. */
.testi-nav { display: none; }

.testi-arrow {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--white) 55%, transparent);
  transition: transform 0.35s var(--ease-soft), background-color 0.35s var(--ease-soft),
    opacity 0.35s var(--ease-soft);
}

.testi-arrow svg { width: 21px; height: 21px; }
.testi-arrow:active { transform: scale(0.94); }
.testi-arrow:disabled { opacity: 0.32; }

.testi-count {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: 1.1rem;
  color: var(--accent-ink);
  letter-spacing: 0.04em;
  min-width: 3.6em;
  text-align: center;
}

/* Dans la zone épinglée : espacement géré par le gap du pin */
.testi-foot { flex: none; margin-top: 0; text-align: center; }

/* Mobile : le CTA finissait à 32px du bord noir du pitch — trop serré contre une
   coupure aussi franche. Réservé au mobile : sur grand écran .testi-foot est DANS
   la zone épinglée, où l'espacement vient du gap du pin (y toucher décalerait la
   composition centrée). */
@media (max-width: 899px) {
  .testi-foot { padding-bottom: clamp(3rem, 10vw, 4.5rem); }
}

/* --- Mode épinglé (grand écran, mouvement autorisé) --- */
.testi.is-pinned .testi-stage { height: var(--testi-stage-h, 300vh); }

.testi.is-pinned .testi-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

.testi.is-pinned .testi-track {
  overflow: visible;
  scroll-snap-type: none;
  padding-inline: clamp(2rem, 8vw, 7rem);
  transform: translate3d(var(--tx, 0), 0, 0);
  will-change: transform;
}

.testi.is-pinned .testi-card { flex-basis: min(430px, 33vw); }

.testi.is-pinned .testi-card figure { padding: clamp(1.4rem, 2.4vw, 1.9rem); }

/* Quote resserrée en mode épinglé : garantit que même le plus long
   témoignage tient dans la hauteur du pin (100vh) sans être coupé. */
.testi.is-pinned .testi-card blockquote p {
  font-size: clamp(0.86rem, 0.92vw, 0.98rem);
  line-height: 1.5;
}

.testi.is-pinned .testi-card .quote-name { padding-top: 1.1rem; }

.testi.is-pinned .testi-photo { width: 54px; height: 54px; margin-bottom: 0.85rem; }

/* ------------------------------------------------------------
   Le pitch — poème sur bande foncée
   ------------------------------------------------------------ */

.poeme {
  font-size: clamp(1.12rem, 2.1vw, 1.45rem);
  line-height: 1.95;
  max-width: 40rem;
}

.poeme p + p { margin-top: 1.7em; }
.poeme .poeme-line { display: block; }

/* Demande cliente : les 4 blocs du pitch (tl/tr/bl/br) en Georgia fin.
   PAS le titre central (.pitch-step--center n'a pas .poeme). NB : Georgia n'a pas
   de coupe « Thin », le poids 100 rend au plus léger disponible (~régulier). */
.pitch-step.poeme {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-weight: 300;   /* Cormorant Light — vrai serif fin (demande cliente) */
  /* Un peu plus gros que la base .poeme (1.45rem) — demande client. Desktop
     seulement : le bloc @media max-width:899px ci-dessous garde la taille mobile.
     Scopé au pitch, donc la CTA qui partage .poeme n'est pas touchée. */
  font-size: clamp(1.5rem, 2.2vw, 1.65rem);
}
/* « Être présente » (accent) suit le même Cormorant fin que son bloc. */
.pitch-step.poeme em.accent { font-family: inherit; }

/* Mobile : dans .poeme, le terme 2.1vw s'écrase sous ~690px de large, donc la
   police reste collée à son PLANCHER (1.12rem) alors que le desktop monte à
   1.45rem — d'où un texte tassé sur téléphone. On relève le plancher pour le
   PITCH SEULEMENT (.poeme reste la base partagée, intouchée) et on plafonne à
   1.45rem : aucune cassure au franchissement des 900px.
   Sans risque pour la scène : .pitch-pin fait 100vh, il n'enfle pas avec le
   texte, et les blocs (160px) ont de la marge dans l'écran. */
@media (max-width: 899px) {
  .pitch-step.poeme { font-size: clamp(1.35rem, 5.4vw, 1.45rem); }
}

/* ------------------------------------------------------------
   Pitch — séquence de textes pilotée par le scroll
   Base (no-JS / reduced-motion) : blocs empilés, tous lisibles.
   Enrichi (.is-seq, posé par main.js) : section haute, contenu
   épinglé, chaque bloc apparaît/disparaît en fondu (opacité JS).
   ------------------------------------------------------------ */

.pitch-step + .pitch-step { margin-top: 1.9em; }

/* Tiret coloré avant chaque bloc (accent qui change par bloc) */
.pitch-dash {
  display: block;
  width: 2.6rem;
  height: 3px;
  border-radius: 2px;
  margin-bottom: 1.1rem;
  background: var(--dash, var(--powder-blue));
}

.pitch-step--center { --dash: var(--powder-blue); }
.pitch-step--tl     { --dash: var(--tan); }
.pitch-step--tr     { --dash: var(--raspberry); }
.pitch-step--bl     { --dash: var(--burnt-orange); }
.pitch-step--br     { --dash: var(--sage); }

.pitch-step--center .pitch-dash { margin-inline: auto; }
.pitch-step--tr .pitch-dash,
.pitch-step--br .pitch-dash { margin-left: auto; }

.pitch-seq.is-seq {
  padding-block: 0;
  height: var(--pitch-h, 580vh);
  position: relative;
  z-index: 3;                            /* passe AU-DESSUS des témoignages (z-index:2) */
  margin-top: var(--pitch-overlap, 0);   /* remonte sur le tiroir de fin des témoignages (posé par JS) */
  will-change: opacity;
}

.pitch-seq.is-seq .pitch-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
}

.pitch-seq.is-seq .pitch-pin > .container {
  position: relative;
  z-index: 1;
  height: 100%;
}

/* Chaque bloc apparaît dans une zone distincte, reste, puis se floute
   au fil du scroll (opacité + flou pilotés par main.js). */
.pitch-seq.is-seq .pitch-step {
  position: absolute;
  margin: 0;
  max-width: min(27rem, 44%);
  opacity: 0;
  will-change: opacity, filter;
}

.pitch-seq.is-seq .pitch-step--center {
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  max-width: 36rem;
  margin-inline: auto;
  text-align: center;
}

.pitch-seq.is-seq .pitch-step--tl { top: 12%; left: 0; text-align: left; }
.pitch-seq.is-seq .pitch-step--tr { top: 14%; right: 0; text-align: right; }
.pitch-seq.is-seq .pitch-step--bl { bottom: 12%; left: 0; text-align: left; }
.pitch-seq.is-seq .pitch-step--br { bottom: 12%; right: 0; text-align: right; }

/* Léger flottement continu des blocs (gauche-droite + haut-bas), façon
   lévitation douce. On anime la propriété `translate` (indépendante de
   `transform`) pour composer avec le centrage translateY(-50%) du bloc
   central. Chaque bloc dérive à son rythme (durées/délais différents) pour
   un mouvement organique. Coupé sous prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes lw-drift-a {
    0%, 100% { translate: 0 0; }
    25% { translate: 7px -5px; }
    50% { translate: -3px 6px; }
    75% { translate: 5px 3px; }
  }
  @keyframes lw-drift-b {
    0%, 100% { translate: 0 0; }
    30% { translate: -6px 5px; }
    60% { translate: 6px 6px; }
    80% { translate: 2px -5px; }
  }
  @keyframes lw-drift-c {
    0%, 100% { translate: 0 0; }
    35% { translate: 5px 6px; }
    65% { translate: -6px -4px; }
  }
  .pitch-seq.is-seq .pitch-step { animation: lw-drift-a 19s ease-in-out infinite; }
  .pitch-seq.is-seq .pitch-step--center { animation-name: lw-drift-b; animation-duration: 24s; animation-delay: -3s; }
  .pitch-seq.is-seq .pitch-step--tl { animation-delay: -9s; }
  .pitch-seq.is-seq .pitch-step--tr { animation-name: lw-drift-c; animation-duration: 21s; animation-delay: -5s; }
  .pitch-seq.is-seq .pitch-step--bl { animation-name: lw-drift-b; animation-duration: 26s; animation-delay: -13s; }
  .pitch-seq.is-seq .pitch-step--br { animation-name: lw-drift-c; animation-duration: 22s; animation-delay: -7s; }
}

/* La galaxie reste dans la zone épinglée (fond du pin) */
.pitch-seq .pitch-pin > .galaxy { z-index: 0; }

/* ------------------------------------------------------------
   Fond « galaxie » — champ de particules animé sur les bandes
   foncées (canvas dessiné par main.js / initGalaxy).
   ------------------------------------------------------------ */

.galaxy {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s var(--ease-soft);
}

.galaxy.is-on { opacity: 1; }

/* ------------------------------------------------------------
   Les trois piliers
   ------------------------------------------------------------ */

/* Chaque pilier porte une teinte de base en accent discret */
.pillar--mind { --pillar: var(--teal);      --pillar-ink: var(--teal-deep); }
.pillar--body { --pillar: var(--aubergine); --pillar-ink: var(--aubergine); }
.pillar--soul { --pillar: var(--wine);      --pillar-ink: var(--wine); }

/* Slider vertical piloté par le scroll : la photo glisse vers celle du
   pilier suivant, le numéro flippe, le nom + texte se fondent.
   Base (no-JS / reduced-motion) : les 3 piliers empilés, lisibles. */

.ps-slide + .ps-slide { margin-top: clamp(2.5rem, 6vw, 5rem); }

.ps-grid { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 860px) { .ps-grid { grid-template-columns: 1.05fr 1fr; } }

.ps-media .media {
  border-radius: var(--radius-soft);
  box-shadow: 0 34px 80px color-mix(in srgb, var(--charcoal) 16%, transparent);
  aspect-ratio: 4 / 5;
}

/* En mode slider la boîte est presque carrée (0,915) alors que la photo est en
   4:5 : `cover` rognerait ~113px EN HAUT et couperait les têtes. Les photos sont
   cadrées avec l'espace au-dessus des têtes -> on les ancre en haut, le rognage
   se fait par le bas (sol, jambes). Sans effet en mode empilé (boîte déjà 4:5). */
.ps-media .media img { object-position: 50% 0; }

/* En-tête flippant (mode slider) : caché par défaut, montré en .is-pslider.
   En-tête par bloc (.ps-panel-head) : l'inverse (mode empilé lisible). */
.ps-head { display: none; align-items: baseline; gap: 0.55em; font-size: clamp(1.6rem, 2.8vw, 2.2rem); margin-bottom: 1.4rem; }
.pillars.is-pslider .ps-head { display: flex; }

.ps-num {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-weight: 300;   /* le plus mince disponible (Cormorant Light) */
  font-size: 1.1em;
  color: var(--ps-accent, var(--teal-deep));
}

.ps-panel-head {
  display: flex;
  align-items: baseline;
  gap: 0.55em;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  margin-bottom: 0.4rem;
}
.ps-panel-head .ps-pn {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-weight: 300;   /* le plus mince disponible (Cormorant Light) */
  font-size: 1.1em;
  color: var(--pillar-ink);
}
.pillars.is-pslider .ps-panel-head { display: none; }
.ps-panel .signature { color: var(--pillar-ink, var(--teal-deep)); }
.ps-panel > p { font-size: 1.02rem; color: var(--ink-soft); }
.ps-panel > p:first-child { margin-top: 0; }

.pillar-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem 1.4rem;
  font-size: 0.98rem;
  color: var(--ink-soft);
  margin-block: 0.4rem;
}
@media (max-width: 520px) { .pillar-list { grid-template-columns: 1fr; } }
.pillar-list li { display: flex; align-items: baseline; gap: 0.7em; }
.pillar-list li::before {
  content: '';
  flex: none;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--pillar);
  transform: translateY(-2px);
}

.signature {
  padding-top: 0.4rem;
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.15rem, 1.9vw, 1.35rem);
  line-height: 1.5;
  color: var(--pillar-ink, var(--teal-deep));
}

.ps-panel { display: flex; flex-direction: column; gap: 1.1rem; }

/* --- Intro épinglée : révélation du titre MOT PAR MOT au scroll --- */
.ps-intro.is-on { position: relative; height: var(--ps-intro-h, 340vh); }
.ps-intro.is-on .ps-intro-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
}
.ps-word { display: inline-block; will-change: opacity, transform; }

/* Réduit le vide entre l'intro et « Mind » : le slider remonte pour combler
   l'espace pendant que le titre s'efface (Mind glisse par-dessus la sortie).
   Uniquement en mode épinglé (>=900px, is-on). */
/* Le recouvrement n'a de sens que si le slider est LUI AUSSI épinglé : il vient
   alors combler le scroll vide de la fin de l'intro. Si le slider est statique
   (mobile), ce -70vh ferait remonter les piliers PAR-DESSUS le titre épinglé.
   Sur desktop les deux classes sont présentes : comportement inchangé. */
.pillars.is-pslider .ps-intro.is-on ~ .ps-stage { margin-top: -70vh; }

/* --- Mode enrichi : slider épinglé (grand écran + mouvement) --- */
/* 440vh (et non 320) : les 2 transitions gardent leur rythme (~110vh chacune,
   sur p[0, 0.65]) et le reste sert de TENUE pour le dernier pilier (Soul),
   qui reste lisible avant que la section ne se relâche. Voir HOLD_AT. */
.pillars.is-pslider .ps-stage { position: relative; height: var(--ps-h, 440vh); }

.pillars.is-pslider .ps-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: flex;
  align-items: center;
}

.pillars.is-pslider .ps-media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-soft);
  height: min(72vh, 620px);
}

.pillars.is-pslider .ps-media .media { aspect-ratio: auto; height: 100%; border-radius: 0; box-shadow: none; }

.pillars.is-pslider .ps-track {
  position: absolute;
  top: 0; left: 0; right: 0;
  will-change: transform;
}

.pillars.is-pslider .ps-slide { height: min(72vh, 620px); margin: 0; }

.pillars.is-pslider .ps-head { perspective: 700px; }
.pillars.is-pslider .ps-num,
.pillars.is-pslider .ps-name {
  display: inline-block;
  transform-origin: center;
  backface-visibility: hidden;
}

.pillars.is-pslider .ps-panels { position: relative; }
.pillars.is-pslider .ps-panel {
  position: absolute;
  inset: 0;
  opacity: 0;
  will-change: opacity;
}

/* ------------------------------------------------------------
   Le lieu — galerie « zoom parallax »
   Base (no-JS / reduced-motion) : grille lisible.
   Enrichi (.is-zoom, posé par main.js) : pile de photos qui se
   zooment au scroll dans un conteneur épinglé de 300vh.
   ------------------------------------------------------------ */

.zoom { margin-bottom: clamp(3rem, 6vw, 4.5rem); }

/* -- Base : grille responsive -- */
.zoom-sticky {
  width: min(var(--container), 100% - clamp(2.5rem, 8vw, 5rem));
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.1rem;
}

@media (min-width: 700px) { .zoom-sticky { grid-template-columns: repeat(3, 1fr); } }

.zoom-el .media { aspect-ratio: 4 / 3; height: 100%; }
.zoom-img { height: 100%; }

/* -- Enrichi : zoom parallax épinglé --
   Hauteur = plongeon (ZOOM_VH) + lecture vidéo scrubée (SCRUB_VH) + « reveal
   tail » (le reste) pendant lequel le dernier frame reste figé et la section
   « Le lieu » arrondie glisse par-dessus. Voir main.js / initZoom. */
.zoom.is-zoom { position: relative; height: 690vh; margin-bottom: 0; }

.zoom.is-zoom .zoom-sticky {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  display: block;
  will-change: opacity;   /* fondu de la vidéo vers le crème en fin de reveal */
}

.zoom.is-zoom .zoom-el {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: scale(1);
  will-change: transform;
}

.zoom.is-zoom .zoom-img {
  position: relative;
  width: 25vw;
  height: 25vh;
  height: 25svh;
}

.zoom.is-zoom .zoom-el .media {
  aspect-ratio: auto;
  width: 100%;
  height: 100%;
  border-radius: 12px;
}

/* Tuile centrale : boîte plein écran -> la vidéo est rastérisée à la
   taille d'affichage (nette). Elle est mise à l'échelle de 0,25 à 1
   (voir data-s0/data-s), jamais agrandie au-delà de sa résolution. */
.zoom.is-zoom .zoom-el--center .zoom-img {
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  height: 100svh;
}

.zoom.is-zoom .zoom-el--center .media { border-radius: 0; }

/* Phase de lecture vidéo : les tuiles périphériques (déjà hors écran)
   sont retirées du rendu pour libérer le GPU et fluidifier le scrub. */
.zoom.is-zoom.is-scrubbing .zoom-el:not(.zoom-el--center) { visibility: hidden; }

/* Positions/tailles des tuiles périphériques (façon zoom parallax) */
.zoom.is-zoom .zoom-el--1 .zoom-img { top: -30vh; left: 5vw;     width: 35vw; height: 30vh; }
.zoom.is-zoom .zoom-el--2 .zoom-img { top: -10vh; left: -25vw;   width: 20vw; height: 45vh; }
.zoom.is-zoom .zoom-el--3 .zoom-img {            left: 27.5vw;   width: 25vw; height: 25vh; }
.zoom.is-zoom .zoom-el--4 .zoom-img { top: 27.5vh; left: 5vw;    width: 20vw; height: 25vh; }
.zoom.is-zoom .zoom-el--5 .zoom-img { top: 27.5vh; left: -22.5vw; width: 30vw; height: 25vh; }
.zoom.is-zoom .zoom-el--6 .zoom-img { top: 22.5vh; left: 25vw;   width: 15vw; height: 15vh; }

/* Respiration entre la galerie zoom et le texte qui suit */
.lieu-after { padding-top: clamp(3.5rem, 8vw, 7rem); }

/* -- Enrichi : « Le lieu » devient un panneau crème arrondi qui GLISSE
   par-dessus la vidéo figée (dernier frame sticky, plus de fondu de sortie).
   - margin-top négatif = remonte sur le « reveal tail » de .zoom (voir
     ZOOM_VH/SCRUB_VH dans main.js) : le panneau entre par le bas de l'écran
     pile quand la vidéo se fige, puis monte par-dessus au scroll.
   - z-index au-dessus du sticky + fond crème OPAQUE pour occulter la vidéo.
   - coins hauts très arrondis (réf. envoyée), largeur réduite (« moins
     large »), même couleur (crème). Ombre douce vers le haut = effet « monte
     par-dessus ». */
.zoom.is-zoom + .lieu-after {
  position: relative;
  z-index: 2;
  margin-top: -120vh;
  /* Beaucoup plus large : marges latérales resserrées (~180px sur grand écran). */
  width: min(1560px, 100% - clamp(2rem, 8vw, 11rem));
  margin-inline: auto;
  background: var(--cream);
  border-radius: clamp(30px, 4.5vw, 60px) clamp(30px, 4.5vw, 60px) 0 0;
  padding: clamp(8.5rem, 16vw, 18rem) clamp(1.5rem, 4vw, 3.5rem) 0;
}

/* Deux colonnes : texte resserré à gauche, carrousel 3D à droite (écart généreux) */
.lieu-grid { display: grid; gap: clamp(3.5rem, 8vw, 9rem); align-items: center; }

@media (min-width: 960px) {
  .lieu-grid { grid-template-columns: minmax(0, 1fr) clamp(360px, 40vw, 520px); }
  /* Décale le carrousel vers la droite (dans la marge) sans le rétrécir */
  .lieu-media { transform: translateX(clamp(24px, 5vw, 110px)); }
}

.lieu-body { display: grid; gap: 1.5rem; }
/* Titre rapproché du texte (on annule la grande marge par défaut du head) */
.lieu-body .section-head { margin-bottom: 0.4rem; }
.lieu-body .lieu-badges { margin-block: 0.4rem 0; }

.lieu-text { display: grid; gap: 1.5rem; color: var(--ink-soft); }
/* Paragraphes du lieu : police ÉDITORIALE (Georgia, déjà utilisée pour les
   accents du site) + interligne aéré et corps un peu plus grand -> rendu plus
   premium et lisible que le sans par défaut. */
.lieu-text p {
  font-family: var(--font-editorial);
  font-size: clamp(1.1rem, 1rem + 0.35vw, 1.22rem);
  line-height: 1.82;
  letter-spacing: 0.003em;
}

/* ------------------------------------------------------------
   Carrousel photo 3D (cylindre rotatif)
   ------------------------------------------------------------ */

.carousel3d { --cell-w: clamp(120px, 13vw, 165px); }

/* La scène peut laisser respirer les cartes de bord au-delà de sa boîte */
.carousel3d.is-3d .carousel3d-stage { overflow: visible; }

/* Repli (avant enrichissement JS) : simple rangée défilable */
.carousel3d-ring {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.carousel3d-cell { flex: 0 0 60%; margin: 0; }

/* Enrichi : cylindre 3D */
.carousel3d.is-3d .carousel3d-stage {
  position: relative;
  height: calc(var(--cell-w) * 4 / 3 + 3rem);
  perspective: 1100px;
  cursor: grab;
  touch-action: pan-y;
}

.carousel3d.is-3d .carousel3d-stage:active { cursor: grabbing; }

.carousel3d.is-3d .carousel3d-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  display: block;
  overflow: visible;
  width: var(--cell-w);
  height: calc(var(--cell-w) * 4 / 3);
  margin-left: calc(var(--cell-w) / -2);
  margin-top: calc(var(--cell-w) * 4 / 3 / -2);
  transform-style: preserve-3d;
  will-change: transform;
}

.carousel3d.is-3d .carousel3d-cell {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.carousel3d-cell .media {
  width: 100%;
  height: 100%;
  border-radius: 14px;
  box-shadow: 0 20px 45px color-mix(in srgb, var(--charcoal) 20%, transparent);
}

.carousel3d.is-3d .carousel3d-cell { cursor: zoom-in; }

.carousel3d-hint {
  margin-top: 0.6rem;
  text-align: center;
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: 0.8;
}

@media (hover: none) { .carousel3d-hint::after { content: ' (touche)'; } }

/* Bouton CTA sous le carrousel du lieu (colonne droite, centré). */
.lieu-cta { margin-top: clamp(1.6rem, 3vw, 2.4rem); text-align: center; }

/* Verre translucide (liquid glass) — UNIQUEMENT les boutons des PRIX (verre
   blanc). Le bouton du LIEU et celui des témoignages gardent le .btn--call
   d'origine « bouton 1 » (teinte douce presque blanche, non touché). */
.price-card .btn--call {
  -webkit-backdrop-filter: blur(14px) saturate(1.35);
  backdrop-filter: blur(14px) saturate(1.35);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),      /* reflet haut */
    inset 0 0 0 1px rgba(255, 255, 255, 0.6),    /* mini bordure pâle -> effet verre */
    0 8px 22px color-mix(in srgb, var(--charcoal) 9%, transparent);
}
.price-card .btn--call { background: color-mix(in srgb, var(--white) 32%, transparent); }              /* verre blanc */

/* ------------------------------------------------------------
   Visionneuse plein écran (lightbox) — injectée par main.js
   ------------------------------------------------------------ */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: color-mix(in srgb, var(--charcoal) 90%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.lightbox.is-open { display: flex; animation: lb-fade 0.3s var(--ease-soft); }

.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 10px;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.55);
  animation: lb-zoom 0.35s var(--ease-soft);
}

.lightbox-close {
  position: absolute;
  top: clamp(0.75rem, 2vw, 1.4rem);
  right: clamp(0.75rem, 2vw, 1.4rem);
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 1.7rem;
  line-height: 1;
  color: var(--cream);
  background: color-mix(in srgb, var(--cream) 12%, transparent);
  transition: background-color 0.3s var(--ease-soft), transform 0.3s var(--ease-soft);
}

.lightbox-close:hover,
.lightbox-close:focus-visible {
  background: color-mix(in srgb, var(--cream) 22%, transparent);
  transform: scale(1.06);
}

.lightbox-close:focus-visible { outline: 2px solid var(--cream); outline-offset: 3px; }

@keyframes lb-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lb-zoom { from { transform: scale(0.92); opacity: 0; } to { transform: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .lightbox.is-open, .lightbox-img { animation: none !important; }
  .lightbox-close { transition: none !important; }
}

.lieu-badges { margin-block: clamp(2.2rem, 4vw, 3rem); }
/* Tags du lieu revisités : rectangle arrondi doux, teinte bleue subtile, fin
   liseré bleu et texte bleu -> plus posé et « de marque » que la pilule blanche
   translucide de base. (Scopé au lieu : ne touche pas les badges du hero.) */
.lieu-badges .badge {
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--color-celestial-tides) 22%, transparent);
  background: color-mix(in srgb, var(--color-celestial-tides) 7%, var(--white));
  color: var(--color-celestial-tides);
}

/* Corps en Open Sans ; Georgia italique réservée aux accents
   (boutons, numéros, grands chiffres et citations). */
.closing-line {
  margin-top: clamp(3rem, 6vw, 5rem); /* respiration après les badges */
  font-size: clamp(1.02rem, 1.7vw, 1.24rem);
  font-style: italic;
  line-height: 1.7;
  max-width: 40rem;
}

/* ------------------------------------------------------------
   Split photo / texte (La table)
   ------------------------------------------------------------ */

.split-grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: center;
}

@media (min-width: 900px) {
  /* Texte à GAUCHE (colonne large), vidéo à DROITE. L'ordre du DOM garde la
     vidéo en premier (c'est le sujet de la section) : on inverse visuellement
     avec `order`, sans toucher au balisage ni au scrub. */
  .split-grid { grid-template-columns: 7fr 5fr; }
  .split-text { order: 1; }
  .table-media-col { order: 2; }
}

.split-text { display: grid; gap: 1.4rem; }
.split-text p { color: var(--ink-soft); }

.media-caption { margin-top: 0.9rem; font-size: 0.9rem; color: var(--ink-soft); }

/* La table : le crédit d'Anita n'est pas une petite légende technique, c'est
   une signature -> on le compose plus grand. Scopé pour ne pas grossir les
   futures légendes qui utiliseraient .media-caption. */
.table-section .media-caption {
  margin-top: 1.1rem;
  font-size: clamp(1.05rem, 1.3vw, 1.2rem);
}

/* La table — vidéo (portrait) de la cheffe Anita, ratio natif de la vidéo. */
.table-media { aspect-ratio: 864 / 1294; }
.table-video { display: block; }

/* Mode enrichi (>=900px + mouvement) : section épinglée, la vidéo défile au
   scroll (voir main.js / initTableScrub). */
.table-section.is-scrub .table-stage { position: relative; height: var(--table-h, 300vh); }
.table-section.is-scrub .table-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
}

/* ------------------------------------------------------------
   L'équipe — présentateur animé (pile de portraits + panneau texte)
   Base (no-JS) : liste lisible photo + nom + rôle + description.
   Enrichi (.is-enhanced, posé par main.js) : une pile de portraits
   qui pivotent, un membre à la fois, avec navigation.
   ------------------------------------------------------------ */

.crew-photos {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2.4rem 1.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 700px) {
  .crew-photos { grid-template-columns: repeat(3, 1fr); }
}

.crew-member figure { margin: 0; display: grid; gap: 0.9rem; }
.crew-member .media { border-radius: var(--radius-soft); }
.crew-caption { display: grid; gap: 0.3rem; }
.crew-name { font-size: 1.18rem; }

.crew-role {
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.crew-quote { font-size: 0.95rem; color: var(--ink-soft); }

/* Panneau + contrôles cachés tant que le JS n'a pas pris le relais */
.crew-info { display: none; }

/* --- Mode enrichi --- */
.crew.is-enhanced .crew-slider {
  display: grid;
  gap: clamp(2.4rem, 5vw, 4rem);
  align-items: center;
}

@media (min-width: 860px) {
  /* Photo à GAUCHE, texte de présentation à DROITE (photo = auto, texte = 1fr). */
  .crew.is-enhanced .crew-slider { grid-template-columns: auto 1fr; }
  .crew.is-enhanced .crew-photos { order: 1; }
  .crew.is-enhanced .crew-info { order: 2; }

  /* Le titre de section se cale AU-DESSUS de la photo, aligné à GAUCHE. Il
     déborde volontairement un peu plus loin vers la DROITE que la photo
     (340px). Élargi à 600px + text-wrap:balance pour que le nouveau titre
     (« Une équipe qui marche à tes côtés. ») tienne sur DEUX lignes équilibrées
     au lieu de trois. */
  .crew.is-enhanced .section-head {
    width: min(600px, 84vw);
    max-width: none;
    margin-left: 0;
    margin-right: auto;
    margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
    text-align: left;
  }
  .crew.is-enhanced .section-head h2 { text-wrap: balance; }
}

/* Dimensions explicites : la pile n'a que des enfants en position
   absolute, donc un conteneur en aspect-ratio seul s'effondrerait. */
.crew.is-enhanced .crew-photos {
  display: block;
  position: relative;
  width: min(340px, 72vw);
  height: calc(min(340px, 72vw) * 4 / 3);
  margin-inline: auto;
  perspective: 1000px;
}

.crew.is-enhanced .crew-member {
  position: absolute;
  inset: 0;
  transform: rotate(var(--rot, 0deg)) scale(0.94);
  opacity: 0;
  transition: transform 0.7s var(--ease-soft), opacity 0.7s var(--ease-soft);
  will-change: transform, opacity;
}

.crew.is-enhanced .crew-member figure { display: block; height: 100%; }
.crew.is-enhanced .crew-member .media { height: 100%; box-shadow: 0 30px 70px color-mix(in srgb, var(--charcoal) 40%, transparent); }
.crew.is-enhanced .crew-caption { display: none; }

/* Cartes derrière : légèrement pivotées et estompées */
.crew.is-enhanced .crew-member.is-behind { opacity: 0.34; }

/* Carte active : à plat, au-dessus */
.crew.is-enhanced .crew-member.is-active {
  transform: rotate(0deg) scale(1);
  opacity: 1;
  z-index: 3;
}

/* Panneau texte */
.crew.is-enhanced .crew-info {
  display: flex;
  flex-direction: column;
  gap: clamp(1.6rem, 4vw, 2.6rem);
}

.crew-panel { min-height: 11rem; }

.crew-panel .crew-name {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  margin-bottom: 0.4rem;
}

.crew-panel .crew-role { margin-bottom: 1.3rem; }

.crew-panel .crew-quote {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.1rem, 1.95vw, 1.4rem);
  line-height: 1.5;
  color: var(--ink);
}

/* Mot par mot (fade + montée + net) — voir animations.css */
.crew-word {
  display: inline-block;
  white-space: pre;
}

.crew-controls { display: flex; align-items: center; gap: 1.4rem; }

.crew-count {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--accent-ink);
  letter-spacing: 0.04em;
}

.crew-arrows { display: flex; gap: 0.7rem; }

.crew-arrow {
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--cream) 8%, transparent);
  transition: transform 0.35s var(--ease-soft), background-color 0.35s var(--ease-soft);
}

.crew-arrow svg { width: 22px; height: 22px; }

.crew-arrow:hover,
.crew-arrow:focus-visible {
  transform: translateY(-2px);
  background: color-mix(in srgb, var(--cream) 16%, transparent);
}

.crew-arrow:active { transform: translateY(0); }

/* --- Sortie pilotée par le scroll (grand écran) ---
   La section se fige (container sticky, centré), ses items s'envolent, puis
   les cartes de la section suivante arrivent par-dessus, sur le MÊME fond
   aubergine. Posé par main.js / initCrewFlow. */
.crew.is-outro { position: relative; height: var(--crew-h, 200vh); padding-block: 0; }
.crew.is-outro > .container {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: clamp(3.5rem, 8vh, 5.5rem);   /* dégage le contenu sous la nav */
  padding-bottom: clamp(1.5rem, 4vh, 2.5rem);
}

/* ------------------------------------------------------------
   Ce que tu ramènes — grille de crochets
   ------------------------------------------------------------ */

.check-grid {
  display: grid;
  gap: 1.3rem 2.2rem;
}

@media (min-width: 600px)  { .check-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .check-grid { grid-template-columns: repeat(3, 1fr); } }

.check-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75em;
  font-size: 1.04rem;
}

.check {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 0.22em;
  color: var(--check-ink, var(--teal));
}

/* Listes à crochets plus compactes (VIP, prix, après) */
.check-list { display: grid; gap: 0.55rem; }
.check-list li { display: flex; align-items: flex-start; gap: 0.7em; }
.check-list .check { width: 18px; height: 18px; margin-top: 0.3em; }

/* ------------------------------------------------------------
   Ce que tu ramènes — cartes « arche / portail »
   Forme hors du commun : le haut forme un demi-cercle (arche),
   le bas reste légèrement arrondi. Icône + titre + courte
   description, centrés. Halo doux qui rappelle la lumière signature.
   Fond aubergine (comme l'équipe) : la section arrive PAR-DESSUS l'équipe
   figée (fondu en place, aucune descente) — voir main.js / initGiftFly.
   ------------------------------------------------------------ */
/* Séquentiel : l'équipe sort d'abord ; PUIS cette section se fige et les cartes
   apparaissent une par une (voir initGiftFly). Même fond aubergine que l'équipe
   -> le passage d'une scène à l'autre est invisible (pas de superposition). */
/* Chevauchement : la section remonte sur la fin (VIDE) de la sortie de l'équipe
   -> le titre apparaît juste après l'envol, plus de long scroll vide. Même fond
   aubergine que l'équipe -> le chevauchement du fond est invisible ; le CONTENU
   (titre/cartes) ne s'affiche qu'après (p >= 0.02), donc aucune superposition. */
.gift-section.is-fly {
  position: relative;
  z-index: 2;
  margin-top: -75vh;
  /* En mode épinglé, le stage donne toute la hauteur : le padding de section
     ne ferait que retarder l'arrivée de la section suivante sous la scène. */
  padding-block: 0;
}
.gift-section.is-fly .gift-stage { position: relative; height: var(--gift-h, 620vh); }
.gift-word { display: inline-block; will-change: opacity, transform; }

/* Le fond aubergine devient une COUCHE (le <section> reste transparent) : on
   peut ainsi le faire disparaître en fondu à la fin du zoom arrière des cartes,
   pour révéler la section suivante. Il couvre toute la section (padding inclus)
   -> aucune bande blanche. */
.gift-section { background: transparent; }
.gift-bg { position: absolute; inset: 0; z-index: 0; background: var(--aubergine); }

/* Fond photo « retraite » : couche AU-DESSUS de l'aubergine, SOUS les cartes.
   Sticky -> couvre le viewport épinglé (un cover sur les 620vh du stage
   déformerait l'image). Révélée par JS EN MÊME TEMPS que les cartes
   (initGiftFly). Voile aubergine pour garder les textes lisibles. */
.gift-photo {
  position: sticky;
  top: 0;
  height: 100vh;
  margin-bottom: -100vh;      /* couche : n'occupe aucun espace de flux */
  z-index: 0;
  pointer-events: none;
  opacity: 0;                 /* révélée au scroll */
  will-change: opacity;
  background:
    linear-gradient(color-mix(in srgb, var(--aubergine) 75%, transparent),
                    color-mix(in srgb, var(--aubergine) 75%, transparent)),
    url('../img/fond-retraite.webp?v=712509a3') center / cover no-repeat;
}
@media (max-width: 899px) {
  .gift-photo { height: 100svh; margin-bottom: -100svh; }
}
.gift-section .gift-stage { position: relative; z-index: 1; }
.gift-section.is-fly .gift-grid { will-change: transform, opacity; }

/* FONDU ENCHAÎNÉ bénéfices -> prix (desktop). Les prix remontent de -100vh SOUS la
   fin des bénéfices : ils sont donc DERRIÈRE (z-index 1) le fond aubergine des
   bénéfices (z-index 2). Quand cet aubergine s'efface en fin de scène (déjà géré
   par initGiftFly), il révèle les prix directement — plus de blanc intermédiaire.
   Les prix se calent en haut de l'écran à la toute fin (p=1.0), puis défilent
   normalement. Scopé is-fly -> desktop uniquement (mobile inchangé). */
.gift-section.is-fly ~ .invest-wrap { margin-top: -100vh; }
.gift-section.is-fly .gift-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
}
.gift-section.is-fly .gift-pin > .container { position: relative; }
/* Le titre est centré EN ABSOLU par-dessus la grille : il apparaît, s'envole,
   puis les cartes se révèlent à la même place (voir initGiftFly). */
.gift-section.is-fly .section-head {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  margin-block: 0;
  margin-inline: auto;   /* reste centré (max-width 46rem) */
  z-index: 2;
  will-change: opacity, transform;
}
.gift-section.is-fly .gift-card { will-change: opacity, transform; }

.gift-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.7rem, 3.4vw, 3.2rem);
  margin-top: clamp(1.1rem, 2.2vw, 1.9rem);
  max-width: 960px;          /* grille plus étroite -> cartes plus petites, plus d'air */
  margin-inline: auto;
  list-style: none;
  padding: 0;
}
@media (min-width: 620px) { .gift-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .gift-grid { grid-template-columns: repeat(3, 1fr); } }

.gift-card {
  --accent: var(--powder-blue);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.3rem;
  padding: clamp(1rem, 1.5vw, 1.35rem) clamp(0.9rem, 1.4vw, 1.25rem);
  /* Forme ABSTRAITE : blob organique (border-radius asymétrique), varié par colonne. */
  border-radius: 52% 48% 56% 44% / 50% 54% 46% 50%;
  /* LIQUID GLASS : verre translucide foncé (l'aubergine transparaît) + flou
     d'arrière-plan + reflet en haut + bord fin lumineux. Un soupçon d'accent
     clair en haut pour une identité par colonne, sinon monochrome et clean. */
  background:
    radial-gradient(120% 55% at 50% 0%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 62%),
    linear-gradient(165deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.045));
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow:
    0 18px 46px rgba(10, 4, 10, 0.30),
    inset 0 1px 0 rgba(255, 255, 255, 0.40);
  transition: border-color 0.4s var(--ease-soft), box-shadow 0.4s var(--ease-soft),
    background 0.4s var(--ease-soft);
}

/* Soupçon d'accent CLAIR par colonne (lisible sur verre foncé). */
.gift-card:nth-child(3n+1) { --accent: var(--powder-blue); border-radius: 58% 42% 56% 44% / 52% 58% 42% 48%; }
.gift-card:nth-child(3n+2) { --accent: var(--tan);         border-radius: 44% 56% 46% 54% / 58% 44% 56% 42%; }
.gift-card:nth-child(3n+3) { --accent: var(--sage);        border-radius: 54% 46% 60% 40% / 44% 54% 46% 56%; }

/* Survol : le verre s'illumine (bord + reflet), sans transform — la carte est
   déjà animée en transform par le scroll (initGiftFly). */
.gift-card:hover {
  border-color: rgba(255, 255, 255, 0.30);
  box-shadow:
    0 28px 62px rgba(10, 4, 10, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

.gift-icon {
  width: clamp(33px, 3.6vw, 40px);
  height: clamp(33px, 3.6vw, 40px);
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--cream);
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45);
  margin-bottom: 0.2rem;
}
.gift-icon svg { width: 56%; height: 56%; }

.gift-title {
  font-size: clamp(0.88rem, 1.02vw, 0.98rem);
  line-height: 1.25;
  max-width: 20ch;
  text-transform: uppercase;
  color: var(--cream);                                     /* texte clair sur verre */
}
.gift-desc {
  font-size: 0.82rem;
  line-height: 1.5;
  color: color-mix(in srgb, var(--cream) 74%, transparent);
  max-width: 26ch;
}

/* ------------------------------------------------------------
   Bande CTA (teal) — texte composé grand (contraste AA « large »)
   ------------------------------------------------------------ */

.cta-band { background: none; text-align: center; }

/* ------------------------------------------------------------
   Bande CTA finale en 2 COLONNES : cadre-appareil (gauche) + texte (droite).
   La choré de scroll (initCtaSeq) est inchangée : elle agit sur le h2 et les
   groupes, désormais dans la colonne de droite (.cta-text). Desktop : 2 colonnes ;
   mobile : empilé (cadre au-dessus du texte).
   ------------------------------------------------------------ */
.cta-layout {
  display: grid;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
@media (min-width: 900px) {
  .cta-layout { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
}

/* Cadre-appareil en LIQUID GLASS + profondeur 3D : verre translucide (flou
   d'arrière-plan -> le teal transparaît flouté), biseau lumineux (arête haute
   claire / basse sombre), reflet spéculaire par-dessus, et écran ENFONCÉ dans
   le verre (inset). */
.cta-frame {
  position: relative;
  width: min(360px, 82%);
  margin-inline: auto;
  aspect-ratio: 3 / 4;
  border-radius: 34px;
  padding: clamp(15px, 1.9vw, 22px);
  background: linear-gradient(150deg,
    rgba(255, 255, 255, 0.32),
    rgba(255, 255, 255, 0.07) 46%,
    rgba(255, 255, 255, 0.18));
  -webkit-backdrop-filter: blur(22px) saturate(1.7);
  backdrop-filter: blur(22px) saturate(1.7);
  border: 1px solid rgba(255, 255, 255, 0.38);
  box-shadow:
    0 44px 92px rgba(0, 0, 0, 0.34),              /* lévitation */
    0 10px 26px rgba(0, 0, 0, 0.20),
    inset 0 2px 1px rgba(255, 255, 255, 0.70),    /* arête HAUTE lumineuse (3D) */
    inset 0 -3px 5px rgba(0, 0, 0, 0.22),         /* arête BASSE sombre (3D) */
    inset 0 0 0 1px rgba(255, 255, 255, 0.10);
  isolation: isolate;
}
/* Reflet « verre » : lumière spéculaire en haut-gauche, par-dessus tout -> donne
   l'épaisseur et le côté vitré. */
.cta-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(130% 72% at 20% -10%, rgba(255, 255, 255, 0.40), rgba(255, 255, 255, 0) 52%),
    linear-gradient(158deg, rgba(255, 255, 255, 0.20), rgba(255, 255, 255, 0) 24%);
}
/* MOBILE — le cadre est la seule variable ajustable du budget vertical de cette
   scène (les textes sont intouchables). La scène ne s'épingle que si son contenu
   tient dans l'écran (main.js / sceneActive) ; sinon on obtient un trou avec du
   texte invisible. Budget : colonne texte (~365px) + gouttière (32px) + marge du
   garde-fou (24px) => il reste `100svh - 421px` pour le cadre. On retire 440px
   pour garder un coussin.
   `svh` et NON `vh`/innerHeight : svh vaut toujours le viewport le PLUS PETIT
   (barre d'adresse iOS visible), donc le cadre est taillé pour le pire cas et le
   garde-fou est d'accord dans tous les états — ça supprime aussi le basculement
   en plein scroll quand la barre se rétracte.
   Pas de plancher : sur un très petit écran le cadre rapetisse, mais la scène
   ne casse jamais. `* 0.75` = l'aspect-ratio 3/4 (largeur = hauteur x 3/4).

   DEUX termes gouvernent la taille, et il faut GARDER LES DEUX :
   - `28svh * 0.75` = la taille VOULUE (demande client : cadre discret, la
     section finale respire). C'est lui qui gouverne sur un téléphone normal.
   - `(100svh - 440px) * 0.75` = le FIT, filet de sécurité. Il ne mord que sur
     les très petits écrans (iPhone SE), où il rapetisse encore le cadre pour
     que la scène tienne. Le retirer ramènerait le trou de texte invisible. */
@media (max-width: 899px) {
  .cta-frame {
    width: min(360px, 82%, calc(28vh * 0.75), calc((100vh - 440px) * 0.75));
    width: min(360px, 82%, calc(28svh * 0.75), calc((100svh - 440px) * 0.75));
  }
}

.cta-frame-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 18px;
  overflow: hidden;
  background: rgba(8, 12, 16, 0.28);            /* léger fond translucide sous l'image */
  box-shadow:
    inset 0 3px 8px rgba(0, 0, 0, 0.42),         /* écran ENFONCÉ dans le verre (3D) */
    inset 0 0 0 1px rgba(255, 255, 255, 0.22),
    inset 0 -1px 2px rgba(255, 255, 255, 0.10);
}
.cta-frame-screen .img-placeholder { border-radius: 18px; }
/* Les 3 photos se superposent ; leur opacité est pilotée au scroll (fondu
   croisé, main.js / initCtaSeq). Défaut (mobile / avant JS) : photo 1 visible. */
.cta-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}
.cta-photo:first-of-type { opacity: 1; }
/* En mode épinglé (desktop), le cadre part MASQUÉ puis est révélé par le JS pile
   quand le mot « c'était » apparaît (main.js / initCtaSeq). Mobile : toujours visible. */
.cta-band.is-cta .cta-frame { opacity: 0; will-change: opacity; }

/* Couche de fond (teal + bloom) : c'est ELLE qu'on fait apparaître en fondu
   en premier, avant tout texte (main.js / initCtaSeq).
   `pointer-events: none` : couche purement décorative (aria-hidden). Sans ça, la
   scène CTA remontant de -60vh sur les prix, cette couche INVISIBLE interceptait
   le tap sur « Ajouter l'option VIP ». Mesuré sur mobile, pas supposé. */
.cta-bg-layer { position: absolute; inset: 0; pointer-events: none; }

/* Toute la scène CTA est transparente aux doigts : remontée de -60vh, elle
   chevauche la fin des prix. Le porter sur .cta-pin ne suffisait pas — c'est
   .cta-stage qui interceptait ensuite. Seul le bouton final redevient cliquable,
   et seulement une fois révélé (initCtaSeq passe groupB à pointer-events: auto). */
.cta-band.is-cta { pointer-events: none; }

/* CTA finale — SÉQUENCE ÉPINGLÉE : la section se superpose à la fin des prix
   (recouvrement) et apparaît EN FONDU sans qu'on descende. Puis, au scroll :
   1) le fond seul, 2) le titre mot par mot, 3) les 3 « Pas de… » une par une,
   4) elles s'effacent, 5) la chute (2 phrases + bouton) apparaît.
   >=900px + mouvement; sinon : section normale, tout visible. */
.cta-band.is-cta {
  position: relative;
  z-index: 2;                              /* passe par-dessus la scène des prix */
  margin-top: var(--cta-overlap, -60vh);
  /* En mode épinglé, c'est le stage qui donne toute la hauteur. Le padding de
     section resterait SOUS le stage sans aucun fond (le teal vit dans le pin)
     -> bande blanche avant le footer. */
  padding-block: 0;
}
.cta-band.is-cta .cta-stage { position: relative; height: var(--cta-h, 560vh); }
.cta-band.is-cta .cta-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
}
.cta-band.is-cta .cta-pin > .container { position: relative; z-index: 1; }
.cta-band.is-cta .cta-seq { position: relative; }
.cta-band.is-cta .cta-group {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  will-change: opacity, transform;
}
.cta-word { display: inline-block; will-change: opacity, transform; }

/* Le bouton est enveloppé : on anime l'enveloppe, jamais le bouton lui-même
   (il garde sa transition de survol). */
.cta-btn-wrap { will-change: opacity, transform; }

/* Le clip absorbe le débordement du fond pendant son scale(1.04 → 1);
   le dégradé très subtil (teal sur teal) rend la respiration du fond
   perceptible sans toucher à la palette. */
.cta-bg-clip { position: absolute; inset: 0; overflow: hidden; }

.cta-bg {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 50% 20%, color-mix(in srgb, var(--powder-blue) 14%, transparent), transparent 60%),
    var(--teal);
}

/* Georgia le plus fin (demande cliente). Crème sur bleu Mermaid ≈ 11:1,
   la finesse ne pose aucun souci de contraste. */
.cta-lines {
  margin-top: 2.2rem;
  font-family: var(--font-editorial);    /* Georgia */
  font-size: clamp(1.22rem, 2.3vw, 1.55rem);
  font-weight: 100;                        /* Georgia rend au plus léger (~régulier) */
  line-height: 2;
}

.cta-lines .poeme-line { display: block; }

.cta-final {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: 1.25em;
}

/* La couleur vient de --accent-ink du thème (blanc sur teal : AA large) */
.cta-final .accent { font-size: 1.35em; }

/* Ligne finale, trois traitements : « Ton équilibre » Georgia (défaut),
   « Ton essence » Royal MAJUSCULES, « Toi » Royal minuscules. */
.cta-final .cta-essence {
  font-family: var(--font-display);   /* Royal */
  font-style: normal;
  text-transform: uppercase;
}
.cta-final .cta-toi {
  font-family: var(--font-display);   /* Royal */
  font-style: normal;
  text-transform: lowercase;
}

.cta-band .btn { margin-top: 2.6rem; }

/* Le bouton final FLOTTE doucement (gauche-droite + haut-bas). Via la propriété
   `translate` -> se compose avec le `transform` (survol du bouton + révélation
   de .cta-btn-wrap) sans conflit. Coupé sous prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes cta-btn-float {
    0%, 100% { translate: 0 0; }
    25% { translate: 7px -6px; }
    50% { translate: -5px 5px; }
    75% { translate: 6px 4px; }
  }
  .cta-btn-wrap .btn { animation: cta-btn-float 8.5s ease-in-out infinite; }
}

/* Variante BLEUTÉE réutilisable du .btn--call (texte blanc) — bande CTA +
   cartes de prix. Repos = pilule bleue #4B6D77 ; survol = remplissage
   #6D9BA8 balayé de gauche à droite ; texte blanc dans les deux états. */
.btn--call.btn--blue {
  /* Liquid glass : bleu translucide + flou d'arrière-plan (pas 100% opaque). */
  background: color-mix(in srgb, var(--color-celestial-tides) 72%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
  color: #fff;
  text-shadow: 0 1px 6px color-mix(in srgb, var(--color-celestial-tides) 55%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),                       /* reflet haut */
    inset 0 0 0 1px color-mix(in srgb, #fff 22%, transparent),     /* bord verre */
    0 12px 30px color-mix(in srgb, var(--color-celestial-tides) 26%, transparent);
}
.btn--call.btn--blue::before { background: color-mix(in srgb, var(--color-celestial-light) 60%, transparent); }
.btn--call.btn--blue .btn-arrow {
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-celestial-tides);   /* cercle blanc translucide, flèche bleue */
}
.btn--call.btn--blue:hover,
.btn--call.btn--blue:focus-visible { color: #fff; }
.btn--call.btn--blue:hover .btn-arrow,
.btn--call.btn--blue:focus-visible .btn-arrow {
  background: #fff;
  color: var(--color-celestial-tides);
}

/* ------------------------------------------------------------
   Après l'immersion + Option VIP
   ------------------------------------------------------------ */

.apres-grid { display: grid; gap: clamp(3rem, 6vw, 4.5rem); }

.apres-intro { max-width: 46rem; display: grid; gap: 1.4rem; }
.apres-intro p { color: var(--ink-soft); }

/* Ancre du bloom qui « allume » la carte (pattern glow-vip) */
.vip-wrap { position: relative; }

.vip-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-soft);
  padding: clamp(2.2rem, 4.5vw, 3.6rem);
  box-shadow: 0 32px 80px color-mix(in srgb, var(--wine) 30%, transparent);
}

.vip-card > * { position: relative; z-index: 1; }

.vip-tag {
  display: inline-block;
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tan);
  padding: 0.55em 1.1em;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-btn);
  margin-bottom: 1.6rem;
}

.vip-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.8rem 1.6rem; }

.vip-price {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(2.4rem, 5vw, 3.4rem);
  line-height: 1;
}

.vip-value { font-size: 0.95rem; color: var(--ink-soft); }

.vip-intro { margin-top: 1.4rem; max-width: 40rem; color: var(--ink-soft); }

.vip-list { margin-top: 2.4rem; display: grid; gap: 1.6rem; counter-reset: vip; }

.vip-list > li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.1rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--hairline);
}

.vip-list > li::before {
  counter-increment: vip;
  content: counter(vip, decimal-leading-zero);
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: 1.35rem;
  line-height: 1.3;
  color: var(--tan);
}

.vip-list h4 { font-size: 1.08rem; }
.vip-list p { margin-top: 0.4rem; font-size: 0.95rem; color: var(--ink-soft); }
.vip-list .check-list { margin-top: 0.9rem; font-size: 0.93rem; color: var(--ink-soft); }
.vip-card .check { --check-ink: var(--tan); }

/* Inclusions de la retraite : réutilise .vip-list sur fond clair (numéros en
   teal profond, lisibles sur crème), liste centrée et resserrée. */
.incl-list { max-width: 46rem; margin-inline: auto; }
.incl-list > li::before { color: var(--teal-deep); }
.incl-list h4 { text-transform: uppercase; }   /* capitales nettes (sans les fioritures Royal) */

/* Inclus dans la retraite — SÉQUENCE au scroll (main.js / initInclScroll) :
   la section se fige, le TITRE se révèle mot par mot puis RESTE en en-tête,
   et les 7 inclusions apparaissent/disparaissent UNE PAR UNE dessous (fondu
   enchaîné + légère montée). Le bloc (titre + fenêtre d'inclusions) est centré
   pour que le titre garde une position stable. >=900px + mouvement; sinon :
   titre + liste normale, tout visible. */
.incl-section.is-incl .incl-stage { position: relative; height: var(--incl-h, 860vh); }
.incl-section.is-incl .incl-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
}
/* Le titre reste fixe au-dessus de la fenêtre d'inclusions. */
.incl-section.is-incl .incl-head { margin-bottom: clamp(2.5rem, 6vh, 5rem); }
.incl-section.is-incl .incl-list { position: relative; }   /* fenêtre : les items se superposent */
.incl-section.is-incl .incl-list > li {
  position: absolute;
  inset: 0;
  margin: 0;
  border-top: none;      /* pas de séparateur en mode empilé */
  padding-top: 0;
  /* Toutes les inclusions démarrent à la MÊME hauteur (le haut de la
     fenêtre, sous le titre) et se déroulent vers le bas : les courtes
     comme les longues commencent au même endroit. */
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  will-change: opacity, transform;
}

/* Option VIP : liste des extras + phrase de clôture en accent */
.vip-extras { margin-top: 1.8rem; }
.vip-outro { margin-top: 1.4rem; font-family: var(--font-accent); font-style: italic; }

/* ------------------------------------------------------------
   Ton investissement — cartes de prix
   ------------------------------------------------------------ */

/* Investissement — UN SEUL fond lumineux (aura + anneau shader), partagé par
   les inclusions et les prix, qui reste FIXE (sticky) pendant que le contenu
   change. La couche de fond ne pousse pas le contenu (margin négative). */
.invest-wrap { position: relative; }
.invest-bg {
  position: sticky;
  top: 0;
  height: 100vh;
  margin-bottom: -100vh;   /* couche de fond : n'occupe pas d'espace de flux */
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--cream);
}
/* Les deux sections deviennent transparentes : le fond partagé transparaît. */
.invest-section { position: relative; z-index: 1; background: transparent; }

/* Crossfade final : les prix remontent par-dessus la fin des inclusions
   (recouvrement) pour entrer pendant que les inclusions sortent, sur le même
   fond. Uniquement en mode piloté (JS actif). */
.invest-wrap.is-flow .pricing { margin-top: var(--invest-overlap, -100vh); }
.incl-section.is-incl .incl-pin .container,
.invest-wrap.is-flow .pricing > .container { will-change: opacity, transform; }

/* Fond doux « aurora » de marque derrière les cartes verre (glassy). */
.pricing { position: relative; overflow: hidden; }
.pricing > .container { position: relative; z-index: 1; }
.pricing-aura {
  position: absolute;
  inset: -12% -6%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(38% 46% at 16% 26%, color-mix(in srgb, var(--teal) 40%, transparent), transparent 68%),
    radial-gradient(42% 52% at 84% 22%, color-mix(in srgb, var(--tan) 52%, transparent), transparent 70%),
    radial-gradient(46% 48% at 62% 70%, color-mix(in srgb, var(--powder-blue) 46%, transparent), transparent 70%),
    radial-gradient(40% 44% at 34% 88%, color-mix(in srgb, var(--raspberry) 22%, transparent), transparent 72%);
  filter: blur(26px) saturate(1.15);
}

/* Anneau lumineux animé (shader WebGL, porté en vanilla) au-dessus de l'aura,
   derrière les cartes. Repli : si pas de WebGL / reduced-motion, seule l'aura
   reste. */
.pricing-shader {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.price-grid { display: grid; gap: clamp(1.4rem, 2.4vw, 2rem); align-items: stretch; }
@media (min-width: 960px) {
  /* Hauteurs décalées façon « arche » (comme la référence) : la carte du
     milieu monte, les deux côtés descendent. Offset en margin pour ne pas
     entrer en conflit avec les transform de survol / d'échelle. Les cartes
     prennent leur hauteur naturelle (align-items: start) : elles ne sont
     plus toutes à la même hauteur. */
  .price-grid { grid-template-columns: repeat(3, 1fr); align-items: start; }
  .price-card { margin-top: 2.4rem; }
  .price-card--double { margin-top: 0; }
}

/* Cartes de prix en VERRE translucide (glassy) — lisent le fond aurora. */
.price-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  border-radius: 24px;
  padding: clamp(1.7rem, 3vw, 2.4rem);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.62), rgba(255, 255, 255, 0.30));
  -webkit-backdrop-filter: blur(20px) saturate(1.35);
  backdrop-filter: blur(20px) saturate(1.35);
  border: 1px solid color-mix(in srgb, var(--white) 45%, transparent);
  box-shadow:
    0 22px 55px color-mix(in srgb, var(--charcoal) 9%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  transition: transform 0.4s var(--ease-soft), box-shadow 0.4s var(--ease-soft);
}
.price-card:hover {
  transform: translateY(-5px);
  box-shadow:
    0 32px 72px color-mix(in srgb, var(--charcoal) 13%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.75);
}
.price-card--double {
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--powder-blue) 20%, rgba(255, 255, 255, 0.60)),
    rgba(255, 255, 255, 0.30));
}

/* Carte VIP (3e, à droite) : accent chaud, léger relief, badge. */
.price-card--vip {
  background: linear-gradient(155deg,
    color-mix(in srgb, var(--tan) 26%, rgba(255, 255, 255, 0.56)),
    rgba(255, 255, 255, 0.30));
  border-color: color-mix(in srgb, var(--burnt-orange) 38%, transparent);
  box-shadow:
    0 26px 64px color-mix(in srgb, var(--burnt-orange) 22%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
.price-card--vip .check { --check-ink: var(--burnt-orange); }
@media (min-width: 960px) {
  .price-card--vip { transform: scale(1.045); z-index: 1; }
  .price-card--vip:hover { transform: scale(1.045) translateY(-5px); }
}

/* Dérive LENTE et douce des cartes (haut-bas + gauche-droite), chacune à son
   rythme pour un mouvement organique. Utilise la propriété `translate` -> se
   COMPOSE avec les `transform` (hover, scale VIP) sans conflit. Coupé sous
   prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes price-float-a {
    0%, 100% { translate: 0 0; }
    25% { translate: 8px -11px; }
    50% { translate: -6px 8px; }
    75% { translate: 7px 6px; }
  }
  @keyframes price-float-b {
    0%, 100% { translate: 0 0; }
    30% { translate: -9px 7px; }
    60% { translate: 8px 10px; }
    80% { translate: 4px -8px; }
  }
  @keyframes price-float-c {
    0%, 100% { translate: 0 0; }
    35% { translate: 8px 9px; }
    65% { translate: -9px -6px; }
  }
  .price-card        { animation: price-float-a 16s ease-in-out infinite; }
  .price-card--double { animation-name: price-float-b; animation-duration: 20s; animation-delay: -5s; }
  .price-card--vip    { animation-name: price-float-c; animation-duration: 18s; animation-delay: -9s; }
}

.glass-badge {
  position: absolute;
  top: -0.85rem;
  right: 1.4rem;
  font-family: var(--font-title);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.5em 1em;
  border-radius: 999px;
  background: var(--burnt-orange);
  color: var(--cream);
  box-shadow: 0 8px 20px color-mix(in srgb, var(--burnt-orange) 42%, transparent);
}

.glass-divider {
  height: 1px;
  margin: 0.1rem 0 0.3rem;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--charcoal) 14%, transparent) 50%, transparent);
}
.price-card--vip .glass-divider {
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--burnt-orange) 42%, transparent) 50%, transparent);
}

.price-was {
  display: inline-block;
  font-size: 0.44em;
  color: var(--ink-soft);
  text-decoration: line-through;
  /* L'épaisseur `auto` écrasait le chiffre (police fine) : on force un trait FIN
     et légèrement transparent -> « 1 500 $ » redevient lisible. */
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--ink-soft) 55%, transparent);
  margin-left: 0.35em;
  vertical-align: middle;
}

.price-name { font-size: 1.25rem; text-transform: uppercase; }
.price-name-sub { display: block; font-size: 0.78em; font-weight: 400; color: var(--ink-soft); margin-top: 0.15rem; }

.price-figure {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(3rem, 6vw, 4.1rem);
  line-height: 1;
  /* Prix en BLEU + « shine » infini qui balaye les montants. */
  color: var(--color-celestial-tides);   /* repli si background-clip: text non géré */
  background-image: linear-gradient(110deg,
    var(--color-celestial-tides) 0%, var(--color-celestial-tides) 42%,
    #bcd8df 50%,
    var(--color-celestial-tides) 58%, var(--color-celestial-tides) 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: price-shine 3.4s linear infinite;
}
/* Les sous-labels ne brillent pas (on annule le fill transparent hérité). */
.price-figure .price-per,
.price-figure .price-figure-note,
.price-figure .price-was {
  -webkit-text-fill-color: currentColor;
  color: var(--ink-soft);
}
@keyframes price-shine {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .price-figure {
    animation: none;
    background-image: none;
    -webkit-text-fill-color: var(--color-celestial-tides);
  }
}

.price-figure-note { font-size: 0.42em; }

.price-per {
  display: block;
  margin-top: 0.55rem;
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.price-note { font-size: 0.95rem; color: var(--ink-soft); }

.price-card .check-list { color: var(--ink-soft); font-size: 0.98rem; margin-bottom: clamp(1.4rem, 3vw, 2.1rem); }

/* Demande cliente : les TEXTES des cartes de prix en Cormorant fin (même
   réglage que le pitch « Un espace où tu n'as rien à gérer… »), tailles
   inchangées. Le titre (.price-name, Royal) et les boutons ne bougent pas. */
.price-figure,
.price-per,
.price-figure-note,
.price-was,
.price-name-sub,
.price-card .check-list {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-weight: 300;
  font-style: normal;
}
/* Descriptions d'inclusions plus épaisses ET plus contrastées (demande cliente). */
.price-card .check-list { font-weight: 600; color: var(--ink); }

/* Option VIP — bloc repliable « + » : dévoile au clic toutes les inclusions de la
   retraite. <details> natif (accessible, sans JS). */
/* Rapproche le bouton « + » de la liste : on resserre la marge de la liste des 5
   avantages (direct-child de la carte, sans toucher la liste dépliée). */
.price-card--vip > .check-list { margin-bottom: 0.55rem; }
.vip-more { margin: 0 0 clamp(1.2rem, 2.4vw, 1.7rem); }
.vip-more > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.15rem 0;
  color: var(--accent-ink);
  font-weight: 600;
  font-size: 0.9rem;   /* plus petit (était ~17px) */
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.vip-more > summary::-webkit-details-marker { display: none; }  /* masque le triangle par défaut */
.vip-more > summary::marker { content: ''; }
.vip-more > summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 3px; border-radius: 6px; }
.vip-more > summary:hover .vip-more-icon { background: color-mix(in srgb, var(--accent-ink) 12%, transparent); }

/* Icône « + » (deux barres) -> « − » quand ouvert. */
.vip-more-icon {
  position: relative;
  flex: none;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  transition: background-color 0.25s var(--ease-soft);
}
.vip-more-icon::before,
.vip-more-icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: opacity 0.2s var(--ease-soft);
}
.vip-more-icon::before { width: 8px; height: 1.5px; }   /* barre horizontale */
.vip-more-icon::after  { width: 1.5px; height: 8px; }   /* barre verticale -> « + » */
.vip-more[open] .vip-more-icon::after { opacity: 0; }    /* « + » devient « − » */

.vip-more-list { margin-top: 0.8rem; margin-bottom: 0; }
/* La classe .check-list pose display:grid, ce qui écrase le masquage natif du
   <details> fermé (règle auteur > règle navigateur). On re-masque explicitement
   quand ce n'est pas ouvert. */
.vip-more:not([open]) .vip-more-list { display: none; }

.price-card .btn { margin-top: auto; align-self: flex-start; }

/* Pastille de réassurance SOUS le bouton de chaque carte : verre BLEUTÉ (teinte
   Celestial), icône carte bancaire + libellé. Le `gap` de 1.15rem de la carte
   l'éloignerait trop du CTA -> marge négative pour qu'elle s'y rattache. */
.pay-tag {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  margin-top: -0.6rem;
  padding: 0.42em 0.95em 0.42em 0.8em;
  border-radius: 999px;
  font-family: var(--font-title);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--color-celestial-tides);
  background: color-mix(in srgb, var(--powder-blue) 14%, rgba(255, 255, 255, 0.5));
  border: 1px solid color-mix(in srgb, var(--powder-blue) 30%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
}
.pay-tag-icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  opacity: 0.85;
}
/* Carte VIP : même bleu, un cran plus soutenu pour tenir sur son fond teinté. */
.price-card--vip .pay-tag {
  color: color-mix(in srgb, var(--color-mermaid-blue) 55%, var(--color-celestial-tides));
  background: color-mix(in srgb, var(--powder-blue) 20%, rgba(255, 255, 255, 0.5));
  border-color: color-mix(in srgb, var(--powder-blue) 42%, transparent);
}

.vip-reminder {
  margin-top: clamp(2.6rem, 5vw, 3.6rem);
  text-align: center;
  color: var(--ink-soft);
}

.vip-reminder a { color: var(--accent-ink); }

.rarity-line {
  margin-top: 1.2rem;
  text-align: center;
  font-family: var(--font-title);
  font-weight: 500;
  font-size: 0.9rem;
  letter-spacing: 0.06em;
}

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

.site-footer { padding-block: calc(var(--section-y) * 0.62) 2.4rem; }

.footer-grid { display: grid; gap: 3rem; }

@media (min-width: 800px) {
  .footer-grid { grid-template-columns: 2.2fr 1fr 1fr; gap: 4rem; }
}

.footer-devise {
  margin-top: 1.7rem;
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 500;
  font-size: 1.28rem;
  line-height: 1.6;
  max-width: 26rem;
  color: var(--ink-soft);
}

.footer-title {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: 1.2rem;
}

.footer-col ul { display: grid; gap: 0.55rem; }

.footer-col a {
  font-size: 0.98rem;
  color: var(--ink-soft);
  text-decoration: none;
}

.footer-col a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------
   Liens « Nous joindre » : icônes en LIQUID GLASS BLEU sur le footer sombre.
   Sélecteurs à 3 classes pour passer devant `.footer-col a:hover` (qui
   souligne) — d'où le text-decoration: none explicite.
   ------------------------------------------------------------ */
/* `.footer-col ul` (classe+élément) bat une simple classe -> on scope pour
   imposer la rangée horizontale. */
.footer-col .footer-social {
  display: flex;          /* annule le `display: grid` de .footer-col ul */
  flex-wrap: wrap;        /* 4 icônes : passent à la ligne si la colonne est étroite */
  gap: 0.85rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.footer-social .social-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: var(--color-celestial-light);
  text-decoration: none;
  /* verre bleu translucide + flou d'arrière-plan */
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--color-celestial-light) 26%, transparent),
    color-mix(in srgb, var(--color-celestial-light) 9%, transparent));
  -webkit-backdrop-filter: blur(12px) saturate(1.5);
  backdrop-filter: blur(12px) saturate(1.5);
  border: 1px solid color-mix(in srgb, var(--color-celestial-light) 42%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--white) 28%, transparent),   /* arête haute (3D) */
    0 8px 20px rgba(0, 0, 0, 0.28);
  transition:
    transform 0.4s var(--ease-soft),
    background 0.4s var(--ease-soft),
    box-shadow 0.4s var(--ease-soft),
    color 0.4s var(--ease-soft),
    border-color 0.4s var(--ease-soft);
}

.footer-social .social-icon svg { width: 20px; height: 20px; display: block; }

/* Hover : le verre s'illumine, l'icône se soulève et passe en crème. */
.footer-social .social-icon:hover,
.footer-social .social-icon:focus-visible {
  transform: translateY(-3px);
  color: var(--cream);
  text-decoration: none;
  border-color: color-mix(in srgb, var(--color-celestial-light) 75%, transparent);
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--color-celestial-light) 55%, transparent),
    color-mix(in srgb, var(--color-celestial-light) 24%, transparent));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--white) 45%, transparent),
    0 14px 30px color-mix(in srgb, var(--color-celestial-light) 32%, transparent);
}

.footer-legal {
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: 1.8rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.footer-legal a { color: inherit; text-underline-offset: 3px; }

/* ------------------------------------------------------------
   Bannière de consentement (Loi 25) — injectée par consent.js
   ------------------------------------------------------------ */

.consent {
  position: fixed;
  z-index: 150;
  inset-inline: 1rem;
  bottom: 1rem;
  margin-inline: auto;
  max-width: 34rem;
  display: none;
  background: var(--charcoal);
  color: var(--cream);
  border-radius: var(--radius-soft);
  padding: 1.4rem 1.6rem;
  box-shadow: 0 26px 70px color-mix(in srgb, var(--charcoal) 50%, transparent);
  --ink: var(--cream);
  --ink-soft: color-mix(in srgb, var(--cream) 82%, var(--charcoal));
  --btn-bg: var(--cream);
  --btn-ink: var(--charcoal);
  --focus-ring: var(--cream);
  --hairline: color-mix(in srgb, var(--cream) 25%, transparent);
}

.consent.is-open { display: block; }

.consent p { font-size: 0.95rem; line-height: 1.6; }

.consent-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.8rem 1.1rem;
  margin-top: 1.1rem;
}

.consent-actions a { font-size: 0.86rem; color: var(--ink-soft); text-underline-offset: 3px; }

.consent-close {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ink-soft);
}

.consent-close:hover { color: var(--ink); }

/* ------------------------------------------------------------
   Pages secondaires (stub, politique)
   ------------------------------------------------------------ */

.page-hero { padding-block: calc(var(--section-y) * 0.7); }

.prose { max-width: 47rem; }
.prose h2 { margin-top: clamp(2.6rem, 5vw, 3.6rem); margin-bottom: 1rem; }
.prose p, .prose li { color: var(--ink-soft); }
.prose p + p { margin-top: 1em; }
.prose ul { padding-left: 1.2em; }
.prose li { margin-block: 0.4em; }

.back-link { margin-top: 2.6rem; }

/* Bouton-lien discret (ex. « Gérer mes témoins » dans le footer) */
.link-btn {
  padding: 0;
  font-size: inherit;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Nav mobile : CTA compact à côté du burger */
@media (max-width: 479px) {
  .nav-cta { font-size: 0.95rem; padding: 0.55em 1.05em; }   /* « Inscription » tient partout */
  .logo-light { font-size: 1.3rem; }
  .logo-worker { font-size: 0.88rem; }
}

/* ============================================================
   MOBILE — scènes épinglées activées (<900px)
   Ce bloc ne s'applique jamais au desktop : aucune régression
   possible sur la version 1440px.
   ============================================================ */
@media (max-width: 899px) {
  /* D1 — durées recalibrées à ~73%. Un cran de molette avance ~100px, un coup
     de pouce ~1200px avec l'inertie : à hauteur égale, l'utilisateur mobile
     traverserait deux ou trois « temps » d'une animation en un seul geste. */
  .ps-intro.is-on                        { --ps-intro-h: 250vh; }
  .incl-section.is-incl .incl-stage      { --incl-h: 630vh; }
  .cta-band.is-cta .cta-stage            { --cta-h: 410vh; }

  /* Le panneau doit tenir dans l'écran RÉELLEMENT visible. `100vh` vaut la
     hauteur barre d'URL RÉTRACTÉE : le panneau serait alors plus haut que
     window.innerHeight et se décrocherait avant la fin de son animation.
     `100svh` est la hauteur barre affichée -> toujours <= innerHeight. */
  .ps-intro.is-on .ps-intro-pin          { min-height: 100svh; }
  .incl-section.is-incl .incl-pin        { min-height: 100svh; }
  .cta-band.is-cta .cta-pin              { min-height: 100svh; }

  /* Le stage des témoignages reste au-dessus de tout résidu de couche. (Le
     `isolation: isolate` posé en même temps a été retiré : il ajoutait un contexte
     d'empilement sur le hero sans corriger le bug, dont la vraie cause était la
     couche sticky EN FLUX — voir plus bas.) */
  .testi .testi-stage { position: relative; z-index: 1; }

  /* Témoignages : UNE SEULE carte à la fois (plus de languettes des voisines), et
     on la change avec les flèches placées juste sous la carte. Le balayage au doigt
     continue de fonctionner (scroll-snap). .is-swipe est posée par initTestimonials
     quand le mode épinglé est inactif -> jamais présente sur grand écran. */
  .testi.is-swipe .testi-track { padding-inline: 0; gap: 0; }
  .testi.is-swipe .testi-card {
    flex: 0 0 100%;                              /* la carte occupe tout l'écran */
    scroll-snap-align: center;
    padding-inline: clamp(1.25rem, 5vw, 2rem);   /* la figure reste en retrait des bords */
  }
  .testi.is-swipe .testi-dots { display: none; } /* remplacées par flèches + compteur */
  .testi.is-swipe .testi-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.1rem;
    margin-bottom: 1.7rem;
  }

  /* Hero : la photo de fond reste en place pendant que le contenu monte, puis se
     libère quand la vidéo est centrée.

     BUG iOS RÉSOLU ICI. La v1 utilisait `position: sticky` sur la couche EN FLUX
     (100svh), suivie d'un frère (.hero-grid) remonté de -505px par une marge
     négative qui la chevauchait. Diagnostic sur l'appareil : les cartes de la
     section suivante existaient (dimensions, fond, opacité 1, au sommet de la pile)
     mais n'étaient PAS PEINTES. La couche aubergine des bénéfices, elle, marche —
     et sa seule différence est d'être HORS FLUX. On sort donc la couche du flux :
     `position: absolute`, et c'est le JS (initHeroBgPin) qui la déplace. Plus de
     sticky, plus de marge négative, donc plus de chevauchement de flux. */
  /* Hero CENTRÉ plein écran : le contenu (dates, logo, tagline, boutons, places)
     est centré verticalement au-dessus de la photo (couche hors flux ci-dessous). */
  .hero {
    min-height: 100svh;
    display: flex;
    align-items: center;
    padding-block: clamp(5rem, 11svh, 7.5rem);
  }
  .hero > .container { width: 100%; }

  .hero-bg {
    position: absolute;
    inset: auto;              /* annule le inset:0 du mode desktop */
    top: 0; left: 0; right: 0;
    height: 100svh;
  }

  /* Ce que tu ramènes (les 9 cases) : RÉACTIVÉ sur mobile à la demande du client
     (D4 levé). Fond aubergine STICKY, titre épinglé un peu au-dessus du centre, et
     les cartes montent une par une dans une fenêtre dessous (JS : initGiftFly /
     branche is-rise). */
  /* Le fond aubergine est devenu STICKY (100svh) : il ne couvre donc plus le
     padding de section, qui laissait voir 110px de blanc en haut ET en bas. En
     mode épinglé, le stage donne toute la hauteur -> padding inutile (le desktop
     fait déjà pareil sur .is-fly). */
  .gift-section.is-rise { padding-block: 0; }

  /* On rapproche l'équipe de la section suivante (même fond aubergine). */
  .crew.is-enhanced { padding-bottom: clamp(1.6rem, 5svh, 3rem); }

  .gift-section.is-rise .gift-bg {
    position: sticky;
    top: 0;
    height: 100svh;
    margin-bottom: -100svh;   /* couche de fond : n'occupe pas d'espace de flux */
  }
  .gift-section.is-rise .gift-stage { position: relative; z-index: 1; height: var(--gift-h, 420vh); }
  .gift-section.is-rise .gift-pin {
    position: sticky;
    top: 0;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding-top: 32svh;        /* titre un peu au-dessus du centre */
  }
  .gift-section.is-rise .gift-pin > .container { position: relative; }
  .gift-section.is-rise .section-head {
    position: relative;
    z-index: 2;
    margin: 0 auto clamp(3rem, 11svh, 7rem);   /* éloigne le titre de la 1re carte */
  }
  /* Fenêtre : les cartes se superposent (une visible à la fois, elle monte). */
  .gift-section.is-rise .gift-grid {
    position: relative;
    grid-template-columns: 1fr;
    margin: 0 auto;
  }
  .gift-section.is-rise .gift-grid > li {
    position: absolute;
    inset: 0;
    margin: 0;
    will-change: opacity, transform;
  }

  /* Inclus dans la retraite : on descend titre + contenu UNIQUEMENT quand l'écran
     est assez grand pour le permettre. La plus haute inclusion (Telegram + 7 points,
     ~450px) remplit déjà les petits téléphones : y ajouter un décalage couperait
     son bas. La formule max(0, (100svh − 43rem)·0,32) vaut 0 sous ~688px (rien ne
     bouge, rien n'est coupé) et grandit sur les grands téléphones (le contenu
     descend, l'espace vide du bas est utilisé). */
  .incl-section.is-incl .incl-pin { padding-top: max(0px, (100svh - 43rem) * 0.32); }

  /* ----- La table : scrub vidéo activé sur mobile (même moteur que le chalet).
     D2 — la vidéo portrait passe PLEIN CADRE dans le pin, le texte de la cliente
     passe PAR-DESSUS sur un voile dégradé. Rien de séquentiel : le texte est un
     overlay statique pendant tout le scrub, il tient dans le 100svh visible. ----- */
  .table-section.is-scrub .table-stage   { --table-h: 220vh; }   /* ~73% du 300vh desktop (D1) */
  .table-section.is-scrub .table-pin     { min-height: 100svh; } /* jamais 100vh (règle svh) */

  .table-section.is-scrub .split-grid {
    position: relative;
    z-index: 0;                    /* contexte d'empilement : la vidéo z-index:-1 reste derrière DANS la grille */
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;     /* texte ancré EN BAS (la nav sticky occupe le haut) */
    gap: 0;
    padding: 0;                    /* full-bleed : annule le padding de .container */
    max-width: none;
    width: 100%;
    overflow: hidden;
  }

  /* La vidéo remplit toute la grille. .table-media-col reste NON positionnée pour
     que l'ancre de .table-media (inset:0) soit .split-grid, pas la colonne. */
  .table-section.is-scrub .table-media-col { position: static; }
  .table-section.is-scrub .table-media {
    position: absolute;
    inset: 0;
    aspect-ratio: auto;            /* annule le ratio 864/1294 en flux */
    border-radius: 0;
    z-index: -1;                   /* derrière le texte (qui peint au-dessus sans z-index) */
    margin: 0;
  }
  .table-section.is-scrub .table-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Ordre de lecture : d'abord le texte de section, puis la légende « Anita ». */
  .table-section.is-scrub .split-text     { order: 1; }
  .table-section.is-scrub .table-media-col { order: 2; }

  /* Voile de lisibilité : dégradé sombre qui monte dans la vidéo, texte en blanc.
     Aucun texte n'est raccourci (D4). */
  .table-section.is-scrub .split-text {
    padding: 2.4rem 1.4rem 0.6rem;
    gap: 0.9rem;
    background: linear-gradient(to top, rgba(5,5,5,0.92) 62%, rgba(5,5,5,0) 100%);
  }
  .table-section.is-scrub .table-media-col {
    padding: 0 1.4rem 2.4rem;
    background: rgba(5,5,5,0.92);
  }
  .table-section.is-scrub .split-text .eyebrow,
  .table-section.is-scrub .split-text h2,
  .table-section.is-scrub .split-text p,
  .table-section.is-scrub .split-text .signature,
  .table-section.is-scrub .media-caption { color: #fff; }
  .table-section.is-scrub .split-text .signature { color: rgba(255,255,255,0.9); }
  .table-section.is-scrub .media-caption {
    margin: 0;
    text-shadow: 0 1px 10px rgba(0,0,0,0.5);
  }

  /* ----- Pitch : séquence des 5 blocs activée sur mobile. Les coins desktop
     (44% ≈ 165px à 375px) seraient illisibles -> on recentre les 5 blocs pleine
     largeur, révélés UN À LA FOIS (opacité/flou pilotés par initPitchSeq). Chaque
     bloc (≤160px) centré tient dans ~640px : aucune perte sous le pli. ----- */
  .pitch-seq.is-seq                { --pitch-h: 420vh; }   /* ~73% de 580vh (D1) */
  .pitch-seq.is-seq .pitch-pin     { min-height: 100svh; } /* jamais 100vh (règle svh) */

  .pitch-seq.is-seq .pitch-step,
  .pitch-seq.is-seq .pitch-step--center,
  .pitch-seq.is-seq .pitch-step--tl,
  .pitch-seq.is-seq .pitch-step--tr,
  .pitch-seq.is-seq .pitch-step--bl,
  .pitch-seq.is-seq .pitch-step--br {
    top: 50%;
    bottom: auto;
    left: 1.25rem;
    right: 1.25rem;
    transform: translateY(-50%);
    max-width: none;
    margin-inline: auto;
    text-align: center;
  }
  .pitch-seq.is-seq .pitch-dash { margin-inline: auto; }

  /* ----- Piliers Mind/Body/Soul : slider épinglé ACTIVÉ sur mobile.
     Image RÉDUITE et centrée en haut, texte DESSOUS ; au scroll la section est
     épinglée et l'image + le texte changent (pilier 1->2->3, même moteur que le
     desktop). Texte légèrement COMPACTÉ (tous les mots gardés) pour que même le
     pilier Body (liste de 7) tienne dans l'écran. Hauteur d'image en svh -> elle
     rétrécit sur les petits téléphones, donc chaque pilier reste entier. ----- */
  .pillars.is-pslider .ps-stage { --ps-h: 320vh; }                    /* ~73% de 440vh (D1) */
  .pillars.is-pslider .ps-intro.is-on ~ .ps-stage { margin-top: 0; }  /* pas de chevauchement sur l'intro épinglée mobile */
  .pillars.is-pslider .ps-pin { min-height: 100svh; }                 /* jamais 100vh (règle svh) */

  .pillars.is-pslider .ps-grid {
    grid-template-columns: 1fr;   /* une colonne : image en haut, texte dessous */
    gap: 1.7rem;                  /* image -> texte : un peu plus d'air (texte descendu) */
    justify-items: center;
    align-content: center;
  }

  /* Image réduite, centrée. Hauteur en svh pour rétrécir avec le téléphone. */
  .pillars.is-pslider .ps-media { width: min(58vw, 210px); height: min(28svh, 245px); margin-inline: auto; }
  .pillars.is-pslider .ps-slide { height: min(28svh, 245px); }

  /* En-tête (numéro + nom) aligné à GAUCHE, en haut du texte (aligné au texte dessous). */
  .pillars.is-pslider .ps-head { justify-content: flex-start; font-size: 1.5rem; margin-bottom: 0.6rem; }

  /* Texte compacté (mêmes mots) pour tenir sous l'image dans l'écran visible. */
  .pillars.is-pslider .ps-content { width: 100%; }
  .pillars.is-pslider .ps-panel { gap: 0.55rem; }
  .pillars.is-pslider .ps-panel > p { font-size: 0.94rem; line-height: 1.46; }
  .pillars.is-pslider .pillar-list { gap: 0.35rem 1rem; }
  .pillars.is-pslider .pillar-list li { font-size: 0.94rem; }

  /* La table plein cadre : pas de padding de section (sinon ~110px de blanc
     entre le texte de « Le lieu » et la vidéo — gap inutile). */
  .table-section.is-scrub { padding-block: 0; }

  /* Équipe : les flèches (+ compteur) remontent AU-DESSUS du nom, juste sous la
     photo, pour une navigation à portée de pouce. */
  .crew.is-enhanced .crew-controls { order: -1; }
}

/* ------------------------------------------------------------
   POP-UP D'INSCRIPTION — une étape à la fois (voir assets/js/form.js).
   Le balisage est injecté par le JS ; ces règles l'habillent.
   ------------------------------------------------------------ */

.lwf {
  width: 100%;
  max-width: min(540px, calc(100vw - 2rem));
  /* Le navigateur centre un <dialog> modal avec `margin: auto` — mais le reset
     du site (`* { margin: 0 }`, brand.css) l'écrasait : la boîte partait en haut
     à gauche. On le rétablit ici. */
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--charcoal);
}
/* Fond volontairement léger : on laisse deviner le site derrière. */
.lwf::backdrop {
  background: color-mix(in srgb, var(--charcoal) 38%, transparent);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

/* LIQUID GLASS de marque : verre clair très flouté, biseau lumineux en haut,
   ombre douce en bas, et une pointe de bleu Lightworker dans la matière. */
/* Le flou vit dans ::before, pas ici. Chrome détoure mal le backdrop-filter
   d'un élément selon son propre border-radius : il le peint dans le rectangle
   CARRÉ -> quatre taches claires dans les coins. Un `overflow: hidden` posé
   ici n'y change rien (overflow ne découpe que les ENFANTS). D'où le montage :
   le parent ne porte que l'arrondi + le détourage, et le flou descend dans un
   enfant, que ce détourage attrape pour de bon. Ne pas refusionner les deux. */
.lwf-boite {
  position: relative;
  isolation: isolate;   /* garde les pseudos en z-index négatif à l'intérieur */
  overflow: hidden;
  border-radius: 26px;
  padding: clamp(1.5rem, 3.6vw, 2.3rem);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--white) 72%, transparent);
  box-shadow:
    0 44px 100px rgba(0, 0, 0, 0.30),           /* lévitation */
    0 10px 26px rgba(0, 0, 0, 0.12),
    inset 0 2px 1px rgba(255, 255, 255, 0.95),  /* arête HAUTE lumineuse (3D) */
    inset 0 -2px 4px color-mix(in srgb, var(--color-celestial-tides) 12%, transparent);
}
/* La matière du verre : teinte + flou. Détourée par l'`overflow` du parent. */
.lwf-boite::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(152deg,
      color-mix(in srgb, var(--white) 88%, transparent),
      color-mix(in srgb, var(--color-celestial-light) 10%, color-mix(in srgb, var(--white) 76%, transparent)) 52%,
      color-mix(in srgb, var(--white) 82%, transparent));
  -webkit-backdrop-filter: blur(34px) saturate(1.7);
  backdrop-filter: blur(34px) saturate(1.7);
}
/* Reflet spéculaire : donne l'épaisseur du verre. Au-dessus de la matière. */
.lwf-boite::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(120% 68% at 18% -8%, rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0) 55%),
    linear-gradient(160deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0) 26%);
}

/* Tête : progression + compteur + fermeture */
.lwf-tete {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: clamp(1.2rem, 3vw, 1.8rem);
}
.lwf-progres {
  flex: 1;
  height: 3px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--color-celestial-tides) 16%, transparent);
  overflow: hidden;
}
.lwf-progres-barre {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: #4B6D77;
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.45s var(--ease-soft);
}
.lwf-compteur {
  font-family: var(--font-title);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: color-mix(in srgb, var(--charcoal) 45%, var(--white));
  white-space: nowrap;
}
.lwf-fermer {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: color-mix(in srgb, var(--charcoal) 55%, var(--white));
  transition: background 0.3s var(--ease-soft), color 0.3s var(--ease-soft);
}
.lwf-fermer svg { width: 17px; height: 17px; }
.lwf-fermer:hover { background: color-mix(in srgb, var(--charcoal) 8%, transparent); color: var(--charcoal); }

/* Scène : les étapes se superposent en absolu -> aucun saut de hauteur
   pendant la transition. */
.lwf-scene { position: relative; min-height: 208px; }

.lwf-etape {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: opacity 0.34s var(--ease-soft), transform 0.34s var(--ease-soft);
}
.lwf-etape.vient-droite { opacity: 0; transform: translateX(36px); }
.lwf-etape.vient-gauche { opacity: 0; transform: translateX(-36px); }
.lwf-etape.part-gauche  { opacity: 0; transform: translateX(-36px); }
.lwf-etape.part-droite  { opacity: 0; transform: translateX(36px); }

.lwf-question {
  margin: 0;
  font-family: var(--font-display);   /* Royal */
  font-weight: 500;
  font-size: clamp(1.32rem, 3.2vw, 1.7rem);
  line-height: 1.25;
  color: var(--charcoal);
}
/* Astérisque des champs requis — même rouge que les messages d'erreur. */
.lwf-requis {
  margin-left: 0.28em;
  font-family: var(--font-title);
  font-weight: 700;
  font-size: 0.62em;
  vertical-align: super;
  color: #b4453f;
}

.lwf-aide {
  margin: 0.55rem 0 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: color-mix(in srgb, var(--charcoal) 58%, var(--white));
}

.lwf-champ {
  width: 100%;
  margin-top: 1.15rem;
  padding: 0.75em 0.1em;
  font: inherit;
  font-size: 1.06rem;
  color: var(--charcoal);
  background: transparent;
  border: 0;
  border-bottom: 2px solid color-mix(in srgb, var(--charcoal) 16%, transparent);
  border-radius: 0;
  transition: border-color 0.3s var(--ease-soft);
}
.lwf-champ:focus { outline: none; border-bottom-color: #4B6D77; }
textarea.lwf-champ { resize: vertical; min-height: 4.4em; }

/* Choix oui / non */
.lwf-choix { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 1.25rem; }
.lwf-option {
  flex: 1 1 auto;
  min-width: 116px;
  padding: 0.85em 1.4em;
  border-radius: 14px;
  font-family: var(--font-title);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #4B6D77;
  background: color-mix(in srgb, #4B6D77 6%, var(--white));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, #4B6D77 26%, transparent);
  transition: background 0.3s var(--ease-soft), color 0.3s var(--ease-soft),
              box-shadow 0.3s var(--ease-soft), transform 0.3s var(--ease-soft);
}
.lwf-option:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1.5px #4B6D77; }
.lwf-option.is-choisi { background: #4B6D77; color: var(--cream); box-shadow: none; }

.lwf-erreur {
  margin: 0.7rem 0 0;
  min-height: 1.2em;
  font-size: 0.85rem;
  color: #b4453f;
}

/* Pied : retour / suivant */
.lwf-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  margin-top: clamp(1.2rem, 3vw, 1.7rem);
}
.lwf-prec {
  font-family: var(--font-title);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--charcoal) 55%, var(--white));
  padding: 0.6em 0.2em;
  transition: color 0.3s var(--ease-soft);
}
.lwf-prec:hover { color: var(--charcoal); }
.lwf-prec[hidden] { display: none; }
.lwf-suiv {
  margin-left: auto;
  padding: 0.85em 1.9em;
  border-radius: 14px;
  background: #4B6D77;
  color: var(--cream);
  font-family: var(--font-title);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: background 0.3s var(--ease-soft), transform 0.3s var(--ease-soft),
              box-shadow 0.3s var(--ease-soft);
}
.lwf-suiv:hover {
  background: var(--color-celestial-light);
  transform: translateY(-2px);
  box-shadow: 0 12px 26px color-mix(in srgb, #4B6D77 40%, transparent);
}

/* États : envoi, succès, échec */
.lwf-etat { align-items: center; text-align: center; }
.lwf-etat .lwf-aide { margin-top: 0.7rem; }
.lwf-etat .lwf-suiv { margin: 1.4rem auto 0; }
.lwf-spin {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, #4B6D77 22%, transparent);
  border-top-color: #4B6D77;
  animation: lwf-tourne 0.75s linear infinite;
}
@keyframes lwf-tourne { to { transform: rotate(360deg); } }
.lwf-coche {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  margin-bottom: 0.3rem;
  border-radius: 50%;
  color: var(--cream);
  background: #4B6D77;
}
.lwf-coche svg { width: 25px; height: 25px; }

/* Piège à robots : hors écran, mais pas `display:none` (que certains
   robots savent ignorer). Invisible et injoignable pour un humain. */
.lwf-pot {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .lwf-etape, .lwf-progres-barre, .lwf-option, .lwf-suiv { transition: none; }
  .lwf-spin { animation: none; }
}

/* ============================================================
   LAPTOP BAS — large mais peu HAUT (1366x768, 1280x800 : ~660-720px de fenêtre).

   Le garde-fou `sceneActive` NE PROTÈGE PAS ici : il vaut `mql.matches ||
   sceneRentre(...)`, et sur desktop `mql.matches` est vrai — le test de fit est
   court-circuité. Au-dessus de 900px de LARGE, une scène s'épingle donc quelle
   que soit la HAUTEUR de l'écran.

   Ces deux scènes sont épinglées en `top: 0` avec une hauteur dictée par leur
   CONTENU (et non par 100vh) : sous ~745px de fenêtre leur bas passe sous le pli,
   et `sticky top:0` ne permet JAMAIS d'atteindre le bas d'un élément plus haut
   que la fenêtre. Mesuré à 1366x700 : la légende « Anita, cheffe cuisinière »
   sortait de 42px, le compteur « 01 — 04 » de 24px.

   On rogne le rembourrage et on plafonne le média. Jamais le texte.

   CE BLOC DOIT RESTER EN FIN DE FICHIER : `.crew.is-outro > .container` (0,3,1)
   bat `.crew .container` et est déclarée plus haut. On reprend donc son sélecteur
   exact, et seule la position en fin de fichier nous fait gagner.
   ============================================================ */
/* ÉCHELLE PILOTÉE PAR LA HAUTEUR — le vrai correctif « laptop ».

   Toute la typo du site est en `vw` et en `rem` : elle dépend donc de la LARGEUR.
   Un laptop est large mais BAS. Mesuré côte à côte, 1920x950 contre 1366x660 :
   titres 38.4px / 38.4px, texte du pitch 23.2 / 23.2, logo 720 / 720 — RIEN ne
   rétrécit, tous les clamp() sont plaqués à leur maximum puisque vw reste grand.
   Sauf qu'il y a 30 % de hauteur en moins : le bloc du pitch passe de 21 % à 31 %
   de l'écran, celui du hero de 33 % à 48 %. D'où « tout est trop gros ».

   On indexe donc l'échelle de base sur la HAUTEUR : 16px au-dessus de ~900px de
   haut (grand écran : rigoureusement INCHANGÉ), puis descente progressive
   jusqu'à 13.5px à 758px et en dessous. Tout ce qui est en rem suit — donc les
   bornes hautes des clamp(), qui sont ce qui plafonne aujourd'hui.
   Réservé au desktop : sous 900px de large, le mobile a ses propres règles. */
@media (min-width: 900px) {
  :root { font-size: clamp(12.5px, 1.78vh, 16px); }
  /* Le logo est en px/vw purs : les rem ne l'atteignent pas. On le borne aussi
     par la hauteur. 80vh vaut exactement 720px à 900px de haut : au-dessus, la
     borne des 720px reprend la main et le grand écran est intact au pixel. */
  .hero-logo { width: min(720px, 90vw, 80vh); }

  /* Même angle mort pour le cadre vidéo : `max-width: 420px` est du pixel pur.
     Avec son aspect-ratio 4/5 il faisait 420x525, soit 80 % de la hauteur d'un
     laptop (contre 55 % sur un 1920x950) — c'est LUI qui dicte la hauteur de la
     section, le texte à côté ne fait que 228px.
     Valeur CALÉE À L'ŒIL par le client, pas sur la proportion du grand écran :
     l'original 420px (80 % d'un écran bas) donnait « trop gros », 47vh (59 %)
     « trop petit ». 54vh tombe entre les deux (~67 %). Leçon générale : sur un
     écran bas, un visuel doit occuper une part PLUS GRANDE qu'un grand écran pour
     produire le même effet — ne pas « rétablir » la proportion du desktop ici.
     54vh vaut 486px à 900px de haut > 420px : grand écran intact. */
  .video-feature-media { max-width: min(420px, 54vh); }

  /* --- Les autres visuels en PIXELS PURS, tous bornés par la hauteur ---------
     Même angle mort à chaque fois : une taille en px que les rem n'atteignent
     pas, donc identique sur un 1920x1080 et sur un laptop de 660px de haut.
     Chaque borne vh est calibrée sur la proportion MESURÉE à 1905x950, et choisie
     pour ne pas mordre au-dessus de ~900px de haut (grand écran préservé). */

  /* Média d'Anita : 91 % de la hauteur d'un laptop, contre 73 % sur grand écran. */
  .table-pin .table-media { max-height: 73vh; }

  /* Cadre CTA. aspect-ratio 3/4 -> on borne la LARGEUR (= hauteur x 0,75), comme
     sur mobile. Valeur CALÉE À L'ŒIL par le client, pas sur la proportion du
     grand écran : 38vh (= ses 51 %) donnait « trop petit », l'original 360px
     (73 % d'un écran bas) « trop gros ». 46vh tombe entre les deux (~61 %).
     46vh vaut 414px à 900px de haut > 360px : grand écran intact. */
  .cta-frame { width: min(360px, 82%, 46vh); }

  /* Photos de l'équipe : 69 % contre 48 %. */
  .crew-photos { max-height: 48vh; }
}

@media (min-width: 900px) and (max-height: 780px) {
  /* L'équipe : le compteur « 01 — 04 » finissait 10px sous le pli à 660px de
     fenêtre. On récupère les ~55px sur le rembourrage (56->16) et sur l'air sous
     l'en-tête (35->20) — surtout PAS sur .crew-photos, dont la hauteur porte le
     carrousel. */
  /* La vidéo a été rétrécie (54vh) mais sa colonne fait toujours ~506px : tout ce
     que j'ai retiré s'est transformé en VIDE entre elle et le texte — 205px, contre
     142px sur grand écran. On la recentre dans sa colonne (le desktop la garde
     collée à gauche, margin-inline: 0) : elle se rapproche du texte de ~75px et
     retrouve l'écart du grand écran, sans toucher aux colonnes ni à la gouttière. */
  .video-feature-media { margin-inline: auto; }

  .crew.is-outro > .container { padding-top: 1rem; }
  .crew.is-outro > .container .section-head { margin-bottom: 1.25rem; }

  /* Les 9 cartes sont du TEXTE, et il est DÉJÀ minuscule (titre 12.25px,
     description 10.25px) : on n'y touche pas. Sur les 149px d'une carte, 34 sont
     du rembourrage — c'est le seul levier qui ne coûte pas de lisibilité.
     NE PAS retenter d'élargir .gift-grid pour gagner de la hauteur : essayé le
     2026-07-16, les cartes sont passées de 270 à 319px de large sans perdre un
     seul pixel de hauteur (le texte ne se reflowe pas sur moins de lignes). */
  .gift-card { padding-block: 0.75rem; }
  /* (Le plafond du média d'Anita vit désormais dans le bloc ci-dessus, avec les
     autres visuels en px purs : `max-height: 73vh`.) */
}
