/* ══════════════════════════════════════════════════════════════════════
   Proposition : la page 19 en visuel (page ajoutée en fin, .p19b).

   Mêmes textes que la page 19, mot pour mot. « Une couverture totale,
   sans zone blanche » se voit avant de se lire :
     le plan des offres se dresse en relief, comme une carte posée sur
     une table qu'on relève vers soi ;
     ses huit points s'allument du nord au sud ; chacun envoie une grande
     onde, et les ondes se rejoignent jusqu'à couvrir tout le territoire ;
     les cinq offres se soulèvent du plan, une à une, au-dessus de leur
     point ; les points continuent ensuite de battre.
   Le bouton arrive en dernier, la main vient le toucher.

   Le mouvement suit la grammaire de la présentation (css/anim.css). Les
   états de départ ne vivent que dans les animations : sans script, à
   l'impression ou avec « réduire les animations », tout est posé.
   ══════════════════════════════════════════════════════════════════════ */

.p19b{ background:#f8f8f8; }

/* ─────────────────────────────── Le décor ───────────────────────────── */
/* Les deux nappes de la maquette, recadrées comme elle, aux bords
   adoucis. */
/* Le cadre du décor : la nappe du bas et la lueur passent librement,
   sauf dans la bande du pied de page (x 180 à 1275, y 770 et plus) :
   deux masques en fondu, l'un garde le haut, l'autre le coin droit. */
.p19b-cadre-decor{
  position:absolute; left:0; top:0; width:1440px; height:810px; pointer-events:none;
  -webkit-mask-image:linear-gradient(180deg, #000 724px, transparent 768px), linear-gradient(90deg, transparent 1276px, #000 1316px);
          mask-image:linear-gradient(180deg, #000 724px, transparent 768px), linear-gradient(90deg, transparent 1276px, #000 1316px);
  -webkit-mask-composite:source-over; mask-composite:add;
}
.p19b-nappe{ pointer-events:none; border-radius:32px; }
.p19b-nappe--haut{
  transform:rotate(-2.7deg);
  -webkit-mask-image:radial-gradient(farthest-side at 55% 45%, #000 55%, transparent 100%);
          mask-image:radial-gradient(farthest-side at 55% 45%, #000 55%, transparent 100%);
}
.p19b-nappe--bas{ transform:rotate(-59.9deg); }

.p19b-lueur{
  position:absolute; left:560px; top:60px; width:900px; height:760px; border-radius:50%;
  background:radial-gradient(closest-side, rgba(0,90,155,.16), rgba(0,90,155,.06) 55%, rgba(0,90,155,0));
  pointer-events:none;
}
/* L'ombre portée du plan sur la table. */
.p19b-socle{
  position:absolute; left:690px; top:668px; width:620px; height:56px; border-radius:50%;
  background:radial-gradient(closest-side, rgba(20,40,90,.30), rgba(20,40,90,0));
  filter:blur(6px);
}

/* ─────────────────────────────── Le plan ────────────────────────────── */
.p19b-scene{
  position:absolute; left:654px; top:146px; width:692px; height:538px;
  perspective:1700px;
}
.p19b-plateau{
  position:absolute; inset:0; border-radius:32px; overflow:hidden;
  background:#fdfdfe;
  box-shadow:0 2px 4px rgba(20,30,60,.06), 0 28px 56px -16px rgba(20,30,60,.30), 0 0 0 1px rgba(36,50,130,.06);
  rotate:0.22 -1 0 8deg;
}
/* Les coordonnées intérieures sont celles de l'image d'origine. */
.p19b-echelle{
  position:absolute; left:0; top:0; width:805px; height:625px;
  transform:scale(.86); transform-origin:0 0;
}
.p19b-plan{ background-size:1076px 717px !important; background-position:-120px -70px !important; }

/* La lumière qui balaie le territoire (n'existe qu'en mouvement). */
.p19b-balayage{
  position:absolute; left:0; top:-80px; width:220px; height:800px; opacity:0;
  background:linear-gradient(90deg, rgba(255,255,255,0), rgba(190,235,255,.55) 50%, rgba(255,255,255,0));
  rotate:14deg; mix-blend-mode:screen; pointer-events:none;
}

/* Un point : un feu sur la tête de l'épingle, une grande onde, deux
   ondes qui battent. */
.p19b-pin{ position:absolute; width:60px; height:60px; pointer-events:none; }
.p19b-pin > span{ position:absolute; border-radius:50%; }
.p19b-feu{
  left:6px; top:6px; width:48px; height:48px;
  background:radial-gradient(closest-side, rgba(255,255,255,1), rgba(170,240,255,.85) 35%, rgba(60,190,255,.35) 65%, rgba(60,190,255,0));
  mix-blend-mode:screen;
}
/* Les ondes des huit points battent ensemble, d'un seul pouls : une
   seule boucle, sur le plan, fait vivre tout le territoire. Au repos
   (sans mouvement), le pouls vaut 1 et les ondes sont invisibles. */
@property --p19b-pouls{ syntax:'<number>'; inherits:true; initial-value:1; }
.p19b-onde{
  left:10px; top:10px; width:40px; height:40px;
  border:2.5px solid rgba(140,225,255,.95); box-sizing:border-box;
  scale:calc(.5 + var(--p19b-pouls) * 1.6);
  opacity:calc(.9 - var(--p19b-pouls) * .9);
}
.p19b-vague{
  left:-170px; top:-170px; width:400px; height:400px; opacity:0;
  background:radial-gradient(closest-side, rgba(120,215,255,.0), rgba(120,215,255,.42) 70%, rgba(180,240,255,.7) 92%, rgba(120,215,255,0));
  mix-blend-mode:screen;
}

/* Une offre, découpée dans le plan, posée soulevée au-dessus de lui. */
.p19b-offre{
  background-size:1076px 717px !important; background-repeat:no-repeat;
  border-radius:10px;
  transform-origin:var(--o);
  translate:0 -6px; scale:1.02;
  filter:drop-shadow(0 14px 14px rgba(20,40,110,.26));
}

/* ─────────────────────────────── Le bouton ──────────────────────────── */
.p19b-bouton{
  position:absolute; border-radius:999px; overflow:hidden;
  background:linear-gradient(120deg, #e8268c 0%, #d20074 50%, #b5006a 100%);
  box-shadow:0 18px 34px -12px rgba(210,0,116,.55), inset 0 1px 0 rgba(255,255,255,.25);
}
/* Un reflet passe sur le bouton (n'existe qu'en mouvement). */
.p19b-bouton::before{
  content:""; position:absolute; top:-20px; left:-120px; width:90px; height:140px; opacity:0;
  background:linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.45), rgba(255,255,255,0));
  rotate:20deg;
}
.p19b-repere{
  position:absolute; left:34px; top:30px; width:30px; height:40px; overflow:visible;
}
.p19b-repere path{ fill:#fff; }
.p19b-repere circle{ fill:#d20074; }
.p19b-lien{
  display:flex; align-items:center; justify-content:center; box-sizing:border-box;
  padding-left:52px; border-radius:999px;
  font-family:'Montserrat', sans-serif; font-weight:800; font-size:29px; letter-spacing:.035em;
  color:#fff; white-space:nowrap;
}
.p19b-main{ transform:rotate(-38deg); transform-origin:50% 0; background-size:contain !important; }

/* ══════════════════════════════ Le mouvement ══════════════════════════
   `--d` est le départ du plan (css/anim.css) ; tout ce qui vit dans le
   plan se cale sur lui. */

/* Le plan se relève vers le lecteur. */
.js-anim :is(.est-active, .est-sortante) .p19b-plateau{
  animation:p19b-dresse 1500ms var(--anim-courbe) var(--d) both;
}
@keyframes p19b-dresse{
  from{ rotate:1 -0.1 0 48deg; translate:0 40px; }
  to  { rotate:0.22 -1 0 8deg; translate:0 0; }
}

/* La lumière passe une fois. */
.js-anim :is(.est-active, .est-sortante) .p19b-balayage{
  animation:p19b-balaie 1500ms var(--anim-douce) calc(var(--d) + 650ms) both;
}
@keyframes p19b-balaie{
  from{ translate:-260px 0; opacity:0; }
  20% { opacity:1; }
  80% { opacity:1; }
  to  { translate:900px 0; opacity:0; }
}

/* Les points s'allument du nord au sud. */
.js-anim :is(.est-active, .est-sortante) .p19b-feu{
  animation:p19b-allume 750ms var(--anim-ressort) calc(var(--d) + 900ms + var(--i) * 110ms) both;
}
@keyframes p19b-allume{
  from{ opacity:0; scale:.2; }
  45% { opacity:1; scale:1.9; }
  to  { opacity:1; scale:1; }
}

/* Chaque point envoie une grande onde : ensemble, elles couvrent tout. */
.js-anim :is(.est-active, .est-sortante) .p19b-vague{
  animation:p19b-couvre 1400ms var(--anim-courbe) calc(var(--d) + 950ms + var(--i) * 110ms) both;
}
@keyframes p19b-couvre{
  from{ opacity:0; scale:.08; }
  30% { opacity:.95; }
  to  { opacity:0; scale:1; }
}

/* Puis le territoire bat d'un même pouls, sans fin. */
.js-anim :is(.est-active, .est-sortante) .p19b-echelle{
  animation:p19b-bat 3200ms cubic-bezier(.2,.6,.3,1) calc(var(--d) + 2400ms) infinite;
}
@keyframes p19b-bat{
  from{ --p19b-pouls:0; }
  to  { --p19b-pouls:1; }
}

/* Les offres se soulèvent une à une au-dessus de leur point. */
.js-anim :is(.est-active, .est-sortante) .p19b-offre{
  animation:p19b-souleve 800ms var(--anim-ressort) calc(var(--d) + 1300ms + var(--i) * 160ms) both;
}
@keyframes p19b-souleve{
  from{ translate:0 0; scale:1; filter:drop-shadow(0 0 0 rgba(20,40,110,0)) brightness(1); }
  50% { filter:drop-shadow(0 18px 16px rgba(20,40,110,.3)) brightness(1.07); }
  to  { translate:0 -6px; scale:1.02; filter:drop-shadow(0 14px 14px rgba(20,40,110,.26)) brightness(1); }
}

/* Les nappes, la lueur et l'ombre du plan se posent sans respirer
   ensuite : les seules boucles sont le pouls des points et le bouton. */
.js-anim :is(.est-active, .est-sortante) :is(.p19b-nappe, .p19b-lueur, .p19b-socle)[data-rv="halo"]{
  animation:rv-halo 1800ms ease-out var(--d) both;
}

/* Le reflet passe sur le bouton, de temps en temps. */
.js-anim :is(.est-active, .est-sortante) .p19b-bouton::before{
  animation:p19b-reflet 3600ms var(--anim-douce) calc(var(--d) + 900ms) infinite;
}
@keyframes p19b-reflet{
  0%  { translate:0 0; opacity:0; }
  8%  { opacity:1; }
  35% { translate:640px 0; opacity:1; }
  36%, 100%{ translate:640px 0; opacity:0; }
}

@media (prefers-reduced-motion:reduce){
  .js-anim .p19b *{ animation:none !important; }
  .js-anim .p19b .p19b-bouton::before{ animation:none !important; }
}
