/* ⚠ CONVENTION DE SCOPE — À LIRE AVANT DE TESTER CE FICHIER
   `saison2-socle.css` est scopé À 100 %% en `[data-s2]`, et un test automatique
   le vérifie. CE FICHIER-CI ne l'est pas entièrement : quelques règles sont
   scopées par un ID d'écran (`#screen-rapide`, `#screen-niveau`, `#screen-recap`,
   `#screen-join`) ou par `body.s2-onglet`. Elles sont sûres — elles ne peuvent
   toucher que l'écran nommé — mais un test « tout est en [data-s2] » les
   signalera comme des faux positifs. C'est voulu, ne les « corrige » pas. */
/* ============================================================================
   HOMIES — SAISON 2 · LA COLLE D'INTÉGRATION (vague 1 : les 5 onglets)
   ----------------------------------------------------------------------------
   saison2-socle.css porte TOUT le dessin des écrans (il est généré, on n'y
   touche pas). Ce fichier-ci ne dessine rien : il fait entrer un écran `.s2`
   dans le shell de la PWA — topbar collante, <main> qui défile, barre du bas
   fixée en bas — et recale la barre du bas, qui PORTE data-s2 mais n'en
   descend pas (les règles `[data-s2] .s2-nav …` du socle ne peuvent donc pas
   l'atteindre : on les redit ici, à l'identique, et rien de plus).

   Il ne touche ni proto.css, ni brutal.css, ni app.css, ni saison2-socle.css.
   Mobile d'abord : tout ce qui suit est la base téléphone.
   ============================================================================ */

/* ── 1. UN ONGLET SAISON 2 OCCUPE TOUT LE CADRE ─────────────────────────────
   `.s2` est `position:absolute; inset:0` : son conteneur doit donc être
   positionné ET avoir la taille du cadre. app.js pose `s2-onglet` sur <body>
   tant qu'un des cinq onglets est à l'écran. Les sélecteurs portent l'id des
   cinq sections : home.css (`#sec-stats,#sec-defis,#sec-reglages`) et
   classement.css (`#sec-classement`) posent leur padding par id — sans id ici,
   ils gagneraient. */
body.s2-onglet .topbar { display: none; }                    /* l'écran s2 pose sa propre barre du haut */
body.s2-onglet main.home-wrap { position: relative; overflow: hidden; padding-bottom: 0; }

#sec-accueil[data-s2],
#sec-defis[data-s2],
#sec-stats[data-s2],
#sec-classement[data-s2],
#sec-reglages[data-s2] {
  position: absolute; inset: 0;
  max-width: none; margin: 0; padding: 0;
}

/* La barre du bas est `position:fixed` (app.css, pour survivre aux ratés de
   100dvh au réveil) : elle ne prend pas de place dans le flux, on la réserve.
   `--s2nav` est mesurée par app.js › mesurerNav(). */
#sec-accueil[data-s2] .s2,
#sec-defis[data-s2] .s2,
#sec-stats[data-s2] .s2,
#sec-classement[data-s2] .s2,
#sec-reglages[data-s2] .s2 { padding-bottom: var(--s2nav, 68px); }

/* …et la colonne qui défile garde l'écart du rythme sous son dernier bloc.
   Avant : `.s2` réservait la barre + 8 px, la zone de défilement s'arrêtait donc
   8 px AU-DESSUS de la barre — le contenu était tranché en l'air, avec une bande
   de papier entre la coupe et la barre. Maintenant la coupe tombe pile sur le
   bord de la barre (rien ne passe dessous, rien ne flotte), et en bas de course
   le dernier bloc s'arrête à `--s2-r` de la barre, son ombre comprise. */
#sec-accueil[data-s2] .s2 > .s2-scroll,
#sec-defis[data-s2] .s2 > .s2-scroll,
#sec-stats[data-s2] .s2 > .s2-scroll,
#sec-classement[data-s2] .s2 > .s2-scroll,
#sec-reglages[data-s2] .s2 > .s2-scroll { padding-bottom: var(--s2-r, 12px); }

/* ── 2. LA BARRE DU BAS ─────────────────────────────────────────────────────
   Le markup garde `.nav-item / .nav-inner / .ico / .lbl` (responsive.css en
   fait un rail vertical sur grand écran) ET prend `.it / .nemoji` de proto.
   Reste à éteindre le seul endroit où les deux se contredisent : l'état actif.
   app.css encadre tout `.nav-inner` d'un bloc magenta ; la maquette n'allume
   que le libellé (`.bottomnav .it.on .lbl`, proto). */
.bottom-nav[data-s2] { padding: 0 6px env(safe-area-inset-bottom); }
.bottom-nav[data-s2] .nav-item.active .nav-inner { background: none; border: 0; box-shadow: none; padding: 5px 6px; }
.bottom-nav[data-s2] .nav-item .ico { width: 20px; height: 20px; opacity: 1; }
.bottom-nav[data-s2] .nav-item .lbl { opacity: 1; letter-spacing: .5px; }

/* les deux seules règles de `.s2-nav` du socle, redites pour la barre elle-même */
.bottom-nav[data-s2] .it { opacity: .72; }
.bottom-nav[data-s2] .it.on { opacity: 1; }
/* NÉON : le libellé actif est un aplat magenta — encre et bord NOIRS. */
html[data-skin="neon"][data-theme] .bottom-nav[data-s2] .it.on .lbl { color: #0A0A0A; border-color: #0A0A0A; }

/* ── 3. LES DEUX COLLISIONS DE NOM AVEC atelier.css ─────────────────────────
   atelier.css (les maquettes s2-10→13 de l'ATELIER) définit DÉJÀ, en global,
   un `.s2-card` et un `.s2-tick` à lui, et il est chargé AVANT le socle. Ses
   règles gagnaient donc dans nos écrans :
     · `.s2-card` posait bord + fond + ombre + padding sur la RACINE, alors
       qu'une carte de proto met l'ombre en ::before et le cadre sur `.bd` —
       on voyait un second encadré autour de la carte de saison ;
     · `.s2-tick` dessine sa coche avec :before/:after en BARRES, qui
       s'ajoutaient à la coche tracée du socle — un pavé noir à la place.
   On les désarme, uniquement dans les cinq écrans. */
#sec-accueil[data-s2] .card.s2-card, #sec-defis[data-s2] .card.s2-card,
#sec-stats[data-s2] .card.s2-card, #sec-classement[data-s2] .card.s2-card,
#sec-reglages[data-s2] .card.s2-card {
  border: 0; background: none; box-shadow: none; padding: 0; color: inherit;
}
#sec-accueil[data-s2] .s2-tick::before, #sec-defis[data-s2] .s2-tick::before,
#sec-stats[data-s2] .s2-tick::before, #sec-classement[data-s2] .s2-tick::before,
#sec-reglages[data-s2] .s2-tick::before { content: none; }

/* ── 4. LE `hidden` DES COMPOSANTS DE PROTO ─────────────────────────────────
   `.pill`, `.card`, `.btn` et `.seg` posent un `display` : il bat le
   `[hidden]` de l'agent utilisateur, et un bloc masqué restait affiché
   (la pastille « #— » du classement, la carte des potes en ligne…). */
#sec-accueil[data-s2] [hidden], #sec-defis[data-s2] [hidden],
#sec-stats[data-s2] [hidden], #sec-classement[data-s2] [hidden],
#sec-reglages[data-s2] [hidden] { display: none !important; }

/* ── 5. UN COMPOSANT DE PROTO PORTÉ PAR UN LIEN ─────────────────────────────
   CRÉER, REJOINDRE et les lignes cliquables sont des <a> : sans ça, le
   navigateur les souligne en bleu par-dessus la couleur de la carte. */
#sec-accueil[data-s2] a, #sec-defis[data-s2] a, #sec-stats[data-s2] a,
#sec-classement[data-s2] a, #sec-reglages[data-s2] a { text-decoration: none; color: inherit; }

/* L'emoji d'une pastille ne rétrécit pas : dans une rangée serrée
   (RÉGLAGES : pays + XP + djai) il tombait à un filet de 2 px. */
#sec-accueil[data-s2] .pill .nemoji, #sec-defis[data-s2] .pill .nemoji,
#sec-stats[data-s2] .pill .nemoji, #sec-classement[data-s2] .pill .nemoji,
#sec-reglages[data-s2] .pill .nemoji { flex-shrink: 0; }

/* ── 6. L'AVATAR ÉQUIPÉ DANS UN AVATAR DE PROTO ─────────────────────────────
   QZ.framedAvatar() rend `.ava-fr > .ava-emo`, et `.ava-emo` porte SON propre
   bord de 3 px (brutal.css). Posé dans le `.avatar` de proto, qui a déjà le
   sien, ça faisait un double cadre. Même correctif que stats.css fait déjà
   pour la carte d'identité de l'ancien écran. */
#sec-accueil[data-s2] :is(.avatar, .s2-moi .av) > :is(.ava-emo, .ava-fr),
#sec-defis[data-s2] :is(.avatar, .s2-moi .av) > :is(.ava-emo, .ava-fr),
#sec-stats[data-s2] :is(.avatar, .s2-moi .av) > :is(.ava-emo, .ava-fr),
#sec-classement[data-s2] :is(.avatar, .s2-moi .av) > :is(.ava-emo, .ava-fr),
#sec-reglages[data-s2] :is(.avatar, .s2-moi .av) > :is(.ava-emo, .ava-fr) {
  width: 100%; height: 100%; border: 0; box-shadow: none;
}
#sec-accueil[data-s2] .ava-fr > .ava-emo,
#sec-stats[data-s2] .ava-fr > .ava-emo,
#sec-classement[data-s2] .ava-fr > .ava-emo,
#sec-reglages[data-s2] .ava-fr > .ava-emo { border: 0; }

/* Les listes de défis espacent leurs cartes elles-mêmes (la colonne `.s2-scroll`
   a son gap, mais `.ds` est un conteneur intermédiaire).
   ⚠ `defis.css` (l'ANCIEN écran) écrit `#sec-defis .ds { padding:0 18px }` : ce
   retrait n'était redit nulle part ici, et les cartes de défi rentraient de
   18 px de chaque côté pendant que le hero et MIX DU JOUR tenaient toute la
   largeur — l'écart horizontal qui saute aux yeux sur la capture d'Edwin.
   Le gap et la réserve d'ombre viennent du RYTHME (saison2-socle.css) : on ne
   les repose pas ici, on laisse juste passer. */
