/* ══════════════════════════════════════════════════
   RAPLAY — Compte joueur
   Écran de connexion / inscription, et présence du compte dans la navigation.
   Les boutons (.btn, .btn-purple) viennent de style.css.
   ══════════════════════════════════════════════════ */

/* ── Écran de connexion ─────────────────────────────────────────────────── */
/* La page occupe au moins toute la hauteur : le contenu se centre dans
   l'espace restant, et le pied de page se pose en bas plutôt que de flotter
   au milieu d'un écran d'ordinateur. */
.cpt-page{min-height:100vh;display:flex;flex-direction:column;}
/* Le bandeau est en position:fixed : sans cette marge haute, le titre passe
   dessous. Même mécanique que .bt-wrap dans blindtest.css. */
.cpt-wrap{flex:1;display:flex;flex-direction:column;justify-content:center;
  width:100%;max-width:420px;margin:0 auto;
  padding:calc(var(--nav-h) + 34px) 20px 46px;}
.cpt-titre{font-family:var(--font-display);font-weight:900;font-size:1.75rem;letter-spacing:-0.06em;
  text-transform:uppercase;color:var(--text);text-align:center;margin-bottom:10px;line-height:1.05;}
.cpt-sous{font-size:0.87rem;color:var(--text-muted);text-align:center;line-height:1.5;margin-bottom:26px;}
.cpt-carte{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:24px 20px;}
.cpt-label{display:block;font-family:var(--font-mono);font-size:0.6rem;letter-spacing:0.18em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:8px;}
.cpt-groupe{margin-bottom:16px;}
/* 1rem = 16 px : en dessous, iOS zoome tout seul quand le champ prend le focus. */
.cpt-champ{width:100%;background:var(--surface2);border:1px solid var(--border);border-radius:8px;
  padding:13px 14px;color:var(--text);font-family:var(--font-body);font-size:1rem;
  transition:border-color .25s ease,box-shadow .25s ease;}
.cpt-champ::placeholder{color:var(--text-muted);}
/* Afficher / masquer le mot de passe. Le champ laisse la place au bouton,
   sinon le texte passerait dessous en fin de saisie. */
.cpt-mdp{position:relative;}
.cpt-mdp .cpt-champ{padding-right:50px;}
.cpt-oeil{position:absolute;top:0;right:0;height:100%;width:46px;
  display:flex;align-items:center;justify-content:center;
  background:none;border:none;cursor:pointer;color:var(--text-muted);
  transition:color .25s ease;}
