/* ============================================================
   SpiLi — La scène cartographique de l'Atlas
   Identité « Le Filet » · lot 3a
   ------------------------------------------------------------
   La carte est un SVG produit à la compilation. Cette feuille
   ne fait que l'habiller : elle ne déclare aucune couleur en
   dur, tout vient des jetons — et comme la scène porte la
   classe `spili-atlas`, ces mêmes jetons y prennent leurs
   valeurs de régime sombre.

   Grammaire des signes, telle que le système la fixe :
   — la FORME dit le niveau : disque = terroir, cercle évidé
     = catégorie. Jamais la couleur ;
   — le CONTOUR dit la précision géographique effectivement
     résolue : net pour une étendue dont le contour est chargé,
     tireté pour un repère dont la position n'est qu'indicative.
     C'est la géométrie qui décide, jamais la déclaration du
     corpus (lot 3-0, src/lib/geographie.js) ;
   — l'ACCENT ne dit qu'une chose, un état : la sélection.
   ============================================================ */

.carte {
  background: var(--spili-fond);
  border: 1px solid var(--spili-texte);
  padding: 18px 20px 16px;
  display: flex; flex-direction: column; gap: 14px;
}

/* ---------- Barre de la scène ---------- */

.carte-barre {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: center; justify-content: space-between;
}

/* Les échelles sont des planches, pas un zoom : chacune a sa projection et
   sa résolution de trait. Segments accolés, l'actif en plein — même motif
   que la barre de modes, parce que c'est le même geste. */
.carte-echelles { display: flex; border: 1px solid var(--spili-texte-faible); }
.carte-echelles button {
  background: none; border: 0; cursor: pointer;
  color: var(--spili-texte-doux);
  font-family: var(--spili-courant); font-size: 13.5px;
  padding: 7px 18px;
  transition: background var(--spili-transition), color var(--spili-transition);
}
.carte-echelles button + button { border-left: 1px solid var(--spili-texte-faible); }
.carte-echelles button:hover { color: var(--spili-texte); background: var(--spili-accent-voile); }
.carte-echelles button.is-active { background: var(--spili-texte); color: var(--spili-fond); }

/* Le relevé : ce que le survol affichait seul dans la version canvas. Il est
   maintenant écrit, donc lisible au clavier, au toucher et à la synthèse. */
.carte-releve {
  font-family: var(--spili-data); font-size: 11.5px;
  letter-spacing: 0.04em; color: var(--spili-texte-doux);
  min-height: 1.5em; text-align: right;
}

/* ---------- La toile ---------- */

/* La toile suit la largeur, mais plus sans limite : à pleine fenêtre, le
   ratio 1200 × 620 la ferait déborder de l'écran en hauteur, et une carte
   qu'on ne voit pas d'un seul tenant ne se lit pas. `preserveAspectRatio`
   fait le reste — la carte se centre, elle ne se déforme jamais. */
.carte-toile {
  display: block; width: 100%; height: auto;
  max-height: 74vh;
}
/* `hidden` est un attribut HTML : la feuille de l'agent utilisateur ne le
   traduit pas en `display:none` sur un élément du namespace SVG. Sans cette
   règle, les trois planches s'empilent. */
.carte-toile[hidden] { display: none; }

.carte-fond { fill: var(--spili-fond); }

.carte-graticule {
  fill: none;
  stroke: var(--spili-trait);
  stroke-width: 0.6;
}
/* Les côtes sont tracées, pas remplies : sur fond sombre, un aplat de terre
   assez clair pour atteindre 3:1 écraserait les repères, alors qu'un trait
   les atteint sans occuper la surface. C'est aussi le registre de la carte
   marine, qui est celui du système. */
.carte-terres {
  fill: var(--spili-fond-eleve);
  stroke: var(--spili-texte-faible);
  stroke-width: 0.7;
  stroke-linejoin: round;
}

/* ---------- La toponymie (lot A-3) ----------
   Un nom de repère situe, il ne documente pas : il est donc en régime discret,
   sans jamais atteindre le blanc des entrées, et il est posé sous elles dans
   l'ordre du document. `pointer-events: none` garantit qu'aucun libellé ne
   vole un clic à un repère.

   Les seuils d'apparition sont portés par une classe d'échelle que pose
   `atelier.js` ; sans script, seule la vue d'ensemble existe, et c'est bien
   la toponymie de cette vue qui s'affiche. */

.carte-toponymie { pointer-events: none; }

.topo {
  font-family: var(--spili-courant);
  fill: var(--spili-texte-doux);
  paint-order: stroke;
  stroke: var(--spili-fond);
  stroke-width: 2.4;
  stroke-linejoin: round;
}