/* ⚠ `defis.css` écrit aussi `gap:13px` sur ce conteneur, avec un id : aucune
   combinaison de classes ne le bat. 13 + les 5 px d'ombre qui débordent = 18 px
   VUS entre deux défis, là où la maquette en montre 3. Sur l'écran, ça fait
   quatre défis visibles au lieu de neuf. La colonne de la maquette
   (`.s2-scroll`, socle.mjs:362) empile à `gap:8px` : c'est cette valeur-là, et
   pas une autre, qui redonne le rendu validé. */
#sec-defis[data-s2] .ds { display: flex; flex-direction: column; padding: 0; gap: 8px; }
/* ⚠ ET LE MARGIN. `proto.css` donne `margin-bottom:10px` à toute `.listcard`.
   La maquette l'annule pour sa colonne (`.s2-scroll > .listcard{margin-bottom:0}`,
   socle.mjs:366) et laisse le gap faire tout le travail. Dans l'app, les cartes
   de défi vivent dans `.ds` : la règle de la maquette ne les atteint pas, et le
   margin s'AJOUTE au gap (8 + 10 = 18 px entre boîtes). On fait pour `.ds`
   exactement ce que la maquette fait pour sa colonne. */
#sec-defis[data-s2] .ds > .listcard { margin-bottom: 0; }
#sec-classement[data-s2] .s2-top > .lbrow { margin-bottom: 0; }

/* ── 7. LA BANNIÈRE « SÉCURISE TON COMPTE » EN PEAU SOMBRE ──────────────────
   Ce bloc de l'app est un aplat JAUNE dont le texte suit `--ink` : en ABÎME et
   en NÉON, `--ink` devient crème et tout le contenu disparaissait sur le jaune.
   Même arbitrage que le socle applique déjà aux aplats vifs : sur un aplat
   clair, l'encre redevient noire. */
html[data-theme="abime"] #sec-accueil[data-s2] :is(.hvsec, .hvsec-h, .hvsec-d, .hvsec-x, .hvsec-g) { color: #0A0A0A; }
html[data-theme="abime"] #sec-accueil[data-s2] .hvsec-d b { background: #0A0A0A; color: var(--yellow); }

/* ── 8. LES STATCARD VIVES EN PEAU SOMBRE ──────────────────────────────────
   brutal.css (chantier dark-mode) éteint TOUTES les `.statcard` en ABÎME :
   `background:var(--paper) !important`. C'est le bon choix pour les
   `.statcard.sN` de l'ancien profil, dont le texte suit `--ink` — mais pas ici :
   les maquettes 08 gardent les aplats vifs en NÉON (jaune, vert, cyan) et y
   mettent l'encre NOIRE. On les rallume, uniquement dans les cinq écrans.
   Le `!important` n'est pas un raccourci : c'est la seule façon de repasser
   devant un `!important`. */
html[data-theme="abime"] #sec-stats[data-s2] .statcard.a { background: var(--yellow) !important; color: #0A0A0A !important; }
html[data-theme="abime"] #sec-stats[data-s2] .statcard.b { background: var(--green) !important; color: #0A0A0A !important; }
html[data-theme="abime"] #sec-stats[data-s2] .statcard.c { background: var(--cyan) !important; color: #0A0A0A !important; }
html[data-theme="abime"] #sec-stats[data-s2] :is(.statcard.a, .statcard.b, .statcard.c) :is(.v, .l) { color: #0A0A0A !important; }
html[data-theme="abime"] #sec-stats[data-s2] :is(.statcard.a, .statcard.b, .statcard.c) .emoji-box {
  background: #FFFEF7; border-color: #0A0A0A; box-shadow: 3px 3px 0 #0A0A0A;
}

/* ── 9. CE QUI EST CLIQUABLE DANS UN ÉCRAN s2 ───────────────────────────────
   Les composants de proto sont des <span> ; dans l'app ils portent une action.
   On leur rend le doigt, jamais l'allure. */
#sec-accueil[data-s2] [role="button"],
#sec-defis[data-s2] [role="button"],
#sec-stats[data-s2] [role="button"],
#sec-classement[data-s2] [role="button"],
#sec-reglages[data-s2] [role="button"] { cursor: pointer; -webkit-tap-highlight-color: transparent; }

/* ── LE BANDEAU DE NOTIFICATION NE MASQUE PLUS LE BAS DES ÉCRANS ────────────
   `.pwa-banner` (brutal.css) est `position:fixed; bottom:12px` : il se posait
   PAR-DESSUS la barre du bas ET par-dessus le dernier bloc de l'écran. Sur
   RÉGLAGES il recouvrait « DONNÉES & CONFIDENTIALITÉ », sur DÉFIS le dernier
   défi — on croyait l'écran coupé, alors qu'il était simplement caché.
   Les cinq onglets ont une barre du bas de 80 px : le bandeau se pose
   au-dessus d'elle. Sur les écrans qui n'en ont pas, rien ne change. */
body:has(.sec.active[data-s2]:not([data-s2-interne])) .pwa-banner {
  bottom: calc(80px + 12px + env(safe-area-inset-bottom));
}

/* ── RÉGLAGES : LES BORDS GAUCHE ET DROITE, COMME PARTOUT AILLEURS ──────────
   Reproche d'Edwin, et il le répétait depuis longtemps : « les espaces gauche
   et droite ne sont pas respectés, alors que sur les autres écrans c'est bon ».
   Mesuré, il avait raison au pixel près :
       maquette RÉGLAGES   16 px  ×17 blocs
       app CLASSEMENT      16 px       app DÉFIS   16 px
       app STATS           16 px       app ACCUEIL 16 px
       app RÉGLAGES        22 px  ×14 blocs      ← le seul
   LA CAUSE : `reglages.css:3` écrit `#sec-reglages * { margin: 0 }`. C'est le
   SEUL écran de l'app à annuler les marges de tous ses descendants — les autres
   ne posent que `box-sizing`. Or la colonne de la maquette vit sur une paire :
   `.s2-scroll { padding: 0 6px 6px; margin: 0 -6px }` — le padding donne l'air
   dont l'ombre a besoin pour ne pas être rognée, et le margin négatif le
   reprend pour que les blocs restent alignés sur les 16 px du `.s2`.
   L'`* { margin: 0 }` tuait le margin et laissait le padding : 16 + 6 = 22.
   On rend la paire. Spécificité (1,2,1) contre (1,0,0) : elle passe. */
#sec-reglages[data-s2] .s2 > .s2-scroll { margin: 0 -6px; }


/* ── LE PODIUM DU CLASSEMENT : TROIS COULEURS, UNE SEULE MARQUE DE RANG ─────
   Edwin : « pour les 3 au classement mets des couleurs différentes, et on a
   déjà les médailles 1 2 3 donc pas besoin des chiffres sinon ça fait
   doublon ». Le chiffre est retiré côté rendu (app.js › renderClassement) ; il
   reste ici à donner sa couleur à chacune des trois lignes. Ce sont les trois
   fonds que le socle donnait déjà au bloc de rang `.s2-rkb.gold/.silver/
   .bronze` — or, argent, bronze — repris tels quels sur la ligne entière :
   aucune couleur nouvelle. L'ombre reste noire : les trois fonds sont clairs,
   on ne pose jamais du noir sur du noir. */
[data-s2] .s2 .lbrow.s2-lbt.gold { background: var(--yellow); }
[data-s2] .s2 .lbrow.s2-lbt.silver { background: #DADADA; }
[data-s2] .s2 .lbrow.s2-lbt.bronze { background: var(--orange); }
/* la ligne est maintenant un aplat clair dans les trois peaux : son texte est
   donc toujours de l'encre noire, y compris en NÉON où `.lbrow` est sombre. */
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt:is(.gold, .silver, .bronze),
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt:is(.gold, .silver, .bronze) :is(.nm, .sc) {
  color: #0A0A0A; border-color: #0A0A0A;
}
/* « TOI » posé sur l'or : le magenta du sticker garde son ombre noire, jamais
   la couleur du fond qui le porte. */
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt:is(.gold, .silver, .bronze) .toi {
  color: #FFFEF7; box-shadow: 2px 2px 0 #0A0A0A;
}

/* ── STATS · L'UNITÉ DU CHIFFRE, ÉCRITE SOUS LUI ────────────────────────────
   Edwin : « par catégories, mode : enlève le %, le chiffre ça correspond à
   quoi ? pas compris ». Le `%` est parti (app.js › renderStats) et le libellé
   de la tuile porte maintenant, sur une seconde ligne, ce que compte le gros
   chiffre : des PARTIES pour un mode, des QUESTIONS pour une catégorie. */
[data-s2] .s2 .statcard .l .u { display: block; margin-top: 2px; opacity: .6; }

/* ── LE NIVEAU, À DROITE DE LA CARTE D'IDENTITÉ (STATS) ────────────────────
   Il vivait dans une `.level-badge` collée devant la barre d'XP : une petite
   carte dans la carte, qui mangeait la largeur de la jauge. Edwin : « la petite
   card enlève et mets-le sur le côté droit dans cette même card ».
   Il rejoint donc la médaille, en haut à droite : aplat jaune, encre noire,
   ombre dure — le chiffre lisible d'un coup d'œil, l'unité dessous en petit. */
#sec-stats[data-s2] .s2-id .s2-niv {
  flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 52px; padding: 5px 9px;
  background: var(--yellow); color: #0A0A0A;
  border: 3px solid #0A0A0A; box-shadow: 3px 3px 0 #0A0A0A;
}
#sec-stats[data-s2] .s2-id .s2-niv b { font-family: var(--font-d); font-size: 23px; line-height: .9; }
#sec-stats[data-s2] .s2-id .s2-niv i {
  font-family: var(--font-m); font-weight: 800; font-style: normal;
  font-size: 8px; letter-spacing: 1.4px; opacity: .72; margin-top: 1px;
}
/* la jauge reprend toute la largeur libérée */
#sec-stats[data-s2] .s2-id .levelbar > .xpbar { flex: 1; }
/* NÉON : l'aplat jaune garde son encre noire, et son ombre passe au magenta */
html[data-skin="neon"][data-theme] #sec-stats[data-s2] .s2-id .s2-niv { box-shadow: 3px 3px 0 #FF2E93; }

