/* ════════════════════════════════════════════════════════════════════
   evalab : Couche vitrine
   ════════════════════════════════════════════════════════════════════

   Le vocabulaire visuel des pages publiques : sections, eyebrows,
   cartes, bento, ruban de témoignages, FAQ, bandeau CTA, doodles, et
   la couche d'animation.

   Dépend de ev-tokens.css, qui doit être chargé AVANT.

   ── Pourquoi un fichier et pas du <style> par page ─────────────────
   Chaque page refaite embarquait jusqu'à 594 lignes de CSS en ligne, et
   recopiait le même bloc `:root` à chaque fois. Résultat : trois
   définitions divergentes de la même carte, et rien de mutualisé entre
   les pages. Ici, une classe définie une fois sert partout, et le
   fichier est mis en cache par le navigateur au lieu d'être renvoyé
   dans chaque réponse HTML.

   ── Préfixe ───────────────────────────────────────────────────────
   Tout est préfixé `ev-`. La vitrine charge encore style.css (294 Ko de
   template) et Bootstrap : sans préfixe, `.card`, `.btn` ou `.container`
   entreraient en collision.
   ════════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════════
   1. Socle
   ════════════════════════════════════════════════════════════════════ */

/* Défilement doux confié au navigateur plutôt qu'à un gestionnaire de
   clic : il respecte alors seul `prefers-reduced-motion`, et l'ancre
   reste dans l'URL, donc le lien demeure partageable. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.ev-page {
  background: var(--ev-bg);
  color: var(--ev-text);
  font-family: var(--ev-ff-body);
  font-feature-settings: "ss01", "cv11";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.ev-page h1,
.ev-page h2,
.ev-page h3,
.ev-page h4,
.ev-page h5,
.ev-page h6 {
  font-family: var(--ev-ff-head);
  letter-spacing: -.02em;
  color: var(--ev-text);
  margin: 0;
}

.ev-page p { margin: 0; }

/* Largeur de lecture unique. 1248px comme la référence : au-delà, les
   lignes de texte deviennent trop longues pour être confortables. */
.ev-wrap {
  width: 100%;
  max-width: 1248px;
  margin-inline: auto;
  padding-inline: 24px;
}
@media (min-width: 640px) { .ev-wrap { padding-inline: 40px; } }

/* Rythme vertical des sections : trois hauteurs, pas plus. Une page qui
   alterne des respirations arbitraires perd sa régularité. */
.ev-sec    { padding-block: 64px; }
.ev-sec-lg { padding-block: 80px; }
.ev-sec-sm { padding-block: 40px; }
@media (min-width: 640px) {
  .ev-sec    { padding-block: 96px; }
  .ev-sec-lg { padding-block: 120px; }
  .ev-sec-sm { padding-block: 56px; }
}

/* Dégagement sous l'en-tête.

   `.main-header` est un bloc de hauteur NULLE : sa barre (`.header-inner`,
   79 px) est positionnée en surimpression. Rien ne réserve donc cette
   hauteur dans le flux, et le premier bloc de chaque page passe dessous.

   La règle vise le premier enfant de `.ev-page` plutôt que d'ajouter une
   marge dans chaque vue : c'est une contrainte du gabarit, pas une
   décision de mise en page, et elle vaut pour les 51 pages publiques.
   `:not(.ev-photohero)` excepte le bandeau photo, conçu pour passer SOUS
   l'en-tête : c'est tout l'intérêt d'une image pleine hauteur. */
.ev-page > *:first-child:not(.ev-photohero) { padding-block-start: 104px; }
@media (min-width: 992px) {
  .ev-page > *:first-child:not(.ev-photohero) { padding-block-start: 120px; }
}

/* Alternance des fonds : c'est elle qui découpe la page en chapitres. */
.ev-on-bg      { background: var(--ev-bg); }
.ev-on-surface { background: var(--ev-surface); }
.ev-on-ink     { background: var(--ev-ink); color: #eef2f5; }
.ev-on-ink h1, .ev-on-ink h2, .ev-on-ink h3 { color: #fff; }

/* ════════════════════════════════════════════════════════════════════
   2. Titres de section
   ════════════════════════════════════════════════════════════════════ */

/* L'eyebrow porte le terracotta. C'est son emploi principal : une
   étiquette courte, capitales, très espacée, au-dessus du titre.
   --ev-accent-deep et non --ev-accent : 7,1:1 contre 3,15:1.

   Aucune décoration : pas de trait, pas de pastille, pas de puce. La
   capitale et l'interlettrage suffisent à distinguer la ligne du titre
   qui la suit, et un tiret répété au-dessus de chaque section finit par
   se lire comme un tic plutôt que comme un signe. */
.ev-eyebrow {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ev-accent-deep);
  margin: 0 0 12px;
}
.ev-eyebrow.is-center { text-align: center; }

.ev-h2 {
  font-size: clamp(30px, 3.4vw, 44px);
  font-weight: 700;
  line-height: 1.08;
}
.ev-h3 { font-size: clamp(20px, 1.6vw, 23px); font-weight: 700; line-height: 1.25; }

.ev-lead {
  font-size: 16px;
  line-height: 1.7;
  color: var(--ev-text-muted);
  max-width: 62ch;
}
.ev-body {
  font-size: 15px;
  line-height: 1.7;
  color: var(--ev-text-muted);
}

/* Le mot mis en avant dans un titre. Le terracotta plein ne passe qu'à
   3,15:1 : réservé aux tailles d'affichage (≥ 30px gras), où le seuil
   WCAG tombe à 3:1. Jamais dans un paragraphe. */
.ev-hl        { color: var(--ev-accent); }
.ev-hl-blue   { color: var(--ev-blue); }

/* Soulignement tracé à la main, posé sous un mot du titre. */
.ev-underline { position: relative; white-space: nowrap; }
.ev-underline::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -.16em;
  height: .28em;
  background: var(--ev-accent);
  opacity: .28;
  border-radius: 999px;
}

/* ════════════════════════════════════════════════════════════════════
   3. Boutons
   ════════════════════════════════════════════════════════════════════ */

.ev-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding-inline: 24px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--ev-ff-body);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none !important;
  transition: background-color .2s var(--ev-ease),
              border-color .2s var(--ev-ease),
              color .2s var(--ev-ease),
              transform .2s var(--ev-ease);
}
.ev-btn:hover { transform: translateY(-1px); text-decoration: none !important; }
.ev-btn:active { transform: translateY(0); }
.ev-btn:focus-visible {
  outline: 2px solid var(--ev-blue);
  outline-offset: 2px;
}
.ev-btn-sm { height: 40px; padding-inline: 18px; font-size: 14px; }
.ev-btn-lg { height: 54px; padding-inline: 30px; font-size: 16px; }

.ev-btn-primary { background: var(--ev-blue); color: var(--ev-on-blue) !important; }
.ev-btn-primary:hover { background: var(--ev-blue-hover); color: var(--ev-on-blue) !important; }

/* Texte encre et non blanc : blanc sur terracotta ne donne que 3,15:1,
   sous le seuil lisible. L'encre remonte à 5,76:1. */
.ev-btn-accent { background: var(--ev-accent); color: var(--ev-on-accent) !important; }
.ev-btn-accent:hover { background: var(--ev-accent-hover); color: var(--ev-on-accent) !important; }

.ev-btn-outline {
  background: var(--ev-surface);
  border-color: var(--ev-border);
  color: var(--ev-text) !important;
}
.ev-btn-outline:hover { background: var(--ev-surface-offset); color: var(--ev-text) !important; }

.ev-btn-ink { background: var(--ev-ink); color: #fff !important; }
.ev-btn-ink:hover { background: #142635; color: #fff !important; }

/* Sur fond sombre (bandeau CTA, hero encre). */
.ev-btn-onink {
  background: transparent;
  border-color: rgba(255,255,255,.22);
  color: #fff !important;
}
.ev-btn-onink:hover { background: rgba(255,255,255,.1); color: #fff !important; }

/* Lien-flèche : la flèche avance au survol. */
.ev-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ev-accent-deep) !important;
  text-decoration: none !important;
}
.ev-link svg, .ev-link i { transition: transform .25s var(--ev-ease); }
.ev-link:hover svg, .ev-link:hover i { transform: translateX(4px); }
.ev-link-blue { color: var(--ev-blue) !important; }
.ev-link-text { color: var(--ev-text) !important; }

/* ════════════════════════════════════════════════════════════════════
   4. Cartes
   ════════════════════════════════════════════════════════════════════ */

.ev-card {
  position: relative;
  background: var(--ev-surface);
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-xl);
  padding: 32px;
}
.ev-card-sm { padding: 24px; border-radius: var(--ev-radius-lg); }
/* Carte « posée » : un cran tonal au-dessus de la surface, sans bordure
   marquée.

   Le fond est --ev-surface-offset et NON --ev-bg : sur une section
   `.ev-on-bg`, c'est le cas du bento de l'accueil, une carte en
   --ev-bg a exactement la couleur de son fond et disparaît. La bordure
   est conservée, atténuée, comme filet de sécurité : une carte doit
   rester délimitée quel que soit le fond sur lequel on la pose. */
.ev-card-flat { background: var(--ev-surface-offset); border-color: var(--ev-divider); }
.ev-card-ink  { background: var(--ev-ink); border-color: transparent; color: #cfd8e0; }
.ev-card-ink h3, .ev-card-ink h4 { color: #fff; }
.ev-card-blue { background: var(--ev-blue-soft); border-color: var(--ev-blue-highlight); }

/* Une carte `--ev-surface` posée sur une section `--ev-surface` a
   exactement la couleur de son fond : en thème clair la bordure la
   sauve encore, en thème sombre elle disparaît complètement. Sur ces
   sections, la carte descend donc d'un cran tonal. Le sens s'inverse
   tout seul entre les thèmes, puisque les deux tokens s'inversent. */
.ev-on-surface .ev-card:not(.ev-card-ink):not(.ev-card-blue) { background: var(--ev-bg); }

/* Le soulèvement au survol. Une seule définition pour toutes les
   sections, sinon elles divergent au fil des pages. */
.ev-lift {
  transition: transform .35s var(--ev-ease),
              box-shadow .35s var(--ev-ease),
              border-color .35s var(--ev-ease);
}
.ev-lift:hover {
  transform: translateY(-6px);
  box-shadow: var(--ev-shadow-lift);
  border-color: var(--ev-accent-highlight);
}
/* L'icône de la carte suit le mouvement, en plus discret. */
.ev-lift .ev-pop { transition: transform .35s var(--ev-ease); }
.ev-lift:hover .ev-pop { transform: scale(1.12) rotate(-3deg); }

/* Image qui respire, sans déborder de son cadre arrondi. */
.ev-zoom { overflow: hidden; }
.ev-zoom img { transition: transform .6s var(--ev-ease); will-change: transform; }
.ev-zoom:hover img { transform: scale(1.05); }

/* Pastille d'icône : le carré arrondi posé en tête de carte. */
.ev-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--ev-radius-md);
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  flex: none;
}
.ev-tile-blue { background: var(--ev-blue-soft); color: var(--ev-blue); }
.ev-tile-ink  { background: rgba(255,255,255,.1); color: #fff; }

/* Pastille ronde numérotée, pour les étapes. */
.ev-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  font-family: var(--ev-ff-head);
  font-size: 15px;
  font-weight: 700;
  flex: none;
}

