/* ===========================================================================
   Maquette v3 — « Studio »

   Trois volets : ce que je veux a gauche, le stuff au centre, le detail a
   droite. Ce que la v1 n'avait pas, et qui compte plus que la mise en page :

   1. UN ECRAN VIDE. Un debutant devait comprendre huit concepts avant
      d'obtenir quoi que ce soit. Ici il choisit sa classe, et c'est tout :
      niveau, sorts d'attaque et planchers de PA et PM sont poses pour lui.

   2. LE VOCABULAIRE DU JOUEUR. « Mode de recherche », « conditions »,
      « figer la reference » sont des mots de l'outil. « Ce que je veux »,
      « au minimum », « mon stuff actuel » sont des mots du joueur.

   3. LA COURBE SOUS LE CURSEUR. Le curseur mixte et la courbe degats/survie
      sont deux vues du meme reglage : elles se touchent, et l'une pilote
      l'autre. Separees par deux metres d'ecran, aucune ne se comprenait.

   4. L'INSPECTEUR OUVRE HUIT LIGNES, pas trente-neuf. Un mur de chiffres ne
      se lit pas, il se subit. « Tout voir » donne le reste.

   5. LA COMPARAISON N'EST PAS UNE PAGE. Cocher un stuff trouve l'ouvre, et
      elle masque les lignes identiques : ce qui ne change pas n'aide pas a
      choisir.

   Le bouton « Chercher » reste : la recherche est longue, elle se lance quand
   le joueur le decide. Il signale en revanche que les reglages ont bouge
   depuis la derniere fois — l'oubli etait la vraie gene, pas le clic.
   La coquille tient en cinq feuilles, chargees dans cet ordre par
   index.html : coquille.css (mise en page), coquille-feuilles.css,
   coquille-blocs.css, coquille-corrections.css et coquille-telephone.css.
   L'ordre est la cascade : une regle plus bas l'emporte a specificite egale.
   =========================================================================== */

/* ---------------------------------------------------------- Ecran vide --- */

.accueil { display: grid; place-items: center; min-height: calc(100vh - var(--barre-h)); padding: 40px 20px; }
.accueil-carte { width: 100%; max-width: 640px; text-align: center; }
.accueil h1 { margin: 0 0 6px; font-size: 22px; font-weight: 600; letter-spacing: -0.4px; }
.accueil p { margin: 0 0 28px; font-size: 13px; color: var(--texte-2); }
.classes { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 6px; }
.classe {
  display: grid; justify-items: center; gap: 6px;
  padding: 12px 6px 10px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--filet);
  color: var(--texte-2); font: 11.5px/1 var(--ui); cursor: pointer;
}
.classe:hover { background: var(--surface-2); border-color: var(--filet-clair); color: var(--texte); }
.classe img { width: 34px; height: 34px; object-fit: contain; }
.accueil .apres { margin: 26px 0 0; font-size: 11.5px; color: var(--texte-3); }

/* ------------------------------------------------------------- Volets --- */

/* La barre peut passer a la ligne : sa hauteur n'est plus connue d'avance.
   L'atelier prend donc ce qui reste sous elle, mesure par le navigateur. */
.appli {
  display: grid;
  grid-template-columns: var(--col-gauche, 300px) minmax(0, 1fr) var(--col-droite, 340px);
  height: calc(100dvh - var(--barre-h));
  min-height: 0;
}

/* Un volet replie ne prend plus de place : sa colonne tombe a zero, et le
   milieu recupere tout. La largeur passe par une variable pour que le repli
   n'ait qu'UN endroit a changer, quelle que soit la taille de l'ecran. */
.appli.gauche-replie { --col-gauche: 0px; }
.appli.droit-replie { --col-droite: 0px; }
.appli.gauche-replie .volet-gauche,
.appli.droit-replie .volet-droit { display: none; }

.volet { overflow-y: auto; min-width: 0; }
.volet-gauche { border-right: 1px solid var(--filet); background: var(--surface); }
.volet-droit { border-left: 1px solid var(--filet); background: var(--surface); }
/* Le milieu ne s'etire pas sans fin : replier les deux volets lui donnait
   toute la fenetre, et le verdict se retrouvait a trois cents pixels du
   personnage qu'il decrit. Une largeur de lecture, centree, garde les memes
   distances quelle que soit la fenetre. */
.scene { max-width: 1180px; margin: 0 auto; padding: 20px 28px 40px; }

