/* ============================================================
   ASTRA GENESIS, 08-MAP.CSS
   v0.56.4, Carte, grille de zones et tags Gxx
   ------------------------------------------------------------
   Trois vues, un seul écran :
     niveau 1  la galaxie   -> assets/map/galaxy.webp, PLEIN CADRE
     niveau 2  la grille    -> assets/map/system.jpg, PLEIN CADRE,
                               10 x 10 zones portant les 5000 planètes
     niveau 3  la planète   -> le champ d'étoiles du jeu (#starfield)

   PLEIN CADRE (changement v0.56.3) : les deux fonds couvrent
   entièrement la scène, il n'y a plus de bande noire. Ce n'est pas un
   `object-fit` posé au hasard : la taille de couverture est CALCULÉE
   (js/10c-map-camera.js) et donnée au plan, ce qui permet de continuer
   à poser les nœuds en POURCENTAGE de l'image tout en la recadrant.

   LE PLAN. `#gal-plane` porte l'image de la galaxie et tous les nœuds,
   et c'est lui que la caméra déplace et zoome, d'un seul `transform`
   composé par le GPU. Les points ne grossissent pas avec le zoom : le
   plan expose `--mz` (= 1/zoom) et chaque nœud l'applique en contre-
   échelle, donc la carte s'écarte mais les repères gardent leur taille.

   ASSOMBRISSEMENT : toujours un CALQUE INDÉPENDANT posé par-dessus
   l'image (.gal-veil / .pv-veil), jamais un traitement du fichier
   source. Les intensités tiennent dans cinq variables déclarées ici et
   nulle part ailleurs :
     --gal-bright / --sys-bright / --gal-veil   (galaxie et système)
     --pv-veil    / --pv-globe-bright           (planète)
   v0.56.3 : les trois ont été assombries d'un cran (demande explicite),
   pour que les fonds rentrent dans la charte navy du jeu.

   Aucun token n'est redéfini ici : tout vient de css/01-tokens.css. Les
   couleurs propres à un nœud sont passées en variable locale par le JS
   (--nc), jamais en style inline complet : le thème reste pilotable
   depuis les tokens.

   Charte (CLAUDE.md, "zéro contrôle natif") : champ de recherche, cases
   de la légende et barre de zoom sont entièrement redessinés.
   ============================================================ */

#screen-map{padding:0 !important;}
.map-wrap{
  position:relative;width:100%;height:100%;
  display:grid;grid-template-columns:1fr calc(340px*var(--scale));
}
/* La bascule mono-colonne sous 1000px est regroupée EN FIN DE FICHIER
   (voir "format étroit") : à spécificité égale, c'est la dernière
   déclaration qui gagne. */

