/* ==========================================================================
   Magellus — feuille de style du site public
   Les couleurs viennent de la charte graphique Magellus (design system v1).
   Deux thèmes : Nuit (référence) et Jour.
   ========================================================================== */

/* --- La police de marque -------------------------------------------------

   Michroma, la police du mot-symbole. Le fichier SVG de includes/motsymbole.php
   n'est rien d'autre que « MAGELLUS » composé ici puis vectorisé : la même
   hauteur de capitale (1536 sur 2048), le même approche gauche du M (196).
   Ce qui est écrit en Michroma sur la page est donc dans la même main que le
   logo, au pixel près.

   Hébergée ici et nulle part ailleurs. La politique de sécurité du site dit
   « font-src 'self' » : un appel à Google Fonts serait refusé par le
   navigateur, et le texte retomberait sur la police système sans que rien ne
   le signale. Aucun en-tête à changer, le .htaccess sert déjà les woff2 avec
   une année de cache.

   Une seule graisse existe, 400. Partout où Michroma s'applique, plus bas,
   font-weight vaut donc 400 : demander 600 ou 700 ferait épaissir les traits
   par le navigateur lui-même, et une grasse fabriquée sur une police aussi
   large se voit au premier coup d'œil.

   Sous-ensemble sur mesure (12 ko) : lettres, chiffres, accents français et
   ponctuation courante. Mesuré le 28 septembre 2026 — le latin complet pesait
   18 ko pour 41 caractères réellement rendus sur les neuf pages. Les caractères
   hors de cette plage retombent sur la police système, lettre par lettre.

   Le nom du fichier change à chaque modification de la police : le .htaccess
   la sert avec un an de cache, donc réécrire le même nom laisserait les
   visiteurs sur l'ancienne version pendant un an.

   SIL Open Font License 1.1 ; la licence accompagne le fichier, dans
   assets/fonts/OFL.txt.
   ------------------------------------------------------------------------- */

@font-face {
  font-family: "Michroma";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/michroma-subset-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- Jetons ------------------------------------------------------------- */

:root {
  /* Couleurs — thème Nuit par défaut */
  --ground: #08101f;
  --ground-rgb: 8, 16, 31;
  --ground-deep: #0d2433;
  --glass: #1a2638d9;
  --glass-edge: #ffffff26;
  --hairline: #ffffff1f;
  --ink: #eef3fa;
  --ink-muted: #9aa8bd;
  --route: #3fd0c0;
  --route-rgb: 63, 208, 192;
  --route-soft: #0f3a3c;
  --route-ink: #3fd0c0;

  /* Les trois voies. Rapide et Découverte sont des alias : la même teinte
     que la route et que la trace, dans les deux thèmes. Économe a la
     sienne, le violet Milka. Une voie garde sa couleur partout où elle est
     nommée, et son nom est toujours écrit à côté. */
  --voie-rapide: var(--route);
  --voie-decouverte: var(--trail);
  --voie-econome: #9a87cf;

  /* Le rouge des actions qui effacent. */
  --danger: #ff9494;
  --on-route: #04201e;
  --route-alt: #6b7a90;
  --trail: #e8a33d;
  --trail-rgb: 232, 163, 61;
  --trail-soft: #3a2a12;
  --trail-ink: #e8a33d;
  --stop: #ff6b5e;
  --on-stop: #1a0503;
  --globe: #5e99e6;
  --space: #02040b;

  /* Surfaces propres au site */
  --surface: #131f30;
  --surface-edge: #ffffff14;

  /* Les tracés sur une carte. Toujours par ces noms, jamais par --route ou
     --route-alt directement : le turquoise est la route à faire, l'ambre le
     chemin parcouru, jamais la route à suivre (Rafael, 06.11.2026, charte v79). Le bouchon et la
     route fermée restent en rouge, comme avant. */
  --itineraire: var(--route);
  --itineraire-parcouru: var(--trail);
  --trafic-bouchon: var(--stop);
  --route-fermee: var(--stop);

  /* Réservé à la flèche de navigation et au point d'Exploration. */
  --route-deep: #2a9e92;

  /* L'anneau du focus clavier : un liseré de fond, puis la route. */
  --focus-ring: 0 0 0 2px #08101f, 0 0 0 4px #3fd0c0;

  /* Traits */
  --stroke-route: 8px;
  --stroke-hairline: 1px;
  --stroke-fermee: 6 14;

  /* Espacements */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 56px;
  --space-16: 80px;
  --space-20: 120px;

  /* Rayons */
  --radius-row: 18px;
  --radius-control: 24px;
  --radius-panel: 28px;
  --radius-full: 9999px;

  /* Typographie */
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
  --rounded: ui-rounded, "SF Pro Rounded", -apple-system, system-ui, sans-serif;

  /* La police de marque. La pile de secours s'affiche pendant le chargement
     et sur les caractères que Michroma ne couvre pas. */
  --display: "Michroma", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* Mise en page */
  --largeur: 1200px;
  --gouttiere: 24px;

  /* Hauteur de la barre supérieure. Le héros remonte d'autant pour
     occuper l'écran entier sous une barre qui reste translucide. */
  --entete-h: 88px;

  /* Mouvement. Une seule courbe, celle que le site employait déjà : un
     départ franc et une arrivée longue, comme un objet qui se pose. Trois
     durées, pas davantage — au-delà de 400 ms, une interface fait attendre. */
  --courbe: cubic-bezier(0.22, 1, 0.36, 1);
  --duree-breve: 150ms;
  --duree: 250ms;
  --duree-ample: 400ms;

  /* Profondeur. La seule ombre du système, réservée à ce qui flotte
     au-dessus du reste : menus, panneaux posés sur la carte. */
  --ombre: 0 18px 40px #00000040;

  color-scheme: dark;
}

:root[data-theme="light"] {
  --ground: #f5f8fb;
  --ground-rgb: 245, 248, 251;
  --ground-deep: #e2eef1;
  --glass: #ffffffd1;
  --glass-edge: #0b15261a;
  --hairline: #0b15261f;
  --ink: #0b1526;
  --ink-muted: #4d5b70;
  --route: #0a7770;
  --route-rgb: 10, 119, 112;
  --route-soft: #ddf4f0;
  --route-ink: #06534f;

  /* Économe, assombri pour le thème clair. Rapide et Découverte suivent
     --route et --trail, déjà assombries plus haut. */
  --voie-econome: #7360a5;

  /* Assombri : le rouge du thème sombre tombe à 3,3 sur fond clair. */
  --danger: #b3261e;
  --on-route: #ffffff;
  --route-alt: #7a8799;
  --trail: #a15f0a;
  --trail-rgb: 161, 95, 10;
  --trail-soft: #fdf4e6;
  --trail-ink: #7f4a06;
  --stop: #c8321f;
  --on-stop: #ffffff;
  --globe: #3c6fc8;

  --surface: #ffffff;
  --surface-edge: #0b152614;

  --route-deep: #075a55;
  --focus-ring: 0 0 0 2px #f5f8fb, 0 0 0 4px #0a7770;
  /* Sur fond clair, une ombre noire salit : elle prend la teinte de l'encre. */
  --ombre: 0 18px 40px #0b15261f;

  color-scheme: light;
}

/* --- Base ---------------------------------------------------------------- */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--duree-ample) var(--courbe), color var(--duree-ample) var(--courbe);
}

/* Le pied de page en bas de la fenêtre quand la page est courte
   (26 octobre 2026, demande de Rafael) : le contenu prend la place qui
   reste, sans rien fixer à l'écran. Une page longue défile comme avant. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

#contenu { flex: 1 0 auto; }

h1, h2, h3 {
  margin: 0;
  line-height: 1.1;
  letter-spacing: -0.022em;
  font-weight: 700;
  text-wrap: balance;
}

h1 { font-size: clamp(38px, 6.2vw, 76px); }
h2 { font-size: clamp(28px, 4vw, 46px); }
h3 { font-size: clamp(20px, 2.2vw, 26px); letter-spacing: -0.012em; }

p { margin: 0; }

a {
  color: var(--route);
  text-decoration-color: color-mix(in srgb, var(--route) 45%, transparent);
  text-underline-offset: 3px;
}
a:hover { text-decoration-color: currentColor; }

ul { margin: 0; padding: 0; list-style: none; }

img, svg { display: block; max-width: 100%; }

/* L'anneau de la charte : un liseré couleur du fond, puis 2 px de route.
   Une ombre plutôt qu'un contour, pour qu'il suive l'arrondi de l'élément
   sans avoir à lui en imposer un. Le contour transparent reste pour le
   mode Contraste élevé de Windows, qui efface les ombres et dessine les
   contours. */
:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}

.saut {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: var(--space-3) var(--space-5);
  background: var(--route);
  color: var(--on-route);
  border-radius: 0 0 var(--radius-control) 0;
  font-weight: 600;
  z-index: 100;
}
.saut:focus { left: 0; }

/* --- Conteneurs ---------------------------------------------------------- */

.conteneur {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.section { padding-block: clamp(64px, 9vw, 128px); }

/* La barre du haut est fixée : sans cette marge, un lien d'ancre déposerait
   le titre de la section juste dessous, à moitié caché. */
[id] { scroll-margin-top: calc(var(--entete-h) + var(--space-4)); }
.section--serree { padding-block: clamp(48px, 6vw, 80px); }

.section__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 720px;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.section__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: clamp(32px, 4vw, 48px);
}

.surtitre {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--route);
}

.chapeau {
  font-size: clamp(18px, 2.1vw, 22px);
  line-height: 1.5;
  color: var(--ink-muted);
  text-wrap: pretty;
}

/* --- Logo ---------------------------------------------------------------- */

/* Le logo validé le 11 octobre 2026 : lettres à l'encre, trajectoire en
   route. Ni trait ni épaississement : le fichier fait foi. Largeur
   minimale 96 px. */
.motsymbole {
  width: 148px;
  height: auto;
  color: var(--ink);
  fill: currentColor;
}
.motsymbole__trajectoire { fill: var(--route); }
.motsymbole--pied { width: 168px; }

/* --- Boutons ------------------------------------------------------------- */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  /* Trois hauteurs, pas une de plus (Graphiste, 13 octobre 2026) :
     moyen 40 px par défaut — actions secondaires, en-tête —, grand 48 px
     pour l'action principale (.bouton--principal), petit 32 px
     (.bouton--petit). Sous 640 px, la zone de clic remonte à 44 px.
     Le line-height à 1 empêche la hauteur de dépendre de la police. */
  min-height: 40px;
  padding: 0 var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--duree-breve) var(--courbe), background-color var(--duree) var(--courbe), border-color var(--duree) var(--courbe);
}
.bouton:active { transform: translateY(1px); }

.bouton--principal {
  min-height: 48px;
  padding: 0 var(--space-6);
  font-size: 17px;
  background: var(--route);
  color: var(--on-route);
}

.bouton--petit {
  min-height: 32px;
  padding: 0 var(--space-3);
  font-size: 13px;
}

@media (max-width: 640px) {
  .bouton,
  .bouton--discret { min-height: 44px; }
}

/* L'action d'une ligne ou d'une carte — « Modifier », « + Ajouter un
   véhicule » : un lien texte, jamais une pastille (charte, et Graphiste,
   règle G2). La zone de clic garde 44 px de haut sans rien dessiner. */
.lien-action {
  /* Calé sur la ligne du nom (R1) : la boîte a la hauteur du texte, et la
     zone de clic de 44 px vient du ::after, en débord invisible. */
  position: relative;
  display: inline-flex;
  align-items: center;
  align-self: start;
  padding: 0;
  border: 0;
  background: none;
  /* --route et non --route-ink : sur une surface, c'est la couleur des
     liens de la charte (5,3:1 en Jour). --route-ink, plus sombre, ne se
     lisait plus comme un lien. */
  color: var(--route);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  list-style: none;
}
.lien-action::-webkit-details-marker { display: none; }
.lien-action::after { content: ""; position: absolute; inset: -12px -8px; }
.carte .fiche__nom,
.carte .lieux__nom { color: var(--ink); }   /* R2 : le nom à l'encre, le détail en muted */
.lieux td:first-child { padding-right: var(--space-4); }   /* R3 */
.lien-action:hover { text-decoration: underline; text-underline-offset: 3px; }
.lien-action--danger { color: var(--danger); }
.bouton--principal:hover { background: color-mix(in srgb, var(--route) 85%, var(--ink)); }

.bouton--second {
  background: transparent;
  border-color: var(--glass-edge);
  color: var(--ink);
}
.bouton--second:hover { border-color: var(--route); color: var(--route); }

/* --- En-tête ------------------------------------------------------------- */

.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter: saturate(160%) blur(16px);
  border-bottom: 1px solid var(--hairline);
}

.entete__barre {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding: var(--space-4) var(--gouttiere);
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* Le tracé du mot-symbole fait 15 px de haut pour 148 de large : sans
   hauteur minimale, le lien vers l'accueil est une cible tactile de 15 px,
   sous les 24 px exigés et loin des 44 px recommandés sur iPhone. Les 44 px
   tiennent sans rien déplacer — la barre fait 77 px de haut sur téléphone —
   et `align-items: center` garde le logo à sa place. */
.entete__marque {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  min-height: 44px;
}

/* beta.magellus.ch : la version testée se signale à côté du logo, sur
   toutes les pages (28 octobre 2026). Même pastille que .marque-plus,
   en couleur d'alerte pour ne pas la confondre avec l'offre payante. */
.entete__beta {
  margin-left: var(--space-2);
  padding: 3px 9px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--stop) 14%, transparent);
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.entete__nav { flex-grow: 1; }

.entete__liste {
  display: flex;
  gap: var(--space-6);
}
.entete__liste a {
  color: var(--ink-muted);
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  padding-block: var(--space-2);
}
.entete__liste a:hover { color: var(--ink); }
.entete__liste a[aria-current="page"] { color: var(--ink); }

.entete__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* La déconnexion est un POST, donc un formulaire. « display: contents »
   le fait disparaître de la mise en page : son bouton devient l'enfant
   direct de la barre, aligné comme les autres, sans qu'on ait à refaire
   ici le flex du parent. */
.entete__sortie { display: contents; }

/* « bouton--discret » est dessiné pour le corps de la page, sur un fond
   clair. Posé sur la barre, son gris tombe à 2,3:1 en thème sombre —
   mesuré, pas supposé. Il reprend donc la couleur de texte principale :
   discret par l'absence de fond et de bordure, pas par un gris illisible. */
.entete__sortie .bouton--discret { color: var(--ink); }

/* Les deux boutons de la barre : même hauteur, même corps de texte. */
.entete__actions .bouton,
.entete__actions .bouton--discret { font-size: 15px; }

.entete__menu {
  display: none;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-full);
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.entete__menu span {
  width: 17px;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
}

/* --- Navigation mobile --------------------------------------------------- */