/* Le milieu se mesure lui-meme : c'est sa largeur qui decide de la mise en
   page du verdict, pas celle de la fenetre. Voir la requete de conteneur
   « scene », plus bas. */
main.volet { container-type: inline-size; container-name: scene; }

/* ---------- Barre haute ---------- */

.score-vif { display: flex; align-items: baseline; gap: 7px; }
.score-vif b { font: 620 19px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.5px; }
.score-vif span { font-size: 11px; color: var(--texte-3); }

/* Les commandes passent a la ligne comme la barre qui les porte. Sans cela,
   elles sortaient de l'ecran des que la fenetre retrecissait : le bandeau se
   repliait autour d'un bloc qui, lui, restait sur une seule ligne. */
#barre-droite { flex-wrap: wrap; }

/* Le bouton dit s'il y a quelque chose a relancer : oublier de relancer
   apres un reglage est la gene la plus frequente, et elle est muette. */
.btn.premier.rappel { box-shadow: 0 0 0 3px color-mix(in srgb, var(--ambre) 24%, transparent); }
.btn .puce { width: 6px; height: 6px; border-radius: 999px; background: var(--ambre); }

.pulse { display: inline-flex; gap: 3px; align-items: center; }
.pulse i { width: 3px; height: 12px; border-radius: 2px; background: var(--iris); animation: respire 1s ease-in-out infinite; }
.pulse i:nth-child(2) { animation-delay: .12s } .pulse i:nth-child(3) { animation-delay: .24s }
.pulse i:nth-child(4) { animation-delay: .36s }
@keyframes respire { 0%, 100% { opacity: .25 } 50% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .pulse i { animation: none; opacity: .7 } }

/* ---------- Volet gauche ---------- */

.section { padding: 14px 14px 16px; border-bottom: 1px solid var(--filet); }
.section:last-child { border-bottom: 0; }
.aide { margin: 8px 0 0; font-size: 11px; line-height: 1.45; color: var(--texte-3); }

.consequence {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 10px; padding: 8px 10px;
  background: var(--surface-2); border-radius: var(--r);
}
.consequence b { font: 560 14px/1 var(--mono); font-variant-numeric: tabular-nums; }
.consequence em { font-style: normal; font-size: 10px; color: var(--texte-3); margin-left: 4px; }

.mini-courbe { width: 100%; height: 86px; display: block; margin-top: 10px; cursor: crosshair; }

.limite {
  /* Sept colonnes : la pastille, l'icone, le nom, la valeur atteinte, la
     barre, l'objectif reglable, la croix. */
  display: grid; grid-template-columns: 6px 15px minmax(0, 1fr) auto auto auto 18px;
  align-items: center; gap: 6px;
  height: 30px; padding: 0 6px; margin: 0 -6px; border-radius: var(--r);
}
.limite:hover { background: var(--surface-2); }
.limite-nom { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.limite-val { font: 12px/1 var(--mono); font-variant-numeric: tabular-nums; }
.limite-val em { font-style: normal; color: var(--texte-3); margin-right: 3px; }
.limite-reel { font: 11px/1 var(--mono); font-variant-numeric: tabular-nums; width: 44px; text-align: right; }
.limite .oter { visibility: hidden; border: 0; background: none; color: var(--texte-3); cursor: pointer; padding: 0; }
.limite:hover .oter { visibility: visible; }
.limite .oter:hover { color: var(--rose); }

.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 8px 0 4px; border-radius: 5px;
  background: var(--surface-2); border: 1px solid var(--filet);
  font-size: 11.5px; color: var(--texte); cursor: pointer;
}
.chip:hover { border-color: var(--filet-clair); }
.chip img { width: 16px; height: 16px; border-radius: 3px; }
.chip.ajout { border-style: dashed; color: var(--texte-2); padding: 0 9px; }

.avoir { display: grid; gap: 6px; }
.avoir-ligne {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px; background: var(--surface-2); border-radius: var(--r); font-size: 12px;
}
.avoir-ligne b { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 560; }
/* Voir la liste et defaire la liste sont deux gestes distincts : le second
   tient dans un bouton de cote, pour qu'un clic distrait n'efface rien. */
.avoir-rangee { display: flex; align-items: stretch; gap: 6px; }
.avoir-rangee > .avoir-ligne { flex: 1; min-width: 0; }
.avoir-rangee > .btn { flex: none; align-self: stretch; }

/* ---------- Centre ---------- */

