/* ==========================================================================
   evenements.css - page « Événements privés » (template-evenements.php).
   Chargée via is_page_template('template-evenements.php'), scope strict
   .page-template-template-evenements. Couleurs : tokens var(--fp-*) UNIQUEMENT.

   REPRODUCTION DE LA MAQUETTE (chantier du 2026-08-12, deuxième passage : « pas
   l'adaptation, la reproduction »), section par section, sauf la liste FERMÉE
   de ce qui reste au thème : règles de titres (Bebas, capitales, tailles du
   thème), en-tête, pied de page, boutons (.fp-btn), largeur de colonne
   (var(--fp-wrap) via .fp-wrap, jamais les 1352 px de la maquette), jetons de
   couleur (palette de la maquette transposée en var(--fp-*), jamais d'orange).
   Tout le reste vient de la maquette.

   Composition de la page :
     1. la BANNIÈRE PROPRE À LA PAGE (fp_render_evenement_banniere), substituée
        sur la zone commune fp-blk-hero (même mécanique que
        fp_render_restauration_banniere, inc/restauration.php) ;
     2. QUATRE sections d'offre, Anniversaires / Entreprises et séminaires /
        EVG et EVJF / Événements privés (fp_render_evenement_offre,
        inc/evenements-prives.php), habillées par le bloc « SECTIONS D'OFFRE » ;
     3. la section CTA Réservation (fp_render_evenement_cta_reservation), bloc
        « CTA RÉSERVATION » ;
     3bis. la section CTA Réservation directe (fp_render_evenement_cta_direct),
        deux tuiles vers la loge et la salle de conférence, ajoutée le
        2026-09-06, bloc « CTA RÉSERVATION DIRECTE » ;
     4. la section du formulaire de demande (inc/demande-offre.php), en fenêtre
        modale dès que le JavaScript est là. HORS PÉRIMÈTRE de ce chantier
        (inc/demande-offre.php n'y est pas), donc HORS DE LA SCÈNE DE FOND
        ANIMÉ ci-dessous : elle garde son fond plein fp-s-cream fixe, comme
        avant. Signalé dans le rapport du chantier.

   REPRIS DE LA MAQUETTE, ce chantier-ci (au-delà du premier passage, voir plus
   bas pour la liste déjà en place) : la bannière propre à la page, LE FOND DE
   PAGE ANIMÉ AU DÉFILEMENT d'une section à l'autre (mécanique de
   assets/js/restauration.js, seuil de 20 % validé sur cette page-là), le RAIL
   latéral (vraie navigation par ancres, comme fp_restauration_rail), le badge
   « 01 · Anniversaires » sur la photo principale (libellé lu depuis le titre
   réel de la zone, jamais figé), la texture topographique sur les phases
   sombres (--fp-e-motif-topo, même fichier partagé que la page Restauration,
   assets/img/em-topo-traits.svg).

   DÉJÀ EN PLACE depuis le premier passage (non répété ici) : chiffre-filigrane
   par section, volet clip-path sur la photo principale, vignette secondaire qui
   déborde à contre-sens, chiffre-clé flottant sous la photo (EVG, Événements
   privés), filets de liste tracés au scroll.

   TITRE RÉVÉLÉ EN UN SEUL VOLET, PAS LIGNE PAR LIGNE COMME LA MAQUETTE :
   couvert par « nos règles sur les titres » (consigne du chantier) : un titre
   est un texte ÉDITABLE de longueur variable, jamais une composition figée en
   deux lignes physiques qui casserait au premier titre retouché dans Gutenberg.
   Décision documentée ici et dans inc/evenements-prives.php.

   NON REPRODUITE, DÉLIBÉRÉMENT : la bande INTRO de la maquette (« Un parc
   entier pour votre groupe », pilules de raccourci) entre la bannière et la
   première section numérotée. Elle demanderait une CINQUIÈME zone Gutenberg de
   plus (donc un fixup de contenu sur les pages déjà en base), alors que les
   deux manques nommés par le client portaient sur la bannière et les
   transitions de fond ; absence signalée explicitement dans le rapport du
   chantier plutôt que passée sous silence.

   ANIMATIONS : GSAP + ScrollTrigger (assets/js/evenements.js), même patron
   anti-clignotement que la page Restauration (état masqué posé SOUS
   html.fp-e-anim, cette classe posée de façon synchrone par un script de
   wp_head AVANT la première peinture, jamais par JavaScript en cours de route :
   voir le bloc ANTI-CLIGNOTEMENT plus bas). Sans JavaScript, ou sous
   « animations réduites », la classe n'existe jamais et la page reste entière,
   chaque section gardant son fond plein (voir FOND DE PAGE ANIMÉ plus bas).

   Les anciennes règles de ce fichier (cartes de formule, points forts, étapes,
   questions fréquentes, invitation finale) ont été retirées avec les zones
   qu'elles habillaient : elles ne correspondaient plus à aucun élément de la
   page. Elles portaient au passage deux visuels servis depuis le site du parc
   modèle, ce qui n'a jamais eu sa place ici.
   ========================================================================== */

.page-template-template-evenements {
  /* Texture « Topo » du client, EN TRAITS SEULS : fichier déjà hébergé par le
     thème pour la page Restauration (assets/img/em-topo-traits.svg), partagé
     ici tel quel plutôt que dupliqué. Utilisée sur la bannière et les phases
     sombres des sections d'offre et de la carte CTA. */
  --fp-e-motif-topo: url('../img/em-topo-traits.svg');

  /* Encre claire des fonds sombres, même dérivation que --fp-r-clair sur la
     page Restauration : blanc teinté d'une pointe d'accent, jamais un gris qui
     romprait avec la marque. */
  --fp-e-clair: color-mix(in srgb, var(--fp-white) 84%, var(--fp-accent));
  --fp-e-clair-doux: color-mix(in srgb, var(--fp-white) 68%, var(--fp-accent));
}

/* --------------------------------------------------------------------------
   BANNIÈRE PROPRE À LA PAGE (.fp-ehero), reprise de la maquette de la cliente.

   Rendu substitué sur la zone COMMUNE fp-blk-hero (fp_render_evenement_banniere,
   inc/evenements-prives.php, même mécanique que fp_render_restauration_banniere) :
   les classes .fp-hero-* génériques du thème ne s'appliquent donc plus ici,
   remplacées par ce jeu propre à la page. Diaporama PLEINE LARGEUR (retour
   client du 2026-08-12, cinquième chantier, point 1 : posture identique à la
   bannière de la page Restauration, plus de marge latérale), coins arrondis
   en BAS seulement, voile en biais, texture topographique, sur-titre en
   pilule (icon-box, verre sur fond sombre), grand titre EN UN SEUL VOLET (nos
   règles de titre : Bebas, capitales, tailles du thème, voir fp-hero-title
   dans main.css, mêmes valeurs reprises ci-dessous), accroche, bouton, pied
   avec repères de diaporama et invitation à défiler.
   -------------------------------------------------------------------------- */
.page-template-template-evenements .fp-ehero {
  position: relative;
  /* PLEINE LARGEUR (retour client du 2026-08-12, cinquième chantier, point 1 :
     « je mettrais une section pleine largeur... là c'est tout coupé ») : plus
     de marge latérale ici, la bannière occupe toute la largeur de l'écran,
     même posture que la bannière de la page Restauration. L'arrondi reste
     porté par .fp-ehero-cadre juste en dessous (coins bas uniquement). */
  /* MÊME COULEUR QUE .fp-ehero-cadre juste en dessous, à dessein : c'est CETTE
     section (porteuse de data-fp-sect) que evenements.js interroge pour
     connaître la couleur de la phase « bannière » avant de la rendre
     transparente (voir la note FOND DE PAGE ANIMÉ plus bas). Sans cette
     déclaration, la couleur lue serait transparente et la première phase du
     fondu de page partirait d'une couleur fausse. */
  background: var(--fp-dark);
}
.page-template-template-evenements .fp-ehero-cadre {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: min(84vh, 700px);
  padding: calc(var(--fp-nav-h) + 40px) 0 clamp(28px, 6vw, 56px);
  border-radius: 0 0 var(--fp-radius-lg) var(--fp-radius-lg);
  overflow: hidden;
  background: var(--fp-dark);
  color: var(--fp-white);
}
.page-template-template-evenements .fp-ehero-bg { overflow: hidden; }
/* AUCUNE PHOTO DÉPOSÉE : plutôt qu'un aplat nu, un dégradé de marque donne de
   la matière à la bannière, état de livraison qui doit tenir. */
.page-template-template-evenements .fp-ehero-bg--nu {
  background-image: radial-gradient(
    120% 100% at 78% 10%,
    color-mix(in srgb, var(--fp-primary) 55%, transparent) 0%,
    transparent 62%
  );
}
/* ZOOM LENT DE LA PHOTO (demande client du 2026-08-13, avec le voile allégé
   juste en dessous) : le fond respire en continu au lieu de rester figé.
   Mouvement volontairement DOUX (1 -> 1.07 en 18 s, aller-retour) : sur une
   bannière plein écran, un zoom plus rapide ou plus ample donne le tournis et
   fait ressortir la compression de la photo.

   PORTÉE : les diapositives, jamais le conteneur. Ce dernier
   ([data-fp-hero-fond]) porte déjà la parallaxe de assets/js/evenements.js
   (yPercent au défilement) ; l'animer ici écraserait cette transformation.
   Le héro NU (aucune photo déposée, .fp-ehero-bg--nu) n'a aucune diapositive
   à animer : le :not() le dit explicitement plutôt que de compter dessus.

   REMPLACE, sur cette page seulement, le Ken Burns générique du thème
   (.fp-hero-slide, fp-kenburns 20s, main.css) : même propriété, sélecteur
   plus spécifique, donc une seule animation tourne, jamais deux.

   ANIMATIONS RÉDUITES : la règle vit SOUS (prefers-reduced-motion:
   no-preference), comme la flèche « Faites défiler » plus bas. Écrite sans
   cette garde, elle l'emporterait sur la neutralisation de main.css
   (@media (prefers-reduced-motion: reduce) .fp-hero-slide { animation: none })
   qui est, elle, moins spécifique. */
@media (prefers-reduced-motion: no-preference) {
  .page-template-template-evenements .fp-ehero-bg:not(.fp-ehero-bg--nu) .fp-hero-slide {
    transform-origin: center;
    animation: fp-ehero-zoom 18s ease-in-out infinite alternate;
  }
}
@keyframes fp-ehero-zoom {
  from { transform: scale(1); }
  to   { transform: scale(1.07); }
}
/* VOILE ALLÉGÉ (retour client du 2026-08-13 : « un overlay léger comme ça on
   la voit quand même »). AVANT : un seul dégradé en biais à 100deg, de 94 %
   d'encre sombre à gauche à 66 % au milieu et 24 % à droite, qui noircissait
   les deux tiers de la photo. APRÈS : un voile VERTICAL, dense seulement là
   où il y a du texte, presque absent au milieu du cadre.

   Pourquoi vertical : le contenu du héro est aligné EN BAS
   (.fp-ehero-cadre, justify-content: flex-end) et centré depuis l'arbitrage
   du 2026-08-13 (.fp-ehero-inner) ; la barre de navigation, elle, passe
   par-dessus le haut du cadre. Les deux extrémités ont donc besoin de
   matière, le milieu non.

   Les deux couches se composent : au bas du cadre, 76 % plus le reliquat du
   biais, soit un titre blanc largement au-dessus des seuils de contraste ;
   au milieu, moins de 20 %, la photo passe. Le second dégradé ne garde du
   biais de la maquette qu'une trace, pour ne pas perdre son identité. */
.page-template-template-evenements .fp-ehero-voile {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--fp-dark) 34%, transparent) 0%,
      color-mix(in srgb, var(--fp-dark) 8%, transparent) 34%,
      color-mix(in srgb, var(--fp-dark) 12%, transparent) 52%,
      color-mix(in srgb, var(--fp-dark) 52%, transparent) 80%,
      color-mix(in srgb, var(--fp-dark) 76%, transparent) 100%
    ),
    linear-gradient(
      100deg,
      color-mix(in srgb, var(--fp-dark) 22%, transparent) 0%,
      color-mix(in srgb, var(--fp-dark) 6%, transparent) 55%,
      transparent 100%
    );
  pointer-events: none;
}
/* Texture topographique (voir la note « TEXTURE TOPOGRAPHIQUE » plus bas dans
   ce fichier) : opacité posée par JS pendant le fondu d'entrée ; repli visible
   sans JavaScript (voir @media (prefers-reduced-motion) et le second filet). */
.page-template-template-evenements .fp-ehero-topo {
  position: absolute;
  inset: -10% 0;
  z-index: 1;
  background-image: var(--fp-e-motif-topo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  opacity: .22;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.page-template-template-evenements .fp-ehero-inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  /* Arbitrage client du 2026-08-13 : tout le héro centré sous le menu
     (pilule, titre, texte, bouton). Les max-width de 16ch et 46ch plus bas
     restent : c'est l'axe qui change, pas les largeurs de lecture. */
  align-items: center;
  text-align: center;
  gap: clamp(16px, 2.4vw, 24px);
}
.page-template-template-evenements .fp-ehero-sur { color: var(--fp-white); }
/* TITRE : mêmes valeurs que .fp-hero-title (main.css), « nos règles sur les
   titres » : Bebas (h1/h2 globaux), capitales, même échelle clamp() que le
   héro commun. UN SEUL VOLET (pas ligne par ligne comme la maquette) : texte
   éditable de longueur variable, jamais une composition figée en deux lignes
   physiques qui casserait au premier titre retouché dans Gutenberg. */
.page-template-template-evenements .fp-ehero-titre {
  margin: 0 0 .2em;
  max-width: 16ch;
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  line-height: .96;
  overflow: hidden;
  padding-bottom: .06em;
}
.page-template-template-evenements .fp-ehero-lead {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  color: color-mix(in srgb, var(--fp-white) 88%, var(--fp-accent));
}
.page-template-template-evenements .fp-ehero-action { margin: 6px 0 0; }
.page-template-template-evenements .fp-ehero-btn { min-height: 52px; }

.page-template-template-evenements .fp-ehero-pied {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: clamp(24px, 5vw, 48px);
}
.page-template-template-evenements .fp-ehero-points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 7px;
}
.page-template-template-evenements .fp-ehero-point {
  width: 26px;
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--fp-white) 30%, transparent);
  transition: background-color .4s ease;
}
.page-template-template-evenements .fp-ehero-point.is-actif { background: var(--fp-accent); }
.page-template-template-evenements .fp-ehero-defile {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 0 auto;
  font-family: var(--fp-font-heading);
  font-size: .85rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fp-white);
}
.page-template-template-evenements .fp-ehero-fleche { display: inline-flex; }
.page-template-template-evenements .fp-ehero-fleche svg { width: 15px; height: 15px; }
@media (prefers-reduced-motion: no-preference) {
  .page-template-template-evenements .fp-ehero-fleche { animation: fp-e-defile 1.8s ease-in-out infinite; }
}
@keyframes fp-e-defile {
  0%, 100% { transform: translateY(0); opacity: .5; }
  50%      { transform: translateY(7px); opacity: 1; }
}
@media (max-width: 720px) {
  /* Bannière quasi plein écran (retour client du 2026-08-18 : « limite du full
     screen ») : svh mesure la hauteur RÉELLEMENT visible sur téléphone, la
     barre d'adresse rétractable ne fait donc ni sauter ni déborder la bannière
     (vh juste au-dessus en repli pour les navigateurs sans svh). Les quelques
     pour cent laissés libres montrent l'amorce de la section suivante. */
  .page-template-template-evenements .fp-ehero-cadre { min-height: 94vh; min-height: 94svh; }
  .page-template-template-evenements .fp-ehero-titre { max-width: 14ch; }
}