.navmobile {
  border-top: 1px solid var(--hairline);
  padding: var(--space-4) var(--gouttiere) var(--space-6);
}
.navmobile[hidden] { display: none; }
.navmobile ul { display: flex; flex-direction: column; }
.navmobile a {
  display: block;
  padding: var(--space-4) 0;
  color: var(--ink);
  text-decoration: none;
  font-size: 19px;
  font-weight: 600;
  border-bottom: 1px solid var(--hairline);
}

/* Même chose en version bouton : dans le menu mobile, la déconnexion doit
   ressembler aux autres entrées, pas à un bouton posé au milieu d'une
   liste de liens. Tout est remis à plat — un bouton arrive avec sa bordure,
   son fond, sa police et son centrage. */
.navmobile__sortie {
  display: block;
  width: 100%;
  padding: var(--space-4) 0;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 19px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

/* --- Héros --------------------------------------------------------------- */

/* Sans JavaScript, le héros est une section normale : un dégradé, un titre,
   deux boutons. Avec JavaScript, il devient une scène haute que l'on
   traverse au défilement pendant que la carte se découvre. */

.heros {
  position: relative;
  background: linear-gradient(180deg, var(--ground) 0%, var(--ground-deep) 100%);
  border-bottom: 1px solid var(--hairline);
  overflow: hidden;
}

.heros__scene {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.heros__carte,
.heros__tete,
.heros__balise,
.heros__fiche,
.heros__voile,
.heros__jauge,
.heros__invite { display: none; }

.heros__contenu {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  align-items: flex-start;
  padding-block: clamp(72px, 11vw, 148px);
}

.heros__surtitre {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: 6px 14px;
  border: 1px solid var(--route-soft);
  border-radius: var(--radius-full);
  background: var(--route-soft);
  color: var(--route);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.heros__titre {
  max-width: 16ch;
  font-size: clamp(38px, 5.4vw, 64px);
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* L'accueil parle plus fort que les autres pages : son titre est court,
   il peut se permettre d'occuper l'écran. */
.heros--carte .heros__titre {
  max-width: 14ch;
  font-size: clamp(42px, 7.2vw, 84px);
  line-height: 1.02;
  letter-spacing: -0.025em;
}

.heros__chapeau {
  font-size: clamp(18px, 2.2vw, 24px);
  line-height: 1.45;
  color: var(--ink-muted);
  max-width: 52ch;
  text-wrap: pretty;
}

.heros--carte .heros__chapeau { max-width: 36ch; }

.heros__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.heros__mention {
  margin: 0;
  font-size: 14px;
  color: var(--ink-muted);
}

/* Les héros des pages intérieures n'ont pas de carte. Une lueur très
   douce leur évite d'être un simple aplat. Plus de lueur ambre depuis la
   charte v34 : l'ambre est réservé aux tracés. */
.heros:not(.heros--carte)::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(58% 76% at 86% 14%, rgba(var(--route-rgb), 0.16), transparent 62%);
}

/* --- Le héros animé, uniquement quand le JavaScript est là --------------- */

.js .heros--carte {
  /* Cette hauteur est la course du défilement : c'est elle qui décide
     combien de temps dure la dissipation du brouillard. */
  height: 280vh;
  overflow: visible;

  /* Le héros remonte sous la barre translucide et occupe l'écran entier. */
  margin-top: calc(-1 * var(--entete-h));
}

.js .heros--carte .heros__scene {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  min-height: 600px;
  padding-block: 0;
}

/* Le texte reste sous la barre, qui le survole sans le couvrir. */
.js .heros--carte .heros__contenu {
  padding-block: 0;
  padding-top: var(--entete-h);
}

.js .heros--carte .heros__carte {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* La carte se manipule : on la prend en main comme on prendrait une carte
   pliée. Le curseur le dit avant même qu'on essaie. */
.js .heros--carte .heros__brume {
  cursor: grab;
  touch-action: pan-y;
}

.js .heros--carte .heros__brume--tenue { cursor: grabbing; }

.js .heros--carte .heros__brume:focus-visible {
  outline: 3px solid var(--route);
  outline-offset: -3px;
}

/* Le texte du héros ne doit pas intercepter les gestes destinés à la
   carte : seuls ses blocs, qui s'arrêtent à leur contenu, restent
   cliquables. */
.js .heros--carte .heros__contenu { pointer-events: none; }
.js .heros--carte .heros__contenu > * { pointer-events: auto; }

/* L'anneau posé sur l'étape que la fiche décrit. */
.js .heros--carte .heros__balise {
  display: block;
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-full);
  border: 2px solid var(--route);
  background: rgba(var(--route-rgb), 0.22);
  box-shadow: 0 0 18px 5px rgba(var(--route-rgb), 0.35);
  pointer-events: none;
}

.js .heros--carte .heros__balise[hidden] { display: none; }

/* La fiche d'une étape, au survol. */
.js .heros--carte .heros__fiche {
  display: block;
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  width: max-content;
  max-width: 260px;
  margin: 14px 0 0 18px;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-row);
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  pointer-events: none;
}

.js .heros--carte .heros__fiche[hidden] { display: none; }

/* Au bout droit de la carte, la fiche s'ouvre vers la gauche. */
.js .heros--carte .heros__fiche--gauche {
  margin-left: 0;
  translate: -100% 0;
}

.heros__fiche-nom {
  margin: 0;
  font-weight: 700;
  font-size: 16px;
  color: var(--ink);
}

.heros__fiche-note {
  margin: 2px 0 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-muted);
}

.heros__fiche-km {
  margin: var(--space-2) 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--route);
  font-variant-numeric: tabular-nums;
}

/* La tête de l'itinéraire. Un élément à part, déplacé par transformation :
   sur le canevas du brouillard, chaque passage laisserait sa trace. */
.js .heros--carte .heros__tete {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 190px;
  height: 190px;
  pointer-events: none;
  will-change: transform;
}

/* Le point d'Exploration de la charte : la même personne que la flèche de
   navigation, au repos. Un disque coupé en deux (la lumière vient de la
   gauche), un halo blanc dans les deux thèmes, une ombre courte portée par
   le halo. Pas de lueur ni de pulsation : le point se déplace, rien
   d'autre. */
.js .heros--carte .heros__tete::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border: 3px solid #ffffff;
  border-radius: var(--radius-full);
  background: linear-gradient(90deg, var(--route) 50%, var(--route-deep) 50%);
  box-shadow: 0 1.5px 1.6px #00000059;
}

.js .heros--carte .heros__voile {
  display: block;
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(100deg,
      rgb(var(--ground-rgb)) 0%,
      rgba(var(--ground-rgb), 0.97) 30%,
      rgba(var(--ground-rgb), 0.78) 44%,
      rgba(var(--ground-rgb), 0.24) 62%,
      rgba(var(--ground-rgb), 0) 78%),
    linear-gradient(180deg,
      rgba(var(--ground-rgb), 0.75) 0%,
      rgba(var(--ground-rgb), 0) 20%,
      rgba(var(--ground-rgb), 0) 68%,
      rgba(var(--ground-rgb), 0.88) 100%);
}

/* Le compteur de kilomètres découverts, en bas à droite de la scène. */
.js .heros--carte .heros__jauge {
  display: block;
  position: absolute;
  z-index: 2;
  right: var(--gouttiere);
  bottom: clamp(28px, 6vh, 56px);
  width: min(220px, 40vw);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-panel);
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  text-align: right;
}

.heros__compteur {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
  font-family: var(--rounded);
  color: var(--ink);
}

.heros__km {
  font-size: clamp(26px, 3.4vw, 38px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.heros__unite {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-muted);
}

.heros__jauge-libelle {
  margin: 4px 0 var(--space-3);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.heros__piste {
  height: 3px;
  border-radius: var(--radius-full);
  background: var(--hairline);
  overflow: hidden;
}

.heros__curseur {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--route);
  transform: scaleX(0);
  transform-origin: left center;
}

/* L'invitation à faire défiler, qui s'efface dès le premier geste. */
.js .heros--carte .heros__invite {
  display: flex;
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: clamp(20px, 4vh, 36px);
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  transform: translateX(-50%);
  color: var(--ink-muted);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 1;
  transition: opacity var(--duree-ample) var(--courbe);
}

.js .heros--carte .heros__invite svg { animation: descendre 2.4s ease-in-out 3; }

.js .heros--parti .heros__invite {
  opacity: 0;
  pointer-events: none;
}

@keyframes descendre {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(5px); opacity: 1; }
}

/* Mouvement réduit : la scène tient sur un écran, la carte est montrée
   déjà découverte, et plus rien ne dépend du défilement. */
@media (prefers-reduced-motion: reduce) {
  .js .heros--carte { height: auto; margin-top: 0; }
  .js .heros--carte .heros__contenu {
    padding-block: clamp(72px, 11vw, 148px);
  }
  .js .heros--carte .heros__scene {
    position: relative;
    height: auto;
    min-height: 78vh;
  }
  .js .heros--carte .heros__invite { display: none; }
}

/* Sur écran étroit, la carte ne peut plus se tenir à côté du texte : elle
   passe dessous. Le voile devient vertical, le texte se cale en haut, et
   le compteur descend sous les boutons plutôt que sur eux. */
@media (max-width: 720px) {
  .js .heros--carte .heros__scene { align-items: flex-start; }

  .js .heros--carte .heros__contenu {
    padding-top: calc(var(--entete-h) + var(--space-8));
    padding-bottom: 148px;
    gap: var(--space-5);
  }

  .js .heros--carte .heros__voile {
    background: linear-gradient(180deg,
      rgb(var(--ground-rgb)) 0%,
      rgba(var(--ground-rgb), 0.96) 34%,
      rgba(var(--ground-rgb), 0.62) 56%,
      rgba(var(--ground-rgb), 0.10) 78%,
      rgba(var(--ground-rgb), 0.55) 100%);
  }

  .js .heros--carte .heros__jauge {
    left: var(--gouttiere);
    right: auto;
    bottom: var(--space-6);
    width: auto;
    min-width: 170px;
    text-align: left;
  }

  .heros__compteur { justify-content: flex-start; }
  .js .heros--carte .heros__invite { display: none; }
  .js .heros--carte .heros__tete { width: 130px; height: 130px; }
}

/* --- Entrées au défilement ----------------------------------------------
   Retirées de la Web App le 13 octobre 2026 : un formulaire restait estompé
   jusqu'à deux secondes au chargement. La vitrine garde les siennes
   (Website/assets/css/site.css et entree.js). */

/* --- Grille de cartes ---------------------------------------------------- */

.grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-5);
}

.carte {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-8);
  background: var(--surface);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-panel);
}

.carte {
  transition: translate var(--duree-ample) var(--courbe),
              border-color var(--duree-ample) var(--courbe);
}

.carte:hover {
  translate: 0 -3px;
  border-color: var(--route-soft);
}

@media (prefers-reduced-motion: reduce) {
  .carte:hover,
  .pays:hover { translate: none; }
}

.carte__icone {
  width: 40px;
  height: 40px;
  color: var(--route);
}
.carte__icone--trail { color: var(--ink-muted); }

.carte h2 {
  font-size: clamp(20px, 2.2vw, 26px);
  letter-spacing: -0.012em;
}

.carte p {
  color: var(--ink-muted);
  text-wrap: pretty;
}

.carte--large { grid-column: 1 / -1; }

/* Carte mise en avant : la formule recommandée. */
.carte--avant {
  border-color: color-mix(in srgb, var(--route) 45%, transparent);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--route-soft) 70%, var(--surface)) 0%,
      var(--surface) 60%);
}

/* Ligne secondaire dans une carte : date, version, précision. */
.carte__meta {
  font-size: 14px;
  color: var(--ink-muted);
}

/* Liste à puces à l'intérieur d'une carte. */
.liste {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-left: var(--space-5);
  list-style: disc;
  color: var(--ink-muted);
}
.liste li::marker { color: var(--route); }
.liste--trail li::marker { color: var(--ink-muted); }

/* Étiquette de statut. */
.etiquette {
  /* Une pastille à la taille de son texte, même hors d'un conteneur flex
     (elle s'étirait sur toute la largeur d'une carte ouverte). */
  display: inline-block;
  width: fit-content;
  align-self: flex-start;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.etiquette--publiee {
  background: var(--route-soft);
  color: var(--route-ink);
}
/* Une information, pas une action : ni turquoise ni ambre (charte v34).
   L'ambre est réservé aux tracés, à la voie Découverte nommée et aux
   étiquettes de trajets enregistrés. */
.etiquette--avenir {
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--surface-edge);
  color: var(--ink-muted);
}

