/* Pages des serveurs de jeux — mise en forme propre a ces vues.
   Separee de style.css : la supervision et le wiki n'ont pas les memes
   besoins, et melanger les deux rendrait chaque retouche risquee. */

/* ------------------------------------------------------------- primitives */
.jx-ico { image-rendering: auto; flex: 0 0 auto; object-fit: contain; }
.jx-ico.vide { background: var(--creux); border-radius: 6px; }

.jx-puce {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px 3px 3px;
  border-radius: 100px; background: var(--creux); border: 1px solid transparent;
  cursor: pointer; font-size: 12px; font-weight: 600; color: var(--texte);
  text-align: left; font-family: var(--f); line-height: 1.2;
}
.jx-puce:hover { border-color: var(--accent); background: var(--accent-fond); }
.jx-puce.inerte { cursor: default; }
.jx-puce.inerte:hover { border-color: transparent; background: var(--creux); }
.jx-puce .n { font-variant-numeric: tabular-nums; color: var(--texte-3); font-weight: 700; }

/* Rangee flottante : la brique de toutes les barres d'outils et de tous les
   trains de pastilles. A ne pas confondre avec « .filtre » de style.css, qui
   est le style d'un CHAMP de saisie — s'en servir comme conteneur donnait une
   colonne de 180 px encadree au lieu d'une ligne. */
