/* =====================================================================
   Événements — hero, blocs modulaires, cases à gratter, popup, bannière.
   Chargé uniquement quand un événement est en cours (ou sur sa page).
   Tout est exprimé avec les variables du site : la couleur dominante de
   l'événement (injectée dans le <head>) repeint donc ces composants aussi.
   ===================================================================== */

/* Nos composants s'ouvrent/se ferment avec l'attribut [hidden]. Or une règle de
   display posée sur la CLASSE l'emporte sur le display:none du navigateur : sans
   cette ligne, `el.hidden = true` laisserait le formulaire et la grille du
   compte à rebours parfaitement visibles. Tout ce qu'on masque en JS est listé ici. */
.evPopup[hidden], .evMailBody[hidden], .evMailResult[hidden], .evScratchHint[hidden],
.evScratchError[hidden], .evScratchProgress[hidden], .evLeaderboard[hidden],
.evMailForm[hidden], .evPopupForm[hidden] { display: none !important; }

/* ---------- Hero ---------- */
.evHero {
  position: relative;
  padding: clamp(48px, 9vw, 96px) 0 clamp(32px, 6vw, 64px);
  text-align: center;
}
/* Couverture : l'image occupe tout le haut de la page et porte le titre, la
   date et le statut. Un voile assombri du bas vers le haut garantit la
   lisibilité quelle que soit la photo — sans lui, un visuel clair rend le
   titre blanc illisible (et un visuel sombre, le titre foncé). */
/* Bloc de tête : il CONTIENT le fil d'Ariane et le bandeau, donc l'image
   s'arrête exactement où le bandeau s'arrête. Un calque de hauteur fixe
   débordait sur le contenu de la page (intro, consigne du jeu posées sur la
   photo). L'ornement, lui, est masqué sur cette page. */
.evTop { position: relative; }
.evTop--cover { background-size: cover; background-position: center; }
.evTop--cover::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(16,10,22,.45) 0%, rgba(16,10,22,.5) 45%, rgba(16,10,22,.8) 100%);
}
.evTop > * { position: relative; z-index: 1; }
.evCrumbs { padding-top: var(--sp-4); }
/* Pas d'ornement sur la page d'un événement : l'image de couverture joue ce rôle. */
body[data-route="event"] .pageOrnament { display: none; }
/* Sur l'image, le fil d'Ariane doit rester lisible. */
.evTop--cover .breadcrumb a,
.evTop--cover .breadcrumb span { color: rgba(255,255,255,.92); }
.evTop--cover .breadcrumb a:hover { color: #fff; }
.evHero--cover {
  min-height: clamp(180px, 24vw, 300px);
  display: flex; align-items: flex-end;
  padding-top: clamp(40px, 8vw, 90px);
}
/* Préfixées par .evTop--cover : à spécificité égale, `.evHero h1` (déclarée
   plus bas) l'emportait par l'ordre et le titre reprenait la couleur du thème
   — rouge sur la photo au lieu de blanc. */
.evTop--cover .evHero h1 { color: #fff; text-shadow: 0 2px 18px rgba(0,0,0,.35); }
.evTop--cover .evHeroDates { color: rgba(255,255,255,.9); }
.evTop--cover .evHeroFlag { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.35); color: #fff; }
.evTop--cover .evHeroInner { color: #fff; }
.evHeroInner { position: relative; z-index: 1; }
.evHero h1 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5.4vw, 3.4rem);
  line-height: 1.08; margin: .2em 0 .3em; color: var(--brand-hover);
}
.evHeroDates {
  margin: 0; text-transform: uppercase; letter-spacing: .14em;
  font-size: .78rem; color: var(--fg-3);
}
.evHeroFlag {
  display: inline-block; margin-top: 18px; padding: 6px 14px;
  border: 1px solid var(--border); border-radius: var(--r-full);
  background: var(--surface); color: var(--fg-3); font-size: .9rem;
}

/* ---------- Blocs ----------
   La page s'organise sur UN axe central : le bandeau, l'introduction et le jeu
   partagent le même alignement. Avec un bandeau centré et un corps aligné à
   gauche, la page paraissait bancale et inachevée. */
.evBody { padding: clamp(40px, 6vw, 72px) 0 var(--sp-16); }
.evBlock { margin: clamp(48px, 7vw, 80px) 0 0; }
.evBlock:first-child { margin-top: 0; }
.evBlockTitle {
  font-family: var(--font-display); font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  margin: 0 0 var(--sp-6); color: var(--brand-hover);
}
.evLead { margin: 0 auto var(--sp-6); color: var(--fg-2); max-width: 68ch; }
.evIntro { max-width: 68ch; margin: 0 auto; text-align: center; font-size: 1.05rem; }
.evBlock--scratch { text-align: center; }
.evBlock--mail { max-width: 720px; margin-left: auto; margin-right: auto; }

/* ---------- Choix du genre ---------- */
.evGenres { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--sp-2); margin-bottom: var(--sp-5); }
/* Un seul genre disponible : le sélecteur n'a rien à sélectionner. */
.evGenres--single { display: none; }
.evGenresLabel { color: var(--fg-3); margin-right: var(--sp-2); }
.evGenre {
  font: inherit; cursor: pointer; padding: 8px 16px; border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface); color: var(--fg-2);
  transition: transform .18s var(--ease), background-color .18s, color .18s, border-color .18s;
}
.evGenre:hover { transform: translateY(-1px); border-color: var(--brand); color: var(--brand-hover); }
.evGenre.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }
/* La consigne et le compteur encadrent le jeu : ils ont besoin d'air des DEUX
   côtés, sinon la phrase colle aux pastilles de genre et le compteur colle à la
   dernière rangée de cartes. */