.cpt-oeil i{width:19px;height:19px;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
/* Mot de passe visible : l'œil s'allume, pour que l'état se lise d'un coup. */
.cpt-oeil.vu{color:var(--purple-light);}
/* Anneau de focus en box-shadow, jamais en bordure : le reset global est en
   border-box, épaissir la bordure décalerait le contenu du champ. */
.cpt-champ:focus{outline:none;border-color:var(--purple);box-shadow:var(--glow-violet);}
/* Exigences du mot de passe : annoncées AVANT la saisie, pas découvertes par
   un refus. Elles passent au vert dès qu'elles sont remplies. */
.cpt-aide{display:flex;align-items:flex-start;gap:7px;margin-top:8px;
  font-family:var(--font-mono);font-size:0.64rem;line-height:1.5;color:var(--text-muted);
  transition:color .25s ease;}
.cpt-aide i{width:12px;height:12px;flex-shrink:0;margin-top:2px;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;
  opacity:0.4;transition:opacity .25s ease;}
.cpt-aide.ok{color:var(--green,#99FF33);}
.cpt-aide.ok i{opacity:1;}
.cpt-action{width:100%;justify-content:center;padding:14px;margin-top:4px;}
.cpt-action[disabled]{opacity:0.5;pointer-events:none;}
.cpt-ou{display:flex;align-items:center;gap:12px;margin:20px 0;font-family:var(--font-mono);
  font-size:0.58rem;letter-spacing:0.2em;text-transform:uppercase;color:var(--text-muted);}
.cpt-ou::before,.cpt-ou::after{content:"";flex:1;height:1px;background:var(--border);}
.cpt-google{width:100%;justify-content:center;gap:10px;padding:13px;background:var(--surface2);
  border:1px solid var(--border);color:var(--text);font-weight:700;}
/* Le logo Google, en image et non en masque : il est multicolore, un masque le
   repeindrait d'une seule teinte — ce que la charte de Google interdit. C'est
   la seule exception au motif --picto du site, elle est donc explicite.
   flex:none : sans lui le bouton, qui est en flex, écraserait le logo quand le
   libellé s'allonge. */
.cpt-google-i{width:18px;height:18px;flex:none;display:block;}
.cpt-bas{text-align:center;margin-top:20px;font-size:0.84rem;color:var(--text-muted);line-height:1.7;}
.cpt-bas a{color:var(--purple-light);text-decoration:none;}
/* Zone tactile de 44 px : un lien de 16 px de haut ne se vise pas au pouce.
   C'est le rembourrage qui l'espace, pas une marge. */
.cpt-lien-row{text-align:right;margin-top:-14px;margin-bottom:2px;}
/* La ligne porte désormais deux éléments : la case à gauche, le lien à droite. */
.cpt-lien-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;}
.cpt-case{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  min-height:36px;font-family:var(--font-body);font-size:0.82rem;color:var(--text-muted);}
/* 18px et non la case native : celle du système ignore la charte et change de
   taille d'un navigateur à l'autre. accent-color suffit à la teinter sans
   reconstruire une case en CSS, qui perdrait le clavier. */
.cpt-case input{width:18px;height:18px;margin:0;flex-shrink:0;
  accent-color:var(--purple);cursor:pointer;}
.cpt-case:hover span{color:var(--text);}
.cpt-lien{display:inline-flex;align-items:center;min-height:44px;padding:0 2px;
  font-size:0.78rem;color:var(--text-muted);text-decoration:none;}
.cpt-msg{margin-top:16px;padding:11px 12px;border-radius:8px;font-family:var(--font-mono);
  font-size:0.68rem;line-height:1.5;display:none;}
.cpt-msg.erreur{display:block;color:var(--red);background:rgba(249,38,89,0.07);
  border:1px solid rgba(249,38,89,0.25);}
.cpt-msg.info{display:block;color:var(--purple-light);background:rgba(109,40,217,0.07);
  border:1px solid rgba(109,40,217,0.25);}
/* La question posée quand l'adresse saisie a l'air morte. Orange et non rouge :
   ce n'est pas un refus, c'est un doute - le rouge de .cpt-msg.erreur reste
   réservé à ce que Supabase a vraiment rejeté. */
.cpt-msg.verif{display:block;color:var(--orange);background:rgba(255,169,40,0.07);
  border:1px solid rgba(255,169,40,0.28);}
.cpt-msg-btns{display:flex;flex-wrap:wrap;gap:8px;margin-top:11px;}
/* 44 px : ces deux boutons décident de la suite d'une inscription, ils se
   visent au pouce. */
.cpt-msg-btns button{min-height:44px;padding:0 14px;border-radius:8px;cursor:pointer;
  font-family:var(--font-mono);font-size:0.62rem;letter-spacing:0.08em;text-transform:uppercase;}
.cpt-msg-oui{background:var(--orange);border:none;color:#20130A;font-weight:700;}
.cpt-msg-non{background:transparent;border:1px solid var(--border);color:var(--text-muted);}
/* Survol sous @media (hover:hover) : sinon l'effet reste collé après un tap
   sur iOS. */
@media (hover:hover){
  .cpt-msg-oui:hover{filter:brightness(1.08);}
  .cpt-msg-non:hover{color:var(--text);border-color:var(--purple-dim);}
}
/* Sur un écran étroit, les deux boutons prennent toute la largeur plutôt que
   de se serrer l'un contre l'autre. */
@media (max-width:600px){
  .cpt-msg-btns button{flex:1;}
}
/* Encadré d'explication : violet charte, pas le rouge de .cpt-msg qui est
   réservé aux vrais refus. */
.cpt-note{display:flex;gap:9px;align-items:flex-start;margin-top:18px;padding:11px 12px;
  border:1px solid rgba(109,40,217,0.25);background:rgba(109,40,217,0.06);border-radius:8px;
  font-family:var(--font-mono);font-size:0.66rem;line-height:1.55;color:var(--text-muted);}
.cpt-note i{width:14px;height:14px;flex-shrink:0;margin-top:2px;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.cpt-envoye{text-align:center;}
.cpt-envoye .cpt-pic{width:44px;height:44px;margin:0 auto 16px;background:var(--purple-light);
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}

/* ── Le compte dans la navigation ───────────────────────────────────────── */
.nav-compte{display:flex;align-items:center;gap:14px;}
.nav-connexion{display:inline-flex;align-items:center;min-height:44px;padding:0 14px;
  font-family:var(--font-body);font-size:0.82rem;font-weight:700;color:var(--purple-light);
  border:1px solid var(--purple-dim);border-radius:8px;text-decoration:none;white-space:nowrap;}
/* Avatar : anneau en box-shadow pour la même raison que le champ ci-dessus. */
.av{position:relative;width:36px;height:36px;border-radius:50%;flex-shrink:0;border:none;padding:0;
  background:linear-gradient(135deg,var(--purple),var(--purple2));
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  box-shadow:0 0 0 2px var(--purple-dim);transition:box-shadow .25s ease;}
.av-txt{font-family:var(--font-display);font-weight:900;font-size:0.72rem;color:#fff;letter-spacing:-0.04em;}
.av-niv{position:absolute;bottom:-5px;left:50%;transform:translateX(-50%);
  background:var(--bg);border:1px solid var(--purple);border-radius:20px;padding:1px 5px;
  font-family:var(--font-mono);font-size:0.5rem;font-weight:700;color:var(--purple-light);line-height:1.3;}
.av-boite{position:relative;}
.av-menu{position:absolute;top:calc(100% + 12px);right:0;width:230px;background:var(--surface);
  border:1px solid var(--border);border-radius:12px;padding:8px;z-index:60;display:none;
  box-shadow:0 18px 40px rgba(0,0,0,0.5);}
.av-menu.ouvert{display:block;}
.av-menu-tete{padding:10px 10px 12px;border-bottom:1px solid var(--border);margin-bottom:6px;}
.av-menu-nom{font-weight:800;font-size:0.9rem;color:var(--text);}
.av-menu-sous{font-family:var(--font-mono);font-size:0.6rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);margin-top:3px;}
.av-menu a{display:flex;align-items:center;gap:10px;min-height:44px;padding:0 10px;border-radius:8px;
  font-size:0.86rem;color:var(--text);text-decoration:none;}
.av-menu i{width:15px;height:15px;background:currentColor;flex-shrink:0;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.av-jauge{height:4px;border-radius:99px;background:var(--xp-dark);margin-top:8px;overflow:hidden;}
.av-jauge span{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--xp),var(--xp-light));}

/* ── Barre du bas, mobile connecté ──────────────────────────────────────── */
/* Affichée hors partie seulement : en jeu, l'écran appartient au jeu. */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:none;
  grid-template-columns:repeat(5,1fr);align-items:end;
  background:var(--surface);border-top:1px solid var(--border);
  padding:8px 4px calc(8px + env(safe-area-inset-bottom));}
.tabbar a{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  gap:5px;min-height:52px;text-decoration:none;color:var(--text-muted);
  font-family:var(--font-mono);font-size:0.53rem;letter-spacing:0.1em;text-transform:uppercase;}
/* L'entrée sélectionnée. La couleur ne suffisait pas : .tabbar a:hover utilise
   EXACTEMENT la même (--purple-light), « sélectionné » et « survolé » étaient
   donc indiscernables. Le trait tranche.
   Un ::before et non une bordure : * { box-sizing:border-box } ferait rétrécir
   la boîte et remonter le picto de 3px à la sélection.
   top:-8px = le padding haut de .tabbar, le trait se colle donc au bord. */
.tabbar a.on{color:var(--purple-light);}
.tabbar a.on::before{content:'';position:absolute;top:-8px;left:50%;
  transform:translateX(-50%);width:26px;height:3px;border-radius:0 0 3px 3px;
  background:var(--purple);box-shadow:0 0 10px rgba(109,40,217,0.9);}
.tabbar i{width:21px;height:21px;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
/* L'avatar déborde vers le haut : c'est le point d'entrée du profil. */
.tabbar .av{width:50px;height:50px;margin:-20px auto 0;box-shadow:0 0 0 4px var(--bg),0 0 18px rgba(109,40,217,0.55);}
.tabbar .av-niv{bottom:-6px;}
@media (max-width:768px){
  /* Ne s'affiche que connecté : la classe est posée par session.js. */
  body.a-compte .tabbar{display:grid;}
  /* Sur mobile, le bandeau se limite au logo et au burger. Le compte vit dans
     le burger quand on n'est pas connecté, et dans la barre du bas quand on
     l'est : un bouton de plus en haut ferait doublon. */
  .nav-compte{display:none;}
  /* La barre couvre le bas de page : on rend sa hauteur au contenu. */
  body.a-compte{padding-bottom:78px;}
}

/* Survol dans @media (hover:hover) : sinon l'effet reste collé après un tap
   sur iOS. Convention appliquée partout sur le site. */
@media (hover:hover){
  .nav-connexion:hover{border-color:var(--purple);box-shadow:var(--glow-violet);}
  .av:hover{box-shadow:0 0 0 2px var(--purple),var(--glow-violet);}
  .av.a-img:hover{box-shadow:0 0 0 2px var(--niv-c,var(--purple)),
    0 0 16px color-mix(in srgb,var(--niv-c,var(--purple)) 55%,transparent);}
  .av-menu a:hover{background:var(--surface2);color:var(--purple-light);}
  .tabbar a:hover{color:var(--purple-light);}
  .cpt-google:hover{border-color:var(--purple-dim);box-shadow:var(--glow-violet);}
  .cpt-bas a:hover,.cpt-lien:hover{color:var(--purple);}
  .cpt-oeil:hover{color:var(--purple-light);}
}

/* ══════════════════════════════════════════════════
   LE PROFIL
   Bandeau à la couleur du titre, avatar à cheval, cinq onglets.
   ══════════════════════════════════════════════════ */

/* La page de profil est large, l'écran de connexion étroit : deux conteneurs
   distincts plutôt qu'une largeur qui changerait de sens selon l'état. */
.pf-wrap{flex:1;width:100%;max-width:1040px;margin:0 auto;
  padding:calc(var(--nav-h) + 30px) 20px 60px;}
/* L'attribut hidden ne pose qu'un display:none de feuille par défaut : le
   display:flex de .cpt-wrap le battait, et l'écran « masqué » restait visible.
   Ce sélecteur est plus spécifique, il n'a pas besoin de !important. */
.cpt-wrap[hidden],.pf-wrap[hidden]{display:none;}

/* Les couleurs des onze paliers sont dans style.css : l'écran de progression
   de fin de partie en a besoin, et les pages de jeu ne chargent pas ce
   fichier. Une seule table, valable partout. */

/* ── Le bandeau ──────────────────────────────────────────────────────────
   <div> et non <header>/<nav> : style.css stylise ces balises nues.
   overflow VISIBLE, c'est ce qui laisse l'avatar déborder en bas ; le dégradé
   est donc porté par un calque enfant qui, lui, est rogné. */
.pf-bandeau{position:relative;border-radius:8px;padding:22px 26px 26px;
  margin-bottom:76px;              /* place rendue à la moitié basse de l'avatar */
  /* Pas de --niv-c ici : à spécificité égale avec [data-rang], la déclaration
     la plus basse gagne, et un défaut posé là écraserait la couleur du palier.
     L'attribut est toujours présent dans le HTML, le repli est donc inutile. */
  --niv-l:color-mix(in srgb,var(--niv-c) 45%,#F8F5FF);
  border:1px solid color-mix(in srgb,var(--niv-l) 78%,transparent);
  box-shadow:0 0 12px color-mix(in srgb,var(--niv-l) 22%,transparent);}
@supports (color: oklch(from red calc(l + 0.1) c h)){
  .pf-bandeau{--niv-l:oklch(from var(--niv-c) calc(l + 0.30) calc(c * 1.35) h);}
}
@supports not (color: color-mix(in srgb, red 50%, blue)){
  .pf-bandeau{border-color:var(--purple-dim);box-shadow:0 0 14px rgba(109,40,217,0.25);}
}
.pf-fond{position:absolute;inset:0;border-radius:inherit;overflow:hidden;
  pointer-events:none;background:var(--surface);}
/* Dégradé du titre : même construction que la TopBar en jeu
   (couleur pleine → 87 % → 53 %). Aucun grain, contrairement aux jeux. */
.pf-fond::before{content:"";position:absolute;inset:0;
  background:linear-gradient(135deg,var(--niv-c),
    color-mix(in srgb,var(--niv-c) 87%,transparent),
    color-mix(in srgb,var(--niv-c) 53%,transparent));}
/* Voile sombre côté texte. Les couleurs de titre vont du bleu ardoise au
   lavande très clair : sans ce voile, le pseudo blanc disparaît sur les
   paliers pâles. Il s'efface vers la droite pour laisser la couleur vivre. */
.pf-fond::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(10,7,16,0.80) 0%,rgba(10,7,16,0.48) 46%,
    rgba(10,7,16,0.05) 100%);}
/* Légende : la couleur du titre est un dégradé, pas une teinte unique. */
.pf-bandeau[data-rang="legende"] .pf-fond::before{
  background:linear-gradient(135deg,#6D28D9,#4a1a95 55%,rgba(60,21,121,0.55));}

/* ── L'avatar, à cheval ──────────────────────────────────────────────────
   Positionné en absolu plutôt qu'en flux : le débordement reste exact quelle
   que soit la hauteur du texte à côté. Sans contour, comme décidé. */
.pf-av{position:absolute;left:26px;bottom:-56px;width:112px;height:112px;z-index:3;}
.pf-av .av-i{display:block;width:100%;height:100%;border-radius:50%;
  background:var(--av) center/contain no-repeat;}
/* Halos par palier : léger sur Elite, Superstar et Monument, plein sur
   Classique, pulsation et brillance sur Légende. */
.pf-bandeau[data-rang="elite"]     .pf-av .av-i,
.pf-bandeau[data-rang="superstar"] .pf-av .av-i,
.pf-bandeau[data-rang="monument"]  .pf-av .av-i{filter:drop-shadow(0 0 8px var(--niv-c));}
.pf-bandeau[data-rang="classique"] .pf-av .av-i{
  filter:drop-shadow(0 0 13px var(--niv-c)) drop-shadow(0 0 28px var(--niv-c));}
@keyframes pfPulse{0%,100%{filter:drop-shadow(0 0 11px #6D28D9) drop-shadow(0 0 24px #6D28D9);}
  50%{filter:drop-shadow(0 0 19px #6D28D9) drop-shadow(0 0 42px #6D28D9);}}
.pf-bandeau[data-rang="legende"] .pf-av .av-i{animation:pfPulse 2.8s ease-in-out infinite;}
/* Brillance intérieure, réservée à Légende : élément séparé, rogné au cercle.
   Le halo, lui, est porté par le filtre de l'image et n'est donc pas coupé. */
.pf-brille{display:none;position:absolute;inset:0;border-radius:50%;
  overflow:hidden;pointer-events:none;}
.pf-bandeau[data-rang="legende"] .pf-brille{display:block;}
.pf-brille::before{content:"";position:absolute;top:-25%;bottom:-25%;left:0;width:48%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,0.42),transparent);
  transform:translateX(-170%) skewX(-14deg);animation:pfBrille 3.8s ease-in-out infinite;}
@keyframes pfBrille{0%{transform:translateX(-170%) skewX(-14deg);}
  55%,100%{transform:translateX(320%) skewX(-14deg);}}
@media (prefers-reduced-motion:reduce){
  .pf-bandeau[data-rang="legende"] .pf-av .av-i{animation:none;}
  .pf-brille::before{animation:none;opacity:0;}
}

/* ── Le bloc d'identité, à droite de l'avatar ────────────────────────────── */
.pf-txt{position:relative;z-index:2;padding-left:138px;min-height:104px;
  display:flex;flex-direction:column;justify-content:center;gap:7px;}
.pf-pseudo{font-family:var(--font-display);font-weight:900;font-size:1.75rem;
  letter-spacing:-0.06em;color:var(--text);line-height:1;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Lexend Mega est une fonte large : au-delà d'une douzaine de caractères, le
   pseudo touche le bord. On descend d'un cran plutôt que de le couper. */
.pf-pseudo.long{font-size:1.32rem;}
.pf-pseudo.tres-long{font-size:1.02rem;letter-spacing:-0.04em;}
.pf-pseudo.mini{font-size:0.85rem;letter-spacing:-0.03em;}
.pf-rang{display:flex;align-items:center;gap:9px;flex-wrap:wrap;}
.pf-titre{font-family:var(--font-mono);font-size:0.68rem;font-weight:700;
  letter-spacing:0.2em;text-transform:uppercase;color:var(--niv-l);}
.pf-niv{font-family:var(--font-mono);font-size:0.6rem;font-weight:700;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text);padding:3px 9px;border-radius:20px;
  background:rgba(10,7,16,0.45);border:1px solid color-mix(in srgb,var(--niv-l) 55%,transparent);}
/* La barre d'expérience porte la couleur de l'XP, pas celle du palier : le
   fond du bandeau dit déjà le titre atteint, la jauge dit la progression.
   Deux informations différentes, deux couleurs. */
.pf-jauge{height:7px;border-radius:99px;background:var(--xp-dark);
  overflow:hidden;max-width:430px;margin-top:2px;}
.pf-jauge span{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--xp),var(--xp-light));}
.pf-xp{font-family:var(--font-mono);font-size:0.6rem;letter-spacing:0.1em;
  text-transform:uppercase;color:rgba(248,245,255,0.68);}
.pf-xp b{color:var(--xp);font-weight:700;}

/* ── Les trois albums de la collection ───────────────────────────────────
   Sans libellé : trois pochettes alignées au-dessus d'un pseudo se lisent
   sans qu'on les nomme. La rareté passe par le contour et son halo. */
.pf-albums{display:flex;gap:6px;margin-bottom:3px;}
.pf-albums .cov{position:relative;width:44px;height:44px;border-radius:5px;display:block;
  flex-shrink:0;background:var(--cov) center/cover no-repeat;
  /* Le reset global est en border-box : une bordure de 2 px rogne l'image de
     2 px, elle ne décale rien autour. */
  border:2px solid var(--rar,rgba(248,245,255,0.18));
  box-shadow:0 0 9px color-mix(in srgb,var(--rar,transparent) 60%,transparent);}
/* Emplacement encore vide : le joueur n'a pas trois albums dans sa collection.
   Pointillé plutôt que trou noir, pour que la place à remplir se voie. */
.pf-albums .cov.vide{background:rgba(10,7,16,0.32);box-shadow:none;
  border:1px dashed rgba(248,245,255,0.3);}
/* Sur SON profil, les trois emplacements se cliquent : ils ouvrent le choix
   dans la collection. Sur celui d'un autre joueur ils restent des <span>,
   rien n'est modifiable. */
button.cov{padding:0;cursor:pointer;color:var(--text);}
button.cov em{position:absolute;inset:0;display:grid;place-items:center;
  font-style:normal;font-family:var(--font-display);font-weight:900;
  font-size:1.1rem;color:rgba(248,245,255,0.45);}
/* La pochette est un fond : un voile sombre au survol dit qu'on peut changer. */
button.cov::after{content:'';position:absolute;inset:0;border-radius:inherit;
  background:rgba(10,7,16,0.45);opacity:0;transition:opacity .18s ease;}
@media (hover:hover){
  button.cov:hover::after{opacity:1;}
  button.cov:hover{border-color:var(--purple-light);}
}

/* ── Le cercle de la bannière ────────────────────────────────────────────
   En bas à droite du bandeau, rond pour ne pas se confondre avec les trois
   favoris qui sont carrés. Il montre la pochette en place, ou un « + ». */
.pf-choix-ban{position:absolute;right:18px;bottom:18px;z-index:4;
  width:46px;height:46px;border-radius:50%;cursor:pointer;padding:0;
  background:var(--cov,rgba(10,7,16,0.42)) center/cover no-repeat;
  border:2px solid rgba(248,245,255,0.28);color:var(--text);
  box-shadow:0 4px 14px rgba(0,0,0,0.35);
  transition:border-color .18s ease,transform .18s ease;}
.pf-choix-ban em{position:absolute;inset:0;display:grid;place-items:center;
  font-style:normal;font-family:var(--font-display);font-weight:900;
  font-size:1.1rem;color:rgba(248,245,255,0.55);}
.pf-choix-ban.plein em{display:none;}
@media (hover:hover){
  .pf-choix-ban:hover{border-color:var(--purple-light);transform:scale(1.06);}
}
/* Le cercle est en absolu : sans place réservée, il passe PAR-DESSUS la jauge
   d'XP qui s'étend jusqu'au bord. On réserve la colonne dans le texte plutôt
   que de déplacer le cercle. */
.pf-txt{padding-right:76px;}
@media (max-width:600px){
  .pf-choix-ban{right:12px;bottom:12px;width:40px;height:40px;}
  .pf-txt{padding-right:62px;}
}
@media (prefers-reduced-motion:reduce){
  .pf-choix-ban:hover{transform:none;}
}
/* Les couleurs de rareté (.r-commun … .r-legend) ont été déplacées dans
   style.css : la FAQ de la page À propos s'en sert aussi, et cette page ne
   charge pas compte.css. Même raison que la table --niv-c des rangs. */

/* ── L'album bannière, fondu dans le fond ────────────────────────────────── */
.pf-banniere{position:absolute;top:0;right:0;bottom:0;width:min(340px,42%);
  pointer-events:none;background:var(--cov) center/cover no-repeat;
  border-radius:inherit;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 62%);
          mask-image:linear-gradient(90deg,transparent,#000 62%);opacity:0.5;}

/* ── Onglets ─────────────────────────────────────────────────────────────── */
/* La rangée déborde sur mobile. Sans repère visible, « Packs » restait
   introuvable : un dégradé et une flèche à chaque bout disent qu'il y a
   quelque chose au-delà, et les faire défiler d'une pression. */
.pf-onglets-boite{position:relative;}
.pf-onglets-boite{margin-bottom:28px;}
.pf-fleche{position:absolute;top:0;bottom:0;width:52px;border:none;padding:0;
  display:flex;align-items:center;cursor:pointer;
  /* Éteinte, elle ne doit pas intercepter le doigt : un bouton invisible
     mangerait les pressions destinées au dernier onglet. */
  opacity:0;pointer-events:none;transition:opacity .22s ease;}
.pf-fleche.gauche{left:0;justify-content:flex-start;
  background:linear-gradient(90deg,var(--bg) 45%,transparent);}
.pf-fleche.droite{right:0;justify-content:flex-end;
  background:linear-gradient(270deg,var(--bg) 45%,transparent);}
.pf-fleche::after{content:"";width:13px;height:13px;background:var(--purple-light);
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
/* Le picto pointe à droite : on le retourne pour l'autre bord. */
.pf-fleche.gauche::after{transform:scaleX(-1);}
.a-gauche > .pf-fleche.gauche,.a-droite > .pf-fleche.droite{opacity:1;pointer-events:auto;}
.pf-onglets{display:flex;gap:2px;border-bottom:1px solid var(--border);
  overflow-x:auto;scrollbar-width:none;}
.pf-onglets::-webkit-scrollbar{display:none;}
.pf-onglet{display:inline-flex;align-items:center;min-height:46px;padding:0 15px;
  font-family:var(--font-mono);font-size:0.63rem;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--text-muted);text-decoration:none;
  white-space:nowrap;border-bottom:2px solid transparent;margin-bottom:-1px;
  background:none;border-left:none;border-right:none;border-top:none;cursor:pointer;}
/* La pastille suit le libellé de l'onglet. position:relative sur le bouton :
   sans lui, une pastille absolue se placerait par rapport à la page. */
.pf-onglet{position:relative;}
.pf-onglet .nz-bulle{margin-left:7px;vertical-align:middle;}
.pf-onglet[aria-selected="true"]{color:var(--text);border-bottom-color:var(--purple);}

/* ── Contenu des onglets ─────────────────────────────────────────────────── */
.pf-sec{margin-bottom:34px;}
.pf-sec-t{font-family:var(--font-mono);font-size:0.6rem;letter-spacing:0.2em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:12px;}

/* Chiffres clés. 230 px de largeur mini : quatre colonnes sur un écran de
   bureau, trois sur tablette, deux sur téléphone — six tuiles remplissent donc
   toujours des rangées entières, sans orpheline. Le seuil tient compte des
   gouttières, sinon on obtient une colonne de moins que prévu. */
.pf-chiffres{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:10px;}
.pf-chiffre{background:var(--surface);border:1px solid var(--border);border-radius:10px;
  padding:16px 14px;}
.pf-chiffre b{display:block;font-family:var(--font-display);font-weight:900;
  font-size:1.4rem;letter-spacing:-0.055em;color:var(--text);line-height:1;white-space:nowrap;}
.pf-chiffre span{display:block;font-family:var(--font-mono);font-size:0.55rem;
  letter-spacing:0.16em;text-transform:uppercase;color:var(--text-muted);margin-top:8px;}
.pf-chiffre em{display:block;font-style:normal;font-family:var(--font-mono);
  font-size:0.55rem;letter-spacing:0.1em;color:var(--text-muted);margin-top:5px;opacity:0.75;}
/* Une couleur par nature de chiffre — la charte les distingue : l'XP progresse,
   la complétion dure, le classement se dispute. */
.pf-chiffre.v-xp b{color:var(--xp);}
.pf-chiffre.v-compl b{color:var(--completion);}
.pf-chiffre.v-rang b{color:var(--rang);}
/* Ce qui n'existe pas encore le dit, plutôt que d'afficher un zéro sec. */
.pf-chiffre.attente{border-style:dashed;}
.pf-chiffre.attente b{color:var(--text-muted);}


/* ── Classement ──────────────────────────────────────────────────────────── */
/* Fond orange translucide et contour orange, comme la ligne « moi » des
   classements (.pf-rang-lig.moi, plus bas) : c'est la même information - ta
   position - et elle doit se signaler pareil partout. */
/* Sans halo : le fond orange et la bordure suffisent à détacher la case. Le
   glow, sur un bloc large et plein, débordait en auréole plutôt que de souligner
   — il est fait pour de petits éléments actifs, pas pour un bandeau. */
.pf-moi{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  background:rgba(255,122,26,0.12);border:1px solid var(--rang);border-radius:10px;
  padding:18px 20px;margin-bottom:22px;}
.pf-moi-r{font-family:var(--font-display);font-weight:900;font-size:2rem;
  letter-spacing:-0.06em;color:var(--rang);line-height:1;}
.pf-moi-t{flex:1;min-width:160px;font-size:0.86rem;color:var(--text-muted);line-height:1.5;}
.pf-moi-t b{color:var(--text);}
.pf-rang-lig{display:grid;grid-template-columns:44px 38px 1fr auto;align-items:center;gap:12px;
  min-height:56px;padding:8px 16px;background:var(--surface);
  border:1px solid var(--border);border-radius:10px;}
.pf-rang-av{width:38px;height:38px;border-radius:50%;
  background:var(--av) center/contain no-repeat;}
/* Sa propre ligne : anneau en box-shadow et non bordure épaissie, sinon le
   reset border-box décalerait le contenu de la ligne d'un pixel. */
/* Le contour de SA propre ligne prend l'orange du classement, pas le violet de
   marque : dans un classement, la couleur qui veut dire « position » est
   --rang. Le violet servait aussi à la sélection, les deux se confondaient. */
/* position:relative + z-index : sans eux, l'anneau en box-shadow passait SOUS
   les lignes voisines — un frère qui vient après dans le DOM est peint par
   dessus, et l'anneau se retrouvait tronqué en haut et en bas. */
.pf-rang-lig.moi{box-shadow:0 0 0 1px var(--rang);border-color:var(--rang);
  position:relative;z-index:1;}
/* Le rang est une position : orange classement, atténué pour les autres,
   plein pour soi — l'échelle d'emphase tient dans une seule couleur. */
.pf-rang-n{font-family:var(--font-display);font-weight:900;font-size:0.95rem;
  letter-spacing:-0.04em;color:color-mix(in srgb,var(--rang) 62%,var(--text-muted));}
.pf-rang-lig.moi .pf-rang-n{color:var(--rang);}
.pf-rang-p{min-width:0;}
/* Le pseudo ouvre le profil du joueur : c'est un bouton, pas un simple texte. */
/* padding + marge negative de meme valeur : la zone touchable gagne 16px en
   hauteur (19 -> 35px avec la seconde ligne, au-dessus du confort de pouce)
   SANS deplacer un seul pixel a l'ecran, la marge annulant exactement le
   rembourrage. Mesure a 375px : le pseudo ne faisait que 19px de haut. */
.pf-rang-p button{display:block;max-width:100%;padding:8px 0;margin:-8px 0;
    background:none;border:none;
  cursor:pointer;text-align:left;font-family:var(--font-body);font-weight:700;
  font-size:0.9rem;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Sur une seule ligne : « Tête d'affiche · Niveau 29 » passait à deux et
   déséquilibrait la hauteur des rangées voisines. */
.pf-rang-p span{display:block;font-family:var(--font-mono);font-size:0.55rem;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--niv-c,var(--text-muted));margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Une valeur de classement se lit à sa couleur : l'XP en vert d'eau, les
   points au lime du jeu, et un zéro en framboise — exactement la convention
   des points qui montent en partie (.sc-float dans style.css). */
.pf-rang-xp{font-family:var(--font-mono);font-size:0.68rem;font-weight:700;
  color:var(--text);white-space:nowrap;}
/* Les sélecteurs sont énumérés plutôt que laissés à une classe seule : à
   spécificité égale c'est l'ordre du fichier qui tranche, et un modificateur
   qui dépend de sa position dans la feuille finit toujours par se faire
   doubler. Ici il gagne par sa spécificité, où qu'il soit. */
.pf-rang-xp.v-xp,.pf-moi-t b.v-xp,.pf-cl-moi b.v-xp{color:var(--xp);}
.pf-rang-xp.v-pts,.pf-moi-t b.v-pts,.pf-cl-moi b.v-pts{color:var(--green);}
.pf-rang-xp.v-zero,.pf-moi-t b.v-zero,.pf-cl-moi b.v-zero{color:var(--red);}

/* ── Classement général : top 5, ta position, « Voir plus » ─────────────────
   Décision du 2026-09-15 : le tableau entier ne s'affiche plus dans l'onglet.
   Les 5 premiers, puis ta ligne et les 5 joueurs qui te suivent, puis une
   rangée « Voir plus » qui ouvre la fenêtre #pfPopGen (compte.php). */
/* 6 px entre les lignes, comme sur l'accueil (.cg-top). Limité à ce bloc : les
   autres listes du profil n'ont jamais eu d'écart (.pf-liste n'a aucune règle),
   les changer demanderait leur propre aperçu. */
.pf-liste-gen{display:grid;gap:6px;}
/* La coupure : le dessin de .cg-saut (index.css), sans la largeur centrée
   propre à l'accueil. Sans elle, un 34e collé au 5e se lirait comme un 6e. */
.pf-saut{display:flex;align-items:center;gap:10px;margin:10px 0 4px;
  color:var(--text-muted);font-family:var(--font-mono);font-size:0.62rem;
  letter-spacing:0.2em;text-transform:uppercase;}
.pf-saut::before,.pf-saut::after{content:'';flex:1;height:1px;background:var(--border);}
/* « Voir plus » au gabarit d'une ligne de classement (option C) : il prolonge
   la liste au lieu de flotter dessous. Son picto (.btn-picto) hérite du
   --picto posé sur #pfTop. */
.pf-plus-lig{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  min-height:56px;padding:8px 16px;background:var(--surface);border:1px solid var(--border);
  border-radius:10px;cursor:pointer;font-family:var(--font-body);font-weight:700;
  font-size:0.8rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--purple-light);}
.pf-plus-lig em{font-style:normal;font-weight:400;letter-spacing:0;text-transform:none;
  color:var(--text-muted);}
/* La fenêtre : ta ligne reste épinglée sous la liste tant qu'elle n'est pas
   visible (option 2). Hors de la zone qui défile, pour ne jamais recouvrir une
   ligne. Pas de display ici : l'attribut hidden doit pouvoir la masquer. */
.pf-gen-epingle{flex-shrink:0;padding:10px 20px 14px;border-top:1px solid var(--border);
  background:var(--surface);}
.pf-gen-fin{margin-top:6px;}
.pf-gen-fin:empty{display:none;}
@media (hover:hover){
  .pf-plus-lig:hover{border-color:var(--purple-dim);background:rgba(109,40,217,0.06);}
}
@media (max-width:600px){
  .pf-plus-lig{padding:8px 12px;}
  .pf-gen-epingle{padding:10px 14px 12px;}
}

/* ── En construction : Missions, Collections, Packs ──────────────────────── */
.pf-attente{text-align:center;padding:52px 20px;background:var(--surface);
  border:1px dashed var(--border);border-radius:12px;}
.pf-attente i{display:block;width:34px;height:34px;margin:0 auto 16px;
  background:var(--text-muted);
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.pf-attente b{display:block;font-family:var(--font-display);font-weight:900;font-size:1rem;
  letter-spacing:-0.04em;text-transform:uppercase;color:var(--text);margin-bottom:8px;}
.pf-attente p{font-size:0.84rem;color:var(--text-muted);line-height:1.6;
  max-width:420px;margin:0 auto;}
.pf-vide{font-size:0.86rem;color:var(--text-muted);line-height:1.6;
  padding:22px;background:var(--surface);border:1px solid var(--border);border-radius:10px;}
.pf-vide a{color:var(--purple-light);text-decoration:none;}

/* ── L'avatar du bandeau de navigation ───────────────────────────────────── */
/* Dès que le profil est connu, l'image de palier remplace les initiales. Le
   dégradé violet reste l'état d'attente, le temps de l'aller-retour. */
.av-i{display:block;width:100%;height:100%;border-radius:50%;
  background:var(--av) center/contain no-repeat;}
/* L'anneau reprend la couleur du palier plutôt que le violet générique : dans
   le bandeau, il sert aussi à détacher l'avatar du fond sombre. */
.av.a-img{background:none;
  box-shadow:0 0 0 2px color-mix(in srgb,var(--niv-c,var(--purple)) 62%,transparent);}
.tabbar .av.a-img{box-shadow:0 0 0 4px var(--bg),
  0 0 16px color-mix(in srgb,var(--niv-c,var(--purple)) 55%,transparent);}
/* L'avatar sélectionné (Résumé et Classement, qui vivent tous deux derrière
   lui). C'est un <button> : .tabbar a.on ne l'atteint pas, et il déborde vers
   le haut, un trait au-dessus n'aurait pas de place. Un anneau, donc.
   ⚠ POSÉE ICI, APRÈS .tabbar .av.a-img : même spécificité (0,3,0), c'est
   l'ordre du fichier qui tranche. Remontée dans le bloc .tabbar, elle perdrait
   contre la règle ci-dessus et l'avatar ne changerait pas d'aspect. */
.tabbar .av.on{box-shadow:0 0 0 4px var(--bg),0 0 0 6px var(--purple),
  0 0 24px rgba(109,40,217,0.85);}

/* ── Mobile ──────────────────────────────────────────────────────────────── */
@media (max-width:600px){
  .pf-wrap{padding:calc(var(--nav-h) + 20px) 14px 40px;}
  .pf-bandeau{padding:16px 16px 20px;margin-bottom:59px;}
  .pf-av{left:16px;bottom:-41px;width:82px;height:82px;}
  .pf-txt{padding-left:96px;min-height:78px;gap:5px;}
  .pf-pseudo{font-size:1.2rem;}
  .pf-pseudo.long{font-size:0.95rem;}
  .pf-pseudo.tres-long{font-size:0.68rem;letter-spacing:-0.03em;}
  .pf-pseudo.mini{font-size:0.58rem;letter-spacing:-0.02em;}
  .pf-titre{font-size:0.6rem;letter-spacing:0.14em;}
  .pf-jauge{max-width:none;}
  .pf-albums{gap:5px;}
  .pf-albums .cov{width:34px;height:34px;}
  /* La vignette rétrécit, pas la cible : 44 px de zone tactile obtenus par un
     débord invisible plutôt qu'en agrandissant l'image, qui déborderait du
     bandeau. Le gap est réduit d'autant pour que l'espacement reste juste. */
  .pf-albums{gap:12px;}
  button.cov::before{content:'';position:absolute;top:50%;left:50%;
    width:44px;height:44px;transform:translate(-50%,-50%);}
  /* La bannière est peinte AU-DESSUS du voile : sur un écran étroit elle
     passait sous la ligne d'XP et la rendait pénible à lire. On la resserre
     et on l'atténue, l'ambiance reste, le texte repasse devant. */
  .pf-banniere{width:52%;opacity:0.36;}
  .pf-onglet{padding:0 12px;font-size:0.58rem;}
  .pf-fleche{width:42px;}
  .pf-chiffres{grid-template-columns:repeat(2,1fr);}
}

/* Survol dans @media (hover:hover) : sinon l'effet reste collé après un tap
   sur iOS. Convention appliquée partout sur le site. */
@media (hover:hover){
  .pf-onglet:hover{color:var(--text);}
  .pf-vide a:hover{color:var(--purple);}
}

/* ══════════════════════════════════════════════════
   LIGNES DÉPLIABLES (Blindtest et Jeux)
   ══════════════════════════════════════════════════ */
.pf-dep{background:var(--surface);border:1px solid var(--border);border-radius:10px;
  overflow:hidden;}
.pf-dep-tete{display:flex;align-items:center;gap:14px;width:100%;min-height:60px;
  padding:10px 16px;background:none;border:none;cursor:pointer;text-align:left;
  color:var(--text);font-family:var(--font-body);}
.pf-vign{width:42px;height:42px;border-radius:6px;flex-shrink:0;display:block;
  background:var(--img) center/cover no-repeat;border:1px solid rgba(248,245,255,0.14);}
/* Le thème sans visuel garde un aplat à sa couleur plutôt qu'un trou. */
.pf-vign.plein{background:color-mix(in srgb,var(--jeu-c,var(--purple)) 30%,transparent);}
/* Picto de jeu : masqué dans un aplat de la couleur du jeu, jamais une image
   colorée — même motif que les GameCards. */
.pf-vign.picto{border:none;background:color-mix(in srgb,var(--jeu-c,var(--purple)) 22%,transparent);
  display:flex;align-items:center;justify-content:center;}
.pf-vign.picto span{display:block;width:24px;height:24px;background:var(--jeu-l,var(--purple-light));
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
@supports (color: oklch(from red calc(l + 0.1) c h)){
  .pf-vign.picto{--jeu-l:oklch(from var(--jeu-c,var(--purple)) calc(l + 0.42) calc(c * 1.5) h);}
}
/* flex:1 sert au Blindtest, où le nom est enfant direct de l'en-tête et doit
   repousser la valeur à droite. Sans effet dans .pf-dep-bloc (jeux), qui est un
   bloc : la déclaration vaut donc pour les deux formes. */
.pf-dep-bloc{flex:1;min-width:0;}
.pf-dep-nom{display:block;flex:1;min-width:0;font-weight:700;font-size:0.92rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pf-dep-val{font-family:var(--font-display);font-weight:900;font-size:1rem;
  letter-spacing:-0.04em;color:var(--completion);white-space:nowrap;}
.pf-dep-val.gris{color:var(--text-muted);font-family:var(--font-mono);font-size:0.68rem;
  letter-spacing:0.12em;}
/* Chevron dessiné en CSS plutôt qu'avec picto-fleche : la flèche des cartes est
   longue et fine, elle se réduit à un trait illisible à cette taille. Deux
   bordures sur un carré tourné restent nettes à n'importe quelle échelle. */
.pf-dep-chev{width:8px;height:8px;flex-shrink:0;margin-right:3px;
  border-right:2px solid var(--text-muted);border-bottom:2px solid var(--text-muted);
  transform:rotate(45deg);transition:transform .22s ease;}
.pf-dep-tete[aria-expanded="true"] .pf-dep-chev{transform:rotate(-135deg);}
.pf-dep-corps{border-top:1px solid var(--border);padding:4px 16px 10px;}
.pf-dep-lig{display:flex;align-items:center;justify-content:space-between;gap:14px;
  width:100%;min-height:38px;font-family:var(--font-mono);font-size:0.62rem;
  letter-spacing:0.12em;text-transform:uppercase;color:var(--text-muted);
  background:none;border:none;text-align:left;}
.pf-dep-lig + .pf-dep-lig{border-top:1px solid rgba(42,36,64,0.6);}
/* Une ligne de tierlist n'ouvre rien : elle EMMÈNE sur la tierlist. C'est un
   lien, et la flèche vers la droite le dit — un chevron vers le bas
   promettrait un dépliant. */
a.pf-dep{display:block;text-decoration:none;color:inherit;}
/* Même ligne, en bouton : dans la fenêtre d'un autre joueur elle ouvre son
   rangement au lieu de mener sur une page. */
button.pf-dep{display:block;width:100%;padding:0;text-align:left;cursor:pointer;
  font-family:inherit;color:inherit;}
.pf-dep-fleche{width:8px;height:8px;flex-shrink:0;margin-right:3px;
  border-right:2px solid var(--text-muted);border-bottom:2px solid var(--text-muted);
  transform:rotate(-45deg);}
.pf-dep-tete.pf-dep-lien{cursor:pointer;}

/* Une ligne de mode ouvre son classement : elle se clique, donc elle a une
   zone tactile de 44 px et un curseur. Les lignes des jeux n'en ont pas. */
button.pf-dep-lig{min-height:44px;cursor:pointer;}
.pf-dep-lig b{font-family:var(--font-body);font-size:0.86rem;letter-spacing:0;
  text-transform:none;color:var(--text);white-space:nowrap;}
.pf-dep-lig b.vide{color:var(--text-muted);font-weight:400;}
.pf-dep-lig b.v-pts{color:var(--green);}
.pf-dep-lig b.v-zero{color:var(--red);}
.pf-dep-lig b.v-compl{color:var(--completion);}
/* Le picto du mode, collé à son libellé. Masque en currentColor, comme tous
   les pictos du site : il suit donc la couleur de la ligne - gris au repos,
   violet clair au survol - sans qu'il existe une seconde version du fichier.
   .pf-dep-mode porte le flex : sans lui, le picto et le texte seraient deux
   enfants directs de la ligne, et justify-content:space-between les aurait
   écartés aux deux bouts. */
.pf-dep-mode{display:inline-flex;align-items:center;gap:8px;min-width:0;}
.pf-dep-mode i{flex:none;width:15px;height:15px;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;
          mask:var(--picto) center/contain no-repeat;}
/* Le score et le rang forment un couple à droite de la ligne. */
.pf-dep-duo{display:flex;align-items:baseline;gap:12px;white-space:nowrap;}
.pf-dep-r{font-family:var(--font-display);font-weight:900;font-size:0.8rem;
  letter-spacing:-0.04em;color:var(--rang);}
/* La jauge de complétion : orange doux sur fond orange sombre. La couleur du
   jeu est déjà portée par son picto juste à côté. */
.pf-dep-jauge{display:block;height:4px;border-radius:99px;background:var(--orange-dark);
  overflow:hidden;margin-top:7px;max-width:260px;}
.pf-dep-jauge span{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--completion),
    color-mix(in srgb,var(--completion) 55%,#F8F5FF));}

/* ══════════════════════════════════════════════════
   FENÊTRES : profil d'un joueur, classement d'un mode
   ══════════════════════════════════════════════════ */
/* z-index au-dessus du bandeau (900) et du menu mobile (890) : à 100, la
   fenêtre passait DESSOUS et sa croix de fermeture, en haut à droite, était
   inatteignable sur téléphone. Sous le décompte de partie (950), qui ne peut
   pas coexister avec le profil. */
.pf-pop{position:fixed;inset:0;z-index:930;display:none;
  align-items:center;justify-content:center;padding:20px;
  background:rgba(10,7,16,0.78);backdrop-filter:blur(3px);}
/* Le classement d'un mode s'ouvre SOUS le profil : depuis ce classement on peut
   cliquer un pseudo, et le profil doit alors passer devant. */
.pf-pop-2{z-index:920;}
/* Le classement ouvert DEPUIS une fenêtre de profil doit passer devant elle
   (930). Posé par pfClOuvrir() seulement dans ce cas : ailleurs il reste en
   dessous, ce qui laisse la fenêtre de profil visible derrière. */
.pf-pop-4{z-index:944;}
.pf-pop.ouvert{display:flex;}
.pf-pop-carte{position:relative;width:100%;max-width:460px;background:var(--surface);
  border:1px solid var(--border);border-radius:14px;
  box-shadow:0 24px 60px rgba(0,0,0,0.6);
  /* dvh plutôt que vh : sur mobile la barre d'adresse mange la hauteur et la
     carte débordait sous l'écran. */
  max-height:calc(100dvh - 40px);display:flex;flex-direction:column;overflow:hidden;}
.pf-pop-haut{position:relative;border-radius:13px 13px 0 0;overflow:hidden;
  padding:24px 22px 22px;text-align:center;flex-shrink:0;}
.pf-pop-haut::before{content:"";position:absolute;inset:0;
  background:linear-gradient(160deg,var(--niv-c),
    color-mix(in srgb,var(--niv-c) 55%,transparent));}
/* L'album mis en bannière, discret : il donne une ambiance, il ne prend pas la
   place de l'avatar. Fondu vers le bas comme dans le bandeau du profil. */
.pf-pop-ban{position:absolute;top:0;left:0;right:0;height:52%;
  background:var(--cov) center/cover no-repeat;opacity:0.5;
  -webkit-mask-image:linear-gradient(180deg,#000 15%,transparent);
          mask-image:linear-gradient(180deg,#000 15%,transparent);}
/* Voile vertical : il garde le pseudo blanc lisible sur les paliers pâles sans
   éteindre la couleur en haut de la carte. Même raison que dans le bandeau. */
.pf-pop-haut::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(10,7,16,0.18),rgba(10,7,16,0.74));}
.pf-pop-av{position:relative;z-index:2;width:88px;height:88px;margin:0 auto 12px;
  background:var(--av) center/contain no-repeat;border-radius:50%;}
/* Mêmes halos que dans le bandeau : c'est le même avatar, il doit se comporter
   pareil. pfPulse est définie plus haut dans ce fichier. */
[data-rang="elite"] .pf-pop-av,
[data-rang="superstar"] .pf-pop-av,
[data-rang="monument"] .pf-pop-av{filter:drop-shadow(0 0 8px var(--niv-c));}
[data-rang="classique"] .pf-pop-av{
  filter:drop-shadow(0 0 13px var(--niv-c)) drop-shadow(0 0 28px var(--niv-c));}
[data-rang="legende"] .pf-pop-av{animation:pfPulse 2.8s ease-in-out infinite;}
@media (prefers-reduced-motion:reduce){
  [data-rang="legende"] .pf-pop-av{animation:none;}
}
/* Les trois albums de sa collection, sous l'avatar. */
.pf-pop-albums{position:relative;z-index:2;display:flex;justify-content:center;gap:6px;
  margin:0 0 12px;}
.pf-pop-albums .cov{position:relative;width:38px;height:38px;border-radius:5px;display:block;
  background:var(--cov) center/cover no-repeat;
  border:2px solid var(--rar,rgba(248,245,255,0.18));
  box-shadow:0 0 8px color-mix(in srgb,var(--rar,transparent) 60%,transparent);}
.pf-pop-albums .cov.vide{background:rgba(10,7,16,0.4);box-shadow:none;
  border:1px dashed rgba(248,245,255,0.3);}
.pf-pop-nom{position:relative;z-index:2;font-family:var(--font-display);font-weight:900;
  font-size:1.3rem;letter-spacing:-0.05em;color:var(--text);
  line-height:1.1;word-break:break-word;}
.pf-pop-rang{position:relative;z-index:2;margin-top:7px;font-family:var(--font-mono);
  font-size:0.62rem;font-weight:700;letter-spacing:0.2em;text-transform:uppercase;
  color:color-mix(in srgb,var(--niv-c) 45%,#F8F5FF);}
.pf-pop-jauge{position:relative;z-index:2;height:6px;border-radius:99px;
  background:var(--xp-dark);overflow:hidden;margin:12px auto 0;max-width:220px;}
.pf-pop-jauge span{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--xp),var(--xp-light));}
/* Onglets de la fenêtre : mêmes règles que ceux du profil, en plus compact. */
.pf-pop-onglets{display:flex;gap:2px;flex-shrink:0;padding:0 14px;
  border-bottom:1px solid var(--border);background:var(--surface);}
.pf-pop-onglet{flex:1;min-height:46px;padding:0 8px;background:none;cursor:pointer;
  border:none;border-bottom:2px solid transparent;margin-bottom:-1px;
  font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);}
.pf-pop-onglet[aria-selected="true"]{color:var(--text);border-bottom-color:var(--purple);}
/* Seul le contenu défile : l'en-tête et les onglets restent en place. */
.pf-pop-corps{padding:18px 20px 22px;overflow-y:auto;flex:1;}
/* La collection d'un autre joueur défile dans ce conteneur : sans ces
   quelques pixels, ses cartes de bord perdent leur liseré de rareté, pour la
   même raison que dans la fenêtre de choix. */
.pf-pop-vue[data-v="collection"]{margin:0 -7px;padding:2px 7px;}
.pf-pop-sec{margin-bottom:20px;}
.pf-pop-sec:last-child{margin-bottom:0;}
.pf-pop-sec-t{font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.2em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:9px;}
.pf-pop-grille{display:grid;grid-template-columns:1fr 1fr;gap:9px;}
.pf-pop-c{background:var(--surface2);border-radius:9px;padding:13px 14px;}
.pf-pop-c b{display:block;font-family:var(--font-display);font-weight:900;font-size:1.1rem;
  letter-spacing:-0.04em;color:var(--text);line-height:1;}
.pf-pop-c b.v-xp{color:var(--xp);}
.pf-pop-c b.v-rang{color:var(--rang);}
.pf-pop-c b.v-compl{color:var(--completion);}
.pf-pop-c span{display:block;font-family:var(--font-mono);font-size:0.52rem;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--text-muted);margin-top:7px;}
/* Zone tactile de 44 px : une croix de 15 px ne se vise pas au pouce. */
.pf-pop-x{position:absolute;top:8px;right:8px;z-index:4;width:44px;height:44px;
  display:flex;align-items:center;justify-content:center;
  background:none;border:none;cursor:pointer;color:var(--text);}
.pf-pop-x::before{content:"";width:15px;height:15px;background:currentColor;
  -webkit-mask:var(--picto-x) center/contain no-repeat;mask:var(--picto-x) center/contain no-repeat;}
.pf-pop-note{margin-top:14px;font-family:var(--font-mono);font-size:0.58rem;
  line-height:1.6;letter-spacing:0.08em;color:var(--text-muted);text-align:center;}
/* En-tête du classement d'un mode : pas de couleur de palier ici, c'est un
   tableau, pas un joueur. */
.pf-cl-tete{flex-shrink:0;padding:22px 56px 16px 22px;border-bottom:1px solid var(--border);}
.pf-cl-nom{font-family:var(--font-display);font-weight:900;font-size:1.05rem;
  letter-spacing:-0.05em;text-transform:uppercase;color:var(--text);line-height:1.15;}
.pf-cl-moi{margin-top:8px;font-size:0.82rem;color:var(--text-muted);line-height:1.5;}
.pf-cl-moi b{color:var(--text);}
/* La POSITION prend l'orange du classement dans les deux phrases de rang ;
   la valeur, elle, garde sa couleur de nature (v-xp, v-pts). */
.pf-moi-t b.v-rang,.pf-cl-moi b.v-rang{color:var(--rang);}

@media (max-width:600px){
  .pf-dep-tete{gap:11px;padding:10px 13px;}
  .pf-vign{width:36px;height:36px;}
  .pf-vign.picto span{width:20px;height:20px;}
  .pf-dep-nom{font-size:0.84rem;}
  .pf-dep-corps{padding:2px 13px 8px;}
  .pf-rang-lig{grid-template-columns:34px 32px 1fr auto;gap:9px;padding:8px 12px;}
  .pf-rang-av{width:32px;height:32px;}
  .pf-pop{padding:12px;}
  .pf-pop-carte{max-width:none;max-height:calc(100dvh - 24px);}
  .pf-pop-onglet{font-size:0.53rem;letter-spacing:0.1em;padding:0 4px;}
  .pf-pop-corps{padding:16px 14px 20px;}
  .pf-cl-tete{padding:18px 52px 14px 16px;}
}

@media (hover:hover){
  .pf-dep-tete:hover{background:rgba(109,40,217,0.06);}
  .pf-dep-tete:hover .pf-dep-nom{color:var(--purple-light);}
  button.pf-dep-lig:hover b{color:var(--purple-light);}
  button.pf-dep-lig:hover .pf-dep-mode{color:var(--purple-light);}
  .pf-rang-p button:hover{color:var(--purple-light);text-decoration:underline;}
  .pf-pop-x:hover{color:var(--purple-light);}
  .pf-pop-onglet:hover{color:var(--text);}
}

/* ══════════════════════════════════════════════════
   SUPPRESSION DU COMPTE
   ══════════════════════════════════════════════════ */
/* Framboise et non violet : c'est la couleur du refus et de la perte dans
   toute la charte. Encadré à part, en bas de l'onglet — une action
   irréversible ne se croise pas au milieu d'un bilan. */
.pf-danger{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  padding:18px 20px;border-radius:10px;background:var(--surface);
  border:1px solid rgba(249,38,89,0.28);}
/* Sélecteur d'adjacence et non un margin-bottom sur tous : le DERNIER bloc de
   la section n'a alors rien à rattraper, et .pf-sec garde la maîtrise de
   l'espace qui la suit. Un bloc masqué (hidden = display:none) ne compte pas :
   l'espace tombe bien entre les deux blocs VISIBLES. */
.pf-danger + .pf-danger{margin-top:12px;}
/* ⚠ INDISPENSABLE à côté du display:flex ci-dessus : l'attribut hidden vaut
   display:none dans la feuille du navigateur, mais TOUTE déclaration d'auteur
   le bat. Sans cette ligne, le bloc « Retirer ma photo » resterait affiché en
   permanence, même sans photo. */
.pf-danger[hidden]{display:none;}
/* .pf-neutre : la mise en page du bloc voisin, sans son rouge. Le retrait de
   photo et le changement de pseudo ne sont pas des actions destructrices ; les
   peindre en framboise ferait croire qu'on va perdre quelque chose.
   Ces règles vivaient sur #pfPhotoBloc, en dur. Une classe : le second bloc
   n'a plus eu qu'à la porter, au lieu d'un second paquet de règles par id. */
.pf-neutre{border-color:var(--border);}
.pf-neutre .pf-danger-btn{background:transparent;color:var(--text-muted);border-color:var(--border);}
@media (hover:hover){
  .pf-neutre .pf-danger-btn:hover{color:var(--text);border-color:var(--purple-dim);
    background:rgba(109,40,217,0.08);box-shadow:none;}
}
/* Le bouton inerte pendant les trois mois d'attente. .pf-danger-btn[disabled]
   coupe déjà les événements ; on retire aussi le curseur main, qui promettait
   un clic qui n'arrive pas. */
.pf-neutre .pf-danger-btn[disabled]{cursor:default;}
/* Valider : pleine largeur comme le bouton de suppression, pour la même raison
   - c'est l'action de la fenêtre, pas une option parmi d'autres. */
/* min-height 44px : le .btn du site plafonne à 42, et c'est le bouton
   principal d'une fenêtre qu'on ouvre au doigt. Même hauteur que le
   bouton de la fenêtre voisine (.pf-danger-btn). */
.pf-ps-valider{width:100%;margin-top:16px;justify-content:center;min-height:44px;}
/* 1rem = 16 px : en dessous, iOS zoome tout seul quand le champ prend le focus. */
#pfPsChamp{margin-top:8px;font-size:1rem;}
.pf-danger-txt{flex:1;min-width:220px;}
.pf-danger-txt b{display:block;font-weight:700;font-size:0.92rem;color:var(--text);
  margin-bottom:6px;}
.pf-danger-txt p{font-size:0.82rem;line-height:1.55;color:var(--text-muted);}
.pf-danger-btn{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 18px;border-radius:8px;cursor:pointer;white-space:nowrap;
  background:rgba(249,38,89,0.07);border:1px solid rgba(249,38,89,0.35);
  color:var(--red);font-family:var(--font-body);font-size:0.84rem;font-weight:700;
  transition:border-color .2s ease,box-shadow .2s ease,background .2s ease;}
.pf-danger-btn[disabled]{opacity:0.45;pointer-events:none;}
.pf-sup-valider{width:100%;margin-top:14px;padding:14px;}
/* Au-dessus des deux autres fenêtres : c'est la dernière qu'on ouvre. */
.pf-pop-3{z-index:940;}
.pf-sup-liste{font-size:0.86rem;line-height:1.6;color:var(--text-muted);margin-bottom:18px;}
.pf-sup-liste b{display:block;color:var(--text);margin-bottom:8px;font-size:0.88rem;}
.pf-sup-liste ul{padding-left:20px;}
.pf-sup-liste li{margin-bottom:5px;}
#pfSupPseudo{color:var(--red);text-transform:none;}
/* 1rem = 16 px : en dessous, iOS zoome tout seul quand le champ prend le focus. */
#pfSupChamp{margin-top:8px;font-size:1rem;}

@media (max-width:600px){
  .pf-danger{gap:14px;padding:16px;}
  .pf-danger-btn{width:100%;}
}

@media (hover:hover){
  .pf-danger-btn:hover{background:rgba(249,38,89,0.13);border-color:var(--red);
    box-shadow:var(--glow-raspberry);}
}

/* ══════════════════════════════════════════════════
   LE RANGEMENT D'UN AUTRE JOUEUR
   ══════════════════════════════════════════════════ */
/* Une image, pas un outil : rien ne se glisse, rien ne se clique. Le
   pointer-events le dit au navigateur, et l'absence de curseur au joueur. */
.pf-tl-retour{display:inline-flex;align-items:center;gap:7px;min-height:38px;
  padding:0 4px;margin-bottom:12px;background:none;border:none;cursor:pointer;
  font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--text-muted);}
.pf-tl-retour::before{content:"";width:7px;height:7px;
  border-left:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg);}
.pf-tl-tete{margin-bottom:14px;}
.pf-tl-titre{font-family:var(--font-display);font-weight:900;font-size:0.95rem;
  letter-spacing:-0.04em;color:var(--text);line-height:1.2;}
.pf-tl-sous{margin-top:5px;font-family:var(--font-mono);font-size:0.55rem;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--text-muted);}
.pf-tl-board{display:flex;flex-direction:column;gap:4px;pointer-events:none;}
.pf-tl-rang{display:flex;align-items:stretch;gap:0;border-radius:6px;overflow:hidden;
  background:var(--surface2);min-height:46px;}
/* Le libellé prend la couleur du tier, comme sur la page de tierlist. */
.pf-tl-lbl{flex:0 0 46px;display:flex;align-items:center;justify-content:center;
  background:var(--tl-c);color:#0A0710;font-family:var(--font-display);font-weight:900;
  font-size:0.88rem;letter-spacing:-0.04em;text-align:center;word-break:break-word;
  padding:4px 2px;}
.pf-tl-items{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:3px;padding:4px;}
.pf-tl-item{width:38px;height:38px;border-radius:4px;flex-shrink:0;
  background:var(--img) center/cover no-repeat;
  border:1px solid rgba(248,245,255,0.12);}
/* Sans visuel, le nom fait l'affaire — un rangement se lit aussi en toutes
   lettres. */
.pf-tl-item.txt{width:auto;max-width:100%;padding:0 8px;display:flex;align-items:center;
  background:var(--surface);font-size:0.62rem;font-weight:700;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pf-tl-vide{padding:10px 4px;font-family:var(--font-mono);font-size:0.55rem;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--text-muted);}

@media (hover:hover){
  .pf-tl-retour:hover{color:var(--purple-light);}
}

/* ══════════════════════════════════════════════════
   ONGLET PACKS
   ══════════════════════════════════════════════════ */

/* ── La pochette scellée ──────────────────────────────────────────────────
   Le même objet pour les quatre packs : c'est ce qui permet à l'animation de
   découpe d'être unique. Seule l'étiquette change, et --pk-c porte le palier.
   Elle sert aussi bien de vignette dans la grille que d'objet à couper. */
.pk-poch{position:relative;aspect-ratio:1/1.16;border-radius:8px;overflow:hidden;
  background:linear-gradient(158deg,#1b1528 0%,#0c0913 52%,#171224 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07),0 14px 34px -16px #000,var(--pk-halo,none);
  isolation:isolate;}
/* Le plastique : un reflet diagonal figé, sinon la pochette se lit comme une
   carte à jouer et le geste de découpe ne va plus de soi. */
.pk-poch::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(112deg,transparent 26%,rgba(255,255,255,.10) 42%,
    rgba(255,255,255,.02) 50%,transparent 64%);}
/* Le disque qu'on devine à travers le plastique. Il annonce le contenu, là où
   un logo de plus n'aurait rien dit. */
.pk-disque{position:absolute;left:50%;top:42%;transform:translate(-50%,-50%);
  width:56%;aspect-ratio:1;border-radius:50%;opacity:.5;
  background:
    radial-gradient(circle,color-mix(in srgb,var(--pk-c) 55%,transparent) 0 11%,transparent 11%),
    repeating-radial-gradient(circle,rgba(255,255,255,.055) 0 2px,transparent 2px 5px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);}
/* Les soudures du blister, en haut et en bas. */
.pk-soud{position:absolute;left:0;right:0;height:6.5%;pointer-events:none;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.11) 0 3px,transparent 3px 6px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);}
.pk-soud.h{top:0;} .pk-soud.b{bottom:0;}
/* L'étiquette de studio. Toujours claire, avec une bande latérale colorée :
   une étiquette au fond violet éteint aurait un texte noir illisible. */
.pk-etiq{position:absolute;left:7%;right:7%;bottom:13%;z-index:2;
  transform:rotate(-2.4deg);background:#EDE9F5;border-radius:3px;
  padding:6px 8px 5px 13px;overflow:hidden;box-shadow:0 6px 16px -6px #000;}
.pk-etiq::before{content:'';position:absolute;left:0;top:0;bottom:0;width:9px;
  background:var(--pk-c);}
.pk-etiq b{display:block;font-family:var(--font-display);font-weight:900;
  font-size:0.66rem;letter-spacing:-0.02em;text-transform:uppercase;color:#0A0710;}
.pk-etiq i{display:block;font-style:normal;font-family:var(--font-mono);
  font-size:0.48rem;letter-spacing:0.16em;text-transform:uppercase;
  color:rgba(10,7,16,.72);margin-top:1px;}
.pk-code{margin-top:4px;height:7px;border-radius:1px;opacity:.8;
  background:repeating-linear-gradient(90deg,#0A0710 0 2px,transparent 2px 3px,
    #0A0710 3px 4px,transparent 4px 6px,#0A0710 6px 9px,transparent 9px 10px);}

/* ── Le solde ─────────────────────────────────────────────────────────────
   En haut et toujours visible : c'est la contrainte qui commande tout le
   reste de l'écran. */
.pk-solde{display:flex;align-items:center;gap:14px;padding:16px 18px;
  background:var(--surface);border:1px solid var(--border);border-radius:12px;
  margin-bottom:14px;flex-wrap:wrap;}
.pk-solde-i{width:38px;height:38px;flex:none;border-radius:9px;
  background:color-mix(in srgb,var(--purple) 22%,transparent);
  display:grid;place-items:center;}
.pk-solde-i em{display:block;width:20px;height:20px;background:var(--purple-light);
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.pk-solde-t{flex:1;min-width:120px;}
.pk-solde-t span{display:block;font-family:var(--font-mono);font-size:0.56rem;
  letter-spacing:0.18em;text-transform:uppercase;color:var(--text-muted);}
.pk-solde-t b{display:block;font-family:var(--font-display);font-weight:900;
  font-size:1.32rem;letter-spacing:-0.04em;color:var(--purple-light);line-height:1.15;}
.pk-aide{padding:14px 16px;margin-bottom:22px;background:var(--surface);
  border:1px solid var(--border);border-radius:12px;font-size:0.84rem;
  color:var(--text-muted);line-height:1.7;}
/* L'aide compte deux paragraphes depuis qu'elle annonce les packs offerts :
   sans écart, les deux blocs se lisaient comme une seule phrase. */
.pk-aide p + p{margin-top:10px;}

/* ── Les packs offerts ────────────────────────────────────────────────────
   Sous la grille : c'est un rappel, pas une action. Le repère qui manque à
   celui qui vient d'ouvrir son pack du jour et n'a plus de raison de revenir. */
.pk-offres{grid-column:1/-1;margin-top:6px;padding:14px 16px;background:var(--surface);
  border:1px solid var(--border);border-radius:12px;
  display:flex;flex-direction:column;gap:9px;}
.pk-offres-t{font-family:var(--font-mono);font-size:0.58rem;font-weight:700;
  letter-spacing:0.18em;text-transform:uppercase;color:var(--text-muted);}
.pk-offre{display:flex;align-items:baseline;justify-content:space-between;gap:12px;}
.pk-offre b{font-family:var(--font-body);font-weight:700;font-size:0.88rem;color:var(--text);}
.pk-offre span{font-family:var(--font-mono);font-size:0.62rem;letter-spacing:0.08em;
  color:var(--text-muted);text-align:right;}
/* Un cadeau qui attend se dit en framboise, comme la pastille : même message. */
.pk-offre.pret span{color:#FF5C86;font-weight:700;}
.pk-offre.pret b{color:var(--text);}

/* Le bouton d'un pack OFFERT est LIME, comme tout pack qui attend.
   Il a été violet un temps, pour marquer le cadeau. Ce n'est plus utile : la
   pastille « Offert » posée sur la pochette dit d'où vient le pack, et la
   couleur peut donc répondre à une question plus utile — violet = ça va te
   coûter, lime = c'est à toi, ouvre-le. Aucune règle propre n'est nécessaire :
   .pk-btn.pret fait déjà tout le travail. */
.pk-aide b{color:var(--text);font-weight:600;}

/* ── La grille ────────────────────────────────────────────────────────────*/
.pk-grille{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;}
.pk-carte{background:var(--surface);border:1px solid var(--border);border-radius:12px;
  padding:12px;display:flex;flex-direction:column;gap:10px;min-width:0;}
/* position:relative pour la pastille « Offert » ci-dessous : sans lui, elle se
   placerait par rapport à la page. */
.pk-visuel{cursor:pointer;border:none;background:none;padding:0;display:block;
  width:100%;position:relative;}
/* La pastille « Offert », en haut à droite de la pochette.
   Posée sur .pk-visuel et NON sur .pk-poch : cette dernière est en
   overflow:hidden pour rogner l'étiquette de studio, tournée de -2,4°, qui
   dépasserait sinon de la pochette. Y passer en overflow:visible ferait
   ressortir ses coins.
   C'est la .nz-bulle du site — celle de la nav et de l'avatar — reprise telle
   quelle : même objet, même framboise, aucun nouveau code visuel à apprendre.
   La carte n'a pas d'overflow:hidden, le débord de 7px reste donc visible. */
.pk-visuel>.nz-bulle{position:absolute;top:-7px;right:-7px;z-index:6;
  height:20px;min-width:20px;padding:0 8px;
  font-size:0.55rem;letter-spacing:0.08em;}
.pk-cout{display:flex;align-items:center;justify-content:center;gap:6px;
  font-family:var(--font-mono);font-size:0.66rem;letter-spacing:0.10em;
  color:var(--purple-light);}
.pk-cout em{width:13px;height:13px;background:currentColor;flex:none;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.pk-cout.court{color:var(--red);}
/* Typographie des boutons du site (.btn dans style.css) : DM Sans en 700,
   0.85rem, 0.08em d'interlettrage. Le style « libellé technique » de
   --font-mono est réservé aux étiquettes, pas aux actions.
   font-size:clamp() parce qu'en grille à quatre colonnes « Acheter ce pack »
   en 0.85rem déborde ; le bouton descend jusqu'à 0.72rem plutôt que de
   couper le mot. */
.pk-btn{min-height:44px;border:none;border-radius:6px;cursor:pointer;width:100%;
  padding:10px 12px;font-family:var(--font-body);font-weight:700;
  font-size:clamp(0.72rem,1.6vw,0.85rem);letter-spacing:0.08em;
  text-transform:uppercase;color:var(--text);
  background:linear-gradient(135deg,var(--purple),var(--purple2));
  transition:filter .2s ease,box-shadow .2s ease,transform .2s ease;}
/* Lime = un pack t'attend, rien à payer. Violet = tu dépenses.
   font-weight:600 et non 700 : à graisse ÉGALE, du texte sombre sur un fond
   clair paraît plus gras que du clair sur du sombre. Les deux boutons étaient
   bien à 700, et le lime sortait quand même plus lourd qu'« Acheter ce pack ».
   On descend d'un cran pour qu'ils se ressemblent à l'œil, pas dans le code. */
.pk-btn.pret{background:var(--green);color:#0A0710;box-shadow:var(--glow-lime);
  font-weight:600;}
/* Le bouton qui clôt l'ouverture d'un pack : violet de marque et halo. Il
   n'annonce pas « quelque chose t'attend » — il valide ce qui vient d'être
   gagné, c'est l'action centrale de l'écran. */
.pk-btn-fort{box-shadow:var(--glow-violet-strong);}
.pk-btn:disabled{background:var(--surface2);color:var(--text-muted);cursor:not-allowed;}
.pk-detail{border:none;background:none;cursor:pointer;padding:2px;min-height:44px;
  font-family:var(--font-mono);font-size:0.53rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);text-decoration:underline;}
@media (hover:hover){
  /* translateY(-2px) : le survol des boutons du site, repris tel quel. */
  .pk-btn:hover{transform:translateY(-2px);filter:brightness(1.08);box-shadow:var(--glow-violet);}
  .pk-btn.pret:hover{transform:translateY(-2px);filter:brightness(1.06);box-shadow:var(--glow-lime);}
  .pk-btn:disabled:hover{transform:none;filter:none;box-shadow:none;}
  .pk-detail:hover{color:var(--text);}
}

/* ── La fiche des cotes ───────────────────────────────────────────────────
   Sous la grille et non en pop-up : on compare les quatre packs sans avoir à
   fermer et rouvrir. */
.pk-fiche{grid-column:1/-1;background:var(--surface);border:1px solid var(--border);
  border-radius:12px;padding:18px;}
.pk-fiche-t{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin-bottom:14px;flex-wrap:wrap;}
.pk-fiche-t b{font-family:var(--font-display);font-weight:900;font-size:0.92rem;
  letter-spacing:-0.03em;text-transform:uppercase;}
.pk-fiche-t span{font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--completion);}
.pk-cote-tete{font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:11px;line-height:1.5;}
.pk-cote{display:flex;align-items:center;gap:10px;margin-bottom:9px;}
.pk-cote-n{width:88px;flex:none;font-family:var(--font-mono);font-size:0.58rem;
  letter-spacing:0.12em;text-transform:uppercase;color:var(--rar-c);}
.pk-cote-j{flex:1;height:8px;border-radius:4px;background:var(--surface2);overflow:hidden;}
/* Barres strictement proportionnelles : une barre qui gonfle le 1,5 % ferait
   croire que le Légendaire est à portée. Le chiffre dit la vérité, la barre
   doit la servir. */
.pk-cote-j i{display:block;height:100%;border-radius:4px;background:var(--rar-c);min-width:3px;}
.pk-cote-v{width:54px;flex:none;text-align:right;font-family:var(--font-mono);
  font-size:0.62rem;color:var(--text);font-variant-numeric:tabular-nums;}
.pk-note{margin-top:14px;padding-top:13px;border-top:1px solid var(--border);
  font-size:0.79rem;color:var(--text-muted);line-height:1.6;}
.pk-note b{color:var(--text);font-weight:600;}
.pk-jauge{margin-top:12px;}
.pk-jauge-h{display:flex;justify-content:space-between;align-items:baseline;
  font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:5px;}
.pk-jauge-h b{color:#FFC93C;}
.pk-jauge-b{height:9px;border-radius:5px;background:var(--surface2);overflow:hidden;}
.pk-jauge-b i{display:block;height:100%;border-radius:5px;
  background:linear-gradient(90deg,var(--orange-dark),#FFC93C);
  box-shadow:0 0 14px rgba(255,201,60,.45);}

@media (max-width:700px){.pk-grille{grid-template-columns:repeat(2,1fr);}}

/* ══════════════════════════════════════════════════
   L'OUVERTURE D'UN PACK
   ══════════════════════════════════════════════════ */

/* z-index 950 : style.css pose position:fixed;z-index:900 sur la balise <nav>
   nue, un overlay en dessous passerait sous la barre de navigation.
   overflow:hidden parce que le vinyle sort de l'écran pendant l'animation, et
   qu'un débordement ferait scroller la page derrière le modal. */
.ouv{position:fixed;inset:0;z-index:950;display:none;touch-action:none;overflow:hidden;
  background:radial-gradient(120% 90% at 50% 40%,#160f26 0%,#07050c 70%);
  overscroll-behavior:contain;}
.ouv.on{display:grid;place-items:center;}
.ouv-x{position:absolute;top:calc(env(safe-area-inset-top) + 10px);right:10px;
  width:44px;height:44px;z-index:5;border:none;background:none;cursor:pointer;
  display:grid;place-items:center;}
.ouv-x em{display:block;width:16px;height:16px;background:var(--text-muted);
  -webkit-mask:var(--picto-x) center/contain no-repeat;mask:var(--picto-x) center/contain no-repeat;}
.ouv-scene{position:relative;width:min(400px,88vw);text-align:center;}

/* — La pochette, en deux moitiés découpables —
   Volontairement plus étroite que la scène : une pochette qui touche les
   bords ne laisse plus la place au geste, et le vinyle n'a nulle part où
   sortir à la révélation. */
.ouv-pack{position:relative;width:min(258px,58vw);aspect-ratio:1/1.16;margin:0 auto;
  cursor:grab;user-select:none;-webkit-user-select:none;}
.ouv-moitie{position:absolute;inset:0;
  transition:transform .8s cubic-bezier(.3,-0.2,.4,1),opacity .8s ease;}
.ouv-moitie.haut{clip-path:var(--coupe-h);}
.ouv-moitie.bas{clip-path:var(--coupe-b);}
.ouv-moitie>*{position:absolute;inset:0;}
.ouv-pack.ouverte .haut{transform:translateY(-128%) rotate(-6deg);opacity:0;}
.ouv-pack.ouverte .bas{transform:translateY(128%) rotate(5deg);opacity:0;}

/* La ligne de découpe : pointillée tant qu'on n'a rien fait, elle se remplit
   d'un trait plein derrière le doigt. Le joueur voit son geste mordre. */
.ouv-ligne{position:absolute;left:0;right:0;top:50%;height:2px;
  transform:translateY(-50%);pointer-events:none;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.34) 0 7px,transparent 7px 13px);}
/* Une largeur nulle projette quand même son ombre : sans la classe .coupe,
   le halo du trait flottait à gauche de la pochette avant tout geste. */
.ouv-ligne i{position:absolute;left:0;top:-1px;height:4px;width:var(--p,0%);
  background:linear-gradient(90deg,transparent,#fff);}
.ouv-ligne.coupe i{box-shadow:0 0 16px 3px rgba(255,255,255,.72);}
.ouv-ligne b{position:absolute;left:var(--p,0%);top:50%;width:16px;height:16px;
  margin:-8px 0 0 -8px;border-radius:50%;opacity:var(--o,0);
  background:radial-gradient(circle,#fff 0%,rgba(255,255,255,.5) 38%,transparent 70%);}
/* Découpe de droite à gauche : le trait s'ancre à l'autre bord. On n'impose
   pas un sens, un gaucher n'entame pas du même côté qu'un droitier. */
.ouv-ligne.inv i{left:auto;right:0;background:linear-gradient(270deg,transparent,#fff);}
.ouv-ligne.inv b{left:auto;right:var(--p,0%);margin:-8px -8px 0 0;}
/* Amorces : elles dépassent de la pochette pour montrer que le geste peut
   commencer à côté de l'objet. Sans elles, personne ne l'essaie. */
.ouv-amorce{position:absolute;top:50%;width:18%;height:2px;margin-top:-1px;
  pointer-events:none;opacity:.30;
  background:repeating-linear-gradient(90deg,var(--text-muted) 0 5px,transparent 5px 11px);}
.ouv-amorce.g{left:-21%;} .ouv-amorce.d{right:-21%;}

.ouv-aide{margin-top:22px;font-family:var(--font-mono);font-size:0.6rem;
  letter-spacing:0.18em;text-transform:uppercase;color:var(--text-muted);}
.ouv-aide em{display:inline-block;font-style:normal;margin-left:6px;
  animation:ouvPousse 1.5s ease-in-out infinite;}
@keyframes ouvPousse{0%,100%{transform:translateX(-5px);opacity:.4;}50%{transform:translateX(5px);opacity:1;}}
/* Le repli. Il apparaît après quatre secondes d'hésitation, et tout de suite
   si le joueur a demandé moins d'animations : le geste est le plaisir, il ne
   doit pas être un péage. */
.ouv-secours{margin-top:14px;min-height:44px;padding:0 18px;border-radius:9px;
  border:1px solid var(--border);background:var(--surface);color:var(--text-muted);
  font-family:var(--font-mono);font-size:0.56rem;letter-spacing:0.14em;
  text-transform:uppercase;cursor:pointer;opacity:0;pointer-events:none;
  transition:opacity .3s ease;}
.ouv-secours.vu{opacity:1;pointer-events:auto;}

/* — La révélation — */
.rev{position:absolute;inset:0;display:none;}
.rev.on{display:flex;flex-direction:column;align-items:center;justify-content:center;
  isolation:isolate;}
/* Un absolu sans z-index passe DEVANT ses frères statiques : sans ce plan
   explicite, le halo de rareté voile la pochette. */
.rev-rayons{position:absolute;z-index:0;left:50%;top:38%;width:150%;aspect-ratio:1;
  transform:translate(-50%,-50%);opacity:0;pointer-events:none;
  background:
    radial-gradient(circle,color-mix(in srgb,var(--rar-c) 20%,transparent) 0%,
      color-mix(in srgb,var(--rar-c) 7%,transparent) 30%,transparent 56%),
    conic-gradient(from 0deg,transparent 0 6deg,
      color-mix(in srgb,var(--rar-c) 30%,transparent) 6deg 12deg,transparent 12deg 30deg,
      color-mix(in srgb,var(--rar-c) 16%,transparent) 30deg 34deg,transparent 34deg 60deg);
  filter:blur(10px);animation:revRayons 22s linear infinite;}
.rev.on .rev-rayons{opacity:var(--rayons,0);transition:opacity .6s ease .3s;}
@keyframes revRayons{to{transform:translate(-50%,-50%) rotate(360deg);}}

.rev-obj{position:relative;z-index:1;width:min(238px,54vw);aspect-ratio:1;margin:0 auto;
  transform:scale(.62);opacity:0;}
.rev.on .rev-obj{animation:revEntree .55s cubic-bezier(.2,1.4,.4,1) forwards;}
@keyframes revEntree{to{transform:scale(1);opacity:1;}}
/* Le vinyle sort de la pochette : il part caché derrière et coulisse. */
.rev-vinyle{position:absolute;inset:-3.5%;border-radius:50%;z-index:0;
  background:
    radial-gradient(circle,#0c0c0f 0 17%,transparent 17%),
    repeating-radial-gradient(circle,#131318 0 2px,#08080b 2px 4px);
  transform:translateX(0) rotate(0deg);}
.rev.on .rev-vinyle{animation:revSort 1.1s cubic-bezier(.25,.8,.3,1) .35s forwards;}
@keyframes revSort{to{transform:translateX(47%) rotate(190deg);}}
/* L'étiquette centrale prend la couleur de la rareté : le disque annonce ce
   qui vient de tomber avant même qu'on lise le badge. */
.rev-vinyle::after{content:'';position:absolute;left:50%;top:50%;width:31%;height:31%;
  margin:-15.5% 0 0 -15.5%;border-radius:50%;
  background:radial-gradient(circle,#0A0710 0 13%,var(--rar-c) 13% 100%);
  box-shadow:0 0 22px -2px var(--rar-c);}
.rev-cover{position:relative;z-index:1;width:100%;height:100%;object-fit:cover;
  border-radius:5px;display:block;background:var(--surface2);
  box-shadow:0 18px 44px -14px #000,0 0 0 1px rgba(255,255,255,.1),
             0 0 34px -6px var(--rar-c);}
.rev-badge{position:relative;z-index:1;margin:26px auto 0;display:inline-flex;
  align-items:center;padding:6px 14px;border-radius:999px;
  background:color-mix(in srgb,var(--rar-c) 18%,transparent);
  box-shadow:inset 0 0 0 1px var(--rar-c);
  font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.2em;
  text-transform:uppercase;color:var(--rar-c);opacity:0;}
.rev.on .rev-badge{animation:revTexte .4s ease .95s forwards;}
.rev-nom{position:relative;z-index:1;margin-top:14px;font-family:var(--font-display);
  font-weight:900;font-size:1.02rem;letter-spacing:-0.04em;text-transform:uppercase;
  opacity:0;padding:0 12px;text-wrap:balance;}
.rev-art{position:relative;z-index:1;margin-top:3px;font-size:0.82rem;
  color:var(--text-muted);opacity:0;}
.rev.on .rev-nom{animation:revTexte .4s ease 1.05s forwards;}
.rev.on .rev-art{animation:revTexte .4s ease 1.15s forwards;}
@keyframes revTexte{from{opacity:0;transform:translateY(7px);}to{opacity:1;transform:none;}}
.rev-dbl{position:relative;z-index:1;margin-top:10px;font-family:var(--font-mono);
  font-size:0.56rem;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--completion);opacity:0;}
/* À la révélation, le badge est posé DANS le flux, pas en pastille de coin :
   il remplace la mention « doublon » au même endroit. */
.badge-new-pill.enligne{position:static;display:inline-flex;font-size:0.56rem;
  letter-spacing:0.16em;padding:5px 12px 5px 10px;}
.rev.on .rev-dbl{animation:revTexte .4s ease 1.25s forwards;}
.rev-pied{position:relative;z-index:1;margin-top:20px;opacity:0;}
.rev.on .rev-pied{animation:revTexte .4s ease 1.4s forwards;}
.rev-compte{font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.2em;
  color:var(--text-muted);font-variant-numeric:tabular-nums;}
/* « Continuer » était un simple texte : rien ne disait qu'on pouvait
   appuyer. C'est un bouton du site, en contour pour ne pas voler la vedette
   à la pochette. Toute la zone reste cliquable au doigt. */
.rev-suite{margin-top:9px;display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:0 22px;border-radius:6px;cursor:pointer;
  background:transparent;color:var(--purple-light);border:1px solid var(--purple-dim);
  font-family:var(--font-body);font-weight:700;font-size:0.8rem;
  letter-spacing:0.08em;text-transform:uppercase;
  transition:border-color .2s ease,background .2s ease;}
@media (hover:hover){
  .rev-suite:hover{border-color:var(--purple);background:rgba(109,40,217,0.10);}
}

/* — Le bilan — */
.pk-bilan{position:absolute;inset:0;display:none;flex-direction:column;
  justify-content:center;padding:0 4px;}
.pk-bilan.on{display:flex;}
.pk-bilan h3{font-family:var(--font-display);font-weight:900;font-size:1.05rem;
  letter-spacing:-0.04em;text-transform:uppercase;margin-bottom:16px;}
/* flex et non grid : une grille à 3 colonnes fixes laissait la pochette d'un
   pack Maquette (1 projet) collée à gauche avec deux cases vides, et donnait
   3 + 1 orphelin pour un Mastering (4 projets).
   Le nombre de colonnes est posé par le JS dans --cols, d'après le nombre réel
   de projets tirés ; en flex, une dernière rangée incomplète se centre d'elle-
   même, ce qu'une grille ne sait pas faire. */
/* justify-content:center : les colonnes sont plus étroites que le conteneur
   dès qu'il y en a moins de trois, et c'est ce qui les centre. Une grille en
   1fr remplissait toute la largeur et laissait la pochette d'un pack à un seul
   projet collée à gauche.
   grid-template-columns est posé EN LIGNE par pkBilanAfficher() : le nombre de
   colonnes ET la largeur des cases dépendent du nombre de projets tirés.
   La valeur ci-dessous n'est qu'un repli si le JS n'a pas tourné.
   ⚠ Une piste écartée : flex + max-width. Le plafond rétrécissait les cases
   au point qu'il en tenait TROIS par rangée alors qu'on en voulait deux — en
   flex, c'est la largeur qui décide du retour à la ligne, pas un compte. */
.pk-bilan-g{display:grid;grid-template-columns:repeat(3,1fr);
  justify-content:center;gap:9px;margin-bottom:14px;}
.pk-bilan-c{position:relative;border-radius:6px;overflow:hidden;aspect-ratio:1;
  background:var(--surface2);
  box-shadow:0 0 0 1px var(--rar-c),0 0 16px -6px var(--rar-c);}
.pk-bilan-c img{width:100%;height:100%;object-fit:cover;display:block;}
.pk-bilan-c span{position:absolute;left:0;right:0;bottom:0;padding:3px 0;
  background:color-mix(in srgb,var(--rar-c) 88%,#000);color:#0A0710;
  font-family:var(--font-mono);font-size:0.44rem;letter-spacing:0.1em;
  text-transform:uppercase;text-align:center;}
.pk-bilan-c em{position:absolute;top:4px;right:4px;font-style:normal;
  background:var(--completion);color:#0A0710;border-radius:3px;padding:1px 4px;
  font-family:var(--font-mono);font-size:0.44rem;letter-spacing:0.06em;}
.pk-bilan-dbl{margin-bottom:14px;text-align:center;font-family:var(--font-mono);
  font-size:0.56rem;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--completion);}

@media (prefers-reduced-motion:reduce){
  .rev-rayons{animation:none;}
  .rev.on .rev-obj,.rev.on .rev-vinyle{animation-duration:.01s;}
  .ouv-moitie{transition-duration:.2s;}
  .ouv-aide em{animation:none;}
}


/* ══════════════════════════════════════════════════
   ONGLET COLLECTION
   ══════════════════════════════════════════════════ */
/* ── Le compteur de complétion ────────────────────────────────────────────*/
.cl-comp{background:var(--surface);border:1px solid var(--border);border-radius:12px;
  padding:16px;margin-bottom:22px;}
.cl-comp-h{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;margin-bottom:9px;flex-wrap:wrap;}
.cl-comp-h b{font-family:var(--font-display);font-weight:900;font-size:1.05rem;
  letter-spacing:-0.04em;color:var(--completion);}
.cl-comp-h span{font-family:var(--font-mono);font-size:0.56rem;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--text-muted);}
/* Exactement le traitement de .pf-dep-jauge (complétion d'un jeu) : piste
   orange sombre, remplissage --completion vers un ton plus clair. L'ancien
   dégradé partait du sombre vers le clair, comme la jauge légendaire — deux
   jauges qui mesurent des choses différentes ne doivent pas se ressembler. */
.cl-comp-j{height:9px;border-radius:5px;background:var(--orange-dark);overflow:hidden;}
.cl-comp-j i{display:block;height:100%;border-radius:5px;
  background:linear-gradient(90deg,var(--completion),
    color-mix(in srgb,var(--completion) 55%,#F8F5FF));}
.cl-comp-r{display:flex;gap:16px;flex-wrap:wrap;margin-top:13px;}
.cl-comp-r div{font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.1em;
  color:var(--rar-c);font-variant-numeric:tabular-nums;}
/* display:flex et non block : le libellé porte maintenant sa pastille de
   couleur, il faut les aligner. */
.cl-comp-r div span{color:var(--text-muted);letter-spacing:0.16em;
  text-transform:uppercase;font-size:0.52rem;display:flex;align-items:center;
  gap:5px;margin-bottom:2px;}
/* La même pastille que dans la légende de l'accueil (.pack-legende i), au
   jeton près : ici la couleur s'appelle --rar-c, posée en ligne par le JS. */
.cl-comp-r i{width:8px;height:8px;border-radius:2px;flex:none;
  background:var(--rar-c);
  box-shadow:0 0 8px color-mix(in srgb,var(--rar-c) 60%,transparent);}

/* ── Filtres ──────────────────────────────────────────────────────────────*/
/* Le tri est une barre à part, au-dessus de la grille : mêlé aux sections de
   rareté il se lirait comme un filtre de plus. */
/* ── Recherche dans la collection ─────────────────────────────────────────
   Même pilule que #presetSearch (Tierlist) et #albumSearch (Remets l'album
   dans l'ordre) : loupe en fond, contour qui s'allume au survol puis au focus.
   Une seule différence, volontaire, expliquée sur font-size. */
/* ── Menu des tris ────────────────────────────────────────────────────────
   Remplace les six chips. Fermé, il affiche le tri en cours : on doit savoir
   comment la grille est rangée sans rien ouvrir. */
.cl-menu{display:flex;align-items:center;gap:8px;flex:1;min-width:0;max-width:300px;
  min-height:44px;padding:0 14px;background:var(--surface);border:1px solid var(--border);
  border-radius:999px;cursor:pointer;color:var(--text);font-family:var(--font-mono);
  font-size:0.62rem;letter-spacing:0.1em;text-transform:uppercase;text-align:left;
  transition:border-color .18s ease,box-shadow .18s ease;}
.cl-menu-l{color:var(--text-muted);flex:none;}
/* Le libellé peut être long (« Légendaire → Commun ») : il s'efface à l'ellipse
   plutôt que de pousser le chevron hors du bouton. */
.cl-menu b{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:700;color:var(--text);}
.cl-menu em{flex:none;width:8px;height:8px;border-right:2px solid var(--purple-light);
  border-bottom:2px solid var(--purple-light);transform:rotate(45deg) translate(-2px,-2px);}
.cl-menu[aria-expanded="true"]{border-color:var(--purple);box-shadow:var(--glow-violet);}
@media (hover:hover){ .cl-menu:hover{border-color:var(--purple-dim);} }

.cl-pan{position:absolute;top:calc(100% + 6px);left:0;z-index:40;min-width:230px;
  background:var(--surface);border:1px solid var(--purple-dim);border-radius:10px;
  padding:5px;box-shadow:0 18px 44px rgba(0,0,0,.6);display:flex;flex-direction:column;}
/* ⚠ [hidden] perd contre display:flex : sans cette ligne, le panneau serait
   ouvert en permanence. */
.cl-pan[hidden]{display:none;}
.cl-pan button{min-height:44px;padding:0 13px;background:none;border:none;border-radius:7px;
  cursor:pointer;text-align:left;color:var(--text-muted);font-family:var(--font-mono);
  font-size:0.6rem;letter-spacing:0.1em;text-transform:uppercase;}
.cl-pan button[aria-selected="true"]{background:var(--purple);color:#fff;font-weight:700;}
@media (hover:hover){
  .cl-pan button:not([aria-selected="true"]):hover{background:var(--surface2);color:var(--text);}
}

/* ── Rond de recherche ────────────────────────────────────────────────────
   44px pile : c'est un bouton d'icône, la taille minimale est la taille. */
.cl-rond{width:44px;height:44px;flex:none;border-radius:50%;border:1px solid var(--border);
  background:var(--surface);color:var(--purple-light);cursor:pointer;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  transition:border-color .18s ease,box-shadow .18s ease;}
.cl-rond svg{width:18px;height:18px;}
.cl-rond[aria-expanded="true"]{border-color:var(--purple);box-shadow:var(--glow-violet);}
@media (hover:hover){ .cl-rond:hover{border-color:var(--purple-dim);} }

@media (max-width:600px){
  /* Le libellé de l'interrupteur saute : il devient un simple bouton d'icône.
     Le compte des manquants reste lisible dans le récapitulatif au-dessus. */
  .cl-bascule span{display:none;}
  .cl-bascule{width:44px;padding:0;justify-content:center;flex:none;}
  .cl-menu{max-width:none;}
}

/* Dépliée par le rond de la barre, jamais visible d'emblée. Marge haute
   négative pour la coller sous la barre : elle en est le prolongement, pas un
   bloc de plus. */
.cl-cherche{position:relative;max-width:340px;margin:-6px 0 16px;}
.cl-cherche[hidden]{display:none;}
.cl-cherche input{display:block;width:100%;box-sizing:border-box;
  padding:13px 48px 13px 48px;
  background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CFB9F3' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='16.5' y1='16.5' x2='21' y2='21'/%3E%3C/svg%3E")
    no-repeat 18px center/18px 18px;
  border:1px solid var(--border);border-radius:999px;color:var(--text);
  font-family:var(--font-body);letter-spacing:0.02em;outline:none;
  /* 0.9rem : le rendu voulu. Bascule à 16px sur tactile, voir plus bas. */
  font-size:0.9rem;
  transition:border-color 0.25s ease,box-shadow 0.25s ease;
  /* La croix native de Safari doublerait la nôtre. */
  -webkit-appearance:none;appearance:none;}
/* ⚠ 16px sur TACTILE seulement. iOS Safari zoome la page quand on touche un
   champ dont la police fait moins de 16px, et il faut pincer pour revenir.
   Ça ne concerne QUE les appareils tactiles : à la souris, rien ne zoome
   jamais, le 0.9rem ci-dessus s'applique tel quel.
   pointer:coarse plutôt que la balise viewport : user-scalable=no est ignoré
   par iOS depuis iOS 10, et bloquer le pincer-zoomer serait de toute façon une
   entorse à l'accessibilité. Même raisonnement que les @media (hover:hover)
   du site : on cible l'appareil, pas la taille d'écran. */
@media (pointer: coarse){ .cl-cherche input{font-size:16px;} }
.cl-cherche input::-webkit-search-cancel-button{display:none;}
.cl-cherche input::placeholder{color:var(--text-muted);}
@media (hover:hover){ .cl-cherche input:hover{border-color:var(--purple-dim);} }
.cl-cherche input:focus{border-color:var(--purple);box-shadow:var(--glow-violet);}
/* La croix est un bouton de 44px : plus petite, elle serait intouchable au
   pouce. Elle occupe le padding droit du champ, d'où les 48px symétriques. */
.cl-cherche button{position:absolute;top:0;right:4px;width:44px;height:100%;
  background:none;border:none;cursor:pointer;color:var(--text-muted);
  font-size:1.5rem;line-height:1;padding:0;border-radius:999px;}
.cl-cherche button[hidden]{display:none;}
@media (hover:hover){ .cl-cherche button:hover{color:var(--text);} }
/* Sous 400px, la pilule prend toute la largeur. À 375px elle mesurait 340px
   dans une zone de 347 : les 7px restants se lisaient comme un défaut
   d'alignement avec la grille en dessous, pas comme un choix.
   400px : l'un des deux points de rupture qui portent le gros du CSS mobile,
   pas un neuvième seuil. */
@media (max-width:400px){ .cl-cherche{max-width:none;} }

.cl-barre{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:14px;}
/* ⚠ Restreint à #clBarre, et pas à la classe : .cl-barre sert AUSSI au choix de
   la vitrine (#pfChoixBarre), qui garde ses chips et a besoin de flex-wrap.
   Ici position:relative ancre le panneau des tris, et le non-retour à la ligne
   garantit que les trois contrôles restent alignés — un panneau ancré sur une
   barre qui se replie sauterait d'une ligne à l'autre. */
#clBarre{gap:8px;flex-wrap:nowrap;position:relative;}
/* ⚠ [hidden] perd contre TOUTE règle d'affichage : la feuille du navigateur
   ne bat jamais une feuille d'auteur, même à spécificité égale. Ces deux
   éléments déclarent display:flex et portaient donc leur attribut hidden sans
   aucun effet - mesuré : hidden posé, display:flex, hauteur non nulle. La
   barre de tri et l'interrupteur s'affichaient donc même sur une collection
   vide. Même correctif que .tu-voile, .pf-danger ou .ms-sect-corps. */
.cl-barre[hidden],.cl-bascule[hidden]{display:none;}
.cl-barre>b{font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--text-muted);font-weight:400;}
.cl-bascule{display:inline-flex;align-items:center;gap:9px;
  min-height:44px;padding:0 14px;border-radius:8px;border:1px solid var(--border);
  background:var(--surface);cursor:pointer;font-family:var(--font-mono);
  font-size:0.55rem;letter-spacing:0.12em;text-transform:uppercase;color:var(--text-muted);}
.cl-bascule[aria-pressed="true"]{color:var(--text);border-color:var(--purple-dim);}
/* L'interrupteur a rejoint .cl-barre, avec les tris : les deux règlent ce
   qu'on voit de la collection, ils vont ensemble.
   Sa marge basse de 26 px a donc sauté. Elle servait quand il était seul sur
   sa ligne, à l'écarter de la grille qu'il commande ; dans une barre en
   align-items:center, elle ne ferait plus que le décaler vers le haut par
   rapport aux chips. C'est la barre qui porte l'espacement maintenant. */
#clMasque{margin-bottom:0;}
.cl-bascule i{width:30px;height:17px;border-radius:9px;background:var(--surface2);
  box-shadow:inset 0 0 0 1px var(--border);position:relative;flex:none;
  transition:background .18s ease;}
.cl-bascule i::after{content:'';position:absolute;top:2px;left:2px;width:13px;height:13px;
  border-radius:50%;background:var(--text-muted);
  transition:transform .18s ease,background .18s ease;}
.cl-bascule[aria-pressed="true"] i{background:var(--purple-dim);}
.cl-bascule[aria-pressed="true"] i::after{transform:translateX(13px);background:var(--purple-light);}
@media (prefers-reduced-motion:reduce){ .cl-bascule i,.cl-bascule i::after{transition:none;} }
.cl-chips{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:16px;}
.cl-chip{border:1px solid var(--border);background:var(--surface);border-radius:999px;
  min-height:44px;padding:0 14px;cursor:pointer;font-family:var(--font-mono);
  font-size:0.55rem;letter-spacing:0.12em;text-transform:uppercase;color:var(--text-muted);}
.cl-chip[aria-pressed="true"]{color:#0A0710;background:var(--chip-c,var(--purple));
  border-color:transparent;font-weight:700;}

/* ── La grille ────────────────────────────────────────────────────────────*/
.cl-sect{margin-bottom:26px;}
.cl-sect-t{display:flex;align-items:baseline;gap:10px;margin-bottom:11px;}
.cl-sect-t b{font-family:var(--font-mono);font-size:0.6rem;letter-spacing:0.18em;
  text-transform:uppercase;color:var(--rar-c);}
.cl-sect-t span{font-family:var(--font-mono);font-size:0.55rem;color:var(--text-muted);
  font-variant-numeric:tabular-nums;}
.cl-grille{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:10px;}
.cl-c{position:relative;border:none;padding:0;background:var(--surface2);cursor:pointer;
  color:var(--text);
  border-radius:7px;overflow:hidden;aspect-ratio:1;display:block;width:100%;
  box-shadow:0 0 0 1px var(--rar-c);transition:transform .15s ease,box-shadow .15s ease;}
.cl-c img{width:100%;height:100%;object-fit:cover;display:block;}
/* Le liseré porte la rareté ; le nom vit dans la fiche, pas sur la vignette :
   quarante étiquettes empilées, ce n'est plus une collection, c'est un
   tableur. */
.cl-c-n{position:absolute;left:0;right:0;bottom:0;padding:16px 5px 4px;text-align:left;
  background:linear-gradient(transparent,rgba(10,7,16,.94) 48%);}
/* L'artiste est sur la vignette : sans lui, un tri par artiste ne se voit pas. */
.cl-c-n b{display:block;font-size:0.58rem;font-weight:600;line-height:1.2;
  /* color explicite : la carte est un <button>, et style.css ne pose pas
     color:inherit dessus. Sans cette ligne le titre sort en noir sur fond
     noir — invisible. L'artiste, lui, avait déjà sa couleur. */
  color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.cl-c-n i{display:block;font-style:normal;font-size:0.5rem;line-height:1.25;
  color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* « Nouveau » : c'est le badge du site (.badge-new-pill dans style.css,
   dégradé framboise). On le reprend tel quel, réduit — la pastille des
   GameCards déborderait d'une vignette de 105 px. Un second badge maison
   aurait fini par diverger de celui des jeux et des thèmes. */
.badge-new-pill.mini{top:5px;left:5px;font-size:0.5rem;letter-spacing:0.1em;
  padding:3px 7px 3px 6px;border-radius:14px;gap:3px;
  box-shadow:0 3px 10px rgba(249,38,89,0.4),0 0 0 1px rgba(248,245,255,0.15) inset;}
.badge-new-pill.mini::before{font-size:0.58rem;}
/* Le point de vitrine se décale quand le badge occupe déjà le coin. */
.cl-c.vitrine:has(.badge-new-pill)::after{top:auto;bottom:5px;left:5px;}
.cl-c-x{position:absolute;top:5px;right:5px;background:var(--completion);color:#0A0710;
  border-radius:4px;padding:1px 5px;font-family:var(--font-mono);font-size:0.52rem;
  font-weight:700;letter-spacing:0.04em;}
/* Manquant : la silhouette dit qu'il existe, sans dire lequel. Elle donne la
   taille de l'objectif sans éventer la surprise du pack. */
.cl-c.vide{cursor:default;background:var(--surface);box-shadow:inset 0 0 0 1px var(--border);}
.cl-c.vide em{position:absolute;inset:0;display:grid;place-items:center;font-style:normal;
  font-family:var(--font-display);font-weight:900;font-size:1.4rem;color:var(--border);}
.cl-c.vitrine::after{content:'';position:absolute;top:5px;left:5px;width:9px;height:9px;
  border-radius:50%;background:var(--purple-light);box-shadow:0 0 8px var(--purple);}
/* En lecture seule : rien n'est cliquable, le curseur ne doit pas le laisser
   croire. */
.cl-c.fige{cursor:default;}
@media (hover:hover){
  .cl-c:not(.vide):not(.fige):hover{transform:translateY(-2px);
    box-shadow:0 0 0 2px var(--rar-c),0 10px 22px -12px var(--rar-c);}
  .cl-chip:hover{color:var(--text);}
  .rg:hover{color:var(--text);}
}

/* ── La fiche d'un projet ─────────────────────────────────────────────────
   En pop-up centré : la grille est longue, une fiche dépliée en place ferait
   sauter tout ce qui est en dessous. z-index 930, au-dessus de la barre de
   navigation du site (900 sur la balise nue). */
.cl-pop{position:fixed;inset:0;z-index:930;display:none;padding:20px;
  background:rgba(6,4,11,.82);overflow-y:auto;overscroll-behavior:contain;}
.cl-pop.on{display:grid;place-items:center;}
.cl-pop-c{position:relative;width:min(400px,100%);background:var(--surface);
  border:1px solid var(--border);border-radius:14px;padding:20px;
  box-shadow:0 26px 60px -20px #000,0 0 40px -18px var(--rar-c);}
.cl-pop-x{position:absolute;top:8px;right:8px;width:44px;height:44px;border:none;
  background:none;cursor:pointer;display:grid;place-items:center;z-index:2;}
.cl-pop-x em{display:block;width:15px;height:15px;background:var(--text-muted);
  -webkit-mask:var(--picto-x) center/contain no-repeat;
          mask:var(--picto-x) center/contain no-repeat;}
.cl-pop-img{width:150px;aspect-ratio:1;margin:0 auto 16px;border-radius:8px;
  overflow:hidden;background:var(--surface2);
  box-shadow:0 0 0 1px var(--rar-c),0 0 30px -10px var(--rar-c);}
.cl-pop-img img{width:100%;height:100%;object-fit:cover;display:block;}
.cl-pop-r{display:inline-flex;padding:5px 13px;border-radius:999px;
  background:color-mix(in srgb,var(--rar-c) 18%,transparent);
  box-shadow:inset 0 0 0 1px var(--rar-c);color:var(--rar-c);
  font-family:var(--font-mono);font-size:0.54rem;letter-spacing:0.2em;
  text-transform:uppercase;margin-bottom:12px;}
.cl-pop-nom{font-family:var(--font-display);font-weight:900;font-size:1.02rem;
  letter-spacing:-0.04em;text-transform:uppercase;text-wrap:balance;}
.cl-pop-art{font-size:0.84rem;color:var(--text-muted);margin-top:3px;}
.cl-pop-q{margin-top:10px;font-family:var(--font-mono);font-size:0.56rem;
  letter-spacing:0.14em;text-transform:uppercase;color:var(--text-muted);}
.cl-pop-a{display:flex;flex-direction:column;gap:8px;margin-top:18px;}
/* Typographie des boutons du site (.btn dans style.css) : DM Sans 700,
   0.85rem, 0.08em. --font-mono est le style des étiquettes, pas des actions. */
.cl-b{min-height:44px;border-radius:6px;border:1px solid var(--border);cursor:pointer;
  background:var(--surface2);color:var(--text);width:100%;padding:10px 14px;
  font-family:var(--font-body);font-weight:700;
  font-size:clamp(0.74rem,2.2vw,0.85rem);letter-spacing:0.08em;
  text-transform:uppercase;transition:filter .2s ease,box-shadow .2s ease;}
/* Les deux boutons de la fiche se lisent à la couleur avant le libellé :
   violet on pose, framboise on retire. .cl-b.actif faisait l'inverse - il
   peignait « Retirer des favoris » en violet parce qu'il décrivait l'ÉTAT du
   projet et non le sens du clic. Remplacé par ces deux classes, plus rien
   n'émet .actif sur un .cl-b.
   « Annuler le remplacement » prend aussi .retirer : c'est un clic qui défait,
   pas un clic qui pose. */
.cl-b.poser{background:var(--purple);border-color:transparent;color:var(--text);
  box-shadow:var(--glow-violet);}
/* ⚠ Texte SOMBRE sur la framboise, et non var(--text). Mesuré : blanc sur
   #F92659 donne 3,58:1, sous le seuil de 4,5:1 pour du texte de cette taille
   (0,74 à 0,85rem, sous les 18,66px du « grand texte »). En #0A0710 on monte à
   5,19:1. C'est la même règle que .pk-btn.pret sur le lime et .cl-chip
   sélectionnée : sur ce site, un aplat vif porte du texte sombre. */
.cl-b.retirer{background:var(--red);border-color:transparent;color:#0A0710;
  box-shadow:var(--glow-raspberry);}
.cl-b.vendre{background:none;border-color:var(--orange-dark);color:var(--completion);}
.cl-b:disabled{opacity:.45;cursor:not-allowed;}
@media (hover:hover){
  .cl-b:not(:disabled):hover{filter:brightness(1.16);}
  .cl-pop-x:hover em{background:var(--text);}
}
/* La revente est irréversible : elle demande une confirmation, et le montant
   est écrit dans le bouton pour qu'on sache ce qu'on échange. */
.cl-conf{margin-top:8px;padding:12px;border-radius:9px;background:var(--surface2);
  border:1px solid var(--orange-dark);}
.cl-conf p{font-size:0.79rem;color:var(--text-muted);line-height:1.55;margin-bottom:10px;}
.cl-conf-l{display:flex;gap:8px;}
.cl-conf-l .cl-b{margin:0;}

/* ── Remplacer un favori ─────────────────────────────────────────────────
   Quand les trois favoris sont pris, la fiche déplie les trois pochettes en
   place. Volontairement SANS encadré, contrairement à .cl-conf de la revente :
   celle-ci est irréversible et doit alerter, un échange de favori se défait
   d'un clic. La vignette est la .cl-c de la collection, reprise telle quelle -
   même liseré de rareté, même dimension carrée, rien de neuf à apprendre. */
.fav-nu{margin-top:12px;}
.fav-nu p{font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--text-muted);margin-bottom:9px;}
/* Trois colonnes fixes et non auto-fit : il y a toujours exactement trois
   favoris, et une grille qui s'adapte les ferait grossir à deux. */
.fav-choix{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;}
.cl-b.oui{background:var(--completion);color:#0A0710;border-color:transparent;}

/* Le bandeau de confirmation après une action : il apparaît en haut de la
   collection, pas dans une boîte système. */
.cl-flash{position:fixed;left:50%;top:calc(var(--nav-h) + 12px);transform:translateX(-50%);
  z-index:940;padding:11px 18px;border-radius:10px;background:var(--surface);
  border:1px solid var(--green);color:var(--green);box-shadow:var(--glow-lime);
  font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.13em;
  text-transform:uppercase;opacity:0;pointer-events:none;transition:opacity .25s ease;
  max-width:calc(100vw - 32px);text-align:center;}
.cl-flash.on{opacity:1;}
@media (prefers-reduced-motion:reduce){
  .cl-c:not(.vide):hover{transform:none;}
}


/* ── Choisir un projet pour la vitrine ───────────────────────────────────
   Réutilise la fenêtre de la collection (.cl-pop) : même cadre, même sortie,
   même comportement au clavier. Seul le contenu change. */
.pf-choix-c{width:min(860px,100%);}
.pf-choix-t{font-family:var(--font-display);font-weight:900;font-size:1rem;
  letter-spacing:-0.04em;text-transform:uppercase;padding-right:40px;}
.pf-choix-s{font-size:0.82rem;color:var(--text-muted);line-height:1.55;
  margin:5px 0 16px;}
.pf-choix-s b{color:var(--text);font-weight:600;}
/* La fenêtre se borne au viewport et c'est la GRILLE qui défile à
   l'intérieur. Une hauteur fixe sur le corps ne tenait pas compte de
   l'en-tête ni de la barre de tri : sur un écran de 812 px la fenêtre en
   faisait 837. dvh plutôt que vh pour que la barre d'URL mobile compte. */
.pf-choix-c{display:flex;flex-direction:column;max-height:calc(100vh - 40px);}
@supports (height:100dvh){ .pf-choix-c{max-height:calc(100dvh - 40px);} }
/* Le liseré de rareté est un box-shadow : il se dessine À L'EXTÉRIEUR de la
   carte. Or overflow-y:auto force overflow-x à auto, et le conteneur rogne
   donc ce qui dépasse sur les côtés — les cartes des colonnes extrêmes
   perdaient leur contour.
   Le padding va sur le CONTENEUR QUI DÉFILE, pas sur .cl-grille ni sur
   .cl-sect : posé sur la grille il désaligne le titre de section, posé sur
   la section il décale aussi la page Collection. Compensé par une marge
   négative, l'alignement avec le titre de la fenêtre est intact. */
#pfChoixCorps{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  margin:0 -9px;padding:5px 9px 2px;}
/* La sélection en cours se voit : sans repère, on ne sait pas lequel des
   trois emplacements on est en train de changer. */
.cl-c.choisi{box-shadow:0 0 0 2px var(--purple-light),0 0 18px -6px var(--purple);}
.pf-choix-vider{margin-top:14px;}


/* ── Choisir : exactement les cartes de la collection ────────────────────
   Aucune surcharge du visuel : .cl-c est déjà le bon composant, et deux
   apparences pour le même objet obligent le joueur à réapprendre l'écran.
   Seule la grille respire un peu plus, la fenêtre étant plus large. */
.pf-choix-c .cl-grille{grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:12px;}
@media (max-width:600px){
  .pf-choix-c .cl-grille{grid-template-columns:repeat(3,1fr);gap:9px;}
}
/* La barre de tri de la fenêtre : même composant que dans la collection. */
#pfChoixBarre{margin:2px 0 14px;}
/* Sous 600 px les quatre tris prenaient trois lignes et mangeaient la moitié
   de la fenêtre. On resserre le libellé, pas la cible : les 44 px de hauteur
   restent. Pas de défilement horizontal : sans flèche, une option cachée est
   une option perdue. */
@media (max-width:600px){
  #pfChoixBarre{gap:7px;margin-bottom:12px;}
  #pfChoixTris .cl-chip{padding:0 10px;font-size:0.5rem;letter-spacing:0.08em;}
}


/* ══════════════════════════════════════════════════
   ONGLET MISSIONS
   ══════════════════════════════════════════════════ */
/* ── Bandeau de tête ─────────────────────────────────────────────────────
   Les gains en attente d'abord : c'est ce qui fait revenir. */
.ms-tete{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:22px;}
.ms-tuile{flex:1;min-width:150px;background:var(--surface);border:1px solid var(--border);
  border-radius:12px;padding:14px 16px;}
.ms-tuile span{display:block;font-family:var(--font-mono);font-size:0.55rem;
  letter-spacing:0.18em;text-transform:uppercase;color:var(--text-muted);margin-bottom:4px;}
.ms-tuile b{font-family:var(--font-display);font-weight:900;font-size:1.3rem;
  letter-spacing:-0.04em;line-height:1.1;}
/* Le nombre de missions accomplies prend la couleur de complétion : c'est un
   état durable, comme « 72 % terminé », pas un score ni une position. */
.ms-tuile b.v-compl{color:var(--completion);}
/* « En attente » porte deux monnaies : sur une seule ligne, séparées d'un
   point médian, elles se lisaient comme un seul nombre. Une par ligne, avec
   sa couleur et son picto. */
.ms-tuile .ms-gains{display:flex;flex-direction:column;gap:5px;}
.ms-tuile .ms-gains span{display:flex;align-items:center;gap:7px;
  font-family:var(--font-display);font-weight:900;font-size:1.12rem;
  letter-spacing:-0.04em;line-height:1.15;}
.ms-tuile .ms-gains .xp{color:var(--xp);}
.ms-tuile .ms-gains .ss{color:var(--purple-light);}
.ms-tuile .ms-gains em{width:15px;height:15px;flex:none;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;
          mask:var(--picto) center/contain no-repeat;}
/* Même traitement sur la ligne de gain d'une mission. */
.ms-gain .ss{display:inline-flex;align-items:center;gap:5px;}
.ms-gain .ss em{width:11px;height:11px;flex:none;background:currentColor;
  -webkit-mask:var(--picto) center/contain no-repeat;
          mask:var(--picto) center/contain no-repeat;}
.ms-tuile.pret{border-color:var(--green);box-shadow:var(--glow-lime);}
.ms-tuile.pret b{color:var(--green);}

/* ── Sections ────────────────────────────────────────────────────────────*/
.ms-sect{margin-bottom:18px;}
/* Le titre devient un bouton qui replie sa section : avec plus de cent
   missions, tout déplier d'un coup fait une page interminable. Même
   mécanique que les jeux du Classement, chevron compris. */
button.ms-sect-t{width:100%;background:none;border:none;cursor:pointer;
  padding:10px 2px;min-height:44px;text-align:left;color:var(--text);
  border-bottom:1px solid var(--border);margin-bottom:0;}
.ms-sect-t{display:flex;align-items:center;gap:10px;margin-bottom:11px;flex-wrap:wrap;}
.ms-sect-chev{width:9px;height:9px;flex:none;margin-left:6px;
  border-right:2px solid var(--text-muted);border-bottom:2px solid var(--text-muted);
  transform:rotate(45deg);transition:transform .2s ease;}
button.ms-sect-t[aria-expanded="true"] .ms-sect-chev{transform:rotate(-135deg);}
.ms-sect-corps{padding-top:12px;}
/* Sous-niveau des Complétions : un simple intertitre, pas une seconde
   section repliable — deux chevrons imbriqués se marchent dessus. */
.ms-dom{margin-bottom:10px;}
/* Repliable comme une famille, mais en retrait et sans bordure : deux
   niveaux de section doivent se distinguer au premier coup d'œil. */
button.ms-dom-t{width:100%;background:none;border:none;cursor:pointer;
  padding:9px 2px 9px 10px;min-height:44px;text-align:left;
  border-left:2px solid var(--border);}
.ms-dom-t{display:flex;align-items:center;gap:8px;
  font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.16em;
  text-transform:uppercase;color:var(--text-muted);}
.ms-dom-t span{color:var(--purple-light);}
.ms-dom-t .ms-sect-chev{margin-left:auto;width:8px;height:8px;}
button.ms-dom-t[aria-expanded="true"]{border-left-color:var(--purple-dim);color:var(--text);}
.ms-dom .ms-sect-corps{padding:8px 0 4px 10px;}
@media (hover:hover){ button.ms-dom-t:hover{color:var(--text);} }
.ms-sect-corps[hidden]{display:none;}
/* Une section qui contient de quoi encaisser se signale, repliée ou non. */
.ms-pastille{flex:none;min-width:22px;height:22px;padding:0 7px;border-radius:11px;
  background:var(--green);color:#0A0710;display:inline-flex;align-items:center;
  justify-content:center;font-family:var(--font-mono);font-size:0.58rem;
  font-weight:700;box-shadow:var(--glow-lime);}
@media (hover:hover){ button.ms-sect-t:hover .ms-sect-chev{border-color:var(--text);} }
@media (prefers-reduced-motion:reduce){ .ms-sect-chev{transition:none;} }
.ms-sect-t b{font-family:var(--font-mono);font-size:0.62rem;letter-spacing:0.18em;
  text-transform:uppercase;color:var(--text);}
/* Le compte à rebours porte l'urgence, pas la couleur du titre. */
.ms-sect-t em.urgent{color:var(--rang);}
.ms-sect-t span{font-family:var(--font-mono);font-size:0.55rem;color:var(--text-muted);}
.ms-sect-t em{font-style:normal;margin-left:auto;order:3;font-family:var(--font-mono);
  font-size:0.55rem;letter-spacing:0.12em;text-transform:uppercase;color:var(--text-muted);}

/* ── Une mission ─────────────────────────────────────────────────────────*/
/* Le liseré gauche monte en intensité de violet selon l'échéance : éteint
   pour une mission permanente, marque pour l'hebdomadaire, clair pour celle
   du jour. Même principe que les quatre packs — une intensité, pas cinq
   teintes, parce que chaque teinte de la charte a déjà un sens. */
.ms{display:flex;align-items:center;gap:14px;padding:13px 16px;margin-bottom:8px;
  background:var(--surface);border:1px solid var(--border);border-radius:11px;
  border-left:3px solid var(--fam-c,var(--purple-dim));}
.ms-corps{flex:1;min-width:0;}
.ms-nom{font-size:0.9rem;font-weight:600;line-height:1.3;}
/* « Reste : Évolutif », sous l'intitulé de la mission. La phrase entière est
   composée par le serveur (missionsReste) : ici on ne fait que la poser.
   Au-dessus de .ms-bas et non dedans : rangée à côté du compteur, elle écrasait
   la jauge à 0 px de large dès 375 px, et se coupait. */
.ms-reste{display:block;margin-top:5px;font-family:var(--font-mono);font-size:0.58rem;
  letter-spacing:0.1em;text-transform:uppercase;color:var(--purple-light);line-height:1.45;}
.ms-bas{display:flex;align-items:center;gap:10px;margin-top:7px;}
/* Copie conforme de .pf-dep-jauge (complétion d'un jeu au Classement) :
   piste orange sombre, remplissage --completion vers un ton plus clair.
   La piste en --surface2 faisait toute la différence à l'œil. */
.ms-jauge{flex:1;max-width:260px;height:5px;border-radius:99px;
  background:var(--orange-dark);overflow:hidden;}
.ms-jauge i{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,var(--completion),
    color-mix(in srgb,var(--completion) 55%,#F8F5FF));}
/* Terminée : la jauge passe au lime, comme tout ce qui est acquis. */
.ms.pret .ms-jauge{background:color-mix(in srgb,var(--green) 22%,#0A0710);}
/* Uni et non dégradé : une jauge pleine n'a plus de progression à suggérer,
   c'est un état acquis. Le dégradé donnait l'impression qu'il restait du chemin. */
.ms.pret .ms-jauge i{background:var(--green);}
.ms-cpt{font-family:var(--font-mono);font-size:0.6rem;color:var(--text-muted);
  font-variant-numeric:tabular-nums;white-space:nowrap;}
.ms-gain{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex:none;
  font-family:var(--font-mono);font-size:0.62rem;white-space:nowrap;}
.ms-gain .xp{color:var(--xp);}
.ms-gain .ss{color:var(--purple-light);}
/* Gain « pack » d'une mission. La règle existait déjà, sans que rien ne la
   produise : aucun JS n'émettait cette classe, et sa couleur (--rang) était
   celle du classement, empruntée faute de mieux.
   Elle est maintenant vivante, et alignée sur les deux autres gains - même
   taille, même graisse, même famille de couleur. Le pack se distingue par son
   picto et par sa place en tête, pas en criant plus fort : la liste peut
   compter cent missions, et un badge voyant sur chacune serait illisible. */
.ms-gain .pack{display:inline-flex;align-items:center;gap:5px;color:var(--purple-light);}
/* --picto-pack, et non --picto : ce dernier porte déjà le picto Sessions pour
   toute la vue Missions (voir compte.php). Deux gains, deux variables. */
.ms-gain .pack em{width:11px;height:11px;flex:none;background:currentColor;
  -webkit-mask:var(--picto-pack) center/contain no-repeat;
          mask:var(--picto-pack) center/contain no-repeat;}
.ms-btn{flex:none;min-height:44px;padding:0 16px;border:none;border-radius:6px;
  cursor:pointer;background:var(--green);color:#0A0710;
  font-family:var(--font-body);font-weight:700;font-size:0.78rem;
  letter-spacing:0.08em;text-transform:uppercase;
  transition:filter .2s ease,transform .2s ease;}
@media (hover:hover){ .ms-btn:hover{transform:translateY(-2px);filter:brightness(1.08);} }
/* Accomplie : la ligne s'éteint mais reste, pour qu'on voie le chemin fait. */
.ms.faite{opacity:.5;border-left-color:var(--green);}
.ms.faite .ms-nom{text-decoration:line-through;text-decoration-thickness:1px;}
.ms-ok{flex:none;font-family:var(--font-mono);font-size:0.58rem;letter-spacing:0.14em;
  text-transform:uppercase;color:var(--green);}
/* Prête à récupérer : c'est la seule ligne qui doit attirer l'œil. Le lime
   prend TOUT le contour, liseré d'échéance compris — savoir qu'une mission
   est quotidienne n'aide plus une fois qu'elle est récupérable. */
.ms.pret{border-color:var(--green);box-shadow:var(--glow-lime);}

.ms-verrou{font-family:var(--font-mono);font-size:0.55rem;letter-spacing:0.12em;
  text-transform:uppercase;color:var(--text-muted);}
.ms-vide{font-size:0.86rem;color:var(--text-muted);padding:18px;background:var(--surface);
  border:1px solid var(--border);border-radius:10px;}

@media (max-width:600px){
  .ms{flex-wrap:wrap;gap:10px;}
  .ms-corps{flex:1 1 100%;}
  .ms-gain{align-items:flex-start;flex-direction:row;gap:10px;}
  .ms-btn{margin-left:auto;}
  .ms-jauge{max-width:none;}
}

/* ── Écran « Une photo ? » ─────────────────────────────────────────────────
   L'aperçu montre ce que le joueur aura : l'avatar de son palier tant qu'il
   n'a rien choisi, sa photo dès qu'elle est posée. data-rang est porté par le
   conteneur, donc --niv-c est disponible pour l'anneau de .av-i.photo. */
.ph-apercu{
  width:132px; height:132px; margin:4px auto 22px;
  position:relative;
}
.ph-apercu .av-i{ width:100%; height:100%; }
#cptPhoto .cpt-action + .cpt-action{ margin-top:10px; }

/* L'avatar du profil devient cliquable : on le signale sans ajouter de bouton,
   qui recouvrirait le visuel. */
@media (hover:hover){
  .pf-av[title]:hover .av-i{ filter:brightness(1.12); }
}
.pf-av[title]{ cursor:pointer; }

/* ── Cadrage des photos de profil ──────────────────────────────────────────
   ⚠ Ce bloc doit rester EN FIN DE FICHIER. Quatre règles d'avatar plus haut
   posent `background: var(--av) center/contain no-repeat` — un RACCOURCI, qui
   réécrit donc background-size au passage. Le `cover` déclaré dans style.css
   perdait contre elles, chargées après : une photo s'affichait cadrée comme
   une illustration, avec des bandes vides sur les côtés.
   L'anneau, lui, vient bien de style.css : il n'entre en conflit avec rien. */
.pf-av .av-i.photo,
.pf-rang-av.photo,
.pf-cl-av.photo,
.pf-pop-av.photo,
.ph-apercu .av-i.photo,
.av-i.photo{
  background-size:cover;
  background-position:center;
}

/* ══ Achat et ouverture des packs ══════════════════════════════════════════
   Ajouté quand « Acheter » a cessé de débiter ET d'ouvrir d'un seul geste. */

/* Le compteur de packs en attente, DANS le bouton — et non en pastille de
   coin : le coin est déjà occupé par la pastille framboise « Offert », les
   deux se disputeraient la même place. */
.pk-x{display:inline-flex;align-items:center;justify-content:center;margin-left:7px;
  min-width:20px;height:18px;padding:0 6px;border-radius:9px;
  background:rgba(10,7,16,0.28);color:#0A0710;
  font-size:0.68rem;font-weight:800;letter-spacing:0;
  font-variant-numeric:tabular-nums;}

/* Le bas de carte est ancré. Les cartes sont étirées à la même hauteur par la
   grille : « Voir les cotes » s'aligne donc quelle que soit la longueur du
   bouton au-dessus. Sans ça, « Ouvrir ce pack offert ×2 » passe à la ligne et
   descend les cotes de 11px sur cette seule carte. */
.pk-detail{margin-top:auto;}

/* La garantie du pack, reprise de l'accueil (.pack-gar dans index.css) à la
   même place et avec le même cadre. .vide et non l'absence de balise : les
   quatre cartes gardent la même hauteur de contenu. */
/* align-self:center et NON flex-start comme sur l'accueil : ici le contenu de
   la carte est centré (le coût l'est déjà), un badge collé à gauche y ferait
   tache. Sur l'accueil la carte est alignée à gauche (nom, tirages), le badge
   y reste donc à gauche — c'est la même intention, pas deux styles. */
/* La couleur suit la RARETÉ garantie, via --rar posé par .r-rare / .r-epique
   (style.css). Le bleu était écrit en dur : le Pressage annonçait « au moins
   un Épique » en bleu Rare, la seule couleur de rareté fausse du site.
   Repli sur le bleu si la classe manque, pour ne jamais afficher un cadre
   transparent. */
.pk-gar{font-family:var(--font-mono);font-size:0.53rem;letter-spacing:0.1em;
  text-transform:uppercase;color:var(--rar,#4F8CFF);
  background:color-mix(in srgb,var(--rar,#4F8CFF) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--rar,#4F8CFF) 30%,transparent);
  border-radius:4px;padding:3px 7px;
  align-self:center;}
.pk-gar.vide{visibility:hidden;}

/* ── La confirmation d'achat ─────────────────────────────────────────────── */
.pkc{text-align:center;}
.pkc-t{font-family:var(--font-display);font-weight:900;letter-spacing:-0.06em;
  text-transform:uppercase;font-size:1.05rem;margin:2px 0 6px;}
.pkc-poch{width:132px;margin:6px auto 14px;}
.pkc-l{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:9px 0;border-top:1px solid var(--border);font-size:0.84rem;text-align:left;}
.pkc-l span{color:var(--text-muted);font-family:var(--font-mono);font-size:0.6rem;
  letter-spacing:0.12em;text-transform:uppercase;flex:none;}
.pkc-l b{font-variant-numeric:tabular-nums;text-align:right;}
/* Le picto Sessions Studio, APRÈS le montant. em et non une image : c'est le
   masque CSS du site, il prend la couleur du texte qui le porte. --picto est
   posé sur #pkConf (voir compte.php). */
.pkc-l b em{display:inline-block;width:12px;height:12px;background:currentColor;
  margin-left:6px;vertical-align:-1px;
  -webkit-mask:var(--picto) center/contain no-repeat;mask:var(--picto) center/contain no-repeat;}
.pkc-l b.cout{color:var(--purple-light);}
.pkc-l b.apres{color:var(--text-muted);}
/* La rareté garantie dans sa couleur, celle de la collection et des cotes :
   « Rare » doit être le même bleu partout, sinon c'est un mot de plus à
   apprendre. Les variables --rar vivent dans style.css. */
.pkc-l b .r{color:var(--rar);font-weight:700;}
.pkc-a{display:flex;gap:10px;margin-top:16px;}
.pkc-a .btn{flex:1;justify-content:center;min-height:48px;}
.pkc-note{margin:14px 0 0;font-size:0.76rem;line-height:1.5;color:var(--text-muted);}

/* Sous 700px la grille passe à 2 colonnes (règle existante) et la carte tombe
   à ~137px : « OUVRIR CE PACK OFFERT ×1 » y prend TROIS lignes, contre deux
   pour tous les autres boutons. Ni la taille de police ni l'interlettrage n'y
   changent rien — c'est le nombre de mots.
   Le mot part donc, mais en .sr-only et non en display:none : la pastille de
   la pochette est aria-hidden, sans ça l'information « offert » disparaîtrait
   pour un lecteur d'écran.
   MÊME point de rupture que .pk-grille : le mot s'efface exactement quand les
   cartes se resserrent, pas à un seuil inventé pour l'occasion. */
@media (max-width:700px){
  .pk-off{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
}

/* Le second bouton d'une carte : « En acheter un autre », sous l'ouverture.
   Il existe parce que posséder un pack faisait disparaître l'achat — on ne
   pouvait plus en cumuler.

   Volontairement discret : ouvrir ce qu'on a déjà ne coûte rien, acheter si.
   Le lime au-dessus garde donc tout le poids visuel, celui-ci prend le contour
   de .btn-outline. Il reste à 44px de haut, c'est une vraie zone tactile. */
.pk-btn-2{background:none;border:1px solid var(--purple-dim);
  color:var(--purple-light);box-shadow:none;font-weight:600;
  font-size:clamp(0.66rem,1.4vw,0.76rem);}
@media (hover:hover){
  .pk-btn-2:hover{border-color:var(--purple);background:rgba(109,40,217,0.10);
    box-shadow:none;transform:translateY(-2px);}
}

/* ══ Le curseur du bandeau de profil ═══════════════════════════════════════
   Le bandeau est une surface d'AFFICHAGE, pas un formulaire. Sans règle, tout
   y est en cursor:auto — le défaut du navigateur — qui dessine un curseur de
   SAISIE dès qu'on survole du texte : pseudo, titre, niveau, XP. D'où
   l'impression de pouvoir y écrire, et le fait que ça n'arrive qu'« à certains
   moments » : ailleurs, entre les mots, c'est la flèche.
   Mesuré : les 24 éléments du bandeau étaient en cursor:auto, aucun ne le
   surchargeait.
   Posé sur le bandeau et REPRIS à pointer sur ce qui se clique vraiment — le
   cercle de la bannière et les trois favoris — sinon on perdrait leur signal. */
.pf-bandeau{cursor:default;}
.pf-bandeau button,
.pf-bandeau [role="button"],
.pf-bandeau a{cursor:pointer;}

/* Le renvoi vers les packs, DANS le récapitulatif, sous les raretés. Un filet
   au-dessus le détache des chiffres : c'est une action, pas une ligne de plus.
   Aligné à gauche comme le reste du bloc, et non centré : le récapitulatif
   entier est ferré à gauche. */
.cl-vers-packs{margin-top:16px;padding-top:15px;
  border-top:1px solid var(--border);}
.cl-vers-packs .btn{min-height:48px;}

