/*
 * Fossilus — mise en page.
 *
 * Le contexte d'usage réel : une falaise ventée, une main occupée par le
 * marteau, des doigts gantés ou mouillés, du soleil rasant, aucun réseau, et
 * une batterie qui doit tenir jusqu'au retour (§6.6). Tout ce qui suit découle
 * de là, pas d'un simulateur de navigateur.
 */

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  overflow: hidden;                    /* la carte gère son propre défilement */
  background: var(--fond-0);
  color: var(--encre);
  font-family: var(--f-ui);
  font-size: var(--t-texte);
  -webkit-text-size-adjust: 100%;
  overscroll-behavior: none;           /* pas de rebond qui déclenche un retour */
}

/* Aucune commande ne doit pouvoir déclencher le zoom par double-tap (§6.6). */
button, .cmd, .onglet, .rail-bande, .poignee, input, select, textarea {
  touch-action: manipulation;
}

button {
  font: inherit; color: inherit;
  background: none; border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ */
/* Carte                                                               */
/* ------------------------------------------------------------------ */

#carte {
  position: fixed; inset: 0;
  background: var(--fond-0);
  z-index: 0;
}

.leaflet-container { background: var(--fond-0); font-family: var(--f-ui); }

.leaflet-control-attribution {
  background: var(--voile) !important;
  color: var(--encre-3) !important;
  font-size: 10px;
  padding: 2px 6px;
  /* Remontée au-dessus de la barre d'onglets et de la zone sûre. */
  margin-bottom: calc(var(--sa-b) + 62px) !important;
  margin-left: calc(var(--sa-l) + 4px) !important;
  max-width: 62vw;
}
.leaflet-control-attribution a { color: var(--encre-2) !important; }

/* Réticule central : la cible du bouton « Identifier ». */
#carte::after {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 22px; height: 22px;
  margin: -11px 0 0 -11px;
  border: 1px solid var(--encre-2);
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,.5), inset 0 0 0 1px rgba(0,0,0,.4);
  opacity: .55;
  pointer-events: none;
  z-index: 400;
}
#carte::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 1px; height: 1px;
  background: var(--encre);
  box-shadow: 0 0 2px 1px rgba(0,0,0,.6);
  pointer-events: none; z-index: 401;
}

/* ------------------------------------------------------------------ */
/* Bandeau d'état                                                      */
/* ------------------------------------------------------------------ */

.bandeau {
  position: fixed;
  top: calc(var(--sa-t) + 8px);
  left: calc(var(--sa-l) + 8px);
  right: calc(var(--sa-r) + var(--rail) + 14px);
  z-index: 950;
  background: var(--voile);
  border: 1px solid var(--trait-fort);
  border-left: 3px solid var(--statut-verifier);
  border-radius: var(--rayon);
  padding: 9px 11px;
  font-size: var(--t-ui);
  line-height: 1.35;
  color: var(--encre-2);
  backdrop-filter: blur(6px);
}
.bandeau b { color: var(--encre); font-weight: 600; }
.bandeau[data-ton="erreur"] { border-left-color: var(--statut-interdit); }
.bandeau[data-ton="ok"] { border-left-color: var(--statut-autorise); }

/* ------------------------------------------------------------------ */
/* Repère de version                                                   */
/* ------------------------------------------------------------------ */

/*
 * Discret par construction : c'est une information de maintenance, pas de
 * terrain. Assez lisible pour être vérifié d'un regard, assez effacé pour ne
 * pas concurrencer la carte.
 */
.version {
  position: fixed;
  top: calc(var(--sa-t) + 8px);
  left: calc(var(--sa-l) + 8px);
  z-index: 920;
  min-height: 26px;
  padding: 4px 9px;
  display: flex; align-items: center; gap: 6px;
  background: var(--voile);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  color: var(--encre-3);
  font-family: var(--f-data);
  font-size: 11px;
  letter-spacing: .04em;
  backdrop-filter: blur(6px);
}
:root[data-rail="gauche"] .version {
  left: auto; right: calc(var(--sa-r) + 8px);
}
/* Le bandeau d'état passe dessous plutôt que de le recouvrir. */
.version:not([hidden]) ~ .bandeau { top: calc(var(--sa-t) + 42px); }
.version[data-etat="ancienne"] { color: var(--statut-verifier); border-color: var(--statut-verifier); }
.version[data-etat="ancienne"]::after { content: '↻'; font-size: 13px; }
.version[data-etat="local"] { opacity: .55; }
.version[data-etat="maj"] { color: var(--encre); border-color: var(--encre-3); }

/* ------------------------------------------------------------------ */
/* Pictogrammes de taxons                                              */
/* ------------------------------------------------------------------ */

.picto {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  color: currentColor;
}
.picto svg { width: 100%; height: 100%; display: block; }
.picto-defaut {
  border: 1px solid var(--trait-fort);
  border-radius: 50%;
  font-family: var(--f-data);
  font-size: 10px; font-weight: 700;
  color: var(--encre-3);
}

/* Chance de rencontre : une barre courte à côté du glyphe. Le libellé complet
   reste dans la fiche — ici on ne donne qu'un ordre de grandeur lisible en
   rafale. */
.jauge-chance {
  display: block;
  width: 100%; height: 2px;
  margin-top: 2px;
  background: var(--fond-3);
  border-radius: 1px; overflow: hidden;
}
.jauge-chance > i { display: block; height: 100%; background: var(--encre-3); }
.jauge-chance[data-n="forte"] > i { background: var(--statut-autorise); }
.jauge-chance[data-n="moyenne"] > i { background: var(--encre-2); }
.jauge-chance[data-n="faible"] > i { background: var(--encre-3); }

/* Mises en garde repliées, au-dessus de la liste des cibles.
   Elles doivent rester accessibles (§11) sans repousser la première cible hors
   de l'écran : une ligne, et le texte à un appui. */
.notes {
  margin: 0 0 10px;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  background: var(--fond-2);
}
.notes > summary {
  min-height: 38px;
  padding: 0 12px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--f-data); font-size: 11.5px;
  letter-spacing: .03em;
  color: var(--encre-3);
  cursor: pointer;
}
.notes > summary::before { content: 'ⓘ'; font-size: 13px; }
.notes-corps { padding: 0 12px 10px; }
.notes-corps p {
  margin: 0 0 8px;
  font-size: 12.5px; line-height: 1.45; color: var(--encre-3);
}
.notes-corps p:last-child { margin-bottom: 0; }
.notes-corps b { color: var(--encre-2); }

/* « Où en trouver ? » — quand la vue courante n'a rien de bon pour le fossile
   demandé, une liste de mauvaises réponses reste une mauvaise réponse. */
.avis-ailleurs {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 10px;
  padding: 8px 10px;
  border: 1px solid var(--statut-verifier);
  border-radius: var(--rayon);
  background: var(--fond-2);
}
.avis-ailleurs p {
  flex: 1; margin: 0;
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--encre-2);
}
.avis-ailleurs b { color: var(--encre); font-family: var(--f-data); }
.avis-ailleurs .bouton { flex: 0 0 auto; }

/* Même cartouche, mais en colonne : la liste est vide, on a la place et il y a
   deux phrases à lire avant de choisir entre deux issues. */