/* Prix affiché en grand. */
.prix {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.prix__montant {
  font-size: clamp(38px, 5vw, 52px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
}
.prix__unite {
  font-size: 16px;
  color: var(--ink-muted);
}

/* --- Formulaires --------------------------------------------------------- */

.formulaire {
  width: 100%;
  max-width: 420px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.formulaire__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.formulaire__intro h1 { font-size: clamp(32px, 4.5vw, 44px); }

.formulaire form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.champ {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.champ label {
  font-size: 15px;
  font-weight: 600;
}

.champ input,
.champ select {
  width: 100%;
  min-height: 52px;
  padding: 0 var(--space-4);
  background: var(--surface);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-row);
  color: var(--ink);
  font: inherit;
  /* 17px : en dessous de 16px, iOS agrandit la page à la mise au point
     du champ, et l'utilisateur se retrouve avec une page zoomée. */
  font-size: 17px;
}
/* Champ figé : lisible, manifestement pas saisissable. */
/* ------------------------------------------------------------------
   Le calendrier des champs de date.

   Le champ natif reste dans la page, masqué : c'est lui qui part au
   serveur. Sans JavaScript il réapparaît et le sélecteur du navigateur
   reprend la main — moins joli, parfaitement utilisable.
   ------------------------------------------------------------------ */
/* ------------------------------------------------------------------
   Mon compte : un menu de rubriques, des cartes repliées.
   ------------------------------------------------------------------ */
.reglages-page {
  display: grid;
  grid-template-columns: minmax(12rem, 15rem) minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

.reglages-menu {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  position: sticky;
  top: var(--space-6);
}

.reglages-menu__item {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-row);
  color: var(--ink-muted);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
}

.reglages-menu__item:hover { background: var(--route-soft); color: var(--ink); }

.reglages-menu__item.est-courant {
  background: var(--route-soft);
  color: var(--route);
}

.reglages-menu__item:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.reglages-panneau {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* Une carte repliée : son titre, et ce qu'elle contient déjà.
 *
 * display:block est indispensable. Les cartes sont en flex, et un <details>
 * en flex garde la place de son contenu même fermé : chaque carte repliée
 * occupait huit cents pixels de vide. */
.carte--pliee {
  display: block;
  padding: 0;
}

/* Une ligne de réglages ne saute pas sous le curseur. */
.carte--pliee:hover { translate: none; }

.carte__resume {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-3) var(--space-5);
  cursor: pointer;
  list-style: none;
}

.carte__resume::-webkit-details-marker { display: none; }

.carte__resume:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: -2px;
  border-radius: var(--radius-panel);
}

/* Un vrai titre, pas un span : sans lui, les sous-titres des adresses
   suivaient directement le titre de la page et sautaient un niveau. */
.carte .carte__titre {
  margin: 0;
  font-size: 20px;
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink);
}

.carte__valeur {
  min-width: 0;
  color: var(--ink-muted);
  font-size: 14px;
  overflow-wrap: anywhere;
}

.carte__resume::after {
  content: 'Modifier';
  flex: none;
  font-size: 15px;
  font-weight: 600;
  color: var(--route);
}

.carte--pliee[open] .carte__resume::after { content: 'Replier'; }

.carte--pliee[open] .carte__resume { border-bottom: 1px solid var(--hairline); }

/* Une carte qui ne se replie pas : le même en-tête, sans action. */
.carte__resume--fixe { cursor: default; border-bottom: 1px solid var(--hairline); }
.carte__resume--fixe::after { content: none; }

.carte__contenu { padding: var(--space-5); }

.carte__contenu > h3:first-child { margin-top: 0; }

/* Un sous-titre dans une carte ouverte (« Domicile », une adresse parmi
   d'autres) : un intertitre, pas un titre de page. Le « .carte h3 » général
   lui donnait 26 px. */
.carte .carte__contenu h3 {
  margin: var(--space-8) 0 var(--space-2);
  font-size: 17px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: 0;
}
.carte .carte__contenu h3:first-child { margin-top: 0; }

/* L'étiquette et la ligne d'adresse qui suivent un sous-titre, puis le
   formulaire : chacun à sa place, au lieu de se coller les uns aux autres. */
.carte__contenu > .etiquette { margin-bottom: var(--space-2); }
.carte__contenu > .carte__meta + form,
.carte__contenu > .etiquette + form { margin-top: var(--space-4); }

@media (max-width: 52rem) {
  .reglages-page { grid-template-columns: 1fr; }

  /* Une seule rangée de pastilles qui défile, au lieu de deux rangées
     qui s'enroulent (Graphiste). */
  .reglages-menu {
    position: static;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: var(--space-2);
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(-1 * var(--gouttiere));
    padding-inline: var(--gouttiere);
    scroll-padding-inline: var(--space-4);   /* R4 */
  }
  .reglages-menu::-webkit-scrollbar { display: none; }

  .reglages-menu__item {
    flex: none;
    min-height: 36px;
    border: 1px solid var(--hairline);
    border-radius: var(--radius-full);
    white-space: nowrap;
  }
}

/* ------------------------------------------------------------------
   Lieux enregistrés : deux colonnes, parce qu'il n'y a que deux lieux.
   ------------------------------------------------------------------ */
.lieux {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.lieux th {
  padding: 0 0 var(--space-3);
  border-bottom: 1px solid var(--hairline);
  color: var(--ink-muted);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
}

.lieux td {
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  vertical-align: top;
}

.lieux td + td { padding-left: var(--space-4); border-left: 1px solid var(--hairline); }

/* Ajouter un lieu depuis le web : le bouton ouvre le formulaire sur place. */
.lieux__ajout { margin-top: var(--space-3); }
.lieux__ajout > summary { list-style: none; width: fit-content; }
.lieux__ajout > summary::-webkit-details-marker { display: none; }
.lieux__ajout[open] > summary { margin-bottom: var(--space-4); }
.lieux__ajout form { display: flex; flex-direction: column; gap: var(--space-4); }

.lieux__nom {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}

.lieux__adresse {
  margin: var(--space-1) 0 0;
  color: var(--ink-muted);
  font-size: 14px;
  overflow-wrap: anywhere;
}

.lieux__retrait { margin-top: var(--space-4); }

/* Une fiche : un véhicule, un pass. Même forme que l'entrée d'un lieu, mais
   en pleine largeur — ces deux cartes n'ont pas de colonnes. */
.carte__meta + .fiche,
.fiche + .fiche,
.fiche + .section__actions {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
}

/* Une fiche se lit comme une ligne de liste iOS : le nom et son détail à
   gauche, l'action à droite, centrée sur les deux lignes. Le bouton
   « Modifier » sous chaque véhicule doublait la hauteur de la liste. */
/* Seulement en lecture : une fiche en modification contient son
   formulaire, qui garde toute la largeur. */
.fiche:has(> .lien-action) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-4);
  align-items: center;
}
.fiche:has(> .lien-action) > :not(.lien-action) { grid-column: 1; }
.fiche:has(> .lien-action) > .lien-action { grid-column: 2; grid-row: 1 / span 2; }

/* Un lieu : même ligne que les fiches, le lien à droite du nom. */
.lieux__entree:has(> .lien-action) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-3);
  align-items: center;
}
.lieux__entree:has(> .lien-action) > :not(.lien-action) { grid-column: 1; }
.lieux__entree:has(> .lien-action) > .lien-action { grid-column: 2; grid-row: 1 / span 2; }

.fiche__nom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}

.fiche__detail {
  margin: var(--space-1) 0 0;
  color: var(--ink-muted);
  font-size: 13px;
  overflow-wrap: anywhere;
}

/* Une étiquette, pas un bouton : elle dit un état, on ne clique pas dessus. */
.fiche__marque {
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid var(--hairline);
  color: var(--ink-muted);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.fiche__marque--fin {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
}

/* Plusieurs lieux peuvent partager une colonne : un filet les sépare. */
.lieux__entree + .lieux__entree {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--hairline);
}

.etat-vide {
  color: var(--ink-muted);
  font-size: 15px;
  font-style: italic;
}

/* Sous 40 rem, deux colonnes de formulaire ne tiennent plus : le tableau
   se déplie en deux blocs, et les en-têtes reviennent devant chaque lieu. */
@media (max-width: 40rem) {
  .lieux, .lieux tbody, .lieux tr, .lieux td { display: block; width: 100%; }

  .lieux thead { display: none; }

  .lieux td + td {
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--hairline);
  }

  .lieux td::before {
    content: attr(data-genre);
    display: block;
    margin-bottom: var(--space-2);
    color: var(--ink-muted);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
}

/* Lu par les lecteurs d'écran, jamais affiché. */
.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------------
   Les voyages : à venir, archive, état, suppression.
   ------------------------------------------------------------------ */
.voyage-carte {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
  overflow: hidden;
  transition: border-color var(--duree) var(--courbe);
}

.voyage-carte:hover { border-color: var(--route-soft); }

.voyage-carte.est-courant {
  border-color: var(--route);
  box-shadow: inset 0 0 0 1px var(--route);
}

.voyage-carte .voyage-onglet {
  flex: 1;
  border: 0;
  border-radius: 0;
  box-shadow: none;

  /* De la place pour la croix : sans elle, un titre long passerait
     dessous et l'on cliquerait sur l'un en visant l'autre. */
  padding-right: calc(var(--space-5) + 28px);
}

/* La croix de suppression, dans le coin où l'on ferme les choses.
   Posée par-dessus la carte plutôt qu'en dessous : une ligne
   « Supprimer » sous chaque voyage prenait une hauteur permanente pour
   une action rare, et allongeait la liste d'autant. */
.voyage-carte__retrait {
  position: absolute;
  top: 6px;
  right: 6px;
}

/* --- La croix qui retire -------------------------------------------------
   Une seule apparence pour toute l'application : la liste des voyages et
   la liste des étapes. Les deux avaient divergé — un tracé au trait d'un
   côté, un « × » typographique dans un rectangle bordé de l'autre.
   Le dessin est en PHP, dans icone_croix(). */

.croix-retrait {
  display: flex;
  align-items: center;
  justify-content: center;

  /* 32 px de cible pour 12 px de dessin : une croix au trait fin se
     vise mal, et c'est une action qu'on ne veut pas déclencher par
     erreur — ni rater trois fois de suite. */
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  transition: color var(--duree) var(--courbe), background-color var(--duree) var(--courbe);
}

/* Sous 640 px, la zone de clic passe à 44 px sans agrandir le dessin
   (Graphiste, n° 7) : un débord invisible de 6 px tout autour. */
@media (max-width: 640px) {
  .croix-retrait { position: relative; }
  .croix-retrait::after { content: ""; position: absolute; inset: -6px; }
}

.croix-retrait svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.croix-retrait:hover {
  color: var(--danger);
  background: rgba(var(--ground-rgb), 0.5);
}

.croix-retrait:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: -2px;
}

/* Au doigt, rien ne survole : la croix reste lisible d'emblée plutôt
   que d'attendre un survol qui n'arrivera jamais. */
@media (hover: none) {
  .croix-retrait { color: var(--ink-muted); }
}

.voyage-etat { color: var(--ink-muted); }
.voyage-etat--fait { color: var(--route); font-weight: 600; }

.archive {
  /* Au-dessus, la barre des voyages laisse déjà 32 px. En dessous, le fil
     des écrans se collait à « Archive » : on lui rend le même espace. */
  margin: 0 0 var(--space-8);
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-4);
}

.archive__titre {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.archive__titre::-webkit-details-marker { display: none; }

/* Un chevron au trait (chevron.right), qui pivote à l'ouverture, à la
   place du triangle du navigateur (Graphiste, n° 8). */
.archive__titre::before {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.75px solid currentColor;
  border-bottom: 1.75px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--duree) var(--courbe);
}
.archive[open] > .archive__titre::before { transform: rotate(45deg); }

.archive__compte {
  display: inline-block;
  min-width: 22px;
  padding: 1px 7px;
  margin-left: 6px;
  border-radius: var(--radius-full);
  background: var(--route-soft);
  color: var(--route);
  font-size: 12px;
  text-align: center;
}

.archive__aide {
  margin: var(--space-3) 0;
  font-size: 14px;
  color: var(--ink-muted);
}

/* Le panneau de confirmation avant suppression. */
.retrait {
  margin-bottom: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--route);
  border-radius: var(--radius-row);
  background: var(--surface);
}

.retrait__titre { font-size: 17px; font-weight: 700; color: var(--ink); }
.retrait__detail { margin-top: var(--space-2); font-size: 14px; color: var(--ink-muted); }

.retrait__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-4);
}

/* L'action qui efface. --danger est un rouge de texte, calculé pour
   tenir 4,5:1 sur le fond et sur une surface dans les deux thèmes : le
   bouton l'emploie donc en texte et en liseré, sans aplat. Plus rien
   n'est écrit en dur, et le survol suit le thème. */
.bouton--danger {
  background: transparent;
  border-color: var(--danger);
  color: var(--danger);
}

.bouton--danger:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); }

/* Ce qu'il reste à faire, détaché du récapitulatif qui le précède. */
.bloc-final {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.bloc-final__titre {
  margin-bottom: var(--space-3);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.bloc-final .formulaire__pied {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Une planification arrêtée. */
.valide {
  margin-top: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--route);
  border-radius: var(--radius-row);
}

.valide__titre { font-size: 17px; font-weight: 700; color: var(--route); }

.valide__detail {
  margin: var(--space-2) 0 var(--space-4);
  font-size: 14px;
  color: var(--ink-muted);
}

/* ------------------------------------------------------------------
   Écran 4 : une étape repliée tient sur deux lignes.
   ------------------------------------------------------------------ */
.halte__edition { min-width: 0; }

.halte__resume {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-1) 0;
  cursor: pointer;
  list-style: none;
}

.halte__texte {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.halte__resume::-webkit-details-marker { display: none; }

.halte__resume::after {
  content: 'Modifier';
  flex: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--route);
}

.halte__edition[open] .halte__resume::after { content: 'Replier'; }

.halte__resume:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
  border-radius: var(--radius-row);
}

.halte__nom {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}

.halte__champs {
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
  margin-top: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Un nombre de nuits tient en deux chiffres : un champ pleine largeur
   pour ça demanderait qu'on y écrive autre chose. La phrase d'aide en
   dessous garde la largeur du bloc, elle. */
.halte__champs .champ--court input { max-width: 7rem; }

/* ------------------------------------------------------------------
   « Surprendre » : une destination proposée par l'IA.
   ------------------------------------------------------------------ */

/* Le premier bouton d'un formulaire est celui qu'Entrée déclenche. Celui-ci
   ne sert qu'à garder ce rôle à « Continuer » ; il ne se voit jamais. */
.bouton-defaut {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0;
}

.lieu__surprendre {
  align-self: flex-start;
  margin-top: var(--space-2);
}

.bouton--discret {
  /* La charte : « texte ink-muted, sans fond ». Même hauteur que les
     boutons moyens pour que deux boutons voisins s'alignent. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 var(--space-3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  color: var(--ink-muted);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
}

.bouton--discret:hover { color: var(--route); }

.bouton--discret:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .bouton--discret { transition: none; }
}

.datepick { position: relative; }

.datepick__bouton {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 52px;
  padding: 0 var(--space-4);
  background: var(--surface);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-row);
  color: var(--ink);
  font: inherit;
  font-size: 17px;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--duree) var(--courbe);
}

.datepick__bouton:hover { border-color: var(--route-soft); }

.datepick__bouton:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.datepick__bouton[aria-expanded="true"] { border-color: var(--route); }

.datepick__valeur::first-letter { text-transform: uppercase; }

.datepick__volet {
  position: absolute;
  z-index: 40;
  top: calc(100% + var(--space-2));
  left: 0;
  width: min(20rem, calc(100vw - var(--space-8)));
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-panel);
  box-shadow: var(--ombre);
}

.datepick__volet[hidden] { display: none; }

.datepick__tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.datepick__mois {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}

.datepick__fleche {
  width: 36px;
  height: 36px;
  flex: none;
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.datepick__fleche:hover { border-color: var(--route); color: var(--route); }

.datepick__fleche:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.datepick__semaine,
.datepick__grille {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.datepick__initiale {
  padding-bottom: var(--space-2);
  color: var(--ink-muted);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}

.datepick__jour {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}

.datepick__jour:hover:not(:disabled) { background: var(--route-soft); }

.datepick__jour:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: -2px;
}

/* Les jours du mois d'avant et d'après s'effacent par la couleur, jamais par
   l'opacité : une opacité les faisait tomber sous le contraste exigé. */
.datepick__jour.est-voisin { color: var(--ink-muted); }

.datepick__jour:disabled { opacity: 0.3; cursor: default; }

.datepick__jour.est-aujourdhui { border-color: var(--route); font-weight: 700; }

.datepick__jour.est-retenu {
  background: var(--route);
  border-color: var(--route);
  color: var(--surface);
  font-weight: 700;
}

.datepick__jour.est-retenu.est-voisin { color: var(--surface); }

@media (prefers-reduced-motion: reduce) {
  .datepick__bouton { transition: none; }
}

.champ input[readonly] {
  color: var(--ink-muted);
  background: transparent;
  border-style: dashed;
  cursor: default;
}

/* La flèche native reste : elle indique que le champ est une liste. */
.champ select {
  appearance: auto;
  padding-block: 12px;
}

.champ input:focus,
.champ select:focus {
  border-color: var(--route);
  outline: none;
}
.champ input:focus-visible,
.champ select:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.formulaire__envoi { width: 100%; }

/* Un formulaire posé dans une carte, sur la page Compte. */
.carte form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: flex-start;
}
/* Le formulaire aligne ses enfants à gauche ; sans cela, un bloc de
   recherche d'adresse se rétrécit à son contenu et le champ devient plus
   étroit que celui du nom, juste au-dessus. */
.carte form .champ,
.carte form .lieu,
.carte form [data-modeles],
.carte form .champ-duo { width: 100%; }

/* Deux champs de largeurs inégales sur une ligne : le modèle prend ce qui
   reste, l'année se contente de ses quatre chiffres. Sous 22 rem, ils se
   remettent l'un sous l'autre plutôt que de devenir illisibles. */
.champ-duo {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4);
}