/* Badge / puce d'information. */
.ev-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border: 1px solid var(--ev-border);
  border-radius: 999px;
  background: var(--ev-surface);
  font-size: 13px;
  font-weight: 700;
  color: var(--ev-text);
}
.ev-badge-onink {
  border-color: rgba(255,255,255,.18);
  background: rgba(255,255,255,.07);
  color: #fff;
}

/* Pile d'avatars de preuve sociale.

   Le recouvrement doit rester PLUS PETIT que la marge autour des
   initiales, sinon la pastille suivante mange la dernière lettre de la
   précédente et la pile a l'air cassée. Ici : pastille de 38 px,
   initiales larges d'environ 22 px donc 8 px de marge de chaque côté,
   recouvrement de 10 px : la lettre reste entière à 2 px près.

   Les z-index décroissants placent la PREMIÈRE pastille au-dessus : sans
   eux, l'ordre du document met la dernière devant, et c'est elle qu'on
   lit en entier au lieu de la première. */
.ev-avatars { display: flex; }
.ev-avatars > * { width: 38px; height: 38px; border: 2px solid var(--ev-surface); }
.ev-avatars > * + * { margin-inline-start: -10px; }
.ev-avatars > :nth-child(1) { z-index: 4; }
.ev-avatars > :nth-child(2) { z-index: 3; }
.ev-avatars > :nth-child(3) { z-index: 2; }
.ev-avatars > :nth-child(4) { z-index: 1; }

/* ════════════════════════════════════════════════════════════════════
   5. Grilles
   ════════════════════════════════════════════════════════════════════ */

.ev-grid { display: grid; gap: 24px; }
.ev-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ev-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ev-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Le bento : une cellule large, une haute, le reste en appoint. C'est
   l'irrégularité qui fait le motif : une grille régulière de six cartes
   identiques est exactement ce qu'on cherche à éviter. */
.ev-bento { display: grid; gap: 24px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ev-bento-wide { grid-column: span 2; }
.ev-bento-tall { grid-row: span 2; }

/* Deux colonnes texte / visuel. `.is-reverse` inverse l'ordre visuel
   sans toucher à l'ordre du document : le texte reste lu en premier par
   un lecteur d'écran et sur mobile. */
.ev-split {
  display: grid;
  gap: 48px;
  align-items: center;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.ev-split.is-reverse > :first-child { order: 2; }

/* Colonne latérale étroite + contenu large (titre de section à gauche,
   FAQ ou liste à droite).

   Cette variante existe parce que l'écrire en ligne
   (`style="grid-template-columns:340px 1fr"`) l'emporterait sur les
   media queries plus bas : un style en ligne bat toujours une feuille,
   quelle que soit la requête média. La grille resterait donc figée à
   deux colonnes sur téléphone, avec une colonne de 340 px sur un écran
   de 375. C'est le genre de casse qu'on ne voit pas sans tester. */
.ev-split-aside {
  display: grid;
  gap: 64px;
  align-items: start;
  grid-template-columns: 340px minmax(0, 1fr);
}

/* Variante « contenu d'abord » : la colonne large passe à gauche et
   l'encadré à droite.

   Elle inverse les LARGEURS sans toucher à l'ordre du balisage. C'est
   voulu : la page d'un sujet doit lire le résumé avant les métadonnées,
   et sur écran étroit la grille retombe sur une seule colonne, où seul
   l'ordre du DOM décide. Écrire l'encadré en premier pour obtenir la
   bonne largeur, comme le font les autres pages, ferait donc remonter
   « Porté par / Domaine / Spécialité » au-dessus du résumé sur mobile. */
.ev-split-aside.is-reverse {
  grid-template-columns: minmax(0, 1fr) 340px;
}

@media (max-width: 991px) {
  .ev-grid-3, .ev-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ev-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ev-bento-wide { grid-column: span 2; }
  .ev-bento-tall { grid-row: auto; }
  .ev-split { grid-template-columns: 1fr; gap: 36px; }
  .ev-split-aside { grid-template-columns: 1fr; gap: 32px; }
  /* `.is-reverse` (deux classes) l'emportait sur la règle ci-dessus : la
     fiche d'un sujet restait sur deux colonnes sur téléphone. */
  .ev-split-aside.is-reverse { grid-template-columns: 1fr; }
  .ev-split.is-reverse > :first-child { order: 0; }
}
@media (max-width: 639px) {
  .ev-grid { gap: 16px; }
  .ev-grid-2, .ev-grid-3, .ev-grid-4,
  .ev-bento { grid-template-columns: 1fr; gap: 16px; }
  .ev-bento-wide { grid-column: auto; }
  .ev-card { padding: 24px; }
  /* Purement décoratifs, et leurs décalages négatifs provoquent un
     défilement horizontal sur écran étroit. */
  .ev-doodle { display: none; }
}

/* ════════════════════════════════════════════════════════════════════
   6. Doodles et décor
   ════════════════════════════════════════════════════════════════════ */

/* Les formes dessinées débordent volontairement de leur cadre : c'est
   ce débordement qui casse la rigueur des cartes. Elles n'ont aucune
   valeur informative : toujours aria-hidden côté balisage. */
.ev-doodle {
  position: absolute;
  pointer-events: none;
  z-index: 1;
}
.ev-doodle-accent { color: var(--ev-accent); }
.ev-doodle-blue   { color: var(--ev-blue); }

/* Le conteneur d'un visuel à doodles ne doit PAS masquer son
   débordement, sinon les formes sont rognées. C'est le cadre intérieur
   qui porte l'arrondi et le masquage. */
.ev-visual { position: relative; }
.ev-visual-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--ev-radius-2xl);
  background: var(--ev-blue-soft);
}
.ev-visual-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Carte flottante posée en débord d'un visuel. */
.ev-floatcard {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-radius: var(--ev-radius-lg);
  background: var(--ev-surface);
  box-shadow: var(--ev-shadow-deep);
  z-index: 2;
}
@media (max-width: 639px) { .ev-floatcard { display: none; } }

/* Filigrane : un tracé de marque surdimensionné en fond de section. */
.ev-watermark {
  position: absolute;
  pointer-events: none;
  color: var(--ev-blue-highlight);
  opacity: .5;
  z-index: 0;
}
.ev-rel { position: relative; z-index: 2; }

/* ════════════════════════════════════════════════════════════════════
   7. Ruban de témoignages
   ════════════════════════════════════════════════════════════════════
   La piste contient la liste deux fois et se translate de -50 % : au
   rebouclage, le second exemplaire est exactement à la place du
   premier, donc la reprise est invisible. Animation CSS et non minuteur
   JS : pas de saut d'image au retour d'onglet, et le navigateur suspend
   l'animation seul quand l'onglet passe à l'arrière-plan.
   ════════════════════════════════════════════════════════════════════ */

.ev-marquee {
  overflow: hidden;
  /* Les cartes s'effacent sur les bords au lieu d'être coupées net. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ev-marquee-track {
  display: flex;
  gap: 24px;
  width: max-content;
  animation: ev-marquee var(--ev-marquee-duration, 46s) linear infinite;
}
@keyframes ev-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* Survol, toucher ou focus clavier : le ruban s'arrête où il est, pour
   qu'on puisse lire une carte en entier. */
.ev-marquee:hover .ev-marquee-track,
.ev-marquee:focus-within .ev-marquee-track { animation-play-state: paused; }

/* Second rang à contresens : deux rubans qui vont dans le même sens
   donnent une impression de bloc, en sens inverse ils se répondent. */
.ev-marquee-track.is-reverse { animation-direction: reverse; }

.ev-testi {
  width: 340px;
  flex: none;
  background: var(--ev-surface);
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-xl);
  padding: 28px;
  text-align: left;
}
.ev-testi-quote { font-size: 15px; line-height: 1.65; color: var(--ev-text-muted); }
.ev-testi-who { display: flex; align-items: center; gap: 12px; margin-top: 22px; }
.ev-testi-av {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  flex: none;
}

/* ════════════════════════════════════════════════════════════════════
   8. FAQ
   ════════════════════════════════════════════════════════════════════
   Un <details> natif : pliage sans JavaScript, accessible au clavier et
   ouvrable par la recherche du navigateur (Ctrl+F trouve le texte replié
   sur les moteurs récents).
   ════════════════════════════════════════════════════════════════════ */

.ev-faq { border-top: 1px solid var(--ev-divider); }
.ev-faq-item { border-bottom: 1px solid var(--ev-divider); }
.ev-faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--ev-ff-head);
  font-size: 17px;
  font-weight: 700;
  color: var(--ev-text);
}
.ev-faq-item > summary::-webkit-details-marker { display: none; }
.ev-faq-item > summary:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 4px; }
.ev-faq-sign {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  font-size: 18px;
  line-height: 1;
  transition: transform .3s var(--ev-ease);
}
.ev-faq-item[open] .ev-faq-sign { transform: rotate(45deg); }
.ev-faq-answer { padding-bottom: 22px; font-size: 15px; line-height: 1.7; color: var(--ev-text-muted); }

/* ════════════════════════════════════════════════════════════════════
   9. Bandeau CTA
   ════════════════════════════════════════════════════════════════════ */

.ev-cta {
  position: relative;
  overflow: hidden;
  border-radius: var(--ev-radius-2xl);
  background: var(--ev-ink);
  padding: 64px 32px;
  text-align: center;
  color: #fff;
}
@media (min-width: 640px) { .ev-cta { padding: 72px 64px; } }
/* Anneaux décoratifs : ils donnent du relief au rectangle sans y poser
   d'image à télécharger. */