/* Une masse continentale : capitales espacées, comme sur une carte marine. */
.topo--masse {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  fill: var(--spili-texte-faible);
}

/* Un océan : italique, la convention cartographique de l'hydrographie. */
.topo--eau {
  font-size: 10.5px;
  letter-spacing: 0.16em;
  font-style: italic;
  fill: var(--spili-texte-faible);
}

/* Un pays : c'est le seul rang qui nomme un territoire documenté par le
   corpus, et il se lit un ton plus haut que les deux autres. */
.topo--pays {
  font-size: 10px;
  letter-spacing: 0.04em;
  fill: var(--spili-texte-doux);
}

/* Les seuils. Les pays n'apparaissent qu'à partir de l'échelle régionale : à
   la vue d'ensemble, quatorze libellés sur l'Europe de l'Ouest formeraient une
   tache là où la carte est déjà la plus dense. */
.carte:not(.echelle-region):not(.echelle-locale) .topo--pays { display: none; }
.carte.echelle-locale .topo--masse,
.carte.echelle-locale .topo--eau { display: none; }

/* ---------- Les deux paliers (lot A-2) ----------
   `hidden` ne suffit pas dans le namespace SVG — la feuille de l'agent
   utilisateur ne le traduit pas en `display:none`. La règle explicite fait
   aussi sortir les repères du palier masqué du parcours de tabulation, ce
   qu'aucune opacité ne ferait. */

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

/* Le filet qui rattache une marque dispersée à son lieu réel. Sans lui, une
   couronne se lirait comme six positions relevées ; avec lui, elle dit ce
   qu'elle est — une même ville-repère, et six entrées qui la partagent. */
.attache {
  stroke: var(--spili-texte-faible);
  stroke-width: 0.6;
  opacity: 0.55;
}

/* ---------- Repères ---------- */

.repere { cursor: pointer; }
/* Cible de pointage élargie : 28 unités de viewBox, soit environ 24 px à
   l'affichage courant. Invisible, mais elle reçoit le toucher. */
.repere-cible { fill: none; pointer-events: all; }
.repere-marque {
  fill: var(--spili-texte);
  stroke: none;
  transition: fill var(--spili-transition), r var(--spili-transition);
}

/* Catégorie : cercle évidé. La distinction avec le terroir est de forme,
   elle survit au monochrome et au daltonisme. */
.repere--categorie .repere-marque {
  fill: none;
  stroke: var(--spili-texte);
  stroke-width: 1.4;
}

/* Repère territorial : la position n'est qu'indicative, l'anneau tireté le
   dit. Même trame que le « probable » de la frise. */
.repere--repere .repere-marque { r: 3.4; }
.repere--repere .repere-cible {
  fill: none;
  stroke: var(--spili-texte-faible);
  stroke-width: 1;
  stroke-dasharray: 2.5 2.5;
  r: 8;
}

.repere-nombre {
  fill: var(--spili-texte);
  /* `color` est redondant pour le rendu — SVG peint avec `fill` — mais les
     contrôleurs de contraste lisent la propriété héritée, qui sinon reste
     celle du régime clair du document. */
  color: var(--spili-texte);
  font-family: var(--spili-data); font-size: 10px;
  text-anchor: middle;
  pointer-events: none;
}

/* Survol, focus, sélection — trois entrées vers le même état. */
.repere:hover .repere-marque,
.repere:focus-visible .repere-marque,
.repere.est-choisi .repere-marque { fill: var(--spili-accent); }
.repere--categorie:hover .repere-marque,
.repere--categorie:focus-visible .repere-marque,
.repere--categorie.est-choisi .repere-marque { fill: none; stroke: var(--spili-accent); }

.repere:focus { outline: none; }
.repere:focus-visible .repere-cible,
.repere.est-choisi .repere-cible {
  fill: none;
  stroke: var(--spili-accent);
  stroke-width: 1.2;
  stroke-dasharray: none;
  r: 11;
}

/* Une entrée écartée par les filtres s'estompe, elle ne disparaît pas : un
   filtre qui vide la carte ment sur l'étendue du corpus. */
.repere.est-ecarte { opacity: 0.14; }
.repere.est-ecarte:hover .repere-marque { fill: var(--spili-texte); }

/* ---------- Liste des repères ----------
   Elle double la carte : même ordre d'ouest en est, même sélection. Elle est
   la voie de sélection sur écran étroit, et l'alternative textuelle partout
   ailleurs. Elle vit dans la scène, donc en régime sombre. */