/* ── RÉGLAGES : UNE GRILLE DE TUILES, PAS UNE LISTE ────────────────────────
   Edwin : « fais des icônes carrées, trois ou quatre par ligne, il faut que ça
   ressemble à un jeu et non à une application mobile ». Neuf lignes pleine
   largeur avec un chevron, c'était une liste de préférences ; ce sont
   maintenant neuf tuiles qu'on vise du pouce.
   Chaque tuile est un aplat de couleur à bord noir et ombre dure — la grammaire
   des cartes d'action de l'accueil. */
/* QUATRE par ligne : avec huit tuiles (PERSO est sorti — on y va par MODIFIER
   MON PROFIL), ça fait deux lignes pleines, sans trou. */
/* Deux par ligne : la carte de partie porte un libellé, un gros titre et un
   détail — à quatre colonnes rien de tout ça ne tient. */
/* ⚠ UNE GOUTTIÈRE PAIRE, SINON LE BORD CASSE. Edwin : « il y a un problème au
   niveau des bordures, elles ne se terminent pas — une cassure sur le coin
   droit, sur le coin gauche en bas, comme s'il manquait un pixel ».
   Sur 358 px de large, 9 px de gouttière donnent deux colonnes de 174,5 :
   le trait de 3 px se rend alors à cheval sur deux pixels et se coupe dans les
   angles. Avec 10 px, les colonnes tombent sur 174 — un nombre entier, un bord
   net. C'est à vérifier sur toute grille à deux colonnes. */
#sec-reglages[data-s2] .s2-set-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;
}
/* ⚠ COPIE CONFORME DE LA CARTE DE PARTIE (`.s2-hotc`, accueil › ENCORE CHAUD).
   Edwin : « tu vois le design de la card des parties ? utilise ce design pour
   faire cumul de stat — mais card coloré — et réglages ». Mêmes chiffres, au
   pixel : gap 3, padding 7/8/8, bord 3, ombre 4, emoji 22 en haut à GAUCHE,
   filigrane dans l'angle bas-droit. Le libellé prend la place du score, le
   détail celle du « 10 Q · 5 MIN ». Rien n'est réinventé ici. */
#sec-reglages[data-s2] .s2-set-t {
  position: relative; display: flex; flex-direction: column; gap: 3px;
  padding: 7px 8px 8px; cursor: pointer; overflow: hidden;
  border: 3px solid #0A0A0A; box-shadow: 4px 4px 0 #0A0A0A;
  background: var(--paper); color: #0A0A0A;
}
#sec-reglages[data-s2] .s2-set-t .hd { display: flex; align-items: center; gap: 6px; }
#sec-reglages[data-s2] .s2-set-t .em { width: 22px; height: 22px; flex: none; position: relative; z-index: 2; }
#sec-reglages[data-s2] .s2-set-t .em .nemoji { width: 100%; height: 100%; }
#sec-reglages[data-s2] .s2-set-t .sc,
#sec-reglages[data-s2] .s2-set-t .sb,
#sec-reglages[data-s2] .s2-set-t .hd { position: relative; z-index: 2; }
/* le titre occupe la place du score : même famille, même graisse, même
   traitement d'une ligne unique — seulement plus petit, parce qu'un mot est
   plus long qu'un nombre. */
#sec-reglages[data-s2] .s2-set-t .sc {
  font-family: var(--font-d); font-size: 16px;
  /* ⚠ la carte de partie serre sa ligne à .95 — elle n'affiche que des
     CHIFFRES. Ici ce sont des mots : à .95, `overflow:hidden` rognait l'accent
     des capitales et « DONNÉES » s'affichait « DONNEES », « À PROPOS » sans
     son À. C'est le seul chiffre du patron qu'on desserre, et c'est pour ça. */
  line-height: 1.15;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-reglages[data-s2] .s2-set-t .sb {
  font-family: var(--font-m); font-weight: 700; font-size: 7px; letter-spacing: .5px;
  opacity: .62; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* le filigrane, comme sur les cartes de partie et les tuiles de stats */
#sec-reglages[data-s2] .s2-set-t::after {
  content: ''; position: absolute; right: -16px; bottom: -18px; z-index: 1;
  width: 80px; height: 80px; opacity: .15; pointer-events: none;
  background: var(--fil) center / contain no-repeat;
}
/* l'appui enfonce la tuile, comme les autres blocs du jeu */

/* les teintes du socle donnent sa couleur à chaque tuile */
#sec-reglages[data-s2] .s2-set-t.s2-c1 { background: var(--yellow); }
#sec-reglages[data-s2] .s2-set-t.s2-c2 { background: var(--cyan); }
#sec-reglages[data-s2] .s2-set-t.s2-c3 { background: var(--green); }
#sec-reglages[data-s2] .s2-set-t.s2-c4 { background: #B57BFF; }
#sec-reglages[data-s2] .s2-set-t.s2-c5 { background: #FF9F45; }
#sec-reglages[data-s2] .s2-set-t.s2-c6 { background: var(--magenta); color: #0A0A0A; }
/* ⚠ `s2-c7` valait le MÊME cyan que `s2-c2` : avec quatre tuiles par ligne, les
   deux se retrouvaient l'une sous l'autre. Deux teintes de plus, et les huit
   n'ont plus jamais deux voisines identiques, ni en ligne ni en colonne. */
/* ⚠ Encre NOIRE, pas crème : en crème le libellé tombait à 3,2 de contraste sur
   le rouge. Ces deux aplats sont clairs — le noir y passe à 5,8 et 5,1, et
   l'ombre noire reste permise (on n'est pas sur un fond sombre). */
#sec-reglages[data-s2] .s2-set-t.s2-c7 { background: #4D7CFF; }
#sec-reglages[data-s2] .s2-set-t.s2-c8 { background: var(--red); }
html[data-theme="abime"] #sec-reglages[data-s2] .s2-set-t:is(.s2-c7, .s2-c8),
html[data-theme="abime"] #sec-reglages[data-s2] .s2-set-t:is(.s2-c7, .s2-c8) .nm,
html[data-skin="neon"][data-theme] #sec-reglages[data-s2] .s2-set-t:is(.s2-c7, .s2-c8),
/* ⚠ NÉON : un aplat vif garde son encre NOIRE, et son ombre passe au magenta —
   jamais de noir sur noir, jamais d'ombre de la couleur du fond.
   ⚠ L'OMBRE NE VA QUE SUR LA TUILE. Le titre et le détail sont des blocs de
   toute la largeur : leur donner la même ombre traçait deux barres magenta en
   travers de chaque tuile. Eux ne reçoivent que la couleur d'encre. */
html[data-skin="neon"][data-theme] #sec-reglages[data-s2] .s2-set-t {
  border-color: #0A0A0A; box-shadow: 4px 4px 0 #FF2E93;
}
html[data-skin="neon"][data-theme] #sec-reglages[data-s2] .s2-set-t,
html[data-skin="neon"][data-theme] #sec-reglages[data-s2] .s2-set-t :is(.sc, .sb) { color: #0A0A0A; }
html[data-skin="neon"][data-theme] #sec-reglages[data-s2] .s2-set-t.s2-c6 { box-shadow: 4px 4px 0 #FFD600; }
/* ⚠ ABÎME et NÉON : l'encre noire doit descendre JUSQU'AU NOM. La tuile la
   recevait, mais son `.nm` est un enfant qui recalcule sa couleur depuis
   `--ink` — clair en thème sombre. « BOUTIQUE » tombait à 1,36 de contraste sur
   son aplat jaune. C'est exactement le piège qu'on avait déjà corrigé ailleurs :
   peindre le bloc ne suffit pas, il faut peindre ce qu'il contient. */
html[data-theme="abime"] #sec-reglages[data-s2] .s2-set-t,
html[data-theme="abime"] #sec-reglages[data-s2] .s2-set-t :is(.sc, .sb) { color: #0A0A0A; }

/* ── LA CARTE JOUEUR SE LIT, EN CLAIR AUSSI ────────────────────────────────
   Edwin : « je vois qu'il y a des points dedans, sur le light mode c'est
   bizarre, on n'arrive pas à bien voir les éléments écrits dessus. En néon
   c'est correct, mais en light la couleur bleue… »
   Deux choses se cumulaient sur le cyan :
   ① DEUX motifs superposés — une trame de points à 26 % ET des rayures à 16 %.
     L'un OU l'autre suffit à donner de la matière ; les deux font un grillage
     qui mange le texte. On garde les rayures, plus douces, et on retire les
     points.
   ② Le pseudo s'écrivait en CRÈME (#FFFEF7) sur ce cyan clair : 1,7 de
     contraste. Sur un aplat clair, l'encre est NOIRE — c'est la règle. */
#sec-accueil[data-s2] .s2-moi .art {
  background-image: repeating-linear-gradient(-30deg, rgba(10, 10, 10, .13) 0 4px, transparent 4px 20px);
}
/* ⚠ PAS `.cos-nick` ICI. Le pseudo (`.nk`) est déjà lisible par construction :
   crème + ombre noire portée de 4 px (socle, .s2-moi .nk). Quand un joueur a
   équipé un pseudo cosmétique, son texte vit dans un `.cos-nick` À L'INTÉRIEUR
   de ce `.nk` — lui forcer l'encre noire, c'était le peindre en noir SUR sa
   propre ombre noire. C'est le « bonsoir CARTER, c'est noir sur noir, on ne le
   voit pas » d'Edwin, et ça ne se voit que si on a un pseudo cosmétique. */
#sec-accueil[data-s2] .s2-moi .in .hello { color: rgba(10, 10, 10, .62); }
/* NÉON : le fond de la carte n'est plus clair, l'encre repasse en crème — et
   c'est déjà ce qu'Edwin trouve correct, on n'y touche pas. */
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-moi .in .hello { color: rgba(255, 254, 247, .66); }

/* ── LE PODIUM : L'EMOJI SEUL, SANS CADRE ─────────────────────────────────
   À la place du chiffre de rang, pour les trois premiers. Il prend la place
   d'un `.rk` — même largeur, même alignement — mais il n'a NI bord, NI fond,
   NI ombre : Edwin ne veut pas que la médaille soit encadrée. La couleur de la
   ligne (or / argent / bronze) reste, elle, intacte. */
#sec-classement[data-s2] .lbrow .s2-rkmed {
  flex: none; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; box-shadow: none;
}
#sec-classement[data-s2] .lbrow .s2-rkmed .nemoji { width: 30px; height: 30px; }