.ev-cta-ring {
  position: absolute;
  border-radius: 999px;
  pointer-events: none;
}
.ev-cta-ring.r1 { inset-block-start: -180px; inset-inline-start: -160px; width: 420px; height: 420px; background: rgba(255,255,255,.05); }
.ev-cta-ring.r2 { inset-block-start: -145px; inset-inline-start: -110px; width: 340px; height: 340px; border: 1px solid rgba(255,255,255,.08); }
.ev-cta-ring.r3 { inset-block-end: -210px; inset-inline-end: -175px; width: 460px; height: 460px; background: rgba(255,255,255,.045); }
.ev-cta-ring.r4 { inset-block-start: 48px; inset-inline-end: 40px; width: 140px; height: 140px; border: 2px solid rgba(217,119,66,.5); }

/* ════════════════════════════════════════════════════════════════════
   10. Bandeau de tête des pages secondaires
   ════════════════════════════════════════════════════════════════════ */

.ev-hero {
  position: relative;
  background: var(--ev-surface);
  padding-block: 72px 56px;
  overflow: hidden;
}
.ev-hero-title {
  font-size: clamp(34px, 5vw, 58px);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -.03em;
}

/* Variante photo pleine largeur. */
.ev-photohero { position: relative; overflow: hidden; min-height: 380px; display: flex; align-items: flex-end; }
.ev-photohero > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ev-photohero::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(10,23,34,.82), rgba(10,23,34,.34) 45%, rgba(10,23,34,.12));
}
.ev-photohero > .ev-wrap { position: relative; z-index: 2; padding-block: 48px; }
.ev-photohero h1, .ev-photohero p { color: #fff; }
/* Sur photo, le terracotta ne passe pas : l'eyebrow repasse en blanc. */
.ev-photohero .ev-eyebrow { color: #fff; }

/* ════════════════════════════════════════════════════════════════════
   11. Bandeau de logos
   ════════════════════════════════════════════════════════════════════ */

.ev-logos { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 28px 56px; }
.ev-logos img {
  height: 34px;
  width: auto;
  opacity: .5;
  /* Des logos partenaires aux couleurs disparates cassent la ligne.
     Désaturés au repos, ils reprennent leur couleur au survol. */
  filter: grayscale(1);
  transition: opacity .3s var(--ev-ease), filter .3s var(--ev-ease);
}
.ev-logos img:hover { opacity: 1; filter: grayscale(0); }
/* Le thème sombre écrase les logos foncés sur fond foncé. */
:root[data-ev-theme="dark"] .ev-logos img { filter: grayscale(1) invert(1) brightness(1.6); }

/* ════════════════════════════════════════════════════════════════════
   11 bis. Onglets
   ════════════════════════════════════════════════════════════════════
   Employés sur /plateform pour montrer quatre écrans du produit sans
   empiler quatre sections identiques.

   Les panneaux inactifs sont masqués par `hidden`, pas par une classe :
   l'attribut retire réellement le contenu de l'arbre d'accessibilité,
   là où `display:none` posé par une classe dépend du CSS. Si la feuille
   ne charge pas, le balisage reste correct.
   ════════════════════════════════════════════════════════════════════ */

.ev-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 5px;
  border: 1px solid var(--ev-divider);
  border-radius: 999px;
  background: var(--ev-surface);
}
.ev-tab {
  padding: 10px 20px;
  border: 0;
  border-radius: 999px;
  background: none;
  font-family: var(--ev-ff-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--ev-text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .2s var(--ev-ease), color .2s var(--ev-ease);
}
.ev-tab:hover { background: var(--ev-surface-offset); color: var(--ev-text); }
.ev-tab[aria-selected="true"] { background: var(--ev-ink); color: #fff; }
.ev-tab:focus-visible { outline: 2px solid var(--ev-accent); outline-offset: 2px; }

/* Le panneau qui vient d'apparaître entre en fondu : sans cela, le
   changement d'onglet est un saut sec. */
.ev-tabpanel[hidden] { display: none; }
.ev-tabpanel { animation: ev-tabin .35s var(--ev-ease) both; }
@keyframes ev-tabin {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ev-tabpanel { animation: none; }
}

/* Cadre de capture d'écran : la barre à trois pastilles signale « ceci
   est une vraie fenêtre d'application » sans avoir à l'écrire. */
.ev-shot {
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-lg);
  overflow: hidden;
  background: var(--ev-surface);
  box-shadow: var(--ev-shadow-lift);
}
.ev-shot-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 11px 14px;
  border-block-end: 1px solid var(--ev-divider);
  background: var(--ev-surface-offset);
}
.ev-shot-bar span {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--ev-border);
  flex: none;
}
.ev-shot img { display: block; width: 100%; height: auto; }

/* ════════════════════════════════════════════════════════════════════
   11 ter. Maquettes d'application
   ════════════════════════════════════════════════════════════════════
   Représentations de l'interface, dessinées en CSS.

   ── Pourquoi pas des captures ─────────────────────────────────────
   Les quatre captures qui occupaient cette place étaient inutilisables :
   filigrane « Activer Windows » sur trois d'entre elles, tableaux vides,
   un diagramme de Gantt illustrant la création d'un site web sur une
   plateforme de recherche scientifique, deux chartes graphiques
   abandonnées, et le nom complet avec la photo d'une personne réelle
   exposés sur une page publique.

   Dessinées, elles sont nettes à toute densité d'écran, suivent le mode
   sombre et les tokens de marque, ne pèsent aucun octet de
   téléchargement, et ne peuvent contenir ni donnée personnelle ni
   filigrane d'un système non activé.

   ── À remplacer ───────────────────────────────────────────────────
   Par de vraies captures dès qu'il en existe de propres : compte de
   démonstration, données de recherche crédibles, charte actuelle,
   système activé. Une vraie capture vaudra toujours mieux qu'un dessin.
   ════════════════════════════════════════════════════════════════════ */

.ev-mock {
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-lg);
  overflow: hidden;
  background: var(--ev-surface);
  box-shadow: var(--ev-shadow-lift);
  font-size: 11px;
  line-height: 1.4;
  /* Aucune information n'est portée par ces maquettes : le texte qu'elles
     contiennent est illustratif et ne doit pas être lu à voix haute. */
  user-select: none;
}

.ev-mock-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 13px;
  border-block-end: 1px solid var(--ev-divider);
  background: var(--ev-surface-offset);
}
.ev-mock-bar i {
  width: 8px; height: 8px;
  border-radius: 999px;
  background: var(--ev-border);
  flex: none;
}
.ev-mock-url {
  margin-inline-start: 10px;
  font-size: 10px;
  color: var(--ev-text-faint);
  letter-spacing: .01em;
}

.ev-mock-body { display: grid; grid-template-columns: 128px minmax(0, 1fr); min-height: 268px; }

.ev-mock-side {
  padding: 14px 10px;
  border-inline-end: 1px solid var(--ev-divider);
  background: var(--ev-surface-2);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.ev-mock-nav {
  display: flex;
  white-space: nowrap;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border-radius: var(--ev-radius-sm);
  color: var(--ev-text-muted);
  font-weight: 600;
}
.ev-mock-nav.is-on { background: var(--ev-blue-soft); color: var(--ev-blue); }
.ev-mock-nav::before {
  content: "";
  width: 12px; height: 12px;
  border-radius: 3px;
  background: currentColor;
  opacity: .35;
  flex: none;
}

.ev-mock-main { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.ev-mock-h { font-family: var(--ev-ff-head); font-size: 13px; font-weight: 700; color: var(--ev-text); }

/* ── Tuiles de chiffres ───────────────────────────────────────── */
.ev-mock-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.ev-mock-tile {
  padding: 10px;
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-sm);
  background: var(--ev-surface);
}
.ev-mock-tile b { display: block; font-family: var(--ev-ff-head); font-size: 17px; color: var(--ev-text); }
.ev-mock-tile span { color: var(--ev-text-faint); font-size: 10px; }

/* ── Barres d'avancement ──────────────────────────────────────── */
.ev-mock-row { display: grid; grid-template-columns: minmax(0, 1fr) 84px 26px; align-items: center; gap: 10px; }
.ev-mock-row > span:first-child { color: var(--ev-text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-mock-track { display: block; height: 5px; border-radius: 999px; background: var(--ev-surface-offset); overflow: hidden; }
/* `display:block` est indispensable : le remplissage est un <span>, donc
   inline par défaut, et un élément inline ignore `height` et `width`. La
   barre restait vide. Le conteneur, lui, est blocifié par la grille
   parente, ce qui masquait le problème. */
.ev-mock-fill { display: block; height: 100%; border-radius: 999px; background: var(--ev-blue); }
.ev-mock-fill.is-accent { background: var(--ev-accent); }
.ev-mock-fill.is-ok { background: var(--ev-success); }
.ev-mock-row > span:last-child { color: var(--ev-text-faint); text-align: end; font-size: 10px; }

/* ── Gantt ────────────────────────────────────────────────────── */
.ev-mock-gantt { display: flex; flex-direction: column; gap: 7px; }
.ev-mock-gantt-head { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; color: var(--ev-text-faint); font-size: 9px; }
.ev-mock-gantt-row { display: grid; grid-template-columns: 78px minmax(0, 1fr); align-items: center; gap: 8px; }
.ev-mock-gantt-row > span { color: var(--ev-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 10px; }
.ev-mock-lane { display: block; position: relative; height: 15px; border-radius: 4px; background: var(--ev-surface-offset); }
.ev-mock-bar-item {
  position: absolute; inset-block: 0;
  border-radius: 4px;
  background: var(--ev-blue);
}
.ev-mock-bar-item.is-accent { background: var(--ev-accent); }
.ev-mock-bar-item.is-ghost { background: var(--ev-blue-highlight); }

/* ── Kanban ───────────────────────────────────────────────────── */
.ev-mock-kanban { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.ev-mock-col { display: flex; flex-direction: column; gap: 6px; }
.ev-mock-col > b { color: var(--ev-text-faint); font-size: 9px; text-transform: uppercase; letter-spacing: .08em; }
.ev-mock-ticket {
  padding: 8px;
  border: 1px solid var(--ev-divider);
  border-radius: 6px;
  background: var(--ev-surface);
  color: var(--ev-text);
  font-size: 10px;
  line-height: 1.35;
}
.ev-mock-ticket em { display: block; margin-block-start: 5px; font-style: normal; color: var(--ev-text-faint); font-size: 9px; }

/* ── Documents ────────────────────────────────────────────────── */
.ev-mock-files { display: flex; flex-direction: column; gap: 6px; }
.ev-mock-file {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px;
  padding: 8px 9px;
  border: 1px solid var(--ev-divider);
  border-radius: 6px;
  background: var(--ev-surface);
}
.ev-mock-file i {
  width: 22px; height: 22px;
  border-radius: 5px;
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  display: grid; place-items: center;
  font-size: 8px; font-weight: 700; font-style: normal;
}
.ev-mock-file i.is-blue { background: var(--ev-blue-soft); color: var(--ev-blue); }
.ev-mock-file > span { color: var(--ev-text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-mock-tag {
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--ev-surface-offset);
  color: var(--ev-text-faint);
  font-size: 9px;
  white-space: nowrap;
}

/* Sur écran étroit la colonne latérale disparaît : elle ne porte aucune
   information, et 116 px pris sur 340 rendraient le contenu illisible. */
@media (max-width: 767px) {
  .ev-mock-body { grid-template-columns: 1fr; }
  .ev-mock-side { display: none; }
  .ev-mock-tiles { grid-template-columns: repeat(2, 1fr); }
}

/* ════════════════════════════════════════════════════════════════════
   11 quater. Tarifs
   ════════════════════════════════════════════════════════════════════ */

.ev-plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; align-items: stretch; }

.ev-plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 32px 28px;
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-xl);
  background: var(--ev-surface);
}

/* La formule mise en avant se distingue par une bordure de marque et une
   ombre, PAS par une hauteur différente : décaler une carte casse
   l'alignement des prix, qui sont précisément ce qu'on vient comparer. */
.ev-plan.is-featured {
  border-color: var(--ev-accent);
  box-shadow: var(--ev-shadow-lift);
}

.ev-plan-flag {
  position: absolute;
  inset-block-start: -13px;
  inset-inline-start: 28px;
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--ev-accent);
  color: var(--ev-ink);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
}

.ev-plan-name {
  font-family: var(--ev-ff-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ev-text-muted);
}
.ev-plan-price {
  font-family: var(--ev-ff-head);
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--ev-text);
  margin-block-start: 12px;
  line-height: 1.1;
}
.ev-plan-unit { font-size: 13px; font-weight: 500; color: var(--ev-text-faint); }
.ev-plan-desc { font-size: 14px; line-height: 1.6; color: var(--ev-text-muted); margin-block-start: 10px; }

.ev-plan-list { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 11px; }
.ev-plan-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ev-text);
}
.ev-plan-list svg { flex: none; margin-block-start: 2px; color: var(--ev-accent-deep); }