/* ================= la scène ================= */
.map-stage{
  position:relative;overflow:hidden;
  /* fond d'espace profond, visible seulement le temps du chargement des
     images : les vues 1 et 2 couvrent désormais tout le cadre. */
  background:
    radial-gradient(circle at 22% 30%, rgba(45,212,191,.05), transparent 55%),
    radial-gradient(circle at 78% 72%, rgba(167,139,250,.045), transparent 55%),
    linear-gradient(180deg, #070B12 0%, #0A0F16 55%, #060A10 100%);
  /* intensités d'assombrissement, réglables sans toucher aux images */
  --gal-bright:.55; --sys-bright:.60; --gal-veil:.55;
  --pv-veil:.85;    --pv-globe-bright:.55;
}
/* niveau 3 : le fond EST le champ d'étoiles du jeu (canvas #starfield,
   z-index 0, visible au travers des écrans). La scène s'efface donc
   complètement, au lieu de poser une image de planète par-dessus. */
.map-stage.lvl-planet{background:transparent;}

/* ---------- niveaux 1 et 2 : le cadre et son plan ----------
   Le cadre occupe toute la scène et masque ce qui dépasse ; le plan,
   dimensionné en pixels par le JS, est plus grand que lui et se déplace
   dedans. `transform-origin` en haut à gauche : c'est ce qui rend le
   calcul de cadrage trivial (translate puis scale, dans cet ordre). */
.gal-frame{
  position:absolute;inset:0;overflow:hidden;
  cursor:grab;touch-action:none;
}
.gal-frame.dragging{cursor:grabbing;}
.gal-frame[hidden]{display:none;}
.gal-plane{
  position:absolute;left:0;top:0;transform-origin:0 0;will-change:transform;
}
/* la spirale, DANS le plan : les nœuds sont posés sur l'image, elle doit
   donc zoomer et se déplacer avec eux. Le plan ayant exactement la
   taille de couverture, `100% 100%` respecte le ratio de l'image. */
.gal-bg{
  position:absolute;inset:0;
  background-image:url('../assets/map/galaxy.webp');
  background-repeat:no-repeat;background-size:100% 100%;background-position:center;
  /* v0.68.0 : assombrissement pondéré par --bg-veil (css/01-tokens.css) */
  filter:brightness(calc(1 - (1 - var(--gal-bright)) * var(--bg-veil, 1))) saturate(.85);
}
/* v0.73.0 : les écrans inactifs sont transparents, pas retirés de
   l'affichage : sans ce garde, les deux fonds de la Carte (14,6 Mo et 4 Mo
   décodés) partaient dès le boot. Ils attendent la première ouverture
   de la Carte (.seen, posée par AG.go, js/03-nav.js). */
.screen:not(.seen) .gal-bg, .screen:not(.seen) .gal-back{background-image:none;}
/* le champ d'étoiles de la vue 2, FIXÉ AU CADRE : le plan y est 34 fois
   plus grand que l'écran, aucune image ne peut le couvrir sans être
   répétée, et une image répétée montre ses coutures. Il est légèrement
   agrandi et décalé au glissement (parallaxe, js/10c-map-camera.js), ce
   qui donne le mouvement sans jamais découvrir un bord. */
.gal-back{
  position:absolute;inset:0;display:none;
  background-image:url('../assets/map/system.jpg');
  background-repeat:no-repeat;background-size:cover;background-position:center;
  filter:brightness(calc(1 - (1 - var(--sys-bright)) * var(--bg-veil, 1))) saturate(.8);
  transform:scale(1.25);transform-origin:50% 50%;will-change:transform;
}
.gal-frame.lvl-system .gal-back{display:block;}
.gal-frame.lvl-system .gal-bg{display:none;}
/* le voile vit dans le plan : il couvre donc la spirale en vue 1 et,
   comme le plan est plus grand que le cadre, le champ d'étoiles en
   vue 2. Un seul calque pour les deux. */
.gal-veil{
  position:absolute;inset:0;pointer-events:none;
  background:#070C16;opacity:calc(var(--gal-veil) * var(--bg-veil, 1));
}

.gal-nodes, .pv-nodes{position:absolute;inset:0;}

/* ================= un nœud de carte (système, planète, secteur) =================
   Même squelette pour les trois vues : un point, un badge optionnel, un
   libellé. Une seule famille de règles à maintenir, et un joueur
   n'apprend qu'un seul langage visuel.
   `--mz` est la contre-échelle du zoom, posée sur le plan : sans elle,
   zoomer grossirait les points au lieu d'écarter la carte. */
.mnode{
  position:absolute;transform:translate(-50%,-50%) scale(var(--mz,1));
  display:flex;flex-direction:column;align-items:center;gap:3px;
  background:none;border:none;padding:0;cursor:pointer;outline:none;
  color:var(--nc, var(--cyan));
}
.mnode .mn-dot{
  width:13px;height:13px;border-radius:50%;
  border:2px solid var(--nc);background:transparent;
  box-shadow:0 0 10px -1px var(--nc), 0 0 0 5px rgba(0,0,0,.35);
  transition:transform .16s cubic-bezier(.2,.8,.2,1), box-shadow .16s;
}
/* "plein" = occupé, "contour" = relevé mais libre, "pointillé gris" =
   jamais relevé. Les trois seuls états des vues 1 et 2 (demande
   explicite) ; l'ambre et le rose ne servent plus qu'en vue 3. */
.mnode.s-colonise .mn-dot{background:var(--nc);}
.mnode.s-anomalie .mn-dot,
.mnode.s-xeno     .mn-dot{background:color-mix(in srgb, var(--nc) 45%, transparent);}
/* Brouillard (v0.56.4) : anneau pointillé clair et badge lumineux.
   Le gris est passé à #9AA7B5 côté JS (AG.MAP_STATE_COLOR) ; ici, on
   remonte l'opacité de .75 à .88 et on rend au point son halo sombre,
   qui le détache du fond. Un système jamais scanné est ce qu'un joueur
   cherche à repérer : il doit se voir, pas se deviner. */
.mnode.s-fog      .mn-dot,
.mnode.s-unscanned .mn-dot{
  border-style:dashed;opacity:.88;
  box-shadow:0 0 0 4px rgba(0,0,0,.42);
}
.mnode.s-fog      .mn-badge,
.mnode.s-unscanned .mn-badge{
  opacity:1;color:#C8D3DE;border-color:rgba(154,167,181,.85);
  background:rgba(10,15,22,.92);
}
.mnode:hover .mn-dot, .mnode:focus-visible .mn-dot{transform:scale(1.45);}
.mnode:focus-visible .mn-dot{box-shadow:0 0 0 2px #fff, 0 0 12px var(--nc);}
.mnode.selected .mn-dot{
  box-shadow:0 0 0 3px rgba(255,255,255,.75), 0 0 16px var(--nc);
}
/* le système d'origine : un halo permanent, pour le retrouver d'un
   coup d'oeil parmi cent points. */
.mnode.is-home .mn-dot{
  width:16px;height:16px;
  animation:mapHomePulse 3.6s ease-in-out infinite;
}
@keyframes mapHomePulse{
  0%,100%{box-shadow:0 0 10px -1px var(--nc), 0 0 0 5px rgba(0,0,0,.35);}
  50%    {box-shadow:0 0 20px 2px var(--nc), 0 0 0 8px rgba(45,212,191,.10);}
}
@media (prefers-reduced-motion: reduce){ .mnode.is-home .mn-dot{animation:none;} }

/* badge "?" d'un signal non identifié. Volontairement discret : il y en
   a 82 sur la vue galaxie, et un badge trop lourd transformait le fond
   spiralé en semis de pastilles (constaté en testant l'écran). */
.mnode .mn-badge{
  position:absolute;top:-6px;left:calc(50% + 5px);
  width:12px;height:12px;border-radius:50%;
  background:rgba(10,15,22,.85);border:1px solid color-mix(in srgb, var(--nc) 55%, transparent);
  color:var(--nc);opacity:.8;
  font-family:var(--font-mono);font-size:.5rem;font-weight:700;line-height:10px;
  text-align:center;pointer-events:none;
}
.mnode:hover .mn-badge{opacity:1;}
/* v0.59.0 : le badge peut aussi porter une ICÔNE, le bouclier d'une
   colonie étrangère sous immunité. Même pastille de 12 px, l'icône y
   est ramenée à 8 px plutôt que de déborder de son cercle. */
.mnode .mn-badge svg{display:block;width:8px;height:8px;margin:1px auto;}
/* une COLONIE ÉTRANGÈRE garde la couleur d'un secteur occupé (aucune
   couleur nouvelle, demande explicite) : ce qui la signale, c'est son
   libellé, qui porte le nom du propriétaire et reste lisible en
   permanence au lieu de s'effacer comme les autres. */
.mnode.foreign .mn-label{color:rgba(230,237,245,.92);}
.mnode.foreign .mn-dot{box-shadow:0 0 10px -2px var(--nc), inset 0 0 0 2px rgba(8,13,22,.85);}
.mnode .mn-label{
  font-family:var(--font-mono);font-size:.62rem;letter-spacing:.02em;
  color:rgba(198,214,235,.80);white-space:nowrap;pointer-events:none;
  text-shadow:0 1px 3px #000, 0 0 6px #000;transition:color .16s;
}
/* sous-libellé : en vue 2, le badge "[N] signaux". MONOCHROME par
   choix (demande explicite) : il dit combien, jamais de quelle nature,
   ce qui reste l'affaire de la vue 3. */
.mnode .mn-sub{
  font-family:var(--font-mono);font-size:.55rem;color:rgba(159,178,204,.62);
  white-space:nowrap;pointer-events:none;text-shadow:0 1px 3px #000;
  border:1px solid rgba(159,178,204,.22);border-radius:999px;padding:0 5px;
  background:rgba(8,13,22,.55);
}
.mnode:hover .mn-label, .mnode.selected .mn-label{color:#fff;}
.mnode:hover .mn-sub{color:rgba(230,237,245,.9);border-color:rgba(159,178,204,.45);}
/* les libellés de la vue 2 sont permanents (demande explicite) mais
   discrets : à zoom 1, un système occupe la vue, ils ne se marchent pas
   dessus. */
.mnode.planet .mn-label{font-size:.58rem;color:rgba(198,214,235,.70);}

/* ================= vue 2 : les zones de la grille =================
   Une zone = un système, un cadre fin et son nom. Le trait et le
   libellé sont contre-échelonnés par `--mz` (= 1/zoom, posé sur le
   plan) : ils gardent exactement la même épaisseur et la même taille à
   l'écran, que l'on regarde une zone ou la grille entière. Sans ça, un
   trait de 1 px devenait 3 px en zoomant et disparaissait en
   dézoomant. */
.mzone{
  position:absolute;pointer-events:none;
  border:1px solid color-mix(in srgb, var(--zc, #8CAFD7) 26%, transparent);
  border-width:calc(1px * var(--mz,1));
  border-radius:calc(10px * var(--mz,1));
}
/* une zone colonisée se repère de loin, même sans son libellé. */
.mzone.z-colonise{
  border-color:color-mix(in srgb, var(--zc) 55%, transparent);
  background:rgba(45,212,191,.045);
}
.mzone.selected{border-color:rgba(45,212,191,.44);background:rgba(45,212,191,.05);}
/* sous AG.ZONE_LABEL_ZOOM, cent libellés se chevaucheraient : seuls
   les cadres restent, et leur couleur porte l'information. */
.gal-plane.zoom-far .mz-name{display:none;}
.mz-name{
  position:absolute;left:0;top:0;transform-origin:0 0;
  transform:scale(var(--mz,1)) translate(10px, 8px);
  pointer-events:auto;cursor:pointer;
  background:rgba(8,13,22,.55);border:1px solid rgba(140,175,215,.18);
  border-radius:var(--r-sm);padding:2px 8px;
  font-family:var(--font-mono);font-size:.64rem;letter-spacing:.06em;
  color:rgba(198,214,235,.72);white-space:nowrap;
  text-shadow:0 1px 3px #000;transition:color .15s, border-color .15s;
}
.mz-name:hover, .mz-name:focus-visible{color:#fff;border-color:var(--cyan);outline:none;}
.mzone.selected .mz-name{color:var(--cyan);border-color:rgba(45,212,191,.45);}

/* ================= niveau 3 : la vue planète ================= */
.pv-layer{position:absolute;inset:0;}
.pv-layer[hidden]{display:none;}
/* vignette légère seulement : le fond est le champ d'étoiles du jeu, un
   voile opaque l'effacerait. */
.pv-veil{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(circle at 50% 50%, rgba(7,12,22,0) 38%, rgba(7,12,22,.72) 100%);
  opacity:calc(var(--pv-veil) * var(--bg-veil, 1));
}
/* le globe : le render de la planète, détouré en cercle, posé au
   centre. Sa taille est calculée par le JS sur la PLUS PETITE dimension
   de la scène, donc il reste rond sur tous les formats. Assombri d'un
   cran en v0.56.3 pour rentrer dans la charte navy. */
.pv-globe{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  border-radius:50%;
  background-repeat:no-repeat;background-position:center;background-size:cover;
  box-shadow:0 0 0 1px rgba(45,212,191,.28), 0 0 60px rgba(45,212,191,.12),
             inset 0 0 110px rgba(6,10,18,.92);
  filter:brightness(var(--pv-globe-bright)) saturate(.85);
  pointer-events:none;
}
/* les secteurs sont plus petits que les nœuds de galaxie : il y en a 50
   sur un seul globe. */
.pv-nodes .mnode.sector .mn-dot{width:11px;height:11px;border-width:2px;}
.pv-nodes .mnode.sector .mn-label{font-size:.55rem;color:rgba(198,214,235,.62);}
/* les signaux en orbite, eux, sont dans les bandes latérales : plus de
   place, donc libellé permanent et point un peu plus gros. */
.pv-nodes .mnode.signal .mn-dot{width:14px;height:14px;}
.pv-nodes .mnode .mn-sub{border:none;background:none;padding:0;}

/* ================= surcouches (fil d'Ariane, HUD, outils, légende, zoom) ================= */
.map-crumb{
  position:absolute;z-index:5;top:calc(18px*var(--scale));left:calc(18px*var(--scale));
  display:flex;align-items:center;gap:10px;
  background:var(--panel);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  padding:calc(9px*var(--scale)) calc(14px*var(--scale));
}
.map-crumb .crumb-cur{font-family:var(--font-head);font-size:.9rem;color:var(--ink-1);letter-spacing:.03em;white-space:nowrap;}
.map-crumb .crumb-hint{font-size:.72rem;color:var(--ink-3);}
/* l'aide "clic" est la première chose qu'on sacrifie quand la place
   manque : elle recouvrait la légende sur une fenêtre étroite. Le fil
   d'Ariane lui-même, qui dit OÙ l'on est, ne disparaît jamais. */
@media(max-width:1400px){.map-crumb .crumb-hint{display:none;}}
.map-crumb .crumb-sep{color:var(--ink-3);}
.map-crumb .crumb-link{
  background:none;border:none;padding:0;cursor:pointer;
  font-family:var(--font-head);font-size:.9rem;color:var(--cyan);letter-spacing:.03em;
  border-bottom:1px solid transparent;transition:.15s;
}
.map-crumb .crumb-link:hover{border-bottom-color:var(--cyan);}

/* HUD de la vue planète, posé JUSTE SOUS le fil d'Ariane, à gauche :
   centré en haut il chevauchait la légende dès qu'une fenêtre était un
   peu étroite. C'est aussi la zone que le semis des signaux exclut. */
.map-planet-hud{
  position:absolute;z-index:5;
  top:calc(72px*var(--scale));left:calc(18px*var(--scale));
  display:flex;align-items:baseline;gap:10px;white-space:nowrap;
  background:var(--panel);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  padding:calc(9px*var(--scale)) calc(16px*var(--scale));
}
.map-planet-hud .pvh-name{font-family:var(--font-head);font-size:.92rem;color:var(--ink-1);letter-spacing:.03em;}
.map-planet-hud .pvh-sep{color:var(--line-strong);}
.map-planet-hud .pvh-num{font-family:var(--font-mono);font-size:.74rem;color:var(--ink-3);}
.map-planet-hud .pvh-own{font-family:var(--font-mono);font-size:.74rem;color:var(--cyan);}
/* `display:flex` ci-dessus l'emporterait sur le display:none que le
   navigateur applique à [hidden] : sans cette règle, le HUD restait
   affiché après un retour à la galaxie. */
.map-planet-hud[hidden]{display:none;}

.map-toolbar{
  position:absolute;z-index:5;bottom:calc(var(--nav-gap) + 14px);left:calc(18px*var(--scale));
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
}
.map-tool{
  background:var(--panel);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:var(--r-sm);
  color:var(--ink-2);font-family:var(--font-head);font-size:.78rem;letter-spacing:.03em;
  padding:calc(8px*var(--scale)) calc(13px*var(--scale));cursor:pointer;transition:.15s;
}
.map-tool:hover{color:var(--cyan);border-color:var(--cyan);background:rgba(45,212,191,.10);}
.map-tool[disabled]{opacity:.45;cursor:not-allowed;}
.map-tool[disabled]:hover{color:var(--ink-2);border-color:var(--line-strong);background:var(--panel);}

/* barre de zoom : deux boutons et le pourcentage, entièrement dessinés
   (aucun contrôle navigateur brut, charte CLAUDE.md). Posée en bas à
   droite de la scène, à l'opposé de la barre d'outils. */
.map-zoom{
  position:absolute;z-index:5;bottom:calc(var(--nav-gap) + 14px);right:calc(18px*var(--scale));
  display:flex;align-items:center;gap:2px;
  background:var(--panel);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:var(--r-sm);
  padding:calc(3px*var(--scale));
}
.map-zoom[hidden]{display:none;}
.mz-btn{
  width:calc(26px*var(--scale));height:calc(26px*var(--scale));
  display:flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid transparent;border-radius:var(--r-sm);
  color:var(--ink-2);font-family:var(--font-mono);font-size:.95rem;line-height:1;
  cursor:pointer;transition:.15s;
}
.mz-btn:hover{color:var(--cyan);border-color:var(--cyan);background:rgba(45,212,191,.10);}
.mz-btn[disabled]{opacity:.35;cursor:not-allowed;}
.mz-btn[disabled]:hover{color:var(--ink-2);border-color:transparent;background:transparent;}
.mz-pct{
  min-width:calc(46px*var(--scale));text-align:center;
  font-family:var(--font-mono);font-size:.7rem;color:var(--ink-3);
}

.map-legend{
  position:absolute;z-index:5;top:calc(18px*var(--scale));right:calc(18px*var(--scale));
  display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end;
  background:var(--panel);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line-strong);border-radius:var(--r-md);
  padding:calc(7px*var(--scale)) calc(9px*var(--scale));max-width:calc(420px*var(--scale));
}
/* case à cocher entièrement dessinée (règle "zéro contrôle natif"). */
.leg-item{
  display:flex;align-items:center;gap:7px;cursor:pointer;transition:.15s;
  background:transparent;border:1px solid transparent;border-radius:var(--r-sm);
  padding:calc(4px*var(--scale)) calc(8px*var(--scale));
  font-family:var(--font-mono);font-size:.7rem;color:var(--ink-2);
}
.leg-item:hover{border-color:var(--line-strong);background:var(--panel-soft);color:var(--ink-1);}
.leg-item .leg-box{
  width:13px;height:13px;flex:none;border-radius:4px;
  border:1px solid var(--lc);background:var(--lc);position:relative;transition:.15s;
}
.leg-item .leg-box::after{
  content:'';position:absolute;left:3.5px;top:.5px;width:4px;height:8px;
  border:solid #0A0F16;border-width:0 2px 2px 0;transform:rotate(42deg);
}
.leg-item i{width:8px;height:8px;border-radius:50%;background:var(--lc);flex:none;}
.leg-item.off{color:var(--ink-3);opacity:.6;}
.leg-item.off .leg-box{background:transparent;}
.leg-item.off .leg-box::after{display:none;}
.leg-item.off i{opacity:.35;}

/* ================= panneau droit ================= */
.map-side{
  position:relative;z-index:4;background:var(--panel-solid);border-left:1px solid var(--line);
  padding:calc(16px*var(--scale));overflow-y:auto;
  display:flex;flex-direction:column;gap:calc(12px*var(--scale));
  padding-bottom:var(--nav-gap);
}
.map-side h3{margin:0 0 2px;font-family:var(--font-head);font-size:.9rem;text-transform:uppercase;letter-spacing:.06em;}
.map-side p.hint{margin:0 0 10px;font-size:.75rem;color:var(--ink-3);}

.map-search{
  display:flex;align-items:center;gap:8px;
  background:var(--hull-2);border:1px solid var(--line-strong);border-radius:var(--r-sm);
  padding:calc(7px*var(--scale)) calc(10px*var(--scale));transition:.15s;
}
.map-search:focus-within{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(45,212,191,.12);}
.map-search .ms-ic{display:flex;color:var(--ink-3);}
.map-search .ms-ic svg{width:15px;height:15px;}
.map-search input{
  flex:1;min-width:0;background:transparent;border:none;outline:none;
  color:var(--ink-1);font-family:var(--font-mono);font-size:.78rem;
}
.map-search input::placeholder{color:var(--ink-3);}
.map-search .ms-clear{
  background:none;border:none;color:var(--ink-3);cursor:pointer;font-size:1rem;line-height:1;
  padding:0 2px;transition:.15s;visibility:hidden;
}
.map-search .ms-clear:hover{color:var(--rose);}

/* ---------- mission de carte en cours (phase 2a) ----------
   Un bandeau au-dessus du détail : l'action, le vaisseau parti, la
   cible en coordonnée complète, et le temps restant. Même vocabulaire
   visuel que les autres files du jeu (barre + minuteur). */
.map-mission{
  background:var(--panel-soft);border:1px solid var(--line);
  border-left:3px solid var(--cyan);border-radius:var(--r-md);
  padding:calc(11px*var(--scale)) calc(12px*var(--scale));
}
.map-mission .mm-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:8px;
  font-family:var(--font-head);font-size:.82rem;color:var(--ink-1);
}
.map-mission .mm-head span{font-family:var(--font-mono);font-size:.62rem;color:var(--ink-3);}
.map-mission .mm-target{font-family:var(--font-mono);font-size:.66rem;color:var(--cyan);margin:2px 0 8px;}
.map-mission .bar{height:4px;background:var(--hull-2);border-radius:3px;overflow:hidden;}
.map-mission .bar i{display:block;height:100%;width:0%;background:var(--cyan);transition:width .6s linear;}
.map-mission .mm-time{margin-top:6px;font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);}

/* ---------- journal des relevés ----------
   Les derniers rapports de scan et de colonisation, sous la liste. */
.map-report{
  display:flex;align-items:flex-start;gap:9px;
  padding:calc(8px*var(--scale)) calc(10px*var(--scale));
  border-radius:var(--r-md);border:1px solid var(--line);background:var(--panel-soft);
  margin-bottom:7px;
}
.map-report .mr-dot{width:7px;height:7px;border-radius:50%;flex:none;margin-top:5px;background:var(--cyan);}
.map-report .mr-txt{font-size:.74rem;color:var(--ink-2);line-height:1.4;}
.map-report .mr-when{font-size:.62rem;color:var(--ink-3);margin-top:2px;}

/* coût et durée portés par un bouton d'action de la carte */
.md-actions .act-meta{
  display:block;font-family:var(--font-mono);font-size:.6rem;
  color:var(--ink-3);font-weight:400;letter-spacing:0;
}
.md-actions .btn.primary .act-meta{color:rgba(3,17,15,.65);}

/* ---------- bloc détail ---------- */
.map-detail{
  background:var(--panel-soft);border:1px solid var(--line);
  border-top:3px solid var(--dc, var(--cyan));border-radius:var(--r-md);
  padding:calc(14px*var(--scale));
  animation:mapDetailIn .28s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes mapDetailIn{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:none;}}
@media (prefers-reduced-motion: reduce){ .map-detail{animation:none;} }
.map-detail.empty{
  border-top-color:var(--line);color:var(--ink-3);font-size:.78rem;text-align:center;
  padding:calc(22px*var(--scale)) calc(14px*var(--scale));
}
.md-head{display:flex;align-items:flex-start;gap:10px;margin-bottom:8px;}
.md-dot{
  width:12px;height:12px;border-radius:50%;flex:none;margin-top:4px;
  background:var(--dc, var(--cyan));box-shadow:0 0 14px var(--dc, var(--cyan));
}
.md-title{font-family:var(--font-head);font-size:1rem;color:var(--ink-1);letter-spacing:.02em;}
.md-tag{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);text-transform:uppercase;letter-spacing:.08em;}
.md-tag.mono{text-transform:none;letter-spacing:.04em;}
.md-desc{margin:0 0 10px;font-size:.78rem;color:var(--ink-2);line-height:1.5;}
/* une COORDONNÉE s'écrit toujours en monospace, dans le détail comme
   sur les cartes de la liste : c'est ce qui la distingue d'un nom. */
.map-detail .v.mono{font-family:var(--font-mono);font-size:.74rem;}
.md-actions{display:flex;flex-direction:column;gap:7px;margin-top:12px;}
.md-actions .soon{
  font-family:var(--font-mono);font-size:.6rem;color:var(--amber);
  border:1px solid rgba(245,158,11,.4);border-radius:6px;padding:1px 5px;margin-left:6px;
}
/* note explicative quand un nœud n'offre aucune action : on dit
   pourquoi, on ne laisse jamais un bloc d'actions vide. */
.md-note{
  margin:12px 0 0;padding:9px 11px;font-size:.74rem;line-height:1.5;color:var(--ink-3);
  background:var(--hull-2);border:1px solid var(--line);border-radius:var(--r-sm);
}

/* raid PvE (bloc existant depuis v0.26.0, réhabillé pour le panneau droit) */
.md-raid{margin-top:14px;padding-top:12px;border-top:1px dashed rgba(255,255,255,.08);}
.md-raid-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:10px;
  font-family:var(--font-head);font-size:.86rem;color:var(--ink-1);
}
.md-raid-head span{font-family:var(--font-mono);font-size:.64rem;color:var(--ink-3);}
.md-raid .pill-tabs{margin-bottom:8px;}

/* ---------- cartes de la liste (systèmes, planètes, secteurs) ---------- */
#map-sys-list{display:flex;flex-direction:column;gap:7px;}
.sys-card{
  display:flex;align-items:flex-start;gap:10px;cursor:pointer;transition:.15s;
  padding:calc(9px*var(--scale)) calc(11px*var(--scale));
  border-radius:var(--r-md);border:1px solid var(--line);background:var(--panel-soft);
  border-left:3px solid var(--sc, var(--ink-3));
}
.sys-card:hover{border-color:var(--line-strong);background:var(--hull-2);transform:translateX(2px);}
.sys-card.selected{border-color:var(--sc);background:rgba(45,212,191,.06);}
.sys-card .sys-dot{width:9px;height:9px;border-radius:50%;flex:none;margin-top:5px;background:var(--sc);}
.sys-card .sys-main{min-width:0;flex:1;}
.sys-card .sys-nm{font-family:var(--font-head);font-size:.86rem;color:var(--ink-1);}
.sys-card .sys-coord{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);}
.sys-card .sys-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:5px;}
.sys-chip{
  font-family:var(--font-mono);font-size:.62rem;color:var(--ink-3);
  border:1px solid var(--line);border-radius:999px;padding:1px 7px;white-space:nowrap;
}
.sys-chip.st{color:var(--sc);border-color:var(--sc);opacity:.85;}
.sys-chip.d-low{color:var(--lime);border-color:rgba(74,222,128,.35);}
.sys-chip.d-moderate{color:var(--amber);border-color:rgba(245,158,11,.35);}
.sys-chip.d-high, .sys-chip.d-extreme{color:var(--rose);border-color:rgba(248,113,113,.35);}
.sys-card .sys-owner{margin-top:5px;font-size:.68rem;color:var(--ink-3);}
.map-empty{font-size:.76rem;color:var(--ink-3);text-align:center;padding:18px 8px;}