/* ── L'AVATAR-IMAGE RESTE DANS SON CADRE ──────────────────────────────────
   Edwin : « l'image que j'ai choisie, la hauteur est un peu grande, ce qui
   fait que lorsqu'elle est appliquée, elle sort du cadre ».
   Un avatar-image (GEAR 5, SANGOKU, les portraits Solo…) n'est pas carré : il
   arrive en 512×768 ou pire. La règle du socle lui donne `width:100%` et
   `height:100%` — sans `object-fit`, l'image s'ÉTIRE et son `.ava-emo`
   intérieur, lui, garde ses proportions et dépasse. On coupe au cadre et on
   cadre par le HAUT : sur un portrait, c'est le visage qu'on veut voir. */
#sec-accueil[data-s2] .s2-moi .av,
#sec-accueil[data-s2] .s2-moi .av > * { overflow: hidden; }
#sec-accueil[data-s2] .s2-moi .av :is(img, .avimg, .dbimg) {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%;
}
/* la même garde pour les autres écrans qui montrent l'avatar en grand */
#sec-stats[data-s2] .s2-id .avatar :is(img, .avimg, .dbimg),
#sec-profil[data-s2] .avatar-lv .avatar :is(img, .avimg, .dbimg) {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%;
}

/* ── ET SI LA CARTE PORTE UNE IMAGE, L'ENCRE REDEVIENT CLAIRE ─────────────
   J'ai forcé l'encre noire sur la carte joueur pour la rendre lisible sur le
   cyan. Mais quand une COVER est équipée, le fond n'est plus le cyan : c'est
   une image, souvent sombre — et le noir disparaît dessus. Edwin : « tu as mis
   une police noire avec un nombre noir, du coup on ne voit plus ».
   Dès qu'une cover est posée, on repasse en crème avec une ombre portée dure,
   comme le fait déjà l'écran profil. */
#sec-accueil[data-s2] .s2-moi.has-cover .in :is(.cos-nick, .nk, .nm, .hello) {
  color: #FFFEF7; text-shadow: 2px 2px 0 rgba(10, 10, 10, .85);
}

/* ── LES CUMULS : TROIS TUILES CARRÉES PAR LIGNE ──────────────────────────
   Six tuiles larges sur deux colonnes, c'était six lignes de texte à lire.
   Elles passent à trois par ligne, carrées, avec une icône au-dessus du
   chiffre : on lit d'un coup d'œil au lieu de déchiffrer. */
#sec-stats[data-s2] .s2-cumul .statcard {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; aspect-ratio: 1.35; padding: 5px 4px; text-align: center;   /* plus large que haut : moins de vide */
}
#sec-stats[data-s2] .s2-cumul .statcard .ic { width: 17px; height: 17px; margin-bottom: 0; }
#sec-stats[data-s2] .s2-cumul .statcard .v { font-size: 21px; line-height: 1; }
#sec-stats[data-s2] .s2-cumul .statcard .l {
  font-size: 8px; letter-spacing: .7px; line-height: 1.1;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── ENCORE CHAUD : UNE CARTE PAR PARTIE, À LA COULEUR DU MODE ─────────────
   La saison 1 avait raison sur cet écran : un aplat coloré, l'emoji du mode,
   le résultat annoncé, le score en gros. La saison 2 l'avait réduit à une
   ligne de texte (« CLASSIQUE · il y a 5 jours · 1 manche · entraînement »).
   On reprend la composition de la saison 1 avec la grammaire de la saison 2 :
   bord noir 3 px, ombre dure, rayon 0. */
/* trois par ligne : Edwin « vu que tu as fait des blocs de deux, on part sur
   six ou sur quatre pour avoir quelque chose d'harmonieux » — avec les cinq
   dernières parties, trois colonnes donnent 3 + 2, sans trou béant. */
#sec-accueil[data-s2] #hvRecent {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
}
/* ⚠ LA CARTE DE PARTIE EST LE PATRON DE LA SAISON 2. Edwin : « tu vois le
   design de la card des parties ? utilise ce design pour faire cumul de stat —
   mais card coloré — et réglages ». CUMUL, PAR MODE et les tuiles de RÉGLAGES
   en descendent : aplat de couleur, emoji en haut à GAUCHE, badge en haut à
   droite, libellé, gros chiffre, détail en petit, filigrane dans l'angle.
   On ne la remet pas en cause sans le lui dire. */
#sec-accueil[data-s2] .s2-hotc {
  position: relative; display: flex; flex-direction: column; gap: 3px;
  padding: 7px 8px 8px; cursor: pointer;
  background: var(--paper); color: #0A0A0A;
  border: 3px solid #0A0A0A; box-shadow: 4px 4px 0 #0A0A0A;
}
#sec-accueil[data-s2] .s2-hotc .hd { display: flex; align-items: center; gap: 6px; }
#sec-accueil[data-s2] .s2-hotc .em { width: 22px; height: 22px; flex: none; position: relative; z-index: 2; }
#sec-accueil[data-s2] .s2-hotc .em .nemoji { width: 100%; height: 100%; }
#sec-accueil[data-s2] .s2-hotc .em img { position: static; }
#sec-accueil[data-s2] .s2-hotc .rs {
  margin-left: auto; padding: 2px 6px;
  font-family: var(--font-d); font-size: 10px; letter-spacing: .6px;
  border: 2px solid #0A0A0A; background: var(--paper); color: #0A0A0A;
}
#sec-accueil[data-s2] .s2-hotc .rs.or { background: var(--yellow); }
#sec-accueil[data-s2] .s2-hotc .rs.ag { background: #DADADA; }
#sec-accueil[data-s2] .s2-hotc .rs.br { background: var(--orange); }
#sec-accueil[data-s2] .s2-hotc .rs.ok { background: var(--green); }
#sec-accueil[data-s2] .s2-hotc .rs.ko { background: var(--red); color: #FFFEF7; }
#sec-accueil[data-s2] .s2-hotc .rs.tr { background: var(--gray2); font-size: 8px; }
/* ⚠ UNE MÉDAILLE NE S'ENCADRE PAS. Edwin : « si tu mets l'icône, pas besoin de
   les encadrer, juste l'icône ça suffit ». L'emoji remplace le mot pour le
   podium et pour l'entraînement : il garde sa place mais perd cadre, fond et
   ombre. Le rang chiffré (4ᵉ, 5ᵉ…) garde, lui, sa pastille. */
#sec-accueil[data-s2] .s2-hotc .rs.nu {
  background: none; border: 0; box-shadow: none; padding: 0;
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
}
#sec-accueil[data-s2] .s2-hotc .rs.nu .nemoji { width: 24px; height: 24px; }
#sec-accueil[data-s2] .s2-hotc .md {
  font-family: var(--font-d); font-size: 11px; letter-spacing: .4px; line-height: 1.05;
  margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-accueil[data-s2] .s2-hotc .sc { font-family: var(--font-d); font-size: 20px; line-height: .95; }
#sec-accueil[data-s2] .s2-hotc .sc small { font-size: 10px; margin-left: 3px; opacity: .6; }
#sec-accueil[data-s2] .s2-hotc .sb {
  font-family: var(--font-m); font-weight: 700; font-size: 7px; letter-spacing: .5px;
  opacity: .62; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* un mode à fond SOMBRE : l'encre passe en crème, et l'ombre ne peut pas être noire */