/* `margin-top:auto` colle le bouton au bas de la carte : sans lui, trois
   cartes aux listes de longueurs différentes ont leurs boutons à trois
   hauteurs, et l'œil ne sait plus les comparer. */
.ev-plan-cta-wrap { margin-block-start: auto; padding-block-start: 28px; }

/* ── Tableau comparatif ───────────────────────────────────────────
   Un vrai <table> : c'est une donnée tabulaire, et un lecteur d'écran
   doit pouvoir annoncer « ligne Paiement sous séquestre, colonne
   Premium ». Une grille de <div> ne le permet pas.
   ──────────────────────────────────────────────────────────────── */

.ev-table-wrap { overflow-x: auto; margin-block-start: 40px; }
.ev-table {
  width: 100%;
  min-width: 620px;
  border-collapse: collapse;
  font-size: 14px;
}
.ev-table th,
.ev-table td {
  padding: 14px 16px;
  text-align: start;
  border-block-end: 1px solid var(--ev-divider);
}
/* Pas de `position: sticky` ici. Le conteneur porte `overflow-x: auto`,
   ce qui en fait un conteneur de défilement : un en-tête collant s'y
   fixerait par rapport à LUI, qui ne défile pas verticalement, et non
   par rapport à la fenêtre. L'effet serait nul, et il masquerait en plus
   la première ligne au moment du défilement horizontal.
   C'est la teinte de la colonne mise en avant qui guide le regard. */
.ev-table thead th {
  background: var(--ev-surface);
  font-family: var(--ev-ff-head);
  font-size: 14px;
  font-weight: 700;
  color: var(--ev-text);
  z-index: 1;
}
.ev-table thead th:not(:first-child),
.ev-table td:not(:first-child) { text-align: center; width: 150px; }

.ev-table tbody th {
  font-weight: 500;
  color: var(--ev-text);
}
.ev-table-group th {
  padding-block: 22px 10px;
  font-family: var(--ev-ff-body);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ev-accent-deep);
  border-block-end-color: transparent;
}
.ev-table td svg { color: var(--ev-success); }
.ev-table td span { color: var(--ev-text-faint); font-size: 13px; }

/* La colonne de la formule mise en avant est teintée sur toute sa
   hauteur, pour qu'on la suive du regard sans recompter les colonnes. */
.ev-table th.is-featured,
.ev-table td.is-featured { background: var(--ev-accent-soft); }

@media (max-width: 991px) {
  .ev-plans { grid-template-columns: 1fr; }
}

/* ════════════════════════════════════════════════════════════════════
   11 quinquies. Formulaires
   ════════════════════════════════════════════════════════════════════
   style.css habille TOUS les `input`, `select` et `textarea` du site
   avec `padding: 20px 16px` et `line-height: 30px`. Chaque valeur est
   donc réécrite ici explicitement : n'en poser qu'une laisserait les
   autres héritées, ce qui avait déjà déformé le champ de la lettre
   d'information dans le pied de page.
   ════════════════════════════════════════════════════════════════════ */

.ev-field { display: block; }
.ev-field + .ev-field,
.ev-grid + .ev-field { margin-block-start: 18px; }
/* Dans une grille, l'écart vient de `gap` : la marge ci-dessus
   décalait vers le bas la seconde colonne (e-mail du contact). */
.ev-grid > .ev-field + .ev-field { margin-block-start: 0; }

.ev-label {
  display: block;
  margin-block-end: 7px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ev-text);
}

.ev-input,
.ev-textarea {
  width: 100%;
  padding: 13px 16px;
  line-height: 1.5;
  border: 1px solid var(--ev-border);
  border-radius: var(--ev-radius-md);
  background: var(--ev-surface);
  color: var(--ev-text);
  font-family: var(--ev-ff-body);
  font-size: 15px;
  transition: border-color .2s var(--ev-ease), box-shadow .2s var(--ev-ease);
}
.ev-textarea { resize: vertical; min-height: 140px; }

.ev-input::placeholder,
.ev-textarea::placeholder { color: var(--ev-text-faint); }

.ev-input:focus,
.ev-textarea:focus {
  outline: none;
  border-color: var(--ev-blue);
  box-shadow: 0 0 0 3px var(--ev-blue-highlight);
}

/* Le message d'erreur est rattaché au champ par `aria-describedby` côté
   balisage : la couleur seule ne suffirait pas à le signaler. */
.ev-error { margin-block-start: 6px; font-size: 13px; color: var(--ev-error); }
.ev-input[aria-invalid="true"],
.ev-textarea[aria-invalid="true"] { border-color: var(--ev-error); }

.ev-alert {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 14px 16px;
  border-radius: var(--ev-radius-md);
  font-size: 14px;
  line-height: 1.55;
}
.ev-alert-ok {
  background: var(--ev-success-highlight);
  color: var(--ev-success);
  border: 1px solid color-mix(in srgb, var(--ev-success) 24%, transparent);
}
.ev-alert svg { flex: none; margin-block-start: 1px; }

/* ════════════════════════════════════════════════════════════════════
   11 sexies. Pages légales
   ════════════════════════════════════════════════════════════════════
   Sert les trois pages servies par standard/components/legal-page :
   confidentialité, CGU et CGV.

   Ce composant embarquait 179 lignes de <style>, dont un bloc qui
   forçait en blanc TOUS les liens de la barre de navigation, pour
   rester lisible sur son ancien hero sombre. Ce correctif fuitait sur
   le menu du compte et y produisait du texte blanc sur fond blanc,
   le défaut que ev-chrome.css neutralise depuis.
   ════════════════════════════════════════════════════════════════════ */

.ev-legal { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 56px; align-items: start; }

/* Le sommaire suit le défilement. `top` dégage la barre de navigation,
   qui est en surimpression et masquerait sinon les premières entrées. */
.ev-legal-toc { position: sticky; inset-block-start: 100px; }
.ev-legal-toc ul { list-style: none; margin: 0; padding: 0; }
.ev-legal-toc li + li { margin-block-start: 2px; }
.ev-legal-toc a {
  display: block;
  padding: 7px 12px;
  border-radius: var(--ev-radius-sm);
  border-inline-start: 2px solid transparent;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ev-text-muted);
  text-decoration: none !important;
  transition: color .2s var(--ev-ease), background-color .2s var(--ev-ease), border-color .2s var(--ev-ease);
}
.ev-legal-toc a:hover { background: var(--ev-surface-offset); color: var(--ev-text); }
.ev-legal-toc a.is-current {
  border-inline-start-color: var(--ev-accent);
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  font-weight: 700;
}

.ev-legal-aside-links { margin-block-start: 22px; padding-block-start: 20px; border-block-start: 1px solid var(--ev-divider); display: grid; gap: 9px; }
.ev-legal-aside-links a { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ev-text-muted); text-decoration: none !important; }
.ev-legal-aside-links a:hover { color: var(--ev-accent-deep); }

.ev-legal-section + .ev-legal-section { margin-block-start: 48px; padding-block-start: 48px; border-block-start: 1px solid var(--ev-divider); }
/* `scroll-margin-top` évite que le titre se retrouve sous la barre de
   navigation après un saut d'ancre. */
.ev-legal-section { scroll-margin-top: 110px; }

.ev-legal-num {
  display: inline-grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 999px;
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  font-family: var(--ev-ff-head);
  font-size: 13px;
  font-weight: 700;
  margin-block-end: 14px;
}

/* Le contenu des sections est du HTML rédigé à la main dans les vues :
   il n'y a pas de classe à y poser, donc on stylise les balises. */