.avis-vide { flex-direction: column; align-items: stretch; gap: 8px; padding: 11px 12px; }
.avis-vide p { display: block; line-height: 1.45; }
.avis-motifs { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.avis-motifs li { font-size: 13px; color: var(--encre-2); }
.avis-motifs b { font-family: var(--f-data); color: var(--encre); }
.avis-exemple {
  display: block;
  font-family: var(--f-texte); font-size: 12.5px; line-height: 1.35;
  color: var(--encre-3);
}
.avis-vide .boutons { margin-top: 2px; }

/* Légende des pastilles de la carte, en tête de la liste des cibles. */
.legende-carte {
  margin: 0 0 12px;
  font-size: 12.5px; line-height: 1.7; color: var(--encre-3);
}
.legende-puce {
  display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; margin-inline-end: 5px;
  vertical-align: -4px;
  border: 2px solid var(--encre-3); border-radius: 50%;
  background: var(--fond-0);
  font-family: var(--f-data); font-size: 10px; font-weight: 700;
  color: var(--encre);
}
.legende-puce[data-predit="1"] { border-style: dashed; border-width: 1.6px; }

/* Bande de taxons sous une cible de la liste.
   Le glyphe seul ne suffisait pas : il fallait le connaître pour le lire, et la
   jauge sans échelle ne disait pas grand-chose. Nom et pour-cent à côté. */
.taxons {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 5px;
  margin-top: 7px;
}
.taxon-puce {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px 3px 5px;
  border: 1px solid var(--trait); border-radius: 20px;
  background: var(--fond-2);
  color: var(--encre-2);
  font-size: 12px; line-height: 1.1;
}
.taxon-puce .picto { flex: 0 0 auto; }
.taxon-nom { white-space: nowrap; }
.taxon-pc {
  font-family: var(--f-data); font-weight: 700; font-size: 11.5px;
  color: var(--encre-3);
}
.taxon-puce[data-n="forte"] {
  color: var(--encre);
  border-color: var(--statut-autorise);
}
.taxon-puce[data-n="forte"] .taxon-pc { color: var(--statut-autorise); }
.taxon-puce[data-n="faible"] { color: var(--encre-3); opacity: .8; }
/* Le taxon qu'on a demandé se voit, même à faible chance : c'est la réponse à
   la question posée, pas un fossile parmi d'autres. */
.taxon-puce[data-vise="1"] {
  opacity: 1;
  color: var(--encre);
  border-color: var(--encre-3);
  background: var(--fond-3);
}
.taxon-puce[data-vise="1"] .taxon-nom { font-weight: 700; }
.taxon-reste {
  align-self: center;
  font-family: var(--f-data); font-size: 11.5px; color: var(--encre-3);
}

/* ------------------------------------------------------------------ */
/* Colonne stratigraphique (§6.1) — élément signature                  */
/* ------------------------------------------------------------------ */

.rail {
  position: fixed;
  top: calc(var(--sa-t) + 8px);
  bottom: calc(var(--sa-b) + 62px);
  right: calc(var(--sa-r) + 6px);
  width: var(--rail);
  z-index: 900;
  display: flex; flex-direction: column;
  gap: 4px;
  pointer-events: none;
}
:root[data-rail="gauche"] .rail {
  right: auto;
  left: calc(var(--sa-l) + 6px);
}
:root[data-rail="gauche"] .bandeau {
  right: calc(var(--sa-r) + 8px);
  left: calc(var(--sa-l) + var(--rail) + 14px);
}

.rail-tete { pointer-events: auto; display: flex; justify-content: center; }

.rail-btn {
  width: var(--rail); height: 44px;
  background: var(--voile);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  color: var(--encre-2);
  font-size: 11px; font-weight: 700; letter-spacing: .08em;
  backdrop-filter: blur(6px);
}
.rail-btn:disabled { opacity: .5; }

.rail-bandes {
  flex: 1;
  display: flex; flex-direction: column;
  gap: 2px;
  pointer-events: auto;
  border: 1px solid var(--trait-fort);
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--fond-1);
  box-shadow: 0 2px 14px rgba(0,0,0,.5);
}

/*
 * Une bande par système. La hauteur est proportionnelle à l'intérêt
 * paléontologique LOCAL, pas à la durée géologique : le Quaternaire dure
 * 2,6 Ma et n'intéresse personne ici, l'Ordovicien moyen dure 12 Ma et porte
 * toute la faune de Postolonnec.
 */
.rail-bande {
  position: relative;
  flex-grow: var(--part, 1);
  flex-basis: 0;
  /* 44 px minimum, même pour les systèmes de faible intérêt : une bande de
     26 px est intouchable avec un gant. Sur un écran de 5 pouces le rail fait
     ~560 px : 10 bandes à 44 px plus la lacune tiennent en 466 px, le reste
     se répartit proportionnellement. */
  min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: var(--couleur);
  color: #10130e;
  font-family: var(--f-ui);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  transition: filter .12s;
}
.rail-bande[data-sombre="1"] { color: #f2f2ea; }
.rail-bande::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(18,22,15,.62);
  transition: background .12s;
}
.rail-bande.est-actif::after { background: transparent; }
.rail-bande.est-actif { box-shadow: inset 0 0 0 2px var(--encre); }
.rail-bande > span { position: relative; z-index: 1; }

/*
 * Chargement en cours.
 *
 * Toucher une bande déclenche 0,4 à 4,2 Mo de téléchargement — l'Ordovicien
 * seul fait 3,5 Mo — et, au premier toucher, les périmètres juridiques et les
 * proxys par-dessus. Sans retour visible, la bande s'allumait puis il ne se
 * passait rien pendant plusieurs secondes : sur un réseau de campagne, la
 * colonne paraissait simplement ne pas fonctionner.
 *
 * Un balayage diagonal sur la bande, plus un état pressé maintenu. Pas de
 * fileur centré : la bande fait 26 px de large.
 */
.rail-bande[aria-busy="true"]::after {
  background: repeating-linear-gradient(
    -45deg,
    rgba(18,22,15,.62) 0 6px,
    rgba(18,22,15,.24) 6px 12px);
  background-size: 200% 200%;
  animation: rail-charge 900ms linear infinite;
}
@keyframes rail-charge { to { background-position: 34px 34px; } }
@media (prefers-reduced-motion: reduce) {
  .rail-bande[aria-busy="true"]::after { animation-duration: 2.4s; }
}

.rail-bande.est-charge::before {
  content: '';
  position: absolute; z-index: 2;
  inset-inline-start: 2px; top: 3px;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--encre);
  opacity: .8;
}

/*
 * La lacune permo-mésozoïque, rendue comme une VRAIE discordance hachurée.
 * Ni Trias, ni Jurassique, ni Crétacé : donc aucune ammonite, aucun dinosaure.
 * C'est le fait structurant de la géologie armoricaine, l'interface doit le dire.
 */
.rail-lacune {
  position: relative;
  flex: 0 0 26px;
  background:
    repeating-linear-gradient(-52deg,
      var(--encre-3) 0 1.5px, transparent 1.5px 6px),
    var(--fond-2);
  border-block: 1px solid var(--encre-3);
  display: flex; align-items: center; justify-content: center;
  cursor: help;
}
.rail-lacune span {
  writing-mode: vertical-rl;
  font-size: 9px; font-weight: 700; letter-spacing: .12em;
  color: var(--encre-2);
  text-shadow: 0 0 3px var(--fond-0), 0 0 3px var(--fond-0);
}

/* ------------------------------------------------------------------ */
/* Commandes de terrain                                                */
/* ------------------------------------------------------------------ */

/*
 * Zone basse : un seul conteneur, les commandes puis la pastille, empilées.
 * Ancrées séparément, elles finissaient par se recouvrir dès que le résumé
 * passait sur deux lignes — la pastille masquait le bouton « Trouvaille ».
 * Un flux en colonne le rend structurellement impossible.
 *
 * Tiers inférieur de l'écran, le long du bord opposé au rail : c'est la zone
 * atteignable au pouce d'une seule main (§6.6).
 */
.bas {
  position: fixed;
  left: calc(var(--sa-l) + 8px);
  right: calc(var(--sa-r) + var(--rail) + 14px);
  bottom: calc(var(--sa-b) + 62px);
  z-index: 940;
  display: flex; flex-direction: column;
  align-items: flex-start;
  gap: var(--ecart);
  pointer-events: none;                /* la carte reste manipulable autour */
}
:root[data-rail="gauche"] .bas {
  left: calc(var(--sa-l) + var(--rail) + 14px);
  right: calc(var(--sa-r) + 8px);
  align-items: flex-end;
}
.bas > * { pointer-events: auto; }

.commandes {
  display: flex; flex-direction: column;
  gap: var(--ecart);
  align-items: flex-start;
}
:root[data-rail="gauche"] .commandes { align-items: flex-end; }