#sec-accueil[data-s2] .s2-hotc.dk { color: #FFFEF7; box-shadow: 4px 4px 0 #FF2E93; }
#sec-accueil[data-s2] .s2-hotc.dk .rs { border-color: #0A0A0A; }
/* NÉON : aplat clair → encre noire, ombre magenta ; jamais de noir sur noir */
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-hotc { box-shadow: 4px 4px 0 #FF2E93; }
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-hotc.dk { box-shadow: 4px 4px 0 #FFD600; }

/* ── LES SQUELETTES DE CHARGEMENT ─────────────────────────────────────────
   Edwin : « on a juste les cadres qui s'affichent avec des petits points et
   les informations se chargent à l'intérieur ; en termes d'expérience
   utilisateur ce n'est pas top ».
   On dessine donc la FORME de ce qui arrive. Pas de flou, pas de dégradé
   glissant (le brandbook les interdit) : des aplats gris francs qui changent
   d'opacité, et rien d'autre. */
@keyframes s2-sk-pulse { 0%, 100% { opacity: .5; } 50% { opacity: .9; } }
[data-s2] .sk-b {
  display: block; background: var(--gray2); border: 2px solid var(--gray);
  animation: s2-sk-pulse 1.1s ease-in-out infinite;
}
[data-s2] .lbrow.s2-sk { pointer-events: none; align-items: center; gap: 9px; }
[data-s2] .lbrow.s2-sk .rk.sk-b { width: 26px; height: 26px; }
[data-s2] .lbrow.s2-sk .sk-av { width: 34px; height: 34px; flex: none; }
[data-s2] .lbrow.s2-sk .sk-nm { flex: 1; height: 15px; }
[data-s2] .lbrow.s2-sk .sk-sc { width: 54px; height: 15px; flex: none; }
/* chaque ligne démarre un peu après la précédente : ça descend, comme une liste
   qui se remplit vraiment */
[data-s2] .lbrow.s2-sk:nth-child(2) .sk-b { animation-delay: .08s; }
[data-s2] .lbrow.s2-sk:nth-child(3) .sk-b { animation-delay: .16s; }
[data-s2] .lbrow.s2-sk:nth-child(4) .sk-b { animation-delay: .24s; }
[data-s2] .lbrow.s2-sk:nth-child(5) .sk-b { animation-delay: .32s; }
[data-s2] .lbrow.s2-sk:nth-child(6) .sk-b { animation-delay: .40s; }
[data-s2] .lbrow.s2-sk:nth-child(7) .sk-b { animation-delay: .48s; }

/* la fiche d'un joueur : deux rangées de tuiles, puis deux lignes */
.pd-sk { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; }
.pd-sk .pd-sk-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.pd-sk .pd-sk-row .sk-b { height: 74px; }
.pd-sk .pd-sk-line { height: 46px; }
.pd-sk .sk-b {
  background: var(--gray2); border: 2px solid var(--gray);
  animation: s2-sk-pulse 1.1s ease-in-out infinite;
}
.pd-sk .pd-sk-row:nth-child(2) .sk-b { animation-delay: .12s; }
.pd-sk .pd-sk-line:nth-child(4) { animation-delay: .24s; }

/* on respecte ceux qui coupent les animations */
@media (prefers-reduced-motion: reduce) {
  [data-s2] .sk-b, .pd-sk .sk-b { animation: none; opacity: .7; }
}

/* ── LE TITRE D'UN JOUEUR PASSE SOUS SON PSEUDO ───────────────────────────
   Edwin : « Animagus a écrit BOSS FINAL ; il y a son emoji singe qui tourne et
   il y a le titre BOSS FINAL, c'est long et c'est moche à lire ».
   Le titre s'ajoutait EN LIGNE, à la suite du pseudo, sur une ligne de
   classement déjà étroite : le tout partait en ellipse ou poussait le score.
   Il descend d'un cran, en petit, dans la place qui existe déjà. */
#sec-classement[data-s2] .lbrow .nm {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 1px; min-width: 0; line-height: 1.05;
}
#sec-classement[data-s2] .lbrow .nm .cos-title {
  display: block; margin-left: 0; transform: none;
  font-family: var(--font-m); font-weight: 800; font-size: 8px; letter-spacing: .6px;
  opacity: .72; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* le <i> qui servait à passer à la ligne en flex n'a plus lieu d'être ici */
#sec-classement[data-s2] .lbrow .nm .cos-br { display: none; }
/* le pseudo garde sa ligne, et s'abrège s'il est long */
#sec-classement[data-s2] .lbrow .nm .cos-nick,
#sec-classement[data-s2] .lbrow .nm > span:first-child {
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── LES TUILES DE STATS REPRENNENT LE DESSIN DES CARTES DE PARTIE ─────────
   Edwin a montré sa capture d'ENCORE CHAUD : « utilise ce design pour faire
   cumul de stat, mais card coloré ». Même composition, donc : l'emoji en haut,
   le libellé, puis le chiffre en gros — et chaque tuile porte SA couleur.
   ⚠ Sans couleur, une tuile prend le papier du thème : en NÉON elle devenait
   prune sur prune, et « on ne voit rien ». Plus une seule tuile sans fond. */
#sec-stats[data-s2] :is(.s2-cumul, #modes-row) { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
/* Un mode jamais joué garde sa place, éteint.
   ⚠ `--gray2` suit le thème : en ABÎME et en NÉON il devient SOMBRE, et l'encre
   noire de la tuile y tombait à 1,28 de contraste. La tuile éteinte garde donc
   un fond clair figé dans les trois peaux — « éteint » se dit par l'opacité,
   pas en devenant illisible. */
#sec-stats[data-s2] .s2-stat.c-off { background: #D8D4CE; color: #0A0A0A; opacity: .62; }
html[data-theme="abime"] #sec-stats[data-s2] .s2-stat.c-off { background: #6E6A72; color: #0A0A0A; opacity: .8; }
#sec-stats[data-s2] .s2-stat {
  display: flex; flex-direction: column; gap: 2px;
  padding: 7px 8px 8px; min-height: 84px;
  border: 3px solid #0A0A0A; box-shadow: 4px 4px 0 #0A0A0A;
  background: var(--cyan); color: #0A0A0A;
}
#sec-stats[data-s2] .s2-stat .ic { width: 20px; height: 20px; position: relative; z-index: 2; }
#sec-stats[data-s2] .s2-stat :is(.l, .v) { position: relative; z-index: 2; }
#sec-stats[data-s2] .s2-stat .ic .nemoji { width: 100%; height: 100%; }
#sec-stats[data-s2] .s2-stat .l {
  font-family: var(--font-m); font-weight: 800; font-size: 8px; letter-spacing: .7px;
  opacity: .66; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-stats[data-s2] .s2-stat .v { font-family: var(--font-d); font-size: 22px; line-height: .95; }
/* les six couleurs — jamais deux voisines identiques */
#sec-stats[data-s2] .s2-stat.c-cy { background: var(--cyan); }
#sec-stats[data-s2] .s2-stat.c-gr { background: var(--green); }
#sec-stats[data-s2] .s2-stat.c-ye { background: var(--yellow); }
#sec-stats[data-s2] .s2-stat.c-vi { background: #B57BFF; }
#sec-stats[data-s2] .s2-stat.c-or { background: #FF9F45; }
/* ⚠ PAS `var(--magenta)` ICI. Le thème ABÎME redéfinit ce token en CYAN
   (brutal.css) : la tuile devenait cyan clair avec son texte crème dessus —
   illisible, et deux tuiles cyan côte à côte. La couleur est figée. */
#sec-stats[data-s2] .s2-stat.c-mg { background: #FF2E93; color: #FFFEF7; }
/* NÉON : l'aplat clair garde son encre noire et prend une ombre magenta ;
   le bloc magenta, lui, ne peut pas porter une ombre magenta → jaune. */
html[data-skin="neon"][data-theme] #sec-stats[data-s2] .s2-stat { color: #0A0A0A; box-shadow: 4px 4px 0 #FF2E93; }
html[data-skin="neon"][data-theme] #sec-stats[data-s2] .s2-stat.c-mg { color: #FFFEF7; box-shadow: 4px 4px 0 #FFD600; }
html[data-theme="abime"] #sec-stats[data-s2] .s2-stat.c-mg { background: #FF2E93; color: #FFFEF7; }

/* ── PAS DE SOULIGNEMENT SOUS LE NOM DES TUILES DE RÉGLAGES ───────────────
   Visible sur la capture NÉON d'Edwin : un trait rose sous chaque nom. Il vient
   d'une règle de lien qui attrape les éléments cliquables. Une tuile n'est pas
   un lien. */
/* ⚠ CETTE RÈGLE VISE LES TEXTES, PAS LA TUILE. Le premier sélecteur nommait la
   tuile elle-même : son `border-bottom: 0` lui retirait son bord du BAS, et on
   ne voyait plus qu'un décrochage noir dans l'angle. Edwin : « les bordures ne
   se terminent pas, une cassure sur le coin, comme s'il manquait un pixel ».
   Le soulignement à supprimer est celui du titre et du détail, eux seuls. */
#sec-reglages[data-s2] .s2-set-t :is(.sc, .sb) { text-decoration: none; border-bottom: 0; }
#sec-reglages[data-s2] .s2-set-t :is(.sc, .sb)::after { content: none; }

/* ── LE PODIUM EN NÉON : DES MÉTAUX, PAS DES NÉONS ────────────────────────
   Edwin, capture du TOP en néon : « on ne voit rien en fait, je ne sais pas
   pourquoi les couleurs sont fluo ».
   Il a raison : sur le prune sombre de la saison, trois aplats pleine largeur
   en jaune vif, gris clair et orange vif sautent à la figure — et les deux
   lignes suivantes, elles, sont sombres. L'écran clignote.
   En NÉON, le podium garde donc le fond de la liste et c'est son BORD qui
   porte le métal, épais, avec l'ombre assortie. La hiérarchie se lit toujours,
   sans que trois lignes crient. En thème clair, rien ne change : les aplats
   fonctionnent sur le papier crème. */
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt:is(.gold, .silver, .bronze) {
  background: #2A1826;
  border-width: 4px;
}
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt:is(.gold, .silver, .bronze) :is(.nm, .sc, .cos-nick) {
  color: #FFFEF7;
}
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt.gold   { border-color: #FFD600; box-shadow: 5px 5px 0 #FFD600; }
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt.silver { border-color: #DADADA; box-shadow: 5px 5px 0 #DADADA; }
html[data-skin="neon"][data-theme] [data-s2] .s2 .lbrow.s2-lbt.bronze { border-color: #FF9F45; box-shadow: 5px 5px 0 #FF9F45; }
/* le titre du joueur (« BOSS FINAL ») se lisait en gris sur l'aplat : sur le
   prune il reprend le crème, assourdi. */
html[data-skin="neon"][data-theme] #sec-classement[data-s2] .lbrow .nm .cos-title { color: rgba(255, 254, 247, .72); }

/* ── L'EMOJI EN FILIGRANE, À DROITE ───────────────────────────────────────
   Edwin : « sur la droite rajouter l'emoji mais en fond, opacité légère ; je te
   laisse faire ça pour cumul, boutique et stats aussi ».
   Le même emoji que celui du coin, en grand et discret dans l'angle bas-droit :
   la tuile gagne de la matière sans qu'on ajoute un mot. Il ne prend pas le
   clic et ne sort jamais de son cadre. */
#sec-stats[data-s2] .s2-stat { position: relative; overflow: hidden; }
#sec-stats[data-s2] .s2-stat::after {
  content: ''; position: absolute; right: -14px; bottom: -16px; z-index: 0;
  width: 74px; height: 74px; opacity: .17; pointer-events: none;
  background: var(--fil) center / contain no-repeat;
}
/* chaque tuile porte son propre filigrane, via la même image que son icône */
#sec-stats[data-s2] .s2-stat.c-cy { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/1f3ae/512.gif'); }
#sec-stats[data-s2] .s2-stat.c-gr { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/1f3c6/512.gif'); }
#sec-stats[data-s2] .s2-stat.c-ye { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/1f4a5/512.gif'); }
#sec-stats[data-s2] .s2-stat.c-vi { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/1f4c8/512.gif'); }
#sec-stats[data-s2] .s2-stat.c-or { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/1fa99/512.gif'); }
#sec-stats[data-s2] .s2-stat.c-mg { --fil: url('https://fonts.gstatic.com/s/e/notoemoji/latest/26a1/512.gif'); }

/* le même geste sur les cartes de partie : l'emoji du mode, en grand, derrière */
#sec-accueil[data-s2] .s2-hotc { position: relative; overflow: hidden; }
#sec-accueil[data-s2] .s2-hotc .hd,
#sec-accueil[data-s2] .s2-hotc .md,
#sec-accueil[data-s2] .s2-hotc .sc,
#sec-accueil[data-s2] .s2-hotc .sb { position: relative; z-index: 2; }
#sec-accueil[data-s2] .s2-hotc::after {
  content: ''; position: absolute; right: -16px; bottom: -18px;
  width: 80px; height: 80px; opacity: .15; pointer-events: none; z-index: 1;
  background: var(--fil) center / contain no-repeat;
}





/* ── LES QUÊTES, SUR LE PATRON DE LA CARTE DE PARTIE (défis) ───────────────
   Mêmes chiffres que `.s2-hotc` et que les tuiles de réglages : padding
   7/8/8, gap 3, bord 3, ombre dure 4, emoji 22 en haut à GAUCHE, filigrane de
   80 px à .15 dans l'angle bas-droit. Deux par ligne, comme les réglages : le
   titre d'une quête est un mot long, il ne tient pas à trois colonnes. */
#sec-defis[data-s2] .ds {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px;
}
#sec-defis[data-s2] .s2-qt {
  position: relative; display: flex; flex-direction: column; gap: 3px;
  padding: 7px 8px 8px; overflow: hidden;
  border: 3px solid #0A0A0A; box-shadow: 4px 4px 0 #0A0A0A;
  background: var(--paper); color: #0A0A0A;
}
#sec-defis[data-s2] .s2-qt::after {
  content: ''; position: absolute; right: -16px; bottom: -18px; z-index: 1;
  width: 80px; height: 80px; opacity: .15; pointer-events: none;
  background: var(--fil) center / contain no-repeat;
}
#sec-defis[data-s2] .s2-qt > * { position: relative; z-index: 2; }
#sec-defis[data-s2] .s2-qt .hd { display: flex; align-items: center; gap: 6px; }
#sec-defis[data-s2] .s2-qt .em { width: 22px; height: 22px; flex: none; }
#sec-defis[data-s2] .s2-qt .em .nemoji { width: 100%; height: 100%; }
/* la récompense, à la place du badge de résultat de la carte de partie */
#sec-defis[data-s2] .s2-qt .pill { margin-left: auto; }
#sec-defis[data-s2] .s2-qt .sc {
  font-family: var(--font-d); font-size: 15px; line-height: 1.15;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* proto donne « flex:1 » à .xpbar : en colonne elle s'écrase à 6 px. */