.ev-legal-body h2 { font-size: clamp(21px, 2vw, 26px); font-weight: 700; margin-block-end: 14px; }
.ev-legal-body h3 { font-size: 17px; font-weight: 700; margin-block: 26px 10px; }
.ev-legal-body p,
.ev-legal-body li { font-size: 15px; line-height: 1.75; color: var(--ev-text-muted); }
.ev-legal-body p + p { margin-block-start: 14px; }
.ev-legal-body ul,
.ev-legal-body ol { margin: 14px 0 0; padding-inline-start: 22px; }
.ev-legal-body li + li { margin-block-start: 8px; }
.ev-legal-body a { color: var(--ev-accent-deep); text-decoration: underline; }
.ev-legal-body strong { color: var(--ev-text); }
.ev-legal-body table { width: 100%; border-collapse: collapse; margin-block-start: 16px; font-size: 14px; }
.ev-legal-body th,
.ev-legal-body td { padding: 11px 13px; border: 1px solid var(--ev-divider); text-align: start; }
.ev-legal-body th { background: var(--ev-surface-offset); font-weight: 700; color: var(--ev-text); }

.ev-legal-meta { display: flex; flex-wrap: wrap; gap: 10px 20px; margin-block-start: 20px; }
.ev-legal-meta span { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ev-text-muted); }
.ev-legal-meta svg { color: var(--ev-accent-deep); }

@media (max-width: 991px) {
  .ev-legal { grid-template-columns: 1fr; gap: 32px; }
  /* Collant sur une seule colonne, le sommaire recouvrirait le texte. */
  .ev-legal-toc { position: static; }
}

/* ════════════════════════════════════════════════════════════════════
   11 septies. Écrans de résultat et cartes de membre
   ════════════════════════════════════════════════════════════════════ */

/* ── Écran de résultat ────────────────────────────────────────── */

.ev-status {
  display: flex;
  align-items: center;
  /* `min-height` et non `height` : le contenu peut dépasser (référence
     de transaction, message long) et doit alors pousser la page plutôt
     que d'être rogné. 100svh, pas 100vh, sur mobile, `vh` compte la
     barre d'adresse rétractée et déborde d'autant. */
  min-height: 72svh;
  padding-block: 120px 80px;
}
.ev-status .ev-wrap { max-width: 620px; }
.ev-status .ev-lead { margin-inline: auto; }

.ev-status-icon {
  display: inline-grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border-radius: 999px;
}
/* Attente : l'anneau tourne pour signaler qu'il se passe quelque chose. */
.ev-status-icon.is-spinning::before {
  content: "";
  position: absolute;
  width: 68px;
  height: 68px;
  border-radius: 999px;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  animation: ev-spin 1s linear infinite;
}
.ev-status-icon { position: relative; }
@keyframes ev-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .ev-status-icon.is-spinning::before { animation: none; opacity: .4; }
}

/* ── Carte de membre ──────────────────────────────────────────── */

.ev-user-card { display: flex; align-items: center; gap: 16px; }

.ev-user-avatar {
  width: 56px;
  height: 56px;
  border-radius: 999px;
  object-fit: cover;
  flex: none;
}
.ev-user-avatar-fallback {
  display: grid;
  place-items: center;
  background: var(--ev-blue-highlight);
  color: var(--ev-blue);
  font-family: var(--ev-ff-head);
  font-size: 18px;
  font-weight: 700;
}

.ev-user-body { min-width: 0; flex: 1; }
.ev-user-name {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--ev-ff-head);
  font-size: 16px;
  font-weight: 700;
  color: var(--ev-text);
}
.ev-user-role { font-size: 13.5px; color: var(--ev-text-muted); margin-block-start: 3px !important; }
.ev-user-stats { display: flex; flex-wrap: wrap; gap: 14px; margin-block-start: 8px !important; font-size: 12.5px; color: var(--ev-text-faint); }
.ev-user-stats strong { color: var(--ev-text); font-weight: 700; }

.ev-user-action { flex: none; }

@media (max-width: 575px) {
  .ev-user-card { flex-wrap: wrap; }
  .ev-user-action { width: 100%; }
  .ev-user-action .ev-btn { width: 100%; }
}

/* ── État vide ────────────────────────────────────────────────── */

.ev-empty {
  padding: 48px 24px;
  border: 1px dashed var(--ev-border);
  border-radius: var(--ev-radius-xl);
  text-align: center;
  color: var(--ev-text-muted);
}
.ev-empty svg { color: var(--ev-text-faint); margin-block-end: 14px; }

/* ════════════════════════════════════════════════════════════════════
   11 octies. Pages-listes
   ════════════════════════════════════════════════════════════════════ */

.ev-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.ev-filter {
  padding: 8px 16px;
  border: 1px solid var(--ev-border);
  border-radius: 999px;
  background: var(--ev-surface);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ev-text-muted);
  text-decoration: none !important;
  transition: background-color .2s var(--ev-ease), color .2s var(--ev-ease), border-color .2s var(--ev-ease);
}
.ev-filter:hover { background: var(--ev-surface-offset); color: var(--ev-text); }
.ev-filter.is-on {
  background: var(--ev-ink);
  border-color: var(--ev-ink);
  color: #fff;
}

/* ── Carte d'article ──────────────────────────────────────────── */

.ev-post { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
.ev-post-media { aspect-ratio: 16/10; background: var(--ev-blue-soft); overflow: hidden; }
.ev-post-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-post-noimage { display: grid; place-items: center; width: 100%; height: 100%; color: var(--ev-text); opacity: .3; }

/* Image de contenu absente du disque : ev-motion.js pose cette classe
   SUR L'IMAGE. Un motif discret vaut mieux qu'un rectangle vide, qu'on
   ne distingue pas d'un chargement en cours.

   Le sélecteur est volontairement limité aux images de contenu. Le repli
   par défaut, défini dans ev-controls.css, est une silhouette : c'est ce
   qu'il faut pour un portrait, où le hachuré dirait « fichier manquant »
   là où il suffit de dire « pas de photo ». */
.ev-post-media img.ev-img-failed,
.ev-photohero img.ev-img-failed,
.ev-mock img.ev-img-failed {
  background-color: var(--ev-surface-offset);
  background-image:
    linear-gradient(45deg, var(--ev-divider) 25%, transparent 25%),
    linear-gradient(-45deg, var(--ev-divider) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--ev-divider) 75%),
    linear-gradient(-45deg, transparent 75%, var(--ev-divider) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.ev-post-body { display: flex; flex-direction: column; flex: 1; padding: 24px; }
.ev-post-title { font-family: var(--ev-ff-head); font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ev-text); }
.ev-post-excerpt { font-size: 14px; line-height: 1.65; color: var(--ev-text-muted); margin-block-start: 10px; }
.ev-post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-block-start: auto;
  padding-block-start: 18px;
  font-size: 12.5px;
  color: var(--ev-text-faint);
}
.ev-post-meta span { display: inline-flex; align-items: center; gap: 5px; }

/* Carte entièrement cliquable.

   Le lien du titre s'étire par un pseudo-élément qui recouvre toute la
   carte, plutôt que d'envelopper la carte dans une <a>. Trois raisons :

     - un seul lien réel par carte, donc un seul élément annoncé par un
       lecteur d'écran, avec le TITRE pour libellé plutôt qu'une lecture
       de tout le contenu ;
     - le texte de la carte reste sélectionnable à la souris, ce qu'une
       grande ancre empêche ;
     - le balisage reste valide : une <a> ne peut pas contenir d'autres
       liens, ce qui interdirait tout bouton secondaire dans la carte.

   Un élément interactif à garder cliquable par-dessus (bouton favori,
   lien secondaire) reçoit `.ev-above` pour repasser devant. */
.ev-card-link { position: relative; }
.ev-card-link .ev-stretch::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.ev-card-link .ev-above { position: relative; z-index: 2; }

/* Le survol de n'importe quel point de la carte déclenche les mêmes
   réactions que le survol du lien : sans cela, la carte est cliquable
   mais rien ne l'indique. */
.ev-card-link:hover .ev-post-title { color: var(--ev-accent-deep); }
.ev-card-link .ev-post-title { transition: color .2s var(--ev-ease); }
/* Le contour de focus doit cerner la CARTE, pas le titre seul, puisque
   c'est la carte entière qui est la cible. */
.ev-card-link:has(.ev-stretch:focus-visible) {
  outline: 2px solid var(--ev-blue);
  outline-offset: 3px;
}
.ev-card-link .ev-stretch:focus-visible { outline: none; }

/* ── Pagination ───────────────────────────────────────────────── */

/* Laravel produit sa propre structure ; on habille ses éléments plutôt
   que d'imposer un gabarit, pour ne pas casser à la mise à jour. */
.ev-pagination nav { display: flex; justify-content: center; }
.ev-pagination svg { width: 16px; height: 16px; }
.ev-pagination .pagination { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; }
.ev-pagination .page-item .page-link,
.ev-pagination a[class*="relative"],
.ev-pagination span[class*="relative"] {
  display: inline-grid;
  place-items: center;
  min-width: 40px;
  height: 40px;
  padding-inline: 12px;
  border: 1px solid var(--ev-border) !important;
  border-radius: var(--ev-radius-sm);
  background: var(--ev-surface) !important;
  color: var(--ev-text-muted) !important;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none !important;
  box-shadow: none !important;
  transition: background-color .2s var(--ev-ease), color .2s var(--ev-ease);
}
.ev-pagination .page-item.active .page-link,
.ev-pagination [aria-current="page"] span,
.ev-pagination span[aria-current="page"] {
  background: var(--ev-ink) !important;
  border-color: var(--ev-ink) !important;
  color: #fff !important;
}
.ev-pagination .page-item.disabled .page-link { opacity: .45; }

/* ════════════════════════════════════════════════════════════════════
   11 nonies. Cartes de prestation et barre de filtres avancée
   ════════════════════════════════════════════════════════════════════ */

.ev-svc-cat {
  position: absolute;
  inset-block-start: 12px;
  inset-inline-start: 12px;
  z-index: 2;
  padding: 4px 11px;
  border-radius: 999px;
  background: rgba(10, 23, 34, .78);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  /* Le fond translucide laisse passer la photo : le flou garantit la
     lisibilité quelle que soit l'image en dessous. */
  backdrop-filter: blur(6px);
}

.ev-svc-fav {
  position: absolute;
  inset-block-start: 10px;
  inset-inline-end: 10px;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, .92);
  color: var(--ev-text-faint);
  font-size: 13px;
  cursor: pointer;
  transition: color .2s var(--ev-ease), transform .2s var(--ev-ease);
}
.ev-svc-fav:hover { transform: scale(1.08); color: var(--ev-error); }
.ev-svc-fav.is-on { color: var(--ev-error); }
.ev-svc-fav:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 2px; }