.evScratchHint {
  color: var(--fg-3); max-width: 46ch;
  margin: 0 auto var(--sp-10); line-height: 1.6;
}
.evScratchProgress {
  margin: var(--sp-10) 0 0; color: var(--fg-3);
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
/* Le tirage a échoué : la grille garde ses cartes, ce mot explique pourquoi
   elles n'ont pas changé. */
.evScratchError {
  max-width: 46ch; margin: 0 auto var(--sp-10);
  color: var(--fg-2); line-height: 1.6;
}

/* ---------- Grille de cases à gratter ---------- */
/* `auto-fit` + largeur PLAFONNÉE + centrage : quand le vivier ne fournit que
   deux ou trois livres, les cartes restent à leur taille et se centrent, au lieu
   de se coller en haut à gauche d'une grille de cinq colonnes vides (ou de
   s'étirer sur toute la largeur). La grille supporte 1 comme 24 cartes. */
.evScratchGrid {
  display: grid; gap: var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(150px, 190px));
  justify-content: center;
  max-width: 940px; margin: 0 auto;
}
/* Changement de genre : les cartes en place restent affichées, en retrait, le
   temps de la requête. Les faire disparaître raccourcissait la page et
   déplaçait le défilement du visiteur. */
.evScratchGrid.is-loading { opacity: .45; pointer-events: none; transition: opacity .15s var(--ease); }
/* Format 2/3 : celui d'une couverture de livre. La carte accueille donc l'image
   entière presque sans marge, et il reste de la hauteur pour le pied. */
.evCard {
  --evTilt: 0deg;
  position: relative; aspect-ratio: 2 / 3; border-radius: var(--r-5);
  overflow: hidden; background: var(--surface);
  border: 1px solid var(--border-soft); box-shadow: var(--shadow-sm);
  transform: rotate(var(--evTilt));
  transition: box-shadow .3s var(--ease);
}
/* Cartes POSÉES, pas imprimées : un travers de un à deux degrés et un décalage
   vertical d'une case sur deux. Le damier au cordeau ressemblait à une planche
   d'usine ; là, on dirait des cases étalées sur une table.
   Le cycle du travers est en 7 et celui du décalage en 2, exprès : sur une
   grille de 4 colonnes, un cycle de 4 aurait recréé des colonnes identiques. */