.cmd {
  min-width: var(--cible); min-height: var(--cible);
  padding: 4px 10px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px;
  background: var(--voile);
  border: 1px solid var(--trait-fort);
  border-radius: var(--rayon);
  color: var(--encre);
  backdrop-filter: blur(6px);
  box-shadow: 0 2px 10px rgba(0,0,0,.45);
}
.cmd-terrain { min-width: var(--cible-terrain); min-height: var(--cible-terrain); }
.cmd-icone { font-size: 17px; line-height: 1; }
.cmd-txt {
  font-size: var(--t-ui-s); font-weight: 700; letter-spacing: var(--ls-ui);
  text-transform: uppercase;
}
.cmd:active { background: var(--fond-3); }
.cmd-accent { border-color: var(--encre-3); }
.cmd[aria-pressed="true"] { background: var(--fond-3); border-color: var(--encre-2); }
.cmd[data-suivi="1"] .cmd-icone { color: var(--statut-autorise); }

/* ------------------------------------------------------------------ */
/* Pastille (§6.2)                                                     */
/* ------------------------------------------------------------------ */

.pastille {
  width: 100%;
  min-height: var(--cible);
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  background: var(--fond-2);
  border: 1px solid var(--trait-fort);
  border-radius: var(--rayon);
  box-shadow: 0 -2px 14px rgba(0,0,0,.5);
  text-align: start;
}
/* Filet de statut sur le bord : la couleur juridique se lit avant le texte, et
   ne peut pas être tronquée par le débordement du résumé. */
.pastille-statut {
  flex: 0 0 auto;
  align-self: stretch;
  width: 4px; border-radius: 2px;
  background: var(--encre-3);
}
.pastille-statut[data-n="interdit"] { background: var(--statut-interdit); }
.pastille-statut[data-n="verifier"] { background: var(--statut-verifier); }
.pastille-statut[data-n="autorise"] { background: var(--statut-autorise); }
.pastille-txt {
  flex: 1; min-width: 0;
  font-size: var(--t-ui);
  line-height: 1.3;
  overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.pastille-txt .notation {
  font-family: var(--f-data); font-weight: 600;
  color: var(--encre);
}
.pastille-plus { flex: 0 0 auto; color: var(--encre-3); font-size: 13px; }

/* ------------------------------------------------------------------ */
/* Barre d'onglets                                                     */
/* ------------------------------------------------------------------ */

.onglets {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 960;
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: var(--fond-1);
  border-top: 1px solid var(--trait-fort);
  padding-bottom: var(--sa-b);
}

.onglet {
  position: relative;
  min-height: var(--cible);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  padding: 6px 2px;
  color: var(--encre-3);
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
}
.onglet-icone { font-size: 16px; line-height: 1; }
.onglet.est-actif { color: var(--encre); }
.onglet.est-actif::before {
  content: ''; position: absolute; top: 0; left: 18%; right: 18%;
  height: 2px; background: var(--encre);
}

.badge {
  position: absolute; top: 4px; right: 22%;
  min-width: 18px; height: 18px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  background: var(--encre); color: var(--fond-0);
  border-radius: 9px;
  font-family: var(--f-data); font-size: 10px; font-weight: 700;
}

/* ------------------------------------------------------------------ */
/* Tiroir (§6.2)                                                       */
/* ------------------------------------------------------------------ */

/*
 * Ancré sur la FENÊTRE (position: fixed) et non sur un conteneur parent.
 * Ancré sur un parent, il se déploie plein écran sur certains navigateurs
 * mobiles — bug rencontré et corrigé. Hauteurs en dvh, jamais vh : la barre
 * d'adresse mobile fait varier la hauteur utile.
 */
.tiroir {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 980;
  display: flex; flex-direction: column;
  background: var(--fond-1);
  border-top: 1px solid var(--trait-fort);
  border-radius: 10px 10px 0 0;
  box-shadow: var(--ombre);
  transform: translateY(100%);
  transition: transform .22s cubic-bezier(.2,.7,.3,1), height .22s cubic-bezier(.2,.7,.3,1);
  height: 58dvh;
}
/* `will-change` uniquement pendant le glissement, jamais en permanence.
   Un panneau promu en couche composite à demeure garde un tampon graphique
   que le navigateur réutilise ; c'est utile le temps d'un geste, c'est une
   source d'artefacts le reste du temps. La classe est posée et retirée par
   tiroir.js autour du toucher. */
.tiroir.est-glisse { will-change: transform; }
.tiroir[data-etat="ferme"] { transform: translateY(100%); pointer-events: none; }
.tiroir[data-etat="mi"] { transform: translateY(0); height: 58dvh; }
.tiroir[data-etat="plein"] { transform: translateY(0); height: 100dvh; border-radius: 0; }

.poignee {
  /* Pleine largeur : la cible est largement atteignable, mais la hauteur doit
     rester conforme — c'est la commande qui change le tiroir de hauteur. */
  width: 100%; min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  padding-top: 6px;
}
.poignee-barre {
  width: 44px; height: 4px; border-radius: 2px;
  background: var(--trait-fort);
}

.tiroir-tete {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 8px;
  padding: 2px 12px 8px;
  padding-inline-start: calc(12px + var(--sa-l));
  border-bottom: 1px solid var(--trait);
}
.tiroir-titre {
  flex: 1; margin: 0;
  font-size: var(--t-titre); font-weight: 600;
  letter-spacing: .01em; line-height: 1.2;
}
.tiroir-fermer {
  flex: 0 0 auto;
  width: var(--cible); height: var(--cible);
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; color: var(--encre-2);
  border: 1px solid var(--trait); border-radius: var(--rayon);
}

/* Retour vers la liste d'où l'on vient. Placé à gauche du titre, là où le
   pouce le cherche, et assez large pour porter le nom de la destination —
   « ← Cibles » dit où l'on va, une flèche seule ne dit rien. */
.tiroir-retour {
  flex: 0 0 auto;
  min-height: var(--cible);
  padding: 0 12px 0 8px;
  display: flex; align-items: center; gap: 5px;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  color: var(--encre-2);
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  white-space: nowrap;
}
/* `display: flex` l'emporte sur l'attribut `hidden` : sans cette ligne, un
   chevron vide et inerte s'affichait dans l'entête de TOUS les panneaux. */
.tiroir-retour[hidden] { display: none; }
.tiroir-retour::before { content: '‹'; font-size: 20px; line-height: 1; }
.tiroir-retour:active { background: var(--fond-3); }
/* Avec un retour, le titre a moins de place : il tronque plutôt que de pousser
   les commandes hors de l'écran. */
.tiroir-retour:not([hidden]) ~ .tiroir-titre {
  font-size: 17px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.tiroir-corps {
  flex: 1; min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Isole les repeints du contenu défilant.
     Sans ça, déplier un <details> dans le tiroir réécrivait une zone de la
     couche composite du panneau sans l'invalider entièrement : sur Android,
     des bandes horizontales de mémoire graphique non initialisée apparaissaient
     par-dessus le texte. `-webkit-overflow-scrolling: touch` a été retiré au
     même endroit — sans effet sur Chrome, obsolète depuis iOS 13, et connu
     pour provoquer exactement ce genre de déchirure quand il s'empile avec un
     ancêtre déjà promu. */
  contain: paint;
  /* Les marges du panneau sont nommées parce qu'un enfant a besoin de les
     annuler : une barre collée en bas doit déborder dans le rembourrage, pas
     flotter au-dessus. Voir `.compteur`. */
  --pad-bas: calc(24px + var(--sa-b));
  --pad-gauche: calc(12px + var(--sa-l));
  --pad-droite: calc(12px + var(--sa-r));
  padding: 12px;
  padding-inline: var(--pad-gauche) var(--pad-droite);
  padding-bottom: var(--pad-bas);
}

/* ------------------------------------------------------------------ */
/* Contenu de fiche                                                    */
/* ------------------------------------------------------------------ */

.bloc { margin: 0 0 18px; }
.bloc:last-child { margin-bottom: 0; }

.bloc-titre {
  margin: 0 0 8px;
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--encre-3);
}

.txt {
  font-family: var(--f-texte);
  font-size: var(--t-texte);
  line-height: 1.5;
  color: var(--encre-2);
  margin: 0 0 10px;
}
.txt strong, .txt b { color: var(--encre); font-weight: 600; }

.donnee { font-family: var(--f-data); font-size: var(--t-data); color: var(--encre); }

/* Grille clé/valeur, en monospace pour les données (§7). */
.paires { display: grid; grid-template-columns: auto 1fr; gap: 5px 12px; align-items: baseline; }
.paires dt {
  font-size: var(--t-ui-s); font-weight: 700; letter-spacing: var(--ls-ui);
  text-transform: uppercase; color: var(--encre-3);
}
.paires dd {
  margin: 0;
  font-family: var(--f-data); font-size: var(--t-data);
  color: var(--encre); word-break: break-word;
}

/* Étiquettes de système, aux couleurs de la charte. */
.puce {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  font-size: var(--t-ui-s); font-weight: 700; letter-spacing: var(--ls-ui);
  text-transform: uppercase;
}
.puce::before {
  content: ''; width: 9px; height: 9px; border-radius: 2px;
  background: var(--couleur, var(--encre-3));
}

/* Statut juridique — les trois couleurs ne servent qu'à ça. */
.statut {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; border-radius: var(--rayon);
  font-size: var(--t-ui); font-weight: 700; letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  border: 1px solid currentColor;
}
.statut[data-n="interdit"] { color: var(--statut-interdit); }
.statut[data-n="verifier"] { color: var(--statut-verifier); }
.statut[data-n="autorise"] { color: var(--statut-autorise); }

/* Provenance — le pointillé est une affirmation, pas une décoration (§5.1). */
.provenance {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-2);
}
.provenance::before {
  content: ''; width: 26px; height: 0;
  border-top: 3px solid currentColor;
}
.provenance[data-p="derive"]::before { border-top-width: 1.5px; }
.provenance[data-p="predit"]::before {
  border-top: 2px dashed currentColor;
  color: var(--encre-2);
}
.provenance[data-p="publie"]::after { content: '§'; font-family: var(--f-data); }