/* niveau de danger dans le bloc détail (mini-row .v) */
.map-detail .v.d-low{color:var(--lime);}
.map-detail .v.d-moderate{color:var(--amber);}
.map-detail .v.d-high, .map-detail .v.d-extreme{color:var(--rose);}

/* barre de défilement fine et sombre, thumb teal au survol
   (charte CLAUDE.md, "zéro contrôle natif"). */
.map-side::-webkit-scrollbar{width:8px;}
.map-side::-webkit-scrollbar-track{background:transparent;}
.map-side::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:8px;}
.map-side::-webkit-scrollbar-thumb:hover{background:var(--cyan);}
.map-side{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;}

/* ================= format étroit =================
   Sous 1000px, la carte et son panneau s'empilent. Le jeu vise le
   desktop (sortie Steam) : cette bascule n'est là que pour que l'écran
   reste UTILISABLE sur un format étroit, pas pour en faire une version
   mobile. À garder en DERNIER dans ce fichier, voir la note du haut. */
@media(max-width:1000px){
  .map-wrap{grid-template-columns:1fr;grid-template-rows:minmax(340px,52vh) auto;overflow-y:auto;}
  .map-side{border-left:none;border-top:1px solid var(--line);overflow:visible;}
  .map-toolbar{bottom:calc(14px*var(--scale));}
  .map-zoom{bottom:calc(14px*var(--scale));}
  /* empilées, pas côte à côte : la barre d'outils occupe déjà toute la
     largeur utile en bas de la scène, la légende se pose au-dessus. */
  .map-legend{
    top:auto;bottom:calc(60px*var(--scale));right:calc(18px*var(--scale));
    max-width:calc(100% - 36px*var(--scale));
  }
}