/* ==========================================================================
   FOND DE PAGE ANIMÉ

   Posée par evenements.js seulement (mécanique de restauration.js reprise à
   l'identique, seuil de bascule à 20 % de l'écran validé sur cette page-là).
   Les sections deviennent transparentes et laissent voir le fond du corps de
   page, que le script teinte en fondu à partir des couleurs RÉELLEMENT lues
   sur chaque section (jamais une couleur écrite dans le script). La COULEUR DU
   TEXTE n'est pas touchée ici : une section sombre garde son encre claire,
   voir le bloc L'ENCRE SUIT LE FOND plus bas.

   SANS JAVASCRIPT : cette classe n'est jamais posée, chaque section garde son
   propre fond plein (.fp-s-light, .fp-s-primary...), page entière et correcte.
   ========================================================================== */
/* L'UNIQUE bascule de fond que subit une section : sa mise en transparence
   quand le fond animé s'active. GSAP arrive une à deux secondes APRÈS le
   premier rendu : sans transition, une section teal visible en bas d'écran à
   cet instant passait d'un COUP au blanc de la phase courante, le « mini
   flash vert » du premier chargement (retour client du 2026-08-14). La
   transition est ciblée background-color, JAMAIS all : rien d'autre ne doit
   s'animer ici. Elle adoucit aussi, du même geste, la disparition du teal
   pour la section active à l'instant de l'activation. */
.page-template-template-evenements [data-fp-sect] {
  transition: background-color .4s ease;
}
.page-template-template-evenements.fp-e-fond-anime [data-fp-sect] {
  background-color: transparent;
}
/* ANNIVERSAIRES : TOUJOURS OPAQUE, JAMAIS TRANSPARENTE, MÊME SOUS
   .fp-e-fond-anime (retour client du 2026-08-12, sixième chantier, point 2,
   confirmé à la remontée : « si je descends un peu et je remonte, la
   première section revient avec un fond VERT FONCÉ, alors qu'elle doit
   vraiment être tout le temps blanche »).

   CAUSE RÉELLE (vert FONCÉ, pas le vert clair des sections d'offre, l'indice
   qui a permis de la trouver) : le héro porte lui aussi un data-fp-sect et
   son propre trigger de bascule, au SEUIL GÉNÉRAL comme toute autre section
   ('top 20%'/'bottom 20%'). En REMONTANT depuis Entreprises vers
   Anniversaires, le trigger du héro redevient actif dès que sa frontière
   basse (partagée avec Anniversaires) repasse sous les 20 % du haut de
   l'écran, un point de défilement encore profondément DANS Anniversaires,
   bien avant que le héro ne soit réellement revisible. Le corps de page
   bascule alors sur fonds[0] (le noir/vert foncé du héro, --fp-dark),
   visible À TRAVERS Anniversaires puisqu'elle est rendue transparente par la
   règle juste au-dessus. Une première tentative avait ajusté le SEUIL de
   cette frontière (voir l'historique dans assets/js/evenements.js) : plus
   fragile qu'il n'y paraissait, cette rustine ne réglait qu'un sens de
   défilement et pouvait se redéfaire à la moindre autre retouche de seuil.

   CORRECTIF CHOISI, DÉLIBÉRÉMENT PLUS SIMPLE ET INFAILLIBLE : rendre
   Anniversaires opaque en propre plutôt que de chercher un réglage de seuil
   parfait entre deux triggers indépendants. Quel que soit l'état du fond
   animé du corps de page (n'importe quelle couleur, n'importe quel timing,
   n'importe quel sens de défilement), Anniversaires ne peut plus jamais
   laisser transparaître une autre couleur : ce correctif ne dépend d'AUCUN
   seuil, il rend la classe entière de bug impossible plutôt que de la
   corriger au cas par cas. Cela couvre du même coup la toute première
   demande du point 2 (blanc dès l'arrivée en haut de page) : plus besoin
   d'un seuil de sortie de héro précoce, elle est de toute façon toujours
   opaque (voir assets/js/evenements.js, seuils redevenus uniformes).
   Sélecteur doublé ([data-fp-sect][data-fp-lieu]) pour une spécificité
   supérieure à la règle de transparence ci-dessus, sans dépendre de l'ordre
   des règles dans ce fichier. */
.page-template-template-evenements.fp-e-fond-anime [data-fp-sect][data-fp-lieu="anniversaires"] {
  background-color: var(--fp-paper);
}

/* NE PAS OPACIFIER LES SECTIONS TEAL. Tenté le 2026-08-13 (délimitation
   nette au bord des sections), retiré le jour même sur retour client : « la
   couleur de fond doit changer au défilement quand on arrive dessus, je ne
   dois pas voir la coupure, ça doit transitionner ». Le fondu global est
   donc le comportement voulu ; l'apparition prématurée du fond, elle, était
   un symptôme de la vraie cause racine, corrigée le même jour : la règle
   html { scroll-behavior: smooth } de main.css faussait les bornes de tous
   les déclencheurs à chaque remesure. Seule Anniversaires (ci-dessus) reste
   opaque, pour la raison documentée à sa règle. */

/* ==========================================================================
   TEXTURE TOPOGRAPHIQUE, PENDANT LES PHASES SOMBRES

   Même principe que la page Restauration : AVEC evenements.js
   (.fp-e-fond-anime), le fond est un aplat GLOBAL porté par le corps de page,
   la texture l'est donc aussi (pseudo-élément fixe, plein écran, sous le
   contenu réel, fondu synchronisé sur .is-fond-sombre). SANS evenements.js, la
   texture reste posée EN STATIQUE sur chaque section réellement sombre (voir
   fp-evo-topo / fp-ehero-topo / fp-evo-cta-topo plus bas), jamais un second
   aplat qui remplacerait le fond réel de la section, neutralisée localement dès
   que la couche globale prend le relais. -1 opacity pour rester un filigrane
   qui ne mord jamais sur le contraste du texte clair déjà élevé.
   ========================================================================== */
.page-template-template-evenements.fp-e-fond-anime::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--fp-e-motif-topo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  opacity: 0;
  transition: opacity .34s ease;
}
.page-template-template-evenements.fp-e-fond-anime.is-fond-sombre::before {
  opacity: .07;
}
/* Texture statique locale, neutralisée dès que la couche globale prend le
   relais (repli sans JavaScript uniquement). */
.page-template-template-evenements.fp-e-fond-anime .fp-ehero-topo,
.page-template-template-evenements.fp-e-fond-anime .fp-evo-topo,
.page-template-template-evenements.fp-e-fond-anime .fp-evo-cta-topo,
.page-template-template-evenements.fp-e-fond-anime .fp-evd-topo {
  opacity: 0;
}

/* ==========================================================================
   BADGE PHOTO (« 01 · Anniversaires »), sur la photo principale.

   Libellé lu depuis le TITRE RÉEL de la zone (fp_render_evenement_offre), donc
   jamais figé ni désynchronisé d'un titre retouché dans Gutenberg.
   ========================================================================== */
.page-template-template-evenements .fp-evo-photo--principale { position: relative; }
.page-template-template-evenements .fp-evo-badge {
  position: absolute;
  left: 20px;
  top: 20px;
  z-index: 1;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 40px);
  padding: 9px 18px;
  border-radius: var(--fp-pill);
  background: color-mix(in srgb, var(--fp-dark) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: var(--fp-font-heading);
  font-size: .95rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fp-white);
  pointer-events: none;
}
.page-template-template-evenements .fp-evo-badge-nom {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Motif topographique sur les sections a fond teal plein et sur la carte CTA :
   memes tokens que le calque global ci-dessus, poses en statique tant que le
   script n'a pas pris la main (voir la note TEXTURE TOPOGRAPHIQUE plus haut). */
.page-template-template-evenements .fp-evo-topo,
.page-template-template-evenements .fp-evo-cta-topo,
.page-template-template-evenements .fp-evd-topo {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--fp-e-motif-topo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  opacity: .1;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.page-template-template-evenements .fp-evo-cta-topo,
.page-template-template-evenements .fp-evd-topo { opacity: .16; }

/* ==========================================================================
   RAIL LATÉRAL (.fp-e-rail), quatre sections d'offre.

   VRAIE navigation par ancres (voir inc/evenements-prives.php,
   fp_evenements_prives_rail) : n'apparaît qu'à partir de 1200 px de large, là
   où les marges de la page peuvent l'accueillir sans mordre sur le texte.
   Sans JavaScript, reste affiché et utilisable dès ce palier ; le point
   « actif » et aria-current sont posés par evenements.js. Couleurs pilotées
   par [data-fp-mode] (clair/sombre), posé par le script sur le rail lui-même
   en fonction de la section en cours de lecture, même mécanique que
   fp-rrail[data-fp-mode] sur la page Restauration.
   ========================================================================== */
.page-template-template-evenements .fp-e-rail { display: none; }
@media (min-width: 1200px) {
  .page-template-template-evenements .fp-e-rail {
    display: block;
    position: fixed;
    right: clamp(18px, 2.4vw, 34px);
    top: 50%;
    z-index: 40;
    transform: translateY(-50%);
    opacity: 0;
    pointer-events: none;
    transition: opacity .4s ease;
  }
  .page-template-template-evenements .fp-e-rail.is-en-champ {
    opacity: 1;
    pointer-events: auto;
  }
  .page-template-template-evenements .fp-e-rail-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 14px;
  }
  .page-template-template-evenements .fp-e-rail-lien {
    display: flex;
    align-items: center;
    gap: 10px;
    /* Cible tactile >= 44 px de haut (mesuré avec le nom masqué au repos, le
       cas le plus bas) : la zone cliquable dépasse largement le point visible. */
    min-height: 44px;
    padding: 4px;
  }
  .page-template-template-evenements .fp-e-rail-nom {
    font-family: var(--fp-font-heading);
    font-size: .82rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
    opacity: 0;
    transform: translateX(8px);
    border-radius: var(--fp-pill);
    padding: 6px 13px;
    background: color-mix(in srgb, var(--fp-paper) 88%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    color: var(--fp-ink);
    /* Relief doux sur fond clair (retour du 2026-09-06 : « sur fond blanc, la
       pilule manque de relief »). Laissée identique en mode sombre : sur un
       fond deja teal fonce, cette ombre neutre reste invisible, aucun besoin
       de la neutraliser par [data-fp-mode="sombre"]. */
    box-shadow: 0 6px 18px color-mix(in srgb, var(--fp-ink) 12%, transparent);
    transition: opacity .35s ease, transform .35s ease, color .5s ease, background-color .5s ease;
  }
  .page-template-template-evenements .fp-e-rail-point {
    display: block;
    width: 10px;
    height: 10px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--fp-ink) 30%, transparent);
    transition: background-color .5s ease, height .35s ease;
  }
  .page-template-template-evenements .fp-e-rail-lien.is-actif .fp-e-rail-point,
  .page-template-template-evenements .fp-e-rail-lien:hover .fp-e-rail-point,
  .page-template-template-evenements .fp-e-rail-lien:focus-visible .fp-e-rail-point {
    height: 26px;
    background: var(--fp-ink);
  }
  .page-template-template-evenements .fp-e-rail-lien.is-actif .fp-e-rail-nom,
  .page-template-template-evenements .fp-e-rail-lien:hover .fp-e-rail-nom,
  .page-template-template-evenements .fp-e-rail-lien:focus-visible .fp-e-rail-nom {
    opacity: 1;
    transform: translateX(0);
  }
  .page-template-template-evenements .fp-e-rail[data-fp-mode="sombre"] .fp-e-rail-point {
    background: color-mix(in srgb, var(--fp-white) 40%, transparent);
  }
  .page-template-template-evenements .fp-e-rail[data-fp-mode="sombre"] .fp-e-rail-lien.is-actif .fp-e-rail-point,
  .page-template-template-evenements .fp-e-rail[data-fp-mode="sombre"] .fp-e-rail-lien:hover .fp-e-rail-point,
  .page-template-template-evenements .fp-e-rail[data-fp-mode="sombre"] .fp-e-rail-lien:focus-visible .fp-e-rail-point {
    background: var(--fp-white);
  }
  .page-template-template-evenements .fp-e-rail-lien:focus-visible {
    outline: 2px solid var(--fp-primary);
    outline-offset: 3px;
    border-radius: var(--fp-radius-sm);
  }
}

/* ==========================================================================
   ANTI-CLIGNOTEMENT : ÉTAT INITIAL MASQUÉ SOUS MARQUEUR SYNCHRONE

   Même patron que la page Restauration (assets/css/restauration.css) : la
   classe html.fp-e-anim est posée de façon SYNCHRONE, avant la première
   peinture, par un tout petit script imprimé dans wp_head
   (fp_evenements_prives_anti_flash_marqueur, inc/evenements-prives.php).

   SOUS CETTE CLASSE SEULEMENT, les éléments qu'assets/js/evenements.js anime
   naissent déjà dans leur état de départ : le premier pixel peint les montre
   déjà masqués, jamais pleins puis masqués (le clignotement que ce patron
   corrige). GSAP n'a donc plus qu'à les amener vers leur état visible
   (gsap.to), jamais l'inverse.

   SANS JAVASCRIPT, LA CLASSE N'EXISTE JAMAIS : ces règles ne s'appliquent
   alors à rien, la page reste entière, chiffres et volets déjà à leur place
   finale. Si GSAP ne charge jamais ou échoue en cours de route,
   evenements.js retire lui-même la classe. Sous « animations réduites », le
   script de tête refuse déjà de la poser ; le bloc de fin de fichier
   (@media prefers-reduced-motion: reduce) est un second filet, au cas où. */
html.fp-e-anim .page-template-template-evenements [data-fp-clip] { clip-path: inset(0% 0% 100% 0%); }
html.fp-e-anim .page-template-template-evenements [data-fp-zoom] { transform: scale(1.22); }
html.fp-e-anim .page-template-template-evenements [data-fp-drift] { opacity: 0; transform: translateY(50px) scale(.94); }
html.fp-e-anim .page-template-template-evenements [data-fp-mask] { clip-path: inset(0% 0% 110% 0%); transform: translateY(22%); }
/* Le filet (.fp-evo-item-rule) part déjà réduit à zéro EN TOUT TEMPS (règle de
   base plus haut, pas seulement ici) : la vraie ligne visible au repos, sans
   JavaScript, est la bordure CSS de .fp-evo-item, jamais ce calque décoratif. */
html.fp-e-anim .page-template-template-evenements [data-fp-row] .fp-evo-puce,
html.fp-e-anim .page-template-template-evenements [data-fp-row] .fp-evo-item-txt { opacity: 0; transform: translateX(-14px); }
/* Bannière : sur-titre et groupe « lead + bouton + pied » (mêmes valeurs de
   départ que fp-rhero-sur / fp-rhero-hero-suite sur la page Restauration). */
html.fp-e-anim .page-template-template-evenements [data-fp-hero-sur] { opacity: 0; transform: translateY(16px); }
html.fp-e-anim .page-template-template-evenements [data-fp-hero-suite] { opacity: 0; transform: translateY(22px); }
/* Carte CTA Réservation qui grandit au défilement (retour client du
   2026-08-12, sixième chantier, point 6a), reprise à l'identique de
   [data-fp-carte] sur la page Restauration (assets/css/restauration.css) :
   au repos (sans JavaScript, ou état de départ avant la première peinture),
   la carte est DÉJÀ à sa taille définitive ; SEUL cet état masqué, sous
   html.fp-e-anim, la réduit avant que assets/js/evenements.js ne l'amène
   vers scale(1) au scrub. */