#sec-defis[data-s2] .s2-qt .xpbar { flex: none; width: 100%; margin-top: 2px; }
/* PRÊT À EMPOCHER : le badge devient l'appel à l'action, et la carte entière
   est le bouton. « RÉCUPÉRER » ne tient pas en pastille dans 175 px, donc on
   le dit court et on fait respirer la carte par sa couleur. */
#sec-defis[data-s2] .s2-qt .rs.go {
  margin-left: auto; padding: 3px 7px;
  font-family: var(--font-d); font-size: 9px; letter-spacing: .5px;
  border: 2px solid #0A0A0A; background: var(--magenta); color: #FFFEF7;
}
#sec-defis[data-s2] .s2-qt.claimable { cursor: pointer; }
#sec-defis[data-s2] .s2-qt.claimable:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #0A0A0A; }

/* les six teintes — aplats CLAIRS, encre noire, ombre noire permise */
#sec-defis[data-s2] .s2-qt.q1 { background: var(--yellow); }
#sec-defis[data-s2] .s2-qt.q2 { background: var(--cyan); }
#sec-defis[data-s2] .s2-qt.q3 { background: var(--green); }
#sec-defis[data-s2] .s2-qt.q4 { background: #B57BFF; }
#sec-defis[data-s2] .s2-qt.q5 { background: #FF9F45; }
#sec-defis[data-s2] .s2-qt.q6 { background: var(--magenta); }
/* ⚠ la jauge se remplit en MAGENTA : sur l'aplat magenta, le remplissage
   disparaissait dans le fond et « 2 / 15 » ne voulait plus rien dire. */
#sec-defis[data-s2] .s2-qt.q6 .xpbar .fill { background: #5BD8E5; }
/* NÉON et ABÎME : l'aplat reste vif, l'encre reste noire, l'ombre passe au
   magenta — et l'encre doit descendre jusqu'aux enfants, sinon ils la
   recalculent depuis --ink et deviennent clairs sur clair. */
html[data-skin="neon"][data-theme] #sec-defis[data-s2] .s2-qt { border-color: #0A0A0A; box-shadow: 4px 4px 0 #FF2E93; }
html[data-skin="neon"][data-theme] #sec-defis[data-s2] .s2-qt.q6 { box-shadow: 4px 4px 0 #FFD600; }
html[data-skin="neon"][data-theme] #sec-defis[data-s2] .s2-qt,
html[data-skin="neon"][data-theme] #sec-defis[data-s2] .s2-qt :is(.sc, .xpbar .txt),
html[data-theme="abime"] #sec-defis[data-s2] .s2-qt,
html[data-theme="abime"] #sec-defis[data-s2] .s2-qt :is(.sc, .xpbar .txt) { color: #0A0A0A; }

/* ══ LA CARTE DU JOUEUR — UN SEUL DESIGN, DEUX ÉCRANS ═════════════════════
   Edwin : « ça fait trois designs pour le même truc, il faut qu'on en ait un
   seul et corriger les autres ». PROFIL et STATS partagent ce bloc, rempli
   par `majCarteJoueur()`. Le squelette vient de `.s2-cov` (socle) — la carte
   du profil, celle qui porte la COVER, parce que c'est elle qu'Edwin veut
   voir : « j'ai appliqué une image de couverture mais je ne vois rien ».
   On n'ajoute que ce qui manquait : la pastille de rang, le djai, la barre de
   progression et la ligne de position. ═══════════════════════════════════ */
/* la carte est un APLAT, comme celle de l'accueil : le fond de saison, la
   trame de `.art`, et le contenu par-dessus. Pas de bandeau au-dessus — Edwin
   l'a montré deux fois. */
[data-s2] .s2-jc > .bd {
  position: relative; overflow: hidden; padding: 13px 0 0;
  background: var(--cyan); color: #0A0A0A;
}
/* le décor du socle : la trame diagonale + les pois de `.s2-moi` */
[data-s2] .s2-jc .art {
  position: absolute; inset: 0; z-index: 0; opacity: .5;
  background-image: radial-gradient(rgba(0,0,0,.28) 1.4px, transparent 1.6px);
  background-size: 11px 11px;
}
/* ⚠ LA COVER ÉQUIPÉE, EN FOND. « J'ai appliqué une image de couverture mais je
   ne vois rien » : elle n'était nulle part. Elle couvre toute la carte, et la
   trame reste par-dessus — c'est elle qui garde le texte lisible sur l'image. */
[data-s2] .s2-jc .cov {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
}
[data-s2] .s2-jc .cov:not([hidden]) ~ .art { background-color: rgba(10,10,10,.42); opacity: 1; }
/* ⚠ SUR UNE COVER, L'ENCRE NOIRE NE SE LIT PLUS. « Rang 6 sur 17 · prochain »
   disparaissait dans l'image. Dès qu'une couverture est équipée, les textes
   posés à même le fond passent en crème, avec l'ombre dure de la maison. */