.champ-duo > .champ { flex: 1 1 11rem; }
/* Le code postal tient en huit caractères : il laisse la place à la localité. */
.champ-duo > .champ--cp { flex: 0 1 8rem; min-width: 7rem; }

.champ-duo > .champ--annee { flex: 0 0 7rem; }

/* Un réservoir tient en trois chiffres, une batterie aussi. */
.champ-duo > .champ--reserve { flex: 0 0 9rem; }

/* Un champ masqué parce que le carburant ne le concerne pas : `hidden`
   seul ne suffit pas, les enfants d'un conteneur flex l'ignorent. */
.champ-duo[hidden],
.champ-duo > [hidden],
.carte__meta[hidden] { display: none; }
.carte .section__actions { margin-top: 0; }
/* Après une liste de fiches, le filet garde son espace de part et d'autre :
   la règle ci-dessus le collait à la dernière ligne. */
.carte .fiche + .section__actions { margin-top: var(--space-3); padding-top: var(--space-1); }

/* G3 : sous 640 px, une seule marge intérieure de 16 px pour l'en-tête et
   le contenu d'une carte repliable. */
@media (max-width: 640px) {
  .carte__resume { padding: var(--space-3) var(--space-4); }
  .carte__contenu { padding: var(--space-4); }
}

.formulaire__pied {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: 15px;
}
.formulaire__pied p { color: var(--ink-muted); }

/* Les actions d'un formulaire : grandes et pleine largeur, l'une sous
   l'autre (Graphiste, n° 10). */
.formulaire__pied > .bouton,
.formulaire__pied > form > .bouton {
  width: 100%;
  min-height: 48px;
  font-size: 17px;
}

/* Un formulaire dans une rangée d'actions ne casse pas l'alignement. */
.section__actions form { margin: 0; }

/* --- Alertes ------------------------------------------------------------- */

/* L'état d'un champ vérifié pendant la saisie — le pseudo, aujourd'hui.
   Le bloc garde sa hauteur même vide : la carte ne sautille pas à chaque
   frappe. */
.champ__etat {
  min-height: 1.35em;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink-muted);
}

.champ__etat--ok  { color: var(--route); }
.champ__etat--non { color: var(--stop); }

/* Les messages de la page Compte. Le conteneur reste en place ; compte.js
   remplace seulement ce qu'il contient. */
.alertes:empty { display: none; }

/* Pendant un enregistrement, le contenu s'estompe un peu : quelque chose
   se passe, sans que rien ne bouge ni ne clignote. */
[aria-busy="true"] {
  opacity: 0.6;
  transition: opacity var(--duree) var(--courbe);
  cursor: progress;
}

.alerte {
  padding: var(--space-4) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-row);
  font-size: 15px;
  color: var(--ink);
  transition: opacity var(--duree-ample) var(--courbe), transform var(--duree-ample) var(--courbe);
}

/* Message en train de s'effacer. Le bloc n'est retiré qu'à la fin du
   fondu, sinon la page sursaute sous les yeux de la personne. */
.alerte--partie {
  opacity: 0;
  transform: translateY(-4px);
}

.alerte[hidden] { display: none; }
.alerte--erreur {
  background: color-mix(in srgb, var(--stop) 14%, transparent);
  border-color: color-mix(in srgb, var(--stop) 40%, transparent);
}
.alerte--info {
  background: var(--route-soft);
  border-color: color-mix(in srgb, var(--route) 30%, transparent);
}

/* --- Bandeau ------------------------------------------------------------- */

.bandeau {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: clamp(32px, 4vw, 56px);
  background: var(--route-soft);
  border: 1px solid color-mix(in srgb, var(--route) 30%, transparent);
  border-radius: var(--radius-panel);
}
.bandeau__texte { display: flex; flex-direction: column; gap: var(--space-3); max-width: 56ch; }
.bandeau__texte p { color: var(--ink-muted); text-wrap: pretty; }

/* --- Pied de page -------------------------------------------------------- */

.pied {
  border-top: 1px solid var(--hairline);
  background: var(--ground);
}

.pied__haut,
.pied__bas {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.pied__haut {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16);
  padding-block: clamp(48px, 6vw, 80px) var(--space-12);
}

.pied__marque { display: flex; flex-direction: column; gap: var(--space-4); }
.pied__baseline { color: var(--ink-muted); font-size: 15px; max-width: 34ch; }

.pied__colonnes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16);
  flex-grow: 1;
}

.pied__colonne h2 {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--space-4);
}
.pied__colonne ul { display: flex; flex-direction: column; gap: var(--space-3); }
.pied__colonne a {
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
}
.pied__colonne a:hover { color: var(--route); }

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-8);
  justify-content: space-between;
  padding-block: var(--space-6) var(--space-10);
  border-top: 1px solid var(--hairline);
  font-size: 14px;
  color: var(--ink-muted);
}

/* --- Pages de texte ------------------------------------------------------ */

.texte {
  max-width: 68ch;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.texte h2 { margin-top: var(--space-8); font-size: clamp(24px, 3vw, 32px); }
.texte h3 { margin-top: var(--space-5); }
.texte p, .texte li { color: var(--ink-muted); }
.texte ul { display: flex; flex-direction: column; gap: var(--space-3); padding-left: var(--space-5); list-style: disc; }
.texte__date { font-size: 14px; color: var(--ink-muted); }

/* --- Justification -------------------------------------------------------
   Le texte justifié n'est lisible que si le navigateur peut couper les mots.
   La césure automatique s'appuie sur l'attribut lang="fr" de la balise <html>
   (défini dans includes/header.php) : sans lui, rien ne se coupe.
   hyphenate-limit-chars : ne coupe pas un mot de moins de 6 lettres, et laisse
   au moins 3 lettres de chaque côté du tiret.

   La justification est volontairement limitée aux pages de texte long.
   Sur les chapeaux, le héros et les cartes, les lignes sont trop courtes :
   la justification y creuse des rivières blanches sans rien apporter.
   -------------------------------------------------------------------------- */

.texte p,
.texte li {
  text-align: justify;
  text-justify: inter-word;
  -webkit-hyphens: auto;
  hyphens: auto;
  -webkit-hyphenate-limit-before: 3;
  -webkit-hyphenate-limit-after: 3;
  hyphenate-limit-chars: 6 3 3;
}

/* La date de mise à jour est une ligne isolée : elle reste au fer à gauche. */
.texte__date {
  text-align: left;
  -webkit-hyphens: manual;
  hyphens: manual;
}

/* --- Un appareil, dessiné ------------------------------------------------

   Aucune capture d'écran : le cadre et ce qu'il contient sont du HTML et
   du SVG, dans la charte. Rien à charger, rien qui vieillisse mal, et la
   même chose en thème Jour comme en thème Nuit.

   Tout est masqué aux lecteurs d'écran (aria-hidden dans la page) : c'est
   une illustration, et le texte à côté dit déjà ce qu'elle montre.
   -------------------------------------------------------------------------- */

.appareil {
  position: relative;
  width: min(300px, 78vw);
  aspect-ratio: 300 / 620;
  padding: 11px;
  border-radius: 46px;
  background: linear-gradient(155deg, #384657 0%, #16202f 42%, #0a121e 100%);
  box-shadow:
    0 34px 70px -24px rgba(2, 4, 11, 0.75),
    inset 0 0 0 1px #ffffff1f;
  flex-shrink: 0;
}

/* L'îlot du haut. Posé au-dessus de l'écran, comme sur l'appareil. */
.appareil::after {
  content: "";
  position: absolute;
  z-index: 3;
  top: 22px;
  left: 50%;
  translate: -50% 0;
  width: 84px;
  height: 24px;
  border-radius: var(--radius-full);
  background: #04070d;
}

.appareil__ecran {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-radius: 36px;
  overflow: hidden;
  background: var(--ground-deep);
  color: var(--ink);
  font-size: 12px;
  line-height: 1.35;
}

/* --- L'écran de guidage --------------------------------------------------- */

.ecran__bandeau {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 46px var(--space-4) var(--space-4);
  background: var(--route);
  color: var(--on-route);
}

.ecran__fleche {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
}

.ecran__distance {
  font-family: var(--rounded);
  font-size: 21px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.ecran__rue {
  margin-top: 3px;
  font-size: 12px;
  font-weight: 600;
  opacity: 0.85;
}

.ecran__carte {
  position: relative;
  flex: 1;
  background: var(--ground-deep);
}

.ecran__carte svg { display: block; width: 100%; height: 100%; }

.ecran__pied {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5) var(--space-6);
  background: var(--surface);
  border-top: 1px solid var(--hairline);
}

.ecran__mesure { text-align: center; }

.ecran__mesure b {
  display: block;
  font-family: var(--rounded);
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ecran__mesure span {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* --- L'écran de préparation ----------------------------------------------- */

.ecran__entete {
  padding: 46px var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--hairline);
  background: var(--surface);
}

.ecran__titre {
  font-family: var(--rounded);
  font-size: 15px;
  font-weight: 700;
}

.ecran__sous {
  margin-top: 2px;
  font-size: 11px;
  color: var(--ink-muted);
}

.ecran__liste {
  flex: 1;
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow: hidden;
}

.etape {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: var(--space-3);
  align-items: start;
}

/* La pastille et le trait qui relie les étapes entre elles. */
.etape__puce {
  position: relative;
  width: 11px;
  height: 11px;
  margin: 3px auto 0;
  border-radius: var(--radius-full);
  border: 2px solid var(--route);
  background: var(--ground-deep);
}

.etape:not(:last-child) .etape__puce::after {
  content: "";
  position: absolute;
  top: 13px;
  left: 50%;
  translate: -50% 0;
  width: 2px;
  height: 30px;
  background: var(--hairline);
}

.etape--faite .etape__puce { background: var(--itineraire-parcouru); border-color: var(--itineraire-parcouru); }

.etape__nom { font-weight: 600; }

.etape__note {
  font-size: 11px;
  color: var(--ink-muted);
}

.etape__heure {
  font-size: 11px;
  font-weight: 600;
  color: var(--route);
  font-variant-numeric: tabular-nums;
}

.ecran__barre {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4) var(--space-6);
  background: var(--surface);
  border-top: 1px solid var(--hairline);
}

.ecran__action {
  flex: 1;
  padding: 9px 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--hairline);
  color: var(--ink-muted);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}

.ecran__action--forte {
  border-color: transparent;
  background: var(--route);
  color: var(--on-route);
}

/* --- Les sections en deux colonnes --------------------------------------- */

.duo {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(32px, 5vw, 88px);
  align-items: center;
}

.duo--inverse > .duo__visuel { order: -1; }

.duo__visuel {
  display: flex;
  justify-content: center;
}

/* --- Les fonctions nommées ------------------------------------------------ */

.fonctions {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  margin-top: clamp(28px, 3vw, 40px);
}

.fonction {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: var(--space-4);
  align-items: start;
}

.fonction__icone {
  width: 34px;
  height: 34px;
  color: var(--route);
}

.fonction h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: 17px;
  margin-bottom: 4px;
}

.fonction p {
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 1.5;
  max-width: 46ch;
}

/* Ce qui demande un abonnement le dit, plutôt que de le laisser découvrir
   au moment de s'en servir. */
.marque-plus {
  padding: 3px 9px;
  border-radius: var(--radius-full);
  background: var(--route-soft);
  color: var(--route-ink);

  /* 12 px et pas 11 : c'est le plus petit texte de tout le site, et il
     porte le nom de l'offre payante. Mesuré sur un iPhone SE. */
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

@media (max-width: 860px) {
  .duo { grid-template-columns: 1fr; }
  .duo--inverse > .duo__visuel { order: 0; }
  .duo__visuel { margin-top: var(--space-8); }

  /* Sur un téléphone, l'illustration ne doit pas prendre toute la largeur :
     un téléphone dessiné à la taille d'un téléphone prête à confusion. */
  .appareil { width: min(250px, 64vw); }
}

/* Un bouton qui n'en est pas un : la place du bouton App Store, tant que
   l'application n'est pas publiée. Ce n'est pas un lien, donc ce n'est pas
   cliquable — mieux vaut un repère désactivé qu'un lien qui ne mène nulle
   part. */
.bouton--attente {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px var(--space-6);
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-muted);
  font-size: 16px;
  font-weight: 600;
  cursor: default;
}

/* --- Passeport ------------------------------------------------------------ */

.passeport {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-4);
}

.pays {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-6);
  background: var(--surface);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-panel);
  transition: translate var(--duree-ample) var(--courbe),
              border-color var(--duree-ample) var(--courbe);
}

.pays:hover {
  translate: 0 -3px;
  border-color: var(--route-soft);
}

.pays__anneau {
  position: relative;
  flex-shrink: 0;
  width: 78px;
  height: 78px;
}

.pays__anneau svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.pays__piste,
.pays__part {
  fill: none;
  stroke-width: 7;
  stroke-linecap: round;
}

.pays__piste { stroke: var(--hairline); }

.pays__part {
  stroke: var(--route);
  /* 2 × π × 34, le tour du cercle tracé dans le SVG. */
  stroke-dasharray: 213.63;
  stroke-dashoffset: 213.63;
}

/* L'anneau se remplit quand la carte entre dans l'écran. Sans JavaScript,
   « --part » n'est jamais posé : l'anneau reste vide et les chiffres
   écrits dans le HTML disent la même chose. */
.js .pays.est-entre .pays__part {
  stroke-dashoffset: calc(213.63 * (1 - var(--part, 0)));
  transition: stroke-dashoffset 1.3s var(--courbe) 0.15s;
}

.pays__part--sans-js { stroke-dashoffset: 0; }

.pays__pourcent {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  font-family: var(--rounded);
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.pays__texte { min-width: 0; }

.pays__texte h3 {
  font-size: 19px;
  margin-bottom: 6px;
}

.pays__km {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pays__detail {
  margin-top: 2px;
  font-size: 13px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.passeport__note {
  margin-top: var(--space-6);
  font-size: 14px;
  color: var(--ink-muted);
}

/* --- Chiffres ------------------------------------------------------------- */

.chiffres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--space-4);
  padding: var(--space-8) var(--space-6);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-panel);
  background: linear-gradient(140deg, var(--surface), var(--ground-deep));
}

.chiffre {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-inline: var(--space-3);
}

.chiffre + .chiffre { border-left: 1px solid var(--hairline); }

