/* =========================================================================
   SWISS PRO MOVING — « Où nous allons », la carte exacte du canton

   Source du dessin : references/carte/carte-geneve.svg (OpenStreetMap, ODbL
   1.0) et references/carte/communes.json (numéros OFS et NPA, swisstopo,
   OGD). L'attribution est OBLIGATOIRE et VISIBLE : elle est dans le
   figcaption, sous le dessin, sans survol ni dépli.

   Géométrie : directions/mediane-carte-v2.md §B à §E, sans une coordonnée
   retouchée. Couleurs : directions/site-swiss-pro-moving.md §4.4 — c'est
   tout ce que le rhabillage change au dessin.

   Toutes les épaisseurs portent vector-effect: non-scaling-stroke, sans quoi
   un filet de 0,6 px réglé pour 880 px tombe à 0,23 px à 375 px et le
   maillage disparaît.

   Cette feuille est la SEULE propriétaire de .carte-intro et .carte-micro :
   accueil.css ne les redéclare pas. Une règle, un seul fichier.
   ========================================================================= */

/* --------------------------------------------------------------- 1. Cadre */

.carte-intro {
  margin-top: var(--e16);
  max-width: var(--mesure-etroite);
  font-size: var(--t-texte-large);
  line-height: 1.45;
  color: var(--texte-secondaire);
}

/* La figure est pleine largeur — c'est le dessin qui a besoin des 880 px —
   mais sa LÉGENDE est du texte courant : elle doit commencer où commence le
   chapeau au-dessus d'elle, et non au pixel 0. La figure rejoue donc, pour
   elle seule, les colonnes de `.bande` (base.css §3) : le plan prend toute la
   largeur, le figcaption prend la colonne de texte et son retrait de rail.
   Sans cela les deux légendes partaient de x = 0, c'est-à-dire 163 px à
   gauche de tout le reste de la page — et la ligne d'itinéraire, qui court à
   x = 87 dans cette section, les traversait mot par mot. */
.carte-geneve {
  position: relative;
  margin: var(--e32) 0 var(--e16);
  display: grid;
  grid-template-columns:
    [pleine-d] minmax(var(--gouttiere-g), 1fr)
    [texte-d] minmax(0, var(--largeur-max))
    [texte-f] minmax(var(--gouttiere-d), 1fr)
    [pleine-f];
}

/* aspect-ratio est exactement le rapport du viewBox : avec
   preserveAspectRatio="xMidYMid meet" le dessin remplit la boîte SANS marge
   morte, ce qui rend les pourcentages des étiquettes linéaires et
   vérifiables. Changer l'un sans l'autre casse toutes les positions. */
.carte-plan {
  position: relative;
  grid-column: pleine-d / pleine-f;
  width: 100%;
  max-width: 880px;
  margin-inline: auto;
  aspect-ratio: 1340 / 1300;
}

.carte-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* ------------------------------------------------- 2. Calques du dessin */

/* .commune est remplie de --fond, la couleur du fond de page : la commune
   paraît vide ET reste survolable, ce qu'un fill: none interdit (aucun
   événement de souris à l'intérieur). Ce remplissage écrase l'attribut
   fill="none" porté par le groupe — une règle CSS l'emporte toujours sur un
   attribut de présentation. */
.commune {
  fill: var(--fond);
  stroke: var(--filet);
  stroke-width: .6px;
  vector-effect: non-scaling-stroke;
  transition: fill var(--duree-courte) var(--entree),
              stroke var(--duree-courte) var(--entree),
              stroke-width var(--duree-courte) var(--entree);
}

/* Un aplat gris doux et OPAQUE : il efface les limites communales qui
   débordent sur l'eau, les données OSM faisant entrer la part de lac dans le
   polygone de chaque commune riveraine. */
.lac { fill: var(--filet); stroke: none; }