/* Bandeau d'avertissement épistémique en tête de fiche prédite. */
.avert-predit {
  border: 1px dashed var(--encre-3);
  border-radius: var(--rayon);
  padding: 10px 12px;
  margin-bottom: 14px;
  background: rgba(233,231,222,.03);
}
.avert-predit p { margin: 0; font-family: var(--f-texte); font-size: 15px; line-height: 1.45; color: var(--encre-2); }
.avert-predit b { color: var(--encre); }

/* Sources : toujours visibles, jamais en pied de page discret (§9). */
.source {
  font-family: var(--f-data); font-size: 11.5px; line-height: 1.45;
  color: var(--encre-3);
  border-inline-start: 2px solid var(--trait-fort);
  padding-inline-start: 8px;
  margin-top: 6px;
}

/* Liste d'items dépliables — raisonnement, motifs, décomposition du score. */
.pli { border: 1px solid var(--trait); border-radius: var(--rayon); margin-bottom: 8px; }
.pli > summary {
  min-height: var(--cible);
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  font-size: var(--t-ui); font-weight: 600;
  list-style: none; cursor: pointer;
}
.pli > summary::-webkit-details-marker { display: none; }
.pli > summary::after { content: '▾'; margin-inline-start: auto; color: var(--encre-3); }
.pli[open] > summary::after { content: '▴'; }

/* Bloc de taxon : glyphe, nom, chance. Tout ce qui concerne un fossile est
   réuni là — argument, source, planche, lithographie. */
.taxon > summary { gap: 10px; }
.taxon-chance {
  font-family: var(--f-data); font-size: 11.5px;
  letter-spacing: 0; text-transform: none; font-weight: 500;
  color: var(--encre-3);
}
.taxon-chance b { font-weight: 700; font-size: 13px; }
/* Avérée : la seule valeur qui n'est pas une estimation. Elle se distingue de
   « forte » — un vert plus franc et un fond —, parce que la différence entre
   « on l'y a trouvé » et « on devrait en trouver » est la distinction que toute
   l'application existe pour tenir (§5.1). */
.taxon-chance[data-n="averee"] {
  color: var(--fond-0); background: var(--statut-autorise);
  padding: 2px 7px; border-radius: var(--rayon);
}
.taxon-chance[data-n="averee"] b { color: var(--fond-0); }
.taxon-chance[data-n="forte"] { color: var(--statut-autorise); }
.taxon-chance[data-n="moyenne"] { color: var(--encre-2); }
.pli-corps { padding: 0 12px 12px; }

.ligne-arg {
  padding: 9px 0;
  border-top: 1px solid var(--trait);
  display: grid; grid-template-columns: 1fr auto; gap: 4px 10px;
  align-items: baseline;
}
.ligne-arg:first-child { border-top: 0; }
.ligne-arg-nom {
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-3);
}
.ligne-arg-val { font-family: var(--f-data); font-size: var(--t-data); color: var(--encre); }
.ligne-arg-txt {
  grid-column: 1 / -1;
  font-family: var(--f-texte); font-size: 15px; line-height: 1.45;
  color: var(--encre-2);
}
.ligne-arg[data-exclu="1"] .ligne-arg-val { color: var(--statut-interdit); }

/* Barre de contribution — rend la pondération lisible d'un coup d'œil. */
.jauge {
  grid-column: 1 / -1;
  height: 3px; background: var(--fond-3); border-radius: 2px; overflow: hidden;
}
.jauge > i { display: block; height: 100%; background: var(--encre-2); }

/* ------------------------------------------------------------------ */
/* Listes (cibles, carnet)                                             */
/* ------------------------------------------------------------------ */

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

.carte-cible {
  width: 100%;
  display: grid; grid-template-columns: auto 1fr auto; gap: 4px 10px;
  align-items: center;
  min-height: var(--cible-terrain);
  padding: 10px 12px;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  margin-bottom: 8px;
  text-align: start;
  background: var(--fond-2);
}
.carte-cible:active { background: var(--fond-3); }
.carte-cible[data-p="predit"] { border-style: dashed; }

.cible-rang {
  font-family: var(--f-data); font-size: 12px; font-weight: 700;
  color: var(--encre-3); min-width: 22px;
}
.cible-nom {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 15px; font-weight: 600; line-height: 1.25;
}
.cible-nom .picto { flex: 0 0 auto; margin-top: 1px; color: var(--encre-2); }
.cible-nom > span {
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.cible-meta {
  grid-column: 2 / -1;
  font-family: var(--f-data); font-size: 11.5px; color: var(--encre-3);
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
}
/* Accès et matériel : ce qui décide d'y aller aujourd'hui plutôt qu'un autre
   jour. Séparé de la ligne d'identité pour rester lisible d'un coup d'œil. */
.cible-acces {
  grid-column: 2 / -1;
  margin-top: 3px;
  font-family: var(--f-data); font-size: 11.5px; color: var(--encre-2);
  display: flex; flex-wrap: wrap; gap: 3px 12px;
}
.cible-acces b { color: var(--encre); font-weight: 700; }
.cible-score {
  display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  font-family: var(--f-data); font-size: 15px; font-weight: 700;
  color: var(--encre);
}
/* Le nombre seul ne se lit pas : ni son échelle, ni son sens. La barre donne
   la part atteinte du plafond propre à la zone. */
.score-mini {
  display: block; width: 34px; height: 3px;
  background: var(--fond-3); border-radius: 2px; overflow: hidden;
}
.score-mini > i { display: block; height: 100%; background: var(--encre-2); }

.score-tete { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.score-echelle {
  font-family: var(--f-data); font-size: 13px; color: var(--encre-3);
}
.score-barre {
  position: relative;
  height: 6px; border-radius: 3px;
  background: var(--fond-3); overflow: hidden;
}
.score-barre > i { display: block; height: 100%; background: var(--encre); }
/* Repère du plafond : jusqu'où cette zone PEUT aller. */
.score-barre > u {
  position: absolute; top: 0; bottom: 0;
  width: 2px; background: var(--statut-verifier);
}
.cible-pastille { width: 8px; height: 8px; border-radius: 2px; background: var(--couleur); }

/* ------------------------------------------------------------------ */
/* Panneau de critères (§6.3)                                          */
/* ------------------------------------------------------------------ */

.axe { border-bottom: 1px solid var(--trait); padding: 12px 0; }
.axe:last-child { border-bottom: 0; }

.axe-tete { display: flex; align-items: center; gap: 8px; min-height: var(--cible); }

.axe-nom { flex: 1; font-size: var(--t-texte); font-weight: 600; }
.axe-aide {
  font-family: var(--f-texte); font-size: 14px; line-height: 1.4;
  color: var(--encre-3); margin: 2px 0 8px;
}

/* Règle unique, énoncée une fois en tête du panneau. Elle remplace le
   basculeur filtre/poids, ses trois gestes et ses deux colonnes de libellés. */
.criteres-regle {
  margin: 0 0 4px;
  padding: 10px 12px;
  border: 1px solid var(--trait); border-left: 3px solid var(--encre-3);
  border-radius: var(--rayon);
  background: var(--fond-2);
  font-size: 13.5px; line-height: 1.45; color: var(--encre-2);
}

/* Marque « restreint » : cet axe écarte réellement des cibles en ce moment. */
.axe-etat {
  font-family: var(--f-data); font-size: 10.5px; font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--statut-verifier);
  border: 1px solid var(--statut-verifier); border-radius: 3px;
  padding: 2px 5px;
}
.axe-effacer {
  min-height: 34px; padding: 0 10px;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  font-size: var(--t-ui-s); color: var(--encre-3);
}
.axe-effacer:active { background: var(--fond-3); }

.axe-note {
  margin: 8px 0 0;
  font-size: 12.5px; line-height: 1.4; color: var(--encre-3);
}
.axe-curseur { display: flex; align-items: center; gap: 12px; }
.axe-curseur input[type="range"] { flex: 1; }
.axe-curseur .donnee { min-width: 6ch; text-align: end; }
.axe-interrupteur { display: flex; align-items: center; gap: 12px; }

.interrupteur {
  flex: 0 0 auto;
  width: 52px; height: 30px; border-radius: 15px;
  border: 1px solid var(--trait-fort); background: var(--fond-2);
  position: relative; transition: background .15s;
}
.interrupteur::after {
  content: ''; position: absolute; top: 3px; inset-inline-start: 3px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--encre-3); transition: transform .15s, background .15s;
}
.interrupteur[aria-checked="true"] { background: var(--fond-3); border-color: var(--encre-3); }
.interrupteur[aria-checked="true"]::after { transform: translateX(22px); background: var(--encre); }