.chiffre__valeur {
  font-family: var(--rounded);
  font-size: clamp(32px, 4vw, 46px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--route);
  font-variant-numeric: tabular-nums;
}

.chiffre__libelle {
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-muted);
  text-wrap: pretty;
}

@media (max-width: 720px) {
  .chiffre + .chiffre { border-left: 0; }
  .chiffres { gap: var(--space-6); }
}

/* --- Les questions fréquentes -------------------------------------------- */

/* Un titre de section qui a l'allure d'un titre de page, sans en être
   un : une page ne porte qu'un seul h1, et c'est celui du héros. */
.texte__grand-titre {
  font-size: clamp(32px, 4.4vw, 52px);
  letter-spacing: -0.02em;
}

.faq__categorie {
  margin-top: clamp(40px, 5vw, 64px);
  margin-bottom: var(--space-4);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--route);
}

.faq__categorie[hidden] { display: none; }

.faq {
  border-bottom: 1px solid var(--hairline);
}

.faq[hidden] { display: none; }

.faq > summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 0;
  cursor: pointer;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
  list-style: none;
  text-align: left;
  -webkit-hyphens: manual;
  hyphens: manual;
}

/* Le triangle par défaut ne suit pas la charte : on met le nôtre. */
.faq > summary::-webkit-details-marker { display: none; }

.faq > summary::after {
  content: "";
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  margin-top: 7px;
  border-right: 2.5px solid var(--route);
  border-bottom: 2.5px solid var(--route);
  rotate: 45deg;
  transition: rotate var(--duree) var(--courbe);
}

.faq[open] > summary::after { rotate: 225deg; }

.faq > summary:hover { color: var(--route); }

.faq > summary:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 3px;
  border-radius: var(--radius-row);
}

.faq__reponse {
  padding-bottom: var(--space-5);
  max-width: 68ch;
}

.faq__reponse > :first-child { margin-top: 0; }

@media (prefers-reduced-motion: no-preference) {
  .faq[open] > .faq__reponse { animation: faq-ouvre var(--duree) var(--courbe); }
}

@keyframes faq-ouvre {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* La barre de recherche, posée par pages.js. */
.faq__barre {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: clamp(28px, 4vw, 44px) 0 0;
  max-width: 520px;
}

.faq__etiquette {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

.faq__champ {
  width: 100%;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}

.faq__champ::placeholder { color: var(--ink-muted); }

.faq__champ:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
  border-color: var(--route);
}

.faq__compte {
  min-height: 1.4em;
  font-size: 14px;
  color: var(--ink-muted);
}

/* --- Le sommaire des pages longues --------------------------------------- */

.avec-sommaire {
  display: grid;
  grid-template-columns: 230px minmax(0, 1fr);
  gap: clamp(32px, 4vw, 72px);
  align-items: start;
}

.sommaire {
  position: sticky;
  top: calc(var(--entete-h) + var(--space-6));
  max-height: calc(100vh - var(--entete-h) - var(--space-12));
  overflow-y: auto;
  padding-right: var(--space-3);
}

.sommaire__titre {
  margin-bottom: var(--space-4);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.sommaire ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-left: 1px solid var(--hairline);
}

.sommaire a {
  display: block;
  padding: 7px var(--space-4);
  margin-left: -1px;
  border-left: 2px solid transparent;
  color: var(--ink-muted);
  text-decoration: none;
  font-size: 14px;
  line-height: 1.4;
  transition: color var(--duree) var(--courbe), border-color var(--duree) var(--courbe);
}

.sommaire a:hover { color: var(--ink); }

.sommaire a.est-courant {
  color: var(--route);
  border-left-color: var(--route);
  font-weight: 600;
}

@media (max-width: 900px) {
  .avec-sommaire { grid-template-columns: 1fr; }

  .sommaire {
    position: static;
    max-height: none;
    padding: var(--space-5) var(--space-5) var(--space-4);
    margin-bottom: var(--space-8);
    border: 1px solid var(--surface-edge);
    border-radius: var(--radius-panel);
    background: var(--surface);
  }

  .sommaire ul { border-left: 0; }
  .sommaire a { padding-inline: 0; border-left: 0; margin-left: 0; }
  .sommaire a.est-courant { border-left: 0; }
}

/* --- La bascule mensuel / annuel ----------------------------------------- */

.bascule {
  display: inline-flex;
  /* Le conteneur est une colonne flex : sans cela, la bascule s'étirerait
     sur toute la largeur. */
  align-self: flex-start;
  gap: 4px;
  margin-top: var(--space-6);
  padding: 4px;
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-full);
  background: var(--surface);
}

.bascule__choix {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 9px var(--space-5);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-muted);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
}

.bascule__choix:hover { color: var(--ink); }

.bascule__choix.est-actif {
  background: var(--route);
  color: var(--on-route);
}

.bascule__choix:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.bascule__gain {
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background: var(--route-soft);
  color: var(--route-ink);
  font-size: 12px;
  font-weight: 700;
}

.bascule__choix.est-actif .bascule__gain {
  background: rgba(0, 0, 0, 0.18);
  color: inherit;
}

/* Le montant change de valeur : sans largeur tabulaire, la carte sautille. */
.prix__montant { font-variant-numeric: tabular-nums; }

/* --- Le mot de passe qu'on peut regarder --------------------------------- */

.champ__avec-oeil { position: relative; }

.champ__avec-oeil input { padding-right: 92px; }

.champ__oeil {
  position: absolute;
  top: 50%;
  right: 8px;
  translate: 0 -50%;
  padding: 7px var(--space-4);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-muted);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.champ__oeil:hover { color: var(--route); }

.champ__oeil:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 1px;
}

/* --- La progression de lecture ------------------------------------------- */

.progression {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  overflow: hidden;
}

.progression span {
  display: block;
  height: 100%;
  background: var(--route);
  transform: scaleX(0);
  transform-origin: left center;
}

/* --- La page introuvable -------------------------------------------------

   Une route qui s'arrête, et la suite qui n'existe pas. Le trait se
   dessine à l'arrivée sur la page, ce qui vaut mieux qu'un gros chiffre.
   -------------------------------------------------------------------------- */

.perdu {
  display: block;
  width: min(320px, 100%);
  height: auto;
  margin-bottom: var(--space-8);
  color: var(--ink-muted);
  overflow: visible;
}

.perdu__suite,
.perdu__fin { color: var(--route-alt); stroke: currentColor; }

@media (prefers-reduced-motion: no-preference) {
  .perdu__trace {
    stroke-dasharray: 320;
    stroke-dashoffset: 320;
    animation: perdu-trace 1.5s var(--courbe) 0.2s forwards;
  }

  .perdu__depart,
  .perdu__fin,
  .perdu__suite {
    opacity: 0;
    animation: perdu-apparait 0.6s var(--courbe) forwards;
  }

  .perdu__depart { animation-delay: 0.25s; }
  .perdu__fin    { animation-delay: 1.4s; }
  .perdu__suite  { animation-delay: 1.6s; }
}

@keyframes perdu-trace  { to { stroke-dashoffset: 0; } }
@keyframes perdu-apparait { to { opacity: 1; } }

/* --- Les voyages et les trajets -------------------------------------------

   Une seule page, deux sections. Rien n'est replié : chaque étape est un
   formulaire ouvert, le champ d'ajout est toujours là. La liste des étapes
   est un <ol> — c'est un ordre, le lecteur d'écran l'annonce comme tel — et
   les deux flèches de chaque ligne suffisent à le changer sans JavaScript.
   Le glisser-déposer n'est qu'un raccourci posé par-dessus.
   -------------------------------------------------------------------------- */

/* --- La barre des voyages ------------------------------------------------ */

.voyages-barre {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
}

.voyage-onglet {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 190px;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-row);
  background: var(--surface);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--duree) var(--courbe), background-color var(--duree) var(--courbe);
}

.voyage-onglet:hover { border-color: var(--route-soft); }

.voyage-onglet:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.voyage-onglet.est-courant {
  border-color: var(--route);
  box-shadow: inset 0 0 0 1px var(--route);
}

.voyage-onglet__titre {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}

.voyage-onglet.est-courant .voyage-onglet__titre { color: var(--route); }

.voyage-onglet__meta {
  font-size: 13px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.voyage-onglet--neuf { border-style: dashed; background: transparent; justify-content: center; }

/* Tous les onglets à la même hauteur, et pleine largeur sous 640 px
   (Graphiste, n° 6). */
.voyages-barre { align-items: stretch; }
.voyages-barre > * { display: flex; }
.voyages-barre > * > .voyage-onglet { flex: 1; }
@media (max-width: 640px) {
  .voyages-barre > * { flex: 1 1 100%; }
  .voyage-onglet { min-width: 0; }
}

/* --- La carte d'un voyage ------------------------------------------------

   Dessinée en SVG depuis les seules coordonnées des étapes : pas de tuiles
   à charger, pas de bibliothèque, rien à demander à un tiers. Ce n'est pas
   une carte routière — c'est la forme du voyage, à l'échelle.
   -------------------------------------------------------------------------- */

.carte-voyage {
  display: block;
  width: 100%;
  aspect-ratio: 8 / 5;
  border-radius: var(--radius-panel);
}

.carte-voyage__fond   { fill: var(--ground-deep); }
.carte-voyage__grille { stroke: var(--hairline); stroke-width: 1; }

/* Un voyage préparé est une route à faire : ambre (--itineraire), comme
   tout itinéraire sur une carte. Les jalons, eux, restent en route. */
.carte-voyage__ombre {
  fill: none;
  stroke: var(--itineraire);
  stroke-opacity: 0.16;
  stroke-width: 10;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.carte-voyage__trace {
  fill: none;
  stroke: var(--itineraire);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.carte-voyage__halo  { fill: var(--route); fill-opacity: 0.2; }

.carte-voyage__jalon {
  fill: var(--route);
  stroke: var(--ground-deep);
  stroke-width: 2.5;
}

.carte-voyage__numero {
  fill: var(--on-route);
  font-size: 13px;
  font-weight: 700;
  text-anchor: middle;
}

.carte-voyage__nom {
  fill: var(--ink);
  font-size: 15px;
  font-weight: 600;
  text-anchor: middle;
}

.carte-voyage--vide {
  display: grid;
  place-content: center;
  gap: var(--space-2);
  aspect-ratio: 8 / 5;
  padding: var(--space-6);
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-panel);
  background: var(--ground-deep);
  text-align: center;
  font-size: 15px;
}

.carte-voyage--vide p { margin: 0; }
.carte-voyage__note { color: var(--ink-muted); font-size: 14px; max-width: 34ch; }

/* Le tracé se dessine, les jalons se posent ensuite. La longueur exacte du
   tracé est inconnue en CSS : un tiret assez long pour n'importe quel
   voyage fait l'affaire. */
@media (prefers-reduced-motion: no-preference) {
  .js .carte-voyage__trace {
    stroke-dasharray: 3000;
    stroke-dashoffset: 3000;
    animation: voyage-trace 1.5s var(--courbe) forwards;
  }

  .js .carte-voyage__halo,
  .js .carte-voyage__jalon,
  .js .carte-voyage__numero,
  .js .carte-voyage__nom {
    opacity: 0;
    animation: voyage-jalon 0.5s var(--courbe) forwards 0.75s;
  }
}

@keyframes voyage-trace { to { stroke-dashoffset: 0; } }
@keyframes voyage-jalon { to { opacity: 1; } }

/* --- Le plan : la carte d'un côté, les étapes de l'autre ----------------- */

.voyage-plan {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-8);
}

/* La colonne s'étire sur toute la hauteur de la liste : c'est ce qui donne
   à la carte de quoi rester collée pendant qu'on fait défiler les étapes. */
.voyage-plan__cote { display: flex; flex-direction: column; }

.voyage-plan__carte { position: sticky; top: calc(var(--entete-h) + var(--space-5)); }

.voyage-plan__legende {
  margin-top: var(--space-4);
  font-size: 14px;
  color: var(--ink-muted);
}

/* Poussés en bas de la colonne : ils s'alignent sur la fin de la liste
   des étapes, et comblent le vide que laisserait la carte seule. */
.reglages {
  /* « auto » poussait le bloc tout en bas de la colonne : entre les
     boutons et « Supprimer ce voyage », on avait un trou. */
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.reglages h3 {
  margin: 0 0 var(--space-5);
  font-size: 18px;
}

.reglages__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.reglages__suppression {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

/* Premier enfant de .reglages, qui porte déjà le filet : un seul trait,
   pas deux traits séparés d'un vide (Graphiste, n° 10). */
.reglages > .reglages__suppression:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* --- Les étapes ---------------------------------------------------------- */

.haltes__intro {
  margin: 0 0 var(--space-5);
  font-size: 14px;
  color: var(--ink-muted);
  max-width: 62ch;
}

.haltes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.halte {
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-panel);
  background: var(--surface);
  transition: border-color var(--duree) var(--courbe), opacity var(--duree) var(--courbe);
}

.halte__saut {
  margin: 0 0 var(--space-4);
  font-size: 13px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.halte__saut span { color: var(--route); margin-right: 4px; }
.halte__saut--neuve { color: var(--route); font-weight: 600; }

.halte__grille {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-4);
  align-items: start;
}

.halte__rang {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background: var(--route);
  color: var(--on-route);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* La poignée ne se distingue que si le glisser-déposer est branché. */
.halte__rang[draggable="true"] { cursor: grab; }
.halte__rang[draggable="true"]:active { cursor: grabbing; }
.halte.est-prise { opacity: 0.45; }
.halte.est-cible { border-color: var(--route); }

.halte__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

/* Une étape est une ligne de liste, pas une page de formulaire : ses
   champs sont plus serrés que ceux d'un formulaire ordinaire. 16 px reste
   la limite en dessous de laquelle iOS agrandit la page à la mise au
   point du champ. */
.halte__form .champ label { font-size: 14px; }

.halte__form .champ input,
.halte__form .champ textarea {
  min-height: 44px;
  font-size: 16px;
}

.halte__dates {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

.halte__rang1 {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px;
  gap: var(--space-4);
  align-items: start;
}

.halte__rang2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--space-4);
  align-items: start;
}

.halte__pied { display: flex; }

/* Les commandes en rangée, pas en colonne : empilées, elles imposaient à
   chaque étape la hauteur de trois boutons alors que le texte en fait deux
   lignes. C'est ce qui rendait la liste interminable. */
.halte__cote {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 4px;
}

.halte__ordre { display: flex; gap: 4px; }

.halte__fleche {
  width: 34px;
  height: 28px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: color var(--duree) var(--courbe), border-color var(--duree) var(--courbe);
}

.halte__fleche:hover:not(:disabled) { color: var(--route); border-color: var(--route-soft); }
.halte__fleche:disabled { opacity: 0.3; cursor: default; }
/* Sur la même ligne que les flèches, et centrée sur elles : elles font
   28 px de haut, la croix 32. Sans ce décalage de deux pixels vers le
   haut, elle pend plus bas que ses voisines. */
.halte__retrait { margin-top: -2px; margin-left: var(--space-1); }

.halte__fleche:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.halte--neuve {
  margin-top: var(--space-4);
  border-style: dashed;
  background: transparent;
}

/* --- Adaptations de la planification ------------------------------------- */

@media (max-width: 1000px) {
  /* Une seule colonne : la carte, puis les étapes, puis les réglages.
     display: contents défait la colonne de gauche pour que ses deux
     enfants se rangent eux-mêmes dans cet ordre. */
  .voyage-plan { display: flex; flex-direction: column; gap: var(--space-8); }
  .voyage-plan__cote { display: contents; }
  .voyage-plan__carte { position: static; order: 1; }
  .voyage-plan__etapes { order: 2; }
  .reglages { order: 3; margin-top: 0; padding-top: var(--space-6); }
  .haltes__intro { margin-top: var(--space-2); }
}

/* Réduite à la largeur d'un téléphone, la carte ne peut plus porter de
   texte lisible : les numéros et la liste suffisent. */
@media (max-width: 700px) {
  .carte-voyage__nom { display: none; }
}

@media (max-width: 560px) {
  .halte { padding: var(--space-4); }

  /* Sur un téléphone, le numéro et les flèches passent sur une ligne à
     eux : le formulaire récupère toute la largeur, et le nom de l'étape
     cesse d'être illisible. */
  .halte__grille {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "rang cote" "form form";
    gap: var(--space-3);
  }

  .halte__rang { grid-area: rang; }
  .halte__form { grid-area: form; }

  .halte__cote {
    grid-area: cote;
    flex-direction: row;
    justify-content: flex-end;
    align-items: center;
  }

  /* En colonne étroite, le conteneur centre déjà tout le monde. */
  .halte__retrait { margin-top: 0; margin-left: var(--space-2); }
  .halte__rang1 { grid-template-columns: minmax(0, 1fr) 76px; }
  .voyage-onglet { min-width: 100%; }
}

/* --- La recherche d'un lieu ----------------------------------------------

   Trois champs pour un seul endroit : le nom qu'on lit, l'adresse, et les
   coordonnées. Choisir un résultat remplit les trois. Sans JavaScript, ou
   tant que la clé du service n'est pas posée, on tape le nom et on colle
   les coordonnées — les mêmes champs, le même envoi.
   -------------------------------------------------------------------------- */

.lieu {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.lieu__etat {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted);
  min-height: 1.2em;
}

.lieu__etat--ok  { color: var(--route); }
.lieu__etat--non { color: var(--ink-muted); }

.lieu__resultats {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  margin: 0;
  padding: var(--space-2);
  list-style: none;
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--route-soft);
  border-radius: var(--radius-row);
  background: var(--surface);
  box-shadow: var(--ombre);
}

.lieu__resultats[hidden] { display: none; }

.lieu__resultat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-radius: var(--radius-row);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.lieu__resultat:hover { background: var(--ground-deep); }

.lieu__resultat:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: -2px;
}