.plateau { display: grid; grid-template-columns: auto auto auto; gap: 10px; justify-content: center; align-items: start; }
.rangee-slots { display: grid; gap: 6px; }
.slot {
  width: 46px; height: 46px; border-radius: 8px; padding: 0;
  background: var(--surface-2); border: 1px solid var(--filet);
  display: grid; place-items: center; cursor: pointer; position: relative;
}
.slot:hover { border-color: var(--filet-clair); background: var(--surface-3); }
.slot.choisi { border-color: var(--iris); box-shadow: 0 0 0 3px color-mix(in srgb, var(--iris) 20%, transparent); }
.slot img { width: 34px; height: 34px; object-fit: contain; }
.slot.vide::after { content: ""; width: 14px; height: 14px; border: 1px dashed var(--filet-clair); border-radius: 4px; }

.avatar {
  width: 196px; height: 206px; border-radius: var(--r-lg);
  background: radial-gradient(120% 90% at 50% 15%, var(--surface-3), var(--surface) 70%);
  border: 1px solid var(--filet);
  display: grid; place-items: end center; overflow: hidden;
}
.avatar img { max-height: 188px; filter: drop-shadow(0 8px 16px var(--ombre)); }
.artefacts { display: flex; gap: 6px; justify-content: center; margin-top: 10px; }

.verdict { display: grid; grid-template-columns: repeat(3, 1fr); margin: 22px 0 0; }
.verdict > div { padding: 0 16px; border-left: 1px solid var(--filet); }
.verdict > div:first-child { border-left: 0; padding-left: 0; }
.verdict dt { font-size: 10px; font-weight: 640; letter-spacing: .8px; text-transform: uppercase; color: var(--texte-3); margin-bottom: 4px; }
.verdict dd { margin: 0; font: 600 30px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -1.2px; }
.verdict small { display: block; margin-top: 7px; font-size: 11px; line-height: 1.4; color: var(--texte-3); }
.verdict button.pourquoi {
  margin-top: 7px; padding: 0; border: 0; background: none; cursor: pointer;
  font: 11px/1.4 var(--ui); color: var(--texte-3); text-align: left;
}
.verdict button.pourquoi { border-bottom: 1px dotted var(--filet-clair); }
.verdict button.pourquoi:hover { color: var(--iris); border-bottom-color: var(--iris); }

/* Les pas suivants SONT l'interface, pas une visite guidee : ils disent en
   mots de joueur ce qu'il reste a faire, et s'effacent une fois faits. */
.pas-suivants { display: flex; flex-wrap: wrap; gap: 6px; margin: 22px 0 0; }
.pas {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--filet-clair);
  color: var(--texte); font: 12px/1 var(--ui); cursor: pointer;
}
.pas:hover { background: var(--surface-2); border-color: var(--iris); }
.pas em { font-style: normal; color: var(--texte-3); }

.regle { height: 1px; background: var(--filet); margin: 26px 0 14px; }
.tete-resultats { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }

.trouve {
  display: grid; grid-template-columns: 20px 70px 70px minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 9px 10px; margin: 0 -10px;
  border-radius: var(--r); cursor: pointer; border-top: 1px solid transparent;
}
.trouve + .trouve { border-top-color: var(--filet); }
.trouve:hover { background: var(--surface); }
.trouve.choisi { background: var(--iris-fond); }
.trouve input { width: 15px; height: 15px; accent-color: var(--iris); cursor: pointer; opacity: 0; margin: 0; }
.trouve:hover input, .trouve input:checked, .trouve input:focus-visible { opacity: 1; }
.trouve-mesure { font: 560 13px/1 var(--mono); font-variant-numeric: tabular-nums; }
.trouve-mesure span { display: block; margin-top: 3px; font: 400 10px/1 var(--ui); color: var(--texte-3); }
.echange { display: flex; align-items: center; gap: 3px; flex-wrap: wrap; }
.echange img { width: 22px; height: 22px; border-radius: 4px; background: var(--surface-2); }
.echange .fleche { color: var(--texte-3); font-size: 11px; margin: 0 1px; }
.achats { font: 11px/1 var(--mono); color: var(--texte-2); white-space: nowrap; }

/* ---------- Volet droit ---------- */

.inspecteur-tete {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 14px;
  background: var(--surface); border-bottom: 1px solid var(--filet);
  font-size: 12px; font-weight: 560;
}
.inspecteur-tete .quoi { color: var(--texte-2); font-weight: 400; }
.inspecteur-tete .retour { border: 0; background: none; color: var(--texte-3); cursor: pointer; padding: 0 2px 0 0; font-size: 15px; line-height: 1; }
.inspecteur-tete .retour:hover { color: var(--texte); }