/* ============================================================
   PHASE 2b : route de mission, escadre, rapports détaillés
   ============================================================ */

/* ---------- route de la mission en cours ----------
   Ligne pointillée ANIMÉE entre le point de départ et la cible, plus
   une icône de flotte qui avance dessus. Le calque est posé DANS le
   plan (vues 1 et 2) ou dans la vue planète : il suit donc le zoom et
   le déplacement sans un seul recalcul en JS. `vector-effect:
   non-scaling-stroke` (posé sur la ligne en HTML) garde l'épaisseur du
   trait et le pas des pointillés constants à l'écran, malgré la
   déformation du viewBox et le zoom de la caméra. */
.map-route{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;z-index:3;overflow:visible;
}
/* Épaisseur et halo calés en regardant l'écran : à 1,6 px sans halo, le
   trait se perdait dans le fond de galaxie éclairci, alors que c'est
   justement l'information qu'on cherche du regard en arrivant sur la
   carte. Le halo suit la couleur du trait, donc teal ou ambre selon
   qu'on part explorer ou attaquer. */
.route-line{
  stroke:var(--cyan);stroke-width:2.2;stroke-linecap:round;
  stroke-dasharray:7 9;opacity:.92;
  filter:drop-shadow(0 0 5px rgba(45,212,191,.55));
  animation:routeDash 1.1s linear infinite;
}
.route-line.hostile{stroke:var(--amber);filter:drop-shadow(0 0 5px rgba(245,158,11,.55));}
@keyframes routeDash{to{stroke-dashoffset:-16;}}