.cours-eau {
  fill: none;
  stroke: var(--filet-fort);
  stroke-width: 1.2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* Le contour noir ferme le dessin. C'est le geste suisse. */
.canton {
  fill: none;
  stroke: var(--texte);
  stroke-width: 1.6px;
  vector-effect: non-scaling-stroke;
}

.trajet-ligne {
  fill: none;
  stroke: var(--marque);
  stroke-width: 2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* Le bout de chaque trait : un sous-chemin de longueur nulle (« M x y h0 »)
   à bouts ronds, soit un disque de 6 px à toutes les largeurs grâce à
   non-scaling-stroke. Le trait s'arrête là, 8 px avant son panneau (D4). */
.trajet-bout {
  fill: none;
  stroke: var(--marque);
  stroke-width: 6px;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.lien-ab {
  fill: none;
  stroke: var(--marque);
  stroke-width: 2px;
  stroke-dasharray: 6 5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* --------------------------------------------------------------- 3. États */

/* data-nommee est posé DANS le balisage, sur les neuf tracés qui portent une
   étiquette : la carte doit être juste sans JavaScript. .est-survolee,
   .est-a et .est-b sont les trois seules classes que carte.js a le droit de
   poser. */
.commune[data-nommee] {
  stroke: var(--filet-fort);
  stroke-width: .7px;
}

.commune.est-survolee {
  fill: var(--surface);
  stroke: var(--filet-fort);
  stroke-width: 1px;
}

.commune.est-a,
.commune.est-b {
  fill: var(--surface);
  stroke: var(--marque);
  stroke-width: 1.6px;
}

/* --------------------------------------------------------- 4. Étiquettes */

.carte-lieux,
.carte-directions {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  pointer-events: none;
}

.carte-lieux > li,
.carte-directions > li { margin-top: 0; max-width: none; }

/* LE LISERÉ. Les deux <ul> viennent APRÈS le <svg> et sont positionnés : les
   noms sont donc peints par-dessus les cinq rayons. Cela ne suffisait pas —
   un trait rouge de 2 px qui passe DERRIÈRE un nom gris de 13 px se lit comme
   un texte barré, et c'est le nom « Genève » qui en souffrait le plus.
   Chaque nom porte donc un liseré de 3 px en --fond (2 px jusqu'au 29.09 :
   le contour noir de la Suisse se lisait encore sous « 1201 Genève » et
   « Vous êtes ici (environ) », DA D3 et D5), posé en seize décalages
   durs, deux anneaux de 1,5 et 3 px pour qu'aucun jour ne reste entre la
   lettre et le liseré (aucun flou : un halo flou laisserait le rouge remonter entre les
   lettres). text-shadow peint TOUJOURS derrière le glyphe, dans les trois
   moteurs, sans dépendre de `paint-order` — que Firefox n'applique au texte
   HTML que depuis sa version 113, et dont l'absence ferait peindre le
   contour PAR-DESSUS la lettre, c'est-à-dire l'effacerait. */
.carte-lieu,
.carte-direction {
  text-shadow:
     3px 0    0 var(--fond), -3px 0    0 var(--fond),
     0    3px 0 var(--fond),  0   -3px 0 var(--fond),
     2.1px  2.1px 0 var(--fond), -2.1px  2.1px 0 var(--fond),
     2.1px -2.1px 0 var(--fond), -2.1px -2.1px 0 var(--fond),
     1.5px 0    0 var(--fond), -1.5px 0    0 var(--fond),
     0    1.5px 0 var(--fond),  0   -1.5px 0 var(--fond),
     1.1px  1.1px 0 var(--fond), -1.1px  1.1px 0 var(--fond),
     1.1px -1.1px 0 var(--fond), -1.1px -1.1px 0 var(--fond);
}

/* --ax : le cadrage (0 %, −50 %, −100 % de la largeur) ; --px : le bord de
   la boîte posé sur le point sourcé (0 %, 50 %, 100 %) ; --tx / --ty : le
   décalage EFFECTIF, --dx/--dy à partir de 768 px, --mdx/--mdy en dessous
   (section 7). Une seule formule pour les deux largeurs. */
.carte-lieu {
  --ax: -50%;
  --px: 50%;
  --tx: var(--dx, 0px);
  --ty: var(--dy, 0px);
  position: absolute;
  left: var(--x);
  top: var(--y);
  font-family: var(--police-chiffre);
  font-size: 13px;
  letter-spacing: .04em;
  white-space: nowrap;
  color: var(--texte-secondaire);
  transform: translate(var(--ax), -50%) translate(var(--tx), var(--ty));
}

/* La pastille reprend le décalage à l'envers : le texte bouge, LE POINT
   RESTE au centre exact de la commune, qui est la seule coordonnée sourcée.

   ⚠️ `left: 50%` ne compense QUE le cadrage centré. Sur une étiquette cadrée
   à droite, `translate(-100%, -50%)` met le BORD DROIT de la boîte sur le
   point sourcé, et le milieu de la boîte tombe une demi-largeur plus à
   gauche : la pastille partait avec lui. Relevé au navigateur le 20.09,
   écart pastille ↔ centre de commune : Genève −21,6 px, Carouge −24,5 px,
   Onex −14,9 px à 1440 px ; Genève +19,9 px, Carouge +22,6 px, Thônex
   +19,7 px à 375 px — c'est-à-dire un disque gris planté DANS le mot
   « Genève », le nom le plus important de la carte. Le point d'ancrage de la
   pastille suit donc le bord que le cadrage a posé sur la coordonnée : 0 %
   pour un cadrage à gauche, 100 % pour un cadrage à droite, 50 % au centre.
   Les huit zéros du même relevé disaient déjà que la règle centrée, elle,
   était juste : on ne la touche pas. */
.carte-lieu::before {
  content: "";
  position: absolute;
  left: var(--px);
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: var(--rayon-rond);
  background: var(--texte-secondaire);
  transform: translate(-50%, -50%)
             translate(calc(var(--tx) * -1), calc(var(--ty) * -1));
}

.carte-lieu.est-a,
.carte-lieu.est-b { color: var(--texte); }

.carte-lieu.est-a::before,
.carte-lieu.est-b::before { background: var(--marque); }

/* Genève, départ des cinq traits (DA 29.09, D14) : point rouge de 8 px,
   anneau blanc de 2 px, à toutes les largeurs ; nom en gras, couleur texte,
   posé au-dessus du faisceau par --dx/--dy et --mdx/--mdy (index.html).
   Contrôle : carte.test.mjs, « G : D14 ». */
.carte-lieu[data-origine] {
  font-weight: 700;
  color: var(--texte);
}
.carte-lieu[data-origine]::before {
  width: 8px;
  height: 8px;
  background: var(--marque);
  box-shadow: 0 0 0 2px #fff;
}

/* Les cinq panneaux de sortie. Casse de PHRASE, et non capitales : le brand
   book met ses dix titres en casse de phrase et n'emploie uppercase que pour
   le logo, la signature et les sigles réels (cahier §1.7). La condensée
   noire fait le graphisme suisse à elle seule. */
/* --x et --y posent le panneau sur le POINT DE SORTIE du rayon ; --ox et --oy
   l'écartent ensuite du trait. C'est la seule façon de tenir les deux pentes
   du §1.2 : on décale l'étiquette, jamais le trait. */
.carte-direction {
  --tox: var(--ox, 0px);
  --toy: var(--oy, 0px);
  position: absolute;
  left: var(--x);
  top: var(--y);
  font-family: var(--police-titre);
  font-weight: var(--graisse-noire);
  font-size: 15px;
  line-height: 1.1;
  letter-spacing: 0;
  white-space: nowrap;
  color: var(--texte);
  transform: translate(-50%, -50%) translate(var(--tox), var(--toy));
}

/* Panneau sur deux lignes (« Lausanne · Berne » / « Zurich », DA 29.09,
   G-1) : le retour à la ligne est DANS le texte du <li> ; pre le garde sans
   jamais couper ailleurs. Sur une ligne, il mesurait 10,5 em et sortait du
   cadre sous 768 px. */
.carte-direction[data-lignes] { white-space: pre; text-align: center; }

/* L'équivalent HTML de text-anchor="middle / start / end". C'est cette
   convention exacte qui a servi au contrôle de non-chevauchement du solveur :
   le cadrage d'abord, le décalage ensuite. */
.carte-lieu[data-align="left"]  { --ax: 0%;    --px: 0%; }
.carte-lieu[data-align="right"] { --ax: -100%; --px: 100%; }

.carte-direction[data-align="left"] {
  transform: translate(0, -50%) translate(var(--tox), var(--toy));
}

.carte-direction[data-align="right"] {
  transform: translate(-100%, -50%) translate(var(--tox), var(--toy));
}

/* Une seule étiquette flottante pour les quarante-cinq communes, jamais
   quarante-cinq éléments. Elle est aria-hidden : elle redit un nom déjà
   présent dans la <desc> du dessin. */
.carte-bulle {
  position: absolute;
  left: var(--bx, 0);
  top: var(--by, 0);
  margin: 0;
  padding: var(--e4) var(--e8);
  max-width: none;
  background: var(--texte);
  color: var(--fond);
  border-radius: var(--rayon);
  font-size: var(--t-petit);
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  transform: translate(var(--btx, 8px), -50%);
}

/* ------------------------------------------------- 5. Légende et licence */

/* La légende et la source commencent au bord du cadre de la carte (880 px
   au plus, centré), jamais plus à gauche que le texte courant (DA 29.09,
   G-6). Gouttières égales dès 768 px : le cadre commence à
   (colonne de texte - 880 px) / 2 du début de la colonne ; la marge en %
   se lit sur la colonne. Sous cette largeur, max() rend 0 : rien ne bouge. */
.carte-legende {
  grid-column: texte-d / texte-f;
  padding-left: var(--retrait-rail);
  margin-left: max(0px, calc((100% - 880px) / 2 - var(--retrait-rail)));
  margin-top: var(--e16);
  max-width: var(--mesure);
  font-size: var(--t-petit);
  line-height: var(--interligne-petit);
  color: var(--texte-secondaire);
}

/* --texte-secondaire et non --filet : la mention doit rester LISIBLE, pas
   décorative. C'est une condition de licence (ODbL 1.0 pour les géométries,
   OGD swisstopo pour les numéros OFS et les NPA), pas un choix éditorial. */
.carte-licence {
  display: block;
  margin-top: var(--e8);
  font-size: var(--t-micro);
  color: var(--texte-secondaire);
}

/* Les 45 communes en texte (24.09, carnet SEO pièce 08). La carte est
   l'illustration, cette liste est ce qui se lit : même corps et même gris
   que la légende au-dessus, sur la mesure du texte courant. Les <li> se
   suivent en ligne, comme une phrase, et chacun est INSÉCABLE : sans cela
   « Aire-la-Ville », « Chêne-Bougeries » ou « Le Grand-Saconnex » se
   coupaient au trait d'union ou à l'espace (relevé à 1440 et à 390). Les
   virgules sont dans le texte : la liste se lit aussi sans cette feuille. */
.carte-communes-tete,
.carte-communes {
  max-width: var(--mesure);
  font-size: var(--t-petit);
  line-height: var(--interligne-petit);
  color: var(--texte-secondaire);
}

.carte-communes-tete { margin-top: var(--e24); }

.carte-communes {
  margin: 0;
  padding-left: var(--retrait-rail);
  list-style: none;
}

.carte-communes li {
  display: inline;
  white-space: nowrap;
}

.carte-micro { margin-top: var(--e8); }

.carte-communes + .carte-micro { margin-top: var(--e16); }

/* -------------------------------------------------- 6. Tracé au défilement */

/* carte.js pose .carte-anime dès son exécution, puis .carte-tracee quand la
   boîte entre dans la fenêtre — une seule fois. TOUTE la règle de pointillé
   vit sous .carte-anime : sans JavaScript la classe n'existe pas, et les
   cinq traits sont peints entiers dès la première image.
   --L, --d et --r sont posés sur chaque tracé dans le balisage : ce sont les
   longueurs calculées, il n'y a rien à mesurer par getTotalLength(). */
.carte-anime .trajet-ligne {
  stroke-dasharray: var(--L);
  stroke-dashoffset: var(--L);
  transition: stroke-dashoffset var(--d) var(--entree) var(--r);
}

.carte-anime.carte-tracee .trajet-ligne { stroke-dashoffset: 0; }

/* Le point final paraît quand son trait l'atteint. */
.carte-anime .trajet-bout {
  opacity: 0;
  transition: opacity 160ms var(--entree) calc(var(--r) + var(--d));
}
.carte-anime.carte-tracee .trajet-bout { opacity: 1; }

/* ------------------------------------------------------------- 7. À 375 px */

/* Le viewBox ne change PAS : un second cadrage obligerait à tenir deux jeux
   de coordonnées pour une seule carte, donc deux vérités, dont une qui se
   périmera sans prévenir.
   Quatre étiquettes sur neuf disparaissent — élément entier, pastille comprise :
   une pastille sans nom n'apprend rien. Les cinq panneaux de direction, eux,
   restent tous les cinq : c'est le message de la section. */
@media (max-width: 767px) {
  .carte-lieu { font-size: 12px; }
  .carte-direction { font-size: 12px; }

  /* data-mcache, --mdx/--mdy et data-malign sont DANS le balisage. Les
     anciennes corrections par [data-ofs] redéfinissaient --dx ici : un style
     en ligne l'emporte sur toute règle de feuille, elles ne s'appliquaient
     donc jamais (point planté dans « Genève » et « Carouge », DA 29.09). */
  .carte-lieu[data-mcache] { display: none; }
  .carte-lieu {
    --tx: var(--mdx, var(--dx, 0px));
    --ty: var(--mdy, var(--dy, 0px));
  }
  .carte-lieu[data-malign="left"]   { --ax: 0%;    --px: 0%; }
  .carte-lieu[data-malign="center"] { --ax: -50%;  --px: 50%; }
  .carte-lieu[data-malign="right"]  { --ax: -100%; --px: 100%; }
  .carte-direction {
    --tox: var(--mox, var(--ox, 0px));
    --toy: var(--moy, var(--oy, 0px));
  }
}

/* A7 (29.09, lot 13) : data-dcache retire un nom, pastille comprise, à
   partir de 768 px seulement (Lancy : son point se lisait comme celui de
   « Carouge »). Sous 768 px, seul data-mcache décide. */
@media (min-width: 768px) {
  .carte-lieu[data-dcache] { display: none; }
}

/* ----------------------------------------------------- 8. Mouvement réduit */

/* Les cinq traits sont entiers, tout de suite, sans transition. Le repli est
   la version la mieux visible, jamais un dessin amputé. Les états de commune
   changent d'un coup : ils ne disparaissent pas. */
@media (prefers-reduced-motion: reduce) {
  .carte-anime .trajet-ligne {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    transition: none;
  }
  .carte-anime .trajet-bout { opacity: 1; transition: none; }

  .commune { transition: none; }
}
