/* sf-regions-v2.css — habillage du PLATEAU À CHEMINS (§6). Va avec sf-regions-v2.js.
 *
 * POURQUOI UNE FEUILLE SÉPARÉE et non `sf-styles.css` : le golden d'extraction du LOT 1 interdit
 * délibérément d'AJOUTER, de retirer ou de déplacer une règle dans `sf-styles.css` — seul le contenu
 * d'une déclaration existante peut changer (`tools/test/lot1-extraction-golden.cjs`). Cette garde vaut
 * mieux qu'un assouplissement de confort : la région garde donc son style avec ses données et sa logique,
 * et reste supprimable d'un bloc.
 *
 * CE QUE CES RÈGLES SERVENT — la lisibilité du choix, demandée après le premier essai manette en main :
 * un embranchement dont on ne sait rien n'est pas un choix mais un tirage au sort. Deux objets :
 *   · `.orb-prize`  — « il y a une récompense ici », visible AVANT d'y aller, même verrouillé ;
 *   · `.orb-branch` — le panneau indicateur d'une voie : ce qu'elle rapporte, ce qu'elle coûte.
 */

/* ---- Carte à caméra mobile ---------------------------------------------------------------
   Le cadre reste à la taille de l'écran ; le plateau fait 120 % en largeur et 165 % en hauteur. Le
   décor reste en `cover` (recadré, jamais étiré). Le joueur peut le faire glisser, tandis que
   `renderMap()` recentre la caméra sur le front jouable après chaque avancée. À 165 %, les huit rangées
   disposent d'environ 90 px au lieu de 60 : noms, récompenses et panneaux cessent d'être compactés. */
.map-stage.graph-journey{
  overflow:auto;
  overscroll-behavior:contain;
  touch-action:pan-x pan-y;
  scroll-behavior:smooth;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.map-stage.graph-journey::-webkit-scrollbar{ width:0; height:0; }
/* Le voile de `.map-stage` ne doit pas défiler comme un faux élément du canevas. Le même voile vit
   directement sur le plateau agrandi. */
.map-stage.graph-journey::after{ display:none; }
.map-journey{
  position:relative;
  width:120%;
  height:165%;
  min-width:120%;
  min-height:165%;
  overflow:visible;
  background-size:cover;
  background-position:center;
}
.map-journey::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  background:radial-gradient(130% 90% at 50% 0%,transparent 62%,rgba(0,0,0,.42));
}
/* Le chemin n'apparaît qu'à portée du joueur. L'animation reste discrète : c'est une découverte, pas
   un changement d'écran. Les nœuds eux-mêmes sont absents du DOM tant qu'ils restent dans la brume. */
.map-journey .orb{ animation:map-node-reveal .28s ease both; }
.map-journey .map-trail line{ animation:map-path-reveal .35s ease both; }
@keyframes map-node-reveal{ from{ opacity:0; filter:blur(3px); } to{ opacity:1; filter:none; } }
@keyframes map-path-reveal{ from{ opacity:0; } to{ opacity:1; } }

/* Pastille de récompense. `order:-1` la place AU-DESSUS de la bulle (l'orbe est un flex column). */
.orb-prize{
  order:-1; margin-bottom:-2px;
  font-family:var(--display); font-weight:800; font-size:9.5px; letter-spacing:.3px;
  color:#0d0a04; background:linear-gradient(180deg,#ffe9a8,#d9a038);
  padding:2px 8px; border-radius:8px; border:1px solid #fff3c4;
  box-shadow:0 2px 8px rgba(217,160,56,.45); white-space:nowrap;
}
/* Une fois obtenue, elle cesse d'appeler : vert calme, plus d'ombre portée. */
.orb-prize.got{
  color:#eaf7ee; background:linear-gradient(180deg,#3f9e6a,#1f6f43);
  border-color:#8ef0ab; box-shadow:none;
}
/* Verrouillée, elle reste lisible : c'est justement là qu'elle sert à décider. */
.orb.locked .orb-prize{ opacity:.72; }

/* Les noms de lieux sont plus longs que les noms d'ennemis (« Stèle de maîtrise » contre « Suie »), et
   `.orb-label` est en `white-space:nowrap` dans la feuille figée par le golden du LOT 1 — donc un nom long
   sortait de la carte et se faisait couper au bord (constaté sur la capture du 2026-07-27). On autorise le
   retour à la ligne pour les seuls nœuds à récompense, sans toucher la feuille figée.
   `.orb-prize + .orb-label` : la pastille précède le nom dans le DOM (elle est remontée visuellement par
   `order:-1`), donc le sélecteur d'adjacence les relie sans avoir besoin d'une classe de plus. */