.carte-liste ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px 18px;
  max-height: 190px; overflow-y: auto;
}
.carte-liste li {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 13px; line-height: 1.5;
  padding: 3px 0;
  border-bottom: 1px solid var(--spili-trait-faible);
}
.carte-liste li[hidden] { display: none; }
.liste-nom {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--spili-courant); font-size: 13px; text-align: left;
  color: var(--spili-texte-doux);
  flex: 1;
}
.liste-nom:hover { color: var(--spili-accent); }
.carte-liste li.est-choisi .liste-nom { color: var(--spili-accent); }
.liste-fiche {
  font-family: var(--spili-data); font-size: 10.5px;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--spili-accent);
}

/* ---------- Légende ---------- */

.carte-legende {
  display: flex; flex-wrap: wrap; gap: 22px; align-items: center;
  font-family: var(--spili-data); font-size: 11px; line-height: 1.6;
  color: var(--spili-texte-doux);
  border-top: 1px solid var(--spili-trait);
  padding-top: 12px;
}
.carte-legende span { display: inline-flex; align-items: center; gap: 8px; }
.jeton { width: 10px; height: 10px; display: inline-block; }
.jeton--aire { background: var(--spili-texte); border-radius: 50%; }
.jeton--repere {
  border-radius: 50%; border: 1px dashed var(--spili-texte-faible);
  width: 12px; height: 12px;
}
.jeton--categorie {
  border-radius: 50%; border: 1.4px solid var(--spili-texte);
}
.jeton--groupe {
  background: var(--spili-texte); border-radius: 50%;
  box-shadow: 0 -7px 0 -4px var(--spili-texte);
}

/* ---------- Indications sous la scène (régime clair) ---------- */

.carte-hors { display: block; margin-top: 6px; color: var(--spili-texte-faible); }

/* ---------- Ruptures ---------- */

/* Les cibles sont dessinées dans les unités de la toile : plus la carte est
   étroite, plus elles rétrécissent à l'écran. On les élargit à mesure — mais
   pas au-delà de ce que la densité des repères autorise, sinon le premier de
   la pile capterait les touchers de ses voisins. Sous 560 px la cible reste
   en deçà des 24 px souhaitables : la carte du monde n'y est pas une surface
   de sélection au doigt, et c'est la liste du lot 3b qui prendra le relais. */
@media (max-width: 1120px) {
  .repere-cible { r: 20; }
  .repere--repere .repere-cible { r: 10; }
}
@media (max-width: 560px) {
  .repere-cible { r: 30; }
  .repere--repere .repere-cible { r: 14; }
}

@media (max-width: 860px) {
  .carte { padding: 14px 14px 12px; }
  .carte-liste ul { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: 240px; }
  .carte-barre { justify-content: flex-start; }
  .carte-releve { text-align: left; width: 100%; }
  .carte-legende { gap: 14px; }
}
@media (max-width: 560px) {
  .carte-liste ul { grid-template-columns: 1fr; max-height: 300px; }
  .carte-liste li { padding: 7px 0; }
  .carte-echelles { width: 100%; }
  .carte-echelles button { flex: 1; padding: 7px 10px; }
}

/* ---------- L'ampleur de la scène (lots 3c puis A-1) ----------
   Dans la colonne du gabarit, la carte tombait à 650 px de large : un atlas
   mondial n'y respire pas. Le lot 3c a donné le moyen d'en sortir — sans API
   plein écran, qui sortirait la page de son URL et romprait le partage que le
   lot 3b venait d'établir.

   Le lot A-1 en fait l'ÉTAT PAR DÉFAUT, et inverse le bouton. Le motif est
   mesuré : la scène étendue était un secret, rien ne l'annonçait, et elle
   disparaissait sous 860 px — la carte du site s'ouvrait donc, pour tout le
   monde, dans le format qui la rend illisible. Le geste inverse reste offert
   à qui veut rendre la page à sa colonne de lecture. */

.carte-etendre {
  background: none; cursor: pointer;
  border: 1px solid var(--spili-texte-faible);
  color: var(--spili-texte-doux);
  font-family: var(--spili-courant); font-size: 13px;
  padding: 6px 14px;
  transition: background var(--spili-transition), color var(--spili-transition);
}
.carte-etendre:hover { color: var(--spili-texte); background: var(--spili-accent-voile); }
.carte-etendre[aria-pressed="true"] { background: var(--spili-texte); color: var(--spili-fond); }

/* La marge négative rend à la scène ce que le gabarit lui prend, sans la
   sortir du flux : la page continue de défiler normalement. `100vw` ignore la
   barre de défilement, d'où le repli sur `100dvw` là où il existe.

   L'ampleur est désormais l'état par défaut de la scène de l'Atlas : la règle
   ne porte plus une classe d'exception mais la scène elle-même, et c'est
   `.est-reduite` qui la ramène dans la colonne. */