.ev-post-media { position: relative; }

.ev-svc-provider { display: flex; align-items: center; gap: 10px; }
.ev-svc-avatar { border-radius: 999px; object-fit: cover; flex: none; }
.ev-svc-name {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ev-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev-svc-meta { display: flex; flex-wrap: wrap; gap: 10px; margin-block-start: 3px !important; font-size: 12px; color: var(--ev-text-muted); }
.ev-dot { width: 6px; height: 6px; border-radius: 999px; flex: none; }

.ev-svc-footer {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-block-start: auto;
  padding-block-start: 18px;
}

/* ── Barre de filtres avancée ─────────────────────────────────── */

/* Barre de recherche sur fond clair.

   Variante distincte de la pilule du pied de page : celle-ci est conçue
   pour le fond encre et pose `color: #fff` sur le champ et un texte de
   substitution en blanc translucide. Réutilisée telle quelle sur un hero
   clair, elle donnait du blanc sur blanc, invisible. */
.ev-searchbar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px;
  border: 1px solid var(--ev-border);
  border-radius: 999px;
  background: var(--ev-surface);
  max-width: 560px;
  transition: border-color .2s var(--ev-ease), box-shadow .2s var(--ev-ease);
}
.ev-searchbar:focus-within {
  border-color: var(--ev-blue);
  box-shadow: 0 0 0 3px var(--ev-blue-highlight);
}
.ev-searchbar input {
  flex: 1 1 auto;
  min-width: 0;
  height: 42px;
  padding: 0 16px;
  line-height: 42px;
  border: 0;
  background: transparent;
  color: var(--ev-text);
  font-family: var(--ev-ff-body);
  font-size: 15px;
}
.ev-searchbar input::placeholder { color: var(--ev-text-faint); }
.ev-searchbar input:focus { outline: none; }
.ev-searchbar button {
  flex: none;
  height: 42px;
  padding-inline: 22px;
  border: 0;
  border-radius: 999px;
  background: var(--ev-blue);
  color: #fff;
  font-family: var(--ev-ff-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color .2s var(--ev-ease);
}
.ev-searchbar button:hover { background: var(--ev-blue-hover); }
.ev-searchbar button:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 2px; }

@media (max-width: 480px) {
  .ev-searchbar { flex-direction: column; border-radius: var(--ev-radius-lg); gap: 8px; padding: 8px; }
  .ev-searchbar input { width: 100%; }
  .ev-searchbar button { width: 100%; }
}

.ev-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-lg);
  background: var(--ev-surface);
}
.ev-select {
  height: 40px;
  padding-inline: 14px 34px;
  border: 1px solid var(--ev-border);
  border-radius: var(--ev-radius-sm);
  background: var(--ev-surface);
  color: var(--ev-text);
  font-family: var(--ev-ff-body);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  /* La flèche native varie d'un système à l'autre ; celle-ci est
     identique partout et suit la couleur du texte. */
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 17px, calc(100% - 12px) 17px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.ev-select:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 1px; }

.ev-toolbar-sep { width: 1px; height: 26px; background: var(--ev-divider); }

/* Étiquettes des filtres actifs, avec leur croix de retrait. */
.ev-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ev-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px 5px 13px;
  border-radius: 999px;
  background: var(--ev-accent-soft);
  color: var(--ev-accent-deep);
  font-size: 12.5px;
  font-weight: 600;
}
.ev-chip a {
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .07);
  color: inherit;
  font-size: 12px;
  line-height: 1;
  text-decoration: none !important;
}
.ev-chip a:hover { background: var(--ev-accent); color: var(--ev-ink); }

@media (max-width: 767px) {
  .ev-toolbar { flex-direction: column; align-items: stretch; }
  .ev-toolbar .ev-select,
  .ev-toolbar .ev-btn { width: 100%; }
  .ev-toolbar-sep { display: none; }
}

/* ════════════════════════════════════════════════════════════════════
   11 decies. Facettes de recherche
   ════════════════════════════════════════════════════════════════════ */

/* Une liste de facettes peut être longue (spécialités, statuts) : on la
   borne et on la fait défiler, plutôt que de laisser la colonne pousser
   la page sur plusieurs écrans. */
.ev-facets {
  display: grid;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
  padding-inline-end: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--ev-border) transparent;
}

.ev-facet {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--ev-radius-sm);
  font-size: 13.5px;
  color: var(--ev-text);
  cursor: pointer;
  transition: background-color .15s var(--ev-ease);
}
.ev-facet:hover { background: var(--ev-surface-offset); }
.ev-facet input { accent-color: var(--ev-blue); width: 15px; height: 15px; flex: none; }
.ev-facet span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-facet b { font-size: 11.5px; font-weight: 700; color: var(--ev-text-faint); flex: none; }
/* Le contour de focus doit cerner la ligne entière, pas la case seule :
   c'est la ligne qui est la cible au clic. */
.ev-facet:has(input:focus-visible) { outline: 2px solid var(--ev-blue); outline-offset: -2px; }

/* ════════════════════════════════════════════════════════════════════
   11 undecies. Panier
   ════════════════════════════════════════════════════════════════════ */

.ev-cart-line { display: flex; align-items: center; gap: 16px; }
.ev-cart-thumb {
  width: 64px; height: 64px;
  border-radius: var(--ev-radius-md);
  overflow: hidden;
  background: var(--ev-blue-soft);
  flex: none;
}
.ev-cart-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.ev-cart-total {
  font-family: var(--ev-ff-head);
  font-size: 15px;
  font-weight: 700;
  color: var(--ev-text);
  min-width: 110px;
  text-align: end;
  flex: none;
}

.ev-cart-remove {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border: 1px solid var(--ev-divider);
  border-radius: var(--ev-radius-sm);
  background: var(--ev-surface);
  color: var(--ev-text-faint);
  cursor: pointer;
  transition: background-color .2s var(--ev-ease), color .2s var(--ev-ease), border-color .2s var(--ev-ease);
}
.ev-cart-remove:hover { background: var(--ev-error-highlight); border-color: transparent; color: var(--ev-error); }
.ev-cart-remove svg { transform: rotate(45deg); }

/* Pendant l'appel au serveur, la ligne s'estompe et cesse de répondre :
   sans cela, un double-clic rapide envoie deux requêtes concurrentes et
   la dernière réponse arrivée gagne, pas la dernière demandée. */
.ev-cart-line.is-busy { opacity: .55; pointer-events: none; }

/* Vignettes de galerie. */
.ev-thumb {
  width: 64px; height: 64px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--ev-radius-sm);
  overflow: hidden;
  background: var(--ev-surface-offset);
  cursor: pointer;
  flex: none;
  transition: border-color .2s var(--ev-ease), opacity .2s var(--ev-ease);
  opacity: .6;
}
.ev-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-thumb:hover { opacity: 1; }
.ev-thumb.is-on { border-color: var(--ev-blue); opacity: 1; }
.ev-thumb:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 2px; }

.ev-qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--ev-border);
  border-radius: 999px;
  overflow: hidden;
  flex: none;
}
.ev-qty button {
  width: 32px; height: 36px;
  border: 0;
  background: var(--ev-surface);
  color: var(--ev-text);
  font-size: 15px;
  cursor: pointer;
  transition: background-color .15s var(--ev-ease);
}
.ev-qty button:hover { background: var(--ev-surface-offset); }
.ev-qty input {
  width: 46px; height: 36px;
  padding: 0;
  border: 0;
  border-inline: 1px solid var(--ev-divider);
  background: var(--ev-surface);
  color: var(--ev-text);
  font-family: var(--ev-ff-body);
  font-size: 14px;
  font-weight: 700;
  text-align: center;
  /* Les flèches natives des champs numériques doublent les boutons
     et déforment la pilule. */
  appearance: textfield;
  -moz-appearance: textfield;
}
.ev-qty input::-webkit-outer-spin-button,
.ev-qty input::-webkit-inner-spin-button { appearance: none; margin: 0; }
.ev-qty input:focus { outline: none; background: var(--ev-blue-soft); }

/* Récapitulatif. */
.ev-sum { display: grid; gap: 12px; margin: 0; }
.ev-sum > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.ev-sum dt { font-size: 14px; color: var(--ev-text-muted); }
.ev-sum dd { margin: 0; font-size: 14px; font-weight: 600; color: var(--ev-text); }
.ev-sum .is-total {
  margin-block-start: 6px;
  padding-block-start: 14px;
  border-block-start: 1px solid var(--ev-divider);
}
.ev-sum .is-total dt { font-weight: 700; color: var(--ev-text); }
.ev-sum .is-total dd { font-family: var(--ev-ff-head); font-size: 20px; font-weight: 700; }

@media (max-width: 767px) {
  .ev-cart-line { flex-wrap: wrap; }
  .ev-cart-total { min-width: 0; text-align: start; }
}

/* ════════════════════════════════════════════════════════════════════
   12. Animations
   ════════════════════════════════════════════════════════════════════
   `ev-motion.js` retire `.ev-reveal` (ou pose `.is-in`) quand l'élément
   entre dans le champ. Sans JavaScript, rien n'est jamais masqué : la
   règle ci-dessous ne s'applique que si le script a marqué la page
   comme prise en charge, sinon un échec de chargement rendrait tout le
   contenu invisible.
   ════════════════════════════════════════════════════════════════════ */

[data-ev-motion] .ev-reveal {
  opacity: 0;
  transform: translateY(22px);
}
[data-ev-motion] .ev-reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .55s var(--ev-ease), transform .55s var(--ev-ease);
  transition-delay: var(--ev-delay, 0ms);
}

/* Flottement continu : le hero ne se fige pas après le premier scroll. */
.ev-float { animation: ev-float var(--ev-float-dur, 5s) ease-in-out var(--ev-float-delay, 0s) infinite; }
@keyframes ev-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(calc(var(--ev-float-dist, 12px) * -1)); }
}

/* Point qui pulse : signal de vie avant même le premier scroll. */
.ev-pulse { position: relative; display: inline-flex; width: 7px; height: 7px; flex: none; }
.ev-pulse::before,
.ev-pulse::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--ev-accent);
}
.ev-pulse::before { animation: ev-ping 1.8s ease-out infinite; }
@keyframes ev-ping {
  from { transform: scale(1);   opacity: .6; }
  to   { transform: scale(2.4); opacity: 0; }
}