.jetons { display: flex; flex-wrap: wrap; gap: var(--ecart); margin-top: 8px; }
.jeton {
  min-height: 40px; padding: 6px 12px;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  font-size: var(--t-ui); font-weight: 600;
  color: var(--encre-2);
  display: inline-flex; align-items: center; gap: 7px;
}
.jeton[aria-pressed="true"] { background: var(--fond-3); color: var(--encre); border-color: var(--encre-3); }
.jeton::before {
  content: ''; width: 9px; height: 9px; border-radius: 2px;
  background: var(--couleur, transparent);
  border: 1px solid var(--trait-fort);
}
.jeton[data-sans-puce]::before { display: none; }
/* Curseur de seuil : le nombre décide, la glose dit ce qu'on est en train de
   demander. Un curseur qui n'affiche qu'un pour-cent ne dit rien. */
.curseur-chance { display: flex; align-items: center; gap: 12px; }
.curseur-chance input[type="range"] { flex: 1; }
.curseur-sortie {
  flex: 0 0 auto; min-width: 9ch; text-align: end;
  display: flex; flex-direction: column; gap: 1px;
}
.curseur-sortie b {
  font-family: var(--f-data); font-size: var(--t-data); font-weight: 700;
  color: var(--encre);
}
.curseur-sortie small {
  font-family: var(--f-texte); font-size: 11.5px; color: var(--encre-3);
}
/* Jeton de taxon : le glyphe porte l'identification, le mot confirme. */
.jeton-taxon { gap: 8px; padding-inline-start: 9px; }
.jeton-taxon .picto { color: var(--encre-3); }
.jeton-taxon[aria-pressed="true"] .picto { color: var(--encre); }

input[type="range"] {
  width: 100%; height: var(--cible);
  accent-color: var(--encre);
  background: transparent;
}

.champ {
  width: 100%; min-height: var(--cible);
  padding: 10px 12px;
  background: var(--fond-2);
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  color: var(--encre);
  font-family: var(--f-texte); font-size: var(--t-texte);
}
textarea.champ { min-height: 96px; resize: vertical; line-height: 1.45; }

.bouton {
  min-height: var(--cible); padding: 0 16px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  background: var(--fond-2);
  font-size: var(--t-ui); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
}
.bouton-fort { background: var(--encre); color: var(--fond-0); border-color: var(--encre); }
.bouton-terrain { min-height: var(--cible-terrain); }
.bouton-danger { color: var(--statut-interdit); border-color: var(--statut-interdit); }
.bouton:disabled { opacity: .4; }
.boutons { display: flex; flex-wrap: wrap; gap: var(--ecart); }
/* Un lien peut porter la même commande qu'un bouton — « Y aller » ouvre Maps.
   Il faut alors lui retirer les attributs de lien, pas seulement l'habiller. */
a.bouton { text-decoration: none; color: var(--encre-2); }
a.bouton-fort { color: var(--fond-0); }
.bouton-large { display: flex; width: 100%; margin-top: 12px; }

/*
 * Barre de validation des critères, collée au bas du panneau.
 *
 * `bottom: 0` ne suffisait pas, et le résultat se voyait : la barre s'arrêtait
 * vingt-quatre pixels au-dessus du bord, avec une lanière de contenu qui
 * défilait dessous. Un élément `sticky` se cale sur le bord du bloc CONTENANT,
 * c'est-à-dire à l'intérieur du rembourrage du panneau — pas sur le bord
 * visible. La marge négative de l'ancienne version tentait de compenser ; elle
 * ne déplace pas un élément collé.
 *
 * Le décalage négatif, lui, le déplace : la barre déborde dans le rembourrage,
 * que `overflow` n'écrête pas. Les valeurs viennent de `.tiroir-corps` par
 * variable, des deux côtés, pour qu'elles ne puissent pas diverger — et le
 * même traitement horizontal donne enfin une barre pleine largeur sur un
 * téléphone à encoche en paysage.
 */
.compteur {
  position: sticky;
  bottom: calc(-1 * var(--pad-bas, 24px));
  margin-block: 12px calc(-1 * var(--pad-bas, 24px));
  margin-inline: calc(-1 * var(--pad-gauche, 12px)) calc(-1 * var(--pad-droite, 12px));
  padding: 12px var(--pad-droite, 12px) calc(12px + var(--sa-b)) var(--pad-gauche, 12px);
  background: var(--fond-1);
  border-top: 1px solid var(--trait-fort);
  display: flex; align-items: center; gap: 12px;
}
.compteur-nb { font-family: var(--f-data); font-size: 20px; font-weight: 700; }
.compteur-txt { flex: 1; font-size: var(--t-ui-s); color: var(--encre-3); line-height: 1.3; }

/* ------------------------------------------------------------------ */
/* Planches de fossiles (§7)                                           */
/* ------------------------------------------------------------------ */

.planche {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: 10px; margin-bottom: 10px;
  color: var(--encre);                 /* les SVG héritent via currentColor */
  background: var(--fond-2);
}
.planche svg { width: 100%; height: auto; display: block; }

/* Planche historique : lithographie du domaine public ou photographie sous
   licence libre. Fond clair assumé — ces images ont été imprimées sur papier,
   les inverser les rendrait illisibles. La légende d'attribution n'est pas
   escamotable : c'est la contrepartie de l'usage. */