/* Le creux de huit pixels est celui du surlignage, pas une marge de texte :
   la ligne peint son fond a l'interieur du volet.

   Elle debordait de six pixels a gauche, par une marge negative. Un volet qui
   defile verticalement ne peut rien montrer de ce qui sort a gauche : le
   surlignage y etait coupe net, et la fiche paraissait tronquee. */
.lignes { padding: 4px 8px 14px; }
.ligne {
  display: grid; grid-template-columns: 16px minmax(0, 1fr) auto auto;
  align-items: center; gap: 8px;
  height: 25px; padding: 0 6px; border-radius: 4px; cursor: pointer;
}
.ligne:hover { background: var(--surface-2); }
.ligne:hover .ligne-geste { opacity: 1; }
.ligne img { width: 14px; height: 14px; object-fit: contain; }
.ligne-nom { font-size: 12px; color: var(--texte-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ligne-val { font: 12px/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--texte); }
.ligne-val.zero { color: var(--texte-3); }
.ligne-val.neg { color: var(--rose); }
.ligne-val.pos { color: var(--jade); }
.ligne-geste { opacity: 0; font-size: 10px; color: var(--iris); white-space: nowrap; }
.groupe { padding: 14px 8px 2px; }

/* Un titre de famille coiffe une dizaine de lignes : il porte un filet et
   respire plus qu'un simple separateur de trois lignes. */
.chapeau.famille {
  padding: 16px 6px 6px; margin: 6px 0 0;
  border-top: 1px solid var(--filet); color: var(--texte-2);
}
.lignes > .chapeau.famille:first-child { border-top: 0; padding-top: 4px; margin-top: 0; }
.sans-icone .ligne { grid-template-columns: minmax(0, 1fr) auto; }

.fiche-piece { padding: 14px; }
.fiche-piece header { display: flex; gap: 11px; align-items: flex-start; margin-bottom: 14px; }
.fiche-piece header img { width: 46px; height: 46px; border-radius: 8px; background: var(--surface-2); }
.fiche-piece h3 { margin: 0 0 2px; font-size: 14px; font-weight: 600; }
.fiche-piece .meta { font-size: 11px; color: var(--texte-3); }
.gestes { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 16px; }

/* ---------- La comparaison ---------- */

.voile {
  position: fixed; inset: 0; z-index: 40;
  background: var(--voile); backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 30px;
}
.voile[hidden] { display: none; }
.comparaison {
  width: min(1240px, 100%); max-height: 100%;
  display: flex; flex-direction: column;
  background: var(--fond); border: 1px solid var(--filet-clair); border-radius: var(--r-lg);
  box-shadow: 0 24px 64px var(--ombre); overflow: hidden;
}
.comparaison-tete { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--filet); }
.comparaison-tete h2 { margin: 0; font-size: 14px; font-weight: 600; }
.comparaison-corps { overflow: auto; }

table { border-collapse: separate; border-spacing: 0; width: 100%; }
th, td { text-align: right; padding: 0 14px; height: 28px; }
.mesure {
  position: sticky; left: 0; z-index: 2; background: var(--fond);
  text-align: left; font-size: 12px; font-weight: 400; color: var(--texte-2);
  border-right: 1px solid var(--filet); white-space: nowrap; min-width: 190px;
}
tbody tr:hover td { background: var(--surface); }
tbody tr:hover .mesure { color: var(--texte); background: var(--surface); }
thead th {
  position: sticky; top: 0; z-index: 3; background: var(--fond);
  border-bottom: 1px solid var(--filet); padding: 12px 14px 10px; vertical-align: top; min-width: 160px; height: auto;
}
thead th.mesure { z-index: 4; }
thead th.porte, td.porte { background: var(--surface); }
tbody tr:hover td.porte { background: var(--surface-2); }
.tete-nom { display: flex; align-items: center; gap: 7px; justify-content: flex-end; font-size: 11px; font-weight: 640; letter-spacing: .7px; text-transform: uppercase; color: var(--texte-3); }
.tete-nom .marqueur { width: 6px; height: 6px; border-radius: 999px; background: var(--jade); }
.tete-score { margin: 7px 0 8px; font: 600 21px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.8px; }
.tete-pieces { display: flex; gap: 2px; justify-content: flex-end; margin-bottom: 9px; }
.tete-pieces img { width: 19px; height: 19px; border-radius: 3px; background: var(--surface-2); }
.tete-pieces img.neuf { box-shadow: 0 0 0 1.5px var(--ambre); }
td { font: 12px/1 var(--mono); font-variant-numeric: tabular-nums; }
tr.titre th, tr.titre td {
  height: 30px; padding-top: 16px;
  font: 640 10px/1 var(--ui); letter-spacing: .8px; text-transform: uppercase;
  color: var(--texte-3); border-top: 1px solid var(--filet); background: var(--fond);
}
.ecart-pos { color: var(--jade); } .ecart-neg { color: var(--rose); } .ecart-nul { color: var(--texte-3); }
.masquees { padding: 10px 16px; font-size: 11.5px; color: var(--texte-3); border-top: 1px solid var(--filet); }
.masquees button { border: 0; background: none; color: var(--iris); cursor: pointer; font: inherit; padding: 0; }