/* Compteur : le chiffre monte quand la section entre dans le champ.
   La valeur est écrite dans le HTML, le script ne fait que l'animer,
   si le script échoue, le chiffre final reste lisible. */
.ev-count { font-variant-numeric: tabular-nums; }

/* ════════════════════════════════════════════════════════════════════
   13. Mouvement réduit
   ════════════════════════════════════════════════════════════════════
   Tout ce qui bouge s'arrête, mais rien ne disparaît : `.ev-reveal`
   doit rester visible, sans quoi la page serait vide pour quelqu'un qui
   a demandé moins d'animation.
   ════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  [data-ev-motion] .ev-reveal,
  [data-ev-motion] .ev-reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .ev-float,
  .ev-marquee-track,
  .ev-pulse::before { animation: none; }
  .ev-lift, .ev-lift .ev-pop, .ev-zoom img, .ev-btn, .ev-link svg, .ev-link i { transition: none; }
  .ev-lift:hover { transform: none; }
  .ev-lift:hover .ev-pop { transform: none; }
  .ev-zoom:hover img { transform: none; }
  .ev-btn:hover { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════
   13 bis. Bandeau de consentement
   ════════════════════════════════════════════════════════════════════
   Carte posée en bas à gauche plutôt qu'un bandeau pleine largeur : le
   bandeau barre la page sur toute sa largeur et pousse le contenu hors
   du champ, alors que la carte n'occupe qu'un coin et laisse lire.

   Fond encre fixe dans les deux thèmes, c'est un aplat identitaire,
   comme le pied de page. Les couleurs de texte sont donc en blanc
   translucide et non en tokens sémantiques, sinon la carte deviendrait
   blanche sur blanc en mode sombre.

   ⚠ De nombreux bloqueurs masquent cet élément par une règle
   `display:none !important` visant `#cookie-banner`, identifiant présent
   dans les listes publiques de blocage. Ce n'est pas un défaut à
   corriger : masqué, le bandeau n'enregistre rien, donc aucun cookie non
   essentiel n'est posé : le comportement correct par défaut.
   ════════════════════════════════════════════════════════════════════ */

.ev-consent {
  position: fixed;
  inset-block-end: 24px;
  inset-inline-start: 24px;
  z-index: 99999;
  width: min(380px, calc(100vw - 32px));
  padding: 22px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: var(--ev-radius-xl);
  background: var(--ev-ink);
  box-shadow: 0 16px 48px rgba(10, 23, 34, .3);
  font-family: var(--ev-ff-body);
  /* Entrée en glissement : la carte monte depuis le bas plutôt que
     d'apparaître d'un coup. Elle n'est posée qu'une fois, à
     l'affichage. */
  animation: ev-consent-in .45s var(--ev-ease) both;
}

@keyframes ev-consent-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

.ev-consent-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ev-ff-head);
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  margin: 0 0 8px;
}
.ev-consent-title svg { color: var(--ev-accent); flex: none; }

.ev-consent p { color: rgba(255, 255, 255, .62); font-size: 13.5px; line-height: 1.6; margin: 0; }
.ev-consent a { color: var(--ev-accent); text-decoration: underline; }

/* Les actions s'empilent : dans 380 px, trois boutons côte à côte
   deviennent illisibles. L'action principale occupe sa propre ligne,
   les deux secondaires se partagent la suivante. */
.ev-consent-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.ev-consent-actions .is-primary { flex: 1 1 100%; }
.ev-consent-actions .ev-consent-btn:not(.is-primary) { flex: 1 1 0; }

.ev-consent-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 40px;
  padding-inline: 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: transparent;
  color: rgba(255, 255, 255, .78);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .2s var(--ev-ease), color .2s var(--ev-ease);
}
.ev-consent-btn:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.ev-consent-btn:focus-visible { outline: 2px solid var(--ev-accent); outline-offset: 2px; }
.ev-consent-btn.is-primary {
  border-color: var(--ev-accent);
  background: var(--ev-accent);
  color: var(--ev-ink);
  font-weight: 700;
}
.ev-consent-btn.is-primary:hover { background: var(--ev-accent-hover); color: var(--ev-ink); }