html.fp-e-anim .page-template-template-evenements [data-fp-carte] { transform: scale(.86); border-radius: 40px; }

/* --------------------------------------------------------------------------
   SECTIONS D'OFFRE (fp-evo : Événement, Offre).

   Quatre sections bâties sur le même markup : colonne de texte (sur-titre en
   pilule, titre, paragraphes, liste de ce qui est compris, bouton de fin de
   section) et colonne visuelle (deux photos qui se chevauchent, ou un panneau
   sobre tant qu'aucune photo n'est déposée).

   Mobile d'abord : une seule colonne, le TEXTE EN PREMIER, ce qui est aussi
   l'ordre du document. Le côté de la photo (`order`) ne change qu'à partir de
   900 px, là où les deux colonnes existent réellement.

   FOND CLAIR / FOND TEAL PLEIN, EN ALTERNANCE (maquette) : Anniversaires et
   EVG/EVJF gardent le fond clair du reste du site (fp-s-light) ; Entreprises et
   séminaires et Événements privés basculent sur fp-s-primary (teal plein,
   texte blanc). Les règles ci-dessous s'appliquent donc aux DEUX registres :
   .fp-evo-prose, .fp-evo-item et .fp-evo-puce ont chacun leur variante sombre,
   choisie par l'ancêtre .fp-s-primary (même mécanique que .fp-s-primary
   .fp-section-sub dans main.css). Les pilules icon-box et le bouton .fp-btn
   s'adaptent déjà tout seuls (voir le composant ICON-BOX de main.css).
   -------------------------------------------------------------------------- */

/* Les ancres de ces sections vont dans le menu du site : le titre visé ne doit
   pas se retrouver sous la barre de navigation, qui est collante. */
.page-template-template-evenements .fp-evo,
.page-template-template-evenements .fp-evo-cta,
.page-template-template-evenements .fp-evd,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre { scroll-margin-top: calc(var(--fp-nav-h) + 16px); }

.page-template-template-evenements .fp-evo { position: relative; }

.page-template-template-evenements .fp-evo-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 5vw, 56px);
}

/* Chiffre-filigrane (01 a 04) : purement decoratif (aria-hidden cote rendu),
   tres attenue, POSE DERRIERE le contenu (z-index négatif du wrap, voir plus
   bas) pour ne jamais gener la lecture ni le clic sur les liens. Cache sous
   980 px : sur une colonne etroite, un tel filigrane ecraserait le texte. */
.page-template-template-evenements .fp-evo-num {
  position: absolute;
  top: clamp(20px, 4vw, 40px);
  right: clamp(-10px, -2vw, 10px);
  z-index: 0;
  font-family: var(--fp-font-heading);
  font-size: clamp(120px, 16vw, 280px);
  line-height: .78;
  color: color-mix(in srgb, var(--fp-ink) 5%, transparent);
  pointer-events: none;
  user-select: none;
}
.page-template-template-evenements .fp-s-primary .fp-evo-num,
.page-template-template-evenements .fp-s-dark .fp-evo-num {
  color: color-mix(in srgb, var(--fp-paper) 12%, transparent);
}
.page-template-template-evenements .fp-evo--media-gauche .fp-evo-num { right: auto; left: clamp(-10px, -2vw, 10px); }
.page-template-template-evenements .fp-evo-grid > * { position: relative; z-index: 1; }
@media (max-width: 980px) {
  .page-template-template-evenements .fp-evo-num { display: none; }
}
/* PASTILLE « BIENTÔT DISPONIBLE ! » ALIGNÉE SUR LE TEXTE (Marino, 11.09.2026 :
   « le Bientôt disponible est décalé, mets-le aligné à Fêter un anniversaire
   sur mobile »). Sous 560 px, la pastille partagée (.fp-formule-bientot,
   assets/css/anniversaire-bientot.css) quitte sa position absolue pour
   rentrer dans le flux. Elle est rendue dans un .fp-wrap à elle
   (.fp-evo-bientot-wrap, inc/evenements-prives.php), le MÊME conteneur que le
   texte : l'alignement vient de là, aucune gouttière n'est recopiée ici. Un
   premier essai posait margin-left: var(--fp-gutter-mobile) sur la pastille ;
   le décalage restait visible en ligne, d'où le conteneur commun. Ce wrap ne
   doit jamais être positionné : sur grand écran la pastille reste en absolu
   par rapport à la section, dans le coin, et le wrap n'a aucune hauteur. */
.page-template-template-evenements .fp-evo-bientot-wrap { position: static; }

/* --- Colonne de texte ----------------------------------------------------- */
/* TÊTE DE SECTION À LA LARGEUR HABITUELLE DU SITE, alignée à gauche (retour
   client du 2026-08-12, à trois reprises, dernière précision : « je ne sais
   pas pourquoi c'est centré »). max-width RETIRÉ sur .fp-evo-titre :
   .fp-evo-titre hérite donc du gabarit standard .fp-lead (22ch, main.css).
   text-align: left explicite, en toute rigueur : ni .fp-lead ni .fp-evo-corps
   ne centrent le TEXTE proprement dit.

   CETTE PREMIÈRE CORRECTION (max-width, text-align) NE SUFFISAIT PAS : LA
   VRAIE CAUSE ÉTAIT UNE PISTE DE GRILLE, PAS UN TEXTE CENTRÉ. Voir la note
   complète juste avant la règle @media (min-width: 900px) plus bas dans ce
   fichier (bloc « Deux colonnes ») : sur les sections fp-evo--media-gauche
   (Anniversaires, EVG et EVJF), .fp-evo-corps se retrouvait projeté dans la
   SECONDE piste de la grille (1.08fr) par un `order: -1` posé sur la colonne
   voisine, donc décalé de presque une pleine largeur de piste vers la droite,
   ce qu'aucun réglage de .fp-evo-titre lui-même ne pouvait corriger. Ce
   correctif-ci (max-width, text-align) reste utile et juste, mais c'est
   l'autre correctif, plus bas, qui règle la position réelle de la colonne. */
.page-template-template-evenements .fp-evo-corps { text-align: left; }
.page-template-template-evenements .fp-evo-titre {
  margin-bottom: 18px;
  /* Le volet-masque de assets/js/evenements.js recouvre exactement le texte :
     un débordement (descendante de lettre, ombre) resterait coupé pendant le
     mouvement. overflow: hidden ne mord donc que le temps de l'animation, la
     ligne retrouve sa place normale une fois révélée (voir data-fp-mask). */
  overflow: hidden;
  padding-bottom: .08em;
}
/* Titres des sections d'offre un peu plus grands sur téléphone (retour client
   du 2026-08-18 : « Anniversaires », « Entreprises et séminaires »... doivent
   s'imposer davantage) : à cette largeur, le plancher du gabarit .fp-lead
   (1.7rem, main.css) faisait presque jeu égal avec la prose. */
@media (max-width: 720px) {
  .page-template-template-evenements .fp-evo-titre { font-size: 2.05rem; }
}
.page-template-template-evenements .fp-evo-prose { max-width: 60ch; }
.page-template-template-evenements .fp-evo-prose p {
  margin: 0 0 1em;
  color: var(--fp-ink-soft);
}
.page-template-template-evenements .fp-evo-prose p:last-child { margin-bottom: 0; }
.page-template-template-evenements .fp-s-primary .fp-evo-prose p,
.page-template-template-evenements .fp-s-dark .fp-evo-prose p {
  color: rgba(255, 255, 255, .92);
}

.page-template-template-evenements .fp-evo-liste {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  gap: 4px;
  max-width: 60ch;
  border-top: 1px solid var(--fp-line);
}
.page-template-template-evenements .fp-s-primary .fp-evo-liste,
.page-template-template-evenements .fp-s-dark .fp-evo-liste {
  border-top-color: rgba(255, 255, 255, .28);
}
/* Chaque ligne porte son propre filet (data-fp-rule, trace au scroll par
   assets/js/evenements.js) : au repos (CSS seul), le filet est deja plein,
   comme une liste ordinaire. */
.page-template-template-evenements .fp-evo-item {
  position: relative;
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 12px;
  align-items: start;
  padding: 13px 0;
  border-bottom: 1px solid var(--fp-line);
  color: var(--fp-ink);
}
.page-template-template-evenements .fp-s-primary .fp-evo-item,
.page-template-template-evenements .fp-s-dark .fp-evo-item {
  border-bottom-color: rgba(255, 255, 255, .28);
  color: var(--fp-paper);
}
/* Le filet visuel EST la bordure ci-dessus : cet element ne sert qu'a
   l'animation (scaleX 0 -> 1 au scroll), superpose a elle, jamais visible tant
   que rien ne l'anime (transform neutre par defaut, cf. l'etat masque plus
   bas). Sans JavaScript, la vraie bordure CSS suffit, ce calque reste inerte. */
.page-template-template-evenements .fp-evo-item-rule {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 1px;
  background: var(--fp-primary);
  transform-origin: left center;
  transform: scaleX(0);
  pointer-events: none;
}
.page-template-template-evenements .fp-s-primary .fp-evo-item-rule,
.page-template-template-evenements .fp-s-dark .fp-evo-item-rule {
  background: var(--fp-paper);
}
/* Pastille de coche : décorative (aria-hidden côté rendu), elle ne remplace
   jamais la puce de liste pour un lecteur d'écran, qui lit bien un <li>. */
.page-template-template-evenements .fp-evo-puce {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin-top: 1px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--fp-primary) 30%, transparent);
  background: color-mix(in srgb, var(--fp-primary) 12%, var(--fp-paper));
  color: var(--fp-primary);
}
.page-template-template-evenements .fp-s-primary .fp-evo-puce,
.page-template-template-evenements .fp-s-dark .fp-evo-puce {
  border-color: rgba(255, 255, 255, .5);
  background: rgba(255, 255, 255, .16);
  color: var(--fp-paper);
}
.page-template-template-evenements .fp-evo-puce svg { width: 15px; height: 15px; }

/* flex + gap plutôt qu'un simple bloc : la section EVG/EVJF (demande de
   Marino du 10.09.2026) y pose DEUX boutons (« Voir le pack EVG / EVJF » puis
   « Demander une offre », secondaire en contour, voir fp_render_evenement_offre,
   inc/evenements-prives.php) ; sans effet sur les trois autres sections, qui
   n'en portent qu'un seul. */
.page-template-template-evenements .fp-evo-action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 18px;
  margin: 30px 0 0;
}
/* 48 px de haut : la cible tactile dépasse le seuil de 44 px, flèche repliée
   comme flèche dépliée.

   SUR FOND TEAL PLEIN, LE BOUTON PORTE LA VARIANTE fp-btn-light, PAS UNE
   SURCHARGE LOCALE (retour client du 2026-08-12, sixième chantier, point 4 :
   « sur un fond plus vert... j'ai un hover avec du blanc, ce qui fait que je
   ne vois plus le texte dessus du tout »). CAUSE DU BUG PRÉCÉDENT : ce fichier
   repeignait ici le bouton fp-btn-primary en blanc pour rester lisible sur
   teal, mais son survol (::before qui glisse) restait celui de la recette
   PRIMARY (remplissage BLANC, texte qui passe teal) : un texte blanc HÉRITÉ
   de la surcharge se retrouvait donc sur un remplissage de survol blanc,
   invisible. fp_render_evenement_offre (inc/evenements-prives.php) pose
   désormais directement la classe fp-btn-light sur ces boutons (recette
   standard du thème pour un bouton sur fond sombre, main.css : fond blanc,
   texte teal, se remplit de TEAL au survol, texte blanc) : plus aucune
   surcharge de couleur nécessaire ici, seule la taille reste propre à cette
   page. */
.page-template-template-evenements .fp-evo-btn { min-height: 48px; }

/* Chiffre-clé flottant sous la photo (maquette : « 20 pistes de bowling »,
   « 10 - 200 personnes par groupe »). Décoratif, jamais la seule source du
   chiffre : le texte et la liste de la section le disent déjà en toutes
   lettres (voir fp_evenements_prives_offres, clé 'fait'). */
.page-template-template-evenements .fp-evo-fait {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 16px 0 0;
  color: var(--fp-ink);
}
.page-template-template-evenements .fp-s-primary .fp-evo-fait,
.page-template-template-evenements .fp-s-dark .fp-evo-fait {
  color: var(--fp-paper);
}
.page-template-template-evenements .fp-evo-fait-valeur {
  font-family: var(--fp-font-heading);
  font-size: clamp(2rem, 4vw, 2.6rem);
  line-height: .85;
  white-space: nowrap;
}
.page-template-template-evenements .fp-evo-fait-label {
  max-width: 15ch;
  font-size: .8rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--fp-ink-soft);
}
.page-template-template-evenements .fp-s-primary .fp-evo-fait-label,
.page-template-template-evenements .fp-s-dark .fp-evo-fait-label {
  color: rgba(255, 255, 255, .82);
}

/* --- Colonne visuelle ----------------------------------------------------- */
.page-template-template-evenements .fp-evo-media {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}
.page-template-template-evenements .fp-evo-photo {
  margin: 0;
  overflow: hidden;
  border-radius: var(--fp-radius-lg);
  background: var(--fp-cream);
  box-shadow: var(--fp-shadow);
}
.page-template-template-evenements .fp-evo-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.page-template-template-evenements .fp-evo-photo--principale { aspect-ratio: 4 / 3; }
.page-template-template-evenements .fp-evo-photo--seconde { aspect-ratio: 16 / 9; }

/* AUCUNE PHOTO : c'est l'état dans lequel la page est livrée, il doit donc être
   fini, pas troué. Un panneau sobre aux tokens du site, marqué de l'icône de la
   section, tient la place jusqu'à ce que la cliente dépose ses images dans la
   galerie de la zone. */
.page-template-template-evenements .fp-evo-media-vide {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--fp-line);
  border-radius: var(--fp-radius-lg);
  background:
    repeating-linear-gradient(
      135deg,
      color-mix(in srgb, var(--fp-secondary) 6%, transparent) 0 12px,
      transparent 12px 24px
    ),
    var(--fp-cream);
  color: color-mix(in srgb, var(--fp-secondary) 34%, transparent);
}
.page-template-template-evenements .fp-evo-media-vide svg {
  width: clamp(52px, 11vw, 88px);
  height: auto;
}