[data-s2] .s2-jc:has(.cov:not([hidden])) :is(.sub, .fl, .id .nm .n) { color: #FFFEF7; }
[data-s2] .s2-jc:has(.cov:not([hidden])) .sub { opacity: 1; text-shadow: 2px 2px 0 #0A0A0A; }
[data-s2] .s2-jc .ti { position: absolute; right: 11px; top: 11px; z-index: 3; }
[data-s2] .s2-jc .in {
  position: relative; z-index: 2; display: flex; align-items: flex-end; gap: 14px;
  padding: 0 12px;
}
[data-s2] .s2-jc .avatar-lv { flex: none; }
[data-s2] .s2-jc .id { flex: 1; min-width: 0; padding-bottom: 3px; }
/* le pseudo ET son drapeau, sur la même ligne */
[data-s2] .s2-jc .id .nm { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
[data-s2] .s2-jc .id .nm .n {
  font-family: var(--font-d); font-size: 32px; line-height: 1; letter-spacing: .5px;
  color: #FFFEF7; text-shadow: 3px 3px 0 #0A0A0A;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
[data-s2] .s2-jc .id .nm .flag { flex: none; display: flex; align-items: center; }
[data-s2] .s2-jc .id .nm .flag img {
  width: 21px; height: 15px; display: block;
  border: 2px solid var(--ink); box-shadow: 2px 2px 0 var(--ink);
}
/* la pastille NIV + RANG : une seule, et elle ouvre l'échelle des rangs */
[data-s2] .s2-jc .rkp {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 9px; cursor: pointer;
  padding: 4px 8px; border: 2px solid var(--ink); background: var(--yellow); color: #0A0A0A;
  font-family: var(--font-d); font-size: 11px; letter-spacing: .5px;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
[data-s2] .s2-jc .rkp .nemoji { width: 15px; height: 15px; flex: none; }
[data-s2] .s2-jc .dj { flex: none; align-self: flex-start; margin-top: -4px; }
[data-s2] .s2-jc .bas { position: relative; z-index: 2; display: flex; align-items: center; gap: 8px; padding: 11px 12px 0; }
/* proto donne « flex:1 » à .xpbar — ici c'est ce qu'on veut, elle est en ligne */
[data-s2] .s2-jc .bas .xpbar { flex: 1; }
[data-s2] .s2-jc .wins { flex: none; }
[data-s2] .s2-jc .sub {
  position: relative; z-index: 2; padding: 8px 12px 13px;
  font-family: var(--font-m); font-weight: 700; font-size: 9px; letter-spacing: .6px;
  opacity: .78; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html[data-skin="neon"][data-theme] [data-s2] .s2-jc .sub { color: #FFFEF7; }
/* NÉON : bords noirs et ombres colorées — jamais de noir sur noir */
html[data-skin="neon"][data-theme] [data-s2] .s2-jc .im { border-color: #0A0A0A; }
html[data-skin="neon"][data-theme] [data-s2] .s2-jc .rkp { border-color: #0A0A0A; box-shadow: 3px 3px 0 #FF5CA8; }


/* ── L'APERÇU DE « MON PROFIL », SUR LA MÊME CARTE ─────────────────────────
   L'overlay de personnalisation vit hors des sections `[data-s2]` : il est
   injecté dans le body. Ce fichier n'est chargé QUE par la saison 2, donc ces
   règles ne peuvent pas fuir ailleurs. Elles reprennent `.s2-jc` — cover de
   100 px bordée, avatar qui déborde de 38 px, pseudo en 26 px — et neutralisent
   la composition d'origine de brutal.css (dégradé, voile, texte flou), qu'on ne
   touche pas. */
.pe-hub-prev.s2-jcl {
  height: auto; border: 3px solid var(--ink); box-shadow: 4px 4px 0 var(--ink);
  background: var(--paper); overflow: hidden; margin-bottom: 14px;
}
.pe-hub-prev.s2-jcl .cv { position: relative; }
.pe-hub-prev.s2-jcl .im {
  display: block; position: static; width: 100%; height: 100px; object-fit: cover;
  border-bottom: 3px solid var(--ink); background: var(--gray2);
}
/* ⚠ pas de dégradé : un aplat, comme partout ailleurs dans le jeu */
.pe-hub-prev.s2-jcl .im.pe-hpnone { background: var(--cyan); }
.pe-hub-prev.s2-jcl .ti { position: absolute; right: 9px; bottom: 9px; z-index: 2; }
.pe-hub-prev.s2-jcl .in { display: flex; align-items: flex-end; gap: 14px; padding: 9px 12px 11px; }
.pe-hub-prev.s2-jcl .avatar-lv { margin-top: -38px; flex: none; }
/* 72 px et pas 78 : c'est la taille de `.avatar.l`, celle des deux écrans.
   Le socle est scopé `[data-s2]`, l'overlay vit dehors — il faut donc la
   redonner ici, mais avec LE MÊME chiffre. */
.pe-hub-prev.s2-jcl .av {
  display: block; width: 72px; height: 72px; overflow: hidden;
  border: 4px solid var(--ink); box-shadow: 4px 4px 0 var(--ink); background: var(--paper);
}
.pe-hub-prev.s2-jcl .av > * { width: 100%; height: 100%; display: block; }
.pe-hub-prev.s2-jcl .id { flex: 1; min-width: 0; padding-bottom: 3px; }
.pe-hub-prev.s2-jcl .id .nm {
  font-family: var(--font-d); font-size: 26px; line-height: 1; letter-spacing: .5px;
  /* ⚠ pas de text-shadow flou : l'encre est posée sur du papier, elle se lit */
  text-shadow: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html[data-skin="neon"][data-theme] .pe-hub-prev.s2-jcl .im,
html[data-skin="neon"][data-theme] .pe-hub-prev.s2-jcl .av { border-color: #0A0A0A; }
html[data-skin="neon"][data-theme] .pe-hub-prev.s2-jcl { box-shadow: 4px 4px 0 #FF2E93; }
html[data-skin="neon"][data-theme] .pe-hub-prev.s2-jcl .av { box-shadow: 4px 4px 0 #FF5CA8; }





/* ══ ACCUEIL · « À QUOI ON JOUE ? » ═══════════════════════════════════════
   Maquette : design-mockups/s28-refonte-saison2.html, bloc « 1 · JOUER (hub
   racine) ». Chiffres repris tels quels — titre 26 px, sous-ligne 9,5 px,
   héros bordé 4 px à ombre 6 px, kicker 9 px à 2 px d'interlettrage, titre
   30 px, boutons en deux colonnes à 11 px de gouttière.
   ⚠ Deux écarts, dits avant de coder : la maquette peint `.art` d'un
   `linear-gradient` et pose un `text-shadow` FLOU sous le titre — le brandbook
   interdit l'un et l'autre. L'art devient un APLAT magenta, la trame de pois
   de la maquette est conservée telle quelle, et l'ombre du titre est DURE. */
/* ⚠ `flex: none` SUR CHAQUE BLOC. `.s2-scroll` est un flex en colonne : sans
   ça, ses enfants se laissent COMPRIMER dès que le contenu dépasse la hauteur
   de l'écran. Le héros mesurait 167 px à l'intérieur et 76 à l'extérieur — il
   s'écrasait en une barre noire, et « ON LANCE QUOI ? » tombait à 5 px de haut.
   Les cartes de l'app n'en souffraient pas : leur ombre `::before` les tient.
   C'est le piège à retenir pour tout nouveau bloc posé dans `.s2-scroll`. */
#sec-accueil[data-s2] :is(.s2-jr-title, .s2-jr-hero, .s2-jr-g3) { flex: none; }
/* le titre porte maintenant le pseudo : il doit tenir sur une ligne, quel que
   soit le pseudo choisi — règle du brandbook. */
#sec-accueil[data-s2] .s2-jr-title {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--font-d); font-size: 26px; letter-spacing: 1px; line-height: 1.15;
  /* ⚠ la maquette pose ces deux blocs dans un écran sans gouttière : ici ils
     sont enfants de `.s2-scroll`, qui espace déjà ses blocs. Le titre et sa
     sous-ligne forment UNE unité — 5 px entre eux, et l'air se met AUTOUR. */
  margin: 0; padding: 0;
}
/* ⚠ ÉGALISER LE BLANC VU, PAS L'ÉCART DES BOÎTES. Entre MIX DU JOUR et
   3 NOUVEAUX FORMATS, l'écart mesure 17 px — mais l'ombre `::before` des cartes
   déborde de 5 px vers le bas, donc on ne voit que 12 px de blanc. Sous le
   titre, il n'y a aucune ombre, et la ligne traîne en plus ~7 px de vide sous
   les capitales : à 16 px d'écart on en voyait 23. On retire la différence. */
#sec-accueil[data-s2] .s2-jr-hero { margin-top: -2px; }
#sec-accueil[data-s2] .s2-jr-hero {
  position: relative; overflow: hidden;
  border: 4px solid var(--ink); box-shadow: 6px 6px 0 var(--ink);
}
#sec-accueil[data-s2] .s2-jr-hero .art { position: absolute; inset: 0; background: var(--magenta); }
/* la trame de pois de la maquette, à l'identique */
#sec-accueil[data-s2] .s2-jr-hero .ht {
  position: absolute; inset: 0; opacity: .5;
  background-image: radial-gradient(rgba(0,0,0,.5) 1.4px, transparent 1.6px);
  background-size: 9px 9px;
}
#sec-accueil[data-s2] .s2-jr-hero .in { position: relative; z-index: 2; padding: 12px 13px 13px; }
#sec-accueil[data-s2] .s2-jr-hero .kr { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
#sec-accueil[data-s2] .s2-jr-hero .k {
  font-family: var(--font-m); font-weight: 700; font-size: 9px; letter-spacing: 2px; color: #FFFEF7;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#sec-accueil[data-s2] .s2-jr-hero .two {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  font-family: var(--font-d); font-size: 9.5px; letter-spacing: .5px;
  background: var(--yellow); color: #0A0A0A;
  border: 3px solid var(--ink); box-shadow: 2px 2px 0 #0A0A0A;
  padding: 3px 7px; transform: rotate(2deg);
}
#sec-accueil[data-s2] .s2-jr-hero .two .nemoji { width: 12px; height: 12px; }
#sec-accueil[data-s2] .s2-jr-hero .t {
  font-family: var(--font-d); font-size: 30px; letter-spacing: 1px; line-height: .95;
  color: #FFFEF7; text-shadow: 3px 3px 0 #0A0A0A; margin-top: 7px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-accueil[data-s2] .s2-jr-hero .s {
  font-family: var(--font-m); font-weight: 700; font-size: 9px; letter-spacing: .5px;
  color: #FFFEF7; opacity: .92; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-accueil[data-s2] .s2-jr-hero .btns { display: flex; gap: 11px; margin-top: 11px; }
#sec-accueil[data-s2] .s2-jr-hb {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px;
  border: 3px solid var(--ink); box-shadow: 4px 4px 0 #0A0A0A; padding: 9px 10px;
  text-decoration: none; cursor: pointer;
}
#sec-accueil[data-s2] .s2-jr-hb .e { flex: none; width: 22px; height: 22px; }
#sec-accueil[data-s2] .s2-jr-hb .e .nemoji { width: 100%; height: 100%; }
#sec-accueil[data-s2] .s2-jr-hb .tt {
  min-width: 0; font-family: var(--font-d); font-size: 16px; letter-spacing: .5px;
  /* ⚠ la maquette serre à 1 : « CRÉER » s'affichait « CREER », l'accent rogné
     par l'`overflow:hidden` du bouton. Même piège que « DONNÉES ». */
  line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#sec-accueil[data-s2] .s2-jr-hb .tt small {
  display: block; font-family: var(--font-m); font-weight: 700; font-size: 7.5px;
  letter-spacing: .5px; opacity: .85; margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ⚠ CRÉER ÉTAIT MAGENTA SUR LE HÉROS MAGENTA : le bouton se fondait dans le
   fond, on ne voyait que sa bordure. Edwin : « créer tu peux le mettre en bleu
   sinon on ne le voit pas ». Le bleu de la maison (#4D7CFF, celui du mode PAR
   ÉQUIPE), encre crème. */
#sec-accueil[data-s2] .s2-jr-hb.mg { background: #4D7CFF; color: #FFFEF7; }
#sec-accueil[data-s2] .s2-jr-hb.yl { background: var(--yellow); color: #0A0A0A; }
/* NÉON : bords noirs, ombres colorées — jamais de noir sur noir */
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-hero { border-color: #0A0A0A; box-shadow: 6px 6px 0 #FFD600; }
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-hb { border-color: #0A0A0A; }
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-hb.mg { box-shadow: 4px 4px 0 #FFD600; }
/* ── « TOUT › » d'ENCORE CHAUD : un vrai bouton ───────────────────────────
   Edwin : « sur la droite il y a TOUT, est-ce que tu peux le rendre en bouton,
   sinon on ne sait pas qu'on peut cliquer dessus ». C'était un simple lien
   dans le filet de section : rien ne disait qu'il menait quelque part. */
#sec-accueil[data-s2] .s2-head #goHistory {
  flex: none; cursor: pointer; text-decoration: none;
  padding: 4px 9px; border: 2px solid var(--ink); background: var(--yellow); color: #0A0A0A;
  box-shadow: 3px 3px 0 var(--ink);
  font-family: var(--font-d); font-size: 10px; letter-spacing: .6px; white-space: nowrap;
}
#sec-accueil[data-s2] .s2-head #goHistory:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-head #goHistory { border-color: #0A0A0A; box-shadow: 3px 3px 0 #FF2E93; }


/* ── ACCUEIL · AUSSI AU MENU (maquette s28, `.jr-g2` / `.jr-sq`) ───────────
   Trois par ligne et non deux : Edwin en a demandé trois, MAQUIS compris. Les
   chiffres de la maquette tiennent, seuls les textes ont été raccourcis pour
   ne pas se couper dans 113 px. */
#sec-accueil[data-s2] .s2-jr-g3 {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px;
}
#sec-accueil[data-s2] .s2-jr-sq {
  position: relative; display: flex; flex-direction: column; cursor: pointer;
  border: 3px solid var(--ink); box-shadow: 4px 4px 0 var(--ink);
  padding: 9px 9px 10px; color: #0A0A0A;
}
/* le filigrane, comme sur les cartes de partie, les tuiles de stats et celles
   des réglages : l'emoji du mode en grand dans l'angle bas-droit. */
#sec-accueil[data-s2] .s2-jr-sq::after {
  content: ''; position: absolute; right: -16px; bottom: -18px; z-index: 0;
  width: 80px; height: 80px; opacity: .15; pointer-events: none;
  background: var(--fil) center / contain no-repeat;
}
#sec-accueil[data-s2] .s2-jr-sq > * { position: relative; z-index: 2; }
#sec-accueil[data-s2] .s2-jr-sq.yl { background: var(--yellow); }
#sec-accueil[data-s2] .s2-jr-sq.cy { background: var(--cyan); }
#sec-accueil[data-s2] .s2-jr-sq.gr { background: var(--green); }
#sec-accueil[data-s2] .s2-jr-sq .e { width: 24px; height: 24px; }
#sec-accueil[data-s2] .s2-jr-sq .e .nemoji { width: 100%; height: 100%; }
#sec-accueil[data-s2] .s2-jr-sq .t {
  font-family: var(--font-d); font-size: 15px; letter-spacing: .5px; line-height: 1.15;
  margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#sec-accueil[data-s2] .s2-jr-sq .s {
  font-family: var(--font-m); font-weight: 700; font-size: 8px; line-height: 1.3;
  opacity: .72; margin-top: 2px;
}
/* la pastille de la maquette : bloc encre, texte jaune */
#sec-accueil[data-s2] .s2-jr-sq .rec {
  align-self: flex-start; margin-top: 7px; padding: 3px 6px;
  font-family: var(--font-d); font-size: 8.5px; letter-spacing: .5px;
  background: #0A0A0A; color: #FFD600;
  max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* NÉON : aplats vifs, encre noire, ombre colorée */
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-sq { border-color: #0A0A0A; box-shadow: 4px 4px 0 #FF2E93; }
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-sq,
html[data-skin="neon"][data-theme] #sec-accueil[data-s2] .s2-jr-sq :is(.t, .s) { color: #0A0A0A; }


/* le badge de nouveautés, réduit à un point sur l'onglet du hub : plus aucun
   mot à caser dans un angle occupé. */
[data-s2] .bottomnav .s2-new {
  position: absolute; top: 4px; right: 6px; z-index: 3;
  width: 9px; height: 9px; padding: 0; font-size: 0;
  background: var(--magenta); border: 2px solid var(--ink); box-shadow: none; transform: none;
}


/* ── LE LOGO DU HEADER ─────────────────────────────────────────────────────
   C'est `/logo.png`, le même que le header de la saison 1 (`.app-brand-btn`).
   La maquette saison 2 posait un ⚡ à cette place, faute d'image dans la
   vignette — mais le logo de HOMIES existe, et c'est lui qui va là.
   Il garde sa pastille magenta bordée et son ombre dure : seul l'emoji change. */
/* ⚠ LE LOGO SEUL, SANS LE MOT. Edwin : « juste le logo ça suffit, pas besoin
   d'écrire HOMIES ». La pastille devient donc un carré à la taille du logo —
   comme le header de la saison 1, qui n'écrivait rien non plus. Le padding du
   socle sautait : sans lui, l'image remplit la pastille bord à bord. */
[data-s2] .s2-logo .body { padding: 0; }
[data-s2] .s2-logo .body .lg { width: 40px; height: 40px; display: block; }


/* le MIX DU JOUR de l'accueil et des défis s'enfonçait de 4 px, sur son `.bd`
   seulement (home.css / defis.css) : même geste que tout le reste. */
[data-s2] :is(.ddj, .ddj-home):active .bd { transform: translate(2px, 2px); }

/* ============================================================
   TA MIXTAPE sur l'ACCUEIL — resserrée.
   Edwin : « la carte est trop grande ». Elle reprenait .s2-art,
   dont la vignette est une bannière 16/7 pleine largeur : 157 px
   d'image + le bloc texte, soit près de 300 px pour une seule
   porte. Ici elle passe en LIGNE, comme RAFALE / SOLO / MAQUIS
   juste au-dessus : vignette carrée à gauche, texte au milieu,
   action à droite. Le composant .s2-art n'est pas touché —
   l'override ne vise que cette carte-ci.
   ============================================================ */
[data-s2] #hvMix > .bd { flex-direction: row; align-items: center; gap: 12px; padding: 12px; }
/* l'emoji est ENCADRÉ, avec sa bordure ET son ombre dure — comme partout */
[data-s2] #hvMix .ph { width: 74px; height: 74px; aspect-ratio: auto; flex: none;
  border: 4px solid var(--ink); box-shadow: 5px 5px 0 var(--ink); background: var(--paper);
  display: flex; align-items: center; justify-content: center; }
html[data-skin="neon"][data-theme] [data-s2] #hvMix .ph { box-shadow: 5px 5px 0 var(--magenta); }
/* et la MÊME icône revient EN FOND de la carte, en filigrane */
[data-s2] #hvMix > .bd { position: relative; overflow: hidden; }
[data-s2] #hvMix > .bd::before {
  content: ''; position: absolute; right: -14px; top: 50%; transform: translateY(-50%);
  width: 116px; height: 116px; pointer-events: none; opacity: .18;
  background: url(https://fonts.gstatic.com/s/e/notoemoji/latest/1f3b6/512.gif) center / contain no-repeat;
}
[data-s2] #hvMix > .bd > * { position: relative; z-index: 1; }
[data-s2] #hvMix .ph img { width: 54px; height: 54px; object-fit: contain; }
[data-s2] #hvMix .in { padding: 0; }
[data-s2] #hvMix .t { font-size: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* une ligne, jamais deux : « 56 PARTIES · CARTE PAR CARTE, EN MUSIQUE »
   repassait à la ligne et faisait grandir la carte. */
[data-s2] #hvMix .d { margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* l'action revient sur la ligne, à droite : plus de bandeau sous le texte */
[data-s2] #hvMix .bas { margin: 0; }
[data-s2] #hvMix > .bd > .in > .bas { display: none; }
[data-s2] #hvMix > .bd::after { content: '›'; position: relative; z-index: 1;
  font-family: var(--font-d); font-size: 42px;
  line-height: .7; opacity: .85; flex: none; padding: 0 6px 6px 0; }

/* ============================================================
   TA MIXTAPE sur l'ÉCRAN SAISON — la même carte que l'accueil.
   Edwin, capture à l'appui : « j'avais dit de juste redesigner ça ».
   Elle était restée au format `.s2-art` : une bannière 16/7 avec une
   grosse cassette grise au milieu, soit ~290 px de haut pour une
   porte. L'accueil avait déjà été resserré (ci-dessus) ; cet
   écran-ci ne l'avait jamais été. Même geste, même mesures —
   vignette carrée encadrée à gauche, texte au milieu, action à
   droite, et l'icône reprise en filigrane dans le fond.
   ============================================================ */
[data-s2] #sznMix > .bd { flex-direction: row; align-items: center; gap: 12px; padding: 12px;
  position: relative; overflow: hidden; }
[data-s2] #sznMix .ph { width: 74px; height: 74px; aspect-ratio: auto; flex: none;
  border: 4px solid var(--ink); box-shadow: 5px 5px 0 var(--ink); background: var(--paper);
  display: flex; align-items: center; justify-content: center; }
html[data-skin="neon"][data-theme] [data-s2] #sznMix .ph { box-shadow: 5px 5px 0 var(--magenta); }
[data-s2] #sznMix .ph img { width: 54px; height: 54px; object-fit: contain; }
/* la cassette revient EN FOND, en filigrane — comme sur l'accueil */
[data-s2] #sznMix > .bd::before {
  content: ''; position: absolute; right: -14px; top: 50%; transform: translateY(-50%);
  width: 116px; height: 116px; pointer-events: none; opacity: .18;
  background: url(https://fonts.gstatic.com/s/e/notoemoji/latest/1f4fc/512.gif) center / contain no-repeat;
}
[data-s2] #sznMix > .bd > * { position: relative; z-index: 1; }
[data-s2] #sznMix .in { padding: 0; flex: 1; min-width: 0; }
[data-s2] #sznMix .t { font-size: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
[data-s2] #sznMix .d { margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* l'action passe à droite, sur la ligne : plus de bandeau sous le texte */
[data-s2] #sznMix .bas { margin: 0; flex: none; }
[data-s2] #sznMix .bas .btn { white-space: nowrap; }

/* ============================================================
   LA CARTE DU JOUEUR — le même écart nom / rang PARTOUT.
   Edwin : « entre le nom et le rang, dans STATS il y a de
   l'espace, dans les RÉGLAGES il n'y en a pas ». Mesuré :
   9 px dans STATS, 0 px dans RÉGLAGES — alors que c'est le
   MÊME composant. On fixe l'écart sur `.id .rkp` (spécificité
   plus forte que tout ce qui traînait) : les trois écrans ne
   peuvent plus diverger.
   Et le rang porte sa bordure AVEC son ombre dure, comme tous
   les blocs de la maison.
   ============================================================ */
[data-s2] .s2-jc .id .rkp {
  /* !important assumé : une règle que l'inspection n'a pas su isoler remettait
     cet écart à 0 dans les RÉGLAGES seulement. L'écart doit être le même sur
     les trois écrans — c'est le même composant. */
  margin-top: 9px !important;
  border: 3px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
}
/* fond sombre -> ombre colorée, jamais noire */
html[data-skin="neon"][data-theme] [data-s2] .s2-jc .id .rkp { box-shadow: 3px 3px 0 #FF5CA8; }


/* ============================================================
   CLASSEMENT — « tu n'es pas encore au classement ».
   Le classement de saison ne liste QUE ceux qui l'ont jouée :
   on n'affiche plus les absents avec un « 0 » à côté du nom.
   Celui qui regarde doit savoir comment y entrer.
   ============================================================ */
[data-s2] .lb-moi-vide {
  flex: 1; display: flex; flex-direction: column; gap: 5px; padding: 13px;
  border: 4px solid var(--ink); box-shadow: 5px 5px 0 var(--magenta);
  background: var(--ink); color: var(--paper); text-align: center;
  /* il passait sous la barre de navigation : on garde la place de l'ombre
     ET celle de la barre. Edwin : « c'est croppé avec la barre de navigation ». */
  margin: 4px 5px calc(16px + env(safe-area-inset-bottom)) 0;
}
[data-s2] .lb-moi-vide .t { font-family: var(--font-d); font-size: 19px; letter-spacing: .5px; }
[data-s2] .lb-moi-vide .d {
  font-family: var(--font-m); font-weight: 700; font-size: 9px; letter-spacing: 1.2px; opacity: .78;
}