/* Panneau de réglage fin : une colonne, la carte est étroite. */
.ev-consent-options { display: grid; gap: 14px; margin-block: 14px 4px; }
.ev-consent-opt { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: rgba(255, 255, 255, .72); cursor: pointer; }
.ev-consent-opt input { accent-color: var(--ev-accent); width: 15px; height: 15px; margin-top: 2px; flex: none; }
.ev-consent-opt strong { color: #fff; font-size: 13px; }
.ev-consent-opt small { display: block; font-size: 11.5px; opacity: .6; margin-top: 2px; line-height: 1.5; }

/* Sur téléphone la carte prend toute la largeur disponible et se colle
   au bas de l'écran : à cette taille, un coin flottant gaspille de la
   place sans rien apporter. */
@media (max-width: 575px) {
  .ev-consent {
    inset-inline: 12px;
    inset-block-end: 12px;
    width: auto;
    padding: 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ev-consent { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════
   13 ter. Pied de page
   ════════════════════════════════════════════════════════════════════
   Fond encre fixe dans les deux thèmes, comme la carte de consentement :
   les couleurs de texte sont donc en blanc translucide, jamais en tokens
   sémantiques, sinon le pied deviendrait blanc sur blanc en sombre.
   ════════════════════════════════════════════════════════════════════ */

.ev-footer {
  position: relative;
  overflow: hidden;
  background: var(--ev-ink);
  color: rgba(255, 255, 255, .62);
  font-family: var(--ev-ff-body);
  padding-block-start: 80px;
}

.ev-footer a { color: inherit; text-decoration: none; transition: color .2s var(--ev-ease); }
.ev-footer a:hover { color: var(--ev-accent); }
.ev-footer p { margin: 0; }
.ev-footer ul { list-style: none; margin: 0; padding: 0; }

/* Le bloc de marque est plus large que les colonnes : il porte la
   phrase de positionnement ET le formulaire, les colonnes ne portent
   que des liens. */
.ev-footer-top {
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: 64px;
  padding-block-end: 56px;
}

.ev-footer-logo { display: inline-block; margin-block-end: 20px; }
.ev-footer-logo img { height: auto; max-width: 164px; }

.ev-footer-statement {
  font-family: var(--ev-ff-head);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -.02em;
  color: #fff;
}
.ev-footer-sub { font-size: 14px; line-height: 1.6; margin-block-start: 8px !important; }

/* ── Lettre d'information ─────────────────────────────────────── */

.ev-news {
  margin-block-start: 32px;
  padding-block-start: 28px;
  border-block-start: 1px solid rgba(255, 255, 255, .1);
}
.ev-news-title { font-family: var(--ev-ff-head); font-size: 15px; font-weight: 700; color: #fff; }
.ev-news-text { font-size: 13px; line-height: 1.6; margin-block-start: 6px !important; }

/* Champ et bouton collés en une seule pilule : deux contrôles séparés
   par un écart donnent l'impression d'un formulaire inachevé. */
.ev-news-form {
  display: flex;
  align-items: center;
  margin-block-start: 16px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 999px;
  background: rgba(255, 255, 255, .05);
  padding: 4px;
  transition: border-color .2s var(--ev-ease);
}
.ev-news-form:focus-within { border-color: var(--ev-accent); }

.ev-news-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: #fff;
  font-family: inherit;
  font-size: 14px;
  /* Les quatre valeurs sont écrites explicitement parce que style.css
     habille TOUS les `input` du site : il impose `padding: 20px 16px` et
     `line-height: 30px`, ce qui portait la pilule à 80 px de haut pour un
     bouton de 40. Poser seulement `padding-inline` laissait le padding
     vertical hérité intact. */
  padding: 0 16px;
  line-height: 40px;
  height: 40px;
}
.ev-news-input::placeholder { color: rgba(255, 255, 255, .4); }
/* L'anneau de focus est porté par le conteneur, pas par le champ :
   un contour autour du seul champ, à l'intérieur de la pilule, est
   illisible. */
.ev-news-input:focus { outline: none; }

.ev-news-btn {
  flex: none;
  height: 40px;
  padding-inline: 20px;
  border: 0;
  border-radius: 999px;
  background: var(--ev-accent);
  color: var(--ev-ink);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color .2s var(--ev-ease);
}
.ev-news-btn:hover { background: var(--ev-accent-hover); }
.ev-news-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.ev-news-ok,
.ev-news-error { font-size: 13px; margin-block-start: 10px !important; }
.ev-news-ok { color: #6fdcae; }
.ev-news-error { color: #f79a9a; }

/* Champ-piège : hors de l'écran plutôt que `display:none`, que les
   robots les plus simples savent détecter. */
.ev-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── Colonnes de liens ────────────────────────────────────────── */

.ev-footer-nav { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; }
.ev-footer-title {
  font-family: var(--ev-ff-body);
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: rgba(255, 255, 255, .38);
  margin: 0 0 16px;
}
.ev-footer-nav li + li { margin-block-start: 10px; }
.ev-footer-nav a { font-size: 14px; }

/* ── Bandeau bas ──────────────────────────────────────────────── */

.ev-footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
  padding-block: 24px 28px;
  border-block-start: 1px solid rgba(255, 255, 255, .08);
}
.ev-footer-copy { font-size: 13px; color: rgba(255, 255, 255, .34); }
.ev-footer-copy a { color: rgba(255, 255, 255, .5); }

.ev-footer-trust { display: flex; flex-wrap: wrap; gap: 18px; }
.ev-footer-trust li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: rgba(255, 255, 255, .34);
}
.ev-footer-trust svg { color: var(--ev-accent); }

.ev-footer-social { display: flex; gap: 8px; }
.ev-footer-social a {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .14);
  color: rgba(255, 255, 255, .8);
  font-size: 13px;
  transition: background-color .2s var(--ev-ease), border-color .2s var(--ev-ease), color .2s var(--ev-ease);
}
.ev-footer-social a:hover {
  background: var(--ev-accent);
  border-color: var(--ev-accent);
  color: var(--ev-ink);
}

/* ── Signature : le nom en très grand, rogné par le bas ───────── */

.ev-footer-wordmark {
  font-family: var(--ev-ff-head);
  font-size: clamp(90px, 19vw, 300px);
  font-weight: 700;
  line-height: .74;
  letter-spacing: -.06em;
  text-align: center;
  color: rgba(255, 255, 255, .05);
  user-select: none;
  pointer-events: none;
  /* Marge négative : le bas des lettres sort du cadre, qui le rogne.
     C'est ce débordement qui fait la signature, un mot entier et
     centré ne serait qu'un gros titre. */
  margin-block-end: -.2em;
  padding-inline: 24px;
}

/* ── Adaptations ──────────────────────────────────────────────── */

@media (max-width: 1100px) {
  .ev-footer-top { grid-template-columns: 1fr; gap: 48px; }
  .ev-footer-nav { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .ev-footer { padding-block-start: 56px; }
  .ev-footer-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 24px; }
  .ev-footer-bottom { flex-direction: column; align-items: flex-start; }
}
@media (max-width: 420px) {
  /* Le champ et le bouton ne tiennent plus côte à côte : la pilule
     s'ouvre en deux lignes. */
  .ev-news-form { flex-direction: column; border-radius: var(--ev-radius-lg); padding: 8px; gap: 8px; }
  .ev-news-input { padding: 8px 12px; }
  .ev-news-btn { width: 100%; }
}

/* La bascule de thème et `.ev-sr` vivaient ici. Elles ont rejoint
   ev-chrome.css : elles habillent l'en-tête PARTAGÉ, rendu aussi bien
   sur la vitrine que sur le fil, alors que cette feuille-ci n'est
   chargée que par la vitrine. Résultat, sur /feed les deux icônes
   s'affichaient en même temps et le libellé « Changer de thème »,
   destiné aux seuls lecteurs d'écran, apparaissait à l'écran.
   Voir ev-chrome.css, section 2 bis. */

/* ════════════════════════════════════════════════════════════════════
   15. Utilitaires
   ════════════════════════════════════════════════════════════════════
   Le strict nécessaire. Tout ce qui se répète sur trois sections mérite
   une classe de composant plus haut, pas une pile d'utilitaires.
   ════════════════════════════════════════════════════════════════════ */

.ev-center { text-align: center; }
.ev-center .ev-lead { margin-inline: auto; }
.ev-stack   { display: flex; flex-direction: column; }
.ev-row     { display: flex; align-items: center; flex-wrap: wrap; }
.ev-gap-8   { gap: 8px; }
.ev-gap-12  { gap: 12px; }
.ev-gap-16  { gap: 16px; }
.ev-gap-24  { gap: 24px; }
/* ── Espacement ────────────────────────────────────────────────
   `!important` est ici la règle, pas l'exception.

   Un utilitaire n'existe que pour l'emporter : on l'écrit dans le
   balisage précisément parce qu'on veut cette valeur-là, à cet
   endroit-là. S'il peut perdre, il ne sert à rien.

   Et il perdait. `.ev-page h1…h6 { margin: 0 }`, quelques centaines de
   lignes plus haut, a une spécificité de (0,1,1) contre (0,1,0) pour
   ces classes : TOUT utilitaire d'espacement posé sur un titre à
   l'intérieur de `.ev-page` était donc silencieusement ignoré. Vingt-
   quatre titres de la vitrine étaient concernés, à commencer par celui
   de la page d'accueil, collé à son badge. Rien ne le signalait : la
   classe était bien là, elle ne faisait simplement rien. */
.ev-mt-8  { margin-top: 8px !important; }
.ev-mt-12 { margin-top: 12px !important; }
.ev-mt-16 { margin-top: 16px !important; }
.ev-mt-24 { margin-top: 24px !important; }
.ev-mt-32 { margin-top: 32px !important; }
.ev-mt-40 { margin-top: 40px !important; }
.ev-mt-56 { margin-top: 56px !important; }
.ev-mb-0  { margin-bottom: 0 !important; }

/* ── Texte enrichi rendu ───────────────────────────────────────
   Habillage de ce que produit l'éditeur : titres, listes, citations,
   tableaux, liens. Sans ces règles, `.ev-page h1…h6 { margin: 0 }` colle
   chaque titre au paragraphe qui le suit, et les listes perdent leurs
   puces : `ul, li { list-style: inherit }` du template les efface.

   Le sélecteur est restreint aux descendants de `.ev-prose` : ces règles
   ne valent que pour du texte rédigé par un utilisateur, jamais pour la
   mise en page du site. */
.ev-prose > *:first-child { margin-block-start: 0; }
.ev-prose p { margin: 0 0 14px; line-height: 1.75; }
.ev-prose p:last-child { margin-block-end: 0; }

.ev-prose h2,
.ev-prose h3,
.ev-prose h4,
.ev-prose h5,
.ev-prose h6 {
  margin: 28px 0 10px !important;
  font-family: var(--ev-ff-head);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.015em;
  color: var(--ev-text);
}
.ev-prose h2 { font-size: 22px; }
.ev-prose h3 { font-size: 19px; }
.ev-prose h4 { font-size: 17px; }
.ev-prose h5, .ev-prose h6 { font-size: 15.5px; }

.ev-prose ul,
.ev-prose ol { margin: 0 0 14px; padding-inline-start: 22px; }
.ev-prose ul { list-style: disc !important; }
.ev-prose ol { list-style: decimal !important; }
.ev-prose li { list-style: inherit !important; margin-block-end: 6px; line-height: 1.7; }

.ev-prose a { color: var(--ev-accent-deep); text-decoration: underline; }

.ev-prose blockquote {
  margin: 16px 0;
  padding: 2px 0 2px 16px;
  border-inline-start: 3px solid var(--ev-accent);
  color: var(--ev-text-muted);
  font-style: italic;
}

.ev-prose pre,
.ev-prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em;
}
.ev-prose code { padding: 2px 5px; border-radius: 4px; background: var(--ev-surface-offset); }
.ev-prose pre {
  margin: 16px 0;
  padding: 14px 16px;
  border-radius: var(--ev-radius-md);
  background: var(--ev-surface-offset);
  overflow-x: auto;
}
.ev-prose pre code { padding: 0; background: none; }

.ev-prose hr { margin: 24px 0; border: 0; border-block-start: 1px solid var(--ev-divider); }

.ev-prose table {
  width: 100%;
  margin: 16px 0;
  border-collapse: collapse;
  font-size: 14.5px;
}
.ev-prose th,
.ev-prose td {
  padding: 9px 12px;
  border: 1px solid var(--ev-divider);
  text-align: start;
  vertical-align: top;
}
.ev-prose th { background: var(--ev-surface-offset); font-weight: 700; }

/* ── Textes secondaires ────────────────────────────────────────── */

/* Aide sous un champ : dit quoi écrire, avant qu'on se trompe. */
.ev-hint {
  display: block;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ev-text-faint);
}

.ev-muted { color: var(--ev-text-muted); }

/* Liste à puces de marque, pour les arguments d'une carte. */
.ev-checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.ev-checklist li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ev-text);
}
.ev-checklist li > svg { flex: none; margin-top: 2px; color: var(--ev-accent-deep); }


/* ════════════════════════════════════════════════════════════════════
   Actions d'un sujet : J'aime, favori, partage (x-ev.topic-actions)

   Boutons en pastille, discrets au repos : sur une carte, l'action
   principale reste l'ouverture du sujet. L'état actif se lit à la
   couleur ET à l'icône pleine, pas à la couleur seule.
   ════════════════════════════════════════════════════════════════════ */

.ev-topic-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 18px; }
.ev-ta-form { display: contents; }

.ev-ta-btn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 6px 12px;
  border: 1px solid var(--ev-border-mid, var(--ev-border));
  border-radius: 999px;
  background: var(--ev-bg-card, var(--ev-surface));
  color: var(--ev-text-muted);
  font: 600 13px/1 var(--ev-ff-body, inherit);
  text-decoration: none;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s, transform .15s;
}
.ev-ta-btn:hover { color: var(--ev-text); border-color: var(--ev-text-faint, var(--ev-border-mid)); }
.ev-ta-btn:active { transform: scale(.96); }
.ev-ta-btn:focus-visible { outline: 2px solid var(--ev-blue); outline-offset: 2px; }
.ev-ta-btn:disabled { opacity: .6; cursor: progress; }
.ev-ta-btn svg { flex: none; }

.ev-ta-btn .ev-ta-on { display: none; }
.ev-ta-btn.is-active .ev-ta-on { display: inline; }
.ev-ta-btn.is-active .ev-ta-off { display: none; }

.ev-ta-btn.is-like.is-active { color: var(--ev-error); border-color: var(--ev-error-border, var(--ev-error)); background: var(--ev-error-highlight); }
.ev-ta-btn.is-fav.is-active  { color: var(--ev-accent-deep, var(--ev-accent)); border-color: var(--ev-accent); background: var(--ev-accent-highlight); }
.ev-ta-btn.is-like.is-active svg { animation: ev-ta-pop .28s var(--ev-ease, ease-out); }
@keyframes ev-ta-pop { 50% { transform: scale(1.25); } }
@media (prefers-reduced-motion: reduce) { .ev-ta-btn.is-like.is-active svg { animation: none; } }

.ev-ta-count { font-variant-numeric: tabular-nums; }

.ev-topic-actions.is-lg .ev-ta-btn { min-height: 40px; padding: 8px 16px; font-size: 14px; }

.ev-ta-share { position: relative; }
.ev-ta-menu {
  position: absolute; z-index: 20; top: calc(100% + 6px); right: 0;
  min-width: 200px; padding: 6px;
  background: var(--ev-bg-card, var(--ev-surface));
  border: 1px solid var(--ev-border);
  border-radius: var(--ev-radius-md, 12px);
  box-shadow: var(--ev-shadow-lift, 0 12px 32px rgba(0,0,0,.14));
}
.ev-ta-menu[hidden] { display: none; }
.ev-ta-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: var(--ev-radius-sm, 8px);
  background: none; color: var(--ev-text);
  font: 500 13.5px/1.2 var(--ev-ff-body, inherit); text-align: left; text-decoration: none;
  cursor: pointer;
}
.ev-ta-item:hover, .ev-ta-item:focus-visible { background: var(--ev-bg-sec, var(--ev-surface-offset)); outline: none; }

/* Sur mobile, le libellé du favori cède la place : l'icône suffit. */
@media (max-width: 480px) {
  .ev-topic-actions.is-sm .is-fav .ev-ta-label { display: none; }
  .ev-ta-menu { right: auto; left: 0; }
}