/* Une option qui change ce qu'un nombre VEUT DIRE se lit a cote de ce
   nombre. « Arme comprise » et « melee » definissent les degats ; le coup de
   reference et le plafond definissent les pdv effectifs. Les seize autres
   options partent dans les reglages : elles ne changent pas la lecture. */
.options-mesure { display: grid; gap: 5px; margin-top: 9px; }
.option {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--texte-2); cursor: pointer;
}
.option input { width: 13px; height: 13px; accent-color: var(--iris); margin: 0; cursor: pointer; }
.option:hover { color: var(--texte); }
.option-val {
  display: inline-flex; align-items: baseline; gap: 6px;
  font-size: 11px; color: var(--texte-3);
}
.option-val input {
  width: 46px; height: 20px; padding: 0 5px;
  font: 11px/1 var(--mono); text-align: right;
}
.radios { display: inline-flex; gap: 10px; }

/* Le segmente grise ses choix tant qu'aucun sort n'est pose : sans degats a
   compter, aucun d'eux ne veut dire quoi que ce soit. */
.segmente.inactif { opacity: .45; }
.segmente.inactif button { cursor: not-allowed; }

/* Les objectifs passent a la ligne plutot que de sortir du volet.
   Le quatrieme — « Monter » — ne tenait plus sur une seule rangee dans un
   volet de deux cent trente pixels : il se coupait au bord, et le joueur ne
   pouvait ni le lire ni le cliquer. Deux rangees de deux valent mieux qu'un
   choix invisible. */
#objectif { flex-wrap: wrap; }
#objectif button { flex: 1 1 calc(50% - 2px); min-width: 0; }

.vide-mesure { color: var(--texte-3); }
.appel {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px; padding: 0; border: 0; background: none; cursor: pointer;
  font: 11px/1.4 var(--ui); color: var(--iris);
  border-bottom: 1px solid var(--iris-sourd);
}
.appel:hover { border-bottom-color: var(--iris); }

.pas.premier-pas { border-color: var(--iris); background: var(--iris-fond); }

/* La feuille des points : les curseurs, les parchemins et les limites ont
   besoin de place. L'inspecteur ne la leur donnait pas. */
.feuille { width: min(560px, 100%); }
.points-ligne {
  display: grid; grid-template-columns: 16px 88px minmax(0, 1fr) 54px 42px 58px;
  align-items: center; gap: 10px;
  height: 34px; padding: 0 8px; margin: 0 -8px; border-radius: var(--r);
}
.points-ligne:hover { background: var(--surface); }
.points-ligne img { width: 14px; height: 14px; }
.points-ligne > span:nth-child(2) { font-size: 12px; }
.points-ligne input[type="range"] { height: 14px; }
.points-ligne input[type="range"]::-webkit-slider-runnable-track { background: var(--surface-3); }
.points-bilan {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 10px 14px; background: var(--surface); border-radius: var(--r); margin-bottom: 12px;
}
.points-bilan b { font: 600 18px/1 var(--mono); font-variant-numeric: tabular-nums; }

@media (max-width: 1500px) { .appli { grid-template-columns: 276px minmax(0, 1fr) 312px; } }
/* Un trace de sept cents pixels sur cent trente est un fil : la courbe s'y
   aplatit, et deux generations voisines ne se distinguent plus. La hauteur
   suit donc la largeur, entre deux bornes — assez haut pour lire une pente,
   jamais au point de pousser les stuffs trouves hors de l'ecran. */
.graphe-v2 {
  width: 100%; display: block; margin: 0;
  aspect-ratio: 16 / 5; min-height: 150px; max-height: 250px;
}