/* ==========================================================================
   L'ENCRE SUIT LE FOND

   Le fond de page se teinte d'une section à l'autre (bloc FOND DE PAGE ANIMÉ
   plus haut), mais les couleurs de texte, elles, appartiennent normalement à
   chaque section : pendant le fondu, un texte prévu pour un fond clair se
   retrouverait sur du sombre, presque illisible. Même correctif que la page
   Restauration.

   PRINCIPE : le fond est global, l'encre l'est donc aussi. evenements.js pose
   .is-fond-sombre sur .page-template-template-evenements en même temps qu'il
   lance le fondu du fond, et toutes les encres basculent avec, sur la MÊME
   durée. Ces règles ne s'appliquent QUE sous .fp-e-fond-anime : sans lui,
   chaque section garde son fond plein et ses propres couleurs (définies plus
   haut, blocs SECTIONS D'OFFRE et CTA RÉSERVATION).

   CE BLOC DOIT VENIR APRÈS « SECTIONS D'OFFRE » DANS CE FICHIER, PAS AVANT
   (retour client du 2026-08-12, sixième chantier, point 3 : « avant que la
   transition de couleur se fasse sur Entreprises et séminaires, le contenu
   est déjà blanc » ; point 5, même famille : « la section EVG/EVJF garde le
   texte en blanc »). CAUSE TROUVÉE, en comparant à assets/css/restauration.css
   (où l'ordre est déjà correct) : les règles de « SECTIONS D'OFFRE » posent
   des couleurs de texte STATIQUES sur les sections déjà fp-s-primary/fp-s-dark
   au rendu (.fp-s-primary .fp-evo-prose p, .fp-evo-item, .fp-evo-item-rule,
   .fp-evo-puce, .fp-evo-fait...), avec la MÊME spécificité (trois classes)
   que les règles dynamiques ci-dessous (.fp-e-fond-anime .fp-evo-prose p...).
   À spécificité égale, c'est l'ORDRE DANS LA FEUILLE qui décide : quand ce
   bloc était placé AVANT « SECTIONS D'OFFRE » (comme livré au chantier
   précédent), les règles statiques, déclarées APRÈS, gagnaient TOUJOURS,
   qu'importe l'état réel de .fp-e-fond-anime/.is-fond-sombre : Entreprises et
   EVG, tous deux fp-s-primary depuis le point 4 du chantier précédent,
   affichaient donc un texte blanc EN PERMANENCE, y compris AVANT que le fond
   du corps de page n'ait fini de virer au vert (d'où le blanc sur blanc
   fugitif), et même SANS JavaScript. Replacer ce bloc APRÈS « SECTIONS
   D'OFFRE » inverse le rapport de force : la règle dynamique, désormais
   déclarée en dernier, l'emporte quand .fp-e-fond-anime est actif (l'encre
   suit alors vraiment le fond, claire tant que le fond n'est pas encore
   vert, blanche seulement une fois qu'il l'est) ; SANS JavaScript, .fp-e-fond-
   anime n'existe jamais, les sélecteurs dynamiques ne correspondent à rien,
   et les règles statiques (texte blanc sur fond teal) redeviennent seules à
   s'appliquer, ce qui est cette fois voulu (fond ET encre statiques,
   cohérents entre eux, jamais l'un sans l'autre).
   ========================================================================== */
.page-template-template-evenements.fp-e-fond-anime {
  --fp-e-titre-vif: var(--fp-dark);
  --fp-e-encre-vive: var(--fp-ink);
  --fp-e-encre-douce: var(--fp-ink-soft);
  --fp-e-trait-vif: var(--fp-line);
}
.page-template-template-evenements.fp-e-fond-anime.is-fond-sombre {
  --fp-e-titre-vif: var(--fp-white);
  --fp-e-encre-vive: var(--fp-e-clair);
  --fp-e-encre-douce: var(--fp-e-clair-doux);
  --fp-e-trait-vif: rgba(255, 255, 255, .28);
}
/* ANNIVERSAIRES NE SUIT PAS L'ENCRE GLOBALE (arbitrage client du 2026-08-13 :
   « cette section sera toujours sur fond blanc, pas besoin d'en changer la
   couleur du texte »). Son fond est opaque en toutes circonstances (règle
   [data-fp-lieu="anniversaires"] plus haut) : tant que le héro sombre est
   encore la section active, l'encre claire globale la rendait blanc sur
   blanc. Ses jetons d'encre sont donc réancrés sur les valeurs claires,
   quelle que soit la phase du fond. Aucune couleur nouvelle : ce sont les
   mêmes jetons que ceux du repos, l'encre de cette section ne change plus
   jamais. */
.page-template-template-evenements.fp-e-fond-anime.is-fond-sombre [data-fp-sect][data-fp-lieu="anniversaires"] {
  --fp-e-titre-vif: var(--fp-dark);
  --fp-e-encre-vive: var(--fp-ink);
  --fp-e-encre-douce: var(--fp-ink-soft);
  --fp-e-trait-vif: var(--fp-line);
}
/* Pas de transition de couleur ici : le script bascule l'encre d'un coup, au
   milieu du fondu du fond (même contrainte de contraste que la page
   Restauration : une transition CSS déclenchée par une variable héritée n'est
   pas fiable d'un navigateur à l'autre). */
.page-template-template-evenements.fp-e-fond-anime .fp-evo-titre {
  color: var(--fp-e-titre-vif);
}
/* Le titre du héro ne suit PAS l'encre globale (arbitrage client du
   2026-08-13 : « il sera toujours sur fond vert donc doit être blanc ») :
   il repose en toutes circonstances sur le cadre opaque du héro (photo
   sombre + voile), jamais sur le fond animé du corps de page. Le laisser
   suivre la phase claire le rendait vert foncé sur photo sombre quand une
   section claire avait la main et que le héro restait partiellement
   visible. */