.route-ship{
  position:absolute;z-index:6;width:22px;height:22px;margin:-11px 0 0 -11px;
  display:grid;place-items:center;pointer-events:none;
  color:#0A0F16;background:var(--cyan);border-radius:50%;
  box-shadow:0 0 14px rgba(45,212,191,.65);
  /* contre-échelle : l'icône garde sa taille quand la caméra zoome,
     exactement comme les nœuds de la carte (--mz posé par le plan). */
  transform:scale(var(--mz, 1));transform-origin:center;
  transition:left .6s linear, top .6s linear;
}
.route-ship.hostile{background:var(--amber);box-shadow:0 0 14px rgba(245,158,11,.65);}
.route-ship svg{width:13px;height:13px;}
@media (prefers-reduced-motion: reduce){
  .route-line{animation:none;}
  .route-ship{transition:none;}
}

/* ---------- bandeau de mission : variante hostile + couvre-feu ---------- */
.map-mission.hostile{border-left-color:var(--amber);}
.map-mission.hostile .bar i{background:var(--amber);}
.map-mission .mm-night{
  margin-top:7px;font-size:.7rem;line-height:1.4;color:var(--amber);
  border-left:2px solid rgba(245,158,11,.45);padding-left:8px;
}
.map-mission .mm-cancel{margin-top:9px;}
/* retard annoncé sur le bouton d'attaque, avant le clic */
.md-actions .act-meta.act-night{color:var(--amber);}

