/* =====================================================================
   VIGIE — les écrans d'entrée (connexion, inscription, code, mot de
   passe oublié), d'après les maquettes du directeur (03/08/2026).

   Deux panneaux : le sombre (titre, question, mentions — le fond est
   l'image officielle de la marque, sans animation, à la demande du
   directeur) et le clair (logotype, formulaire, langue). Titres en
   Nexa Pro ExtraBold, textes en Inter.
   ===================================================================== */

@font-face {
  font-family: "Nexa Pro";
  src: url("polices/NexaPro-ExtraBold.otf") format("opentype");
  font-weight: 800;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("polices/Inter-Variable.ttf") format("truetype");
  font-weight: 100 900;
  font-display: swap;
}

:root {
  --noir: #000000;
  --vert: #88c73b;
  --vert-fonce: #6ba32c;
  --encre: #333333;
  --gris-texte: #6f757c;
  --gris-champ: #f4f5f4;
  --gris-bord: #e4e6e4;
}

* { box-sizing: border-box; }

/* CACHÉ VEUT DIRE CACHÉ. Un élément qui porte `hidden` reste affiché
   dès qu'une règle lui donne un `display` — la ligne d'attente de
   l'étape 4 restait ainsi visible après la recherche, et poussait la
   liste sur les boutons (05/08/2026). */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body { font-family: "Inter", "Segoe UI", system-ui, sans-serif;
       color: var(--encre); background: #ffffff; }

/* ------------------------------------------------------- la scène */

.scinde { display: flex; min-height: 100vh; }

/* --- panneau sombre ------------------------------------------------ */

.panneau-sombre {
  position: relative; overflow: hidden;
  width: 56%; min-height: 100vh;
  background: url("fond-sombre.jpg") center / cover no-repeat #030503;
  color: #ffffff;
  display: flex; flex-direction: column;
  padding: 52px 56px 36px;
}
.panneau-sombre .marque { width: 66px; height: 66px; flex-shrink: 0; }

.panneau-sombre .parole { margin: auto 0; position: relative; z-index: 2;
                          max-width: 520px; }
.panneau-sombre h1 {
  font-family: "Nexa Pro", "Inter", sans-serif; font-weight: 800;
  font-size: clamp(24px, 2.5vw, 36px); line-height: 1.35;
  letter-spacing: .2px; margin: 0 0 30px;
}
.panneau-sombre .question { font-size: 15.5px; font-weight: 400;
                            color: #e8ece4; margin: 0 0 5px; }
.panneau-sombre .question-lien {
  display: inline-block; color: var(--vert); font-size: 15.5px;
  text-decoration: underline; text-underline-offset: 4px;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-weight: 400;
}
.panneau-sombre .mentions { position: relative; z-index: 2;
  font-size: 12px; line-height: 1.7; color: #8a9087; margin: 0; }
.panneau-sombre .mentions a { color: #a9afa6; }

/* --- panneau clair ------------------------------------------------- */

.panneau-clair {
  width: 44%; min-height: 100vh;
  display: flex; flex-direction: column; align-items: center;
  padding: 64px 40px 28px;
}
.panneau-clair .logotype { height: 58px; margin-bottom: 48px; }
.panneau-clair .formulaire { width: 100%; max-width: 440px;
                             display: flex; flex-direction: column;
                             gap: 18px; margin: auto 0; }

.titre-clair { font-family: "Nexa Pro", "Inter", sans-serif;
               font-weight: 800; font-size: 24px; color: var(--encre);
               text-align: center; margin: 0 0 2px; }
.sous-clair { font-size: 14.5px; color: var(--gris-texte);
              text-align: center; margin: -8px 0 6px; line-height: 1.6; }
.sous-clair .destinataire { color: var(--vert-fonce); font-weight: 700;
                            word-break: break-all; }

.champ-pilule {
  width: 100%; padding: 17px 26px;
  /* Les écrans du parcours imposent la hauteur de la maquette ; les
     écrans d'entrée gardent le rembourrage d'origine. */
  font: 500 15px "Inter", sans-serif; color: var(--encre);
  background: var(--gris-champ);
  border: 1px solid var(--gris-bord); border-radius: 999px;
  outline: none; transition: border-color .15s, background .15s;
}
.champ-pilule::placeholder { color: #a9aeb4; font-weight: 400; }
.champ-pilule:focus { border-color: var(--vert); background: #ffffff; }

.champ-code { text-align: center; letter-spacing: 14px;
              font-weight: 700; font-size: 18px; }
.champ-code::placeholder { letter-spacing: 8px; }

.bouton-vert {
  width: 100%; padding: 17px 26px; border: none; border-radius: 999px;
  background: var(--vert); color: #fff;
  font: 700 16px "Inter", sans-serif; cursor: pointer;
  transition: background .15s, transform .05s;
}
.bouton-vert:hover { background: var(--vert-fonce); }
.bouton-vert:active { transform: translateY(1px); }

.bouton-blanc {
  width: 100%; padding: 15px 26px; border-radius: 999px;
  background: #ffffff; border: 1px solid #d9dcd9; color: var(--encre);
  font: 700 15px "Inter", sans-serif; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  text-decoration: none; transition: border-color .15s, background .15s;
}
.bouton-blanc:hover { border-color: #b9beb9; background: #fafbfa; }

.separateur { display: flex; align-items: center; gap: 18px;
              color: var(--gris-texte); font-size: 13.5px; margin: 4px 0; }
.separateur::before, .separateur::after {
  content: ""; flex: 1; height: 1px; background: var(--gris-bord);
}

.lien-discret { display: block; text-align: center; margin-top: 4px;
                color: var(--gris-texte); font-size: 14px;
                text-decoration: none; background: none; border: none;
                cursor: pointer; font-family: inherit; width: 100%; }
.lien-discret:hover { color: var(--encre); text-decoration: underline; }

/* Renvoyer le code : un décompte gris d'une minute ; à zéro, le TEXTE
   devient vert et cliquable — pas un bouton (demande du 04/08/2026). */
.renvoi { text-align: center; margin-top: 2px; }
.renvoi .decompte { color: var(--gris-texte); font-size: 14px; }
.renvoi-lien {
  display: none; margin: 0 auto; padding: 0;
  background: none; border: none; cursor: pointer;
  color: var(--vert-fonce); font: 600 14px "Inter", sans-serif;
}
.renvoi-lien:hover { text-decoration: underline; text-underline-offset: 3px; }
.renvoi.pret .decompte { display: none; }
.renvoi.pret .renvoi-lien { display: inline-block; }

/* --- la langue, en bas du panneau clair ---------------------------- */

.langue { position: relative; margin-top: 26px; }
.langue .bouton-langue .globe-langue { width: 17px; height: 17px; }
.langue .bouton-langue {
  display: flex; align-items: center; gap: 8px;
  background: none; border: none; cursor: pointer;
  color: var(--encre); font: 500 14.5px "Inter", sans-serif;
}
.langue .bouton-langue .chevron { transition: transform .15s; }
.langue.ouverte .bouton-langue .chevron { transform: rotate(180deg); }
.langue-choix {
  display: none; position: absolute; bottom: calc(100% + 10px);
  left: 50%; transform: translateX(-50%);
  min-width: 170px; background: #ffffff;
  border: 1px solid var(--gris-bord); border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .10); padding: 6px; z-index: 30;
}
.langue.ouverte .langue-choix { display: block; }
.langue-choix a { display: flex; justify-content: space-between; gap: 14px;
  padding: 9px 13px; border-radius: 9px; text-decoration: none;
  color: var(--encre); font-size: 14px; }
.langue-choix a:hover { background: var(--gris-champ); }
.langue-choix a[aria-current="true"] { color: var(--vert-fonce);
                                       font-weight: 700; }

/* --- messages passagers : dans static/messages.css, la feuille commune
   à tous les écrans (16/10/2026). */

/* --- petits écrans : le sombre devient un bandeau ------------------- */

@media (max-width: 940px) {
  .scinde { flex-direction: column; }
  .panneau-sombre { width: 100%; min-height: 0; padding: 34px 26px; }
  .panneau-sombre .parole { margin: 18px 0 6px; }
  .panneau-sombre h1 { font-size: 24px; margin-bottom: 18px; }
  .panneau-sombre .mentions { display: none; }
  .panneau-clair { width: 100%; min-height: 0; padding: 40px 22px 24px; }
  .panneau-clair .logotype { height: 48px; margin-bottom: 30px; }
}

/* =====================================================================
   L'ÉCRAN CENTRÉ SUR FOND SOMBRE — « Personnalisez votre profil », et
   demain les étapes du formulaire. Même image de fond que la page de
   connexion, tout centré, la langue en bas au milieu.
   ===================================================================== */

.scene-sombre {
  position: relative;
  min-height: 100vh;
  background: url("fond-sombre.jpg") center / cover no-repeat #030503;
  color: #ffffff;
  display: flex; flex-direction: column; align-items: center;
  gap: 22px; padding: 32px 24px 24px;
}

/* LE CENTRAGE QUI NE COUPE PAS. « justify-content: center » a un défaut
   connu : quand le contenu dépasse, il déborde des DEUX côtés, et le
   haut devient inatteignable — on ne peut pas remonter plus haut que le
   début de la page. Le bouton de langue, lui, passait sous la ligne de
   flottaison (signalé par le directeur, 05/08/2026).

   Deux marges automatiques font le même centrage, et se réduisent à
   zéro quand la place manque : tout s'empile alors depuis le haut, et
   la page défile normalement. Rien n'est jamais coupé. */
.scene-sombre > .cadre-etape,
.scene-sombre > .colonne { margin-block: auto; }
/* Un voile noir à 40 % sur l'image : les textes et les champs s'y
   détachent, sans éteindre le fond (demande du 04/08/2026). */
.scene-sombre::before {
  content: ""; position: absolute; inset: 0;
  background: rgba(0, 0, 0, .40); pointer-events: none;
}
.scene-sombre > * { position: relative; z-index: 1; }

/* L'ORDRE DES PLANS. Une animation crée un plan d'empilement : le
   z-index d'un menu reste donc prisonnier de son bloc, et la barre de
   boutons — plus bas dans la page — lui montait dessus (constaté le
   04/08/2026). On range donc les BLOCS eux-mêmes : les champs
   au-dessus, les boutons en dessous. */
.case-champs  { position: relative; z-index: 30; }
.case-boutons { position: relative; z-index: 10; }
.scene-sombre .langue { z-index: 5; }
.scene-sombre .colonne {
  width: 100%; max-width: 470px; margin: auto 0;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}

.titre-sombre {
  font-family: "Nexa Pro", "Inter", sans-serif; font-weight: 800;
  font-size: clamp(24px, 2.4vw, 34px); line-height: 1.3;
  text-align: center; margin: 6px 0 0;
}
.sous-sombre { color: #b9c0b4; font-size: 15px; line-height: 1.6;
               text-align: center; margin: 0 0 10px; max-width: 420px; }

/* Les champs, sur fond sombre : la même pilule, en tenue de nuit. */
.champ-sombre {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(255, 255, 255, .14);
  color: #ffffff; text-align: center;
}
.champ-sombre::placeholder { color: #8f968b; }
.champ-sombre:focus { background: rgba(255, 255, 255, .16);
                      border-color: var(--vert); }

.barre-boutons { display: flex; gap: 14px; width: 100%; }
.barre-boutons .bouton-vert { flex: 1; }
.bouton-fantome {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 17px 30px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .22);
  background: none; color: #cbd2c6; cursor: pointer;
  font: 500 15px "Inter", sans-serif; text-decoration: none;
  transition: border-color .15s, color .15s;
}
.bouton-fantome:hover { border-color: rgba(255, 255, 255, .45); color: #ffffff; }

/* --- le portrait ---------------------------------------------------- */

.portrait { position: relative; width: 118px; height: 118px; cursor: pointer;
            display: block; }
.portrait-image {
  width: 118px; height: 118px; border-radius: 50%;
  background: rgba(255, 255, 255, .09) center / cover no-repeat;
  border: 1px solid rgba(255, 255, 255, .16);
  display: flex; align-items: center; justify-content: center;
  transition: background-color .2s, transform .2s;
}
.portrait:hover .portrait-image { background-color: rgba(255, 255, 255, .14);
                                  transform: scale(1.02); }
.portrait-image img { width: 44px; height: 39px; opacity: .85; }
.portrait-crayon {
  position: absolute; right: 2px; bottom: 2px;
  width: 34px; height: 34px; border-radius: 50%;
  background: #4a4f46; border: 2px solid #0b0d0a;
  display: flex; align-items: center; justify-content: center;
  transition: background .2s;
}
.portrait:hover .portrait-crayon { background: var(--vert-fonce); }
.portrait-crayon img { width: 14px; height: 14px; }

/* --- la langue, au bout à droite ------------------------------------ */

.bouton-langue.clair-sur-sombre { color: #9a9a9a; }   /* le gris de la maquette */
.langue-du-bas .langue-choix { background: #12150f;
                                border-color: rgba(255, 255, 255, .12); }
.langue-du-bas .langue-choix a { color: #e4e8e0; }
.langue-du-bas .langue-choix a:hover { background: rgba(255, 255, 255, .07); }

/* --- ARRIVER ET PARTIR ----------------------------------------------

   Une seule animation, courte et discrète : le contenu monte de huit
   pixels en apparaissant, et redescend en partant. Rien d'autre — pas
   de bond, pas d'agrandissement, pas de cascade interminable.

   Le CADRE, lui, ne bouge jamais : jauge et boutons n'ont pas de classe
   `anime`. C'est ce qui donne l'impression d'un logiciel posé plutôt
   que d'une page qui se remonte à chaque écran.
   -------------------------------------------------------------------- */

.anime { animation: apparait .3s cubic-bezier(.22, 1, .36, 1) both;
         animation-delay: calc(var(--rang, 0) * .05s); }
@keyframes apparait {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.part .anime { animation: disparait .16s ease-in both; animation-delay: 0s; }
@keyframes disparait {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(8px); }
}

/* L'icône change d'une étape à l'autre : elle a droit à un peu plus
   d'ampleur que le texte, sans pour autant faire le voyage. */
.etape-icone.anime { animation-duration: .38s; }
.etape-icone.anime { animation-name: apparait-icone; }
@keyframes apparait-icone {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
.part .etape-icone.anime { animation-name: disparait-icone;
                           animation-duration: .16s; }
@keyframes disparait-icone {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(16px); }
}

@media (prefers-reduced-motion: reduce) {
  .anime, .part .anime { animation: none; }
}

@media (max-width: 620px) {
  .scene-sombre { padding: 40px 18px 20px; gap: 24px; }
  .barre-boutons { flex-direction: column-reverse; }
}

/* =====================================================================
   LA GRILLE DES ÉTAPES

   RÈGLE (directeur, 04/08/2026) : « ça bouge toujours ». Un formulaire
   en huit écrans où chaque élément se replace à chaque étape donne le
   sentiment d'un brouillon. On passe donc à une GRILLE : sept cases de
   hauteur fixe, et chaque chose y revient toujours au même endroit.

     1. l'icône           84 px
     2. la jauge          10 px
     3. le titre          jusqu'à deux lignes
     4. le sous-titre     jusqu'à deux lignes
     5. les champs        le reste (c'est ici que l'espace varie)
     6. les deux boutons  hauteur fixe — ils ne bougent JAMAIS
     7. « Plus tard »     la case existe même quand le bouton n'y est pas

   L'espace qui varie d'une étape à l'autre est absorbé par la case des
   champs, c'est-à-dire au seul endroit où l'œil ne le remarque pas :
   entre le dernier champ et les boutons.

   Les hauteurs des cases 3 et 4 tiennent les textes les plus longs des
   huit étapes. tests/test_parcours.py les borne pour qu'une phrase
   ajoutée demain ne défasse pas la grille sans qu'on s'en aperçoive.
   ===================================================================== */

/* LES MESURES DE LA MAQUETTE (relevées le 05/08/2026).

   La maquette est dessinée sur une largeur de 1728 points ; la fenêtre
   de Vigie en fait 1280. Tout est donc rapporté au même facteur (0,74)
   pour garder les proportions exactes du dessin, et non ses points.

     colonne          784 → 580        champ             81 → 60
     icône             78 → 58         écart des champs  32 → 24
     jauge        303 x 13 → 224 x 10  bouton            99 → 72
     titre             44 → 33         écart avant eux   59 → 44
*/
:root {
  --colonne: 580px;
  --haut-champ: 60px;
  --ecart-champs: 24px;
  --haut-choix: 60px;          /* la hauteur d'un champ */
  --ecart-choix: 21px;         /* 29 sur la maquette */
  --haut-bouton: 72px;

  /* Les hauteurs des sept cases de la grille. Chacune porte son propre
     écart au-dessus : les changer ici les change partout. */
  --case-icone: 96px;         /* la scène animée (20/10/2026), 58 avant */
  --case-jauge: 25px;         /* 15 d'écart + 10 de jauge */
  /* UNE seule ligne de titre : mesuré au navigateur le 05/08/2026, le
     plus long des huit ("Qui d'autre travaillera avec vous ?") fait
     551 points pour 580 de colonne. Réserver deux lignes creusait un
     trou de 41 points sous chaque titre — la maquette n'en montre
     aucun. tests/test_parcours.py borne la longueur des titres pour
     que cela reste vrai. */
  --case-titre: 78px;         /* 35 d'écart + 1 ligne (33 x 1,25) */
  --case-amorce: 68px;        /* 20 d'écart + 2 lignes (16 x 1,45) */
  /* Taillée sur L'ÉTAPE LA PLUS CHARGÉE (la 6e : trois adresses, puis
     « Ajouter » et « Copier le lien »). Les autres y flottent, centrées. */
  --case-champs: 325px;
  --case-boutons: 116px;      /* 44 d'écart + 72 de bouton */
  --case-plus-tard: 57px;
}

.cadre-etape {
  display: grid;
  grid-template-rows:
    var(--case-icone)
    var(--case-jauge)
    var(--case-titre)
    var(--case-amorce)
    auto
    auto
    auto;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  width: 100%; max-width: var(--colonne);

  /* LE HAUT NE BOUGE PAS, LES BOUTONS SUIVENT LE CONTENU (directeur, 31/10/2026).
     Le centrage se fait sur la hauteur de toutes les cases : l'icône, la jauge et le
     titre restent au même endroit ; une étape courte laisse sa place sous les boutons,
     jamais entre le dernier champ et eux. */
  min-height: calc(var(--case-icone) + var(--case-jauge) + var(--case-titre) + var(--case-amorce)
                   + var(--case-champs) + var(--case-boutons) + var(--case-plus-tard));

  /* LA CARTE FAIT LA HAUTEUR DE SES SEPT CASES, ni plus ni moins.
     Elle avait auparavant une hauteur imposée, et la case des champs
     prenait tout le reste (« 1fr ») : sur un grand écran cela creusait
     un trou de cent points entre le dernier champ et les boutons
     (signalé par le directeur le 05/08/2026, capture à l'appui).
     Une carte qui vaut la somme de ses parties ne peut plus se creuser. */
  height: auto;
}

/* =====================================================================
   LES PETITS ÉCRANS

   « Le logiciel doit s'adapter en fonction de l'écran sur lequel il est
   exécuté » (directeur, 05/08/2026). Trois tailles, et une seule règle
   dans chacune : les ÉCARTS cèdent avant les ÉLÉMENTS, et les éléments
   cèdent avant le contenu. Un titre plus petit se lit encore ; un
   bouton qu'on ne voit pas ne sert à rien.

   `--hors-cadre` est ce qui entoure le formulaire dans la scène : les
   rembourrages, l'écart, et la ligne de la langue. C'est ce qu'il faut
   retrancher de la fenêtre pour que TOUT tienne, langue comprise.
   ===================================================================== */

:root { --hors-cadre: 122px; }

/* Écran d'ordinateur portable courant (1366 x 768, 1280 x 720). Le seuil
   passe de 860 à 900 avec la scène animée (20/10/2026) : la grille haute
   fait 887 points, hors-cadre compris. */
@media (max-height: 900px) {
  :root {
    --case-icone: 84px; --case-jauge: 22px;
    --case-titre: 68px; --case-amorce: 68px;
    --case-champs: 300px; --case-boutons: 96px; --case-plus-tard: 46px;
    --ecart-champs: 18px; --ecart-choix: 16px;
    --hors-cadre: 108px;
  }
  .scene-sombre { gap: 16px; padding: 24px 24px 18px; }
}

/* Portable de 800 points de haut, barre des tâches comprise (relecture
   finale du 20/10/2026) : sans ce palier, la grille du palier 900 (792
   points) débordait de 721 à 791. */
@media (max-height: 800px) {
  :root {
    --case-icone: 58px; --case-jauge: 20px;
    --case-titre: 60px; --case-amorce: 64px;
    --case-champs: 288px; --case-boutons: 82px; --case-plus-tard: 40px;
    --hors-cadre: 108px;
  }
}

/* Petit écran, ou fenêtre réduite à la main. */
@media (max-height: 720px) {
  :root {
    --haut-champ: 52px; --haut-choix: 52px; --haut-bouton: 60px;
    --case-icone: 64px; --case-jauge: 20px;
    --case-titre: 58px; --case-amorce: 64px;
    --case-champs: 276px; --case-boutons: 82px; --case-plus-tard: 40px;
    --ecart-champs: 15px; --ecart-choix: 14px;
    --hors-cadre: 96px;
  }
  .scene-sombre { gap: 12px; padding: 18px 20px 14px; }
  .cadre-etape .titre-sombre { font-size: clamp(21px, 2.2vw, 26px); }
  .cadre-etape .sous-sombre { font-size: 14px; }
}

/* Fenêtre étroite : la colonne prend toute la place disponible. */
@media (max-width: 680px) {
  :root { --colonne: 100%; }
  .cadre-etape .titre-sombre { max-width: 100%; width: auto; }
}

/* Chaque case porte son propre écart en haut : c'est plus lisible qu'un
   jeu de marges éparpillées, et cela garde les hauteurs vérifiables. */
.case-icone   { display: flex; align-items: flex-end; }
.case-jauge   { display: flex; align-items: flex-end; }
.case-titre   { padding-top: 35px; }
.case-amorce  { padding-top: 20px; }
.case-champs  { padding-top: 25px; display: flex; flex-direction: column;
                justify-content: flex-start; gap: var(--ecart-champs); }
.case-boutons { padding-top: 44px; }
.case-plus-tard { padding-top: 14px; }
.case-plus-tard .plus-tard { margin-top: 0; }

.etape-icone { width: auto; height: var(--case-icone); display: flex;
               align-items: flex-end; justify-content: flex-start; }
.etape-icone .illustration-etape { height: 100%; width: auto; margin-left: -6px; }
.etape-icone img, .etape-icone svg { max-width: 100%; max-height: 100%;
                                     display: block; }

/* La jauge : l'avancée dans les huit étapes, d'un trait. Dimensions des
   maquettes (300 x 10), couleurs de Vigie. Elle ne s'anime pas — elle
   avance, c'est tout. */
.jauge-etapes { width: 224px; height: 10px; border-radius: 999px;
                background: #d9d9d9; overflow: hidden; }
.jauge-etapes span { display: block; height: 100%; border-radius: 999px;
                     background: var(--vert);
                     transition: width .4s cubic-bezier(.22, 1, .36, 1); }

/* Tout est aligné à gauche dans les étapes, comme sur les maquettes. */
/* LE TITRE DÉBORDE LA COLONNE, et c'est voulu : les maquettes du
   directeur le montrent plus large que les champs. « Où voulez-vous
   recevoir vos alertes ? » mesure 601 points au navigateur pour une
   colonne de 580 — sans ces 40 points de marge, il passerait à deux
   lignes et creuserait un trou sous tous les autres titres. */
/* `width: max-content` est indispensable : sans lui le titre reste
   large comme sa case (580) et `max-width` ne sert à rien. Avec, il
   prend la largeur de son texte, plafonnée à 620. */
.cadre-etape .titre-sombre { text-align: left; margin: 0;
                             width: max-content; max-width: 620px;
                             font-size: clamp(26px, 2.6vw, 33px);
                             line-height: 1.25; }
.cadre-etape .sous-sombre  { text-align: left; max-width: none; margin: 0;
                             font-size: 16px; line-height: 1.45; }

/* Hauteurs relevées sur la maquette. Une hauteur se mesure ; un
   rembourrage se devine — et c'est ainsi que les écrans finissent par
   ne plus se ressembler. */
.cadre-etape .champ-pilule { height: var(--haut-champ); padding: 0 26px;
                             text-align: left; }
.cadre-etape .bouton-vert,
.cadre-etape .bouton-fantome { height: var(--haut-bouton); padding: 0 30px;
                               font-size: 15.5px; }
.cadre-etape .bouton-fantome { min-width: 132px; flex: 0 0 auto; }
.cadre-etape .barre-boutons { gap: 19px; }

.duo-champs { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }

/* --- la liste déroulante intelligente -------------------------------- */

.liste { position: relative; }
.liste .champ-pilule { text-align: left; padding-left: 26px; }
.liste.avec-drapeau .champ-pilule { padding-left: 58px; }
.liste-vignette { position: absolute; left: 22px; top: 50%;
                  transform: translateY(-50%); width: 26px; height: 18px;
                  border-radius: 3px; object-fit: cover; display: none;
                  box-shadow: 0 0 0 1px rgba(255, 255, 255, .18); }
.liste-chevron { position: absolute; right: 22px; top: 50%;
                 transform: translateY(-50%); pointer-events: none;
                 color: #9aa197; transition: transform .15s; }
.liste.ouverte .liste-chevron { transform: translateY(-50%) rotate(180deg); }

/* La liste ouverte passe AU-DESSUS des champs et des boutons qui la
   suivent : sans cela, « Site web » et « Continuer » lui montaient
   dessus (signalé le 04/08/2026). */
.liste.ouverte { z-index: 60; }
.liste-choix {
  display: none; position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  /* QUATRE lignes visibles, le reste au défilement — une liste ne doit
     pas manger l'écran. */
  max-height: calc(4 * 44px + 12px); overflow-y: auto; z-index: 60;
  /* Le même fond que le menu de la langue — une seule matière pour
     tous les menus de Vigie. */
  background: #12150f; border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 18px; padding: 6px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .45);
  scrollbar-width: thin; scrollbar-color: #4a5142 transparent;
}
.liste.ouverte .liste-choix { display: block; animation: entre .18s ease-out both; }
.choix-ligne {
  width: 100%; display: flex; align-items: center; gap: 11px;
  padding: 10px 14px; border: none; border-radius: 12px; cursor: pointer;
  background: none; color: #e4e8e0; font: 500 14.5px "Inter", sans-serif;
  text-align: left;
}
.choix-ligne:hover, .choix-ligne.surligne { background: rgba(255, 255, 255, .09); }
.choix-drapeau { width: 24px; height: 17px; border-radius: 3px;
                 object-fit: cover; flex-shrink: 0;
                 box-shadow: 0 0 0 1px rgba(255, 255, 255, .16); }

/* Un pays hors liste : la ville se saisit librement, sans menu vide. */
.liste.sans-liste .liste-chevron { opacity: .3; }

@media (max-width: 620px) {
  .duo-champs { grid-template-columns: 1fr; }
}

/* Le bloc des champs empile ses lignes lui-même (le gabarit ne porte
   plus de style en dur : tout se règle ici). */

/* =====================================================================
   LA LISTE DE CHOIX DES ÉTAPES 2 ET 3 (maquettes du 05/08/2026)

   Chaque ligne est l'énoncé ET le bouton qui le prend. TROIS se voient,
   le reste s'atteint au défilement — barre à droite, fine et discrète,
   comme dans tous les menus de Vigie.

   Les puces vertes et leur menu déroulant ont disparu avec ce dessin :
   un seul geste (cliquer la ligne) remplace deux (ouvrir la liste,
   choisir), et l'on voit d'un coup d'œil ce qui est pris.
   ===================================================================== */

.choix-boite { display: flex; flex-direction: column; gap: var(--ecart-champs); }

.choix-liste {
  display: flex; flex-direction: column; gap: var(--ecart-choix);
  /* trois lignes visibles, pas une de plus */
  max-height: calc(3 * var(--haut-choix) + 2 * var(--ecart-choix));
  overflow-y: auto; padding-right: 12px;
  scrollbar-width: thin; scrollbar-color: #4a5142 transparent;
}
.choix-liste::-webkit-scrollbar { width: 8px; }
.choix-liste::-webkit-scrollbar-track { background: transparent; margin: 4px 0; }
.choix-liste::-webkit-scrollbar-thumb {
  background: #3d4437; border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
}
.choix-liste::-webkit-scrollbar-thumb:hover { background: #5c6555;
                                              background-clip: content-box; }

.choix-carte {
  flex: 0 0 auto; width: 100%; min-height: var(--haut-choix);
  display: flex; align-items: center; gap: 16px;
  padding: 0 26px; border-radius: 999px; text-align: left;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .10);
  color: #ffffff; font-family: "Inter", sans-serif; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.choix-carte:hover { background: rgba(255, 255, 255, .11); }

/* Pris : le vert de Vigie, du liseré jusqu'à la case. */
.choix-carte.pris {
  border-color: var(--vert);
  background: linear-gradient(90deg, rgba(136, 199, 59, .22),
                                     rgba(136, 199, 59, .07));
}
.choix-carte.pris:hover { background: linear-gradient(90deg,
                            rgba(136, 199, 59, .30), rgba(136, 199, 59, .10)); }

/* LA CASE GARDE SA PLACE MÊME VIDE. Sur la maquette elle n'apparaît que
   sur les lignes prises ; le texte y saute donc de trente pixels à
   chaque clic. On la laisse en place, vide et discrète : c'est le même
   dessin, sans le sursaut. */
.choix-case {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 7px;
  border: 1.6px solid rgba(255, 255, 255, .32);
  display: flex; align-items: center; justify-content: center;
  color: transparent;
  transition: background .15s, border-color .15s, color .15s;
}
.choix-case svg { width: 16px; height: 16px; }
.choix-carte.pris .choix-case { background: var(--vert); border-color: var(--vert);
                                color: #ffffff; }

.choix-texte { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.choix-nom { font-weight: 700; font-size: 15px; line-height: 1.25; }
.choix-aide { font-weight: 400; font-size: 13px; line-height: 1.3;
              color: #a7ae9f; }

/* Le champ libre, au bout de la liste : ce que Vigie ne propose pas. */
.choix-autre { position: relative; flex: 0 0 auto; }
/* Plus de bouton + dans le champ (20/10/2026) : le gros bouton vert de
   l'étape devient « Ajouter » tant que le champ est rempli. */
.choix-autre .champ-pilule { height: var(--haut-choix); padding: 0 26px;
                             text-align: left; }

/* « Plus tard » : discret, sous les boutons. */
.plus-tard { display: block; width: 100%; text-align: center; margin-top: 12px;
             background: none; border: none; cursor: pointer;
             color: #8f968b; font: 500 14.5px "Inter", sans-serif; }
.plus-tard:hover { color: #cbd2c6; text-decoration: underline;
                   text-underline-offset: 3px; }

/* =====================================================================
   LA BARRE DE DÉFILEMENT — visible, mais sobre. Elle vaut pour TOUS les
   menus dépliants de Vigie, ceux d'aujourd'hui et ceux à venir.
   ===================================================================== */

.liste-choix::-webkit-scrollbar,
.langue-choix::-webkit-scrollbar { width: 8px; }
.liste-choix::-webkit-scrollbar-track,
.langue-choix::-webkit-scrollbar-track { background: transparent; margin: 6px 0; }
.liste-choix::-webkit-scrollbar-thumb,
.langue-choix::-webkit-scrollbar-thumb {
  background: #3d4437; border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
  transition: background .15s;
}
.liste-choix::-webkit-scrollbar-thumb:hover,
.langue-choix::-webkit-scrollbar-thumb:hover { background: #5c6555;
                                               background-clip: content-box; }

/* Chaque ligne a une hauteur connue : c'est elle qui fait « quatre
   lignes visibles » ci-dessus. */
.choix-ligne, .popup-ligne { min-height: 44px; }

/* LA FLÈCHE DES CHAMPS DÉPLIANTS — c'est elle, et elle seule, qu'on
   clique pour dérouler : cliquer dans le champ sert à écrire. Le
   dessin fait douze pixels, on lui donne une cible de trente-quatre :
   personne ne vise douze pixels. Le script l'habille tout seul, y
   compris pour les listes à venir. */
.liste-fleche {
  position: absolute; right: 13px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border-radius: 50%; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 0; cursor: pointer;
  color: #9aa197; transition: background .15s, color .15s;
}
.liste-fleche:hover { background: rgba(255, 255, 255, .10); color: #ffffff; }
.liste-fleche .liste-chevron { position: static; transform: none; }
.liste.ouverte .liste-fleche .liste-chevron { transform: rotate(180deg); }

/* --- la langue, au bout à droite et plus discrète (04/08/2026) ------ */

.langue-du-bas { align-self: flex-end; margin: 0; }
.langue-du-bas .bouton-langue { font-size: 12px; gap: 6px; }
.langue-du-bas .bouton-langue .globe-langue { width: 14px; height: 14px; }
.langue-du-bas .bouton-langue .chevron { width: 10px; height: 10px; }
.langue-du-bas .langue-choix { left: auto; right: 0; transform: none;
                                min-width: 160px; }

/* =====================================================================
   L'ÉTAPE 4 — la recherche des sources.

   L'écran s'ouvre AVANT que la recherche ne soit finie : elle prend une
   à deux minutes. On montre donc qu'elle travaille, et les sources
   s'ajoutent au fil de l'eau — le directeur peut cocher les premières
   pendant que les suivantes arrivent.
   ===================================================================== */

.prospection-attente {
  display: flex; align-items: center; gap: 12px;
  color: #b9c0b4; font: 400 14.5px "Inter", sans-serif;
  min-height: 26px;
}
.prospection-attente b { color: var(--vert); font-weight: 700; }
.prospection-rond {
  width: 16px; height: 16px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .18);
  border-top-color: var(--vert);
  animation: tourne 1s linear infinite;
}
@keyframes tourne { to { transform: rotate(360deg); } }

.prospection-rien { margin: 0; color: #b9c0b4;
                    font: 400 14.5px "Inter", sans-serif; line-height: 1.5; }

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

/* =====================================================================
   L'ÉTAPE 5 — le canal des alertes.

   La liste des canaux est celle des pays (liste_intelligente.js), à une
   différence près : les logos sont CARRÉS. Le cadre des drapeaux les
   écraserait.
   ===================================================================== */

.liste-vignette-carree { width: 24px; height: 24px; border-radius: 6px;
                         object-fit: contain; box-shadow: none; }
.canal-liste.avec-drapeau .champ-pilule { padding-left: 60px;
                                          font-weight: 700; }

/* Un canal choisi se voit comme une ligne prise à l'étape 2 : c'est le
   même geste, ce doit être le même vert. */
.canal-liste .champ-pilule:not(:placeholder-shown) {
  border-color: var(--vert);
  background: linear-gradient(90deg, rgba(136, 199, 59, .22),
                                     rgba(136, 199, 59, .07));
}

.canal-note { margin: 0; color: #b9c0b4;
              font: 400 14.5px "Inter", sans-serif; line-height: 1.5; }
.canal-note b { color: var(--vert); font-weight: 700; word-break: break-all; }

/* =====================================================================
   L'ÉTAPE 6 — l'équipe.

   DEUX adresses se voient, les suivantes s'atteignent au défilement
   (règle du directeur, 05/08/2026). Le cadre des étapes est fixe : une
   liste qui s'allonge sans fin pousserait les boutons hors de l'écran.
   ===================================================================== */

.equipe-boite { display: flex; flex-direction: column; gap: 14px; }

.equipe-liste {
  display: flex; flex-direction: column; gap: var(--ecart-champs);
  /* TROIS adresses se voient (le directeur est passé de deux à trois
     le 05/08/2026) ; les suivantes s'atteignent au défilement. */
  max-height: calc(3 * var(--haut-champ) + 2 * var(--ecart-champs));
  overflow-y: auto; padding-right: 12px;
  scrollbar-width: thin; scrollbar-color: #4a5142 transparent;
}
.equipe-liste::-webkit-scrollbar { width: 8px; }
.equipe-liste::-webkit-scrollbar-track { background: transparent; margin: 4px 0; }
.equipe-liste::-webkit-scrollbar-thumb {
  background: #3d4437; border-radius: 999px;
  border: 2px solid transparent; background-clip: content-box;
}
.equipe-liste::-webkit-scrollbar-thumb:hover { background: #5c6555;
                                               background-clip: content-box; }
.equipe-champ { flex: 0 0 auto; }

.equipe-lien {
  display: flex; align-items: center; gap: 10px; align-self: flex-start;
  background: none; border: none; padding: 0; cursor: pointer;
  font: 500 14.5px "Inter", sans-serif;
}

/* Le lien d'invitation est en vert : c'est une action, pas une note. */
.equipe-lien { color: var(--vert); font-weight: 700; }
.equipe-lien:hover { text-decoration: underline; text-underline-offset: 4px; }
.equipe-lien.copie { color: #ffffff; }

/* =====================================================================
   LA DERNIÈRE ÉTAPE — elle enregistre, et ouvre.
   ===================================================================== */

.final { display: flex; align-items: center; gap: 14px;
         color: #b9c0b4; font: 400 15px "Inter", sans-serif; }
.final-rond {
  width: 20px; height: 20px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .18);
  border-top-color: var(--vert);
  animation: tourne 1s linear infinite;
}
.final.bloque .final-rond { animation: none; border-top-color: #b45309; }

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

/* =====================================================================
   LA DERNIÈRE PAGE — ni jauge, ni icône (maquette du 05/08/2026).

   Elle n'appartient plus au parcours : la barre est pleine dès la
   sixième étape. Ici, il n'y a plus rien à remplir — seulement un mot,
   le temps que Vigie mette les réponses en place.

   Elle quitte donc la grille des sept cases pour un simple bloc centré :
   rien ne vient après elle, il n'y a plus rien à aligner.
   ===================================================================== */

.cadre-etape.sans-entete {
  display: flex; flex-direction: column; justify-content: center;
  gap: 14px; min-height: 320px; height: auto;
}
.sans-entete .case-titre,
.sans-entete .case-amorce,
.sans-entete .case-champs { padding-top: 0; }
.sans-entete .case-champs { margin-top: 10px; justify-content: center; }
.sans-entete .case-plus-tard { display: none; }

/* Les boutons attendent en coulisse : ils ne paraissent que si
   l'enregistrement automatique échoue. */
.sans-entete .case-boutons { display: none; padding-top: 34px; }
.sans-entete:has(.final.bloque) .case-boutons { display: block; }

/* =====================================================================
   LES ILLUSTRATIONS DES ÉCRANS D'ENTRÉE — proposition B du directeur
   (20/10/2026) : la table de travail du matin, au-dessus du titre.
   Sur un petit écran, le panneau sombre devient un bandeau : elle s'y
   efface, pour que le formulaire reste près du haut.

   DEUXIÈME TOUR, même jour (planche : outils/planche_entree.py) :
   « animées », et « tout doit tenir en plein écran sans barre de
   défilement ». Les mouvements sont lents, en boucle, jamais
   clignotants ; ils s'arrêtent net quand Windows demande moins
   d'animations.
   ===================================================================== */
.illustration-entree { display: block; width: min(100%, 440px); height: auto; margin: 0 0 26px -8px; }
/* Seules les pièces animées tournent sur elles-mêmes : appliquée à tout,
   cette règle déplaçait les rotations écrites dans le dessin (graduations,
   aiguille des heures, clé). */
.illustration-entree [class*="a-"] { transform-box: fill-box; transform-origin: center; }

.illustration-entree .a-minute { transform-box: view-box; transform-origin: 396px 58px; animation: a-tour 24s linear infinite; }
@keyframes a-tour { from { transform: rotate(180deg); } to { transform: rotate(540deg); } }
.illustration-entree .a-vapeur { animation: a-vapeur 3.2s ease-in-out infinite; }
.illustration-entree .v2 { animation-delay: .8s; }
@keyframes a-vapeur { 0%, 100% { opacity: .2; transform: translateY(4px); } 50% { opacity: 1; transform: translateY(-4px); } }
.illustration-entree .a-voyant { animation: a-voyant 2.4s ease-in-out infinite; }
@keyframes a-voyant { 50% { opacity: .35; } }
.illustration-entree .a-case { animation: a-case 6s ease-in-out infinite; }
.illustration-entree .c2 { animation-delay: 2s; }
.illustration-entree .c3 { animation-delay: 4s; }
@keyframes a-case { 0%, 30%, 100% { fill: #f3f4f1; } 8%, 22% { fill: #e2f2cf; } }
.illustration-entree .a-ligne { transform-origin: left center; animation: a-ligne 6s ease-out infinite; }
.illustration-entree .l2 { animation-delay: .3s; }
.illustration-entree .l3 { animation-delay: .6s; }
@keyframes a-ligne { 0% { transform: scaleX(0); } 18%, 92% { transform: scaleX(1); } 100% { transform: scaleX(1); opacity: 0; } }
.illustration-entree .a-coche { animation: a-pop .7s .6s cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes a-pop { from { transform: scale(0); } to { transform: scale(1); } }
.illustration-entree .a-trait { stroke-dasharray: 44; animation: a-trace .5s 1.1s ease-out both; }
@keyframes a-trace { from { stroke-dashoffset: 44; } to { stroke-dashoffset: 0; } }
.illustration-entree .a-onde { opacity: 0; animation: a-onde 3s 1.4s ease-out infinite; }
@keyframes a-onde { 0% { opacity: .8; transform: scale(1); } 100% { opacity: 0; transform: scale(1.7); } }
/* Les autres écrans : un geste chacun. */
.illustration-entree .a-point-code { animation: a-respire 2.4s ease-in-out infinite; }
.illustration-entree .a-place { animation: a-respire 2.4s ease-in-out infinite; }
@keyframes a-respire { 50% { transform: scale(1.12); } }
.illustration-entree .a-cadenas { animation: a-balance 3s ease-in-out infinite; }
.illustration-entree .a-cle { animation: a-balance 3s ease-in-out infinite; }
@keyframes a-balance { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(-6deg); } }

/* Créer un compte : l'espace qui se monte (choix « A » du directeur). Les
   briques tombent l'une après l'autre, restent, s'effacent, recommencent ;
   la barre se remplit avec elles. */
.illustration-entree .a-brique { animation: a-chute 8s cubic-bezier(.3, .8, .4, 1) infinite; }
.illustration-entree .b2 { animation-delay: .5s; }
.illustration-entree .b3 { animation-delay: 1s; }
@keyframes a-chute { 0% { transform: translateY(-150px); opacity: 0; } 6% { opacity: 1; }
  14% { transform: translateY(5px); } 18%, 88% { transform: translateY(0); opacity: 1; }
  96%, 100% { transform: translateY(0); opacity: 0; } }
.illustration-entree .a-progres { transform-origin: left center; animation: a-progres 8s ease-in-out infinite; }
@keyframes a-progres { 0%, 4% { transform: scaleX(0); } 30%, 92% { transform: scaleX(1); } 100% { transform: scaleX(1); opacity: 0; } }
.illustration-entree .a-fanion { transform-origin: left center; animation: a-fanion 2.6s ease-in-out infinite; }
@keyframes a-fanion { 0%, 100% { transform: skewY(0); } 50% { transform: skewY(-5deg); } }
.illustration-entree .a-etincelle { opacity: 0; animation: a-etincelle 2.8s ease-in-out infinite; }
.illustration-entree .e2 { animation-delay: .7s; }
.illustration-entree .e3 { animation-delay: 1.4s; }
.illustration-entree .e4 { animation-delay: 2.1s; }
@keyframes a-etincelle { 0%, 100% { opacity: 0; transform: scale(.4) rotate(0); } 50% { opacity: 1; transform: scale(1) rotate(45deg); } }

@media (prefers-reduced-motion: reduce) {
  .illustration-entree *, .illustration-entree { animation: none !important; }
  .illustration-entree .a-onde, .illustration-entree .a-etincelle { opacity: 0; }
  /* Sans l'animation, l'aiguille des minutes pointait midi : 6 h 00 à
     côté de « 6 h 30 ». */
  .illustration-entree .a-minute { transform: rotate(180deg); }
}

/* TOUT TIENT DANS LA FENÊTRE, SANS DÉFILER : sur un grand écran, les
   deux panneaux prennent exactement la hauteur de la fenêtre, et
   l'illustration, le titre et les champs se règlent sur elle — de 640
   à 1080 pixels de haut. La fenêtre du directeur (1280 × 720) en est la
   mesure. */
@media (min-width: 941px) {
  .scinde { height: 100vh; min-height: 0; }
  .panneau-sombre, .panneau-clair { height: 100vh; min-height: 0; overflow-y: auto; }
  .panneau-sombre { padding: clamp(22px, 4.5vh, 52px) clamp(30px, 4.2vw, 56px) clamp(16px, 3vh, 36px); }
  .panneau-sombre .marque { width: clamp(40px, 6.4vh, 66px); height: auto; }
  .illustration-entree { width: auto; max-width: 100%; height: clamp(130px, 31vh, 290px);
                         margin: 0 0 clamp(10px, 2.4vh, 24px) -8px; }
  .panneau-sombre h1 { font-size: clamp(20px, min(2.1vw, 3.9vh), 34px); line-height: 1.3;
                       margin-bottom: clamp(12px, 2.6vh, 28px); }
  .panneau-sombre .question, .panneau-sombre .question-lien { font-size: clamp(13.5px, 2vh, 15.5px); }
  .panneau-sombre .mentions { margin-top: clamp(10px, 2vh, 18px); font-size: 11.5px; line-height: 1.55; }
  .panneau-clair { padding: clamp(26px, 6vh, 64px) 40px clamp(14px, 3vh, 28px); }
  .panneau-clair .logotype { height: clamp(38px, 6.8vh, 58px); margin-bottom: clamp(14px, 3.6vh, 48px); }
  .panneau-clair .formulaire, .panneau-clair .formulaire form { gap: clamp(10px, 1.9vh, 18px) !important; }
  /* Les champs et boutons des écrans d'entrée seulement : le parcours
     garde la hauteur de sa maquette. */
  .panneau-clair .champ-pilule, .panneau-clair .bouton-vert {
    padding-top: clamp(11px, 2.1vh, 17px); padding-bottom: clamp(11px, 2.1vh, 17px); }
  .panneau-clair .bouton-blanc { padding-top: clamp(10px, 1.9vh, 15px); padding-bottom: clamp(10px, 1.9vh, 15px); }
}
@media (max-width: 940px) {
  .illustration-entree { display: none; }
}

/* =====================================================================
   LES SCÈNES ANIMÉES DU PARCOURS — à la place des icônes (directeur,
   20/10/2026 ; planche : outils/planche_parcours.py). Une par étape
   (templates/_illustrations_parcours.html) : l'immeuble et l'épingle, la
   loupe sur le dossier, la cloche, le radar, le téléphone et ses canaux,
   l'invitation qui vole. Lentes, en boucle, arrêtées quand Windows
   demande moins d'animations.
   ===================================================================== */
.illustration-etape [class*="p-"] { transform-box: fill-box; transform-origin: center; }
.illustration-etape .p-flotte { animation: p-flotte 3s ease-in-out infinite; }
@keyframes p-flotte { 50% { transform: translateY(-4px); } }
.illustration-etape .p-fenetre { animation: p-fenetre 4s ease-in-out infinite; }
@keyframes p-fenetre { 0%, 40%, 100% { fill: #dfe3d8; } 10%, 25% { fill: #88c73b; } }
.illustration-etape .p-epingle { animation: p-epingle 2.4s cubic-bezier(.4, 0, .6, 1) infinite; }
@keyframes p-epingle { 0%, 100% { transform: translateY(0); } 45% { transform: translateY(-12px); } 60% { transform: translateY(0); } 70% { transform: translateY(-3px); } }
.illustration-etape .p-ombre { animation: p-ombre 2.4s cubic-bezier(.4, 0, .6, 1) infinite; }
@keyframes p-ombre { 0%, 100% { transform: scale(1); opacity: 1; } 45% { transform: scale(.55); opacity: .5; } 60% { transform: scale(1); } }
.illustration-etape .p-carte { animation: p-flotte 3.2s ease-in-out infinite; }
.illustration-etape .k2 { animation-delay: 1.6s; }
.illustration-etape .p-loupe { animation: p-loupe 4s ease-in-out infinite alternate; }
@keyframes p-loupe { 0% { transform: translate(-14px, -12px); } 50% { transform: translate(8px, 6px); } 100% { transform: translate(-6px, 18px); } }
.illustration-etape .p-coche { animation: p-coche 4s ease-out infinite; }
@keyframes p-coche { 0%, 30% { transform: scale(0); } 38% { transform: scale(1.2); } 44%, 92% { transform: scale(1); } 100% { transform: scale(0); } }
.illustration-etape .p-cloche { transform-box: view-box; transform-origin: 120px 24px; animation: p-cloche 2.4s ease-in-out infinite; }
@keyframes p-cloche { 0%, 55%, 100% { transform: rotate(0); } 8% { transform: rotate(14deg); } 18% { transform: rotate(-12deg); } 28% { transform: rotate(8deg); } 38% { transform: rotate(-5deg); } 46% { transform: rotate(2deg); } }
.illustration-etape .p-onde { animation: p-onde 2.4s ease-out infinite; }
@keyframes p-onde { 0%, 55%, 100% { opacity: 0; transform: scale(.9); } 10% { opacity: 1; } 40% { opacity: 0; transform: scale(1.15); } }
.illustration-etape .p-puce { animation: p-puce 6s ease-out infinite; }
.illustration-etape .q2 { animation-delay: .7s; }
.illustration-etape .q3 { animation-delay: 1.4s; }
@keyframes p-puce { 0% { transform: scale(0); opacity: 0; } 8% { transform: scale(1.1); opacity: 1; } 12%, 84% { transform: scale(1); opacity: 1; } 94%, 100% { transform: scale(1); opacity: 0; } }
.illustration-etape .p-balai { transform-box: view-box; transform-origin: 120px 56px; animation: p-balai 4s linear infinite; }
@keyframes p-balai { to { transform: rotate(360deg); } }
.illustration-etape .p-halo { opacity: 0; animation: p-halo 4s ease-out infinite; }
@keyframes p-halo { 0% { opacity: 1; transform: scale(1); } 25% { opacity: 0; transform: scale(1.7); } 100% { opacity: 0; } }
.illustration-etape .p-source { animation: p-source 4s ease-out infinite; }
@keyframes p-source { 0% { fill: #88c73b; } 30%, 100% { fill: #f4f6f1; } }
.illustration-etape .p-ecran { animation: p-ecran 1.5s ease-in-out infinite; }
@keyframes p-ecran { 50% { opacity: .4; } }
.illustration-etape .p-bulle { animation: p-bulle 6s cubic-bezier(.3, .8, .4, 1) infinite; }
.illustration-etape .b2 { animation-delay: .5s; }
.illustration-etape .b3 { animation-delay: 1s; }
.illustration-etape .b4 { animation-delay: 1.5s; }
@keyframes p-bulle { 0% { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; }
  12% { transform: translate(0, 0) scale(1.08); opacity: 1; } 16%, 86% { transform: translate(0, 0) scale(1); opacity: 1; }
  96%, 100% { transform: translate(0, 0) scale(1); opacity: 0; } }
.illustration-etape .p-place { animation: p-place 2.4s ease-in-out infinite; }
@keyframes p-place { 50% { transform: scale(1.1); } }
.illustration-etape .p-vol { animation: p-vol 4s ease-in-out infinite; }
@keyframes p-vol { 0% { transform: translate(0, 0); opacity: 0; } 10% { opacity: 1; }
  40% { transform: translate(80px, -14px) rotate(-6deg); } 70% { transform: translate(157px, 28px) scale(.6); opacity: 1; }
  78%, 100% { transform: translate(157px, 28px) scale(.6); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .liste.ouverte .liste-choix { animation: none; }
  .illustration-etape *, .illustration-etape { animation: none !important; }
  .illustration-etape .p-halo { opacity: 0; }
}

/* =====================================================================
   L'ENTRÉE DE VIGIE SUR TÉLÉPHONE (directeur, 22/10/2026 : « identique
   au logiciel mais adapté au téléphone » ; planche validée). Sur un
   ordinateur, rien ne change.
   ===================================================================== */
@media (max-width: 640px) {
  /* ── CONNEXION, CRÉATION DE COMPTE, CODE : comme sur l'ordinateur,
     l'illustration et le titre sur le fond sombre, puis le formulaire
     sur une feuille blanche qui monte du bas ; les mentions au pied. ── */
  .scinde { flex-direction: column; min-height: 100dvh;
            background: url("fond-sombre.jpg") center top / cover no-repeat #030503; }
  .panneau-sombre { display: contents; }
  .panneau-sombre .marque { display: none; }
  .panneau-sombre .parole { order: 1; margin: 0; max-width: none; color: #fff;
                            padding: max(18px, env(safe-area-inset-top)) 24px 22px; }
  .illustration-entree { display: block; width: 100%; max-width: 300px; height: auto; margin: 0 auto 6px; }
  .panneau-sombre h1 { font-size: 22px; line-height: 1.3; margin: 0 0 12px; }
  .panneau-sombre .question, .panneau-sombre .question-lien { font-size: 15px; }
  .panneau-clair { order: 2; flex: 1; width: 100%; min-height: 0; background: #fff;
                   border-radius: 24px 24px 0 0; padding: 26px 22px 14px; }
  .panneau-clair .logotype { display: none; }
  .panneau-clair .formulaire { margin: 0; }
  .panneau-clair .champ-pilule { font-size: 16px; }
  .panneau-clair .langue { margin-top: 18px; }
  .panneau-sombre .mentions { order: 3; display: block; background: #fff; color: #8a9087; text-align: center;
                              font-size: 11px; line-height: 1.5; padding: 0 22px calc(14px + env(safe-area-inset-bottom)); }
  .panneau-sombre .mentions a { color: #6f757c; }

  /* ── LE PARCOURS D'INSTALLATION. LA CAUSE DU DÉBORDEMENT (vue à
     l'aperçu, 22/10/2026) : la grille n'avait pas de colonne fixée, et
     un élément large l'élargissait au-delà de l'écran. Au téléphone, les
     cases s'empilent ; les titres passent à la ligne ; « Retour » et
     « Continuer » tiennent le bas de l'écran, côte à côte. ── */
  .scene-sombre { min-height: 100dvh; gap: 12px; padding: max(14px, env(safe-area-inset-top)) 20px 12px; }
  .scene-sombre > .cadre-etape { margin-block: 0; flex: 1; }
  .cadre-etape { grid-template-columns: minmax(0, 1fr); display: flex; flex-direction: column; min-height: 0; }
  .etape-icone { height: 84px; }
  .case-titre { padding-top: 22px; }
  .cadre-etape .titre-sombre { font-size: 24px; line-height: 1.25; width: auto; max-width: 100%; }
  .case-amorce { padding-top: 8px; }
  .cadre-etape .sous-sombre { font-size: 15px; }
  .case-champs { padding-top: 22px; justify-content: flex-start; }
  .case-champs .champ-pilule { font-size: 16px; }
  .case-boutons { position: sticky; bottom: 0; z-index: 40; margin-top: auto;
                  padding: 18px 0 calc(8px + env(safe-area-inset-bottom));
                  background: linear-gradient(rgba(3, 5, 3, 0), rgba(3, 5, 3, .92) 34%); }
  .cadre-etape .barre-boutons { flex-direction: row; gap: 10px; }
  .cadre-etape .bouton-vert, .cadre-etape .bouton-fantome { height: 56px; }
  .cadre-etape .barre-boutons .bouton-fantome { flex: none; min-width: 0; padding: 0 18px; }
  .cadre-etape .barre-boutons .bouton-vert { flex: 1; min-width: 0; }
  .case-plus-tard { padding-top: 4px; text-align: center; }
}

/* ── LA DÉCOUVERTE (templates/decouvrir.html) : trois écrans qu'on fait
   glisser du doigt — un défilement aimanté, sans script. ── */
.decouvrir { min-height: 100dvh; color: #fff; font-family: "Inter", sans-serif;
             background: url("fond-sombre.jpg") center / cover no-repeat #030503; }
.decouvrir .diapos { display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
                     scrollbar-width: none; min-height: 100dvh; }
.decouvrir .diapos::-webkit-scrollbar { display: none; }
.decouvrir .diapo { flex: 0 0 100%; scroll-snap-align: start; display: flex; flex-direction: column;
                    min-height: 100dvh; background: rgba(0, 0, 0, .35);
                    padding: max(14px, env(safe-area-inset-top)) 24px calc(18px + env(safe-area-inset-bottom)); }
.decouvrir .haut-decouvrir { display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
.decouvrir .haut-decouvrir img { width: 34px; height: 34px; }
.decouvrir .passer { color: #c9d0c4; font-size: 15px; text-decoration: none; padding: 10px 0; }
.decouvrir .corps-diapo { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.decouvrir .scene-decouvrir { display: flex; justify-content: center; margin-bottom: 26px; }
.decouvrir .scene-decouvrir svg { width: 100%; max-width: 330px; height: auto; margin: 0; }
.decouvrir h1 { font-family: "Nexa Pro", "Inter", sans-serif; font-weight: 800; font-size: 27px; line-height: 1.2; margin: 0 0 12px; }
.decouvrir p { font-size: 16px; line-height: 1.55; color: #c9d0c4; margin: 0; }
.decouvrir .points { display: flex; gap: 6px; margin: 26px 0 22px; }
.decouvrir .points i { width: 8px; height: 8px; border-radius: 4px; background: rgba(255, 255, 255, .3); }
.decouvrir .points i.ici { width: 26px; background: var(--vert); }
.decouvrir .actions { display: flex; flex-direction: column; gap: 10px; }
.decouvrir .actions a { display: flex; align-items: center; justify-content: center; min-height: 54px; border-radius: 999px;
                        font-weight: 700; font-size: 16px; text-decoration: none; }
.decouvrir .actions .bouton-vert { width: 100%; }
.decouvrir .actions .bouton-contour { border: 1.5px solid rgba(255, 255, 255, .35); color: #fff; }
@media (prefers-reduced-motion: no-preference) { .decouvrir .diapos { scroll-behavior: smooth; } }

/* LA FENÊTRE DU BAS (directeur, 31/10/2026) : au format téléphone, les listes
   du parcours (le pays et ses drapeaux, la ville, le canal) montent du bas,
   sur toute la largeur, au-dessus d'un voile. */
@media (max-width: 640px) {
  /* Le fondu d'entrée laisse une transformation sur la case : elle enfermerait
     la fenêtre dans la case au lieu de la poser sur l'écran. */
  .case-champs.anime:has(.liste.ouverte) { animation: none; transform: none; z-index: 100; }
  .scene-sombre:has(.liste.ouverte) > .langue-du-bas { visibility: hidden; }
  .liste.ouverte::before { content: ""; position: fixed; inset: 0; z-index: 90; background: rgba(0, 0, 0, .55); }
  .liste.ouverte .liste-choix {
    position: fixed; z-index: 91; top: auto; left: 0; right: 0; bottom: 0;
    max-height: 70dvh; border: 0; border-radius: 28px 28px 0 0;
    padding: 34px 16px calc(16px + env(safe-area-inset-bottom));
    animation: monte-du-bas .22s cubic-bezier(.22, 1, .36, 1);
  }
  .liste.ouverte .liste-choix::before {
    content: ""; position: absolute; top: 12px; left: 50%; width: 44px; height: 5px;
    margin-left: -22px; border-radius: 999px; background: rgba(255, 255, 255, .24);
  }
  .liste.ouverte .choix-ligne { min-height: 54px; border-radius: 16px; font-size: 16px; }
}
@keyframes monte-du-bas { from { transform: translateY(40%); } }

/* L'INSCRIPTION ET LE PARCOURS, UN PEU PLUS PETITS (directeur, 31/10/2026) :
   tout tient mieux, et la liste prend la place au lieu de laisser un trou
   entre elle et les boutons. */
@media (max-width: 640px) {
  :root { --haut-champ: 50px; --haut-choix: 52px; --ecart-choix: 10px; }
  .etape-icone { height: 62px; }
  .jauge-etapes { height: 8px; }
  .case-titre { padding-top: 14px; }
  .cadre-etape .titre-sombre { font-size: 22px; }
  .cadre-etape .sous-sombre { font-size: 14.5px; }
  .case-champs { padding-top: 14px; gap: 12px; }
  .choix-liste { max-height: max(calc(3 * var(--haut-choix) + 2 * var(--ecart-choix)), calc(100dvh - 330px)); }
  .cherche .choix-liste { max-height: max(calc(3 * var(--haut-choix)), calc(100dvh - 370px)); }
  .cadre-etape .bouton-vert, .cadre-etape .bouton-fantome { height: 52px; }
  .case-boutons { padding-top: 12px; }
  .illustration-entree { max-width: 215px; }
  .panneau-sombre .parole { padding: max(10px, env(safe-area-inset-top)) 24px 12px; }
  .panneau-sombre h1 { font-size: 19px; margin-bottom: 8px; }
  .panneau-clair { padding: 18px 22px 10px; }
  .panneau-clair .formulaire, .panneau-clair .formulaire form { gap: 12px !important; }
  .panneau-clair .champ-pilule, .panneau-clair .bouton-vert { padding-top: 14px; padding-bottom: 14px; }
  .panneau-clair .bouton-blanc { padding-top: 12px; padding-bottom: 12px; }
}