.lieu__resultat-nom { font-weight: 600; font-size: 16px; }

.lieu__resultat-adresse {
  font-size: 13px;
  color: var(--ink-muted);
}

.champ--coord input { font-variant-numeric: tabular-nums; }

/* Une nuit ne se lit pas comme un arrêt : la bordure le dit avant le texte. */
.halte--nuit { border-left: 3px solid var(--ink-muted); }

/* --- L'assistant : le fil, l'écran ----------------------------------------

   Cinq écrans dans l'ordre, et le même assistant sert à modifier : on
   revient par celui qu'on veut. Le fil est un <ol> — c'est une suite, le
   lecteur d'écran l'annonce comme telle — et l'écran courant porte
   aria-current="step".
   -------------------------------------------------------------------------- */

.fil { margin-bottom: var(--space-8); }

.fil__liste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.fil__pas { flex: 1 1 130px; min-width: 0; }

.fil__pas > a,
.fil__pas > span {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
  color: var(--ink-muted);
  text-decoration: none;
  transition: border-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
}

.fil__pas > a:hover { border-color: var(--route-soft); color: var(--ink); }

.fil__pas > a:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.fil__numero {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-full);
  border: 1px solid currentColor;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.fil__titre { font-size: 15px; font-weight: 600; }

/* Sous 640 px, les cinq étapes tiennent sur une rangée (Graphiste, n° 9) :
   des pastilles numérotées, et seule l'étape courante garde son nom.
   Empilées, elles prenaient 300 px avant le contenu. */
