  /* =========================================================
     ARBRE DE TALENTS (js/92 à js/94) — boutique de sorts, améliorations,
     réagencement de la barre. Même grammaire visuelle que la boutique du
     colporteur (css/09) : carte centrée, liste scrollable, prix en pastille.
     Chargé AVANT css/14-fenetres-hauteur.css, qui reste le dernier mot sur
     les hauteurs de fenêtre.
  ========================================================= */
  /* ancré SOUS l'en-tête, comme les autres fenêtres plein écran — voir la
     note dans css/10 : à partir de inset:0, la carte des compétences passait
     derrière la barre de menu et son bouton du bas devenait inatteignable. */
  #talentShop{
    position:fixed; top:var(--hdr-h, 80px); left:0; right:0; bottom:0;
    display:none; align-items:center; justify-content:center;
    background:rgba(8,6,12,.78);
    z-index:60;
  }
  #talentShop.show{ display:flex }
  .tal-card{
    background:var(--panel);
    border:1px solid var(--accent-dim);
    border-radius:12px;
    padding:18px 20px 14px;
    width:min(720px, calc(100vw - 24px));
    /* PLAFOND RELATIF AU CONTENEUR, PAS À L'ÉCRAN (2026-09-07, retour Pixel :
       « en mobile, une fois le sort sélectionné, on n'a pas accès au bouton
       Continuer »). C'était `calc(100vh - 32px)` : la hauteur de l'écran ENTIER.
       Depuis que la fenêtre démarre sous l'en-tête, la place réellement
       disponible vaut 100vh − hauteur d'en-tête ; la carte s'autorisait donc à
       dépasser de toute cette hauteur, et c'est le pied de carte — avec le
       bouton Continuer — qui passait sous le bord. Mesuré en paysage
       812 × 375 : conteneur 305 px, carte 315 px.
       `100%` la borne à son conteneur, lequel est ancré haut ET bas ; en prime
       cela règle le piège du 100vh sur téléphone, qui vaut la hauteur SANS la
       barre d'URL et déborde donc dès qu'elle est déployée. La liste interne
       (.tal-list, flex:1 overflow:auto) absorbe la différence en défilant, le
       pied reste visible. */
    max-height:calc(100% - 12px);
    display:flex; flex-direction:column;
    box-shadow:0 0 40px rgba(224,168,60,.15), 0 12px 40px rgba(0,0,0,.6);
    animation:pop .3s ease-out;
  }
  .tal-card h2{
    color:var(--accent); font-size:1.15rem; letter-spacing:.1em;
    text-transform:uppercase; margin-bottom:6px; text-align:center;
  }
  .tal-pts{ text-align:center; color:var(--ink); font-size:.9rem; margin-bottom:10px }
  .tal-pts b{ color:var(--accent); font-size:1.1rem }
  .tal-pts .tal-meta{ margin-left:6px }

  .tal-tabs{ display:flex; gap:6px; justify-content:center; margin-bottom:10px; flex-wrap:wrap }
  .tal-tabs button{
    background:#241d33; color:var(--ink-dim);
    border:1px solid #3a3050; border-radius:8px;
    padding:6px 12px; font-size:.82rem; cursor:pointer;
  }
  .tal-tabs button:hover{ border-color:var(--accent-dim); color:var(--ink) }
  .tal-tabs button.active{ background:var(--accent-dim); color:#1a1424; border-color:var(--accent) }

  .tal-list{ overflow:auto; flex:1; display:flex; flex-direction:column; gap:8px; padding-right:4px }
  /* ---------- Encarts « Sorts de classe » / « Sorts communs » ----------
     2026-09-03, demande Pixel : « distingue bien ceux de classe dans un
     encart dédié et les communs dans un autre, trié par coût ». Même carte
     que les lignes de sort (fond légèrement plus sombre pour se distinguer
     du panneau), le titre en tête suffit à porter la distinction — pas
     besoin de reprendre l'étiquette « classe »/« commun » sur chaque ligne. */
  .tal-group{
    display:flex; flex-direction:column; gap:7px;
    background:#1c1728; border:1px solid #2c2440; border-radius:10px;
    padding:9px;
  }
  .tal-group-h{
    color:var(--accent); font-size:.76rem; font-weight:700;
    letter-spacing:.06em; text-transform:uppercase; padding:0 2px 2px;
  }
  .tal-row{
    display:flex; align-items:flex-start; gap:10px;
    background:#221c2e; border:1px solid #33294a; border-radius:9px;
    padding:9px 11px;
  }
  .tal-row.tal-off{ opacity:.55 }
  .tal-row.tal-eq{ border-color:var(--accent-dim); background:#26203a }
  .tal-row.tal-up{ flex-wrap:wrap }
  .tal-ic{ font-size:1.4rem; width:30px; text-align:center; flex:none; line-height:1.2 }
  .tal-ic img{ width:1.4em; height:1.4em; image-rendering:pixelated; vertical-align:middle }
  .tal-txt{ flex:1; min-width:0 }
  .tal-nm{ color:var(--ink); font-size:.92rem; font-weight:600 }
  .tal-meta{ color:var(--ink-dim); font-size:.74rem; margin-top:1px }
  .tal-desc{ color:var(--ink-dim); font-size:.78rem; margin-top:3px; line-height:1.35 }

  .tal-tag{
    display:inline-block; margin-left:6px; padding:1px 6px; border-radius:6px;
    font-size:.64rem; letter-spacing:.06em; text-transform:uppercase;
    background:#3a3050; color:#c8bce0; vertical-align:middle;
  }
  .tal-tag.tal-common{ background:#2c4a3c; color:#a8e0c0 }
  .tal-tag.tal-form{ background:#4a3c22; color:#e8d0a0 }
  .tal-tag.tal-ult{ background:#5a2a3a; color:#f0b0c0 }

  .tal-buy{ display:flex; flex-direction:column; align-items:flex-end; gap:4px; flex:none }
  .tal-price{ color:var(--accent); font-size:.8rem; font-weight:600; white-space:nowrap }
  /* BOUTON ACTIONNABLE EN OR VIF, PAS EN OR TERNE (2026-09-03, retour Pixel :
     « on dirait que le bouton est grisé alors que non, c'est un peu ambigu »).
     --accent-dim (le ton terne) ne se distinguait pas assez de --disabled une
     fois posé sur fond sombre — et au TOUCHER, il n'y a pas de survol pour
     révéler la vraie couleur d'action : le bouton restait terne EN
     PERMANENCE tant qu'on ne l'avait pas déjà pressé. --accent (le même or
     vif que les CTA « acheter » ailleurs dans le jeu, ed-primary/lb-filter-
     btn.active) rend l'état actionnable non ambigu d'un coup d'œil, sans
     attendre un survol qui n'existe pas sur mobile. */
  .tal-buy button, .tal-done{
    background:var(--accent); color:#1a1424; border:none; border-radius:7px;
    padding:6px 12px; font-size:.8rem; cursor:pointer; font-weight:700;
  }
  .tal-buy button:hover:not(:disabled), .tal-done:hover{ background:#f0c060 }
  .tal-buy button:disabled{ background:#3a3050; color:#7a6e90; cursor:not-allowed; font-weight:600 }
  .tal-lock{ color:#c8a0a0; font-size:.68rem; white-space:nowrap }

  .tal-tracks{ display:flex; flex-wrap:wrap; gap:6px; width:100%; margin-top:6px }
  .tal-track{
    display:flex; align-items:center; gap:6px;
    background:#2a2340; color:var(--ink); border:1px solid #3a3050;
    border-radius:7px; padding:5px 9px; font-size:.76rem; cursor:pointer;
  }
  .tal-track:hover:not(:disabled){ border-color:var(--accent-dim) }
  .tal-track.off, .tal-track:disabled{ opacity:.5; cursor:not-allowed }
  .tal-pips{ display:inline-flex; gap:2px }
  .tal-pips i{
    width:6px; height:6px; border-radius:50%;
    background:#4a4060; display:inline-block;
  }
  .tal-pips i.on{ background:var(--accent) }

  .tal-sub{ color:var(--ink-dim); font-size:.8rem; margin-bottom:2px }
  /* ---------- En-tête de la barre : compte bien visible ----------
     2026-09-03, demande Pixel : « met bien en évidence le nombre de sorts,
     genre 5/8 ou 9/9 ». Grosse pastille façon compteur, plutôt qu'un chiffre
     noyé dans une phrase. */
  .tal-barhead{
    display:flex; align-items:center; gap:12px;
    background:#221c2e; border:1px solid #33294a; border-radius:9px;
    padding:9px 11px; margin-bottom:2px;
  }
  .tal-barcount{
    flex:none; min-width:52px; text-align:center;
    font-size:1.5rem; font-weight:800; color:var(--accent);
    background:#1a1626; border:1px solid var(--accent-dim); border-radius:8px;
    padding:4px 8px; line-height:1;
  }
  .tal-barcount span{ font-size:.85rem; font-weight:600; color:var(--ink-dim) }
  .tal-barcount.full{ color:#f08a6a; border-color:#8a4444 }
  /* ---------- Fiche d'amélioration au survol / appui long ----------
     2026-09-03, demande Pixel : signaler qu'il y a quelque chose à voir avant
     même le geste — un petit repère discret sur la ligne, pas une étiquette
     de plus qui crierait aussi fort que « classe »/« commun ». */
  .tal-row.tal-has-upg{ border-left:2px solid var(--accent-dim) }
  .tal-row.tal-has-upg .tal-nm::after{
    content:" 🔧"; font-size:.7rem; opacity:.75;
  }
  .tal-empty{ color:var(--ink-dim); font-size:.85rem; text-align:center; padding:18px 0 }
  .tal-msg{ color:#e0a0a0; font-size:.8rem; text-align:center; min-height:1.1em; margin-top:4px }
  .tal-foot{ display:flex; justify-content:center; margin-top:8px }

  @media (max-width: 560px){
    .tal-card{ padding:14px 12px 10px }
    .tal-desc{ font-size:.74rem }
    .tal-row{ flex-wrap:wrap }
    .tal-buy{ flex-direction:row; align-items:center; width:100%; justify-content:flex-end }
  }

  /* ---------- Livre de sort : réserve et repères de l'arbre ---------- */
  .sb-row .sb-base{
    font-size:.6rem; letter-spacing:.06em; text-transform:uppercase;
    background:#3a3050; color:#c8bce0; border-radius:5px; padding:1px 5px; margin-left:5px;
  }
  .sb-resv-head{
    color:var(--ink-dim); font-size:.78rem; margin:10px 0 4px;
    border-top:1px solid #33294a; padding-top:8px;
  }
  .sb-resv-head i{ color:#a08cc0; font-style:normal }
  .sb-resv-empty{ color:var(--ink-dim); font-size:.76rem; padding:2px 0 4px }
  .sb-row.sb-resv{ opacity:.85; background:#1e1a2a }

  /* ---------- Fiche de classe : ce qui est acquis vs à débloquer ---------- */
  .cp-abilities .cp-locked{ opacity:.55 }

  /* ---------- Rappel : points de talent non dépensés (bouton de la boutique) ---------- */
  #shopTalents.shop-talents-alert{
    background:var(--accent); color:#1a1424;
    box-shadow:0 0 0 0 rgba(224,168,60,.55);
    animation:talPulse 2.2s ease-out infinite;
  }
  @keyframes talPulse{
    0%   { box-shadow:0 0 0 0 rgba(224,168,60,.55) }
    70%  { box-shadow:0 0 0 10px rgba(224,168,60,0) }
    100% { box-shadow:0 0 0 0 rgba(224,168,60,0) }
  }
  @media (prefers-reduced-motion: reduce){
    #shopTalents.shop-talents-alert{ animation:none }
  }

  /* =========================================================
     BARRE D'ACTION COLLANTE des fenêtres de démarrage (2026-09-03, retour
     Pixel : « le bouton fermer doit s'appeler lancer la partie et être
     toujours accessible, là il faut aller le chercher trop loin quand la
     boutique est bien remplie »).
     Les cartes de #metaShop et #mutatorPick défilent (css/14) : le bouton de
     sortie, placé en dernier, pouvait se retrouver à des dizaines d'articles
     plus bas. Il colle désormais au bas de la carte, avec un fond opaque et
     un dégradé qui montre que du contenu passe dessous.
  ========================================================= */
  .modal-actions-sticky{
    /* `bottom` NÉGATIF, égal au padding bas de la carte (24px, css/09) : avec
       bottom:0, la barre se fige au bas de la ZONE DE CONTENU et laisse voir
       défiler les articles dans les 24px de padding en dessous (mesuré :
       25 px d'articles visibles sous le bouton). Ici elle affleure vraiment le
       bord inférieur de la fenêtre. */
    position:sticky; bottom:-24px;
    display:flex; gap:10px; justify-content:center; flex-wrap:wrap;
    margin:10px -30px -24px;          /* annule le padding de la carte */
    padding:12px 30px 16px;
    background:linear-gradient(to bottom, rgba(26,20,36,0), var(--panel) 38%);
    border-radius:0 0 12px 12px;
    z-index:2;
  }
  .modal-actions-sticky button{
    background:var(--accent); color:#1a1424; border:none; border-radius:8px;
    padding:10px 20px; font-size:.92rem; font-weight:600; cursor:pointer;
    box-shadow:0 4px 14px rgba(0,0,0,.45);
  }
  .modal-actions-sticky button:hover{ filter:brightness(1.1) }
  @media (max-width: 560px){
    .modal-actions-sticky{ margin:8px -12px -14px; padding:10px 12px 14px; bottom:-14px }
    .modal-actions-sticky button{ padding:9px 14px; font-size:.85rem }
  }

  /* Tarif annoncé sur chaque carte de mutateur (js/76) : le joueur doit voir
     les deux termes du marché avant de cliquer. */
  #mutatorGrid .mut-pay{
    display:block; margin-top:6px; padding-top:5px;
    border-top:1px solid rgba(255,255,255,.10);
    color:var(--accent); font-size:.72rem; letter-spacing:.02em;
  }

  /* =========================================================
     ACHAT EN DEUX TEMPS SUR TACTILE (js/47, js/75) — 1er appui : détails
     dépliés + demande de confirmation ; 2e appui : achat.
  ========================================================= */
  .shop-btn.shop-armed{
    border-color:var(--accent);
    box-shadow:0 0 0 2px rgba(224,168,60,.35), 0 6px 18px rgba(0,0,0,.5);
    background:#2a2238;
  }
  /* le comparatif « vs équipé » se déplie comme au survol sur ordinateur */
  .shop-btn.shop-armed .shop-cmp{ max-height:220px; opacity:1; margin-top:4px }
  .shop-confirm-hint{
    display:block; margin-top:6px; padding-top:5px;
    border-top:1px solid rgba(224,168,60,.35);
    color:var(--accent); font-size:.72rem; font-weight:600; letter-spacing:.02em;
    animation:shopHintPulse 1.4s ease-in-out infinite;
  }
  @keyframes shopHintPulse{ 0%,100%{opacity:.65} 50%{opacity:1} }
  @media (prefers-reduced-motion: reduce){
    .shop-confirm-hint{ animation:none; opacity:1 }
  }

  /* ---------- Imprégnation élémentaire d'un sort (js/92, js/94) ---------- */
  .tal-elems{
    display:flex; flex-wrap:wrap; align-items:center; gap:5px;
    width:100%; margin-top:6px; padding-top:6px;
    border-top:1px dashed #3a3050;
  }
  .tal-elem{
    background:#2a2340; color:var(--ink); border:1px solid #3a3050;
    border-radius:7px; padding:4px 8px; font-size:.74rem; cursor:pointer;
  }
  .tal-elem:hover:not(:disabled){ border-color:var(--accent-dim) }
  .tal-elem.on{ background:var(--accent-dim); color:#1a1424; border-color:var(--accent); font-weight:600 }
  .tal-elem.off:not(.on){ opacity:.45; cursor:not-allowed }

  /* ---------- Achat d'un emplacement de sort supplémentaire (js/92, js/94) ---------- */
  .tal-row.tal-slotbuy{ border-style:dashed; border-color:var(--accent-dim); background:#241d33 }
  .tal-row.tal-slotbuy .tal-nm{ color:var(--accent) }

  /* ---------- Mutateurs : la famille annoncée sous le nom (js/76) ---------- */
  #mutatorGrid .mut-fam{
    display:block; margin-top:4px; color:#a08cc0; font-size:.68rem; font-style:italic;
  }