.jx-rang { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.jx-rang.serre { gap: 5px; }
.jx-rang.haut { align-items: flex-start; }
/* « .bouton.actif » n'existe dans style.css que sous « .onglets-media » : les
   bascules d'une rangee de jeu n'auraient sinon aucun etat visible. */
.jx-rang .bouton.actif {
  border-color: var(--accent); color: var(--accent); background: var(--accent-fond);
}

/* ------------------------------------------------------------ grille de cartes */
.jx-grille {
  display: grid; gap: 10px;
  /* `auto-fit` et NON `auto-fill` : le second cree toutes les colonnes qui
     rentrent, y compris vides. Une grille de 8 tuiles sur un ecran de 2560
     obtenait 16 colonnes, gardait ses tuiles au plancher de 130 px et laissait
     1 118 px de vide a droite. `auto-fit` efface les pistes vides et laisse les
     tuiles s'etirer. Les deux sont identiques des que les tuiles remplissent
     une rangee : la difference ne se voit que sur les grilles CLAIRSEMEES,
     donc surtout sur un grand ecran. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.jx-carte {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 8px; border-radius: 12px; background: var(--creux);
  border: 1px solid transparent; cursor: pointer; text-align: center;
  font-family: var(--f); color: var(--texte);
}
.jx-carte:hover { border-color: var(--accent); }
.jx-carte.actif { border-color: var(--accent); background: var(--accent-fond); }
.jx-carte .nom { font-size: 12.5px; font-weight: 650; line-height: 1.25; }
.jx-carte .no { font-size: 10px; color: var(--texte-3); font-variant-numeric: tabular-nums; }
.jx-carte .els { display: flex; gap: 3px; flex-wrap: wrap; justify-content: center; }

/* --------------------------------------------------------------- barres de stat */
.jx-stat { display: grid; grid-template-columns: 84px 1fr 46px; gap: 8px; align-items: center;
           font-size: 12px; margin: 3px 0; }
.jx-stat .l { color: var(--texte-3); }
.jx-stat .v { text-align: right; font-variant-numeric: tabular-nums; font-weight: 650; }
.jx-jauge { height: 7px; border-radius: 100px; background: var(--creux); overflow: hidden; }
.jx-jauge i { display: block; height: 100%; border-radius: 100px;
              background: linear-gradient(90deg, var(--accent), var(--accent-2)); }

/* ---------------------------------------------------------------------- carte */
/* La hauteur commande, pas la largeur : un carre aussi large que la page
   depasse l'ecran et oblige a faire defiler pour voir la carte entiere. Le
   plan est un carre centre, dimensionne en JS d'apres la boite. */
.jx-map {
  position: relative; width: 100%; height: min(76vh, 820px); overflow: hidden;
  border-radius: 14px; background: #06121c; border: 1px solid var(--bord);
  cursor: grab; touch-action: none;
}
.jx-map.tire { cursor: grabbing; }
.jx-map .plan { position: absolute; transform-origin: 0 0; will-change: transform; }
.jx-map .plan img, .jx-map .plan canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
.jx-map .plan img { object-fit: fill; }
.jx-outils {
  position: absolute; right: 10px; top: 10px; display: flex; flex-direction: column; gap: 6px;
  z-index: 2;
}
.jx-outils button {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--bord);
  background: rgba(10, 20, 30, .78); color: #e8f1fa; font-size: 15px; cursor: pointer;
  font-family: var(--f); line-height: 1; backdrop-filter: blur(4px);
}
.jx-outils button:hover { border-color: var(--accent); color: var(--accent); }
.jx-bulle-map {
  position: absolute; left: 10px; bottom: 10px; right: 56px; z-index: 2;
  padding: 8px 11px; border-radius: 10px; font-size: 12px; line-height: 1.45;
  background: rgba(8, 16, 24, .84); color: #dfeaf5; border: 1px solid var(--bord);
  backdrop-filter: blur(4px); pointer-events: none;
}
.jx-legende { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11.5px;
              color: var(--texte-3); margin-top: 8px; align-items: center; }
.jx-legende i { width: 9px; height: 9px; border-radius: 50%; display: inline-block;
                margin-right: 5px; vertical-align: -1px; }

/* ------------------------------------------------- echelle technologique
   Un palier par niveau de joueur : c'est la disposition du jeu lui-meme, et
   la seule que les donnees autorisent — il n'y a pas d'arborescence. */
.jx-echelle { display: flex; flex-direction: column; gap: 2px; }
.jx-palier { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 10px;
             align-items: start; padding: 7px 0; border-top: 1px solid var(--bord); }
.jx-palier:first-child { border-top: 0; }
.jx-palier .n { display: flex; flex-direction: column; align-items: flex-end;
                padding-top: 4px; line-height: 1.2; }
.jx-palier .n b { font-size: 15px; font-variant-numeric: tabular-nums; }
.jx-palier .n span { font-size: 10px; color: var(--texte-3); }
.jx-palier.verrouille { opacity: .38; }

.jx-tuile {
  display: flex; align-items: center; gap: 8px; width: 178px; box-sizing: border-box;
  padding: 6px 9px 6px 6px; border-radius: 10px; background: var(--creux);
  border: 1px solid transparent; cursor: pointer; font-family: var(--f);
  color: var(--texte); text-align: left; line-height: 1.2;
}
.jx-tuile:hover, .jx-tuile.actif { border-color: var(--accent); background: var(--accent-fond); }
.jx-tuile.ancienne { border-style: dashed; border-color: var(--bord); }
.jx-tuile.ancienne:hover, .jx-tuile.ancienne.actif { border-color: var(--accent); }
.jx-tuile.efface { opacity: .22; }
.jx-tuile .t { display: flex; flex-direction: column; min-width: 0; gap: 1px;
               line-height: 1.25; }
.jx-tuile .nom { font-size: 11.5px; font-weight: 620; overflow: hidden;
                 text-overflow: ellipsis; white-space: nowrap; }
.jx-tuile .meta { font-size: 10px; color: var(--texte-3); overflow: hidden;
                  text-overflow: ellipsis; white-space: nowrap; }

/* ------------------------------------------------------------------ divers */
.jx-deux { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
@media (max-width: 900px) { .jx-deux { grid-template-columns: 1fr; } }
.jx-chaine { list-style: none; margin: 0; padding-left: 16px; border-left: 1px solid var(--bord); }
.jx-chaine li { margin: 4px 0; }
.jx-vide { padding: 18px; text-align: center; color: var(--texte-3); font-size: 13px; }
/* Un « aucun résultat » est un message, pas une carte : posé dans une grille
   de vignettes, il se pliait dans une colonne de 112 px. */
.jx-grille > .jx-vide { grid-column: 1 / -1; }
.jx-notes { max-height: 460px; overflow: auto; padding-right: 8px; max-width: 78ch; }
.jx-notes h4 { margin: 16px 0 6px; font-size: 13.5px; color: var(--accent);
               letter-spacing: .01em; }
.jx-notes h4:first-child { margin-top: 2px; }
.jx-notes h5 { margin: 12px 0 3px; font-size: 12.5px; font-weight: 700; color: var(--texte); }
.jx-notes ul { margin: 2px 0 8px; padding-left: 18px; }
.jx-notes li { margin: 3px 0; font-size: 12.5px; line-height: 1.5; }
.jx-notes li::marker { color: var(--texte-3); }
.jx-notes p { margin: 6px 0; font-size: 12.5px; line-height: 1.55; }
.jx-notes hr { border: 0; border-top: 1px solid var(--bord); margin: 12px 0; }
.jx-notes img { max-width: 100%; border-radius: 8px; margin: 6px 0; }

/* --------------------------------------------- constructeur d'equipe de combat */
.jx-slots { display: grid; gap: 10px;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.jx-slot { display: flex; flex-direction: column; gap: 8px; padding: 10px;
           border-radius: 12px; background: var(--creux);
           border: 1px solid var(--bord); }
.jx-champs { display: flex; flex-wrap: wrap; gap: 8px 12px; }
.jx-champ { display: flex; flex-direction: column; gap: 2px; font-size: 10.5px;
            color: var(--texte-3); }
.jx-champ.ligne { flex-direction: row; align-items: center; gap: 6px;
                  align-self: flex-end; padding-bottom: 6px; }
.jx-champ .t { letter-spacing: .02em; }
.jx-bloc { border-top: 1px solid var(--bord); padding-top: 7px; }
.jx-bloc .titre { font-size: 10.5px; color: var(--texte-3); margin-bottom: 5px;
                  letter-spacing: .02em; }
/* Une attaque retenue : le contour accentue ne suffit pas quand la pastille
   porte deja une pilule d'element coloree. */
.jx-puce.choisi { background: var(--accent-fond); border-color: var(--accent);
                  box-shadow: inset 2px 0 0 var(--accent); }
.jx-coefs { display: grid; gap: 8px 16px;
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.jx-coef { display: flex; align-items: center; gap: 9px; font-size: 12px;
           padding: 4px 0; }
.jx-coef .t { flex: 0 0 auto; font-weight: 600; }
.jx-coef .n { color: var(--texte-3); font-size: 10.5px; line-height: 1.35; }
.jx-slot select.saisie, .jx-slot input.saisie { font-size: 12px; padding: 5px 8px; }

/* Le bilan de l'emplacement. Sans lui, changer un passif ne se voyait que
   dans le tableau de resultat, tout en bas d'une page longue : le chiffre
   bougeait hors ecran et on croyait que rien n'etait recalcule. */
/* Colle au bas de la fenetre tant que son emplacement est a l'ecran : c'est
   la seule facon de voir bouger le chiffre quand on regle un passif situe
   plus bas que lui. Le collant va sur l'HOTE, enfant direct de la carte :
   pose sur le bilan, son conteneur faisait sa hauteur et rien ne collait. */
.jx-bilan-hote { position: sticky; bottom: 6px; z-index: 2; }
.jx-bilan {
  margin-top: 8px; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 9%, var(--carte));
  border: 1px solid var(--accent-bord); box-shadow: var(--ombre);
  display: grid; gap: 2px 14px;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
}
.jx-bilan .l { display: flex; align-items: baseline; gap: 6px; font-size: 12px; }
.jx-bilan .l .t { flex: 1 1 auto; color: var(--texte-3); font-size: 10.5px;
                  letter-spacing: .02em; }
.jx-bilan .l b { font-variant-numeric: tabular-nums; font-weight: 700; }
.jx-bilan .l .e { font-size: 10px; font-variant-numeric: tabular-nums; }
.jx-bilan .l .e.plus { color: var(--ok); }
.jx-bilan .l .e.moins { color: var(--warn); }
.jx-bilan .jx-rang { grid-column: 1 / -1; margin-top: 4px; }

/* Le detail chiffre d'un passif ou d'une competence de partenaire, sous le
   selecteur qui le choisit. */
.jx-effets { font-size: 11.5px; line-height: 1.45; color: var(--texte-2);
             padding: 3px 0 6px 2px; display: flex; flex-direction: column; gap: 3px; }
.jx-effets .d { color: var(--texte); white-space: pre-line; }
.jx-bloc .sous { font-size: 10px; color: var(--texte-3); letter-spacing: .02em;
                 margin: 6px 0 4px; text-transform: lowercase; }
/* La provenance d'une attaque : niveau appris, ou fruit de competence. */
.jx-puce .f { font-size: 9.5px; color: var(--texte-3); font-weight: 700;
              text-transform: uppercase; letter-spacing: .03em; }
.jx-bloc details > summary { font-size: 11.5px; padding: 4px 0; }

/* Une barre de sous-onglets dans une carte : meme grammaire que les onglets
   du haut, mais sans la marge basse qui separe une page de son contenu. */
.jx-sous-onglets { flex-wrap: wrap; margin-bottom: 0; border-bottom: none; gap: 2px 4px; }
.jx-sous-onglets button { padding: 5px 10px; font-size: 12.5px; }
/* Une description de lieu tient en trois lignes dans sa cellule. */
.jx-desc-lieu { display: block; white-space: pre-line; font-size: 11.5px;
                line-height: 1.4; color: var(--texte-2); max-width: 46ch; }

/* La condition d'une compétence de partenaire : elle vaut autant que le
   chiffre qu'elle accompagne, et se lit sur la même ligne que lui. */
.jx-condition { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline;
                font-size: 11.5px; line-height: 1.45; color: var(--texte-2);
                padding: 5px 8px; margin: 4px 0; border-radius: 8px;
                background: var(--creux); border-left: 2px solid var(--accent); }
.jx-condition .t { font-size: 10px; letter-spacing: .03em; color: var(--texte-3);
                   text-transform: uppercase; }
.jx-cond-courte { display: block; font-size: 11.5px; line-height: 1.4;
                  color: var(--texte-2); max-width: 40ch; }

/* --- la fiche façon jeu : portrait, nourriture, capacités de travail ------ */
/* Dans un emplacement d'équipe la colonne fait ~300 px : le portrait et la
   grille côte à côte donnaient deux icônes par ligne sur sept lignes. On
   laisse le corps passer sous le portrait dès qu'il n'a plus 180 px. */
.jx-fiche3d { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; margin: 8px 0;
  padding: 10px; border: 1px solid var(--bord); border-radius: 10px;
  background: linear-gradient(160deg, var(--carte-2), transparent 70%); }
.jx-portrait { position: relative; flex: 0 0 auto; width: 128px; height: 128px;
  display: grid; place-items: center; border-radius: 10px;
  background: radial-gradient(circle at 50% 40%, var(--carte-2), var(--carte));
  border: 1px solid var(--bord); overflow: hidden; }
.jx-portrait img { image-rendering: auto; }
.jx-portrait .l { position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; justify-content: space-between; padding: 2px 6px;
  font-size: 10.5px; letter-spacing: .04em; color: var(--texte-2);
  background: color-mix(in srgb, var(--carte) 78%, transparent); }
.jx-portrait .ta { font-weight: 600; }
.jx-fiche-corps { flex: 1 1 180px; min-width: 0; display: flex;
  flex-direction: column; gap: 10px; }
.jx-faim { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 12px; }
.jx-faim .pips { display: inline-flex; gap: 2px; }
.jx-faim .pips i { width: 9px; height: 14px; border-radius: 2px;
  background: var(--bord); }
.jx-faim .pips i.on { background: var(--accent); }
.jx-faim .n { font-variant-numeric: tabular-nums; color: var(--texte-2); }
.jx-metiers { display: grid; grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 4px; }
.jx-metiers .m { display: flex; flex-direction: column; align-items: center;
  gap: 1px; padding: 4px 2px; border: 1px solid var(--bord); border-radius: 7px;
  background: var(--carte-2); }
.jx-metiers .m .n { font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.jx-metiers .m.off { opacity: .3; }
.jx-metiers .m.off .n { font-weight: 400; }
.jx-coeurs { display: flex; gap: 3px; font-size: 15px; color: var(--bord); }
.jx-coeurs .on { color: #e0566f; }
/* --- la compétence de partenaire, en phrase ------------------------------- */
.jx-part { margin: 6px 0; padding: 9px 11px; border-radius: 9px;
  border: 1px solid var(--bord);
  background: color-mix(in srgb, var(--accent) 7%, var(--carte-2)); }
.jx-part .p { margin-top: 5px; font-size: 13px; line-height: 1.5; }

/* --- choisir un Pal : bouton + grille cherchable, pas une liste déroulante */
.jx-choix-pal { display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px 4px 4px; border-radius: 9px; border: 1px solid var(--bord);
  background: var(--carte-2); color: var(--texte); cursor: pointer;
  font: inherit; text-align: left; }
.jx-choix-pal:hover { border-color: var(--accent-bord); }
.jx-choix-pal .t { display: flex; flex-direction: column; line-height: 1.2;
  min-width: 0; }
.jx-choix-pal .l { font-size: 10px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--texte-3); }
.jx-choix-pal .n { font-weight: 600; font-size: 13px; }
.jx-choix-pal .fl { color: var(--texte-3); font-size: 11px; margin-left: auto; }
/* Un emplacement vide doit se lire comme une invite, pas comme un nom de Pal
   qu'on n'arriverait pas à identifier. */
.jx-choix-pal .n.creux { color: var(--texte-3); font-weight: 500; font-style: italic; }

/* --- le même bouton, pour un passif ------------------------------------- */
/* Un passif n'a pas d'icône dans le jeu : la place de l'image revient à une
   pastille de rang, qui emprunte `--pw-r` à l'échelle des Optimums. Sans rang
   — emplacement libre — elle reste neutre et porte un « + ». */
.jx-choix-passif { --pw-r: var(--texte-3); }
.jx-choix-passif .past { flex: none; width: 32px; height: 32px; border-radius: 50%;
  display: inline-grid; place-items: center; font-size: 13px; color: var(--pw-r);
  background: color-mix(in srgb, var(--pw-r) 14%, var(--carte)); }
.jx-choix-passif .pw-etoiles { margin-left: auto; }
.jx-choix-passif .pw-etoiles + .fl { margin-left: 6px; }
.jx-choix-passif .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Un passif déjà posé dans un autre emplacement reste choisissable — aucune
   table n'interdit le doublon — mais il ne doit pas se proposer comme neuf. */
.jx-carte.deja { opacity: .5; }
.jx-carte.deja .no:last-child { color: var(--warn); text-align: left;
  margin-top: 3px; }

/* --- deux ou trois blocs côte à côte, qui retombent en colonne au besoin */
.jx-duo { display: grid; gap: 12px; margin-top: 8px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.jx-duo > .jx-bloc { border-top: none; border: 1px solid var(--bord);
  border-radius: 10px; padding: 9px 11px; background: var(--carte-2); }
.jx-bloc .p { font-size: 12.5px; line-height: 1.5; margin: 4px 0; }
/* Un identifiant affiché faute de nom publié : il doit se voir comme tel. */
.jx-anon { font-family: var(--fm); font-size: 11.5px; color: var(--texte-3);
  border-bottom: 1px dotted var(--bord-fort); cursor: help; }

/* ============================================================== MINECRAFT

   Les textures du jeu font 16 px. Les afficher lissees les rend floues et
   trahit le jeu : `image-rendering: pixelated` est ici une exigence de
   fidelite, pas un effet de style.                                          */
.mc-ico { image-rendering: pixelated; }
.mc-grille { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
.mc-tag .d { color: var(--accent); font-weight: 800; }

/* L'etiquette de regime de preuve. Elle n'est pas decorative : elle dit d'ou
   vient le bloc qu'elle surmonte, et Atlas 11 § 1 l'exige. */
.mc-etq { font-size: 9.5px; letter-spacing: .06em; font-weight: 800;
          margin-bottom: 8px; display: inline-block; }
.mc-etq-mesure { background: var(--ok-fond);     color: var(--ok); }
.mc-etq-source { background: var(--accent-fond); color: var(--accent); }
.mc-etq-meta   { background: var(--warn-fond);   color: var(--warn); }

/* La grille d'etabli. Une recette a motif ne se lit pas en liste : la place
   des cases EST l'information. */
.mc-motif { display: grid; gap: 3px; }
.mc-case {
  position: relative; width: 40px; height: 40px; border-radius: 6px;
  background: var(--creux); border: 1px solid var(--bord);
  display: flex; align-items: center; justify-content: center;
}
.mc-case.grand { width: 56px; height: 56px; }
.mc-case.tag { border-style: dashed; border-color: var(--accent); }
.mc-case .multi {
  position: absolute; right: 2px; bottom: 0; font-size: 10px; font-weight: 800;
  color: var(--accent); text-shadow: 0 0 3px var(--fond);
}
.mc-recette-haut { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
                   margin-bottom: 10px; }
.mc-fleche { font-size: 22px; color: var(--texte-3); }
.mc-cle { gap: 4px; padding: 3px 8px; border-radius: 8px; background: var(--creux); }
.mc-cle b { font-family: var(--fm); color: var(--accent); }
.mc-recette { margin: 3px 0; }

/* L'arbre des progres. Le decalage rend l'ordre de progression visible d'un
   coup d'oeil, ce qu'une liste a plat ne fait pas. */
.mc-arbre { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; }
.mc-prog-t.but { border-color: color-mix(in srgb, var(--accent-2) 60%, transparent); }
.mc-prog-t.defi { border-color: var(--accent-2); border-style: dashed; }

/* Le catalogue de mods. Deux colonnes suffisent : la description tient en une
   ligne ou deux, et une grille plus dense rendrait le tri illisible. */
.mc-mods { display: grid; gap: 8px;
           grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }
.mc-mod {
  display: flex; gap: 10px; padding: 9px 11px; border-radius: 11px;
  background: var(--creux); border: 1px solid transparent;
  text-decoration: none; color: var(--texte); min-width: 0;
}
.mc-mod:hover { border-color: var(--accent); background: var(--accent-fond); }
.mc-mod-ico {
  flex: 0 0 40px; width: 40px; height: 40px; border-radius: 8px;
  background: var(--fond-2); display: flex; align-items: center;
  justify-content: center; font-weight: 800; color: var(--texte-3);
  overflow: hidden;
}
.mc-mod-ico img { width: 40px; height: 40px; object-fit: cover; border-radius: 8px; }
.mc-mod-t { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mc-mod-n { font-size: 13px; line-height: 1.2; }
.mc-mod-n .au { font-size: 10.5px; color: var(--texte-3); font-weight: 500; }
.mc-mod-d { font-size: 11.5px; color: var(--texte-2); line-height: 1.35; }
.mc-mod-p { display: flex; flex-wrap: wrap; gap: 4px; }
.mc-mod-p .pilule { font-size: 9.5px; }
.mc-mod-m { font-size: 10px; color: var(--texte-3); font-variant-numeric: tabular-nums; }

/* ================================================================ NECESSE
   Necesse n'a AUCUNE image cote serveur : pas d'icone d'objet, pas de
   vignette de creature. La page est donc typographique — c'est le texte qui
   porte l'information, et la mise en page doit rester lisible sans images.
   Les seules images sont les logos de mods, rapatries depuis Steam. */

.nc-etq { font-size: 9.5px; letter-spacing: .06em; font-weight: 800;
          margin-bottom: 8px; display: inline-block; padding: 2px 7px;
          border-radius: 6px; }
.nc-etq.-mesure { background: var(--ok-fond);     color: var(--ok); }
.nc-etq.-source { background: var(--accent-fond); color: var(--accent); }
.nc-etq.-meta   { background: var(--warn-fond);   color: var(--warn); }

.nc-note { font-size: 11.5px; color: var(--texte-3); line-height: 1.45;
           margin: 6px 0; }
.nc-tip { font-size: 12px; color: var(--texte-2); font-style: italic;
          margin: 6px 0 10px; }
.nc-id { font-family: var(--fm); font-size: 10px; color: var(--texte-3);
         margin-left: 8px; }

/* Un ecart entre ce qui tourne et ce qui est installe merite d'etre vu sans
   deplier quoi que ce soit. */
.nc-alerte { margin: 10px 0 2px; padding: 9px 12px; border-radius: 10px;
             background: var(--warn-fond); color: var(--texte);
             border-left: 3px solid var(--warn); font-size: 12px;
             line-height: 1.45; }
.nc-absents { margin: 4px 0 0 18px; padding: 0; font-size: 12px;
              color: var(--texte-2); line-height: 1.5; }
.nc-absents li { margin: 3px 0; }
.nc-pre { font-family: var(--fm); font-size: 11px; line-height: 1.45;
          white-space: pre-wrap; word-break: break-word; background: var(--creux);
          padding: 9px 11px; border-radius: 9px; margin: 6px 0;
          max-height: 340px; overflow: auto; color: var(--texte-2); }
.nc-bloc { margin-top: 12px; }
.nc-bloc h4 { margin: 0 0 6px; font-size: 12.5px; }

/* Les compteurs du socle servent de sommaire : chacun mene a son onglet. */
/* `auto-fit` : mesure du 31 aout 2026 sur 2560 px — 16 pistes creees pour 3 a
   12 compteurs selon le jeu, jusqu'a 1 822 px de vide a droite (Valheim, 3
   compteurs). Voir la note de `.jx-grille`. */
.nc-compteurs { display: grid; gap: 6px; margin-top: 10px;
                grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
.nc-compteur { display: flex; flex-direction: column; gap: 1px; padding: 8px 10px;
               border-radius: 10px; background: var(--creux);
               border: 1px solid transparent; cursor: pointer; text-align: left;
               color: var(--texte); font: inherit; }
.nc-compteur:hover { border-color: var(--accent); background: var(--accent-fond); }
.nc-compteur.inerte { cursor: default; }
.nc-compteur.inerte:hover { border-color: transparent; background: var(--creux); }
.nc-compteur b { font-size: 16px; font-variant-numeric: tabular-nums; }
.nc-compteur span { font-size: 10.5px; color: var(--texte-3); }

/* Les statistiques d'un objet : libelle a gauche, valeur a droite, paliers
   d'amelioration en dessous. Une grille les aligne d'une fiche a l'autre, ce
   qui rend la comparaison possible a l'oeil. */
.nc-stats { display: grid; gap: 4px; margin: 10px 0;
            grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.nc-stat { display: flex; align-items: baseline; gap: 8px; padding: 5px 9px;
           border-radius: 8px; background: var(--creux); flex-wrap: wrap; }
.nc-stat .l { font-size: 11.5px; color: var(--texte-2); flex: 1; }
.nc-stat b { font-variant-numeric: tabular-nums; font-size: 13px; }
.nc-stat b.inconnu { color: var(--texte-3); font-weight: 500; }
.nc-stat i { flex-basis: 100%; font-size: 10.5px; color: var(--texte-3);
             font-style: normal; }

/* Un modificateur se lit « libelle  valeur » ; la valeur est ce qui compte,
   donc elle est mise en avant. */
.nc-mods { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.nc-mod { display: inline-flex; align-items: baseline; gap: 6px;
          padding: 2px 8px; border-radius: 7px; background: var(--creux);
          font-size: 11px; }
.nc-mod b { font-weight: 600; color: var(--texte-2); }
.nc-mod i { font-style: normal; font-weight: 800; color: var(--accent);
            font-variant-numeric: tabular-nums; }

.nc-cartes { display: grid; gap: 7px; margin-top: 8px;
             grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.nc-fiche { padding: 8px 11px; border-radius: 10px; background: var(--creux); }
.nc-fiche-t { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* Une recette tient sur une ligne : produit, fleche, ingredients, atelier. */
.nc-recettes { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; }
.nc-recette { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
              padding: 4px 8px; border-radius: 9px; }
.nc-recette:hover { background: var(--creux); }
.nc-fleche { color: var(--texte-3); font-size: 15px; }
.nc-atelier { margin-left: auto; font-size: 10.5px; color: var(--texte-3);
              padding: 2px 8px; border-radius: 7px; background: var(--creux); }

.nc-zone { padding: 10px 12px; border-radius: 11px; background: var(--creux);
           margin-top: 8px; }

/* Le catalogue de mods : meme densite que Minecraft, les compteurs Steam en
   pied de carte. */
.nc-mods-l { display: grid; gap: 8px; margin-top: 8px;
             grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }
a.nc-mod { display: flex; gap: 10px; padding: 9px 11px; border-radius: 11px;
           background: var(--creux); border: 1px solid transparent;
           text-decoration: none; color: var(--texte); min-width: 0;
           align-items: flex-start; }
a.nc-mod:hover { border-color: var(--accent); background: var(--accent-fond); }
.nc-mod-i { flex: 0 0 48px; width: 48px; height: 48px; border-radius: 8px;
            background: var(--fond-2); overflow: hidden; }
.nc-mod-i img { width: 48px; height: 48px; object-fit: cover; border-radius: 8px; }
.nc-mod-t { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.nc-mod-n { display: flex; align-items: center; gap: 6px; font-size: 13px;
            line-height: 1.2; flex-wrap: wrap; }
.nc-mod-r { font-size: 11.5px; color: var(--texte-2); line-height: 1.35;
            display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
            overflow: hidden; }
.nc-mod-p { display: flex; flex-wrap: wrap; gap: 4px; }
.nc-mod-p .pilule { font-size: 9.5px; }
.nc-mod-m { font-size: 10px; color: var(--texte-3); font-variant-numeric: tabular-nums; }

/* Les icônes de Necesse sont du pixel art 32 px : les lisser les rendrait
   floues à la taille où elles s'affichent. */
.nc-ico { image-rendering: pixelated; vertical-align: middle; }
.nc-ico-vide { vertical-align: middle; }
/* La place est réservée même sans icône, sinon les colonnes se décalent d'une
   ligne à l'autre et la lecture en table devient pénible. */
td.ico, th.ico { width: 34px; padding-left: 8px; padding-right: 0; }
.nc-entete-ico { margin: 2px 0 8px; }
.nc-entete-ico .nc-ico { image-rendering: pixelated; border-radius: 8px;
                         background: var(--creux); padding: 4px; }

/* Un lien de tableau qui porte son icone : l'icone ne doit pas ecarter la
   ligne de base du texte, sinon les lignes du tableau ne s'alignent plus. */
.nc-lien-ico { display: inline-flex; align-items: center; gap: 6px;
               text-align: left; }
.nc-lien-ico .nc-ico, .nc-lien-ico .nc-ico-vide { flex: 0 0 auto; }

/* La description d'un objet : c'est le texte du JEU, pas une glose. On la
   pose en retrait pour qu'on ne la confonde pas avec nos propres notes. */
.nc-desc { margin: 6px 0 10px; padding-left: 10px; font-size: .86rem;
           line-height: 1.45; color: var(--texte-2);
           border-left: 2px solid var(--bord); }

/* Le profil de lutte d'un poisson : une barre par phase, largeur
   proportionnelle a sa duree. Un tableau de chiffres ne dit pas la meme
   chose — c'est le rythme qu'on lit ici. */
.ck-profil { display: flex; gap: 1px; height: 14px; min-width: 130px;
             border-radius: 4px; overflow: hidden; }
.ck-profil i { display: block; }
.ck-profil i.lutte { background: var(--warn); }
.ck-profil i.calme { background: var(--creux); }

/* Les logos mod.io sont des bandeaux 16:9, pas des icônes carrées : les
   recadrer en carré coupe le titre que l'auteur y a mis. On garde le rapport
   et on élargit la vignette pour Core Keeper. */
.nc-mod-i.-large { flex: 0 0 96px; width: 96px; height: 54px; border-radius: 6px; }
.nc-mod-i.-large img { width: 96px; height: 54px; object-fit: cover;
                       border-radius: 6px; }

/* Un paquet déprécié reste consultable mais ne doit pas se lire comme un mod
   vivant : on l'affaiblit sans le cacher, et la pastille dit pourquoi. */
a.nc-mod.-fane { opacity: .55; }
a.nc-mod.-fane:hover { opacity: 1; }

/* ------------------------------------------------------------- VALHEIM */
/* Les icônes de Valheim sont des sprites 64 px lissés, pas du pixel art :
   contrairement à Necesse, on ne force PAS `pixelated`. */
.vh-ico { flex: 0 0 auto; object-fit: contain; vertical-align: middle; }
.vh-ico.vide { display: inline-block; background: var(--creux); border-radius: 5px; }
.vh-fiche { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 10px; }
.vh-fiche-n { font-size: 16px; font-weight: 700; line-height: 1.2; }
.vh-desc { font-size: 12px; color: var(--texte-2); line-height: 1.45;
           margin-top: 4px; max-width: 62ch; font-style: italic; }
.vh-recettes { display: grid; gap: 3px; margin-top: 8px; }
.vh-prod { display: inline-flex; align-items: center; gap: 5px; min-width: 210px; }
.vh-ing { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px 2px 3px;
          border-radius: 100px; background: var(--creux); font-size: 11.5px; }
.vh-ing .n { color: var(--texte-3); font-variant-numeric: tabular-nums; }
.vh-st { margin-left: auto; font-size: 10.5px; color: var(--texte-3);
         white-space: nowrap; padding-left: 10px; }

/* ------------------------------------------------------------ TERRARIA */
/* Terraria n'a AUCUNE icône : le serveur dédié n'embarque pas une image, et
   celles du client sont en XNB compressé LZX, qu'aucun décodeur Python ne
   sait ouvrir. Pas de règle d'icône ici, donc — la place n'est même pas
   réservée, pour que l'absence se voie au lieu de ressembler à un chargement
   qui n'arrive jamais. */
.tr-fiche { margin-bottom: 10px; }
.tr-fiche-n { font-size: 16px; font-weight: 700; line-height: 1.2; }
/* Les descriptions du jeu portent de VRAIS retours à la ligne — c'est ainsi
   que Re-Logic écrit une infobulle à plusieurs lignes. Sans `pre-line`, tout
   arrive collé sur une seule. */
.tr-desc { font-size: 12px; color: var(--texte-2); line-height: 1.45;
           margin-top: 4px; max-width: 62ch; font-style: italic;
           white-space: pre-line; }

/* Une recette tient sur une ligne : produit à gauche, ingrédients au milieu,
   station à droite. C'est la forme la plus lisible pour en survoler 250. */
.tr-recs { display: grid; gap: 3px; margin-top: 8px; }
.tr-rec { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
          padding: 4px 8px; border-radius: 7px; background: var(--creux); }
.tr-rec-p { min-width: 220px; font-size: 12.5px; }
.tr-rec-i { display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
            flex: 1 1 auto; }
.tr-rec-s { margin-left: auto; font-size: 10.5px; color: var(--texte-3);
            white-space: nowrap; padding-left: 10px; }
/* Ce que le fichier ne porte pas doit se lire comme un trou, pas comme un
   champ vide : italique et grisé, jamais un tiret muet. */
.tr-abs { font-size: 11px; color: var(--texte-3); font-style: italic; }

/* ============================================================ ARK ======= */
.ak-ico { border-radius: 3px; vertical-align: middle; flex: 0 0 auto;
          object-fit: contain; }
.ak-ico.vide { display: inline-block; border: 1px dashed var(--bord);
               border-radius: 3px; opacity: .35; }
.ak-fiche { display: flex; gap: 14px; align-items: flex-start;
            margin-bottom: 12px; }
.ak-fiche-n { font-size: 1.15rem; font-weight: 600; }
.ak-desc { margin-top: 6px; color: var(--texte-2); font-size: .86rem;
           line-height: 1.45; white-space: pre-line; max-width: 62ch; }
.ak-rec { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 2px; }
.ak-ing { display: inline-flex; align-items: center; gap: 4px;
          padding: 2px 7px; border: 1px solid var(--bord); border-radius: 11px;
          background: var(--creux); font-size: .8rem; white-space: nowrap; }
button.ak-ing { cursor: pointer; }
button.ak-ing:hover { border-color: var(--accent); }
.ak-recs { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.ak-rec-l { display: grid; grid-template-columns: 250px 1fr 190px;
            gap: 10px; align-items: center; padding: 6px 8px;
            border-radius: 6px; }
.ak-rec-l:nth-child(odd) { background: var(--creux); }
.ak-rec-p { display: flex; align-items: center; gap: 7px; min-width: 0; }
.ak-rec-p .jx-lien { text-align: left; }
.ak-rec-i { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.ak-rec-s { color: var(--texte-2); font-size: .78rem; text-align: right;
            overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 900px) {
  .ak-rec-l { grid-template-columns: 1fr; }
  .ak-rec-s { text-align: left; }
}
.ak-ing.vide { opacity: .6; font-style: italic; border-style: dashed; }

/* ---- ARK : cartes ---- */
.ak-carte { display: flex; flex-direction: column; gap: 10px; }
.ak-carte-info { max-width: 900px; }
.ak-fams { display: flex; flex-wrap: wrap; gap: 6px; }
.ak-fam { display: inline-flex; align-items: center; gap: 6px;
          padding: 3px 10px; border: 1px solid var(--bord); border-radius: 13px;
          background: var(--creux); color: var(--texte-2); font-size: .78rem;
          cursor: pointer; }
.ak-fam i { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto;
            background: var(--texte-2); }
.ak-fam.on { color: var(--texte); border-color: var(--accent);
             background: var(--carte-2); }
.ak-fams-sep { flex: 1 1 8px; }
.ak-esp { padding: 3px 8px; border: 1px solid var(--bord); border-radius: 13px;
          background: var(--creux); color: var(--texte); font-size: .78rem;
          max-width: 22rem; }
/* ⚠️ La LISTE déroulante d'un `select` est peinte par le navigateur, pas par
   la règle du `select`. Sans `color-scheme`, Chrome la peint en clair pendant
   que le texte hérite de la couleur du thème : en thème sombre, ça donne du
   blanc sur blanc. `appliquerTheme()` écrit toujours `data-theme`, donc les
   deux cas sont couverts. Les couleurs d'`option` sont posées en plus, pour
   les navigateurs qui les honorent. */
.ak-esp { color-scheme: dark; }
html[data-theme="clair"] .ak-esp { color-scheme: light; }
.ak-esp option { background: var(--carte); color: var(--texte); }
.ak-carte-cadre { position: relative; width: 100%; max-width: 900px;
                  aspect-ratio: 1 / 1; align-self: center;
                  border: 1px solid var(--bord); border-radius: 8px;
                  overflow: hidden; background: var(--creux);
                  touch-action: none; }
.ak-carte-cadre.zoome { cursor: grab; }
.ak-carte-cadre.tire { cursor: grabbing; }
/* Le plan porte le zoom. Son origine est le coin haut-gauche : c'est ce qui
   permet de convertir un point de l'écran en point du plan par une simple
   division, sans corriger d'un demi-cadre à chaque cran de molette. */
.ak-carte-plan { position: absolute; inset: 0; transform-origin: 0 0;
                 will-change: transform; }
.ak-carte-img { width: 100%; height: 100%; object-fit: fill; display: block;
                user-select: none; -webkit-user-drag: none; }
.ak-carte-couche { position: absolute; inset: 0; pointer-events: none; }
/* Les pastilles sont contre-mises à l'échelle par `--z` : le plan est agrandi,
   elles gardent leur taille à l'écran. Sans ça un zoom ×8 donne des disques de
   72 px qui recouvrent l'île. */
.ak-carte-couche .ak-pt { position: absolute;
  width: calc(9px / var(--z, 1)); height: calc(9px / var(--z, 1));
  margin: calc(-4.5px / var(--z, 1)) 0 0 calc(-4.5px / var(--z, 1));
  border-radius: 50%; pointer-events: auto;
  box-shadow: 0 0 0 calc(1.5px / var(--z, 1)) rgba(0,0,0,.65); cursor: help; }
.ak-carte-couche .ak-pt.f-spawn {
  width: calc(5px / var(--z, 1)); height: calc(5px / var(--z, 1));
  margin: calc(-2.5px / var(--z, 1)) 0 0 calc(-2.5px / var(--z, 1));
  opacity: .75; }
.ak-carte-couche .ak-pt.f-biome {
  width: calc(7px / var(--z, 1)); height: calc(7px / var(--z, 1));
  margin: calc(-3.5px / var(--z, 1)) 0 0 calc(-3.5px / var(--z, 1));
  opacity: .8; }
.ak-carte-couche .ak-sp { position: absolute;
  width: calc(11px / var(--z, 1)); height: calc(11px / var(--z, 1));
  margin: calc(-5.5px / var(--z, 1)) 0 0 calc(-5.5px / var(--z, 1));
  border-radius: 50%; pointer-events: auto; cursor: help;
  background: rgba(74, 222, 128, .45);
  box-shadow: inset 0 0 0 calc(1.6px / var(--z, 1)) rgba(22, 163, 74, .95),
              0 0 0 calc(1px / var(--z, 1)) rgba(0, 0, 0, .35); }
.ak-carte-couche .ak-g { position: absolute; background: rgba(255,255,255,.28); }
.ak-carte-couche .ak-g.h { left: 0; right: 0; height: calc(1px / var(--z, 1)); }
.ak-carte-couche .ak-g.v { top: 0; bottom: 0; width: calc(1px / var(--z, 1)); }
.ak-carte-couche .ak-gl { position: absolute;
  font-size: calc(.62rem / var(--z, 1));
  color: rgba(255,255,255,.75); text-shadow: 0 0 3px rgba(0,0,0,.9);
  font-weight: 600; }
.ak-carte-couche .ak-gl.h { left: calc(2px / var(--z, 1));
  transform: translateY(-100%); }
.ak-carte-couche .ak-gl.v { top: calc(2px / var(--z, 1));
  transform: translateX(calc(2px / var(--z, 1))); }
.ak-zoom { position: absolute; right: 8px; bottom: 8px; display: flex;
           gap: 4px; z-index: 3; }
.ak-zoom button { width: 26px; height: 26px; line-height: 1;
  border: 1px solid var(--bord); border-radius: 6px; cursor: pointer;
  background: rgba(0,0,0,.55); color: #fff; font-size: .9rem; }
.ak-zoom button:hover { background: rgba(0,0,0,.8); }

/* Les silhouettes de créature sont des masques : la couleur vient du fond,
   la forme du canal alpha du WebP. Peindre l'image elle-même obligerait à
   réextraire une variante par catégorie. */
.ak-masque { display: inline-block; vertical-align: middle;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center; }
.ak-dossier { margin: 12px 0 0; }
.ak-dossier img { width: 100%; max-width: 900px; border-radius: 8px;
  border: 1px solid var(--bord); display: block; }
.ak-dossier figcaption { margin-top: 5px; }
.ak-variantes { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.ak-curseur { display: inline-flex; align-items: center; gap: 8px;
  font-size: .8rem; color: var(--texte-2); }
.ak-curseur input[type=range] { width: 200px; accent-color: var(--accent); }
.ak-curseur b { color: var(--texte); font-variant-numeric: tabular-nums;
  min-width: 2.4em; text-align: right; }

/* --- une pastille qui MENE quelque part ---------------------------------- */
/* Elle annonçait « boss de terrain, à un point fixe de la carte » sans qu'on
   puisse y aller. Le renvoi doit se voir sans crier : la flèche apparaît au
   survol, la bordure dit que c'est cliquable. */
/* `.pilule` est en `nowrap` : ces phrases-la font 55 caracteres et
   debordaient la colonne d'une fiche. */
.jx-pil-lien { cursor: pointer; border: 1px solid currentColor; font: inherit;
  font-size: 11px; line-height: 1.4; text-align: left; white-space: normal;
  max-width: 46ch; }
.jx-pil-lien:hover { filter: brightness(1.15); }
.jx-pil-lien .fl { opacity: 0; transition: opacity .12s; white-space: nowrap; }
.jx-pil-lien:hover .fl, .jx-pil-lien:focus-visible .fl { opacity: .8; }

/* --- un boss humain : pas d'icône dans le jeu, un cartouche à la place ---- */
.jx-humain { width: 56px; height: 56px; border-radius: 10px; display: flex;
  align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; color: var(--texte-3); background: var(--creux);
  border: 1px dashed var(--bord); }

/* ═══════════════════════════════ constructeur d'équipe de camp, refonte UI */

/* --- les métiers, en pastilles cochables --------------------------------- */
/* Treize boutons de largeurs inégales sur deux rangs ne se lisaient pas comme
   des cases à cocher : rien ne disait qu'ils étaient cumulables. Une grille
   régulière, un état « actif » franc, et le plafond du métier écrit dessous —
   sinon on coche à l'aveugle, et « Extraction du pétrole brut » (max 4) se
   demande comme « Artisanat » (max 8). */
.jx-chips { display: grid; gap: 6px; margin: 8px 0;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.jx-chip { display: flex; align-items: center; gap: 7px; text-align: left;
  padding: 7px 9px; border-radius: 9px; cursor: pointer;
  background: var(--creux); border: 1px solid transparent;
  font-family: var(--f); font-size: 12px; color: var(--texte-2); }
.jx-chip:hover { border-color: var(--bord); }
.jx-chip .n { flex: 1; line-height: 1.2; }
.jx-chip .p { font-size: 10px; color: var(--texte-3); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.jx-chip.actif { background: var(--accent-fond); border-color: var(--accent);
  color: var(--texte); font-weight: 620; }
.jx-chip.actif .p { color: var(--accent); }
.jx-chip.mort { opacity: .45; }
.jx-chip.mort .p { color: var(--warn); }
.jx-chip img { opacity: .55; }
.jx-chip.actif img { opacity: 1; }

/* --- une vignette d'ouvrier ---------------------------------------------- */
/* Elle portait trois pastilles empilées et deux boutons pleine largeur : cinq
   éléments sous une image de 64 px, dix fois de suite. Les deux actions
   passent en coin, et n'apparaissent qu'au survol — elles ne servent qu'une
   fois qu'on a lu la vignette. */
.jx-ouvrier { position: relative; border-radius: 12px; background: var(--creux);
  border: 1px solid transparent; overflow: hidden; }
.jx-ouvrier:hover { border-color: var(--bord); }
.jx-ouvrier.impose { border-color: var(--accent); background: var(--accent-fond); }
.jx-ouvrier .corps { display: flex; flex-direction: column; align-items: center;
  gap: 5px; width: 100%; padding: 10px 8px 6px; cursor: pointer;
  background: none; border: 0; font-family: var(--f); color: var(--texte); }
.jx-ouvrier .nom { font-size: 12.5px; font-weight: 650; line-height: 1.2;
  text-align: center; }
.jx-ouvrier .mets { display: flex; flex-wrap: wrap; gap: 4px;
  justify-content: center; }
.jx-ouvrier .mets .m { display: inline-flex; align-items: center; gap: 2px;
  font-size: 10.5px; color: var(--texte-3); font-variant-numeric: tabular-nums;
  background: var(--carte-2); border-radius: 5px; padding: 1px 4px; }
.jx-ouvrier .role { font-size: 10px; text-align: center; padding: 3px 6px;
  letter-spacing: .02em; background: var(--carte-2); color: var(--texte-3); }
.jx-ouvrier .role.couverture { background: var(--ok-fond); color: var(--ok); }
.jx-ouvrier .role.impose { background: var(--accent-fond); color: var(--accent);
  font-weight: 650; }

/* Elles restent VISIBLES au repos, en retrait. Les cacher jusqu'au survol
   rendait la page plus propre et le constructeur plus opaque : c'est
   exactement ce qu'on cherchait à corriger. Un contrôle qu'il faut deviner
   n'existe pas. */
.jx-ouvrier .act { position: absolute; top: 4px; right: 4px; display: flex;
  gap: 2px; opacity: .4; transition: opacity .12s; z-index: 1; }
.jx-ouvrier:hover .act, .jx-ouvrier:focus-within .act { opacity: 1; }
.jx-ouvrier .act button { border: 1px solid var(--bord); background: var(--carte);
  color: var(--texte-2); border-radius: 6px; width: 22px; height: 22px;
  font-size: 11px; line-height: 1; cursor: pointer; padding: 0; }
.jx-ouvrier .act button:hover { border-color: var(--accent); color: var(--texte); }
.jx-ouvrier .act button.on { border-color: var(--accent); background: var(--accent-fond); }
@media (hover: none) { .jx-ouvrier .act { opacity: 1; } }

/* --- une valeur posée à côté d'un contrôle ------------------------------- */
.jx-cle-val { font-size: 12px; font-weight: 650; color: var(--texte);
  font-variant-numeric: tabular-nums; }

/* --- sprites Terraria ----------------------------------------------------- */
/* ⚠ UN FOND `color-mix(..., transparent)` N'EST PAS UN FOND SUR UNE PAGE DE
   JEU. Les trois tuiles de rang des Optimums melaient `--pw-r` a 14-15 % VERS
   TRANSPARENT : sur une page normale elles posaient une teinte sur la carte
   blanche, mais sous elles il y a desormais le calque photo, et l'encre de
   rang tombait a 2,7:1 en thema clair. Elles melent maintenant vers
   `var(--carte)`, qui suit le thema : meme apparence, mais c'est une surface.
   Meme piege que les `#RRGGBB22` des pastilles d element du Paldeck. */

/* Du pixel art : `pixelated` est obligatoire. Réduit au lissage bilinéaire,
   un sprite de 22 px devient une bouillie — c'est le § 8.6 du catalogue. */
.tr-ico { image-rendering: pixelated; object-fit: contain; flex: none; }
.tr-ico.vide { display: inline-block; }
.tr-avec-ico { display: inline-flex; align-items: center; gap: 7px;
  text-align: left; }

/* =====================================================================
   PALWORLD — onglet Optimums : le bloc des passifs et les palmarès.
   Refondu le 2026-08-24 sur une maquette. Trois idées, pas plus.

   1. UNE ÉCHELLE DE RANG, UNE COULEUR. Le rang d'un passif (-3 à 5) vient
      de DT_PassiveSkill_Main. Chaque rang pose `--pw-r`, et bordure, halo,
      étoiles, valeur et pied d'une même tuile s'y accordent sans qu'aucune
      couleur soit écrite deux fois. Les teintes sont des jetons de
      `style.css` : elles tiennent le contraste dans les DEUX thèmes.
   2. DIX EN TUILES, LE RESTE EN PASTILLES. Quinze passifs au même poids
      formaient une liste, pas un classement.
   3. LES PALMARÈS EN LIGNES. Douze pastilles flottantes ne se comparent
      pas : la valeur tombait où elle pouvait. Calée à droite, elle se lit.

   ⚠ La maquette montrait une illustration de Pal dans chaque tuile. Le jeu
   n'en fournit AUCUNE — il n'existe pas d'icône de passif dans le pak — et
   92 des 115 passifs n'ont aucun porteur natif. Rien ici ne remplit cette
   place par une image choisie au jugé : c'est la valeur qui l'occupe.
   ===================================================================== */

/* --- l'échelle ----------------------------------------------------------- */
.pw-r5   { --pw-r: var(--warn); }
.pw-r4   { --pw-r: var(--violet); }
.pw-r3   { --pw-r: var(--info); }
.pw-r2   { --pw-r: var(--ok); }
.pw-r1   { --pw-r: var(--texte-2); }
.pw-rneg { --pw-r: var(--crit); }

.pw-etoiles { color: var(--pw-r); font-size: 12px; letter-spacing: .14em;
  line-height: 1; white-space: nowrap; }

/* --- la carte de tête ---------------------------------------------------- */
/* Le titre monte d'un cran : c'est la seule carte de la page qui ouvre une
   section plutôt que d'en porter une. Le reste du site garde ses h3 à 11 px. */
.carte.pw-hero > h3 { font-size: 14px; color: var(--texte); letter-spacing: .055em; }
.pw-glyphe { color: var(--accent); font-size: 12px; line-height: 1; }
.carte.pw-danger .pw-glyphe { color: var(--crit); }
.pw-sous { font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 2px; }

/* --- le podium ----------------------------------------------------------- */
/* `row-gap` est plus large que `column-gap` : la médaille déborde de 10 px
   au-dessus de sa tuile et viendrait sinon mordre la rangée précédente. */
/* CINQ colonnes, pas « autant que ça rentre ». `auto-fit` en donnait six et
   la seconde rangée finissait à quatre : dix passifs classés se lisent en
   deux rangées de cinq, ou ce n'est plus un podium. */
.pw-podium { display: grid; column-gap: 10px; row-gap: 22px; margin-top: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 620px) { .pw-podium { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .pw-podium { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* Une forme spéciale (alpha, boss de tour, prédateur) sur la fiche d'un Pal.
   Le liseré à gauche la sépare de sa voisine sans ajouter une carte par forme :
   certains Pals en portent quatre, et quatre cartes empilées feraient passer
   la variante pour le sujet de la page. */
.pw-forme { border-left: 2px solid var(--bord); padding: 2px 0 2px 10px;
  margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.pw-forme:first-of-type { margin-top: 4px; }

.pw-tuile {
  position: relative; display: flex; flex-direction: column; gap: 5px;
  padding: 20px 12px 10px; border-radius: 14px; cursor: pointer;
  text-align: left; font-family: var(--f); color: var(--texte);
  border: 1px solid color-mix(in srgb, var(--pw-r) 32%, transparent);
  background:
    radial-gradient(130% 80% at 50% -8%,
      color-mix(in srgb, var(--pw-r) 20%, transparent), transparent 68%),
    var(--creux);
  transition: border-color .14s, transform .14s, box-shadow .14s;
}
.pw-tuile:hover {
  border-color: var(--pw-r); transform: translateY(-2px);
  box-shadow: 0 10px 26px -16px var(--pw-r);
}
.pw-tuile .med {
  position: absolute; top: -10px; left: 11px; width: 26px; height: 26px;
  border-radius: 50%; display: grid; place-items: center;
  font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums;
  color: var(--carte); background: var(--pw-r); border: 2px solid var(--carte);
  box-shadow: 0 2px 9px -3px var(--pw-r);
}
.pw-tuile .art {
  display: grid; place-items: center; min-height: 56px; border-radius: 10px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--pw-r) 14%, transparent), transparent);
}
.pw-tuile .art .v {
  font-family: var(--fm); font-size: 25px; font-weight: 700; line-height: 1;
  color: var(--pw-r); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 24px color-mix(in srgb, var(--pw-r) 40%, transparent);
}
.pw-tuile .art .v.acquis { font-size: 13px; letter-spacing: .06em;
  text-transform: uppercase; font-weight: 800; }
/* Une PERTE nette en tête de tuile ne prend pas la couleur du rang : un rang 5
   peut se payer, et le nombre doit le dire de lui-même. */
.pw-tuile .art .v.perte { color: var(--crit);
  text-shadow: 0 0 24px color-mix(in srgb, var(--crit) 35%, transparent); }
.pw-tuile .nom { font-size: 13px; font-weight: 700; line-height: 1.2; }
.pw-tuile .eff { display: flex; flex-direction: column; gap: 1px; }
.pw-tuile .eff .l { font-size: 11px; line-height: 1.35; color: var(--texte-2); }
.pw-tuile .eff .l i { font-style: normal; }
.pw-tuile .eff .l b { margin-left: 5px; color: var(--texte);
  font-variant-numeric: tabular-nums; }
/* `wrap` n'est pas décoratif : une tuile de 166 px qui porte À LA FOIS des
   porteurs natifs et le poids de tirage fait tenir les deux sur une ligne en
   les chevauchant. Ils passent l'un sous l'autre plutôt que de se marcher
   dessus. */
.pw-tuile .pied {
  margin-top: auto; padding-top: 7px; display: flex; align-items: center;
  flex-wrap: wrap; gap: 3px 7px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--pw-r);
  border-top: 1px solid color-mix(in srgb, var(--pw-r) 20%, transparent);
}
.pw-tuile .pied .tir { margin-left: auto; color: var(--texte-3); font-weight: 600;
  letter-spacing: .03em; }
.pw-tuile .pied .tir.rare { color: var(--pw-r); }
.pw-tuile .pied .ic { display: inline-flex; padding-right: 6px; }
.pw-tuile .pied .ic img { margin-right: -7px; border-radius: 50%;
  background: var(--carte-2); box-shadow: 0 0 0 1px var(--creux); }

/* --- ce que le podium ne prend pas --------------------------------------- */
.pw-mineurs { display: grid; gap: 8px; margin-top: 16px;
  grid-template-columns: repeat(auto-fit, minmax(206px, 1fr)); }
.pw-mineur {
  display: flex; align-items: center; gap: 9px; padding: 7px 11px 7px 8px;
  border-radius: 11px; background: var(--creux); cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--pw-r) 24%, transparent);
  font-family: var(--f); color: var(--texte); text-align: left;
}
.pw-mineur:hover { border-color: var(--pw-r); }
.pw-mineur .past { flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; font-size: 11px; color: var(--pw-r);
  background: color-mix(in srgb, var(--pw-r) 15%, var(--carte)); }
.pw-mineur .t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pw-mineur .t b { font-size: 12px; font-weight: 700; line-height: 1.25; }
.pw-mineur .t i { font-style: normal; font-size: 10.5px; line-height: 1.3;
  color: var(--texte-3); }
.pw-mineur .f { margin-left: auto; flex: none; font-size: 9.5px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--pw-r); }

/* --- les palmarès -------------------------------------------------------- */
.pw-quatre { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr)); }
.carte.pw-palmares { padding: 12px 13px; }
.pw-palmares .tete { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.pw-palmares .tete .t { font-size: 11.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--accent); line-height: 1.15; }
.pw-classement { display: flex; flex-direction: column; }
.pw-classement .l {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 3px 5px; border: 0; border-top: 1px solid var(--bord);
  border-radius: 7px; background: none; cursor: pointer;
  font-family: var(--f); color: var(--texte); text-align: left;
}
.pw-classement .l:first-child { border-top: 0; }
.pw-classement .l:hover { background: var(--accent-fond); }
.pw-classement .n { font-size: 12.5px; font-weight: 600; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pw-classement .v { margin-left: auto; flex: none; font-size: 12.5px; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--texte-2); }

/* --- le pied de l'onglet : légende, rangs mineurs, rangs négatifs -------- */
.pw-pied { display: grid; gap: 12px; margin-top: 12px;
  grid-template-columns: minmax(0, 210px) minmax(0, 1fr); align-items: start; }
@media (max-width: 860px) { .pw-pied { grid-template-columns: 1fr; } }
.carte.pw-legende .l { display: flex; flex-direction: column; gap: 8px; margin-top: 5px; }
.carte.pw-legende .e { display: flex; align-items: center; gap: 10px; }
.carte.pw-legende .e .pw-etoiles { flex: none; width: 74px; }
.carte.pw-legende .e .t { font-size: 12px; color: var(--texte-2); }
.carte.pw-danger { border-color: color-mix(in srgb, var(--crit) 32%, var(--bord)); }

.pw-chips { display: grid; gap: 7px; margin-top: 5px;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.pw-chip {
  display: flex; align-items: flex-start; gap: 8px; padding: 6px 9px 6px 7px;
  border-radius: 10px; background: var(--creux); cursor: pointer;
  border: 1px solid transparent; font-family: var(--f); color: var(--texte);
  text-align: left;
}
.pw-chip:hover { border-color: var(--pw-r); }
/* `.pt` ne peint RIEN : la couleur vient soit de `.rang` ci-dessous, soit de
   `.pilule.el-*` de theme.css. Deux règles de même poids qui se disputent une
   couleur, c'est la panne qu'aucune capture ne montre. */
.pw-chip .pt { flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: inline-grid; place-items: center; font-size: 11px; line-height: 1; }
.pw-chip .pt.rang { color: var(--pw-r);
  background: color-mix(in srgb, var(--pw-r) 14%, var(--carte)); }
.pw-chip .pt.pilule { padding: 0; }
.pw-chip .t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pw-chip .t b { font-size: 11.5px; font-weight: 700; line-height: 1.25; }
.pw-chip .t i { font-style: normal; font-size: 10.5px; line-height: 1.3;
  color: var(--texte-3); }

/* =====================================================================
   GEOMETRIE PAR JEU — le pendant de theme.css pour les primitives `jx-*`.

   Ces regles ne peuvent pas vivre dans theme.css : jeux.css charge apres
   lui et recouvrirait ses rayons. Comme la-bas, les valeurs de `:root`
   sont celles qui etaient codees en dur juste au-dessus, et les blocs par
   jeu visent les deux portees — `body[data-vue="jeu-x"]` pour les pages
   du site, `[data-jeu="x"]` pour un fragment monte hors page.
   ===================================================================== */
:root{ --r-vignette:12px; --r-tuile:10px; --r-chip:9px; --r-pw-tuile:14px }

.jx-carte,.jx-slot                                  { border-radius:var(--r-vignette) }
.jx-tuile,.jx-bilan,.nc-fiche,.nc-compteur,.pw-chip { border-radius:var(--r-tuile) }
.jx-chip                                            { border-radius:var(--r-chip) }
.pw-tuile                                           { border-radius:var(--r-pw-tuile) }

[data-jeu="palworld"],body[data-vue="jeu-palworld"]
  { --r-vignette:18px; --r-tuile:14px; --r-chip:13px; --r-pw-tuile:20px }
[data-jeu="minecraft"],body[data-vue="jeu-minecraft"]
  { --r-vignette:0px; --r-tuile:0px; --r-chip:0px; --r-pw-tuile:0px }
[data-jeu="valheim"],body[data-vue="jeu-valheim"]
  { --r-vignette:3px; --r-tuile:3px; --r-chip:3px; --r-pw-tuile:4px }
[data-jeu="ark"],body[data-vue="jeu-ark"]
  { --r-vignette:5px; --r-tuile:5px; --r-chip:5px; --r-pw-tuile:6px }
[data-jeu="terraria"],body[data-vue="jeu-terraria"]
  { --r-vignette:4px; --r-tuile:4px; --r-chip:4px; --r-pw-tuile:4px }
[data-jeu="core-keeper"],body[data-vue="jeu-core-keeper"]
  { --r-vignette:12px; --r-tuile:10px; --r-chip:9px; --r-pw-tuile:14px }
[data-jeu="necesse"],body[data-vue="jeu-necesse"]
  { --r-vignette:9px; --r-tuile:8px; --r-chip:7px; --r-pw-tuile:10px }

/* =====================================================================
   `.jx-lien` — le nom cliquable qui ouvre une fiche. 28 emplois dans cinq
   modules, et AUCUN style jusqu'au 26 aout 2026 : c'etait un <button> nu,
   donc peint avec le `buttonface` du navigateur. Un bouton nu n'est pas
   « sans fond », il a celui de l'UA — et il ne suit pas nos jetons.
   Il est desormais rendu pour ce qu'il est : du texte cliquable. Fond
   transparent (le calque passe derriere), encre heritee, et c'est le survol
   seul qui porte l'accent — 400 lignes en couleur d'accent seraient un
   tapis, pas un reperage.
   ===================================================================== */
.jx-lien {
  background: transparent;
  border: 0;
  padding: 1px 6px;
  margin: 0 -6px;
  border-radius: var(--r-s);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.jx-lien:hover { background: var(--accent-fond); color: var(--accent); }
.jx-lien:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ======================================================== STAR CITIZEN =====
   La page Star Citizen n'a pas d'icônes : elle porte des NIVEAUX et des
   encarts d'honnêteté. Ces deux familles-là, et rien d'autre.               */

/* ⚠ Un niveau se lit sur DEUX canaux, jamais sur la seule teinte. L'échelle
   demandée va du rouge foncé au vert en passant par l'orange et le jaune —
   c'est exactement le gradient qu'une deutéranopie (≈ 8 % des hommes) ne
   sépare pas. Les cinq crans portent donc la même information que la
   couleur, et le libellé est toujours écrit à côté. Retirer les crans, c'est
   rendre la colonne muette pour un lecteur sur douze.                       */
.sc-niv{display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
/* ⚠ LE LIBELLÉ N'EST PAS COLORÉ, ET C'EST MESURÉ. Peindre le texte à la
   couleur du niveau donnait 68 nœuds sous 4,5:1 en thème clair (pire : 2,48
   sur le jaune #8A7200), parce qu'un jaune lisible EST clair et que le fond
   des cartes l'est aussi. La couleur vit donc dans les crans — un objet
   graphique, tenu à 3:1 et non à 4,5 — et le texte garde l'encre ordinaire.
   Le double encodage y gagne : la couleur n'est plus le seul canal, elle
   n'est même plus le canal du texte. */
.sc-niv .t{color:var(--texte);font-variant-numeric:tabular-nums}
.sc-crans{display:inline-flex;gap:2px}
.sc-crans i{width:5px;height:12px;border-radius:1px;
  background:color-mix(in srgb, var(--texte-3) 26%, transparent)}
.sc-crans i.on{background:currentColor}
/* Teintes du thème CLAIR, choisies pour tenir 3:1 sur le fond composé des
   cartes (luminance mesurée ≈ 0,50 avec le calque photo dessous). Les valeurs
   « naturelles » — #C0392B, #B26A00, #8A7200, #1E7A3C — tombaient toutes
   entre 2,2 et 2,9. */
.sc-niv-tres-bas   { color:#8C1D18 }   /* 4,7:1 */
.sc-niv-bas        { color:#A62F23 }   /* 3,6:1 */
.sc-niv-moyen      { color:#8A5200 }   /* 3,3:1 */
.sc-niv-haut       { color:#6E5B00 }   /* 3,6:1 */
.sc-niv-tres-haut  { color:#17632F }   /* 3,9:1 */
html[data-theme="sombre"] .sc-niv-tres-bas,
html:not([data-theme="clair"]) body.auto-sombre .sc-niv-tres-bas  { color:#E06C63 }
html[data-theme="sombre"] .sc-niv-bas,
html:not([data-theme="clair"]) body.auto-sombre .sc-niv-bas       { color:#F07167 }
html[data-theme="sombre"] .sc-niv-moyen,
html:not([data-theme="clair"]) body.auto-sombre .sc-niv-moyen     { color:#F0A44E }
html[data-theme="sombre"] .sc-niv-haut,
html:not([data-theme="clair"]) body.auto-sombre .sc-niv-haut      { color:#E8CC57 }
html[data-theme="sombre"] .sc-niv-tres-haut,
html:not([data-theme="clair"]) body.auto-sombre .sc-niv-tres-haut { color:#5FCF87 }

/* Un encart dit ce que la page NE sait pas. Il se lit, donc il ne crie pas :
   filet à gauche, fond à peine teinté, pas de pictogramme d'alerte. */
.sc-encart{margin:8px 0;padding:9px 12px;border-radius:6px;font-size:13px;
  line-height:1.5;color:var(--texte-2);
  border-left:3px solid color-mix(in srgb, var(--texte-3) 45%, transparent);
  background:color-mix(in srgb, var(--creux-pur) 40%, transparent)}
.sc-encart.ok        { border-left-color:var(--ok) }
.sc-encart.attention { border-left-color:var(--accent-2) }
.sc-desc{margin:8px 0 2px;font-size:13px;line-height:1.55;color:var(--texte-2);
  max-width:74ch}
/* La matrice du raffinage : trois vitesses par trois qualités. La première
   colonne est un en-tête de ligne, pas une donnée — elle ne se trie pas. */
.sc-matrice td:first-child{white-space:nowrap;color:var(--texte-2)}
.sc-matrice .bouton{width:100%;justify-content:center}
/* Vignettes des commodités : des SVG tirés du p4k.

   ⚠ ELLES SONT EN BLANC PUR — `fill="#FFFFFF"` et rien d'autre. Sur le thème
   clair elles disparaissent purement et simplement, et rien ne le signale :
   l'image se charge, `naturalWidth` est bon, la balise est là. Un fond de
   pastille derrière ne suffit pas non plus — il faut INVERSER le glyphe, qui
   est monochrome et se prête exactement à ça. En sombre on n'y touche pas :
   du blanc sur fond noir est déjà ce qu'on veut.

   La place est réservée même sans icône (72 commodités sur 135 n'en déclarent
   aucune dans le jeu), sinon la colonne se désaligne d'une ligne à l'autre. */
.sc-nom{display:inline-flex;align-items:center;gap:8px}
.sc-ico{flex:none;display:inline-block;vertical-align:middle}
html[data-theme="clair"] img.sc-ico,
html:not([data-theme="sombre"]) body:not(.auto-sombre) img.sc-ico{
  filter:invert(1) opacity(.78)}
.sc-tete{display:flex;align-items:flex-start;gap:12px}