.planche-histo { background: #efece2; padding: 8px; }
.planche-histo img {
  width: 100%; height: auto; display: block;
  border-radius: 2px;
  background: #efece2;
}
.planche-histo figcaption {
  margin-top: 8px;
  border-inline-start-color: #9a9384;
  color: #4c4941;
}
.planche-histo figcaption a { color: #2f2d28; }
.planche-nom {
  font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-3); margin-bottom: 6px;
}

/* ---- Carrousel d'images d'un taxon ---------------------------------
   Empilées, quatre planches faisaient un écran et demi par groupe fossile.
   La bande défile au pouce, avec accrochage : on voit la première en entier,
   on sait combien il y en a, et on va chercher les autres si on veut. */

.carrousel { margin-top: 10px; }
.carrousel-piste {
  display: flex; gap: 8px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* Le défilement horizontal d'une bande ne doit pas devenir un retour arrière
     ni entraîner le tiroir avec lui. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.carrousel-piste::-webkit-scrollbar { display: none; }
.carrousel-vue {
  flex: 0 0 100%; margin: 0;
  scroll-snap-align: start;
  border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: 10px;
  background: var(--fond-2);
  color: var(--encre);
}
.carrousel-vue[data-type="photo"] { background: #efece2; padding: 8px; }
.carrousel-image svg { width: 100%; height: auto; display: block; }
.carrousel-image img { width: 100%; height: auto; display: block; border-radius: 2px; }
.carrousel-legende {
  margin-top: 8px;
  font-family: var(--f-data); font-size: 11.5px; line-height: 1.4;
  color: var(--encre-3);
  border-inline-start: 2px solid var(--trait-fort);
  padding-inline-start: 8px;
}
.carrousel-vue[data-type="photo"] .carrousel-legende {
  color: #4c4941; border-inline-start-color: #9a9384;
}
.carrousel-vue[data-type="photo"] .carrousel-legende a { color: #2f2d28; }

.carrousel-barre {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 6px;
}
.carrousel-compte {
  font-family: var(--f-data); font-size: 12px; color: var(--encre-3);
  min-width: 5ch; text-align: center;
}
.carrousel-fleche {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  font-size: 20px; line-height: 1; color: var(--encre-2);
}
.carrousel-fleche:disabled { opacity: .3; }

/* ------------------------------------------------------------------ */
/* Sur place — le protocole de terrain                                 */
/* ------------------------------------------------------------------ */

/* Le verdict : la seule ligne qui répond à « est-ce qu'il y en a beaucoup ici ». */
.verdict {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; margin-bottom: 10px;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  background: var(--fond-2);
}
.verdict[data-n="forte"] { border-color: var(--statut-autorise); }
.verdict[data-n="averee"] {
  border-color: var(--statut-autorise); border-width: 2px;
  background: linear-gradient(var(--fond-2), var(--fond-2)) padding-box,
              rgba(127,191,106,.10);
}
.verdict .picto { flex: 0 0 auto; color: var(--encre); }
.verdict-corps { flex: 1; min-width: 0; }
.verdict-phrase {
  margin: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
  font-family: var(--f-titre);
  font-weight: var(--titre-graisse);
  text-transform: var(--titre-casse);
  letter-spacing: var(--titre-espace);
  font-size: 21px; line-height: 1.15;
  color: var(--encre);
}
.verdict-vise {
  font-family: var(--f-ui); font-size: 10.5px; font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--fond-0); background: var(--encre-2);
  padding: 2px 6px; border-radius: var(--rayon);
}
.verdict-detail {
  margin: 3px 0 0;
  font-family: var(--f-texte); font-size: 13.5px; color: var(--encre-3);
}
/* Le nombre en chiffres tabulaires, la phrase autour en texte courant : la
   monospace sur de la prose se lit comme un listing. */
.verdict-detail b {
  font-family: var(--f-data); font-size: 15px; color: var(--encre);
}

/* Rappel épistémique du bloc : générique, jamais observé ici (§5.1). */
.terrain-avert {
  margin: 0 0 12px;
  font-family: var(--f-texte); font-size: 12.5px; line-height: 1.4;
  color: var(--encre-3);
}

/* Le danger passe avant le geste, jamais après. */
.danger {
  padding: 9px 11px; margin-bottom: 12px;
  border: 1px solid var(--statut-interdit); border-radius: var(--rayon);
  background: rgba(224,83,61,.07);
  font-family: var(--f-texte); font-size: 14px; line-height: 1.45;
  color: var(--encre-2);
}
.danger b { color: var(--statut-interdit); font-weight: 700; }

.etape { margin-bottom: 16px; }
.etape-titre {
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 8px;
  font-size: var(--t-ui); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre);
}
.etape-n {
  flex: 0 0 auto;
  width: 21px; height: 21px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--trait-fort); border-radius: 50%;
  font-family: var(--f-data); font-size: 11px; color: var(--encre-3);
}
.etape-tete { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.etape-tete .picto { color: var(--encre-2); }
.etape-cle {
  font-family: var(--f-ui); font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-2);
}
.etape .txt { font-size: 15px; }
.txt-second { color: var(--encre-3); }

.litho { margin-bottom: 10px; }
.litho .txt { margin: 3px 0 0; }

.reconn {
  padding: 9px 0; border-top: 1px solid var(--trait);
}
.reconn:first-child { border-top: 0; padding-top: 0; }
.reconn-tete { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.reconn-tete .picto { color: var(--encre-2); }
.reconn-tete .taxon-chance { margin-inline-start: auto; }
.reconn .txt { margin: 0; }

.gestes { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.gestes li {
  position: relative; padding-inline-start: 18px;
  font-family: var(--f-texte); font-size: 15px; line-height: 1.4;
  color: var(--encre-2);
}
.gestes li::before {
  content: ''; position: absolute; inset-inline-start: 0; top: .62em;
  width: 7px; height: 7px; border-radius: 1px;
  background: var(--trait-fort);
}

/* La consigne juridique du protocole : elle change le geste, donc elle porte
   la couleur du statut. */
.consigne {
  padding: 9px 11px; margin-bottom: 10px;
  border-inline-start: 3px solid var(--statut-verifier);
  background: var(--fond-2);
  font-family: var(--f-texte); font-size: 14.5px; line-height: 1.45;
  color: var(--encre-2);
}
.consigne[data-n="interdit"] { border-inline-start-color: var(--statut-interdit); }
.consigne[data-n="autorise"] { border-inline-start-color: var(--statut-autorise); }

/* ---- Statut juridique condensé ------------------------------------ */

.statut-verdict {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
}
.statut-verdict[data-n="interdit"] .picto { color: var(--statut-interdit); }
.statut-verdict[data-n="verifier"] .picto { color: var(--statut-verifier); }
.statut-verdict[data-n="autorise"] .picto { color: var(--statut-autorise); }

.pli-juridique > summary { gap: 10px; }
.pli-juridique > summary .picto { flex: 0 0 auto; color: var(--encre-3); }
.pli-libelle {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600;
}
.pli-point {
  flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%;
  background: var(--encre-3);
}
.pli-point[data-n="interdit"] { background: var(--statut-interdit); }
.pli-point[data-n="verifier"] { background: var(--statut-verifier); }
.pli-point[data-n="autorise"] { background: var(--statut-autorise); }
/* Un inventaire ne contraint rien : le point est creux, pas coloré. */
.pli-point[data-n="inventaire"] {
  background: transparent; border: 1px solid var(--trait-fort);
}

/* ---- Avertissement de prédiction, replié -------------------------- */

.avert-pli { padding: 0; }
.avert-pli > summary {
  min-height: var(--cible);
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  list-style: none; cursor: pointer;
}
.avert-pli > summary::-webkit-details-marker { display: none; }
.avert-pli > summary::after { content: '▾'; margin-inline-start: auto; color: var(--encre-3); }
.avert-pli[open] > summary::after { content: '▴'; }
.avert-pli > summary b {
  font-family: var(--f-ui); font-size: var(--t-ui); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre);
}
.avert-conf { font-family: var(--f-data); font-size: 11.5px; color: var(--encre-3); }
.avert-pli > p { padding: 0 12px 10px; }

/* ------------------------------------------------------------------ */
/* Écran de démarrage                                                  */
/* ------------------------------------------------------------------ */

.demarrage {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  background: var(--fond-0);
  transition: opacity .3s;
}
.demarrage.est-parti { opacity: 0; pointer-events: none; }
.demarrage-marque { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.demarrage-nom {
  font-family: var(--f-ui); font-size: 30px; font-weight: 700;
  letter-spacing: .3em; text-indent: .3em;
}
.demarrage-sous {
  font-family: var(--f-data); font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--encre-3);
}
.demarrage-etat {
  font-family: var(--f-data); font-size: 12px; color: var(--encre-3);
  min-height: 1.4em;
}

/* ---- Écran d'attente : on dégage un trilobite ----------------------
   Le chargement complet fait 3,4 Mo et prend le temps qu'il prend sur un
   réseau de campagne. Plutôt que de faire patienter devant une barre, on
   montre quelque chose qui a un rapport avec ce qu'on est venu faire : le
   fossile se dessine au rythme exact des emprises qui arrivent, comme il
   sortirait de la gangue sous le burin. La progression n'est pas illustrée,
   elle est le dessin lui-même. */

.demarrage-scene {
  display: flex; align-items: stretch; gap: 16px;
}

.demarrage-fossile {
  position: relative;
  width: 132px; height: 210px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  /* La gangue : une roche schisteuse sommaire, qui s'éclaircit à mesure que
     le dégagement avance. */
  background:
    linear-gradient(118deg, rgba(255,255,255,.05) 0 1px, transparent 1px 7px),
    linear-gradient(160deg, var(--fond-3), var(--fond-2));
  overflow: hidden;
}
.demarrage-fossile::after {
  /* Poussière de taille : un voile qui se retire du bas vers le haut. */
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--fond-2), transparent);
  transform: scaleY(calc(1 - var(--p, 0)));
  transform-origin: bottom;
  transition: transform .5s ease;
}
.demarrage-fossile svg {
  position: relative; z-index: 1;
  width: 104px; height: 104px;
  fill: none;
  stroke: var(--encre);
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
.demarrage-fossile path {
  /* `--l` (longueur du tracé) est posé par main.js, qui la mesure. On ne peut
     pas la deviner en CSS, et une valeur approchée ferait sauter le trait. */
  stroke-dasharray: var(--l, 200);
  stroke-dashoffset: calc(var(--l, 200) * (1 - var(--p, 0)));
  transition: stroke-dashoffset .55s cubic-bezier(.3,.8,.4,1);
}
/* Une fois dégagé, le fossile respire doucement — signe que l'application est
   vivante pendant les dernières secondes, les plus lourdes. */
.demarrage-fossile[data-fini="1"] svg {
  animation: fossile-souffle 2.6s ease-in-out infinite;
}
@keyframes fossile-souffle {
  0%, 100% { opacity: 1; }
  50% { opacity: .62; }
}
@media (prefers-reduced-motion: reduce) {
  .demarrage-fossile path { transition: none; }
  .demarrage-fossile[data-fini="1"] svg { animation: none; }
}

/* Colonne stratigraphique de démarrage : les bandes s'allument dans l'ordre où
   les systèmes arrivent — par intérêt paléontologique, donc l'Ordovicien en
   premier. On regarde la colonne se construire, ce qui est à la fois le sujet
   de l'outil et une jauge honnête. */
.demarrage-colonne {
  display: flex; flex-direction: column;
  width: 38px; height: 210px;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  overflow: hidden;
}
.demarrage-colonne i {
  display: block; flex: 1 1 0;
  background: var(--couleur, #555);
  opacity: .16;
  transition: opacity .45s ease;
}
.demarrage-colonne i[data-charge="1"] { opacity: 1; }
.demarrage-colonne i[data-lacune="1"] {
  flex: 0 0 8px; opacity: .5;
  background: repeating-linear-gradient(-45deg,
    var(--trait-fort) 0 2px, transparent 2px 5px);
}

.demarrage-mot {
  margin: 0; max-width: 27ch;
  text-align: center;
  font-size: 12.5px; line-height: 1.45;
  color: var(--encre-3);
  min-height: 3.6em;
  transition: opacity .3s;
}
.demarrage-mot.est-change { opacity: 0; }

/* ---- Sondage de départ ---------------------------------------------
   Deux questions posées pendant que les emprises arrivent. Elles n'ajoutent
   aucune seconde d'attente : elles en occupent qui existaient déjà. Le
   trilobite continue de se dégager à côté, en petit — c'est lui qui dit où en
   est le téléchargement pendant qu'on répond, et l'écran ne devient donc
   jamais un formulaire posé sur du vide. */

.demarrage-fossile, .demarrage-fossile svg, .demarrage-colonne {
  transition: width .35s ease, height .35s ease;
}
.demarrage[data-etape="sondage"] {
  justify-content: flex-start;
  gap: 10px;
  padding: calc(var(--sa-t) + 14px) 16px calc(var(--sa-b) + 12px);
  overflow-y: auto;
}
.demarrage[data-etape="sondage"] .demarrage-mot { display: none; }
.demarrage[data-etape="sondage"] .demarrage-nom { font-size: 19px; letter-spacing: .26em; text-indent: .26em; }
.demarrage[data-etape="sondage"] .demarrage-sous { display: none; }
.demarrage[data-etape="sondage"] .demarrage-scene { gap: 10px; }
.demarrage[data-etape="sondage"] .demarrage-fossile { width: 62px; height: 76px; border-radius: 6px; }
.demarrage[data-etape="sondage"] .demarrage-fossile svg { width: 48px; height: 48px; }
.demarrage[data-etape="sondage"] .demarrage-colonne { width: 15px; height: 76px; }

.depart {
  width: 100%; max-width: 430px;
  display: flex; flex-direction: column; gap: 17px;
}
.depart-q { display: flex; flex-direction: column; gap: 5px; }
.depart-titre {
  margin: 0;
  font-family: var(--f-titre);
  font-weight: var(--titre-graisse);
  text-transform: var(--titre-casse);
  letter-spacing: var(--titre-espace);
  font-size: 24px; line-height: 1.12;
}
.depart-titre:focus { outline: none; }
.depart-aide, .depart-note {
  margin: 0;
  font-family: var(--f-texte); font-size: 13.5px; line-height: 1.4;
  color: var(--encre-3);
}
.depart-grille { display: flex; flex-wrap: wrap; gap: var(--ecart); margin-top: 3px; }
.depart-taxon { min-height: 44px; }
/* Estompé, jamais pointillé : le pointillé appartient à `predit` (§5.1). */
.depart-taxon[data-absent] { opacity: .45; }
.depart-note { margin-top: 5px; }

.depart-plus {
  align-self: flex-start;
  min-height: 42px; padding: 0 2px;
  font-family: var(--f-ui); font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-3);
  text-decoration: underline; text-underline-offset: 3px;
}

.depart-intentions { display: flex; gap: var(--ecart); margin-top: 3px; }
.depart-intention {
  flex: 1 1 0;
  min-height: 60px; padding: 9px 11px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  background: var(--fond-1);
  text-align: start;
}
.depart-intention b {
  font-family: var(--f-ui); font-size: var(--t-ui); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-2);
}
.depart-intention small {
  font-family: var(--f-texte); font-size: 12.5px; line-height: 1.2;
  color: var(--encre-3);
}
.depart-intention[aria-pressed="true"] {
  background: var(--fond-3); border-color: var(--encre-3);
}
.depart-intention[aria-pressed="true"] b { color: var(--encre); }