/* ==================================== Quand l'ecran retrecit ===

   Les trois colonnes tiennent jusqu'a mille deux cent quarante pixels. En
   dessous, elles etranglent celle du milieu : le personnage, le trace et les
   stuffs trouves se serraient dans quatre cents pixels pendant que deux
   listes de reglages en occupaient six cents.

   Les volets ne s'empilent plus sous le milieu — il fallait defiler huit
   cents pixels pour voir le stuff. Ils passent PAR-DESSUS, a la demande,
   depuis la barre du haut, et le milieu garde toute la largeur.

   Voir web/v2/volets.mjs : c'est lui qui pose « volets-flottants », et qui
   ferme l'un quand l'autre s'ouvre. */

.volets-voile {
  position: fixed; inset: var(--barre-h) 0 0 0; z-index: 24;
  background: var(--voile);
}

@media (max-width: 1240px) {
  /* Le milieu prend toute la place : les volets flottants n'en occupent
     aucune dans la grille. */
  .appli { grid-template-columns: minmax(0, 1fr); }

  .appli .volet-gauche, .appli .volet-droit {
    position: fixed; top: var(--barre-h); bottom: 0; z-index: 25;
    width: min(330px, 86vw); max-height: none;
    box-shadow: 0 0 40px var(--ombre);
  }
  .appli .volet-gauche { left: 0; border-right: 1px solid var(--filet-clair); }
  .appli .volet-droit { right: 0; border-left: 1px solid var(--filet-clair); }

  /* Replie veut dire absent, a toutes les largeurs : c'est la meme regle
     plus haut qui s'applique, et il n'y a rien a redire ici. */
}

/* Le trace de la recherche a toute la largeur de la page : il peut donc
   monter un peu plus haut sans repousser quoi que ce soit. */
@media (max-width: 1240px) {
  .graphe-v2 { aspect-ratio: 5 / 2; }
}

.rangee-artefacts {
  grid-column: 1 / -1;
  display: flex; gap: 8px; justify-content: center; margin-top: 10px;
}
.colonne-cases { display: flex; flex-direction: column; gap: 8px; }
.avatar-v2 {
  width: 190px; height: 250px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--filet); border-radius: var(--r-lg);
}
.avatar-v2 img { max-width: 100%; max-height: 100%; object-fit: contain; }

.case-slot {
  width: 46px; height: 46px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px solid var(--filet);
  border-radius: var(--r); cursor: pointer; color: var(--texte-3);
}
.case-slot:hover { border-color: var(--filet-clair); }
.case-slot img { width: 38px; height: 38px; object-fit: contain; }
/* La couleur ne porte jamais seule : le lisere double la pastille. */
.case-slot.vide { cursor: default; border-style: dashed; }
.case-slot.pose { border-color: var(--ambre); }
.case-slot.verrou { border-color: var(--iris); }

.limite {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 5px 0; border-bottom: 1px solid var(--filet);
  font-size: 12px; color: var(--texte-2);
}
.limite b { color: var(--texte); }

.fils { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.fil { font: 11px/1 var(--mono); color: var(--texte-3); }

/* Le message se pose au-dessus de tout : une erreur de chargement doit se
   lire meme quand l'ecran vide occupe la page entiere. */
/* Le message est un passager, pas un obstacle.

   Colle au centre du bas, il recouvrait la liste des stuffs trouves pendant
   toute sa duree de vie — et un clic dessus ne tombait pas sur la ligne
   visee. Il se range donc dans le coin, hors de la colonne centrale, et
   laisse passer la souris. */
.message-v2 {
  position: fixed; right: 18px; bottom: 18px;
  z-index: 60; padding: 8px 14px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--filet-clair);
  box-shadow: 0 6px 20px var(--ombre);
  font-size: 12px; color: var(--texte-2); max-width: min(40vw, 380px);
  pointer-events: none;
}
.message-v2:empty { display: none; }
.message-v2.erreur { border-color: var(--rose); color: var(--rose); }

/* La fiche porte une icone par ligne : la grille de `.ligne` reserve sa
   premiere colonne pour elle. Sans image, le libelle y tomberait et se
   couperait a une lettre. */
.ligne-icone { width: 16px; height: 16px; object-fit: contain; }
.ligne-icone[src=""] { visibility: hidden; }


/* Un minimum montre sa valeur observee et sa cible. Le point double la
   couleur : un minimum en defaut ne doit pas dependre du seul rouge. */
.limite { gap: 8px; }
.limite-nom { flex: 1; min-width: 0; }
.limite.defaut b { color: var(--rose); }