.page-template-template-evenements.fp-e-fond-anime .fp-ehero-titre {
  color: var(--fp-white);
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-prose p,
.page-template-template-evenements.fp-e-fond-anime .fp-evo-item {
  color: var(--fp-e-encre-vive);
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-item-txt {
  color: inherit;
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-fait,
.page-template-template-evenements.fp-e-fond-anime .fp-evo-fait-label {
  color: var(--fp-e-encre-douce);
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-item {
  border-bottom-color: var(--fp-e-trait-vif);
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-item-rule {
  background: var(--fp-e-titre-vif);
}
.page-template-template-evenements.fp-e-fond-anime .fp-evo-puce {
  border-color: color-mix(in srgb, var(--fp-e-titre-vif) 40%, transparent);
  background: color-mix(in srgb, var(--fp-e-titre-vif) 12%, transparent);
  color: var(--fp-e-titre-vif);
}
/* Les pilules icon-box (sur-titres) suivent par la classe utilitaire du thème
   (.fp-fond-sombre, main.css), posée et retirée par le script sur chaque
   section : aucune variable du composant n'est redéfinie ici. */
.page-template-template-evenements.fp-e-fond-anime .fp-ibox {
  transition: background-color .3s ease, border-color .3s ease, color .3s ease;
}

/* --------------------------------------------------------------------------
   CTA RÉSERVATION (fp-evo-cta), zone fp-blk-evenement-cta-reservation.

   Maquette : carte teal pleine largeur (bord arrondi, marge de respiration
   autour), texte à gauche, photo à droite. Mêmes composants que les sections
   d'offre (.fp-lead, icon-box, .fp-btn) : rien de nouveau à réapprendre
   visuellement pour la cliente.

   UN SEUL CTA, retour client du 2026-08-12 (cinquième chantier, point 5) :
   cette carte portait jusqu'ici l'invitation à réserver une activité (bouton
   vers le popup « Bientôt disponible ») ; elle reprend désormais le contenu
   ET l'action de l'ancien CTA final « Demander une offre » de la page
   (inc/evenements-prives.php, fp_render_evenement_cta_reservation). L'entête
   devenue redondante de la zone fp-blk-demande-offre (inc/demande-offre.php,
   hors périmètre de ce chantier) est masquée un peu plus bas dans ce fichier,
   bloc « UN SEUL CTA : ENTÊTE REDONDANTE MASQUÉE ».
   -------------------------------------------------------------------------- */
/* V3 (2026-09-06, retour de Marino, choix validé) : la bande claire sous la
   carte disparaît, la carte vient toucher le pied de page. La carte ne porte
   aucune box-shadow (vérifié : aucun liseré ne se forme), son rayon bas
   (assets/css/evenements.css, bloc « Coins BAS de la carte ») reste donc
   suffisant tel quel.

   PAS DE overflow: hidden ICI (relecture Opus du 2026-09-06) : la carte
   porte .fp-reveal (état de départ opacity: 0, transform: translateY(24px),
   main.css), et sans JavaScript (ou avant que GSAP ne prenne la main), ce
   décalage de 24px se retrouvait rogné par l'overflow de la section, un
   morceau de la carte disparaissant purement et simplement pendant le
   fondu. Le garde-fou anti-débordement horizontal des particules
   décoratives (.fp-evo-cta-particules) vit désormais SUR le SVG lui-même,
   qui se découpe seul sur son propre viewport (voir plus bas). */
/* Respiration sous la carte (Marino, 2026-09-07 : « pour pas être collé » au
   pied de page) : le bas de section n'était pas rembourré. */
.page-template-template-evenements .fp-evo-cta { padding: clamp(20px, 4vw, 40px) 0 clamp(40px, 6vw, 72px); }
.page-template-template-evenements .fp-evo-cta-carte {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  overflow: hidden;
  border-radius: var(--fp-radius-lg);
  background: var(--fp-primary);
  color: var(--fp-paper);
}
.page-template-template-evenements .fp-evo-cta-mots {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: clamp(30px, 5vw, 54px) clamp(24px, 5vw, 54px);
}
.page-template-template-evenements .fp-evo-cta-titre { max-width: 16ch; overflow: hidden; padding-bottom: .08em; }
.page-template-template-evenements .fp-evo-cta-texte {
  margin: 0;
  max-width: 54ch;
  font-size: 1.05rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, .92);
}
.page-template-template-evenements .fp-evo-cta-action { margin: 6px 0 0; }
/* Couleurs retirées d'ici (retour client du 2026-08-12, sixième chantier,
   point 4, même cause et même correctif que .fp-evo-btn plus haut) : le
   bouton porte désormais directement la classe fp-btn-light
   (fp_render_evenement_cta_reservation, inc/evenements-prives.php), recette
   standard du thème pour un bouton sur fond teal plein. Seule la taille reste
   propre à cette carte. */
.page-template-template-evenements .fp-evo-cta-btn { min-height: 52px; }

.page-template-template-evenements .fp-evo-cta-media { position: relative; min-height: 240px; }
.page-template-template-evenements .fp-evo-cta-photo {
  margin: 0;
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.page-template-template-evenements .fp-evo-cta-photo img { width: 100%; height: 100%; object-fit: cover; }
.page-template-template-evenements .fp-evo-cta-media-vide {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--fp-dark) 20%, var(--fp-primary));
  color: rgba(255, 255, 255, .5);
}
.page-template-template-evenements .fp-evo-cta-media-vide svg { width: clamp(52px, 9vw, 84px); height: auto; }

@media (min-width: 780px) {
  .page-template-template-evenements .fp-evo-cta-carte { grid-template-columns: 1.15fr .85fr; align-items: stretch; }
  .page-template-template-evenements .fp-evo-cta-media { min-height: 100%; }
}

/* Coins BAS de la carte vraiment arrondis (retour client du 2026-08-18 :
   « arrondis en haut mais pas en bas »). Le rognage par overflow: hidden du
   parent arrondi lâche sur Safari quand l'enfant est animé (clip-path du volet
   photo data-fp-clip, transformation du scrub) : la photo ressort alors au
   carré. Double parade : isolation sur la carte (rétablit le rognage en créant
   le contexte d'empilement qui manque à Safari) ET rayons posés en dur sur le
   média, qui suivent sa place dans la grille (dernière ligne de la pile
   mobile, colonne droite pleine hauteur dès 780 px). */
.page-template-template-evenements .fp-evo-cta-carte { isolation: isolate; }
.page-template-template-evenements .fp-evo-cta-media,
.page-template-template-evenements .fp-evo-cta-photo,
.page-template-template-evenements .fp-evo-cta-media-vide {
  overflow: hidden;
  border-radius: 0 0 var(--fp-radius-lg) var(--fp-radius-lg);
}
@media (min-width: 780px) {
  .page-template-template-evenements .fp-evo-cta-media,
  .page-template-template-evenements .fp-evo-cta-photo,
  .page-template-template-evenements .fp-evo-cta-media-vide {
    border-radius: 0 var(--fp-radius-lg) var(--fp-radius-lg) 0;
  }
}

/* Pile mobile de la carte CTA (sous le palier des deux colonnes) : tout le
   contenu est centré, le titre et le bouton gagnent en présence (retour client
   du 2026-08-18 : « tout centrer, demander une offre en plus grand »). */
@media (max-width: 779px) {
  .page-template-template-evenements .fp-evo-cta-mots { align-items: center; text-align: center; }
  .page-template-template-evenements .fp-evo-cta-titre {
    margin-left: auto;
    margin-right: auto;
    font-size: 2.05rem;
  }
  .page-template-template-evenements .fp-evo-cta-texte { margin-left: auto; margin-right: auto; }
  .page-template-template-evenements .fp-evo-cta-btn { min-height: 56px; font-size: 1.05rem; }

  /* LA CARTE PREND PRESQUE TOUTE LA LARGEUR DE L'ÉCRAN (retour client du
     2026-08-20 : « à son maximum, il reste trop de marge à gauche et à
     droite »).

     D'OÙ VENAIT LA MARGE. La colonne standard du site est .fp-wrap, bornée à
     min(1300px, 90vw) PLUS une gouttière intérieure de 20 px sous 720 px
     (main.css) : sur un téléphone de 390 px, la carte plafonnait donc à
     351 - 40 = 311 px, soit huit dixièmes de l'écran, et le scrub s'arrêtant à
     l'échelle 1, elle ne pouvait pas aller plus loin.

     CE QUI EST FAIT, ET CE QUI NE L'EST PAS. On élargit LE CONTENEUR de cette
     seule zone (gouttière ramenée à 10 px, plafond de colonne levé), on ne
     pousse PAS l'échelle finale au-delà de 1 : une échelle supérieure à 1
     déborderait de la largeur de l'écran, interdit ici, et le débordement
     d'une transformation ne se rattrape pas par un simple recadrage. La carte
     atteint donc 100 % de la largeur de l'écran moins 20 px, sans qu'un seul
     pixel ne puisse sortir.

     MÊME LARGEUR FINALE DANS TOUS LES ÉTATS, par construction : le repos (sans
     JavaScript), l'état « animations réduites » (transform: none, plus bas
     dans ce fichier) et la fin du scrub (échelle 1) rendent tous les trois la
     carte à 100 % de ce conteneur, qui est le seul à avoir changé. */
  .page-template-template-evenements .fp-evo-cta > .fp-wrap {
    max-width: none;
    padding-left: 10px;
    padding-right: 10px;
  }

  /* SUR-TITRE EN PILULE MASQUÉ SUR TÉLÉPHONE (retour client du 2026-08-20 :
     la pilule passait sur deux lignes et mangeait la hauteur utile de la
     carte). Masquage d'AFFICHAGE seulement, et sur la seule carte CTA : le
     texte reste dans le contenu de la zone, éditable dans Gutenberg, et
     l'information qu'il portait est déjà dans le titre juste en dessous. Les
     sur-titres des quatre sections d'offre, eux, ne sont pas concernés. */
  .page-template-template-evenements .fp-evo-cta-carte .fp-section-eyebrow {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   V3 (2026-09-06, retour de Marino) : plan du parc en filigrane sur TOUT le
   fond vert de la carte, même idiome que .fp-formules-plan (activite.css) et
   .fp-carte-plan (restaurant.css), mais posé en z-index négatif plutôt qu'en
   z-index: 0 : la carte porte déjà isolation: isolate (bloc « Coins BAS »
   ci-dessus), donc ce z-index négatif reste piégé DANS le contexte
   d'empilement de la carte, au-dessus de son propre fond (var(--fp-primary))
   mais SOUS tout le reste (texte, média, texture topo), sans toucher à leur
   position/z-index actuels. -------------------------------------------- */
.page-template-template-evenements .fp-evo-cta-plan {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('../img/em-plan.svg');
  background-size: min(900px, 140%);
  background-position: center;
  background-repeat: no-repeat;
  opacity: .1;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   V3 (2026-09-06) : particules décoratives projetées depuis derrière la
   carte à son arrivée dans l'écran, puis flottement lent. Déclenchées par la
   classe .is-in que main.js pose déjà sur tout élément .fp-reveal visible
   (voir la note dans fp_render_evenement_cta_reservation, inc/evenements-
   prives.php) : le conteneur .fp-evo-cta-particules porte lui-même
   .fp-reveal pour profiter de cette mécanique SANS ajouter de script, mais
   son propre fondu générique (main.css) est neutralisé ci-dessous, seules
   les particules internes doivent bouger.

   GARDE-FOU ANTI-DÉBORDEMENT (relecture Opus du 2026-09-06) : posé ICI, sur
   le SVG lui-même (overflow: hidden, comportement natif d'un <svg> qui se
   découpe sur son propre viewport), plutôt que sur la section .fp-evo-cta
   (voir la note juste au-dessus de .fp-evo-cta) : le débordement horizontal
   reste impossible (le SVG couvre toute la largeur de la section, inset: 0),
   sans plus jamais rogner la carte pendant son fondu d'entrée. -------------- */
.page-template-template-evenements .fp-evo-cta-particules {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  /* Neutralise le fondu/translateY générique de .fp-reveal (main.css) : le
     conteneur reste toujours présent, seules les particules (ci-dessous)
     animent, chacune depuis son propre état de repos. */
  opacity: 1;
  transform: none;
  transition: none;
}
.page-template-template-evenements .fp-evo-cta-particule {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  transform: translate(0, 0) rotate(0deg) scale(.4);
}
.page-template-template-evenements .fp-evo-cta-particules.is-in .fp-evo-cta-particule {
  animation-name: fp-evo-particule-jaillir, fp-evo-particule-flotter;
  animation-duration: var(--fp-p-dur, 1.5s), 5.5s;
  animation-timing-function: ease-out, ease-in-out;
  animation-delay: var(--fp-p-delay, 0s), calc(var(--fp-p-delay, 0s) + var(--fp-p-dur, 1.5s));
  animation-iteration-count: 1, infinite;
  animation-fill-mode: forwards, none;
}
@keyframes fp-evo-particule-jaillir {
  0% { opacity: 0; transform: translate(0, 0) rotate(0deg) scale(.4); }
  55% { opacity: 1; }
  100% { opacity: .9; transform: translate(var(--fp-p-tx, 0px), var(--fp-p-ty, 0px)) rotate(var(--fp-p-rot, 0deg)) scale(1); }
}
@keyframes fp-evo-particule-flotter {
  0%, 100% { transform: translate(var(--fp-p-tx, 0px), var(--fp-p-ty, 0px)) rotate(var(--fp-p-rot, 0deg)) scale(1); opacity: .9; }
  50% { transform: translate(calc(var(--fp-p-tx, 0px) + 6px), calc(var(--fp-p-ty, 0px) - 6px)) rotate(calc(var(--fp-p-rot, 0deg) + 4deg)) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  /* « Rien n'apparaît » : les particules sont purement décoratives, elles
     restent invisibles plutôt qu'immobiles en pleine vue à mi-course. */
  .page-template-template-evenements .fp-evo-cta-particule {
    animation: none !important;
    opacity: 0 !important;
    transform: none !important;
  }
}

/* --------------------------------------------------------------------------
   DEMANDE D'OFFRE (zone fp-blk-demande-offre, inc/demande-offre.php).

   Deux etats pour le MEME markup, c'est la cle de lecture de ce bloc :
     - sans JavaScript, le panneau .fp-offre-panneau reste dans la page et le
       formulaire s'utilise tel quel ;
     - avec JavaScript, assets/js/demande-offre.js deplace ce panneau dans une
       <dialog> et pose le bouton d'ouverture.
   Les regles de champ sont donc ecrites sur .fp-offre-form, pas sur la fenetre :
   elles valent dans les deux cas. Mobile d'abord, la fenetre doit tenir a
   320 px de large avec neuf champs, d'ou le defilement INTERNE au corps.

   FENETRE PARTOUT (2026-09-10, inc/demande-offre.php,
   fp_demande_offre_render_fenetre) : le MEME markup, en pied de page des
   gabarits qui n'ont pas la zone dediee (classe is-fenetre-seule, attribut
   HTML natif hidden). D'ou le prefixe :is(...) sur chaque regle de ce bloc,
   qui remplace l'ancien scope unique ".page-template-template-evenements" :
   l'habillage suit le formulaire hors de la page Evenements prives des que le
   corps porte la classe fp-offre-fenetre (voir fp_demande_offre_body_class).
   -------------------------------------------------------------------------- */
.fp-offre.is-fenetre-seule[hidden] { display: none; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre { background: var(--fp-cream); }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-inner { text-align: center; }
/* .fp-lead est borne a 22ch (main.css) : sans marges automatiques, le titre
   restait colle a gauche pendant que l'accroche et le bouton, eux, etaient
   bien centres. Mesure faite a 1024 et 1440 px. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-inner .fp-lead {
  margin-left: auto;
  margin-right: auto;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-sub {
  max-width: 56ch;
  margin: 14px auto 0;
  color: var(--fp-ink-soft);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-declencheur { margin: 26px 0 0; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-declencheur:empty { margin: 0; }

/* --------------------------------------------------------------------------
   UN SEUL CTA : ENTÊTE REDONDANTE MASQUÉE (retour client du 2026-08-12,
   cinquième chantier, point 5).

   La carte CTA Réservation, juste au-dessus (bloc « CTA RÉSERVATION » plus
   haut), porte désormais l'invitation à demander une offre. L'entête de
   CETTE zone (sur-titre, titre, accroche) et l'emplacement du bouton
   d'ouverture (.fp-offre-declencheur, rempli par assets/js/demande-offre.js)
   deviendraient donc un second CTA, quasi identique, juste en dessous : un
   retour arrière exactement contraire à la demande. inc/demande-offre.php est
   HORS PÉRIMÈTRE de ce chantier (impossible d'y retoucher le rendu PHP) :
   cette entête est donc masquée ICI, EN CSS SEUL, jamais retirée du contenu
   Gutenberg (la cliente peut toujours l'y retoucher, mais elle ne s'affiche
   plus). RIEN N'EST PERDU côté fonctionnement : .fp-offre-panneau (le
   formulaire lui-même) N'EST PAS masqué, il reste la cible réelle du bouton
   de la carte CTA au-dessus (même ancre #demande-offre, même fenêtre modale
   quand JavaScript est là) ; sans JavaScript, il reste visible et utilisable
   tel quel, avec son propre intitulé interne (.fp-offre-form-titre, voir
   fp_demande_offre_formulaire, inc/demande-offre.php), qui n'est pas
   concerné par ce masquage. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre .fp-section-eyebrow,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre > .fp-offre-inner > h2.fp-lead,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre .fp-offre-sub,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-declencheur {
  display: none;
}

/* Panneau du formulaire dans son etat « en pleine page » (repli sans script).
   Une fois deplace dans la fenetre, il perd son cadre : le cadre, c'est la
   fenetre elle-meme. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-panneau {
  max-width: 620px;
  margin: 26px auto 0;
  padding: clamp(18px, 4vw, 30px);
  text-align: left;
  border: 1px solid var(--fp-line);
  border-radius: var(--fp-radius-lg);
  background: var(--fp-paper);
  box-shadow: var(--fp-shadow);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog .fp-offre-panneau {
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

/* --- Champs du formulaire (valables dans la page ET dans la fenetre) ------ */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form-titre {
  margin: 0;
  font-family: var(--fp-font-heading);
  font-size: 1.6rem;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form label {
  font-weight: 600;
  font-size: .95rem;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-field-req { color: var(--fp-primary); }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form input,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form select,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form textarea {
  font: inherit;
  /* PLANCHER EXPLICITE DE 16 PX (Marino, 2026-09-10, point 6) : « font: inherit »
     reprend déjà les 17 px du corps de page (assets/css/main.css), mais on le
     fixe ici en dur, sans dépendre de la chaîne d'héritage : Safari iOS
     zoome automatiquement au focus tout champ dont la taille de police
     calculée descend sous 16 px, y compris les champs natifs date/heure/
     nombre qui n'empruntent pas toujours la même cascade que le texte
     courant. max() garantit ce plancher même si le corps de page changeait
     un jour de taille. */
  font-size: max(1rem, 16px);
  width: 100%;
  /* 14 px de rembourrage vertical + la hauteur de ligne : la cible tactile
     depasse 44 px sur tous les champs, y compris le menu deroulant. */
  min-height: 44px;
  padding: 12px 14px;
  border: 1px solid var(--fp-line-strong);
  border-radius: var(--fp-radius-sm);
  background: var(--fp-paper);
  color: var(--fp-ink);
  transition: border-color .18s ease, box-shadow .18s ease;
}
/* Le contour de focus par defaut est remplace par un anneau PLUS visible, pas
   supprime : la navigation au clavier reste parfaitement lisible. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form input:focus-visible,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form select:focus-visible,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form textarea:focus-visible {
  outline: none;
  border-color: var(--fp-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fp-primary) 26%, transparent);
}
/* --------------------------------------------------------------------------
   LISTES DÉROULANTES (Formule, Heure) HABILLÉES (Marino, 2026-09-11 : « fais
   que le dropdown soit un petit peu plus sexy, là c'est le dropdown de base,
   mets-y un style moderne »). Le <select> perd son apparence native, garde
   exactement la géométrie des autres champs (bordure, rayon, hauteur, fond)
   et gagne : un chevron en couleur de THÈME porté par le conteneur
   .fp-offre-select-wrap (::after, masque SVG neutre + background-color en
   jeton, même technique que .fp-resbar-select-wrap, assets/css/home.css : un
   <select> n'accepte pas les pseudo-éléments de façon fiable) ; un survol
   qui affirme la bordure et pose une ombre teal légère, comme les cartes du
   site ; un chevron qui se retourne pendant que la liste a le focus
   (:focus-within, neutralisé sous prefers-reduced-motion) ; et l'option
   d'invite (« Sélectionner », « Choisir une heure ») en gris doux tant que
   rien n'est choisi (:invalid, les deux listes étant required), comme un
   placeholder. Curseur main : c'est un choix, pas une saisie.

   CES RÈGLES SUR LE <select> SONT LE REPLI SANS JAVASCRIPT. Avec JavaScript
   (assets/js/demande-offre-champs.js, construireListe), le <select> reste
   dans le formulaire mais devient invisible sous un COMPOSANT MAISON
   (deuxième retour de Marino le même jour : « les listes qui s'ouvrent n'ont
   aucun style, on dirait Microsoft XP ») : le panneau d'options d'un <select>
   est dessiné par le système, aucun CSS ne l'atteint. Le composant, plus
   bas : bouton .fp-offre-select-btn (même géométrie que les champs, chevron
   du conteneur conservé), panneau .fp-offre-select-liste (carte blanche à
   coins arrondis, ombre teal, défilement interne au-delà de six options,
   barre fine en jeton), options .fp-offre-select-opt (survol et focus clavier
   en teal très clair, choix courant en teal plein avec coche, options
   désactivées estompées), message d'erreur .fp-offre-select-msg (rouge du
   thème). Le panneau déborde de la fenêtre modale au lieu de l'allonger (voir
   .fp-offre-corps-deborde plus bas) et s'ouvre au-dessus du bouton quand la
   place manque en dessous (classe is-haut posée par le script).
   -------------------------------------------------------------------------- */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap {
  position: relative;
  display: block;
  width: 100%;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  /* Place du chevron : 18 px de marge droite + 12 px de chevron + 14 px. */
  padding-right: 44px;
  cursor: pointer;
  font-weight: 500;
  text-overflow: ellipsis;
  /* Aucune flèche héritée d'un navigateur qui ignorerait appearance. */
  background-image: none;
  transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select::-ms-expand { display: none; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select:hover {
  border-color: var(--fp-primary);
  box-shadow: var(--fp-shadow);
}
/* Invite en gris doux tant que rien n'est choisi (--fp-ink-soft sur blanc :
   6,9:1, déjà la couleur de placeholder du thème). */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select:invalid {
  color: var(--fp-ink-soft);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select option {
  color: var(--fp-ink);
  background: var(--fp-paper);
  font-weight: 400;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap::after {
  content: '';
  position: absolute;
  right: 18px;
  top: 50%;
  width: 12px;
  height: 8px;
  transform: translateY(-50%);
  pointer-events: none;
  background-color: var(--fp-primary);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
  transition: transform .18s ease, background-color .18s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap:hover::after {
  background-color: var(--fp-secondary);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap:focus-within::after {
  background-color: var(--fp-secondary);
  transform: translateY(-50%) rotate(180deg);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-ouverte::after {
  background-color: var(--fp-secondary);
  transform: translateY(-50%) rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap select,
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap::after { transition: none; }
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap:focus-within::after,
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-ouverte::after { transform: translateY(-50%); }
}

/* --- Composant maison (avec JavaScript), voir le commentaire de section --- */
/* Le natif reste dans le formulaire, invisible, hors clic et hors
   tabulation (tabindex -1 posé par le script) : il garde sa boîte sous le
   bouton pour que rien ne bouge dans la mise en page. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-custom > select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 44px;
  padding: 12px 44px 12px 14px;
  border: 1px solid var(--fp-line-strong);
  border-radius: var(--fp-radius-sm);
  background: var(--fp-paper);
  color: var(--fp-ink);
  font: inherit;
  font-size: max(1rem, 16px);
  font-weight: 500;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  transition: border-color .18s ease, box-shadow .18s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-val {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-vide .fp-offre-select-btn {
  color: var(--fp-ink-soft);
  font-weight: 400;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn:hover:not(:disabled) {
  border-color: var(--fp-primary);
  box-shadow: var(--fp-shadow);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn:focus-visible,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-ouverte .fp-offre-select-btn {
  outline: none;
  border-color: var(--fp-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fp-primary) 26%, transparent);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn[aria-invalid="true"] {
  border-color: var(--fp-danger);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn:disabled {
  opacity: .55;
  cursor: not-allowed;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-liste {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  z-index: 70;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--fp-paper);
  border: 1px solid var(--fp-line);
  border-radius: var(--fp-radius-sm);
  box-shadow: var(--fp-shadow-lg);
  /* Six options et demie visibles : la demi-option du bas dit qu'on peut
     faire défiler (48 créneaux d'heure). */
  max-height: 272px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--fp-primary) 40%, transparent) transparent;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-liste::-webkit-scrollbar { width: 8px; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-liste::-webkit-scrollbar-track { background: transparent; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-liste::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--fp-primary) 40%, transparent);
  border-radius: 999px;
  border: 2px solid var(--fp-paper);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-haut .fp-offre-select-liste {
  top: auto;
  bottom: calc(100% + 6px);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  margin: 0;
  padding: 9px 12px 9px 14px;
  border-radius: 8px;
  color: var(--fp-ink);
  font-size: max(1rem, 16px);
  line-height: 1.3;
  cursor: pointer;
  outline: none;
  transition: background-color .12s ease, color .12s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt + .fp-offre-select-opt { margin-top: 2px; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt:hover,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-actif {
  background: color-mix(in srgb, var(--fp-primary) 10%, var(--fp-paper));
  color: var(--fp-secondary);
}
/* Focus clavier : l'anneau intérieur distingue l'option atteinte au clavier
   de celle simplement survolée à la souris. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-actif {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--fp-primary) 45%, transparent);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-choisi,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-choisi:hover,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-choisi.is-actif {
  background: var(--fp-primary);
  color: var(--fp-paper);
  font-weight: 600;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-choisi.is-actif {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--fp-paper) 55%, transparent);
}
/* Coche du choix courant : masque SVG neutre, couleur héritée (currentColor
   via background-color), même technique que le chevron. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt.is-choisi::after {
  content: '';
  flex: 0 0 auto;
  margin-left: auto;
  width: 14px;
  height: 11px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 11'><path d='M1.5 5.5l4 4 7-8' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 11'><path d='M1.5 5.5l4 4 7-8' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") center / contain no-repeat;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-msg {
  display: block;
  margin-top: 6px;
  font-size: .85rem;
  color: var(--fp-danger);
}
@media (prefers-reduced-motion: no-preference) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-liste {
    animation: fp-offre-liste-entree .16s var(--fp-anim-ease, ease-out);
  }
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-wrap.is-haut .fp-offre-select-liste {
    animation-name: fp-offre-liste-entree-haut;
  }
  @keyframes fp-offre-liste-entree {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  @keyframes fp-offre-liste-entree-haut {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}
@media (prefers-reduced-motion: reduce) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-btn,
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-select-opt { transition: none; }
}

:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form textarea {
  /* PLUS HAUTE (Marino, 2026-09-10, point 8), depuis que l'encart vert du
     haut de cette étape a disparu (voir plus bas, .fp-offre-prerempli[hidden]) :
     la place gagnée revient au champ le plus utile de cette dernière étape. */
  min-height: 160px;
  resize: vertical;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form [aria-invalid="true"] { border-color: var(--fp-danger); }

/* --------------------------------------------------------------------------
   CHAMP DE DATE (Flatpickr), meme mecanique que le module de reservation de
   l'accueil (assets/css/reservation-ui.css). Voir assets/js/demande-offre-
   champs.js pour la configuration complete (locale fr, altInput, static).

   .flatpickr-wrapper EN display:block LARGEUR PLEINE (retour du defaut de la
   librairie, inline-block) : sans cette regle, le compteur d'enfants du
   pack "static" prend la largeur de son contenu, plus etroit que les autres
   champs du formulaire, casse visuel immediat a cote des autres champs qui
   sont tous en width:100% (regle .fp-offre-form input plus haut).

   AUCUN appendTo/body ici (voir le commentaire du script) : le calendrier est
   insere comme enfant du champ (option "static"), jamais ajoute a <body>, ce
   formulaire finissant dans une <dialog> modale une fois deplace par
   assets/js/demande-offre.js.
   -------------------------------------------------------------------------- */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .flatpickr-wrapper {
  display: block;
  width: 100%;
}
.flatpickr-calendar.fp-offre-calendar {
  font-family: var(--fp-font-body);
  border-radius: var(--fp-radius);
  box-shadow: var(--fp-shadow-lg);
  border: 0;
  /* AU-DESSUS DES CHAMPS QUI SUIVENT (Marino, 10.09.2026). Le calendrier est
     pose « static », donc DANS le flux du corps defilant de la fenetre modale
     (voir assets/js/demande-offre-champs.js pour la raison : hors de la
     <dialog>, il serait inerte). Sans cote d'empilement, les champs suivants,
     leurs bordures et le pied de la fenetre passaient devant lui. Valeur haute
     mais LOCALE : elle ne joue qu'entre freres a l'interieur de la fenetre, la
     couche modale du navigateur reste au-dessus de tout. Le fait qu'il
     puisse DEBORDER de la fenetre, lui, ne vient pas d'ici : un z-index ne
     fait jamais sortir un enfant d'un ancetre en overflow auto ou hidden.
     C'est l'overflow visible pose le temps de l'ouverture qui le permet, voir
     .fp-offre-corps-deborde et .fp-offre-deborde plus bas
     (11.09.2026). */
  z-index: 60;
}
/* EN-TÊTE DU CALENDRIER (mois et année) NON COUPÉ (Marino, 2026-09-11 : « le
   mois et l'année sont coupés dans le calendrier »). Flatpickr écrit l'année
   dans un <input> et, avec un sélecteur de mois déroulant, le mois dans un
   <select>, tous deux DANS le formulaire : les règles génériques des champs
   de la fenêtre (« .fp-offre-form input, select » plus haut : 44 px de hauteur
   minimale, 12 px de rembourrage vertical, bordure, fond) s'y appliquaient et
   gonflaient l'année, alors que l'en-tête de Flatpickr mesure 34 px et rogne
   ce qui dépasse : le mois, aligné sur cette ligne trop haute, et l'année
   partaient vers le bas et se coupaient. Le calendrier de l'accueil n'a pas
   ce défaut : il ne vit dans aucun formulaire à règles de champ. Ici, ces
   deux contrôles retrouvent la métrique de la librairie ; les couleurs de
   thème posées juste en dessous ne changent pas. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar input,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar select {
  min-height: 0;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  font-size: inherit;
  line-height: inherit;
  transition: none;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar .flatpickr-current-month input.cur-year {
  padding-left: .5ch;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar .flatpickr-monthDropdown-months {
  padding-left: .5ch;
  width: auto;
  appearance: menulist;
  -webkit-appearance: menulist;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar input:focus-visible,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-calendar select:focus-visible {
  border: 0;
  box-shadow: none;
  outline: 2px solid var(--fp-primary);
  outline-offset: 1px;
}
.fp-offre-calendar .flatpickr-months .flatpickr-month,
.fp-offre-calendar .flatpickr-current-month,
.fp-offre-calendar .flatpickr-current-month input.cur-year,
.fp-offre-calendar .flatpickr-monthDropdown-months,
.fp-offre-calendar span.flatpickr-weekday {
  color: var(--fp-secondary);
}
.fp-offre-calendar .flatpickr-prev-month svg,
.fp-offre-calendar .flatpickr-next-month svg {
  fill: var(--fp-secondary);
}
.fp-offre-calendar .flatpickr-day { color: var(--fp-ink); border-radius: var(--fp-radius-sm); }
.fp-offre-calendar .flatpickr-day.flatpickr-disabled,
.fp-offre-calendar .flatpickr-day.prevMonthDay,
.fp-offre-calendar .flatpickr-day.nextMonthDay { color: var(--fp-ink-soft); opacity: .5; }
.fp-offre-calendar .flatpickr-day:hover { background: var(--fp-cream); }
.fp-offre-calendar .flatpickr-day.today { border-color: var(--fp-accent); }
.fp-offre-calendar .flatpickr-day.today:hover,
.fp-offre-calendar .flatpickr-day.today:focus { border-color: var(--fp-accent); background: var(--fp-cream); }
.fp-offre-calendar .flatpickr-day.selected,
.fp-offre-calendar .flatpickr-day.selected:hover,
.fp-offre-calendar .flatpickr-day.selected:focus {
  background: var(--fp-primary); border-color: var(--fp-primary); color: var(--fp-white);
}
.fp-offre-calendar .flatpickr-time input,
.fp-offre-calendar .flatpickr-time .flatpickr-am-pm { color: var(--fp-ink); }

/* --------------------------------------------------------------------------
   COMPTEUR DE DUREE (moins / valeur / plus), voir assets/js/demande-offre-
   champs.js. Le champ reste un <input type="number"> ordinaire (name, bornes
   serveur) : les deux boutons ne sont qu'un raccourci au clic, les fleches du
   clavier restent actives des que le champ a le focus.
   -------------------------------------------------------------------------- */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper input[type="number"] {
  flex: 1 1 auto;
  /* PLANCHER DE LARGEUR (2026-09-11) : la valeur la plus longue possible est
     « 24,5 » (bornes 1 à 24, pas de 0,5) ; 4 caractères plus les 28 px de
     padding horizontal du champ. Quelle que soit la colonne qui le contient,
     le champ ne peut plus descendre sous ce qu'il doit afficher : le
     chiffre après la virgule reste toujours visible. */
  min-width: calc(4ch + 28px);
  text-align: center;
  /* Masque les fleches natives du navigateur : les deux boutons du compteur
     les remplacent visuellement, sans rien retirer au clavier (les fleches
     haut/bas du clavier continuent d'agir sur le champ une fois focalise). */
  -moz-appearance: textfield;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper input[type="number"]::-webkit-outer-spin-button,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid var(--fp-line-strong);
  border-radius: var(--fp-radius-sm);
  background: var(--fp-paper);
  color: var(--fp-ink);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  /* PLUS DE ZOOM AU DOUBLE APPUI (Marino, 2026-09-10 : « empêche le zoom si
     plusieurs clics sur le plus ou le moins »). Deux appuis rapprochés sur un
     bouton sont lus comme un double-tap par les navigateurs mobiles, qui
     zooment. touch-action: manipulation supprime ce geste sur le bouton seul,
     sans toucher au zoom à deux doigts, qui reste disponible partout. La
     sélection de texte est coupée pour la même raison. */
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper-btn:hover:not(:disabled) {
  background: var(--fp-secondary);
  border-color: var(--fp-secondary);
  color: var(--fp-paper);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper-btn:focus-visible {
  outline: none;
  border-color: var(--fp-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fp-primary) 26%, transparent);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper-btn:disabled {
  opacity: .4;
  cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-stepper-btn { transition: none; }
}

/* Une colonne par defaut : a 320 px, deux champs cote a cote seraient
   illisibles. Le passage a deux colonnes se fait plus bas, a 560 px. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}
/* HEURE ET DURÉE, CÔTE À CÔTE (Marino, 2026-09-10, point 2) : la durée reste
   « plus petite » que l'heure dans cette rangée précise, sélecteur à deux
   classes pour l'emporter sur la répartition égale (1fr 1fr) de la règle
   générale ci-dessus, sans dépendre de l'ordre dans la feuille. Une seule
   colonne sous 560 px, comme .fp-form-row. */
@media (min-width: 560px) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-row.fp-offre-row-heure-duree {
    /* HEURE À LA LARGEUR D'UN CHAMP ORDINAIRE (Marino, 2026-09-10 : « fais en
       sorte que le champ soit au maximum large comme le reste, pas plus
       large »). La moitié de la rangée moins la moitié de l'espacement, soit
       exactement ce que mesure un champ des autres rangées à deux colonnes ;
       la durée garde sa largeur réduite à côté, demandée le même jour.
       LARGEUR DE LA DURÉE PORTÉE DE 150 À 200 px (2026-09-11) : à 150 px, les
       deux boutons (2 x 44 px) et leurs espacements (2 x 8 px) laissaient
       46 px au champ, dont 28 px de padding horizontal (.fp-contact-form
       input, main.css) : 18 px de texte, « 4,5 » était coupé après la
       virgule. À 200 px, le champ mesure 96 px, soit 68 px de texte, assez
       pour « 24,5 » en toutes lettres tout en restant nettement plus étroit
       que l'heure. */
    grid-template-columns: calc(50% - 8px) minmax(0, 200px);
  }
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-legend {
  margin: 0;
  font-size: .85rem;
  color: var(--fp-ink-soft);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-envoi {
  align-self: stretch;
  justify-content: center;
  min-height: 48px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-errors {
  background: color-mix(in srgb, var(--fp-danger) 9%, var(--fp-paper));
  border: 1px solid var(--fp-danger);
  border-radius: var(--fp-radius-sm);
  padding: 14px 18px;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-errors-title { margin: 0; font-weight: 700; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-errors ul { margin: 6px 0 0; padding-left: 20px; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-errors li { color: var(--fp-ink); }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-success {
  margin: 0;
  background: color-mix(in srgb, var(--fp-primary) 11%, var(--fp-paper));
  border: 1px solid var(--fp-primary);
  border-radius: var(--fp-radius-sm);
  padding: 18px 20px;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-errors:focus-visible,
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-success:focus-visible {
  outline: 2px solid var(--fp-secondary);
  outline-offset: 3px;
}

/* Pastilles « choix déjà pris en compte » (pré-remplissage depuis la barre de
   réservation de l'accueil). role="status" sur le conteneur : simple
   information, pas une confirmation d'envoi (fp-form-success ci-dessus) ni
   une erreur.

   REVU le 2026-09-10 (Marino, point 3) : PLUS DE PHRASE (« Vos choix sont pris
   en compte : ... Il ne reste que la durée et vos coordonnées. ») ; à la
   place, une pastille PAR CHOIX connu (formule, nombre de personnes, date),
   sans aucun texte d'accompagnement. Voir inc/demande-offre.php,
   fp_demande_offre_formulaire(), pour le détail des pastilles rendues. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-prerempli {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
}
/* MASQUÉ sur les étapes « Coordonnées » et « Explications » (Marino,
   2026-09-10, points 7 et 8 : « on ne doit pas scroller sur cette page »),
   basculé par assets/js/demande-offre.js à chaque changement d'étape. La
   règle [hidden] est INDISPENSABLE : le display:flex ci-dessus l'emporterait
   sinon sur le display:none que le navigateur attache par défaut à l'attribut
   hidden (même piège que .fp-offre-etape[hidden] plus bas dans ce fichier). */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-prerempli[hidden] {
  display: none;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-prerempli-badge {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: var(--fp-pill);
  background: color-mix(in srgb, var(--fp-accent) 20%, var(--fp-paper));
  border: 1px solid var(--fp-accent);
  color: var(--fp-ink);
  font-size: .85rem;
  font-weight: 600;
}

/* --- Les quatre étapes (revue client du 2026-08-20) ----------------------- */
/* DEUX ÉTATS POUR LE MÊME MARKUP, exactement comme le panneau lui-même :
     - sans JavaScript, les quatre groupes s'affichent À LA SUITE et le
       formulaire s'utilise en une seule page (aucune règle ci-dessous ne
       masque quoi que ce soit de son propre chef) ;
     - avec assets/js/demande-offre.js, un seul groupe reste visible, les
       autres portent l'attribut hidden, et le script ajoute l'indicateur
       d'étape ainsi que les boutons « Précédent » et « Suivant ».
   La règle [hidden] ci-dessous n'est pas une précaution de style : elle est
   INDISPENSABLE. Un display posé par une classe l'emporte sur le display:none
   que le navigateur attache à l'attribut hidden ; sans elle, les étapes
   masquées resteraient à l'écran. Même piège pour les boutons de navigation,
   qui sont des .fp-btn (inline-flex). */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-etapes {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-etape {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-etape[hidden] { display: none; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-etape-titre {
  margin: 0;
  font-family: var(--fp-font-heading);
  font-size: 1.25rem;
  line-height: 1.2;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-etape-titre:focus-visible {
  outline: 2px solid var(--fp-primary);
  outline-offset: 3px;
  border-radius: var(--fp-radius-sm);
}

/* Indicateur d'étape : le texte porte l'information (il est annoncé à chaque
   changement), les puces ne sont qu'un repérage visuel. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-txt {
  margin: 0;
  font-size: .85rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--fp-ink-soft);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-puces {
  display: flex;
  align-items: center;
  gap: 6px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-puce {
  display: block;
  width: 22px;
  height: 4px;
  border-radius: 999px;
  background: var(--fp-line-strong);
  transition: background-color .25s ease, width .25s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-puce.is-fait { background: var(--fp-accent); }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-puce.is-actif {
  width: 34px;
  background: var(--fp-primary);
}
@media (prefers-reduced-motion: reduce) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fil-puce { transition: none; }
}

/* Barre de navigation : les deux boutons se partagent la largeur sur téléphone
   (cible tactile de 48 px de haut, bien au-dessus du seuil de 44 px), et se
   rangent à gauche dès que la fenêtre s'élargit. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-nav [hidden] { display: none; }
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-nav .fp-btn {
  flex: 1 1 auto;
  justify-content: center;
  min-height: 48px;
}

/* Accord sur l'usage des informations saisies (dernière étape). L'étiquette
   entière est la cible de la case, et sa hauteur utile dépasse 44 px. Le lien
   vers la page « Protection des données » vit HORS de l'étiquette (voir
   inc/demande-offre.php) : il doit rester un lien, pas une façon de cocher.
   Sélecteur à trois classes (relecture du 2026-08-20) : à deux, la règle
   perdait contre « .fp-offre-form .fp-field { gap: 7px } » et le resserrement
   n'existait pas. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-consent { gap: 4px; }
/* Case en erreur VISIBLE (relecture du 2026-08-20) : les navigateurs ignorent
   border sur une case native, la seule règle aria-invalid du formulaire
   (border-color) n'y montrait donc rien : le visiteur renvoyé à cette étape ne
   voyait aucun champ marqué. Sélecteur à DEUX attributs (type + aria-invalid,
   ajouté le 2026-09-10) : cette règle doit l'emporter sur le contour par
   défaut posé juste en dessous, à spécificité égale sinon, quel que soit
   l'ordre des deux règles dans la feuille. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-consent input[type="checkbox"][aria-invalid="true"] {
  outline: 2px solid var(--fp-danger);
  outline-offset: 2px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-consent-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 44px;
  padding: 5px 0;
  font-weight: 400;
  cursor: pointer;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-offre-consent input[type="checkbox"] {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  min-height: 0;
  margin: 2px 0 0;
  padding: 0;
  accent-color: var(--fp-primary);
  /* CONTOUR VISIBLE À L'ÉTAT DÉCOCHÉ (Marino, 2026-09-10, point 9 : « quand
     elle est décochée, elle est à peine visible »). Même parade que la règle
     d'erreur ci-dessus : un navigateur ignore `border` sur une case native,
     `outline` reste le seul moyen fiable d'un contour net. Même token que la
     bordure des autres champs du formulaire (--fp-line-strong), pour rester
     cohérent avec le reste du formulaire ; visible quel que soit l'état
     (coché ou non), la règle d'erreur au-dessus la remplace en cas de refus. */
  outline: 2px solid var(--fp-line-strong);
  outline-offset: 1px;
  border-radius: 3px;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-consent-txt {
  font-size: .95rem;
  line-height: 1.45;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-consent-lien {
  align-self: flex-start;
  margin-left: 34px;
  font-size: .85rem;
  color: var(--fp-primary);
}

/* --- La fenetre modale ---------------------------------------------------- */
/* La <dialog> est ajoutee au <body> par le script : les classes de corps du
   modele s'appliquent donc bien a elle. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog {
  width: min(100% - 20px, 620px);
  max-width: none;
  max-height: min(90vh, 820px);
  padding: 0;
  border: 0;
  border-radius: var(--fp-radius-lg);
  background: var(--fp-paper);
  color: var(--fp-ink);
  box-shadow: var(--fp-shadow-lg);
  overflow: hidden;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog[open] { display: flex; }
/* Le fond assombri. Deux declarations volontairement : ::backdrop n'herite les
   proprietes personnalisees de son element d'origine que depuis Chrome 122,
   Firefox 118 et Safari 17.4. Sur un navigateur plus ancien, var(--fp-dark)
   serait irresolvable et le fond disparaitrait purement et simplement ; la
   premiere ligne, neutre, garantit alors un voile. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog::backdrop {
  background: rgba(0, 0, 0, .6);
  background: color-mix(in srgb, var(--fp-dark) 78%, transparent);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog-boite {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: min(90vh, 820px);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 16px 12px 20px;
  border-bottom: 1px solid var(--fp-line);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog-titre {
  margin: 0;
  font-family: var(--fp-font-heading);
  font-size: clamp(1.4rem, 5vw, 1.9rem);
  line-height: 1.1;
  color: var(--fp-ink);
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fermer {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--fp-line);
  border-radius: 50%;
  background: var(--fp-paper);
  color: var(--fp-ink);
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fermer:hover {
  background: var(--fp-secondary);
  color: var(--fp-paper);
  border-color: transparent;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-fermer:focus-visible {
  outline: 2px solid var(--fp-primary);
  outline-offset: 2px;
}
/* Defilement INTERNE : neuf champs ne tiennent pas dans 90 vh a 320 px de
   large. Rien n'est jamais coupe, c'est le corps de la fenetre qui defile,
   pas la page derriere. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog-corps {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 18px 20px 24px;
}
/* CALENDRIER OU LISTE OUVERTS : LA FENETRE NE BOUGE PAS, L'ELEMENT DEBORDE
   (Marino, 11.09.2026 : « ca m'agrandit enormement le popup, ca ne devrait
   pas, et le calendrier devrait pouvoir depasser du popup si necessaire, sans
   barre de scroll ou autre dans le popup »). Les deux classes sont posees a
   l'ouverture et retirees a la fermeture par assets/js/demande-offre-champs.js
   (laisserDeborder(), partagee par le calendrier Flatpickr et les panneaux
   des listes deroulantes maison), jamais en dur.

   Elles REMPLACENT la reserve de 360 px de marge basse posee ici le
   10.09.2026 : c'est elle qui allongeait la fenetre d'un coup, et le
   defilement qu'elle rendait possible qui posait une barre. Le calendrier,
   en position absolue sous le champ (mode « static » de Flatpickr), n'est
   plus enferme : le corps cesse de defiler et la fenetre cesse de rogner, il
   se dessine par-dessus le bas de la fenetre et le fond assombri, la <dialog>
   vivant dans la couche superieure du navigateur. Hors de cette parenthese,
   le corps retrouve son defilement interne (etapes longues sur petit ecran)
   et la fenetre son rognage. */
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog-corps.fp-offre-corps-deborde {
  overflow: visible;
}
:is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog.fp-offre-deborde {
  overflow: visible;
}

/* Le fond de page ne defile pas derriere la fenetre. Pose sur <html> par le
   script (classe fp-offre-fige), donc HORS de la portee des classes de corps :
   c'est la seule regle de ce fichier qui ne peut pas etre scopee au modele.
   Sans consequence, la feuille n'est chargee que sur cette page. */
html.fp-offre-fige { overflow: hidden; }

/* Animation d'ouverture, desactivee des que le systeme demande moins de
   mouvement. */
@media (prefers-reduced-motion: no-preference) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-dialog[open] {
    animation: fp-offre-entree .22s var(--fp-anim-ease, ease-out);
  }
  @keyframes fp-offre-entree {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

/* --------------------------------------------------------------------------
   Responsive.
   -------------------------------------------------------------------------- */
@media (min-width: 560px) {
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-form .fp-form-row {
    grid-template-columns: 1fr 1fr;
  }
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-envoi { align-self: flex-start; }
  /* Les boutons d'étape reprennent leur largeur naturelle : c'est sur téléphone
     qu'ils se partagent la ligne pour offrir une cible confortable, pas ici. */
  :is(.page-template-template-evenements, .fp-offre-fenetre) .fp-offre-nav .fp-btn { flex: 0 0 auto; }
}

/* LES DEUX PHOTOS SE CHEVAUCHENT, ET ELLES SONT PAYSAGE (retour client : « une
   passe sur l'autre ok, mais trop vertical la, j'ai mis des images
   horizontales »). La version precedente les posait COTE A COTE en 4/5, donc en
   PORTRAIT : une photo horizontale y etait rognee sur les cotes par le
   object-fit, et la colonne entiere paraissait etroite et haute.

   Composition retenue : la principale occupe toute la largeur de la colonne en
   3/2, la seconde la recouvre en bas, decalee du cote oppose au texte, avec un
   liseré clair qui la detache. Le chevauchement se fait par MARGE NEGATIVE et
   non par positionnement absolu : la colonne garde donc sa hauteur reelle, rien
   ne peut sortir de la section ni recouvrir le texte.

   Photo seule ou panneau vide : pleine largeur, en 3/2 egalement. */
@media (min-width: 600px) {
  .page-template-template-evenements .fp-evo-media {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .page-template-template-evenements .fp-evo-photo--principale { aspect-ratio: 3 / 2; }
  .page-template-template-evenements .fp-evo-photo--seconde {
    aspect-ratio: 16 / 10;
    width: 58%;
    /* Remonte d'un tiers de sa propre hauteur : le recouvrement se voit sans
       jamais masquer le sujet de la photo du dessous. */
    margin-top: clamp(-92px, -7vw, -40px);
    margin-left: auto;
    position: relative;
    z-index: 1;
    /* Liseré de la couleur du fond de section : c'est lui qui fait lire les deux
       photos comme deux plans, et non comme une seule image decoupee. */
    border: 6px solid var(--fp-paper);
    box-shadow: var(--fp-shadow-lg);
  }
  /* L'ancienne bascule « colonne visuelle à gauche du texte, la seconde photo
     déborde du côté opposé » a été retirée d'ici (retour client du
     2026-08-12, sixième chantier, point 1 : voir la note complète sur
     .fp-evo-corps plus bas, qui explique pourquoi la colonne média ne bascule
     plus visuellement de côté). */
  .page-template-template-evenements .fp-evo-media.is-solo .fp-evo-photo--principale,
  .page-template-template-evenements .fp-evo-media.is-vide .fp-evo-media-vide {
    aspect-ratio: 3 / 2;
  }
}

/* Respiration : la seconde photo flotte tres legerement, et se recale au survol
   de la section. Enferme dans « no-preference » : absent par defaut pour qui
   demande moins d'animation, aucune regle a annuler ailleurs. */
@media (prefers-reduced-motion: no-preference) and (min-width: 600px) {
  .page-template-template-evenements .fp-evo-photo--seconde {
    transition: transform .5s var(--fp-anim-ease), box-shadow .5s var(--fp-anim-ease);
  }
  .page-template-template-evenements .fp-evo-grid:hover .fp-evo-photo--seconde,
  .page-template-template-evenements .fp-evo-grid:focus-within .fp-evo-photo--seconde {
    transform: translateY(-8px) scale(1.015);
    box-shadow: 0 22px 44px -18px color-mix(in srgb, var(--fp-dark) 45%, transparent);
  }
}

/* Deux colonnes. LA COLONNE DE TEXTE (.fp-evo-corps) N'INVERSE PLUS JAMAIS DE
   CÔTÉ (retour client du 2026-08-12, sixième chantier, point 1, réitéré à
   trois reprises : « la zone avec le titre, elle est centrée... la zone de
   texte est vraiment centrée, c'est plus fin que le menu... elle n'est
   absolument pas de la largeur du contenu standard »).

   CAUSE RÉELLE, TROUVÉE EN MESURANT LA GÉOMÉTRIE RÉELLE (voir le rapport du
   chantier pour le calcul complet) : .fp-evo--media-gauche posait `order: -1`
   sur .fp-evo-media SEUL. En CSS Grid, l'ORDRE MODIFIE L'AUTO-PLACEMENT DANS
   LES PISTES, pas seulement l'affichage : avec order:-1, .fp-evo-media (photo)
   était placé dans la PREMIÈRE piste (.92fr, celle qui commence pile au bord
   gauche de .fp-wrap) et .fp-evo-corps (texte) se retrouvait DANS LA SECONDE
   (1.08fr), donc physiquement décalé vers la droite d'une pleine largeur de
   piste. Mesuré au banc (Playwright, 1920 px) : le texte des sections
   « Anniversaires » et « EVG et EVJF » (les deux seules à porter
   fp-evo--media-gauche) démarrait à x=941 px sur une page de x=310 à x=1610,
   c'est-à-dire quasi EXACTEMENT au milieu de la largeur de contenu (x=960) :
   la sensation de « titre centré, plus étroit que le menu » n'était donc pas
   une impression, c'est un calcul de géométrie qui la confirme au pixel près.
   Les sections « droite » (Entreprises, Événements privés), elles, n'ont
   jamais eu ce défaut : leur texte, jamais réordonné, restait déjà dans la
   première piste, au bord gauche, comme le menu.

   CORRECTIF : la photo ne bascule plus de côté, sur AUCUNE des quatre
   sections ; .fp-evo-corps reste TOUJOURS dans la première piste (.92fr),
   flush à gauche de .fp-wrap, EXACTEMENT comme le menu et comme toute autre
   tête de section du site. C'est un renoncement délibéré à l'alternance
   gauche/droite de la maquette, au profit d'une position de texte fiable et
   cohérente : demandé trois fois de suite par la cliente, la position du
   texte prime sur cette variation esthétique. Seul le petit repère chiffré en
   filigrane (.fp-evo-num) garde encore sa bascule de côté (fp-evo--media-gauche
   .fp-evo-num, plus haut dans ce fichier) : lui seul est purement décoratif,
   absolument sans effet sur la position du texte. */
@media (min-width: 900px) {
  .page-template-template-evenements .fp-evo-grid {
    /* La colonne visuelle passe devant : les photos sont paysage et se
       chevauchent, elles ont besoin de largeur pour que ca se lise. */
    grid-template-columns: .92fr 1.08fr;
    align-items: center;
  }
}

/* ==========================================================================
   ANIMATIONS RÉDUITES : SECOND FILET

   Le script de tête (fp_evenements_prives_anti_flash_marqueur) refuse déjà de
   poser html.fp-e-anim quand prefers-reduced-motion vaut reduce ; ce bloc est
   un second filet, au cas où une bascule système survenue ENTRE le premier
   rendu et l'exécution du script laisserait la classe posée. Il annule alors
   TOUS les états masqués ci-dessus d'un coup : rien ne reste caché.
   evenements.js se coupe entièrement dès sa première ligne sous la même
   préférence (aucun fondu de fond, aucune bascule d'encre, rail sans script).
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.fp-e-anim .page-template-template-evenements [data-fp-clip],
  html.fp-e-anim .page-template-template-evenements [data-fp-mask] {
    clip-path: none;
    transform: none;
  }
  html.fp-e-anim .page-template-template-evenements [data-fp-zoom],
  html.fp-e-anim .page-template-template-evenements [data-fp-drift] {
    opacity: 1;
    transform: none;
  }
  html.fp-e-anim .page-template-template-evenements [data-fp-row] .fp-evo-puce,
  html.fp-e-anim .page-template-template-evenements [data-fp-row] .fp-evo-item-txt {
    opacity: 1;
    transform: none;
  }
  html.fp-e-anim .page-template-template-evenements [data-fp-hero-sur],
  html.fp-e-anim .page-template-template-evenements [data-fp-hero-suite] {
    opacity: 1;
    transform: none;
  }
  html.fp-e-anim .page-template-template-evenements [data-fp-carte] {
    transform: none;
    border-radius: var(--fp-radius-lg);
  }
  .page-template-template-evenements .fp-evo-num,
  .page-template-template-evenements.fp-e-fond-anime::before,
  .page-template-template-evenements .fp-e-rail,
  .page-template-template-evenements .fp-e-rail-nom,
  .page-template-template-evenements .fp-e-rail-point,
  .page-template-template-evenements .fp-ehero-point {
    transition: none;
  }
}

/* ==========================================================================
   PASSE TABLETTE (2026-08-24) : bande 721 px à 779 px, et rien d'autre.

   Règle bornée des deux côtés. Le palier mobile de cette feuille est
   max-width: 720px : sous 721 px, rien de ce bloc n'est évalué, la plage
   validée par la cliente ne bouge pas d'un pixel. Le plafond à 779 px est
   collé au palier @media (min-width: 780px) déjà présent plus haut : au-delà,
   c'est ce palier existant qui pilote, on ne le double pas.
   ========================================================================== */

/* CARTE « DEMANDER UNE OFFRE » : DEUX COLONNES DÈS 721 px.

   Défaut mesuré au banc à 768 px : la carte du bas de page reste sur une
   seule colonne (texte, puis un pavé de média de 748 px de large sous lui),
   parce que son passage à deux colonnes est déclaré à partir de 780 px.
   Douze pixels séparent donc l'iPad en portrait, la tablette la plus
   répandue, de la mise en page prévue pour lui : le pavé de média y devient
   plus large (748 px) que sur un poste de travail (456 px), pour un bloc
   purement illustratif.

   On abaisse le seuil à 721 px en RECOPIANT à l'identique les deux
   déclarations du palier de 780 px, sans en modifier une seule : à 780 px et
   au-delà, la page rend exactement ce qu'elle rendait. À 721 px la colonne de
   texte mesure environ 375 px et le média 330 px, deux valeurs confortables.
   Les rayons du média suivent sa place dans la grille (bloc « Coins BAS de la
   carte » plus haut), ils n'ont rien à recalculer. */
@media (min-width: 721px) and (max-width: 779px) {
  .page-template-template-evenements .fp-evo-cta-carte { grid-template-columns: 1.15fr .85fr; align-items: stretch; }
  .page-template-template-evenements .fp-evo-cta-media { min-height: 100%; }
}

/* Réservation directe des prestations B2B (loges, conférence), sous le bouton
   principal de la carte : volontairement discrète, elle ne doit pas concurrencer
   « Demander une offre », qui reste l'action attendue de la plupart des
   visiteurs. Liens séparés d'une puce, repliés proprement sur petit écran. */
.page-template-template-evenements .fp-evo-cta-directs {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  margin: 14px 0 0;
  font-size: .86rem;
  line-height: 1.5;
}
.page-template-template-evenements .fp-evo-cta-directs-intro {
  color: color-mix(in srgb, var(--fp-white) 72%, transparent);
}
.page-template-template-evenements .fp-evo-cta-direct {
  color: var(--fp-white);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.page-template-template-evenements .fp-evo-cta-direct:hover,
.page-template-template-evenements .fp-evo-cta-direct:focus-visible {
  color: var(--fp-accent);
}
.page-template-template-evenements .fp-evo-cta-direct + .fp-evo-cta-direct::before {
  content: "·";
  margin-right: 12px;
  color: color-mix(in srgb, var(--fp-white) 50%, transparent);
  text-decoration: none;
  display: inline-block;
}

/* ==========================================================================
   CTA RÉSERVATION DIRECTE (fp-evd), zone fp-blk-evenement-cta-direct.

   Demande de Marino du 2026-09-06 : un CTA « stylé », visible, à MI-PAGE (pas
   en fin de page comme la carte CTA Réservation ci-dessus), pour réserver
   directement une loge ou la salle de conférence, deux prestations Apex
   retirées du widget grand public (voir fp_render_evenement_cta_direct,
   inc/evenements-prives.php). Les petits liens texte « Réservation directe :
   ... » de la carte CTA Réservation de fin de page restent en place, cette
   section-ci est un ajout, pas un remplacement.

   MÊME FAMILLE DE COMPOSANTS que « CTA RÉSERVATION » juste au-dessus : icon-
   box (sur-titre). Le bouton texte a cédé la place à deux vraies cartes-photo
   (voir la note V4 plus bas), la tuile ENTIÈRE reste la cible cliquable.

   V4 (2026-09-07, retour de Marino, remplace le fond sombre du 2026-09-06 et
   les filets clairs du V2 du même jour) : LA SECTION EST BLANCHE ET FIXE,
   elle ne participe plus au changement de couleur au défilement de la page.
   Fond posé en dur (voir la règle .fp-evd ci-dessous), avec une déclaration
   plus spécifique que la transparence générale de [data-fp-sect] sous
   .fp-e-fond-anime : EXACTEMENT le même procédé que la section Anniversaires
   (voir la note « ANNIVERSAIRES : TOUJOURS OPAQUE » plus haut dans ce
   fichier), choisi plutôt qu'une exclusion dans assets/js/evenements.js, hors
   périmètre de ce chantier. data-fp-mode passe à "clair"
   (inc/evenements-prives.php) : la traversée de cette section n'allume plus
   le mode sombre du reste de la page (rail, icon-box…). Plus de bande vert
   foncé, plus de filets clairs : la SÉPARATION NETTE avec les sections
   voisines (qui, elles, continuent de changer dynamiquement : vert clair
   avant « Entreprises et séminaires », vert plus foncé vers « EVG et EVJF »)
   vient du contraste franc entre le blanc fixe et leurs teintes, sans le
   moindre trait décoratif de plus. Titre et sur-titre passent au vert foncé
   (--fp-secondary-dark), le paragraphe à l'encre atténuée des sections
   claires (--fp-ink-soft, même convention que .fp-evo-prose p plus haut) :
   les trois combinaisons dépassent largement le seuil AA de 4,5:1 sur blanc
   (~14,6:1 pour le vert foncé, ~6,9:1 pour l'encre atténuée). La texture
   topographique statique (.fp-evd-topo, pensée pour les phases sombres) est
   neutralisée ici, sans objet sur un fond blanc.

   V4, CARTES (retour de Marino du 2026-09-07, remplace les pilules allongées
   du 2026-09-06) : DEUX VRAIES CARTES HAUTES plutôt que deux lignes de
   bouton. ~380 px de haut sur ordinateur (proportion proche de 3/2), deux
   colonnes à partir de 900 px, empilées à 260 px de haut en dessous. Photo de
   fond pleine carte (bloc image de la zone, INCHANGÉ, voir
   fp_zone_image_url_class dans inc/evenements-prives.php) sous un voile en
   dégradé PLUS FORT EN BAS, là où vit le texte (~78 %) : calculé AA au pire
   cas (une photo blanche) à cet endroit précis (~7,3:1). EN HAUT, le voile
   est au contraire plus clair (~40 %), mais aucune exigence de contraste de
   texte n'y vit : seule l'icône, purement décorative (déjà posée sur son
   propre rond blanc translucide), occupe cette zone. Sans
   photo déposée (état actuel, en attente des photos de la cliente) : fond
   teal (--fp-primary) avec le motif em-plan en filigrane, LA MÊME mise en
   page ; --fp-primary derrière du blanc plein donne déjà ~4,85:1, AA, que la
   trace d'em-plan à basse opacité n'entame pas de façon sensible. Composition
   : les trois enfants du lien (markup PHP inchangé) passent en POSITION
   ABSOLUE sur la carte : l'icône en haut à gauche dans un rond blanc
   translucide, le titre (grand, Bebas, blanc) et le sous-texte (blanc plein)
   en bas à gauche, la flèche en bas à droite dans un rond, qui glisse de 4 px
   au survol comme avant. La carte entière reste un seul lien (nom accessible
   = titre + sous-texte, icône et flèche aria-hidden, déjà le cas). Zoom lent
   de la photo au survol conservé (1,08, 1,2 s ease-out) ; le voile, lui, ne
   change plus au survol (simplification du 2026-09-06, plus nécessaire avec
   cette mise en page). :focus-visible net (contour vert foncé, lisible sur
   les deux fonds possibles). Reduced motion : ni zoom, ni élévation, ni
   glissement de la flèche.
   -------------------------------------------------------------------------- */
.page-template-template-evenements .fp-evd {
  position: relative;
  overflow: hidden;
  background-color: var(--fp-white);
  /* Sur-titre (icon-box) en vert foncé plutôt que le teal par défaut des
     sections claires (table de contexte .fp-s-light, main.css) : une
     déclaration portée par cette section, plus proche, l'emporte sans
     toucher au composant partagé. */
  --fp-ibox-fg: var(--fp-secondary-dark);
  --fp-ibox-line: var(--fp-secondary-dark);
  --fp-ibox-pastille: color-mix(in srgb, var(--fp-secondary-dark) 12%, var(--fp-white));
}
/* FOND FIXE, même sous le fond de page animé : sélecteur doublé
   ([data-fp-sect].fp-evd), même technique que la règle ANNIVERSAIRES plus
   haut, pour battre la transparence générale de [data-fp-sect] sous
   .fp-e-fond-anime quel que soit l'ordre des règles dans ce fichier. */
.page-template-template-evenements.fp-e-fond-anime [data-fp-sect].fp-evd {
  background-color: var(--fp-white);
}
.page-template-template-evenements .fp-evd-topo { opacity: 0; }
.page-template-template-evenements .fp-evd-inner { position: relative; z-index: 1; }

/* DEUX COLONNES dès 900 px (Marino, 2026-09-07 : « colonne de gauche contient
   le texte, cartes l'une sur l'autre dans la colonne de droite, plus
   petites ») : sur-titre, titre et texte à gauche, centrés verticalement
   sur la pile des deux cartes à droite. Une seule colonne en dessous. */
.page-template-template-evenements .fp-evd-carte {
  display: flex;
  flex-direction: column;
  gap: clamp(26px, 5vw, 40px);
}
@media (min-width: 900px) {
  .page-template-template-evenements .fp-evd-carte {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items: center;
    gap: clamp(32px, 5vw, 64px);
  }
}

.page-template-template-evenements .fp-evd-mots { max-width: 56ch; }
.page-template-template-evenements .fp-evd-titre {
  max-width: 22ch;
  overflow: hidden;
  padding-bottom: .08em;
  color: var(--fp-secondary-dark);
}
.page-template-template-evenements .fp-evd-texte {
  margin: 14px 0 0;
  max-width: 56ch;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--fp-ink-soft);
}

/* Les deux cartes EMPILÉES à toute largeur (Marino, 2026-09-07, second
   retour : plus de côte à côte, la pile occupe la colonne de droite). */
.page-template-template-evenements .fp-evd-tuiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

/* --------------------------------------------------------------------------
   DEUX VRAIES CARTES HAUTES (voir la note V4 en tête de ce bloc pour le
   détail des choix). Le markup PHP ne change pas (icône, mots, flèche
   restent trois enfants directs du lien) : seule la mise en page devient
   absolue.
   -------------------------------------------------------------------------- */
.page-template-template-evenements .fp-evd-tuile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--fp-radius-lg);
  min-height: 260px;
  background: var(--fp-primary);
  color: var(--fp-paper);
  text-decoration: none;
  transition: transform 1.2s ease-out, box-shadow 1.2s ease-out;
}
/* Cartes PLUS PETITES (même retour) : 380 px avant, 210 px maintenant, la
   pile de deux restant à hauteur de lecture du texte de gauche. */
@media (min-width: 900px) {
  .page-template-template-evenements .fp-evd-tuile { min-height: 210px; }
}
.page-template-template-evenements .fp-evd-tuile:hover,
.page-template-template-evenements .fp-evd-tuile:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--fp-shadow-lg);
}
.page-template-template-evenements .fp-evd-tuile:focus-visible {
  outline: 2px solid var(--fp-secondary-dark);
  outline-offset: 3px;
}

/* Fond : motif em-plan en filigrane SANS photo, photo pleine carte AVEC (même
   ::before pour les deux, la seconde règle sert de repli tant qu'aucune
   photo n'est déposée : voir fp_zone_image_url_class, inc/evenements-prives.php). */
.page-template-template-evenements .fp-evd-tuile::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url('../img/em-plan.svg');
  background-size: min(480px, 150%);
  background-position: center;
  background-repeat: no-repeat;
  opacity: .16;
  pointer-events: none;
}
.page-template-template-evenements .fp-evd-tuile.has-photo::before {
  background-image: var(--fp-evd-photo);
  background-size: cover;
  background-position: center;
  opacity: 1;
  transform: scale(1);
  transition: transform 1.2s ease-out;
}
.page-template-template-evenements .fp-evd-tuile.has-photo:hover::before,
.page-template-template-evenements .fp-evd-tuile.has-photo:focus-visible::before {
  transform: scale(1.08);
}
/* Voile dégradé, SEULEMENT avec photo (le fond teal seul offre déjà ~4,85:1,
   voir la note de tête) : plus fort en bas pour le texte (~78 %), léger en
   haut pour l'icône (~40 %). Ne change plus au survol (simplification du
   2026-09-06, plus nécessaire avec cette mise en page : seule la photo zoome). */
.page-template-template-evenements .fp-evd-tuile.has-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--fp-dark) 40%, transparent) 0%,
    color-mix(in srgb, var(--fp-dark) 78%, transparent) 100%
  );
}

/* Icône : rond blanc translucide, en haut à gauche. */
.page-template-template-evenements .fp-evd-tuile-icone {
  position: absolute;
  z-index: 2;
  top: 20px;
  left: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--fp-paper) 22%, transparent);
  color: var(--fp-paper);
}
.page-template-template-evenements .fp-evd-tuile-icone svg { width: 24px; height: 24px; }

/* Titre et sous-texte : en bas à gauche, la largeur s'arrête avant le rond de
   la flèche (right calé sur sa zone : 20 px de marge + 44 px de rond + 16 px
   de respiration). HAUTEUR BORNÉE PAR LE HAUT (top: 88px, relecture Opus du
   2026-09-07) : un libellé long combiné à un sous-texte long chevauchait
   l'icône à 390 px (mesuré 5 px de recouvrement) tant que le bloc n'avait
   qu'un bottom et grandissait librement vers le haut. 88px laisse 16px sous
   l'icône (top: 20px, 52px de rond) ; justify-content: flex-end garde le
   contenu collé au bas de cette zone désormais bornée, comme avant pour un
   texte court. */
.page-template-template-evenements .fp-evd-tuile-mots {
  position: absolute;
  z-index: 2;
  top: 88px;
  left: 20px;
  right: 80px;
  bottom: 20px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
}
.page-template-template-evenements .fp-evd-tuile-label {
  font-family: var(--fp-font-heading);
  font-size: 1.5rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  line-height: 1.05;
  color: var(--fp-paper);
  overflow-wrap: break-word;
}
.page-template-template-evenements .fp-evd-tuile-sous {
  font-size: .92rem;
  color: var(--fp-paper);
}

/* Flèche : rond translucide, en bas à droite, glisse de 4 px au survol. */
.page-template-template-evenements .fp-evd-tuile-fleche {
  position: absolute;
  z-index: 2;
  right: 20px;
  bottom: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--fp-paper) 20%, transparent);
  color: var(--fp-paper);
  transition: transform .22s ease;
}
.page-template-template-evenements .fp-evd-tuile:hover .fp-evd-tuile-fleche,
.page-template-template-evenements .fp-evd-tuile:focus-visible .fp-evd-tuile-fleche {
  transform: translateX(4px);
}

@media (prefers-reduced-motion: reduce) {
  .page-template-template-evenements .fp-evd-tuile,
  .page-template-template-evenements .fp-evd-tuile-fleche,
  .page-template-template-evenements .fp-evd-tuile.has-photo::before {
    transition: none;
  }
  .page-template-template-evenements .fp-evd-tuile:hover,
  .page-template-template-evenements .fp-evd-tuile:focus-visible,
  .page-template-template-evenements .fp-evd-tuile:hover .fp-evd-tuile-fleche,
  .page-template-template-evenements .fp-evd-tuile:focus-visible .fp-evd-tuile-fleche,
  .page-template-template-evenements .fp-evd-tuile.has-photo:hover::before,
  .page-template-template-evenements .fp-evd-tuile.has-photo:focus-visible::before {
    transform: none;
  }
}

/* PASSE MOBILE DE LA PAGE ÉVÉNEMENTS (Marino, 2026-09-10). Borné sous 720px.
   1. Le texte du héro (pas le titre, pas la pilule) descend d'un cran :
      16.8 à 15px, il tenait trop de place sous le titre sur un petit écran.
   2. Plus d'air entre les sections d'événement : les photos vivent en bas de
      chaque section et la suivante commençait 64px plus bas, si bien qu'on
      ne savait plus à quelle section elles appartenaient. Le padding
      vertical passe de 64 à 96px, la respiration lit la coupure. */
@media (max-width: 720px) {
  .page-template-template-evenements .fp-ehero-lead { font-size: 15px; line-height: 1.5; }
  .page-template-template-evenements .fp-evo { padding-top: 96px; padding-bottom: 96px; }
}