/* Réservée à la conséquence juridique du choix : elle change de texte, jamais
   de place, pour qu'on la relise au même endroit. */
.depart-effet {
  margin: 0; min-height: 3.1em;
  font-family: var(--f-texte); font-size: 13.5px; line-height: 1.4;
  color: var(--encre-2);
}

.depart-pied { display: flex; align-items: center; gap: 12px; }
.depart-ok { flex: 1 1 auto; }
.depart-passer {
  min-height: var(--cible); padding: 0 8px;
  font-family: var(--f-ui); font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-3);
  text-decoration: underline; text-underline-offset: 3px;
}

/* ------------------------------------------------------------------ */
/* Paysage (§6.6) — pas un simple écrasement du portrait               */
/* ------------------------------------------------------------------ */

@media (orientation: landscape) and (max-height: 560px) {
  /* La colonne stratigraphique passe en bandeau horizontal, en haut. */
  .rail {
    top: var(--sa-t); bottom: auto;
    left: var(--sa-l); right: var(--sa-r);
    width: auto; height: 42px;
    flex-direction: row-reverse;
  }
  .rail-tete { align-items: center; }
  .rail-btn { width: 44px; height: 100%; }
  .rail-bandes { flex-direction: row; }
  /* En paysage le rail devient horizontal : c'est la largeur qui porte la
     cible, la hauteur est celle du bandeau. */
  .rail-bande { writing-mode: horizontal-tb; min-height: 0; min-width: 44px; font-size: 9.5px; }
  .rail-lacune { flex: 0 0 22px; }
  .rail-lacune span { writing-mode: horizontal-tb; font-size: 8px; }

  /* Le tiroir devient un panneau latéral, pas une feuille écrasée. */
  .tiroir {
    top: 0; bottom: 0; left: auto;
    right: 0;
    width: min(62vw, 460px);
    height: 100dvh !important;
    border-radius: 10px 0 0 10px;
    border-top: 0; border-left: 1px solid var(--trait-fort);
    transform: translateX(100%);
  }
  .tiroir[data-etat="ferme"] { transform: translateX(100%); }
  .tiroir[data-etat="mi"], .tiroir[data-etat="plein"] { transform: translateX(0); }
  .tiroir[data-etat="plein"] { width: min(86vw, 720px); }
  .poignee { display: none; }

  .onglets {
    grid-template-columns: repeat(4, auto);
    justify-content: start;
    left: var(--sa-l); right: auto;
    padding-inline: 4px;
  }
  .onglet { padding-inline: 14px; }
  /* En paysage la hauteur manque : les commandes passent en rangée et la
     pastille se limite à la moitié gauche, hors du panneau latéral. */
  .bas {
    top: calc(var(--sa-t) + 46px);
    bottom: calc(var(--sa-b) + 58px);
    right: auto; width: min(58vw, 430px);
    justify-content: flex-end;
  }
  .commandes { flex-direction: row; }
}