#atlas-explorer.vue-carte {
  width: 100vw;
  width: 100dvw;
  margin-left: calc(50% - 50vw);
  margin-left: calc(50% - 50dvw);
  padding: 0 24px;
}
#atlas-explorer.vue-carte.a-selection { --panneau: 400px; }

#atlas-explorer.vue-carte.est-reduite {
  width: auto;
  margin-left: 0;
  padding: 0;
}
#atlas-explorer.vue-carte.est-reduite.a-selection { --panneau: 380px; }

/* La barre qui commande la scène la suit (lot A-4). Depuis A-1 la scène sort
   du gabarit ; la barre d'outils, elle, y restait, et les filtres se
   retrouvaient alignés cent-quatre-vingts pixels à droite du bord de la carte
   qu'ils commandent. Un contrôle se pose sur ce qu'il contrôle. */
.atlas-section:has(#atlas-explorer.vue-carte:not(.est-reduite)) .atlas-toolbar,
.atlas-section:has(#atlas-explorer.vue-carte:not(.est-reduite)) .atlas-count {
  width: 100vw;
  width: 100dvw;
  margin-left: calc(50% - 50vw);
  margin-left: calc(50% - 50dvw);
  padding-left: 24px;
  padding-right: 24px;
}

/* ---------- La scène sur téléphone (lot A-5) ----------
   Mesuré avant ce lot : la carte tombait à 297 × 153 px et ses cibles à 5 px.
   Aucun réglage de rayon ne rattrape cela — des cibles de 24 px à cette
   largeur feraient soixante-dix-sept unités de rayon et se recouvriraient
   toutes. Ce qui les rend atteignables est le ZOOM, et au doigt le zoom
   s'appelle le pincement : c'est lui que le lot ajoute (js/atelier.js).

   La scène gagne en attendant ce qu'on peut lui donner sans rien fausser :
   les marges du gabarit, que sa boîte reprend en sortant du conteneur. */
@media (max-width: 560px) {
  #atlas-explorer.vue-carte .carte {
    width: 100vw;
    width: 100dvw;
    margin-left: calc(50% - 50vw);
    margin-left: calc(50% - 50dvw);
    padding-left: 12px;
    padding-right: 12px;
    border-left: 0;
    border-right: 0;
  }
  /* Le geste tactile a besoin d'une hauteur pour être confortable : sous
     `slice` la carte remplirait en coupant les bords, ce qui retirerait les
     Amériques. On garde donc le cadrage entier et on annonce le geste. */
  #atlas-explorer.vue-carte .carte-toile { max-height: 52vh; }
}

@media (max-width: 860px) {
  /* Sous cette largeur le gabarit ne retient déjà presque rien : le bouton
     n'aurait rien à rendre, et la scène est pleine par construction. */
  .carte-etendre { display: none; }
  .atlas-section:has(#atlas-explorer.vue-carte) .atlas-toolbar,
  .atlas-section:has(#atlas-explorer.vue-carte) .atlas-count {
    width: auto; margin-left: 0; padding-left: 0; padding-right: 0;
  }
  #atlas-explorer.vue-carte,
  #atlas-explorer.vue-carte.est-reduite { width: auto; margin-left: 0; padding: 0; }
}

/* ---------- Entrée dans la scène ----------
   Le seul mouvement de la page, et il révèle une structure : les côtes se
   tracent d'ouest en est à l'ouverture, une fois. Ni parallaxe, ni
   apparition au défilement, ni compteur animé — dans une institution
   scientifique, le mouvement gratuit se lit comme du marketing. */

@media (prefers-reduced-motion: no-preference) {
  .carte-terres { animation: carte-tracer 520ms ease-out 1; }
  @keyframes carte-tracer {
    from { stroke-dasharray: 1; stroke-dashoffset: 1; }
    99%  { stroke-dasharray: 1; stroke-dashoffset: 0; }
    to   { stroke-dasharray: none; }
  }
}

/* ---------- La porte de la visite conduite (lot 3-2) ---------- */

/* Un renvoi, pas une bannière : le filet de notation à gauche le rattache au
   système, et rien d'autre ne le distingue du corps de la page. */
.atlas-porte { padding: 0 0 26px; }
.atlas-porte .container {
  border-left: var(--spili-notation) solid var(--spili-texte);
  padding-left: 18px;
}
.atlas-porte-kicker {
  font-family: var(--spili-data); font-size: 10.5px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--spili-texte-faible); margin-bottom: 6px;
}
.atlas-porte-texte {
  font-size: 1rem; line-height: 1.6; max-width: 72ch; margin: 0;
}
.atlas-porte-texte a { white-space: nowrap; }