.evScratchGrid .evCard:nth-child(7n+1) { --evTilt: -1.6deg; }
.evScratchGrid .evCard:nth-child(7n+2) { --evTilt: 1.1deg; }
.evScratchGrid .evCard:nth-child(7n+3) { --evTilt: -.7deg; }
.evScratchGrid .evCard:nth-child(7n+4) { --evTilt: 1.8deg; }
.evScratchGrid .evCard:nth-child(7n+5) { --evTilt: -1.2deg; }
.evScratchGrid .evCard:nth-child(7n+6) { --evTilt: .6deg; }
.evScratchGrid .evCard:nth-child(7n+7) { --evTilt: -1.9deg; }
.evScratchGrid .evCard:nth-child(2n) { margin-top: clamp(10px, 2.2vw, 22px); }
/* La couverture EST le fond de la carte : elle occupe tout le cadre, le titre
   et les liens se posent dessus, en bas. Le texte reste lisible parce que le
   voile appartient au PIED et grandit donc avec lui : il est quasi opaque
   partout où passe du texte, quel que soit le nombre de lignes du titre. Un
   dégradé posé sur toute la carte, lui, laissait le blanc se perdre sur une
   couverture claire dès que le titre débordait. */
.evCardInner {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.evCardFoot {
  position: relative; flex: none; padding-top: 34px;
  background: linear-gradient(180deg, rgba(10,6,16,0) 0, rgba(10,6,16,.74) 34px, rgba(10,6,16,.94) 100%);
}
.evCardCover { position: absolute; inset: 0; overflow: hidden; }
.evCardCover img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Copie floutée et agrandie : elle remplit les côtés que la couverture entière
   laisse vides, sans jamais rogner le titre du livre. */
.evCardShotBg { object-fit: cover; filter: blur(16px) saturate(1.25) brightness(.72); transform: scale(1.2); }
.evCardShot { object-fit: contain; }
.evCardNoCover {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-size: 3.4rem; color: #fff;
  background: var(--brand);
}
.evCardMeta {
  color: #fff; padding: 0 10px 6px; text-align: center;
  text-shadow: 0 1px 6px rgba(0,0,0,.6);
}
/* Un titre à rallonge mangerait la couverture : deux lignes, puis les points
   de suspension. Le titre entier reste accessible sur la fiche du livre. */
.evCardMeta b {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; font-family: var(--font-display); font-size: .95rem; line-height: 1.25;
}
.evCardMeta i {
  display: block; font-style: normal; font-size: .78rem; color: rgba(255,255,255,.85);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.evCardLinks {
  display: flex; gap: 6px; flex-wrap: wrap;
  justify-content: center; padding: 0 8px 10px;
}
.evCardLinks a {
  font-size: .74rem; padding: 3px 10px; border-radius: var(--r-full);
  background: rgba(255,255,255,.94); color: var(--brand-hover); text-decoration: none;
}
.evCardLinks a:hover { background: #fff; }
.evCardCanvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  cursor: grab; touch-action: none; /* sinon le doigt fait défiler la page au lieu de gratter */
}
/* Tant que le vernis n'est pas peint (onglet en arrière-plan, mise en page pas
   encore stabilisée), le livre reste masqué : sinon la carte s'afficherait en
   clair avant d'être recouverte. On ne peut PAS mettre un fond sur le canvas
   pour ça — il apparaîtrait sous les pixels grattés à la place du livre. */
.evCard.is-covered .evCardInner { visibility: hidden; }
.evCard.is-revealed { box-shadow: var(--shadow-md); }
.evCard.is-revealed .evCardCanvas { pointer-events: none; }
/* Chemin SANS GSAP : la révélation est jouée par ces trois règles. Avec GSAP
   (classe posée par event.js), c'est le tween qui pilote le vernis, la
   couverture et le soulèvement de la carte — les deux sur la même propriété se
   marcheraient dessus, la transition CSS rejouant l'écriture inline du tween.
   L'éclat, lui, vit sur un pseudo-élément que GSAP ne touche pas : il reste en
   CSS dans les deux cas. */
.evScratch:not(.is-gsap) .evCard.is-revealed { transform: rotate(var(--evTilt)) translateY(-3px); }
.evScratch:not(.is-gsap) .evCard.is-revealed .evCardCanvas { opacity: 0; transition: opacity .45s var(--ease); }
.evScratch:not(.is-gsap) .evCard.is-revealed .evCardInner { animation: evPop .5s var(--ease) both; }
/* Éclat au moment de la révélation : un halo qui s'ouvre puis disparaît. */
.evCard.is-revealed::after {
  content: ""; position: absolute; inset: -30%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.9), transparent 55%);
  animation: evFlash .7s var(--ease) both;
}
@keyframes evPop { from { transform: scale(.9); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes evFlash { from { opacity: .95; transform: scale(.4); } to { opacity: 0; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .evCard.is-revealed .evCardInner, .evCard.is-revealed::after { animation: none; }
  .evCard.is-revealed::after { content: none; }
}

/* ---------- Inscription (mailbonjour) ---------- */
.evMail {
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--r-6); padding: var(--sp-8); box-shadow: var(--shadow-sm);
}
.evMailLock { margin: 0; color: var(--fg-3); text-align: center; }
.evMailForm { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.evMailForm input[type=email] {
  flex: 1 1 240px; font: inherit; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: var(--r-4); background: var(--surface-2); color: var(--fg);
}
.evMailForm input[type=email]:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.evMailConsent { margin: var(--sp-3) 0 0; font-size: .84rem; color: var(--fg-3); }
.evMailResult { margin-top: var(--sp-4); }
.evMailResult p { margin: 0 0 var(--sp-3); }
.evReferral { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.evReferral input {
  flex: 1 1 260px; font: inherit; padding: 10px 12px; border-radius: var(--r-4);
  border: 1px dashed var(--border); background: var(--surface-2); color: var(--fg-2);
}
.evLeaderboard { margin-top: var(--sp-5); }
.evLeaderboard h3 { font-family: var(--font-display); margin: 0 0 var(--sp-2); }
.evLeaderboard ol { margin: 0; padding-left: 1.2em; color: var(--fg-2); }
.evLeaderboard li { margin: 2px 0; }

/* ---------- Bannière ----------
   Emplacements HORIZONTAUX (accueil, catégories, générateurs, articles) : le
   visuel garde son ratio mais sa hauteur est bornée à celle d'un leaderboard.
   Sans ce plafond, un visuel carré de 728 px de large occupe 728 px de HAUT —
   un demi-écran de bannière sur chaque page. Un vrai 728x90 n'est pas touché.
   La card « entre les cards » (.adSlot--native) n'est pas concernée : elle est
   déjà cadrée par .cardShot. */
.adSlot--event:not(.adSlot--native):not(.adSlot--bar) img { max-height: 120px; width: auto; }

/* ---------- Le reste : aucun style propre ----------
   Elle emprunte les classes des créas maison de la régie (.adSlot--house,
   .adSlot--native, .card/.cardShot/.cardBody), donc elle hérite du même rendu
   dans tous les emplacements. Rien à redéfinir ici : un style local finirait
   par diverger de celui des pubs. */

/* ---------- Popup bas-droite ---------- */
.evPopup {
  position: fixed; right: 18px; bottom: 18px; z-index: 60; width: min(340px, calc(100vw - 36px));
  opacity: 0; transform: translateY(14px);
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.evPopup.is-in { opacity: 1; transform: none; }
.evPopupInner {
  position: relative; border-radius: var(--r-6); overflow: hidden;
  background: var(--brand-hover) center/cover no-repeat;
  box-shadow: var(--shadow-lg); color: #fff;
}
.evPopupInner::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(20,14,26,.58), rgba(20,14,26,.9));
}
.evPopupBody { position: relative; padding: var(--sp-6); }
.evPopupBody h3 { font-family: var(--font-display); font-size: 1.25rem; margin: 0 0 6px; color: #fff; }
.evPopupBody p { margin: 0 0 var(--sp-4); font-size: .92rem; color: rgba(255,255,255,.9); }
.evPopupClose {
  position: absolute; top: 6px; right: 8px; z-index: 2; width: 32px; height: 32px;
  font-size: 1.4rem; line-height: 1; cursor: pointer; color: #fff;
  background: transparent; border: 0; border-radius: var(--r-full);
}
.evPopupClose:hover { background: rgba(255,255,255,.16); }
.evPopupForm { display: flex; gap: 6px; }
.evPopupForm input[type=email] {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: .9rem; padding: 9px 11px;
  border-radius: var(--r-3); border: 1px solid rgba(255,255,255,.4);
  background: rgba(255,255,255,.94); color: var(--fg);
}
.evPopup .evMailResult { position: relative; padding: 0 var(--sp-6) var(--sp-5); font-size: .88rem; color: #fff; }
@media (max-width: 520px) { .evPopup { right: 10px; left: 10px; bottom: 10px; width: auto; } }
@media (prefers-reduced-motion: reduce) { .evPopup { transition: none; } }