/* ---------- panneau ESCADRE ---------- */
/* v0.70.1 : bloc à en-tête de la liste des systèmes (repliable) */
.map-syslist{display:flex;flex-direction:column;gap:6px;min-height:0;}
.map-syslist .ms-list-head{
  display:flex;align-items:center;gap:8px;
  font-family:var(--font-head);font-size:.82rem;color:var(--ink-1);
  text-transform:uppercase;letter-spacing:.06em;
}
.map-squad{
  background:var(--panel-soft);border:1px solid var(--line);border-radius:var(--r-md);
  padding:calc(11px*var(--scale)) calc(12px*var(--scale));
}
.map-squad .sq-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:9px;
  font-family:var(--font-head);font-size:.82rem;color:var(--ink-1);
  text-transform:uppercase;letter-spacing:.06em;
}
.map-squad .sq-head span{
  font-family:var(--font-mono);font-size:.64rem;color:var(--cyan);
  text-transform:none;letter-spacing:.02em;
}
.map-squad .sq-list{display:flex;flex-direction:column;gap:5px;max-height:200px;overflow-y:auto;}
.sq-row{
  display:flex;align-items:center;gap:9px;cursor:pointer;transition:.15s;
  padding:calc(6px*var(--scale)) calc(8px*var(--scale));
  border:1px solid transparent;border-radius:var(--r-sm);
}
.sq-row:hover{background:var(--hull-2);border-color:var(--line-strong);}
.sq-row.on{border-color:rgba(45,212,191,.35);background:rgba(45,212,191,.06);}
.sq-row.locked{opacity:.5;cursor:not-allowed;}
.sq-row.locked:hover{background:transparent;border-color:transparent;}
.sq-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;}
.sq-nm{font-size:.78rem;color:var(--ink-1);}
.sq-sub{font-family:var(--font-mono);font-size:.62rem;color:var(--ink-3);}
.sq-sub .sq-dmg{color:var(--amber);font-weight:400;}
.sq-repair{
  flex:none;cursor:pointer;transition:.15s;
  background:transparent;border:1px solid rgba(245,158,11,.4);border-radius:6px;
  color:var(--amber);font-family:var(--font-mono);font-size:.62rem;padding:3px 8px;
}
.sq-repair:hover{background:rgba(245,158,11,.12);border-color:var(--amber);}
.sq-repair:disabled{opacity:.5;cursor:not-allowed;}
.map-squad .sq-note{margin:9px 0 0;font-size:.68rem;line-height:1.45;color:var(--ink-3);}

/* ---------- rapport détaillé au journal ---------- */
.map-report.contact{border-left:3px solid var(--cyan);}
.map-report.contact.hard{border-left-color:var(--amber);}
.map-report.contact.hard .mr-dot{background:var(--amber);}
.mr-detail{
  list-style:none;margin:7px 0 0;padding:0;
  display:flex;flex-direction:column;gap:3px;
}
.mr-detail li{
  position:relative;padding-left:11px;
  font-size:.68rem;line-height:1.45;color:var(--ink-3);
}
.mr-detail li::before{
  content:'';position:absolute;left:0;top:7px;
  width:4px;height:1px;background:var(--line-strong);
}