.orb-prize + .orb-label{
  white-space:normal; max-width:124px; line-height:1.15; text-align:center;
}

/* Panneau indicateur de voie, sous le nom du nœud d'entrée. */
.orb-branch{
  display:flex; flex-direction:column; align-items:center; gap:1px;
  max-width:132px; text-align:center;
  background:rgba(6,10,22,.82); border:1px solid #33436b; border-radius:9px;
  padding:4px 7px; margin-top:-1px;
}
.orb-branch b{ font-family:var(--display); font-weight:800; font-size:9.5px; color:#e8ecf7; letter-spacing:.2px; }
.orb-branch i{ font-style:normal; font-size:9px; color:#ffe9a8; line-height:1.25; }   /* le gain */
.orb-branch u{ text-decoration:none; font-size:8.5px; color:#9fb0d6; }               /* le risque */
/* Voie à difficulté relevée : le danger s'annonce en rouge, pas en petits caractères. */
.orb-branch.risky{ border-color:#7a3f45; background:rgba(28,10,14,.85); }
.orb-branch.risky u{ color:#ff9aa5; }

/* ---- « un gain devenu accessible doit se voir » ----------------------------------------------
   Deux dispositifs distincts et volontairement redondants : le BANDEAU marque l'instant du déblocage,
   la PULSATION dure tant que le gain n'est pas pris. Le premier se rate (on regarde ailleurs, on
   enchaîne) ; le second attend. */

/* La pastille pulse tant que la récompense est accessible et non réclamée. */
@keyframes pu-pulse{
  0%,100%{ transform:scale(1);   box-shadow:0 2px 8px rgba(217,160,56,.45); }
  50%    { transform:scale(1.09); box-shadow:0 0 16px 4px rgba(255,233,168,.85); }
}
.orb-prize.ready{ animation:pu-pulse 1.5s ease-in-out infinite; }

/* Bandeau de fin de combat : « ce lieu est maintenant accessible ». Ne bloque pas le jeu — il s'efface
   seul, et une touche l'écarte. `pointer-events` n'est actif que pendant l'affichage. */
#prizeUnlock{
  position:fixed; inset:0; z-index:2147482000; display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; transition:opacity .22s ease;
  background:radial-gradient(circle at 50% 45%, rgba(8,6,2,.62), rgba(4,3,8,.18) 60%, transparent 78%);
}
#prizeUnlock.show{ opacity:1; pointer-events:auto; }
#prizeUnlock .pu-card{
  display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:16px 26px 18px; border-radius:16px; text-align:center; max-width:78vw;
  background:linear-gradient(180deg, rgba(28,22,8,.97), rgba(12,9,4,.97));
  border:1px solid #d9a038; box-shadow:0 10px 40px rgba(217,160,56,.35), inset 0 1px 0 rgba(255,243,196,.35);
  transform:translateY(10px) scale(.94); opacity:0;
}
#prizeUnlock.show .pu-card{ animation:pu-in .52s cubic-bezier(.2,1.3,.4,1) forwards; }
@keyframes pu-in{ to{ transform:translateY(0) scale(1); opacity:1; } }
#prizeUnlock .pu-ico{ font-size:40px; line-height:1; filter:drop-shadow(0 3px 10px rgba(255,233,168,.6)); }
#prizeUnlock.show .pu-ico{ animation:pu-ico .9s ease .18s both; }
@keyframes pu-ico{ 0%{transform:scale(.4) rotate(-14deg);opacity:0} 60%{transform:scale(1.18) rotate(4deg)} 100%{transform:scale(1) rotate(0);opacity:1} }
#prizeUnlock .pu-kicker{
  font-family:var(--display); font-weight:800; font-size:10px; letter-spacing:2.4px; text-transform:uppercase;
  color:#ffe9a8; margin-top:4px;
}
#prizeUnlock .pu-name{ font-family:var(--display); font-weight:800; font-size:19px; color:#fff8e4; }
#prizeUnlock .pu-sub{ font-size:11.5px; color:#cbb98e; line-height:1.35; margin-top:3px; }

/* Respect du réglage système : on garde l'information, on retire le mouvement. */
@media (prefers-reduced-motion:reduce){
  .map-stage.graph-journey{ scroll-behavior:auto; }
  .map-journey .orb,
  .map-journey .map-trail line{ animation:none; }
  .orb-prize.ready{ animation:none; box-shadow:0 0 12px 3px rgba(255,233,168,.8); }
  #prizeUnlock.show .pu-card,
  #prizeUnlock.show .pu-ico{ animation:none; transform:none; opacity:1; }
}

/* Écrans étroits : le panneau ne doit pas déborder ni pousser les bulles voisines. */
@media (max-width:380px){
  .orb-branch{ max-width:112px; padding:3px 5px; }
  .orb-branch b{ font-size:9px; }
  .orb-branch i{ font-size:8.5px; }
}
/* États de purification : lecture immédiate Nuit → Aube, sans modifier les nœuds. */
.map-stage.purity-nuit{filter:saturate(.68) brightness(.72)}.map-stage.purity-lune{filter:saturate(.82) brightness(.84)}.map-stage.purity-crepuscule{filter:saturate(.98) brightness(.95)}.map-stage.purity-aube{filter:saturate(1.08) brightness(1.04)}.map-stage.purity-restauree{filter:saturate(1.16) brightness(1.12)}
/* Route de campagne : les mondes se lisent comme un seul voyage, plus comme sept pages isolées. */
.campaign-route{display:none!important}.campaign-stop{position:relative;min-width:68px;flex:1 0 68px;border:0;background:transparent;color:#aab1c5;padding:0 2px 2px;font:600 9px Inter,sans-serif}.campaign-stop:disabled{opacity:.42}.cs-line{position:absolute;top:15px;left:50%;width:100%;height:3px;background:linear-gradient(90deg,var(--oc),#5e6074);opacity:.55}.campaign-stop:last-child .cs-line{display:none}.cs-orb{position:relative;z-index:1;display:grid;place-items:center;width:30px;height:30px;margin:auto;border-radius:50%;border:2px solid var(--oc);background:#111624;box-shadow:0 0 10px color-mix(in srgb,var(--oc) 60%,transparent);font-size:13px}.cs-name{display:block;margin-top:5px;white-space:nowrap;font-family:var(--display);font-size:9px}.campaign-stop small{display:block;font-size:8px;white-space:nowrap;color:#8d96ae}.campaign-stop.on{color:#fff}.campaign-stop.on .cs-orb{background:var(--oc);color:#111;transform:scale(1.15);box-shadow:0 0 16px var(--oc)}.campaign-stop.on .cs-line{opacity:1}
/* Vue globale et plateau régional : deux niveaux de zoom explicites. */
.map-atlas-return{display:none;width:100%;min-height:64px;margin:0 0 10px;padding:10px 13px;border:1px solid #dac47c80;border-radius:14px;background:linear-gradient(105deg,#2c1b42,#121426);color:#f7efd5;text-align:left;box-shadow:0 7px 18px #0005}.map-atlas-return span{float:left;margin:0 10px 0 1px;color:#ffe28b;font:900 25px/28px var(--display)}.map-atlas-return b{display:block;font:800 12px var(--display)}.map-atlas-return small{display:block;margin-top:2px;color:#bdb4ca;font-size:9px}.region-mode .map-atlas-return{display:block}.region-mode #campaignAtlas,.region-mode .plateau-caption,.region-mode .map-region-detail{display:none}.atlas-mode #mapStage,.atlas-mode .world-switch,.atlas-mode .map-intro{display:none}
/* Carte du monde : le WebP porte terrain et routes. Les calques CSS suivants ne sont qu'un repli
   si l'image est indisponible ; aucun voile ni tracé n'est posé sur l'illustration. */
#tab-map.atlas-mode{position:relative;padding:0;scrollbar-width:none;background:#117d8b}
#campaignAtlas{position:relative;width:100%;min-height:0;aspect-ratio:var(--worldmap-ratio,914 / 1426);margin:0 0 0 50%;overflow:visible;border:0;border-radius:0;background-image:var(--worldmap-art),var(--plateau-biomes),radial-gradient(circle at 50% 50%,#27324a 0,#101528 58%,#070a12 100%);background-position:center;background-size:100% 100%;box-shadow:none;transform:translateX(-50%);isolation:isolate}
#campaignAtlas:before{content:'';position:absolute;z-index:0;inset:5% 4%;border:1px solid #e9d39045;border-radius:47% 53% 45% 55% / 32% 29% 71% 68%;background:linear-gradient(165deg,#fff1 0,transparent 25%,#0004 100%);box-shadow:inset 0 0 45px #fff1,0 0 0 8px #0b10204d;clip-path:polygon(42% 0,62% 5%,82% 17%,93% 33%,87% 51%,98% 68%,80% 84%,59% 100%,36% 95%,16% 85%,5% 67%,13% 48%,4% 31%,22% 14%)}
#campaignAtlas.has-worldmap-art:before{display:none}
.atlas-mode .plateau-caption{position:absolute;z-index:7;top:8px;left:50%;width:auto;margin:0;padding:5px 10px;border:0;border-radius:0;background:transparent;color:#fff4cd;text-align:center;text-shadow:0 2px 6px #000,0 0 12px #000;transform:translateX(-50%);white-space:nowrap;pointer-events:none}.plateau-caption b{display:block;font:800 13px var(--display);letter-spacing:.5px}.plateau-caption small{display:block;margin-top:2px;color:#f2e8d5;font:9px Inter,sans-serif}.plateau-caption strong{color:#ffe48d}
.plateau-sanct{position:absolute;z-index:5;left:var(--x);top:var(--y);transform:translate(-50%,-50%);display:grid;place-items:center;width:88px;height:88px;padding:0;border:0;background:transparent;color:#fff7d1;text-align:center;overflow:visible}.ps-ring{position:absolute;left:50%;top:50%;width:78px;height:78px;border:2px solid #ffe7a1;border-radius:50%;background:transparent;box-shadow:0 0 0 2px #6b3a7a70,0 0 13px #ffd15da6,inset 0 0 10px #ffd15d55;transform:translate(-50%,-50%)}.ps-gem{position:absolute;z-index:1;left:50%;top:4px;transform:translateX(-50%);color:#ffe58c;font-size:14px;text-shadow:0 1px 4px #000}.ps-copy{position:absolute;left:50%;top:88px;transform:translateX(-50%);width:92px;padding:3px 5px;border:0;border-radius:7px;background:#17101ce6;text-shadow:0 1px 3px #000}.ps-copy b{display:block;font:800 10px var(--display)}.ps-copy small{display:block;margin-top:1px;color:#ead8aa;font:7px Inter,sans-serif}
.plateau-zone{position:absolute;z-index:4;left:var(--x);top:var(--y);transform:translate(-50%,-50%);width:58px;height:58px;padding:0;border:0;background:transparent;color:#fff;overflow:visible}.plateau-zone:not(.locked):active{transform:translate(-50%,-50%) scale(.96)}.plateau-zone.active{animation:plateau-active 2.2s ease-in-out infinite}.plateau-zone.active:after{content:'';position:absolute;left:50%;top:50%;width:34px;height:34px;border:2px solid #fff1a8;border-radius:50%;box-shadow:0 0 0 3px color-mix(in srgb,var(--oc) 65%,transparent),0 0 17px #fff0a8;transform:translate(-50%,-50%);pointer-events:none}.pz-pin{position:absolute;left:50%;top:50%;display:grid;place-items:center;width:18px;height:18px;border:2px solid color-mix(in srgb,var(--oc) 78%,#fff 22%);border-radius:50%;background:#11131de6;color:#fff2bc;box-shadow:0 2px 6px #000a,0 0 7px color-mix(in srgb,var(--oc) 65%,transparent);font-size:7px;transform:translate(-50%,-50%)}.plateau-zone.locked .pz-pin{border-color:#eee6d7;background:#161821e8;color:#ffe39a;font-size:6px}.pz-copy{position:absolute;left:50%;top:35px;transform:translateX(-50%);width:max-content;min-width:68px;max-width:86px;padding:3px 6px;border:0;border-radius:7px;background:#10131be6;color:#fff;text-align:center;text-shadow:0 1px 3px #000;box-shadow:0 2px 6px #0006}.plateau-zone.active .pz-copy{top:45px}.pz-copy b{display:block;font:800 10px var(--display);letter-spacing:.1px}.pz-copy small{display:block;margin-top:1px;color:#ffe9a2;font:800 8px/1.1 Inter,sans-serif;white-space:nowrap}.pz-progress{display:block;width:48px;height:2px;margin:3px auto 0;border-radius:4px;background:#ffffff33;overflow:hidden}.pz-progress i{display:block;height:100%;background:var(--oc)}.pz-hero{position:absolute;z-index:3;left:5px;top:2px;display:grid;place-items:center;width:34px;height:34px;border:2px solid #fff0aa;border-radius:50%;background:#241938;box-shadow:0 2px 8px #000,0 0 10px #ffe081;overflow:hidden}.pz-hero img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.map-region-detail{position:fixed;z-index:8;left:50%;bottom:calc(72px + env(safe-area-inset-bottom));display:none;width:min(calc(100% - 24px),496px);min-height:64px;padding:10px 50px 10px 13px;border:0;border-radius:12px;background:#11131bf2;color:#fff;text-align:left;box-shadow:0 8px 24px #0009;transform:translateX(-50%)}.map-region-detail.on{display:block}.map-region-detail>b{display:inline-block;margin-right:8px;color:#fff4cd;font:800 14px var(--display)}.map-region-detail>span{color:#ffe59a;font-size:13px;font-weight:850}.map-region-detail>p{margin:4px 0 0;color:#f2e8d5;font-size:11px}.map-region-detail>button{position:absolute;right:8px;top:50%;width:44px;height:44px;border:0;border-radius:50%;background:#ffffff12;color:#fff;font-size:24px;transform:translateY(-50%)}
.map-stage.world-enter .map-journey{animation:world-board-enter .42s ease both}@keyframes world-board-enter{from{opacity:.35;transform:scale(1.025);filter:brightness(1.35)}to{opacity:1;transform:none;filter:none}}@keyframes plateau-active{50%{filter:brightness(1.16);transform:translate(-50%,-50%) scale(1.045)}}
@media(max-width:380px){.plateau-zone{width:52px;height:52px}.pz-copy{top:32px;min-width:64px;max-width:80px;padding-inline:4px}.pz-copy b{font-size:9px}.plateau-sanct{width:82px;height:82px}.ps-ring{width:70px;height:70px}.ps-copy{top:82px;width:82px}.atlas-mode .plateau-caption b{font-size:12px}}
@media(prefers-reduced-motion:reduce){.plateau-zone.active,.map-stage.world-enter .map-journey{animation:none}}

/* TÂCHE 28 — trois états enfant sans seuil chiffré. Les sélecteurs sont bornés au shell
   éducatif : le plateau adulte conserve strictement ses médaillons et sa progression actuels. */
.education-shell .plateau-zone .pz-pin{width:27px;height:27px;background:var(--oc);border-color:#fff1c8;color:#fff7dc;font-size:14px;overflow:hidden}
.education-shell .plateau-zone.open .pz-pin{box-shadow:0 2px 7px #000a,0 0 12px var(--oc)}
.education-shell .plateau-zone.restored .pz-pin{filter:saturate(1.2) brightness(1.12);box-shadow:0 2px 7px #0009,0 0 17px #fff0a8}
.education-shell .plateau-zone.locked{filter:saturate(.3) brightness(.56)}
.education-shell .plateau-zone.locked .pz-pin{background:#24242b;border-color:#dfd9ce;color:#fff0bf;font-size:14px}
.education-shell .pz-boss{width:100%;height:100%;object-fit:contain;filter:brightness(0) drop-shadow(0 1px 1px #fff8)}
.education-shell .plateau-zone .pz-hero{left:-7px;top:-7px;width:30px;height:30px}
.education-shell .plateau-zone .pz-progress{display:none}
.education-shell .map-region-detail{background:#3a2c66;box-shadow:0 8px 24px #0009}
.education-shell .map-region-detail>button{background:#5b4890}

/* PASSE G (26/08) — LE GESTE UNIQUE DU CHAPITRE. « Continuer » lance l'étape en cours sans avoir à
   viser une bulle : le plateau redevient le RÉCIT du chemin, il n'est plus le seul moyen de jouer.
   Même or que le geste suivant du duel (Aube dorée) : dans tout l'écran enfant, doré = « c'est ici
   qu'on touche ». Aplat plein, jamais de translucide. */
.map-continue-host{margin:10px 0 0}
.map-continue-host[hidden]{display:none}
.atlas-mode .map-continue-host{display:none}
.map-continue{display:block;width:100%;min-height:72px;padding:12px 14px;border:0;border-radius:16px;background:linear-gradient(160deg,#ffd777,#f0a24a);color:#3a2408;text-align:left;box-shadow:0 8px 20px #0006}
.map-continue b{display:block;font:900 19px var(--display)}
.map-continue small{display:block;margin-top:3px;color:#5a3a10;font:700 11.5px Inter,sans-serif}
.map-continue:active{transform:scale(.985)}
.map-continue.done{background:#3a2c66;color:#f7efd5}
.map-continue.done small{color:#d8cdf0}
/* PASSE G — le pense-bête adulte quitte l'écran enfant. Il portait une cible de 18 px (le point
   « i », mesuré par run-child-touch-audit.sh dès que la Carte s'ouvre sur le chapitre au lieu du
   grand plateau, qui le masquait) et un texte devenu faux : « touche une bulle pour combattre »,
   alors que le geste du chapitre est maintenant « Continuer ». L'écran s'explique tout seul. */
.education-shell .map-intro{display:none}