@media (max-width: 640px) {
  .fil__liste { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .fil__pas { flex: 0 0 auto; }
  .fil__pas.est-courant { flex: 1 1 auto; }
  .fil__pas > a,
  .fil__pas > span { min-height: 44px; padding: 0 var(--space-2); justify-content: center; }
  .fil__pas:not(.est-courant) .fil__titre {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

.fil__pas.est-fait > a { color: var(--route); border-color: var(--route-soft); }

.fil__pas.est-fait .fil__numero {
  background: var(--route-soft);
  border-color: transparent;
}

.fil__pas.est-courant > span {
  border-color: var(--route);
  box-shadow: inset 0 0 0 1px var(--route);
  color: var(--ink);
}

.fil__pas.est-courant .fil__numero {
  background: var(--route);
  border-color: transparent;
  color: var(--on-route);
}

.ecran {
  padding: var(--space-8);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-panel);
  background: var(--surface);
}

.ecran__tete { margin-bottom: var(--space-6); }

.ecran__tete h2 {
  margin: var(--space-2) 0 0;
  font-size: clamp(24px, 2.6vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.ecran__detail {
  margin: var(--space-2) 0 0;
  font-size: 15px;
  color: var(--ink-muted);
}

.ecran__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 640px;
}

.ecran__suite { margin-top: var(--space-8); }

/* --- Les variantes d'itinéraire ------------------------------------------ */

.variantes {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  border: 0;
}

.variantes__legende {
  padding: 0;
  margin-bottom: var(--space-3);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

/* Le composant RouteChooser de la charte : une ligne par route, et la
   route choisie sur un fond --route-soft, au rayon d'une ligne. Pas de
   cadre en plus : la sélection se dit par le fond et par le bouton radio
   plein, jamais par la couleur seule. */
.variante {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
  cursor: pointer;
  transition: background-color var(--duree) var(--courbe), border-color var(--duree) var(--courbe);
}

.variante:hover { border-color: var(--route-alt); }

/* Une seule route au menu : plus de bouton à cocher, donc plus rien à
   survoler ni à viser. Elle est encadrée comme une route retenue, parce
   qu'elle l'est — sans faire croire qu'on pourrait en choisir une autre. */
.variante--seule {
  cursor: default;
  border-color: transparent;
  background: var(--route-soft);
}

.variante--seule:hover { border-color: transparent; }

.variante input {
  width: 19px;
  height: 19px;
  margin-top: 3px;
  accent-color: var(--route);
  flex-shrink: 0;
}

.variante:has(input:checked) {
  border-color: transparent;
  background: var(--route-soft);
}

.variante:has(input:focus-visible) { box-shadow: var(--focus-ring); }

.variante__corps { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.variante__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* La durée en headline (17/22, 600) : c'est elle qui fait choisir. */
.variante__duree {
  font-size: 17px;
  line-height: 22px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* « Le plus rapide », sur la première route seulement. Sur la ligne
   choisie, dont le fond est déjà --route-soft, un liseré le détache. */
.variante__badge {
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--route-soft);
  color: var(--route-ink);
  font-size: 11px;
  line-height: 13px;
  font-weight: 600;
}
.variante:has(input:checked) .variante__badge,
.variante--seule .variante__badge { box-shadow: inset 0 0 0 1px var(--route-ink); }

/* Distance, « par <route> », péage : en footnote (13/18). */
.variante__chiffres {
  font-size: 13px;
  line-height: 18px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.variante__detail { font-size: 13px; line-height: 18px; color: var(--ink-muted); }

/* « + 12 min par rapport au plus rapide ».

   C'est ce qui fait choisir, donc c'est écrit plus fort que le reste du
   détail — mais en --ink-muted comme lui : ce n'est pas une alerte, juste
   le prix du détour. Les chiffres en chasse fixe pour que trois lignes
   empilées s'alignent sur leur « + ». */
.variante__perdu {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* « sans péage », « par l'autoroute ».

   Inutilisées tant que PLAN_OPTIONS vaut false dans planner.php — gardées
   exprès : les cases reviendront, et les styler à nouveau à ce moment-là
   serait du travail refait.

   Ce que le chemin comporte vraiment, affiché seulement quand la question
   se pose. Le vert dit « c'est ce que vous vouliez » ; l'absence de couleur
   dit le contraire sans crier — une route à péage reste choisissable, et la
   teinter en rouge la ferait passer pour une erreur. */
.variante__mentions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: 2px;
}

.variante__mention {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  border: 1px solid var(--hairline);
  color: var(--ink-muted);
}

.variante__mention.est-conforme {
  border-color: var(--route);
  color: var(--route);
}

/* Une aide qui signale une limite plutôt qu'un fonctionnement. Pas une
   alerte : rien n'est cassé, et le réglage est bien enregistré. */
.champ__aide--attention {
  border-left: 3px solid var(--ink-muted);
  padding-left: var(--space-3);
}

/* ------------------------------------------------------------------
   Écran 3 : les routes à gauche, la carte à droite.
   ------------------------------------------------------------------ */
/* Les formulaires sont tenus à 640 px — une colonne de texte se lit mal
   plus large. L'écran 3 est l'exception : la carte a besoin de la place. */
.ecran__form:has(.plan-carte) { max-width: none; }

/* L'écran Étapes n'a pas de formulaire unique à élargir : la grille y est
   posée directement, et c'est elle qui prend toute la largeur. */
.plan-carte--seule { max-width: none; }

.plan-carte {
  display: grid;
  grid-template-columns: minmax(20rem, 1fr) minmax(0, 1.25fr);
  gap: var(--space-6);
  align-items: start;
}

.plan-carte__choix { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
.plan-carte__vue { position: sticky; top: var(--space-6); min-width: 0; }

/* « carte » tout court désigne déjà les cartes du site : celle-ci porte donc
   son propre nom. Sans cela, toutes les cartes de « Mon compte » héritaient
   de cette hauteur fixe. */
.carte-vive {
  width: 100%;
  height: clamp(22rem, 58vh, 34rem);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
  overflow: hidden;
  background: var(--surface);
}

.carte-vive[hidden] { display: none; }

.carte-vive__vide {
  padding: var(--space-6);
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-row);
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 1.5;
}

.carte-vive__note,
.carte-vive__aide {
  margin-top: var(--space-2);
  font-size: 14px;
  color: var(--ink-muted);
}

/* La vignette suit la règle des tracés, comme la carte : la route
   choisie en --itineraire (ambre), les autres en --route-alt. Ces routes
   sont les alternatives d'Apple, pas des voies nommées : aucune couleur
   de voie ici. */
.variante__trace { color: var(--route-alt); }
.variante:has(input:checked) .variante__trace,
.variante--seule .variante__trace { color: var(--itineraire); }

/* Sous 62rem la carte passe au-dessus : c'est elle qu'on regarde d'abord. */
@media (max-width: 62rem) {
  .plan-carte { grid-template-columns: 1fr; }
  .plan-carte__vue { position: static; order: -1; }
  .carte-vive { height: clamp(16rem, 42vh, 24rem); }
}

/* Le tracé de la variante : dessiné dans la page, sans carte ni requête. */
.variante__trace {
  display: block;
  /* La vignette garde la forme du trajet — large pour un trajet est-ouest,
     haute pour un nord-sud — et le plafond l'empêche de manger la carte. */
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 8rem;
  margin-top: var(--space-3);
  overflow: visible;
}

.trace__ligne {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Le trait garde son épaisseur quelle que soit la réduction : sans cela,
     un long trajet se dessine avec un cheveu. */
  vector-effect: non-scaling-stroke;
}

.trace__depart {
  /* Creux, pas blanc : la pastille laisse voir le fond de la carte, quel
     qu'il soit, dans les deux thèmes. */
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

.trace__arrivee { fill: currentColor; }
.trace__halte { fill: var(--route); }

/* La route retenue se lit d'un coup d'oeil parmi les trois. */
.variante:has(input:checked) .trace__ligne { stroke-width: 3.6; }

@media (max-width: 480px) {
  .variante__trace { max-height: 6.5rem; }
}

/* --- Le récapitulatif ---------------------------------------------------- */

.recap {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.recap__ligne {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--hairline);
}

.recap__ligne dt {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

.recap__ligne dd {
  margin: 0;
  font-size: 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.recap__detail { font-size: 14px; color: var(--ink-muted); }

.recap__note {
  margin-top: var(--space-6);
  font-size: 14px;
  color: var(--ink-muted);
  max-width: 62ch;
}

@media (max-width: 560px) {
  .ecran { padding: var(--space-4); }
  .recap__ligne { grid-template-columns: 1fr; gap: var(--space-2); }
}

/* --- Les champs longs, courts et larges ---------------------------------- */

.champ textarea {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-row);
  color: var(--ink);
  font: inherit;
  font-size: 17px;
  line-height: 1.5;
  resize: vertical;
}

.champ textarea:focus { border-color: var(--route); outline: none; }

.champ textarea:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: 2px;
}

.champ--court input { text-align: center; }

.champ__aide {
  font-size: 13px;
  color: var(--ink-muted);
  max-width: 56ch;
}

.bouton--mince {
  min-height: 42px;
  padding-inline: var(--space-5);
  font-size: 15px;
}

.carte form .duo-champs { width: 100%; }

/* --- Les champs par paires ----------------------------------------------- */

.duo-champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  align-items: start;
}

.champ__note {
  font-weight: 400;
  font-size: 13px;
  color: var(--ink-muted);
}

/* --- Les groupes de choix ------------------------------------------------ */

.bloc {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
}

.bloc legend {
  padding-inline: var(--space-2);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-muted);
}

.bloc__suite {
  margin-left: 30px;
  padding-bottom: var(--space-2);
}

.bloc__suite[hidden] { display: none; }

.choix {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
  font-size: 15px;
}

.choix input {
  width: 19px;
  height: 19px;
  accent-color: var(--route);
  flex-shrink: 0;
}

/* Une fois, ou chaque semaine (écran Dates du planificateur). `.champ` est
   en flex : sans cette règle, l'attribut hidden ne cachait rien. */
.champ[hidden],
.repetition__jours[hidden] { display: none; }

/* « Une fois » et « Chaque semaine » côte à côte, les jours en dessous :
   empilés, les choix laissaient de grands vides (tour esthétique du
   13 octobre 2026). */
.repetition {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-6);
  margin: 0;
  padding: 0;
  border: 0;
}
.repetition legend { padding: 0; margin-bottom: var(--space-1); font-size: 15px; font-weight: 600; }
.repetition > .choix { min-height: 44px; }

.repetition__jours {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  gap: 0 var(--space-5);
  margin-top: var(--space-1);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-row);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}

/* La cible du doigt : 44 px de haut, même pour une case. */
.repetition__jour { min-height: 44px; }

/* Le bloc qui porte la répétition et les champs date et heure : le même
   écart que le reste du formulaire entre ses enfants. */
div[data-recurrence] { display: flex; flex-direction: column; gap: var(--space-5); }

/* --- Transitions entre pages ---------------------------------------------

   Passer d'une page à l'autre se fait en fondu plutôt que par un
   clignotement blanc. C'est le navigateur qui s'en charge : pas de
   routeur maison, pas de page rechargée en JavaScript, aucune adresse
   qui cesse de fonctionner. Les navigateurs qui ne connaissent pas
   encore ces règles les ignorent et naviguent comme avant.
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: page-sort var(--duree) var(--courbe) both; }
::view-transition-new(root) { animation: page-entre var(--duree) var(--courbe) both; }

@keyframes page-sort  { to   { opacity: 0; } }
@keyframes page-entre { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* --- Adaptations ---------------------------------------------------------- */

@media (max-width: 900px) {
  :root { --entete-h: 77px; }
  .entete__nav { display: none; }
  .entete__menu { display: flex; }
  .entete__cta { display: none; }
  /* Déconnecté, il n'y a pas de menu : le bouton Connexion reste visible. */
  .entete__cta--seul { display: inline-flex; }
  .entete__barre { gap: var(--space-4); justify-content: space-between; }
  .pied__haut { gap: var(--space-10); flex-direction: column; }
  .pied__colonnes { gap: var(--space-10); }
}

@media (max-width: 560px) {
  :root { --gouttiere: 16px; }
  /* Pas pour une carte repliable : sa marge est dans son en-tête et son
     contenu, et elle s'y ajoutait (titre à 45 px du bord, Graphiste G3). */
  .carte:not(.carte--pliee) { padding: var(--space-4); }
  .heros__actions { width: 100%; }
  .heros__actions .bouton { flex-grow: 1; }

  /* Lignes trop courtes pour être justifiées proprement : retour au fer
     à gauche, même avec la césure. */
  .texte p,
  .texte li {
    text-align: left;
  }
}
/* --- La page Carte -------------------------------------------------------- */

/* La carte est le sujet de la page : elle prend toute la fenêtre sous le
   menu, et les commandes se posent par-dessus. Un bandeau de titre et une
   colonne latérale, c'était un tiers de l'écran pris à ce qu'on est venu
   regarder. */

.atlas {
  position: relative;

  /* Le fond des panneaux flottants, plus opaque que --glass.
     Ceux-ci se posent sur une carte dont on ne choisit pas les couleurs :
     mesuré à 0.85, le texte d'invite de la recherche tombait à 4,02:1
     au-dessus d'une image satellite enneigée en thème sombre. À 0.94, le
     pire cas repasse au-dessus du seuil, et le flou garde l'effet de
     verre. */
  --atlas-verre: rgba(var(--ground-rgb), 0.94);

  /* La hauteur du menu est mesurée par atlas.js et posée en variable :
     deux lignes de menu sur un écran étroit, une seule sur un large, et
     une valeur en dur laisserait un trou ou une barre de défilement.
     La valeur de repli sert le temps que le script s'exécute.

     dvh et non vh : sur mobile, vh compte la barre d'adresse comme si
     elle était toujours repliée, et la carte dépasse sous l'écran. */
  height: calc(100dvh - var(--entete-h, 76px));
  min-height: 24rem;
  overflow: hidden;
}

.atlas__vue {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
}

.atlas__vue[hidden] { display: none; }

.atlas__vide {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: var(--space-8);
  color: var(--ink-muted);
  text-align: center;
}

/* --- Les commandes, posées sur la carte --- */

.atlas__commandes {
  position: absolute;
  top: var(--space-5);
  left: var(--space-5);
  right: var(--space-5);

  display: flex;
  align-items: flex-start;
  gap: var(--space-3);

  /* La barre ne doit pas intercepter les gestes destinés à la carte :
     seuls ses enfants réels le font. Sans cela, une bande invisible en
     haut de la carte refuserait le glissement. */
  pointer-events: none;
}

.atlas__commandes > * { pointer-events: auto; }

.atlas__recherche {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 0 1 26rem;
  min-width: 0;

  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-2);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-full);

  /* Posée sur une carte dont on ne connaît pas les couleurs : le flou et
     l'ombre la détachent aussi bien d'une forêt que d'un lac. */
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 6px 24px rgba(var(--ground-rgb), 0.28);
}

.atlas__recherche input[type="search"] {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 42px;
  padding: 0 var(--space-3);
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  /* 17px : en dessous de 16px, iOS agrandit la page à la mise au point du
     champ, et le visiteur se retrouve avec une carte zoomée. */
  font-size: 17px;
  -webkit-appearance: none;
  appearance: none;
}

.atlas__recherche input[type="search"]::placeholder { color: var(--ink-muted); }
.atlas__recherche input[type="search"]:focus { outline: none; }

.atlas__recherche:focus-within {
  outline: 2px solid var(--route);
  outline-offset: 1px;
}

/* La loupe, en tête du champ : un repère, pas un bouton. */
.atlas__loupe {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-left: var(--space-2);
  fill: none;
  stroke: var(--ink-muted);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* La croix qui efface. Le champ de recherche du navigateur a la sienne ;
   elle est retirée pour n'en garder qu'une, la même partout. */
.atlas__effacer[hidden] { display: none; }
.atlas__recherche input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

/* Le bouton rond de la barre : effacer. */
.atlas__chercher {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.atlas__chercher svg {
  width: 20px;
  height: 20px;
  /* Des traits, pas des aplats : l'icône reste nette dans les deux
     thèmes sans qu'on ait à en dessiner deux versions. */
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.atlas__chercher:hover { color: var(--route); }

.atlas__chercher:focus-visible { box-shadow: var(--focus-ring); }

/* --- Les résultats de recherche, et les messages --- */

.atlas__resultats,
.atlas__message {
  position: absolute;
  top: calc(44px + var(--space-3));
  left: 0;
  width: min(26rem, calc(100vw - 2 * var(--space-5)));

  padding: var(--space-3);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-panel);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 12px 40px rgba(var(--ground-rgb), 0.38);
}

.atlas__message {
  padding: var(--space-4) var(--space-5);
  font-size: 15px;
  color: var(--ink);
}

.atlas__resultats[hidden],
.atlas__message[hidden] { display: none; }

/* Les filtres (26 octobre 2026) : une rangée de pastilles sous la
   recherche. Sur un écran étroit, elle défile à l'horizontale plutôt que
   de couvrir la carte sur trois lignes. Les résultats et le message se
   posent par-dessus quand ils s'ouvrent. */
.atlas__filtres {
  position: absolute;
  top: calc(44px + var(--space-3));
  left: 0;
  right: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.atlas__filtres[hidden] { display: none; }

.atlas__filtre {
  min-height: 36px;
  padding: 0 var(--space-4);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-full);
  background: var(--atlas-verre);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 4px 16px rgba(var(--ground-rgb), 0.22);
  color: var(--ink-muted);
  font: 500 14px/1 var(--sans);
  white-space: nowrap;
  cursor: pointer;
}

.atlas__filtre[aria-pressed="true"] {
  background: var(--route-soft);
  border-color: var(--route);
  color: var(--ink);
}

.atlas__filtre[aria-pressed="false"] { opacity: 0.72; }

.atlas__filtre:focus-visible { outline: 2px solid var(--route); outline-offset: 2px; }

.atlas__resultats,
.atlas__message { z-index: 2; }

/* Le message et les résultats occupent la même place : quand les deux
   sont là, les résultats descendent sous le message. */
.atlas__message:not([hidden]) ~ .atlas__resultats {
  top: calc(44px + var(--space-3) + 4.5rem);
}

.atlas__rien {
  padding: var(--space-3);
  font-size: 15px;
  color: var(--ink-muted);
}

.atlas__trouvailles {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  max-height: 20rem;
  overflow-y: auto;
}

.atlas__trouvaille {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: var(--space-3);
  border: 0;
  border-radius: var(--radius-row);
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.atlas__trouvaille:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }

.atlas__trouvaille:focus-visible {
  outline: 2px solid var(--route);
  outline-offset: -2px;
}

.atlas__trouvaille[aria-current] {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  box-shadow: inset 2px 0 0 var(--route);
}

.atlas__trouvaille-nom { font-weight: 600; font-size: 15px; }

.atlas__trouvaille-adresse {
  font-size: 13px;
  color: var(--ink-muted);
}

/* --- Les suggestions (composant SuggestionList de la charte) -------------
   Le même dessin pour la recherche de la carte et pour le champ de lieu
   du planificateur : une épingle route, le nom sur une ligne (body),
   l'adresse sur une ligne en dessous (footnote, ink-muted), un filet entre
   deux suggestions. Ce qui dépasse se coupe sur « … » plutôt que de
   s'enrouler : une liste se parcourt, elle ne se lit pas. */
.suggestion {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  align-items: start;
  column-gap: var(--space-3);
}

.suggestion__epingle {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  fill: none;
  stroke: var(--route);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.suggestion__textes { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.suggestion__nom,
.suggestion__adresse {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.suggestion__nom { font-size: 17px; line-height: 22px; font-weight: 400; color: var(--ink); }
.suggestion__adresse { font-size: 13px; line-height: 18px; color: var(--ink-muted); }

.atlas__trouvailles { gap: 0; }
.atlas__trouvailles > li + li,
.lieu__resultats > li + li { border-top: 1px solid var(--hairline); }

/* Sans JavaScript, rien de tout cela ne répond : les lignes redeviennent
   du texte plutôt que des boutons qui font semblant. */
html:not(.js) .atlas__trouvaille {
  cursor: default;
  pointer-events: none;
}

/* Sur un écran étroit, la barre de recherche prend la largeur et le
   bouton de réglages reste à côté : le panneau, lui, s'aligne à droite
   sans dépasser. */
@media (max-width: 40rem) {
  .atlas__commandes {
    top: var(--space-3);
    left: var(--space-3);
    right: var(--space-3);
    gap: var(--space-2);
  }

  .atlas__recherche { flex: 1 1 auto; }

  .atlas__filtres {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: var(--space-1);
  }

  .atlas__filtres::-webkit-scrollbar { display: none; }

  .atlas__resultats,
  .atlas__message {
    width: calc(100vw - 2 * var(--space-3));
  }

  .atlas__resultats,
  .atlas__message { left: 0; }
}

/* ------------------------------------------------------------------
   Exploration : le passeport posé sur la carte.

   Même verre que les commandes de la page Carte — c'est le même genre de
   panneau flottant au-dessus d'une carte dont on ne choisit pas les
   couleurs, et il lui faut la même opacité pour rester lisible sur un
   satellite enneigé comme sur une ville de nuit.
   ------------------------------------------------------------------ */

/* Sur cette page, les panneaux s'empilent au lieu de se ranger côte à
   côte : il n'y a pas de barre de recherche pour leur tenir la ligne, et
   le bandeau de panne, positionné en absolu pour la page Carte, tombait
   par-dessus le passeport. Vu à l'écran le 28 septembre. */
.atlas--exploration .atlas__commandes {
  flex-direction: column;
  align-items: flex-start;
  width: min(22rem, calc(100vw - 2 * var(--space-5)));

  /* La colonne s'arrête avant le bas de l'écran et défile si besoin :
     avec une dizaine de tampons elle passait sous la fenêtre, et la
     dernière ligne se lisait à moitié. Le --entete-h est posé par
     atlas.js ; le reste est la marge haute et basse. */
  max-height: calc(100dvh - var(--entete-h, 88px) - 2 * var(--space-5));
  overflow-y: auto;
  overscroll-behavior: contain;
  gap: var(--space-4);

  /* Le défilement rend la colonne cliquable sur toute sa hauteur : sans
     cela elle intercepterait les gestes destinés à la carte. */
  pointer-events: none;
}

.atlas--exploration .atlas__commandes > * { pointer-events: auto; }

/* Sous 640 px, les panneaux recouvraient toute la carte (Graphiste, n° 14) :
   ils deviennent une feuille posée en bas, qui laisse voir la carte et
   défile sur elle-même. Le bouton « me localiser » se place au-dessus. */
@media (max-width: 640px) {
  .atlas--exploration .atlas__commandes {
    top: auto;
    bottom: var(--space-4);
    left: var(--space-4);
    right: var(--space-4);
    width: auto;
    max-height: 42dvh;
    scrollbar-width: none;   /* R5 */
  }
  .atlas--exploration .atlas__commandes::-webkit-scrollbar { display: none; }
  .atlas__position { bottom: calc(42dvh + 2 * var(--space-4)); left: auto; right: var(--space-4); }
}

/* Pages à carte plein écran : l'en-tête prend toute la largeur, avec la
   même marge que les panneaux posés sur la carte. Le logo et les panneaux
   s'alignent (Graphiste, règle G7). */
body:has(.atlas) .entete__barre {
  max-width: none;
  padding-inline: var(--space-5);
}
@media (max-width: 640px) {
  body:has(.atlas) .entete__barre { padding-inline: var(--space-4); }
}

/* Le bouton « me localiser » de la carte d'exploration, en haut à droite,
   loin des panneaux de gauche. Même verre que la barre de recherche. */
.atlas__position {
  position: absolute;
  z-index: 2;
  top: var(--space-5);
  right: var(--space-5);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
}
.atlas__position[hidden] { display: none; }

/* Sous 640 px, voir la feuille d'exploration plus haut : le bouton se
   place au-dessus d'elle, à droite. */
@media (max-width: 640px) {
  .atlas__position { top: auto; left: auto; right: var(--space-4); bottom: calc(42dvh + 2 * var(--space-4)); }
}
.atlas__position[aria-busy="true"] { color: var(--ink-muted); }

/* Le point d'Exploration (charte, composant ExplorationPoint). Le halo
   est blanc dans les deux thèmes : c'est lui qui détache le point du
   brouillard comme de la carte dégagée. */
.point-exploration { display: block; overflow: visible; }
.point-exploration__halo { fill: #ffffff; filter: drop-shadow(0 1.5px 1.6px #00000059); }
.point-exploration__clair { fill: var(--route); }
.point-exploration__sombre { fill: var(--route-deep); }

.atlas--exploration .atlas__message {
  position: static;
  width: 100%;
}

.passeport {
  width: 100%;
  min-width: 0;

  padding: var(--space-4) var(--space-5);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-panel);
  backdrop-filter: blur(12px);
}

.passeport__titre {
  margin: 0 0 var(--space-3);
  font-size: 15px;
  font-weight: 600;
}

.passeport__chiffres { margin: 0; }

.passeport__ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--hairline);
}

.passeport__ligne:first-child { border-top: 0; }

.passeport__ligne dt {
  font-size: 14px;
  color: var(--ink-muted);
}

.passeport__ligne dd {
  margin: 0;
  font-weight: 600;
  /* Trois lignes empilées dont les chiffres s'alignent : sans chasse
     fixe, « 1 240 » et « 212,5 » ne tombent pas l'un sous l'autre. */
  font-variant-numeric: tabular-nums;
}

.passeport__vide {
  margin: 0;
  font-size: 14px;
  color: var(--ink-muted);
}

.passeport__note {
  margin: var(--space-3) 0 0;
  font-size: 13px;
  color: var(--ink-muted);
}

/* Sur un téléphone, le panneau prend la largeur : à 20rem il déborderait,
   et la carte n'a de toute façon plus la place d'être regardée à côté. */
@media (max-width: 34rem) {
  .passeport { flex: 1 1 100%; }
}

/* ------------------------------------------------------------------
   Le passeport : un tampon par pays.

   Sous le résumé, dans la même colonne de verre. La liste peut être
   longue — un grand voyageur a vingt pays —, d'où le défilement propre
   au panneau plutôt qu'à la page : la carte, elle, ne défile pas.
   ------------------------------------------------------------------ */

.tampons {
  width: 100%;
  min-width: 0;

  padding: var(--space-4) var(--space-5);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-panel);
  backdrop-filter: blur(12px);
}

.tampons__liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tampon {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--hairline);
}

.tampon:first-child { border-top: 0; }

/* Le drapeau est un émoji : sa taille suit le texte, et aucune police
   d'icônes n'est nécessaire. aria-hidden côté HTML — le nom du pays est
   juste à côté, et « drapeau de la Suisse Suisse » se lit deux fois. */
.tampon__drapeau {
  font-size: 22px;
  line-height: 1.2;
  flex-shrink: 0;
}

.tampon__corps {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.tampon__pays {
  font-weight: 600;
  font-size: 15px;
}

.tampon__chiffres {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* Le séparateur appartient au chiffre qui suit, pas à celui qui précède :
   collé à la fin, un retour à la ligne laissait un « · » suspendu tout
   seul en bout de ligne. */
.tampon__chiffres > span + span::before {
  content: '·';
  margin: 0 0.35em;
  color: var(--ink-muted);
  font-weight: 400;
}

.tampon__depuis {
  font-size: 12px;
  color: var(--ink-muted);
}


/* --- La charte typographique ---------------------------------------------

   Michroma ne sert qu'aux libellés de marque : les surtitres, les noms de
   catégories, les intitulés de colonnes du pied de page, le sommaire. C'est
   le registre du mot-symbole — court, en capitales, largement espacé — et le
   seul où une police d'affichage tient sans fatiguer l'œil.

   Elle ne touche ni les titres (h1, h2, h3) ni le texte courant. Michroma n'a
   ni grasse ni italique, et ses lettres sont deux fois plus larges que celles
   du système : un h1 de 76 px passerait de seize signes à huit par ligne, et
   « text-wrap: balance » n'y pourrait rien.

   Elle ne touche pas non plus les étiquettes d'état ni les en-têtes de
   tableau. La règle, pour la suite : un libellé qui dit qui nous sommes prend
   Michroma ; un libellé qui dit où en est quelque chose garde la police du
   système. Les deux se côtoient sur la même page sans se gêner, parce qu'ils
   ne disent pas la même chose.

   L'interlettrage redescend à 0,04 em. Michroma porte déjà ses blancs : les
   0,09 em prévus pour la police système la feraient flotter.
   ------------------------------------------------------------------------- */

/* Dans la Web App, les surtitres gardent la police du système
   (12 octobre 2026). La charte réserve Michroma aux libellés de marque,
   et dans l'outil — planificateur, carte, compte — ce sont des repères
   d'état : « Écran 2 sur 5 », « Mon compte ». Restent en Michroma le
   sommaire et les colonnes du pied de page, et le logo, qui est un dessin.
   La vitrine, elle, garde ses surtitres en Michroma. */
.heros__surtitre,
.faq__categorie,
.sommaire__titre,
.pied__colonne h2 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0.04em;
}

/* Michroma compose une fois et demie plus large que la police du système :
   « Pour tous vos déplacements » tenait sur une ligne, plus maintenant, et la
   pastille du héros passait à deux lignes sous 400 px de large. Un point de
   moins et elle tient. Elle ne paraît pas plus petite pour autant : les
   capitales de Michroma occupent les trois quarts du corps, contre un peu
   moins pour celles du système. Mesuré à 390 px, largeur d'un iPhone. */
@media (max-width: 560px) {
  .heros__surtitre { font-size: 12px; }
}

/* La carte Magellus+ : l'état à l'encre, l'explication en dessous, plus
   petite (Graphiste, 13 octobre 2026). */
[data-carte="abonnement"] strong { color: var(--ink); }
[data-carte="abonnement"] .carte__contenu > p + p {
  margin-top: var(--space-2);
  color: var(--ink-muted);
  font-size: 13px;
}

/* La proposition de « Surprenez-moi », écran Destination (13 octobre 2026) :
   un voyage entier, comme dans l'app — titre, pourquoi, date, étapes. */
.proposition {
  display: grid;
  gap: var(--space-3);
  margin: 0 0 var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
  background: var(--surface);
}

.proposition legend {
  padding: 0 var(--space-2);
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
}

.proposition__pourquoi { margin: 0; color: var(--ink); }

.proposition__faits {
  margin: 0;
  font-size: 13px;
  color: var(--ink-muted);
}

.proposition__etapes {
  margin: 0;
  padding-left: var(--space-5);
  font-size: 15px;
}

.proposition__etapes li + li { margin-top: var(--space-1); }

/* Le détail d'une étape, replié (13 octobre 2026). */
.etape__details {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-2);
}

.etape__details > summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  font-weight: 600;
  color: var(--route);
  cursor: pointer;
}

.etape__details textarea { width: 100%; resize: vertical; }

/* Les trois voies de l'écran Itinéraire (13 octobre 2026) : Rapide,
   Découverte, Économe, comme dans l'app. La couleur de chaque voie ne
   marque que l'onglet courant. */
.voies {
  display: flex;
  gap: var(--space-1);
  margin: 0 0 var(--space-4);
  padding: var(--space-1);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  overflow-x: auto;
}

.voies__onglet {
  flex: 1 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-4);
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-muted);
  text-decoration: none;
  white-space: nowrap;
}