/* ------------------------------------------------------------------ */
/* Préférences système                                                 */
/* ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

@media print { .rail, .commandes, .onglets, .pastille, .poignee { display: none; } }


/* ------------------------------------------------------------------ */
/* Accès et conditions                                                 */
/* ------------------------------------------------------------------ */

/* Sept lignes de libellés alignés se lisaient comme un formulaire. Un signe
   devant chacune la rend repérable : sur le terrain on cherche « le marteau »,
   pas la quatrième ligne d'un tableau. */
.acces { display: flex; flex-direction: column; }
.acces-ligne {
  display: flex; align-items: center; gap: 10px;
  min-height: 34px;
  padding: 4px 0;
  border-bottom: 1px solid var(--trait);
}
.acces-ligne:last-child { border-bottom: 0; }
.acces-ligne .picto { color: var(--encre-3); }
.acces-label {
  flex: 0 0 auto; min-width: 8.5ch;
  font-family: var(--f-data); font-size: 11px;
  letter-spacing: var(--ls-ui); text-transform: uppercase;
  color: var(--encre-3);
}
.acces-val {
  flex: 1;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--f-data); font-size: 14px; color: var(--encre);
}
/* La méthode d'estimation tient dans une infobulle plutôt qu'en deux lignes
   de prose répétées sur chaque fiche. §2 demande de ne pas faire passer une
   estimation pour un calcul — pas de la redire indéfiniment. */
.acces-estime {
  font-family: var(--f-ui); font-style: normal;
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--encre-3);
  border: 1px solid var(--trait); border-radius: 3px;
  padding: 1px 5px;
  cursor: help;
}
/* Difficulté : cinq points valent mieux qu'une fraction. */
.acces-points { display: inline-flex; gap: 4px; }
.acces-points i {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1px solid var(--encre-3);
}
.acces-points i[data-on] { background: var(--encre); border-color: var(--encre); }


/* ------------------------------------------------------------------ */
/* Application des rôles typographiques                                */
/* ------------------------------------------------------------------ */

/* Les titres prennent la famille de titre du parti pris courant, avec sa
   graisse, sa casse et son interlettrage propres — trois réglages qui font
   qu'un même mot ne se lit pas pareil selon la famille. */
#tiroir-titre,
.bloc-titre,
.demarrage-nom,
.compteur-nb,
.cible-score b,
.score-tete .compteur-nb {
  font-family: var(--f-titre);
  font-weight: var(--titre-graisse);
  text-transform: var(--titre-casse);
  letter-spacing: var(--titre-espace);
}
/* Le titre du tiroir porte le nom d'une formation : il mérite le corps. */
#tiroir-titre { font-size: 22px; line-height: 1.15; }
.bloc-titre { font-size: 13px; }
:root[data-typo="lithographie"] .bloc-titre,
:root[data-typo="terrain"] .bloc-titre {
  /* En serif ou en grotesque, les petites capitales espacées du parti
     « état-major » deviennent illisibles : on garde le libellé en UI. */
  font-family: var(--f-ui);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--ls-ui);
  font-size: 11.5px;
}
:root[data-typo="lithographie"] #tiroir-titre { font-size: 26px; }

/* Lecture longue partout où il y a de la prose. */
.txt, .prose, .notes-corps p, .axe-aide, .acces-estime + *, .avert-predit p,
.ligne-arg-txt, .source {
  font-family: var(--f-texte);
}
.source { font-size: 12.5px; }

/* ------------------------------------------------------------------ */
/* Récapitulatif de fiche                                              */
/* ------------------------------------------------------------------ */

/* Une fiche complète fait sept sections et trois écrans. C'est le bon volume
   pour préparer une sortie au chaud et le mauvais pour trancher : la question
   sur le terrain est « j'y vais ou pas », et elle se répond avec cinq nombres.
   Tout le reste est replié, chaque sommaire portant de quoi décider s'il faut
   l'ouvrir. */

.recap {
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  background: var(--fond-2);
  padding: 12px; margin-bottom: 14px;
}
.recap-verdict {
  display: flex; align-items: center; gap: 11px;
  padding-bottom: 11px; margin-bottom: 10px;
  border-bottom: 1px solid var(--trait);
}
.recap-verdict .picto { flex: 0 0 auto; color: var(--encre); }
.recap-verdict[data-n="averee"] .picto { color: var(--statut-autorise); }
.recap-quoi {
  margin: 0;
  font-family: var(--f-titre);
  font-weight: var(--titre-graisse);
  text-transform: var(--titre-casse);
  letter-spacing: var(--titre-espace);
  font-size: 21px; line-height: 1.1; color: var(--encre);
}
.recap-chance {
  margin: 2px 0 0;
  font-family: var(--f-texte); font-size: 13px; color: var(--encre-3);
}
.recap-chance b { font-family: var(--f-data); font-size: 14px; color: var(--encre); }
.recap-verdict[data-n="averee"] .recap-chance b { color: var(--statut-autorise); }

.recap-grille { display: grid; gap: 7px; }
.recap-ligne { display: flex; align-items: baseline; gap: 9px; }
.recap-ligne .picto { flex: 0 0 17px; color: var(--encre-3); align-self: center; }
.recap-label {
  flex: 0 0 4.6em;
  font-family: var(--f-ui); font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--encre-3);
}
.recap-val {
  flex: 1; min-width: 0;
  font-family: var(--f-texte); font-size: 14px; line-height: 1.35; color: var(--encre-2);
}
.recap-val strong { color: var(--encre); font-weight: 600; }
.recap-val .statut { padding: 2px 7px; font-size: var(--t-ui-s); }
.recap-form { display: inline-flex; align-items: center; gap: 7px; margin-inline-start: 8px; }
.recap .bouton-large { margin-top: 12px; }

/* ---- Sections repliées ------------------------------------------- */

.bloc-pli {
  border: 1px solid var(--trait); border-radius: var(--rayon);
  margin-bottom: 8px;
}
.bloc-pli > summary {
  min-height: var(--cible);
  display: flex; align-items: baseline; gap: 10px;
  padding: 10px 12px;
  list-style: none; cursor: pointer;
}
.bloc-pli > summary::-webkit-details-marker { display: none; }
.bloc-pli > summary::after {
  content: '▾'; margin-inline-start: auto; align-self: center; color: var(--encre-3);
}
.bloc-pli[open] > summary::after { content: '▴'; }
.bloc-pli[open] > summary { border-bottom: 1px solid var(--trait); }
.pli-titre {
  flex: 0 0 auto;
  font-family: var(--f-ui); font-size: var(--t-ui-s); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--encre);
}
/* Le résumé est ce qui rend le repli utilisable : « Statut juridique » ne dit
   pas s'il faut l'ouvrir, « Statut juridique · prélèvement interdit » le dit. */
.pli-resume {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--f-texte); font-size: 12.5px; color: var(--encre-3);
}
.bloc-corps { padding: 12px; }
.bloc-corps > .bloc:last-child { margin-bottom: 0; }