.voies__onglet:hover { color: var(--ink); }
.voies__onglet:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

.voies__onglet.est-courant { color: var(--on-route); background: var(--voie-rapide); }
.voies__onglet--decouverte.est-courant { background: var(--voie-decouverte); }
.voies__onglet--econome.est-courant { background: var(--voie-econome); }

.voies__plus {
  font-size: 11px;
  font-weight: 600;
  opacity: .8;
}

.voies__verrou {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
  margin-bottom: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-row);
}

.voies__verrou p { margin: 0; }

/* L'accord pour l'IA (13 octobre 2026) : la carte de l'app, AIConsentCard. */
.ia-accord {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-3) 0 var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-row);
  background: var(--route-soft);
  color: var(--ink);
}

.ia-accord p, .ia-accord ul { margin: 0; }
.ia-accord__titre { font-weight: 600; }
.ia-accord__boutons { display: flex; flex-wrap: wrap; gap: var(--space-3); }

.variante__decouverte { color: var(--ink); }

@media (max-width: 639px) {
  .voies__onglet { min-height: 44px; }
}

/* La couleur d'accent, Personnalisation Magellus+ (13 octobre 2026) :
   les valeurs de l'app (Theme.palette), aux deux thèmes. Lagon, le
   turquoise de la charte, reste celle de tout le monde par défaut. Aucun
   accent ne reprend l'ambre des tracés ni le violet de l'Économe. */
:root[data-perso-accent="glacier"] { --route: #5ab0ff; --route-rgb: 90, 176, 255; --route-soft: #10283f; --route-ink: #5ab0ff; --on-route: #04162a; }
:root[data-perso-accent="forest"] { --route: #5fd08a; --route-rgb: 95, 208, 138; --route-soft: #123a24; --route-ink: #5fd08a; --on-route: #05200f; }
:root[data-perso-accent="raspberry"] { --route: #ff7aa8; --route-rgb: 255, 122, 168; --route-soft: #3d1424; --route-ink: #ff7aa8; --on-route: #2a0613; }
:root[data-perso-accent="slate"] { --route: #c9d3e0; --route-rgb: 201, 211, 224; --route-soft: #1f2a38; --route-ink: #c9d3e0; --on-route: #0b1526; }
:root[data-theme="light"][data-perso-accent="glacier"] { --route: #1a5fb4; --route-rgb: 26, 95, 180; --route-soft: #ddebfb; --route-ink: #154c90; --on-route: #ffffff; }
:root[data-theme="light"][data-perso-accent="forest"] { --route: #1e7a45; --route-rgb: 30, 122, 69; --route-soft: #dff3e6; --route-ink: #175f36; --on-route: #ffffff; }
:root[data-theme="light"][data-perso-accent="raspberry"] { --route: #b0245a; --route-rgb: 176, 36, 90; --route-soft: #fbe1eb; --route-ink: #8c1c47; --on-route: #ffffff; }
:root[data-theme="light"][data-perso-accent="slate"] { --route: #3a4a5e; --route-rgb: 58, 74, 94; --route-soft: #e4eaf1; --route-ink: #2c3a4b; --on-route: #ffffff; }

/* La carte Personnalisation (13 octobre 2026). */
.perso { display: grid; gap: var(--space-5); }

.perso__groupe {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  border: 0;
}

.perso__groupe > legend {
  margin-bottom: var(--space-3);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.perso__choix { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.perso__pastille { position: relative; }

.perso__pastille input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.perso__pastille span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: 0 var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  font-size: 15px;
  color: var(--ink);
  cursor: pointer;
}

.perso__pastille input:checked + span {
  border-color: var(--route);
  background: var(--route-soft);
  font-weight: 600;
}

.perso__pastille input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* La pastille de couleur, dans la teinte du thème courant. */
.perso__pastille[class*="--"] span::before {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--pastille);
}

.perso__pastille--lagoon    { --pastille: #3fd0c0; }
.perso__pastille--glacier   { --pastille: #5ab0ff; }
.perso__pastille--forest    { --pastille: #5fd08a; }
.perso__pastille--raspberry { --pastille: #ff7aa8; }
.perso__pastille--slate     { --pastille: #c9d3e0; }
:root[data-theme="light"] .perso__pastille--lagoon    { --pastille: #0a7770; }
:root[data-theme="light"] .perso__pastille--glacier   { --pastille: #1a5fb4; }
:root[data-theme="light"] .perso__pastille--forest    { --pastille: #1e7a45; }
:root[data-theme="light"] .perso__pastille--raspberry { --pastille: #b0245a; }
:root[data-theme="light"] .perso__pastille--slate     { --pastille: #3a4a5e; }

@media (max-width: 639px) {
  .perso__pastille span { min-height: 44px; }
}

/* L'import Fog of World, sous le Passeport (13 octobre 2026) : la même
   carte de verre que les tampons. */
.import-fow {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
  width: 100%;
  min-width: 0;
  padding: var(--space-4) var(--space-5);
  background: var(--atlas-verre);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-panel);
  backdrop-filter: blur(12px);
}

.import-fow[hidden] { display: none; }
.import-fow .passeport__titre,
.import-fow .passeport__note { margin: 0; }
.import-fow__choisir { cursor: pointer; }
.import-fow__choisir:focus-within { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* « Votre parcours peut être optimisé » (Magellus+, 13 octobre 2026,
   session Planification) : une notification dans la liste des étapes,
   pas une fenêtre — on peut l'ignorer et continuer d'écrire. */
.ordre {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--route);
  border-radius: var(--radius-row);
  background: var(--surface);
  color: var(--ink);
}

.ordre[hidden] { display: none; }

.ordre__titre { font-size: 16px; font-weight: 700; color: var(--ink); }
.ordre__texte { margin-top: var(--space-2); font-size: 14px; color: var(--ink-muted); }

.ordre__detail { margin-top: var(--space-3); font-size: 14px; }
.ordre__detail summary { cursor: pointer; color: var(--route); font-weight: 600; }

.ordre__listes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.ordre__legende { font-size: 13px; font-weight: 700; color: var(--ink-muted); }
.ordre__listes ol { margin: var(--space-2) 0 0; padding-left: 1.4em; color: var(--ink-muted); }
.ordre__listes li + li { margin-top: 2px; }
.ordre__deplacee { color: var(--ink); font-weight: 700; }

.ordre__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-4);
}

/* « Où s'arrêter en chemin » : les lieux de la Découverte (13 octobre 2026,
   session Planification), sous la liste des routes. */
.arrets-decouverte {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--route);
  border-radius: var(--radius-row);
  background: var(--surface);
}

.arrets-decouverte__titre { font-size: 16px; font-weight: 700; color: var(--ink); }
.arrets-decouverte__liste { margin: var(--space-3) 0 0; padding: 0; list-style: none; display: grid; gap: var(--space-3); }

.arrets-decouverte__lieu {
  display: grid;
  gap: 2px;
  padding-top: var(--space-3);
  border-top: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
}

.arrets-decouverte__lieu:first-child { padding-top: 0; border-top: 0; }
.arrets-decouverte__nom { font-weight: 700; color: var(--ink); }
.arrets-decouverte__pourquoi { font-size: 14px; color: var(--ink-muted); }
.arrets-decouverte__lieu form { margin-top: var(--space-2); }

/* Le rappel d'un paiement refusé (25.10.2026) : une bande sous l'en-tête,
   discrète, qui se ferme jusqu'au lendemain. */
.rappel {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  background: var(--route-soft);
  color: var(--ink);
  font-size: 14.5px;
}

.rappel__texte { flex: 1; min-width: 0; margin: 0; }
.rappel__texte a { color: var(--route-ink); font-weight: 600; }

.rappel__fermer {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-row);
}

.rappel__fermer:focus-visible { outline: 2px solid var(--route); outline-offset: 2px; }

:root[data-rappel-ferme] .rappel { display: none; }

/* Le choix de formule de la page d'abonnement sans compte (26.10.2026) :
   un vrai groupe de boutons radio, sans le cadre par défaut du navigateur. */
fieldset.champ {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
  display: grid;
  gap: var(--space-3);
}

fieldset.champ > legend {
  padding: 0;
  margin-bottom: var(--space-2);
  font-size: 15px;
  font-weight: 600;
}

/* Le rappel personnalisé de la Planification (27.10.2026) : un nombre et
   une unité, montrés seulement quand « Personnalisé » est choisi. Sans
   :has() (navigateur ancien), ils restent visibles : rien n'est perdu. */
.rappel-choix__perso {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.rappel-choix__perso input[type="number"] {
  width: 6rem;
  flex: none;
}

.rappel-choix__perso select {
  width: auto;
  flex: 1 1 9rem;
}

.rappel-choix__avant { color: var(--ink-muted); }

.rappel-choix:not(:has(option[value="perso"]:checked)) .rappel-choix__perso,
.rappel-choix:not(:has(option[value="perso"]:checked)) .champ__aide { display: none; }
