:root{--t-1:.75rem;--t-2:.9375rem;--t-3:1.125rem;--t-4:1.5rem;--t-5:1.875rem;--t-6:2.375rem;--t-7:3rem;--r-1:10px;--r-2:16px;--r-3:24px;--r-4:32px;--e-1:4px;--e-2:8px;--e-3:16px;--e-4:24px;--e-5:32px;--e-6:48px;--e-7:64px;--c-texte:#FFFFFF;--c-texte-2:#C8C5CF;--c-texte-3:#A19CAB;--o-1:0 6px 14px rgba(0,0,0,.24);--o-2:0 8px 22px rgba(0,0,0,.55);--o-3:0 12px 30px -10px rgba(0,0,0,.62),0 3px 8px -4px rgba(0,0,0,.4);--filet-verre:rgba(255,255,255,.35);--filet-verre-leger:rgba(255,255,255,.35);--filet-verre-menu:rgba(255,255,255,.6)}  /* [20/10] charte de Trinke : tailles, arrondis, espacements, textes, ombres, bords (docs/CHARTE.md) */
:root{
  --bg:#0c0c0f; --card:#16161c; --line:rgba(255,255,255,.10); --line2:rgba(255,255,255,.20);
  --ink:#FFFFFF; --dim:#A19CAB; --mut:#A19CAB;
  --accent:#8b5cf6; --accent2:#c084fc; --accent-ink:#0c0c0f;
  --violet-hi:#A78BFA;   /* violet clair de la marque, cf. fin-nue */
  /* ⚠️ SANS CECI, LA BARRE DE DEFILEMENT D'iOS EST NOIRE SUR NOTRE FOND NOIR.
     Faute de `color-scheme`, iOS suppose une page CLAIRE et dessine son indicateur en
     sombre : mesure sur photo, notre barre est a rgb(8,8,10) sur un fond a rgb(12,12,15),
     donc PLUS SOMBRE que le fond. Apple fait l'inverse, gris clair sur fond clair : un
     reperage se lit en clair sur sombre, jamais en creux.
     Le declarer bascule aussi les controles natifs non stylés (champs, listes) en sombre.
     Le pendant `color-scheme:light` vit dans html.clair, qui l'emporte en specificite. */
  color-scheme:dark;
  --font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  /* UI-05 : le texte de carte etait bloque sur son plancher (22,4 px de 320 a 407 px de large),
     donc la borne haute annoncee n'etait atteinte sur aucun telephone en portrait. Nouvelle
     valeur mesuree : 24 px a 360, 25,35 px a 390. UI-04 : plancher de 12 px sur le micro-texte. */
  --t-card:clamp(1.5rem,6.5vw,2.25rem);
  --t-micro:.75rem;
  /* [04/08] LES DEUX JETONS DU SOCLE PARTAGE (SOCLE-TRINKE.html). La
     courbe est celle de toute la vague : les ecrans d'app doivent bouger
     de la meme facon, sinon la barre d'onglets et l'ecran qu'elle change
     n'ont pas la meme main. --presence est le vert du point de presence,
     unique pour tout le produit — c'est deja la valeur du Multijoueur en
     production, elle est ici REMONTEE au socle, pas changee. */
  --ease:cubic-bezier(.22,.9,.25,1);
  --presence:#34D399;
  /* [20/10] JETONS DU MOUVEMENT, charte docs/MOUVEMENT.md. L'INTERFACE n'utilise que ces valeurs ;
     les objets de jeu (roue, bombe, chrono...) ont leur propre rythme, voir la charte. */
  --m-court:.22s;    /* menus, voiles, sorties, reponse a un toucher */
  --m-moyen:.34s;    /* elements qui arrivent, cartes, pastilles */
  --m-long:.46s;     /* entree d'une carte, revelation douce */
  --m-fort:.7s;      /* moment fort : verdict, chiffre qui tombe */
  --m-sortie:var(--ease);                       /* ce qui arrive : vite puis se pose */
  --m-depart:cubic-bezier(.4,0,1,1);           /* ce qui s'en va : part lentement puis file */
  --m-douce:cubic-bezier(.45,0,.25,1);          /* boucles d'ambiance, aller-retour */
  --m-ressort:cubic-bezier(.34,1.4,.64,1);      /* verdicts, depassement leger */
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
/* overscroll-behavior : Safari faisait rebondir toute la page a l'ouverture du clavier
   (il essaie d'amener le champ a l'ecran sur une page qui ne defile pas). L'app descendait
   de 175 px puis remontait, ce qui donnait l'impression d'un bug. Constate le 26/07. */
/* UNE SEULE UNITE : dvh. Le melange height:100% + height:100dvh est le piege du dossier :
   sur iOS, height:100% sur html/body se resout sur la fenetre barre masquee, plus haute que
   l'affichee. Inerte tant que .app est fixe, mais le jour ou .app cesse de l'etre, le bug
   d'origine revient sans qu'on comprenne pourquoi. */
/* ⚠️ LA CHAINE DE REPLIS, DEMANDEE PAR LE DOSSIER DE LA VUE LISTE (03/08). `100dvh`
   SEUL est ignore par un moteur ancien, et la page tombe alors a ZERO de haut : ecran
   blanc. Les trois se succedent, la derniere COMPRISE gagne :
        100vh  ... partout, mais compte la barre du navigateur
        100svh ... la plus petite hauteur, barres deployees
        100dvh ... la hauteur VISIBLE, celle qu'on veut
   ⚠️ CE N'EST PAS LE MELANGE QUE LE COMMENTAIRE CI-DESSUS INTERDIT. Lui vise
      `height:100%` MELE a `100dvh`, ou les deux se resolvent sur des hauteurs
      differentes ; ici ce sont trois ecritures de la MEME propriete en viewport, dont
      une seule survit au parsing. La regle « une seule unite » tient toujours. */
html,body{height:100vh;height:100svh;height:100dvh;background:var(--bg);overscroll-behavior:none}
body{font-family:var(--font);background:var(--bg);color:var(--ink);line-height:1.5;overflow:hidden;
  transition:background .4s;touch-action:manipulation}
/* LA HAUTEUR DU CONTENEUR EST LA FENETRE VISIBLE (cause trouvee le 30/07, TRINKE.md).
   L'etirement top:0/bottom:0 d'un element fixe se dimensionne, sur iOS Safari, sur la fenetre
   de mise en page = barre d'adresse MASQUEE (852 pt pour 763 affiches) : les ressorts de
   l'accueil repartissaient 89 pt hors ecran et la mention legale passait sous la barre.
   Symptome qui ne trompe pas : des intervalles qui grandissent quand on abaisse leur minimum.
   height:100dvh suit la fenetre visible ; l'etirement fixe ne reste que pour l'app installee
   (media query plus bas), sans barre d'adresse, ou 100dvh laissait une bande noire sous le
   trait d'accueil (bug corrige le 26/07 : cette separation le preserve). */
/* 560 : la largeur de l'APP, tous ecrans (retabli le 30/07 apres arbitrage Theo : passer a
   440 aurait retreci quatre ecrans jamais revus ; l'accueil suit la largeur de l'app) */
.app{position:fixed;top:0;left:0;right:0;height:100vh;height:100svh;height:100dvh;
  max-width:560px;margin:0 auto;overflow:hidden}
/* ⚠️⚠️ [07/08] LA DIVERGENCE DE MARGE EST ANNULEE : L'ECRAN REVIENT A 18, LA VALEUR DE
   TOUTE L'APP. Elle valait 12 depuis le 03/08 « parce que le dossier de la vue liste le
   demande explicitement » — or les quatre rendus finaux du 07/08 posent 18 partout, et
   le disent : « une marge de page se declare une fois ; redonnee bloc par bloc, elle
   finit par differer d'un bloc a l'autre, et personne ne sait plus laquelle fait foi ».
   L'argument qui l'avait fait descendre a 12 (« ca fait tenir cinq fils sans defiler »)
   ne tient plus non plus : le grand titre et son chapo, qui coutaient 102 px de haut,
   sont supprimes ce soir. On y gagne bien plus que les 12 px de marge.
   ⚠️ LE CHIFFRE ECRIT ICI EST 14, ET LA MARGE VUE EST BIEN 18 : le corps `.jr-body`
      ajoute 4 px de chaque cote (ils protegent le lisere de focus de la recherche, colle
      au bord d'une zone qui defile). 14 + 4 = 18. Toute retouche de l'un des deux refait
      ce calcul, et la marge negative de `.mu-liste` avec.
   ⚠️ LA VUE FIL GARDE LES 22 : elle a sa propre construction (conversation bord a bord
      par marges negatives, en-tete flottant), et lui appliquer autre chose decalerait
      tout ce qui y a ete cale a la mesure. La marge vaut pour la LISTE, pas pour le mode
      entier. */
#s-multi:not(.au-fil){padding-left:var(--e-3);padding-right:var(--e-3)}
/* ⚠️ ET LE CORPS COUPE LE DEBORDEMENT LATERAL. La liste sort volontairement de son
   conteneur par une marge negative, pour aller bord a bord ; or un element qui declare
   overflow-y:auto passe AUTOMATIQUEMENT son overflow-x de visible a auto, ce qui donne une
   barre de defilement horizontale et un fil qui part de cote au doigt. Meme parade que dans
   la conversation : on ferme l'axe, des deux facons. */
#s-multi:not(.au-fil)>.jr-body{overflow-x:hidden;touch-action:pan-y}
@media (display-mode:standalone){
  .app{height:auto;bottom:0}
}
.screen{position:absolute;inset:0;display:none;flex-direction:column;padding:var(--e-4);overflow-y:auto;
  overscroll-behavior:contain}   /* le defilement d'un ecran ne se propage plus a la page */
.screen.on{display:flex}
.grow{flex:1}
/* TE-29 : .screen est un flex colonne qui defile (overflow-y:auto). Avec justify-content:center,
   un contenu plus haut que l'ecran deborde des DEUX cotes et le haut devient inatteignable :
   au bilan a huit joueurs, la fleche de retour se trouvait a -167 px. Les marges auto donnent
   le meme centrage quand ca rentre, et se resolvent a 0 quand ca deborde. 18 ecrans concernes.
   safe center n'est pas utilise ici : WebKit ne le connait que depuis Safari 17.6, donc pas sur
   les vieux iPhone, qui sont justement les plus petits ecrans. */
.center{align-items:center;text-align:center}
.center>:first-child{margin-top:auto}
.center>:last-child{margin-bottom:auto}
h1{font-size:clamp(1.8rem,7vw,2.6rem);font-weight:900;letter-spacing:-.02em;line-height:1.05}
h2{font-size:var(--t-4);font-weight:800;margin-bottom:var(--e-1)}
.dim{color:var(--dim)}.mut{color:var(--mut);font-size:var(--t-2)}
.accentword{background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.btn{font-family:inherit;display:inline-flex;align-items:center;justify-content:center;gap:var(--e-2);background:linear-gradient(90deg,var(--accent),var(--accent2));
  color:var(--accent-ink);font-weight:800;font-size:var(--t-3);border:none;border-radius:var(--r-2);padding:var(--e-3) var(--e-4);cursor:pointer;
  width:100%;transition:transform .1s,opacity .1s}
.btn:active:not(.enfonce){transform:scale(.98)}
.btn.sec{background:transparent;color:var(--ink);border:1px solid var(--line2)}
.btn.sm{width:auto;padding:var(--e-2) var(--e-3);font-size:var(--t-2);border-radius:var(--r-1)}
/* UI-08 : l'etat desactive etait traite par opacity:.4, qui fait fondre le bouton ENTIER dans
   le fond, texte compris. Contraste calcule le 27/07 : 1,66:1, contre 4,5 exiges pour du texte.
   Le libelle devenait donc illisible au moment precis ou l'utilisateur cherche a comprendre
   pourquoi il ne peut pas appuyer. Un bouton desactive doit rester LISIBLE, il doit seulement
   cesser d'appeler l'action : plus de degrade, plus de lueur, un fond neutre et un texte gris
   clair a 7,32:1. Concerne aussi les deux boutons de la porte d'age, qui naissent desactives
   depuis UI-17. */
.btn:disabled{background:#26262e;color:var(--c-texte-2);box-shadow:none;opacity:1;cursor:default}
.btn:disabled:active{transform:none}
.row{display:flex;gap:var(--e-2);align-items:center}
.chip{border:1px solid var(--line2);border-radius:999px;padding:var(--e-2) var(--e-3);min-height:44px;display:inline-flex;align-items:center;font-size:var(--t-2);color:var(--dim);cursor:pointer;background:var(--card);transition:.12s}
.chip.on{background:var(--accent);color:var(--accent-ink);border-color:transparent;font-weight:700}
.chips{display:flex;flex-wrap:wrap;gap:var(--e-2);margin-top:var(--e-2)}
.seg{display:flex;flex:none;background:var(--card);border:1px solid var(--line);border-radius:var(--r-1);overflow:hidden;margin-top:var(--e-2)}
.seg button{flex:1;background:none;border:none;color:var(--dim);padding:var(--e-3) var(--e-2);font:inherit;font-weight:700;cursor:pointer}
/* 5 choix sur la largeur d'un telephone : on resserre plutot que de couper les mots */
.seg.seg-serre button{padding:var(--e-3) 2px;font-size:var(--t-2);letter-spacing:-.01em}
.seg button.on{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--accent-ink)}
.cl-seg button.on{background:var(--gcol,var(--accent));color:#12030f}
/* le critere se choisit avec son symbole, en haut : c'est la qu'on regarde */
.seg.cl-seg button{display:flex;flex-direction:column;align-items:center;gap:var(--e-1);padding:var(--e-2) 2px var(--e-2);
  font-size:var(--t-1);letter-spacing:-.01em}
.seg.cl-seg button i{display:block;width:19px;height:19px;color:var(--bcol,var(--dim));opacity:.85}
.seg.cl-seg button i svg{width:100%;height:100%;display:block}
.seg.cl-seg button.on i{color:inherit;opacity:1}
.field{margin-top:var(--e-3)}
.field>label{display:block;font-weight:700;font-size:var(--t-2);margin-bottom:2px}
/* ⚠️ [07/08] `date` AJOUTE A LA LISTE, ET LA LECON EST DANS LA FORME DE LA REGLE :
   elle enumere les types un par un, donc tout type qui n'y figure pas retombe sur
   l'apparence du navigateur. Le champ de date de l'inscription rendait un rectangle
   GRIS CLAIR au milieu de champs sombres — mesure sur la capture, invisible a la
   lecture de la feuille, parce qu'aucune declaration n'etait fausse : il en manquait
   une. Une liste blanche de types vieillit mal ; celle-ci se relit quand un champ
   d'un type neuf apparait. */
input[type=text],input[type=number],input[type=email],input[type=tel],input[type=search],input[type=password],input[type=date]{width:100%;background:var(--card);color:var(--ink);border:1px solid var(--line2);border-radius:var(--r-1);padding:var(--e-3);font:inherit;font-size:1rem}
/* le bouton de calendrier natif de WebKit est sombre par defaut sur fond clair : on le
   force en clair, sinon il disparait dans la carte. `color-scheme` fait le reste sur
   le selecteur lui-meme, qui est dessine par le systeme et non par la page. */
input[type=date]{color-scheme:dark;text-align:center}
input[type=date]::-webkit-calendar-picker-indicator{filter:invert(1);opacity:.55;cursor:pointer}
input:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
/* le remplissage automatique du navigateur repeint le champ en JAUNE (constate sur l'ecran du
   lien e-mail). On lui reimpose le fond sombre et la couleur du texte de l'app. */
input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,
select:-webkit-autofill,textarea:-webkit-autofill{
  -webkit-text-fill-color:var(--ink);caret-color:var(--ink);
  -webkit-box-shadow:0 0 0 1000px var(--card) inset;box-shadow:0 0 0 1000px var(--card) inset;
  transition:background-color 9999s ease-in-out 0s}
.players{display:flex;flex-direction:column;gap:var(--e-2);margin-top:var(--e-2)}
.player{display:flex;align-items:center;justify-content:space-between;background:var(--card);border:1px solid var(--line);border-radius:var(--r-1);padding:var(--e-3) var(--e-3)}
.player b{font-weight:700}
.player .del{background:none;border:none;color:#ff6b81;font-size:var(--t-4);cursor:pointer;line-height:1;padding:0 var(--e-2)}
.bottom{padding-top:var(--e-3)}
/* game card */
/* UI-38 : overflow:hidden coupait le contenu SANS barre de defilement, et l'instrument de
   mesure du dossier (scrollHeight - clientHeight) renvoyait donc 0 px exactement dans le cas
   ou le defaut se produisait. A 360x640 en grand texte avec un prenom de 18 caracteres, une
   carte perdait 17 px, et c'etaient ceux du nombre de gorgees. overflow-x reste cache pour
   continuer a rogner le halo violet du ::before. */
.gamecard{flex:1;display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--e-3);padding:var(--e-5) var(--e-4);margin:var(--e-3) 0 var(--e-2);background:var(--card);border:1px solid var(--line);border-radius:var(--r-3);position:relative;overflow-y:auto;overflow-x:hidden}
/* La carte defile depuis UI-38, donc elle tombe sur le MEME piege que TE-29 : avec
   justify-content:center, un contenu plus haut que la carte deborde des deux cotes et le haut
   devient inatteignable. Mesure du 27/07 a 360x640 en grand texte : la pastille "A toi, X" se
   retrouvait a -62 px, donc le joueur ne voyait plus a qui la carte s'adresse. Marges auto :
   meme centrage quand ca rentre, remontee complete quand ca deborde. */
.gamecard>:first-child{margin-top:auto}
.gamecard>:last-child{margin-bottom:auto}
/* Ces deux marges ne s'appliquaient a RIEN sur la carte de Soiree : son premier enfant est le
   bouton "passer" en position absolue (pas un flex-item, sa marge auto vaut 0) et son dernier
   est le bouton "voir la reponse", en display:none sur la quasi-totalite des cartes (aucune
   boite generee). Le contenu se tassait donc en haut. Mesure du 28/07 : 31 px de vide en haut
   contre 95 en bas. On vise les enfants reellement EN FLUX. Apres : 63 et 63.
   Pas de justify-content:center, qui recreerait TE-29 (le haut d'une carte trop longue devient
   inatteignable des qu'elle defile). */
#s-game .gamecard>.g-turn{margin-top:auto}
#s-game .gamecard>.sanction{margin-bottom:auto}
/* Grand texte : quand le texte grandit, les marges doivent CEDER la place, sinon 279 des 391
   cartes demandent de faire defiler (mesure du 27/07). */
body.bigtext .gamecard{padding:var(--e-3) var(--e-3);gap:var(--e-3)}
.gamecard::before{content:"";position:absolute;inset:0;background:radial-gradient(120% 55% at 50% 0%,var(--accent),transparent 58%);opacity:.18;pointer-events:none}
.gamecard>*{position:relative;z-index:1}
.tag{font-size:var(--t-micro);font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--accent2)}
.cardtext{font-size:var(--t-card);font-weight:800;line-height:1.25}
/* Ceinture, pas correctif : mesure du 27/07 sur les 128 libelles de sanction distincts, a
   360 px et dans les deux modes, AUCUN ne sort de la carte (le plus large fait 283 px pour
   316 px, et le libelle passe de lui-meme sur deux lignes). max-width est garde comme filet
   pour les 1 200 cartes en cours de tri : un libelle sans espace, lui, ne se couperait pas.
   (Une premiere mesure annoncait 13 libelles en debordement : elle stylait ".s-lab" alors que
   app.js pose ".s-label", donc le texte etait rendu a 1rem au lieu de 0,82rem.) */
.sanction{display:inline-flex;flex-direction:column;align-items:center;gap:2px;margin-top:var(--e-1);background:rgba(255,255,255,.06);border:1px solid var(--line2);border-radius:var(--r-3);padding:var(--e-2) var(--e-3);max-width:100%}
.sanction .s-label{font-size:var(--t-1);font-weight:600;color:rgba(255,255,255,.6);text-align:center;line-height:1.25}
.sanction .s-count{font-size:var(--t-4);font-weight:900;color:var(--accent2);letter-spacing:.01em;line-height:1.1}
/* UI-36 : quand la phrase source commence par le montant ("2 gorgees si oui", 61 cartes sur
   378), la pastille le met devant elle aussi. Sinon on lisait a l'envers de ce qui est ecrit
   sur la carte. Rien d'autre ne change : meme composant, meme cadre, l'ordre suit le texte. */
.sanction.s-montant-devant{flex-direction:column-reverse}
.sanction.s-montant-devant .s-label{font-size:var(--t-1);opacity:.85}
/* [23/09, Romain] Quiz et Defi : le nombre en jeu au-dessus, les deux issues cote a cote. */
.sanction.s-deux-issues{padding:var(--e-2) var(--e-3) var(--e-3);gap:var(--e-2);min-width:15rem}
.sanction .s-issues{display:grid;grid-template-columns:1fr 1fr;width:100%;border-top:1px solid var(--line2);padding-top:var(--e-2)}
.sanction .s-issues>span{display:flex;flex-direction:column;align-items:center;gap:1px;padding:0 var(--e-2)}
.sanction .s-issues>span+span{border-left:1px solid var(--line2)}
.sanction .s-issues b{font-size:var(--t-2);font-weight:800;color:var(--ink)}
.sanction .s-issues small{font-size:var(--t-1);font-weight:600;color:rgba(255,255,255,.62)}
.mv-main{display:block;margin-bottom:var(--e-2);line-height:1.3}
.topbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--e-2)}
.iconbtn{background:var(--card);border:1px solid var(--line);color:var(--ink);width:44px;height:44px;border-radius:var(--r-1);font-size:var(--t-3);cursor:pointer}
.progress{height:4px;background:var(--card);border-radius:var(--r-1);overflow:hidden;margin:var(--e-2) 0}
.progress>span{display:block;height:100%;background:linear-gradient(90deg,var(--accent),var(--accent2));width:0;transition:width .3s}
/* modal */
.modal{position:fixed;inset:0;background:rgba(0,0,0,.6);display:none;align-items:flex-end;z-index:80}
.modal.on{display:flex}
.sheet{background:var(--card);width:100%;border-radius:var(--r-3) var(--r-3) 0 0;padding:var(--e-4);max-height:80%;overflow-y:auto;border-top:1px solid var(--line2)}
/* apercu anime du jeu dans la fenetre des regles */
.rules-preview{position:relative;height:140px;border-radius:var(--r-3);margin-bottom:var(--e-3);display:flex;align-items:center;justify-content:center;overflow:hidden;background:#101016;border:1px solid var(--line)}
.rules-preview::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 50% 42%,var(--pc,#c084fc),transparent 62%);opacity:.16}
.rp-ico{width:68px;height:68px;color:var(--pc,#c084fc);position:relative;z-index:1;filter:drop-shadow(0 0 12px var(--pc,#c084fc))}
.rp-ico svg{width:100%;height:100%;display:block}
.rp-spin .rp-ico{animation:tourne 3s linear infinite}
@keyframes tourne{to{transform:rotate(360deg)}}
.rp-pulse .rp-ico{animation:rppulse 1.4s ease-in-out infinite}
@keyframes rppulse{0%,100%{transform:scale(1)}50%{transform:scale(1.2)}}
.rp-jump .rp-ico{animation:rpjump 1.8s ease-in-out infinite}
@keyframes rpjump{0%{transform:translate(-32px,-16px)}25%{transform:translate(30px,-12px)}50%{transform:translate(22px,20px)}75%{transform:translate(-26px,16px)}100%{transform:translate(-32px,-16px)}}
.rp-flash{animation:rpflash 1.8s steps(1) infinite}
@keyframes rpflash{0%,44%{background:#4c1414}50%,100%{background:#14532d}}
.rp-flash::before{opacity:0}
.rp-flash .rp-ico{color:var(--c-texte);filter:drop-shadow(0 0 10px rgba(255,255,255,.5))}
.rp-ripple .rp-ring{position:absolute;width:56px;height:56px;border-radius:50%;border:2px solid var(--pc,#c084fc);opacity:0;animation:rpring 1.5s ease-out infinite}
.rp-ripple .rp-ring2{animation-delay:.75s}
@keyframes rpring{0%{transform:scale(.4);opacity:.7}100%{transform:scale(1.9);opacity:0}}
.rp-slide{flex-direction:column;gap:var(--e-3)}
.rp-slide .rp-ico{width:42px;height:42px}
.rp-track{position:relative;container-type:inline-size;width:66%;height:8px;border-radius:var(--r-1);background:rgba(255,255,255,.1)}
.rp-mark{position:absolute;top:-4px;left:0;width:16px;height:16px;border-radius:50%;background:var(--pc,#c084fc);box-shadow:0 0 10px var(--pc,#c084fc);animation:rpslidemark 1.7s ease-in-out infinite}
@keyframes rpslidemark{0%,100%{transform:translateX(0)}50%{transform:translateX(calc(100cqw - 16px))}}   /* [20/10] glisse au lieu de left */
/* bespoke : cercle qui se trace */
.rp-draw .rp-draw-svg{width:96px;height:96px;position:relative;z-index:1;filter:drop-shadow(0 0 10px var(--pc,#c084fc))}
.rp-draw circle{stroke-dasharray:214;stroke-dashoffset:214;animation:rpdraw 2.8s ease-in-out infinite}
@keyframes rpdraw{0%{stroke-dashoffset:214;opacity:.35}55%{stroke-dashoffset:0;opacity:1}84%{stroke-dashoffset:0;opacity:1}100%{stroke-dashoffset:214;opacity:.2}}
/* bespoke : multiplicateur cash out qui grimpe */
.rp-mult{font-size:var(--t-6);font-weight:900;color:#34d399;position:relative;z-index:1;font-variant-numeric:tabular-nums;text-shadow:0 0 18px rgba(52,211,153,.55)}
.rp-climb::before{background:radial-gradient(circle at 50% 45%,#34d399,transparent 62%)!important}
/* bespoke : pierre-feuille-ciseaux qui defilent */
/* bespoke : intrus, grille avec la case differente qui pulse */
.rp-grid .rp-cells{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--e-2);z-index:1;position:relative}
.rp-grid .rp-cell{width:18px;height:18px;border-radius:var(--r-1);background:rgba(255,255,255,.2)}
.rp-grid .rp-cell.odd{background:var(--pc,#c084fc);box-shadow:0 0 12px var(--pc,#c084fc);animation:rppulse 1s ease-in-out infinite}
/* bespoke : Le 5 parfait, le chrono defile et se fige pile sur 5,00 */
.rp-chrono{font-size:var(--t-7);font-weight:900;color:var(--pc,#5eead4);position:relative;z-index:1;
  font-variant-numeric:tabular-nums;text-shadow:0 0 18px var(--pc,#5eead4);transition:color .12s,transform .12s}
.rp-chrono.ok{color:#4ade80;text-shadow:0 0 24px rgba(74,222,128,.65);transform:scale(1.1)}
/* bespoke : Timer aveugle, on compte a l'aveugle puis la valeur se revele */
.rp-blind{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;width:100%;height:70px}
.rp-blind-mask,.rp-blind-num{position:absolute;font-weight:900;font-variant-numeric:tabular-nums}
.rp-blind-mask{font-size:var(--t-7);color:var(--pc,#a78bfa);text-shadow:0 0 20px var(--pc,#a78bfa);
  animation:rpblindq 4s ease-in-out infinite}
.rp-blind-mask i{display:block;font-style:normal;animation:rpbeat .8s ease-in-out infinite}
.rp-blind-num{font-size:var(--t-6);color:#4ade80;text-shadow:0 0 20px rgba(74,222,128,.55);opacity:0;
  animation:rpblindn 4s ease-in-out infinite}
@keyframes rpblindq{0%,2%{opacity:0}6%,70%{opacity:1}73%,100%{opacity:0}}
@keyframes rpbeat{0%,100%{transform:scale(1)}45%{transform:scale(1.16)}}
@keyframes rpblindn{0%,72%{opacity:0;transform:scale(.85)}77%,97%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1)}}
/* bespoke : Doigt du destin, le sort passe d'un doigt a l'autre puis en garde un */
.rp-fings{position:relative;z-index:1;width:168px;height:104px}
.rp-fing{position:absolute;width:32px;height:32px;border-radius:50%;background:var(--pc,#4ade80);
  box-shadow:0 0 16px var(--pc,#4ade80);opacity:.28}
.rp-fing.f1{left:4px;top:2px;animation:rpf1 3.6s ease-in-out infinite}
.rp-fing.f2{right:4px;top:2px;animation:rpf2 3.6s ease-in-out infinite}
.rp-fing.f3{left:34px;bottom:2px;animation:rpf3 3.6s ease-in-out infinite}
.rp-fing.f4{right:34px;bottom:2px;animation:rpf4 3.6s ease-in-out infinite}
@keyframes rpf1{0%,9%{opacity:1;transform:scale(1.18)}12%,100%{opacity:.28;transform:scale(1)}}
@keyframes rpf2{0%,9%{opacity:.28;transform:scale(1)}12%,21%{opacity:1;transform:scale(1.18)}24%,100%{opacity:.28;transform:scale(1)}}
@keyframes rpf3{0%,21%{opacity:.28;transform:scale(1)}24%,33%{opacity:1;transform:scale(1.18)}36%,100%{opacity:.28;transform:scale(1)}}
@keyframes rpf4{0%,33%{opacity:.28;transform:scale(1)}36%,44%{opacity:1;transform:scale(1.18)}
  50%,94%{opacity:1;transform:scale(1.34)}100%{opacity:.28;transform:scale(1)}}
@media(prefers-reduced-motion:reduce){.rules-preview,.rules-preview *{animation:none!important}}
/* perfect circle */
#pc-canvas{background:radial-gradient(circle at center,rgba(103,232,249,.06),transparent 68%),var(--card);border:2px solid rgba(103,232,249,.28);border-radius:var(--r-3);touch-action:none;width:100%;aspect-ratio:1;display:block;margin-top:var(--e-2);box-shadow:0 0 34px rgba(103,232,249,.1),inset 0 0 40px rgba(0,0,0,.3)}
.score{font-size:4rem;font-weight:900;letter-spacing:-.03em}
/* wheel */
#wheel{width:80vw;max-width:344px;aspect-ratio:1;border-radius:50%;margin:var(--e-2) auto;position:relative;transition:transform 4.2s cubic-bezier(.12,.72,.12,1);filter:drop-shadow(0 12px 26px rgba(0,0,0,.55))}
.wpointer{width:0;height:0;border-left:13px solid transparent;border-right:13px solid transparent;border-top:26px solid #f8fafc;margin:0 auto -14px;position:relative;z-index:3;filter:drop-shadow(0 3px 3px rgba(0,0,0,.6))}

/* apercu de La roue : la roue tourne, le repere ne bouge pas (comme dans le jeu) */
.rp-roue-box{position:relative;width:92px;height:100px;display:flex;align-items:flex-end;justify-content:center}
.rp-roue-pt{position:absolute;top:0;left:50%;transform:translateX(-50%);width:0;height:0;z-index:2;
  border-left:9px solid transparent;border-right:9px solid transparent;border-top:17px solid #f8fafc;
  filter:drop-shadow(0 2px 3px rgba(0,0,0,.65))}
.rp-roue-w{width:84px;height:84px;color:var(--pc,#f472b6);display:block;
  filter:drop-shadow(0 0 12px var(--pc,#f472b6));animation:tourne 3s linear infinite}
.rp-roue-w svg{width:100%;height:100%;display:block}

/* bombe */
#bomb-pulse{width:120px;height:120px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#fdba74,#7c2d12);margin:var(--e-4) auto;box-shadow:0 0 40px rgba(249,115,22,.4)}
#bomb-pulse.on{animation:bp .5s infinite}
@keyframes bp{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}
/* doigt du destin */
#finger-zone{flex:1;position:relative;touch-action:none;overflow:hidden;display:flex;align-items:center;justify-content:center;text-align:center;padding:var(--e-4)}
#finger-zone::before{content:"";position:absolute;top:50%;left:50%;width:230px;height:230px;margin:-115px 0 0 -115px;border-radius:50%;border:2px dashed rgba(74,222,128,.45);animation:tourne 9s linear infinite;z-index:0}
#finger-zone::after{content:"";position:absolute;top:50%;left:50%;width:160px;height:160px;margin:-80px 0 0 -80px;border-radius:50%;background:radial-gradient(circle,rgba(74,222,128,.16),transparent 70%);animation:fatePulse 2.2s ease-in-out infinite;z-index:0}
#finger-zone>.finger-mid{position:relative;z-index:1}

@keyframes fatePulse{0%,100%{transform:scale(1);opacity:.55}50%{transform:scale(1.13);opacity:1}}
.fdot{position:absolute;width:74px;height:74px;margin:-37px 0 0 -37px;border-radius:50%;border:3px solid #fff;background:rgba(74,222,128,.32);pointer-events:none;transition:background .15s}
.fdot.win{background:#fff}
/* reflexe */
#reflex-zone{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--e-4);background:#3a1010;transition:background .05s;cursor:pointer}
#reflex-zone.go{background:#0e3a1a}
/* 04-minijeux-a-31 : cette regle etait ecrasee 500 lignes plus bas, comme #gn-inst et .ca-num.
   Troisieme selecteur du fichier declare deux fois. Celle qui compte vit avec son jeu. */

/* arcade */
.arcade{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-3);margin-top:var(--e-3);padding-bottom:var(--e-4)}
.tile{background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-3);cursor:pointer;text-align:left;transition:transform .1s,border-color .12s;min-height:104px;display:flex;flex-direction:column;justify-content:space-between}
.tile:active:not(.enfonce){transform:scale(.97)}
.tile b{font-size:var(--t-2);font-weight:800}
.tile span{color:var(--mut);font-size:var(--t-1);margin-top:var(--e-2);display:block}
.tile .dotmark{width:26px;height:26px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent2))}
/* timing bar */
.tmbar{position:relative;width:100%;height:46px;background:var(--card);border:1px solid var(--line);border-radius:var(--r-1);overflow:hidden;margin:var(--e-2) 0}
.tmtarget{position:absolute;top:0;bottom:0;background:rgba(103,232,249,.25);border-left:2px solid #67e8f9;border-right:2px solid #67e8f9}
.tmmark{position:absolute;top:0;bottom:0;width:5px;background:#fff;left:0}
/* target game */
#tg-zone{flex:1;position:relative;overflow:hidden;touch-action:none;display:flex;align-items:center;justify-content:center;text-align:center;padding:var(--e-4)}
#tg-dot{position:absolute;width:74px;height:74px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#86efac,#15803d);box-shadow:0 0 22px rgba(74,222,128,.6);cursor:pointer}
#tap-count{font-size:5rem}

/* pierre-papier-ciseaux + reponses */
.rps-row{display:flex;gap:var(--e-2);width:100%}
.ans{flex:1;background:var(--card);border:1px solid var(--line2);color:var(--ink);border-radius:var(--r-2);padding:var(--e-3) var(--e-2);font:inherit;font-weight:800;font-size:var(--t-2);cursor:pointer}
.ans.good{background:#14532d;border-color:#22c55e}.ans.bad{background:#4c1414;border-color:#ef4444}
/* trouve l'intrus */
#in-grid{flex:1;display:grid;grid-template-columns:repeat(5,1fr);gap:var(--e-2);padding:var(--e-3) var(--e-3);align-content:center}
.icell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;background:var(--card);border:1px solid var(--line);border-radius:var(--r-1);font-size:var(--t-4);font-weight:800;cursor:pointer;color:var(--dim)}
/* vert ou rouge */
#gn-zone{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--e-4);background:var(--card);transition:background .05s;cursor:pointer}
#gn-zone.green{background:#14532d}#gn-zone.red{background:#4c1414}
/* 05-minijeux-b-20 : la declaration de #gn-inst posee ici etait ecrasee 500 lignes plus bas.
   Celle qui compte vit avec le reste du jeu Vert-ou-rouge. */

/* ===== accueil ===== */
.home-bg{position:absolute;inset:0;z-index:-1;overflow:hidden}
.home-bg span{position:absolute;border-radius:50%;filter:blur(65px)}
.home-bg span:nth-child(1){width:260px;height:260px;background:#8b5cf6;opacity:.45;top:-50px;left:-60px;animation:flt1 9s ease-in-out infinite}
.home-bg span:nth-child(2){width:220px;height:220px;background:#ff5da2;opacity:.4;bottom:40px;right:-55px;animation:flt2 11s ease-in-out infinite}
.home-bg span:nth-child(3){width:180px;height:180px;background:#22d3ee;opacity:.28;bottom:-40px;left:22%;animation:flt1 13s ease-in-out infinite}
@keyframes flt1{0%,100%{transform:translateY(0)}50%{transform:translateY(28px)}}
@keyframes flt2{0%,100%{transform:translateY(0)}50%{transform:translateY(-32px)}}
.brand-xl{font-size:clamp(3rem,16vw,5rem);font-weight:900;letter-spacing:.02em;line-height:1;
  background:linear-gradient(90deg,#c084fc,#ff5da2 55%,#fbbf24);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.home-tag{color:var(--dim);margin-top:var(--e-3);max-width:26ch;font-size:var(--t-2)}
.home-stats{display:flex;gap:var(--e-4);margin-top:var(--e-4)}
.stat{display:flex;flex-direction:column;align-items:center}
.stat b{font-size:var(--t-4);font-weight:900}
.stat span{font-size:var(--t-1);color:var(--mut);text-transform:uppercase;letter-spacing:.08em;margin-top:2px}
/* rapport DA 28/07 : a 320 px, "MINI-JEUX" et "FACONS DE JOUER" passent sur deux lignes quand
   "DEFIS" reste sur une. Le plancher CONTRACTUEL de 12 px (UI-04) interdit de reduire la police :
   on ne resserre que l'interlettrage, le reste du defaut est assume (2 % des ecrans, cosmetique). */
@media (max-width:360px){ .stat span{letter-spacing:.02em} }
.btn-xl{padding:var(--e-3) var(--e-4);font-size:var(--t-3);border-radius:var(--r-2);margin-top:var(--e-3)}
.home-legal{margin-top:var(--e-4);max-width:30ch;line-height:1.4}
/* action en haut a droite de l'ecran multijoueur */
.mu-act{min-width:44px;display:flex;justify-content:flex-end}
.mu-btn{background:rgba(255,255,255,.07);border:1px solid var(--line2);color:var(--ink);font:inherit;
  font-weight:800;font-size:var(--t-2);padding:var(--e-2) var(--e-3);border-radius:999px;cursor:pointer;white-space:nowrap}
.mu-btn.cyan{background:linear-gradient(135deg,#22d3ee,#67e8f9);color:#04222a;border-color:transparent}
.mu-btn:active:not(.enfonce){transform:scale(.97)}
/* la recherche des discussions */
/* la barre de recherche est collee en haut d'une zone qui defile : sans cette marge, le
   liseré de focus etait coupe en haut (signale par Theo 26/07) */
#s-multi .jr-body{padding:var(--e-1) var(--e-1) 0}
.mu-rech{margin:2px 0 var(--e-2)}
.mu-rech input{width:100%;background:var(--card);border:1px solid var(--line2);border-radius:999px;
  padding:var(--e-3) var(--e-3);color:var(--ink);font:inherit}
.dis.on{border-color:#22d3ee;background:rgba(34,211,238,.10)}
.dis-check{flex:none;width:24px;height:24px;border-radius:50%;border:1px solid var(--line2);
  display:flex;align-items:center;justify-content:center;color:#04222a;font-weight:900;font-size:var(--t-2)}
.dis.on .dis-check{background:#22d3ee;border-color:transparent}

/* ---------- MULTIJOUEUR : liste de discussions et fil de messages ---------- */
/* [03/08] LE STYLE CARTES EST MORT DANS CE MODE (carnet du multijoueur, deux versions
   comparees a taille reelle). Les autres sections portent des cartes parce qu'elles
   presentent des CONTENUS a lancer, un mode, un jeu ; une liste de conversations n'a
   pas a emprunter ce langage. Marges 18 -> 8, rangees bord a bord, aucun rayon, fond
   transparent, aucun ecart, UN FILET a la place.
   ⚠️ LE FILET EST UNE EXCEPTION NOMMEE AU SOCLE, pas un oubli. Le socle dit « aucun
      filet nulle part, c'est l'espace qui separe ». Les deux cas qui ont produit cette
      regle DECOUPAIENT UNE PAGE EN ZONES ; un separateur entre rangees IDENTIQUES d'une
      meme serie ne decoupe rien, il articule une repetition. La regle garde toute sa
      force pour les separateurs de SECTION. */
.dis-l{display:flex;flex-direction:column;gap:0;margin:0 -10px}
.dis{width:100%;display:flex;align-items:center;gap:var(--e-3);background:transparent;border:0;
  border-radius:0;padding:var(--e-3) var(--e-2);color:var(--ink);font:inherit;text-align:left;cursor:pointer;
  position:relative}
.dis+.dis::before{content:"";position:absolute;left:60px;right:8px;top:0;height:1px;
  background:var(--line)}
.dis:active:not(.enfonce){background:rgba(255,255,255,.05)}
/* ⚠️ LE NON-LU SE VOIT PAR CONTRASTE, PAS PAR UN POINT. Aucune couleur n'etait libre :
   le vert est deja la presence, SUR LA MEME RANGEE ; le sarcelle en est trop proche a
   9 px ; le blanc ne dit rien ; les trois modes sont pris. Quatre variables bougent donc
   ensemble, et c'est plus lisible qu'une pastille de plus. */
.dis.neuf{background:rgba(255,255,255,.045)}
.dis.neuf .dis-t b{font-weight:800}
.dis.neuf .dis-t i{color:var(--c-texte-2);font-weight:600}
.dis.neuf .dis-q{color:#4FBFB4;font-weight:600}
.dis-av{flex:none;width:42px;height:42px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-weight:900;font-size:var(--t-3);background:linear-gradient(135deg,#8b5cf6,#c084fc);color:#12030f}
.dis-av.grp{background:linear-gradient(135deg,#0e7490,#22d3ee);color:#04222a}
/* la pastille de presence se pose sur le rond, comme dans la liste des amis */
.dis-av{position:relative}
.dis-av .fr-etat{position:absolute;right:-1px;bottom:-1px;width:12px;height:12px;border:2px solid var(--card)}
.dis-t i{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dis-t{flex:1;min-width:0}
.dis-t b{display:block;font-size:var(--t-2);font-weight:800}
.dis-t i{display:block;font-style:normal;color:var(--dim);font-size:var(--t-1);margin-top:1px}
/* le fil : les messages prennent la place, la saisie reste en bas */
#s-multi .jr-body{display:flex;flex-direction:column}
/* en-tete d'une discussion : rond a l'initiale + nom + etat */
.mu-tt{display:flex;align-items:center;gap:var(--e-2);justify-content:center;min-width:0}
.dis-av.sm{width:34px;height:34px;font-size:var(--t-2);position:relative}
.dis-av.sm .fr-etat{position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;border:2px solid var(--bg)}
.mu-tt-t{min-width:0;text-align:left}
.mu-tt-t b{display:block;font-size:var(--t-2);font-weight:800;line-height:1.15;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mu-sous{display:flex;align-items:center;gap:var(--e-1);font-style:normal;font-size:var(--t-1);font-weight:700;color:var(--mut);margin-top:1px}
.mu-sous.on{color:#4ade80}
.mu-sous svg{width:13px;height:13px}

/* la banniere d'une partie qui attend, en haut de la discussion */
.mu-ban{width:100%;display:flex;align-items:center;gap:var(--e-2);background:linear-gradient(135deg,rgba(34,211,238,.18),rgba(34,211,238,.06));
  border:1px solid rgba(34,211,238,.45);border-radius:var(--r-2);padding:var(--e-2) var(--e-3);margin-bottom:var(--e-2);
  color:var(--ink);font:inherit;text-align:left;cursor:pointer}
.mu-ban-t{flex:1;min-width:0}
.mu-ban-t b{display:block;font-size:var(--t-2);font-weight:800}
.mu-ban-t i{display:block;font-style:normal;font-size:var(--t-1);color:var(--dim);margin-top:1px}
.mu-ban-a{flex:none;font-weight:900;font-size:var(--t-1);color:#04222a;background:#22d3ee;border-radius:999px;padding:var(--e-2) var(--e-3)}
/* l'invitation a rejoindre, posee dans le fil comme un message */
.ln-c{max-width:82%;min-width:0}
.ln.moi .ln-c{display:flex;flex-direction:column;align-items:flex-end}
.bul-h.hors{color:var(--mut);padding:0 var(--e-1)}
.bul-partie{display:flex;align-items:center;gap:var(--e-2);cursor:pointer;
  background:linear-gradient(135deg,rgba(34,211,238,.18),rgba(34,211,238,.05));
  border:1px solid rgba(34,211,238,.45);border-radius:var(--r-2);padding:var(--e-2) var(--e-3)}
.bul-partie.morte{background:var(--card);border-color:var(--line);opacity:.6;cursor:default}
.bp-t{flex:1;min-width:0}
.bp-t b{display:block;font-size:var(--t-2);font-weight:800}
.bp-t i{display:block;font-style:normal;font-size:var(--t-1);color:var(--dim);margin-top:1px}
.bp-a{flex:none;font-weight:900;font-size:var(--t-1);color:#04222a;background:#22d3ee;border-radius:999px;padding:var(--e-2) var(--e-3)}

/* LA PARTIE A DISTANCE : la meme carte pour tout le monde */
.mp-tete{display:flex;align-items:center;justify-content:space-between;gap:var(--e-2);padding:2px 2px var(--e-2)}
.mp-tour{font-size:var(--t-1);font-weight:800;color:var(--mut);font-variant-numeric:tabular-nums}
.mp-qui{font-size:var(--t-1);font-weight:800;color:var(--dim)}
.mp-qui.moi{color:#4ade80}
.mp-carte{flex:none;margin:0;min-height:210px;padding:var(--e-4) var(--e-4)}
.mp-next:disabled{background:var(--card);border:1px solid var(--line2);color:var(--mut);opacity:1}
.mp-j{display:flex;flex-wrap:wrap;gap:var(--e-2);justify-content:center;margin-top:var(--e-3)}
.mp-p{font-size:var(--t-1);font-weight:700;color:var(--mut);background:rgba(255,255,255,.05);
  border-radius:999px;padding:var(--e-1) var(--e-2)}
.mp-p.on{color:#04222a;background:#22d3ee;font-weight:900}

/* un bouton qui n'est pas encore actionnable ne doit pas ressembler a un bouton actif */
#mu-go2:disabled{background:var(--card);border:1px solid var(--line2);color:var(--mut);opacity:1}
/* LE SALON, version compacte : on lit l'essentiel sans faire defiler */
.sal-tete{display:flex;flex-direction:column;align-items:center;gap:var(--e-1);padding:var(--e-2) 0 var(--e-3)}
.sal-quoi{font-size:var(--t-1);font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:#22d3ee}
.sal-etat{font-size:var(--t-4);font-weight:900;letter-spacing:-.02em}
.sal-chrono{font-size:var(--t-1);font-weight:800;color:var(--mut);font-variant-numeric:tabular-nums;
  background:rgba(255,255,255,.06);border-radius:999px;padding:var(--e-1) var(--e-2)}
.sal-r{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-3);padding:var(--e-1) 0 var(--e-2)}
.sal-j{display:flex;flex-direction:column;align-items:center;gap:var(--e-1);width:64px}
.sal-j i{font-style:normal;font-size:var(--t-1);font-weight:700;color:var(--dim);max-width:64px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sal-j.chef .dis-av{box-shadow:0 0 0 2px #4ade80}
.sal-j .dis-av.sm{width:46px;height:46px;font-size:var(--t-3)}
.dis-av.vide{background:none;border:2px dashed var(--line2);color:var(--mut);font-weight:800;
  animation:salp 1.6s ease-in-out infinite}
.sal-mot{text-align:center;color:var(--dim);font-size:var(--t-2);line-height:1.45;margin:2px 0 0;padding:0 var(--e-2)}
.sal-reg{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-2);margin-top:var(--e-3)}
.sal-reg span{display:flex;flex-direction:column;align-items:center;gap:1px;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-1);padding:var(--e-2) var(--e-3);min-width:82px}
.sal-reg i{font-style:normal;font-size:var(--t-1);font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--mut)}
.sal-reg b{font-size:var(--t-2);font-weight:800;color:#67e8f9}
/* le resultat d'une partie, dans la discussion */
.bul-fini{display:flex;flex-direction:column;gap:var(--e-2);background:var(--card);
  border:1px solid var(--line);border-left:3px solid var(--line2);border-radius:var(--r-2);padding:var(--e-2) var(--e-3)}
.bul-fini.gagne{border-left-color:#4ade80}
.bul-fini.perdu{border-left-color:#f87171}
.bul-fini.egalite{border-left-color:#fbbf24}
.bul-fini.annulee{opacity:.65}
.bf-h{display:flex;align-items:center;justify-content:space-between;gap:var(--e-2)}
.bf-h b{font-size:var(--t-2);font-weight:800}
.bf-r{flex:none;font-size:var(--t-1);font-weight:900;letter-spacing:.06em;text-transform:uppercase;
  border-radius:999px;padding:var(--e-1) var(--e-2);background:rgba(255,255,255,.07);color:var(--dim)}
.bul-fini.gagne .bf-r{background:rgba(74,222,128,.18);color:#4ade80}
.bul-fini.perdu .bf-r{background:rgba(248,113,113,.18);color:#f87171}
.bul-fini.egalite .bf-r{background:rgba(251,191,36,.18);color:#fbbf24}
.bf-d{font-size:var(--t-1);color:var(--dim)}
.bf-l{display:flex;flex-wrap:wrap;gap:var(--e-2);margin-top:2px}
.bf-l i{font-style:normal;font-size:var(--t-1);font-weight:700;color:var(--mut);background:rgba(255,255,255,.05);
  border-radius:999px;padding:var(--e-1) var(--e-2)}
.bf-l i.moi{color:var(--ink);background:rgba(255,255,255,.12)}
.bf-l i b{color:#67e8f9}

/* le salon : qui est deja la */
.sal-l{display:flex;flex-direction:column;gap:var(--e-2)}
.sal{display:flex;align-items:center;gap:var(--e-2);background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-2);padding:var(--e-2) var(--e-3)}
.sal b{flex:1;font-size:var(--t-2);font-weight:800}
.sal .jr-tag{position:static;margin:0}
.sal.vide{border-style:dashed;opacity:.7}
.sal-dots{display:flex;gap:var(--e-1);padding-left:var(--e-2)}
.sal-dots i{width:7px;height:7px;border-radius:50%;background:#22d3ee;opacity:.35;animation:salp 1.2s ease-in-out infinite}
.sal-dots i:nth-child(2){animation-delay:.15s}
.sal-dots i:nth-child(3){animation-delay:.3s}
@keyframes salp{0%,100%{opacity:.25;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}

/* l'appui long ouvre NOTRE menu, pas celui du navigateur : on coupe la selection dans le fil */
.chat{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.chat .bul,.chat .bul-partie,.chat .bul-fini{-webkit-touch-callout:none}
.bul.presse,.bul-partie.presse,.bul-fini.presse{transform:scale(.97);transition:transform .12s}
/* CHAT : separateur de jour, groupes, heures, etat d'envoi, "ecrit..." */
.chat-jour{display:flex;justify-content:center;margin:var(--e-2) 0 var(--e-1)}
.chat-jour span{font-size:var(--t-1);font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--mut);background:rgba(255,255,255,.05);border-radius:999px;padding:var(--e-1) var(--e-3)}
/* un message ecrit = une bulle bien ovale ; une partie garde sa carte carree (demande Theo 26/07) */
.bul{border-radius:var(--r-3) var(--r-3) var(--r-3) var(--r-1);padding:var(--e-2) var(--e-3)}
.bul.moi{border-radius:var(--r-3) var(--r-3) var(--r-1) var(--r-3)}
.ln.fin{margin-bottom:var(--e-2)}
.bul-partie,.bul-fini{margin:2px 0}
.bul-h{display:block;font-style:normal;font-size:var(--t-1);font-weight:700;color:var(--mut);
  text-align:right;margin-top:var(--e-1);letter-spacing:.02em}
.bul.moi .bul-h{color:rgba(255,255,255,.55)}
.bul-etat{font-style:normal;margin-left:5px}
.bul-etat.ko{color:#f87171;font-weight:900}
.chat-tape{margin:0 0 var(--e-2);padding-left:var(--e-2);font-size:var(--t-1);font-weight:700;color:#22d3ee;display:none}
.chat-saisie textarea{flex:1;min-width:0;background:var(--card);border:1px solid var(--line2);border-radius:var(--r-3);
  /* [03/08] 1rem ET PAS .95, ET CE N'EST PAS UN CHOIX DE DESSIN. Safari iOS ZOOME
     automatiquement sur tout champ dont la police est SOUS 16 px, et il ne dezoome pas en
     sortant : c'est la cause du « zoom sans raison » signale par Theo, et de tout ce qui
     suit (la fenetre visible s'effondre, le calcul de hauteur du clavier travaille sur des
     valeurs zoomees, et l'ecran clignote). 15,2 px passaient juste sous la barre. */
  padding:var(--e-3) var(--e-3);color:var(--ink);font:inherit;font-size:1rem;resize:none;max-height:118px;line-height:1.35}
.chat-jeu{flex:none;width:42px;height:42px;border-radius:50%;border:1px solid var(--line2);cursor:pointer;
  background:rgba(255,255,255,.06);color:#22d3ee;display:flex;align-items:center;justify-content:center}
.chat-jeu svg{width:22px;height:22px}
.chat-jeu:active:not(.enfonce){transform:scale(.95)}

/* rappel discret en haut du fil : les messages ne sont pas des archives */
/* le rappel de duree de vie est sous la conversation, au-dessus de la barre de saisie */
/* [03/08] elle ouvre la conversation au lieu de la fermer : plus de filet AU-DESSUS (elle
   n'a plus rien a separer d'en haut, elle est le premier element), et un ecart en dessous
   pour la detacher du premier separateur de date. */
.chat-note{flex:none;display:flex;align-items:center;justify-content:center;gap:var(--e-2);color:var(--mut);
  font-size:var(--t-1);font-weight:700;padding:2px 0 0;margin:0 0 var(--e-3)}
.chat-note i{flex:none;width:15px;height:15px;display:flex;color:#22d3ee}
.chat-note i svg{width:100%;height:100%}
/* touch-action:pan-y = le defilement vertical appartient au NAVIGATEUR, en natif ; nous ne
   gardons que l'horizontal (le tirage des heures). Sans cela, notre ecouteur bloquait le
   defilement au doigt sur iOS. */
/* ⚠️ overscroll-behavior:contain = FORCER AU BOUT DE COURSE NE REMONTE PLUS A L'ECRAN.
   Sans lui, arriver en butee dans la conversation propage le geste au parent : c'est toute
   la page qui repond a un geste qui visait le fil. `contain` coupe la propagation SANS
   supprimer le rebond local, qu'on veut garder (c'est lui, l'elastique, quand iOS pilote).
   Trouve en auditant les bouts de course le 03/08. */
.chat{flex:1;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;touch-action:pan-y;display:flex;flex-direction:column;gap:0;padding:var(--e-1) 2px var(--e-2);min-height:180px}
.chat-vide{text-align:center;padding:var(--e-4) var(--e-3);line-height:1.5}
/* une LIGNE de message : le rond a l'initiale a l'extremite, la bulle a cote */
/* LES HEURES VIVENT A DROITE, hors du champ, et entrent quand on tire la conversation vers
   la gauche (comme sur iPhone). Au repos, aucune heure n'encombre le fil.
   Le second axe est l'ELASTIQUE : le fil suit le doigt de haut en bas et revient tout seul,
   meme quand il n'y a rien a faire defiler. */
/* ⚠️ UNE SEULE PISTE BOUGE, PAS CHAQUE LIGNE, ET C'EST TOUTE LA DIFFERENCE DE DOUCEUR.
   La premiere version posait deux variables CSS sur le conteneur et laissait chaque .ln
   s'en servir pour sa propre transformation. Poser une variable custom invalide le style
   de TOUS les descendants qui la lisent : a chaque image, le navigateur recalculait le
   style et repeignait toutes les lignes visibles, cartes de partie comprises.
   Mesure sur les deux enregistrements iPhone du 03/08, correlation de phase image par
   image a 60 im/s : notre variation de vitesse valait 7,76 px par image contre 2,63 a
   iMessage, avec des reprises a 259 px en une seule image, c'est-a-dire des sauts.
   Desormais la conversation vit dans UNE piste, et c'est elle seule qui se translate :
   une transformation composee, sans recalcul de style ni repeinture du contenu. */
.chat-piste{display:flex;flex-direction:column;
  transition:transform .24s cubic-bezier(.2,.8,.3,1)}
.ln{display:flex;align-items:flex-end;gap:var(--e-2);margin-bottom:2px;position:relative}
/* pendant le geste la piste suit le doigt, sans transition, et on annonce au navigateur
   qu'elle va bouger pour qu'il lui donne sa propre couche AVANT la premiere image. */
.chat.glisse .chat-piste{transition:none;will-change:transform}
.ln-heure{position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:12px;
  font-style:normal;font-size:var(--t-1);font-weight:700;color:var(--mut);white-space:nowrap;
  pointer-events:none}
.ln.moi{flex-direction:row-reverse}
.ln-av{flex:none;width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:var(--t-1);font-weight:900;background:linear-gradient(135deg,#0e7490,#22d3ee);color:#04222a}
.ln-av.moi{background:linear-gradient(135deg,#8b5cf6,#c084fc);color:#12030f}
.ln-av.vide{background:none}
.bul{max-width:78%;background:var(--card);border:1px solid var(--line2);
  padding:var(--e-2) var(--e-3);font-size:var(--t-2);line-height:1.35;word-break:break-word}
.bul.moi{background:linear-gradient(135deg,#6d28d9,#8b5cf6);border-color:transparent;color:var(--c-texte)}
.bul-qui{display:block;font-style:normal;font-size:var(--t-1);font-weight:800;color:#22d3ee;margin-bottom:2px}
.chat-bas{flex:none;padding-top:var(--e-2)}
.chat-saisie{display:flex;gap:var(--e-2);align-items:center}
.chat-saisie input{flex:1;background:var(--card);border:1px solid var(--line2);border-radius:999px;
  padding:var(--e-3) var(--e-3);color:var(--ink);font:inherit}
.chat-env{flex:none;width:46px;height:46px;border-radius:50%;border:none;cursor:pointer;font-size:var(--t-4);
  font-weight:900;background:linear-gradient(135deg,#22d3ee,#67e8f9);color:#04222a}
.chat-jouer{margin-top:var(--e-2);display:flex;align-items:center;justify-content:center;gap:var(--e-2)}
/* la pastille est absolue par defaut : dans un bouton, elle partait se coller en haut de l'ecran */
.chat-jouer .jr-tag{position:static;margin:0}

/* pied de l'accueil : deux liens discrets, joignables sans compte */
.home-pied{margin-top:var(--e-2);display:flex;align-items:center;justify-content:center;gap:var(--e-2);flex-wrap:wrap}
.home-pied button{background:none;border:0;padding:2px 0;color:var(--mut);font:inherit;font-size:var(--t-1);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.home-pied span{color:var(--line2);font-size:var(--t-1)}
/* ===== reglages ===== */
#s-setup{padding:0}
#s-setup .topbar{padding:var(--e-3) var(--e-3) var(--e-1)}
.setup-scroll{flex:1;overflow-y:auto;padding:var(--e-2) var(--e-3) var(--e-3)}
.scard{background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-3);margin-bottom:var(--e-3)}
.scard-h{display:flex;align-items:center;gap:var(--e-2);margin-bottom:var(--e-3)}
.scard-h b{font-size:var(--t-3);font-weight:800}
.snum{width:24px;height:24px;border-radius:var(--r-1);background:linear-gradient(135deg,var(--accent),var(--accent2));color:#160f22;font-weight:900;font-size:var(--t-1);display:flex;align-items:center;justify-content:center;flex:none}
.count{margin-left:auto;background:#262a31;color:var(--accent2);font-weight:800;border-radius:999px;padding:var(--e-1) var(--e-3);font-size:var(--t-2)}
.scard .players{margin-top:var(--e-2)}
.scard .seg,.scard .chips{margin-top:0}
.scard #int-desc{margin-top:var(--e-2)}
.setup-cta{padding:var(--e-3) var(--e-3) calc(var(--e-3) + env(safe-area-inset-bottom));border-top:1px solid var(--line);background:rgba(12,12,15,.92);backdrop-filter:blur(8px)}
/* beer pong */

.collapse{display:none}
.collapse.open{display:block}

/* home mode cards */
.modes{display:flex;flex-direction:column;gap:var(--e-3);width:100%}
.mode{background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);padding:var(--e-3) var(--e-6) var(--e-3) var(--e-3);text-align:left;cursor:pointer;color:var(--ink);transition:transform .1s,border-color .12s;position:relative;overflow:hidden;display:flex;align-items:center;gap:var(--e-3)}
.mode:active:not(.enfonce){transform:scale(.98)}
.mode-ico{flex:none;width:38px;height:38px;color:var(--accent2)}
.mode-ico svg{width:100%;height:100%;display:block}
.mode-txt{flex:1;min-width:0}
.mode b{font-size:var(--t-3);font-weight:800;display:block}
.mode-txt>span{color:var(--dim);font-size:var(--t-2);margin-top:var(--e-1);display:block}
.modes>.mode:first-child,.modes>.mode-wrap:first-child .mode{border-color:transparent;background:linear-gradient(120deg,rgba(139,92,246,.28),rgba(255,93,162,.2)),var(--card)}
/* accueil allege : un seul bouton d'entree dans le jeu */
.home-play{margin-top:var(--e-3);font-size:var(--t-3);padding:var(--e-3) var(--e-4)}
/* (regle de l'ancien accueil retiree le 30/07 : le slot d'accroche est rythme par les
   ressorts .hsp, une marge en plus faussait la repartition mesuree) */
/* ce qui n'existe pas encore se voit, et se dit */
/* l'attenuation va sur les ENFANTS : .mode porte l'animation uiCarteMonte dont la keyframe
   finale fixe opacity:1 et ecraserait la valeur posee sur la tuile elle-meme */
.mode-soon .mode-ico,.mode-soon .mode-txt{opacity:.72}
.mode-soon::after{opacity:.55}
.mode-soon .soon{display:inline-block;font-style:normal;font-size:var(--t-1);font-weight:900;letter-spacing:.06em;
  text-transform:uppercase;vertical-align:middle;margin-left:8px;padding:var(--e-1) var(--e-2);border-radius:999px;
  background:var(--line2);color:var(--ink)}
/* le badge vit dans la ligne de description : rendu identique quel que soit le titre */
.mode-soon .mode-txt>span .soon{margin:0 6px 2px 0}
.modes>.mode-wrap:not(:first-child) .mode{background:var(--card)}
.mode::after{content:"›";position:absolute;right:18px;top:50%;transform:translateY(-50%);font-size:var(--t-5);color:var(--accent2)}
/* reglages avances toggle */
.advtoggle{width:100%;background:none;border:1px dashed var(--line2);color:var(--dim);border-radius:var(--r-1);padding:var(--e-3);font:inherit;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--e-3)}
.advtoggle .chev{font-size:var(--t-3)}
.chip.preset{padding:var(--e-2) var(--e-3);font-size:var(--t-2)}
/* arcade categories */
.arcade-list{padding-bottom:var(--e-4)}
.arcade-cat{font-size:var(--t-1);font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--accent2);margin:var(--e-3) 2px 2px}
.arcade-list .arcade{margin-top:var(--e-2)}

/* pierre-papier-ciseaux (refonte) */

/* cash out cible */
.co-target{color:#34d399;font-weight:800;font-size:var(--t-3);margin-bottom:var(--e-2);letter-spacing:.02em}
/* bouton ? sur les tuiles d'arcade */
.tile{position:relative}
.tile-help{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:50%;background:#262a31;color:var(--accent2);border:1px solid var(--line2);font-weight:800;font-size:var(--t-2);cursor:pointer;line-height:1;padding:0}
.tile-help:active:not(.enfonce){transform:scale(.9)}

/* halo d'ambiance sur chaque mini-jeu (couleur d'accent de l'ecran) */
.gscreen{overflow-x:hidden}
.gscreen::before{content:"";position:absolute;left:50%;top:-8%;transform:translateX(-50%);width:112%;height:50%;background:radial-gradient(closest-side,var(--accent),transparent 72%);opacity:.13;pointer-events:none;z-index:0;filter:blur(8px)}
.gscreen>*{position:relative;z-index:1}
.bl-clock{width:150px;height:150px;margin:0 auto var(--e-2);filter:drop-shadow(0 6px 16px rgba(124,58,237,.4))}
.bl-clock svg{width:100%;height:100%}
/* roulette russe - barillet acier premium */
.cyl-wrap{position:relative;width:238px;height:238px;margin:var(--e-2) auto var(--e-1);display:flex;align-items:center;justify-content:center}
.cyl-wrap::before{content:"";position:absolute;width:150%;height:150%;left:-25%;top:-25%;background:radial-gradient(circle,rgba(220,38,38,.22),transparent 62%);pointer-events:none}
.cyl-pointer{position:absolute;top:-6px;left:50%;transform:translateX(-50%);width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:22px solid #f1f1f4;z-index:5;filter:drop-shadow(0 3px 3px rgba(0,0,0,.7))}
.cylinder{position:relative;width:238px;height:238px;border-radius:50%;
  background:radial-gradient(circle at 50% 32%,#6a6a74 0%,#42424c 34%,#26262c 66%,#17171b 100%);
  border:2px solid #0c0c0f;
  box-shadow:0 0 0 7px #2c2c33,0 0 0 9px #4b4b55,inset 0 3px 10px rgba(255,255,255,.14),inset 0 -12px 26px rgba(0,0,0,.7),0 16px 34px rgba(0,0,0,.6);
  transition:transform .95s cubic-bezier(.15,.85,.2,1)}
.cylinder::after{content:"";position:absolute;top:50%;left:50%;width:46px;height:46px;margin:-23px;border-radius:50%;
  background:radial-gradient(circle at 45% 35%,#5a5a64,#1c1c20 70%);
  box-shadow:inset 0 2px 4px rgba(255,255,255,.25),inset 0 -3px 6px rgba(0,0,0,.6),0 0 0 2px #0c0c0f;z-index:2}
.cylinder::before{content:"";position:absolute;top:50%;left:50%;width:9px;height:9px;margin:-4.5px;border-radius:50%;background:#0a0a0c;box-shadow:inset 0 1px 1px rgba(255,255,255,.2);z-index:3}
.chamber{position:absolute;top:50%;left:50%;width:52px;height:52px;border-radius:50%;
  background:radial-gradient(circle at 50% 40%,#0b0b0d 40%,#050506 100%);
  box-shadow:inset 0 3px 7px rgba(0,0,0,.9),inset 0 -2px 4px rgba(255,255,255,.06),0 1px 0 rgba(255,255,255,.08);
  display:flex;align-items:center;justify-content:center}
.chamber .round{width:28px;height:28px;border-radius:50%;
  background:radial-gradient(circle at 38% 30%,#ffe9a8,#d99a2a 55%,#8a5a12 100%);
  box-shadow:inset 0 -2px 3px rgba(0,0,0,.45),0 0 6px rgba(255,200,90,.5);transition:opacity .3s,transform .3s}
.chamber.spent .round{opacity:0;transform:scale(.2)}
.chamber.live{box-shadow:inset 0 3px 7px rgba(0,0,0,.9),0 0 20px 3px rgba(248,68,68,.85)}
.chamber.live .round{background:radial-gradient(circle at 38% 30%,#ffc9c9,#dc2626 60%,#7f1010 100%)}
/* roulette casino */
.roul-wrap{position:relative;width:252px;height:252px;margin:var(--e-2) auto}
.roul-wheel{width:100%;height:100%;border-radius:50%;display:block;transition:transform 4.2s cubic-bezier(.08,.7,.12,1);filter:drop-shadow(0 12px 26px rgba(0,0,0,.55))}
.roul-ballarm{position:absolute;inset:0;transform-origin:50% 50%;transition:transform 4.2s cubic-bezier(.08,.7,.12,1);z-index:4;pointer-events:none}
.roul-ball{position:absolute;top:21px;left:50%;transform:translateX(-50%);width:14px;height:14px;border-radius:50%;background:radial-gradient(circle at 38% 30%,#fff,#dfe3ea 55%,#9aa0ac);box-shadow:0 2px 5px rgba(0,0,0,.7),0 0 8px rgba(255,255,255,.6)}
.roul-ptr{position:absolute;top:-8px;left:50%;transform:translateX(-50%);width:0;height:0;border-left:9px solid transparent;border-right:9px solid transparent;border-top:16px solid #f8fafc;z-index:6;filter:drop-shadow(0 2px 2px rgba(0,0,0,.6))}
.roul-hub{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:52px;height:52px;border-radius:50%;background:radial-gradient(circle at 50% 34%,#2a2a30,#0d0d10);border:2px solid rgba(255,235,150,.7);display:flex;align-items:center;justify-content:center;z-index:5;box-shadow:inset 0 0 8px rgba(0,0,0,.7),0 3px 8px rgba(0,0,0,.5)}
/* 05-minijeux-b-23 : cette classe etait declaree DEUX fois a la suite, la premiere valeur
   (1,3rem) etant morte des la ligne suivante. Une seule declaration. */
.ca-num{font-size:var(--t-5);font-weight:900;color:var(--c-texte);min-width:1ch;text-align:center}
.ca-num.red{color:#f87171}.ca-num.black{color:var(--c-texte)}.ca-num.green{color:#4ade80}
.ca-bets{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin-top:var(--e-3);width:100%;max-width:340px;align-self:center}
.ca-bet{padding:var(--e-3);border-radius:var(--r-2);font-weight:800;font-size:var(--t-2);cursor:pointer;border:2px solid transparent;color:var(--c-texte);transition:transform .1s,outline .12s}
.ca-neutral{background:linear-gradient(160deg,#3f3f46,#1c1c22);border-color:#52525b}
.ca-red{background:linear-gradient(160deg,#e11d48,#9f1239)}
.ca-black{background:linear-gradient(160deg,#3f3f46,#0c0c0f);border-color:#52525b}
.ca-bet:active:not(.enfonce){transform:scale(.97)}
.ca-bet.on{outline:3px solid #fbbf24;outline-offset:2px;transform:translateY(-2px)}
/* intro de tour (qui joue) */
.turn-card{position:relative;overflow:hidden;text-align:center;width:100%;background:var(--card);border:1px solid var(--line);border-radius:var(--r-4);padding:var(--e-5) var(--e-4) var(--e-5);box-shadow:0 22px 55px rgba(0,0,0,.5);display:flex;flex-direction:column;align-items:center}
.turn-card::before{content:"";position:absolute;inset:0;background:radial-gradient(120% 65% at 50% 0%,var(--accent),transparent 60%);opacity:.22;pointer-events:none}
.turn-card>*{position:relative;z-index:1}
.turn-card.pin{animation:popIn var(--m-long) var(--m-sortie) both}
.turn-ico{width:84px;height:84px;color:var(--accent2);margin-bottom:var(--e-3);filter:drop-shadow(0 0 16px var(--accent))}
.turn-ico svg{width:100%;height:100%;display:block}
.turn-kick{color:var(--dim);font-size:var(--t-2);letter-spacing:.16em;text-transform:uppercase;font-weight:700}
.turn-name{font-size:clamp(2.6rem,12vw,3.6rem);font-weight:900;line-height:1;margin:var(--e-2) 0 var(--e-3);word-break:break-word}
.turn-game{color:var(--accent2);font-weight:800;font-size:var(--t-3);line-height:1.3}
#turn-badge{position:fixed;top:calc(env(safe-area-inset-top,0px) + 66px);left:50%;transform:translateX(-50%);z-index:60;display:none;background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--accent-ink);font-weight:900;font-size:var(--t-3);padding:var(--e-2) var(--e-4);border-radius:999px;box-shadow:var(--o-2);border:2px solid rgba(255,255,255,.18);pointer-events:none;white-space:nowrap;max-width:88vw;overflow:hidden;text-overflow:ellipsis;animation:turnPulse 1.8s ease-in-out infinite}
#turn-badge::before{content:"Au tour de "}
/* [23/09] La bombe : « Léa commence » (classe posee par openBomb, retiree par setTurnBadge) */
#turn-badge.commence::before{content:none}
#turn-badge.commence::after{content:" commence"}
/* [28/10, Romain] la bombe a distance, une fois « Commencer » touche : « À vous ! », sans « Au tour de » */
#turn-badge.tous::before{content:none}
@keyframes turnPulse{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.05)}}
#mini-timer{position:fixed;top:56px;right:12px;z-index:62;display:none;background:#1b1b22;color:var(--accent2);border:1px solid var(--line2);font-weight:800;font-variant-numeric:tabular-nums;font-size:var(--t-2);padding:var(--e-1) var(--e-3);border-radius:999px;box-shadow:0 4px 12px rgba(0,0,0,.4);pointer-events:none;min-width:56px;text-align:center}
#mini-timer.warn{color:#0c0c0f;background:linear-gradient(90deg,#f87171,#fbbf24);border-color:transparent;animation:pulseWarn .5s ease-in-out infinite alternate}
@keyframes pulseWarn{from{transform:scale(1)}to{transform:scale(1.08)}}
.home-players{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--e-3);background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-3) var(--e-3);margin:0 0 var(--e-3);cursor:pointer;color:var(--ink);text-align:left;font:inherit}
.home-players span{color:var(--dim);font-size:var(--t-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.home-players b{color:var(--accent2);font-size:var(--t-2);flex:none;font-weight:800}
.home-players:active:not(.enfonce){transform:scale(.99)}
/* UI-22 : 42 px, sous le minimum de 44 recommande pour une cible tactile. C'est le SEUL defaut
   qui restait de cette fiche, mesure sur l'application reelle le 27/07 :
   - elle annonçait trois boutons flottants en meme temps. Il n'y en a jamais trois : reglages
     et compte sur l'accueil (body.show-sound), menu ailleurs (body.menu-on), jamais ensemble.
   - elle annonçait une superposition. Mesure des boites : aucune.
   - elle demandait de figer le fond anime sous prefers-reduced-motion. Deja fait (.home-bg span
     {animation:none}), plus une regle globale sur toutes les animations.
   Il ne restait donc que deux pixels a corriger, pas une refonte. */
#menu-btn{position:fixed;top:12px;left:12px;z-index:65;display:none;width:44px;height:44px;border-radius:var(--r-1);background:var(--card);border:1px solid var(--line);color:var(--ink);cursor:pointer;align-items:center;justify-content:center;padding:0}
#menu-btn:active:not(.enfonce){transform:scale(.94)}
body.menu-on #menu-btn{display:flex}
body.menu-on .topbar>.iconbtn:first-child:not([data-back]){visibility:hidden;pointer-events:none}
/* presets en cartes */
.preset-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2)}
.preset-card{text-align:left;background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);padding:var(--e-3);cursor:pointer;color:var(--ink);transition:transform .1s,border-color .12s}
.preset-card:active:not(.enfonce){transform:scale(.97)}
.preset-card b{font-size:var(--t-2);font-weight:800;display:block}
.preset-card span{color:var(--dim);font-size:var(--t-1);margin-top:var(--e-1);display:block;line-height:1.3}
.preset-card.on{border-color:transparent;background:linear-gradient(135deg,rgba(139,92,246,.3),rgba(255,93,162,.22)),var(--card)}

/* ===== couche d'animation globale ===== */
@keyframes uiEcran{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.screen.on{animation:uiEcran var(--m-moyen) var(--m-sortie) both}
@keyframes uiCarteMonte{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.setup-scroll .scard,.setup-scroll .advtoggle{animation:uiCarteMonte var(--m-moyen) var(--m-sortie) both}
.setup-scroll .scard:nth-child(2){animation-delay:.05s}
.setup-scroll .scard:nth-child(3){animation-delay:.1s}
.setup-scroll #adv-wrap .scard{animation-delay:.02s}
.arcade .tile-wrap,.arcade .tile-rand{animation:uiCarteMonte var(--m-moyen) var(--m-sortie) both}
.arcade .tile-wrap:nth-child(2){animation-delay:.04s}.arcade .tile-wrap:nth-child(3){animation-delay:.08s}
.arcade .tile-wrap:nth-child(4){animation-delay:.12s}.arcade .tile-wrap:nth-child(5){animation-delay:.16s}.arcade .tile-wrap:nth-child(6){animation-delay:.2s}
.modes .mode{animation:uiCarteMonte var(--m-moyen) var(--m-sortie) both}.modes .mode:nth-child(2){animation-delay:.07s}
.preset-card{animation:uiCarteMonte var(--m-moyen) var(--m-sortie) both}
.preset-card:nth-child(2){animation-delay:.04s}.preset-card:nth-child(3){animation-delay:.08s}.preset-card:nth-child(4){animation-delay:.12s}
/* [20/10] la brillance (sheen) des gros boutons est retiree : le reflet est reserve a « Lancer une Soiree » (Romain) */
.btn-xl,.setup-cta .btn{position:relative;overflow:hidden}
/* carte de defi animee a chaque tirage */
@keyframes cardPop{0%{opacity:0;transform:translateY(16px) scale(.985)}100%{opacity:1;transform:none}}
.gamecard.anim .cardtext{animation:cardPop var(--m-moyen) var(--m-sortie) both}
.gamecard.anim .tag{animation:cardPop var(--m-moyen) var(--m-sortie) both}
.gamecard.anim .sanction{animation:popIn var(--m-moyen) var(--m-sortie) both}
@keyframes popIn{0%{opacity:0;transform:scale(.82)}100%{opacity:1;transform:scale(1)}}
.pop-in{animation:popIn var(--m-moyen) var(--m-sortie) both}
/* selection chips/seg plus vivante */
.chip,.seg button,.tile,.mode,.preset-card{will-change:transform}
@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms !important}}

/* effets confettis / flash defaite */
.fx{position:absolute;inset:0;pointer-events:none;z-index:60;overflow:hidden}
.confetti{position:absolute;top:-16px;width:9px;height:14px;border-radius:var(--r-1);animation:confall 1.4s cubic-bezier(.3,.6,.4,1) forwards}
/* [14/10, Romain] « jamais de flash » (lueur de la Soiree retiree le 14/10) : le rate ne claque plus
   un cadre rouge a 55 % en 0,17 s. Un voile rouge sur les bords seulement, a 22 %, qui monte en 0,4 s
   et s'eteint en 1 s : on sent l'echec sans eclair. */
/* [20/10, Romain, direction B2] verdict perdu : un rouge corail doux qui touche seulement les bords, une fois (Romain :
   « fait le rouge de perdu plus doux, il est trop agressif »). Gagne : la meme lueur en vert (.winfx), sans confettis. */
.losefx{position:absolute;inset:0;pointer-events:none;z-index:60;background:radial-gradient(circle at 50% 45%,transparent 62%,rgba(248,113,113,.12));animation:losep var(--m-fort) ease-in-out both}
.winfx{position:absolute;inset:0;pointer-events:none;z-index:60;background:radial-gradient(circle at 50% 45%,transparent 55%,rgba(74,222,128,.24));animation:losep var(--m-fort) ease-in-out both}
@media (prefers-reduced-motion:reduce){.losefx,.winfx{animation:none;opacity:0}}
@keyframes losep{0%{opacity:0}28%{opacity:1}100%{opacity:0}}

/* mode defi (scores) */
.defi-turn{text-align:center;margin:var(--e-2) 0}
.defi-name{font-size:var(--t-6);font-weight:900;letter-spacing:-.02em;margin:var(--e-2) 0}
.defi-board{margin-top:var(--e-3);background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);overflow:hidden}
.defi-row{display:flex;justify-content:space-between;align-items:center;padding:var(--e-3) var(--e-3);border-bottom:1px solid var(--line)}
.defi-row:last-child{border-bottom:none}
.defi-row:first-child{background:linear-gradient(90deg,rgba(139,92,246,.2),transparent)}
.defi-row span{font-weight:700}.defi-row b{font-weight:900;color:var(--accent2);font-size:var(--t-3)}
#toast{position:fixed;left:50%;bottom:96px;transform:translateX(-50%) translateY(20px);z-index:90;max-width:88vw;background:#1b1b22;color:var(--ink);border:1px solid var(--line2);border-radius:var(--r-2);padding:var(--e-3) var(--e-3);font-size:var(--t-2);font-weight:600;text-align:center;box-shadow:0 10px 30px rgba(0,0,0,.55);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
#toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

/* covers des mini-jeux */
.tile-ico{width:38px;height:38px;flex:none}
.tile-ico svg{width:100%;height:100%;display:block}
.tile{overflow:hidden}
.tile::before{content:"";position:absolute;inset:0;background:radial-gradient(130% 90% at 100% 0%, var(--gcol,#8b5cf6), transparent 62%);opacity:.13;pointer-events:none}
.tile-rand{grid-column:1/-1;min-height:auto;flex-direction:row;align-items:center;gap:var(--e-3);border-color:var(--accent)}
.tile-rand::before{opacity:.2}
.tile-rand .tile-ico{width:34px;height:34px}
.tile-rand b{font-size:var(--t-3);background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.tile-rand span{margin-top:2px}

/* assistant page par page */
.wiz-dots{display:flex;gap:var(--e-2);justify-content:center;padding:var(--e-3) 0 2px}
.wiz-dots i{width:8px;height:8px;border-radius:50%;background:var(--line2);transition:.2s}
.wiz-dots i.on{background:var(--accent2);width:22px;border-radius:var(--r-1)}
.wiz-dots i.done{background:var(--accent)}
.wiz-body{flex:1;overflow-y:auto;padding:var(--e-5) var(--e-3) var(--e-3);display:flex;flex-direction:column;justify-content:flex-start}
.wiz-h{font-size:var(--t-4);font-weight:800;margin:var(--e-2) 0 var(--e-3);text-align:center}
.wiz-seg{margin-bottom:var(--e-2)}

/* ============ PASSE DESIGN MINI-JEUX (overrides finaux) ============ */
/* Le stop parfait */
.tmbar{height:56px;border-radius:var(--r-2);background:linear-gradient(180deg,#0c0c11,#181820);border:1px solid var(--line2);box-shadow:inset 0 2px 10px rgba(0,0,0,.65);margin:var(--e-3) 0}
.tmtarget{background:linear-gradient(180deg,rgba(103,232,249,.4),rgba(103,232,249,.18));border-left:2px solid #67e8f9;border-right:2px solid #67e8f9;box-shadow:0 0 22px rgba(103,232,249,.55)}
.tmmark{width:6px;background:linear-gradient(180deg,#fff,#cbd5e1);border-radius:var(--r-1);box-shadow:0 0 14px rgba(255,255,255,.9)}
/* Tape le plus vite : gros bouton compteur */
#tap-count{font-size:4.4rem;font-weight:900;font-variant-numeric:tabular-nums;color:#fde047;width:184px;height:184px;margin:0 auto;display:flex;align-items:center;justify-content:center;border-radius:50%;background:radial-gradient(circle at 50% 34%,rgba(234,179,8,.2),transparent 70%),var(--card);border:3px solid rgba(234,179,8,.55);box-shadow:0 0 44px rgba(234,179,8,.2),inset 0 0 34px rgba(234,179,8,.08)}
/* Cash out : multiplicateur lumineux + cible en pill */
#co-mult{font-size:4.3rem;font-weight:900;font-variant-numeric:tabular-nums;letter-spacing:.02em;text-shadow:0 0 26px rgba(52,211,153,.45)}
.co-target{display:inline-block;color:#34d399;font-weight:800;font-size:var(--t-3);padding:var(--e-2) var(--e-3);border:1px solid rgba(52,211,153,.45);border-radius:999px;margin:0 auto var(--e-3);background:rgba(16,185,129,.08)}
/* Le 5 parfait : chrono digital */
#dx-clock{font-size:4.7rem;font-weight:900;font-variant-numeric:tabular-nums;letter-spacing:.05em;color:#5eead4;text-shadow:0 0 28px rgba(94,234,212,.5);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
/* La bombe : mèche + étincelle */
#bomb-pulse{width:132px;height:132px;background:radial-gradient(circle at 38% 30%,#fdba74,#9a3412 68%,#5a1e08);box-shadow:0 0 52px rgba(249,115,22,.45),inset -9px -9px 20px rgba(0,0,0,.55),inset 7px 7px 14px rgba(255,255,255,.16);position:relative}
#bomb-pulse::before{content:"";position:absolute;top:-16px;right:26px;width:4px;height:24px;background:#3a2a1a;border-radius:var(--r-1);transform:rotate(22deg);transform-origin:bottom left}
#bomb-pulse::after{content:"";position:absolute;top:-26px;right:20px;width:11px;height:11px;border-radius:50%;background:radial-gradient(circle,#fff,#fbbf24 45%,#f97316);box-shadow:0 0 14px #f97316,0 0 24px #fbbf24;animation:spark .28s infinite alternate}
@keyframes spark{from{transform:scale(.8);opacity:.85}to{transform:scale(1.35);opacity:1}}
/* Pierre-papier-ciseaux : mains + VS stylés */
/* Calcul express : question XL, réponses hautes */
#ma-q{font-size:3.3rem;font-weight:900;letter-spacing:.04em}
.ans{padding:var(--e-4) var(--e-2);font-size:var(--t-3)}
/* La cible : vraie mire rouge/blanc */
#tg-dot{background:radial-gradient(circle at 50% 50%,#fca5a5 0 16%,#dc2626 16% 34%,#fff 34% 46%,#dc2626 46% 64%,#fff 64% 76%,#dc2626 76% 100%);border:2px solid #fff;box-shadow:0 0 28px rgba(220,38,38,.6),inset 0 0 10px rgba(0,0,0,.35)}
/* Vert ou rouge : mot géant */
#gn-inst{font-size:var(--t-4);font-weight:900}
#gn-zone.green #gn-inst,#gn-zone.red #gn-inst{font-size:var(--t-7);letter-spacing:.1em;text-shadow:0 0 24px rgba(0,0,0,.4)}
/* Réflexe : dégradés + instruction XL */
#reflex-zone{background:radial-gradient(circle at 50% 40%,#4a1414,#280a0a)}
#reflex-zone.go{background:radial-gradient(circle at 50% 40%,#0f5a28,#07331a)}
#reflex-inst{font-size:var(--t-4);font-weight:900}
/* [01/08, ordre Theo] Reflexe = un FEU : boitier a DEUX lampes, rouge en haut, vert en bas,
   jamais d'orange (rien a anticiper entre les deux). Le fond de zone reste en renfort (vu de
   loin sur une table), mais l'objet du jeu est le feu. L'information ne repose pas sur la
   couleur seule : la lampe allumee change de POSITION, le texte et la vibration suivent. */
#reflex-feu{width:min(38vw,150px);padding:var(--e-3) 0;border-radius:var(--r-4);background:#111016;
  border:1px solid #2C2736;box-shadow:inset 0 2px 8px rgba(0,0,0,.6),0 10px 30px -18px rgba(0,0,0,.8);
  display:flex;flex-direction:column;align-items:center;gap:var(--e-3);margin-bottom:var(--e-4)}
.feu-lampe{width:min(24vw,96px);height:min(24vw,96px);border-radius:50%;background:#1d1b24;
  border:1px solid #35303f;transition:background .05s,box-shadow .05s}
#reflex-zone .feu-rouge{background:#ef4444;border-color:transparent;
  box-shadow:0 0 34px rgba(239,68,68,.55),inset 0 -6px 14px rgba(0,0,0,.3)}
#reflex-zone.go .feu-rouge{background:#1d1b24;border-color:#35303f;box-shadow:none}
#reflex-zone.go .feu-vert{background:#22c55e;border-color:transparent;
  box-shadow:0 0 40px rgba(34,197,94,.65),inset 0 -6px 14px rgba(0,0,0,.3)}
#reflex-zone.arming .feu-rouge{animation:armpulse .7s ease-in-out infinite alternate}
/* Trouve l'intrus : cases avec relief */
.icell{background:linear-gradient(180deg,#1b1b21,var(--card));box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 2px 5px rgba(0,0,0,.35);color:var(--c-texte);font-size:var(--t-5)}
.icell:active:not(.enfonce){transform:scale(.94)}
/* Roulette casino : canvas numérote, la profondeur est dessinee dedans */

/* ===== V1.1 : son, temps forts, onboarding, accessibilite ===== */
/* bouton son flottant (accueil / age uniquement) */
/* temps fort plein ecran (PAN, BOUM) */
.bigfx{position:fixed;inset:0;z-index:90;display:flex;align-items:center;justify-content:center;pointer-events:none;
  font-size:clamp(3.5rem,22vw,8rem);font-weight:900;letter-spacing:.04em;color:var(--c-texte);opacity:0;
  background:radial-gradient(circle at center,rgba(0,0,0,.35),rgba(0,0,0,.72))}
.bigfx.lose{color:#fecaca;text-shadow:0 0 40px rgba(239,68,68,.8)}
.bigfx.win{color:#bbf7d0;text-shadow:0 0 40px rgba(74,222,128,.8)}
.bigfx.show{animation:bigpop .95s ease-out}
@keyframes bigpop{0%{opacity:0;transform:scale(.4)}18%{opacity:1;transform:scale(1.08)}40%{transform:scale(1)}100%{opacity:0;transform:scale(1.02)}}
/* onboarding */
.intro-dots{display:flex;gap:var(--e-2);margin-bottom:var(--e-3)}
.intro-dots i{width:22px;height:5px;border-radius:var(--r-1);background:var(--line2);transition:.2s}
.intro-dots i.on{background:linear-gradient(90deg,var(--accent),var(--accent2));width:30px}
/* accessibilite : contraste des textes secondaires + focus visible + cibles tap */
:root{--dim:#C8C5CF;--mut:#A19CAB}
button:focus-visible,.tile:focus-visible,.mode:focus-visible,.preset-card:focus-visible,.chip:focus-visible{outline:2px solid var(--accent2);outline-offset:2px}
.tile-help{min-width:26px;min-height:26px}
/* --- animations V1.2 (mini-jeux) --- */
#tap-count{transition:transform .07s ease-out}
@keyframes tgpop{0%{transform:scale(.5);opacity:.35}100%{transform:scale(1);opacity:1}}
#co-mult.cashable{animation:copulse .5s ease-in-out infinite}
@keyframes copulse{0%,100%{transform:scale(1)}50%{transform:scale(1.1)}}
#co-mult.shake{animation:coshake .42s}
@keyframes coshake{0%,100%{transform:translateX(0)}20%{transform:translateX(-7px)}40%{transform:translateX(7px)}60%{transform:translateX(-5px)}80%{transform:translateX(4px)}}
.icell{--k:0}
#in-grid.stag .icell{animation:icellIn var(--m-court) both;animation-delay:calc(var(--k)*9ms)}
@keyframes icellIn{0%{opacity:0;transform:scale(.6)}100%{opacity:1;transform:scale(1)}}
.icell.good{animation:icellGood .42s;background:#14532d;color:var(--c-texte);border-color:#22c55e}
@keyframes icellGood{0%{transform:scale(1)}50%{transform:scale(1.25)}100%{transform:scale(1)}}
/* [01/08] la pulsation d'attente vit sur la LAMPE ROUGE du feu, plus sur toute la zone
   (regle deplacee avec le concept du feu, ordre Theo) */
@keyframes armpulse{from{filter:brightness(1)}to{filter:brightness(1.55)}}
.countfx{position:fixed;inset:0;z-index:88;display:flex;align-items:center;justify-content:center;font-size:clamp(4rem,26vw,9rem);font-weight:900;color:var(--c-texte);pointer-events:none;opacity:0;text-shadow:0 0 40px rgba(0,0,0,.5)}
.countfx.tick{animation:cnt .55s ease-out}
@keyframes cnt{0%{opacity:0;transform:scale(1.5)}30%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.85)}}

/* --- accueil : "Qui joue ?" repliable (visible mais discret) --- */
.home-players-card{width:100%;flex:none;text-align:left;background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);margin:var(--e-4) 0 var(--e-3);overflow:hidden}
.hpc-head{width:100%;display:flex;align-items:center;gap:var(--e-2);background:none;border:none;color:var(--ink);padding:var(--e-3);cursor:pointer;font:inherit}
.hpc-head b{font-size:var(--t-3);font-weight:800}
.hpc-count{margin-left:auto;flex:none;font-size:var(--t-1);font-weight:800;color:var(--accent2);background:rgba(139,92,246,.2);border:1px solid rgba(139,92,246,.35);border-radius:999px;padding:var(--e-1) var(--e-2)}
.hpc-chev{flex:none;color:var(--mut);font-size:var(--t-4);line-height:1;transition:transform .2s}
.home-players-card.open .hpc-chev{transform:rotate(90deg)}
.hpc-body{max-height:0;overflow:hidden;transition:max-height .28s ease}
.home-players-card.open .hpc-body{max-height:700px}
/* accueil en flex-start : le centrage reste via les espaceurs, mais le HAUT reste scrollable quand le clavier/contenu déborde (sinon justify-content:center rogne le haut) */
/* [02/08] LE FOND EST PLAT : toute la lumiere de l'ecran est emise par les cartes et
   s'eteint en 14 px. Les deux declarations de #s-home doivent le dire, sinon celle qui
   perd la cascade reste une fausse piste pour qui la lit. */
#s-home{justify-content:flex-start;background:var(--bg)}
/* ══════════════════════════════════════════════════════════════════════════════
   [07/08, decision de Theo] L'ACCUEIL NE DEFILE PLUS DU TOUT. « Pas de defilement sur
   la page principale, tout est prevu pour l'eviter. »

   POURQUOI IL LE POUVAIT : `.screen` porte `overflow-y:auto` pour toute l'app, donc
   l'accueil defilait par CONSTRUCTION des qu'un pixel depassait — et sur iOS la hauteur
   visible change quand la barre d'adresse se retracte. Un decalage transitoire suffisait
   pour que le geste attrape, ce qui explique le micro-defilement intermittent signale par
   Theo, et le fait qu'un rechargement le fasse disparaitre.

   ⚠️ CE N'ETAIT PAS UN PROBLEME DE CONTENU, ET C'EST MESURE : sur trois hauteurs (667,
      714, 844) et trois garnitures de trinkeurs (0, 5, 14), l'accueil ne deborde JAMAIS
      en taille normale. Le verrou ne cache donc rien.

   ⚠️⚠️ SAUF EN GRAND TEXTE SUR UN PETIT ECRAN, ET CE CAS GARDE SON DEFILEMENT. Mesure :
      +25 px a 667 de haut, quelle que soit la garniture. Y poser `hidden` COUPERAIT la
      mention legale sans aucun moyen de l'atteindre — c'est le piege TE-29 deja paye sur
      ce projet, ou un contenu trop haut devenait inaccessible des DEUX cotes. Le dossier
      autorise explicitement le defilement en Grand texte, et c'est le seul endroit ou il
      subsiste. **Un verrou qui protege l'usage normal ne doit pas emmurer le cas
      degrade.**
   ══════════════════════════════════════════════════════════════════════════════ */
#s-home{overflow:hidden}
html.bigtext #s-home{overflow-y:auto}
.hpc-body-inner{padding:var(--e-2) var(--e-3) var(--e-3)}
.hpc-btn{min-width:108px}
.hpc-okrow{display:flex;justify-content:flex-end;margin-top:var(--e-2)}
.hpc-list{display:flex;flex-wrap:wrap;gap:var(--e-2);margin-top:var(--e-2)}
.hp-chip{display:inline-flex;align-items:center;gap:var(--e-2);background:rgba(255,255,255,.06);border:1px solid var(--line2);border-radius:999px;padding:var(--e-2) var(--e-2) var(--e-2) var(--e-3);font-weight:700;font-size:var(--t-2)}
.hp-chip .hp-x{background:none;border:none;color:#ff6b81;font-size:var(--t-3);line-height:1;cursor:pointer;padding:0 var(--e-1)}
.hpc-ok{background:linear-gradient(90deg,#16a34a,#22c55e);color:#06130a;font-weight:800}
/* --- son colore (vert=activé / rouge=coupé) sur le menu + le bouton flottant --- */
/* --- categorie de la bombe : bien visible --- */
#bomb-cat{display:flex;flex-direction:column;align-items:center;gap:var(--e-2);background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);padding:var(--e-3) var(--e-4);margin:2px auto var(--e-2);max-width:92%}
.bomb-cat-k{font-size:var(--t-1);font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--accent2)}
.bomb-cat-v{font-size:var(--t-4);font-weight:900;line-height:1.15;color:var(--ink)}
/* --- Pierre-papier-ciseaux : duel (score, secousse, gagnant/perdant) --- */
/* --- Doigt du destin : multi-touch, dots colorés, sort qui tourne --- */
.finger-count{margin-top:var(--e-3);font-weight:800;font-size:var(--t-3);color:var(--ink)}
.fdot{transition:transform .18s ease,opacity .3s,box-shadow .2s,background .15s;z-index:2}
.fdot.pop{animation:fdotpop var(--m-court) var(--m-sortie)}
@keyframes fdotpop{0%{transform:scale(.3);opacity:0}100%{transform:scale(1);opacity:1}}
.fdot.sel{transform:scale(1.2);filter:brightness(1.55)}
.fdot.win{border-color:#fff!important;background:rgba(255,255,255,.92)!important;box-shadow:0 0 48px rgba(255,255,255,.95)!important;transform:scale(1.35);z-index:3}
.fdot.out{opacity:.12;transform:scale(.8)}
@media (prefers-reduced-motion:reduce){
  .bigfx.show{animation-duration:.5s}
  .home-bg span{animation:none}
}

/* ===== V1.2 (24/07 soir) : correctifs d'audit ===== */
/* tuiles = vrais boutons, "?" hors du bouton (a11y) + cible tactile correcte */
.tile-wrap{position:relative;display:flex}
.tile{width:100%;font:inherit;color:var(--ink);text-align:left;border:1px solid var(--line);appearance:none}
.tile-help{width:34px;height:34px;min-width:34px;min-height:34px;font-size:var(--t-2);top:6px;right:6px;z-index:2}
.arcade .tile-wrap:last-child:nth-child(odd){grid-column:1/-1}
.arcade .tile-wrap:last-child:nth-child(odd) .tile{flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--e-3);min-height:auto;padding-right:var(--e-6)}
.arcade .tile-wrap:last-child:nth-child(odd) .tile>div:last-child{flex:1;min-width:0}
/* le tour s'affiche DANS la carte (le badge flottant chevauchait la bordure et masquait la progression) */
.g-turn{display:none;align-items:baseline;justify-content:center;gap:var(--e-2);margin-bottom:2px}
.g-turn .gt-k{font-size:var(--t-1);font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--mut)}
.g-turn .gt-n{font-size:var(--t-4);font-weight:900;letter-spacing:-.01em}
.g-turn .gt-all{color:var(--accent2)}
/* assistant : sous-titre + compteur de cartes */
.wiz-h2{font-size:var(--t-3);margin:var(--e-4) 0 2px;color:var(--dim)}
.wz-count{text-align:center;margin-top:var(--e-2)}
/* paquet trop court : l'ambre previent sans alarmer. Le rouge reste reserve au destructif. */
.wz-count.court{color:#fbbf24;font-weight:700}
/* GD-15 : passer une carte. Dans le coin de la carte, assez visible pour etre trouve, assez
   discret pour ne pas rivaliser avec les deux boutons du bas. Cible tactile de 40 px. */
.card-passer{position:absolute;top:10px;right:10px;width:40px;height:40px;padding:0;
  display:flex;align-items:center;justify-content:center;border-radius:50%;
  background:rgba(255,255,255,.05);border:1px solid var(--line);color:var(--mut);
  cursor:pointer;transition:color .15s,background .15s}
.card-passer svg{width:17px;height:17px}
.card-passer:active{background:rgba(255,255,255,.12);color:var(--ink)}
.card-passer[disabled]{opacity:.32;pointer-events:none}
/* GD-18 : le bandeau des reglages d'un Classique. Il informe d'abord, il agit ensuite : discret,
   mais assez visible pour qu'on sache toujours a quoi on joue. */
.cl-reglages{display:flex;align-items:center;justify-content:center;gap:var(--e-2);width:100%;
  margin:2px 0 0;padding:var(--e-2) var(--e-3);background:none;border:0;cursor:pointer;
  font-size:var(--t-1);color:var(--dim)}
.cl-reglages span{font-weight:700;color:var(--ink)}
.cl-reglages i{font-style:normal;color:var(--mut)}
.cl-reglages em{font-style:normal;margin-left:4px;font-size:var(--t-1);font-weight:700;
  color:var(--accent2);border:1px solid var(--line2);border-radius:999px;padding:var(--e-1) var(--e-2)}
/* GD-17 : les prenoms a designer, sur la carte. Cibles larges : on appuie a plusieurs, vite,
   et le telephone n'est pas toujours dans la bonne main. */
.designe{display:flex;flex-wrap:wrap;gap:var(--e-2);justify-content:center;margin-top:var(--e-1)}
.designe-n{min-height:44px;padding:var(--e-2) var(--e-3);border-radius:999px;font-size:var(--t-2);font-weight:700;
  color:var(--ink);background:rgba(255,255,255,.06);border:1px solid var(--line2);cursor:pointer;
  transition:background .14s,border-color .14s,transform .1s}
.designe-n:active{background:var(--accent);border-color:transparent;color:var(--accent-ink);transform:scale(.96)}
/* GD-20 : Action ou verite. Les deux choix ont exactement la meme taille, aucun n'est suggere,
   et ils occupent la carte : c'est le geste central de l'ecran, pas une option de coin. */
/* NOM UNIQUE : une classe ".av" existait deja (les cartes d'avantages du compte) et imposait
   flex-direction:column. Les deux choix se retrouvaient empiles. Prefixe "cl-" pour l'ecran des
   Classiques, comme le reste de ses identifiants. */
.designe.cl-duo{width:100%;gap:var(--e-2);margin-top:var(--e-2);flex-wrap:nowrap;flex-direction:row}
.cl-duo-b{flex:1 1 0;min-width:0;justify-content:center;text-align:center;font-size:var(--t-2);padding:var(--e-3) var(--e-2)}
/* Les faits de chaque mode, DANS la carte : ce que ce mode donne, pas ce qu'il promet.
   Plus petit que la description, en gris, pour se lire apres elle et non a sa place. */
.mode-faits{display:block;margin-top:var(--e-2);font-style:normal;font-size:var(--t-1);font-weight:700;
  letter-spacing:.02em;color:var(--dim)}
.mode-faits span{white-space:nowrap;font-weight:700;font-size:var(--t-1);color:inherit}  /* un fait ne se coupe jamais */
.mode-faits em{font-style:normal;color:var(--mut);margin:0 6px}
.mode-faits.manque{color:var(--mut)}
/* Les deux ecrans de passage : un vrai apercu du jeu plutot que du vide. Il informe, il ne
   reclame pas l'attention : pas de bordure marquee, pas de couleur d'accent, rien de cliquable. */
.apercu{width:100%;margin:var(--e-3) 0 var(--e-1);padding:var(--e-3) var(--e-3);border-radius:var(--r-3);
  background:rgba(255,255,255,.035);border:1px solid var(--line);text-align:left}
.apercu-t{font-size:var(--t-1);font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:var(--mut);margin-bottom:var(--e-2)}
.apercu-c{font-size:var(--t-2);line-height:1.5;color:var(--ink);font-weight:600}
.apercu-n{margin-top:var(--e-2);font-size:var(--t-1);color:var(--dim)}
.apercu-l{font-size:var(--t-2);line-height:1.6;color:var(--dim)}
/* GD-23 : un jeu qui demande trois joueurs, vu par un duo. Grise mais lisible : le libelle dit
   pourquoi, donc il doit rester au-dessus du seuil de contraste. */
/* [02/08] .tile-wrap.verrouille est parti avec l'ancienne grille des Classiques : GD-23 vit
   desormais sur la tuile .jeu du catalogue (aria-disabled, teinte du mode conservee,
   opacite .42, sous-titre remplace par la condition). */
/* GD-20 : le decompte des voix de "Tu preferes". Un seul appui suffit : on annonce combien ont
   choisi la premiere option, la seconde s'en deduit. Prefixe "cl-" comme le reste de cet ecran. */
.designe.cl-vote{width:100%;flex-direction:column;flex-wrap:nowrap;gap:var(--e-2);margin-top:var(--e-3)}
.cl-vote-q{font-size:var(--t-1);color:var(--dim);text-align:center;line-height:1.4;margin:0}
.cl-vote-l{display:flex;flex-wrap:wrap;gap:var(--e-2);justify-content:center;width:100%}
.cl-vote-b{min-width:44px;padding:var(--e-2) var(--e-3);font-size:var(--t-2)}
.cl-vote-passe{background:none;border:0;color:var(--mut);font-size:var(--t-1);padding:var(--e-2);cursor:pointer;
  text-decoration:underline;text-underline-offset:3px}
/* GD-12 : la soiree en cours, nommee sur l'accueil. Discret : c'est une information, pas une action. */
.soiree-encours{text-align:center;font-size:var(--t-1);margin:2px 0 var(--e-2);letter-spacing:.2px}
/* GD-15 : la liste des cartes mises de cote, dans les reglages */
#set-ecartees{margin-top:var(--e-3);border-top:1px solid var(--line);padding-top:var(--e-3)}
.ecart-tete{display:flex;align-items:center;justify-content:space-between;font-size:var(--t-2)}
.ecart-tete span{font-size:var(--t-1);font-weight:800;color:var(--bg);background:var(--accent);
  border-radius:999px;padding:2px var(--e-2)}
.ecart-sous{color:var(--mut);font-size:var(--t-1);margin:var(--e-1) 0 var(--e-2);line-height:1.45}
.ecart-l{max-height:190px;overflow-y:auto;display:flex;flex-direction:column;gap:var(--e-2)}
.ecart-i{display:flex;align-items:center;gap:var(--e-2);font-size:var(--t-1);color:var(--dim);
  background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:var(--r-1);padding:var(--e-2) var(--e-2)}
.ecart-i span{flex:1;line-height:1.4}
.ecart-b{flex:none;font-size:var(--t-1);font-weight:700;color:var(--accent2);background:none;
  border:1px solid var(--line2);border-radius:999px;padding:var(--e-2) var(--e-2);cursor:pointer}
#wz-themes{justify-content:center}
/* reglages */
/* arbitrage 30/07 : l'en-tete est DANS LE FLUX (premier bloc de la pile de l'accueil, comme
   les rendus) et defile avec le contenu. Plus de position:fixed : la marque passait dessous
   des que la page defilait (Grand texte). */
/* [06/08] TOUTES LES COTES DE CE BOUTON ONT DEMENAGE dans `.hicobtn` (bloc de l'en-tete de
   l'accueil), qu'il partage maintenant avec le bouton de compte : le lot du 05/08 leur donne
   une meme boite de 28, et c'est elle qui touche la marge de 18 des deux cotes. Les 40/13/
   #1B1823/#3E3650 du 30/07 sont supprimes ici, PAS reecrits ailleurs en double.
   ⚠️ ON NE LES LAISSE PAS « au cas ou » : un selecteur d'ID pese (1,0,0) et aurait ecrase la
      classe en silence, sans qu'aucune erreur ne le dise. Une cote vit au seul endroit qui
      gagne, sinon elle se lit 28 et se livre 40.
   Ce qui reste ici est la seule chose qui lui soit propre : il ne s'affiche que sur l'accueil. */
#settings-btn{display:none}
body.show-sound #settings-btn{display:grid}
/* ⚠️⚠️ [11/08] LES DIX REGLES DE L'ANCIENNE FEUILLE DE REGLAGES SONT SUPPRIMEES (`.set-row`,
   `.set-l`, `.set-ico`, `.set-t`, `.switch`). Son balisage a ete remplace par le portage du
   rendu `reglages-rapides.html`, et PLUS AUCUN ELEMENT NE LES PORTE — verifie dans
   `index.html` ET dans `app.js`, y compris le balisage construit en JavaScript.
   ⚠️ C'EST LE CONTROLE CSS-03 QUI LES A DESIGNEES, et par un chemin qu'on n'attendait pas :
      `.set-ico` lisait `--c`, `--cb`, `--cl`, trois variables qui n'etaient declarees QUE
      dans l'attribut `style=` de l'ancien balisage. En le retirant, ces regles se sont mises
      a appeler des variables qui n'existent plus nulle part. UNE REGLE MORTE NE FAIT PAS
      D'ERREUR ; c'est sa dependance a un fantome qui l'a trahie. */
.btn.sec.danger{border-color:#ef4444;color:#fca5a5}
/* le bouton son ne doit pas etre l'element le plus attirant de l'accueil */
.hpc-ok{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--accent-ink)}
/* GRAND TEXTE (contrepartie du zoom bloque sur iOS). Refonte du 28/07, fiche nav-19.
   AVANT : une LISTE de neuf selecteurs re-declares un par un. Mesure au navigateur le 28/07 :
   sur 224 elements portant du texte, 49 changeaient de taille, soit 22 %. Les ecrans les plus
   lourds en lecture (les Classiques, les regles, les mini-jeux) n'etaient pas dans la liste, et
   toute regle ecrite plus tard naissait hors du mode. C'etait une liste a tenir a jour a la main,
   donc une liste fausse.
   MAINTENANT : un seul rapport pose sur la racine. Toutes les tailles du fichier sont en rem ou
   en em (les 19 dernieres valeurs en px ont ete converties le meme jour, a l'identique au pixel
   pres en mode normal), donc elles suivent toutes, y compris celles qui n'existent pas encore.
   Le rapport 1,1875 (16 -> 19 px) est proche des 1,214 de l'ancienne carte, sans les debordements
   qu'un rapport plus fort provoque sur les boutons a deux colonnes.
   UI-06 tient toujours : un rapport unique ne peut pas reduire un texte.
   NE PAS remettre de surcharge `body.bigtext ... {font-size}` ici : elle se MULTIPLIERAIT au
   rapport de la racine au lieu de le remplacer. */
html.bigtext{font-size:118.75%}
.reveal{width:auto;padding:var(--e-2) var(--e-3);font-size:var(--t-2);border-radius:var(--r-1);margin-top:2px}
.reveal.shown{border-color:var(--accent2);color:var(--accent2);font-weight:800;opacity:1}
.reveal:disabled{opacity:1}
/* classement des bilans : couronne au 1er, rang ensuite */
.rank-row{display:grid;grid-template-columns:38px 1fr auto;gap:var(--e-3);align-items:center;padding:var(--e-3) var(--e-3);border-bottom:1px solid var(--line)}
.rank-row:last-child{border-bottom:none}
.rank-row .rk{display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:var(--r-1);
  background:rgba(255,255,255,.06);border:1px solid var(--line2);color:var(--mut);font-weight:900;font-size:var(--t-2)}
.rank-row .rk svg{width:20px;height:20px;display:block}
.rank-row.first{background:linear-gradient(90deg,rgba(251,191,36,.16),transparent)}
.rank-row.first .rk{background:linear-gradient(135deg,#fbbf24,#f59e0b);border-color:transparent;color:#3a2600}
.rank-row.first .rw-t b{color:#fcd34d}
.rw-t{display:flex;flex-direction:column;align-items:flex-start;text-align:left;min-width:0}
.rw-t b{font-weight:800;font-size:var(--t-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rw-t i{font-style:normal;font-size:var(--t-1);color:var(--mut);margin-top:2px}
.rw-g{font-weight:900;color:var(--accent2);font-size:var(--t-2);white-space:nowrap}
.rank-sub{text-align:center;margin:var(--e-3) 0 -6px}

/* ===== V1.3 : hierarchie de la carte + aide contextuelle ===== */
/* 1) la carte : une seule info mise en avant (QUI), le type de carte redevient un label discret */
.g-turn{margin-bottom:var(--e-2)}
.gt-chip{display:inline-flex;align-items:center;gap:var(--e-2);padding:var(--e-2) var(--e-3);border-radius:999px;
  background:rgba(255,255,255,.07);border:1px solid var(--line2);color:var(--dim);
  font-size:var(--t-2);font-weight:700;letter-spacing:0;text-transform:none}
.gt-chip b{color:var(--ink);font-weight:900}
.gt-chip.all{background:rgba(192,132,252,.14);border-color:rgba(192,132,252,.4)}
.gt-chip.all b{color:var(--accent2)}
/* .68rem = 10,88 px, sous le plancher de 12 px pose pour le micro-texte. Mesure du 28/07 : en
   balayant TOUS les textes de l'ecran de jeu, ce libelle etait le SEUL a passer dessous. Son
   contraste, lui, est bon (5,29:1) : c'est la taille seule qu'il fallait corriger. Effet de bord
   verifie : hauteur de la carte inchangee a 412 px, aucun debordement. */
.tag{color:var(--mut);font-size:var(--t-1);letter-spacing:.18em;margin-bottom:-12px}
.gamecard{gap:var(--e-3)}
/* 2) bouton "?" : un seul composant, decline selon le contexte */
.helpbtn{line-height:1;padding:0;width:2.1em;height:2.1em;min-width:2.1em;border-radius:50%;background:rgba(255,255,255,.06);
  border:1px solid var(--line2);color:var(--dim);font:inherit;font-weight:900;font-size:var(--t-2);line-height:1;
  cursor:pointer;padding:0;display:inline-flex;align-items:center;justify-content:center;flex:none}
/* UI-09 : la pastille reste a 30 px pour ne pas deformer les titres, mais la zone qui repond
   au doigt fait 44 px. Mesure du 27/07 : elle n'en faisait que 30, soit la moitie de la cible. */
.helpbtn{position:relative}
.helpbtn::after{content:"";position:absolute;top:50%;left:50%;width:44px;height:44px;
  transform:translate(-50%,-50%)}
.helpbtn:active:not(.enfonce){transform:scale(.92)}
.helpbtn-h{vertical-align:middle;margin-left:8px;transform:translateY(-2px)}
.helpbtn-top{width:42px;height:42px;border-radius:var(--r-1);background:var(--card);color:var(--accent2)}
.helpbtn-mode{position:absolute;right:14px;top:50%;transform:translateY(-50%);width:34px;height:34px;
  background:rgba(255,255,255,.07);color:var(--accent2);border-color:var(--line2);z-index:2}
.helpbtn-mode:active:not(.enfonce){transform:translateY(-50%) scale(.92)}
.mode-wrap{position:relative;display:flex}
.mode-wrap .mode{flex:1;padding-right:var(--e-7)}
.mode-wrap .mode::after{content:none}
/* le "?" d'une tuile prend la couleur du jeu : on voit tout de suite a quoi il se rapporte */
.tile-help{background:rgba(0,0,0,.45);color:var(--gcol,var(--accent2));border:1.5px solid var(--gcol,var(--line2));
  box-shadow:0 0 12px -4px var(--gcol,transparent)}
.tile-help:active:not(.enfonce){transform:scale(.9)}
/* 3) "Qui joue ?" : un reglage, pas un mode de jeu */
.home-players-card{background:transparent;border:1px dashed var(--line2);border-radius:var(--r-2);margin:var(--e-4) 0 var(--e-3)}
.home-players-card.open{background:var(--card);border-style:solid}
.hpc-head{padding:var(--e-3) var(--e-3);gap:var(--e-2)}
.hpc-head b{font-size:var(--t-2);font-weight:700;color:var(--dim)}
.home-players-card.open .hpc-head b{color:var(--ink)}
.hpc-ico{flex:none;width:22px;height:22px;color:var(--mut);display:flex}
.hpc-ico svg{width:100%;height:100%}
.hpc-count{font-size:var(--t-1);padding:var(--e-1) var(--e-2)}
.hpc-chev{font-size:var(--t-3);color:var(--mut)}

/* ===== V1.4 : ecran de fin commun (Soiree / Chacun son tour / Defi) ===== */
.sum-hero{position:relative;overflow:hidden;text-align:center;padding:var(--e-4) var(--e-4) var(--e-4);margin-bottom:var(--e-3);
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-3);box-shadow:0 18px 44px rgba(0,0,0,.42)}
.sum-hero::before{content:"";position:absolute;inset:0;background:radial-gradient(120% 62% at 50% 0%,var(--accent),transparent 62%);opacity:.2;pointer-events:none}
.sum-hero.gold::before{background:radial-gradient(120% 62% at 50% 0%,#fbbf24,transparent 62%);opacity:.16}
.sum-hero>*{position:relative;z-index:1}
.sum-ico{width:62px;height:62px;margin:0 auto var(--e-2);color:var(--accent2);filter:drop-shadow(0 0 16px var(--accent))}
.sum-hero.gold .sum-ico{color:#fbbf24;filter:drop-shadow(0 0 18px rgba(251,191,36,.55))}
.sum-ico svg{width:100%;height:100%;display:block}
.sum-kick{font-size:var(--t-1);font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:var(--mut)}
.sum-big{font-size:clamp(2rem,10vw,3rem);font-weight:900;line-height:1.05;margin:var(--e-1) 0 var(--e-2);word-break:break-word;
  background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.sum-hero.gold .sum-big{background-image:linear-gradient(90deg,#fde68a,#fbbf24 55%,#f59e0b)}
.sum-sub{color:var(--dim);font-size:var(--t-2);line-height:1.35;max-width:30ch;margin:0 auto}
.sum-list{margin-top:0}
.sum-foot{margin-top:var(--e-3);text-align:center;color:var(--mut);font-size:var(--t-1);line-height:1.45;padding:0 var(--e-2)}
#s-defi .defi-board+.defi-board{margin-top:var(--e-2)}

/* ===== V1.5 : ecran d'age (premiere impression, vu une seule fois) ===== */
#s-age{justify-content:flex-start;background:radial-gradient(125% 70% at 50% 0%,rgba(139,92,246,.34),transparent 60%),radial-gradient(125% 60% at 50% 100%,rgba(236,72,153,.2),transparent 60%),#15121e}
.age-logo{width:74px;height:74px;color:var(--accent2);margin-bottom:var(--e-3);filter:drop-shadow(0 0 22px rgba(139,92,246,.65))}
.age-logo svg{width:100%;height:100%;display:block}
/* 01-entree-21 : "TRINKE" changeait de peinture entre la porte d'age et l'accueil, a une
   seconde d'intervalle : la porte avait sa propre couleur au lieu du degrade de marque. La
   classe .brand-xl porte deja le degrade ; ici on ne regle QUE la taille. Un seul logo. */
.age-brand{font-size:clamp(2.6rem,13vw,4rem)}
.age-legal{display:flex;align-items:flex-start;gap:var(--e-3);text-align:left;margin-top:var(--e-4);padding:var(--e-3) var(--e-3);
  background:rgba(255,255,255,.05);border:1px solid var(--line2);border-radius:var(--r-2);max-width:34ch}
.age-legal p{color:var(--mut);font-size:var(--t-1);line-height:1.45}
/* arbitrage 30/07 : plus de rouge (reserve a l'irreversible) — meme traitement que la
   pastille 18+ de la mention legale de l'accueil : rectangle, encre claire, filet */
.age-badge{flex:none;display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;border-radius:var(--r-1);
  background:none;border:1.6px solid #6E6485;color:var(--c-texte-2);font-weight:700;font-size:var(--t-2);letter-spacing:-.02em}
/* LA PORTE D'AGE TIENT SUR UN PETIT ECRAN (nav-8 / 01-entree-4, 28/07).
   Son contenu mesure 646 px : sous 600 px de hauteur, le bouton "J'ai 18 ans" passe sous la
   ligne de flottaison. L'ecran defile, mais c'est justement celui ou personne ne pense a faire
   defiler : rien n'annonce qu'il y a un bouton plus bas, et c'est la premiere chose que voit
   quelqu'un qui ouvre l'app. Le seuil de 600 px n'est pas theorique : un iPhone SE en paysage,
   un Android avec clavier ouvert ou une fenetre de navigateur reduite y tombent.
   RIEN N'EST RETIRE : le logo, la mention legale et les deux boutons restent tous la, tout se
   resserre. En dessous de 500 px, la mention legale garde sa taille de lecture, on rogne
   seulement les espaces : un texte legal ne se rapetisse pas. */
@media (max-height:600px){
  #s-age .age-logo{width:52px;height:52px;margin-bottom:var(--e-2)}
  #s-age .age-brand{font-size:clamp(2rem,10vw,2.8rem)}
  #s-age .home-tag{margin:var(--e-2) 0}
  #s-age .home-stats{margin:var(--e-2) 0}
  #s-age .age-legal{margin-top:var(--e-3);padding:var(--e-2) var(--e-3);gap:var(--e-2)}
  #s-age .age-badge{width:34px;height:34px}
  #s-age .bottom{padding-top:var(--e-2)}
}
@media (max-height:500px){
  #s-age .age-logo{display:none}   /* le calice, seul element purement decoratif de l'ecran */
  #s-age .home-stats{display:none} /* les trois compteurs sont repetes tels quels sur l'accueil */
  #s-age .age-legal{margin-top:var(--e-2)}
}
/* UI-16 : le refus d'age portait .btn.ghost, seul bouton de l'application sans fond ni bordure,
   alors qu'il porte l'une des deux seules reponses possibles de l'ecran. Il doit rester visible
   et visable sans devenir un appel a l'action : bordure et taille reduite, pas de fond.
   Classe DEDIEE et non .btn.ghost, qui sert aussi au bouton Annuler d'une autre fenetre. */
/* GD-38 : les paliers de parcours. Une barre par palier, remplie ou non : on voit d'un coup
   ou l'on en est et combien il reste, ce que douze interrupteurs binaires ne disaient pas. */
.pal-l{display:flex;flex-direction:column;gap:var(--e-2)}
.pal{background:var(--card);border:1px solid var(--line);border-radius:var(--r-1);padding:var(--e-2) var(--e-3)}
.pal-h{display:flex;align-items:baseline;gap:var(--e-2)}
.pal-h b{flex:1;font-size:var(--t-2)}
.pal-h span{font-size:var(--t-2);color:var(--accent2);font-weight:800}
.pal-b{display:flex;gap:var(--e-1);margin:var(--e-2) 0 var(--e-1)}
.pal-b i{flex:1;height:5px;border-radius:var(--r-1);background:rgba(255,255,255,.10)}
.pal-b i.on{background:linear-gradient(90deg,var(--accent),var(--accent2))}
.pal-s{font-size:var(--t-1);color:var(--mut)}

/* GD-40 : le record de la table. Sous le titre du jeu avant de jouer, et en pastille au verdict
   quand il vient d'etre battu. Ton sobre : c'est un fait de groupe, pas un trophee personnel. */
.turn-record{margin-top:var(--e-2);font-size:var(--t-1);color:var(--dim);text-align:center;line-height:1.4}
.rec-table{display:inline-block;margin-top:var(--e-2);padding:var(--e-1) var(--e-3);border-radius:999px;
  background:rgba(251,191,36,.16);border:1px solid rgba(251,191,36,.4);color:#fcd34d;
  font-size:var(--t-1);font-weight:800}

/* GD-58 : le QR sous le tableau du bilan. Fond blanc obligatoire et marge conservee : un
   lecteur a besoin du contraste et de la zone calme autour du code. */
.qr-bloc{margin-top:var(--e-3);text-align:center}
.qr-t{font-size:var(--t-2);color:var(--dim);margin-bottom:var(--e-2)}
.qr-bloc svg{border-radius:var(--r-1);display:inline-block}
.qr-u{font-size:var(--t-micro);color:var(--mut);margin-top:var(--e-2);letter-spacing:.06em;font-weight:700}

/* GD-28 : la dose annoncee, sous le choix de duree. Ton neutre, jamais alarmiste ni
   encourageant : c'est un fait pour choisir, pas un objectif a atteindre. */
.wiz-dose{margin-top:var(--e-2);text-align:center;font-size:var(--t-2);color:var(--dim);line-height:1.5}

/* IN-14 : le geste a faire sur iPhone, ou l'installation ne peut pas etre automatisee. */
.inst-geste{margin-top:var(--e-3);padding:var(--e-2) var(--e-3);border-radius:var(--r-1);background:rgba(255,255,255,.05);
  border:1px solid var(--line);font-size:var(--t-2);color:var(--dim);line-height:1.5}
.inst-geste b{color:var(--ink)}

/* [01/08] GD-49 : la liste des mini-jeux des Reglages est supprimee (vague Mini-jeux, la
   selection vit par partie dans les avances de la serie) ; ses styles .mj-* partent avec. */

/* UI-68 : inviter un ami. Bouton a contour, pas plein : c'est une porte de sortie utile, pas
   l'action principale de l'ecran. Passe au vert quand le lien est parti ou copie, 1,8 s. */
.am-inviter{display:block;width:100%;min-height:44px;margin-top:var(--e-3);padding:var(--e-2) var(--e-3);
  background:transparent;border:1px dashed var(--line2);color:var(--dim);border-radius:var(--r-1);
  font:inherit;font-size:var(--t-2);font-weight:700;cursor:pointer;transition:color .15s,border-color .15s}
.am-inviter:active{transform:scale(.98)}
.am-inviter.ok{color:#4ade80;border-color:rgba(74,222,128,.5);border-style:solid}

/* UI-56 : le record de la tablee sur l'accueil. Discret et informatif, pas un trophee : il dit
   ce que le groupe a deja fait de mieux, et le mieux est de boire MOINS. Aucune couleur de
   victoire, aucun nom : il appartient a la table. */
/* 02-choix-4 : l'entree discrete du jeu a distance, sous le grand Jouer.
   Meme grammaire que les cartes voisines (radius, fond, bordure, police), texte centre
   pour la rattacher a Jouer et non aux lignes de navigation. */
.home-distance{width:100%;margin:var(--e-2) 0 0;background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);
  padding:var(--e-2) var(--e-3);color:var(--ink);cursor:pointer;text-align:center;font-family:inherit}
/* Statistiques n'appartient pas au groupe Jouer / A distance : 24 px de respiration */
#home-stats:not(:empty){margin-top:var(--e-4)}
.home-distance b{font-weight:800;font-size:var(--t-2)}
.home-distance span{display:block;color:var(--dim);font-size:var(--t-1);margin-top:2px}
.home-record{width:100%;margin:var(--e-2) 0 0;padding:var(--e-2) var(--e-3);border-radius:var(--r-2);
  background:rgba(255,255,255,.05);border:1px solid var(--line);text-align:left}
.home-record b{display:block;font-size:var(--t-1);font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut);margin-bottom:2px}
.home-record span{font-size:var(--t-2);color:var(--dim)}

/* UI-29 : le bandeau d'annulation apres retrait d'un trinkeur. Ambre et non rouge : rien n'est
   detruit tant qu'il est la, il annonce une action reparable. Le bouton fait 44 px de haut. */
.jr-undo{display:flex;align-items:center;gap:var(--e-2);margin-top:var(--e-2);padding:var(--e-2) var(--e-3);
  background:rgba(251,191,36,.12);border:1px solid rgba(251,191,36,.35);border-radius:var(--r-1);
  font-size:var(--t-2);color:#fcd34d}
.jr-undo span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jr-undo button{flex:none;min-height:44px;padding:0 var(--e-3);border-radius:var(--r-1);border:0;
  background:#fbbf24;color:#2a1c00;font:inherit;font-weight:800;cursor:pointer}
.jr-undo button:active{transform:scale(.97)}

/* UI-40 : le compteur de manches porte la seule information de POSITION du jeu, et il etait en
   .mut, le gris le plus faible de l'application. La fiche annoncait 3,84:1 ; mesure du 27/07
   apres la correction de --mut, il etait deja a 5,81:1, donc au-dessus du seuil AA. On le monte
   quand meme a --dim (7,03:1) et 14 px : discret, mais lisible d'un coup d'oeil au milieu d'une
   soiree, ce qui est tout ce qu'on lui demande. */
.hud-compte{font-size:var(--t-2);color:var(--dim);font-weight:600}

/* IN-04 : mention discrete sur les deux ecrans les plus photographies (carte et bilan).
   Taille prise sur le jeton --t-micro : le plancher de 12 px de UI-04 s'applique aussi ici. */
.marque{font-size:var(--t-micro);color:var(--mut);opacity:.6;text-align:center;
  letter-spacing:.10em;margin-top:var(--e-2);font-weight:700}
.age-non{background:transparent;border:1px solid var(--line2);color:var(--dim);font-weight:700;
  font-size:var(--t-2);height:48px;padding:0 var(--e-3);width:100%;margin:var(--e-2) auto 0;border-radius:var(--r-2)}  /* [26/10, Romain] « même largeur pour les deux » : 60 % donnait 215 px sous un bouton de 358 */
.age-non:active:not(.enfonce){transform:none;opacity:.7}
.btn.ghost{background:transparent;border:none;color:var(--mut);font-weight:700;font-size:var(--t-2);padding:var(--e-3);margin-top:var(--e-2)}
.btn.ghost:active:not(.enfonce){transform:none;opacity:.7}
.age-trust{text-align:center;margin-top:var(--e-2);font-size:var(--t-1)}

/* ===== V1.6 : zones sures iOS (app installee, viewport-fit=cover) =====
   Le contenu passait SOUS la barre d'etat et l'ile dynamique : chaque conteneur
   qui touche un bord de l'ecran reserve desormais l'encoche. */
/* ⚠️ LA DECLARATION DE REPLI VIENT D'ABORD, ET C'EST ELLE LA VRAIE PROTECTION. Un moteur
   qui ne connait pas `env()` ne jette pas la fonction, il jette la DECLARATION ENTIERE :
   sans la ligne qui precede, le rembourrage tomberait alors a zero et le contenu toucherait
   les bords. Une premiere ecriture en valeurs simples survit, la seconde la remplace partout
   ou `env()` est compris.
   ⚠️ LE DOSSIER DE LA VUE LISTE DEMANDE `max(env(...), 20px)` AVEC UNE RAISON INEXACTE :
      il ecrit que sans le max, « sur un moteur qui ignore env(), la marge tombe a zero ».
      C'est faux, `max()` ne sauve rien dans ce cas puisque son argument reste inconnu. Et
      l'appliquer nous ferait REGRESSER : `calc(22px + env)` garantit deja les 22 px et y
      AJOUTE l'encoche, la ou `max(env, 20px)` prendrait le plus grand des deux, donc 34 au
      lieu de 56 sur une app installee. Notre ecriture est la meilleure des deux ; ce qui
      manquait vraiment est la ligne de repli. */
/* ══════════════════════════════════════════════════════════════════════════════
   [07/08, ordre de Theo : « cela doit etre pareil que sur mes rendus, point »]
   LE BORD DES ECRANS PASSE DE 22 A 18, LA VALEUR DE TOUS LES RENDUS.

   MESURE QUI A DECLENCHE LA CORRECTION, captures a l'appui : a 390 de large, une carte
   faisait **354 px sur le rendu et 346 chez nous** — 4 px de marge en trop de chaque
   cote, sur tous les ecrans a la fois.

   ⚠️⚠️ CE N'ETAIT PAS UNE DECOUVERTE, ET C'EST TOUT LE PROBLEME : l'ecart est signale
      a CHAQUE portage depuis le 31/07 (« adaptations habituelles : marges d'ecran 22
      du projet, le rendu pose 18 »), assume a chaque fois comme une convention maison,
      et jamais regarde a l'ecran. **Un ecart repete assez souvent finit par passer
      pour une regle.** Theo l'a vu en comparant ; huit portages ne l'avaient pas vu.

   ⚠️ ET IL PASSE PARTOUT, PAS SEULEMENT SUR LA FAMILLE COMPTE. Ma premiere correction
      ne visait que les ecrans de ce lot : elle aurait cree DEUX bords dans l'app,
      visibles au premier aller-retour entre le Compte et le Classement. Corriger un
      ecart en creant une exception, c'est deplacer le probleme.

   ⚠️ CE QUE CA ELARGIT : chaque carte gagne 8 px. Aucune hauteur ne s'en trouve
      augmentee — un texte dans une boite plus large tient sur autant ou moins de
      lignes, jamais plus. Les hauteurs calees au pixel (accueil a 714 pile, fiches de
      reglages) sont remesurees apres coup, pas supposees.
   ══════════════════════════════════════════════════════════════════════════════ */
.screen{padding:var(--e-3)}
.screen{padding:calc(var(--e-3) + env(safe-area-inset-top,0px)) var(--e-3) calc(var(--e-3) + env(safe-area-inset-bottom,0px))}
.screen.nopad{padding:0}
.screen.nopad>.topbar{padding:calc(var(--e-3) + env(safe-area-inset-top,0px)) var(--e-3) var(--e-2)}
.screen.nopad>.bottom{padding:var(--e-3) var(--e-3) calc(var(--e-3) + env(safe-area-inset-bottom,0px))}
.screen.nopad>p,.screen.nopad>.score{padding-left:var(--e-3);padding-right:var(--e-3)}
/* [02/08] fusion des ecrans d'entree : s-arcade et s-classics n'existent plus, leurs grilles
   vivent dans les lanceurs (padding d'ecran standard 22px, plus de rattrapage a 16). */
#s-wiz,#s-game,#s-classic-run{padding-left:0;padding-right:0}
#s-wiz>.topbar,#s-game>.topbar,#s-classic-run>.topbar{padding-left:var(--e-4);padding-right:var(--e-4)}
/* [08/08] `:is(#s-game,#s-classic-run) .jn-paquet>.gamecard` AJOUTE, ET CE N'EST PAS UN DOUBLON : la carte de
   la Soiree est desormais enveloppee de deux conteneurs (voir le bloc « Je n'ai jamais » en
   fin de fichier), donc elle n'est plus enfant DIRECT de l'ecran et le selecteur d'a cote ne
   l'atteint plus. Sans cette ligne, les six types de carte non concernes par le rendu du
   07/08 perdraient leurs 22 px de marge laterale. */
#s-game>.progress,#s-game>.gamecard,:is(#s-game,#s-classic-run) .jn-paquet>.gamecard,#s-game>.bottom,#s-classic-run>.gamecard,#s-classic-run>.bottom{margin-left:22px;margin-right:22px}
#menu-btn{top:calc(env(safe-area-inset-top,0px) + 12px)}
#mini-timer{top:calc(env(safe-area-inset-top,0px) + 56px)}
.sheet{padding-bottom:calc(var(--e-4) + env(safe-area-inset-bottom,0px))}
/* bouton de lancement d'un mini-jeu : centre sous le visuel, jamais colle en bas */
.screen.cta-mid>.bottom{padding-top:var(--e-4)}

/* actions du menu : rouge = on detruit la partie, vert = on valide (paire semantique) */
#menu-end{background:rgba(239,68,68,.14);border-color:rgba(239,68,68,.55);color:#fca5a5;font-weight:800}
#menu-end:active{background:rgba(239,68,68,.24)}
.hpc-ok{background:linear-gradient(90deg,#16a34a,#22c55e);color:#06130a;font-weight:800;border:none}
.hpc-ok:disabled{opacity:.45}
.wiz-group+.wiz-group{margin-top:var(--e-4)}
.wiz-group .wiz-h2{margin-top:0}
/* Trouve l'intrus : la case a trouver se montre quand le temps est ecoule */
.icell.dimmed{opacity:.22;transition:opacity .25s}
.icell.reveal{background:linear-gradient(180deg,#4c1414,#2a0d0d);border-color:#ef4444;color:var(--c-texte);
  box-shadow:0 0 0 3px rgba(239,68,68,.45),0 0 26px rgba(239,68,68,.55);animation:icellReveal .7s ease-in-out infinite alternate;z-index:2}
@keyframes icellReveal{from{transform:scale(1)}to{transform:scale(1.16)}}
@media(prefers-reduced-motion:reduce){.icell.reveal{animation:none}}
.pc-hint{display:inline-block;margin-top:var(--e-2);font-size:var(--t-1);color:var(--mut)}

/* ===== Profil : statistiques a vie et badges (lot 0) ===== */
/* Les deux entrees de l'accueil : de vraies cartes, pas des pointilles qui font "desactive".
   Meme matiere que les cartes de mode, en plus discret que le bouton Jouer. */
.home-line{width:100%;display:flex;align-items:center;gap:var(--e-3);background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3);margin:0 0 var(--e-2);color:var(--ink);font:inherit;cursor:pointer;text-align:left;
  transition:transform .1s,border-color .12s}
/* les deux cartes de l'accueil partagent le meme trait violet a gauche ET en bas : c'est ce
   trait qui leur donne du relief. Il ne vaut que pour l'accueil. */
.home-line{border-left:3px solid var(--accent);border-bottom:3px solid var(--accent)}
#home-stats .cp-grp{border-bottom:3px solid var(--gcol,var(--accent))}
.home-line b{flex:1;font-size:var(--t-2);font-weight:800;color:var(--ink)}
.home-line .hpc-ico{width:24px;height:24px;color:var(--accent2)}
.home-line .hpc-chev{color:var(--dim);font-size:var(--t-4)}
.home-line:active:not(.enfonce){transform:scale(.985);border-color:var(--accent)}
/* (marge de l'ancien accueil retiree le 30/07 : la rangee est rythmee par l'intitule
   de territoire au-dessus d'elle, pas par une marge propre) */
.prof-scroll{flex:1;overflow-y:auto;padding:var(--e-2) var(--e-1) var(--e-4)}
.prof-row{width:100%;text-align:left;background:none;border:none;border-bottom:1px solid var(--line);font:inherit;cursor:pointer}
.prof-row .rk{background:linear-gradient(135deg,var(--accent),var(--accent2));border-color:transparent;color:#160f22}
.prof-row .rw-g{color:var(--mut);font-size:var(--t-4)}
.badge-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin-top:var(--e-2)}
.badge{background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-3);opacity:.45}
.badge.on{opacity:1;border-color:rgba(251,191,36,.5);background:linear-gradient(160deg,rgba(251,191,36,.12),transparent),var(--card)}
.badge b{display:block;font-size:var(--t-2);font-weight:800}
.badge.on b{color:#fcd34d}
.badge span{display:block;margin-top:var(--e-1);font-size:var(--t-1);color:var(--mut);line-height:1.3}

/* ===== Compte : creation, code, connexion ===== */
#set-compte{display:flex;align-items:center}
.cp-dispo{margin-top:var(--e-2);text-align:center;min-height:1.2em}
.cp-dispo.ok{color:#4ade80}
.cp-dispo.ko{color:#f87171}
.code-box{margin:var(--e-3) 0 var(--e-3);padding:var(--e-3) var(--e-3);text-align:center;border-radius:var(--r-2);background:rgba(251,191,36,.1);
  border:1px dashed rgba(251,191,36,.55);color:#fcd34d;font-weight:900;font-size:var(--t-4);letter-spacing:.06em;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-all}
.cp-check{display:flex;align-items:center;gap:var(--e-2);margin-top:var(--e-3);color:var(--dim);font-size:var(--t-2)}
.cp-check input{width:20px;height:20px;accent-color:#22c55e}
/* ⚠️⚠️ [07/08, Theo captures a l'appui : « l'espace entre le bord de mon ecran et le
   bord des cases est enorme »] LES DEUX BORDS S'ADDITIONNAIENT. `.screen` en posait un
   (22, puis 18 depuis v534) et CE BLOC en remettait 18 par-dessus : les cartes du Compte
   vivaient donc a 36 ou 40 px du bord, contre 18 sur le rendu.
   ⚠️ C'EST CE QUI A FAIT ECHOUER MA CORRECTION PRECEDENTE. J'ai mesure la largeur
      DISPONIBLE de l'ecran (354 px, exacte) et conclu que c'etait regle — sans regarder
      la largeur des CARTES, qui vivent un cran plus bas et perdaient encore 36 px.
      **Mesurer le contenant ne dit rien du contenu quand un second rembourrage
      s'intercale.** Theo l'a vu tout de suite ; ma mesure disait le contraire.
   ⚠️ LE BORD HORIZONTAL PASSE DONC A ZERO ICI : il appartient a l'ECRAN, un seul objet
      le porte. Le haut et le bas restent, ils ne font double emploi avec rien. */
#cp-body{padding:var(--e-2) 0 var(--e-4)}

/* ===== bouton Compte : en haut a DROITE, a l'oppose des reglages ===== */
/* meme famille de contour que l'engrenage (TRINKE.md §4) : une forme carree, une forme ronde.
   Dans le flux comme l'engrenage (arbitrage 30/07). */
/* [05/08] LES REGLES DU BOUTON COMPTE DE L'EN-TETE SONT SUPPRIMEES. L'element a quitte
   l'accueil le 04/08 (il doublait l'onglet Profil) mais ses dix regles etaient restees :
   du CSS sans porteur, exactement la faute que j'avais invoquee le meme jour pour retirer
   celles de la carte Multijoueur. La pastille des demandes vit desormais sur .ong-dot. */

/* amis a ajouter d'un geste comme trinkeurs de la soiree */
.hp-ami{background:transparent;border:1px dashed var(--line2);color:var(--dim);font:inherit;font-size:var(--t-2);font-weight:700;
  border-radius:999px;padding:var(--e-2) var(--e-3);margin:0 6px var(--e-2) 0;cursor:pointer}
.hp-ami:active:not(.enfonce){transform:scale(.97)}
.hp-lie{font-style:normal;font-size:var(--t-1);font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  color:var(--accent-ink);background:linear-gradient(90deg,var(--accent),var(--accent2));border-radius:999px;padding:2px var(--e-2);margin-left:2px}

/* ---------- Menu du compte : des rubriques qu'on deplie ---------- */
.cp-tete{display:flex;align-items:center;gap:var(--e-3);background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-3);padding:var(--e-3) var(--e-3);margin-bottom:var(--e-3)}
.cp-tete .cl-av{width:46px;height:46px;font-size:var(--t-3);position:relative}
/* la meme pastille de presence que chez les amis, posee sur mon propre rond */
.cp-tete .cl-av .fr-etat{width:13px;height:13px;border:2px solid var(--card);right:0;bottom:0}
.cp-tete-t{display:flex;flex-direction:column;min-width:0}
.cp-tete-t i{font-style:normal;font-size:var(--t-1);font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:var(--mut)}
.cp-tete-t b{font-size:var(--t-4);font-weight:900;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* chaque rubrique porte sa couleur : liseré à gauche, icône, et teinte quand elle est ouverte */
.cp-grp{background:var(--card);border:1px solid var(--line2);border-left:3px solid var(--gcol,#8b5cf6);
  border-radius:var(--r-2);margin-bottom:var(--e-3);overflow:hidden;transition:border-color .15s}
.cp-grp.on{border-color:var(--line2);border-left-color:var(--gcol,#8b5cf6);
  background:linear-gradient(180deg,color-mix(in srgb,var(--gcol,#8b5cf6) 13%,transparent),transparent 78%),var(--card)}
.cp-grp-h{width:100%;display:flex;align-items:center;gap:var(--e-3);background:none;border:none;color:var(--ink);
  font:inherit;padding:var(--e-3) var(--e-3);cursor:pointer;text-align:left}
.cp-grp-h b{flex:1;font-size:var(--t-3);font-weight:800}
.cp-grp-ico{flex:none;width:26px;height:26px;color:var(--gcol,#8b5cf6);display:flex}
.cp-grp-ico svg{width:100%;height:100%}
.cp-grp .hpc-chev{transition:transform .2s}
.cp-grp.on .cp-grp-h .hpc-chev{transform:rotate(90deg)}
/* le depliant : padding sur le conteneur, jamais de marges sur des enfants en width:100%
   (sinon les entrees debordent de la carte) */
.cp-grp-b{max-height:0;overflow:hidden;transition:max-height .25s ease,padding .25s ease;padding:0 var(--e-3)}
.cp-grp.on .cp-grp-b{max-height:660px;padding:0 var(--e-3) var(--e-1)}
.cp-grp-b>*:last-child{margin-bottom:var(--e-2)}
.cp-item{width:100%;display:flex;align-items:center;gap:var(--e-2);background:rgba(255,255,255,.04);
  border:1px solid var(--line);border-radius:var(--r-1);padding:var(--e-3) var(--e-3);margin-bottom:var(--e-2);color:var(--ink);
  font:inherit;text-align:left;cursor:pointer}
.cp-item b{font-size:var(--t-2);font-weight:800;display:block}
.cp-item .cp-act-t{flex:1;min-width:0}
.cp-item .cp-act-t>span{display:block;color:var(--dim);font-size:var(--t-1);margin-top:1px}
.cp-item:active:not(.enfonce){transform:scale(.99);border-color:var(--gcol,var(--accent))}
.cp-item.danger b{color:#f87171}

.cp-item-ico{flex:none;width:22px;height:22px;color:var(--gcol,var(--accent));opacity:.85;display:flex}
.cp-item-ico svg{width:100%;height:100%}
.cp-item.danger .cp-item-ico{color:#f87171;opacity:1}
/* [08/08] `.cp-seul` RETIREE : son seul porteur etait la rangee « Legal et donnees » de
   l'ecran sans compte, remplacee par la ligne de mentions du composant verrouille. Une
   regle CSS dont l'element disparait se retire — sinon la feuille garde des dessins dont
   plus personne ne sait s'ils sont morts ou seulement en sommeil. */

/* ---------- Changer de pseudo : on voit l'avant et l'apres, en direct ---------- */
.ps-prev{display:grid;grid-template-columns:1fr 30px 1fr;align-items:center;gap:var(--e-1);
  background:var(--card);border:1px solid var(--line2);border-radius:var(--r-3);padding:var(--e-3) var(--e-2)}
.ps-side{display:flex;flex-direction:column;align-items:center;gap:var(--e-2);min-width:0;width:100%}
.ps-side i{font-style:normal;font-size:var(--t-1);font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:var(--mut)}
.ps-side b{max-width:100%;font-size:var(--t-2);font-weight:900;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ps-side .cl-av{width:52px;height:52px;font-size:var(--t-4)}
.ps-side.neuf .cl-av{box-shadow:0 0 22px rgba(139,92,246,.45)}
.ps-side.vide .cl-av{background:none;border:2px dashed var(--line2);color:var(--mut);box-shadow:none}
.ps-side.vide b{color:var(--mut);font-weight:700}
.ps-arw{text-align:center;color:var(--mut);font-size:var(--t-3);font-weight:900}
/* l'etat du pseudo tape : une pastille de couleur + une phrase, jamais un gris perdu */
.ps-etat{display:flex;align-items:center;justify-content:center;gap:var(--e-2);min-height:22px;margin-top:var(--e-3);
  font-size:var(--t-2);font-weight:700;color:var(--dim)}
.ps-etat .pt{flex:none;width:9px;height:9px;border-radius:50%;background:var(--line2)}
.ps-etat.wait .pt{background:#fbbf24;animation:psPulse 1s ease-in-out infinite}
.ps-etat.ok{color:#4ade80}
.ps-etat.ok .pt{background:#4ade80;box-shadow:0 0 10px rgba(74,222,128,.65)}
.ps-etat.ko{color:#f87171}
.ps-etat.ko .pt{background:#f87171}
@keyframes psPulse{0%,100%{opacity:.3}50%{opacity:1}}
/* les listes "ce qui te suit" / "ce que tu perds" : une idee par ligne, marquee par un signe */
.ps-l{list-style:none;margin:0;padding:0;background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-2);overflow:hidden}
/* PAS de flex ici : en flex, un <b> au milieu d'une phrase devient un item separe et le texte
   se casse en colonnes (constate sur "Un lien envoye a th...@gmail.com"). Le marqueur est donc
   pose en absolu et la ligne reste un texte normal, qui se coupe la ou il faut. */
.ps-l li{position:relative;display:block;padding:var(--e-2) var(--e-3) var(--e-2) var(--e-5);font-size:var(--t-2);line-height:1.45;
  color:var(--ink);border-bottom:1px solid var(--line)}
.ps-l li:last-child{border-bottom:none}
.ps-l li::before{content:"✓";position:absolute;left:14px;top:11px;font-weight:900;color:#4ade80;
  line-height:1.45}
.ps-l.perte li::before{content:"×";color:#f87171;font-weight:750;font-size:var(--t-4);top:5px}
/* le meme marqueur, repris a droite du titre de la section : l'oeil fait le lien
   entre le titre et la liste sans avoir a lire. */
.jr-sec .sec-s{margin-left:8px;font-size:var(--t-2);vertical-align:-1px}
.jr-sec .sec-s.perte{color:#f87171;font-size:var(--t-3);font-weight:750;vertical-align:-1px}
.jr-sec .sec-s.garde{color:#4ade80}
.ps-l.regles li{color:var(--dim)}
.ps-l.regles li::before{content:"•";color:var(--accent2)}

/* actions du compte : de vrais boutons pleine largeur, chacun menant a sa page d'avertissement */
.cp-act{width:100%;display:flex;align-items:center;gap:var(--e-3);background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3);margin-bottom:var(--e-2);color:var(--ink);font:inherit;text-align:left;cursor:pointer;
  transition:transform .1s,border-color .12s}
.cp-act .cp-act-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.cp-act b{font-size:var(--t-2);font-weight:800}
.cp-act span span,.cp-act .cp-act-t>span{color:var(--dim);font-size:var(--t-2);line-height:1.4}
.cp-act:active:not(.enfonce){transform:scale(.985);border-color:var(--accent)}
/* une pastille dans un bouton d'action reste DANS le bouton (sinon elle se pose sur l'en-tete) */
.cp-act .jr-tag{position:static;flex:none;margin-left:auto}
.cp-act.danger b{color:#f87171}
.cp-act.danger{border-color:rgba(248,113,113,.3)}
.cp-act.danger:active{border-color:#f87171}

/* ---------- Amis ---------- */
.fr-sec{display:flex;align-items:center;gap:var(--e-2);font-weight:800;font-size:var(--t-2);color:var(--dim);margin:var(--e-4) 0 var(--e-2);
  text-transform:uppercase;letter-spacing:.06em}
.fr-cpt{display:inline-block;min-width:20px;padding:0 var(--e-2);border-radius:999px;background:#ef4444;color:var(--c-texte);
  font-size:var(--t-1);font-weight:900;line-height:20px;text-align:center}
.fr-cpt.calme{background:var(--line2);color:var(--ink)}
.fr-row{display:flex;align-items:center;gap:var(--e-2);background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-2) var(--e-3);margin-bottom:var(--e-2)}
.fr-av{position:relative;flex:none;width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent2));
  color:var(--accent-ink);font-weight:900;display:flex;align-items:center;justify-content:center;font-size:var(--t-2)}
/* presence : vert = en ligne, rouge = hors ligne */
.fr-etat{position:absolute;right:-1px;bottom:-1px;width:12px;height:12px;border-radius:50%;
  background:#ef4444;border:2px solid var(--card)}
.fr-etat.on{background:#22c55e;box-shadow:0 0 8px rgba(34,197,94,.75)}
.fr-on{font-style:normal;color:#4ade80;font-weight:800}
.fr-id{flex:1;min-width:0;display:flex;flex-direction:column}
.fr-id b{font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fr-sub{color:var(--mut);font-size:var(--t-1)}
.fr-act{flex:none;display:flex;gap:var(--e-2)}
.fr-btn{border:1px solid var(--line2);background:transparent;color:var(--ink);font:inherit;font-size:var(--t-1);font-weight:700;
  border-radius:var(--r-1);padding:var(--e-2) var(--e-3);cursor:pointer;transition:.12s}
.fr-btn:active:not(.enfonce){transform:scale(.97)}
.fr-btn.ajouter,.fr-btn.accepter{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--accent-ink);border-color:transparent}
.fr-btn.refuser,.fr-btn.retirer{color:#f87171;border-color:rgba(248,113,113,.45)}
.fr-btn:disabled{opacity:.5;cursor:default}
/* classement entre amis */
.cl-seg{margin:0 0 var(--e-2)}
.cl-seg button{font-size:var(--t-2);padding:var(--e-2) var(--e-1)}
.cl-board{background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);overflow:hidden}
.cl-row{display:flex;align-items:center;gap:var(--e-2);padding:var(--e-3) var(--e-3);border-top:1px solid var(--line)}
.cl-row:first-child{border-top:none}
.cl-row.moi{background:rgba(139,92,246,.13)}   /* [26/10] rendu : un remplacement global du 11/08 l'avait lie au halo de la page de fin, jamais declare ici, donc la ligne « moi » n'etait plus surlignee */
.cl-row.clic,.fr-row.clic{cursor:pointer}
.cl-row.clic:active,.fr-row.clic:active{background:rgba(255,255,255,.06)}
.cl-row b{flex:1;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* le rang, garde en plus du rond (1er, 2e, 3e...) */
.cl-rg{flex:none;min-width:28px;text-align:center;font-weight:900;font-size:var(--t-1);color:var(--mut);letter-spacing:-.01em}
.cl-rg.prem{color:#fbbf24}
/* le rond du profil, comme le bouton du compte : une initiale sur le degrade d'accent */
.cl-av{position:relative;flex:none;width:34px;height:34px;border-radius:50%;
  background:linear-gradient(135deg,var(--accent),var(--accent2));color:var(--accent-ink);
  font-weight:900;font-size:var(--t-2);display:flex;align-items:center;justify-content:center}
/* 07-compte-10 : la couronne etait un EMOJI (dessin different sur chaque telephone, couleur
   imposee par le systeme) alors qu'un trace SVG existait deja dans le fichier. Elle prend donc
   une taille en pixels, comme une icone, et la couleur or de l'app. */
.cl-crown{position:absolute;top:-9px;right:-7px;width:15px;height:15px;font-style:normal;line-height:0;
  display:inline-flex;color:#f0b429;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}
.cl-crown svg{width:100%;height:100%;display:block}
.cl-v{flex:none;font-size:var(--t-2);font-weight:800}

/* ---------- Ecran plein "Qui joue ?" ---------- */
.jr-body{flex:1;overflow-y:auto;padding:0 2px}
.jr-hint{color:var(--dim);font-size:var(--t-2);text-align:center;margin:2px 0 var(--e-3)}
.jr-add{display:flex;gap:var(--e-2);align-items:stretch}
.jr-add input{flex:1;font-size:var(--t-3);padding:var(--e-3) var(--e-3)}
.jr-add .btn{width:auto;flex:none;padding:var(--e-3) var(--e-4);font-size:var(--t-2)}
.jr-list{margin-top:var(--e-3);display:flex;flex-direction:column;gap:var(--e-2)}
.jr-row{display:flex;align-items:center;gap:var(--e-2);background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-2);padding:var(--e-2) var(--e-3)}
.jr-row b{flex:1;min-width:0;font-weight:800;font-size:var(--t-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jr-row .jr-x{flex:none;width:44px;height:44px;border-radius:var(--r-1);border:1px solid rgba(248,113,113,.4);
  background:transparent;color:#f87171;font-size:var(--t-4);line-height:1;cursor:pointer}
.jr-row .jr-x:active:not(.enfonce){transform:scale(.95)}
#s-joueurs .bottom{padding-top:var(--e-3)}
/* deuxieme facon d'ajouter quelqu'un : son compte, avec sa validation */
.jr-compte-btn{width:100%;display:flex;align-items:center;gap:var(--e-2);margin-top:var(--e-3);padding:var(--e-3) var(--e-3);
  background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);color:var(--ink);cursor:pointer}
.jr-compte-btn b{font-size:var(--t-2);font-weight:800}
.jr-cb-t{flex:1;min-width:0;display:flex;flex-direction:column;text-align:left}
.jr-cb-t i{font-style:normal;color:var(--dim);font-size:var(--t-1);line-height:1.3;margin-top:2px}
.jr-compte-btn:active:not(.enfonce){transform:scale(.99)}
.jr-sec{font-weight:800;font-size:var(--t-2);color:var(--dim);margin:var(--e-4) 0 var(--e-2);text-transform:uppercase;letter-spacing:.06em}
/* en-tete de la page "quelqu'un qui a un compte" */
.jr-tete{background:var(--card);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--e-3) var(--e-3)}
.jr-tete b{display:block;font-size:var(--t-3);font-weight:900;margin-bottom:var(--e-1)}
.jr-tete span{display:block;color:var(--dim);font-size:var(--t-2);line-height:1.45}
/* les deux facons de valider, mises au meme niveau pour que le choix se voie */
.jr-choix{display:flex;flex-direction:column;gap:var(--e-2)}
.jr-opt{position:relative;display:grid;grid-template-columns:34px 1fr;grid-template-rows:auto auto;
  gap:2px var(--e-3);text-align:left;background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);
  padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);color:var(--ink);cursor:pointer}
.jr-opt .jr-opt-ico{grid-row:1 / span 2;align-self:center;width:34px;height:34px;color:var(--dim)}
.jr-opt .jr-opt-ico svg{width:100%;height:100%;display:block}
.jr-opt b{font-size:var(--t-2);font-weight:800;padding-right:78px}
.jr-opt .jr-opt-d{color:var(--dim);font-size:var(--t-2);line-height:1.4}
.jr-opt.on{border-color:transparent;background:linear-gradient(120deg,rgba(139,92,246,.3),rgba(192,132,252,.16)),var(--card)}
.jr-opt.on .jr-opt-ico{color:var(--accent2)}
.jr-opt:active:not(.enfonce){transform:scale(.99)}
.jr-tag{position:absolute;top:13px;right:13px;font-style:normal;font-size:var(--t-1);font-weight:900;
  letter-spacing:.06em;text-transform:uppercase;padding:var(--e-1) var(--e-2);border-radius:999px;
  background:var(--line2);color:var(--dim)}
.jr-tag.ok{background:rgba(34,197,94,.2);color:#4ade80}
.jr-amis-l{display:flex;flex-wrap:wrap;gap:var(--e-2)}
.jr-champ{width:100%;font-size:var(--t-3);padding:var(--e-3) var(--e-3);text-align:center}
/* l'attente : ca doit vivre a l'ecran pendant qu'on regarde le telephone d'en face */
.jr-att{text-align:center;padding:var(--e-3) var(--e-1) var(--e-1)}
.jr-pulse{position:relative;width:132px;height:132px;margin:var(--e-2) auto var(--e-4);display:flex;align-items:center;justify-content:center}
.jr-ring{position:absolute;inset:0;margin:auto;width:76px;height:76px;border-radius:50%;
  border:2px solid var(--accent2);opacity:0;animation:jrring 2.4s ease-out infinite}
.jr-ring.r2{animation-delay:.8s}
.jr-ring.r3{animation-delay:1.6s}
@keyframes jrring{0%{transform:scale(.62);opacity:.75}100%{transform:scale(1.75);opacity:0}}
.jr-face{position:relative;z-index:1;width:76px;height:76px;border-radius:50%;
  background:linear-gradient(135deg,var(--accent),var(--accent2));color:var(--accent-ink);
  font-weight:900;font-size:var(--t-5);display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 34px rgba(139,92,246,.55);animation:jrbeat 2.4s ease-in-out infinite}
/* 07-compte-12 : l'enveloppe est passee d'un emoji a une icone au trait, comme le reste. */
.jr-face svg{width:38px;height:38px;display:block}
@keyframes jrbeat{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
.jr-att-t{font-size:var(--t-3);font-weight:900;display:flex;align-items:center;justify-content:center;gap:2px}
.jr-dots{display:inline-flex;gap:var(--e-1);margin-left:4px}
.jr-dots i{width:5px;height:5px;border-radius:50%;background:var(--accent2);opacity:.3;animation:jrdot 1.2s ease-in-out infinite}
.jr-dots i:nth-child(2){animation-delay:.2s}
.jr-dots i:nth-child(3){animation-delay:.4s}
@keyframes jrdot{0%,100%{opacity:.25;transform:translateY(0)}50%{opacity:1;transform:translateY(-3px)}}
.jr-att-s{color:var(--ink);font-size:var(--t-2);margin-top:var(--e-2);line-height:1.45}
.jr-att-p{margin:var(--e-3) 0 var(--e-4);line-height:1.5}
@media(prefers-reduced-motion:reduce){.jr-ring,.jr-face,.jr-dots i{animation:none!important}.jr-ring{opacity:.3}}
.jr-wait{font-style:normal;font-size:var(--t-1);font-weight:800;text-transform:uppercase;letter-spacing:.05em;
  color:var(--mut);background:rgba(255,255,255,.07);border-radius:999px;padding:var(--e-1) var(--e-2);margin-right:8px}

/* statistiques par jeu : une carte par mini-jeu, a la couleur du jeu */
.jeu-card{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--gcol,#c084fc);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3);margin-bottom:var(--e-2)}
.jeu-h{display:flex;align-items:center;gap:var(--e-2);margin-bottom:var(--e-2)}
.jeu-h b{font-weight:800;font-size:var(--t-2)}
.jeu-ico{flex:none;width:24px;height:24px;color:var(--gcol,#c084fc);display:block}
.jeu-ico svg{width:100%;height:100%;display:block}
.jeu-vals{display:flex;gap:var(--e-2)}
.jeu-vals>div{flex:1;background:rgba(255,255,255,.04);border-radius:var(--r-1);padding:var(--e-2) var(--e-2);min-width:0}
.jeu-vals span{display:block;color:var(--mut);font-size:var(--t-1);font-weight:800;text-transform:uppercase;letter-spacing:.05em}
.jeu-vals b{display:block;font-weight:900;font-size:var(--t-2);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* pas encore d'amis : invitation a la place du classement */
/* les trois raccourcis de la page profil : generales / par jeu / badges */
.rac{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--e-2);margin:var(--e-3) 0 var(--e-3)}
.rac-b{position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:center;gap:var(--e-2);
  background:var(--card);border:1px solid var(--line2);border-radius:var(--r-2);padding:var(--e-3) var(--e-1) var(--e-2);
  color:var(--dim);font:inherit;font-size:var(--t-1);font-weight:800;line-height:1.25;text-align:center;
  cursor:pointer;transition:border-color .15s,color .15s}
.rac-b>*{position:relative;z-index:1}
.rac-b i{display:block;width:22px;height:22px;color:var(--gcol,var(--accent));opacity:.72}
.rac-b i svg{width:100%;height:100%;display:block}
.rac-b span{display:block;min-height:2.5em}
.rac-b.on{color:var(--ink);border-color:var(--gcol,var(--accent))}
.rac-b.on i{opacity:1}
.rac-b.on::before{content:"";position:absolute;inset:0;background:var(--gcol,var(--accent));opacity:.15}
.rac-b:active:not(.enfonce){transform:scale(.985)}
/* les trois periodes, dans la carte du haut */
.per{display:flex;gap:var(--e-1);background:rgba(0,0,0,.3);border-radius:999px;padding:var(--e-1);margin-bottom:var(--e-3)}
.per button{flex:1;background:none;border:none;color:var(--mut);font:inherit;font-size:var(--t-1);font-weight:800;
  letter-spacing:-.01em;padding:var(--e-2) 2px;border-radius:999px;cursor:pointer;white-space:nowrap}
.per button.on{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--accent-ink)}
/* variante ROUGE du grand en-tete : pour les pages qui detruisent quelque chose */
.sum-hero.rouge::before{background:radial-gradient(120% 62% at 50% 0%,#ef4444,transparent 62%);opacity:.18}
.sum-hero.rouge .sum-big{background-image:linear-gradient(90deg,#fca5a5,#ef4444 55%,#dc2626)}
.sum-hero.rouge .sum-kick{color:#f87171}
/* la case a cocher d'une action destructrice n'est pas verte */
.cp-check.danger input{accent-color:#ef4444}

/* le champ a code : gros, espace, centre. Un seul input pour que le telephone puisse le remplir. */
.code6{width:100%;text-align:center;font-size:var(--t-5);font-weight:900;letter-spacing:.5em;
  text-indent:.5em;padding:var(--e-3) var(--e-2);background:var(--card);color:var(--ink);
  border:1px solid var(--line2);border-radius:var(--r-2);font-variant-numeric:tabular-nums}
.code6::placeholder{color:var(--line2);letter-spacing:.5em}

/* separateur "ou" entre deux facons de faire la meme chose */
.ou{display:flex;align-items:center;gap:var(--e-3);margin:var(--e-3) 2px var(--e-3);color:var(--mut);
  font-size:var(--t-1);font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.ou::before,.ou::after{content:"";flex:1;height:1px;background:var(--line2)}

/* l'etat de l'adresse : confirmee ou non, visible d'un coup d'oeil */
.mail-etat{display:flex;align-items:center;gap:var(--e-3);background:var(--card);border:1px solid rgba(251,191,36,.35);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3)}
.mail-etat.ok{border-color:var(--line2)}
.mail-l{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.mail-l span{color:var(--dim);font-size:var(--t-2)}
.mail-l b{font-size:var(--t-2);font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mail-etat .jr-tag{position:static;flex:none}
.jr-tag.att{background:rgba(251,191,36,.2);color:#fbbf24}

/* les trois etapes annoncees avant de creer un compte */
.etapes{display:flex;gap:var(--e-2);margin-top:var(--e-3)}
.etapes span{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--e-2);
  background:rgba(255,255,255,.045);border:1px solid var(--line);border-radius:var(--r-1);
  padding:var(--e-2) var(--e-1);font-size:var(--t-1);font-weight:800;color:var(--dim);letter-spacing:-.01em}
.etapes i{font-style:normal;width:17px;height:17px;flex:none;border-radius:50%;
  background:linear-gradient(135deg,var(--accent),var(--accent2));color:var(--accent-ink);
  font-size:var(--t-1);font-weight:900;display:flex;align-items:center;justify-content:center}
/* le cas "je joue sans compte" : une vraie carte, pas une note de bas de page */
/* La phrase sous "Jouer sans compte" : elle explique le bouton, elle ne le remplace pas. */
.sans-note{text-align:center;font-size:var(--t-2);margin-top:var(--e-2)}
/* [08/08] `.cp-apart` RETIREE avec la rubrique legale qu'elle separait : les mentions
   vivent maintenant SOUS le bouton, dans la ligne du composant verrouille, et elles s'en
   separent par la typographie et l'ecart, jamais par un filet. */

/* les arguments de la page Compte : une pastille coloree, un titre, une phrase */
.av{display:flex;flex-direction:column;gap:var(--e-2);margin-top:var(--e-3)}
.av-l{display:flex;align-items:center;gap:var(--e-3);background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3)}
.av-l>i{flex:none;width:42px;height:42px;border-radius:var(--r-2);display:flex;align-items:center;
  justify-content:center;color:var(--gcol,var(--accent));
  background:color-mix(in srgb,var(--gcol,var(--accent)) 17%,transparent)}
.av-l>i svg{width:22px;height:22px;display:block}
.av-t{min-width:0}
.av-t b{display:block;font-size:var(--t-2);font-weight:800;line-height:1.25}
.av-t span{display:block;color:var(--dim);font-size:var(--t-2);line-height:1.35;margin-top:var(--e-1)}

/* en-tete des etapes d'inscription : ou j'en suis, ce que je fais, pourquoi */
.wiz-tete{display:flex;flex-direction:column;align-items:center;text-align:center;margin:var(--e-2) 0 var(--e-3)}
.wiz-tete .intro-dots{justify-content:center;margin-bottom:var(--e-3)}
.wiz-tete h2{font-size:var(--t-4);font-weight:900;letter-spacing:-.02em;margin:0}
.wiz-tete p{color:var(--dim);font-size:var(--t-2);line-height:1.45;margin:var(--e-2) 0 0;max-width:19em}

/* le drapeau du pays, a cote du rond du profil (jamais dessus : la couronne et la pastille
   de presence y sont deja). Sur Windows, le navigateur affiche les deux lettres du pays. */
.pav{flex:none;font-style:normal;font-size:var(--t-3);line-height:1;margin-left:-3px}
select.jr-champ{appearance:none;-webkit-appearance:none;background:var(--card);color:var(--ink);
  border:1px solid var(--line2);border-radius:var(--r-2);text-align:center;text-align-last:center}

/* les chiffres a vie : une tuile par statistique, symbole et couleur propres */
.st-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin-top:2px}
.st-tile{position:relative;overflow:hidden;background:var(--card);border:1px solid var(--line2);
  border-radius:var(--r-2);padding:var(--e-3) var(--e-3) var(--e-3)}
/* tuile seule sur sa ligne : a plat, sinon elle sonne creux */
.st-tile.full{grid-column:1 / -1;display:flex;align-items:center;gap:var(--e-3)}
.st-tile.full .st-ico{margin-bottom:0}
.st-tile.full .st-l{margin-top:0}
.st-tile::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(95% 80% at 0% 0%,var(--gcol,var(--accent)),transparent 72%);opacity:.14}
.st-tile>*{position:relative;z-index:1}
.st-ico{display:flex;width:23px;height:23px;color:var(--gcol,var(--accent));margin-bottom:var(--e-2)}
.st-ico svg{width:100%;height:100%}
.st-tile b{display:block;font-size:var(--t-4);font-weight:900;line-height:1;letter-spacing:-.02em}
.st-l{display:block;color:var(--dim);font-size:var(--t-1);font-weight:700;line-height:1.25;margin-top:var(--e-1)}
/* le classement se lit comme un tableau : deux colonnes nommees, le critere porte sa couleur */
.cl-tete{display:flex;align-items:center;justify-content:space-between;gap:var(--e-2);padding:var(--e-3) var(--e-1) var(--e-2);
  font-size:var(--t-1);font-weight:900;letter-spacing:.08em;text-transform:uppercase;color:var(--mut)}
.cl-crit{display:flex;align-items:center;gap:var(--e-2);color:var(--gcol,var(--accent))}
.cl-crit i{display:block;width:15px;height:15px}
.cl-crit i svg{width:100%;height:100%;display:block}
.cl-v{color:var(--gcol,var(--dim))}
/* podium : or, argent, bronze. Le rang reste ecrit en toutes lettres. */
.cl-rg.arg{color:var(--c-texte-2)}
.cl-rg.bro{color:#d8a06a}
.cl-vide{background:var(--card);border:1px dashed var(--line2);border-radius:var(--r-2);padding:var(--e-3) var(--e-3);text-align:center}
.cl-vide p{color:var(--dim);font-size:var(--t-2);margin-bottom:var(--e-3)}
.cl-vide .btn{width:auto;padding:var(--e-2) var(--e-3);font-size:var(--t-2)}

/* ligne a deux actions : les boutons passent sous le nom, sinon le texte est ecrase */
.fr-row.col{flex-wrap:wrap}
.fr-row.col .fr-act{flex:0 0 100%;margin-top:var(--e-2);gap:var(--e-2)}
.fr-row.col .fr-act .fr-btn{flex:1}

/* pendant la remise en place de l'ecran apres un rechargement : rien ne clignote */
.app{transition:opacity .16s ease}
html.boot-restaure .app{opacity:0}

/* LA COULEUR DIT QUI PARLE, y compris pour les messages de partie.
   Moi = violet (comme ma bulle et mon rond) ; mon ami = la carte neutre. */
.ln.moi .bul-partie{background:linear-gradient(135deg,rgba(109,40,217,.42),rgba(139,92,246,.30));
  border-color:rgba(167,139,250,.55)}
.ln.moi .bul-fini{background:linear-gradient(135deg,rgba(109,40,217,.32),rgba(139,92,246,.22));
  border-top-color:rgba(167,139,250,.42);border-right-color:rgba(167,139,250,.42);
  border-bottom-color:rgba(167,139,250,.42)}
.ln.moi .bf-r{background:rgba(255,255,255,.13)}
.bul-fini.annulee{opacity:.8}

/* [08/08] `.arc-ou` RETIREE (trois regles). Le « OU » entre deux filets ne restait porte
   que par l'ecran sans compte ; la page des mini-jeux, pour laquelle il avait ete dessine,
   ne s'en sert plus depuis sa refonte. Le partage des trois issues se dit desormais par
   l'ecart : 12 dans le couple, 24 avant celle qui se passe de compte. */

/* LA PASTILLE DE REACTION, posee comme sur iPhone.
   Deux regles, dans cet ordre d'importance :
   1. PLACEMENT : elle chevauche le coin HAUT EXTERIEUR de la bulle et deborde sur le fond.
      Posee sous la bulle (v277), une pastille violette sur une bulle violette se lisait comme
      un bout du message (constat de Theo le 26/07). Le cercle de fond autour acheve de la
      detacher, quelle que soit la couleur en dessous.
   2. COULEUR : celle de CELUI QUI A REAGI, pas de l'auteur du message. Violet plein si la
      reaction est de moi, carte neutre si elle vient de l'ami. */
.bul,.bul-partie,.bul-fini{position:relative}   /* repere exact de la pastille */
.ln.a-reac{margin-top:var(--e-4)}
/* Elle ne mord que le COIN ARRONDI (12 px), le reste deborde sur le fond : le texte du
   message reste entier. Les pastilles suivantes s'empilent vers l'INTERIEUR, le long du
   bord haut de la bulle : vers l'exterieur, la deuxieme partait trop loin du message
   (constat de Theo le 26/07) et pouvait sortir de l'ecran. */
.bul-reacs{position:absolute;top:-24px;right:-19px;z-index:2;display:flex;flex-direction:row-reverse;gap:var(--e-1)}
.ln.moi .bul-reacs{right:auto;left:-19px;flex-direction:row}   /* mon message est a droite : le coin est a gauche */
.bul-reacs span{display:flex;align-items:center;justify-content:center;gap:var(--e-1);
  min-width:31px;height:31px;padding:0 var(--e-2);border-radius:999px;
  font-size:var(--t-2);line-height:1;font-weight:800;
  background:var(--card);border:1px solid var(--line2);
  box-shadow:0 0 0 3px var(--bg),0 4px 10px rgba(0,0,0,.45)}
.bul-reacs span.moi{background:linear-gradient(135deg,#6d28d9,#8b5cf6);border-color:transparent;color:var(--c-texte)}

/* la citation quand un message repond a un autre */
.bul-rep{display:block;border-left:2px solid var(--line2);padding-left:var(--e-2);margin-bottom:var(--e-1);
  font-size:var(--t-1);color:var(--mut);opacity:.95}
.bul.moi .bul-rep{border-left-color:rgba(255,255,255,.55);color:rgba(255,255,255,.8)}
.bul-rep b{display:block;font-size:var(--t-1);color:#22d3ee}
.bul.moi .bul-rep b{color:rgba(255,255,255,.9)}

/* la barre "je reponds a..." au-dessus du champ de saisie */
.chat-rep{display:flex;align-items:center;gap:var(--e-2);background:var(--card);border:1px solid var(--line);
  border-left:3px solid var(--accent2);border-radius:var(--r-1);padding:var(--e-2) var(--e-2);margin-bottom:var(--e-2)}
.chat-rep .cr-t{flex:1;min-width:0;font-size:var(--t-1);color:var(--mut);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.chat-rep .cr-t b{display:block;color:var(--ink);font-size:var(--t-1)}
.chat-rep button{flex:none;background:none;border:0;color:var(--mut);font-size:var(--t-3);cursor:pointer;padding:0 var(--e-1)}

/* le mode selection : une case a gauche de chaque message, une barre d'action en bas */
.chat.sel .ln{padding-left:var(--e-5);position:relative}
.chat.sel .ln.moi{padding-left:var(--e-5)}
.sel-case{position:absolute;left:2px;top:50%;transform:translateY(-50%);width:22px;height:22px;
  border-radius:50%;border:1.5px solid var(--line2);display:flex;align-items:center;justify-content:center;
  color:#04222a;font-weight:900;font-size:var(--t-1)}
.sel-case.on{background:#22d3ee;border-color:transparent}
.sel-bar{display:flex;align-items:center;gap:var(--e-2);margin-bottom:var(--e-2)}
.sel-bar b{flex:1;font-size:var(--t-2)}
.sel-bar button{background:none;border:1px solid var(--line2);border-radius:999px;padding:var(--e-2) var(--e-3);
  color:var(--ink);font:inherit;font-weight:800;cursor:pointer}
.sel-bar button.rouge{border-color:rgba(248,113,113,.6);color:#f87171}
.sel-bar button[disabled]{opacity:.4}

/* la page "Reinitialiser mes donnees" : elle reprend le composant de listes du reste de
   l'app (titre de section + carte), rien de nouveau a apprendre a l'oeil. */
.raz-vide{background:var(--card);border:1px dashed var(--line2);border-radius:var(--r-2);padding:var(--e-4) var(--e-3);
  text-align:center}
.raz-vide span{display:block;color:var(--mut);height:26px;margin-bottom:var(--e-2)}
.raz-vide span svg{width:26px;height:26px}
.raz-vide b{display:block;font-size:var(--t-2);font-weight:800;margin-bottom:var(--e-1)}
.raz-vide i{font-style:normal;font-size:var(--t-2);line-height:1.45;color:var(--mut)}

/* la page de confirmation de la remise a zero : une seule carte, une seule idee */
/* "C'est definitif" : plus d'encadrement, aligne sur la case a cocher juste en dessous */
.raz-fin{margin:var(--e-2) 0 0;padding:0;background:none;border:none;text-align:left}
.raz-fin b{display:block;font-size:var(--t-3);font-weight:900;color:#f87171}

/* le numero de version, en pied de la page A propos : discret, mais lisible pour le support */
.cp-ver{margin:var(--e-3) 0 var(--e-1);text-align:center;font-size:var(--t-1);color:var(--dim)}

/* MENU CONTEXTUEL D'UN MESSAGE (appui long), a la maniere d'iOS : le fond se floute, le message
   presse reste net a sa place, la barre de reactions flotte au-dessus et le menu s'ancre dessous.
   Aucune feuille pleine largeur, aucun texte repete, aucun bouton Annuler : on ferme a cote. */
#msg-ctx{position:fixed;inset:0;z-index:120;display:none}
#msg-ctx.on{display:block}
/* 1. le fond se floute en premier (mesure sur la video d'iOS : environ 150 ms) */
.ctx-fond{position:absolute;inset:0;background:rgba(6,6,10,.55);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);opacity:0;transition:opacity .16s ease}
#msg-ctx.on .ctx-fond{opacity:1}
/* 2. le message se souleve pour faire de la place, en restant net */
.ctx-copie{position:absolute;pointer-events:none;transform:translateY(0) scale(1);
  transition:transform .28s cubic-bezier(.2,.9,.3,1.02)}
#msg-ctx.on .ctx-copie{transform:translateY(var(--monte,0px)) scale(1.02)}
.ctx-copie .ctx-bulle{max-width:100%}
/* 3. le menu grandit depuis une petite taille, ancre sous le message ; 4. la barre arrive apres */
.ctx-emos,.ctx-menu{position:absolute;opacity:0}
.ctx-menu{transform:scale(.82) translateY(-6px);transform-origin:top center;
  transition:opacity .2s ease .06s, transform .26s cubic-bezier(.2,.9,.3,1.04) .06s}
.ctx-emos{transform:scale(.8);transform-origin:bottom center;
  transition:opacity .18s ease .15s, transform .22s cubic-bezier(.2,.9,.3,1.06) .15s}
#msg-ctx.on .ctx-menu{opacity:1;transform:scale(1) translateY(0)}
#msg-ctx.on .ctx-emos{opacity:1;transform:scale(1)}
/* Tailles reglees sur iOS : emoji d'environ 30 px, ligne de menu d'environ 46 px, texte
   d'environ 17 px. Avant, tout etait a l'echelle d'une liste de reglages, donc etrique. */
.ctx-emos{display:flex;gap:var(--e-1);padding:var(--e-2) var(--e-2);border-radius:999px;
  background:rgba(32,32,40,.94);border:1px solid var(--line2);box-shadow:0 14px 34px rgba(0,0,0,.55)}
.ctx-emos button{background:none;border:0;font-size:var(--t-5);line-height:1;padding:var(--e-2) var(--e-2);border-radius:999px;cursor:pointer}
.ctx-emos button.on{background:rgba(139,92,246,.4)}
.ctx-menu{min-width:252px;max-width:290px;border-radius:var(--r-2);overflow:hidden;
  background:rgba(32,32,40,.97);border:1px solid var(--line2);box-shadow:0 20px 48px rgba(0,0,0,.6)}
.ctx-menu button{display:flex;align-items:center;gap:var(--e-3);width:100%;min-height:46px;background:none;border:0;
  border-bottom:1px solid rgba(255,255,255,.07);color:var(--ink);font:inherit;font-weight:700;
  font-size:var(--t-3);padding:var(--e-3) var(--e-3);text-align:left;cursor:pointer}
.ctx-menu button:last-child{border-bottom:0}
.ctx-menu button:active{background:rgba(255,255,255,.06)}
.ctx-menu button i{flex:none;width:22px;height:22px;color:var(--mut);display:flex;align-items:center;justify-content:center}
.ctx-menu button i svg{width:22px;height:22px}
.ctx-menu button.rouge{color:#f87171}
.ctx-menu button.rouge i{color:#f87171}
.ctx-menu button[disabled]{opacity:.45;cursor:default}
.ctx-menu button[disabled] small{margin-left:auto;font-size:var(--t-1);font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--mut)}

/* segment a symboles : le pictogramme au-dessus du mot (niveaux de gorgees) */
.seg.seg-sym button{display:flex;flex-direction:column;align-items:center;gap:var(--e-1);padding:var(--e-2) 2px}
.seg.seg-sym button i{display:block;width:19px;height:19px;line-height:0}
.seg.seg-sym button i svg{width:19px;height:19px}
.seg.seg-sym button span{display:block;font-size:var(--t-1);line-height:1.15}

/* l'heure du dernier message, a droite d'une ligne de discussion */
.dis-q{flex:none;align-self:flex-start;margin-top:2px;font-style:normal;font-size:var(--t-1);
  font-weight:700;color:var(--mut);white-space:nowrap}

/* ------------------------------------------------------------------ *
 * RETOUR AU TOUCHER, partout et a l'identique (v291).
 * L'effet est celui du bouton "Jouer", mesure image par image sur la video de Theo : la surface
 * retrecit de 2 % et RIEN d'autre ne change (ni couleur, ni voile). La classe est posee par
 * app.js des l'appui et gardee 110 ms au minimum, pour qu'un appui bref se voie quand meme.
 * `scale` plutot que `transform` : la ou une translation existe deja (boutons d'aide centres,
 * badge du tour), elle n'est pas ecrasee.
 * ------------------------------------------------------------------ */
.enfonce{scale:.98!important}
/* 2 % sur un bouton de 44 px font moins d'un pixel : les petits ronds ont besoin de plus,
   comme le faisaient deja les boutons d'aide de l'app. */
.iconbtn.enfonce,.helpbtn.enfonce,.tile-help.enfonce,.chat-env.enfonce,.chat-jeu.enfonce,
.ctx-emos button.enfonce,#menu-btn.enfonce,#settings-btn.enfonce,#home-moi.enfonce{scale:.92!important}
/* [06/08] LE DISQUE DE COMPTE S'ENFONCE DE 6 %, PAS DE 8. Le rendu du 05/08 pose .94 sur le
   disque et .92 sur la gelule : deux objets de matiere differente ne s'enfoncent pas pareil,
   un disque plein encaisse moins de retrait qu'une surface creuse avant de paraitre sauter. */
#home-moi.connecte.enfonce{scale:.94!important}

/* ------------------------------------------------------------------ *
 * LA BARRE DE SAISIE DU CHAT (v296)
 * ------------------------------------------------------------------ */
/* Plus d'anneau bleu du navigateur : `input:focus` ne couvrait pas les <textarea>, et le champ
   du chat en est un. On garde un indice, la bordure s'eclaircit, dans le cyan du bouton d'envoi. */
.chat-saisie textarea:focus,.chat-saisie textarea:focus-visible{
  outline:none;border-color:rgba(103,232,249,.5)}
/* La barre descend au plus pres du bas : chaque point gagne est un point de conversation.
   Le reste de l'ecart, dans Safari, appartient au navigateur (barre d'adresse compacte et barre
   de formulaire) et disparait quand l'app est installee sur l'ecran d'accueil. */
#s-multi{padding-bottom:calc(var(--e-2) + env(safe-area-inset-bottom,0px))}

/* Clavier ouvert : plus de reserve pour le trait d'accueil, il est sous le clavier. La barre de
   saisie descend d'autant, au plus pres de la barre d'iOS. */
html.clavier .screen{padding-bottom:var(--e-2)}
/* ⚠️⚠️ [07/08, Theo] LA BARRE NE REMONTE PLUS AVEC LE CLAVIER. Elle est ancree au bas de
   `.app`, dont la hauteur suit la fenetre VISIBLE : quand le clavier s'ouvre, la fenetre
   se replie et la barre remonte avec elle, pour venir se poser juste au-dessus des
   touches. Deux barres empilees a l'ecran, dont une qui n'a rien a faire la pendant qu'on
   ecrit.
   ⚠️ ON LA MASQUE PLUTOT QUE DE LA REANCRER, et c'est le meme resultat pour moins de
      risque : la maintenir a sa place absolue demanderait de calculer la hauteur du
      clavier a chaque image, sur une valeur que Safari ne donne pas directement et qui
      bouge pendant l'animation d'ouverture. Sous le clavier, elle est invisible de toute
      facon — Theo le dit ainsi : « elle doit rester a sa place, donc sous le clavier et
      non visible ».
   ⚠️ ET CA VAUT PARTOUT, PAS SEULEMENT DANS LE FIL. Le fil de discussion retirait deja sa
      barre par `.au-fil`, mais tous les autres champs de l'app (recherche d'un ami,
      changement de pseudo, saisie d'un code, e-mail) la laissaient remonter. La regle
      porte donc sur `html.clavier`, l'etat, pas sur un ecran. */
html.clavier .barre.on{display:none}
html.clavier #s-multi{padding-bottom:var(--e-2)}

/* ---------- Une fenetre AU MILIEU de l'ecran (page "Je suis mineur") ----------
   Le panneau colle en bas coupait en deux ce qui restait visible derriere. Au milieu, avec un
   fond assombri et floute, la page se lit seule et l'ecran d'age ne la parasite plus. */
.modal.milieu{align-items:center;justify-content:center;padding:var(--e-4);
  background:rgba(6,6,10,.74);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.modal.milieu .sheet{background:none;border:0;box-shadow:none;padding:0;overflow:visible;
  width:100%;max-width:420px;border-radius:0;max-height:100%}
/* La carte "mineur" : un seul bloc, bouton compris. Titre volontairement plus petit que les
   grands titres de fin de partie : ici c'est la phrase qui porte l'information, pas le titre. */
.mineur{background:var(--card);border:1px solid var(--line2);border-radius:var(--r-3);
  padding:var(--e-4) var(--e-4) var(--e-4);text-align:center;box-shadow:0 18px 44px rgba(0,0,0,.5)}
.mineur-ico{width:46px;height:46px;margin:0 auto var(--e-3);color:var(--accent2)}
.mineur-ico svg{width:100%;height:100%;display:block}
.mineur-kick{font-size:var(--t-1);font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mut)}
.mineur-t{font-size:var(--t-4);font-weight:900;line-height:1.15;margin:var(--e-2) 0 var(--e-2);color:var(--ink)}
.mineur-p{color:var(--dim);font-size:var(--t-2);line-height:1.45;max-width:32ch;margin:0 auto}
.mineur .btn{margin-top:var(--e-4)}

/* [08/08] `.btn.discret` RETIREE. Elle habillait « Jouer sans compte » et « Pas
   maintenant », les deux libelles de l'ecran sans compte d'avant. La lecon qu'elle portait
   ne se perd pas, elle change de porteur : la troisieme issue est un VRAI bouton, meme
   gabarit et meme cible que les deux autres (`.vq-issue.vq-invite`), et c'est sa matiere —
   voile a .03, filet blanc a .10 — qui la met en retrait, pas sa taille. Sur un ecran qui
   compte trois issues, la plus discrete est celle qu'on choisit quand on est presse : la
   rendre plus difficile a toucher, c'est decider a la place de quelqu'un. */

/* La case d'acceptation de la creation de compte : lisible, et le lien vers les conditions se
   voit comme un lien sans casser la ligne. */
.cp-check.cgu{align-items:flex-start;line-height:1.4;font-size:var(--t-2);margin-top:var(--e-3)}
.lien-cgu{background:none;border:0;padding:0;color:var(--accent2);font:inherit;font-weight:800;
  text-decoration:underline;text-underline-offset:2px;cursor:pointer;text-align:left}

/* Rubrique Statistiques VERROUILLEE (sans compte) : elle se deplie normalement, et chaque
   entree porte un cadenas dans le violet de l'app, a la place de son chevron. Pas de voile gris :
   avec quatre cadenas il n'apprend rien de plus et gene la lecture. */
.cp-grp.verrou .cp-grp-h b,.cp-grp.verrou .cp-act-t b{color:var(--dim)}
.hs-cle{display:inline-flex;flex:none;width:15px;height:15px;margin-left:8px;
  color:var(--gcol,var(--accent2));vertical-align:middle}
.cp-item .hs-cle{width:14px;height:14px;opacity:.9}
.hs-cle svg{width:100%;height:100%;display:block}

/* Le kicker de la page "Compte requis" : a peine plus visible que les autres (Theo, 26/07).
   Violet de la DA + le cadenas des rubriques verrouillees, taille et graisse inchangees. */
.sum-kick.kick-verrou{color:#a78bfa;display:flex;align-items:center;justify-content:center;gap:var(--e-2)}
.kv-cle{display:inline-flex;width:13px;height:13px}
.kv-cle svg{width:100%;height:100%;display:block}
/* "Le joueur a un compte" sans compte connecte : la DA des rubriques verrouillees (v314) */
.jr-compte-btn.verrou b{color:var(--dim)}
.jr-compte-btn.verrou .hpc-ico{opacity:.6}

/* Les points forts des cartes du compte, ligne par ligne (v315). Le point prend la couleur
   de la carte (--gcol), la ligne garde le gris des descriptions. */
.av-t span.av-p{display:flex;align-items:flex-start;gap:var(--e-2);color:var(--dim);font-size:var(--t-2);line-height:1.35;margin-top:var(--e-1)}
.av-p::before{content:"";display:block;flex:none;width:5px;height:5px;margin-top:var(--e-2);border-radius:50%;background:var(--gcol,#a78bfa)}

/* 05-minijeux-b-12 : TREIZE tailles vivaient en style EN LIGNE dans index.html. Un style en
   ligne gagne contre toute regle de la feuille, y compris contre le mode grand texte : ces
   textes-la etaient donc les seuls de l'app a ne jamais grandir, et le controle UI-06 ne
   pouvait pas les voir puisqu'il lit la feuille. Ils sont ici, ils suivent le mode comme le
   reste. Les display:none restent dans le HTML : ils sont pilotes par le JS, pas par le style. */
/* 04-minijeux-a-7 : la place RESERVEE au verdict variait d'un jeu a l'autre (2 / 1,8 / 1,6 /
   2,4 rem) et TROIS jeux n'en reservaient aucune : chez eux, l'apparition du verdict poussait
   la mise en page d'un coup, juste au moment ou l'oeil cherche le resultat. Une seule hauteur
   pour tous, calee sur la plus grande police de verdict du lot.
   05-minijeux-b-25 : la zone du timer aveugle etait a 2,4rem, presque le double de la plupart
   des autres, pour dire la meme chose. Les tailles se resserrent sur deux valeurs : 2rem pour
   un verdict court (un chiffre, un mot), 1,4rem pour une phrase. */
.score[id$="-result"]{min-height:2.4rem}
#w-result{font-size:var(--t-4);margin-top:var(--e-2)}
#reflex-result{font-size:var(--t-5)}
#tm-result{font-size:var(--t-5)}
#rl-result{font-size:var(--t-4)}
#ca-result{font-size:var(--t-4);margin-top:var(--e-2)}
#bl-result{font-size:var(--t-5)}
#tg-result{font-size:var(--t-5)}
#ma-q{font-size:var(--t-7)}
#ma-result{font-size:var(--t-4)}
#in-result{font-size:var(--t-4);text-align:center}
#gn-result{font-size:var(--t-5)}
#dx-clock{font-size:4.5rem;font-variant-numeric:tabular-nums}
#dx-result{font-size:var(--t-4);padding:0 var(--e-3)}

/* [01/08] 02-choix-11 : l'etat « retiré du hasard » n'existe plus (la grille ne filtre plus
   rien depuis la vague Mini-jeux) ; ses styles .hors-hasard partent avec. */

/* 03-partie-5 : un prenom en pause se voit, au lieu de disparaitre sans explication. */
.designe-n.gele{opacity:.4;text-decoration:line-through;cursor:default}

/* 03-partie-15 : le bouton "passer" epuise se voit, et il repond au doigt (voir passerLaCarte). */
.pass-btn.epuise,#c-passer.epuise{opacity:.45}
/* 03-partie-21 : une reponse revelee n'est plus un bouton, c'est du texte. */
.reveal.shown{border-color:transparent;background:none;text-transform:none;letter-spacing:0;
  font-weight:700;padding:var(--e-2) 0}

/* 01-entree-7 : le zoom systeme est rendu (filet d'accessibilite), mais le double tap et le
   pincement ACCIDENTELS pendant qu'on joue sont neutralises la ou l'on tape vite : ecrans de
   jeu, carte de Soiree, classiques. Ailleurs, on peut agrandir librement. */
#s-game,#s-classic-run,[id^="s-"] .gamecard,#pc-canvas,#wheel,
#finger-zone,#reflex-zone,#tg-zone,#gn-zone,#tap-zone{touch-action:manipulation}

/* ================= LOT DU 28/07 : mise en page et grand texte ================= */

/* 02-choix-13 : l'exemple de carte n'etait borne par rien. Une carte longue poussait l'ecran
   des modes et repoussait les trois tuiles hors de vue, sur l'ecran ou l'on CHOISIT. */
.apercu-c{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}

/* 03-partie-4 et 03-partie-10 : le compteur de manche passait sur deux lignes en grand texte,
   et un prenom long debordait la pastille "A toi, X" alors qu'il est tronque dans le bilan.
   Une seule ligne, et le prenom se coupe proprement au lieu de pousser la barre. */
.hud-compte{white-space:nowrap}
.gt-chip{max-width:11ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 01-entree-6 : la porte d'age n'avait pas le patron des autres ecrans centres : ses boutons
   flottaient a une hauteur qui changeait avec le contenu. */
#s-age .bottom{margin-bottom:0}

/* 04-minijeux-a-29 : deux barres horizontales qui bougent l'une au-dessus de l'autre (le
   chrono et le curseur), impossible de savoir laquelle regarder. Le chrono s'efface. */
#s-timing #tm-progwrap{opacity:.45;height:4px}

/* 05-minijeux-b-19 : le verdict de cash out s'affichait dans le paragraphe de consigne, donc
   en petit et en gris, alors que tous les autres jeux ont une zone de verdict. */
#co-inst.verdict-co{font-size:var(--t-4);color:var(--ink);font-weight:800}

/* 08-social-17 : deux pseudos au meme debut devenaient identiques une fois tronques a 64 px.
   On donne la place reelle : la ligne s'adapte, le nom se coupe en dernier recours. */
.sal-j i{max-width:none}
.sal-r{flex-wrap:wrap}

/* 08-social-32 : le sous-titre du nouveau groupe listait TOUS les prenoms coches, sans borne :
   a quinze amis, il poussait le champ du nom hors de l'ecran. */
.wiz-tete p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* [03/08] 08-social-25 EST RENVERSE : la pastille de non-lu est retiree. Elle etait verte,
   or le vert dit la PRESENCE sur la meme rangee : deux sens pour une couleur, a 8 px
   d'intervalle. Le non-lu passe au contraste (voir .dis.neuf). */

/* 08-social-12 : une invitation de groupe dans la liste des discussions. Vert = accepter,
   rouge = refuser, la regle des couleurs de Theo. */
.inv-grp{cursor:default}
.inv-act{display:flex;gap:var(--e-2);flex:none}
.inv-act .fr-btn{padding:var(--e-2) var(--e-2)}

/* 08-social-23 : un nom de groupe de 20 caracteres poussait le bouton Terminer hors de la
   barre. Le titre prend la place restante et se coupe, le bouton ne bouge jamais. */
/* coherence : tous les autres ecrans centrent le titre de leur topbar ; celui du multi
   restait colle a la fleche (flex:1 + texte a gauche). */
#mu-title{flex:1;min-width:0;text-align:center}
#mu-title .mu-tt-t b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 04-minijeux-a-10 : le verdict du doigt du destin etait rendu en 4rem, la plus grosse police
   de tous les mini-jeux, pour une phrase entiere : elle debordait sur deux lignes enormes. Il
   revient a la taille des autres verdicts. */
#finger-result{font-size:var(--t-4)}
/* 04-minijeux-a-18 : la roulette russe injecte un prenom dans son verdict, et un prenom long
   debordait de l'ecran. Le verdict se coupe proprement au lieu de pousser. */
#rl-result{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:92vw}
/* 04-minijeux-a-14 : en mouvement reduit, la bombe perdait TOUTE montee visuelle et explosait
   sans prevenir. Un signal sans animation : le fond se rechauffe par paliers, ce qui informe
   sans clignoter. */
@media (prefers-reduced-motion:reduce){
  #bomb-pulse{transition:background-color .5s}
}

/* 03-partie-17 : le bouton "passer" etait DANS le flux defilant de la carte : une carte longue
   qui defile l'emportait hors du pouce. Il se fige par rapport a la carte, pas au texte. */
#s-game .gamecard{position:relative}
#c-passer{position:absolute;top:8px;right:8px;z-index:2}

/* 07-compte-23 : la pastille verte de VALIDATION servait aussi de simple bouton Modifier :
   le meme vert disait tantot "c est confirme", tantot "clique ici". Modifier devient neutre. */
.jr-tag{background:var(--line2);color:var(--dim)}
.jr-tag.ok{background:#0f2a19;color:#4ade80}
.jr-tag.att{background:#3a2f0e;color:#fcd34d}

/* 06-classiques-13 : a quatorze trinkeurs, la grille des prenoms a designer poussait la carte
   hors de l ecran. La zone plafonne et defile a l interieur, la carte reste visible. */
#cl-designe{max-height:38vh;overflow-y:auto}

/* ================================================================================
   ACCUEIL — refonte portee le 30/07 depuis design/ecrans/ (TRINKE.md fait foi).
   Jetons du dossier poses ICI, scopes a l'accueil et prefixes (--h-*, --encre-*) :
   les noms globaux --ink / --card / --dim / --line existent deja avec d'AUTRES
   valeurs dans toute l'app, les redefinir repeindrait des ecrans hors perimetre.
   Tailles de TEXTE en rem (Grand texte : html.bigtext passe la racine a 118,75 %,
   proche du +18 % du rendu accueil-grand-texte) ; icones, avatars et rayons en px,
   ils ne grandissent pas — "Grand texte" est un reglage de lisibilite du texte.
   ================================================================================ */
#s-home{
  --h-card2:#231F2E; --h-line:#2C2736; --h-muted:#A8A0BA; --h-dim:#8A82A6;
  --h-text:#F7F5FA;         /* texte clair de l'accueil (JAMAIS var(--ink) global ici) */
  --encre:#170B20;          /* encre des surfaces violettes */
  --encre-fuchsia:#2A0A19;  /* encre des surfaces fuchsia   */
  --encre-or:#2A1B02;       /* encre des surfaces or        */
  --encre-teal:#052322;     /* encre des surfaces sarcelle  */
  /* MINIMUM entre deux groupes, une seule valeur pour tous les ecrans (arbitrage 30/07).
     Trois seuils de media query de hauteur ont echoue (740, 780, 900) : l'outil etait le
     probleme, pas le nombre. Quand une adaptation depend de la hauteur, c'est l'ELASTICITE
     qui la porte, jamais un seuil : les ressorts .hsp s'etirent pour remplir la hauteur
     disponible, abaisser leur minimum suffit — ecran serre, la page rentre ; ecran large,
     ils reprennent l'air et l'espacement redevient genereux sans connaitre l'appareil. */
  --h-gap:16px;
  --h-ease:cubic-bezier(.22,.9,.25,1);
  padding:calc(env(safe-area-inset-top,0px) + var(--e-2))
          calc(env(safe-area-inset-right,0px) + var(--e-3))
          calc(env(safe-area-inset-bottom,0px) + var(--e-3))
          calc(env(safe-area-inset-left,0px) + var(--e-3));
  background:var(--bg);
}
/* entree orchestree : decalages courts et croissants, eteinte sous reduced-motion.
   REGLE (bug prod 30/07, corrige au dossier) : l'etat de REPOS d'un element anime a
   l'entree doit etre VISIBLE ; l'etat cache vit dans les keyframes (from), et `both`
   tient l'etat de depart pendant le delai. Si l'animation ne se joue pas (retour sur
   l'ecran, redeclaration d'animation), l'element est simplement visible. */
#s-home .h-in{animation:uiMonte var(--m-long) var(--m-sortie) both;animation-delay:var(--d,0ms)}
@keyframes uiMonte{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* UNE FOIS PAR CHARGEMENT DE PAGE (arbitrage 30/07) : revenir d'un autre ecran est de la
   navigation interne, pas une arrivee. Une fois la premiere sequence jouee, le JS pose
   .entree-jouee sur la section : plus aucune animation d'entree, l'etat de repos etant
   visible tout s'affiche immediatement. Sans exception, banniere comprise. */
#s-home.entree-jouee .h-in{animation:none}
/* ---- en-tete en flux : reglages a gauche, mot-symbole au centre, compte a droite ---- */
/* QUAND LE SLOT D'ACCROCHE EST OCCUPE, LA MARQUE MONTE DANS L'EN-TETE (arbitrage 30/07,
   TRINKE.md). Mesure sur iPhone : fenetre Safari 714 pt, contenu 773, ressorts au minimum —
   il manquait 59 pt qu'aucun espacement ne pouvait rendre. Le bandeau de marque en coutait 93 :
   il cede la place quand il y a une action a reprendre. Le mot-symbole passe au centre de
   l'en-tete, la signature disparait, l'en-tete NE GRANDIT PAS.
   Grille 3 colonnes plutot que space-between : le centrage reste vrai quelle que soit la
   largeur des boutons. */
/* [06/08] GRILLE 28 / 1fr / 28 (lot du 05/08, §1.5). Elle remplace le 36/1fr/36 du 04/08,
   qui remplacait lui-meme un 40/1fr/43.
   ⚠️ CE QUI A COMMANDE LA VALEUR, C'EST L'ENCRE, PAS LA BOITE. Releve sur appareil avant de
      toucher a quoi que ce soit : le bord gauche de l'encre du glyphe tombait a 22,2 pt du
      bord d'ecran, le bord droit du disque a 17,9. Les deux BOITES etaient bien posees sur
      la marge de 18 ; une seule des deux ENCRES l'etait, parce que le disque remplit sa
      boite et pas le glyphe. Une marge se lit sur ce qu'on voit, pas sur la boite qui le
      contient. Les deux boutons partagent donc une boite de 28, et c'est elle qui touche la
      marge de 18 des deux cotes : le disque est plein, la gelule est une surface, ce sont
      deux objets, et deux objets s'alignent par leurs bords.
   ⚠️ 28 CONTRE 23,1 DE CAPITALE, SOIT 21 % DE PLUS, ET C'EST VOULU. Caler la boite SUR la
      capitale du mot-symbole rendait la ligne maigre : une barre de navigation n'aligne pas
      ses commandes sur la capitale de son titre, elle les centre sur son axe. Ce qui reste
      cale sur la capitale, c'est l'ENCRE du glyphe : boite 26, trace a 90 %, encre 23,13
      pour 23,10 de capitale. Deux boutons de meme hauteur ne pesent pareil que si leur
      encre occupe la meme part de leur boite (mesure avant correction : disque 100 % du T,
      glyphe 53 %). */
#s-home .htop{display:grid;grid-template-columns:28px 1fr 28px;align-items:center;flex:0 0 auto}
/* COLONNES PLACEES EXPLICITEMENT (correctif 30/07, TRINKE.md) : le mot-symbole peut etre
   MASQUE et non retire (un seul document pour les sept etats), or un enfant en display:none
   ne reserve pas sa case dans une grille — sans ces regles, le bouton de compte remonterait
   dans la colonne du milieu, colle au bouton de reglages. Piege general : des qu'un enfant de
   grille peut disparaitre, les colonnes se placent explicitement. */
#s-home .htop>#settings-btn{grid-column:1}
#s-home .htop>.hwm-top{grid-column:2}
#s-home .htop>#home-moi{grid-column:3;justify-self:end}
/* ---- les deux boutons de l'en-tete : une seule boite, deux glyphes ---- */
/* ⚠️ UN VOILE ET UN RAYON, JAMAIS UN TRAIT (barème du lot, §0.4). C'est le geste de l'onglet
   actif de la barre du bas, repris en negatif sur sombre. Le `1px solid #3E3650` du 30/07 fait
   TROIS pixels physiques a 3x : un cadre, pas un cheveu. Le voile est a .045 — commande rare,
   a peine visible — contre .07 pour une commande courante et .12 pour un etat actif.
   ⚠️ LE RAYON EST 9,2 SUR UNE BOITE DE 28, soit la meme proportion que les 13 sur 40 d'avant :
      un carre arrondi dit une fonction, un rond dit une personne (TRINKE.md §4). */
.hicobtn{position:relative;width:28px;height:28px;border-radius:var(--r-1);
  border:0;padding:0;flex:0 0 auto;
  background:rgba(255,255,255,.045);color:var(--c-texte-2);
  display:grid;place-items:center;cursor:pointer}
/* CIBLE TACTILE DE 44 px SANS CHANGER LA TAILLE VUE : 28 + 2 x 8 = 44. Le ::after ne
   grandit rien, il etend la seule zone du toucher (TRINKE.md §3). */
.hicobtn::after{content:"";position:absolute;inset:-8px;border-radius:var(--r-3)}
.hicobtn.hrond,.hicobtn.hrond::after{border-radius:999px}
/* le trace : 26 dans une boite de 28, a 90 %, pour que l'encre tombe sur la capitale du
   mot-symbole. Trait 1,75 comme les glyphes de la barre du bas, bouts arrondis, aucun
   remplissage — une icone de cette app est un fil de fer. */
.hicobtn>svg{width:26px;height:26px;fill:none;stroke:currentColor;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ PAS DE :active ICI, ET CE N'EST PAS UN OUBLI. Le retour au toucher de toute l'app est
   la classe `.enfonce`, posee par app.js et gardee 110 ms au minimum : un appui bref se voit
   quand meme, ce qu'un :active ne garantit pas. Et l'effet mesure image par image sur la
   video de Theo (v291) ne change QUE la taille — ni couleur, ni voile. Le rendu du 05/08
   assombrit le fond a l'appui ; c'est l'ecart le plus visible de ce portage, il est assume
   pour ne pas faire deux grammaires de l'appui dans la meme app. */
/* ---- le bouton de compte : un porteur, deux etats ---- */
/* [06/08] IL REVIENT, la ou le 04/08 l'avait retire parce qu'il doublait l'onglet Profil.
   Le chemin de BASE reste la barre du bas ; celui-ci est un raccourci, d'ou sa matiere et
   non celle d'un onglet actif. Deux entrees vers le meme lieu ne se contredisent que si
   elles ont le meme poids.
   ⚠️ LE DISQUE CONNECTE N'EST PAS REDESSINE ICI : c'est `.ong-av`, l'objet de la barre du
      bas, pose tel quel dans le markup. Degrade vertical a deux arrets, initiale a .84rem en
      graisse 800, bague DOUBLE en box-shadow (un liseré clair puis un anneau violet, ce
      qu'un outline ne sait pas faire). On copie l'objet, donc on copie sa technique — et ses
      decimales. Le jour ou la barre du bas change, celui-ci change avec elle.
   ⚠️ CE QUE CA COUTE, ET IL FAUT LE REGARDER SUR L'APPAREIL : avec sa bague, le disque
      occupe 34 px la ou le bouton de reglages en fait 28. La bague est peinte, pas mise en
      page : elle ne pousse rien, mais elle deborde de 3 px vers le bord d'ecran. Si la bande
      penche a droite, il faudra choisir entre « le meme objet que la barre » et « l'equilibre
      de la ligne » : les deux ne tiennent pas ensemble. */
#s-home .htop>#home-moi.connecte{background:none}
#s-home .htop>#home-moi>.ong-av{display:none}
#s-home .htop>#home-moi.connecte>.ong-av{display:grid}
#s-home .htop>#home-moi.connecte>#home-ico{display:none}
/* [04/08] LE MOT-SYMBOLE EST DESORMAIS VISIBLE AUX SEPT ETATS. Il ne partage plus sa
   rangee qu'avec l'engrenage : ce sont les deux boutons qui bornaient sa taille, il
   devient le bandeau a lui seul. 2.0625rem = les 33 px du rendu, en rem pour que Grand
   texte l'agrandisse (UI-06) : 39 px a 118,75 %, qui tiennent dans une en-tete sans
   hauteur fixe. */
/* [06/08] LE CALAGE OPTIQUE DU MOT-SYMBOLE (lot du 05/08, §1.4). L'encre du mot est SOUS le
   centre de sa boite, et il a fallu mesurer la police pour le savoir : SF Pro Display porte
   une ascendante de 0,952 et un jambage de 0,213, pas les 0,75 / 0,25 des manuels. A corps 33
   et interligne 1,05, le contenu de la police vaut 38,45 pour une boite de 34,65 : le
   demi-interligne est NEGATIF, le texte deborde sa propre boite, et tous les signes
   s'inversent. Encre de 6,42 a 29,52, centre a 17,97 contre 17,32 pour la boite, soit 0,64 px
   de trop bas — d'ou la remontee.
   ⚠️ ELLE EST EN `em`, PAS EN `px`, ET C'EST UNE ADAPTATION AU PROJET. Le dossier ecrit
      -.64px pour un corps FIXE de 33 ; ici le corps est en rem et grandit avec Grand texte
      (39,19 px a 118,75 %). Une valeur en px serait juste en normal et fausse en Grand texte.
      -0,64 / 33 = -.0194em : le calage suit le corps, ce qui est exactement ce que le dossier
      demande (« ces 0,64 se recalculent, ils ne se recopient pas »).
   ⚠️ ET IL DEPEND DE LA POLICE. Sur iPhone la pile systeme EST SF Pro, donc la mesure vaut ;
      ailleurs (Roboto, Segoe) le decalage reel differe. Changer de famille rend ce nombre
      faux, il ne se reajuste pas tout seul. */
#s-home .hwm-top{display:block;justify-self:center;min-width:0;line-height:1.05;
  position:relative;top:-.0194em;
  font-weight:900;font-size:var(--t-5);letter-spacing:0;
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  --teintes:#FBBF24,#EC4899,#A78BFA,#2DD4BF;
  /* reflet plus doux qu'au bandeau (bande 38-62 %, blanc .55) : a 24 px un balayage plein
     blanc scintille. Memes keyframes hreflet, memes teintes, meme cadence. */
  background-image:linear-gradient(120deg,rgba(255,255,255,0) 38%,rgba(255,255,255,.55) 50%,rgba(255,255,255,0) 62%),
    linear-gradient(90deg,var(--teintes));
  background-size:220% 100%,100% 100%;
  background-repeat:no-repeat;
  background-position:-70% 0,0 0;
  /* [20/10] reflet hreflet retire : mot-symbole invisible depuis aout (docs/MOUVEMENT.md) */}
/* [04/08] LES QUATRE BASCULES D'ETAT DU MOT-SYMBOLE SONT SUPPRIMEES avec le bloc de
   marque : il n'y a plus deux emplacements a arbitrer, donc plus rien a basculer. Le
   .hmarque de l'accueil et sa signature n'existent plus (le mot-symbole vit dans
   l'en-tete, aux sept etats) ; le .wm de la porte d'age, lui, reste entier. */
/* mot-symbole : texte decoupe au degrade, PLUS un SVG. Ordre des teintes contraint
   (or -> fuchsia -> violet -> sarcelle) : or et sarcelle voisins font un vert-citron.
   Le reflet balaie, les couleurs ne bougent pas (une rotation de teinte passerait par
   le vert du compte et le rouge de l'irreversible, et repeindrait en boucle sous Wake Lock). */
#s-age .wm{display:block;margin:0 auto;text-align:center;
  font-size:clamp(2.125rem,15vw,3.75rem);font-weight:900;letter-spacing:0;line-height:1.05;
  text-indent:0;   /* suit toujours le letter-spacing : a 0 il n'a rien a compenser */
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  --teintes:#FBBF24,#EC4899,#A78BFA,#2DD4BF;
  background-image:
    linear-gradient(102deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.95) 50%,rgba(255,255,255,0) 100%),
    linear-gradient(90deg,var(--teintes));
  background-size:52% 100%,100% 100%;background-repeat:no-repeat;background-position:-70% 0,0 0;
  /* [20/10] reflet hreflet retire : mot-symbole invisible depuis aout (docs/MOUVEMENT.md) */}
/* ---- pile centrale et ressorts ponderes ---- */
/* pas de min-height:0 (present dans le rendu) : notre .screen est un conteneur FIXE qui
   defile, pas un body en min-height:100dvh — avec 0, la pile debordait SOUS le pied legal
   au lieu de pousser la page. min-height auto : la pile grandit, l'ecran defile si besoin. */
#s-home .hstack{flex:1 1 auto;display:flex;flex-direction:column}
#s-home .hsp{flex:1 1 auto;min-height:var(--h-gap)}
/* [04/08] DEUX RESSORTS AU LIEU DE QUATRE, ET LE BAS PESE PLUS QUE LE HAUT. La carte
   Multijoueur est partie dans la barre d'onglets : le ressort qui la separait du groupe
   (.hsp-b) n'a plus rien a separer, et le supprimer valait mieux que le laisser pousser
   du vide. Rapport repris du rendu : .8 en haut, 1.2 en bas — le bloc de modes se pose
   au-dessus du milieu optique, ce qui laisse la barre respirer. */
#s-home .hsp-a{flex-grow:.8}
#s-home .hsp-x{flex-grow:.8}
#s-home .hsp-c{flex-grow:1.2}
#s-home .hstack.occupe .hsp-a{flex-grow:.5}
/* [02/08] les intitules de territoire sont RETIRES de l'accueil (decision produit 01/08) :
   les styles .hlab partent avec eux. La regle du socle « deux intitules maximum » continue
   de valoir ailleurs. Au passage, l'exemption typographique #s-home des .hlab (.656rem,
   seule entorse au plancher UI-04) disparait avec son dernier usage. */
#s-home .hchev{margin-left:auto;flex:0 0 auto;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
/* ---- [04/08] LES DEUX INTITULES DE SECTION ---- */
/* Ils disent l'INTENTION, pas le lieu : « pour tes soirees », « pour changer de rythme ».
   .75rem = les 12 px du rendu, qui est aussi le plancher UI-04 : on ne descend pas. */
#s-home .hlab{display:flex;align-items:center;gap:var(--e-2);font-size:var(--t-micro);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--c-texte-2);
  margin:var(--e-4) 0 var(--e-2);padding-left:var(--e-1)}
/* ---- [04/08] LE FILIGRANE DES CARTES ---- */
/* ⚠️ .025 ET PLUS .05. Il avait ete calibre sur des cartes SOMBRES, ou il faisait une
   matiere ; des que la couleur devient claire et saturee, il concurrence le texte. Ce
   n'est pas un reglage de gout : le trait blanc et la lettre blanche se disputent alors
   le meme fond. */
#s-home .hfond{position:absolute;right:-14px;top:50%;transform:translateY(-50%);
  width:132px;height:132px;pointer-events:none;z-index:0;
  opacity:.025;fill:none;stroke:#FFFFFF;stroke-width:1.1;
  stroke-linecap:round;stroke-linejoin:round}
#s-home .hduo .hfond{width:104px;right:-20px;top:auto;bottom:-22px;transform:none}
/* le filigrane est un fond : tout le reste passe devant, sans exception */
#s-home .htete>*:not(.hfond),#s-home .hmode>*:not(.hfond){position:relative;z-index:1}
/* ---- [04/08] LA PASTILLE D'ETIQUETTE (« Recommande », « Bientot ») ---- */
#s-home .hbadge{flex:0 0 auto;align-self:flex-start;margin-top:2px;
  padding:2px var(--e-2);border-radius:999px;
  font-size:var(--t-micro);font-weight:600;letter-spacing:0;
  color:rgba(255,255,255,.82);background:rgba(255,255,255,.09)}
/* ---- rangee trinkeurs : creusee la ou les modes sont poses, neutre, jamais un mode ---- */
#s-home .h-qui{display:flex;align-items:center;gap:var(--e-3);width:100%;text-align:left;cursor:pointer;
  background:#0A090E;border:1px solid #38304A;border-radius:var(--r-2);padding:var(--e-2) var(--e-3);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.6);margin-bottom:var(--e-2);font:inherit;
  color:var(--h-text);transition:transform .16s var(--h-ease),border-color .16s}
#s-home .h-qui:active:not(.enfonce){transform:scale(.985)}
@media (hover:hover){#s-home .h-qui:hover{border-color:#3A3348}}
#s-home .h-qui>b{flex:0 1 auto;font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;line-height:1.2}
#s-home .h-qui-d{margin-left:auto;font-size:var(--t-1);font-weight:500;color:var(--c-texte-3)}
#s-home .h-qui .hchev{margin-left:10px;width:9px;height:15px;stroke:#8A82A6}
/* icone de la FONCTION (liste vide) : carre arrondi, gris utilitaire — pas une personne */
#s-home .hqi{width:30px;height:30px;border-radius:var(--r-1);flex:0 0 auto;display:grid;place-items:center;
  background:var(--h-card2)}
#s-home .hqi svg{width:17px;height:17px;stroke:#BFB7CE;fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
/* avatars : cercle = une personne. 30px, chevauchement de 9px, anneau de la couleur de la
   rangee (un vide, pas un filet). La TEINTE identifie (arc bleu -> indigo 205-250°),
   la CLARTE separe : alternance fonce / clair. */
#s-home .havs{display:flex;flex:0 0 auto;align-items:center}
#s-home .hav{position:relative;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  font-size:var(--t-1);font-weight:700;letter-spacing:0;box-shadow:0 0 0 2px #0A090E}
#s-home .hav+.hav{margin-left:-9px}
#s-home .hav1{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav2{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav3{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav4{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav5{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav6{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav7{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
#s-home .hav8{background:#DDD5C7;color:#170B20}   /* crème, comme la barre du bas (maquette validée 03/09) */
/* MOI : le violet est reserve au connecte, meme degrade et meme encre que le bouton compte.
   Deux anneaux concentriques ; z-index car la pastille suivante se peint par-dessus et
   mangerait l'anneau sur son bord droit des le deuxieme trinkeur. */
#s-home .hav.estmoi{background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);
  color:var(--encre);box-shadow:0 0 0 2px #0A090E,0 0 0 3.5px #A78BFA;z-index:2}
/* au-dela de cinq visibles : « +N », N plafonne a 9 par la limite de 14 en local */
#s-home .havplus{background:#DDD5C7;color:#170B20;font-size:var(--t-1)}   /* [02/10, Romain] crème aussi, comme les ronds */
/* ---- cartes pleines : anatomie commune ---- */
/* [02/08] AUCUNE ENCRE N'EST BLANC PUR SUR CES CARTES : #EDEAF2, deux points sous le
   blanc. Le blanc pur sur un aplat sombre donne l'impression que la lettre EMET. Aucun
   text-shadow, a aucune taille. */
#s-home .htete{display:flex;align-items:center;width:100%;border-radius:var(--r-3);text-align:left;
  cursor:pointer;color:var(--c-texte);position:relative;font:inherit;border:0;background:none;
  transition:transform .16s var(--h-ease),box-shadow .16s var(--h-ease)}
#s-home .htete:active:not(.enfonce){transform:scale(.982)}
/* le relief de l'icone, et rien d'autre : une ligne claire sur l'arete haute, un lisere.
   Aucune diffusion, un support qui rayonne redevient une source de lumiere. */
#s-home .hmi{flex:0 0 auto;display:grid;place-items:center;background:rgba(23,11,32,.26)}
#s-home .hmi svg{stroke:rgba(255,255,255,.95);fill:none;stroke-width:1.75;
  stroke-linecap:round;stroke-linejoin:round}
#s-home .htx{flex:1 1 auto;min-width:0}
/* [04/08] LA GRAISSE PASSE DE 700 A 600. Sur les couleurs recalibrees, un 700 blanc pur
   epaissit le trait au point de le faire vibrer sur le degrade ; 600 tient la hierarchie
   sans emettre. Valeur du rendu, pour les quatre cartes. */
#s-home .htete b{display:block;font-weight:600;letter-spacing:-.02em;line-height:1.08}
#s-home .htete small{display:block;color:var(--c-texte);line-height:1.25;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
#s-home .htete .hchev{stroke:rgba(23,11,32,.5)}
#s-home .httl{display:flex;align-items:center;gap:var(--e-2)}
/* SOIREE — la seule carte a porter du relief, et la plus grande. Une seule carte par ecran
   porte de la matiere : quand une banniere occupe le slot d'accroche, Soiree devient .plate. */
/* PLATEAU CENTRAL : le meme ton repete de 28 a 68 %, la zone qui porte le texte ne varie
   plus que de 1,16x. Assombri de 35 % en lumiere lineaire, puis RESATURE a luminance
   constante (le -35 % avait emporte la saturation avec lui, et un ton gris se lit comme un
   calque pose sur la carte). */
/* [04/08] VALEURS RECALIBREES, A QUATRE ARRETS. Le degre passe de 128 a 148 et le
   plateau central est REPETE de 40 a 72 % : un degrade a deux arrets fabrique une bande
   de Mach, et la bande de texte doit traverser un ton stable. Contraste obtenu sur le
   titre blanc pur : 4,84:1.
   ⚠️ LE BLANC PUR EST RESERVE A CES QUATRE CARTES. Ailleurs, sur du quasi-noir, il brule :
      le socle garde #F7F5FA. */
#s-home .hsoiree{padding:var(--e-4) var(--e-3) var(--e-4) var(--e-3);gap:var(--e-3);
  background:linear-gradient(148deg,#B486F8 0%,#8E48F0 40%,#8E48F0 72%,#7526D8 100%);
  /* La lumiere est DEHORS, et elle commence a 6 px du bord : sans cet ecart, la moitie de
     son alpha tombe sur l'arete meme et le contour se noie dans son propre halo. */
  box-shadow:0 0 30px -6px rgba(139,92,246,.34),
             0 0 76px -20px rgba(139,92,246,.16),
             inset 0 0 0 1px rgba(255,255,255,.13),
             inset 0 1px 0 rgba(255,255,255,.10)}
/* ⚠️ PLATE NE VEUT PLUS DIRE ETEINTE. Le GLOW appartient a la carte et vit aux sept etats ;
   le RELIEF (l'arete haute) n'appartient qu'a un objet par ecran, et la banniere le prend
   quand elle est la. Ce que Soiree perd ici, c'est l'arete, et elle seule. */
#s-home .hsoiree.plate{box-shadow:0 0 30px -6px rgba(139,92,246,.34),
             0 0 76px -20px rgba(139,92,246,.16),
             inset 0 0 0 1px rgba(255,255,255,.13)}
/* filet independant du JS : si la banniere est dans le DOM, Soiree est plate, point.
   Regle SEPAREE (pas en liste) : un vieux moteur sans :has() ne doit invalider que celle-ci. */
#s-home .hstack:has(#btn-resume) .hsoiree{box-shadow:0 0 30px -6px rgba(139,92,246,.34),
             0 0 76px -20px rgba(139,92,246,.16),
             inset 0 0 0 1px rgba(255,255,255,.13)}
/* ⚠️ LE CREUX DE L'ICONE S'INVERSE : LUMIERE, PLUS OMBRE. Sur les cartes d'avant, sombres
   et rabattues, un carre d'encre a .26 se lisait en creux ; sur les valeurs recalibrees,
   claires et saturees, la meme encre fait une TACHE SOMBRE a cote du texte. Le rendu pose
   une lumiere a .07 avec son arete haute — le motif est le meme, sa valeur est l'opposee. */
#s-home .htete .hmi,#s-home .hmode .hmi{background:rgba(255,255,255,.07);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.15),
             inset 0 0 0 1px rgba(255,255,255,.10)}
#s-home .htete .hmi svg,#s-home .hmode .hmi svg{stroke:rgba(237,234,242,.92)}
#s-home .hsoiree .hmi{width:48px;height:48px;border-radius:var(--r-2)}
#s-home .hsoiree .hmi svg{width:25px;height:25px}
#s-home .hsoiree b{font-size:var(--t-4)}
#s-home .hsoiree small{font-size:var(--t-1);margin-top:var(--e-1)}
#s-home .hsoiree .hchev{width:10px;height:17px;stroke:#BFA6E6}
/* la ligne du titre porte le titre ET son etiquette ; le sous-titre passe dessous */
#s-home .hsoiree .httl{display:flex;align-items:center;gap:var(--e-2);min-width:0}
/* ---- [04/08] LES CARTES DE MODE : DEUX FORMES, UNE SEULE ANATOMIE ---- */
/* ⚠️ LA FORME SUIT LA SECTION, PAS LA CARTE. Les classiques passent en PLEINE LARGEUR
   (.hplein) parce qu'elles sont une soiree, comme Soiree ; Mini-jeux et Les quiz restent
   en duo parce qu'ils sont un changement de rythme. Le meme composant rend les deux :
   rangee quand il est plein, colonne quand il est en duo.
   ⚠️ border:0 EXPLICITE. Un <button> sans border declaree reprend celle du NAVIGATEUR
      (2px outset), que WebKit rend en relief clair — c'etait le « contour blanc » vu sur
      iPhone le 02/08, et ce n'etait pas du dessin. */
#s-home .hduo{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin-top:var(--e-3)}
#s-home .hmode{position:relative;overflow:hidden;font:inherit;
  display:flex;align-items:center;gap:var(--e-3);width:100%;
  border:0;background-color:transparent;
  border-radius:var(--r-3);padding:var(--e-3);text-align:left;cursor:pointer;
  color:var(--c-texte);   /* chaque bouton fixe sa color, sinon iOS le rend en bleu systeme */
  transition:transform .16s var(--h-ease)}
#s-home .hmode:active:not(.enfonce){transform:scale(.982)}
#s-home .htete{overflow:hidden}
/* pleine largeur : la carte suit Soiree de 12 px, pas du pas courant — c'est la suite du
   meme groupe, pas un nouveau. */
#s-home .hplein{margin-top:var(--e-3)}
#s-home .hmode .hbas{flex:1 1 auto;min-width:0}
#s-home .hmode .hchev{width:9px;height:15px;flex:0 0 auto}
#s-home .hmode .hmi{width:42px;height:42px;border-radius:var(--r-2);flex:0 0 auto;
  display:grid;place-items:center}
#s-home .hmode .hmi svg{width:22px;height:22px;stroke-width:1.85}
#s-home .hmode b{display:block;font-size:var(--t-3);font-weight:600;color:var(--c-texte);line-height:1.15;
  letter-spacing:-.02em}
#s-home .hmode small{display:block;font-size:var(--t-1);margin-top:var(--e-1);line-height:1.25;
  color:var(--c-texte);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ---- la meme carte, en duo : colonne, et le chevron quitte le flux ---- */
/* ⚠️ LE CHEVRON EST POSE, PAS ALIGNE. En colonne, un chevron dans le flux tomberait sous
   le texte ; pose a droite au milieu, il dit la meme chose qu'en rangee. Le sous-titre lui
   reserve sa place par un rembourrage, sinon la derniere lettre passe dessous. */
#s-home .hduo .hmode{flex-direction:column;align-items:stretch;gap:var(--e-2)}
#s-home .hrang{display:flex;align-items:center;gap:var(--e-3)}
#s-home .hduo .hmode>.hchev{position:absolute;right:14px;top:50%;
  transform:translateY(-50%);z-index:2;margin-left:0}
#s-home .hduo .hmode b{font-size:var(--t-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ⚠️ min-height SUR DEUX LIGNES, PAS UNE HAUTEUR. Les deux tuiles vivent dans une grille :
   elles s'alignent de toute facon. Le minimum sert au cas ou UNE seule ligne s'ecrit —
   sans lui, la rangee entiere remonterait d'un cran selon le texte. */
#s-home .hduo .hmode small{white-space:normal;line-height:1.3;padding-right:var(--e-4);
  min-height:2.03rem;text-overflow:clip}
/* ⚠️ LES BORDER DEVIENNENT DES INSET. Un lisere pose en ombre interieure ne peut pas
   deplacer la geometrie ; une border, meme en border-box, rogne le fond d'un pixel sur
   tout le tour. */
/* [04/08] LES TROIS AUTRES TEINTES, RECALIBREES COMME SOIREE : 148°, plateau central
   repete de 40 a 72 %, glow a -6 px et lisere a l'interieur. Contrastes du titre blanc
   pur : 4,62 (classiques) · 4,75 (mini-jeux) · 4,64 (quiz). */
#s-home .hclassiques{background:linear-gradient(148deg,#F45CC0 0%,#D22C96 40%,#D22C96 72%,#B01A7C 100%);
  box-shadow:0 0 30px -6px rgba(228,40,160,.25),
             0 0 76px -20px rgba(228,40,160,.13),
             inset 0 0 0 1px rgba(255,255,255,.13),
             inset 0 1px 0 rgba(255,255,255,.10)}
#s-home .hclassiques .hchev{stroke:#DFA9C4}
#s-home .hminijeux{background:linear-gradient(148deg,#D9A32B 0%,#996A11 40%,#996A11 72%,#7E560B 100%);
  box-shadow:0 0 30px -6px rgba(248,166,20,.26),
             0 0 76px -20px rgba(248,166,20,.13),
             inset 0 0 0 1px rgba(255,255,255,.13),
             inset 0 1px 0 rgba(255,255,255,.10)}
#s-home .hminijeux .hchev{stroke:#C8A96A}
/* ⚠️ LE BLEU DES QUIZ EST UN CINQUIEME TERRITOIRE, ET IL A FALLU LE TROUVER. Les quatre
   couleurs de mode sont prises (violet 262°, fuchsia 330°, or 43°, sarcelle 174°), plus le
   vert du compte et le rouge de l'irreversible. Le sarcelle etait tentant — il vient de
   perdre son porteur ici, la carte Multijoueur etant partie dans la barre — MAIS IL DESIGNE
   ENCORE LE MODE dans ses onze ecrans : on verrait le meme turquoise pour les Quiz ici et
   pour les Discussions un toucher plus loin.
   ⚠️ CE QUE LE BLEU 210° COUTE QUAND MEME : l'arc des avatars (205° a 250°) perd de la
      marge, et un trinkeur en bleu franc vit sur la rangee juste au-dessus. A surveiller
      sur l'appareil. */
#s-home .hquiz{background:linear-gradient(148deg,#5A9BE0 0%,#2E76C6 40%,#2E76C6 72%,#2160A8 100%);
  box-shadow:0 0 30px -6px rgba(60,130,200,.22),
             0 0 76px -20px rgba(60,130,200,.11),
             inset 0 0 0 1px rgba(255,255,255,.13),
             inset 0 1px 0 rgba(255,255,255,.10)}
/* la carte inerte garde ses couleurs : les eteindre aurait casse l'accord de luminance des
   quatre plateaux, mesure. C'est l'etiquette qui dit l'etat, pas un voile gris. */
#s-home .hquiz[disabled]{cursor:default}
#s-home .hquiz[disabled]:active{transform:none}
#s-home .hbientot{background:rgba(255,255,255,.14);color:var(--c-texte)}
/* [04/08] LA CARTE MULTIJOUEUR A QUITTE L'ACCUEIL : elle est devenue l'onglet Discussions.
   Ses regles partent avec elle — un selecteur sans porteur est du CSS mort, et c'est
   exactement la faute que controle-rendu.py releve sur les rendus. Le cadenas « compte
   requis » (.hlock) part aussi : un onglet ne porte pas de cadenas, c'est l'ecran d'arrivee
   qui propose le compte.
   ⚠️ CE QUE CA COUTE, ET IL FAUT LE SAVOIR : le sarcelle 174° n'a plus AUCUN porteur hors
      des onze ecrans du Multijoueur. Un des quatre territoires du socle n'a plus de lieu ou
      s'apprendre. Dette reelle, signalee au design, non payee ici. */
/* ---- banniere d'accroche : un occupant a la fois, la couleur dit le mode en cours ---- */
/* ⚠️ ELLE NE CHANGE NI DE COULEUR NI D'ENCRE, ET C'EST MESURE : sur un aplat or assombri,
   une encre blanc casse rend 1,94:1. L'or est une teinte lumineuse, le socle lui donne deja
   son encre sombre a 10,5:1. La banniere garde donc ses aplats, ses encres et son relief.
   Elle recoit le glow, rien d'autre — et reste la seule carte a pleine luminance de l'ecran,
   ce qui rend la hierarchie plus nette qu'avant, pas moins. */
#s-home .reprise{padding:var(--e-3) var(--e-3);gap:var(--e-3);
  --voile:rgba(0,0,0,.26);--ombre:rgba(0,0,0,.6);--halo:rgba(0,0,0,.34);
  box-shadow:0 0 26px -6px var(--ombre),
             0 0 58px -16px var(--halo),
             0 16px 40px -24px var(--ombre),
             inset 0 1px 0 rgba(255,255,255,.32),
             inset 0 -1px 0 rgba(0,0,0,.14)}
#s-home .reprise .hmi{width:40px;height:40px;border-radius:var(--r-2);background:var(--voile)}
#s-home .reprise .hmi svg{width:21px;height:21px}
#s-home .reprise b{font-size:var(--t-3)}
#s-home .reprise small{font-size:var(--t-1);margin-top:2px;opacity:.82;color:inherit}
#s-home .reprise .hchev{width:9px;height:15px;stroke:currentColor;opacity:.5}
/* [04/08] LA BANNIERE SUIT LA CARTE DE SON MODE, VALEURS RECALIBREES. Elle porte la
   couleur du mode interrompu : si la carte change de teinte et pas elle, le lien entre
   « reprendre » et « ce que je reprends » se coupe. Son rembourrage reste a 12/16 contre
   20/18 pour les cartes — elle doit se distinguer sans devenir une cinquieme carte.
   Ses ENCRES SOMBRES ne bougent pas : c'etait une decision mesuree du 02/08 (sur un aplat
   or, une encre blanc casse rend 1,94:1) et les nouveaux plateaux sont a la meme luminance. */
#s-home .rep-soiree{color:var(--encre);--voile:rgba(23,11,32,.26);--ombre:rgba(139,92,246,.56);--halo:rgba(139,92,246,.27);
  background:linear-gradient(148deg,#B486F8 0%,#8E48F0 40%,#8E48F0 72%,#7526D8 100%)}
#s-home .rep-classiques{color:var(--encre-fuchsia);--voile:rgba(42,10,25,.26);--ombre:rgba(236,72,153,.56);--halo:rgba(236,72,153,.27);
  background:linear-gradient(148deg,#F45CC0 0%,#D22C96 40%,#D22C96 72%,#B01A7C 100%)}
#s-home .rep-minijeux{color:var(--encre-or);--voile:rgba(42,27,2,.26);--ombre:rgba(251,191,36,.56);--halo:rgba(251,191,36,.27);
  background:linear-gradient(148deg,#D9A32B 0%,#996A11 40%,#996A11 72%,#7E560B 100%)}
/* [03/08, Theo] LE RAPPEL LEGAL A QUITTE L'ACCUEIL, et ses regles partent avec lui : un
   selecteur sans porteur est du CSS mort, la faute que controle-rendu.py releve justement
   sur les rendus. Le texte n'a pas disparu du produit, il vit toujours sur la porte d'age
   et dans Compte > Mentions legales.
   ⚠️ Les deux arbitrages qu'il portait sont donc CADUQUES sur cet ecran, et il faut le
      savoir si le bloc revient un jour : le corps monte a 12 px (30/07) et le refus, deux
      fois, de l'estomper. Un retour a l'identique devrait les reprendre.
   Le pendant du theme clair reste declare plus bas pour  (les vraies mentions), il
   ne cible plus .hlegal. */
/* ---- erreur 7 du dossier : aucun « … » en fin de sous-titre. Les sous-titres rapetissent
   plutot que d'atteindre la troncature ; la banniere retrecit avant de tronquer.
   Seuil monte de 380 a 412 px (adaptation signalee) : avec la pile systeme de Windows
   (Segoe UI, plus large que SF), « Tous les jeux reunis au meme endroit » tronquait a 390. ---- */
@media (max-width:412px){
  #s-home .hsoiree small{font-size:var(--t-1)}
}
@media (max-width:380px){
  #s-home .reprise b{font-size:var(--t-2)}
  #s-home .reprise small{font-size:var(--t-1)}
}
/* PLUS AUCUNE MEDIA QUERY DE HAUTEUR sur l'accueil (arbitrage 30/07, regle au dossier).
   Le reste de l'ancien bloc compact a disparu avec elle : rembourrage et titre de Soiree,
   taille de la signature sont des valeurs typographiques, elles n'ont jamais eu a dependre
   de la hauteur d'ecran. Le minimum des ressorts (--h-gap, plus haut) fait tout le travail. */
#s-home :focus-visible{outline:2px solid #A78BFA;outline-offset:3px;border-radius:var(--r-2)}
/* porte d'age : meme mot-symbole que l'accueil (arbitrage 30/07), aux tailles de la porte */
#s-age .wm{font-size:clamp(2.6rem,13vw,4rem)}
@media (max-height:740px){ #s-age .wm{font-size:clamp(2rem,10vw,2.8rem)} }
/* Grand texte : la page a le droit de defiler (seul cas), les ressorts cessent de s'etirer,
   les sous-titres s'enroulent au lieu de tronquer. Rendu de reference : accueil-grand-texte. */
html.bigtext #s-home .hsp{flex:0 0 auto}
html.bigtext #s-home .htete small{white-space:normal;overflow:visible;text-overflow:clip}
@media (prefers-reduced-motion:reduce){
  /* animation:none suffit desormais : l'etat de repos est visible par construction */
  #s-home .h-in{animation:none}
  #s-home .hwm-top,#s-age .wm{animation:none;background-position:200% 0,0 0}
}

/* ================= REGLAGES DE SOIREE (refonte 31/07, feu vert Theo) =================
   Valeurs et jetons des rendus soiree-reglages-fiche / soiree-recap / soiree-avances-*
   (references, jamais copiees : reimplantation dans les conventions du projet).
   Corps en rem, jamais en px (UI-06 : le reglage Grand texte doit tout agrandir). */
/* [02/08] le flex du corps vaut pour les TROIS fiches (Soiree, serie de mini-jeux, serie de
   classiques) : scope au seul #sreg-corps, les ressorts des deux autres etaient inertes et
   le contenu collait au haut de page (constate sur la fiche des Classiques a la mesure). */
#sreg-corps,#mreg-corps,#clreg-corps{display:flex;flex-direction:column;flex:1 1 auto}
.sreg-grp{flex:0 0 auto}
/* le mou se repartit, il ne s'entasse pas : ressorts ponderes (.8 entre reglages, 1.8 avant
   la rangee des avances), memes poids que le rendu */
/* minimum a 16 px : la convention posee par l'accueil (v408), le rendu disait 22 mais le
   contenu demande 718 pt pour 714 avec les marges du projet ; l'elasticite absorbe */
.sreg-sp{flex:1 1 auto;min-height:16px}
.sreg-sp.sp-a{flex-grow:.8}
.sreg-sp.sp-b{flex-grow:1.8}
/* le rail des glyphes : colonne fixe de 24 px, les quatre intitules demarrent au meme x */
.sreg-lab{display:grid;grid-template-columns:24px 1fr;column-gap:var(--e-2);align-items:center;min-height:24px;margin-bottom:var(--e-2)}
.sreg-lab svg{width:22px;height:22px;justify-self:center}
.sreg-lab b{font-size:var(--t-1);font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--c-texte-3)}
/* une couleur par reglage, choisie d'apres son symbole (carnet 4bis) ; le violet reste
   entierement a la selection */
.g-amb svg{stroke:#FF9A5C}.g-qui svg{stroke:#7B9BFF}.g-gor svg{stroke:#3FD9B0}.g-dur svg{stroke:#F58FC4}
/* pose, pas creuse : les rangees sont plus claires que la page */
.sreg-seg{display:flex;background:#151319;border:1px solid #2C2736;border-radius:var(--r-2);padding:var(--e-1);gap:var(--e-1)}
.sreg-seg button{flex:1 1 0;min-width:0;min-height:38px;padding:var(--e-2) var(--e-1);border-radius:var(--r-1);display:grid;place-items:center;
  font-family:inherit;border:0;background:none;cursor:pointer;
  font-size:var(--t-1);font-weight:600;color:var(--c-texte-3);transition:background .16s,color .16s}
/* un violet PLUS SOMBRE que le bouton (#6D3FE0) : les selections marquent sans rivaliser */
.sreg-seg button[aria-pressed="true"]{background:#6D3FE0;color:var(--c-texte);font-weight:700}
.sreg-crans button{padding:var(--e-2) 2px;font-size:var(--t-2);font-weight:700;font-variant-numeric:tabular-nums}
.sreg-crans svg{width:21px;height:21px;stroke:currentColor;stroke-width:1.7}
/* la description nomme son choix : nom en graisse 700, deux-points, meme encre ; alignee sur
   l'interieur du cadre (4 px), pas sur son trait */
.sreg-dit{margin-top:var(--e-2);padding-left:var(--e-1);font-size:var(--t-1);line-height:1.4;color:var(--c-texte-3)}
.sreg-dit b{font-weight:700}
/* reglages avances : la seule rangee creusee de l'ecran (l'anatomie de la rangee trinkeurs) */
.sreg-avance{flex:0 0 auto;display:flex;align-items:center;gap:var(--e-3);width:100%;text-align:left;
  font-family:inherit;cursor:pointer;
  background:#0A090E;border:1px solid #38304A;box-shadow:inset 0 1px 2px rgba(0,0,0,.5);
  border-radius:var(--r-2);padding:var(--e-2) var(--e-3) var(--e-2) var(--e-2);font-size:var(--t-1);font-weight:600;color:var(--c-texte-3);
  transition:transform .16s,border-color .16s}
.sreg-avance:active{transform:scale(.99);border-color:#4A4160}
.sreg-pastille{width:30px;height:30px;flex:0 0 auto;border-radius:var(--r-1);background:#231F2E;display:grid;place-items:center}
.sreg-pastille svg{width:16px;height:16px;stroke:#BFB7CE;stroke-width:1.7}
/* la rangee annonce ce qui a ete exclu : "Tout", sinon le compte des exclusions */
.sreg-val{margin-left:auto;font-size:var(--t-1);font-weight:600;color:var(--c-texte-3)}
/* [01/08] a l'etat par defaut la valeur est vide : le chevron reprend le bord droit */
.sreg-val:empty{display:none}
.sreg-avance .sreg-ch{margin-left:auto}
.sreg-val:not(:empty)+.sreg-ch{margin-left:10px}
.sreg-ch{flex:0 0 auto;width:8px;height:14px;stroke:#6E6684}
.sreg-go{width:100%;margin-top:var(--e-3)}
/* [01/08, rendu fiche v30] l'en-tete de la Soiree s'allege : le bouton retour etait seul dans
   sa rangee face a un titre, sans jumeau pour l'equilibrer, et colle au premier intitule.
   36 px visuels, CIBLE TACTILE MAINTENUE A 44 par un ::after qui deborde de 4 px de chaque
   cote (le mecanisme que le socle prevoit pour les pastilles) ; chevron reduit dans la meme
   proportion (36 % du bouton) ; ecart sous l'en-tete porte a 18 px.
   Cible #s-sreg seulement : les autres ecrans gardent l'en-tete standard de l'app.
   Releve honnete : en prod le bouton faisait 44 et l'ecart 6 (pas 40 et 14 comme le rendu
   le croyait) ; l'intention s'applique aux valeurs reelles. */
#s-sreg .topbar{margin-bottom:var(--e-3)}
#s-sreg .iconbtn{position:relative;width:36px;height:36px;font-size:var(--t-1)}
#s-sreg .iconbtn::after{content:'';position:absolute;inset:-4px}
@media (max-width:390px){
  .sreg-crans button{font-size:var(--t-1)}
}
/* sous 340 px, les rangees de quatre passent sur deux lignes de deux plutot que de tronquer */
@media (max-width:340px){
  .sreg-quatre{flex-wrap:wrap}
  .sreg-quatre button{flex:1 1 calc(50% - 3px)}
}

/* ---- la fenetre de verification "On y va ?" ---- */
/* voile clair avec flou statique de 3 px ; repli sans backdrop-filter : voile a 72 % */
.srecap-voile{align-items:center;justify-content:center;background:rgba(6,6,8,.72);z-index:90}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .srecap-voile{background:rgba(6,6,8,.52);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
}
/* hauteur plafonnee et defilement interne : le Grand texte ne doit rien casser */
.srecap-fen{margin:0 auto;width:calc(100% - 32px);max-width:436px;
  max-height:calc(100dvh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px) - 44px);
  overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:var(--e-4) var(--e-3) var(--e-3);border-radius:var(--r-3);background:#0C0C0F;border:1px solid #342E44;
  box-shadow:0 30px 70px -28px rgba(0,0,0,.9)}
.srecap-h{padding:0 var(--e-1);font-size:var(--t-3);font-weight:700;letter-spacing:-.02em;text-align:center}
.srecap-chapo{padding:0 var(--e-1);margin-top:var(--e-1);margin-bottom:var(--e-3);font-size:var(--t-1);line-height:1.4;color:var(--c-texte-3);text-align:center}
.srecap-lignes{display:flex;flex-direction:column;gap:var(--e-2)}
/* quatre rangees touchables, ancrees sur la pastille et la valeur (pas sur le centre) */
.srecap-ligne{display:flex;align-items:flex-start;gap:var(--e-3);width:100%;text-align:left;
  font-family:inherit;cursor:pointer;color:var(--c-texte);
  background:#151319;border:1px solid #2C2736;border-radius:var(--r-3);padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);
  transition:transform .16s,border-color .16s}
.srecap-ligne:active{transform:scale(.99);border-color:#3E3650}
.srecap-gauche{flex:0 0 auto;width:74px;display:flex;flex-direction:column;align-items:center;gap:var(--e-2)}
.srecap-gauche small{font-size:var(--t-1);font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--c-texte-3);text-align:center;line-height:1.2}
.srecap-pic{width:44px;height:44px;flex:0 0 auto;border-radius:var(--r-2);display:grid;place-items:center}
.srecap-pic svg{width:24px;height:24px;stroke-width:1.7}
.p-amb{background:rgba(255,154,92,.15)}.p-amb svg{stroke:#FF9A5C}
.p-qui{background:rgba(123,155,255,.15)}.p-qui svg{stroke:#7B9BFF}
.p-gor{background:rgba(63,217,176,.14)}.p-gor svg{stroke:#3FD9B0}
.p-dur{background:rgba(245,143,196,.14)}.p-dur svg{stroke:#F58FC4}
.srecap-txt{min-width:0;flex:1 1 auto;padding-top:var(--e-3)}
.srecap-txt b{display:block;font-size:var(--t-2);font-weight:700;letter-spacing:-.01em;color:var(--c-texte);line-height:1.15}
/* etiquettes, pas des phrases : aucun point final ici (regle des sous-titres, 30/07) */
.srecap-txt i{display:block;margin-top:var(--e-1);font-style:normal;font-size:var(--t-1);line-height:1.32;color:var(--c-texte-3)}
.srecap-ligne .sreg-ch{align-self:center}
.srecap-go{width:100%;margin-top:var(--e-3)}
.srecap-retour{width:100%;margin-top:var(--e-2);padding:var(--e-3);border-radius:var(--r-3);border:1px solid #332C44;
  font-family:inherit;background:none;cursor:pointer;
  font-size:var(--t-1);font-weight:600;color:var(--c-texte-3);transition:border-color .16s,color .16s}
.srecap-retour:active{border-color:#4A4160;color:var(--c-texte)}
@media (max-width:390px){
  .srecap-txt b{font-size:var(--t-2)}
  .srecap-h{font-size:var(--t-3)}
}

/* ---- les reglages avances : trois sections depliantes ---- */
/* la rangee d'en-tete garde sa hauteur A LA MAIN : la fleche de retour qui la tenait a 40 px
   n'existe pas ici (deux sorties en bas), lecon du carnet 4bis */
.sav-top{display:grid;grid-template-columns:40px 1fr 40px;align-items:center;flex:0 0 auto;min-height:44px;margin-bottom:var(--e-4)}
.sav-titre{grid-column:2;justify-self:center;display:flex;align-items:center;gap:var(--e-2);font-size:var(--t-3);font-weight:700;letter-spacing:-.02em}
.sav-titre svg{width:20px;height:20px;flex:0 0 auto;stroke:#BFB7CE}
/* une section = une carte qui s'ouvre : la grille apparait DANS la meme carte */
.sav-sec{flex:0 0 auto;background:#151319;border:1px solid #2C2736;border-radius:var(--r-3);overflow:hidden}
.sav-sec+.sav-sec{margin-top:var(--e-3)}
.sav-tete{display:grid;grid-template-columns:24px 1fr 16px;align-items:center;column-gap:var(--e-2);width:100%;min-height:56px;padding:0 var(--e-3);text-align:left;
  font-family:inherit;background:none;border:0;cursor:pointer;color:var(--c-texte);transition:background .16s}
.sav-tete:active{background:rgba(255,255,255,.04)}
.sav-tete>svg:first-child{width:22px;height:22px;justify-self:center;stroke-width:1.6}
.s-car .sav-tete>svg:first-child{stroke:#A78BFA}
.s-min .sav-tete>svg:first-child{stroke:#FCD34D}
.s-suj .sav-tete>svg:first-child{stroke:#F58FC4}
.sav-tete b{font-size:var(--t-1);font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--c-texte)}
.sav-chb{width:16px;height:10px;stroke:#6E6684;transition:transform .2s}
.sav-tete[aria-expanded="true"] .sav-chb{transform:rotate(180deg)}
/* la description vit HORS du panneau : visible section repliee, elle dit ce qu'elle cache */
.sav-dit{margin:-3px 15px 0;padding-bottom:var(--e-3);font-size:var(--t-1);line-height:1.45;color:var(--c-texte-3)}
.sav-panneau{padding:0 var(--e-3) var(--e-3)}
/* grille de deux colonnes egales ; cellules a 44 px, la cible tactile, un libelle long s'y
   enroule sans faire grandir la rangee */
.sav-grille{display:grid;grid-template-columns:1fr 1fr;gap:2px var(--e-2)}
.sav-cel{display:flex;align-items:center;gap:var(--e-2);min-height:44px;padding:0 var(--e-2);border-radius:var(--r-2);text-align:left;
  font-family:inherit;background:none;border:0;cursor:pointer;color:var(--c-texte-3);transition:background .16s}
.sav-cel:active{background:rgba(255,255,255,.05)}
/* le carre porte l'etat, jamais le fond : une case cochee se lit meme quand toutes le sont */
.sav-case{width:21px;height:21px;flex:0 0 auto;border-radius:var(--r-1);border:1.6px solid #4A4160;display:grid;place-items:center;transition:background .16s,border-color .16s}
.sav-case svg{width:12px;height:12px;stroke:#170B20;stroke-width:2.7;opacity:0;transition:opacity .16s}
.sav-cel[aria-pressed="true"] .sav-case{background:#8B5CF6;border-color:transparent}
.s-min .sav-cel[aria-pressed="true"] .sav-case{background:#FCD34D}
.s-suj .sav-cel[aria-pressed="true"] .sav-case{background:#F58FC4}
.sav-cel[aria-pressed="true"] .sav-case svg{opacity:1}
.sav-nom{flex:1 1 auto;min-width:0;font-size:var(--t-1);font-weight:600;letter-spacing:-.01em;color:var(--c-texte-3);line-height:1.2}
.sav-cel[aria-pressed="true"] .sav-nom{color:var(--c-texte)}
/* le Doigt du destin grise au-dela de 5 joueurs (multitouch iPhone) : refuse, et le dit au tap */
.sav-cel.off{opacity:.4}
/* le seul ressort plafonne du projet : 64 px d'ecart franc, le reste tombe SOUS les boutons */
/* minimum a 16 px (convention accueil v408) : a 24, les sections Jeux et Sujets ouvertes
   defilaient de 2 pt a 714 avec les marges du projet */
.sav-sp{flex:1 1 auto;min-height:16px;max-height:64px}
#sav-ok{width:100%}
/* "Annuler" : un cran au-dessus du muet (encre #BFB7CE, lisere discret), jamais une surface
   pleine : une seule chose porte de la matiere par ecran, et c'est "Valider" */
.sav-annuler{flex:0 0 auto;width:100%;margin-top:var(--e-2);padding:var(--e-3);border-radius:var(--r-3);border:1px solid #332C44;
  font-family:inherit;background:none;cursor:pointer;
  font-size:var(--t-2);font-weight:600;color:var(--c-texte-2);transition:color .16s,border-color .16s}
.sav-annuler:active{color:var(--c-texte);border-color:#4A4160}
@media (max-width:390px){
  .sav-nom{font-size:var(--t-1)}
  .sav-tete b{font-size:var(--t-1)}
}

/* ============ VAGUE MINI-JEUX (01/08) : lanceur + serie aleatoire en or ============
   References : mini-jeux-allege v6 (fusion entree + catalogue, 02/08), minijeux-serie-reglages
   v13, -avances v6, -recap v8.
   La structure reutilise les classes de la fiche de Soiree (sreg-, sav-, srecap-) ; ici ne
   vivent que le lanceur et les surcharges or/dimensions, ciblees par ecran.
   (Meme piege etoile-barre que le bloc Classiques : ce commentaire se fermait a « sreg-* »
   suivi d'une barre et jetait la regle .mjh-top au parsing depuis v423. Corrige le 02/08.) */
/* -- l'ecran d'entree (fusion 02/08 : le lanceur porte aussi son catalogue) -- */
#s-mjhub .mjh-top,#s-clhub .mjh-top{display:flex;align-items:center;flex:0 0 auto;min-height:44px;margin-bottom:var(--e-3)}
/* ⚠️ UN SEUL BOUTON RETOUR POUR LES ECRANS D'ENTREE (Theo, 05/08, sur captures). « Qui
   joue ? » portait le sien : 32x32, rayon 12, ses propres fond et bordure en dur, et un
   chevron DESSINE (svg 12 px, graisse 2,2) la ou les lanceurs posent le glyphe de la
   police a 13 px. Deux boutons a la meme place, a deux touchers l'un de l'autre, dont un
   plus gros et plus gras : l'ecart se voyait avant de se mesurer.
   ⚠️ ON LE FAIT ENTRER DANS LA REGLE EXISTANTE, ON NE RECOPIE PAS SES VALEURS. Recopier
      aurait cree une deuxieme source de verite qui aurait diverge a la premiere retouche
      des lanceurs. La cible tactile reste a 44 (36 vus + 4 de debord de chaque cote). */
#s-mjhub .iconbtn,#s-clhub .iconbtn,#s-clreg .iconbtn,
:is(#s-joueurs,#s-home) .jr-retour{position:relative;width:36px;height:36px;font-size:var(--t-1)}
#s-mjhub .iconbtn::after,#s-clhub .iconbtn::after,#s-clreg .iconbtn::after,
:is(#s-joueurs,#s-home) .jr-retour::after{content:'';position:absolute;inset:-4px}
.mjh-titre{flex:0 0 auto;display:flex;align-items:center;justify-content:center;margin-bottom:var(--e-2)}
.mjh-titre h1{font-size:var(--t-5);font-weight:800;letter-spacing:-.03em;line-height:1}
/* la seule coloration de texte de l'app : le titre EST l'objet principal, pas de carte au-dessus
   pour porter la couleur du mode. Aplat, aucun degrade (il appartient au mot-symbole). */
.mjh-titre h1 i{font-style:normal;color:#FCD34D}
/* [02/08] 30 px sous le chapo (etait 22) : un ecart de tete ne doit jamais etre le plus
   petit de la page. Les RESSORTS mjh-sp sont morts avec la fusion : une page qui defile
   n'a plus rien a etirer, c'est ce remplacement qui tient l'ecart. */
.mjh-chapo{flex:0 0 auto;margin-bottom:var(--e-5);padding:0 var(--e-2);font-size:var(--t-2);line-height:1.45;color:var(--c-texte-3);text-align:center}
/* le separateur des deux chemins : une PHRASE centree (pas une etiquette de famille) —
   bas de casse, 15 px, gris clair, sans glyphe, flottant a 34 px de part et d'autre.
   Six ecarts avec les intitules de famille, aucun n'est un reglage de gout. */
.mjh-sep{flex:0 0 auto;margin:var(--e-5) 0;text-align:center;font-size:var(--t-2);font-weight:700;
  letter-spacing:-.01em;color:var(--c-texte-3)}
/* min-height et non height : en Grand texte le contenu doit pouvoir pousser */
.mjh-carte{position:relative;overflow:hidden;flex:0 0 auto;width:100%;min-height:178px;
  padding:var(--e-4) var(--e-4) var(--e-3);border-radius:var(--r-3);text-align:left;font-family:inherit;cursor:pointer;
  color:var(--c-texte);transition:transform .16s}
.mjh-carte:active{transform:scale(.99)}
/* [03/08, Theo] LA CARTE DE SERIE REPREND EXACTEMENT LA COULEUR DE SA TUILE D'ACCUEIL.
   Elle etait deux crans en dessous (#AF8427 -> #81611C, un or rabattu) : on touchait une tuile
   OR et on arrivait sur une carte MOUTARDE, la couleur ne suivait pas le doigt. Meme rampe que
   #s-home .hminijeux, stop pour stop, meme angle 128deg : deux surfaces de la meme famille ne
   peuvent pas avoir deux couleurs. (Remplace la valeur figee du 01/08, sur ordre de Theo.)
   (La carte Catalogue mjh-cata est morte avec la fusion du 02/08 : ses regles partent.) */
/* ⚠️⚠️ [08/08, Theo] L'ACCUEIL FAIT FOI POUR TOUTES LES COULEURS DE MODE : « les couleurs de
   reference pour toute l'app en fonction des modes de jeux sont sur la page principale ».
   Cette carte s'en ecartait, et le commentaire du 03/08 juste au-dessus affirmait pourtant
   qu'elle reprenait la rampe « stop pour stop, meme angle ». Mesure : 5/0/39 d'ecart sur la
   crete de l'or, 3/42/3 sur celle du fuchsia, et jusqu'a 22 sur un plateau. DEUX DESSINS
   PRESQUE IDENTIQUES SONT PIRES QUE DEUX DESSINS DIFFERENTS : on ne les distingue pas, on les
   sent. Et un commentaire qui affirme une egalite fausse est pire que pas de commentaire — il
   dispense de verifier.
   Les deux cartes prennent donc la rampe EXACTE de leur tuile d'accueil, angle compris
   (148°, quatre arrets, plateau repete de 40 a 72 %), comme les tuiles de catalogue posees le
   meme jour. Les trois surfaces d'un mode ne peuvent plus diverger : elles lisent la meme
   valeur. */
.mjh-alea{background:linear-gradient(148deg,#D9A32B 0%,#996A11 40%,#996A11 72%,#7E560B 100%);
  border:1px solid rgba(252,211,77,.34)}
/* la filigrane : plus claire que son fond (blanc chaud .21), taillee dans la carte, descendue
   a -52 pour ne pas passer derriere le chevron */
.mjh-fil{position:absolute;right:-28px;bottom:-52px;width:194px;height:194px;fill:none;
  stroke:rgba(255,246,220,.21);stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.mjh-dedans{position:relative;display:block}
.mjh-mi{width:44px;height:44px;border-radius:var(--r-2);display:grid;place-items:center;margin-bottom:var(--e-4);
  background:rgba(252,211,77,.17)}
.mjh-mi svg{width:21px;height:21px;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
/* [03/08] LA PASTILLE SUIT LE FOND, ELLE NE PEUT PAS RESTER. Un carre or a 17 % et un glyphe
   #FBBF24 se lisaient sur l'or rabattu ; sur l'or de marque ils sont la MEME couleur que leur
   fond et disparaissent. Traitement de la tuile d'accueil repris tel quel : encre de la famille
   (--ink-or) en creux, glyphe blanc, chevron a la meme encre. */
.mjh-alea .mjh-mi{background:rgba(42,27,2,.26)}
.mjh-alea .mjh-mi svg{stroke:#FFFFFF}
.mjh-alea .mjh-ch{stroke:rgba(42,27,2,.55)}
.mjh-carte b{display:block;font-size:var(--t-4);font-weight:800;letter-spacing:-.02em;line-height:1.1;color:var(--c-texte)}
.mjh-carte p{margin-top:var(--e-2);font-size:var(--t-1);line-height:1.4;max-width:14em;color:rgba(255,255,255,.8)}
/* [03/08] SUR LA COULEUR PLEINE, LA DESCRIPTION PASSE EN BLANC ENTIER. Un blanc a 80 % tenait
   sur les fonds rabattus ; sur la teinte de marque il se dilue. Meme decision qu'a l'accueil
   (02/08, prise par Theo en connaissance des contrastes) : les surfaces de marque ecrivent en
   blanc, l'ecart a 4,5:1 est VOULU et ecrit, ne pas le « reparer ». */
.mjh-alea b,.clh-alea b{color:var(--c-texte)}
.mjh-alea p,.clh-alea p{color:var(--c-texte)}
/* chevron en haut a droite : entorse assumee au socle, la filigrane traverse la bande mediane */
.mjh-ch{position:absolute;right:18px;top:18px;width:9px;height:15px;fill:none;
  stroke:rgba(252,211,77,.62);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
@media (max-width:390px){
  .mjh-titre h1{font-size:var(--t-4)}
  .mjh-carte p{font-size:var(--t-1)}
}
/* -- le catalogue v14 (02/08) : familles a glyphe gris, tuiles or plates, deux colonnes --
   Seize tuiles de meme rang : aucune matiere (le socle veut zero quand rien ne domine), et
   elles sont plus discretes que les deux cartes du lanceur (.16/.07 contre .48/.20) : seize
   tuiles dorees a valeurs egales feraient un mur. L'ecran defile, c'est un catalogue. */
.cat-fam{display:flex;align-items:center;gap:var(--e-2);margin:var(--e-5) 2px var(--e-3);font-size:var(--t-1);
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--c-texte-3)}
/* [02/08] fusion : le separateur porte deja les 34 px au-dessus de la premiere famille */
.cat-fam:first-child{margin-top:0}
.cat-fam svg{width:14px;height:14px;flex:0 0 auto;stroke:#8A82A6}
.cat-grille{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2)}
/* min-height et jamais height : le Grand texte doit pouvoir pousser ; deux lignes reservees
   a la description meme quand elle n'en fait qu'une (sinon le contenu PARAIT remonter) */
.jeu{position:relative;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
  min-height:124px;padding:var(--e-3) var(--e-3) var(--e-3);border-radius:var(--r-3);text-align:left;font-family:inherit;cursor:pointer;
  color:var(--c-texte);background:linear-gradient(155deg,rgba(252,211,77,.16),rgba(251,191,36,.07));
  border:1px solid rgba(252,211,77,.20);transition:transform .16s,border-color .16s}
.jeu:active{transform:scale(.98);border-color:rgba(252,211,77,.42)}
/* 26 px (glyphe de carte pleine secondaire, valeur de l'echelle) ; le trait reste a 1,7 */
.jeu svg{width:26px;height:26px;flex:0 0 auto;stroke:#FCD34D}
.jeu b{display:block;margin-top:var(--e-2);font-size:var(--t-2);font-weight:700;letter-spacing:-.01em;
  color:var(--c-texte);line-height:1.15}
.jeu small{display:block;margin-top:var(--e-1);font-size:var(--t-1);line-height:1.32;
  min-height:calc(0.75rem * 1.32 * 2);color:var(--c-texte-3)}
@media (max-width:390px){
  .jeu b{font-size:var(--t-2)}
}
/* ============ VAGUE CLASSIQUES (02/08) : lanceur + serie aleatoire en fuchsia ============
   References : classiques-allege v6 (fusion entree + catalogue, 02/08), classiques-serie-reglages v3,
   classiques-serie-avances v4. La structure reutilise les classes mjh-, sreg-, sav- et
   cat- ; ici ne vivent que les surcharges fuchsia, ciblees par ecran.
   PIEGE PAYE EN LIGNE (v428) : ce commentaire ecrivait « mjh-* / sreg-* » avec etoile-barre
   colles, ce qui FERMAIT le commentaire au premier d'entre eux ; le debris avalait la regle
   fuchsia du titre, jetee au parsing, et les deux grands titres s'affichaient OR (la couleur
   des Mini-jeux). Jamais d'etoile suivie d'une barre dans un commentaire CSS. */
/* le second mot du titre prend la couleur du mode : fuchsia ici, or aux Mini-jeux.
   [02/08] fusion : s-classics est mort, le lanceur s-clhub porte tout l'ecran. */
#s-clhub .mjh-titre h1 i{color:#F9A8D4}
/* [03/08, Theo] MEME CORRECTION QU'AUX MINI-JEUX, ET C'EST ICI QU'ELLE SAUTAIT LE PLUS AUX
   YEUX : le rose #C46C9B -> #975377 est un fuchsia DELAVE, la tuile de l'accueil est franche.
   La carte reprend la rampe exacte de #s-home .hclassiques, stop pour stop, angle 128deg.
   La pastille suit le fond (le rose pale #FFB4D9 s'annule sur du fuchsia plein) : encre de la
   famille en creux, glyphe blanc, chevron a la meme encre.
   (La carte Catalogue clh-cata est morte avec la fusion du 02/08.) */
.clh-alea{background:linear-gradient(148deg,#F45CC0 0%,#D22C96 40%,#D22C96 72%,#B01A7C 100%);
  border:1px solid rgba(249,168,212,.34)}
.clh-alea .mjh-fil{stroke:rgba(255,246,220,.21)}
.clh-alea .mjh-mi{background:rgba(42,10,25,.26)}
.clh-alea .mjh-mi svg{stroke:#FFFFFF}
.clh-alea .mjh-ch{stroke:rgba(42,10,25,.55)}
/* le catalogue des Classiques : les tuiles .jeu passent au fuchsia sur cet ecran */
#s-clhub .jeu{background:linear-gradient(155deg,rgba(249,168,212,.16),rgba(236,72,153,.07));
  border:1px solid rgba(249,168,212,.20)}
#s-clhub .jeu:active{border-color:rgba(249,168,212,.42)}
/* [03/08, Theo] LES GLYPHES DU CATALOGUE PRENNENT LE ROSE DE LA MARQUE, PAS SON TON PALE.
   Mesure faite sur la capture AVANT de toucher : les cinq glyphes etaient deja identiques
   entre eux au pixel (#F9A8D4, la meme valeur que le grand titre) — ce qui manquait, c'est
   qu'ils portaient le ton CLAIR de la famille quand la carte, elle, porte la teinte de marque.
   Deux roses sur le meme ecran, dont un pastel. Ils passent a #EC4899, la valeur de la famille
   au socle, celle qui teinte deja le fond de ces tuiles (rgba(236,72,153,.07)).
   ⚠️ MESURE : sur le fond reel des tuiles (releve a #281C26), #EC4899 rend 4,76:1, donc au-dessus
      du seuil des objets graphiques (3:1) ET de celui du texte (4,5:1). Le stop median exact de
      la carte (#E81F82) serait d'un cran plus vif mais tombe a 3,96:1 : ecarte pour cette raison,
      pas par gout. */
#s-clhub .jeu svg{stroke:#EC4899}
/* GD-23 : la tuile desactivee garde la teinte du mode, l'OPACITE la met en retrait ; le
   gris est reserve a ce qui ne repond pas du tout (elle, elle dit sa condition) */
#s-clhub .jeu[aria-disabled="true"]{opacity:.42;cursor:default}
#s-clhub .jeu[aria-disabled="true"]:active{transform:none;border-color:rgba(249,168,212,.20)}
#s-clhub .jeu[aria-disabled="true"] small{color:var(--c-texte-3)}
/* la fiche de serie : deux groupes, cellules 46 reelles, selection fuchsia sombre a texte
   BLANC (contrairement a l'or : le fuchsia #A31857 reste sombre, le blanc y tient) */
#s-clreg .topbar{margin-bottom:var(--e-3)}
#s-clreg .sreg-seg button{min-height:46px;padding:var(--e-2) var(--e-1)}
#s-clreg .sreg-seg button[aria-pressed="true"]{background:#A31857;color:var(--c-texte)}
#s-clreg .sreg-go{background:linear-gradient(128deg,#F9A8D4 0%,#EC4899 46%,#C42A72 100%);color:#2A0A19}
/* les avances : deux sections ouvertes (pas de depliant), coche fuchsia a l'encre du mode,
   sujets roses ; la tete n'est pas touchable */
#s-clavances .sav-tete{cursor:default}
#s-clavances .sav-tete:active{background:transparent}
#s-clavances .sav-panneau{padding-top:var(--e-2)}
#s-clavances .s-car .sav-tete>svg:first-child{stroke:#F9A8D4}
#s-clavances .s-car .sav-cel[aria-pressed="true"] .sav-case{background:#EC4899}
#s-clavances .sav-case svg{stroke:#2A0A19}
#s-clavances .sreg-go{background:linear-gradient(128deg,#F9A8D4 0%,#EC4899 46%,#C42A72 100%);color:#2A0A19}

/* -- la fiche de serie : structure de la Soiree, respiration et or du rendu v13 -- */
#s-mreg .topbar{margin-bottom:var(--e-5)}
#s-mreg .iconbtn{position:relative;width:36px;height:36px;font-size:var(--t-1)}
#s-mreg .iconbtn::after{content:'';position:absolute;inset:-4px}
#s-mreg .sreg-lab{margin-bottom:var(--e-3)}
.g-dif svg{stroke:#FF9A5C}
/* cellules a 46 px REELS : le socle demande 44, ici sans zone etendue */
#s-mreg .sreg-seg button{min-height:46px;padding:var(--e-2) var(--e-1)}
/* la selection : or #C79414 a l'ENCRE SOMBRE, pas du blanc (le blanc tombe sous 4,5:1 sur
   une teinte lumineuse ; une encre par famille de surface coloree, les surfaces or portent
   l'encre or). Ne pas repasser en blanc. */
#s-mreg .sreg-seg button[aria-pressed="true"]{background:#C79414;color:#2A1B02}
#s-mreg .sreg-dit{margin-top:var(--e-2)}
/* ressorts : minimum 16 (convention accueil v408 / fiche Soiree v417) et non les 34 du rendu.
   En taille normale les ressorts s'etirent bien au-dela ; le plancher bas ne sert qu'au Grand
   texte, ou il evite 13 pt de defilement. Adaptation signalee au journal. */
#s-mreg .sreg-avance{padding:var(--e-2) var(--e-3) var(--e-2) var(--e-2)}
#s-mreg .sreg-go{margin-top:var(--e-4);padding:var(--e-4);border-radius:var(--r-3);
  background:linear-gradient(128deg,#FDE68A 0%,#FBBF24 46%,#E09B08 100%);color:#2A1B02}
/* -- les avances de la serie : une liste, pas de depliant ; l'or remplace le violet -- */
#s-mavances .sav-tete{cursor:default}
#s-mavances .sav-tete:active{background:transparent}
/* 8 px de plus entre la consigne et la premiere rangee : l'ouverture gagne de l'air */
#s-mavances .sav-panneau{padding-top:var(--e-2)}
/* la coche porte l'encre des surfaces or */
#s-mavances .sav-case svg{stroke:#2A1B02}
#s-mavances .sreg-go{background:linear-gradient(128deg,#FDE68A 0%,#FBBF24 46%,#E09B08 100%);color:#2A1B02}
/* -- la fenetre « On y va ? » de la serie : la meme que la Soiree, bouton en or -- */
#m-mrecap .srecap-go{background:linear-gradient(128deg,#FDE68A 0%,#FBBF24 46%,#E09B08 100%);color:#2A1B02}
.p-dif{background:rgba(255,154,92,.15)}.p-dif svg{stroke:#FF9A5C}

/* ══════════════════════════════════════════════════════════════════════════════
   THÈME CLAIR — [03/08, demande de Theo, d'après sa maquette du mode clair]

   ⚠️ CE QUE LE RELEVÉ A DIT AVANT D'ÉCRIRE UNE LIGNE. L'app porte 322 couleurs
      passant par une variable, et 835 écrites EN DUR (547 hex, 288 rgba). Un
      thème ne peut donc pas se poser d'un seul geste : ce bloc traite tout ce
      qui passe par les variables (fonds, cartes, textes, filets, modales) et
      l'accueil au pixel. Les écrans de jeu qui portent leurs propres teintes
      (le revolver, le feu, les grilles) gardent les leurs pour l'instant, et
      c'est une passe à part, annoncée.

   ⚠️ LES QUATRE CARTES DE MODE NE CHANGENT PAS D'UN THÈME À L'AUTRE. Mesuré sur
      la maquette : leurs luminances y sont celles qu'on a déjà. C'est ce qui
      rend ce thème sûr, aucun débat de contraste n'est rouvert sur elles.

   Le fond n'est pas un blanc plat : c'est le pendant clair du fond à halos,
   quatre foyers pastel relevés sur la maquette (rose, lavande, pêche, jaune).
   ══════════════════════════════════════════════════════════════════════════ */
html.clair{
  --bg:#F3EEF4;            /* le blanc cassé sous les halos */
  --card:#FFFFFF;
  --line:rgba(23,11,32,.12); --line2:rgba(23,11,32,.22);
  --ink:#191322;           /* le texte principal : un anthracite violacé, jamais du noir pur */
  --dim:#4E4560; --mut:#655C78;
  color-scheme:light;      /* les contrôles natifs et la barre de Safari suivent */
}
/* le second :root du fichier réaffirme --dim et --mut : il faut donc les
   redéclarer ici avec la même spécificité, sinon le thème perd ces deux-là. */
html.clair{--dim:#4E4560;--mut:#655C78}

/* ── LE FOND : quatre foyers pastel, relevés sur la maquette ─────────────── */
html.clair #s-home,
html.clair #s-age{
  background:
    radial-gradient(520px 380px at 4% 2%,   #F7DEE6 0%, transparent 62%),
    radial-gradient(560px 420px at 98% 6%,  #D9D7FB 0%, transparent 64%),
    radial-gradient(480px 520px at -6% 46%, #FAE5DC 0%, transparent 60%),
    radial-gradient(620px 460px at 104% 92%,#E1DBBE 0%, transparent 66%),
    var(--bg);
}
/* tout autre écran : le fond uni, la couleur porte déjà l'écran */
html.clair .screen{background:var(--bg)}
html.clair #s-home,html.clair #s-age{background-color:var(--bg)}

/* ── L'ACCUEIL ───────────────────────────────────────────────────────────── */
/* la rangée des trinkeurs reste SOMBRE sur fond clair : c'est un creux, pas une
   carte. Sur la maquette elle est un gris taupe translucide, et c'est ce qui la
   distingue des quatre cartes de mode, qui, elles, sont pleines. */
html.clair #s-home .h-qui{
  background:rgba(60,48,74,.62);
  border-color:rgba(23,11,32,.18);
  box-shadow:inset 0 1px 3px rgba(23,11,32,.22);
  color:#FFFFFF;
}
html.clair #s-home .h-qui .hchev{stroke:rgba(255,255,255,.72)}
html.clair #s-home .h-qui-d{color:rgba(255,255,255,.78)}
html.clair #s-home .hqi{background:rgba(255,255,255,.16)}
html.clair #s-home .hqi svg{stroke:#EDE7F5}
/* [04/08] la signature de marque a quitte l'accueil : sa regle de theme clair part avec
   elle. La mention legale, elle, reste obligatoire dans les deux themes. */
/* ⚠️ LA MENTION LEGALE EST OBLIGATOIRE, ELLE SE LIT DANS LES DEUX THEMES. Le selecteur
   de l'accueil est .hlegal (et non .legal) : la premiere version de ce bloc ratait sa
   cible et la laissait a 2,08:1 sur le fond clair, le badge 18+ a 1,58:1. */
html.clair .legal p{color:var(--mut)}
html.clair .legal .age{border-color:rgba(23,11,32,.30);color:var(--dim)}
/* [06/08] LES DEUX BOUTONS DE L'EN-TETE, EN CLAIR. La regle vaut maintenant pour les deux
   (elle ne visait que l'engrenage tant que la colonne de droite etait vide), et c'est une
   OBLIGATION, pas une finition : le voile de .045 en blanc est invisible sur un fond clair,
   et l'encre #D8D1E6 du glyphe y tomberait sous 1,5:1. Surface blanche a .86 + ombre douce,
   encre --ink : le meme traitement qu'au 30/07, applique aux deux.
   ⚠️ `border-color` EST RETIRE : le bouton n'a plus de border depuis que le voile a remplace
      le trait (§0.4 du lot). Une declaration qui ne s'applique a rien est un mensonge dans le
      fichier — on la lit et on croit qu'un cadre existe. */
html.clair #s-home .htop>.hicobtn{
  background:rgba(255,255,255,.86);
  box-shadow:0 2px 10px rgba(23,11,32,.10);
  color:var(--ink);
}
/* le disque connecte garde SA matiere dans les deux themes : c'est l'objet de la barre du
   bas, et la barre du bas est claire par construction. Lui poser la surface blanche des
   commandes le ferait disparaitre. */
html.clair #s-home .htop>#home-moi.connecte{background:none;box-shadow:none}

/* ── LES SURFACES COMMUNES DE TOUTE L'APP ────────────────────────────────── */
/* ⚠️ Un <button> ne prend PAS la couleur de son parent : chacun fixe la sienne,
   sinon iOS le rend en bleu système. La règle vaut dans les deux thèmes. */
html.clair body{color:var(--ink)}
html.clair .modal{background:rgba(23,11,32,.38)}
html.clair .sheet,html.clair .card,html.clair .tile{color:var(--ink)}
html.clair .btn.sec,html.clair .btn.ghost{color:var(--ink)}

/* ── LE MOT-SYMBOLE EN CLAIR : deux corrections, et toutes deux mesurees ──────
   1. LE REFLET EST BLANC. Sur du noir c'est un eclat ; sur un fond pastel il
      LAVE le mot, qui disparait au passage de la bande. Il devient un voile
      SOMBRE : le meme balayage, lu a l'envers.
   2. LES QUATRE TEINTES SONT TROP CLAIRES POUR UN FOND CLAIR. Mesure sur
      #F3EEF4 : l'or rend 1,46:1, le turquoise 1,63, le violet 2,38, le fuchsia
      3,08. Versions foncees a teinte et saturation constantes, calees a 4:1
      (le mot est du grand texte, seuil 3, on garde de la marge). */
html.clair #s-age .wm{
  --teintes:#986F03,#E0177B,#7F56F8,#1B8376;
  background-image:
    linear-gradient(102deg,rgba(23,11,32,0) 0%,rgba(23,11,32,.30) 50%,rgba(23,11,32,0) 100%),
    linear-gradient(90deg,var(--teintes));
}
/* la signature sous la marque suit le meme raisonnement */
html.clair #s-home .hwm-top{--teintes:#986F03,#E0177B,#7F56F8,#1B8376}

/* ══════════════════════════════════════════════════════════════════════════════
   MULTIJOUEUR · LA LISTE DES FILS — [03/08] portage du rendu multijoueur-fils,
   validé sur téléphone le 02/08. Les classes portent le préfixe `mu-` : la
   maquette nomme `.fil`, `.tete`, `.nom`, `.heure`, `.ligne`, `.ch`, tous déjà
   pris ailleurs dans l'app.

   ⚠️ CHAQUE VALEUR CI-DESSOUS EST UNE DÉCISION DU CARNET, PAS UN RÉGLAGE. Les
      commentaires disent le pourquoi ; les retirer, c'est rouvrir des débats qui
      ont coûté plusieurs passes sur l'appareil.
   ══════════════════════════════════════════════════════════════════════════ */

/* ⚠️ LA RANGÉE EST UNE GRILLE À QUATRE COLONNES, pas un flex : l'aperçu doit
   pouvoir courir SOUS l'heure (il occupe deux colonnes), ce qu'un flex ne
   permet pas sans imbriquer un conteneur de plus. */
.mu-fil{display:grid;grid-template-columns:44px 1fr auto 12px;
  grid-template-rows:auto auto;align-items:center;
  position:relative;column-gap:var(--e-2);row-gap:0;width:100%;min-height:79px;
  /* rembourrage asymétrique : 10 en haut, 21 en bas. Le bloc de texte est CENTRÉ
     dans la rangée, donc le raccourcir le recentre au lieu de remonter l'aperçu.
     C'est le rembourrage qui remonte l'aperçu sans déplacer le nom. */
  /* ⚠️ 18 DE REMBOURRAGE LATERAL, ET C'EST LA MARGE DE PAGE, PAS UNE COTE DE RANGEE.
     L'ecran redeclarait sa marge bloc par bloc — 14 pour la ligne d'outils, 16 pour les
     rangees — et trois marges pour une seule page donnent trois bords gauches. Les cotes
     VERTICALES, elles, ne bougent pas : le 10/21 est le resultat du recentrage documente
     juste au-dessus. */
  padding:var(--e-2) var(--e-3) var(--e-4);text-align:left;
  /* ⚠️ background/border/color/font/cursor SONT ECRITS ICI ET NE SE RETIRENT JAMAIS :
     cette feuille n'a AUCUN reset global sur `button`. Sans eux le navigateur peint la
     rangee lui-meme — fond gris, bordure 2px outset, Arial 13,3 px. Faute payee quatre
     fois sur ce projet, la derniere en production le 07/08 sur trois rangees. */
  background:transparent;border:0;color:inherit;font:inherit;cursor:pointer;
  transition:background .34s cubic-bezier(.22,.9,.25,1)}
/* ⚠️ LE FILET VA D'UN BORD À L'AUTRE ET LA LISTE EST FERMÉE AUX DEUX BOUTS : un
   filet au-dessus de la première rangée, un sous la dernière. Sans eux la liste
   n'a ni début ni fin, elle se dissout dans le fond en haut et s'arrête dans le
   vide en bas. Ce sont eux qui en font UN objet. */
/* ⚠️ [07/08] LE FILET PASSE AU PIXEL PHYSIQUE, comme celui de la vitrine d'Amis. Il
   valait `1px` a .042 : a 3x, TROIS pixels physiques peints faiblement, donc un trait
   epais et sale la ou on veut un cheveu. Une hauteur est de la MISE EN PAGE, arrondie
   avant peinture — elle ne peut pas valoir .34 ; on garde donc une boite d'un pixel
   plein qu'un `scaleY(.34)` ecrase, et l'opacite monte a .13 puisqu'un trait trois fois
   plus fin rend trois fois moins d'encre (.13 x .34 = .044, l'encre d'avant).
   ⚠️ IL PART DE 72 ET S'ARRETE A 18 : il commence exactement la ou le NOM commence
      (18 de marge + 44 de colonne d'avatar + 10 de gouttiere) et finit sur la marge de
      page. S'il restait a 70/16 il serait decale de 2 px du nom, et ce decalage se
      verrait plus que le filet lui-meme. */
.mu-fil::after{content:'';position:absolute;left:72px;right:18px;bottom:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.13)}
/* le filet du haut se pose par une CLASSE, jamais par une position : sur
   `:first-of-type` il matche un élément PAR TYPE, donc le premier paragraphe ET
   le premier bouton, et il en posait trois dans l'écran à invitation.
   ⚠️ [07/08] IL VISE LE PREMIER OBJET DE LA LISTE, QUEL QUE SOIT SON TYPE : quand une
      invitation ouvre la liste, c'est ELLE qui en est le debut. Le selecteur ne peut donc
      plus s'accrocher a `.mu-fil` seul, sinon la liste n'a pas de bord haut ce jour-la et
      en gagne un au milieu le lendemain. */
#s-multi .mu-liste>.premier::before{content:'';position:absolute;left:72px;right:18px;top:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.13)}
/* le non-lu gagne un voile, seule variation de fond de la liste : il remplace le
   point supprimé, se voit en balayant, et ne coûte aucun objet. */
.mu-fil.nl{background:rgba(168,178,225,.045)}
/* ⚠️ L'APPUI RÉPOND VITE ET SE RETIRE LENTEMENT : 90 ms pour s'allumer, 340 pour
   s'éteindre. C'est ce rapport qui donne une surface qui réagit plutôt qu'un
   bouton qui clignote ; l'inverse ferait traînard. */
.mu-fil:active{background:rgba(94,234,212,.085);transition:background .09s}
@media (hover:hover){.mu-fil:hover{background:rgba(168,178,225,.075)}}
.mu-fil>.mu-ava{grid-area:1/1/3/2;margin-top:var(--e-1)}
.mu-fil>.mu-tete{grid-area:1/2/2/3}
.mu-fil>.mu-heure{grid-area:1/3/2/4;justify-self:end}
.mu-fil>.mu-ch{grid-area:1/4/3/5;align-self:center;justify-self:end}
.mu-fil>.mu-ligne{grid-area:2/2/3/4}
/* ⚠️ LE NON-LU N'EST PLUS UN OBJET, C'EST DU CONTRASTE, et le sens ne repose pas
   sur la couleur seule : la graisse et l'encre changent ensemble. */
.mu-fil.nl .mu-nom{font-weight:800}
.mu-fil.nl .mu-ligne span{color:var(--c-texte-2);font-weight:600}
.mu-fil.nl .mu-heure{color:#4FBFB4;font-weight:600}

/* ⚠️ TOUS LES BLOCS D'AVATAR FONT EXACTEMENT 40 px, quel que soit le nombre de
   personnes : c'est ce qui garde UNE colonne alignée au défilement. Un groupe se
   remarque par le CHEVAUCHEMENT, jamais par la largeur.
   ⚠️ L'ANNEAU EST LA CAUSE QU'AUCUN CALCUL NE VOIT : une ombre portée ne compte
      pas dans la largeur d'un élément. Les blocs se calent sur 38 pour que
      l'anneau de 2 px tombe pile à 40. */
.mu-ava{position:relative;width:40px;height:42px;margin-left:2px;
  display:flex;align-items:center;justify-content:flex-start}
/* ⚠️⚠️ [07/08] LA PASTILLE PREND LA PALETTE DES AMIS, ET C'EST UNE SOURCE UNIQUE. Elle
   portait cinq couleurs ecrites en attribut `style`, calculees par `muTeinte` sur le
   PSEUDO et inventees pour ce seul ecran. Deux consequences, toutes deux mesurables :
   le meme ami n'avait pas la meme teinte dans Amis et dans Discussions, et une teinte
   ecrite dans le markup echappe a tout controle — elle ne se change pas d'un endroit et
   rien n'empeche la sixieme.
   La couleur vient donc de `.am-av1..8` (declarees UNE fois, dans la section Amis) via
   `--ami-fond` / `--ami-encre`, posees par `amTeinte(id de compte)`. ON LIT LA SOURCE,
   ON NE LA RECOPIE PAS. */
.mu-pas{position:relative;flex:0 0 auto;border-radius:999px;display:grid;
  place-items:center;background:var(--ami-fond,#5567B4);color:var(--ami-encre,#FFFFFF);
  font-weight:800;letter-spacing:-.01em}
.mu-ava.un .mu-pas{width:40px;height:40px;font-size:var(--t-2)}
.mu-ava.deux .mu-pas{width:26px;height:26px;font-size:var(--t-1)}
.mu-ava.deux .mu-pas+.mu-pas{margin-left:-14px}
/* ⚠️ À TROIS ET PLUS : UN SEUL AVATAR ET UN « +N », ET C'EST DE L'ARITHMÉTIQUE.
   Pour qu'une initiale de 12 px se voie, son cercle doit montrer S/2 + 6 px ;
   trois objets dans 44 px donnent S = 16, et un cercle de 16 ne porte pas un
   texte de 12. Avec deux objets, l'avatar montre 22 px sur 26 : ça tient.
   ⚠️ ET LE « +N » EST OPAQUE. Sur un voile translucide il faisait un TROU, et
      il était le SEUL objet translucide parmi des pastilles opaques, donc sa
      couleur changeait selon l'endroit de la liste. #464852 compte sans se
      prendre pour quelqu'un. */
.mu-ava.trois .mu-pas{width:26px;height:26px;font-size:var(--t-1)}
.mu-ava.trois .mu-pas.plus{width:22px;height:22px;font-size:var(--t-1);
  background:#DDD5C7;color:#170B20;margin-left:-10px}   /* [02/10, Romain] crème, comme les ronds */
.mu-pas+.mu-pas{box-shadow:0 0 0 2px rgba(12,12,15,.45)}
/* la présence ne se montre QUE quand elle est là : l'absence n'a pas de point.
   Jamais sur un groupe, un groupe n'a pas de présence. */
.mu-vu{position:absolute;right:0;bottom:0;width:10px;height:10px;
  border-radius:999px;background:#34D399;
  box-shadow:0 0 0 2px rgba(12,12,15,.45)}

.mu-tete{display:flex;align-items:center;gap:var(--e-2);min-width:0}
.mu-nom{font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;line-height:1.2;
  color:var(--c-texte);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
/* ⚠️ LA MARGE NÉGATIVE EST LE SEUL LEVIER QUI RESTAIT, le row-gap était déjà à
   zéro. Le vide entre deux textes n'est pas le vide entre leurs boîtes de ligne :
   une police pose sa ligne de base à 96 % de la hauteur et réserve le bas aux
   jambages, ce qui laissait 7 px de vide réel pour un gap nul.
   À surveiller : un jambage (« Jules », « Georges ») mord de 3,3 px dans les
   capitales de l'aperçu. C'est le prix du presque collé, et iMessage l'accepte. */
.mu-ligne{display:flex;align-items:center;gap:var(--e-2);min-width:0;margin-top:-7px;min-height:17.5px}
.mu-ligne span{font-size:var(--t-2);font-weight:400;line-height:1.25;color:var(--c-texte-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mu-heure{font-size:var(--t-1);font-weight:500;line-height:1.2;color:var(--c-texte-3);
  white-space:nowrap;margin-right:9px}
.mu-ch{width:8px;height:13px;flex:0 0 auto;margin-right:-1px;stroke:var(--dim);fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
/* l'intitulé de section : petites capitales espacées, à l'aplomb du texte */
.mu-sect{margin:var(--e-3) 0 var(--e-2) 16px;font-size:var(--t-1);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
/* ⚠️ LA MARGE NEGATIVE DOIT VALOIR LA MARGE DE L'ECRAN, ET C'EST UN COUPLE : les
   rangees vont bord a bord, donc elles ressortent d'exactement ce que la page rentre.
   [07/08] 14 de l'ecran plus 4 du corps = 18, la marge de toute l'app (elle valait 16
   du temps de la divergence a 12). Trop peu : une bande de fond reste a gauche des
   rangees ; trop : la liste deborde et une barre de defilement laterale apparait.
   Toute retouche des marges de cet ecran doit refaire ce calcul. */
.mu-liste{display:flex;flex-direction:column;margin:0 -18px}

/* ══════════════════════════════════════════════════════════════════════════════
   MULTIJOUEUR · LE FIL — [03/08] portage des six rendus du fil.

   Ce bloc est en FIN DE FEUILLE et il le reste : il surcharge des règles écrites
   très haut dans le fichier, sans avoir à monter la spécificité de chacune.

   ⚠️ CE QUI N'EST PAS PORTÉ, ET POURQUOI. Les rendus dessinent « Envoyé », « Lu »,
      les réactions posées, la citation en bulle creuse et la sélection multiple.
      Le relevé du 02/08 est net : « Envoyé » et « Lu » n'existent nulle part dans
      le code, rien ne remonte au serveur qu'un message a été vu. Ce sont des
      CAPACITÉS À CONSTRUIRE, pas des états à peindre. Les peindre maintenant
      afficherait des accusés de lecture faux.
   ══════════════════════════════════════════════════════════════════════════ */

/* ⚠️ TROIS DÉCLARATIONS RÈGLENT LE PASSAGE À LA LIGNE, ET IL FAUT LES TROIS.
   Le défaut le plus visible de l'écran déployé : une bulle casse un mot par ligne,
   « Rom / ain ». La cause est une LARGEUR, pas une césure — sans max-width, une
   bulle prend la largeur de son plus long mot dès qu'un parent la contraint, sa
   boîte tombe à min-content.
   ⚠️ 76 % ET PAS 80 : à 80, deux bulles opposées qui se suivent laissent moins de
      40 px entre elles, et le COULOIR qui sépare les deux locuteurs disparaît.
      C'est lui qui dit qui parle, avant même la couleur.
   ⚠️ ET word-break:break-all EST INTERDIT : il coupe à n'importe quelle lettre,
      y compris au milieu d'un mot court. overflow-wrap ne coupe QUE si le mot
      seul dépasse la ligne. */
/* ⚠️ LE PLAFOND VIT SUR LE CONTENEUR, PAS SUR LA BULLE, et c'est TOUT le defaut.
   `max-width:76%` pose sur la bulle se calcule sur son PARENT — or ce parent s'etait
   deja reduit a la largeur du texte. Mesure sur l'app en ligne : le mot « Ok » fait
   46 px, le parent 46 px, et la bulle 35, soit 76 % de son propre contenu. Une bulle
   qui ne peut jamais contenir son texte casse TOUJOURS, et comme `overflow-wrap`
   autorise la coupe, elle casse LETTRE PAR LETTRE : c'est « Rom / ain ».
   Le plafond descend donc sur .ln-c, qui vit dans la colonne de conversation, et la
   bulle prend la largeur de son texte, bornee par lui.
   ⚠️ ET width:max-content, PAS auto : un div en display:block prend toute la largeur
      offerte. Dans le rendu la bulle est un item flex avec align-self, ce qui la
      ramene a son contenu — l'app n'a pas cette structure, il faut le dire au CSS.
   Verifie en ligne : « Ok » 46 px sur une ligne, « anticonstitutionnellement » 199 px
   sur une ligne, seule une URL plus longue que le plafond se coupe. */
#s-multi .ln-c{max-width:76%}
#s-multi .bul{width:-webkit-max-content;width:max-content;max-width:100%;
  overflow-wrap:break-word;word-break:normal;hyphens:none}

/* ⚠️ MES BULLES NE SONT PLUS VIOLETTES. Le violet est la couleur de la SOIRÉE, et
   le socle interdit de réutiliser une couleur de mode pour autre chose sur le même
   écran : une bulle violette dans un fil dit qu'il s'y passe quelque chose de la
   Soirée. Elles passent au sarcelle, avec l'encre --ink-teal — le traitement de la
   carte Multijoueur de l'accueil.
   C'est aussi la première fois que la couleur de ce mode couvre une vraie surface :
   le socle demandait dès l'origine qu'un aplat se décline « sur quarante écrans,
   bulles de conversation comprises ». */
#s-multi .bul.moi{color:#052322;border-color:transparent;
  background:linear-gradient(150deg,#3FDBC6 0%,#14B8A6 62%,#0E9384 100%)}
#s-multi .bul.moi .bul-h{color:rgba(5,35,34,.62)}
/* ⚠️ LES BULLES REÇUES RESTENT NEUTRES. Deux locuteurs, deux traitements : celui
   qui parle porte la couleur, l'autre porte la surface. Colorer les deux ferait
   deux héros, donc aucun. */
#s-multi .bul:not(.moi){background:rgba(168,178,225,.10);border-color:transparent;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);color:var(--c-texte)}

/* ⚠️ LE SÉPARATEUR DE DATE PERD SA PASTILLE. Le socle ne veut aucun contenant qui
   ne porte pas de sens, et une date n'est pas un objet touchable. Il reste le
   traitement des intitulés de famille des catalogues : une date range des messages
   comme « Adresse et précision » range des tuiles. */
#s-multi .chat-jour span{background:none;padding:0;color:var(--dim);
  letter-spacing:.1em}

/* ⚠️ LES CARTES DE PARTIE PORTENT LA COULEUR DU MODE JOUÉ, comme la bannière de
   reprise de l'accueil : un aplat suit son mode partout. Sur l'écran déployé elles
   sont grises, et un événement de Soirée, un de Mini-jeux et un de Classiques s'y
   ressemblent trait pour trait.
   ⚠️ MAIS EN TEINTÉ, PAS EN PLEIN : une carte pleine pèserait plus qu'une bulle et
      l'événement passerait devant la conversation. */
#s-multi .bul-partie.m-soiree,#s-multi .bul-fini.m-soiree{background:rgba(139,92,246,.15);border-color:transparent}
#s-multi .bul-partie.m-classiques,#s-multi .bul-fini.m-classiques{background:rgba(236,72,153,.14);border-color:transparent}
#s-multi .bul-partie.m-minijeux,#s-multi .bul-fini.m-minijeux{background:rgba(251,191,36,.13);border-color:transparent}
/* la carte VIVANTE porte sa couleur plus franchement : elle est la seule à demander
   quelque chose, et le socle veut qu'un seul objet par écran porte de la matière. */
#s-multi .bul-partie.m-soiree{background:rgba(139,92,246,.22)}
#s-multi .bul-partie.m-classiques{background:rgba(236,72,153,.20)}
#s-multi .bul-partie.m-minijeux{background:rgba(251,191,36,.19)}
/* ⚠️ UNE CARTE FINIE N'EST PAS TOUCHABLE : un objet qui réagit au doigt PROMET une
   suite. Seule la vivante garde son effet d'appui. */
#s-multi .bul-fini{cursor:default}

/* ⚠️ LES BADGES D'ÉTAT NE SONT JAMAIS ROUGES. « Annulée » et « Terminée » sont deux
   CONDITIONS de la partie, pas deux signaux : un badge dit l'état d'un objet,
   jamais qu'il attire. Et une partie annulée n'est pas irréversible, on peut en
   relancer une. Le rouge reste à ce qui ne se rattrape pas. */
#s-multi .bul-fini.gagne .bf-r,#s-multi .bul-fini.perdu .bf-r,
#s-multi .bul-fini.egalite .bf-r{background:rgba(255,255,255,.07);color:var(--c-texte-2)}
#s-multi .bul-fini.gagne,#s-multi .bul-fini.perdu,#s-multi .bul-fini.egalite{border-left-color:transparent}

/* ⚠️ LA LIGNE DE FRAPPE PASSE DU CYAN AU SARCELLE. Le cyan n'appartient à aucun
   mode. Et elle reste UNE LIGNE DE TEXTE, pas trois points animés : l'app n'a aucun
   canal temps réel, la frappe est déjà en retard d'au plus 3 s, et des points qui
   s'animent PROMETTENT du temps réel — ils tourneraient encore deux secondes après
   que la personne a fini. Une ligne ne promet rien, et elle dit QUI. */
#s-multi .chat-tape{color:#5EEAD4}

/* ⚠️ LE BOUTON D'ENVOI N'EST PLUS CYAN, ET IL EST CARRÉ ARRONDI. Le cyan était
   l'objet le plus lumineux de l'écran, devant les messages eux-mêmes. Et « forme =
   nature » : un cercle est une PERSONNE, un carré arrondi une FONCTION. C'est la
   forme du « + » de la liste, et c'est ce qui les rattache.
   Le rond est la convention des messageries ; le socle tranche l'inverse pour tout
   le projet, et céder ici obligerait à rouvrir le bouton compte de l'accueil, rond
   PARCE QU'il porte une personne. */
#s-multi .chat-env{border-radius:var(--r-1);
  background:linear-gradient(140deg,#3FDBC6 0%,#14B8A6 58%,#0E9384 100%);
  color:#052322}
#s-multi .chat-env svg{stroke:#052322}

/* le halo du mode, seul porteur de la couleur avec les bulles. Il s'éteint avant
   les messages pour ne pas les teinter. */
/* ⚠️⚠️ [07/08] IL EST ETEINT SUR LA LISTE, ET SEULEMENT SUR ELLE. Les quatre rendus
   finaux le suppriment : « un halo se justifie derriere un objet qui brille — le podium,
   une carte de mode — pas derriere une liste ». Le Classement, Amis et les cinq ecrans du
   Compte n'en ont aucun ; Discussions etait le dernier a peindre son fond, et c'est ce
   qui rendait l'ecran charge (halo, champ, bouton en degrade, rangees).
   ⚠️ IL RESTE DANS LE FIL ET DANS LES AUTRES VUES DU MODE. La regle vit sur `#s-multi`,
      donc sur les onze vues ; le rendu ne couvre que la liste, et le fil a ete cale a la
      mesure sur ce fond-la. On l'eteint sur `.racine` (la classe que muRender pose quand
      et seulement quand muVue vaut « liste »), pas sur l'ecran. */
#s-multi.racine::before{content:none}
#s-multi::before{content:'';position:absolute;left:0;right:0;top:0;height:100%;
  pointer-events:none;z-index:0;
  background:
    radial-gradient(118% 52% at 82% -6%,rgba(94,234,212,.13) 0,transparent 62%),
    radial-gradient(150% 62% at 40% 0%,rgba(20,184,166,.09) 0,transparent 66%);
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 10%,rgba(0,0,0,.30) 34%,transparent 62%);
  mask-image:linear-gradient(180deg,#000 0,#000 10%,rgba(0,0,0,.30) 34%,transparent 62%)}
#s-multi>*{position:relative;z-index:1}

/* ══ MULTIJOUEUR · LA BARRE DE NAVIGATION DE LA LISTE — [07/08], d'après les quatre
   rendus finaux (discussionsliste / vide / invitation / nouveau) ══
   ⚠️⚠️ LE GRAND TITRE « MULTI/JOUEUR » ET SON CHAPO SONT SUPPRIMES, ET LEURS QUATRE
      REGLES AVEC (une regle dont l'element disparait se retire). Deux raisons.
      ① UN NOM : l'onglet s'appelle DISCUSSIONS. Un ecran qui porte un autre nom que
         l'onglet qui y mene fait douter d'etre au bon endroit. Le titre porte le nom de
         l'onglet, pas celui du mode.
      ② LA DA : le grand titre a gauche a ete abandonne le 05/08. Classement, Amis,
         Profil et les cinq ecrans du Compte portent tous la meme barre — titre 21/600
         centre, hauteur 44, 32 en dessous. Discussions etait le dernier a porter
         l'ancienne. Un socle qu'on amende se repasse sur les ecrans restes en arriere.
      ⚠️ LE CHAPO PART AVEC : « Retrouve tes amis, discute et joue » presentait un mode ;
         on ne presente pas un onglet ou l'on revient dix fois par jour.
      ⚠️ ET « joueur » EN SARCELLE DISPARAIT AVEC LUI : c'etait la seule coloration de
         texte du projet. Le mode ne perd pas sa couleur pour autant — elle vit sur le
         « + », sur l'heure d'un fil non lu et sur les bulles du fil.
   ⚠️ LES COTES SONT CELLES DU COMPTE, AU PIXEL : meme grille 36 / minmax(0,1fr) / 36,
      meme hauteur mini, meme ecart dessous, meme corps de titre. On ne pose pas une
      seconde barre dans le corps : celle-ci existe deja, elle est branchee au retour, au
      geste iOS et a `.racine`.
   ⚠️⚠️ ET C'EST BORNE A `.racine`, C'EST-A-DIRE A LA VUE LISTE. muRender pose cette
      classe quand et seulement quand muVue vaut « liste ». Les autres vues du mode
      (choix des membres, nouveau groupe, salon, modes, fil) gardent leur barre : leur
      fleche de retour est un `.iconbtn` de 44 px, qui deborderait d'une colonne de 36.
      Un socle porte sur l'ecran qu'on a mesure, pas sur les onze d'un coup. */
#s-multi.racine>.topbar{display:grid;grid-template-columns:36px minmax(0,1fr) 36px;
  align-items:center;min-height:44px;margin-bottom:var(--e-5)}
#s-multi.racine>.topbar>#mu-title{grid-column:2;justify-self:center;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;line-height:1.2;
  color:var(--c-texte);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-multi.racine>.topbar>.mu-act{grid-column:3}
/* ⚠️ A LA RACINE D'UN ONGLET LA FLECHE DISPARAIT MAIS SA COLONNE RESTE : un enfant de
   grille en display:none ne reserve pas sa case, et le titre glisserait de 18 px vers la
   gauche. D'ou visibility (posee plus bas, avec celle du Compte), et une cote ramenee a
   36 pour que l'objet invisible ne deborde pas de sa colonne. */
#s-multi.racine>.topbar>#mu-back{grid-column:1;width:36px;height:36px}

/* la recherche et le « + » sur une seule rangée
   ⚠️ 16 SOUS LA LIGNE D'OUTILS, ET C'EST UN RYTHME, PAS UNE VALEUR ISOLEE : l'ecran de
      liste se lit barre 32 · vitrine 32 · outils 16 · liste. Deux ecrans de la meme
      famille ne se ressemblent pas par leurs objets, ils se ressemblent par leurs
      intervalles (meme rythme que sur Amis). */
#s-multi .mu-barre{display:flex;align-items:center;gap:var(--e-2);flex:0 0 auto;margin:0 0 var(--e-3)}
/* ⚠️⚠️ [07/08] LE VERRE DU CHAMP SAUTE, ET IL MONTE A 36. Deux corrections du meme
   rendu. ① Le champ est DANS LE FLUX : rien ne defile dessous, son `backdrop-filter`
   floutait un aplat. Un flou qui ne floute rien coute une couche de composition pour zero
   pixel — c'est l'argument qui avait deja fait tomber le verre du selecteur d'Amis. Le
   voile passe donc a rgba(255,255,255,.07), celui des commandes courantes.
   ② 36 de haut, la cote du bouton qui le jouxte : deux objets d'une meme ligne d'outils
   ont la meme hauteur, sinon la ligne a deux fonds. */
#s-multi .mu-rech{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:1 1 auto;min-width:0;margin:0;padding:0 var(--e-3);min-height:36px;border-radius:999px;
  background:rgba(255,255,255,.07);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035)}
/* la cible reste a 44 par un ::after : la capsule fait 36, on ne grossit pas l'objet
   pour agrandir la zone touchable.
   ⚠️ pointer-events:none, ET SANS LUI LA RECHERCHE NE MARCHE PAS DU TOUT. Ce
      pseudo-element est peint APRES le champ, donc AU-DESSUS : il interceptait chaque
      toucher et l'input ne le recevait jamais. Une cible tactile agrandie doit laisser
      passer ce qu'elle couvre, sinon elle protege l'objet au lieu de le servir.
      C'est ce qui rendait la barre « pas fonctionnelle » (Theo, 03/08).
   ⚠️ ET LE CHAMP LUI-MEME PREND LA HAUTEUR DE LA CAPSULE : il ne mesurait que 24 px,
      donc meme sans l'obstacle, la zone reellement touchable etait deux fois trop courte.
      C'est LUI qui doit remplir la capsule, pas le hasard de sa ligne de texte. */
#s-multi .mu-rech::after{content:'';position:absolute;left:0;right:0;top:-5px;bottom:-5px;
  pointer-events:none}
/* ⚠️ LA BAGUE DE FOCUS VIT SUR LA CAPSULE, PAS SUR LE CHAMP. Posee sur le champ, elle
   epouse SA boite, qui est plus petite et decalee : on voyait un contour bleu de Safari
   flotter au milieu de la capsule sans la suivre (releve de Theo, capture a l'appui). Le
   champ perd donc son contour, et c'est la capsule qui montre le focus, dans la couleur du
   mode et non dans le bleu du systeme. */
#s-multi .mu-rech input{min-height:36px;outline:none;border:0;background:none}
#s-multi .mu-rech input:focus,#s-multi .mu-rech input:focus-visible{outline:none;box-shadow:none}
#s-multi .mu-rech:focus-within{box-shadow:inset 0 1px 0 rgba(255,255,255,.035),
  0 0 0 2px rgba(94,234,212,.34)}
#s-multi .mu-rech svg{width:15px;height:15px;flex:0 0 auto;stroke:#9990AE;fill:none;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
#s-multi .mu-rech:focus-within{box-shadow:inset 0 1px 0 rgba(94,234,212,.12),
  0 0 0 2px rgba(20,184,166,.22)}
#s-multi .mu-rech:focus-within svg{stroke:#4FBFB4}
/* [03/08] MEME PIEGE QUE LE CHAMP DU CHAT : a .875rem, soit 14 px, Safari iOS zoomait au
   focus de la recherche et ne dezoomait pas en sortant. Le champ monte a 16 px.
   ⚠️ ECART ASSUME AVEC LE DOSSIER, QUI POSE 14 : aucune valeur de dessin ne peut passer
      sous 16 sur un champ de saisie iOS sans declencher le zoom. Le seul autre moyen serait
      de bloquer le zoom au niveau du viewport, ce qui empeche AUSSI le pincement et casse
      l accessibilite. La capsule garde sa hauteur (min-height), c est le texte qui grandit. */
#s-multi .mu-rech input{flex:1 1 auto;min-width:0;background:none;border:0;padding:0;
  font-size:1rem;color:var(--ink)}
#s-multi .mu-rech input::placeholder{color:var(--c-texte-3)}
/* ⚠️ CARRÉ ARRONDI, PAS ROND : un cercle est une PERSONNE, un carré arrondi une
   FONCTION. C'est la forme du bouton d'envoi du fil, et c'est ce qui les rattache. */
/* ⚠️⚠️ [07/08] 36 px, RAYON 12, ET UN DEGRADE A DEUX ARRETS. Trois changements du rendu
   final, chacun avec sa raison.
   ① LA COTE : 36/12 est celle des boutons d'en-tete du Compte et du Profil. Un bouton
      d'action ne se redessine pas d'un ecran a l'autre. Il gagne aussi la hauteur du
      champ qu'il jouxte : deux objets d'une meme ligne d'outils ont la meme hauteur.
   ② LE DEGRADE PERD SON TROISIEME ARRET : trois arrets sur trente-six pixels ne se
      voient pas — un degrade plus court que ce qu'il traverse est un aplat coûteux.
      Deux arrets, verticaux comme les tuiles de l'app.
   ③ LA TEINTE REDESCEND DE #5EEAD4 A #14B8A6, le sarcelle du mode. Le 06/08 il etait
      monte au clair pour sortir d'un vert rabattu (releve de Theo sur capture) ; le vert
      rabattu venait du VERRE et de l'opacite a .93, tous deux retires — pas du ton. Il
      reste opaque, sans flou. ⚠️ SIGNALE : c'est le seul point ou le rendu du 07/08
      revient sur un arbitrage de Theo du 06/08. L'encre --ink-teal #052322 rend 5,09:1
      sur #14B8A6, au-dessus du seuil AA.
   ⚠️ ET LA CIBLE RESTE A 44 PAR UN ::after : 36 + 2 x 4 = 44. Elle valait -6 quand le
      bouton faisait 33 (33 + 12 = 45) ; garder -6 sur 36 aurait donne 48, une cible plus
      large que le bouton d'a cote. Ce qu'on voit peut changer, ce qu'on touche reste 44. */
/* ⚠️⚠️ `font:inherit` ET IL N'EST PAS DECORATIF. Cette feuille n'a AUCUN reset global sur
   `button` : releve au CSSOM, ce bouton portait encore Arial 13,3 px, la police du
   navigateur. Il ne montre qu'un glyphe, donc ca ne se voyait pas — jusqu'au jour ou on y
   met un caractere. Faute payee quatre fois sur ce projet, la derniere en production le
   07/08 : on la referme partout ou on la trouve, meme quand elle dort. */
#s-multi .mu-plus{position:relative;flex:0 0 auto;width:36px;height:36px;
  border-radius:var(--r-1);display:grid;place-items:center;border:0;font:inherit;
  background:linear-gradient(180deg,#2FB5A4 0%,#14B8A6 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.20);
  color:#052322;transition:transform .16s cubic-bezier(.22,.9,.25,1)}
#s-multi .mu-plus::after{content:'';position:absolute;inset:-4px}
#s-multi .mu-plus:active{transform:scale(.92)}
#s-multi .mu-plus svg{width:15px;height:15px;stroke:#052322;fill:none;stroke-width:2.05;
  stroke-linecap:round;stroke-linejoin:round}

/* ══ MULTIJOUEUR · LE MENU DU « + » — [03/08], d'après multijoueur-menu-nouveau ══
   Le menu est ANCRÉ SUR LE BOUTON, pas centré : c'est ce qui dit d'où il sort. Un
   panneau centré aurait l'air d'un écran, pas d'un menu. */
/* ⚠️ [06/08, Theo sur capture] z-index:6 COMME LE MENU, SINON LE VOILE ASSOMBRIT LE
   BOUTON. Le voile est fixe a z:5 : le menu (z:6) passait devant, mais le « + » qui
   l'ouvre restait DESSOUS et virait au terne des que le menu s'ouvrait. Le porteur
   monte a 6 : bouton et menu vivent au-dessus du voile ensemble, nets tous les deux.
   (Sans danger au repos : pas de voile, et la capsule d'onglets vit a z:20.) */
#s-multi .mu-plus-z{position:relative;flex:0 0 auto;z-index:6}
#s-multi .mu-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:6;
  min-width:212px;padding:var(--e-1);border-radius:var(--r-3);
  background:linear-gradient(rgba(14,14,18,.10),rgba(14,14,18,.10)),rgba(122,122,136,.34);
  -webkit-backdrop-filter:blur(40px) saturate(1.8);backdrop-filter:blur(40px) saturate(1.8);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 2px 6px rgba(0,0,0,.12);
  transform-origin:100% 0;animation:uiMenu var(--m-court) var(--m-sortie) both}
@keyframes uiMenu{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:none}}
#s-multi .mu-mit{position:relative;z-index:1;display:flex;align-items:center;gap:var(--e-3);
  width:100%;min-height:44px;padding:0 var(--e-3);border:0;background:none;border-radius:var(--r-2);
  font:inherit;font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:var(--c-texte);
  text-align:left;transition:background .09s;
  animation:uiMenuItem var(--m-court) var(--m-sortie) both}
#s-multi .mu-mit:nth-child(2){animation-delay:40ms}
@keyframes uiMenuItem{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
#s-multi .mu-mit:active{background:rgba(255,255,255,.09)}
@media (hover:hover){#s-multi .mu-mit:hover{background:rgba(255,255,255,.06)}}
/* ⚠️ LE SÉPARATEUR EST EN RETRAIT DERRIÈRE LE GLYPHE, comme celui de la liste
   l'était derrière l'avatar : il articule deux entrées d'une même série, il ne
   coupe pas le menu en deux. */
/* ⚠️ [07/08] MEME PIXEL PHYSIQUE QUE LES FILETS DE LA LISTE : boite d'un pixel plein
   ecrasee par scaleY(.34), opacite remontee a .09 (une hauteur est de la mise en page,
   elle s'arrondit avant peinture ; .021 sur trois pixels physiques rendait un trait
   epais et pale au lieu d'un cheveu). */
#s-multi .mu-mit+.mu-mit::before{content:'';position:absolute;left:34px;right:0;top:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.09)}
#s-multi .mu-mit svg{width:19px;height:19px;flex:0 0 auto;stroke:#5EEAD4;fill:none;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
/* le voile ferme au toucher : sans lui on cherche une croix qui n'existe pas */
#s-multi .mu-voile{position:fixed;inset:0;z-index:5;background:rgba(6,6,9,.46);
  animation:uiVoile var(--m-court) var(--m-sortie) both}
@keyframes uiVoile{from{opacity:0}to{opacity:1}}
/* ⚠️ LE SECOND PLAN EST FLOUTÉ PAR UN filter SUR LE CONTENU, PAS PAR LE MENU.
   Le rendu note quatre échecs successifs de backdrop-filter, tous réels : une cage
   d'empilement, un pseudo-élément descendant d'un élément transformé, le menu qui
   porte lui-même un transform, un second backdrop-filter sur le voile. Un
   backdrop-filter n'échantillonne que l'intérieur de sa racine de backdrop, et un
   élément transformé crée cette racine pour ses descendants : le filtre devenait
   un no-op. On floute donc ce qu'il y a derrière, directement. */
/* ⚠️ LA BARRE EST EXCLUE DANS LE SELECTEUR, PAS ANNULEE APRES, ET C'EST TOUTE LA
   DIFFERENCE. La protection s'ecrivait en annulant le filtre sur la barre dans une regle a
   part, soit une specificite de (1,2,0) contre (1,3,0) pour celle qui floute : elle ne
   s'appliquait
   donc JAMAIS. Resultat, le menu lui-meme etait flou et ses deux entrees illisibles, alors
   que le rendu montre un menu NET sur un fond flou (releve de Theo sur appareil, capture a
   l'appui). Un :not() de plus regle le probleme a la source, sans course a la specificite.
   ⚠️ ET LE MENU VIT DANS LA BARRE : flouter la barre floutait donc aussi le « + » et son
      menu, c'est-a-dire exactement ce qu'on veut garder net. */
/* ⚠️⚠️ [07/08] LE RAYON PASSE DE 3 A 4,5 px, ET LA RECHERCHE ENTRE DANS LE SECOND PLAN.
   ① LE RAYON SE CALCULE : un flou efface un texte quand il approche la MOITIE de sa
      hauteur d'x. L'apercu d'une rangee fait 14 px, soit 7,3 px d'x — 3 px n'en
      couvraient que 41 %, 4,5 en couvrent 62. Le mot est detruit par la page seule,
      quoi qu'il advienne du filtre du menu.
   ② LA RECHERCHE ETAIT NETTE AU MILIEU D'UNE PAGE FLOUTEE : elle est exclue avec toute
      la barre, alors que le rendu la floute comme le reste. Ce qui doit rester net,
      c'est LE BOUTON SEUL — sur les menus natifs d'iOS l'ancre ne floute jamais, c'est
      ce qui dit « le menu sort d'ici ». On floute donc l'objet, pas son conteneur.
   ⚠️ ET SURTOUT PAS `.mu-barre` : un `filter` sur elle creerait un bloc conteneur pour
      le voile en `position:fixed` ET une racine d'empilement pour le menu. C'est le
      piege deja demele quatre fois sur cet ecran. La barre reste sans filtre ; ce sont
      ses DEUX enfants qui en portent un, chacun le sien, et `.mu-plus-z` (qui contient
      le menu) n'en porte aucun. */
#s-multi.menu-ouvert .jr-body>*:not(.mu-voile):not(.mu-barre){filter:blur(4.5px);transition:filter .2s}
#s-multi.menu-ouvert .mu-rech{filter:blur(4.5px);transition:filter .2s}
/* ⚠️ LA BARRE DE TITRE AUSSI : le rendu floute `.top` avec le reste. Elle vit HORS de
   `.jr-body`, donc la regle ci-dessus ne l'atteint pas — elle n'etait qu'assombrie par le
   voile, et un titre net au-dessus d'une page floue fait un second point d'attention. */
#s-multi.menu-ouvert>.topbar{filter:blur(4.5px);transition:filter .2s}
/* ⚠️ LE BOUTON N'EST PAS FLOU, IL EST PLUS CLAIR. Il est l'ancre du menu, donc il doit
   se voir ; mais un second objet net ferait deux points d'attention et l'ancre volerait
   la vedette a ce qu'elle a ouvert. Un eclat de 28 % suffit a le sortir du fond assombri
   par le voile. */
#s-multi.menu-ouvert .mu-plus{filter:brightness(1.28);transition:filter .2s}

/* ⚠️ LA ZONE QUI DEFILE VA BORD A BORD, ET L'ESPACE PASSE EN PADDING.
   La barre de defilement se dessine au bord de la BOITE qui defile, pas au bord de
   l'ecran. `.chat` s'arretait a 22 px du bord (le padding de .screen), donc la barre
   flottait au milieu du contenu, alignee sur le bord des bulles. Mesure sur photo :
   29 pt du bord droit, contre 3 pt chez Apple.
   La marge negative rend la largeur pleine, le padding rend l'espace exactement ou il
   etait : le contenu ne bouge pas d'un pixel (releve avant/apres, 24 px a gauche dans
   les deux cas), seule la barre se recolle au bord.
   ⚠️ IL Y A DEUX PADDINGS A REPRENDRE, PAS UN. Les 22 de .screen ET les 4 de .jr-body,
      le conteneur intermediaire. La premiere version n'en reprenait que 2 (chiffre lu dans
      une regle .jr-body surchargee ailleurs, jamais verifie sur l'element) : la barre
      restait a 4 px du bord au lieu de s'y coller, et la conversation se decalait.
      Releve sur l'element : .jr-body vaut bien `4px 4px 0 4px`. */
/* ⚠️ ET overflow-x:hidden AVEC. La conversation deborde volontairement de son conteneur
   (marges negatives, pour que la barre de defilement se colle au bord) ; or un element qui
   declare overflow-y:auto passe AUTOMATIQUEMENT son overflow-x de visible a auto. Sans
   cette ligne, le fil gagne un defilement LATERAL : invisible sur iOS ou la barre est en
   surimpression, mais la conversation part de cote au doigt.
   ⚠️ ET touch-action:pan-y AVEC, parce que `overflow-x:hidden` n'interdit que le GESTE,
   jamais le deplacement programmatique : la boite deborde toujours de 22 px, et n'importe
   quel `scrollLeft` ou mise au point d'un champ peut la faire glisser lateralement sans
   qu'on la ramene jamais. Le pan-y dit au navigateur qu'il n'y a rien a faire sur cet axe.
   ⚠️ CE COMMENTAIRE A DEJA CASSE LA REGLE QUI SUIT, DEUX FOIS. La premiere en le
   rajoutant sans sa marque d'ouverture, ce qui laissait une fin orpheline ; la seconde en
   CITANT cette marque de fermeture en clair pour l'expliquer, ce qui refermait le
   commentaire au milieu de la phrase. Dans les deux cas le parseur jette la declaration
   suivante EN SILENCE, et la regle reste morte alors qu'elle est bien dans le fichier.
   Donc : on ne cite JAMAIS ces deux caracteres cote a cote, meme pour en parler. Meme
   famille que l'etoile-barre de la v429. Le controle CSS-01 du contrat parcourt la
   feuille et refuse le deploiement si un commentaire n'est pas equilibre. */
#s-multi.au-fil>.jr-body{padding:0;overflow-x:hidden;touch-action:pan-y}
#s-multi .chat{margin-left:-22px;margin-right:-22px;padding-left:var(--e-5);padding-right:var(--e-5)}

/* ═══ LE FIL : L'EN-TETE FLOTTE, LA CONVERSATION MONTE A L'INFINI ════════════
   Releve sur iMessage (Theo, 03/08) : il n'y a PAS de barre qui coupe l'ecran en deux.
   Le retour et le bloc profil sont deux objets POSES sur la conversation, en verre, et la
   conversation court jusqu'en haut de l'ecran, sous l'heure, visible en flou a travers.
   Deux choses distinctes, et il faut les deux : la conversation qui monte (sinon on gagne
   juste un fond translucide sur une barre qui coupe toujours), et le verre (sinon la
   conversation disparait derriere un bandeau opaque).
   Le traitement ne vaut QUE dans le fil : la liste, les modes et le salon gardent leur
   barre posee, c'est la classe .au-fil (mise par muRender) qui fait la difference. */
#s-multi.au-fil{padding-top:0}
#s-multi.au-fil>.topbar{position:absolute;left:0;right:0;top:0;z-index:6;margin:0;
  display:block;text-align:center;pointer-events:none;
  padding:calc(var(--e-2) + env(safe-area-inset-top,0px)) var(--e-3) var(--e-2)}
/* ⚠️ LA BARRE NE PREND PAS LES APPUIS, SES OBJETS OUI. Elle couvre toute la largeur pour
   poser ses trois reperes ; sans cela elle avalerait les appuis sur les messages du haut. */
#s-multi.au-fil>.topbar>*{pointer-events:auto}

/* ══ LE GESTE DE RETOUR DEPUIS LE BORD GAUCHE — [06/08] ══════════════════════════════
   Le comportement, ses mesures et ce qui n'a pas ete porte sont documentes au-dessus de
   muGesteRetour dans app.js. Ici il n'y a que ce que le geste demande au moteur.
   ⚠️ CES REGLES NE VIVENT QUE PENDANT LE GESTE. Aucune n'a d'effet au repos : la classe
      .mu-geste est posee au toucher et retiree a la fin, donc l'ecran a l'arret est au
      pixel celui d'avant le 06/08. Rien ici ne pose de couleur, de dimension ni de
      libelle. */
/* ⚠️ ET L'AXE HORIZONTAL SE FERME LE TEMPS DU GESTE. .screen declare overflow-y:auto, ce
   qui bascule AUTOMATIQUEMENT son overflow-x de visible a auto : une conversation
   translatee vers la droite rendrait l'ecran defilable lateralement, avec sa barre. Meme
   piege que la conversation et que la liste, meme parade. */
#s-multi.mu-geste{overflow:hidden}
/* La couche est annoncee AU TOUCHER, pas a la premiere image : la promouvoir en pleine
   course coute une image, et c'est celle ou le doigt part. */
#s-multi.mu-geste>#mu-body{will-change:transform}
/* LA COURBE DE FIN, MESUREE : 13 images a 60 im/s (217 ms) et cubic-bezier(.3,.75,.55,1),
   ajuste sur les 13 points de la video a 1,2 % d'ecart maximum. Elle vaut pour le retour
   comme pour le depart : les deux progressions se superposent a 1,8 % pres. */
#s-multi.mu-geste-fin>#mu-body{transition:transform .22s cubic-bezier(.3,.75,.55,1)}
/* SEUL LE DEPART EFFACE L'EN-TETE FLOTTANT, et seulement sur sa deuxieme moitie : dans la
   video la barre reste entiere pendant tout le geste et ne s'efface qu'a la toute fin. */
#s-multi.mu-geste-part>.topbar{opacity:0;transition:opacity .13s linear .09s}
/* ⚠️ MOUVEMENT REDUIT : PLUS DE GLISSEMENT, MAIS LE GESTE RESTE. Suivre son propre doigt
   n'est pas une animation, c'est de la manipulation directe ; ce qui se coupe ici, c'est
   la course de 220 ms qui part toute seule au relachement. Le JS tranche alors sans
   animer (reduceMotion dans muGesteRetour) ; cette regle est le second verrou, pour le
   cas ou une transition serait quand meme posee. */
@media (prefers-reduced-motion:reduce){
  #s-multi.mu-geste-fin>#mu-body{transition:none}
  #s-multi.mu-geste-part>.topbar{transition:none}
}
#s-multi.au-fil #mu-back,#s-multi.au-fil .mu-act{position:absolute;
  top:calc(7px + env(safe-area-inset-top,0px))}
#s-multi.au-fil #mu-back{left:14px}
#s-multi.au-fil .mu-act{right:14px}
/* ⚠️ CENTRE SANS transform. `left:50%;transform:translateX(-50%)` serait le reflexe, et
   il TUERAIT le flou : un ancetre transforme cree un nouveau plan de fond, et le
   backdrop-filter de la capsule n'echantillonne plus la conversation. Le centrage passe
   donc par text-align sur la barre et un inline-block sur le titre. */
#s-multi.au-fil #mu-title{display:inline-block;vertical-align:top;max-width:calc(100% - 120px)}

/* LE VERRE. Repli d'abord (voile plus dense), flou ensuite pour qui sait le faire : sans
   flou, un voile leger laisserait passer le texte de la conversation SOUS le nom. */
#s-multi.au-fil #mu-back,#s-multi.au-fil .mu-tt{
  background:rgba(20,20,26,.86);
  border:1px solid rgba(255,255,255,.09);
  box-shadow:0 6px 22px rgba(0,0,0,.34),inset 0 1px 0 rgba(255,255,255,.06)}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  /* [03/08] voile descendu de .62 a .30 : « pas du tout assez transparents » (Theo). Le
     flou monte de 20 a 30 dans le meme geste, c'est LUI qui tient la lisibilite du nom
     quand la matiere se retire ; baisser l'un sans monter l'autre rend le texte illisible
     des qu'une bulle vive passe derriere. */
  #s-multi.au-fil #mu-back,#s-multi.au-fil .mu-tt{background:rgba(20,20,26,.30);
    -webkit-backdrop-filter:blur(30px) saturate(1.7);backdrop-filter:blur(30px) saturate(1.7)}
}
/* ⚠️ LE RETOUR RESTE UN CARRE ARRONDI, la capsule est reservee a la personne. « forme =
   nature » : un cercle est une PERSONNE, un carre arrondi une FONCTION. iMessage met une
   capsule parce qu'il y loge un compteur de messages non lus ; nous n'en avons pas. */
#s-multi.au-fil .mu-tt{padding:var(--e-1) var(--e-3) var(--e-1) var(--e-1);border-radius:999px;max-width:100%}
#s-multi.au-fil .mu-tt-t{padding-right:2px}

/* LA CONVERSATION PASSE DESSOUS. Le creux en haut du fil vaut la hauteur de l'en-tete :
   au repos le premier message se lit entier, et des qu'on defile il glisse sous le verre. */
/* releve sur l'ecran : l'en-tete mesure 63 px de haut (7 + 49 + 7), le creux le couvre
   et laisse 11 px pour que le premier message de l'historique ne colle pas au verre. */
#s-multi.au-fil .chat{padding-top:calc(74px + env(safe-area-inset-top,0px))}

/* LE FONDU DU HAUT. Sur la capture iMessage, le contenu ne s'estompe pas SEULEMENT sous les
   pilules : il palit sur TOUTE la largeur de la bande haute, entre elles comprises. C'est ce
   qui donne le « vaguement » de la demande. Sans lui, un message qui passe entre le retour et
   le nom reste net et vient bagarrer avec eux.
   Pose au-dessus de la conversation (z-index 5) et SOUS l'en-tete (6) : les deux objets en
   verre restent nets, seul ce qui defile derriere s'efface.
   ⚠️ LA COULEUR DE FIN EST ECRITE EN TOUTES LETTRES, alpha a zero. `transparent` vaut
      rgba(0,0,0,0) : un degrade vers lui traverse du noir, et sur le theme clair la bande
      virerait au gris sale au lieu de disparaitre. */
#s-multi.au-fil::after{content:'';position:absolute;left:0;right:0;top:0;z-index:5;
  pointer-events:none;height:calc(88px + env(safe-area-inset-top,0px));
  background:linear-gradient(180deg,rgba(12,12,15,.92) 0%,rgba(12,12,15,.60) 48%,rgba(12,12,15,0) 100%)}
html.clair #s-multi.au-fil::after{
  background:linear-gradient(180deg,rgba(243,238,244,.92) 0%,rgba(243,238,244,.60) 48%,rgba(243,238,244,0) 100%)}

/* ⚠️ LE VERRE A UN PENDANT CLAIR, SINON IL RESTE NOIR SUR LE THEME CLAIR. Releve apres
   coup : la capsule gardait rgba(20,20,26,.62) une fois le theme bascule, soit un objet
   sombre pose sur une page claire. Un materiau translucide prend la valeur de SA page, il
   ne se decline pas tout seul.
   Specificite : `html.clair` passe devant les regles sombres, @supports compris (une
   requete de fonctionnalite ne change pas le poids d'un selecteur). */
html.clair #s-multi.au-fil #mu-back,html.clair #s-multi.au-fil .mu-tt{
  background:rgba(255,255,255,.88);border:1px solid rgba(23,11,32,.10);
  box-shadow:0 6px 20px rgba(23,11,32,.13),inset 0 1px 0 rgba(255,255,255,.85)}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  html.clair #s-multi.au-fil #mu-back,html.clair #s-multi.au-fil .mu-tt{
    background:rgba(255,255,255,.36);
    -webkit-backdrop-filter:blur(30px) saturate(1.7);backdrop-filter:blur(30px) saturate(1.7)}
}

/* ═══ « QUI JOUE ? » — REFONTE DU 03/08 (dossier « ECRAN TRINKEURS ») ════════════════
   Tout est scopé à #s-joueurs : .cl-av, .jr-row et .btn vivent dans sept autres écrans,
   les redéfinir globalement les emporterait avec.

   L'ÉCHELLE DE PROFONDEUR, mesurée en luminance et non choisie à l'œil :
     1 fond de page ....... #0C0C0F
     2 surfaces de saisie . #1F1F24   les rangées ET le champ
     3 carte d'action ..... #2B2B32   l'autre route
     4 actions pleines .... le violet du bouton et du « + »
   ⚠️ LES NIVEAUX 2 ET 3 SONT NEUTRES, le violet ne leur sert qu'à BORDER. Une teinte
      posée sur une surface la fait avancer ; sur un filet d'un pixel elle dit seulement
      « ceci est à toi ». La page ne garde que deux accents : le violet des actions et les
      couleurs des pastilles.

   ⚠️ LES TROIS HALOS VIOLETS DU DOSSIER NE SONT PAS PORTÉS. L'app est passée en fond NOIR
      PLAT le 02/08 (régime OLED de l'accueil) ; les rallumer ici ferait diverger les deux
      écrans dès le premier aller-retour, ce que le dossier cherche justement à éviter.
      Conséquence mesurable et favorable : il calibrait ses rapports sur le pic du halo
      (#151221), donc sur le pire cas ; sur fond nu l'écart des surfaces passe de ×1,99 à
      ×3,6. Rien ne perd en lisibilité, tout en gagne. */

/* le bouton retour prend sa propre ligne. 32 VU, 44 TOUCHÉ : une cible ne se rétrécit
   jamais pour des raisons de dessin, c'est le ::after qui la rend.
   ⚠️ ET LE CHEVRON SUIT SON CARRÉ, à 12 px, soit 38 % de la boîte. Réduire un contenant
      sans réduire son contenu est l'oubli que le dossier a déjà payé : le glyphe restait à
      44 % et c'était LUI, surtout, qui faisait lourd. */
/* ⚠️ [07/08] GRILLE 36/1fr/36, LE MOTIF DE TOUTES LES BARRES DE L'APP. En flex, le titre
   se posait apres le bouton et flottait au tiers de la largeur ; la grille rend au bouton
   sa colonne, en reserve une identique a droite, et CENTRE LE TITRE SUR L'ECRAN, pas sur
   la place qui reste. Hauteur 44 : la cote d'une barre d'iOS et le plancher de cible. */
:is(#s-joueurs,#s-home) .jr-entete{display:grid;grid-template-columns:36px 1fr 36px;align-items:center;
  flex:0 0 auto;min-height:44px;margin-bottom:0}
/* ⚠️ [08/08] LE CORPS DEVIENT UNE COLONNE, ET C'EST CE QUI FAIT DESCENDRE LE DEPART.
   Le bouton « Commencer » s'arretait a 450 px sur 852 avec 400 px de vide dessous : il
   flottait au milieu d'un ecran a moitie vide, alors qu'il est la derniere chose de
   l'ecran. `margin-top:auto` ne pouvait rien tant que le corps n'etait pas un conteneur
   flex — une propriete ecrite sur un enfant ne vaut que ce que son parent en fait.
   ⚠️ ET CA NE POUSSE RIEN QUAND LA LISTE EST LONGUE : `margin-top:auto` ne distribue que
      la place qui RESTE. A vingt trinkeurs le corps defile et l'ecart retombe a zero. */
#s-joueurs .jr-body{display:flex;flex-direction:column}
#s-joueurs .bottom{padding-top:var(--e-5)}
:is(#s-joueurs,#s-home) .jr-entete .jr-retour{grid-column:1}
/* il ne garde en propre que ce que sa mise en page exige : le reste vient de .iconbtn et
   de la regle des lanceurs, comme sur Mini-jeux et Les classiques. */
:is(#s-joueurs,#s-home) .jr-retour{min-height:0;display:grid;place-items:center;color:var(--c-texte-2)}

/* L'INTRODUCTION : 34 au-dessus, 34 en dessous, 12 dedans. Un rapport de 1 à 2,8.
   ⚠️ CES DEUX 34 NE SONT PAS DES ESPACEMENTS, CE SONT DES CÉSURES. Le pas courant de
      l'écran reste 16. Une introduction se détache de ce qui la précède ET de ce qui la
      suit ; si elle ne se détachait que d'un côté, elle appartiendrait à l'autre. */
/* ⚠️ [07/08] `.jr-intro` EST RETIREE, PAS LAISSEE EN PLACE. Son element a disparu du HTML
   quand le titre est monte dans la barre et que la ligne d'aide est descendue sous le champ.
   Une regle qui ne cible plus rien finit par etre corrigee a la place de celle qui sert —
   c'est ce qui etait arrive le 05/08 avec dix regles orphelines du bouton compte. */
/* 26 px pour un LIEU. L'échelle se tient : 34 pour l'arrivée d'un mode, 26 pour un lieu,
   18 pour une barre. Et son écart avec l'accroche fait 2× : un point focal se fabrique par
   un RAPPORT, pas par une taille absolue.
   ⚠️ AUCUNE COULEUR DESSUS. Mini-jeux porte un « jeux » or, Les classiques un
      « classiques » fuchsia, le Multijoueur un « joueur » sarcelle ; le socle écrit que la
      rangée trinkeurs n'est PAS un mode et reste neutre. Colorer une syllabe lui
      inventerait un territoire et rendrait la couleur muette partout ailleurs. */
/* ⚠️ 21/600 CENTRE, la cote des titres de barre de l'app. Il valait 26/800 quand il vivait
   dans le corps de la page : un titre de LIEU, pas un titre de BARRE. En remontant il change
   de role, donc de mesure — **un ecart se recalcule quand ce qu'il separe change de nature.** */
:is(#s-joueurs,#s-home) .jr-titre{grid-column:2;justify-self:center;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;
  color:var(--ink);line-height:1.2}
/* ⚠️ SA MESURE EST PLUS COURTE QUE CELLE DU TITRE, et c'est la seule chose de ce bloc qui
   ne soit pas un chiffre : un titre large avec un texte plus étroit dessous, c'est la FORME
   d'une introduction, on la reconnaît avant d'avoir lu les mots. En Grand texte la phrase
   passe à deux lignes équilibrées au lieu d'une longue et d'un mot orphelin. */
/* ⚠️ 14 ET NON 12 : elle suivait un TITRE, elle suit maintenant un CHAMP de saisie, dont
   la boite arrondie descend plus bas que ne descendait une ligne de texte. **Un ecart se
   recalcule quand ce qu'il separe change de nature.** */
#s-joueurs .jr-accroche{margin:var(--e-3) auto 0;max-width:31ch;font-size:var(--t-1);font-weight:400;
  line-height:1.4;text-wrap:balance;color:var(--c-texte-3);text-align:center}

/* ⚠️ [08/08, Theo] LA DESCRIPTION SOUS LE TITRE, ET L'ECRAN QUI RESPIRE.
   Releve avant correction, a 393x852 avec deux trinkeurs : l'ecart entre le bas de
   l'en-tete et la premiere rangee valait ZERO, et tout le contenu s'arretait a 450 px
   sur 852, donc un ecran tasse en haut avec 400 px de vide en bas. « Rien ne respire »
   etait litteralement vrai.
   L'echelle du fichier ne change pas, on l'applique : 10 d'un titre a sa description
   (8-13 au socle, un intitule et son contenu), 26 d'une introduction a un contenu (la
   cote d'un LIEU, deja celle qui separe l'ajout de l'autre route), 16 pour le pas
   courant. Ce sont les memes chiffres que le reste de l'ecran, pas de nouveaux.
   ⚠️ SA MESURE EST CELLE DE L'ACCROCHE, PAS CELLE DU TITRE : un titre large avec un
      texte plus etroit dessous, c'est la FORME d'une introduction, on la reconnait
      avant d'avoir lu les mots. */
/* ⚠️ [08/08, 2e passe, Theo] « LA DESCRIPTION N'EST PAS ASSEZ RATTACHEE AU TITRE ET TROP
   RAPPROCHEE DU RESTE DE LA PAGE ». Mesure de la premiere passe : 19 px au-dessus contre
   26 en dessous. Presque egaux, donc la description n'appartenait a rien — elle flottait
   entre les deux. Un ecart ne dit pas une distance, il dit une APPARTENANCE : c'est le
   RAPPORT entre les deux qui designe le proprietaire, pas leur valeur absolue.
   ⚠️ ET LE 10 QUE J'AVAIS ECRIT NE FAISAIT PAS 10. L'en-tete a `min-height:44px` pour la
      cote de cible, le titre n'en occupe que 26 : il reste 9 px de barre SOUS le texte,
      qui s'ajoutent a la marge. Une marge posee sur un frere ne mesure pas ce qu'on voit.
      3 + 9 = 12 a l'oeil, et 34 en dessous : le rapport de 1 a 2,8 que ce fichier prescrit
      deja pour une introduction. */
#s-joueurs .jr-sous{margin:var(--e-3) auto 0;max-width:31ch;font-size:var(--t-1);font-weight:400;
  line-height:1.4;text-wrap:balance;color:var(--c-texte-3);text-align:center}

/* LA LISTE PASSE EN TÊTE : l'écran demande qui joue, son contenu est la liste de ceux qui
   jouent. Il ouvrait par ses outils, il ouvre par sa réponse. */
/* ⚠️ [08/08, 3e passe] 34, ET C'EST DESORMAIS DU VIDE PUR. Tant que la description vivait
   la, ces 34 la separaient d'un contenu ; maintenant qu'elle est passee sous « Commencer »,
   c'est l'ecart du TITRE a la liste, et il ne porte plus rien. Theo a valide l'espacement
   d'avant (73 px) mais il contenait deux lignes de texte : garder 73 de blanc aurait fait un
   trou, pas de la respiration. On garde donc la cesure de 34, la cote deja en usage entre
   une tete d'ecran et son contenu. Le pas courant de l'ecran reste 16. */
#s-joueurs .jr-list{display:flex;flex-direction:column;gap:var(--e-2);margin-top:var(--e-5)}
/* liste vide : sans ca, la marge de la liste et celle de la zone d'ajout s'additionnaient
   (34 + 16 = 50) et le premier ecran de l'app etait le seul a ne pas suivre son propre pas.
   Une boite vide garde ses marges : elle n'a plus de contenu, elle a encore une place. */
#s-joueurs .jr-list:empty{margin-top:0}
#s-joueurs .jr-list:empty+#jr-add-zone{margin-top:var(--e-5)}
/* ⚠️ DEUX COLONNES, ET LA RANGÉE NE CHANGE PAS D'UN PIXEL : même hauteur, même pastille,
   même croix. UN SEUL OBJET, DEUX ARRANGEMENTS. Seule la place du prénom se réduit, et elle
   se réduit par TRONCATURE, jamais par un corps plus petit : un prénom coupé se devine, un
   prénom rapetissé ne se lit plus.
   ⚠️ CE QUE ÇA COÛTE, MESURÉ PAR LE DOSSIER : le prénom tombe de 33 caractères à 11 sur un
      iPhone de 402, et à NEUF sur un 375. « Alexandre » passe tout juste, les prénoms
      composés sont perdus. Ce qu'on gagne : 776 px de liste ramenés à 384. */
#s-joueurs .jr-list.deux{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2)}
/* min-width:0 EST OBLIGATOIRE, ET SON ABSENCE COUTE LA CROIX. Un enfant de grille vaut
   min-width:auto par defaut, donc il refuse de descendre sous son contenu minimum : les
   colonnes s'elargissaient au-dela de la place disponible et la croix de la colonne droite
   sortait de l'ecran. Mesure avant : la rangee reclamait 177 px la ou la colonne en offre
   167. C'est la meme famille que ce que le dossier avait releve sur la liste Multijoueur,
   « l'anneau des pastilles debordait de la colonne, 2,5 px qu'aucun calcul ne voyait ». */
#s-joueurs .jr-list.deux .jr-row{padding-right:var(--e-1);gap:var(--e-2);min-width:0}
/* L'ÉQUATION DE LA RANGÉE : hauteur = 2 × rembourrage + disque + 6. Le disque n'est pas
   seul, le connecté porte deux anneaux (2 px de vide, 3,5 de violet), donc son EMPREINTE
   vaut son diamètre PLUS SIX. Le dossier a déjà payé l'erreur sur la liste Multijoueur :
   « l'anneau des pastilles débordait de la colonne, 2,5 px qu'aucun calcul de largeur ne
   voyait ». 32 + 6 = 38 d'empreinte, 5 de rembourrage, rangée de 48.
   min-height et JAMAIS height : le Grand texte doit pouvoir pousser. */
#s-joueurs .jr-row{display:flex;align-items:center;gap:var(--e-3);min-height:48px;
  padding:var(--e-1) var(--e-2) var(--e-1) var(--e-3);background:#1F1F24;border:1px solid rgba(139,92,246,.34);
  border-radius:var(--r-2);box-shadow:inset 0 1px 0 rgba(255,255,255,.07)}
#s-joueurs .jr-row b{flex:1 1 auto;min-width:0;font-size:var(--t-2);font-weight:700;
  letter-spacing:-.01em;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠️ LE TRAIT DE 2 px EST PEINT DE LA COULEUR DE LA RANGÉE, PAS D'UNE CONSTANTE. Sur
   l'accueil la rangée vaut #0A090E, ici #1F1F24 : laissé à la valeur de l'accueil, le vide
   deviendrait un anneau NOIR visible autour de chaque disque. */
#s-joueurs .jr-row .cl-av{width:32px;height:32px;font-size:var(--t-2);font-weight:700;
  box-shadow:0 0 0 2px #1F1F24}
/* les huit teintes de la rangee de l'accueil, aux memes valeurs : une personne garde sa
   couleur d'un ecran a l'autre. Arc 205 -> 250 degres, clartes ALTERNEES pour que deux
   pastilles voisines ne se confondent jamais.
   ATTENTION, ces huit-la sont TOUTES portees : la liste peut aller jusqu'a quatorze, donc
   aucune n'est une regle morte. Au-dela de huit les couleurs recommencent et c'est
   l'initiale qui identifie (decision de Theo du 03/08) : elargir l'arc mordrait sur le
   fuchsia des Classiques, l'or des Mini-jeux, le sarcelle du Multijoueur, le vert du compte
   ou le rouge de l'irreversible. */
#s-joueurs .jr-row .cl-av.av1{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av2{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av3{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av4{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av5{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av6{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av7{background:#DDD5C7;color:#170B20}
#s-joueurs .jr-row .cl-av.av8{background:#DDD5C7;color:#170B20}
/* le connecté porte le double anneau de l'accueil, À SES VALEURS ACTUELLES (3,5 px,
   #A78BFA) : le dossier propose 3 px et #9B7BF2, mais `.av.estmoi` vit dans les neuf
   fichiers de l'accueil et cette marque dit « celui-là n'est pas retirable » ; elle ne peut
   pas différer d'un écran à l'autre, c'est ce qu'elle sert à ne pas faire. Décision de Theo
   du 03/08 : on ne touche pas au socle dans cette passe. */
#s-joueurs .jr-row .cl-av.moi{background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);
  color:var(--accent-ink);box-shadow:0 0 0 2px #1F1F24,0 0 0 3.5px #A78BFA}
/* 34 VU, 44 TOUCHÉ. Le plein rouge cède un simple contour : l'acte reste signalé, il ne
   crie plus. ⚠️ LE ROUGE EST GARDÉ ET C'EST MESURÉ, PAS SUPPOSÉ : retirer un trinkeur
   efface AUSSI toutes ses gorgées de la partie en cours (UI-29), et la croix est immédiate,
   c'est une annulation de quatre secondes qui protège, pas une confirmation. L'acte est donc
   plus lourd qu'un simple retrait de ligne. */
#s-joueurs .jr-row .jr-x{position:relative;width:34px;height:34px;min-height:0;border-radius:50%;
  flex:0 0 auto;display:grid;place-items:center;background:transparent;
  border:1px solid rgba(248,113,113,.28);color:#F87171;font-size:var(--t-3);line-height:1}
#s-joueurs .jr-row .jr-x::after{content:"";position:absolute;inset:-5px;border-radius:50%}
#s-joueurs .jr-row .jr-x:active:not(.enfonce){transform:scale(.9);background:rgba(248,113,113,.12)}
/* le badge « compte » RESTE pour les autres, et il ne fait pas doublon : le double anneau ne
   marque que MOI, dont la ligne n'a pas de croix. Un ami connecté à son compte, lui, a une
   croix et rien ne le distinguerait sans ce mot. Le dossier ne traite que le cas du
   connecté : ne pas retirer une information qu'il n'a pas regardée. */
#s-joueurs .jr-row .hp-lie{flex:0 0 auto}

/* UNE SEULE LIGNE VISUELLE : le bouton n'est plus à côté du champ, il est DEDANS.
   ⚠️ LA RECETTE DE LA BARRE DE RECHERCHE VOYAGE, SON NOMBRE NON. Voile translucide bleuté,
      flou, AUCUNE bordure, liseré de lumière sur l'arête haute. Mais son alpha de .055
      marche sur le Multijoueur parce que sa page est éclairée par un halo sarcelle ; ici il
      rendrait un TROU plus sombre que les rangées. À .12 la barre passe AU-DESSUS d'elles,
      ce qu'une surface de saisie doit toujours faire. */
:is(#s-joueurs,#m-players) .jr-ajout{position:relative;margin-top:0}
:is(#s-joueurs,#m-players) .jr-saisie{width:100%;height:52px;padding:0 var(--e-6) 0 var(--e-3);
  background:rgba(168,178,225,.12);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);backdrop-filter:blur(16px) saturate(1.3);
  border:0;border-radius:999px;font-family:inherit;font-size:var(--t-2);color:var(--ink);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);transition:box-shadow .18s}
:is(#s-joueurs,#m-players) .jr-ajout:focus-within .jr-saisie{box-shadow:inset 0 1px 0 rgba(167,139,250,.14),
  0 0 0 2px rgba(139,92,246,.22)}
/* un texte d'invite qui rivalise avec du contenu réel fait croire que le champ est rempli */
:is(#s-joueurs,#m-players) .jr-saisie::placeholder{color:var(--c-texte-3)}
/* [05/11, Romain : « le + à droite de la barre est pas aligné »] la charte a passé la boîte à 40 px (plus bas) et le top fixe
   de 11 px, calculé pour 30, posait le + 5 px trop bas. Centré dans le champ quelle que soit la boîte, et sur l'axe des croix
   de la liste (right 9). Banc : outils/test-qui-joue-barre.py. */
:is(#s-joueurs,#m-players) .jr-plus{position:absolute;top:0;bottom:0;margin:auto 0;right:9px;width:30px;height:30px;min-height:0;
  border-radius:50%;border:0;display:grid;place-items:center;background:#8B5CF6;padding:0}
:is(#s-joueurs,#m-players) .jr-plus::after{content:"";position:absolute;inset:-7px;border-radius:50%}
:is(#s-joueurs,#m-players) .jr-plus:active:not(.enfonce){transform:scale(.9)}
:is(#s-joueurs,#m-players) .jr-plus svg{width:14px;height:14px;stroke:var(--accent-ink);fill:none;
  stroke-width:2.5;stroke-linecap:round}

/* ⚠️ L'AUTRE ROUTE, ET SON ÉCART CHANGE DE SENS. Après le bouton de validation, tout ce qui
   reste n'est plus la suite de l'écran : c'est « ou bien, ce trinkeur a un compte ». Un
   écart de 16 en ferait la suite du bouton, 26 en fait une alternative.
   ⚠️ ELLE NE DOIT PAS RESSEMBLER À UN TRINKEUR : les rangées sont des CHOSES, des gens déjà
      là ; celle-ci est un ACTE. Fond levé au niveau 3, arête haute au lieu d'un creux : elle
      est POSÉE, elles sont CREUSÉES.
   ⚠️ ET ELLE SORT DU VIOLET : elle concurrençait « Valider » en teinte alors qu'elle n'est
      qu'une autre route. Anthracite neutre ; la seule chose violette qui lui reste est le
      support de son icône. */
#s-joueurs .jr-lien{display:flex;align-items:center;gap:var(--e-3);width:100%;margin-top:var(--e-4);
  padding:var(--e-3) var(--e-3);text-align:left;cursor:pointer;
  background:linear-gradient(180deg,#33333C 0%,#2B2B32 62%,#26262C 100%);
  border:1px solid #383842;border-radius:var(--r-3);color:var(--ink)}
#s-joueurs .jr-lien:active:not(.enfonce){transform:scale(.985)}
#s-joueurs .jr-gi{width:40px;height:40px;border-radius:var(--r-2);flex:0 0 auto;display:grid;
  place-items:center;background:rgba(139,92,246,.13);border:1px solid rgba(139,92,246,.22);
  color:#CBB6FC}
#s-joueurs .jr-gi svg{width:20px;height:20px}
#s-joueurs .jr-lien .jr-cb-t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;text-align:left}
#s-joueurs .jr-lien b{display:block;font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:var(--ink)}
#s-joueurs .jr-lien i{font-style:normal;display:block;font-size:var(--t-1);margin-top:var(--e-1);
  line-height:1.3;color:var(--mut)}
#s-joueurs .jr-chev{width:9px;height:15px;flex:0 0 auto;fill:none;stroke:var(--dim);
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* le pas courant de l'écran reste 16 : le champ suit la liste, le bouton suit le champ. */
#s-joueurs #jr-add-zone{margin-top:var(--e-3)}
#s-joueurs .bottom{padding-top:var(--e-3)}

/* LE BOUTON DE VALIDATION REDEVIENT VIOLET, ET LE DOSSIER A RAISON SUR LES DEUX POINTS.
   Il rendait un vert mesure a #1BB353, teinte 142 degres : le socle reserve le vert autour
   de 145 au COMPTE connecte, et le Multijoueur s'en sert deja pour la presence. Deux sens
   pour une teinte sur le meme ecran, c'est l'erreur 20 du dossier.
   Et surtout, l'app a DEJA un bouton primaire, violet : ce vert en etait un second, donc
   un doublon. Un ecran a un seul bouton principal, sinon aucun ne l'est.
   Scope a #s-joueurs : .hpc-ok est declare TROIS fois dans cette feuille (deux verts, un
   violet, le dernier gagne) alors qu'il ne sert que sur ce bouton. Je ne nettoie pas ce
   doublon ici, ce serait toucher a autre chose que l'ecran porte ; il est signale. */
#s-joueurs .hpc-ok{background:linear-gradient(90deg,var(--accent),var(--accent2));
  color:var(--accent-ink)}

/* ═══ LA BARRE DE SAISIE DU FIL, RELEVÉE SUR iMESSAGE (03/08) ═══════════════════════════
   Mesure au pixel sur les deux captures de Theo, ramenée en points :

                        Apple      nous, avant
     hauteur du champ   43,0 pt    46,7 pt
     bouton d'envoi     28 pt      46 pt
     ou vit-il          DANS       à côté
     largeur du champ   306 pt     237 pt

   ⚠️ LE VRAI ÉCART N'EST PAS LA HAUTEUR, C'EST LA PLACE VOLÉE. Un bouton de 46 pt posé à
      côté du champ lui prend sa largeur plus l'écart : 69 points de moins pour écrire, soit
      près d'un quart. Le rentrer dans la capsule rend cette place au texte, et c'est ce qui
      fait toute la différence de silhouette avec iMessage.
   ⚠️ ET LE CHAMP DEVIENT UNE VRAIE CAPSULE. Un rayon de 20 px sur une hauteur de 46 n'est
      pas un arrondi, c'est un rectangle aux coins cassés : il faut la moitié de la hauteur
      pour que la forme se lise comme une capsule. C'est le « pas assez arrondi ». */
#s-multi .chat-zone{position:relative;flex:1 1 auto;min-width:0;display:flex}
/* la hauteur passe de 46,7 à 43 pt, la valeur d'Apple : le rembourrage tombe de 12 à 10, le
   corps reste à 16 px (sous 16, iOS zoome au focus, cf. v458). */
#s-multi .chat-saisie textarea{padding:var(--e-2) var(--e-6) var(--e-2) var(--e-3);border-radius:999px;
  max-height:112px}
/* [03/08, après jugement de Theo sur appareil] LE BOUTON DEVIENT ROND, ET IL FLOTTE.
   Mesure des deux captures, ramenée en points :

                              Apple    nous, v459
     diamètre                 28,0     34,0
     écart au bord du champ    7,7      4,5
     forme                    cercle   carré arrondi

   ⚠️ LA FORME SUIT LA BARRE, ET C'EST LA RÈGLE QUE THEO POSE : le champ est une capsule,
      donc son bouton est un rond. Un carré arrondi dans une capsule donne deux géométries
      pour un seul objet, et c'est ce qui le faisait paraître collé.
   ⚠️ CECI ANNULE MON ARBITRAGE DE LA v459, qui gardait le carré arrondi au nom de
      « forme = nature » (cercle pour une personne, carré arrondi pour une fonction). La
      règle vaut toujours ailleurs ; ici c'est l'appartenance à la capsule qui l'emporte.
      À faire suivre au dossier, qui écrit encore que le bouton d'envoi est carré arrondi.
   ⚠️ 28 VU, 44 TOUCHÉ : l'inset passe à -8 pour que la cible reste entière alors que
      l'objet rétrécit. Une cible ne se rétrécit jamais pour des raisons de dessin. */
#s-multi .chat-env{position:absolute;right:7px;top:50%;margin-top:-14px;
  width:28px;height:28px;min-height:0;border-radius:50%;font-size:var(--t-2);padding:0}
#s-multi .chat-env::after{content:"";position:absolute;inset:-8px;border-radius:50%}

/* ═══ LA CITATION DEVIENT UN BLOC À PART (03/08, relevé de Theo sur appareil) ═══════════
   Elle vivait DANS la bulle, sur le même fond : on ne distinguait ni le message cité de la
   réponse, ni qui avait écrit quoi. Sur la capture, « Romain / baise ta m / Ouaii » formait
   un seul rectangle sarcelle.

   ⚠️ DEUX BLOCS, ET DEUX COULEURS D'AUTEUR. C'est la demande, et c'est ce que fait
      iMessage : la citation porte la couleur de CELUI QUI A ÉCRIT LE MESSAGE CITÉ, la
      réponse porte la mienne. Sans ça, répondre à quelqu'un ressemble à se répondre
      soi-même.
   ⚠️ ET ELLE EST CREUSE, PAS PLEINE. Le dossier le demandait déjà sous le nom « citation en
      bulle creuse », resté non porté. Une citation pleine ferait deux messages de rang égal
      empilés ; creuse, elle se lit comme un rappel de ce à quoi on répond. C'est aussi ce
      qui la distingue d'une vraie bulle sans lui inventer une troisième couleur. */
/* ⚠️ LA COLONNE DEVIENT UNE COLONNE POUR TOUT LE MONDE. `.ln-c` n'etait en flex que
   pour MES messages ; sur un message recu, il restait un bloc simple et la citation
   n'aurait pas su se placer. On l'aligne donc a gauche par defaut, a droite pour les
   miens, ce qui ne change rien a la bulle : elle prend deja la largeur de son texte. */
#s-multi .ln-c{display:flex;flex-direction:column;align-items:flex-start}
#s-multi .ln.moi .ln-c{align-items:flex-end}
#s-multi .bul-cite{max-width:100%;width:-webkit-max-content;width:max-content;
  align-self:flex-start;
  padding:var(--e-2) var(--e-3);margin-bottom:var(--e-1);border-radius:var(--r-2);
  background:transparent;border:1px solid rgba(168,178,225,.30);
  font-size:var(--t-1);line-height:1.3;color:var(--c-texte-2);
  overflow-wrap:break-word;word-break:normal}
/* le nom de l'auteur cité, sur sa propre ligne : c'est lui qui dit « c'est à ça que je
   réponds », donc il passe avant le texte et il est le seul élément net du bloc. */
/* .75rem et pas .72 : le contrat a attrape la faute, UI-04 pose un plancher de 12 px sur
   TOUT texte de l'app et 11,5 passait dessous. Un nom d'auteur est de l'information, pas
   une decoration : il se lit. */
#s-multi .bul-cite b{display:block;font-size:var(--t-1);font-weight:700;color:var(--c-texte-3);
  margin-bottom:1px}
/* ma propre citation prend l'encre du mode, comme mes bulles : on doit voir d'un coup d'œil
   si l'on se cite soi-même ou si l'on cite l'autre. */
#s-multi .bul-cite.moi{border-color:rgba(94,234,212,.42);color:#BDE8E2}
#s-multi .bul-cite.moi b{color:#5EEAD4}
/* la citation SUIT le côté de la réponse : à droite quand je réponds, à gauche quand
   l'autre répond. Elle est ainsi toujours au-dessus de la bulle qu'elle annonce. */
#s-multi .ln.moi .bul-cite{align-self:flex-end}

/* ═══ CITER UN JEU N'EST PAS CITER UN MESSAGE (03/08, relevé de Theo) ═══════════════════
   La citation d'une partie affichait « Romain / Partie » : le mot générique, sans le jeu ni
   son état. À l'écran, répondre à une soirée annulée ressemblait trait pour trait à répondre
   à « ouais ». Elle est maintenant plus large, porte la manette, le nom du jeu, son état, et
   la couleur du mode joué.
   ⚠️ ELLE RESTE CREUSE ET RESTE UNE CITATION. Plus grosse ne veut pas dire plus lourde
      qu'une vraie carte de partie : celle-ci est un rappel de ce à quoi on répond, la vraie
      carte est l'événement. La teinte du mode vit donc sur le FILET et sur l'icône, pas en
      aplat, sinon la citation passerait devant le message qu'elle annonce. */
/* ⚠️ `bc-partie` ET PAS `jeu` : la classe `.jeu` est DEJA prise par les tuiles du
   catalogue, qui posent flex-direction:column. Ma citation heritait donc de leur colonne et
   empilait icone, texte et badge les uns sous les autres. Troisieme collision de nom de la
   nuit apres .mu-tete et .jr-champ : dans une feuille de cette taille, une classe d'un seul
   mot courant est presque toujours deja prise. */
#s-multi .bul-cite.bc-partie{display:flex;align-items:center;gap:var(--e-2);
  padding:var(--e-2) var(--e-3);border-radius:var(--r-2);font-size:var(--t-1);
  border:1px solid rgba(168,178,225,.34)}
#s-multi .bul-cite.bc-partie .bc-ico{flex:0 0 auto;width:26px;height:26px;border-radius:var(--r-1);
  display:grid;place-items:center;background:rgba(168,178,225,.10);color:var(--c-texte-2)}
#s-multi .bul-cite.bc-partie .bc-ico svg{width:16px;height:16px}
#s-multi .bul-cite.bc-partie .bc-t{min-width:0;display:flex;flex-direction:column}
#s-multi .bul-cite.bc-partie .bc-t b{display:block;font-size:var(--t-1);font-weight:700;
  color:var(--c-texte-3);margin:0}
#s-multi .bul-cite.bc-partie .bc-t i{font-style:normal;font-size:var(--t-1);font-weight:600;
  color:var(--c-texte);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* l'état porte le même traitement que sur la vraie carte de partie : un badge neutre, jamais
   rouge. « Annulée » et « Terminée » sont deux CONDITIONS, pas deux signaux, et une partie
   annulée se rattrape en en relançant une. Le rouge reste à ce qui ne se rattrape pas. */
/* .75rem : UI-04 pose un plancher de 12 px sur TOUT texte de l'app, capitales comprises.
   Le contrat l'a attrape a 11 px. */
#s-multi .bul-cite.bc-partie .bc-etat{flex:0 0 auto;font-size:var(--t-1);font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--c-texte-2);
  background:rgba(255,255,255,.07);border-radius:var(--r-1);padding:var(--e-1) var(--e-2)}

/* LA COULEUR DU MODE VIT SUR LE FILET ET SUR L'ICÔNE. Un aplat suit son mode partout dans
   l'app (bannière de reprise, carte de partie) ; ici il ne peut être qu'un liseré, sinon la
   citation pèserait plus que la réponse qu'elle introduit. */
#s-multi .bul-cite.bc-partie.m-soiree{border-color:rgba(139,92,246,.52)}
#s-multi .bul-cite.bc-partie.m-soiree .bc-ico{background:rgba(139,92,246,.16);color:#C4B5FD}
#s-multi .bul-cite.bc-partie.m-classiques{border-color:rgba(236,72,153,.52)}
#s-multi .bul-cite.bc-partie.m-classiques .bc-ico{background:rgba(236,72,153,.16);color:#F9A8D4}
#s-multi .bul-cite.bc-partie.m-minijeux{border-color:rgba(251,191,36,.52)}
#s-multi .bul-cite.bc-partie.m-minijeux .bc-ico{background:rgba(251,191,36,.16);color:#FCD34D}
/* le nom de celui qui a lancé suit la même règle que sur une citation de message : sarcelle
   quand c'est moi, bleuté quand c'est l'autre. */
#s-multi .bul-cite.bc-partie.moi .bc-t b{color:#5EEAD4}

/* ═══ LA CARTE DE PARTIE, PORTÉE SUR LE RENDU DE RÉFÉRENCE (03/08) ══════════════════════
   Mesure au pixel du rendu contre notre écran, ramenée en points :

                              rendu     nous, avant
     largeur de la carte      362 pt    263 pt
     luminance / la page      1,25-1,49×  0,93×   (donc PLUS SOMBRE que le fond)
     titre                    11,7 pt   10,0 pt
     sous-titre               11,0 pt    9,3 pt
     icône du mode            34 pt     aucune

   ⚠️ LE PLUS GRAVE N'ÉTAIT PAS LA TAILLE, C'ÉTAIT DEUX ERREURS DE NATURE.
      1. UNE CARTE DE PARTIE N'EST PAS UNE BULLE. Elle héritait du plafond de 76 % réservé
         aux messages, alors qu'un événement de partie concerne toute la conversation et
         n'appartient à personne : il prend donc toute la largeur, comme le séparateur de
         date. C'est ce qui explique les 263 pt contre 362.
      2. ELLE ÉTAIT PLUS SOMBRE QUE SA PAGE (0,93×). Un objet posé sur un fond doit être
         plus clair que lui, sinon il se lit comme un trou et non comme une carte. */
#s-multi .ln-c:has(.bul-fini),#s-multi .ln-c:has(.bul-partie){max-width:100%;width:100%}
#s-multi .bul-fini,#s-multi .bul-partie{width:100%}

/* la carte devient une rangée : icône, contenu, et le badge d'état au bout du titre. */
#s-multi .bul-fini{flex-direction:row;align-items:center;gap:var(--e-3);
  padding:var(--e-3) var(--e-3);border-radius:var(--r-3);border-left-width:1px}
#s-multi .bul-fini .bf-ico{flex:0 0 auto;width:34px;height:34px;border-radius:var(--r-1);
  display:grid;place-items:center;background:rgba(168,178,225,.10);color:var(--c-texte-2)}
#s-multi .bul-fini .bf-ico svg{width:19px;height:19px}
#s-multi .bul-fini .bf-c{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:var(--e-1)}
/* 1,05rem contre .94 : le titre du rendu mesure 11,7 pt de capitale contre nos 10,0. */
#s-multi .bul-fini .bf-h b{font-size:var(--t-3);font-weight:800;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* .8125rem contre .76 : 11,0 pt de capitale dans le rendu contre nos 9,3. */
#s-multi .bul-fini .bf-d{font-size:var(--t-1);color:var(--mut)}

/* ⚠️ LES FONDS SONT RECALCULÉS POUR ÊTRE PLUS CLAIRS QUE LA PAGE, PAS PLUS SOMBRES.
   Les valeurs viennent du rendu, relevées au pixel : fuchsia rgb(44,23,37), or
   rgb(43,35,18), violet rgb(31,24,49), sur une page à rgb(12,17,20). Elles donnent le
   rapport de 1,25 à 1,49 mesuré chez lui, contre 0,93 chez nous.
   ⚠️ ET C'EST UNE COULEUR PLEINE, PAS UNE TEINTE POSÉE EN ALPHA : un rgba sur un fond qui
      porte déjà un halo ne donne pas la même chose selon l'endroit de l'écran, et c'est
      précisément ce qui rendait nos cartes plus sombres en bas qu'en haut. */
#s-multi .bul-fini.m-soiree{background:#1F1831;border-color:rgba(139,92,246,.30)}
#s-multi .bul-fini.m-classiques{background:#2C1725;border-color:rgba(236,72,153,.30)}
#s-multi .bul-fini.m-minijeux{background:#2B2312;border-color:rgba(251,191,36,.30)}
/* le repli, pour une partie dont le mode n'est pas connu */
#s-multi .bul-fini{background:#1E1E26;border-color:rgba(168,178,225,.22)}
/* l'icône prend la teinte de son mode, en clair : c'est le seul objet coloré de la carte,
   le texte reste neutre pour que le titre porte l'information et non la couleur. */
#s-multi .bul-fini.m-soiree .bf-ico{background:rgba(139,92,246,.20);color:#C4B5FD}
#s-multi .bul-fini.m-classiques .bf-ico{background:rgba(236,72,153,.20);color:#F9A8D4}
#s-multi .bul-fini.m-minijeux .bf-ico{background:rgba(251,191,36,.20);color:#FCD34D}
/* ⚠️ UNE PARTIE ANNULÉE N'EST PLUS ESTOMPÉE. L'opacité à .65 la rendait illisible sur un
   fond déjà sombre, alors que « annulée » est une CONDITION et non une mise au rebut : la
   carte se lit, c'est son badge qui dit son état. */
#s-multi .bul-fini.annulee{opacity:1}

/* ═══ LES DEUX AUTRES ÉTATS DE LA LISTE (03/08, dossier « vue liste ») ═══════════════════
   « Cas courant », « invitation » et « vide » ne sont pas trois écrans, ce sont trois ÉTATS
   DU MÊME ÉCRAN. Les deux derniers restaient dessinés à l'ancienne : ouverts à côté du
   premier, ils ne décrivaient plus le même produit. Le dossier dit avoir déjà payé ça une
   fois, et le cas « vide » est celui de TOUT NOUVEL INSCRIT, donc le premier écran
   Multijoueur que verra n'importe qui. */

/* ── L'INVITATION ─────────────────────────────────────────────────────────────────────
   Même grille que la rangée de conversation (pastille 44, tête, ligne), plus une rangée
   d'actions dessous. Elle n'est PAS un bouton : on n'ouvre pas une invitation, on y répond,
   et ses deux réponses sont les seules choses touchables. */
/* ⚠️ [07/08] L'INTITULE S'ALIGNE SUR LA MARGE DE PAGE, PAS SUR UN NOMBRE A LUI. Il
   vivait a 2 px du bord du corps, donc a 18 de l'ecran par accident ; la liste, elle,
   ressort bord a bord. On pose donc la marge de page (18) sur le seul objet du bloc qui
   ne ressort pas. Le rendu ecrit 16, la valeur de la page AVANT qu'elle ne passe a 18
   dans la meme vague : une cote qui se DEDUIT de la page se reproduit toute seule, une
   cote recopiee finit par diverger. Ecart signale a Theo, pas subi. */
#s-multi .mu-sect{margin:var(--e-3) 0 var(--e-2) 18px;padding:0;font-size:var(--t-1);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
/* ⚠️ MEME REMBOURRAGE QU'UNE RANGEE, AU PIXEL : 10 / 18 / 21. L'invitation prend la
   geometrie exacte d'un fil — meme colonne d'avatar, meme grille, meme filet — et gagne
   une troisieme ligne pour ses actions. Ce qui la distingue est ce qu'elle EST (elle
   porte une action), pas ce qu'elle vaut. Elle vivait a `10px 4px 14px`, donc son texte
   commencait 14 px avant celui des rangees voisines. */
#s-multi .mu-invit{position:relative;display:grid;grid-template-columns:44px 1fr auto;
  align-items:center;column-gap:var(--e-2);width:100%;min-height:79px;
  padding:var(--e-2) var(--e-3) var(--e-4);text-align:left;background:transparent;border:0}
/* ⚠️ ET ELLE PORTE LE MEME FILET QUE SES VOISINES : sans lui, la seule rangee a trois
   lignes de l'ecran etait aussi la seule sans bord bas, et la liste se coupait en deux
   a l'endroit exact ou elle devait se lire d'une traite. */
#s-multi .mu-invit::after{content:'';position:absolute;left:72px;right:18px;bottom:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.13)}
#s-multi .mu-invit>.mu-ava{grid-area:1/1/3/2}
#s-multi .mu-invit>.mu-tete{grid-area:1/2/2/4;display:flex;align-items:center;gap:var(--e-2);min-width:0}
#s-multi .mu-invit>.mu-ligne{grid-area:2/2/3/4}
/* ⚠️ 22 D'ECART, 9 AU-DESSUS : les cotes de `amis-demandes`. Deux ecrans qui portent la
   meme rangee portent les memes intervalles. */
#s-multi .mu-invit>.mu-actes{grid-area:3/2/4/4;display:flex;flex-wrap:wrap;
  align-items:center;gap:var(--e-4);margin-top:var(--e-2);min-width:0}
/* l'étiquette dit l'état SANS bouton et sans couleur d'alerte : tant qu'on n'a pas répondu,
   on n'est pas dans le groupe, et cela n'a rien d'anormal. */
#s-multi .mu-etiq{flex:0 0 auto;font-size:var(--t-1);font-weight:700;color:#5EEAD4}
/* ⚠️⚠️ [07/08] LES DEUX ACTIONS NE SONT PLUS DEUX MOTS COLORES, CE SONT LES DEUX GELULES
   D'`amis-demandes`, ET C'EST LA MEME REGLE QUI LES DESSINE (`.am-act`, plus bas dans
   cette feuille, dont le selecteur accueille desormais les deux ecrans). Trois raisons,
   toutes du rendu final :
   ① ACCEPTER OU REFUSER UNE INVITATION DE GROUPE ET ACCEPTER OU REFUSER UNE DEMANDE
      D'AMI SONT LE MEME ACTE : on repond oui ou non a quelqu'un. Deux objets qui font la
      meme chose portent le meme dessin — et une seule regle, sinon les deux divergent.
   ② DEUX MOTS NE SONT PAS DEUX BOUTONS : « Accepter » a 14/700 offrait une cible de la
      taille du mot, etendue a la main par un `::after` de -12/-10. Une action qui engage
      quelqu'un d'autre ne se pose pas sur une cible de la taille de son texte. La gelule
      fait 36 de haut, la cible du socle, sans pseudo-element.
   ③ « ACCEPTER » PASSE DU SARCELLE AU BLEU. Le sarcelle est la teinte du MODE ; ici on
      ajoute des GENS a un groupe, et le bleu appartient aux gens — c'est deja pourquoi
      le « + » d'Amis est bleu et pourquoi « Accepter » l'est sur les demandes d'ami.
   ⚠️ « REFUSER » N'EST TOUJOURS PAS ROUGE : refuser ne detruit rien, on peut etre
      reinvite. Et les deux pesent pareil — dans un choix qui engage quelqu'un d'autre,
      les deux issues doivent se valoir.
   ⚠️ LES CINQ REGLES `.mu-acte` SONT RETIREES AVEC L'OBJET : une regle dont l'element
      disparait se retire, sinon elle devient un piege pour qui relit. */

/* ── LA LISTE VIDE ────────────────────────────────────────────────────────────────────
   ⚠️ ELLE EST UNE RANGÉE, PAS UN ÉCRAN. `.court` raccourcit la rangée : un raccourci n'a
      pas à peser autant qu'une conversation. Et `.mu-fil` lui-même ne bouge pas, c'est un
      MODIFICATEUR qui porte la différence, ce qui garde la règle commune identique aux
      quatre états. */
/* ⚠️ min-width:0 SUR LA RANGEE ET SUR SES BLOCS. Un enfant de grille vaut min-width:auto
   et refuse de descendre sous son contenu, et la rangee sortait de 4 px, ce qui donnait
   une barre de defilement laterale. Meme famille que le debordement des deux colonnes de
   « Qui joue ? ».
   ⚠️⚠️ [07/08] LES TROIS ARGUMENTS SONT SUPPRIMES (« Discute avec tes amis · Joue chacun
      sur son telephone · Cree des groupes »), et leurs quatre regles avec — la troisieme
      ligne de la grille comprise, qui n'a plus rien a porter.
      ① ILS VENDAIENT UNE FONCTION A QUELQU'UN QUI EST DEJA DANS L'APP. Un argument de
         vente ne se lit qu'une fois, et cet ecran arrive apres l'installation : la
         personne a ouvert l'onglet, elle sait qu'elle veut discuter. C'est la meme raison
         qui a fait tomber le chapo du titre dans la meme vague.
      ② TROIS GLYPHES SARCELLE ALIGNES, C'EST UNE TEXTURE, PAS UNE INFORMATION — la faute
         deja payee sur la page Confidentialite.
      Ce qui reste est la seule chose utile : une rangee qui MENE quelque part. Un ecran
      vide n'a pas a expliquer ce qu'on rate, il a a montrer la porte.
   ⚠️ ET LA RANGEE GARDE SON REMBOURRAGE PROPRE : 9 / 18 / 17. Le 18 lateral est la marge
      de page, comme sur `.mu-fil` ; seule la hauteur raccourcit, parce qu'un raccourci
      n'a pas a peser autant qu'une conversation. */
/* ⚠️ 26 SOUS LA LIGNE D'OUTILS DANS L'ETAT VIDE, ET C'EST UNE DIVERGENCE VOULUE : la page
   ne porte qu'un seul objet de liste, elle peut respirer la ou une liste peuplee serait
   tassee. Elle est listee ici pour que personne ne l'« harmonise » avec les 16 du rythme
   normal. La classe est posee par le rendu, pas deduite d'un compte de rangees : c'est
   l'ETAT qui la commande. */
#s-multi .mu-barre.seule{margin-bottom:var(--e-4)}
#s-multi .mu-fil.court{min-height:70px;padding:var(--e-2) var(--e-3) var(--e-3);min-width:0}
#s-multi .mu-fil.court>*{min-width:0}
/* la pastille de la rangée d'amorce n'est pas une personne : c'est un ACTE. Elle prend donc
   le carré arrondi des fonctions et la teinte du mode, jamais un rond ni une initiale.
   ⚠️ SON CONTOUR EST UN box-shadow INTERIEUR, PAS UNE BORDURE. Une bordure est de la mise
      en page : a 1 px elle rend trois pixels physiques a 3x, et elle mange 2 px de cote
      utile a l'interieur d'une boite de 40. Un box-shadow est de la peinture, il accepte
      le sous-pixel — .34px a .54 rend le meme trait, en plus fin, sans rien deplacer. */
#s-multi .mu-qi{width:40px;height:40px;border-radius:var(--r-2);display:grid;place-items:center;
  background:linear-gradient(150deg,rgba(94,234,212,.15),rgba(20,184,166,.07));
  box-shadow:inset 0 0 0 .34px rgba(94,234,212,.54)}
#s-multi .mu-qi svg{width:20px;height:20px;stroke:#5EEAD4;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

/* ══════════════════════════════════════════════════════════════════════
   VAGUE DU 04/08 · ① LE SOCLE PARTAGE ET ② LA BARRE D'ONGLETS
   Porte depuis design/ecrans/vague-04-08/SOCLE-TRINKE.html, qui fait foi
   (le plan de deploiement resume, le rendu mesure). Structure, valeurs et
   glyphes en sont extraits ; le balisage et les selecteurs sont ceux du
   projet.

   ⚠️ UNE SEULE BARRE DANS TOUT LE PRODUIT, ET C'EST STRUCTUREL. Elle vit
      une fois dans index.html, hors des .screen et apres elles ; show()
      ne fait que designer l'onglet actif. Le dossier demande « un seul
      endroit du code, jamais recopie » et propose de le verifier par
      empreinte md5 : une empreinte constate qu'une copie n'a pas derive,
      l'exemplaire unique fait qu'aucune copie n'existe. Le controle
      BARRE-01 de verif.js refuse le deploiement s'il en trouve deux.

   ⚠️ POSITION ABSOLUE, PAS FIXE — SEULE DIVERGENCE DE CONSTRUCTION. Le
      rendu la pose en `fixed` sur une `.app` de 440 px ; la notre fait
      560 (arbitrage Theo du 30/07, quatre ecrans jamais revus en
      dependent) et un element fixe se cale sur la FENETRE, pas sur la
      colonne : au-dela de 560 px de large, la capsule se serait etiree
      hors de l'app. `absolute` dans `#app` — lui-meme fixe, centre et en
      overflow:hidden — lui rend exactement la largeur de l'app. Sur un
      telephone, les deux constructions rendent au pixel la meme chose.

   ⚠️ AUCUN `transform` SUR SES ANCETRES. Un ancetre transforme casse le
      `backdrop-filter` sur WebKit : c'est l'une des quatre causes deja
      payees sur le menu du « + » (dossier §4.4). D'ou le centrage par
      `#app` et non par un translateX sur la barre. Son animation
      d'entree, elle, porte un transform SUR ELLE-MEME et se termine a
      `none` : c'est ce que fait le rendu, valide sur appareil.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠️ LES 74 px SONT RESERVES PAR L'ECRAN, PAS PAR LA BARRE. Un element
   sorti du flux ne pousse rien : sans cette reserve, la derniere carte de
   chaque ecran passe SOUS la capsule. La valeur vient du dossier §2.5.
   ⚠️ ET LE PLANCHER DE 6 px EXISTE PARCE QUE SAFARI DECLARE 0. Sa propre
      barre occupe deja la zone de l'indicateur d'accueil ; une app
      installee, elle, declare 34 pt. `max()` tient les deux cas avec une
      seule ecriture. [06/08, Theo sur capture Safari : « on a de la marge
      pour descendre la barre »] : plancher abaisse de 12 a 6 px. Seul le
      cas Safari bouge, le `max()` protege l'app installee. */
.screen.avec-barre{
  padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 74px)}

/* ══ LA CAPSULE ══
   ⚠️ ELLE EST CLAIRE, ET C'EST CE QUI LA DISTINGUE DE MATERIAL. Une
      gelule sombre flottant sur du sombre est la barre de Material You ;
      une gelule claire posee sur du contenu est celle d'iOS. La forme est
      la meme, le regime de lumiere ne l'est pas — et c'est lui qu'on lit.
   ⚠️ LE VOILE EST A .74, PAS PLUS. `backdrop-filter` floute ce qui passe
      DERRIERE : un fond a .94 recouvrirait ce flou de 94 % de peinture,
      le calcul aurait lieu et ne se verrait pas. Un verre opaque n'est
      pas du verre, c'est un mur peint en clair.
   [24/09, Romain, essais a 85, 95 puis 100 % vus sur capture] LA CAPSULE PASSE AU CREME
      PLEIN, celui du bouton reglages (#EFE9DF) : elle ne se lit plus comme une vitre mais
      comme le meme objet que le bouton et le liseré de « Qui joue ? ». A 85 % le noir de
      l'accueil passait au travers et la tirait vers le beige gris. Le flou est retire : sous
      un fond plein il se calcule sans se voir. */
.barre{position:absolute;left:24px;right:24px;
  bottom:max(env(safe-area-inset-bottom,0px), 18px);z-index:20;
  display:none;align-items:center;padding:var(--e-2);
  border-radius:999px;
  background:#EFE9DF;
  box-shadow:var(--o-3),
             inset 0 1px 0 rgba(255,255,255,.9)}
.barre.on{display:flex}

/* ⚠️ LA PASTILLE ACTIVE EST UN OVALE, PAS UN ROND. Un rond dirait « ce
   bouton-ci » ; un ovale qui remplit sa colonne dit « cette COLONNE-ci ».
   C'est un onglet qu'on designe, pas un objet. */
.ong{flex:1 1 0;min-width:0;height:42px;border-radius:999px;
  position:relative;
  display:grid;place-items:center;cursor:pointer;border:0;
  background:none;color:#332C40;
  transition:color .2s var(--ease),background .2s var(--ease),
             transform .14s var(--ease)}
/* ⚠️ CIBLE ETENDUE, ET C'EST UN AJOUT AU RENDU. La capsule fait 54 px de
   haut, ses onglets 42 : sous le plancher de 44 du contrat. Les colonnes
   se touchent deja bord a bord, l'extension ne peut donc empieter que sur
   le rembourrage de la capsule — 46 px touches pour 42 vus. */
.ong::after{content:"";position:absolute;left:0;right:0;top:-2px;bottom:-2px}
/* ⚠️ LE TRAIT EST A 1,75, PAS A 2. Le plan de deploiement annonce 2 et
   2,15 ; le rendu, qui fait foi, est descendu a 1,75 et 1,85 apres mesure
   sur la reference (l'epaisseur y vaut 2,8 % de la largeur du dessin, la
   notre en valait 11). Ecart signale au design. */
.ong svg{width:27px;height:27px;fill:none;stroke:currentColor;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ DISCUSSIONS EST PLUS GRAND DE 15 %, ET SON TRAIT SUIT. A trait
   constant, un glyphe plus grand se lit comme un glyphe PLUS LEGER :
   c'est le retablissement de poids qui le rend visible, pas ses quatre
   pixels de large. */
.ong.majeur svg{width:31px;height:31px;stroke-width:1.85}
.ong .p{transition:fill-opacity .2s var(--ease)}
/* ⚠️ L'ETAT ACTIF NE PORTE AUCUNE COULEUR, ET C'EST MESURE. L'inactif
   rend 12,71:1 sur la capsule, un violet moyen n'en rendrait que 5,43 :
   colorer l'actif le rendrait MOINS contraste que ses voisins, et la
   selection se dirait par un affaiblissement. Elle se dit par la bulle et
   par le remplissage du glyphe, les deux a encre constante. */
.ong.actif{background:rgba(110,90,60,.13)}   /* [24/09] un creme plus fonce : le gris violace se perdait sur le creme */
.ong.actif svg .p{fill:currentColor;fill-opacity:.14}
.ong:active{transform:scale(.92)}
/* ⚠️ L'ONGLET PROFIL EST UN ETAT, PAS UNE ICONE. Connecte, il porte
   l'avatar violet et son anneau — le seul des cinq qui dise un ETAT en
   plus d'une destination. Sans compte, il redevient une silhouette, comme
   les quatre autres.
   ⚠️ `.ong-av` ET NON `.av` : `.av` existe deja dans ce fichier (la liste
      des avantages du compte, ligne ~1722) et lui aurait impose
      `flex-direction:column` et `margin-top:16px`. Quatre collisions de
      nom en une seule session le 03/08 : prefixer, toujours. */
.ong-av{width:28px;height:28px;border-radius:50%;
  display:grid;place-items:center;font-size:var(--t-2);font-weight:800;
  color:#170B20;letter-spacing:0;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  box-shadow:0 0 0 1.5px rgba(250,249,252,.95), 0 0 0 3px #8B5CF6;
  transition:transform .2s var(--ease)}
.ong.compte.actif{background:none}
.ong.compte.actif .ong-av{transform:scale(1.07)}
/* la pastille des demandes en attente suit l'onglet Profil : c'est la que
   la reponse se donne. Meme encre que le compte, pose sur la capsule
   claire, donc cercle plein et non creux. */
/* ⚠️ 18 px DE HAUT POUR 12 px DE TEXTE, ET C'EST LE PLANCHER QUI COMMANDE.
   Dessinee a 16 px avec un chiffre a 11, elle aurait ete sous le plancher
   UI-04 ; c'est la pastille qui grandit, jamais le texte qui descend — le
   dossier prend exactement la meme decision sur les pastilles de rang du
   podium (15 → 18). */
.ong-dot{position:absolute;top:0;right:4px;min-width:18px;height:18px;
  padding:0 var(--e-1);border-radius:999px;background:#F0475F;color:var(--c-texte);
  font-size:var(--t-micro);font-weight:800;line-height:18px;text-align:center;
  box-shadow:0 0 0 2px rgba(250,249,252,.92)}
.ong-dot:empty{display:none}

/* ⚠️ LE MOUVEMENT SE COUPE, PAS L'AFFICHAGE. L'etat de repos de la barre
   est VISIBLE : si l'animation d'entree ne se joue pas, la barre reste la.
   Un bloc qui disparait en silence est le pire echec possible. */
/* ⚠️⚠️ `backwards`, JAMAIS `both`, ET C'EST CE QUI AURAIT TUE L'ANIMATION DE LA BARRE.
   Une animation en `both` GARDE A VIE l'etat de sa derniere image ; `uiMonte` finit sur
   `transform:none`, et UNE VALEUR D'ANIMATION L'EMPORTE SUR TOUTE DECLARATION NORMALE,
   quelle que soit sa specificite. `.barre.reduite{transform:scale(.84)}` aurait donc ete
   calculee, appliquee, puis ecrasee a chaque image par un `transform:none` vieux de quatre
   dixiemes de seconde — et rien dans l'inspecteur ne l'aurait montre comme un conflit : la
   regle n'est pas barree, elle est DOMINEE.
   `backwards` fait ce qu'on attendait de `both` : il tient l'etat de depart pendant le
   delai, ce qui evite le clignotement, et il REND la propriete des la derniere image. */
.barre.on{animation:uiMonte var(--m-long) var(--m-sortie) backwards;
  animation-delay:120ms}

@media (prefers-reduced-motion:reduce){
  .barre.on{animation:none;opacity:1;transform:none}
}

/* ⚠️ LE FIL DE DISCUSSION N'A PAS D'ONGLETS. Sa barre de saisie occupe deja
   le bas de l'ecran : deux barres l'une sur l'autre est un defaut, pas un
   choix, et le clavier les empilerait a trois. majBarre() retire la barre
   des que .au-fil est pose, et l'ecran reprend son rembourrage normal. */
#s-multi.au-fil.avec-barre{padding-bottom:calc(var(--e-4) + env(safe-area-inset-bottom,0px))}

/* l'onglet Profil montre l'avatar OU la silhouette, jamais les deux */
.ong.compte .ong-av{display:none}
.ong.compte.connecte .ong-av{display:grid}
.ong.compte.connecte #ong-ico{display:none}

/* ══════════════════════════════════════════════════════════════════════
   VAGUE DU 04/08 · ④ L'ECRAN AMIS
   Porte depuis design/ecrans/vague-04-08/amis.html, qui fait foi.

   ⚠️ IL NE CREE RIEN. La liste d'amis, la recherche par pseudo, les
      demandes recues et envoyees, le retrait et le profil d'un ami
      existaient deja — dans Mon compte, et branches sur les memes routes
      serveur (GET /api/friends, friends/search, friends/demande,
      friends/repondre, friends/retirer). Cet ecran leur donne une porte,
      un dessin, et la vitrine des connectes recemment.

   ⚠️ TOUT EST PREFIXE `am-`. `.seg` existe deja (le selecteur de critere
      du classement de Mon compte), `.av` aussi (la liste des avantages du
      compte), `.pt` aussi (les pastilles d'etat du salon). Quatre
      collisions de nom en une seule session le 03/08 : prefixer, toujours.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠️⚠️ [06/08, lot PORTAGE-AMIS §1.1] LE TITRE PASSE EN BARRE DE NAVIGATION, ET C'EST UN
   RENVERSEMENT DE REGLE, PAS UN REGLAGE. Le socle posait deux familles : ecran de REGLAGES
   = titre 18/600 centre, on y entre par un chevron ; ecran d'APP = grand titre a gauche, on
   y entre par la barre d'onglets — « la porte decide de la famille », regle trouvee apres
   trois versions ratees de cet ecran-ci. Le Classement est passe centre le 05/08, et la
   consequence etait notee comme NON RESOLUE : deux onglets voisins, deux grammaires.
   ELLE EST RESOLUE ICI, ET DANS L'AUTRE SENS : les ecrans d'onglet portent desormais une
   BARRE DE NAVIGATION, pas un grand titre. Amis suit le Classement, au pixel.
   ⚠️ « AMIS », PLUS « MES AMIS ». Le segment s'appelle maintenant « Mes amis » : les deux
      se lisaient a trente pixels d'ecart. LE TITRE PORTE LE NOM DE L'ONGLET, LE SEGMENT
      PORTE LA POPULATION — exactement comme au Classement (« Classement » / « Entre amis ·
      Communaute »).
   ⚠️ 32 SOUS LA BARRE : il n'y a ici ni filet ni verre pour marquer sa fin. Quand aucun
      signe ne separe, c'est l'espace qui fait tout le travail. Le socle n'a que quatre
      valeurs — 8, 16, 24, 32.
   ⚠️ 21 px = 1.3125rem, ECRIT EN REM et non en px : c'est le reglage Grand texte qui doit
      l'emporter (UI-06 refuse toute taille de police en px dans cette feuille). */
#s-amis{padding-top:calc(var(--e-2) + env(safe-area-inset-top,0px))}
#s-amis .am-titre{position:relative;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  min-height:44px;margin:2px 0 var(--e-5)}
#s-amis .am-titre h1{flex:0 0 auto;max-width:100%;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;
  line-height:1.2;color:var(--c-texte)}
#s-amis .am-corps{flex:1 1 auto;min-height:0}

/* ══ [07/08, PORTAGE-AMIS §2] LES DEUX POPULATIONS PASSENT DANS LE TITRE ══
   Le selecteur en gelule « Mes amis / Demandes » est SUPPRIME ; le titre porte les deux
   mots, exactement comme « Classement / Statistiques ».

   ⚠️⚠️ CE QU'ON GAGNE : UNE LIGNE ET UN OBJET. L'ecran portait un titre qui disait
      « Amis » et, quarante pixels plus bas, une gelule qui disait « Mes amis ». DEUX FOIS
      LE MEME MOT DANS LE MEME ECRAN, C'EST UN MOT QUI N'APPREND RIEN LA SECONDE FOIS. Le
      titre etait devenu « Amis » pour eviter la collision (regle posee ici le 06/08) : le
      probleme n'etait pas le mot, c'etait D'AVOIR DEUX OBJETS POUR UNE SEULE INFORMATION.
      Un selecteur qui ne contient que deux entrees n'a pas besoin d'etre un selecteur.
   ⚠️ LES CHEVRONS DIFFERENT PAR LA DIRECTION, PAS PAR LA PRESENCE : la vue courante pointe
      vers le bas (la liste juste dessous), l'autre vers la droite (l'ailleurs ou elle
      mene). Ils s'echangent a la bascule EN MEME TEMPS que l'encre : le signe suit la
      fonction, jamais le mot. Un signe de direction doit designer quelque chose de reel.
   ⚠️ `font:inherit` : les deux vues heritent du 21/600 du h1. DEUX OBJETS QUI DOIVENT
      AVOIR LE MEME CORPS NE LE DECLARENT PAS DEUX FOIS, sinon l'un des deux derivera.
   ⚠️ ALIGNEMENT PAR LA LIGNE DE BASE : ce sont des signes poses dans du texte, pas des
      objets poses a cote.
   ⚠️ CIBLES : 25,2 + 2 x 9,4 = 44, et 8 de chaque cote a l'horizontale — seize pixels pris
      sur les vingt-deux de l'ecart, donc LES DEUX ZONES NE SE TOUCHENT PAS.
   ⚠️⚠️ L'ENCRE DE LA VUE AU REPOS EST ECRITE EN CLAIR, ET C'EST UNE DIVERGENCE OBLIGEE :
      le rendu appelle un jeton nomme « muted », qui N'EXISTE PAS dans ce socle — il
      declare `--mut` (#8b8b99). Une variable absente rend la declaration INVALIDE EN
      SILENCE et la couleur retombe sur l'heritage, ici le blanc du h1 : les deux vues
      auraient eu la meme encre et le choix aurait disparu. On pose donc la valeur du
      rendu, #A8A0BA, mesuree a 7,8:1 sur le fond de page. Meme raison pour `:active`, ou
      le rendu appelle un jeton « text » : ce socle-ci le nomme `--ink`.
   ⚠️ ET LE CONTROLE ENTETE-03a INTERDIT CE JETON DANS LA FEUILLE — commentaire compris.
      C'est pour ca qu'il n'est pas ecrit ici sous sa forme d'appel : UN CONTROLE NEGATIF
      NE DOIT PAS ATTRAPER SON PROPRE COMMENTAIRE, et un commentaire ne doit pas non plus
      aller au-devant de lui. Quatrieme fois que ce piege se referme en une journee. */
#s-amis .am-vues{display:flex;align-items:baseline;gap:var(--e-4)}
#s-amis .am-vue{position:relative;display:flex;align-items:baseline;gap:var(--e-2);
  border:0;padding:0;background:none;cursor:pointer;
  font:inherit;letter-spacing:inherit;color:var(--c-texte-3);
  transition:color .16s var(--ease)}
#s-amis .am-vue::after{content:'';position:absolute;inset:-9.4px -8px}
#s-amis .am-vue:active{color:var(--ink)}
#s-amis .am-vue.actif{color:var(--c-texte)}
#s-amis .am-vue svg{flex:0 0 auto;width:10px;height:10px;fill:none;stroke:currentColor;
  stroke-width:2.3;stroke-linecap:round;stroke-linejoin:round}

/* ══ [07/08, §0.1] L'ANIMATION D'ENTREE DE L'ECRAN — ELLE N'EXISTAIT PAS ══
   Le markup posait `class="h-in"` et des `--d` echelonnes depuis le 04/08 ; or `.h-in`
   n'est declaree QUE sous `#s-home`. Les blocs d'Amis portaient donc une classe morte et
   un retard sans animation a retarder : RIEN NE MONTAIT, et rien ne le disait — une regle
   absente ne laisse aucune trace, elle ne barre rien dans l'inspecteur. Meme constat sur
   `#s-classement .cm-*`, hors perimetre de ce lot, signale.
   ⚠️ `backwards`, JAMAIS `both`. Avec `both`, une animation garde a vie l'etat de sa
      derniere image, ET UNE VALEUR D'ANIMATION L'EMPORTE SUR TOUTE DECLARATION NORMALE,
      quelle que soit sa specificite. (`#s-home .h-in` est en `both` : signale, pas touche.)
   ⚠️ ET AUCUNE INFORMATION NE REPOSE SUR LE MOUVEMENT : sous `prefers-reduced-motion`,
      les blocs sont deja a leur place a la premiere image. */
:is(#s-amis,#s-multi) .am-in{animation:uiMonte var(--m-long) var(--m-sortie) backwards;animation-delay:var(--d,0ms)}

@media (prefers-reduced-motion:reduce){
  :is(#s-amis,#s-multi) .am-in{animation:none}
}

/* ══ [07/08, §0.3] L'INTITULE DE GROUPE ══
   ⚠️ UNE RANGEE QUI EST UNE PERSONNE SE DESSINE EN CARTE SEPAREE ; une rangee qui est une
      POSITION se dessine dans un groupe a filets, parce que les rangs se comparent. Les
      groupes d'Amis gardent donc leurs cartes separees, et c'est l'intitule qui les nomme.
   ⚠️ 12 px ECRIT EN REM (var(--t-micro)) : UI-06 refuse toute taille de police en px dans
      cette feuille, c'est le reglage Grand texte qui doit l'emporter. */
#s-amis .am-lab{flex:0 0 auto;display:flex;align-items:center;gap:var(--e-2);
  font-size:var(--t-micro);font-weight:700;letter-spacing:.10em;
  text-transform:uppercase;color:var(--c-texte-3);margin:0 0 var(--e-3);padding-left:var(--e-1)}
#s-amis .am-lab+.am-groupe{margin-bottom:var(--e-5)}
#s-amis .am-groupe+.am-lab{margin-top:0}

/* ══ [07/08, rendu du soir] LES DEUX INTITULES DE DEMANDES PORTENT LEUR SIGNE ══
   ⚠️ 14 POUR UN TEXTE DE 12 : le glyphe depasse la capitale de deux pixels. UN SIGNE POSE
      A COTE D'UN MOT SE CALE SUR SA HAUTEUR D'OEIL, PAS SUR SON CORPS — a 12, il
      paraitrait plus petit que le texte. La cote reste en px : ce n'est pas une taille de
      police, elle ne doit pas suivre le reglage Grand texte au risque de deborder la
      ligne. Ecart de 8, la premiere valeur du socle.
   ⚠️ TRAIT 1,75 ET BOUTS ARRONDIS : la famille de la barre du bas, sans retouche.
   ⚠️⚠️ CHAQUE INTITULE PREND LA COULEUR DE L'OBJET ACTIF DE SA SECTION, ET C'EST CE QUI
      EMPECHE CES DEUX TEINTES D'ETRE DECORATIVES.
        Reçues   → #6C96FA, le bleu du bouton « Accepter » juste dessous. LE BLEU AGIT SUR
                   UNE PERSONNE : dans cette section, c'est a toi de repondre.
        Envoyées → #A788FF, le violet de la tuile « Ajouter un ami » qui ouvre l'ecran. LE
                   VIOLET OUVRE UN LIEU : ici tu n'agis pas, tu attends.
      LA COULEUR DE L'INTITULE DIT QUI DOIT AGIR. Aucune des deux n'est neuve : ce sont les
      teintes deja posees dans ces memes sections. UNE COULEUR NOUVELLE N'APPREND RIEN ;
      UNE COULEUR DEJA PRESENTE DANS LA SECTION APPREND CE QUE LA SECTION CONTIENT.
   ⚠️ SEUL LE GLYPHE PREND LA TEINTE, PAS LE MOT : un intitule de section colore
      deviendrait un titre. D'ou l'abandon de `currentColor` sur ces deux-la.
   ⚠️ CONTRASTES SUR LE FOND DE PAGE : bleu 6,86:1, violet 7,08:1 — bien au-dela du seuil
      de 3:1 d'un trace. L'intitule « Résultats » de l'ecran d'ajout, lui, n'a pas de
      glyphe : la regle du dessous ne s'applique qu'a ce qui en porte un. */
#s-amis .am-lab svg{width:14px;height:14px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
#s-amis .am-lab.recu svg{stroke:#6C96FA}
#s-amis .am-lab.envoi svg{stroke:#A788FF}

/* ══ LA VITRINE DES CONNECTES RECEMMENT ══
   Elle est la seule surface en relief de l'ecran : le RELIEF APPARTIENT A
   LA VITRINE, la liste en dessous reste plate. Une liste ne met pas en
   volume ce qu'elle enumere — c'est ce qui la rend calme, et ce qui laisse
   la vitrine seule a briller. */
/* ⚠️ [07/08, §1.2 reecrit] 32 SOUS L'APERCU. Le selecteur en gelule a disparu (§2) : le
   rythme de l'ecran est desormais 32 sous la barre de navigation, 32 sous le bloc vitrine,
   16 sous la ligne d'outils. DEUX ECRANS DE LA MEME FAMILLE NE SE RESSEMBLENT PAS PAR
   LEURS OBJETS, ILS SE RESSEMBLENT PAR LEURS INTERVALLES.
   ⚠️ [06/08, §4.1] LE FILET PASSE AU PIXEL PHYSIQUE. Il valait `1px` a .13, soit TROIS
      pixels physiques a 3x : un trait epais la ou on voulait un cheveu. Un trait trois fois
      plus fin rend trois fois moins d'encre, donc l'opacite triple (.13 -> .38), sinon la
      carte perd son bord au lieu de l'affiner. `.34px` n'est legitime QUE dans un
      box-shadow : c'est de la peinture, elle accepte le sous-pixel.
   ⚠️⚠️ [07/08, §3.2] LA CARTE NE DEBORDE PLUS LA MARGE DE PAGE, ET C'EST MESURE. Elle
      portait `margin:0 -11px` : releve au CSSOM a 402 px de large, elle occupait 388 quand
      toutes les cartes de l'ecran occupent 366 — onze pixels dehors de chaque cote. Le
      meme bloc rendait 379 sur Amis et 365 sur Discussions.
      UN OBJET QUI DEBORDE LA MARGE DE PAGE DEMANDE UNE RAISON ; s'il n'y en a qu'une
      esthetique, LA MARGE GAGNE. Et une cote qui se DEDUIT de la page se reproduit toute
      seule, quand une cote qui la deborde se RECOPIE — et une recopie finit par diverger.
      C'est aussi le piege paye ailleurs aujourd'hui : mesurer le CONTENANT ne dit rien du
      CONTENU. La largeur d'ecran etait juste des le depart ; c'est la carte, un cran plus
      bas, qui etait fausse de 22 px. */
:is(#s-amis,#s-multi) .am-apercu{flex:0 0 auto;margin:0 0 var(--e-5);padding:var(--e-3) 0 var(--e-1);overflow:hidden;
  border-radius:var(--r-4);
  background:linear-gradient(180deg,rgba(124,110,220,.13) 0%,
                                    rgba(124,110,220,.05) 100%);
  -webkit-backdrop-filter:blur(22px) saturate(1.5);
  backdrop-filter:blur(22px) saturate(1.5);
  box-shadow:0 20px 40px -18px rgba(0,0,0,.8),
             0 6px 14px -8px rgba(0,0,0,.5),
             inset 0 1px 0 rgba(255,255,255,.10),
             inset 0 0 0 .34px rgba(167,139,250,.38),
             inset 0 -26px 34px -26px rgba(139,92,246,.07)}
:is(#s-amis,#s-multi) .am-apercu-tete{display:flex;align-items:center;gap:var(--e-2);padding:0 var(--e-3) var(--e-3);
  font-size:var(--t-micro);font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--c-texte)}
:is(#s-amis,#s-multi) .am-apercu-tete svg{width:15px;height:15px;flex:0 0 auto;fill:none;
  stroke:#A78BFA;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
/* ══ [06/08, §3] L'APERCU DEVIENT UNE BOBINE ══════════════════════════
   Elle porte TOUS les amis, tries par derniere connexion decroissante, et
   elle tourne sans fin : cinq exemplaires poses cote a cote, recousus a
   l'arret. La piste est le conteneur qui defile, le ruban est la bande.

   ⚠️ `scroll-snap-type:x mandatory` RESTE, `scroll-snap-stop` PART (il
      etait pose ici le 04/08, raison reecrite le 06/08). Le crantage seul
      fait la sensation Apple : une lancee decelere avec la physique du
      systeme PUIS se pose sur une tete. Avec `stop:always`, un geste ample
      ne franchissait qu'UN cran : ce n'est plus un carrousel, c'est une
      pagination — et sur une bobine sans fin, c'est intenable.
   ⚠️ `overscroll-behavior-x:contain` EMPECHE iOS DE PRENDRE LE GESTE POUR
      UN RETOUR ARRIERE — sinon un balayage vers la droite quitte l'ecran.
   ⚠️ ET LE REMBOURRAGE DE CENTRAGE A DISPARU AVEC LE TRAIT LUMINEUX : la
      piste ne centre plus une tete, elle en montre cinq. Le rembourrage
      est un 18 fixe, pose sur le RUBAN, pour tomber sur le texte de
      l'intitule. Rien a mesurer, donc rien qui puisse tomber a cote. */
:is(#s-amis,#s-multi) .am-piste{overflow-x:auto;overflow-y:hidden;
  overscroll-behavior-x:contain;touch-action:pan-x;
  -webkit-overflow-scrolling:touch;
  scroll-snap-type:x mandatory;scrollbar-width:none}
:is(#s-amis,#s-multi) .am-piste::-webkit-scrollbar{display:none}
:is(#s-amis,#s-multi) .am-ruban{display:flex;align-items:flex-start;gap:var(--e-3);padding:2px var(--e-3) var(--e-4)}
:is(#s-amis,#s-multi) .am-rec{flex:0 0 auto;width:56px;display:flex;flex-direction:column;
  align-items:center;justify-content:flex-start;gap:var(--e-2);
  border:0;background:none;cursor:pointer;color:var(--ink);
  scroll-snap-align:start;
  transition:transform .16s var(--ease)}
:is(#s-amis,#s-multi) .am-rec:active{transform:scale(.92)}
/* ⚠️⚠️ LE SEPARATEUR NE PEUT PAS ETRE UNE LARGEUR DE 0,34, ET C'EST LE PIEGE
   DE TOUT CE LOT. Une largeur est une propriete de MISE EN PAGE : elle est
   arrondie a l'entier AVANT peinture, donc 0,34 tombe a ZERO et le trait
   disparait — sans erreur, sans regle barree, sans rien a voir dans
   l'inspecteur. Le pixel physique ne s'obtient que par de la PEINTURE :
   une boite d'UN pixel plein, ecrasee par `transform:scaleX(.34)`.
   ⚠️ ET LES MARGES NEGATIVES DE 6,5 NE SONT PAS UN REGLAGE OPTIQUE : sans
      elles, le trait s'intercale comme une tete de plus et ajoute DEUX
      ecarts de 14 la ou on n'en veut qu'un. Elles rendent a l'ecart sa
      valeur, donc au calcul de position sa justesse.
   ⚠️ IL TOMBE APRES LA CINQUIEME TETE, PAS APRES LES CONNECTES : il ne
      separe pas deux categories, il marque LA FIN DE CE QUI TIENT DANS LA
      LARGEUR AU REPOS. C'est un repere de position, et c'est aussi la
      COUTURE : sur une bobine sans fin, il est le seul point qui dise ou
      la serie recommence. Sans lui, une bobine triee serait indiscernable
      d'une bobine melangee. */
:is(#s-amis,#s-multi) .am-sep{flex:0 0 auto;width:1px;height:50px;margin:0 -6.5px;
  transform:scaleX(.34);background:rgba(255,255,255,.16)}
:is(#s-amis,#s-multi) .am-rec .am-heure{max-width:100%;font-size:var(--t-micro);font-weight:500;color:var(--c-texte-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ⚠️ LE RELIEF EST FAIT DE TROIS COUCHES, AUCUNE DECORATIVE : un reflet
   radial en haut a gauche — la lumiere vient d'en haut dans toute l'app —,
   une ombre interne en bas (la face qui echappe a cette lumiere), et la
   lueur de la teinte. Chaque teinte declare la sienne, ce qui permet
   d'ecrire le relief UNE fois au lieu de huit. */
:is(#s-amis,#s-multi) .am-rec .am-av{width:50px;height:50px;font-size:var(--t-3);
  background-image:radial-gradient(circle at 30% 22%,
      rgba(255,255,255,.32) 0%,
      rgba(255,255,255,.13) 32%,
      rgba(255,255,255,.035) 64%,
      rgba(255,255,255,0) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28),
             inset 0 -9px 16px -9px rgba(0,0,0,.42),
             0 4px 9px -5px rgba(0,0,0,.7),
             0 8px 18px -6px rgba(var(--lueur),.70),
             0 0 22px -8px rgba(var(--lueur),.40)}
/* ⚠️ [06/08, §3.6] LE TRAIT LUMINEUX ET SES QUATRE REGLES D'ETAT SONT SUPPRIMES,
   PAS DESACTIVES. Il marquait la tete au centre — sa SEULE fonction — et le centre
   n'a plus aucun sens depuis que cinq tetes sont montrees ensemble. UN REPERE QUI NE
   REPERE PLUS RIEN EST PIRE QU'UNE ABSENCE DE REPERE : IL DESIGNE AU HASARD. Partent
   avec lui : `.am-neon`, `.am-neon-zone`, `.am-rec.focus .am-av`, `.am-rec.focus
   .am-heure`, la classe `focus` du markup et les lignes de script qui lisaient la
   position. Le dessin du trait (20 x 3, trois lueurs dont une qui remonte dans la
   carte) reste au dossier de design si on revient un jour au carrousel un-a-un. */

/* ══ [07/08, §2] LE SELECTEUR EN GELULE EST SUPPRIME, PAS DESACTIVE ══
   Partent avec lui : `.am-segments`, `.am-segments::-webkit-scrollbar`, `.am-seg`,
   `.am-seg svg`, `.am-seg svg .p`, `.am-seg.actif`, `.am-seg.actif svg .p` et
   `.am-seg-n`. Les deux populations vivent maintenant dans le TITRE (voir `.am-vues`
   plus haut) : garder la gelule aurait fait dire deux fois « Mes amis » sur le meme
   ecran. UNE REGLE CSS DONT L'ELEMENT DISPARAIT SE RETIRE — laissee en place, elle finit
   par etre corrigee a la place de celle qui sert.
   ⚠️⚠️ CE QUI DISPARAIT AVEC LUI, ET QUI N'EST PAS UN DETAIL : `.am-seg-n`, LA PASTILLE
      QUI COMPTAIT LES DEMANDES EN ATTENTE. Elle etait un ajout au rendu, pose ici le
      06/08. Le dossier du 07/08 le dit en toutes lettres (§8.3, question ouverte 6) :
      « rien n'annonce qu'il y en a. IL N'EXISTE AUCUN BADGE DANS LE SOCLE — a dessiner si
      la fonction arrive. » L'information n'est pourtant PAS perdue : la barre d'onglets
      porte deja son propre compteur (`#ong-dot`, alimente par majPastille), qui est le
      seul endroit ou elle serve a quelque chose quand on n'est pas sur cet ecran. Signale
      a Theo comme un retrait, pas comme un oubli.
   ⚠️ ET LE `filter` DU MENU DU « + » A ETE RELU AVEC CE RETRAIT (§5) : il nommait
      `.am-segments`. UN SELECTEUR QUI NOMME DES BLOCS DOIT ETRE RELU CHAQUE FOIS QU'UN
      BLOC DISPARAIT, sinon il floute un fantome et oublie un vivant. */

/* ══ RECHERCHE ET BOUTON « + » ══
   ⚠️⚠️ [06/08, §5.3] LE `position:relative` N'EST PAS DECORATIF : c'est LUI le bloc de
      reference du menu du « + ». LE MENU EST FRERE DU BOUTON, JAMAIS DEDANS — un
      bouton ne peut pas contenir un bouton, l'analyseur HTML ferme le premier des
      qu'il en rencontre un second, et le menu se retrouve sans ancre. Le fichier
      reste pourtant parfaitement valide : accolades equilibrees, balises equilibrees,
      zero classe orpheline. UNE ROUTINE QUI COMPTE DES PAIRES NE VOIT PAS UNE
      IMBRICATION INTERDITE (controle AMIS-11 pose pour ca).
   ⚠️ ET IL EST POSE DANS LES DEUX ETATS, menu ouvert comme ferme : le bloc doit etre
      identique, sinon l'ouverture deplace la ligne d'un pixel.
   ⚠️ 16 SOUS LA LIGNE D'OUTILS (§1.2), la valeur du Classement sous ses reglages. */
#s-amis .am-outils{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:0 0 auto;margin:0 0 var(--e-3)}
:is(#s-amis,#s-multi) .am-rech{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:1 1 auto;min-width:0;min-height:35px;padding:0 var(--e-3);
  border-radius:999px;border:0;
  background:rgba(168,178,225,.055);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);
  backdrop-filter:blur(16px) saturate(1.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035)}
/* cible etendue : 35 px vus, 45 touches */
:is(#s-amis,#s-multi) .am-rech::after{content:'';position:absolute;left:0;right:0;top:-5px;bottom:-5px;
  pointer-events:none}
:is(#s-amis,#s-multi) .am-rech svg{width:15px;height:15px;flex:0 0 auto;fill:none;stroke:#9990AE;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ 16 px ET NON 14, ET C'EST UNE DIVERGENCE DEJA PAYEE. Sous 16 px dans
   un champ de saisie, iOS ZOOME la page a la mise au point et ne la
   redescend jamais tout a fait. Meme correction que sur la barre de saisie
   du fil, le 03/08. Le rendu ecrit 14. */
/* ⚠️⚠️ [07/08] `padding:0` N'EST PAS COSMETIQUE, IL REND SA COTE A LA LIGNE D'OUTILS. La
   feuille declare `input[type=search]{padding:14px}` pour toute l'app ; ce champ-ci le
   ramenait a `8px 0`, ce qui ajoutait 16 px au-dessus des 24 de la ligne de texte : la
   capsule mesurait 40 au CSSOM alors que sa regle demande 35, et le « + » de 33 pose a
   cote se retrouvait 7 px plus bas au lieu des 2 documentes (un plein de meme hauteur
   qu'un creux parait toujours plus grand : deux pixels rendus au creux egalisent le poids
   vu — sept les desequilibrent dans l'autre sens). MESURER LE CONTENANT NE DIT RIEN DU
   CONTENU : la regle etait juste, c'est l'enfant qui la debordait. A zero, le `min-height`
   de 35 reprend la main et la cible reste a 45 par le `::after`. */
:is(#s-amis,#s-multi) .am-rech input{flex:1 1 auto;min-width:0;font:inherit;font-size:1rem;
  color:var(--ink);background:none;border:0;outline:none;padding:0}
:is(#s-amis,#s-multi) .am-rech input::placeholder{color:var(--c-texte-3)}
/* ⚠️ LE BOUTON EST BLEU 225°, PAS VIOLET NI SARCELLE. Le socle reserve le
   violet au compte connecte ; le sarcelle est a 29° du vert de presence, et
   il y a cinq points verts a quarante pixels de la. CE BOUTON AJOUTE UNE
   PERSONNE, ET LES GENS SONT BLEUS.
   ⚠️ ET SON ENCRE EST SOMBRE, C'EST MESURE : sur le plateau #4875E0 le
      blanc rend 4,29 et l'encre 4,20, egalite ; mais le degrade monte a
      #658CEA vers le coin, ou le blanc tombe a 3,23 quand l'encre grimpe a
      5,57. Un glyphe doit tenir sur TOUT le degrade, pas sur sa moyenne. */
#s-amis .am-ajout{position:relative;flex:0 0 auto;width:33px;height:33px;
  border-radius:var(--r-1);border:0;cursor:pointer;
  background:linear-gradient(140deg,rgba(108,150,250,.93) 0%,
    rgba(76,125,240,.93) 58%, rgba(46,92,200,.93) 100%);
  -webkit-backdrop-filter:blur(16px) saturate(1.2);
  backdrop-filter:blur(16px) saturate(1.2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16);
  color:#071630;
  display:grid;place-items:center;transition:transform .16s var(--ease)}
#s-amis .am-ajout::after{content:'';position:absolute;inset:-6px}
#s-amis .am-ajout:active{transform:scale(.92)}
#s-amis .am-ajout svg{width:15px;height:15px;stroke:#071630;fill:none;stroke-width:2.05;
  stroke-linecap:round;stroke-linejoin:round}

/* ══ LES RANGEES ══
   Une rangee qui est une PERSONNE se dessine en carte separee ; une rangee
   qui est une POSITION se dessine dans un groupe a filets. Ici ce sont des
   personnes : cartes, avec de l'air entre elles.
   ⚠️ ET LEUR SURFACE EST PRESQUE AUSSI SOMBRE QUE LA PAGE. C'est UN LISERE
      D'UN PIXEL qui les dessine, pas leur remplissage : un objet qui se
      distingue par sa CLARTE est un bloc de contenu, un objet qui se
      distingue par son ARETE est un composant. */
#s-amis .am-groupe{display:flex;flex-direction:column;gap:var(--e-3)}
#s-amis .am-ami{display:flex;align-items:center;gap:var(--e-3);width:100%;
  min-height:76px;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);border-radius:var(--r-3);
  text-align:left;cursor:pointer;border:0;font:inherit;color:var(--ink);
  background:rgba(150,140,210,.022);
  -webkit-backdrop-filter:blur(18px) saturate(1.2);
  backdrop-filter:blur(18px) saturate(1.2);
  /* ⚠️ [06/08, §4.1] FILET AU PIXEL PHYSIQUE : `1px` a .065 valait TROIS pixels a 3x.
     Un trait trois fois plus fin rend trois fois moins d'encre, donc l'opacite triple
     (.065 -> .19), sinon la carte perd son bord au lieu de l'affiner. */
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.19),
             0 8px 20px -14px rgba(0,0,0,.7);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-amis .am-ami:active{transform:scale(.985);background:rgba(150,140,210,.07)}
/* ⚠️ LA PASTILLE DE LA LISTE EST PLATE. Ni reflet, ni ombre interne, ni
   lisere : le Multijoueur, valide et en production, ne donne rien de tout
   cela a ses pastilles de rangee. Le relief appartient a la vitrine. */
#s-amis .am-ami .am-av{width:46px;height:46px;font-size:var(--t-3)}
/* ⚠️ [11/08] LE PSEUDO EST SEUL DANS SA CASE, DONC IL SE CENTRE. Il etait la premiere
   ligne d'une pile de deux ; la seconde partie, il se serait cale en haut et la rangee
   aurait paru bancale. `align-items:center` sur la rangee ne suffit pas : c'est ce bloc-ci
   qui doit cesser de se comporter comme une colonne. */
#s-amis .am-txt{flex:1 1 auto;min-width:0;display:flex;align-items:center;min-height:46px}
#s-amis .am-ami b{display:block;font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ══⚠️⚠️ [07/08, §4] LE BOUTON DE CONVERSATION DEVIENT UNE GELULE 54 x 36 ══
   Il etait un carre de 38 a rayon 13, pose dans le coin d'une carte de rayon 20 : IL SE
   LISAIT COMME UN SECOND COIN DE LA CARTE. 54 x 36, soit un rapport de 1,5 — celui des
   pastilles d'onglet de la barre du bas. UNE FORME SE COPIE PAR SA PROPORTION, PAS PAR SA
   TAILLE. Et le rayon ferme a 999 : LE CARRE ARRONDI APPARTIENT AUX CONTENANTS, LA GELULE
   AUX COMMANDES (la barre du bas, ses onglets, les filtres, le bouton Valider).
   ⚠️ LA RANGEE PORTE DEUX DESTINATIONS : toucher la carte ouvre le PROFIL de l'ami,
      toucher la gelule ouvre la DISCUSSION. Deux destinations dans une meme rangee
      demandent deux cibles franchement separables au doigt — d'ou la gelule et son
      `::after` de 4.
   ⚠️⚠️ IL NE SE GRISE PLUS QUAND L'AMI EST HORS LIGNE. Deux regles le faisaient (voile
      .07 -> .035, encre #C6BFD6 -> #6E6883) et ELLES SONT SUPPRIMEES : on eteignait une
      commande QUI MARCHE. Ecrire a quelqu'un d'absent fonctionne exactement pareil, le
      message attend. L'AFFAIBLISSEMENT D'UN BOUTON VEUT DIRE « INDISPONIBLE ». Et le
      statut se dit deja deux fois dans la rangee, par le point et par « Vu il y a 12
      jours » : une information portee par le texte n'a pas besoin d'etre repetee par la
      matiere.
      ⚠️⚠️ [11/08] ET LE BOUTON LUI-MEME EST SUPPRIME, sur demande de Theo : la rangee n'a
      plus qu'une destination. Ce bloc de commentaire est conserve parce qu'il porte une
      regle qui vaut ailleurs — l'affaiblissement d'un bouton veut dire « indisponible » —
      mais IL NE DECRIT PLUS RIEN DE CETTE PAGE.
   ⚠️ IL RESTE SANS COULEUR : vingt rangees, vingt boutons. UN ACCENT REPETE VINGT FOIS
      N'EST PLUS UN ACCENT.
   ⚠️ SON GLYPHE EST CELUI DE L'ONGLET DISCUSSIONS, AU TRACE PRES. Il en etait une
      VARIANTE : la grande bulle commencait a 11,9 au lieu de 10,1, ses rayons valaient
      2,4 au lieu de 1,6. DEUX DESSINS PRESQUE IDENTIQUES SONT PIRES QUE DEUX DESSINS
      DIFFERENTS — on ne les distingue pas, on les sent. Le trace vit dans app.js. */
#s-amis .am-chev{width:8px;height:13px;flex:0 0 auto;fill:none;stroke:#7A7391;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;
  margin-left:11px;margin-right:3px}

/* ══ LE POINT DE PRESENCE — UNE SEULE REGLE POUR TOUT L'ECRAN ══
   11 px, bague de 2 px en rgba(12,12,15,.45), partout. C'est la valeur du
   Multijoueur, deja en production. AUCUNE surcharge dans la vitrine : elle
   en a eu quatre — taille, position, bague blanche, centre creux — et
   chacune eloignait le point de la vitrine de celui de la liste. Une bague
   de separation est un detail de construction, et un detail de
   construction ne varie pas selon l'endroit ou on le regarde.
   ⚠️ LE PLACEMENT EST EN POURCENTAGE, PAS EN PIXELS. A right:0 le point se
      pose au coin de la BOITE CARREE, soit 7 px hors du disque ; et la
      valeur juste change avec la taille — 46, 50, 56 px selon l'endroit. */
:is(#s-amis,#s-multi) .am-pt{position:absolute;right:2%;bottom:2%;width:11px;height:11px;
  border-radius:50%;background:var(--presence);
  box-shadow:0 0 0 2px rgba(12,12,15,.45)}
/* ⚠️ [06/08, ordre de Theo sur capture : « les pastilles rouges dans la liste,
   pas de grise »] LE ROUGE « HORS LIGNE » VIT PARTOUT SUR L'ECRAN, vitrine ET
   liste, meme valeur #C0524F. Ca DEFAIT l'arbitrage du 04/08 (« le rouge ne vit
   que dans la vitrine, la liste passe au gris ») — defait par Theo lui-meme,
   comme le contrat l'exigeait. L'ecart au socle reste connu et assume : le
   rouge est normalement reserve a l'irreversible, et la convention courante
   lit un point rouge comme OCCUPE ; ici il dit « hors ligne », des deux cotes,
   et la rangee de liste garde « Vu il y a… » en toutes lettres en renfort. */
:is(#s-amis,#s-multi) .am-rec .am-av.off .am-pt{background:#C0524F}

/* ══ L'ARC DES TEINTES ══
   205° a 250°, VIOLET EXCLU : il est reserve au connecte, et un ami en
   violet se ferait passer pour toi.
   ⚠️ `background-color` ET NON `background` : le raccourci remet
      `background-image` a `none` et effacerait le reflet radial de la
      vitrine, sur les quatre teintes a la fois.
   ⚠️ L'ARC S'EPUISE AU NEUVIEME AMI. Huit teintes ; au neuvieme, deux
      personnes portent le meme bleu et c'est l'initiale qui identifie.
      Sans solution de dessin : l'arc ne peut pas s'elargir sans mordre sur
      le fuchsia, l'or, le sarcelle, le vert ou le rouge. */
/* ══⚠️⚠️ [07/08] LES HUIT TEINTES SONT DECLAREES UNE FOIS, HORS DE TOUT SCOPE ══
   Elles etaient enfermees dans `#s-amis`, et le profil d'un ami — qui vit dans `#s-compte`
   depuis le 07/08 — a du LES RECOPIER : huit regles `#s-compte .c-grand.ami.am-avN` avec
   les memes hexadecimaux. La note de ce jour-la disait « dette assumee, la feuille d'Amis
   est en cours de refonte, les deux blocs se rejoindront ». C'EST FAIT ICI.
   ⚠️ LA SOURCE UNIQUE N'EST PAS UN SCOPE, C'EST LA CLASSE ELLE-MEME : `.am-avN` ne pose
      plus AUCUNE peinture, elle ne declare que trois variables. Chaque endroit qui montre
      un ami les LIT — la liste, la bobine, le grand portrait. Une valeur qu'on lit ne peut
      pas diverger de sa source ; une valeur qu'on recopie finit toujours par diverger.
   ⚠️ ET LA GARDE RESTE : `outils/test-teinte-avatar.js` compare toujours les deux cotes,
      reecrit pour lire cette source unique au lieu des deux copies (raison datee sur
      place). Le controle ne disparait pas parce que la dette est payee : c'est lui qui
      empeche qu'on rouvre une seconde copie demain.
   ══ L'ARC : 205° a 250°, VIOLET EXCLU ══
   Il est reserve au connecte, et un ami en violet se ferait passer pour toi.
   ⚠️ `background-color` ET NON `background` sur la bobine : le raccourci remet
      `background-image` a `none` et effacerait le reflet radial, sur les huit teintes.
   ⚠️ L'ENCRE SUIT LA CLARTE, elle n'est pas decorative : sur les quatre bleus fonces, une
      encre sombre tomberait sous le seuil ; ceux-la portent du blanc.
   ⚠️ L'ARC S'EPUISE AU NEUVIEME AMI. Huit teintes ; au-dela, deux personnes portent le
      meme bleu et c'est l'initiale qui identifie. Sans solution de dessin : l'arc ne peut
      pas s'elargir sans mordre sur le fuchsia, l'or, le sarcelle, le vert ou le rouge. */
/* [07/10, Romain : « le blanc de l'icône de Theo, je le trouve vraiment pas beau »] LES AMIS EN
   VERRE NUIT, pas en creme. La teinte unique creme du 02/10 (avatar sorti de l'app) faisait une
   pastille blanche sur la nuit. Un ami porte maintenant la matiere des commandes : fond nuit
   translucide, initiale lavande, filet lavande (pose par la regle de forme plus bas). Le violet
   plein reste au connecte : un ami en verre ne se fait pas passer pour toi. Une seule source,
   toujours : les trois variables, lues par la liste, la bobine, le grand portrait et les fils. */
/* [13/10, Romain, v969] LES HUIT TEINTES SE DISTINGUENT A NOUVEAU (maquettes Amis du 13/10, piste A) :
   un rond colore par ami sur l'arc 205-250, degrade --ami-hi -> --ami-lo, initiale blanche. Le verre
   nuit du 07/10 ci-dessus est remplace. --ami-fond reste la teinte pleine lue par l'anneau de v951. */
.am-av1{--ami-fond:#2F93DA;--ami-encre:#FFFFFF;--lueur:91,168,224;--ami-hi:#5AA9E2;--ami-lo:#2477B2}
.am-av2{--ami-fond:#3C5CDD;--ami-encre:#FFFFFF;--lueur:102,124,226;--ami-hi:#5A75E2;--ami-lo:#2441B2}
.am-av3{--ami-fond:#337CDB;--ami-encre:#FFFFFF;--lueur:94,148,226;--ami-hi:#5A95E2;--ami-lo:#2462B2}
.am-av4{--ami-fond:#4050DD;--ami-encre:#FFFFFF;--lueur:110,118,228;--ami-hi:#5A68E2;--ami-lo:#2433B2}
.am-av5{--ami-fond:#2F87DA;--ami-encre:#FFFFFF;--lueur:92,160,226;--ami-hi:#5AA0E2;--ami-lo:#246DB2}
.am-av6{--ami-fond:#3869DC;--ami-encre:#FFFFFF;--lueur:98,134,226;--ami-hi:#5A83E2;--ami-lo:#244FB2}
.am-av7{--ami-fond:#3C54DD;--ami-encre:#FFFFFF;--lueur:106,121,228;--ami-hi:#5A6FE2;--ami-lo:#243AB2}
.am-av8{--ami-fond:#524DDB;--ami-encre:#FFFFFF;--lueur:118,112,226;--ami-hi:#6B67E0;--ami-lo:#302CBA}
:is(#s-amis,#s-multi) .am-av{position:relative;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-weight:700;
  background-color:var(--ami-fond);color:var(--ami-encre)}

/* etats vides et messages : la meme voix que le reste de l'app */
#s-amis .am-vide{padding:var(--e-4) var(--e-2);text-align:center;color:var(--dim);
  font-size:var(--t-2);line-height:1.45}
#s-amis .am-vide b{display:block;color:var(--ink);font-size:var(--t-3);
  font-weight:700;margin-bottom:var(--e-2)}
#s-amis :focus-visible{outline:2px solid #A78BFA;outline-offset:3px;border-radius:var(--r-2)}

/* ══════════════════════════════════════════════════════════════════════
   [07/08, §6] LA VUE DEMANDES — ECRAN NEUF

   Elle remplace les rangees `.am-ami` a boutons minuscules (`.am-act` / `.am-btn`,
   34 px de haut, supprimees avec ce lot : leur cible tombait sous le plancher).

   ⚠️⚠️ LA RANGEE A DEUX LIGNES, ET C'EST LA PLACE QUI L'IMPOSE. Une rangee d'ami tient
      sur une ligne parce qu'elle porte UN bouton de 54 ; une demande recue en porte DEUX.
      QUAND DEUX OBJETS NE TIENNENT PAS SUR UNE LIGNE, ON AJOUTE UNE LIGNE — ON NE
      RETRECIT PAS LES OBJETS. Des boutons de 60 se rateraient au doigt, et c'est
      justement ce qu'on ne veut pas sur un choix qui engage quelqu'un d'autre.
   ⚠️ L'AVATAR OCCUPE LES DEUX LIGNES (`grid-area:1/1/3/2`) : UNE PERSONNE SE POSE EN
      FACE DE TOUT CE QU'ON DIT D'ELLE, pas en face de sa premiere ligne.
   ⚠️⚠️ « ACCEPTER » EST BLEU, ET C'EST LE SOCLE QUI LE DIT : LE BLEU APPARTIENT AUX GENS.
      C'est deja pourquoi le « + » est bleu et non violet — il ajoute une personne. UNE
      ACTION QUI FAIT LA MEME CHOSE QU'UNE AUTRE PORTE LA MEME COULEUR.
   ⚠️⚠️ « REFUSER » N'EST PAS ROUGE. Refuser ne detruit rien : la personne peut redemander.
      EMPLOYER LE ROUGE POUR CE QUI SE REFAIT, C'EST USER LE SEUL SIGNAL QUI RESTE QUAND
      QUELQUE CHOSE EST VRAIMENT DEFINITIF. Le socle reserve le rouge a l'irreversible.
   ⚠️ ET LES DEUX PESENT PAREIL, EXPRES : dans un choix qui engage quelqu'un d'autre, les
      deux issues doivent se valoir. Meme hauteur, meme corps, meme rembourrage.
   ⚠️ UNE DEMANDE ENVOYEE N'A QU'UNE ACTION, ET ELLE EST DISCRETE. On ne « valide » pas ce
      qu'on a deja fait : UNE RANGEE QUI N'ATTEND RIEN DE TOI NE PORTE PAS DE BOUTON PLEIN.
   ══════════════════════════════════════════════════════════════════════ */
#s-amis .am-dem{display:grid;grid-template-columns:46px 1fr;
  grid-template-rows:auto auto;align-items:center;
  column-gap:var(--e-3);row-gap:var(--e-3);width:100%;
  padding:var(--e-3) var(--e-3);border-radius:var(--r-3);text-align:left;
  background:rgba(150,140,210,.022);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.19),
             0 8px 20px -14px rgba(0,0,0,.7)}
#s-amis .am-dem .am-av{grid-area:1/1/3/2;align-self:start;margin-top:2px;
  width:46px;height:46px;font-size:var(--t-3)}
#s-amis .am-dem .am-txt{grid-area:1/2/2/3;min-width:0}
#s-amis .am-dem b{display:block;font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-amis .am-dem small{display:block;font-size:var(--t-2);margin-top:var(--e-1);color:var(--c-texte-3)}
/* ⚠️⚠️ [07/08] `flex-wrap` ET `min-width:0` : MESURE, PAS PRECAUTION. A 320 px en Grand
   texte, « Accepter » fait 128,9 et « Refuser » 118,1 ; avec l'ecart de 10 et la colonne
   d'avatar de 46 + 15, il faut 318 pour une page qui en donne 284. La rangee sortait de
   32 px a droite, et l'ecran entier devenait defilant lateralement — releve au CSSOM,
   invisible a 402 px ou tout tient. LE DEBORDEMENT NE SE VOIT PAS SUR LE TELEPHONE OU
   L'ON DESSINE.
   ⚠️ ET ON ENROULE, ON NE RETRECIT PAS : c'est la regle meme du §6. QUAND DEUX OBJETS NE
      TIENNENT PAS SUR UNE LIGNE, ON AJOUTE UNE LIGNE — des boutons rapetisses se
      rateraient au doigt, et c'est justement ce qu'on ne veut pas sur un choix qui engage
      quelqu'un d'autre. La rangee monte a trois lignes dans ce cas extreme, et les deux
      actions gardent leur poids egal.
   ⚠️ `min-width:0` PARCE QU'UN ELEMENT DE GRILLE NE DESCEND PAS SOUS SON CONTENU MINIMUM
      par defaut : sans lui, `flex-wrap` n'a jamais l'occasion de s'appliquer, la colonne
      `1fr` s'elargit d'elle-meme et le debordement revient. Les deux vont ensemble. */
#s-amis .am-actions{grid-area:2/2/3/3;display:flex;flex-wrap:wrap;gap:var(--e-2);min-width:0}
/* ⚠️⚠️ [07/08] LA GELULE SORT DU SCOPE `#s-amis`, ET C'EST LE RENDU DES DISCUSSIONS QUI
   L'EXIGE : une invitation de groupe s'accepte ou se refuse EXACTEMENT comme une demande
   d'ami — on repond oui ou non a quelqu'un. Deux objets qui font la meme chose portent le
   meme dessin, et une SEULE regle les dessine : la recopier sous `#s-multi` aurait fait
   deux sources qui divergeraient a la premiere correction.
   ⚠️ SEUL LE SELECTEUR CHANGE, AUCUNE VALEUR : Amis rend au pixel ce qu'il rendait avant
      (verifie au CSSOM avant/apres). La specificite tombe de (1,2,0) a (0,2,0), sans
      consequence : rien d'autre dans la feuille ne cible `.am-act`.
   ⚠️ ET ELLE PORTE SON PROPRE RESET : `border:0`, `background` (par .oui/.non),
      `font-family:inherit`, `color`. Cette feuille n'a AUCUN reset global sur `button` —
      sans eux le navigateur peint la gelule lui-meme, fond gris, bordure 2px outset,
      Arial 13,3 px. Faute payee quatre fois sur ce projet. */
.am-act{position:relative;display:flex;align-items:center;justify-content:center;
  gap:var(--e-2);height:36px;padding:0 var(--e-3);border-radius:999px;
  border:0;cursor:pointer;white-space:nowrap;font-family:inherit;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;
  transition:transform .16s var(--ease),background .16s var(--ease)}
.am-act:active{transform:scale(.96)}
.am-act svg{width:16px;height:16px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
.am-act.oui{background:linear-gradient(180deg,#6C96FA 0%,#4C7DF0 100%);
  color:#071630;box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
.am-act.oui:active{background:linear-gradient(180deg,#5E8CF8 0%,#3E70E8 100%)}
.am-act.non{background:rgba(255,255,255,.07);color:var(--c-texte-2);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.15)}
.am-act.non:active{background:rgba(255,255,255,.14)}
#s-amis .am-dem.envoyee{background:rgba(150,140,210,.014)}
#s-amis .am-dem.envoyee b{color:var(--c-texte-2)}

/* ══ [07/08, rendu du soir] LA PORTE : « AJOUTER UN AMI · PAR PSEUDO » ═══════════════
   ⚠️⚠️ ELLE EST EN TETE D'ECRAN, PAS DANS UNE SECTION. Ajouter un ami n'alimente pas
      « Envoyées », c'est LA RAISON D'ETRE DE L'ECRAN : rangee dans une section, elle en
      devenait un detail. UNE ACTION QUI VAUT POUR TOUT L'ECRAN SE POSE AVANT LES
      SECTIONS, PAS DANS L'UNE D'ELLES — et sa place ne depend alors ni du nombre de
      demandes, ni de l'existence des sections.
   ⚠️⚠️ C'EST UN `<button>`, ET CETTE FEUILLE N'A AUCUN RESET GLOBAL SUR `button`. Sans
      `background`, `border:0` et `font-family:inherit` ECRITS ICI, le navigateur le peint
      lui-meme : fond gris, bordure `2px outset`, Arial 13,3 px. Faute payee quatre fois
      sur ce projet, la derniere en production le 07/08 sur trois rangees.
   ⚠️ 58 ET NON 76 : 76 est la cote d'une rangee qui porte une PERSONNE (avatar de 46, nom,
      sous-titre) ; celle-ci porte une tuile de 36. UNE RANGEE SE MESURE A CE QU'ELLE
      CONTIENT. Rembourrage 11 en haut et en bas : (58 − 36) / 2, la tuile est centree par
      le calcul, pas a l'oeil. 58 est aussi la cote des rangees de reglage du Compte.
   ⚠️ 32 SOUS ELLE, comme sous le titre : le rythme d'un ecran de liste est
      barre 32 · objet 32 · sections.
   ⚠️⚠️ SA TUILE EST UN CARRE ARRONDI, PAS UN CERCLE : LE CERCLE APPARTIENT AUX GENS, et
      ici il n'y a personne. Elle est VIOLETTE et non bleue, et la distinction n'est pas
      une nuance : LE BLEU AGIT SUR UNE PERSONNE (le « + » de la liste, « Accepter »,
      « Ajouter » d'un resultat creent un lien avec quelqu'un de precis), LE VIOLET OUVRE
      UN LIEU. Cette tuile n'ajoute personne, elle ouvre un ecran.
      Le vert a ete essaye et ecarte pour une raison mesurable : dans cette app il ne veut
      dire qu'une chose, « en ligne », et sur l'etat plein un POINT vert de presence se
      serait trouve a quarante pixels d'un CARRE vert d'action. UNE COULEUR QUI SERT DEUX
      FOIS SUR LE MEME ECRAN NE DIT PLUS NI L'UN NI L'AUTRE.
   ⚠️ LE DEGRADE EST CELUI DE L'AVATAR VIOLET, a l'identique : un meme violet ne se
      redessine pas d'un objet a l'autre, c'est la FORME qui les distingue.
   ⚠️ ET L'ENCRE DU GLYPHE EST L'ENCRE SOMBRE DE LA MARQUE, #170B20 : 4,49:1 sur le bas du
      degrade, 6,88 sur le haut. Le blanc n'y rendrait que 4,23, SOUS LE PLANCHER LA OU LE
      VIOLET EST LE PLUS DENSE — sur un degrade, un contraste se verifie a son point le
      plus defavorable, pas a sa moyenne.
   ⚠️⚠️ 36 ET NON 46 : LA TUILE MAIGRIT, LA COLONNE NE BOUGE PAS. Les commandes de cette
      app font 36 a rayon 12 (retour, reglages, « + » de la liste) — UN OBJET SE MESURE A
      CE QU'IL EST, PAS A CE QU'IL REMPLACE. Les 5 px de marge de chaque cote ne sont pas
      un reglage : ils recentrent le 36 dans la colonne de 46, pour que le texte parte au
      meme pixel que sur les rangees voisines.
          rangee de personne ··· 16 + 46 + 15 = 77
          cette rangee ········· 16 + 5 + 36 + 5 + 15 = 77
      UNE COLONNE SE TIENT, MEME QUAND CE QU'ELLE CONTIENT EST PLUS PETIT.
   ⚠️ LE GLYPHE SUIT : 19 pour 36, la proportion des boutons de commande. Son chevron est
      `.am-chev`, celui des rangees d'ami — pas un second dessin.
   ⚠️ `--text` DU RENDU N'EXISTE PAS DANS CE SOCLE (il declare `--ink`) : une variable
      absente rend la declaration invalide EN SILENCE et le titre retomberait sur
      l'heritage. Divergence de nom, meme valeur. */
#s-amis .am-porte{display:flex;align-items:center;gap:var(--e-3);width:100%;
  min-height:58px;padding:var(--e-2) var(--e-3) var(--e-2) var(--e-3);border-radius:var(--r-3);
  margin:0 0 var(--e-5);
  text-align:left;cursor:pointer;border:0;font-family:inherit;
  background:rgba(150,140,210,.022);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.19),
             0 8px 20px -14px rgba(0,0,0,.7);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-amis .am-porte:active{transform:scale(.985);background:rgba(150,140,210,.05)}
#s-amis .am-porte .am-tu{width:36px;height:36px;border-radius:var(--r-1);flex:0 0 auto;
  margin:0 5px;display:grid;place-items:center;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
#s-amis .am-porte .am-tu svg{width:19px;height:19px;fill:none;stroke:#170B20;
  stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
#s-amis .am-porte b{display:block;font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--ink)}
#s-amis .am-porte small{display:block;font-size:var(--t-2);margin-top:var(--e-1);color:var(--c-texte-3)}

/* ══ [07/08, rendu du soir] L'ABSENCE, SECTION PAR SECTION ══
   Elle remplace le grand bloc « Rien a repondre » qui prenait la place des deux sections.
   ⚠️⚠️ CE N'EST PLUS UNE CARTE DU TOUT. Elle en etait une, 58 de haut, pleine largeur, avec
      son voile et son filet : 357 pixels de surface pour vingt-deux caracteres. Le cadre
      promettait un objet et n'en contenait aucun. UNE CARTE CONTIENT QUELQUE CHOSE ; UNE
      ABSENCE NE SE MET PAS DANS UNE BOITE. Reduire le cadre a la largeur du texte
      n'aurait pas mieux valu : une gelule de deux cents pixels a gauche d'une liste se lit
      comme un bouton — LE PROBLEME N'ETAIT PAS LA TAILLE DU CADRE, C'ETAIT LE CADRE.
   ⚠️⚠️ ELLE S'ALIGNE A 16, PAS A 4. A 4, elle partageait le retrait de l'intitule : deux
      textes gris, sans surface, au meme bord gauche. DEUX TEXTES QUI COMMENCENT AU MEME
      PIXEL SE LISENT COMME UN SEUL BLOC, quelle que soit leur graisse — l'intitule et la
      phrase formaient un en-tete de deux lignes. ON DISTINGUE PAR LA COLONNE AVANT DE
      DISTINGUER PAR L'ENCRE. A 16, elle prend le retrait du CONTENU d'une carte : elle
      occupe la place d'une rangee, elle s'aligne comme une rangee.
   ⚠️ ET ELLE PREND LE CORPS ET L'ENCRE D'UN SOUS-TITRE DE RANGEE — 14 et #8E879F,
      exactement `.am-dem small`. CE QUI REMPLACE UNE RANGEE EMPRUNTE LA VOIX DE CE QU'ELLE
      CONTENAIT, pas une voix a elle.
   ⚠️ NI GLYPHE NI ILLUSTRATION : cette app n'en a aucun pour les etats vides, et en
      inventer un ici creerait un vocabulaire visuel de plus pour une seule occurrence. */
#s-amis .am-rien{padding:var(--e-1) var(--e-3);font-size:var(--t-2);line-height:1.4;color:var(--c-texte-3)}

/* ══════════════════════════════════════════════════════════════════════
   [07/08, §7] AJOUTER UN AMI · PAR PSEUDO — ECRAN NEUF

   ⚠️ LE TITRE EST « AJOUTER UN AMI », PAS « PAR PSEUDO ». Ce n'est pas au titre de
      distinguer, c'est au contenu : le champ dit « Pseudo ». LE TITRE DIT CE QU'ON FAIT,
      LE CHAMP DIT AVEC QUOI — un titre nomme une intention, pas un moyen.
   ⚠️⚠️ LE CHAMP FAIT 44, PAS 36. Sur la liste, le champ est un OUTIL pose sur des cartes ;
      ici il est LE SUJET DE L'ECRAN. UN OBJET SE MESURE A CE QU'IL FAIT DANS LA PAGE, PAS
      A SON NOM. 44 est aussi le plancher de cible : aucun `::after` n'est necessaire.
   ⚠️ AUCUN VERRE : rien ne defile dessous. UN FLOU QUI NE FLOUTE RIEN COUTE UNE COUCHE DE
      COMPOSITION POUR ZERO PIXEL.
   ⚠️ ET LE CHAMP EST A 16 px (1rem), COMME PARTOUT DANS CETTE APP. Le rendu ecrit lui
      aussi 16 ici — c'est le seul champ du lot ou les deux sont d'accord. Sous ce seuil,
      iOS zoome la page a la mise au point et ne la redescend jamais tout a fait.

   ══ LES TROIS ETATS D'UN RESULTAT ══
        a ajouter ····  gelule bleue pleine        UNE ACTION
        demande ······  gelule voilee, INERTE      UN ETAT
        deja ami ·····  texte gris, aucun objet    UN FAIT
   ⚠️ UN ECRAN DE RECHERCHE DOIT MONTRER CE QUI ARRIVE QUAND ON TROUVE QUELQU'UN QU'ON
      CONNAIT DEJA. Et ce qui n'attend rien de toi ne porte pas de bouton.
   ⚠️ « DEMANDE » EST LE SEUL ENDROIT DE CET ECRAN OU L'AFFAIBLISSEMENT EST JUSTE : on ne
      peut pas redemander. C'etait faux pour un ami hors ligne (§4), c'est vrai pour une
      demande deja partie.
   ⚠️ LE BLEU D'« AJOUTER » EST CELUI D'« ACCEPTER » ET DU « + » : le bleu appartient aux
      gens, et ces trois actions ajoutent une personne.
   ══════════════════════════════════════════════════════════════════════ */
#s-amis .am-entete{display:grid;grid-template-columns:36px 1fr 36px;align-items:center;
  flex:0 0 auto;min-height:44px;margin:2px 0 var(--e-5)}
#s-amis .am-entete h1{grid-column:2;justify-self:center;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;
  line-height:1.2;color:var(--c-texte)}
#s-amis .am-retour{grid-column:1;position:relative;width:36px;height:36px;
  border-radius:var(--r-1);background:rgba(255,255,255,.07);border:0;
  display:grid;place-items:center;cursor:pointer;color:var(--c-texte-2);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-amis .am-retour::after{content:'';position:absolute;inset:-4px}
#s-amis .am-retour:active{transform:scale(.94);background:rgba(255,255,255,.14)}
#s-amis .am-retour svg{width:12px;height:12px;stroke:#C6BFD6;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
#s-amis .am-champ{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:0 0 auto;width:100%;min-height:44px;padding:0 var(--e-3);margin:0 0 var(--e-5);
  border-radius:999px;
  background:rgba(255,255,255,.07);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.15);
  transition:box-shadow .18s var(--ease)}
#s-amis .am-champ:focus-within{box-shadow:inset 0 0 0 .34px rgba(167,139,250,.55)}
#s-amis .am-champ svg{width:17px;height:17px;flex:0 0 auto;fill:none;stroke:#9990AE;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ `padding:0` POUR LA MEME RAISON QUE SUR `.am-rech` : la regle generale des champs de
   l'app pose 14 px de rembourrage, qui feraient 52 la ou le dessin en demande 44. */
#s-amis .am-champ input{flex:1 1 auto;min-width:0;border:0;background:none;outline:none;
  padding:0;font-family:inherit;font-size:1rem;font-weight:400;color:var(--ink)}
#s-amis .am-champ input::placeholder{color:var(--c-texte-3)}
#s-amis .am-res{display:flex;align-items:center;gap:var(--e-3);width:100%;
  min-height:76px;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);border-radius:var(--r-3);
  text-align:left;
  background:rgba(150,140,210,.022);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.19),
             0 8px 20px -14px rgba(0,0,0,.7)}
#s-amis .am-res .am-av{width:46px;height:46px;font-size:var(--t-3)}
#s-amis .am-res .am-txt{flex:1 1 auto;min-width:0}
#s-amis .am-res b{display:block;font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-amis .am-res small{display:block;font-size:var(--t-2);margin-top:var(--e-1);color:var(--c-texte-3)}
#s-amis .am-etat{flex:0 0 auto;display:flex;align-items:center;gap:var(--e-2);
  height:36px;padding:0 var(--e-3);border-radius:999px;white-space:nowrap;font-family:inherit;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em}
#s-amis .am-etat.oui{background:linear-gradient(180deg,#6C96FA 0%,#4C7DF0 100%);
  color:#071630;box-shadow:inset 0 1px 0 rgba(255,255,255,.22);
  border:0;cursor:pointer;
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-amis .am-etat.oui:active{transform:scale(.96);
  background:linear-gradient(180deg,#5E8CF8 0%,#3E70E8 100%)}
#s-amis .am-etat.fait{background:rgba(255,255,255,.05);color:var(--c-texte-3);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.10)}
#s-amis .am-etat svg{width:16px;height:16px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
#s-amis .am-deja{flex:0 0 auto;font-size:var(--t-2);font-weight:500;color:var(--c-texte-3);
  padding-right:var(--e-2)}

/* ══════════════════════════════════════════════════════════════════════
   [06/08] L'ETAT « AJOUTER UN AMI » — le menu du « + » (lot PORTAGE-AMIS §5)

   ⚠️⚠️ LE MENU N'A QU'UNE ENTREE, ET C'EST UN REFUS MOTIVE, PAS UN OUBLI.
      Le rendu en propose deux : « Par pseudo » et « Par code ami ». LE CODE
      AMI N'EXISTE NULLE PART DANS L'APP — ni colonne de schema, ni route,
      ni ecran. Le seul code du produit est le CODE DE RECUPERATION DE
      COMPTE, qui ne doit JAMAIS etre partage : une entree « par code ami »
      pousserait exactement a le donner. Ecart signale au design le 04/08,
      revenu dans le lot du 05/08, refuse une seconde fois le 06/08.
      Controle AMIS-12 pose pour que personne ne le remette sans le vouloir.
   ⚠️ LE DECOR EST FLOUTE PAR `filter` SUR LES ELEMENTS, PAS PAR UN
      `backdrop-filter` SUR LE VOILE, et c'est le choix robuste : quatre
      causes independantes tuent un backdrop-filter sur WebKit (cage
      d'empilement, ancetre transforme, transform sur l'element lui-meme,
      second backdrop-filter). ON FLOUTE LES OBJETS EUX-MEMES, PAS CE QU'ON
      VOIT A TRAVERS. Le voile ne fait plus qu'assombrir. Meme construction
      que le menu du Multijoueur, deja en production.
   ⚠️ LA BARRE DU BAS N'EST PAS DANS LA LISTE DES ELEMENTS FLOUTES, et le
      « + » non plus : elle reste nette et touchable, il reste net sous le
      doigt. UN MENU LOCAL NE PREND PAS LA NAVIGATION EN OTAGE. La barre
      vit hors des `.screen` et porte z-index:20 : le voile a 5 passe donc
      dessous sans qu'aucune regle n'ait a l'exclure.
   ⚠️ L'ORIGINE D'ECHELLE EST LE COIN HAUT-DROIT — le point de contact avec
      le « + ». UN OBJET GRANDIT DEPUIS L'ENDROIT OU ON L'A TOUCHE ; au
      centre, il apparaitrait au lieu de s'ouvrir.
   ⚠️ `backwards`, JAMAIS `both` (§0.3). Avec `both`, une animation garde a
      vie l'etat de sa derniere image, ET UNE VALEUR D'ANIMATION L'EMPORTE
      SUR TOUTE DECLARATION NORMALE, quelle que soit sa specificite. Rien
      dans l'inspecteur ne le montre : la regle n'est pas barree, elle est
      DOMINEE. C'est ce qui avait rendu le retrecissement de la barre
      impossible le 05/08.
   ══════════════════════════════════════════════════════════════════════ */
#s-amis .am-voile{position:fixed;inset:0;z-index:5;background:rgba(6,6,9,.46);
  animation:uiVoile var(--m-court) var(--m-sortie) backwards}

/* ⚠️⚠️ [07/08, §5] LA LISTE DES ELEMENTS FLOUTES A ETE RELUE AVEC CE LOT : `.am-segments`
   N'EXISTE PLUS (§2). UN SELECTEUR QUI NOMME DES BLOCS DOIT ETRE RELU CHAQUE FOIS QU'UN
   BLOC DISPARAIT, sinon il floute un fantome et oublie un vivant — et rien ne le montre,
   puisqu'un selecteur sans cible ne produit ni erreur ni regle barree. */
#s-amis.am-ajout-ouvert .am-titre,
#s-amis.am-ajout-ouvert .am-apercu,
#s-amis.am-ajout-ouvert .am-rech,
#s-amis.am-ajout-ouvert .am-groupe{filter:blur(4.5px)}

#s-amis .am-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:6;
  min-width:212px;padding:var(--e-1);border-radius:var(--r-3);
  background:linear-gradient(rgba(14,14,18,.10),rgba(14,14,18,.10)),
    rgba(122,122,136,.34);
  -webkit-backdrop-filter:blur(40px) saturate(1.8);
  backdrop-filter:blur(40px) saturate(1.8);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),
    0 2px 6px rgba(0,0,0,.12);
  transform-origin:100% 0;
  animation:uiMenu var(--m-court) var(--m-sortie) backwards}

/* ⚠️ 44 DE HAUT, SANS `::after` : deux rangees qui se touchent ne peuvent pas deborder
   l'une sur l'autre. QUAND DES CIBLES SE SUIVENT, LA HAUTEUR REELLE DOIT ETRE LA BONNE
   DU PREMIER COUP — une cible etendue par pseudo-element volerait le bord de sa voisine.
   ⚠️ ET LE CONTENU ENTRE APRES SON CONTENANT (70 ms) : un contenant et son contenu
      n'arrivent pas ensemble, sinon on ne voit ni l'un ni l'autre. */
#s-amis .am-mit{position:relative;z-index:1;
  animation:uiMenuItem var(--m-court) var(--m-sortie) backwards;animation-delay:var(--md,0ms);
  display:flex;align-items:center;gap:var(--e-3);
  width:100%;min-height:44px;padding:0 var(--e-3);border-radius:var(--r-2);
  border:0;background:none;cursor:pointer;
  font:inherit;font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:var(--c-texte);
  text-align:left;transition:background .09s}

#s-amis .am-mit svg{width:19px;height:19px;flex:0 0 auto;stroke:#8FB4FF;
  fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ LE FILET DU MENU JUMEAU EST A `.021` ET A `height:1px` — UNE FAUTE DE FRAPPE QUI A
   SURVECU (elle vit encore dans `#s-multi .mu-mit+.mu-mit::before`, signale, hors
   perimetre de ce lot). A .021 sur ce fond, il rendait moins d'un demi-ton d'ecart : la
   regle existait, LE TRAIT NON. UNE VALEUR QU'ON NE VOIT PAS N'EST PAS UNE VALEUR
   DISCRETE, C'EST UNE VALEUR ABSENTE. Ici .09, et l'epaisseur par la boite ecrasee —
   `height:1px` en dur valait trois pixels physiques a 3x.
   ⚠️ RETRAIT DE 34 A GAUCHE : il commence au texte, pas au bord. Il ARTICULE deux
      rangees d'une meme serie, il ne COUPE pas le panneau en deux. */
#s-amis .am-mit+.am-mit::before{content:'';position:absolute;left:34px;right:0;top:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.09)}
#s-amis .am-mit:active{background:rgba(255,255,255,.09)}
/* mouvement reduit : le menu s'ouvre, il ne se joue pas. Aucune information ne repose
   sur le mouvement seul — le panneau est deja la, a sa place, des la premiere image. */
@media (prefers-reduced-motion:reduce){
  #s-amis .am-voile,#s-amis .am-menu,#s-amis .am-mit{animation:none}
}

/* ══════════════════════════════════════════════════════════════════════
   [05/08] LE CLASSEMENT AU RENDU — barre des modes, podium, liste
   Porte de design/ecrans/vague-05-08/classement.html.
   Toutes les cotes du rendu sont en px ; elles sont ecrites ici en rem
   (÷16) pour que le reglage Grand texte les emporte, ce que le contrat
   impose et que le dossier laisse ouvert (§16.5). Le dessin est le meme
   a taille normale.
   ══════════════════════════════════════════════════════════════════════ */

/* ══ LA BARRE DES MODES : une capsule, cinq signes, seul l'actif nomme ══
   ⚠️ « TOUS LES JEUX », PAS « TOUT ». Un mot seul de quatre lettres ne dit
      pas de quoi il est le tout : pose devant quatre modes, il pouvait se
      lire « toutes les periodes » ou « tous les amis ». Un totalisateur
      doit nommer ce qu'il totalise. */
/* ⚠️ LA CAPSULE NE CHANGE PLUS JAMAIS DE TAILLE (Theo, 06/08 : « il faut que tout reste
   fixe »). Elle epousait son contenu, donc sa largeur suivait le libelle du mode actif : de
   272 a 320 px selon le mode. Trois defauts en decoulaient, et c'etaient TOUS le meme :
     · elle sautait a chaque changement, et animer sa largeur revenait a courir apres une
       cible mouvante (deux versions y sont passees) ;
     · le moindre repaint arrivant en plein vol la faisait retomber d'un bloc ;
     · centree sur son contenu, elle se decalait de 8 px sur deux modes.
   ⚠️ UN OBJET QUI NE BOUGE PAS N'A RIEN A ANIMER. En lui donnant la largeur de la colonne,
      il ne reste qu'un seul mouvement dans l'ecran : les pastilles qui glissent DANS un
      cadre immobile. C'est aussi ce que fait iOS avec ses barres segmentees.
   ⚠️ ET L'ECRAN GAGNE SA TROISIEME VERTICALE : le dossier du design ecrivait que les filtres
      « ne pourront jamais aligner aucun bord, leur largeur changeant avec le mode actif ».
      C'etait vrai tant que la largeur suivait le contenu. Filtres, reglages et liste partagent
      desormais les memes bords, a 22 et 353.
   ⚠️ `safe center` ET NON `center` : en cas de debordement (Grand texte), un centrage nu
      coupe le contenu DES DEUX COTES et le debut devient inatteignable ; `safe` bascule
      alors sur un alignement au debut. */
#s-classement .cm-filtres{flex:0 0 auto;width:100%;
  display:flex;justify-content:safe center;gap:2px;padding:var(--e-1);margin:0 0 var(--e-3);
  border-radius:999px;background:rgba(120,120,134,.13);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.15);
  overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
#s-classement .cm-filtres::-webkit-scrollbar{display:none}
#s-classement .cm-f{position:relative;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;gap:var(--e-2);font:inherit;
  height:38px;min-width:38px;padding:0 var(--e-2);border-radius:999px;border:0;
  cursor:pointer;white-space:nowrap;background:none;
  font-size:var(--t-2);font-weight:500;letter-spacing:-.005em;color:var(--c-texte);
  transition:background .24s var(--ease),transform .14s var(--ease)}
#s-classement .cm-f::after{content:'';position:absolute;left:0;right:0;top:-4px;bottom:-4px}
#s-classement .cm-f>span{display:none}
#s-classement .cm-f>svg{flex:0 0 auto;width:21px;height:21px;fill:none;stroke:var(--fc);
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;opacity:.55;
  transition:opacity .24s var(--ease)}
#s-classement .cm-f:active{transform:scale(.94)}
#s-classement .cm-f.actif{font-weight:600;padding:0 var(--e-3) 0 var(--e-2);
  background:rgba(255,255,255,.12);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
#s-classement .cm-f.actif>span{display:block}
#s-classement .cm-f.actif>svg{opacity:1}
/* le filet apres « Tous les jeux » : il n'est pas un mode, il est leur reunion. */
#s-classement .cm-f.tout{--fc:#A8A0BA;margin-right:7px}
#s-classement .cm-f.tout::before{content:'';position:absolute;right:-4.5px;top:10px;bottom:10px;
  width:1px;transform:scaleX(.34);background:rgba(255,255,255,.18)}
#s-classement .cm-f.soiree{--fc:#B486F8}
#s-classement .cm-f.minijeux{--fc:#FCD34D}
#s-classement .cm-f.classiques{--fc:#F45CC0}
#s-classement .cm-f.quiz{--fc:#5A9BE0}

/* ══ LE PODIUM — trois metaux, et chacun porte TROIS valeurs ══
   ⚠️ LE PODIUM CESSE DE SUIVRE LE MODE, IL SUIT LE RANG. La regle
      precedente (« l'accent suit le mode ») meurt ici, et la perte est
      petite : le podium n'existe que dans trois filtres, dont l'un n'a
      pas de couleur.
   ⚠️ UN METAL, C'EST UNE COULEUR ET LA LUMIERE QU'IL RENVOIE. Un argent
      eclaire par un reflet chaud n'est plus de l'argent ; un bronze ombre
      de bleu devient gris. D'ou trois variables par metal, pas une.
   ⚠️ ET LES GENS RESTENT BLEUS DANS LA LISTE : le metal ne dit pas qui
      est Romain, il dit ce qu'il a fait. Le podium est la vitrine du
      rang, la liste est la liste des gens. */
/* ⚠️ LA COUPURE DE LA LISTE N'ETAIT QU'UN DIV VIDE (trouve le 05/08 par le controle du
   §1.2 : une classe posee dans le markup sans aucune regle). Quand on n'est pas dans les
   cinquante premiers, l'app ajoute sa propre rangee a la suite du dernier du haut — sans
   rien pour dire QU'IL MANQUE DES RANGS ENTRE LES DEUX. Une 4e place collee a une 312e se
   lit comme une 5e. Le defaut dormait parce qu'a quatre joueurs, tout le monde est dans le
   haut du tableau.
   ⚠️ CE DESSIN EST DE NOTRE MAIN : le rendu du 05/08 ecrit « en deux avec un saut. Non
      traite ici », et le point reste ouvert au dossier (§7.2 : epingler ou couper). Trois
      points, la convention d'iOS pour un ensemble qui continue ailleurs, sans filet — un
      filet dirait « deux sections », alors qu'il n'y en a qu'une, trouee. */
#s-classement .cm-saut{position:relative;flex:0 0 auto;height:22px}
#s-classement .cm-saut::before{content:'';position:absolute;left:50%;top:50%;
  width:3px;height:3px;border-radius:50%;background:rgba(255,255,255,.26);
  transform:translate(-50%,-50%);
  box-shadow:-7px 0 0 rgba(255,255,255,.26),7px 0 0 rgba(255,255,255,.26)}

#s-classement .cm-podium{position:relative;flex:0 0 auto;margin:0 0 var(--e-4);padding:var(--e-2) var(--e-2) 0}
#s-classement .cm-podium::before{content:'';position:absolute;left:50%;top:-86px;
  width:240px;height:200px;transform:translateX(-50%);pointer-events:none;
  background:radial-gradient(closest-side,
    rgba(var(--accr),.13) 0%, rgba(var(--accr),.045) 46%, rgba(var(--accr),0) 100%)}
#s-classement .cm-tri{position:relative;display:grid;grid-template-columns:1fr 1.14fr 1fr;
  align-items:end;gap:var(--e-2)}
/* ⚠️ UNE MARCHE LIBRE MONTRE LA PLACE, PAS QUELQU'UN (Theo, 05/08 : le podium reste entier
   meme si personne ne peut etre dessus). Elle garde la geometrie exacte de sa voisine —
   sphere, socle, colonne, pastille de rang — et perd tout ce qui designe une personne :
   la matiere de la sphere, le nom, la couronne, le score, et le fait meme d'etre touchable.
   ⚠️ ELLE N'EST PAS « GRISEE » : un objet grise dit « indisponible ». Celui-ci dit « libre ».
      D'ou un cerne, pas un aplat : un contour se lit comme une place a prendre. */
#s-classement .cm-pl.cm-libre{cursor:default;pointer-events:none}
#s-classement .cm-pl.cm-libre .cm-vacant{width:60px;height:60px;border-radius:50%;
  position:relative;z-index:2;background:rgba(255,255,255,.028);
  box-shadow:inset 0 0 0 1.2px rgba(255,255,255,.10)}
#s-classement .cm-p1.cm-libre .cm-vacant{width:71px;height:71px}   /* la meme sphere que le 1er, au pixel */
#s-classement .cm-pl.cm-libre>b,
#s-classement .cm-pl.cm-libre .cm-pts b{color:#5C5670;font-weight:500}
#s-classement .cm-pl.cm-libre .cm-socle,
#s-classement .cm-pl.cm-libre .cm-colonne{opacity:.34}
#s-classement .cm-pl.cm-libre .cm-rg{background:rgba(255,255,255,.07);color:var(--c-texte-3);
  box-shadow:none}
#s-classement .cm-pl{display:flex;flex-direction:column;align-items:center;
  border:0;background:none;cursor:pointer;font:inherit;color:var(--ink);
  --reflet:205,225,240;--ombre:10,35,120;
  transition:transform .2s var(--ease)}
#s-classement .cm-pl:active{transform:scale(.96)}
#s-classement .cm-tete{position:relative;display:flex;flex-direction:column;align-items:center}
#s-classement .cm-p2{--lueur:198,208,228;--reflet:245,248,255;--ombre:30,38,66}
#s-classement .cm-p3{--lueur:201,139,87;--reflet:255,232,205;--ombre:92,40,10}
/* ⚠️ UNE RAMPE VERTICALE, PAS RADIALE : la reference est plate en travers.
   Et L'OMBRE D'UNE SPHERE EST DANS LA TEINTE DE LA SPHERE. */
#s-classement .cm-pl .cm-av{width:60px;height:60px;font-size:var(--t-4);position:relative;z-index:2;
  background-image:linear-gradient(180deg,
    rgba(var(--reflet),.60) 0%, rgba(var(--reflet),.48) 18%,
    rgba(var(--reflet),.12) 34%, rgba(var(--reflet),0) 45%,
    rgba(var(--ombre),.16) 56%, rgba(var(--ombre),.33) 68%,
    rgba(var(--ombre),.40) 80%, rgba(var(--ombre),.43) 100%);
  box-shadow:inset 0 3px 4px -2px rgba(255,255,255,.62),
             inset 3px 0 5px -3px rgba(255,255,255,.20),
             inset 0 -2px 4px -1px rgba(var(--reflet),.75),
             0 0 0 .34px rgba(255,255,255,.103),
             0 5px 9px -5px rgba(var(--ombre),.72),
             0 0 17px 3px rgba(var(--lueur),.44),
             0 0 40px -2px rgba(var(--lueur),.25),
             0 0 85px -20px rgba(var(--lueur),.18)}
#s-classement .cm-p2 .cm-av{background-color:#C8D0E0;color:#170B20}
#s-classement .cm-p3 .cm-av{background-color:#C98B57;color:#170B20}
#s-classement .cm-p1 .cm-av{width:71px;height:71px;font-size:var(--t-5);color:#170B20;
  background-color:#F3C63E;
  background-image:linear-gradient(180deg,
    rgba(255,255,255,.34) 0%, rgba(255,255,255,.245) 20%,
    rgba(255,255,255,.06) 33%, rgba(255,255,255,0) 42%,
    rgba(146,38,16,.12) 54%, rgba(146,38,16,.25) 68%,
    rgba(146,38,16,.35) 80%, rgba(146,38,16,.36) 100%);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.55),
             inset 3px 0 5px -3px rgba(255,244,200,.34),
             inset 0 -3px 5px -1px rgba(255,238,178,.90),
             0 0 0 .34px rgba(255,232,150,.37),
             0 6px 11px -6px rgba(72,38,0,.70),
             0 0 18px 3px rgba(var(--accr),.50),
             0 0 44px -2px rgba(var(--accr),.31),
             0 0 95px -22px rgba(var(--accr),.23)}
/* ⚠️ CE N'EST PAS UNE OMBRE PORTEE, C'EST UNE OMBRE DE CONTACT. Une ombre
   portee noierait la flaque : une sphere lumineuse n'assombrit pas son
   sol, elle l'eclaire. L'etalement tres negatif est ce qui la rend
   « contact » — une ombre de contact se mesure a ce qu'elle ne montre pas. */
#s-classement .cm-couronne{width:25px;height:18px;margin-bottom:var(--e-2);
  filter:drop-shadow(0 0 10px rgba(var(--accr),.38))}
#s-classement .cm-socle{width:90px;height:15px;margin-top:-3px;border-radius:50%;
  position:relative;z-index:1;
  background:linear-gradient(180deg, rgba(var(--lueur),.23) 0%, rgba(var(--lueur),.31) 42%,
    rgba(var(--lueur),.40) 74%, rgba(var(--lueur),.49) 100%) #000;
  box-shadow:inset 0 0 0 1px rgba(var(--lueur),.66),
             0 0 16px 0 rgba(var(--lueur),.38),
             0 0 40px -8px rgba(var(--lueur),.32)}
#s-classement .cm-p1 .cm-socle{width:101px;height:16px;margin-top:-4px;
  background:linear-gradient(180deg, rgba(var(--accr),.22) 0%, rgba(var(--accr),.29) 40%,
    rgba(var(--accr),.38) 74%, rgba(var(--accl),.48) 100%) #000;
  box-shadow:inset 0 0 0 1.5px rgba(255,232,150,.66),
             0 0 18px 0 rgba(var(--accr),.49),
             0 0 48px -8px rgba(var(--accr),.36)}
/* ⚠️ UN VOILE NE DOIT PAS SURVIVRE A LA MATIERE QU'IL ASSOMBRIT : le
   masque coupe les deux couches ensemble. Et un masque s'applique a toute
   la descendance, d'ou les pastilles de rang SORTIES de la colonne. */
#s-classement .cm-colonne{width:90px;height:39px;margin-top:-7px;
  -webkit-mask-image:linear-gradient(180deg,#000 55%,transparent 94%);
  mask-image:linear-gradient(180deg,#000 55%,transparent 94%);
  background:
    linear-gradient(90deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,.12) 20%, rgba(0,0,0,0) 50%,
      rgba(0,0,0,.12) 80%, rgba(0,0,0,.45) 100%),
    linear-gradient(180deg, rgba(var(--lueur),.55) 0%, rgba(var(--lueur),.34) 26%,
      rgba(var(--lueur),.18) 48%, rgba(var(--lueur),.08) 70%, rgba(var(--lueur),0) 92%)}
#s-classement .cm-p3 .cm-colonne{height:28px}
#s-classement .cm-p1 .cm-colonne{width:101px;height:61px;margin-top:-8px;
  background:
    linear-gradient(90deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,.12) 20%, rgba(0,0,0,0) 50%,
      rgba(0,0,0,.12) 80%, rgba(0,0,0,.45) 100%),
    linear-gradient(180deg, rgba(var(--accr),.69) 0%, rgba(var(--accr),.57) 16%,
      rgba(var(--accr),.31) 28%, rgba(var(--accr),.18) 40%,
      rgba(var(--accr),.08) 58%, rgba(var(--accr),0) 82%)}
#s-classement .cm-rg{position:relative;margin-top:-10px;z-index:1;
  display:grid;place-items:center;min-width:20px;height:20px;padding:0 var(--e-1) .6px;
  border-radius:999px;font-size:var(--t-micro);font-weight:700;
  font-variant-numeric:tabular-nums;color:#170B20;background:#BDC9F1;
  box-shadow:0 0 20px -3px rgba(var(--lueur),.46)}
#s-classement .cm-p2 .cm-rg{background:linear-gradient(180deg,#E3E8F5,#B4BFD6)}
#s-classement .cm-p3 .cm-rg{background:linear-gradient(180deg,#E0A870,#B97B45)}
#s-classement .cm-p1 .cm-rg{top:-13px;
  background:linear-gradient(180deg,#FCD34D,#F0AF1E);
  box-shadow:0 0 22px -3px rgba(var(--accr),.50)}
/* ⚠️ LES 17 px DE REMONTEE DU PREMIER SONT RELEVES, PAS CHOISIS : sa
   pastille est 17,4 px plus haut que les deux autres, et sans remontee
   l'ecart entre son rang et son prenom vaudrait dix-sept pixels de plus
   que chez les autres. Un ecart entre deux objets qui se TOUCHENT se voit
   plus qu'un desalignement entre deux objets separes de cent pixels. */
#s-classement .cm-pl>b{display:block;max-width:100%;margin-top:var(--e-2);
  font-size:var(--t-2);font-weight:600;letter-spacing:-.015em;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#s-classement .cm-p1>b{margin-top:var(--e-3)}
#s-classement .cm-p1>b,#s-classement .cm-p1>.cm-pts{position:relative;top:-17px}
/* ⚠️ 3,75 AU-DESSUS ET 7,5 EN DESSOUS FONT LE MEME ECART OPTIQUE. Un ecart
   CSS se mesure de boite a boite, l'oeil mesure d'encre a encre : sous le
   nom il reste 5,25 px de vide reserves a un jambage qu'aucun prenom n'a,
   au-dessus du score le haut de capitale est a 1,5. On egalise l'encre,
   pas les boites. Ces deux valeurs sont FAUSSES des qu'un interligne
   change : elles se recalculent, elles ne se recopient pas. */
#s-classement .cm-pts{position:relative;display:flex;align-items:baseline;
  justify-content:center;gap:2px;margin-top:var(--e-1);padding-top:var(--e-2)}
/* ⚠️ NI border NI height : les deux sont de la mise en page, arrondies a
   l'entier avant peinture, et 0,34 tombe a zero. Une boite d'un pixel
   plein ecrasee par une transformation est de la PEINTURE. 26 px de
   large, moins que le plus court des noms : une barre aussi large que ce
   qu'elle separe ferait un trait de tableau. */
#s-classement .cm-pts::before{content:'';position:absolute;top:0;left:50%;
  width:26px;height:1px;margin-left:-13px;
  transform:scaleY(.34);background:rgba(255,255,255,.19)}
#s-classement .cm-pts>b{font-size:var(--t-2);font-weight:700;color:var(--c-texte-3);
  letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
/* ⚠️ L'UNITE RESTE AU PLANCHER DE 12 px, PAS 9. Le rendu descend a 9 avec
   des compensations ; le contrat verifie le plancher sur TOUTES les regles
   du fichier, et le percer pour un cas ouvrirait la porte aux suivants.
   Ecart au rendu, assume et signale. */
#s-classement .cm-pts>small{font-size:var(--t-micro);font-weight:500;
  letter-spacing:.02em;color:var(--c-texte-3)}

/* ══ LA LIGNE QUI / QUAND ══
   ⚠️ LA PAIRE EST CENTREE COMME UN SEUL OBJET, pas le selecteur seul :
      248 + 80 = 328, les deux se chevaucheraient avant d'atteindre le
      bord. Quand deux objets ne tiennent pas chacun dans sa moitie, ils
      n'en forment plus qu'un, et c'est lui qu'on centre. */
/* ⚠️ QUATRE OBJETS CENTRES, QUATRE LARGEURS : l'ecran n'avait aucune ligne verticale
   (lot du 05/08, S3.1). Filtres 227 a 275 selon le mode, paire reglages 336, liste 357.
   TROIS LARGEURS PRESQUE EGALES SONT PIRES QUE TROIS FRANCHEMENT DIFFERENTES : l'oeil
   cherche la ligne, ne la trouve pas, et lit un defaut la ou il y avait une intention.
   La ligne qui/quand passe donc en PLEINE LARGEUR et se cale sur la liste, seul objet
   qui remplit la colonne : son bord gauche tombe sur celui de la liste, le bord droit de
   la periode sur le sien.
   ⚠️ ET LES DEUX BULLES S'ALIGNENT PAR LE BAS, PLUS PAR LE CENTRE : 46 de haut contre 28,
      centrees elles ne partageaient AUCUN bord et la ligne n'avait pas de sol. Le bas
      plutot que le haut, parce que ce qui suit est une liste, et c'est le bord bas qui
      ouvre le bloc suivant.
   ⚠️ CE QUI NE S'ALIGNERA JAMAIS : les filtres. Leur largeur suit le nom du mode actif,
      et un objet dont la largeur change ne peut aligner aucun bord — il ne partage
      qu'un axe. */
#s-classement .cm-reglages{flex:0 0 auto;width:100%;
  display:flex;align-items:flex-end;justify-content:space-between;gap:var(--e-2);margin:0 0 var(--e-3)}
#s-classement .cm-segments{flex:0 0 auto;width:max-content;max-width:100%;
  display:flex;gap:2px;padding:var(--e-1);margin:0;
  border-radius:999px;background:rgba(120,120,134,.13);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.15)}
#s-classement .cm-seg{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  gap:var(--e-2);height:38px;padding:0 var(--e-2);border-radius:999px;border:0;font:inherit;
  cursor:pointer;background:none;white-space:nowrap;
  font-size:var(--t-2);font-weight:500;letter-spacing:-.005em;color:var(--c-texte-3);
  transition:color .24s var(--ease),background .24s var(--ease),transform .14s var(--ease)}
#s-classement .cm-seg>svg{flex:0 0 auto;width:19px;height:19px;fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
#s-classement .cm-seg:active{transform:scale(.96)}
#s-classement .cm-seg.actif{color:var(--c-texte);font-weight:600;background:rgba(255,255,255,.12);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
#s-classement .cm-seg.actif>svg .p{fill:currentColor;fill-opacity:.14}
#s-classement .cm-seg>svg .p{transition:fill-opacity .22s var(--ease)}
/* ⚠️ ELLE EST DIMENSIONNEE SUR SA VALEUR LA PLUS LONGUE, JAMAIS SUR CELLE
   DU JOUR : sinon elle change de taille au premier changement, et toute
   la ligne avec. Et c'est un bouton « a peine » : un voile et un rayon,
   jamais un trait — ce qui fait une pastille dans cette app. */
#s-classement .cm-periode{position:relative;flex:0 0 auto;height:28px;padding:0 var(--e-2);border:0;
  cursor:pointer;display:flex;align-items:center;justify-content:center;gap:var(--e-1);
  border-radius:999px;background:rgba(255,255,255,.07);font:inherit;
  font-size:var(--t-micro);font-weight:400;letter-spacing:0;color:var(--c-texte-3);
  /* ⚠️ LE min-width DE 5,5rem EST RETIRE (05/08). Il existait pour que le bouton ne change
     pas de taille au changement de periode, du temps ou la ligne etait CENTREE : une
     largeur variable y decalait les deux bulles a chaque fois. Depuis que la ligne est en
     pleine largeur et que le bouton est pousse a droite, son bord droit est fixe par
     construction — seul son bord gauche respire. Le garder faisait 88 px la ou la place
     restante en vaut 74 : le bouton DEBORDAIT de la colonne, mesure a 367 quand la liste
     finit a 353, et c'est exactement le bord que la recette demande d'aligner.
     Une contrainte posee pour une mise en page cesse d'etre vraie quand la mise en page change. */
  white-space:nowrap;transition:background .16s var(--ease)}
#s-classement .cm-periode::after{content:'';position:absolute;inset:-8px -6px}
#s-classement .cm-periode:active{background:rgba(255,255,255,.14)}
#s-classement .cm-periode>svg{flex:0 0 auto;fill:none;stroke-linecap:round;stroke-linejoin:round}
#s-classement .cm-periode .cal{width:12px;height:12px;stroke:#A8A0BA;stroke-width:2}
#s-classement .cm-periode .chev{margin-left:auto;width:8px;height:8px;stroke:#7E778F;stroke-width:2.4}

/* ══ LA LISTE ══
   ⚠️ 337 = 8 + 5x61 + 4x4 + 8. La promesse est « cinq rangees », pas
      « trois cent trente-sept pixels » : toute reprise de la hauteur de
      rangee ou de l'ecart refait ce calcul.
   ⚠️ UNE BORNE EN px, JAMAIS EN dvh : dvh change pendant le defilement sur
      Safari iOS.
   ⚠️ `overflow:hidden auto`, JAMAIS `overflow-y` seul, qui force
      `overflow-x:auto` et fait apparaitre une barre horizontale.
   ⚠️ RAYONS CONCENTRIQUES : rangee 16 + rembourrage 8 = 24 pour le
      plateau. Un rayon exterieur qui n'est pas la somme laisse un
      croissant d'epaisseur variable dans chaque angle.
   TROIS NIVEAUX, DEUX CONTRASTES : le plateau creuse, les rangees montent.
   Chacun prend un levier different — le plateau est un CONTENANT, il se
   distingue par son arete ; les rangees sont du CONTENU, par leur clarte. */
#s-classement .cm-liste{flex:0 0 auto;height:337px;padding:var(--e-2);border-radius:var(--r-3);
  overflow:hidden auto;overscroll-behavior:contain;
  background:rgba(0,0,0,.34);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.132)}
/* ⚠️ RENVERSEMENT DE REGLE : le socle voulait un groupe a filets, « les
   rangs se comparent donc ils doivent se toucher ». Ecart de 4 px releve
   sur Monopoly Go (moins de 4 % de la hauteur de rangee). Quand trois
   signes disent deja la separation — rayon, voile, plateau — l'espace n'a
   plus a la dire. */
#s-classement .cm-rangee{position:relative;display:flex;align-items:center;gap:var(--e-3);
  width:100%;min-height:61px;margin-bottom:var(--e-1);padding:var(--e-2) var(--e-3) var(--e-2) var(--e-3);font:inherit;
  text-align:left;cursor:pointer;border:0;border-radius:var(--r-2);color:var(--ink);
  background:rgba(255,255,255,.06);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.29);
  transition:background .16s var(--ease)}
#s-classement .cm-rangee:last-child{margin-bottom:0}
#s-classement .cm-rangee:active{background:rgba(255,255,255,.11)}
/* ⚠️ MA RANGEE N'A PAS DE FOND A ELLE : elle en portait un EN PLUS du
   filet, deux signes pour une information, et deux signes qui ne tombent
   pas au meme endroit — le voile remplit la boite, le filet en suit le
   bord interieur, et le moindre ecart d'arrondi se lit comme une bavure.
   Une exception se dit par UN signe. Meme epaisseur que les autres : une
   exception de teinte, pas de matiere. */
#s-classement .cm-rangee.moi{box-shadow:inset 0 0 0 .34px rgba(167,139,250,.90)}
#s-classement .cm-rangee.moi .cm-pos{color:#B49CFC;font-weight:600}
/* ⚠️ SEUL LE CHIFFRE PREND LA TEINTE, PAS SON UNITE (Theo, 05/08) : « pour taper l'oeil
   sans forcer ». C'est le nombre qu'on cherche dans sa propre ligne, et un « pts » violet
   ferait deux objets colores la ou il n'y a qu'une information.
   ⚠️ ET C'EST LE MEME #B49CFC QUE LE RANG, jamais une troisieme valeur : la rangee porte
      deja cette teinte, la reprendre ne fait pas un accent de plus, elle fait un ensemble. */
#s-classement .cm-rangee.moi .cm-score b{color:#B49CFC}
#s-classement .cm-pos{flex:0 0 auto;width:22px;height:22px;display:grid;place-items:center;
  text-align:center;padding-bottom:.7px;
  font-size:var(--t-2);font-weight:500;color:var(--c-texte-3);font-variant-numeric:tabular-nums}
#s-classement .cm-pos.metal{padding-bottom:0}
/* ⚠️ LES RANGS 1, 2 ET 3 PORTENT UN GLYPHE TRACE, PAS UN APLAT : une icone
   de cette app est un fil de fer, tout ce qui est plein y est une surface,
   pas un signe. Et la premiere place n'est pas le premier degre d'une meme
   chose, c'est AUTRE CHOSE : une coupe pour elle, une medaille pour les
   deux autres. Trois glyphes identiques se seraient lus comme une
   repetition avant de se lire comme une serie. */
#s-classement .cm-pos>svg{width:21px;height:21px;fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
#s-classement .cm-pos.or{color:#F5C136}
#s-classement .cm-pos.argent{color:var(--c-texte-2)}
#s-classement .cm-pos.bronze{color:#CC9159}
#s-classement .cm-rangee .cm-av{width:34px;height:34px;font-size:var(--t-2)}
#s-classement .cm-txt{flex:1 1 auto;min-width:0}
#s-classement .cm-txt>b,#s-classement .cm-nom>b{display:block;font-size:var(--t-2);
  font-weight:600;letter-spacing:-.015em;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#s-classement .cm-txt>small{display:block;font-size:var(--t-1);margin-top:1px;color:var(--c-texte-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#s-classement .cm-nom{display:flex;align-items:center;gap:var(--e-2);min-width:0}
#s-classement .cm-score{flex:0 0 auto;display:flex;align-items:baseline;gap:2px;text-align:right}
#s-classement .cm-score>b{font-size:var(--t-3);font-weight:700;color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.025em;line-height:1.08}
#s-classement .cm-score>small{font-size:var(--t-micro);font-weight:500;
  letter-spacing:.02em;color:var(--c-texte-3)}
#s-classement .cm-toi{flex:0 0 auto;height:20px;padding:0 var(--e-2);border-radius:999px;
  display:grid;place-items:center;
  font-size:var(--t-micro);font-weight:600;letter-spacing:.01em;color:#C4A6FF;
  box-shadow:inset 0 0 0 .34px rgba(167,139,250,.62)}
/* les teintes des gens, dans la liste : le podium a ses metaux, la liste a
   ses visages bleus. */
#s-classement .cm-av{position:relative;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-weight:700}

/* --accl : le ton CLAIR de l'accent, pour le bas du socle du premier. Sans lui, la
   derniere bande du degrade tombe a du transparent et le socle perd son assise. */
#s-classement{--acc:#FCD34D;--accr:252,176,28;--accl:255,232,150}
#s-classement.cm-soiree{--acc:#A78BFA;--accr:139,92,246}
#s-classement.cm-classiques{--acc:#F9A8D4;--accr:236,72,153}
#s-classement.cm-quiz{--acc:#8FB4FF;--accr:76,125,240}
#s-classement .cm-av1{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av2{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av3{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av4{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av5{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av6{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av7{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av8{--lueur:221,213,199;background-color:#DDD5C7;color:#170B20}
#s-classement .cm-av.estmoi{background-color:#8B5CF6;--lueur:139,92,246;color:var(--c-texte)}

#s-classement .cm-vide{padding:var(--e-5) var(--e-2);text-align:center;color:var(--dim);
  font-size:var(--t-2);line-height:1.45}
#s-classement .cm-vide b{display:block;color:var(--ink);font-size:var(--t-3);
  font-weight:700;margin-bottom:var(--e-2)}
#s-classement :focus-visible{outline:2px solid #A78BFA;outline-offset:3px;border-radius:var(--r-2)}

/* ⚠️ [04/08, Theo] LA FLECHE DE RETOUR DISPARAIT A LA RACINE D'UN ONGLET. On entre
   sur ces ecrans par la BARRE, pas par une navigation : il n'y a rien derriere, et
   une fleche qui ne promet rien est pire qu'une absence de fleche. C'est aussi la
   regle du socle pour les ecrans d'app (« GRAND TITRE A GAUCHE, pas de retour »).
   ⚠️ ELLE REVIENT DANS LES VUES INTERNES, et ce n'est pas une exception : dans un fil
      de discussion ou dans « Créer un compte », elle ramene a la racine de l'onglet.
      Sans elle on serait enferme dans la vue.
   ⚠️ visibility ET NON display : la barre de titre est une rangee a trois colonnes ou
      le titre est CENTRE sur l'ecran. Retirer le bouton du flux decalerait le titre de
      21 px a chaque changement de vue. */
#s-multi.racine > .topbar > #mu-back,
#s-compte.racine > .topbar > #cp-back{visibility:hidden}

/* le bareme dans la feuille d'explication : trois rangees, l'intitule a gauche et la
   valeur a droite. Un tableau se lit mieux qu'une phrase quand il y a des chiffres a
   comparer, et ces trois-la se comparent. */
#m-cm-info .cm-bareme{margin-top:var(--e-3);border-radius:var(--r-2);overflow:hidden;
  background:rgba(255,255,255,.04);box-shadow:inset 0 0 0 .34px rgba(255,255,255,.103)}
#m-cm-info .cm-bareme>div{display:flex;align-items:baseline;gap:var(--e-3);
  padding:var(--e-2) var(--e-3);text-align:left}
#m-cm-info .cm-bareme>div+div{box-shadow:inset 0 .34px 0 rgba(255,255,255,.081)}
#m-cm-info .cm-bareme span{flex:0 0 auto;min-width:88px;font-size:var(--t-1);color:var(--dim)}
#m-cm-info .cm-bareme b{flex:1 1 auto;font-size:var(--t-2);font-weight:600;color:var(--ink)}

/* [04/08] L'ecran des statistiques est devenu la racine de l'onglet Profil : sa fleche se
   retire la, et seulement la. Ouvert depuis le profil d'un ami ou depuis la liste, il
   garde sa fleche, qui ramene. Meme mecanique que les deux autres onglets, meme raison :
   une fleche qui ne promet rien est pire qu'une absence de fleche. */
#s-profil.racine > .topbar > #prof-back{visibility:hidden}

/* ══════════════════════════════════════════════════════════════════════
   [05/08, defaut signale par Theo sur capture] LA RESERVE DE LA BARRE
   APPARTIENT A CE QUI DEFILE, PAS A L'ECRAN.

   Deux modeles de defilement coexistent dans l'app, et la meme regle ne
   pouvait pas servir les deux :
     · l'accueil, le Classement et Amis font defiler L'ECRAN lui-meme. La
       reserve posee sur lui est juste : le contenu glisse SOUS la capsule
       pendant le defilement, et le dernier element remonte au-dessus a la
       fin.
     · Statistiques, Mon compte et Discussions font defiler une boite
       INTERNE (.prof-scroll, .jr-body). La meme reserve RACCOURCIT cette
       boite au lieu de rembourrer son contenu : le contenu s'arrete net,
       et rien ne passe jamais sous la barre.

   ⚠️ MESURE AVANT CORRECTION (iPhone 390x844, ecran Statistiques) : la
      boite qui defile finissait a 758 px, la barre commencait a 778 —
      86 px de noir sous le contenu, et la derniere tuile coupee. C'est
      exactement ce que la capture du 05/08 montre.

   On rend donc sa hauteur a la boite, et on met la reserve DEDANS.
   ══════════════════════════════════════════════════════════════════════ */
#s-profil.avec-barre,
#s-compte.avec-barre,
#s-multi.avec-barre:not(.au-fil){padding-bottom:0}
/* 74 px de barre, son ecart au bord, et 10 px d'air : au bout du defilement
   le dernier element se pose au-dessus de la capsule au lieu de la toucher. */
#s-profil.avec-barre>.prof-scroll,
#s-compte.avec-barre>.prof-scroll,
#s-multi.avec-barre:not(.au-fil)>.jr-body{
  padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 84px)}

/* ⚠️⚠️ [05/08] L'ACCUEIL N'A JAMAIS EU SA RESERVE, ET C'EST UN PIEGE DE
   SPECIFICITE. `.screen.avec-barre` pese (0,2,0) ; la regle de rembourrage
   de l'accueil, posee le 02/08, cible `#s-home` et pese (1,0,0) : l'ID gagne
   toujours, quel que soit l'ordre dans le fichier. La barre recouvrait donc
   le bas de l'accueil sans qu'aucune place lui soit reservee — invisible
   tant que la pile tient dans l'ecran grace a ses ressorts, mais en Grand
   texte ou sur un petit telephone, la derniere carte passait sous la
   capsule sans pouvoir en ressortir.
   ⚠️ CE QUE CA APPREND, ET QUI VAUT POUR TOUTE LA FEUILLE : une regle
      transversale posee sur une CLASSE ne peut rien contre une regle
      d'ECRAN posee sur un ID. Une reserve commune doit donc etre reprise
      ecran par ecran, ou verifiee au CSSOM — ecrite, elle n'est pas
      appliquee. Controle BARRE-05b pose dans verif.js. */
#s-home.avec-barre{padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 74px)}

/* ══════════════════════════════════════════════════════════════════════
   [05/08] LA BARRE D'ONGLETS SUIT LE DEFILEMENT — COMPOSANT GLOBAL
   Porte du lot PORTAGE-CLASSEMENT §3. Releve sur Instagram : capsule
   isolee au seuil de luminance 130 sur 769 images a 60 im/s.

        etat          largeur    hauteur
        deployee ···  350 pt     58,7 pt
        retrecie ···  294 pt     49,5 pt

   ⚠️ CE N'EST PAS UNE ANIMATION DE GEOMETRIE, C'EST UNE HOMOTHETIE. Les
      deux rapports sont identiques (294/350 = 0,840 et 49,5/58,7 = 0,843)
      et LE CENTRE NE BOUGE PAS. C'est ce qui la rend douce : une
      homothetie ne redistribue rien, elle ne coute aucune mise en page.
      Animer left, right et height donnerait le meme dessin et un geste
      qui accroche.
   ⚠️ 320 ms, DEPART LENT. Progression relevee : 0,10 au quart, 0,54 a la
      moitie, 0,89 aux trois quarts. Sans le depart lent, la barre SAUTE
      au premier pixel de defilement et on la voit reagir au lieu de la
      voir suivre.
   ⚠️ RISQUE CONNU ET NON TRANCHE : un `transform` sur l'element est l'une
      des quatre causes qui tuent un `backdrop-filter` sur WebKit. Test a
      faire sur l'appareil (voir le journal). Si le flou tombe en
      retreci, le repli est d'animer left/right/height/padding : meme
      dessin, geste moins doux. Cotes equivalentes a scale(.84) :
      left/right 24 -> 51,5 px, height 54 -> 45,4, padding 6 -> 5.
   ══════════════════════════════════════════════════════════════════════ */
.barre{transform-origin:50% 50%;
  transition:transform .32s cubic-bezier(.5,0,.35,1)}
.barre.reduite{transform:scale(.84)}
/* ⚠️ INERTE, PAS INVISIBLE. La barre flotte au-dessus du contenu : pendant
   un glissement dans une carte, le doigt finit souvent sa course sur elle
   et un onglet se declenche alors qu'on voulait faire defiler. Un objet
   fixe pose sur une zone de defilement doit rendre le toucher tant que
   cette zone bouge. La masquer ferait disparaitre un repere a chaque
   geste : elle reste visible. */
.barre.inerte{pointer-events:none}
/* mouvement reduit : la barre ne bouge plus du tout. Le rendu ne le
   prevoyait pas ; une reduction de mouvement qui laisse passer la seule
   animation permanente de l'app n'en est pas une. */
@media (prefers-reduced-motion:reduce){
  .barre{transition:none}
  .barre.reduite{transform:none}
}

/* ══════════════════════════════════════════════════════════════════════
   [05/08] L'EN-TETE DU CLASSEMENT — titre centre et menu de vue
   Porte du lot PORTAGE-CLASSEMENT §4, variante B (celle qui pousse).

   ⚠️ 21 px, PAS 32, ET CENTRE. Releve du dossier sur une capture de
      Reglages iOS : hauteur de capitale 46 px a l'echelle 3,069, soit
      15,0 pt, donc un corps d'environ 21 pour un rapport de capitale de
      0,71. 1.3125rem = ces 21 px, en rem pour que Grand texte les
      agrandisse.
   ⚠️ RENVERSEMENT DE REGLE, A CONSIGNER. Le socle pose deux familles :
      ecran de reglages = titre 18/600 centre ; ecran d'app = grand titre
      A GAUCHE, « la porte decide de la famille », regle trouvee apres
      trois versions ratees de l'ecran Amis. Le Classement passe centre.
      CONSEQUENCE NON RESOLUE : Amis, qui est le meme genre d'ecran, garde
      son grand titre a gauche. Deux onglets voisins, deux grammaires. Si
      celui-ci est le bon, il faut y passer Amis aussi.
   ⚠️ 32 px SOUS LA BARRE : il n'y a ici ni filet ni verre, donc l'espace
      fait la totalite du travail de separation. Le socle n'a que quatre
      valeurs, 8 / 16 / 24 / 32.
   ══════════════════════════════════════════════════════════════════════ */
#s-classement .cm-titre{position:relative;flex:0 0 auto;
  display:flex;align-items:flex-start;justify-content:center;
  min-height:44px;margin:2px 0 var(--e-5)}
#s-classement .cm-titre h1{flex:0 0 auto;max-width:100%;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;
  line-height:1.2;color:var(--c-texte)}
/* le titre EST le bouton : c'est lui l'ancre, et une ancre ne s'anime jamais */
/* ══════════════════════════════════════════════════════════════════════════════════════
   LES DEUX VUES SONT EXPOSEES (lot du 05/08, §2) — le menu du titre est supprime

   ⚠️ UN MENU QUI NE CONTIENT QUE DEUX ENTREES N'A PAS BESOIN D'ETRE UN MENU. Les deux mots
      tiennent largement dans la barre (108 + 22 + 117 = 247 sur 357) : les cacher derriere
      une touche n'ajoutait qu'un geste, un voile, un etat a dessiner et une arithmetique de
      cibles. CE QUI TIENT A L'ECRAN SE MONTRE.
   ⚠️ ET LE CHEVRON DANS SA PASTILLE PART AVEC LE MENU : il promettait un depliant, le
      depliant est maintenant ouvert en permanence. ON NE GARDE PAS LE BOUTON D'UNE PORTE
      QU'ON A ENLEVEE.
   ⚠️ L'ENCRE DEPARTAGE, PAS LE CORPS : blanc pour la vue courante, gris du socle pour
      l'autre, meme taille et meme graisse — deux vues de MEME RANG s'ecrivent de la meme
      facon. C'est la regle du menu de periode, appliquee ici.
   ⚠️ CHAQUE VUE PORTE UN CHEVRON, MAIS PAS LE MEME, et la difference est une DIRECTION :
      « Classement » prend le ⌄ parce que son contenu est juste dessous ; « Statistiques »
      prend le › parce qu'elle mene ailleurs. Ils s'echangent a la bascule, en meme temps
      que l'encre : le signe suit la FONCTION, jamais le mot. Un signe de direction doit
      designer quelque chose de reel dans la page, sinon c'est un ornement.
   ⚠️ ALIGNEMENT PAR LA LIGNE DE BASE, pas par le centre : c'est un signe pose DANS du
      texte, pas un objet pose a cote.
   ⚠️ ET LES DEUX CIBLES NE SE TOUCHENT PAS : 8 px de part et d'autre pris sur un ecart de
      22, il reste 6 px de jeu ; 9,4 en hauteur pour atteindre les 44 du socle. */
#s-classement .cm-vues{display:flex;align-items:baseline;gap:var(--e-4)}
#s-classement .cm-vue{position:relative;display:flex;align-items:baseline;gap:var(--e-2);
  border:0;padding:0;background:none;cursor:pointer;
  font:inherit;letter-spacing:inherit;color:var(--c-texte-3);   /* la valeur du dossier, deja employee sur cet ecran */
  transition:color .16s var(--ease)}
#s-classement .cm-vue::after{content:'';position:absolute;inset:-9.4px -8px}
/* ⚠️ [07/08] `--text` N'EXISTE PAS DANS CE SOCLE, ET LA DECLARATION ETAIT MORTE. Le jeton
   du texte s'appelle `--ink` ; `--text` est le nom qu'il porte dans les dossiers de design.
   Une variable absente rend la declaration invalide EN SILENCE : la couleur retombait sur
   l'heritage, et l'appui ne changeait rien. Les trois occurrences de cet ecran etaient les
   seules du fichier ; la regle jumelle d'Amis (`.am-vue:active`) porte bien `var(--ink)`,
   ce qui dit l'intention. Trouve par le controle CSS-VAR, pose le meme jour. */
#s-classement .cm-vue:active{color:var(--ink)}
#s-classement .cm-vue.actif{color:var(--c-texte)}
/* le chevron prend l'encre de son mot et bascule avec lui : un signe qui appartient a un
   mot n'a pas de couleur propre. */
#s-classement .cm-vue svg{flex:0 0 auto;width:10px;height:10px;fill:none;stroke:currentColor;
  stroke-width:2.3;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ LE BOUTON D'INFO SORT DU FLUX, ET C'EST CE QUI GARDE LE TITRE CENTRE
   SUR L'ECRAN plutot que sur la place qui reste. Le rendu ne le montre
   pas ; on le garde parce que c'est une piece de CONFORMITE : un
   classement dans une app a boire doit pouvoir dire d'ou viennent ses
   chiffres. Ecart signale au design. */
/* ⚠️ SES REGLES DE FORME AVAIENT DISPARU avec l'ancien bloc, et il ne restait que sa
   position : le bouton rendait un trait blanc. Un remplacement de bloc emporte ce qu'on
   n'a pas relu. 32 px vus, 44 touches par l'::after. */
/* ⚠️ LE « i » PERD SON JETON, IL NE GARDE QUE SON GLYPHE (Theo, 06/08). Sa pastille grise
   en faisait le troisieme objet de la barre, a cote de deux mots qui, eux, n'ont aucune
   matiere : c'est le plus accessoire des trois qui pesait le plus lourd. Un signe pose dans
   une barre de titre n'a pas besoin d'un contenant pour exister.
   ⚠️ SA CIBLE NE BOUGE PAS D'UN PIXEL : elle vit dans le ::after, jamais dans le fond. Un
      objet peut perdre sa matiere sans perdre sa surface touchable, et c'est exactement ce
      qui separe « plus discret » de « plus difficile a viser ». */
#s-classement .cm-info{position:relative;flex:0 0 auto;margin:0 2px 0 auto;
  width:28px;height:28px;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;color:var(--ink);
  transition:opacity .2s var(--ease),transform .14s var(--ease)}
#s-classement .cm-info::after{content:'';position:absolute;inset:-6px}
#s-classement .cm-info:active{transform:scale(.92);opacity:.55}
#s-classement .cm-info>svg{width:16px;height:16px;fill:none;stroke:#B9B1CB;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

/* ══════════════════════════════════════════════════════════════════════════════════════
   LE MENU DE PERIODE SE DEPLIE (lot du 05/08, §5) — remplace la feuille du produit

   ⚠️ LA VALEUR EN COURS EST LA PREMIERE LIGNE DU MENU, seules les TROIS AUTRES se
      deplient. Ecrire les quatre sous le bouton faisait lire « Global » deux fois a dix
      pixels d'ecart.
   ⚠️ CE QUI FAIT UN MENU DEPLIANT, C'EST UNE SEULE SURFACE. Deux essais ecartes chez le
      design : garder la gelule sur l'ancre seule (elle disait « c'est celle-la » et la
      SORTAIT du groupe : une surface contre trois mots nus fait un bouton et trois textes
      qui flottent) ; la supprimer (quatre mots alignes, et rien pour les tenir). La gelule
      s'etire donc de l'ancre jusqu'a la derniere option, AVEC LE MEME RAYON qu'elle avait
      fermee : on ne voit pas un panneau apparaitre sous un bouton, on voit LE BOUTON
      S'ALLONGER.
   ⚠️ ET CA TRANCHE LA QUESTION DES DEUX MENUS DE CET ECRAN : celui du titre n'a pas de
      cadre parce que son ancre est un TITRE, et un titre n'entre pas dans une boite ;
      celui-ci en a un parce que son ancre est une GELULE, et une gelule qui se deplie
      reste une gelule. Deux dessins, une regle : le menu prend la matiere de son ancre.
   ⚠️ LE PANNEAU EST PEINT PAR UN ::before, jamais par un element du flux : sinon la ligne
      des reglages ferait 160 de haut et TOUT L'ECRAN DESCENDRAIT a l'ouverture d'un menu.
      Un menu se pose sur la page, il ne la repousse pas. Les options, elles, sortent du
      flux par `position:absolute`, pour la meme raison.
   ⚠️ IL PORTE UNE OMBRE, contrairement au menu du titre : celui-la n'a pas de surface,
      donc rien a faire flotter.
   ══════════════════════════════════════════════════════════════════════════════════════ */
/* ⚠️ REGRESSION QUE J'AI INTRODUITE MOI-MEME LE 06/08, ET QUI EST LA LECON DU 05/08 REJOUEE :
   « un remplacement de bloc emporte ce qu'on n'a pas relu ». En retirant le bloc du menu de
   VUE (devenu inutile puisque les deux vues sont exposees), j'ai emporte `.cm-voile` — que le
   menu de PERIODE utilise aussi. Depuis, son voile etait pose dans le DOM et n'assombrissait
   RIEN : la classe existait, la regle non. Trouve par un agent en portant Amis, pas par moi.
   ⚠️ ET C'EST LE CONTROLE ⑬ DU DOSSIER EN ACTION (toute classe posee a une regle) : c'est le
      seul qui attrape ce cas, parce qu'un contrat qui ne verifie que le CODE ECRIT ne voit
      jamais ce qui a disparu a cote. */
#s-classement .cm-voile{position:fixed;inset:0;z-index:25;background:rgba(0,0,0,.56);
  -webkit-backdrop-filter:blur(8px) saturate(.92);
  backdrop-filter:blur(8px) saturate(.92);
  animation:uiVoile var(--m-court) var(--m-sortie) backwards}

@media (prefers-reduced-motion:reduce){ #s-classement .cm-voile{animation:none} }
#s-classement .cm-deroulant{position:relative}
#s-classement.per-ouverte .cm-deroulant{z-index:30}
#s-classement.per-ouverte .cm-deroulant::before{content:'';position:absolute;left:0;right:0;
  top:-6px;height:160px;border-radius:var(--r-2);
  background:rgba(255,255,255,.09);
  box-shadow:0 18px 40px -14px rgba(0,0,0,.72),
             0 4px 10px -6px rgba(0,0,0,.5);
  animation:cm-panneau var(--m-court) var(--m-sortie) backwards}
@keyframes cm-panneau{from{opacity:0;height:40px}to{opacity:1;height:160px}}
#s-classement.per-ouverte .cm-periode{background:none;color:var(--c-texte);font-weight:600}
#s-classement.per-ouverte .cm-periode .cal{stroke:#FFFFFF}
#s-classement.per-ouverte .cm-periode .chev{transform:rotate(180deg)}
#s-classement .cm-periode .chev{transition:transform .26s cubic-bezier(.18,.9,.24,1)}
/* ⚠️ RYTHME STRICTEMENT EGAL : centres des quatre lignes a 20 · 60 · 100 · 140 du haut du
   panneau, quarante pixels partout. Six pixels entre la gelule et la premiere option, six
   de rembourrage en haut, pour que le centre de l'ancre tombe a 20 comme celui de la
   derniere option tombe a 20 du bas. Un bloc se reconnait a ce que ses extremites
   respirent pareil. Hauteur : 6 + 28 + 6 + 3 × 40 = 160. */
#s-classement .cm-choix{position:absolute;top:calc(100% + 6px);left:0;right:0;
  display:flex;flex-direction:column;align-items:stretch;
  animation:cm-choix-entre var(--m-court) var(--m-sortie) backwards;
  animation-delay:40ms}
@keyframes cm-choix-entre{from{opacity:0;transform:translateY(-10px)}
  to{opacity:1;transform:none}}
/* ⚠️ LE FILET SE PLACE ENTRE DEUX CENTRES, pas contre un bord : centre de l'ancre a 20,
   de la premiere option a 60, donc le milieu est a 40 — exactement le haut de .cm-choix.
   Sinon il appartient a l'un des deux au lieu de les departager.
   ⚠️ EN RETRAIT DE 7, LES DEUX COLONNES DU BLOC : un filet qui touche les deux bords COUPE
      l'objet en deux, un filet en retrait l'ARTICULE — et il n'invente pas ses bornes, il
      les emprunte a ce qu'il separe.
   ⚠️ NI BORDURE NI HAUTEUR : les deux sont de la mise en page, arrondies a l'entier, et
      0,34 tomberait a zero. Troisieme occurrence du piege dans ce lot. */
#s-classement .cm-choix::before{content:'';position:absolute;top:0;left:7px;right:7px;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.10)}
/* ⚠️ BANDES A 40 ET NON 44, ARBITRAGE ASSUME DU DESIGN : a 12 px de texte, une bande de 44
   est remplie a 27 % quand iOS travaille a 39 %, et un menu dont chaque ligne baigne dans
   du vide se lit comme des mots disperses. CE QUE CA COUTE : trois cibles a 40, qu'on ne
   peut PAS rattraper par un ::after — une rangee du milieu n'a de vide ni au-dessus ni
   au-dessous, et deux cibles qui debordent l'une sur l'autre se volent des touches.
   ⚠️ ON N'ALIGNE PAS LES MOTS, ON ALIGNE LES TETES DE LIGNE : les quatre commencent au
      meme pixel, a 7 du bord — le calendrier pour l'ancre, le mot pour les trois autres.
      Indenter les options de 22 px pour faire partir leur texte ou part « Global » ne
      laissait que 48 px a « Semaine ». */
#s-classement .cm-ch{display:flex;align-items:center;gap:var(--e-1);
  height:40px;padding:0 var(--e-2);border:0;background:none;cursor:pointer;
  font-size:var(--t-1);font-weight:400;letter-spacing:0;color:var(--c-texte-3);   /* la valeur du dossier, deja employee sur cet ecran */
  white-space:nowrap;transition:color .16s var(--ease)}
#s-classement .cm-ch:active{color:var(--ink)}   /* voir CSS-VAR : `--text` n'existe pas ici */
#s-classement .cm-ch svg{flex:0 0 auto;margin-left:auto;width:8px;height:8px;fill:none;
  stroke:#7E778F;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
#s-classement .cm-ch:active svg{stroke:var(--ink)}   /* voir CSS-VAR */
@media (prefers-reduced-motion:reduce){
  #s-classement.per-ouverte .cm-deroulant::before,
  #s-classement .cm-choix{animation:none}
  #s-classement .cm-periode .chev{transition:none}
}

/* ══════════════════════════════════════════════════════════════════════
   [06/08] LE LOT COMPTE — SOCLE COMMUN (§0 du dossier PORTAGE-COMPTE)
   ⚠️ TOUT EST PREFIXE `c-` ET SCOPE SOUS #s-compte, ET CE N'EST PAS UN
      CAPRICE : les noms du dossier (.ligne, .titre, .groupe, .voile,
      .menu, .stat, .badge, .marque, .carte, .act, .val, .chev, .moi,
      .in, .ch, .nom) EXISTENT DEJA dans cette feuille, et trois d'entre
      eux (.badge, .stat, .marque) sont GLOBAUX : les reprendre tels
      quels ferait porter leurs proprietes a nos elements sans qu'aucune
      regle du lot ne le montre. Quatre collisions de nom avaient deja
      ete payees le 03/08. On prefixe, toujours.
   ⚠️ LE DOSSIER EST UN RENDU AUTONOME, PAS NOTRE APP : ses `.app`
      (440 px, marges 18) et son `body` ne sont PAS portes — l'app a sa
      colonne (560) et ses marges (22), et un ecran a onglets porte deja
      sa reserve de barre. Seuls les BLOCS de composant sont portes.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠️ §0.1 : --card-2 passe de #231F2E a #232329. L'ancienne valeur portait
   ONZE points de bleu de plus que de rouge : sur des surfaces qui couvrent
   presque tout l'ecran, ca se lit comme une teinte, pas comme un gris. La
   nouvelle en porte six — on corrige un exces, on ne va pas au gris neutre
   (le socle batit tout sur un violet, une surface neutre y ferait une tache
   morte). Applique PARTOUT (decision de Theo 06/08) : deux valeurs pour le
   meme jeton recreeraient le defaut que le lot corrige. */
:root{ --card-2:#232329 }

/* §0.2 — l'animation d'entree.
   ⚠️ `backwards`, JAMAIS `both`. Avec `both` l'animation garde a vie l'etat
   de sa derniere image, et une valeur d'animation l'emporte sur toute
   declaration normale quelle que soit sa specificite : uiEcran finit sur
   `transform:none` et rend toute transformation ulterieure impossible.
   Rien dans l'inspecteur ne le montre — la regle n'est pas barree, elle est
   dominee. (Piege deja paye le 05/08 sur la barre du Classement.) */
#s-compte .c-in{animation:uiEcran var(--m-long) var(--m-sortie) backwards;
  animation-delay:var(--d,0ms)}

@media (prefers-reduced-motion:reduce){#s-compte .c-in{animation:none}}

/* ══ §0.4 · LA BARRE DE NAVIGATION — identique dans les 8 ecrans de liste ══
   ⚠️ LE TITRE EST A 21/600, PAS 18. Le 18 venait du §7.1 du dossier, qui
      posait deux directions : ecrans de REGLAGES titre 18 centre, ecrans
      d'APP grand titre a gauche. Cette regle est amendee — Classement, Amis
      et Profil portent tous une barre a titre 21/600 centre. Laisser 18 ici
      ferait de ces ecrans les seuls d'une TROISIEME famille.
   ⚠️ 44 DE HAUT : la cote d'une barre d'iOS ET le plancher de cible du
      socle. Une barre dont la hauteur EST la cible n'a besoin d'aucun
      ::after.
   ⚠️ 32 EN DESSOUS : il n'y a ni filet ni verre pour marquer sa fin, donc
      l'espace fait tout le travail. Un ecart se recalcule quand ce qu'il
      separe change de taille. */
#s-compte .c-entete{display:grid;grid-template-columns:36px minmax(0,1fr) 36px;
  align-items:center;flex:0 0 auto;min-height:44px;margin-bottom:var(--e-5)}
#s-compte .c-titre{grid-column:2;justify-self:center;font-size:var(--t-4);
  font-weight:600;letter-spacing:-.015em;line-height:1.2;color:var(--c-texte)}
/* ⚠️ LE BOUTON DE RETOUR PREND LE VOILE, jamais une couleur opaque a lui :
   ce qui fait une pastille dans cette app, c'est un voile et un rayon.
   Rayon 12 sur 36 = 0,33, la proportion des carres arrondis. Cible 44 par
   un ::after de -4. L'appui gagne son voile EN PLUS de son echelle : le
   scale dit « ca bouge », le voile dit « ca s'allume ». */
#s-compte .c-retour{grid-column:1;position:relative;width:36px;height:36px;
  border-radius:var(--r-1);background:rgba(255,255,255,.07);border:0;
  display:grid;place-items:center;cursor:pointer;color:var(--c-texte-2);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-retour::after{content:'';position:absolute;inset:-4px}
#s-compte .c-retour:active{transform:scale(.94);background:rgba(255,255,255,.14)}
#s-compte .c-retour svg{width:12px;height:12px;stroke:#C6BFD6;fill:none;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

/* ══ §0.5 · LES GROUPES ET LES RANGEES ══ */
#s-compte .c-lab{flex:0 0 auto;font-size:var(--t-1);font-weight:700;
  letter-spacing:.10em;text-transform:uppercase;color:var(--c-texte-3);
  margin:var(--e-4) 0 var(--e-2);padding-left:var(--e-1)}
/* ⚠️ LE PREMIER INTITULE PERD SON ECART DU HAUT : la barre en pose deja 32,
   et 22 de plus en feraient 54. Deux ecarts qui se suivent ne s'additionnent
   pas, le plus grand suffit. */
#s-compte .c-entete + .c-lab{margin-top:0}

#s-compte .c-groupe{flex:0 0 auto;border-radius:var(--r-3);overflow:hidden;
  background:var(--card-2);box-shadow:inset 0 1px 0 rgba(255,255,255,.07)}

#s-compte .c-ligne{position:relative;display:flex;align-items:center;gap:var(--e-3);
  width:100%;min-height:58px;padding:var(--e-2) var(--e-2) var(--e-2) var(--e-3);
  text-align:left;cursor:pointer;background:none;border:0;color:inherit;
  font:inherit;transition:background .16s var(--ease)}
/* ⚠️⚠️ LE FILET EST UN PIXEL PHYSIQUE, PAS UN PIXEL CSS. `height:1px` vaut
   TROIS pixels sur un ecran a 3x. La hauteur etant une propriete de MISE EN
   PAGE, on ne peut pas l'ecrire en `.34` : elle serait arrondie a zero. On
   garde la boite d'un pixel plein et on l'ECRASE par une transformation,
   qui est de la peinture. L'opacite triple pour compenser (.06 -> .17) :
   un trait plus fin rend moins d'encre.
   ⚠️ RETRAIT DE 60 A GAUCHE : il commence au texte, apres la tuile. Un filet
      n'invente pas ses bornes, il les emprunte a ce qu'il separe. */
#s-compte .c-ligne+.c-ligne::before{content:"";position:absolute;left:60px;
  right:0;top:0;height:1px;transform:scaleY(.34);
  background:rgba(255,255,255,.17)}
#s-compte .c-ligne:active{background:rgba(255,255,255,.04)}
/* ⚠️ [08/08, Theo] UNE RANGEE QUI NE MENE NULLE PART NE REAGIT PAS AU DOIGT. Elle garde le
   gabarit de ses voisines — meme hauteur, meme tuile, meme filet, sinon le groupe se
   deforme — mais elle perd les trois signes de ce qu'on touche : le curseur, le creux a
   l'appui, et le chevron (retire du balisage, puisqu'un chevron est une promesse de
   destination). C'est la difference entre « je ne fais rien » et « je suis desactive » : une
   rangee grisee dirait qu'elle pourrait servir un jour. */
#s-compte .c-ligne.c-fixe{cursor:default}
#s-compte .c-ligne.c-fixe:active{background:none}

#s-compte .c-tu{width:30px;height:30px;border-radius:var(--r-1);flex:0 0 auto;
  display:grid;place-items:center;box-shadow:inset 0 1px 0 rgba(255,255,255,.18)}
#s-compte .c-gl{width:17px;height:17px;fill:none;stroke:#FFFFFF;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
#s-compte .c-ligne .c-txt{flex:1 1 auto;min-width:0}
#s-compte .c-ligne .c-txt b{display:block;font-size:var(--t-3);font-weight:400;
  color:var(--ink)}
#s-compte .c-ligne .c-txt small{display:block;font-size:var(--t-1);margin-top:2px;
  line-height:1.3;color:var(--c-texte-3)}
#s-compte .c-val{flex:0 0 auto;font-size:var(--t-3);font-weight:400;color:var(--c-texte-3);
  max-width:52%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-compte .c-chev{width:8px;height:13px;flex:0 0 auto;fill:none;
  stroke:#6E6883;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ══ §0.6 · LES SIX TEINTES DE TUILE — VOCABULAIRE FERME ══
   Aucune teinte n'est inventee dans tout le lot : les ecrans neufs puisent
   dans ces six-la.
   ⚠️⚠️ LE ROUGE EST RESERVE A L'IRREVERSIBLE, DANS UNE RANGEE. « Se
      deconnecter » portait une tuile rouge a cote de « Supprimer mon
      compte » : deux rouges pour deux actions qui n'ont rien de commun,
      alors que la rangee dit elle-meme qu'on se reconnecte a tout moment.
      Une couleur qui contredit le texte qu'elle accompagne se croit avant
      lui. Passee a l'ardoise.
   La teinte d'une RANGEE classe l'action ; la teinte d'un BOUTON D'ALERTE
   designe l'engagement : les deux ne disent pas la meme chose. */
#s-compte .c-tu.violet{background:linear-gradient(180deg,#9A70F8 0%,#8B5CF6 100%)}
#s-compte .c-tu.bleu{background:linear-gradient(180deg,#5C8BF5 0%,#4C7DF0 100%)}
#s-compte .c-tu.indigo{background:linear-gradient(180deg,#4C5DE6 0%,#3D4FDD 100%)}
#s-compte .c-tu.violet-bleu{background:linear-gradient(180deg,#5A55E2 0%,#4B45D9 100%)}
#s-compte .c-tu.ardoise{background:linear-gradient(180deg,#6A7386 0%,#5B6478 100%)}
#s-compte .c-tu.rouge{background:linear-gradient(180deg,#EC5B5F 0%,#E5484D 100%)}

/* ══ §0.7 · LE POINT DE PRESENCE ET LA BASCULE — 07/08 ══
   Deux objets que la famille n'avait pas, poses par l'ecran Informations.

   ⚠️ LE POINT REMPLACE LA TUILE, IL NE S'Y AJOUTE PAS. Une tuile porte un
      SYMBOLE de la chose ; ici la chose EST un symbole. Le meme disque vert
      dit deja « en ligne » sur les pastilles d'avatar, dans la liste des
      fils et dans l'en-tete d'une discussion : l'enfermer dans un carre
      violet en ferait la representation d'un signal au lieu du signal.
   ⚠️ SA BOITE FAIT 30, LA COTE D'UNE TUILE, PAS 14 CELLE DU DISQUE. C'est
      la boite qui pousse le texte : a 28 elle aurait decale « Statut en
      ligne » de 2 px a gauche des cinq autres titres. On ne voit pas le
      point, on voit la COLONNE.
   ⚠️ ET LE VERT EST CELUI DES PASTILLES, AU CARACTERE PRES (#22C55E, deja
      employe par .fr-etat.on). Un vert voisin aurait suffi a casser la
      reconnaissance. Eteint, il passe a l'encre morte : un point vert
      au-dessus d'un interrupteur ferme mentirait. */
#s-compte .c-point{width:30px;height:30px;flex:0 0 auto;display:grid;
  place-items:center}
#s-compte .c-point::before{content:"";width:14px;height:14px;border-radius:50%;
  background:#22C55E;transition:background .22s var(--ease)}
#s-compte .c-point.off::before{background:#5B5470}

/* ⚠️ 51 x 31 EST LA MESURE DU SYSTEME, PAS UN CHOIX. Un interrupteur d'iOS
      fait cette taille depuis toujours ; s'en ecarter fait hesiter avant
      meme de le toucher. La cible passe a 44 par un ::after, comme le
      bouton de retour.
   ⚠️ LE VERT EST LEGITIME ICI ET NULLE PART AILLEURS. Le socle reserve le
      vert au compte connecte, et c'est exactement la presence que cette
      bascule commande : ce n'est pas un emprunt, c'est le meme sens a sa
      source. Une seconde bascule sur un autre sujet devra prendre le
      violet, sinon le vert redevient decoratif.
   ⚠️ LA PASTILLE SE DEPLACE PAR `transform`, JAMAIS PAR `left`. Animer une
      position de mise en page, c'est faire recalculer la rangee a chaque
      image ; une translation ne coute que de la peinture. */
#s-compte .c-bascule{position:relative;width:51px;height:31px;flex:0 0 auto;
  border-radius:999px;cursor:pointer;background:rgba(255,255,255,.12);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);border:0;padding:0;
  transition:background .22s var(--ease)}
#s-compte .c-bascule::after{content:"";position:absolute;inset:-7px 0;
  border-radius:999px}
#s-compte .c-bascule i{position:absolute;top:2px;left:2px;width:27px;height:27px;
  border-radius:50%;background:#FFFFFF;box-shadow:0 1px 3px rgba(0,0,0,.35);
  transition:transform .22s var(--ease)}
#s-compte .c-bascule.on{background:#22C55E;box-shadow:none}
#s-compte .c-bascule.on i{transform:translateX(20px)}
#s-compte .c-bascule[disabled]{opacity:.5;cursor:default}
@media (prefers-reduced-motion:reduce){
  #s-compte .c-bascule,#s-compte .c-bascule i,#s-compte .c-point::before{transition:none}
}

/* ══ §2.1 · LA CARTE « THEO » ══
   ⚠️ ELLE PORTE LE MEME CHEVRON QUE LES RANGEES : elle mene ailleurs comme
      elles, elle est cliquable comme elles, et elle etait la seule a ne pas
      le dire. Deux objets qui font la meme chose portent le meme signe.
   ⚠️ REMBOURRAGE DROIT A 10, celui des rangees : ce n'est pas la carte qui
      aligne son chevron, c'est la COLONNE qui impose sa position. Six
      chevrons sur une seule verticale.
   ⚠️ LE CHEVRON GARDE SA COTE 8x13 malgre la hauteur de la carte : un
      chevron se mesure a sa famille, pas a la boite qui le contient.
   ⚠️ ET `border:0` EST OBLIGATOIRE : .c-moi est un <button>, et un <button>
      sans border declaree reprend celle du navigateur (2px outset), que
      WebKit rend en relief clair. Defaut deja paye le 02/08 sur l'accueil. */
#s-compte .c-moi{position:relative;display:flex;align-items:center;gap:var(--e-3);
  width:100%;padding:var(--e-3) var(--e-2) var(--e-3) var(--e-3);border-radius:var(--r-3);border:0;
  background:var(--card-2);box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
  text-align:left;cursor:pointer;font:inherit;color:inherit;
  transition:background .16s var(--ease)}
#s-compte .c-moi:active{background:#2A2A31}
#s-compte .c-moi-av{position:relative;width:52px;height:52px;border-radius:50%;
  flex:0 0 auto;display:grid;place-items:center;font-size:var(--t-4);font-weight:700;
  color:#170B20;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%)}
#s-compte .c-moi-t{flex:1 1 auto;min-width:0}
#s-compte .c-moi-t b{display:block;font-size:var(--t-3);font-weight:600;
  letter-spacing:-.02em;color:var(--ink);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* ⚠️ LE CRAYON DU SOUS-TITRE N'EST PAS UN CHEVRON ET NE LE REMPLACE PAS :
   il dit ce qu'on trouvera la-bas (personnaliser), pas qu'on y va. Un
   glyphe de contenu ne fait jamais office de mecanisme. */
#s-compte .c-moi-t small{display:flex;align-items:center;gap:var(--e-2);
  margin-top:var(--e-1);font-size:var(--t-1);line-height:1.3;color:var(--c-texte-3)}
#s-compte .c-moi-t small svg{width:12px;height:12px;flex:0 0 auto;fill:none;
  stroke:#ABA5B8;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* ══ §9 · LE COMPOSANT ALERTE — deux emplois, UN SEUL BLOC ══
   ⚠️ LE DECOR EST FLOUTE PAR `filter` SUR LES ELEMENTS, pas par un
      backdrop-filter sur le voile : quatre causes independantes tuent un
      backdrop-filter ici (cage d'empilement, pseudo-element descendant d'un
      element transforme, panneau qui porte lui-meme un transform, second
      backdrop-filter sur le voile). On floute les objets eux-memes.
   ⚠️ LE VOILE VIT DANS LA BOITE QUI DEFILE, pas sur l'ecran : #s-compte
      pose `position:relative;z-index:1` sur sa boite interne, qui devient
      un contexte d'empilement et EMPRISONNE les z:6 du panneau. Defaut
      exactement identique paye ce matin sur le menu « + » du Multijoueur.
   ⚠️ LE PANNEAU GRANDIT DEPUIS SON CENTRE : contrairement a un menu, il n'a
      pas d'ancre. Et il est centre verticalement — ce qui se DECIDE se met
      devant les yeux, ce qui s'EXECUTE se met sous la main.
   ⚠️ 17 ET NON 19 pour la question : 19 n'existe nulle part dans l'app. Une
      question posee dans un panneau est un titre de CARTE, pas d'ecran. */
#s-compte .c-voile{position:fixed;inset:0;z-index:5;background:rgba(6,6,9,.46);
  animation:uiVoile var(--m-court) var(--m-sortie) backwards}

#s-compte.c-demande-on #cp-body>*:not(.c-voile):not(.c-demande){filter:blur(4.5px);
  transition:filter .2s}
#s-compte .c-demande{position:fixed;top:50%;left:50%;z-index:6;
  width:min(320px,100% - 36px);padding:var(--e-4) var(--e-4) var(--e-3);
  transform:translate(-50%,-50%);border-radius:var(--r-3);
  background:linear-gradient(rgba(14,14,18,.10),rgba(14,14,18,.10)),
    rgba(122,122,136,.34);
  -webkit-backdrop-filter:blur(40px) saturate(1.8);
  backdrop-filter:blur(40px) saturate(1.8);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),
    0 24px 60px -20px rgba(0,0,0,.8);
  animation:c-demandeOuvre var(--m-court) var(--m-sortie) backwards;animation-delay:40ms}
@keyframes c-demandeOuvre{from{opacity:0;transform:translate(-50%,-50%) scale(.94)}
  to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
#s-compte .c-demande h2{font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--c-texte);text-align:center}
#s-compte .c-demande p{margin-top:var(--e-2);font-size:var(--t-2);line-height:1.45;
  color:var(--c-texte-2);text-align:center}
#s-compte .c-choix{display:flex;gap:var(--e-2);margin-top:var(--e-4)}
/* ⚠️ « ANNULER » A GAUCHE, L'ACTION A DROITE : le pouce droit atteint la
   droite en premier, donc on y met ce qu'on choisit le MOINS souvent.
   ⚠️ ET « ANNULER » N'EST PAS PLUS DISCRET : dans un choix irreversible, la
      sortie doit peser autant que l'entree. */
#s-compte .c-ch{flex:1 1 0;min-width:0;min-height:44px;border:0;font:inherit;
  display:flex;align-items:center;justify-content:center;
  border-radius:999px;cursor:pointer;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;
  transition:background .16s var(--ease)}
#s-compte .c-ch.annuler{background:rgba(255,255,255,.10);color:var(--c-texte)}
#s-compte .c-ch.annuler:active{background:rgba(255,255,255,.18)}
#s-compte .c-ch.oui{background:rgba(229,72,77,.16);color:#EC5B5F;
  box-shadow:inset 0 0 0 .34px rgba(236,91,95,.34)}
#s-compte .c-ch.oui:active{background:rgba(229,72,77,.26)}

/* ══ §0.4 (suite) · LA BARRE EXISTANTE DU COMPTE PREND LES COTES DU LOT ══
   ⚠️ ON NE POSE PAS UNE SECONDE BARRE DANS LE CORPS. Le dossier dessine une
      `.entete` autonome parce que ses rendus n'ont pas de barre ; l'ecran, lui,
      en a deja une (`.topbar` + #cp-title), branchee au retour, au geste iOS et
      a la classe `.racine` qui retire la fleche a la racine d'un onglet. En
      poser une deuxieme aurait fabrique deux barres a maintenir, dont une
      seule sait revenir. On porte les COTES du lot sur la barre qui existe.
   ⚠️ minmax(0,1fr) ET NON 1fr : un titre long pousserait les colonnes de 36 et
      deplacerait le bouton de retour. Et la forme litterale « 36px 1fr 36px »
      est interdite au contrat depuis le 04/08 (grille de l'accueil qui ne doit
      pas revenir) : le controle est GLOBAL alors que la decision ne visait que
      l'accueil — signale a Theo, non contourne, la valeur ici est meilleure. */
#s-compte .topbar{display:grid;grid-template-columns:36px minmax(0,1fr) 36px;
  align-items:center;min-height:44px;margin-bottom:var(--e-5)}
#s-compte .topbar>b#cp-title{grid-column:2;justify-self:center;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;line-height:1.2;
  color:var(--c-texte);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-compte .topbar>span{grid-column:3}
/* le bouton de retour prend le voile et le rayon du lot, pas une couleur a lui */
#s-compte .topbar>#cp-back{grid-column:1;position:relative;width:36px;height:36px;
  min-height:0;border-radius:var(--r-1);background:rgba(255,255,255,.07);border:0;
  display:grid;place-items:center;color:var(--c-texte-2);font-size:var(--t-2);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .topbar>#cp-back::after{content:'';position:absolute;inset:-4px}
#s-compte .topbar>#cp-back:active{transform:scale(.94);background:rgba(255,255,255,.14)}
#s-compte .topbar>#cp-back svg{width:12px;height:12px;stroke:#C6BFD6;fill:none;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ A LA RACINE D'UN ONGLET LA FLECHE DISPARAIT MAIS SA COLONNE RESTE : un
   enfant de grille en display:none ne reserve pas sa case, et le titre
   glisserait de 18 px vers la gauche. Piege deja paye le 02/08 sur l'accueil
   (v412, placement explicite des colonnes). D'ou visibility, pas display. */
#s-compte.racine .topbar>#cp-back{visibility:hidden;pointer-events:none}

/* ══ LA PILE DU COMPTE ══ un groupe, son intitule, la carte, l'espace entre eux */
#s-compte #cp-body{display:flex;flex-direction:column}
#s-compte #cp-body>.c-moi+.c-lab{margin-top:var(--e-4)}

/* ══════════════════════════════════════════════════════════════════════
   [07/08] LOT COMPTE — LES ECRANS (§3, §5, §6, §7, §8, §10)
   Suite du socle pose le 06/08. Memes regles : prefixe `c-`, scope
   #s-compte, tailles de police en rem (le px echapperait au Grand texte).
   ══════════════════════════════════════════════════════════════════════ */

/* ══ §3 · PROFIL ══
   ⚠️ LA BARRE DU PROFIL N'EST PAS UNE `.c-entete` MAIS UNE `.c-nav` : elle
      porte DEUX commandes, une a chaque bout. Le titre « Profil » est
      revenu apres avoir ete retire — suivre le rendu, qui n'en met pas,
      valait pour un ecran isole ; une barre vide au milieu de trois barres
      qui portent un titre ne se lit pas comme une intention, elle se lit
      comme un oubli. Et le titre TIENT L'AXE : sans lui, deux boutons
      flottent aux deux bouts d'une bande de 357.
   ⚠️ DEUX RONDS 32/28 CHEZ EUX, 36/36 CHEZ NOUS : deux commandes de meme
      rang aux deux bouts d'une barre pesent pareil. Et carre arronди
      plutot que rond : a dimension egale un disque parait 16 % plus petit
      qu'un carre arrondi, et LE CERCLE APPARTIENT AUX GENS. */
#s-compte .c-nav{display:grid;grid-template-columns:36px minmax(0,1fr) 36px;
  align-items:center;flex:0 0 auto;min-height:44px;margin-bottom:var(--e-4)}
#s-compte .c-navbtn{position:relative;width:36px;height:36px;border-radius:var(--r-1);
  display:grid;place-items:center;cursor:pointer;color:var(--c-texte-2);border:0;
  background:rgba(255,255,255,.07);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-navbtn::after{content:'';position:absolute;inset:-4px}
#s-compte .c-navbtn:active{transform:scale(.94);background:rgba(255,255,255,.14)}
#s-compte .c-navbtn.g{grid-column:1}
#s-compte .c-navbtn.d{grid-column:3;justify-self:end}
#s-compte .c-navbtn svg{width:19px;height:19px;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* §3.4 · le portrait.
   ⚠️ DISQUE 88 ET NON 106,5 : un portrait qui prend un quart de l'ecran
      repousse tout ce qui suit. Il reprend le degrade ET la bague de
      l'avatar de la barre du bas, a l'echelle — un meme objet ne se
      redessine pas a chaque endroit ou il apparait. `box-shadow` et non
      `outline` : la bague a DEUX couches, ce qu'un outline ne sait pas faire.
   ⚠️ INITIALE A 34 POUR 88 = 0,39, le rapport des GRANDS disques ; les
      petits travaillent a 0,50. Un rapport typographique n'est pas
      universel, il appartient a une echelle. */
/* ⚠️⚠️ [07/08, signale par Theo] LE PORTRAIT DEBORDAIT A GAUCHE DES CARTES. Son halo est
   un `box-shadow` d'ECART (0 0 0 4.5px), et une ombre ne fait PAS partie de la boite :
   elle se peint EN DEHORS, sans place reservee. Le disque commencait donc a 18 - 4,5 =
   13,5 px du bord, quand les cartes commencent a 18. Theo le decrit exactement :
   « le rond est mange par le bord ».
   ⚠️ ON ALIGNE LE BORD VISIBLE, PAS LA BOITE. C'est ce qu'on voit qui doit tomber sur la
      verticale des cartes ; la boite, elle, n'est visible nulle part. Le decalage vaut le
      RAYON DU HALO, arrondi au demi-pixel superieur (4,5), et il est ecrit une seule fois.
   ⚠️ ET IL S'APPLIQUE AU CONTENEUR, PAS AU DISQUE : le texte a cote suit le meme
      decalage, sinon le portrait bougerait et le nom resterait. Ce qui compte est
      l'ecart ENTRE eux, et il ne change pas. */
#s-compte .c-portrait{flex:0 0 auto;display:flex;align-items:center;gap:var(--e-3);
  margin:0 0 var(--e-4);padding-left:var(--e-1)}
#s-compte .c-grand{position:relative;width:88px;height:88px;border-radius:50%;
  flex:0 0 auto;display:grid;place-items:center;font-size:var(--t-6);
  font-weight:700;letter-spacing:-.01em;color:#170B20;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  box-shadow:0 0 0 2px rgba(250,249,252,.95), 0 0 0 4.5px #8B5CF6}
/* ══════════════════════════════════════════════════════════════════════════════
   [07/08] LA TEINTE CHOISIE PEINT ENFIN MES AVATARS — signale par Theo en video :
   « ca ne change pas la couleur ». Le toast disait vrai, la valeur ETAIT enregistree,
   mais `trinke_teinte_moi` n'apparaissait QU'UNE FOIS dans tout le projet : ecrit,
   jamais relu. L'ecran de la roue etait une demonstration branchee sur rien.

   ⚠️⚠️ LE VIOLET D'ORIGINE N'EST PAS TOUCHE, ET C'EST DELIBERE. Ses deux arrets ne
      portent meme pas la meme teinte (255,6° en haut, 258,3° en bas, mesures) : c'est
      un degrade dessine a la main, pas derive d'une teinte unique. Le parametrer
      aurait decale le violet de tout le monde de un a deux points de rouge pour
      satisfaire une formule. Les regles d'origine restent donc INTACTES, et ces
      trois-ci ne s'appliquent QUE si `html` porte la classe `teinte`, posee par le JS
      uniquement quand une couleur a ete choisie. **Qui n'a rien choisi ne voit pas un
      pixel bouger.**

   ⚠️ L'APERCU DE LA ROUE PREND LE MEME DEGRADE QUE L'AVATAR. Il etait un aplat a 72 %
      de luminance quand l'avatar est un degrade de 76 a 66 : on validait une couleur
      et on en obtenait une autre, legerement. Sur un ecran dont le seul travail est de
      montrer le resultat, l'apercu doit etre le resultat.
   ══════════════════════════════════════════════════════════════════════════════ */
html.teinte{--av-lhi:76%; --av-llo:66%;
  --av-hi:hsl(var(--av-h) var(--av-s) var(--av-lhi));
  --av-lo:hsl(var(--av-h) var(--av-s) var(--av-llo))}
/* ⚠️⚠️ [07/08] `:not(.ami)` N'EST PAS UNE PRECAUTION, C'EST LA REGLE ELLE-MEME :
   MA teinte ne peint QUE MES ronds. Depuis que le profil d'un ami est le meme
   ecran que le mien, `.c-grand` sert deux personnes : sans cette garde, le grand
   disque du profil de quelqu'un d'autre prenait MA couleur, et on lisait son
   pseudo sous mon avatar. Un rond qui ment sur son proprietaire est pire qu'un
   rond mal colore. La couleur d'un ami vient de `amTeinte(son identifiant)`, la
   meme fonction que la liste des amis : deux telephones voient la meme couleur
   pour la meme personne. Verrouille par `outils/test-teinte-avatar.js`. */
html.teinte #s-compte .c-grand:not(.ami),
html.teinte .ong-av{background:linear-gradient(180deg,var(--av-hi) 0%,var(--av-lo) 100%)}
html.teinte #s-compte .c-grand:not(.ami){box-shadow:0 0 0 2px rgba(250,249,252,.95), 0 0 0 4.5px var(--av-lo)}
/* ══ LE GRAND PORTRAIT D'UN AMI — l'arc bleu vers indigo des trinkeurs ══
   ⚠️⚠️ [07/08, SECONDE ECRITURE] LA COPIE DES HUIT COULEURS EST PAYEE. Ce bloc etait
      huit regles portant les memes hexadecimaux que `:is(#s-amis,#s-multi) .am-av1..8`, recopies
      parce que la palette etait enfermee dans le scope `#s-amis`, dont le rendu etait
      alors en cours de refonte. Le rendu est arrive : la palette est sortie de son
      scope et ne declare plus que des variables (`--ami-fond`, `--ami-encre`,
      `--lueur`, cherchez `.am-av1{` dans la section Amis). ON LIT LA SOURCE, ON NE LA
      RECOPIE PLUS — donc UNE regle au lieu de huit, et plus rien a synchroniser.
   ⚠️ L'ENCRE SUIT LA CLARTE, elle n'est pas decorative : `.c-grand` pose
      `color:#170B20`, l'encre des surfaces claires. Sur les quatre bleus fonces
      elle tomberait sous le seuil ; ceux-la portent du blanc, et c'est `--ami-encre`
      qui le sait — la meme variable des deux cotes.
   ⚠️ ET L'ANNEAU PREND LA COULEUR DU DISQUE : le halo de `.c-grand` est un
      `box-shadow` d'ecart en violet fixe ; le laisser violet aurait cercle de MA
      couleur un disque qui n'est pas le mien. */
#s-compte .c-grand.ami{background:var(--ami-fond);color:var(--ami-encre);
  box-shadow:0 0 0 2px rgba(250,249,252,.95), 0 0 0 4.5px var(--ami-fond)}
html.teinte .ong-av{box-shadow:0 0 0 1.5px rgba(250,249,252,.95), 0 0 0 3px var(--av-lo)}
/* ⚠️ LA CARTE DE COMPTE A SA PROPRE CONSTRUCTION, ET MA PREMIERE VERSION L'ECRASAIT :
   trois arrets a 135°, pas deux a 180°, releve au CSSOM. Reprendre le degrade du grand
   portrait lui aurait fait perdre son volume et son angle des qu'une couleur est choisie,
   c'est-a-dire un changement de dessin que personne n'a demande. Elle garde donc SA forme,
   seule la teinte varie. Les trois luminances viennent de ses trois arrets d'origine
   (76 %, 66 %, 55 %), le liseré de son propre ton (72 %). */
html.teinte #s-compte .c-moi-av{
  background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 55%,
                                     hsl(var(--av-h) var(--av-s) calc(var(--av-llo) - 11%)) 100%);
  box-shadow:0 0 0 2px var(--card-2),
             0 0 0 3px hsl(var(--av-h) var(--av-s) calc(var(--av-llo) + 6%))}

/* ══ ET PARTOUT AILLEURS OU CE ROND EST MOI — demande de Theo, 07/08 : « verifie que
   ca change bien la couleur du rond sur tous les endroits de l'app ou il est visible,
   classement etc, pense a tout ».

   ⚠️⚠️ LE RECENSEMENT A MONTRE QUE JE N'EN AVAIS FAIT QUE TROIS SUR SEPT. Le portrait,
      la carte de compte et l'onglet etaient teintes ; le classement, la rangee des
      trinkeurs de l'accueil, « Qui joue ? » et le salon restaient violets. Ce n'etait
      pas un oubli d'un cas isole : c'est que j'avais cherche les avatars LA OU JE
      VENAIS DE TRAVAILLER, au lieu de chercher tous les endroits ou un rond porte mon
      initiale. **Un recensement se fait sur l'objet, pas sur l'ecran qu'on a en tete.**

   ⚠️ TROIS DE CES QUATRE ETAIENT DEJA MARQUES `moi` OU `estmoi` DANS LE CODE, et deja
      peints en violet fixe : la notion existait, il ne manquait que la teinte. Le
      quatrieme n'avait aucun marqueur, il a fallu le poser (voir app.js).

   ⚠️ CHACUN GARDE SA PROPRE CONSTRUCTION. Le classement est un aplat avec une lueur, la
      rangee de l'accueil et « Qui joue ? » sont des degrades a 135° avec deux anneaux :
      leur imposer le degrade du portrait aurait change quatre dessins pour teinter une
      couleur. On ne remplace que la TEINTE, jamais la forme. */

/* la rangee des trinkeurs de l'accueil : degrade a trois arrets, deux anneaux */
html.teinte #s-home .hav.estmoi{
  background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 55%,
                                     hsl(var(--av-h) var(--av-s) calc(var(--av-llo) - 11%)) 100%);
  box-shadow:0 0 0 2px #0A090E, 0 0 0 3.5px var(--av-hi)}

/* « Qui joue ? » : meme construction, un fond d'anneau different */
html.teinte #s-joueurs .jr-row .cl-av.moi{
  background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 55%,
                                     hsl(var(--av-h) var(--av-s) calc(var(--av-llo) - 11%)) 100%);
  box-shadow:0 0 0 2px #1F1F24, 0 0 0 3.5px var(--av-hi)}

/* l'onglet Classement : un APLAT, et sa lueur doit suivre — elle est declaree en
   composantes rouge/vert/bleu separees, donc elle ne peut pas prendre une couleur hsl
   telle quelle. On la recalcule par `color-mix`, seul moyen d'obtenir des composantes
   depuis une teinte sans passer par le JS. */
html.teinte #s-classement .cm-av.estmoi{
  background-color:var(--av-lo);
  box-shadow:0 0 18px -2px color-mix(in srgb, var(--av-lo) 55%, transparent)}

/* le classement de Mon compte, la fiche de statistiques, l'apercu de pseudo et le salon
   multijoueur : le marqueur `moi` vient d'etre pose sur ces ronds (app.js), leur dessin
   est celui de `.cl-av` / `.dis-av`, un degrade simple. */
html.teinte .cl-av.moi,
html.teinte .dis-av.moi{
  background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 100%)}

#s-compte .c-identite{flex:1 1 auto;min-width:0;display:flex;
  flex-direction:column;gap:var(--e-2)}
#s-compte .c-ligne-nom{display:flex;align-items:center;gap:var(--e-2);min-width:0}
#s-compte .c-nom{flex:0 1 auto;min-width:0;font-size:var(--t-4);font-weight:700;
  letter-spacing:-.025em;line-height:1.1;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠️⚠️ « DEPUIS AOUT 2018 » N'EST PAS UN BOUTON. Il portait une gelule, un
   voile, un etat presse et une cible de 44 : tout disait « touche-moi » pour
   une phrase qui ne mene nulle part. Une information qui porte les signes
   d'une commande est une promesse qu'on ne tient pas. C'est un <span> — le
   clavier et les lecteurs d'ecran cessent de s'y arreter.
   ⚠️ ET IL NE RESTE QUE LA DATE : « Membre », puis « depuis ». Un mot qui ne
      survit pas au retrait du contexte est un mot qui REPETAIT le contexte,
      et un glyphe est un contexte. La phrase entiere reste dans aria-label :
      ce qu'on retire parce que l'oeil le deduit, la voix en a encore besoin. */
#s-compte .c-marque{align-self:flex-start;display:inline-flex;align-items:center;
  gap:var(--e-2);font-size:var(--t-1);font-weight:500;color:var(--c-texte-3);white-space:nowrap}
#s-compte .c-marque b{font-weight:600;color:var(--c-texte-2)}
#s-compte .c-marque svg{width:13px;height:13px;fill:none;stroke:#9A93AC;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* §3.5 · DEUX boutons d'edition, pas un.
   > « Un bouton d'edition appartient a ce qu'il edite » ne veut pas dire
     qu'un seul bouton edite tout.
   Le crayon pres du nom change le PSEUDO, la pastille sur le disque change
   l'AVATAR. En les fusionnant on fabrique un bouton « modifier » generique,
   c'est-a-dire un bouton qui n'appartient a rien. */
#s-compte .c-crayon{position:relative;flex:0 0 auto;width:30px;height:22px;
  border-radius:999px;display:grid;place-items:center;cursor:pointer;border:0;
  background:rgba(255,255,255,.09);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-crayon::after{content:'';position:absolute;inset:-11px -7px}
#s-compte .c-crayon:active{transform:scale(.94);background:rgba(255,255,255,.18)}
#s-compte .c-crayon svg{width:13px;height:13px;fill:none;stroke:#C6BFD6;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️⚠️ LA PASTILLE EST RONDE, ET LE SOCLE S'AMENDE. La regle disait « le
   cercle appartient aux gens » ; elle existe pour qu'un rond ISOLE ne se
   lise pas comme quelqu'un. Ici il chevauche le bord d'un avatar : un rond
   pose sur le bord d'un disque n'est pas un second visage, c'est une PIECE
   du premier. Amendement : le cercle appartient aux gens, SAUF ce qui se
   pose SUR une personne pour la modifier. Et l'ovale etait le vrai defaut —
   une gelule collee a un cercle introduit une seconde geometrie sur le meme
   objet : ce qui se pose sur une forme en epouse la geometrie.
   ⚠️⚠️ SA POSITION SE CALCULE, ELLE NE SE REGLE PAS :
        rayon 44 + bague 4,5 = 48,5 ; centre a 45 degres : 48,5/racine(2) =
        34,3 en x comme en y -> centre a 78,3 du bord gauche -> pastille a
        -3 en bas et a droite. Posee a l'oeil elle est toujours fausse d'un
        pixel ou deux ; posee sur la CIRCONFERENCE elle est juste, et le
        reste si le disque change de taille.
   ⚠️ SA BAGUE EST PEINTE EN COULEUR DE PAGE, seule fois ou cette technique
      est juste : le fond de CET ecran est plat. Ce qu'on avait interdit,
      c'etait de peindre un fond qui BOUGE. */
#s-compte .c-retouche{position:absolute;right:-3px;bottom:-3px;
  width:26px;height:26px;border-radius:50%;border:0;
  display:grid;place-items:center;cursor:pointer;
  background:#3A3844;box-shadow:0 0 0 3px var(--bg);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-retouche::after{content:'';position:absolute;inset:-9px}
#s-compte .c-retouche:active{transform:scale(.94);background:#494654}
#s-compte .c-retouche svg{width:13px;height:13px;fill:none;stroke:#E6E1F0;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* §3.6 · le score et les quatre statistiques.
   Ordre : Victoires · Gorgees · Parties · Reussite. Le taux en DERNIER
   parce qu'il est le seul pourcentage — une serie se lit mieux quand ce qui
   change d'unite est au bout.
   ⚠️ LES QUATRE INTITULES TIENNENT EN UN MOT : une rangee de colonnes egales
      exige des intitules de longueur comparable, sinon c'est la plus bavarde
      qui fixe la hauteur de toutes.
   ⚠️ LES CHIFFRES RESTENT BLANCS : quatre colonnes teintees se liraient
      comme quatre CATEGORIES au lieu de quatre MESURES. La couleur designe,
      elle ne remplit pas.
   ⚠️ AUCUNE COULEUR DE GLYPHE N'EST INVENTEE — or (rang), fuchsia
      (Classiques), violet (Soiree), bleu (Quiz) : quand un glyphe existe
      deja ailleurs, sa couleur est deja decidee. */
#s-compte .c-stats{position:relative;display:grid;
  grid-template-columns:repeat(4,1fr);padding:var(--e-3) 0 var(--e-3)}
#s-compte .c-stats::before{content:'';position:absolute;top:0;left:0;right:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.10)}
#s-compte .c-stat{position:relative;display:flex;flex-direction:column;
  align-items:center;gap:var(--e-2);padding:0 var(--e-1)}
#s-compte .c-stat+.c-stat::before{content:'';position:absolute;left:0;top:6px;
  bottom:6px;width:1px;transform:scaleX(.34);background:rgba(255,255,255,.10)}
#s-compte .c-stat svg{width:21px;height:21px;fill:none;stroke:#A8A0BA;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
#s-compte .c-stat.or svg{stroke:#FCD34D}
#s-compte .c-stat.fuchsia svg{stroke:#F45CC0}
#s-compte .c-stat.violet svg{stroke:#B486F8}
#s-compte .c-stat.bleu svg{stroke:#5A9BE0}
#s-compte .c-stat b{font-size:var(--t-4);font-weight:700;letter-spacing:-.02em;
  color:var(--c-texte);font-variant-numeric:tabular-nums;line-height:1}
#s-compte .c-stat small{font-size:var(--t-1);font-weight:400;line-height:1.25;
  color:var(--c-texte-3);text-align:center;letter-spacing:-.005em}

/* §3.7 · les badges — l'hexagone entre dans le socle.
   ⚠️⚠️ C'EST LA SEULE FORME NEUVE DU LOT. Le socle attribuait deja chaque
      forme : le cercle aux gens, le carre arrondi aux contenants, la gelule
      aux commandes. Un badge n'est aucun des trois — une forme qui ne sert
      qu'a une chose ne peut pas etre confondue.
   ⚠️ LE BADGE PORTE LA TEINTE DU MODE OU IL SE GAGNE : une couleur nouvelle
      n'apprend rien, une couleur deja connue apprend d'ou vient la chose. Le
      verrouille n'a pas de teinte — ce qu'on n'a pas encore n'appartient a
      aucun territoire. */
#s-compte .c-badges{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--e-3)}
#s-compte .c-badge{display:flex;flex-direction:column;align-items:center;gap:var(--e-2)}
#s-compte .c-hex{position:relative;width:100%;aspect-ratio:1/1.09;
  display:grid;place-items:center;
  clip-path:polygon(50% 0%,100% 25%,100% 75%,50% 100%,0% 75%,0% 25%)}
#s-compte .c-hex::before{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(var(--bt),.34),rgba(var(--bt),.12))}
#s-compte .c-hex svg{position:relative;width:22px;height:22px;fill:none;
  stroke:rgb(var(--bt));stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
#s-compte .c-badge small{font-size:var(--t-1);line-height:1.2;color:var(--c-texte-3);
  text-align:center}
#s-compte .c-badge.soiree{--bt:180,134,248}
#s-compte .c-badge.minijeux{--bt:252,211,77}
#s-compte .c-badge.quiz{--bt:90,155,224}
#s-compte .c-badge.classiques{--bt:244,92,192}
#s-compte .c-badge.verrou{--bt:138,130,166}

/* ══ §5.3 · LA CARTE DU CODE DE RECUPERATION ══
   ⚠️ CE N'EST PAS UNE RANGEE, ET CA NE POUVAIT PAS EN ETRE UNE : la valeur
      EST le sujet, elle se lit signe a signe, elle se recopie a la main. Ce
      qu'on doit transcrire ne se met pas dans une colonne de droite.
   ⚠️ CHASSE FIXE ET INTERLETTRAGE +.14em, le seul endroit de l'app ou l'on
      ecarte les lettres, PARCE QU'ON NE LIT PAS UN MOT. Et le code est
      groupe par quatre : on ne raccourcit pas un code, on le decoupe.
   ⚠️ LE MASQUE A EXACTEMENT LA LARGEUR DU CODE : un masque qui change la
      largeur de ce qu'il cache ANNONCE la longueur du secret.
   ⚠️ LE FOND DE LA PLAQUE EST PLUS SOMBRE QUE LA CARTE : un creux, pas un
      relief. Ce qui se lit se pose au fond, ce qui s'actionne monte. */
#s-compte .c-carte{flex:0 0 auto;border-radius:var(--r-3);background:var(--card-2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);padding:var(--e-3)}
#s-compte .c-carte h2{font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  color:var(--ink)}
#s-compte .c-carte p{margin-top:var(--e-1);font-size:var(--t-1);line-height:1.45;color:var(--c-texte-3)}
#s-compte .c-plaque{margin-top:var(--e-3);padding:var(--e-3) var(--e-3);border-radius:var(--r-2);
  background:rgba(0,0,0,.30);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.10);
  /* ⚠️ [07/08] L'INTERLETTRAGE TOMBE DE .14 A .05 : le code fait dix-neuf caracteres,
     et depuis que le bouton de copie prend 38 px sur la ligne, il ne restait que 218 px.
     A .14 il passait sur DEUX lignes et poussait le bouton au milieu du bloc. Mesure :
     a .05, le corps reste identique (1,1875 rem) et le code tient sur une ligne. On
     resserre l'espacement AVANT de reduire la taille — un code se lit caractere par
     caractere, sa taille est ce qui compte le plus. */
  text-align:center;font-size:var(--t-3);font-weight:600;letter-spacing:.05em;
  font-variant-numeric:tabular-nums;color:var(--c-texte);word-break:break-word}
#s-compte .c-plaque.cache{color:var(--c-texte-3);letter-spacing:.14em}
/* ══ [07/08] LA PLAQUE PORTE SA COPIE, ET SON ETAT VIDE DIT LA VERITE ══
   ⚠️ LE BOUTON DE COPIE EST DANS LA PLAQUE, pas sous elle : c'est ce que Theo
      decrivait (« l'option copier avec la petite icone sur la meme ligne »), et
      c'est aussi ce que fait iOS partout ou une valeur se copie. La plaque passe
      donc en grille de deux colonnes, le code au centre de la PREMIERE et non de
      la plaque entiere — sinon l'icone le pousserait de 18 px vers la gauche.
   ⚠️ SA CIBLE FAIT 44 par un ::after qui deborde, sans changer la taille vue :
      un carre de 30 px se rate au doigt, et on ne fait pas grossir un objet
      pose a cote d'une valeur qu'il ne doit pas ecraser. */
#s-compte .c-plaque:not(.vide){display:grid;grid-template-columns:1fr 30px;
  align-items:center;gap:var(--e-2);padding-right:var(--e-2)}
#s-compte .c-plaque>span{min-width:0;word-break:break-word}
#s-compte .c-copie{position:relative;width:30px;height:30px;border:0;padding:0;
  border-radius:var(--r-1);background:rgba(255,255,255,.09);color:var(--c-texte-2);
  display:grid;place-items:center;cursor:pointer;
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-copie::after{content:'';position:absolute;inset:-7px}
#s-compte .c-copie:active{transform:scale(.94);background:rgba(255,255,255,.16)}
#s-compte .c-copie svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ L'ETAT VIDE N'EST PAS UNE PLAQUE, C'EST UNE PHRASE. Elle perd la graisse, les
   chiffres tabulaires et l'interlettrage d'un CODE : ce qui s'y trouve n'en est pas
   un. Lui laisser l'allure d'une valeur, c'est laisser chercher la valeur. */
#s-compte .c-plaque.vide{font-size:var(--t-2);font-weight:400;letter-spacing:0;
  color:var(--c-texte-3);line-height:1.4;background:rgba(0,0,0,.18)}
#s-compte .c-actions{display:flex;gap:var(--e-2);margin-top:var(--e-3)}
#s-compte .c-act{position:relative;flex:1 1 0;min-width:0;border:0;font:inherit;
  display:flex;align-items:center;justify-content:center;gap:var(--e-2);
  height:40px;border-radius:999px;cursor:pointer;
  background:rgba(255,255,255,.07);
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:var(--c-texte);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte .c-act::after{content:'';position:absolute;inset:-2px}
#s-compte .c-act:active{transform:scale(.96);background:rgba(255,255,255,.14)}
#s-compte .c-act svg{width:15px;height:15px;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* ══ §6.1 · LA RANGEE A TUILE REMPLACE LES PUCES ══
   ⚠️⚠️ DIX-SEPT CROIX ROUGES ET COCHES VERTES SUPPRIMEES. Une croix rouge
      devant « Reserve aux personnes majeures » fait lire la regle comme une
      INTERDICTION SUBIE, alors que c'est une protection. Et la coche verte
      entrait en collision avec la seule autre chose que le vert designe dans
      l'app : LA PRESENCE — un point vert dit « en ligne » sur cinq ecrans,
      il ne peut pas dire « vrai » sur celui-ci. Ce qui se repete a chaque
      rangee appartient a la CARTE, pas a la rangee.
   > Le glyphe dit QUOI, la teinte dit OU. Une teinte par section, pas une
     par enonce.
   ⚠️ LA TUILE S'ALIGNE SUR LA PREMIERE LIGNE DU TEXTE, pas au centre du
      bloc : un signe pose devant un texte se cale sur ce qu'il ANNONCE, pas
      sur ce qu'il accompagne.
   ⚠️ AUCUN CHEVRON SUR LES ENONCES : ils ne menent nulle part, et un chevron
      qui ne mene a rien est une faute plus grave qu'un element muet. */
/* ⚠️⚠️ [07/08, trouve a l'audit] TROIS DE CES RANGEES SONT DES `<button>`, ET LE
   NAVIGATEUR LES PEIGNAIT. Sans remise a zero, Safari leur pose son propre chrome :
   mesure au CSSOM, fond `rgb(107,107,107)` au lieu de transparent, bordure `2px outset`
   blanche, et la POLICE TOMBE EN ARIAL 13,3 px au lieu de la pile systeme a 16.
   « Exporter mes donnees », « Effacer les donnees de ce telephone » et son equivalent de
   l'ecran Supprimer etaient donc des BLOCS GRIS a l'ecran, en production.
   ⚠️ C'EST LA TROISIEME FOIS QUE CE PIEGE SE REFERME sur ce projet : le 02/08 sur les
      tuiles de l'accueil (« un <button> sans `border` declaree reprend celle du
      navigateur »), puis sur la carte du compte, puis ici. **Une carte qui devient
      cliquable pose `background:none;border:0;font:inherit` dans le meme geste**, sinon
      la moitie de ce qu'on croit avoir dessine vient du navigateur.
   ⚠️ ET AUCUN CONTROLE NE POUVAIT LE VOIR : ils verifient ce qui est ECRIT dans la
      feuille, or ici rien n'etait faux — il MANQUAIT une declaration. */
#s-compte .c-dit{position:relative;display:flex;align-items:flex-start;gap:var(--e-3);
  width:100%;min-height:58px;padding:var(--e-3) var(--e-3);text-align:left;
  background:none;border:0;color:inherit;font:inherit;
  -webkit-appearance:none;appearance:none}
/* les deux rangees d'action reagissent au doigt comme les autres */
#s-compte button.c-dit{cursor:pointer;transition:background .16s var(--ease)}
#s-compte button.c-dit:active{background:rgba(255,255,255,.04)}
/* ⚠️ ET LE TITRE DESTRUCTEUR REDEVIENT ROUGE : `.c-dit.danger` n'existait pas, et la
   regle generale des titres forcait l'encre normale. On ne peut pas employer
   `currentColor` ici — sur un bouton non reinitialise il aurait rendu du blanc. */
#s-compte .c-dit.danger .c-txt b{color:#E0716D}
#s-compte .c-dit+.c-dit::before{content:"";position:absolute;left:60px;right:0;
  top:0;height:1px;transform:scaleY(.34);background:rgba(255,255,255,.17)}
#s-compte .c-dit .c-tu{margin-top:2px}
#s-compte .c-dit .c-txt b{display:block;font-size:var(--t-2);font-weight:600;
  letter-spacing:-.01em;color:var(--ink)}
#s-compte .c-dit .c-txt small{display:block;font-size:var(--t-2);margin-top:var(--e-1);
  line-height:1.4;color:var(--c-texte-3)}
/* ⚠️⚠️ §7 · LA MENTION LEGALE N'EST PAS ABREGEE : c'est une formule imposee
   par la loi francaise, elle s'ecrit mot pour mot ou elle ne compte pas. On
   minimise ce qu'on a redige, JAMAIS ce qu'on nous impose de rediger. Elle
   est la seule rangee dont le sous-titre est plus long que le titre, et son
   encre est celle du TEXTE PLEIN pour qu'on ne la prenne pas pour un
   commentaire. */
#s-compte .c-dit.legale .c-txt small{color:var(--ink);font-size:var(--t-2)}

/* ══ §8.2 · LE BOUTON DE SUPPRESSION ══
   ⚠️ ROUGE EN VOILE, JAMAIS EN APLAT : un bouton destructeur doit etre
      TROUVABLE, jamais attirant.
   ⚠️⚠️ ET LE ROUGE N'EST QUE LA. La version d'avant peignait en rouge les
      quatre tuiles de « Ce qui sera supprime » : quatre signaux plus un,
      c'est-a-dire aucun. Un signal qui se repete n'est plus un signal —
      c'est l'argument meme qui a fait tomber les dix-sept croix du §6.
   ⚠️ 32 AU-DESSUS, PAS 26 : le socle n'a que 8, 16, 24, 32. Un ecart hors de
      l'echelle ne se remarque pas, il se paie plus tard quand il faut
      expliquer pourquoi celui-la est different.
   ⚠️ IL PREND LA LARGEUR, contre la regle des gelules qui epousent leur
      contenu — seul ecart du lot : ce qui ne se defait pas se pose la ou le
      doigt SAIT qu'il va le trouver. */
#s-compte .c-detruire{position:relative;width:100%;margin-top:var(--e-5);
  min-height:46px;border:0;font:inherit;
  display:flex;align-items:center;justify-content:center;
  border-radius:999px;cursor:pointer;
  background:rgba(229,72,77,.13);
  box-shadow:inset 0 0 0 .34px rgba(236,91,95,.30);
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:#EC5B5F;
  transition:background .16s var(--ease)}
#s-compte .c-detruire:active{background:rgba(229,72,77,.22)}

/* ══ §10 · LE COMPOSANT MENU (menu avatar) ══
   ⚠️ LE MENU EST FRERE DU BOUTON, JAMAIS DEDANS : un bouton ne peut pas
      contenir un bouton — l'analyseur ferme le premier et le menu perd son
      bloc de reference.
   ⚠️ LE DISQUE RESTE NET pendant que le decor floute : c'est l'objet qu'on
      modifie. Ce qu'un menu gouverne ne se floute pas.
   ⚠️ L'ORIGINE D'ECHELLE EST LE POINT DE CONTACT : un objet grandit depuis
      l'endroit ou on l'a touche, et un menu ne choisit pas son sens, son
      ancre le lui impose. */
#s-compte .c-menu-z{position:relative;z-index:6}
#s-compte .c-menu{position:absolute;top:calc(100% + 8px);left:0;z-index:6;
  min-width:206px;padding:var(--e-1);border-radius:var(--r-3);
  background:linear-gradient(rgba(14,14,18,.10),rgba(14,14,18,.10)),
    rgba(122,122,136,.34);
  -webkit-backdrop-filter:blur(40px) saturate(1.8);
  backdrop-filter:blur(40px) saturate(1.8);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 2px 6px rgba(0,0,0,.12);
  transform-origin:0 0;
  animation:c-menuOuvre var(--m-court) var(--m-sortie) backwards}
@keyframes c-menuOuvre{from{opacity:0;transform:scale(.92)}to{opacity:1;transform:none}}
#s-compte .c-mit{position:relative;z-index:1;border:0;font:inherit;
  animation:uiMenuItem var(--m-court) var(--m-sortie) backwards;animation-delay:var(--md,0ms);
  display:flex;align-items:center;gap:var(--e-3);background:none;
  width:100%;min-height:44px;padding:0 var(--e-3);border-radius:var(--r-2);cursor:pointer;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:var(--c-texte);
  text-align:left;transition:background .09s}

#s-compte .c-mit:active{background:rgba(255,255,255,.09)}
/* ⚠️ LE FILET DU MENU ETAIT A .021 — une faute de frappe qui a survecu :
   moins d'un demi-ton d'ecart. Une valeur qu'on ne voit pas n'est pas une
   valeur discrete, c'est une valeur ABSENTE. */
#s-compte .c-mit+.c-mit::before{content:'';position:absolute;left:34px;right:0;
  top:0;height:1px;transform:scaleY(.34);background:rgba(255,255,255,.09)}
#s-compte .c-mit svg{width:19px;height:19px;flex:0 0 auto;fill:none;
  stroke:#B9B2CC;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
#s-compte.c-menu-on #cp-body>*:not(.c-voile):not(.c-portrait){filter:blur(3px);
  transition:filter .2s}

/* ══ [07/08] LE MENU « … » DU PROFIL D'UN AMI ══
   Meme composant que le menu de l'avatar : seule son ANCRE change, et l'ancre
   commande le sens. Colle a droite de la barre, il ne peut pas s'ouvrir vers la
   droite sans sortir de l'ecran ; il s'aligne donc sur le bord droit du bouton,
   et son origine d'echelle suit — un objet grandit depuis l'endroit ou on l'a
   touche, jamais depuis un coin qu'on n'a pas vise. */
/* ⚠️⚠️ LA LARGEUR EST CELLE DU CONTENU, PAS UN NOMBRE HERITE — DEFAUT VU A LA
   CAPTURE, PAS AU RELEVE. Le menu de l'avatar est calibre sur « Changer la
   couleur » et vit avec un plancher de 206 px ; « Statistiques détaillées » est
   plus long, et il passait a la ligne. Mes chiffres disaient pourtant tout juste :
   trois entrees, hauteurs 44/45/44 — c'est la ligne de 45 qui etait le symptome,
   et je l'avais lue comme un arrondi. **Une hauteur qui depasse d'un pixel est un
   texte qui a plie, pas une valeur qui a glisse.**
   `max-content` fait la largeur du plus long libelle ; le plancher reste pour que
   le menu ne maigrisse jamais sous celui de l'avatar, et le plafond l'empeche de
   sortir de l'ecran en Grand texte, ou il replie alors normalement. */
#s-compte .c-menu.droite{left:auto;right:0;transform-origin:100% 0;
  width:max-content;max-width:calc(100vw - 54px)}
/* ⚠️ 36 px VISIBLES, 44 DE CIBLE, comme la fleche a l'autre bout de la barre :
   deux commandes de meme rang aux deux bouts d'une barre pesent pareil. Le
   `::after` etend la zone sans changer la taille du dessin. */
#s-compte .topbar>#cp-plus-z{justify-self:end}
#s-compte #cp-plus{position:relative;width:36px;height:36px;min-height:0;
  border:0;border-radius:var(--r-1);background:rgba(255,255,255,.07);
  display:grid;place-items:center;cursor:pointer;color:var(--c-texte-2);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte #cp-plus::after{content:'';position:absolute;inset:-4px}
#s-compte #cp-plus:active{transform:scale(.94);background:rgba(255,255,255,.14)}
#s-compte #cp-plus svg{width:19px;height:19px;fill:currentColor;stroke:none}
/* le rouge de l'irreversible, la regle du socle : il ne teinte que le retrait */
#s-compte .c-mit.rouge{color:#F87171}
#s-compte .c-mit.rouge svg{stroke:#F87171}

/* ══ §3.8 · LA ROUE DE TEINTES ══
   ⚠️⚠️ LA CLARTE EST CONFISQUEE, ET C'EST CE QUI REND LA ROUE POSSIBLE. Le
      doigt regle la TEINTE (l'angle) et la SATURATION (le rayon) ; la
      clarte, JAMAIS. Mesure : #170B20 sur hsl(240,82%,63%) tombe a 3,48:1.
      A 72 %, le pire cas de toute la roue (216 combinaisons) remonte a
      5,51:1. Une roue n'est utilisable que si l'une de ses trois dimensions
      est confisquee : on ne peut pas laisser choisir librement une couleur
      qui doit porter une LETTRE.
   ⚠️⚠️ L'ETAT DE DEPART EST EN CSS, PAS DANS LE SCRIPT. Le rendu se cassait
      dans l'apercu des Fichiers d'iOS (avatar noir, bouton noir, curseur
      jete dans un coin) : cet apercu n'execute pas le JavaScript, et sans
      --t-h / --t-s, `hsl(var(--t-h) …)` est une valeur INVALIDE, donc la
      declaration entiere est jetee. Un rendu ne doit jamais dependre de son
      script pour son etat de depart.
   ⚠️ aspect-ratio:1 PLUTOT QU'UNE HAUTEUR ECRITE : une forme dont la rondeur
      est une coincidence entre deux nombres n'est pas ronde, elle l'est par
      hasard.
   ⚠️ LE BORD EXTERIEUR EST UN ANNEAU DETACHE (3 px de fond puis le filet) :
      un trait pose CONTRE un disque devient son contour, un trait pose a
      DISTANCE devient sa limite. Et le filet est SOMBRE — le filet d'une
      surface claire est l'inverse de celui d'une surface sombre.
   ⚠️ LE CURSEUR NE S'ANIME PAS PENDANT LE GESTE : ce qui suit un doigt ne
      s'interpole jamais, c'est ce qui donne l'impression qu'un ecran est
      lent. */
#s-compte .c-roue-bloc{ --t-l:72%; --t-h:258deg; --t-s:82%; --t-lhi:76%; --t-llo:66%;
  flex:1 1 auto;display:flex;flex-direction:column;justify-content:center;
  margin-bottom:var(--e-7)}
#s-compte .c-roue{position:relative;width:240px;aspect-ratio:1;border-radius:50%;
  margin:0 auto;flex:0 0 auto;touch-action:none;cursor:pointer;
  background:
    radial-gradient(circle closest-side,
      hsl(0 0% 100% / 1) 0%, hsl(0 0% 100% / 0) 78%),
    conic-gradient(
      hsl(0 82% var(--t-l)),   hsl(30 82% var(--t-l)),
      hsl(60 82% var(--t-l)),  hsl(90 82% var(--t-l)),
      hsl(120 82% var(--t-l)), hsl(150 82% var(--t-l)),
      hsl(180 82% var(--t-l)), hsl(210 82% var(--t-l)),
      hsl(240 82% var(--t-l)), hsl(270 82% var(--t-l)),
      hsl(300 82% var(--t-l)), hsl(330 82% var(--t-l)),
      hsl(360 82% var(--t-l)));
  box-shadow:inset 0 0 0 .34px rgba(23,11,32,.28),
             0 0 0 3px var(--bg),
             0 0 0 3.34px rgba(255,255,255,.22),
             0 14px 34px -16px rgba(0,0,0,.8)}
#s-compte .c-curseur{position:absolute;width:30px;height:30px;border-radius:50%;
  margin:-15px 0 0 -15px;pointer-events:none;left:9.9%;top:58.5%;
  box-shadow:0 0 0 3px rgba(255,255,255,.96),
             0 0 0 4.6px rgba(0,0,0,.34),
             0 3px 9px -2px rgba(0,0,0,.5);
  background:hsl(var(--t-h) var(--t-s) var(--t-l));
  transition:background .12s linear}
#s-compte .c-apercu{margin:0 auto var(--e-4);width:88px;height:88px;border-radius:50%;
  display:grid;place-items:center;font-size:var(--t-6);font-weight:700;
  color:#170B20;
  background:linear-gradient(180deg, hsl(var(--t-h) var(--t-s) var(--t-lhi)) 0%,
                                     hsl(var(--t-h) var(--t-s) var(--t-llo)) 100%);
  box-shadow:0 0 0 2px rgba(250,249,252,.95),
             0 0 0 4.5px hsl(var(--t-h) var(--t-s) var(--t-llo));
  transition:background .12s linear,box-shadow .12s linear}
#s-compte .c-valider{position:relative;flex:0 0 auto;margin:var(--e-5) auto 0;
  align-self:center;width:max-content;min-width:150px;padding:0 var(--e-5);border:0;
  display:flex;align-items:center;justify-content:center;
  height:40px;border-radius:999px;cursor:pointer;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;color:#170B20;
  background:linear-gradient(180deg,
    hsl(var(--t-h) var(--t-s) calc(var(--t-l) + 9%)) 0%,
    hsl(var(--t-h) var(--t-s) var(--t-l)) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32);
  transition:transform .16s var(--ease),background .12s linear}
#s-compte .c-valider::after{content:'';position:absolute;inset:-2px}
#s-compte .c-valider:active{transform:scale(.95)}

/* ══════════════════════════════════════════════════════════════════════
   [07/08] LOT COMPTE — ALIGNEMENT AU CARACTERE PRES SUR LES ONZE RENDUS
   Deuxieme passe : les rendus livres montrent des cotes et des composants
   que la premiere lecture du document ne donnait pas.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠️ LA CARTE « THEO » : MEME TON QUE LES GROUPES, et c'est un renoncement
   voulu. Elle etait plus claire pour marquer un niveau 3 ; sur l'appareil,
   ce bloc plus clair que tous les autres etait la premiere chose que l'oeil
   accrochait, et il n'avait rien de plus a dire. Dans les Reglages d'iOS,
   la carte du compte a EXACTEMENT la surface des autres : sa place et son
   contenu suffisent. */
#s-compte .c-moi{gap:var(--e-3)}
#s-compte .c-moi:active{transform:scale(.985);background:var(--card-2)}
/* ⚠️⚠️ [11/08, Theo] PLUS DE POINT DE PRESENCE SUR SA PROPRE CARTE. « On
   sait qu'on est en ligne vu que c'est nous-memes qui utilisons le compte. »
   Il a raison, et la raison est plus generale : UN INDICATEUR QUI NE PEUT
   AVOIR QU'UNE SEULE VALEUR N'INFORME DE RIEN. Sur sa propre carte, ce point
   etait vert a chaque ouverture, sans exception possible ; il occupait la
   place d'un signal en n'en portant aucun.
   ⚠️ IL RESTE PARTOUT OU IL DIT QUELQUE CHOSE : sur la bobine, dans la liste
      d'amis, sur le profil d'un ami, dans les discussions. La ou il peut
      etre vert OU gris, il informe.
   ⚠️ ET LE COMMENTAIRE D'ORIGINE RESTE VRAI POUR LE RESTE : le socle reserve
      le vert 145° au compte connecte. Cet ecran n'a simplement plus de vert. */
#s-compte .c-moi-av{width:52px;height:52px;font-size:var(--t-4);letter-spacing:0;
  background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);
  box-shadow:0 0 0 2px var(--card-2),0 0 0 3px #9B7BF2}
#s-compte .c-moi-t b{font-size:var(--t-4);font-weight:600;letter-spacing:-.01em}
/* ⚠️ UN CRAYON, PAS UN CHEVRON, ET IL NE SORT PAS LE CHEVRON DE LA CARTE :
   le chevron dit qu'on se DEPLACE, le crayon dit ce qu'on trouvera la-bas.
   ⚠️ 10 px ET NON 12 : un glyphe en ligne se cale sur la HAUTEUR D'X de sa
      ligne, pas sur son corps. A 13 px de texte, l'x fait environ 6,5 px ;
      un crayon de 12 depassait au-dessus et en dessous, et c'est ce qui le
      faisait paraitre colle.
   ⚠️ IL PREND LA COULEUR DU MOT : un glyphe pose dans une ligne de texte
      appartient a sa phrase ; plus sombre qu'elle, il se decrocherait. */
/* ⚠️⚠️ [07/08, Theo] « LA DESCRIPTION EST TROP ESPACEE, PRENDS EXEMPLE SUR LES
   AUTRES EN DESSOUS. » Mesure a l'ecran, iPhone 393, avant correction :
        carte du pseudo   bas du nom 153  ·  haut du sous-titre 158  ->  5 px
        rangees en dessous  bas du titre 278,5 · haut du sous-titre 280,5 -> 2 px
   ⚠️ ET LES 3 PX DECLARES N'EXPLIQUAIENT QUE LA MOITIE DE L'ECART. Le sous-titre
      etait passe en `inline-flex` : un element de ligne est pose dans une BOITE
      DE LIGNE, dont la hauteur vient de la police du parent, et cette boite
      ajoutait 2 px que rien dans la feuille ne montrait. La rangee, elle, est en
      `block` : sa marge est son ecart, au pixel pres.
      **Une marge ne dit la verite que sur un element de bloc.** On repasse donc
      en `flex` (bloc, et le glyphe reste centre sur le texte) et on aligne la
      marge sur celle des rangees : 2 px, meme valeur, meme resultat mesure. */
#s-compte .c-moi-t small{display:flex;margin-top:2px;color:var(--c-texte-3)}
#s-compte .c-moi-t small svg{width:10px;height:10px;stroke:currentColor;
  stroke-width:2}

/* ⚠️ UNE RANGEE DESTRUCTRICE TEINTE SON TITRE, pas seulement sa tuile : sur
   un ecran de six rangees, une tuile rouge seule se lit comme une categorie.
   Le sous-titre, lui, reste gris — c'est le titre qui porte l'alerte. */
#s-compte .c-ligne.danger{color:#F87171}
#s-compte .c-ligne.danger .c-txt b{color:currentColor}
#s-compte .c-ligne.danger .c-txt small{color:var(--c-texte-3)}
/* la sortie n'est pas une destruction : son sous-titre s'eclaircit d'un ton
   pour dire qu'elle se defait (« Reconnecte-toi a tout moment »). */
#s-compte .c-ligne.sortie .c-txt small{color:var(--c-texte-3)}

/* ⚠️ LA VERSION EST UNE INFORMATION, PAS UN BOUTON : ni gelule, ni cible,
   ni :active. Centree parce qu'elle ne se lit pas, elle se CHERCHE. Ce qu'on
   ne lit qu'une fois par an peut etre centre ; ce qu'on lit se range a
   gauche. */
#s-compte .c-pied{flex:0 0 auto;margin-top:var(--e-4);text-align:center;
  font-size:var(--t-1);letter-spacing:.02em;color:var(--c-texte-3)}
#s-compte .c-pied.gauche{margin:var(--e-3) 4px 0;text-align:left;font-size:var(--t-1);
  line-height:1.45;color:var(--c-texte-3);letter-spacing:0}

/* ══ §3 · LA CARTE DE SCORE DU PROFIL ══
   ⚠️ LE FILET QUI SEPARE LE SCORE DES QUATRE MESURES TRAVERSE TOUTE LA
      CARTE : il ne separe pas deux categories mais deux NIVEAUX de lecture,
      un chiffre qui resume et quatre qui detaillent. Un filet pleine largeur
      dit « la suite est d'un autre ordre » ; un filet en retrait dirait
      « la suite est une rangee de plus ».
   ⚠️ 40 DE CORPS POUR LE NOMBRE, pas 33 comme au releve : la reference n'a
      qu'un chiffre a montrer et nous en avons quatre de plus dessous. Un
      nombre n'est pas gros dans l'absolu, il est gros par rapport a ceux qui
      l'entourent. `tabular-nums` : un score change, et des chiffres de
      largeurs differentes feraient sauter le mot « pts ». */
#s-compte .c-carte-p{flex:0 0 auto;border-radius:var(--r-3);background:var(--card-2);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.07);
  overflow:hidden;margin-bottom:var(--e-4)}
#s-compte .c-score{position:relative;padding:var(--e-3) var(--e-3) var(--e-3)}
#s-compte .c-score-tete{display:flex;align-items:center;gap:var(--e-2);
  font-size:var(--t-2);font-weight:500;color:var(--c-texte-3)}
/* ⚠️ LE « i » EST UN VRAI BOUTON, PAS UN ORNEMENT : il porte la seule chose
   que l'ecran ne peut pas montrer, COMMENT LE SCORE SE CALCULE. Et c'est la
   qu'on ecrit que les points viennent d'une PERFORMANCE, pas d'une
   consommation — c'est un point de conformite, pas une note de bas de page.
   ⚠️ 12 px ET NON 11 : le plancher UI-04 ne descend pas sous 12, et sa seule
      derogation est l'unite « pts » d'une LISTE. Un « i » est une LETTRE, il
      se lit seul, donc il obeit au plancher. Une derogation reste attachee au
      cas qui l'a justifiee. */
#s-compte .c-info{position:relative;width:19px;height:19px;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;border:0;
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.26);
  font-size:var(--t-1);font-weight:700;color:var(--c-texte-3);background:none;
  transition:background .16s var(--ease)}
#s-compte .c-info::after{content:'';position:absolute;inset:-12.5px}
#s-compte .c-info:active{background:rgba(255,255,255,.10)}
#s-compte .c-valeur{display:flex;align-items:baseline;gap:var(--e-1);margin-top:var(--e-2)}
#s-compte .c-valeur b{font-size:var(--t-6);font-weight:700;letter-spacing:-.03em;
  line-height:1;color:var(--c-texte);font-variant-numeric:tabular-nums}
/* ⚠️ « pts » A 12 ET NON 9 : la derogation du Classement vaut pour une unite
   collee a un score de LISTE, repetee douze fois, qu'on ne lit jamais. Ici
   l'unite est ecrite UNE fois, sur le chiffre principal de l'ecran. */
#s-compte .c-valeur small{font-size:var(--t-1);font-weight:600;letter-spacing:.01em;
  color:#A78BFA}
/* « Top 3 % » est la seule mesure qui SITUE par rapport aux autres : d'où le
   violet, la seule information dont on veut qu'elle attire l'oeil apres le
   nombre lui-meme. */
#s-compte .c-rang{display:flex;align-items:center;gap:var(--e-2);margin-top:var(--e-2);
  font-size:var(--t-1);font-weight:600;color:#A78BFA}
#s-compte .c-rang svg{width:13px;height:13px;fill:none;stroke:#FCD34D;
  stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️⚠️ LA COUPE REMPLACE L'ILLUSTRATION VOLUMETRIQUE, ET CE N'EST PAS UN
   APPAUVRISSEMENT : l'app n'a AUCUN objet de ce type hors des spheres du
   podium. Importer une illustration ici creerait une famille visuelle
   entiere pour un seul ecran. On reprend donc la coupe deja dessinee pour la
   premiere place du Classement, agrandie et posee dans un halo dore — et son
   halo est celui du podium, deux drop-shadow dont un lointain plus un voile
   radial. C'est la seule facon de faire briller sans peindre. */
#s-compte .c-coupe{position:absolute;top:16px;right:14px;width:76px;height:76px;
  display:grid;place-items:center;pointer-events:none}
#s-compte .c-coupe::before{content:'';position:absolute;inset:-10px;
  border-radius:50%;
  background:radial-gradient(closest-side,rgba(252,211,77,.13),transparent 72%)}
#s-compte .c-coupe svg{position:relative;width:64px;height:64px;fill:none;
  stroke:#FCD34D;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 9px rgba(252,211,77,.34))
         drop-shadow(0 0 24px rgba(252,211,77,.16))}

/* ══ §3.7 · LES BADGES, EN CARTE ══ */
#s-compte .c-badges-c{padding:var(--e-3) var(--e-3) var(--e-3)}
#s-compte .c-badges-tete{display:flex;align-items:baseline;
  justify-content:space-between;margin-bottom:var(--e-3)}
#s-compte .c-badges-tete h2{font-size:var(--t-3);font-weight:600;
  letter-spacing:-.015em;color:var(--ink)}
/* « Voir tout » est un LIEN, pas un bouton : ni gelule ni contour. Ce qui se
   lit comme une phrase se traite comme une phrase. Cible a 44 par ::after. */
#s-compte .c-tout{position:relative;font-size:var(--t-2);font-weight:600;
  color:#A78BFA;cursor:pointer;border:0;background:none;
  transition:opacity .16s var(--ease)}
#s-compte .c-tout::after{content:'';position:absolute;inset:-13px -10px}
#s-compte .c-tout:active{opacity:.55}
/* ⚠️ [07/08] minmax(0,1fr) ET NON 1fr : `1fr` vaut minmax(AUTO,1fr), donc une
   colonne dont le nom est long refuse de descendre sous sa largeur de contenu.
   Mesure avant correction, avec « Le distributeur » en troisieme : 49,6 · 49,6 ·
   58,6 · 49,6 · 49,6 — un hexagone plus gros que ses quatre voisins, sans que
   rien dans la feuille ne parle de largeur. **Cinq colonnes egales se declarent,
   elles ne se supposent pas.** Meme piege que la barre du haut, deja corrige la. */
#s-compte .c-badges{grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--e-2)}
#s-compte .c-badge{cursor:pointer;transition:transform .16s var(--ease);
  border:0;background:none;gap:var(--e-2)}
#s-compte .c-badge:active{transform:scale(.94)}
/* ⚠️ [07/08] LE GLYPHE NE REMONTE QUE S'IL Y A UN NOMBRE SOUS LUI. Les 9 px
   etaient poses sur TOUS les hexagones ; comme aucun badge n'affichait de
   compte, chaque dessin flottait au-dessus d'un vide de 9 px sans qu'aucune
   regle ne dise pourquoi. La place se reserve pour ce qui existe : c'est le
   contenu qui pose `avec-compte`, pas la feuille qui suppose. */
#s-compte .c-hex svg{width:25px;height:25px;stroke-width:1.75;margin-bottom:0}
#s-compte .c-hex.avec-compte svg{margin-bottom:var(--e-2)}
/* ⚠️ LE COMPTE EST DANS L'HEXAGONE, SOUS LE GLYPHE : il qualifie le BADGE,
   pas le joueur. Sorti de la forme, il se lirait comme une statistique de
   plus. 12 px et non 11 : un compte de badge est un NOMBRE qu'on lit, pas
   une unite qu'on reconnait. */
#s-compte .c-hex i{position:absolute;bottom:14%;font-style:normal;
  font-size:var(--t-1);font-weight:700;color:rgb(var(--bt));
  font-variant-numeric:tabular-nums}
#s-compte .c-badge small{font-weight:500;letter-spacing:-.005em}
#s-compte .c-badge.verrou .c-hex::before{background:rgba(255,255,255,.045)}
/* (la regle « le verrouille ne remonte pas son glyphe » est retiree : elle
   redisait le defaut. Un verrou n'a jamais de compte, donc jamais `avec-compte`,
   donc jamais de decalage. Deux regles pour un seul effet, c'est celle qu'on
   oublie de corriger qui reste.) */

/* ⚠️ LA PASTILLE DE RETOUCHE EST POSEE SUR LA CIRCONFERENCE, PAS A L'OEIL :
   rayon 44 + bague 4,5 = 48,5 ; a 45°, 48,5/racine(2) = 34,3 en x comme en y
   depuis le centre, donc 65 depuis le bord. Posee a l'oeil elle est toujours
   fausse d'un pixel ou deux ; posee sur la circonference elle est juste, et
   le reste si le disque change de taille. */
#s-compte .c-retouche{right:auto;bottom:auto;left:65px;top:65px}
#s-compte .c-grand{position:relative}

/* ══════════════════════════════════════════════════════════════════════════
   [07/08] LES TROIS ONGLETS VERROUILLES — UN SEUL DESSIN, TROIS TEINTES
   Porte du lot « PORTAGE — LES TROIS ECRANS VERROUILLES » (07/08). Classement,
   Discussions et Amis sans compte sont LE MEME ECRAN : seuls le titre,
   l'embleme, sa teinte et la phrase changent. Le reste — halo, particules,
   accroche, boutons — est identique au caractere pres.

   ⚠️⚠️ LES JETONS DU DOSSIER NE SONT PAS CEUX DE CE SOCLE, ET LA CONFUSION EST
      PIEGEUSE. Le dossier ecrit `--text`, `--muted`, `--violet-hi`, `--or-hi`,
      `--sarcelle-hi` : AUCUN N'EXISTE ICI. Le socle declare `--ink` (le texte,
      #f4f4f7) et `--mut` (le texte secondaire). Et le dossier appelle `--ink`
      l'ENCRE SOMBRE des surfaces violettes (#170B20) — c'est-a-dire l'inverse
      de notre `--ink`. Ecrire color:var(--ink) sur le bouton plein aurait
      donne du blanc casse la ou il faut du presque-noir : 4,23:1 au lieu de
      4,49:1, au point le plus defavorable du degrade.
      ⚠️ ET UNE VARIABLE ABSENTE REND LA DECLARATION INVALIDE EN SILENCE : la
         couleur retombe sur l'heritage, aucun inspecteur ne barre la ligne.
      Les tons hauts sont donc ecrits en LITTERAL, comme partout ailleurs dans
      cette feuille. #8FB4FF (le bleu d'Amis) n'entre pas dans :root non plus :
      un jeton ajoute pour un seul ecran fait diverger les blocs de jetons.
   ══════════════════════════════════════════════════════════════════════════ */

/* ⚠️ LES TROIS ECRANS SE CALENT SUR LES MEMES QUATRE COTES. Ils ne les avaient
   pas : Amis ouvrait a 8 px du haut, Classement et Discussions a 18 ; et
   Discussions ajoutait 4 px de chaque cote par son corps (14 + 4 = 18) que les
   deux autres n'ont pas. DEUX REMBOURRAGES QUI S'ADDITIONNENT NE SE VOIENT
   DANS AUCUN DES DEUX : les boutons auraient ete 8 px plus etroits sur le seul
   Discussions, et personne n'aurait su lequel des deux fichiers mentait.
   ⚠️ LA SPECIFICITE EST CALCULEE, PAS ESPEREE : #s-amis pese (1,0,0) et
      #s-multi.avec-barre:not(.au-fil) pese (1,2,0). Les selecteurs ci-dessous
      pesent (1,1,0) et (1,3,0) : ils gagnent par leur poids, pas par leur
      place dans le fichier. */
#s-classement.vq-on,
#s-amis.vq-on,
#s-multi.vq-on.avec-barre:not(.au-fil){
  padding:calc(var(--e-2) + env(safe-area-inset-top,0px))
          calc(var(--e-3) + env(safe-area-inset-right,0px))
          calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 74px)
          calc(var(--e-3) + env(safe-area-inset-left,0px))}
/* ⚠️ DISCUSSIONS MASQUE SA BARRE DE TITRE : le composant porte la sienne, aux
   memes cotes. Deux barres empilees auraient decale ce seul ecran des deux
   autres, et le paragraphe 7 du dossier demande que passer de l'un a l'autre
   ne fasse bouger QUE l'embleme, le titre et la phrase. */
#s-multi.vq-on>.topbar{display:none}
#s-multi.vq-on>#mu-body{padding:0}
/* ⚠️⚠️ LE CORPS NE SE COMPRIME PAS : `flex:1 0 auto`, ET C'EST UN ECART AU DOSSIER.
   Mesure a 320x568 en Grand texte avec le `1 1 auto` du dossier : le bloc etait comprime
   a 402 px pour un contenu de 480, son debordement ne comptait PAS dans la hauteur
   defilante de l'ecran (scrollHeight 568 = clientHeight 568), et « Se connecter » finissait
   a 566 — SOUS la barre du bas, sans aucun moyen d'en sortir. Le dossier ne pouvait pas le
   voir : chez lui `.app` est une page qui s'allonge, ici `.screen` est une boite qui defile,
   et un enfant qu'on autorise a retrecir ne fait jamais defiler son parent.
   ⚠️ RIEN NE BOUGE QUAND CA RENTRE : a flex-basis auto, l'element demande sa hauteur de
      contenu puis `flex-grow:1` l'etire jusqu'au bas. Verifie a 402x844 : bloc de 678 px,
      contenu centre au pixel (425,05 contre 425,00 pour le milieu de la boite). */
#s-classement.vq-on>#cm-body,
#s-amis.vq-on>#am-body,
#s-multi.vq-on>#mu-body{display:flex;flex-direction:column;flex:1 0 auto}

/* ══ LA BARRE DE TITRE ══
   Pas de fleche de retour : c'est un onglet, il n'y a rien derriere. Cotes du
   socle des ecrans d'app : 44 de haut, 32 dessous, 21/600 centre. */
.vq-titre{position:relative;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;min-height:44px;margin:2px 0 var(--e-5)}
.vq-titre h1{flex:0 0 auto;max-width:100%;font-size:var(--t-4);font-weight:600;
  letter-spacing:-.015em;line-height:1.2;color:var(--c-texte)}

/* ══ LE BLOC CENTRE ══
   ⚠️⚠️ AUCUNE COMPENSATION ICI. L'ecran reserve DEJA les 74 px de la barre du
      bas (regle .screen.avec-barre, reprise ci-dessus). Une marge basse
      recopiee d'un ecran sans barre remonterait le bloc de la moitie de sa
      valeur au-dessus de son vrai centre. UNE COMPENSATION SE RECALCULE DANS
      LE FICHIER OU ON LA POSE.
   ⚠️ ET LE DEFAUT SERAIT INVISIBLE A L'OEIL : le halo deborde de 84 px vers le
      haut et tire le regard. Une masse lumineuse fausse le jugement de
      centrage — on mesure la boite, on ne juge pas la lueur. */
.vq-bloc{flex:1 0 auto;display:flex;flex-direction:column;justify-content:center}

/* ══ LA SCENE ET SA LUMIERE ══
   ⚠️ CE QUI REND UN HALO INVISIBLE, C'EST LA PENTE, PAS LA TAILLE. Une
      decroissance reguliere produit toujours un anneau perceptible : l'oeil
      detecte la pente constante et en deduit un bord. Les arrets suivent la
      loi du carre de la distance — la moitie de l'intensite est depensee dans
      le premier quart du rayon.
   ⚠️ LE HALO SE TERMINE AVANT SA BOITE : extinction a 64 pour cent pour un
      debordement de 84 px, donc le dernier tiers est du fond pur. Deux limites
      au meme endroit se renforcent, et le halo redevient un disque. Aucun
      border-radius non plus : une nappe radiale n'a pas besoin qu'on lui
      decoupe un cercle, elle en est un.
   ⚠️ L'ASYMETRIE PASSE PAR UN MASQUE, JAMAIS PAR UNE DEFORMATION. On ne
      deplace pas la source et on ne deforme pas le cercle : on retire de la
      lumiere la ou il n'y a pas de raison qu'il y en ait. Prefixe -webkit-
      d'abord ; si le masque n'est pas honore, le halo reste correct, seulement
      symetrique — une degradation qui n'abime rien.
   ⚠️ LA BOITE EPOUSE L'EMBLEME : 152 pour 136. Un ecart qu'on lit dans la
      feuille n'est le vrai ecart que si les boites epousent ce qu'elles
      contiennent. La lumiere, elle, ne retrecit pas avec : les nappes sont en
      inset negatif. */
.vq-scene{position:relative;flex:0 0 auto;align-self:center;
  width:152px;height:152px;margin:0 0 var(--e-4)}
.vq-scene::before{content:'';position:absolute;inset:-84px;pointer-events:none;
  background:radial-gradient(circle at 50% 50%,
    rgba(139,92,246,.10) 0%,
    rgba(139,92,246,.042) 16%,
    rgba(139,92,246,.015) 30%,
    rgba(139,92,246,.005) 44%,
    rgba(139,92,246,.0012) 56%,
    transparent 64%);
  -webkit-mask-image:linear-gradient(to bottom,
    #000 0%, #000 38%, rgba(0,0,0,.55) 62%,
    rgba(0,0,0,.22) 82%, rgba(0,0,0,.08) 100%);
  mask-image:linear-gradient(to bottom,
    #000 0%, #000 38%, rgba(0,0,0,.55) 62%,
    rgba(0,0,0,.22) 82%, rgba(0,0,0,.08) 100%);
  animation:vqSouffle 9s var(--ease) infinite}
/* ⚠️ LA RESPIRATION PORTE SUR UN PSEUDO-ELEMENT : on anime la lumiere, pas ce
   qu'elle eclaire. Animer la boite deplacerait l'embleme et les particules.
   Une seule animation sur l'ecran : un ecran qui attend une decision a le
   droit d'etre vivant, pas d'etre occupe. */
@keyframes vqSouffle{0%,100%{opacity:.76;transform:scale(.96)}
  50%{opacity:1;transform:scale(1.05)}}
/* deux couches, pas trois : un noyau serre derriere l'objet, une diffusion
   large loin derriere. Une lumiere naturelle est une seule source vue de deux
   distances — et un seul centre, sinon deux lueurs decentrees creent une
   frange la ou elles se croisent. */
.vq-scene::after{content:'';position:absolute;inset:-4px;pointer-events:none;
  background:radial-gradient(circle at 50% 50%,
    rgba(167,139,250,.14) 0%,
    rgba(167,139,250,.062) 18%,
    rgba(167,139,250,.020) 34%,
    rgba(167,139,250,.005) 48%,
    transparent 58%)}
/* ⚠️ L'EPAISSEUR DE TRAIT SE RECALCULE A LA TAILLE D'USAGE, elle ne se copie
   pas : 0,75 sur un viewBox de 24 rendu a 136 px vaut 4,25 px, le poids
   optique des glyphes de la barre du bas. */
.vq-embleme{position:absolute;left:50%;top:50%;width:136px;height:136px;
  transform:translate(-50%,-50%);fill:none;
  stroke-width:.75;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ TROIS PARTICULES, PAS CINQ : a cinq elles forment une constellation ;
   trois points ne font jamais de motif, ils font un accident. Trois tailles,
   trois opacites, la plus grande la plus pale — trois points identiques se
   lisent comme une repetition, trois points differents comme une profondeur.
   Aucune sur un axe (un point a la verticale du centre se lit comme un
   repere), aucune ne bouge (le halo respire deja, et deux mouvements lents
   dans le meme cadre donnent l'impression que l'ecran tremble). Positions
   calculees sur un cercle : centre (76, 76), angles 200 / 340 / 75 degres,
   distances 88 / 84 / 88, moins la demi-taille. */
.vq-gr{position:absolute;border-radius:50%;pointer-events:none}
.vq-g1{width:5px;height:5px;left:-9.2px;top:103.6px;background:rgba(167,139,250,.30)}
.vq-g2{width:3px;height:3px;left:153.4px;top:103.2px;background:rgba(249,168,212,.26)}
.vq-g3{width:2px;height:2px;left:97.8px;top:-10px;background:rgba(167,139,250,.44)}

/* ══ LA SEULE DIFFERENCE ENTRE LES TROIS ══
   ⚠️⚠️ LA TEINTE DE L'EMBLEME N'EST PAS UNE NAPPE, ELLE EST PORTEE PAR
      L'OBJET. Une ombre portee epouse la silhouette de ce qui l'emet ; une
      nappe radiale ne connait que le cercle. Une coupe qui rayonne en disque,
      c'est une coupe posee DEVANT une lampe, pas une coupe qui brille. Deux
      drop-shadow serres a 9 et 22, et la couleur du mode ne doit pas atteindre
      le violet : des qu'ils se touchent, on voit deux couleurs se melanger au
      lieu d'un objet qui brille.
   ⚠️ LE HALO, LES PARTICULES ET LES BOUTONS RESTENT VIOLETS SUR LES TROIS : la
      couleur appartient au mode pour l'embleme, a l'app pour l'action. */
.vq-scene.vq-or .vq-embleme{stroke:#FCD34D;
  filter:drop-shadow(0 0 9px rgba(252,211,77,.42))
         drop-shadow(0 0 22px rgba(252,211,77,.15))}
.vq-scene.vq-sarcelle .vq-embleme{stroke:#5EEAD4;
  filter:drop-shadow(0 0 9px rgba(94,234,212,.40))
         drop-shadow(0 0 22px rgba(94,234,212,.14))}
.vq-scene.vq-bleu .vq-embleme{stroke:#8FB4FF;
  filter:drop-shadow(0 0 9px rgba(143,180,255,.40))
         drop-shadow(0 0 22px rgba(143,180,255,.14))}

/* ══ L'ACCROCHE ══
   ⚠️ 32/700 SUR DEUX LIGNES : la seule grande cote de l'echelle qui convienne.
      Une accroche n'invente pas un corps, elle emprunte le plus grand qui
      existe. Interligne 1,08 : un titre de deux lignes n'a pas d'interligne,
      il a une hauteur de bloc.
   ⚠️ L'ACCENT EST UNE COULEUR DU SOCLE, PAS UN DEGRADE. Aucun texte de cette
      app n'est en degrade hors du mot-symbole de la marque : on accentue avec
      une couleur qu'on a deja, jamais avec une matiere qu'on invente.
   ⚠️ LA MESURE EST BORNEE A 272, et ce n'est pas qu'une question de lecture :
      sans borne, un texte centre se coupe ailleurs sur chaque appareil, et une
      coupure qui bouge sur deux lignes centrees, c'est une composition qui
      bouge.
   ⚠️ LES MARGES SONT REMISES A PLAT : le h2 du socle porte margin-bottom:4px
      qui se serait ajoute aux 8 de la phrase sans se voir dans aucun des deux. */
.vq-accroche{flex:0 0 auto;text-align:center;margin:0 0 var(--e-4)}
.vq-accroche h2{margin:0;font-size:var(--t-5);font-weight:700;letter-spacing:-.032em;
  line-height:1.08;color:var(--c-texte)}
.vq-accroche h2 i{font-style:normal;color:#A78BFA}
.vq-accroche p{max-width:272px;margin:var(--e-2) auto 0;
  font-size:var(--t-2);line-height:1.42;color:var(--mut)}

/* ══ LES DEUX ISSUES ══
   ⚠️ MEME GABARIT POUR LES DEUX : deux actions de meme rang portent le meme
      gabarit et se distinguent par la matiere, pas par la taille. Rempli pour
      la premiere, voile pour la seconde — la grammaire d'Accepter / Refuser.
   ⚠️⚠️ RAYON 16, PAS 999. Une gelule pleine largeur a un rayon de 25 : a cette
      largeur, la gelule cesse d'etre une forme, elle devient deux demi-cercles
      relies par une barre. 16 sur 50, c'est 0,32, le rapport des carres
      arrondis du socle.
   ⚠️ 16 DE MARGE DE CHAQUE COTE, soit 34 depuis le bord d'ecran : un bouton
      qui touche les memes bords que la liste se lit comme un bloc de la page ;
      recule, il se lit comme un objet pose dessus.
   ⚠️ TEXTE EN 600, PAS 700 : sur un bouton, la matiere porte deja
      l'insistance. Glyphes a 1,55 : un glyphe de bouton n'a pas a peser autant
      que son texte.
   ⚠️⚠️ ET font-family:inherit + border:0 + une color EXPLICITE SUR CHAQUE
      VARIANTE. Un bouton sans remise a zero est peint par le navigateur : fond
      gris, bordure 2px outset rendue en relief clair par WebKit, Arial
      13,3 px. Ce socle n'a PAS de regle button globale — chaque bouton paie sa
      propre remise a zero, et l'oubli est deja passe en production. */
.vq-issue{position:relative;flex:0 0 auto;
  width:calc(100% - 32px);align-self:center;min-height:50px;
  display:flex;align-items:center;justify-content:center;gap:var(--e-2);
  padding:0 var(--e-4);border-radius:var(--r-2);border:0;cursor:pointer;
  font-family:inherit;font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;
  transition:transform .16s var(--ease),background .16s var(--ease),
             box-shadow .16s var(--ease)}
.vq-issue:active{transform:scale(.985)}
.vq-issue .vq-g{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:1.55;stroke-linecap:round;stroke-linejoin:round}
/* ⚠️ LA LUEUR SOUS LE BOUTON PRINCIPAL — TROIS COUCHES : un lisere de lumiere
   en haut, une ombre noire courte qui l'assied, une lueur violette longue qui
   l'eclaire. Etalement negatif partout, sinon le halo devient une aureole a
   bord net. La lueur est de la couleur du bouton, pas noire : une ombre noire
   sous un objet colore le salit, une lueur de sa propre teinte le pose. Elle
   s'eteint a l'appui — un objet qui s'enfonce ne peut pas continuer a flotter.
   ⚠️ ENCRE SOMBRE #170B20 ET NON BLANCHE : 4,49:1 sur le bas du degrade contre
      4,23 pour le blanc. Sur un degrade, un contraste se verifie a son point
      le plus defavorable, pas a sa moyenne. */
.vq-issue.vq-creer{background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  color:#170B20;margin-bottom:var(--e-3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),
             0 4px 10px -6px rgba(0,0,0,.55),
             0 14px 30px -14px rgba(139,92,246,.62),
             0 0 22px -8px rgba(139,92,246,.28)}
.vq-issue.vq-creer:active{background:linear-gradient(180deg,#9A78FA 0%,#7C4DF0 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),
             0 2px 6px -5px rgba(0,0,0,.5),
             0 6px 16px -12px rgba(139,92,246,.4)}
/* ⚠️⚠️ LA SECONDE ISSUE EST DELIBEREMENT AFFAIBLIE, et c'est le seul endroit
   de l'app ou l'on affaiblit un bouton qui marche. La regle du socle —
   l'affaiblissement veut dire indisponible — vaut entre un objet et lui-meme.
   Ici les deux sont allumes et voisins : ce n'est plus un etat, c'est une
   HIERARCHIE. Son encre reste a 6,42:1 : une seconde issue se met en retrait,
   elle ne se cache pas. */
.vq-issue.vq-deja{background:rgba(255,255,255,.035);color:var(--c-texte-3);
  box-shadow:inset 0 0 0 .34px rgba(167,139,250,.18)}
.vq-issue.vq-deja:active{background:rgba(255,255,255,.09);color:var(--c-texte-2)}

/* ══ L'ENTREE ══
   ⚠️ backwards, JAMAIS both. Avec both, une animation garde a vie l'etat de sa
      derniere image, ET UNE VALEUR D'ANIMATION L'EMPORTE SUR TOUTE DECLARATION
      NORMALE : uiMonte finit sur transform:none et bloquerait le scale(.985)
      de l'appui sans qu'aucun inspecteur ne montre le conflit.
   ⚠️ ET LE REPLI DE MOUVEMENT COUPE TOUT, LA RESPIRATION DU HALO COMPRISE. Le
      repli global de cette feuille ne pose qu'une duree de 0,01 ms : sur une
      animation infinie, ca ne l'arrete pas, ca la fait tourner mille fois plus
      vite — un repeint permanent, exactement ce que le reglage veut eviter. On
      coupe donc le NOM de l'animation, pas sa duree. */
.vq-in{animation:uiMonte var(--m-long) var(--m-sortie) backwards;animation-delay:var(--d,0ms)}

@media (prefers-reduced-motion:reduce){
  .vq-in{animation:none}
  .vq-scene::before{animation:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   [08/08] LA QUATRIEME VARIANTE — L'ONGLET PROFIL SANS COMPTE
   Portage de `comptesanscompte.html`. Tout ce qui suit s'ajoute au composant
   ci-dessus ; RIEN n'y est modifie, les trois autres ecrans ne bougent pas.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ LES COTES DE L'ECRAN ══
   ⚠️⚠️ LE REMBOURRAGE DE LA BOITE QUI DEFILE TOMBE A ZERO SUR LES COTES, et ce
      n'est pas une coquetterie : `.screen` en pose 18 et `.prof-scroll` en
      ajoute 4, donc les boutons auraient ete 8 px plus etroits que sur les
      trois autres ecrans verrouilles. DEUX REMBOURRAGES QUI S'ADDITIONNENT NE
      SE VOIENT DANS AUCUN DES DEUX — c'est la faute payee le 07/08 sur
      Discussions, au meme endroit du meme composant.
   ⚠️ LE BAS N'EST PAS TOUCHE : la reserve des 74 px de la barre vit sur
      `#s-compte.avec-barre>.prof-scroll`, et elle appartient a CE QUI DEFILE.
      La redeclarer ici l'aurait perdue, et le dernier bouton serait passe sous
      la capsule. On ne redeclare donc pas `padding` en bloc.
   ⚠️ ET LE CORPS NE SE COMPRIME PAS : `flex:1 0 auto`, comme les trois autres.
      Mesure du 07/08 a 320x568 en Grand texte avec `1 1 auto` : le bloc etait
      comprime, son debordement ne comptait pas dans la hauteur defilante, et le
      dernier bouton finissait SOUS la barre sans moyen d'en sortir. */
#s-compte.vq-on>#cp-body{padding-left:0;padding-right:0;padding-top:0;
  display:flex;flex-direction:column;flex:1 0 auto}
/* ⚠️⚠️ L'ECRAN GARDE SA PROPRE BARRE DE TITRE, A L'INVERSE DE DISCUSSIONS QUI
   MASQUE LA SIENNE. Deux raisons, et la seconde est la vraie : elle porte la
   FLECHE DE RETOUR, dont les trois vues legales atteignables d'ici ont besoin
   (Conditions, Confidentialite, A propos). Le composant, lui, n'a pas de
   fleche : c'est un onglet, il n'a rien derriere.
   ⚠️ ELLE PREND LES COTES DU COMPOSANT : 32 px dessous au lieu de 6, et une
      grille 44 / 1fr / 44 au lieu d'un `space-between`. En flex reparti, le
      titre se centre entre les deux boutons — donc sur la place qui reste, pas
      sur l'ecran ; ses colonnes ne pesant pas pareil (44 a gauche, 36 a
      droite), il tombait 4 px a cote de l'axe. On reserve la place du plus
      large des deux, sinon le centre se decale. */
#s-compte.vq-on>.topbar{display:grid;grid-template-columns:44px minmax(0,1fr) 44px;
  align-items:center;min-height:44px;margin:2px 0 var(--e-5)}
#s-compte.vq-on>.topbar>#cp-title{grid-column:2;justify-self:center;
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;line-height:1.2;color:var(--c-texte)}

/* ══ LA TEINTE DU QUATRIEME ══
   ⚠️⚠️ C'EST LE SEUL DES QUATRE OU L'EMBLEME ET LA LUMIERE PARTAGENT LEUR
      TEINTE, et ce n'est pas un accident : le compte est le seul « mode » dont
      la couleur est celle de l'app. L'or dit le rang, le sarcelle les
      discussions, le bleu les gens — le violet dit Trinke, et le compte, c'est
      Trinke. La regle « la teinte du mode ne doit pas atteindre le violet »
      tombe donc ici : il n'y a pas de frange a craindre entre deux teintes de
      la meme famille, et c'est ce qui rend cet ecran plus calme que les trois
      autres. Les deux ombres restent a 9 et 22 : le chiffre depend de la TAILLE
      de l'objet, pas de sa teinte. Une cote partagee reste partagee meme quand
      sa raison d'etre disparait sur un ecran, sinon les quatre divergent. */
.vq-scene.vq-violet .vq-embleme{stroke:#A78BFA;
  filter:drop-shadow(0 0 9px rgba(167,139,250,.40))
         drop-shadow(0 0 22px rgba(167,139,250,.14))}

/* ══ CE QU'UN COMPTE OUVRE ══
   ⚠️⚠️ LA LARGEUR DE LA GRILLE EST CALCULEE, PAS REGLEE. On veut que les deux
      tuiles extremes tombent exactement sur la mesure du paragraphe, 272. La
      grille etant en quatre colonnes egales, le centre de la premiere est a W/8
      et son bord gauche a W/8 - 18 :
          portee visible = W - 2(W/8 - 18) = 0,75 W + 36
          0,75 W + 36 = 272   ->   W = 315
      Les tetes de la ligne s'alignent donc au pixel sur le texte qui la
      surplombe, alors que la grille, elle, n'est visible nulle part. UNE
      LARGEUR NE COMPTE DANS LA COMPOSITION QUE SI ON PEUT LA VOIR.
   ⚠️ 12 AU-DESSUS, PAS 24 : ce qui ILLUSTRE une phrase se pose sous elle, pas
      apres elle. 12 est l'ecart des groupes du socle, la moitie de celui qui
      separe deux blocs — d'ou `.vq-serre`, qui rend a l'accroche sa marge
      basse de zero quand la ligne des tuiles la suit.
   ⚠️ NI CARTE, NI CADRE, NI FILET : quatre objets de meme rang alignes se
      lisent comme un groupe sans qu'on ait besoin de les enfermer. L'ecran
      gagne trois cents pixels sur les quatre cartes empilees d'avant. */
.vq-accroche.vq-serre{margin-bottom:0}
/* ⚠️⚠️ LE `column-gap` EST AJOUTE AU RENDU, ET IL CORRIGE UN DEFAUT MESURE AU
   BANC. Le rendu ne pose AUCUN ecart entre les quatre colonnes : tant qu'un
   intitule tient dans sa colonne on ne voit pas le probleme, mais un mot plus
   large qu'elle DEBORDE des deux cotes et vient toucher son voisin — une grille
   sans gouttiere n'a rien pour l'arreter. Mesure de l'ecart entre
   « Statistiques » et « Classements » :
        402 px normal ······  14,5 px
        402 px Grand texte ·   2,6 px
        320 px Grand texte ·   0,0 px   ← les deux mots SE TOUCHENT
   ⚠️ ET LA GOUTTIERE SEULE NE SUFFIT PAS : elle retrecit les colonnes, donc
      elle deplace la collision au lieu de la supprimer. C'est la COUPURE qui la
      supprime — avec la gouttiere, un mot trop long passe a deux lignes au lieu
      de deborder, et les huit pixels restent huit pixels quoi qu'il arrive.
      `hyphens:auto` sur un document en `lang="fr"` coupe au bon endroit
      (« Statis-tiques », verifie au banc) ; `overflow-wrap` est le filet du
      moteur qui n'aurait pas de dictionnaire : il coupe sans trait d'union,
      ce qui est laid mais jamais illisible. UNE DEGRADATION QUI ABIME LE
      DESSIN VAUT MIEUX QU'UNE QUI SUPERPOSE DEUX MOTS.
   ⚠️ CE QUI N'A PAS ETE FAIT, ET C'EST A TRANCHER PAR LE DESSIN : passer la
      ligne a DEUX RANGEES DE DEUX en Grand texte. Ca rend les quatre mots
      entiers et sans coupure, mais ca coute 80 px de hauteur et ca defait
      l'intention du rendu — « les quatre territoires de l'app tiennent sur une
      ligne ». Ecarte pour rester fidele, pas parce que c'est mauvais. */
/* ⚠️ ET LA LARGEUR SE RECALCULE AVEC LA GOUTTIERE, ELLE NE SE RECOPIE PAS. La
   formule du rendu — 0,75 W + 36 = 272, donc W = 315 — suppose des colonnes
   jointives. Avec une gouttiere `g`, la colonne vaut (W - 3g)/4 et la portee
   visible devient (3W + 3g)/4 + 36 : a g = 8, garder 315 aurait pousse les deux
   tuiles extremes 3 px hors de la mesure du paragraphe. On resout pour 272 :
   W + g = 314,67, donc W = 306,67. UNE COTE CALCULEE SE RECALCULE DES QU'UN DE
   SES TERMES BOUGE — sinon elle devient un nombre magique qui a l'air juste. */
.vq-ouvre{flex:0 0 auto;display:grid;grid-template-columns:repeat(4,1fr);
  column-gap:var(--e-2);
  align-items:start;width:100%;max-width:306.67px;margin:var(--e-3) auto var(--e-4)}
.vq-co{display:flex;flex-direction:column;align-items:center;gap:var(--e-2)}
/* les tuiles des rangees du compte : 36, rayon 12, degrade vertical a deux
   arrets. Un ecran neuf ne dessine pas un composant neuf tant que l'app en a un
   qui fait la chose. */
.vq-tu{width:36px;height:36px;border-radius:var(--r-1);display:grid;place-items:center;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.20)}
/* ⚠️⚠️ L'ENCRE EST ECRITE EN DUR, ET C'EST LE PIEGE DE JETON DU LOT. Le rendu
   ecrit `var(--ink)` en pensant « encre des surfaces violettes, #170B20 ». DANS
   CE SOCLE `--ink` VAUT `#f4f4f7` — le texte principal, presque du blanc. Le
   jeton existe, la declaration serait donc VALIDE, et les quatre glyphes
   auraient rendu entre 1,44 et 2,85:1 sur leur tuile, pour un seuil de 3.
   UNE VARIABLE QUI EXISTE MAIS NE VEUT PAS DIRE LA MEME CHOSE EST PIRE QU'UNE
   VARIABLE ABSENTE : l'absente rend la regle invalide et se voit, celle-ci
   peint une couleur plausible. */
.vq-tu svg{width:20px;height:20px;fill:none;stroke:#170B20;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.vq-tu-sarcelle{background:linear-gradient(180deg,#5EEAD4 0%,#14B8A6 100%)}
.vq-tu-bleu{background:linear-gradient(180deg,#6C96FA 0%,#4C7DF0 100%)}
.vq-tu-fuchsia{background:linear-gradient(180deg,#F97BC9 0%,#EC4899 100%)}
.vq-tu-or{background:linear-gradient(180deg,#FCD34D 0%,#F0B429 100%)}
/* 12, le plancher du socle : ce sont des ETIQUETTES, pas du texte. On ne les
   lit pas, on les verifie une fois. */
.vq-ouvre b{font-size:var(--t-1);font-weight:500;letter-spacing:-.005em;
  color:var(--dim);text-align:center;line-height:1.2;
  -webkit-hyphens:auto;hyphens:auto;overflow-wrap:break-word}

/* ══ LA TROISIEME ISSUE ══
   ⚠️ SON FILET N'EST PAS VIOLET, et c'est la seule chose qui la separe de la
      seconde. Le violet est l'accent du COMPTE : il est sur le bouton plein,
      sur l'accent du titre, sur le filet de « Se connecter ». Un bouton qui se
      PASSE de compte ne peut pas porter la couleur du compte. Filet blanc a
      .10, encre `--dim` : il appartient a la page, pas au couple.
   ⚠️ 24 AU-DESSUS CONTRE 12 DANS LE COUPLE : le rapport du simple au double
      suffit a dire qu'on change de famille, et il ne coute rien au vocabulaire.
      L'app deployee posait un « OU » entre deux filets pour dire la meme chose.
   ⚠️ SON ENCRE RESTE A 5,4:1 : une troisieme issue se met en retrait, elle ne
      se cache pas. */
.vq-issue.vq-invite{background:rgba(255,255,255,.03);color:var(--dim);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.10);margin-top:var(--e-4)}
.vq-issue.vq-invite:active{background:rgba(255,255,255,.075);color:var(--c-texte-2)}

/* ══ LES MENTIONS ══
   ⚠️ 13 ET NON 12. Le plancher du socle est a 12, mais UN TEXTE QUI ENGAGE
      JURIDIQUEMENT NE SE MET PAS AU PLANCHER : il se lit, donc il se pose un
      cran au-dessus.
   ⚠️ AUCUN FILET AU-DESSUS : le corps, l'encre et l'ecart de 32 le font deja.
      La typographie separe mieux qu'un trait, et sans rien ajouter.
   ⚠️ LES LIENS SONT DE VRAIS BOUTONS, donc ils paient leur REMISE A ZERO —
      `font:inherit`, `border:0`, `background:none` et une `color` explicite. Un
      <button> sans remise a zero est peint par le navigateur : fond gris,
      bordure 2px outset, Arial 13,3 px. Quatre fois en une journee le 07/08,
      dont deux en production.
   ⚠️ CIBLE PORTEE A 44 PAR UN `::after` VERTICAL DE -13 : il deborde sur les
      lignes voisines sans les gener, puisqu'elles ne sont pas cliquables. Une
      cible grandit du cote ou il n'y a rien.
   ⚠️ « A PROPOS » EST SUR SA PROPRE LIGNE, avec 6 px d'air : il ne fait pas
      partie de ce qu'on accepte, il ne peut donc pas entrer dans la phrase. */
.vq-legal{flex:0 0 auto;margin:var(--e-5) auto 0;max-width:300px;
  font-size:var(--t-1);line-height:1.45;color:var(--dim);text-align:center}
.vq-lien{position:relative;display:inline;border:0;padding:0;background:none;
  font:inherit;color:#A78BFA;cursor:pointer;
  transition:opacity .16s var(--ease)}
.vq-lien::after{content:'';position:absolute;inset:-13px -2px}
.vq-lien:active{opacity:.55}
.vq-legal-2{display:block;margin-top:var(--e-2)}

/* ═══════════════════════════════════════════════════════════════════════════
   CREER UN COMPTE — UNE SEULE PAGE            rendu du 07/08, porte le 08/08
   ═══════════════════════════════════════════════════════════════════════════
   ⚠️ TOUT EST SOUS `#cp-body .cr` : la vue « creer » et elle seule. Les vingt
      autres vues de l'ecran Compte partagent le meme conteneur et ne doivent
      pas bouger d'un pixel.
   ⚠️ CLASSES PREFIXEES `cr-`. Le 07/08, `.jeu` a ete repris sans verifier :
      c'etait deja la tuile du catalogue des mini-jeux. Une collision de nom ne
      se voit dans aucune relecture.
   ⚠️ AUCUNE TAILLE DE TEXTE EN px (contrat UI-06) : sinon le reglage Grand
      texte ne les agrandit pas. Valeurs du rendu converties en rem, base 16.
   ═══════════════════════════════════════════════════════════════════════════ */

#cp-body .cr{display:flex;flex-direction:column;margin-top:var(--e-4)}

/* ── une demande : un intitule, un champ, une aide, toujours dans cet ordre ──
   Ce qui se repete quatre fois doit se repeter A L'IDENTIQUE : c'est ce qui
   permet de descendre la page sans relire la structure a chaque bloc.
   ⚠️ 26 ENTRE DEUX DEMANDES, 8 A L'INTERIEUR D'UNE : le rapport du simple au
      triple. Un ecart ne se choisit pas pour ce qu'il separe, mais pour le
      rang qu'il occupe parmi les autres. */
#cp-body .cr-d{flex:0 0 auto;margin:0 0 var(--e-4)}

/* ── l'intitule ────────────────────────────────────────────────────────────
   ⚠️ UN INTITULE DE CHAMP N'EST PAS UN INTITULE DE SECTION. Ailleurs dans
      l'app, `.jr-sec` nomme une SECTION posee au-dessus d'une carte : il
      chuchote, parce que les rangees en dessous disent tout. Ici il nomme un
      CHAMP, c'est-a-dire LA QUESTION QU'ON POSE, et il doit dominer la ligne
      qui l'explique. D'ou 15/600 en bas de casse et encre pleine, au lieu de
      12/700 capitales espacees.
   ⚠️ TROIS DIFFERENCES AVEC L'AIDE, PAS UNE : le corps, la graisse et l'encre.
      Deux textes qui ne different que par une dimension se lisent comme un
      seul.
   ⚠️ ET SON ECART A SON CHAMP EST DE 8 : il ne le surplombe pas, il lui
      appartient. Le rembourrage de 4 aligne son texte sur celui du champ, dont
      le contenu commence apres le glyphe. */
#cp-body .cr-lab{font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;
  color:var(--ink);margin:0 0 var(--e-2);padding-left:var(--e-1);text-transform:none}

/* ── le champ ──────────────────────────────────────────────────────────────
   ⚠️ 50 DE HAUT, LA HAUTEUR DU BOUTON QUI LE VALIDE : un champ et le bouton
      qui le conclut ont la meme hauteur, sinon la colonne a deux gabarits. Le
      deploye etait a 58, au-dela de tout ce que l'app connait.
   ⚠️ VOILE .09 ET FILET .20 : sur un ecran ou quatre champs se suivent, un
      objet qui se distingue a peine du fond se distingue encore moins de son
      voisin. Le filet est en pixel physique (.34) et non en pixel de mise en
      page : a 3x, un demi-pixel a toujours un bord a moitie allume.
   ⚠️ L'ANNEAU DE FOCUS REMPLACE LE FILET, IL NE S'Y AJOUTE PAS : deux bords
      sur un meme objet font une double ligne. */
#cp-body .cr-champ{position:relative;display:flex;align-items:center;gap:var(--e-2);
  width:100%;min-height:50px;padding:0 var(--e-3);border-radius:var(--r-2);
  background:rgba(255,255,255,.09);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.20);
  transition:box-shadow .18s var(--ease)}
#cp-body .cr-champ:focus-within{box-shadow:inset 0 0 0 1px rgba(167,139,250,.75)}
/* ⚠️ L'ANNEAU DU CHAMP REMPLACE CELUI DU NAVIGATEUR, IL NE S'Y AJOUTE PAS. La regle
   generale `input:focus{outline:2px solid var(--accent)}` du socle dessinait un SECOND
   anneau, a l'interieur du premier : deux bords sur un meme objet font une double ligne, et
   ca se voyait tout de suite a l'ecran. C'est le conteneur qui porte le focus ici, parce que
   c'est lui qu'on voit — l'anneau doit entourer le glyphe ET le texte, pas le seul champ de
   saisie. L'etat reste donc parfaitement visible, il n'est peint qu'une fois. */
#cp-body .cr-champ input:focus,
#cp-body .cr-champ select:focus,
#cp-body .cr-champ input:focus-visible{outline:none;border-color:transparent}

/* ── le signe ──────────────────────────────────────────────────────────────
   ⚠️ LA TEINTE DIT OU LA DONNEE SERA VUE, ET C'EST TOUTE LA GRAMMAIRE :
        bleu ····· vu par les autres joueurs   pseudo
        violet ··· vu dans l'app               pays
        ardoise ·· vu par personne             date · email
      Trois teintes et non quatre : deux champs qui font la meme promesse
      portent la meme teinte. Une couleur par objet serait un inventaire.
   ⚠️ L'ARDOISE EST ECLAIRCIE DE #6A7386 A #8E9AB0 : l'ardoise du socle est
      faite pour un APLAT de tuile, ou l'encre du glyphe fait le contraste ; en
      trait nu sur le fond elle ne rend que 4,10:1. Une teinte de fond et une
      teinte de trait ne peuvent pas etre la meme valeur.
   ⚠️ ET SEUL LE SIGNE PREND LA TEINTE, PAS L'INTITULE : on teinte le signe, on
      laisse le texte a sa place dans la hierarchie. */
#cp-body .cr-champ>svg{width:19px;height:19px;flex:0 0 auto;fill:none;
  stroke:var(--cr-t,#8E9AB0);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
#cp-body .cr-t-pseudo{--cr-t:#8FB4FF}
#cp-body .cr-t-pays{--cr-t:#A78BFA}

/* ⚠️ CE QU'ON A ECRIT PESE PLUS QUE CE QU'ON NOUS PROPOSE D'ECRIRE : texte
   saisi en encre pleine, invite a #8E86A2.
   ⚠️ 17 px ET JAMAIS MOINS DE 16 : sous ce seuil, Safari zoome sur le champ au
      premier appui et ne revient pas. Piege paye le 03/08. */
#cp-body .cr-champ input,
#cp-body .cr-champ>span{flex:1 1 auto;min-width:0;text-align:left;
  font-size:var(--t-3);font-weight:400;color:var(--ink);
  background:none;border:0;padding:0;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
#cp-body .cr-champ input::placeholder{color:var(--c-texte-3)}
#cp-body .cr-champ>span.cr-vide{color:var(--c-texte-3)}

/* ⚠️ CE QUI SE DEPLIE EN PLACE PORTE UN CHEVRON VERS LE BAS. Le pays et la
   date ouvrent le selecteur du systeme. */
#cp-body .cr-ouvre{margin-left:auto;width:11px;height:11px;flex:0 0 auto;
  fill:none;stroke:#8E86A2;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

/* ⚠️ LE SELECTEUR NATIF EST CONSERVE, SUPERPOSE ET TRANSPARENT. Le rendu
   dessine un bouton qui affiche « 12 mars 2004 » ; un `input[type=date]` rend
   le texte que le navigateur veut, et sur iOS on ne le commande pas. On garde
   donc le selecteur du systeme — celui que les gens savent utiliser, et qui
   applique `max` — et on peint par-dessus ce que le rendu demande.
   ⚠️ `opacity:0` ET NON `visibility:hidden` NI `display:none` : les deux
      derniers rendraient le champ intouchable, donc le selecteur inouvrable. */
#cp-body .cr-ouvrant>input,
#cp-body .cr-ouvrant>select{position:absolute;inset:0;width:100%;height:100%;
  opacity:0;margin:0;padding:0;border:0;background:none;
  font-size:var(--t-3);   /* jamais sous 16 : Safari zoome sur un champ trop petit */
  -webkit-appearance:none;appearance:none;cursor:pointer;z-index:2}

/* ── l'aide ────────────────────────────────────────────────────────────────
   ⚠️ ELLE EST SOUS LE CHAMP, PAS AU-DESSUS : elle dit ce qu'il advient de ce
      qu'on tape, donc elle se lit apres avoir tape. Une indication placee
      avant le champ se lit avant d'en avoir besoin, et ne se relit jamais.
   ⚠️ ET ELLE DIT POURQUOI ON DEMANDE, pas ce que la donnee subit : sous un
      champ, la bonne phrase n'est pas ce qu'on fera de la donnee, c'est la
      raison pour laquelle on la demande. C'est aussi ce qui desamorce la
      mefiance — on ne reclame pas une date de naissance, on justifie un
      controle.
   ⚠️ PAS DE POINT FINAL : une aide sous un champ est une etiquette, pas une
      phrase, et une ponctuation qui n'est pas systematique se remarque plus
      que son absence.
   ⚠️ L'ERREUR REMPLACE L'AIDE, ELLE NE S'AJOUTE PAS SOUS ELLE : deux lignes
      sous un champ, on ne sait plus laquelle est vraie. */
#cp-body .cr-aide{margin:var(--e-2) 0 0;padding-left:var(--e-1);font-size:var(--t-1);
  line-height:1.4;color:var(--mut)}
#cp-body .cr-aide.faux{color:#E5484D}

/* ── le bouton ─────────────────────────────────────────────────────────────
   50 de haut, rayon 16, degrade vertical, encre sombre, lueur a etalement
   negatif : le bloc des quatre ecrans verrouilles, sans retouche. Un bouton
   d'action ne se redessine pas d'un ecran a l'autre.
   ⚠️ ET SON ETAT ETEINT NE RESSEMBLE A AUCUN BOUTON ACTIF DE L'APP : voile
      .04, encre grise, aucune lueur. CE QUI ATTEND NE DOIT PAS RESSEMBLER A CE
      QUI EST PRET — le deploye leur donnait le meme gris qu'un bouton
      secondaire actif. */
#cp-body .cr-valider{position:relative;flex:0 0 auto;width:100%;min-height:50px;
  display:flex;align-items:center;justify-content:center;gap:var(--e-2);
  margin:var(--e-2) 0 0;border:0;border-radius:var(--r-2);cursor:pointer;
  font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;color:#170B20;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),
             0 4px 10px -6px rgba(0,0,0,.55),
             0 14px 30px -14px rgba(139,92,246,.62);
  transition:transform .16s var(--ease),background .16s var(--ease),
             box-shadow .16s var(--ease)}
#cp-body .cr-valider:active:not(.inerte){transform:scale(.985)}
#cp-body .cr-valider .cr-g{width:20px;height:20px;flex:0 0 auto;fill:none;
  stroke:currentColor;stroke-width:1.55;stroke-linecap:round;stroke-linejoin:round}
#cp-body .cr-valider.inerte{background:rgba(255,255,255,.04);color:var(--mut);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.08);
  cursor:default;pointer-events:none}

/* ── la mention ────────────────────────────────────────────────────────────
   ⚠️ PAS DE CASE A COCHER, ET LA MENTION APPARTIENT AU BOUTON. Le fondement du
      traitement est l'execution du contrat, pas le consentement : une case
      transforme une information en obstacle et ajoute un etat d'echec de plus
      a un formulaire qui en a deja quatre. Une mention qui conditionne l'acte
      fait partie du bouton, d'ou l'ecart de 12 et non 14.
      ⚠️ A FAIRE VALIDER PAR UN CONSEIL : si un avis juridique exige la case,
         elle revient AU-DESSUS du bouton, et le bouton reste inerte tant
         qu'elle n'est pas cochee.
   ⚠️ MESURE CALCULEE, PAS REGLEE A L'OEIL : le texte fait 84 signes ; a 12 px,
      un signe mesure en moyenne 5,45 px, soit 458 px d'encre. Pour tenir en
      deux lignes il faut au moins 229 de mesure ; 332 laisse la marge des
      coupures. Une mesure ne se regle pas jusqu'a ce que ca tombe juste, elle
      se calcule a partir de la longueur du texte.
   ⚠️ 12 px EST LE PLANCHER DU SOCLE, et une mention secondaire est le seul
      texte qui a le droit de s'y poser : elle ne se lit pas, elle se consulte.
   ⚠️ ET « POLITIQUE DE CONFIDENTIALITE », PAS « CONFIDENTIALITE » : un lien
      juridique se nomme par le titre du document qu'il ouvre. Un raccourci de
      nom sur un lien de consentement fait douter qu'on ait lu le bon texte. */
#cp-body .cr-legal{flex:0 0 auto;margin:var(--e-3) auto 0;max-width:332px;
  font-size:var(--t-1);line-height:1.4;color:var(--mut);text-align:center}
#cp-body .cr-lien{position:relative;display:inline;border:0;padding:0;
  background:none;font:inherit;color:#A78BFA;cursor:pointer;
  transition:opacity .16s var(--ease)}
/* la cible tactile deborde sans changer la taille visible (contrat des 44 px) */
#cp-body .cr-lien::after{content:'';position:absolute;inset:-13px -2px}
#cp-body .cr-lien:active{opacity:.55}

/* [08/08] LES TUILES DE CATALOGUE GARDENT LEUR DA D'ORIGINE (degrade translucide,
   155°, .16/.07). Elles ont porte la rampe pleine de l'accueil pendant une version : c'etait
   une MAUVAISE LECTURE de la demande de Theo, qui visait la page de reglages ouverte depuis le
   catalogue, pas les tuiles. Remises telles quelles sur sa demande — et le commentaire du
   02/08 juste au-dessus reste donc vrai : seize tuiles pleines feraient un mur. */

/* ═══════════════════════════════════════════════════════════════════════════
   NOUVEAU GROUPE — UNE SEULE PAGE                  rendu du 08/08, porte le 08/08
   ═══════════════════════════════════════════════════════════════════════════
   ⚠️ TOUT EST PREFIXE `ng-` ET SCOPE A `#s-multi` : l'ecran des Discussions
      porte une vingtaine de vues dans le meme conteneur, et `.jeu` nous a deja
      appris qu'une collision de nom ne se voit dans aucune relecture.
   ⚠️ AUCUNE TAILLE DE TEXTE EN px (contrat UI-06) : converties en rem, base 16.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── le nom du groupe ───────────────────────────────────────────────────────
   ⚠️ LES DEUX CHAMPS SE DISTINGUENT PAR LEUR MATIERE, PAS PAR UN INTITULE : le
      nom est une SAISIE (voile .09, filet, anneau de focus, rayon 16), la
      recherche est un OUTIL (voile .075, gelule). Deux champs qui ne font pas
      le meme metier ne portent pas la meme peau.
   ⚠️ 50 DE HAUT, comme la recherche et comme le bouton : les trois objets
      pleine largeur de l'ecran ont la meme hauteur, et c'est ce qui fait la
      colonne. */
#s-multi .ng-nom{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:0 0 auto;width:100%;min-height:50px;padding:0 var(--e-3);border-radius:var(--r-2);
  background:rgba(255,255,255,.09);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.20);
  transition:box-shadow .18s var(--ease)}
#s-multi .ng-nom:focus-within{box-shadow:inset 0 0 0 1px rgba(167,139,250,.75)}
/* ⚠️ L'ETIQUETTE DE `compte-acces`, PAS LES BULLES DE L'ONGLET. Ce glyphe-la ne
   veut pas dire « une conversation », il veut dire « l'onglet Discussions » :
   pose dans un champ de saisie, il annoncerait le mode et non le champ. Un
   glyphe d'onglet nomme un LIEU, il ne peut pas nommer ce qu'on fait dedans.
   ⚠️ SA TEINTE RESTE SARCELLE : le dessin change, pas la couleur. La teinte dit
      le mode, le dessin dit la chose. */
#s-multi .ng-nom>svg{width:19px;height:19px;flex:0 0 auto;fill:none;stroke:#5EEAD4;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}

/* ── la recherche ───────────────────────────────────────────────────────────
   ⚠️ 32 SOUS LE NOM, CONTRE 16 PARTOUT AILLEURS : le plus grand ecart de la
      page, et le double du suivant. Le nom ne fait pas partie du meme travail
      que le reste — on le tape une fois, on ne le regarde plus ; chercher,
      ajouter, retirer sont une seule tache continue. Un ecart de rang double
      separe deux taches, un ecart de rang simple deux objets d'une meme tache. */
#s-multi .ng-outils{position:relative;display:flex;align-items:center;gap:var(--e-2);
  flex:0 0 auto;margin:var(--e-5) 0 0}
#s-multi .ng-rech{position:relative;display:flex;align-items:center;gap:var(--e-3);
  flex:1 1 auto;min-width:0;min-height:50px;padding:0 var(--e-3);
  border-radius:999px;background:rgba(255,255,255,.075);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.14);
  transition:box-shadow .18s var(--ease)}
#s-multi .ng-rech:focus-within{box-shadow:inset 0 0 0 1px rgba(167,139,250,.75)}
#s-multi .ng-rech>svg{width:18px;height:18px;flex:0 0 auto;fill:none;stroke:#9990AE;
  stroke-width:1.85;stroke-linecap:round;stroke-linejoin:round}
/* 17 px et jamais moins de 16 : sous ce seuil, Safari zoome au premier appui */
#s-multi .ng-nom input,#s-multi .ng-rech input{flex:1 1 auto;min-width:0;
  font-size:var(--t-3);font-weight:400;color:var(--ink);background:none;border:0;padding:0}
#s-multi .ng-nom input::placeholder,#s-multi .ng-rech input::placeholder{color:var(--c-texte-3)}
#s-multi .ng-nom input:focus,#s-multi .ng-rech input:focus{outline:none}

/* [08/08, Theo] LE « + » DU CHAMP DE RECHERCHE EST RETIRE : « il n'a aucune utilite sur
   cette page ». Il en avait une dans le rendu, ou l'ajout passait par lui ; il n'en a plus
   depuis que les amis trouves s'affichent sous le champ et qu'un appui les fait entrer. Ses
   regles partent avec lui — une regle qui ne cible plus rien finit par etre corrigee a la
   place de celle qui sert (lecon des dix regles orphelines du 05/08).
   ⚠️ ET LE CHAMP REPREND UN REMBOURRAGE SYMETRIQUE : les 10 de droite etaient la place du
      bouton, pas une marge. */

/* ── la liste ───────────────────────────────────────────────────────────────
   ⚠️ GROUPE A FILETS, PAS DE CARTES SEPAREES : ici on ne visite pas les gens, on
      les rassemble. La carte separee est pour ce qu'on visite.
   ⚠️ 62 DE HAUT : l'avatar fait 40 et il n'y a qu'une ligne de texte. Une rangee
      se mesure a ce qu'elle contient. */
#s-multi .ng-lab{flex:0 0 auto;font-size:var(--t-1);font-weight:700;letter-spacing:.10em;
  text-transform:uppercase;color:var(--c-texte-3);margin:var(--e-4) 0 var(--e-2);padding-left:var(--e-1)}
#s-multi .ng-groupe{flex:0 0 auto;border-radius:var(--r-3);overflow:hidden;
  background:var(--card-2);box-shadow:inset 0 1px 0 rgba(255,255,255,.07)}
#s-multi .ng-ami{position:relative;display:flex;align-items:center;gap:var(--e-3);width:100%;
  min-height:62px;padding:var(--e-2) var(--e-3);text-align:left;cursor:pointer;border:0;
  background:none;color:inherit;font:inherit;
  transition:background .16s var(--ease)}
/* le filet emprunte ses bornes a ce qu'il separe : il commence au texte, apres
   l'avatar. Pixel physique et non pixel de mise en page (lecon des demi-pixels). */
#s-multi .ng-ami+.ng-ami::before{content:"";position:absolute;left:70px;right:0;top:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.17)}
#s-multi .ng-ami:active{background:rgba(255,255,255,.04)}
/* ⚠️⚠️ [08/08, Theo : « les ronds de profil ils sont ou ? »] LE DISQUE SE PEINT ICI, ET LA
   COULEUR VIENT DE LA PALETTE DES AMIS. `.am-av1..8` ne peignent RIEN : elles ne declarent
   que `--ami-fond` / `--ami-encre`, et il faut les CONSOMMER. L'ecran a ete porte avec la
   classe de teinte posee dans le markup mais sans cette ligne : le cercle etait transparent,
   il ne restait qu'une initiale nue, dans les trois listes de l'ecran.
   ⚠️ LE REPLI N'EST PAS DECORATIF : la teinte arrive de `amTeinte(id de compte)`, donc d'une
      donnee serveur. Sans repli, un identifiant manquant rendrait un disque invisible au lieu
      d'un disque neutre — la meme faute, mais silencieuse. Ce sont les valeurs de `.mu-pas`,
      qui a deja tranche la question pour les Discussions.
   ⚠️ ET L'ENCRE SUIT LE FOND, pas le theme : quatre des huit teintes sont claires et portent
      une initiale sombre. Un blanc fixe rendrait 1,7:1 sur `#BCB2FE`. */
#s-multi .ng-av{position:relative;width:40px;height:40px;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;font-size:var(--t-3);font-weight:700;
  background:var(--ami-fond,#5567B4);color:var(--ami-encre,#FFFFFF)}
#s-multi .ng-ami b{flex:1 1 auto;min-width:0;font-size:var(--t-3);font-weight:400;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── la case ────────────────────────────────────────────────────────────────
   ⚠️ CARREE ARRONDIE, PAS RONDE : le cercle appartient aux gens. Une case ronde
      posee a cote d'un avatar rond fait deux cercles sur une meme ligne, dont un
      seul est quelqu'un. 24 de cote, rayon 8, le rapport 0,33 du socle.
   ⚠️ COCHEE, ELLE SE REMPLIT DE SARCELLE, la teinte du groupe qu'on fabrique : ce
      qu'on coche devient une partie de la chose qu'on cree, il doit en porter la
      couleur.
   ⚠️ ENCRE DE LA COCHE SOMBRE : un trait blanc sur #5EEAD4 rend 1,48:1, l'encre
      sarcelle 6,64.
   ⚠️ LA CIBLE EST LA RANGEE ENTIERE, pas la case : une case de 24 est une cible
      de 24. */
#s-multi .ng-ck{flex:0 0 auto;width:24px;height:24px;border-radius:var(--r-1);
  display:grid;place-items:center;
  box-shadow:inset 0 0 0 1.4px #4A4458;
  transition:background .16s var(--ease),box-shadow .16s var(--ease)}
#s-multi .ng-ck svg{width:13px;height:13px;fill:none;stroke:#052322;
  stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;opacity:0;
  transition:opacity .16s var(--ease)}
#s-multi .ng-ami.on .ng-ck{box-shadow:none;
  background:linear-gradient(180deg,#5EEAD4 0%,#14B8A6 100%)}
#s-multi .ng-ami.on .ng-ck svg{opacity:1}

/* ── le bouton ancre ────────────────────────────────────────────────────────
   ⚠️ LA PLACE AU BAS DE L'ECRAN APPARTIENT A UN SEUL OBJET : la barre d'onglets,
      ou l'action de l'ecran s'il n'y a pas d'onglets. Ici il n'y en a pas — une
      barre d'onglets pendant un parcours propose de partir, et partir veut dire
      perdre les amis qu'on vient de cocher.
      78 = 50 de bouton + 14 au-dessus + 14 en dessous.
   ⚠️ LE VOILE EST UN DEGRADE VERS LE FOND, PAS UN `backdrop-filter` : quatre
      causes independantes tuent un backdrop-filter sur WebKit, et un objet anime
      par-dessus en est une. On peint le fond plutot que de le flouter. Il s'eteint
      sur 62 px, donc la rangee qui passe dessous s'efface au lieu d'etre coupee net.
   ⚠️ ET IL ENTRE PAR LE BAS : ce qui arrive d'un bord y retourne. L'animation
      REPORTE le centrage a chaque image — une animation qui ecrit `transform`
      efface celui de la regle. */
#s-multi .ng-ancre{position:absolute;left:0;right:0;bottom:0;z-index:20;
  padding:34px var(--e-3) calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + var(--e-3));
  background:linear-gradient(180deg,rgba(12,12,15,0) 0%,
                                    rgba(12,12,15,.86) 34px,
                                    var(--bg) 62px);
  animation:uiCarteMonte var(--m-court) var(--m-sortie) backwards;pointer-events:none}
#s-multi .ng-ancre>*{pointer-events:auto}

/* le corps rend la place au bouton, sinon la derniere rangee finit dessous */
#s-multi.ng-on>.jr-body{padding-bottom:78px}

/* ⚠️⚠️ [08/08, Theo sur capture : « le bouton est cache par la barre d'app, il faut qu'il soit
   juste au dessus »] LE COMMENTAIRE CI-DESSUS SE TROMPAIT SUR CET ECRAN. Il posait que la place
   du bas appartient a un seul objet, « la barre d'onglets, ou l'action de l'ecran s'il n'y a pas
   d'onglets. Ici il n'y en a pas ». Il y en a : `#s-multi` porte `avec-barre` et la capsule est
   bien affichee en production. Le bouton, ancre a `bottom:0`, passait donc DESSOUS. On ne discute
   pas la regle, on corrige la prémisse : les deux objets existent, ils s'empilent.
   ⚠️ LE BOUTON MONTE DE LA HAUTEUR REELLE DE LA CAPSULE, reprise a la lettre de la reserve
      commune (`max(safe-area, 6px) + 74`) et non recopiee a la main : deux ecritures du meme
      nombre finissent toujours par diverger, et celle-la a deja ete corrigee une fois le 06/08.
   ⚠️ ET SON REMBOURRAGE BAS REDESCEND A 14 : la zone sure est deja franchie par la capsule qui
      se trouve dessous. La compter deux fois ferait flotter le bouton 34 px trop haut sur une
      app installee, et nulle part ailleurs — le pire des defauts, celui qui ne se voit pas sur
      l'appareil ou l'on teste. Il reste donc 14 px d'air entre le bouton et la capsule.
   ⚠️ LA RESERVE DU CORPS ADDITIONNE LES DEUX, sinon la derniere rangee se cache sous le bouton
      au lieu de se cacher sous la barre : on aurait deplace le defaut, pas repare. Elle pese
      (1,4,0) et passe donc devant la reserve de barre (1,3,0) comme devant celle du bouton
      (1,2,0). Verifie au CSSOM, pas a la lecture. */
#s-multi.avec-barre .ng-ancre{
  bottom:calc(max(env(safe-area-inset-bottom,0px), 18px) + 74px);
  padding-bottom:var(--e-3)}
#s-multi.ng-on.avec-barre:not(.au-fil)>.jr-body{
  padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 84px + 78px)}
#s-multi .ng-valider{position:relative;width:100%;min-height:50px;
  display:flex;align-items:center;justify-content:center;gap:var(--e-2);border:0;
  border-radius:var(--r-2);cursor:pointer;
  font-size:var(--t-3);font-weight:600;letter-spacing:-.015em;color:#170B20;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),
             0 4px 10px -6px rgba(0,0,0,.55),
             0 14px 30px -14px rgba(139,92,246,.62);
  transition:transform .16s var(--ease)}
#s-multi .ng-valider:active{transform:scale(.985)}
#s-multi .ng-valider .ng-g{width:20px;height:20px;flex:0 0 auto;fill:none;
  stroke:currentColor;stroke-width:1.55;stroke-linecap:round;stroke-linejoin:round}

/* ═══════════════════════════════════════════════════════════════════════════
   « JE N'AI JAMAIS » EN SOIREE — rendu du 08/08, porte le 08/08
   ═══════════════════════════════════════════════════════════════════════════
   ⚠️ PERIMETRE : LES 74 CARTES DE TYPE `jamais` DU MODE SOIREE, ET ELLES SEULES.
   Tout ce bloc vit sous `:is(#s-game,#s-classic-run)[data-carte]`. Les six autres types de
   la Soiree (verite, action, tu preferes, pour combien, balance, quiz) gardent
   l'ecran d'avant au pixel, et le jeu « Je n'ai jamais » des CLASSIQUES, qui est
   un autre ecran (`s-classic-run`) nourri d'un autre fichier (classics-fr.json,
   267 phrases), n'est pas concerne : il aura son propre rendu, different.

   ⚠️ TOUTES LES CLASSES SONT PREFIXEES `jn-`. Le 07/08, `.jeu` a ete reutilise
      sans verifier : c'etait deja la tuile du catalogue des mini-jeux, avec un
      `min-height:124px` qui ecrasait la phrase. Une collision de nom ne se voit
      dans AUCUNE relecture — la declaration fautive n'est ecrite nulle part.

   ⚠️ AUCUN `color-mix` : le rendu en emploie, un Safari d'avant 16.2 rendrait la
      declaration invalide et perdrait le halo. Memes valeurs, en rgba().
   ⚠️ AUCUNE TAILLE EN px pour le TEXTE (contrat UI-06) : sinon le reglage Grand
      texte ne les agrandit pas. Valeurs du rendu converties en rem sur base 16.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── les enveloppes sont INERTES hors du type ──────────────────────────────
   `display:contents` retire la boite sans retirer l'element : la carte
   participe a la mise en page de l'ecran exactement comme avant, et les six
   autres types ne peuvent pas etre affectes. */
:is(#s-game,#s-classic-run) .jn-scene,:is(#s-game,#s-classic-run) .jn-paquet{display:contents}
/* ⚠️ TOUT OBJET AJOUTE DANS LA CARTE DOIT ENTRER DANS CETTE LISTE, SANS EXCEPTION. Le
   08/08 j'ai pose `.jn-choix` et `.jn-cond` dans le markup sans les y mettre : le conteneur
   vide se dessinait pour les SEPT types et ajoutait sa hauteur a des cartes qui ne l'ont
   jamais demande. Le banc des six autres types l'a vu, la relecture non — un conteneur vide
   n'a pas de contenu a montrer, seulement une hauteur a prendre. */
:is(#s-game,#s-classic-run) .jn-titre,:is(#s-game,#s-classic-run) .jn-quand,:is(#s-game,#s-classic-run) .jn-trait,:is(#s-game,#s-classic-run) .jn-valeur,
:is(#s-game,#s-classic-run) .jn-choix,:is(#s-game,#s-classic-run) .jn-cond,:is(#s-game,#s-classic-run) .jn-appel,
:is(#s-game,#s-classic-run) .jn-av{display:none}

/* ── la famille du defi : « Je n'ai jamais » est un CLASSIQUE ───────────────
   LE DECOR DIT OU ON EST, LE BADGE DIT CE QU'ON JOUE. Le decor de l'ecran
   (jauge, halo de carte, bouton) reste le violet de la Soiree et ne bouge
   jamais ; seul le badge porte la famille, ici le fuchsia. Sans cette
   separation l'ecran clignoterait a chaque manche, puisqu'une Soiree melange
   les familles. */
:is(#s-game,#s-classic-run)[data-carte]{
  --jn-decor:#8E48F0; --jn-decor-hi:#B486F8; --jn-decor-bas:#7526D8;
  /* ⚠️ [08/08] LES QUATRE VALEURS DERIVEES DU DECOR, calculees et non choisies :
     le degrade du bouton prend 20 % et 55 % du ton bas dans le ton plein, le halo
     a besoin du ton plein en composantes, et le nom du mode de 35 % de la crete dans
     #837B94. Ecrites en dur parce que ce bloc s'interdit `color-mix` (Safari d'avant
     16.2 jette la declaration) ; le calcul vit dans outils, pas dans la feuille. */
  --jn-decor-rvb:142,72,240; --jn-decor-20:#8941EB; --jn-decor-55:#8035E3;
  --jn-titre-teinte:#947FB7;
  --jn-m1:#F45CC0; --jn-m2:#D22C96; --jn-m3:#B01A7C;
  --jn-encre:#F7F5FA;
  /* ⚠️ [08/08] DEUX ENCRES ET NON UNE. Le badge porte l'encre de l'app (#F7F5FA) ;
     la carte est une AUTRE famille de surface et porte la sienne (#F6F3F7, 14,9:1
     sur le centre de la carte). Le socle demande une encre par famille de surface,
     et le metal noir en est une. */
  --jn-metal:#F6F3F7;
  /* ⚠️ [08/08] #A8A0BA -> #A9A2B2 : le gris de la carte n'est pas celui de l'app.
     Le premier est violace et se posait sur un noir prune ou il disparaissait a
     moitie ; celui-ci est le gris du metal, mesure 6,1:1. */
  --jn-gris:#A9A2B2;
  --jn-filet:rgba(255,255,255,.15);
  /* ⚠️ [08/08] LE CHIFFRE PORTE LE ROSE DE LA FAMILLE, ECLAIRCI D'UN CRAN. Il n'a
     PAS le rose du badge, et c'est voulu : le badge est un aplat qui doit tenir du
     blanc dessus, donc il est sombre ; le chiffre est de l'encre, donc il est clair.
     Deux roles, deux valeurs, une seule teinte. Mesure 5,25:1 sur le centre. */
  --jn-chiffre:#F072BE;
  /* ⚠️ L'ECART DE COLONNE PASSE A 14, celui que le composant pose entre la ligne du haut et
     la jauge. Il etait a 16 ET la jauge portait en plus son `margin-top:14` : deux mecanismes
     pour un seul ecart, donc 30 au lieu de 14. On garde le `gap` — un seul nombre, une seule
     mecanique — et la jauge ne redonne plus le sien. */
  display:flex;flex-direction:column;gap:var(--e-3);overflow:hidden;
  /* ⚠️ 18 SUR LES COTES, ET C'EST LA SEULE MARGE DE LA PAGE : elle pose les deux boutons
     du haut et la jauge, qui ne redonnent plus la leur. Le releve du composant trouvait
     TROIS marges sur quatre objets superposes (11,7 · 12,1 · 18 · 49,9). */
  /* ⚠️ EN HAUT, `zone sure + 8` ET NON `max(zone sure, 16)` : le composant pose son
     conteneur ainsi, et la ligne du haut y gagne 8 pt qui vont a la carte. La difference ne
     se voit que sur un telephone SANS encoche — avec encoche, les deux formules donnent
     presque la meme chose. */
  padding:calc(env(safe-area-inset-top,0px) + var(--e-2)) max(env(safe-area-inset-right,0px),var(--e-3))
          max(env(safe-area-inset-bottom,0px),1rem) max(env(safe-area-inset-left,0px),var(--e-3));
}

/* ⚠️⚠️ [08/08] LE DECOR SUIT LE MODE, ET C'EST LA SEULE CHOSE QUI CHANGE D'UN MODE A
   L'AUTRE. Le rendu des Classiques ne differe de celui de la Soiree que par
   `data-jeu="classiques"` : meme cadre, meme carte, meme interieur, autre couleur.
   ⚠️ MON PORTAGE DU 08/08 AVAIT FIGE LE VIOLET, et le banc l'avait annonce comme une
      reussite : il verifiait l'EGALITE du bouton entre les deux ecrans, donc un bouton
      violet sur les Classiques passait pour une preuve que le cadre tenait. Ce qui doit
      etre identique d'un mode a l'autre c'est la FORME, pas la couleur. */
#s-classic-run[data-carte]{
  --jn-decor:#D22C96; --jn-decor-hi:#F45CC0; --jn-decor-bas:#B01A7C;
  --jn-decor-rvb:210,44,150; --jn-decor-20:#CB2891; --jn-decor-55:#BF2288;
  --jn-titre-teinte:#AB70A3;}

/* le compte de manches quitte l'ecran (la jauge le dit deja, sans chiffre a
   lire) mais reste LU par les lecteurs d'ecran, ou il ne coute rien. */
/* ⚠️ `margin-bottom:0` : la barre de titre de l'app en portait 6, que le rendu n'a pas.
   Six points invisibles a l'oeil, pris a la carte, et qui ne se voient que dans un budget
   de hauteur bloc par bloc. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar{padding:0;min-height:0;flex:0 0 auto;margin-bottom:0}
/* ⚠️⚠️ [08/08, Theo sur photo d'appareil : « alignement, centrer »] « SOIREE » N'ETAIT
   PAS CENTRE, IL TOMBAIT 21 pt A DROITE. La barre porte deux cales de 42 px, une de
   chaque cote du titre, posees pour equilibrer un bouton qui n'existe plus sur CET
   ecran : le « ? » des regles y est masque et le compte de manches est passe en
   lecture d'ecran seule. Les deux cales sont donc devenues du vide, et elles ne se
   sont pas retrecies pareil — l'une a rendu 42, l'autre 0.
   ⚠️ `!important` EST NECESSAIRE ICI, ET C'EST LA SEULE RAISON QUI LE JUSTIFIE : la
      largeur est ecrite en attribut `style` dans le HTML, et un style en ligne bat
      n'importe quel selecteur sans lui. On ne retire pas les cales du markup : elles
      servent aux six autres types de carte, qui gardent leur barre.
   ⚠️ ET ON NE CENTRE PAS PAR `position:absolute` : la barre perdrait sa hauteur, et
      tout ce qui suit remonterait de 20 pt. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar>span:not(.jn-titre):not(.hud-compte){width:0!important}
:is(#s-game,#s-classic-run)[data-carte] .hud-compte{
  position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* ⚠️⚠️ [08/08] LE NOM DU MODE REDEVIENT LE NOM DE CE QU'ON JOUE. A 13 px en 700 sur
   un gris neutre, il etait traite comme une mention : au-dessus du seuil de
   lisibilite mais au NIVEAU DU DECOR. Il monte a 15 px, descend en 600, et prend
   35 % de la crete du mode dans un gris de base.
   ⚠️ L'INTERLETTRAGE BAISSE QUAND LE CORPS MONTE : .16em a 13 px et .16em a 15 px
      ne posent pas le meme blanc entre les lettres. L'espacement est proportionnel,
      l'oeil ne l'est pas. .085em.
   ⚠️ ET LA COULEUR EST CALCULEE, PAS CHOISIE : 35 % de #B486F8 (la crete du violet)
      dans #837B94 donne #947FB7. Ecrite en dur parce que ce bloc s'interdit
      `color-mix` (Safari d'avant 16.2 jetterait la declaration), et parce que le
      decor d'un mode ne change JAMAIS a l'interieur de ce mode : il n'y a rien a
      calculer au vol. Mesure du rendu : rgb(148, 127, 183), soit la meme valeur.
   ⚠️ ON NE PEUT PAS DESCENDRE PLUS BAS QUE #837B94 COMME BASE : #7A7389 rend 4,39
      et #6F6880 3,76. Le gris ECLAIRCIT en recevant la teinte, il ne s'assombrit
      pas — aucun mode ne passe sous le seuil. */
:is(#s-game,#s-classic-run)[data-carte] .jn-titre{
  display:block;flex:1;text-align:center;
  /* ⚠️ INTERLIGNE 1 : herite, il rendait 23 pt la ou le rendu en rend 20, et ces 3 pt
     etaient pris a la carte. Une ligne de titre ne se mesure pas au texte courant. */
  /* ⚠️⚠️ [08/08, Theo, image de reference du haut] CORPS 18, INTERLETTRAGE .2em. Resolu par
     MESURE et non a l'oeil : sur l'image, « SOIREE » rend 80 pt de large pour 13,3 pt de
     capitale. Vingt-cinq couples corps/interlettrage ont ete rendus et mesures ; celui-ci
     donne 80,1 et 13,0. Le notre rendait 56 pt, soit 30 % trop petit — le titre etait une
     mention, il redevient le nom de ce qu'on joue.
     ⚠️ ET L'INTERLETTRAGE MONTE AVEC LE CORPS ICI, contre la regle posee le 08/08 au matin
        (« l'interlettrage baisse quand le corps monte »). Cette regle vaut pour un meme
        dessin agrandi ; ici le dessin CHANGE, l'image de reference etale franchement les
        lettres. La regle n'est pas fausse, elle ne s'applique pas a ce cas. */
  font-size:var(--t-3);font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  line-height:1.34;color:var(--jn-titre-teinte)}
/* le « ? » des regles quitte cet ecran, comme dans le rendu : il reste joignable
   depuis l'accueil, sur la tuile du mode, avant de lancer la partie. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar>.iconbtn{display:none}
/* ⚠️⚠️ [08/08] LES DEUX OBJETS PROPRES AUX CLASSIQUES QUE LE CADRE NE PREVOIT PAS.
   ① Le titre du jeu (« Qui pourrait ») vivait dans la barre du haut. Le cadre y met le
      nom du MODE, et le nom du JEU est deja sur le badge de la carte, juste dessous :
      l'ecrire aux deux endroits ne dit pas deux choses, ca en repete une.
   ② Le bouton de reglages se tenait ENTRE la jauge et la carte, la ou le cadre ne laisse
      rien. Il ne disparait pas du produit : les memes deux reglages s'ouvrent par le menu,
      qui prend la place de la fleche retour. Le retirer sans porte l'aurait supprime.
   Les deux restent dans le markup : ils servent aux etats sans cadre. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar>b{display:none}
:is(#s-game,#s-classic-run)[data-carte]>.cl-reglages{display:none}

/* ⚠️⚠️ [08/08] LA JAUGE PREND LA LARGEUR DE LA SCENE, PAS CELLE DE L'ECRAN. Elle
   traversait d'un bord a l'autre quand tout le reste s'est resserre : la carte est
   centree avec ses marges, et la jauge restait le seul objet a toucher les deux
   bords. Elle pesait donc plus que ce qu'elle dit — un avancement, pas une
   information qu'on lit. Meme retrait que la scene, 44 px.
   ⚠️ 3 px -> 2 px, ET 2 EST UN PLANCHER : en dessous, un trait de progression
      disparait sur un ecran a forte densite, et la part remplie ne se distingue
      plus du creux.
   ⚠️ LE CREUX S'ASSOMBRIT (--card-2 #231F2E -> #1A1522) ET LA PART REMPLIE SE
      CALME : la jauge ne doit pas etre le premier objet qu'on voit en arrivant.
      La part remplie est la crete du mode ramenee a 70 % sur le fond, soit
      rgb(129, 97, 177) — valeur mesuree sur le rendu, ecrite en dur pour la meme
      raison que le titre. Le rayon manquait : sur 2 px il ne se voit pas, mais il
      evite que la tete de la part remplie soit carree quand la partie avance. */
/* ⚠️⚠️ [08/08, Theo : « la barre de progression est trop large »] ELLE PREND LA LARGEUR DE
   LA CARTE, MESUREE. Elle valait la largeur de la SCENE, donc 317 quand la carte en fait
   298 : elle debordait de 10 pt de chaque cote, et son bord gauche venait buter contre le
   bouton de menu. Une jauge plus large que ce dont elle mesure l'avancement ne dit pas la
   meme chose.
   ⚠️ LE RENDU VOULAIT DEJA CA ET Y A RENONCE, en l'ecrivant : « suivre sa largeur exacte
      demanderait de la mesurer, donc du script ». Nous mesurons deja la carte pour la poser,
      il suffisait de publier le resultat — `ajusteJamais` ecrit `--jn-carte-l` sur la racine.
   ⚠️ LE REPLI COMPTE : avant la premiere mesure, et sur un moteur ou elle echoue, la jauge
      reprend la largeur de la scene. Jamais zero, jamais pleine largeur. */
/* ⚠️⚠️ ELLE PREND LA MARGE DE PAGE, PAS LA SIENNE. Je l'avais calee sur la largeur MESUREE
   de la carte ; le composant tranche l'inverse et il a raison sur un point que je n'avais pas
   vu : calee sur la carte, elle n'etait alignee ni sur les boutons du dessus ni sur la marge
   de la page. Pleine largeur du conteneur, donc les memes 18 que les boutons.
   ⚠️ ET ELLE EST A UN PIXEL PHYSIQUE : une boite d'un pixel plein ecrasee par
      `transform:scaleY(.34)`. « Un filet a `height:1px` est arrondi a l'entier sur un ecran
      3x, soit trois pixels physiques. » Meme lecon que les demi-pixels du 05/08.
   ⚠️ LE REMPLI PREND `--violet-2`, LA PISTE LE VOILE DES COMMANDES : ce qui progresse porte
      la couleur de l'app, ce qui reste a faire porte la matiere du fond. */
:is(#s-game,#s-classic-run)[data-carte]>.progress{
  position:relative;flex:0 0 auto;width:100%;height:1px;margin:0;border-radius:0;
  transform:scaleY(.34);background:rgba(255,255,255,.10);overflow:visible}
:is(#s-game,#s-classic-run)[data-carte]>.progress>span{
  position:absolute;left:0;top:0;bottom:0;height:auto;border-radius:0;background:var(--jn-decor)}

/* ── la scene ─────────────────────────────────────────────────────────────
   ⚠️ LES 20 pt D'AIR SONT PORTES PAR LA SCENE, PAS PAR LA CARTE. Plafonner la
      carte a `calc(100% - 40px)` a ete essaye le 07/08 : sur un ecran large la
      hauteur etait coupee sans que la largeur suive, et le rapport tombait a
      1,443. LE FORMAT EST FIGE — on ne lui prend pas 40 pt pour faire de la
      place. En rembourrage de la scene, le rapport tient et l'air vient du
      dehors. Et la carte est CENTREE : sans ca les 40 pt rendus a l'air
      tombaient tous en bas (mesure du 07/08 : 53 en haut contre 96 en bas). */
/* ⚠️⚠️ [08/08] LA RESERVE D'EVENTAIL EST DES DEUX COTES — 22 pt a gauche COMME a
   droite, soit 44 en tout. Elle n'etait qu'a droite, la ou l'eventail passe : la
   CARTE se retrouvait donc decalee d'une dizaine de points a gauche du centre de
   l'ecran, meme une fois le groupe centre. C'est la carte que l'oeil centre, pas le
   groupe — l'eventail n'est qu'un lisere, et il a le droit de deborder dans la
   marge d'ecran. La carte perd 22 pt de large, et c'est le prix accepte. */
:is(#s-game,#s-classic-run)[data-carte] .jn-scene{
  display:flex;flex-direction:column;justify-content:center;align-items:center;
  /* ⚠️⚠️ [08/08] L'AIR EST UN RESSORT, PAS UN SEUIL — et j'avais mis un seuil. J'ai porte
     le `@media (max-height:700px)` du rendu, qui fait tomber l'air de 20 a 8 sur ecran
     court. Le dossier l'interdit, et il donne la raison : « Aucune media query de hauteur,
     nulle part. Trois calibrages ont echoue — 740, 780, 900 — et la cause n'etait pas le
     nombre, c'etait l'outil. Sur iOS, Safari evalue les media queries de hauteur contre la
     fenetre barre d'adresse MASQUEE, pas contre ce qui est affiche. » Autrement dit le
     seuil se declenche au mauvais moment sur le telephone meme ou il devait servir.
     ⚠️ LE RESSORT REPOND DEJA A LA QUESTION. L'air vaut 16, le minimum du projet (« un
        ressort ne descend jamais sous 16 px »), et la carte etant plafonnee a 94 % de la
        place, les 6 % restants se repartissent au-dessus et en dessous par le centrage :
        l'air GRANDIT tout seul quand l'ecran est grand et se reduit quand il est serre,
        sans qu'aucun seuil n'ait a connaitre l'appareil.
     ⚠️ CE QUE CA COUTE, ET C'EST DIT : sur un tres petit ecran le rendu descendait a 8, on
        s'arrete a 16. Deux points de carte en moins, contre un reglage qui ne ment pas. */
  flex:1 1 auto;min-height:0;width:calc(100% - 44px);margin-inline:auto;padding:var(--e-3) 0}

/* ⚠️⚠️ [08/08] QUAND LA HAUTEUR MANQUE, C'EST LA LARGEUR QUI CEDE, JAMAIS LE
   RAPPORT. Avec `width:100%` + `max-height:100%`, un ecran serre coupait la hauteur
   sans que la largeur suive : la carte rendait 1,44 au lieu de 1,561, et sur un
   petit telephone elle devenait presque carree. UN FORMAT FIGE NE CEDE PAS, c'est
   l'objet qui retrecit.
   ⚠️⚠️ ECART ASSUME AVEC LE RENDU, ET C'EST LE SEUL DE CE PORTAGE. Le rendu plafonne
      la largeur par une formule qui contient `--hors-carte`, « tout ce qui n'est pas
      la carte » : 258 px, puis 234 sous 700. Son propre en-tete le designe comme
      LE SEUL NOMBRE FRAGILE DU FICHIER, qui ment des qu'un element autour de la
      carte bouge d'un pixel, et renvoie a huit lignes de JavaScript pour le
      remplacer par une mesure. Ce nombre ne vaut de toute facon pas chez nous : nos
      marges, notre barre de titre et notre pied ne sont pas les siens.
      C'est donc `ajusteJamais` qui MESURE la scene et pose la largeur. Il n'y a
      aucune constante a tenir a jour : le jour ou le pied change, la mesure suit
      toute seule.
   ⚠️⚠️ ET SURTOUT PAS `height:100%` ICI. Essaye puis retire le 08/08 : `aspect-ratio`
      ne calcule que la dimension NON SPECIFIEE. Avec une hauteur imposee, la largeur
      s'est fait rattraper par un `max-width` et la hauteur, elle, n'avait plus le
      droit de ceder — la carte rendait 295 x 538, soit un rapport de 1,82. C'est
      EXACTEMENT le defaut que le rendu decrit pour l'ancienne ecriture, refait par
      une autre porte. La largeur commande, la hauteur suit, et rien d'autre.
   ⚠️ LE −6 % EST DANS LA MESURE, PAS DANS LE CSS. Un `max-width:94%` ici s'ajouterait
      a la largeur deja calculee au lieu de la remplacer : deux plafonds pour une
      seule largeur, et c'est le plus bas qui gagne sans qu'on sache lequel. */
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet{
  display:flex;position:relative;flex:0 1 auto;min-height:0;
  width:100%;max-height:100%;margin-inline:auto;aspect-ratio:57/89}

/* ── l'eventail : trois plans, jamais deux ────────────────────────────────
   ⚠️ IL EST DE LA MEME MATIERE QUE LA CARTE. Un paquet n'est pas un decor,
      c'est le meme objet vu de dessous : le teinter au mode ferait porter deux
      choses a une seule variable, et mentirait sur ce qu'on regarde.
   ⚠️ SUR NOIR, LE BAS DE LA PILE RESTE AU-DESSUS DU FOND (#121217 au plus
      sombre contre #0C0C0F) : plus sombre que l'ecran, la carte du dessous
      n'est plus posee dessus, elle est creusee dedans. C'est le BORD qui
      silhouette, pas l'ecart de valeur. */
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet::before,
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet::after{
  content:'';position:absolute;inset:0;border-radius:var(--r-3);
  transform-origin:0% 55%;z-index:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16)}
/* ⚠️ [08/08] TROIS RANGS DE BORD, PAS TROIS COULEURS. Les liseres etaient blancs a
   14 % puis 10 % : sur un noir prune, un blanc translucide vire au gris et sort de
   la famille de la carte. Ce sont des violets sombres, et c'est leur CLARTE qui
   creuse la pile — elle decroit regulierement, 0x40 puis 0x2C puis 0x20 sur le bleu.
   Les fonds suivent la matiere prune de la carte, un cran plus sombre chacun, sans
   jamais descendre sous le fond de l'ecran : plus sombre que l'ecran, une carte
   n'est plus posee dessus, elle est creusee dedans. */
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet::after{
  transform:translateX(7px) rotate(.8deg);border:1px solid #2E2140;
  background:linear-gradient(160deg,#151119 0%,#121016 100%)}
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet::before{
  transform:translateX(15px) rotate(1.6deg);border:1px solid #281C38;
  background:linear-gradient(160deg,#121016 0%,#0F0D13 100%)}

/* ── la carte ─────────────────────────────────────────────────────────────
   Le metal noir n'est pas le fond de l'ecran assombri : c'est une surface qui
   RECOIT la lumiere, donc plus claire que le fond, sinon elle redevient un
   trou. Les deux ombres interieures sont la matiere, les deux exterieures le
   halo du mode — le seul endroit ou le mode touche la carte. */
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet>.gamecard{
  position:absolute;inset:0;z-index:1;margin:0;
  display:flex;flex-direction:column;overflow:hidden;border-radius:var(--r-3);
  /* le rythme du corps est porte par la carte elle-meme : pas de conteneur en
     plus, donc pas de structure differente entre les sept types de carte.
     Au moins 16 entre deux groupes (socle) ; c'est le SEUL endroit ou la carte
     a du jeu, donc c'est lui qui se resserre quand la place manque. */
  /* ⚠️ [08/08] L'AIR EST ECRIT, IL N'EST PLUS UN RESTE. Le rythme descend de 18 a
     14, et le retrait devient dissymetrique — 24 en haut, 30 en bas : le quart bas
     de la carte ne porte que la dose, il lui faut plus de sol qu'au badge de ciel. */
  /* ⚠️⚠️ [08/08, Theo : « on ne peut pas garder juste la meme DA comme la »] LES ECARTS
     INTERIEURS SONT FIXES ET C'EST LE GROUPE QUI SE CENTRE. La bande du milieu grandissait
     pour absorber toute la place libre : sur une carte plus haute que celle du rendu — la
     notre fait 489 la ou le rendu en fait 434 au meme ecran — les 55 pt supplementaires
     tombaient TOUS entre le badge et la condition. Les options se retrouvaient isolees entre
     deux vides et la sanction descendait d'autant.
     ⚠️ LE RENDU LE DIT, ET C'EST SON COMMENTAIRE QUI AVAIT RAISON CONTRE SON CSS : « les trois
        blocs forment un groupe compact, aux ecarts choisis, et c'est le GROUPE qui est centre ;
        le reste de la place tombe en haut et en bas, la ou le vide se lit comme de la marge et
        non comme un trou. » J'avais porte le CSS.
     ⚠️ CONSEQUENCE MESUREE : les ecarts interieurs deviennent identiques a ceux du rendu, et
        la difference de hauteur de carte devient de la MARGE, en haut et en bas, a parts
        egales. Une carte plus grande ne redessine plus son interieur. */
  align-items:center;text-align:center;gap:var(--e-3);padding:var(--e-4) var(--e-4) var(--e-5);
  /* ⚠️ [08/08] LE LISERE N'EST PLUS UN BLANC TRANSLUCIDE. A 11 % sur un noir prune
     il rendait un gris qui n'appartenait a rien ; c'est un violet sombre, de la
     meme famille que la carte et que les deux rangs de l'eventail. */
  border:1px solid #39284D;
  /* ⚠️⚠️ [08/08] LA CARTE DOIT EXISTER SANS SON HALO. Test : on masque mentalement
     la lueur violette ; s'il ne reste qu'un rectangle noir sur du noir, la carte n'a
     pas de surface, elle a un CONTOUR. C'etait le cas — les bandes etaient neutres
     (#1A1A20 a #0E0E13, du gris) et la carte ne tenait que par sa lueur.
     Trois valeurs separent maintenant trois plans, et l'ecart est petit mais reel :
     c'est un OLED, deux points de clarte s'y voient. Le noir reste PRUNE : entre un
     noir bleute, un violet froid et un blanc neutre, toute la carte tirait vers le
     froid et le rose du badge restait isole.
     ⚠️ LA RADIALE N'EST PAS UN HALO : elle ne dessine aucun bord et n'a pas de
        limite visible, c'est la carte qui est plus claire au milieu, comme une
        surface prend la lumiere. Si on commence a voir ou elle s'arrete, c'est
        qu'elle est trop forte. */
  background:
    radial-gradient(74% 46% at 50% 44%, rgba(255,255,255,.022) 0%, transparent 70%),
    linear-gradient(160deg,
    #16121B 0%, #131019 22%, #110D15 44%,
    #141018 60%, #100D15 78%, #0E0B12 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.20),
    inset 0 -1px 0 rgba(0,0,0,.6),
    0 0 20px -2px rgba(var(--jn-decor-rvb),.46),
    0 0 54px -14px rgba(var(--jn-decor-rvb),.38)}
/* le halo radial d'accent de l'ecran d'avant n'a rien a faire sur le metal :
   le pseudo-element est REPRIS pour porter le grillage, seul motif de la carte.
   Il s'eteint moins qu'un bruit de fond sous le texte : assez pour ne pas
   gener la lecture, assez pour se voir partout ailleurs. */
:is(#s-game,#s-classic-run)[data-carte] .jn-paquet>.gamecard::before{
  background:none;opacity:1;
  /* ⚠️⚠️ [08/08] ON REGLE LE MASQUE, PAS L'ENCRE — et c'est la lecon du rendu, payee
     chez lui en trois passes perdues. Baisser l'opacite partout eteint le motif au
     BORD avant de l'eteindre au MILIEU, parce que le masque n'en laisse passer
     qu'une fraction au centre et tout aux angles. Le creux descend et grossit
     (80x60 a 46 %), l'encre baisse de 20 %, et le motif devient une BORDURE de
     matiere : il encadre la carte comme un bord de papier et ne dispute plus rien a
     la phrase. Effectif au centre : .0017, invisible meme a forte densite.
     ⚠️ SI ON VEUT UN JOUR LE REVOIR AU CENTRE, C'EST LE MASQUE QU'ON OUVRE, PAS
        L'ENCRE QU'ON MONTE. */
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,.058) 0 1px, transparent 1px 11px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.036) 0 1px, transparent 1px 11px);
  -webkit-mask-image:radial-gradient(80% 60% at 50% 46%, rgba(0,0,0,.03) 0%, rgba(0,0,0,.07) 55%, rgba(0,0,0,.45) 84%, #000 100%);
  mask-image:radial-gradient(80% 60% at 50% 46%, rgba(0,0,0,.03) 0%, rgba(0,0,0,.07) 55%, rgba(0,0,0,.45) 84%, #000 100%)}

/* ── le corps : le jeu, la phrase, qui boit et combien ─────────────────────
   Rythme du socle : au moins 16 entre deux groupes. Le corps est le SEUL
   endroit ou la carte a du jeu, donc c'est lui qui se resserre quand la place
   manque (voir les trois crans de compaction plus bas). */

/* ── le nom du jeu, en premier des trois blocs ─────────────────────────────
   Il s'encadre au traitement des tuiles de l'accueil (148°, quatre arrets,
   plateau repete de 40 a 72 %) : le joueur reconnait la famille qu'il a vue
   deux ecrans plus tot. Le cadre n'est pas un aplat plein — l'aplat reste
   reserve a ce qu'on touche, c'est-a-dire au bouton. */
/* ⚠️⚠️ [08/08] LE BADGE N'EST PLUS UNE TUILE DE MENU. Il reprenait la recette de
   l'accueil — 148°, quatre arrets, 40 points d'ecart entre la crete et le pied,
   plus deux halos roses. Sur une carte, ce contraste interne en faisait un BOUTON :
   c'est lui qui donnait le plus l'air d'une interface de jeu mobile. Il redevient
   un marqueur de categorie : deux arrets a 160°, 5 % d'ecart, et AUCUN halo. Le
   degrade est presque invisible, ce qui est exactement la demande.
   ⚠️ ET IL MAIGRIT DE 9 % : sur l'appareil il revient plus large et plus gras que
      dans les rendus, et il reprend l'ascendant sur la phrase qu'il coiffe. Le
      retrait suit le corps, sinon le bandeau regrossit en proportion de son texte —
      13/26 -> 9/20, rayon 16 -> 12, graisse 800 -> 700.
   ⚠️ LES DEUX ARRETS SONT CALCULES DEPUIS LA FAMILLE, pas choisis : #D22C96 tel
      quel, puis 12 % et 25 % de #B01A7C dedans, soit #CE2A93 et #C92890. Ecrits en
      dur, ce bloc s'interdisant `color-mix`. Si le rose de famille bouge, ces deux
      valeurs se recalculent — elles n'ont aucune existence propre. */
:is(#s-game,#s-classic-run)[data-carte] .tag{
  align-self:center;flex:0 0 auto;margin:0;
  padding:var(--e-2) var(--e-4);border-radius:var(--r-1);border:0;
  background:linear-gradient(160deg, var(--jn-m2) 0%, #CE2A93 55%, #C92890 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14);
  font-size:clamp(1.0625rem,4.7vw,1.25rem);font-weight:700;letter-spacing:-.005em;
  line-height:1.15;text-transform:none;color:var(--jn-encre)}

/* ── la phrase, dans le tiers haut ────────────────────────────────────────
   ⚠️ ELLE NE REPETE PLUS LE NOM DU JEU. Nos 74 cartes ecrivent « Je n'ai
      jamais … » alors que le badge le dit deja juste au-dessus : le debut est
      retire A L'AFFICHAGE (poseJamais dans app.js), jamais dans le contenu —
      reecrire les cartes leur ferait perdre leur validation. */
:is(#s-game,#s-classic-run)[data-carte] .cardtext{
  /* ⚠️⚠️ C'EST LA PHRASE QUI PORTE LE RESSORT, ET C'EST VOULU. Essaye en `flex:0 0 auto` le
     08/08, avec le groupe centre : tous les ecarts interieurs tombaient a 14, alors que le
     rendu en a 28 entre le badge et le coeur et 51 entre le coeur et la condition. Son rythme
     VIENT de cette bande qui s'etire. Le vrai ecart n'etait pas la, il etait dans la HAUTEUR
     de la carte — voir le plafond pose dans `ajusteJamais`. */
  flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;
  width:100%;margin:0;
  /* ⚠️ [08/08] 800 -> 600, ET L'AIR VIENT DE L'INTERLIGNE. A 800 la phrase pesait
     autant que le badge qui la coiffe : deux vedettes sur trois blocs. Elle reste ce
     qu'on lit en premier, mais elle cesse de former un pave — 1,2 -> 1,32. */
  font-weight:600;letter-spacing:-.015em;line-height:1.32;color:var(--jn-metal);
  overflow-wrap:anywhere}
:is(#s-game,#s-classic-run)[data-carte] .cardtext>span{display:block;width:100%;text-wrap:balance}
/* ⚠️⚠️ [08/08] LES QUATRE RANGS DESCENDENT DE 10 %, ET LA DEMANDE VIENT D'UNE PHOTO
   D'APPAREIL, PAS D'UNE CAPTURE. SF Pro Display est plus LARGE et plus GRASSE a
   corps egal que la grotesque de repli d'un navigateur de bureau : ce qui tient sur
   deux lignes dans un rendu en prend trois sur le telephone. 34/29/25/21 -> 31/26/23/19.
   ⚠️ CE QUE CA APPREND POUR LA SUITE : tout reglage de corps decide sur un rendu
      d'ordinateur est un PROVISOIRE. Seule la photo de l'appareil tranche. */
:is(#s-game,#s-classic-run)[data-carte] .cardtext[data-taille="s"] {font-size:clamp(1.5rem,6.8vw,1.9375rem)}
:is(#s-game,#s-classic-run)[data-carte] .cardtext[data-taille="m"] {font-size:clamp(1.3125rem,5.9vw,1.625rem)}
:is(#s-game,#s-classic-run)[data-carte] .cardtext[data-taille="l"] {font-size:clamp(1.125rem,5.2vw,1.4375rem);line-height:1.26}
:is(#s-game,#s-classic-run)[data-carte] .cardtext[data-taille="xl"]{font-size:clamp(1rem,4.4vw,1.1875rem);line-height:1.34}

/* ── la condition ─────────────────────────────────────────────────────────
   Elle appartient a la phrase : elle dit qui est concerne par ce qu'on vient
   de lire. En petites capitales grises tres espacees elle etait le reglage le
   moins lisible de l'ecran, et elle portait la phrase la plus longue du bloc ;
   elle redevient une phrase. */
/* ⚠️ LE CONTENEUR DE LA CONDITION REVIENT AVEC ELLE : il est inerte pour les types non
   portes, mais la condition vit DEDANS. Rendre l'enfant sans rendre son parent ne rend
   rien — le premier `display:none` rencontre en remontant gagne. */
:is(#s-game,#s-classic-run)[data-carte] .jn-cond{display:flex;flex-direction:column;align-items:center;flex:0 0 auto}
:is(#s-game,#s-classic-run)[data-carte] .jn-quand{
  display:block;flex:0 0 auto;
  font-size:var(--t-2);font-weight:600;line-height:1.35;color:var(--jn-gris);
  text-wrap:balance}

/* ── le trait a l'etoile ──────────────────────────────────────────────────
   ⚠️ EXCEPTION NOMMEE AU SOCLE. « Aucun filet nulle part » vaut pour ce qui
      SEPARE deux blocs de meme nature. Ici le trait n'est pas une couture : il
      encadre la sanction comme le cadre d'une carte imprimee, et il porte
      l'etoile de la marque.
   ⚠️ L'ETOILE PREND LA COULEUR DE LA FAMILLE, pas celle du decor. */
:is(#s-game,#s-classic-run)[data-carte] .jn-trait{
  display:flex;align-items:center;gap:var(--e-3);width:100%;flex:0 0 auto}
:is(#s-game,#s-classic-run)[data-carte] .jn-trait::before,
:is(#s-game,#s-classic-run)[data-carte] .jn-trait::after{
  content:'';height:1px;flex:1;
  background:linear-gradient(90deg,transparent,var(--jn-filet),transparent)}
:is(#s-game,#s-classic-run)[data-carte] .jn-trait svg{
  width:15px;height:15px;flex:0 0 auto;fill:var(--jn-m2);opacity:.85}

/* ── la valeur ────────────────────────────────────────────────────────────
   Le chiffre est traite comme la valeur d'une carte a jouer : gros, seul, le
   mot en petites capitales dessous. Il reste le plus gros du BAS et non le
   plus gros de la carte — l'ordre de lecture voulu est le jeu, la phrase, la
   sanction.
   ⚠️ MEME ENCRE NE VEUT PAS DIRE MEME GRIS A L'OEIL : des capitales grasses
      posent bien plus d'encre par surface qu'un bas-de-casse. C'est la
      DENSITE qu'on egalise avec la condition, pas la couleur. */
:is(#s-game,#s-classic-run)[data-carte] .jn-valeur{
  display:flex;flex-direction:column;align-items:center;gap:2px;flex:0 0 auto}
/* ⚠️⚠️ [08/08] LE CHIFFRE EST UNE INFORMATION DE JEU, PAS DU TEXTE. En blanc il
   etait lisible et anonyme ; il prend le rose de la famille, eclairci d'un cran
   pour tenir sur le noir prune.
   ⚠️ ET PAS DE DEGRADE DESSUS, MEME S'IL A ETE PROPOSE : un texte en
      `background-clip` ne se MESURE plus, aucun controle ne peut dire s'il passe le
      seuil, et c'est exactement le genre d'objet qui derive ensuite sans qu'on le
      voie. Une couleur pleine et verifiable, 5,25:1. */
:is(#s-game,#s-classic-run)[data-carte] .jn-valeur b{
  font-size:clamp(1.875rem,8vw,2.125rem);font-weight:700;line-height:1;
  letter-spacing:-.03em;color:var(--jn-chiffre)}
:is(#s-game,#s-classic-run)[data-carte] .jn-valeur span{
  font-size:var(--t-1);font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--jn-gris)}

/* ── ce que la carte « Je n'ai jamais » ne porte pas ───────────────────────
   Elle ne designe personne (aucune de nos 74 ne nomme quelqu'un) et n'a pas de
   reponse a reveler. Les blocs restent dans le DOM, inertes. La pastille
   `.sanction` reste la SOURCE du decoupage : masquee, jamais court-circuitee. */
:is(#s-game,#s-classic-run)[data-carte] .g-turn,
:is(#s-game,#s-classic-run)[data-carte] .reveal,
:is(#s-game,#s-classic-run)[data-carte] .sanction{display:none!important}
/* ⚠️⚠️ [08/08, DEUX TEMPS DANS LA MEME JOURNEE, ET LES DEUX SONT ECRITS ICI.
   ① J'avais REPARE l'affichage des prenoms sur « Qui pourrait » : la regle ci-dessus,
      ecrite quand le portage ne couvrait que « Je n'ai jamais » (dont aucune des 74 cartes
      ne nomme personne), enoncait une verite de ce TYPE et pas du cadre, et elle masquait
      le bloc par un `!important`.
   ② PUIS THEO L'A RETIRE : « on ne doit pas pouvoir selectionner des joueurs, ca se fait a
      l'oral ». Ce n'est donc pas un defaut qui revient, c'est une decision qui remplace une
      reparation. Le meme mouvement que « Je me degonfle » sur Action et Verite, tranche dans
      la meme heure.
   ⚠️ CE QUE CA COUTE : une carte de ce type ne designe personne au depart, donc c'etait cet
      ecran qui attribuait la gorgee. Les 42 cartes annoncent leur dose et l'app n'en compte
      aucune — ni bilan, ni statistiques, ni la protection GD-17 contre six designations de
      suite sur la meme personne. Le rituel existait avant l'outil ; il redevient verbal.
   ⚠️⚠️ ON L'EXCLUT DU MASQUAGE, ON NE LE FORCE PAS VISIBLE. Force, le conteneur VIDE
      prenait sa hauteur sur toutes les cartes de ce type qui ne designent encore personne :
      mesure, la dose remontait de 18 px avant meme qu'un prenom existe. C'est mot pour mot
      la lecon deja ecrite plus haut pour `.jn-choix`, repayee le meme jour. Exclu, c'est le
      code d'affichage qui decide, comme partout ailleurs dans l'app.
   ⚠️ LE RENDU NE DESSINE PAS CET ETAT. Les prenoms reprennent donc la forme qu'ils ont
      partout ailleurs dans l'app, et c'est au dossier de dire s'il veut autre chose. */
:is(#s-game,#s-classic-run)[data-carte] .designe{display:none!important}
/* ⚠️⚠️ [08/08, Theo : « le bouton (>>) qui n'existe pas de base », applique a l'identique]
   LE BOUTON « PASSER » SORT DE LA CARTE. Le rendu ne le dessine pas, et pose sur la carte
   il disputait le regard au badge, juste a cote. La carte redevient exactement l'objet du
   rendu ; la fonction, elle, ne disparait pas — elle remonte dans la barre du haut, a
   droite, la ou le « ? » des regles a ete retire. C'est `poseJamais` qui le deplace dans
   le DOM, et qui le remet dans la carte pour les six autres types.
   ⚠️ IL EST HORS DU FLUX (`absolute`) ET C'EST VOULU : dans le flux il prendrait 42 pt
      d'un seul cote de la barre et decalerait « SOIREE » de 21 pt, le defaut qu'on vient
      justement de corriger. Hors du flux, il ne pese sur rien.
   ⚠️ ET IL NE GRANDIT PAS LA BARRE : `top:50%` + translation le centre sur la ligne du
      titre sans lui donner de hauteur, sinon les 42 pt du bouton seraient repris a la
      carte — exactement ce qu'on vient de rendre. */
/* ⚠️⚠️ [08/08, Theo : « le bouton >> doit etre plus au-dessus de la carte que tout en haut »]
   IL SE POSE DANS L'AIR AU-DESSUS DE LA CARTE, pas dans la barre de titre. Colle tout en
   haut, il appartenait au chrome du navigateur plus qu'a la partie ; juste au-dessus de la
   carte, il appartient a la carte qu'il fait passer, et son bord droit s'aligne sur le sien.
   ⚠️ IL EST ENFANT DU PAQUET ET NON DE LA CARTE : `.gamecard` porte `overflow:hidden` pour
      tenir la matiere dans ses coins arrondis, et un enfant a `top` negatif y serait COUPE.
      Le paquet, lui, ne coupe rien.
   ⚠️ 32 pt DE DESSIN POUR 44 pt DE CIBLE : la bande au-dessus de la carte fait 36 pt, un
      bouton de 44 n'y tient pas sans toucher la jauge. La cible est etendue par un `::after`
      sans changer la taille visible — le plancher tactile du socle porte sur la CIBLE, pas
      sur le dessin. */
/* ══════════════════════════════════════════════════════════════════════════
   LA LIGNE DU HAUT — portee du composant `design/ecrans/soiree-ligne-haut.html`
   ══════════════════════════════════════════════════════════════════════════
   ⚠️⚠️ UNE GRILLE A TROIS COLONNES, ET C'EST LA DECISION QUI PORTE TOUT LE RESTE.
   Le composant releve 6,5 pt d'ecart entre l'axe des boutons et celui du titre sur
   la version deployee, et tranche : « On n'aligne pas trois objets a l'oeil quand
   une grille le fait au pixel. » Les deux boutons prennent les colonnes 1 et 3, le
   titre la colonne 2, centre DANS SA COLONNE et non dans ce qui reste.
   ⚠️ QUATRE DESACCORDS RELEVES SUR LE DEPLOYE, TOUS CORRIGES ICI : deux formes
      (un carre a gauche, un ROND a droite, alors que le socle reserve le rond aux
      gens), deux voiles (violace a gauche, neutre a droite), 6,5 pt d'ecart d'axe,
      et TROIS marges pour quatre objets superposes — 11,7 · 12,1 · 18 · 49,9.
      « Une marge de page se declare une fois ; redonnee bloc par bloc, elle finit
      par differer d'un bloc a l'autre. »
   ⚠️ D'OU LA MARGE LATERALE DE L'ECRAN A 18 : c'est elle, et elle seule, qui pose
      les boutons ET la jauge. Plus aucun objet ne redonne la sienne. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar{
  display:grid;grid-template-columns:36px 1fr 36px;align-items:center;
  flex:0 0 auto;min-height:44px;margin:2px 0 0;padding:0}
/* les deux cales de 42 px tenaient un bouton qui n'existe pas sur cet ecran ; la
   grille les remplace, elles n'ont plus rien a tenir. */
:is(#s-game,#s-classic-run)[data-carte]>.topbar>span:not(.jn-titre):not(.hud-compte){display:none}
:is(#s-game,#s-classic-run)[data-carte] .jn-titre{
  display:block;grid-column:2;justify-self:center;
  /* ⚠️ 1.1875rem ET NON 19px : le contrat UI-06 refuse toute taille de police en px, parce
     qu'elles echappent au reglage Grand texte. Le composant ecrit 19px — c'est un rendu
     autonome, il n'a pas ce reglage. 19/16 = 1.1875. */
  font-size:var(--t-3);font-weight:700;letter-spacing:.16em;
  /* ⚠️⚠️ #A8A0BA EN DUR, ET C'EST UN PIEGE PAYE ICI : le composant appelle ce jeton « muted »,
     notre feuille l'appelle `--mut` ET lui donne #8b8b99. Le nom du composant etant inconnu
     chez nous, la declaration devient INVALIDE — pas ignoree avec un repli, invalide — et le
     titre retombe sur l'encre heritee #F4F4F7. Mesure : rgb(244,244,247) la ou le composant
     rend rgb(168,160,186). Une variable qui n'existe pas ne previent jamais.
     ⚠️ ET LES DEUX JETONS NE SE VALENT PAS : #A8A0BA contre #8b8b99, deux gris differents
        sous un meme nom. A trancher au dossier ; en attendant on prend la valeur du
        composant, qui est celle qui a ete jugee. */
  /* ⚠️⚠️ [08/08] ET C'EST FINALEMENT LA TEINTE DU MODE QUI GAGNE, PAS CE GRIS NEUTRE.
     Deux decisions coexistaient dans cette feuille : le bloc du dessus pose la teinte
     (35 % de la crete du mode dans #837B94) en commentant « mesure du rendu :
     rgb(148,127,183) », et CETTE regle, posee plus bas par le portage de la ligne du haut,
     l'ecrasait par simple ordre de cascade. La teinte n'a donc JAMAIS ete rendue depuis le
     08/08, et personne ne l'a vu : deux gris voisins ne se distinguent pas de memoire.
     ⚠️ CE QUI TRANCHE : les deux rendus de carte, Soiree et Classiques, teintent le titre,
        et le second n'existe que pour dire que le decor suit le mode. Un titre neutre sur
        les deux ecrans supprimerait justement ce qui les distingue. Le composant de la
        ligne du haut, lui, est autonome et n'a pas de mode a nommer.
     ⚠️ A SIGNALER AU DOSSIER : `soiree-ligne-haut.html` porte encore le gris neutre. Les
        deux sources sont de Theo, elles se contredisent, et c'est a lui de trancher. */
  text-transform:uppercase;line-height:1.2;color:var(--jn-titre-teinte)}

/* ⚠️⚠️ DEUX BOUTONS QUI SE FONT FACE SONT UN COUPLE : « ils partagent la cote, la
   forme, la marge et la ligne ; ce qui les distingue, c'est leur glyphe, rien
   d'autre. »
   ⚠️ RAYON 12 SUR 36, le rapport 0,33 du socle. Voile `rgba(255,255,255,.07)`, celui
      des commandes de l'app, IDENTIQUE pour les deux : « une matiere ne se choisit
      pas bouton par bouton, elle appartient au rang. »
   ⚠️ `position:relative` EST NECESSAIRE, pas decoratif : la cible etendue est un
      `::after` en `inset:-4px`, qui exige un ancetre positionne. 36 + 4 + 4 = 44, le
      plancher tactile du contrat — sans lui, une commande de 36 est une cible de 36. */
body.jn-carte #menu-btn,
body.jn-carte #c-passer{
  position:relative;top:auto;right:auto;bottom:auto;left:auto;
  width:36px;height:36px;padding:0;margin:0;
  border:0;border-radius:var(--r-1);background:rgba(255,255,255,.07);
  display:grid;place-items:center;box-shadow:none;color:var(--c-texte-2);
  transition:transform .16s var(--ease),background .16s var(--ease)}
body.jn-carte #menu-btn{grid-column:1}
body.jn-carte #c-passer{grid-column:3}
body.jn-carte #menu-btn::after,
body.jn-carte #c-passer::after{content:'';position:absolute;inset:-4px}
body.jn-carte #menu-btn:active:not(.enfonce),
body.jn-carte #c-passer:active{transform:scale(.94);background:rgba(255,255,255,.14)}
/* ⚠️ MEME TRAIT, MEME ENCRE, DEUX TAILLES : le double chevron est un signe DENSE,
   les trois traits un signe aere. « Un glyphe dense a besoin de plus de marge qu'un
   glyphe aere, a taille egale. » */
body.jn-carte #menu-btn svg,
body.jn-carte #c-passer svg{
  fill:none;stroke:#C6BFD6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
body.jn-carte #menu-btn svg{width:16px;height:16px}
body.jn-carte #c-passer svg{width:13px;height:13px;stroke-width:2.2}

/* ── le pied ──────────────────────────────────────────────────────────────
   ⚠️ LA PLACE DU REFUS EST TOUJOURS RESERVEE, meme quand il n'y en a pas.
      Sans reservation, une carte sans refus remonte de 26 pt et parait changer
      de taille d'une manche a l'autre. Le vide en fin d'ecran se lit comme un
      ecran qui se termine ; le meme vide au milieu se lirait comme un defaut. */
/* ⚠️ LA RESERVE DE 108 EST CELLE DU PIED SEUL, LA MARQUE VIT DESSOUS. Dans le rendu
   ce sont deux blocs freres separes par l'ecart de l'ecran ; chez nous la marque est
   DANS le pied depuis toujours (IN-04). On rend donc au conteneur la hauteur des
   deux, et la marque se colle en bas par `margin-top:auto` : le bouton garde sa
   place, le creux du refus reste reserve entre les deux, et la signature retombe ou
   le rendu la pose. Sans ca elle se collait sous le bouton, et le vide passait
   dessous — un vide en fin d'ecran se lit comme un ecran qui se termine, le meme
   vide au milieu se lirait comme un defaut. */
/* ⚠️⚠️ [08/08, Theo : « si mon rendu je le vois en entier sur mon tel, c'est oblige que tu
   puisses faire rentrer les memes proportions sur l'app, applique a l'identique »] LE PIED
   FAIT 108, COMME LE RENDU. Il valait 108 + la hauteur de la signature : notre decor
   s'ajoutait au sien, et c'est la CARTE qui payait — 389 pt de haut contre 434, soit 90 %
   du rendu, a rapport pourtant exact.
   ⚠️ LA SIGNATURE N'EST PAS SUPPRIMEE, ELLE ENTRE DANS LA RESERVE. Les 108 pt couvrent le
      bouton (46), son ecart (8) et la place gardee au refus (44). Sur les 74 cartes
      « Je n'ai jamais », aucune ne propose « Je me degonfle » (verifie sur content-fr.json,
      la sortie payante se lit dans le texte de la sanction) : cette place est donc libre
      ici, et la signature s'y pose par `margin-top:auto`. Rien n'est perdu, rien n'est
      ajoute, et le bas de l'ecran rend exactement la meme hauteur que le rendu.
   ⚠️ ET SI UN JOUR UNE CARTE DE CE TYPE DEVENAIT REFUSABLE, le bloc grandirait au lieu de
      superposer : `min-height` est un plancher, pas une hauteur. */
/* ⚠️⚠️ [08/08, Theo : « trinke.app en bas on l'enleve, la carte est trop petite en general »]
   LE PIED NE PORTE PLUS QUE LE BOUTON, ET C'EST CE QUI REND LA CARTE A SA LARGEUR. On y
   reservait 108 pt — le bouton, son ecart, et la place gardee au « Je me degonfle » — plus
   une signature. Or AUCUNE des 74 cartes de ce type ne propose de se degonfler (verifie sur
   content-fr.json : la sortie payante se lit dans le texte de la sanction), donc on gardait
   62 pt pour deux choses dont l'une n'arrive jamais et l'autre vient de partir.
   ⚠️ ET CES 62 pt SONT DE LA LARGEUR, PAS DE LA HAUTEUR. Le format est fige : la carte est
      plafonnee par la hauteur disponible, donc tout ce qu'on rend en bas se retrouve AUSSI
      sur les cotes. Mesure a 393x720 : 276 pt de large avant, 298 apres, soit exactement le
      maximum que la largeur d'ecran permet. C'est la largeur du rendu.
   ⚠️ SI UN JOUR UNE CARTE DE CE TYPE DEVENAIT REFUSABLE, le bloc grandirait au lieu de la
      recouvrir : il n'y a plus de plancher, la hauteur vient du contenu. La carte sauterait
      alors d'une manche a l'autre — c'est le prix, et il ne se paie que le jour ou une carte
      « Je n'ai jamais » offrira une sortie payante, ce qu'aucune ne fait. */
:is(#s-game,#s-classic-run)[data-carte]>.bottom{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  /* ⚠️⚠️ [08/08] LE PIED RESERVE 108, ET C'EST CE QUI TIENT LE FORMAT DE LA CARTE.
     Les trois rendus (jamais, action, action ou verite) posent le MEME `min-height:108`
     alors qu'ils ne contiennent pas la meme chose : deux boutons pour Action, un seul
     pour « Je n'ai jamais », AUCUN pour la carte de choix. C'est justement l'objet de la
     reservation. Sans elle, la carte grandirait sur les 39 cartes d'Action sans
     echappatoire et retrecirait sur les 43 qui en offrent une — le format changerait
     A L'INTERIEUR d'un meme jeu, ce que la regle de Theo interdit au pixel pres.
     Notre portage n'avait que `min-height:0` : il ne se voyait pas parce qu'aucune des
     74 cartes « Je n'ai jamais » n'offre de sortie payante. */
  gap:var(--e-2);flex:0 0 auto;min-height:108px;margin:var(--e-3) 0 0;padding:0}
/* la signature quitte CET ecran, et lui seul : elle reste partout ailleurs (IN-04, la marque
   qui voyage sur les captures d'ecran). */
:is(#s-game,#s-classic-run)[data-carte] .marque{display:none}
/* ⚠️⚠️ [08/08] LE BOUTON REPREND LE DEGRADE DE LA TUILE DU MODE, MAIS RESSERRE :
   trois arrets sur une amplitude de moitie. En aplat plein il paraissait venir
   d'une autre couche de dessin que la carte. Sa CRETE reste le plateau du mode et
   non une valeur eclaircie « pour le volume » : le libelle traverse toute la hauteur
   du bouton, donc c'est l'arret le plus CLAIR qui decide du contraste, et le plateau
   est la seule valeur deja mesuree en blanc (4,85 sur le violet).
   ⚠️ LES DEUX AUTRES ARRETS SONT CALCULES : 20 % et 55 % de #7526D8 dans #8E48F0,
      soit #8941EB et #8035E3. Ecrits en dur, ce bloc s'interdisant `color-mix`.
   ⚠️ ET SA LARGEUR SUIT L'ECRAN, PAS LE PIED — `min(47vw,200px)`. Un pourcentage se
      resoudrait sur le conteneur et rendrait 187 pt la ou l'on en veut 200. 210 pt
      le rapprochait de la largeur des deux branches d'« Action ou verite » : trois
      objets de meme largeur se repondent comme trois reponses possibles, alors que
      deux servent a choisir et le troisieme a avancer. */
:is(#s-game,#s-classic-run)[data-carte] :is(#btn-next,#cl-next){
  align-self:center;width:auto;min-width:min(47vw,200px);max-width:100%;
  border:0;border-radius:999px;min-height:46px;padding:var(--e-3) var(--e-6);
  font-size:var(--t-2);font-weight:700;line-height:1;
  color:var(--c-texte);
  background:linear-gradient(160deg,var(--jn-decor) 0%,var(--jn-decor-20) 55%,var(--jn-decor-55) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16)}
/* ⚠️⚠️ [08/08] LE REFUS PREND LA FORME DES BOUTONS DE DIALOGUE — 44 de haut, 15,5 en 600,
   celle de `.ch` sur le site et celle du rendu. Le notre faisait 56 (rembourrage 16/22,
   corps 16,8) et portait en plus 10 de marge EN LIGNE : 46 + 8 + 56 + 10 = 120, soit 12
   de plus que le pied reserve. Consequence mesuree au banc : la carte etait plus PETITE
   de 11 px (417 contre 428) sur les 43 cartes d'Action qui offrent une echappatoire que
   sur les 39 qui n'en offrent pas — le format changeait a l'interieur d'un meme jeu.
   ⚠️ `!important` EST ICI LE BON OUTIL, PAS UNE FACILITE : la marge est posee EN LIGNE
      dans le markup, ou elle sert encore les trois types non portes ; aucune regle
      ordinaire ne peut la reprendre. */
:is(#s-game,#s-classic-run)[data-carte] :is(#btn-degonfle,#cl-bu,#cl-ose){
  margin:0!important;min-height:44px;padding:var(--e-3);
  font-size:var(--t-2);font-weight:600;line-height:1}
/* ⚠️⚠️ [08/08, Theo sur photo d'appareil] LA MARQUE SE COLLE EN BAS, ET C'ETAIT LA
   PIECE MANQUANTE DU PORTAGE. Sans `margin-top:auto` elle se posait juste sous le
   bouton, et toute la place reservee au refus tombait DESSOUS : l'ecran se terminait
   sur 52 pt de noir apres la signature, ce qui se lit comme une page inachevee. Avec
   elle, le creux reserve reprend sa place ENTRE le bouton et la signature, et la
   signature retombe ou le rendu la pose, au bord.
   ⚠️ LE VIDE EN FIN D'ECRAN SE LIT COMME UN ECRAN QUI SE TERMINE ; LE MEME VIDE AU
      MILIEU SE LIRAIT COMME UN DEFAUT. C'est la meme regle qui justifie de reserver
      la place du refus et de ne pas la laisser en dernier. */
:is(#s-game,#s-classic-run)[data-carte] .marque{
  order:9;margin:auto 0 0;flex:0 0 auto;opacity:1;
  font-size:var(--t-1);font-weight:600;color:var(--dim)}

/* ── carte serree : le corps se resserre, le format ne cede jamais ─────────
   ⚠️ LA CONTRAINTE N'EST PAS LA HAUTEUR DE L'ECRAN MAIS CELLE DE LA CARTE.
      A 393x693 la carte rend exactement ce qu'elle rendrait sur un ecran de
      640 : c'est donc `ajusteJamais` qui pose ces crans, en mesurant la carte,
      et jamais une media query de hauteur d'ecran. */
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-serre{gap:var(--e-3);padding:var(--e-4) var(--e-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court{gap:var(--e-3);padding:var(--e-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court .tag{font-size:var(--t-3);padding:var(--e-2) var(--e-4)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court .cardtext[data-taille="s"] {font-size:clamp(1.375rem,7vw,1.625rem)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court .cardtext[data-taille="m"] {font-size:clamp(1.25rem,6vw,1.4375rem)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court .cardtext[data-taille="l"] {font-size:clamp(1.125rem,5.2vw,1.25rem)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-court .cardtext[data-taille="xl"]{font-size:clamp(1rem,4.4vw,1.125rem)}
/* le quatrieme cran est de notre main : le Grand texte sur un petit ecran n'est
   pas dans le rendu, et sans lui la phrase recouvre le badge. 12 px reste le
   plancher du contrat UI-04. */
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini{gap:var(--e-2);padding:var(--e-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .tag{font-size:var(--t-3);padding:var(--e-2) var(--e-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .cardtext[data-taille="s"] {font-size:var(--t-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .cardtext[data-taille="m"] {font-size:var(--t-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .cardtext[data-taille="l"] {font-size:var(--t-3)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .cardtext[data-taille="xl"]{font-size:var(--t-2)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .jn-quand{font-size:var(--t-1)}
:is(#s-game,#s-classic-run)[data-carte] .gamecard.jn-mini .jn-valeur b{font-size:var(--t-4)}

/* l'animation d'entree suit les blocs qui ont change de place */
:is(#s-game,#s-classic-run)[data-carte] .gamecard.anim .jn-valeur{animation:popIn var(--m-moyen) var(--m-sortie) both}

/* ══════════════════════════════════════════════════════════════════════════
   « TU PREFERES » — L'INTERIEUR, ET LUI SEUL
   ══════════════════════════════════════════════════════════════════════════
   Le cadre est celui de toute carte portee (`:is(#s-game,#s-classic-run)[data-carte]`). Ne vivent
   ici que les trois objets propres a ce type : les deux options, le « ou » qui
   les separe, et l'appel au vote.

   ⚠️⚠️ LES DEUX OPTIONS SONT NUES, ET C'EST UNE DECISION DU RENDU : « le bloc
   gris en faisait deux objets a choisir, alors qu'il n'y a rien a toucher —
   c'est une question posee a la table, on repond a voix haute. » Sans fond,
   elles redeviennent du texte, et le « ou » suffit a les separer. Le socle le
   dit dans l'autre sens : ce qui a un FOND se touche, ce qui n'en a pas se lit.

   ⚠️ LE « OU » RESTE, ET IL PORTE LA LECTURE. Theo, 08/08 : « y a quand meme un
   ou entre les deux options ». C'est lui qui permet aux options d'etre des
   MORCEAUX DE PHRASE plutot que deux etiquettes autonomes — « Perdre toutes tes
   photos / OU / Tous tes messages » se lit comme la carte l'ecrit. Sans lui, il
   aurait fallu reecrire dix-huit secondes options pour qu'elles tiennent seules.

   ⚠️ « VOTEZ, » EST DANS LE MEME GROUPE QUE LA CONDITION, PAS AU-DESSUS D'ELLE.
   D'ou le conteneur a 6 pt : a 18, le pas normal du corps, il serait devenu un
   quatrieme bloc de la carte au lieu d'ouvrir le troisieme. Une phrase et son
   sujet ne se separent pas au meme pas que deux idees.
   ⚠️ ET IL SE DISTINGUE PAR LA DENSITE, PAS PAR LA COULEUR : 13 px en 500 contre
   15 en 600, meme encre. Deux gris pour deux rangs auraient fait un troisieme
   gris a memoriser. */
/* ⚠️ C'EST LE CHOIX QUI PORTE LE RESSORT, puisque la phrase est masquee sur ce type.
   Sans `flex:1 1 auto`, plus rien ne prend la place libre : les trois blocs se tassent en
   haut et le bas de la carte reste vide sur un tiers de sa hauteur. « Il n'y a que deux
   facons de traiter un reste de hauteur : le laisser quelque part, et il fait un trou ; le
   repartir, et il devient de l'air. » */
:is(#s-game,#s-classic-run)[data-carte="preferes"] .jn-choix{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  flex:1 1 auto;min-height:0;gap:var(--e-3);width:100%}
:is(#s-game,#s-classic-run)[data-carte="preferes"] .jn-option{
  display:block;width:100%;
  font-size:clamp(1.1875rem,5.4vw,1.4375rem);font-weight:800;line-height:1.28;
  letter-spacing:-.02em;color:var(--jn-metal);text-wrap:balance}
:is(#s-game,#s-classic-run)[data-carte="preferes"] .jn-ou{
  display:block;font-size:var(--t-1);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--jn-gris)}
/* ⚠️ LA CONDITION DEVIENT UN GROUPE DE DEUX LIGNES sur ce type, et d'une seule
   ailleurs : c'est le conteneur qui change, pas la condition. */
:is(#s-game,#s-classic-run)[data-carte="preferes"] .jn-cond{
  display:flex;flex-direction:column;align-items:center;gap:var(--e-2);flex:0 0 auto}
:is(#s-game,#s-classic-run)[data-carte="preferes"] .jn-appel{
  display:block;font-size:var(--t-1);font-weight:500;line-height:1.3;
  color:var(--jn-gris);flex:0 0 auto}
/* la phrase pleine largeur n'a plus lieu d'etre : les options la remplacent */
:is(#s-game,#s-classic-run)[data-carte="preferes"] .cardtext{display:none}
/* ⚠️ SOUS UNE CARTE COURTE, LES OPTIONS CEDENT AVANT LE « OU » : ce sont elles
   qui portent le texte, lui ne porte que la separation. Les deux crans reprennent
   ceux du rendu (20 px puis 16). */
:is(#s-game,#s-classic-run)[data-carte="preferes"] .gamecard.jn-court .jn-option{font-size:var(--t-3);line-height:1.24}
:is(#s-game,#s-classic-run)[data-carte="preferes"] .gamecard.jn-mini .jn-option{font-size:var(--t-2);line-height:1.24}
:is(#s-game,#s-classic-run)[data-carte="preferes"] .gamecard.jn-court .jn-choix,
:is(#s-game,#s-classic-run)[data-carte="preferes"] .gamecard.jn-mini .jn-choix{gap:var(--e-2)}

/* ── « ACTION OU VÉRITÉ », TEMPS 1 : LA CARTE DE CHOIX ─────────────────────
   Rendu `design/ecrans/soiree-action-ou-verite-sombre.html`. Le jeu se joue en deux
   temps : on choisit, PUIS on lit. Montrer les deux consignes d'un coup reviendrait a
   faire lire a voix haute ce qu'on n'a pas choisi, et a laisser voir la verite a qui
   prend l'action.
   ⚠️ CETTE CARTE N'A NI CONDITION NI DOSE, et c'est un refus documente du rendu :
      « ou 2 gorgees » y a ete essaye en troisieme issue le 06/08 puis RETIRE. On ne
      renonce pas a un defi qu'on n'a pas encore lu ; le choix de boire vient apres,
      sur la carte qui porte la consigne, quand on sait a quoi on renonce.
   ⚠️ ET « av » N'EST PAS UN TYPE DE CARTE : c'est un TEMPS pose sur une carte d'Action
      ou de Verite. Aucune des 391 cartes ne porte ce type, le paquet n'en contient
      aucune, et le reglage `SAV_TYPES` met les deux paquets en jeu ENSEMBLE — donc une
      branche ne peut jamais tomber sur un paquet vide. */
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-av{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  /* c'est le choix qui porte le ressort, la phrase etant masquee sur ce temps */
  flex:1 1 auto;min-height:0;width:100%;
  /* ⚠️ 30 ET NON 12 : le prenom n'est pas l'etiquette des boutons. A 12 il collait a
     « Action » et la carte se lisait « un bouton nomme Camille, Action ». Une PERSONNE
     interpellee puis deux CHOSES a toucher sont deux natures differentes, et le socle
     demande 16 au moins des qu'on change de nature. */
  gap:var(--e-5)}
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-prenom{
  display:block;flex:0 0 auto;
  font-size:clamp(1.5rem,6.5vw,1.8125rem);font-weight:800;
  letter-spacing:-.02em;line-height:1.1;color:var(--jn-metal)}
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-branches{
  display:flex;flex-direction:column;align-items:center;gap:var(--e-3);width:100%}
/* ⚠️ DES OBJETS A TOUCHER, PAS DES ZONES A LIRE. En main, on comprend mal qu'on peut
   appuyer sur une simple ligne de texte : les deux branches sont des pastilles pleines.
   Encre = `--jn-m2`, le plateau du degrade de la famille, la meme valeur que le badge. */
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-branche{
  width:66%;min-width:190px;min-height:56px;padding:var(--e-3) var(--e-4);
  border:0;border-radius:999px;
  font-size:var(--t-3);font-weight:800;letter-spacing:-.01em;line-height:1;
  background:#FFFFFF;color:var(--jn-m2);
  box-shadow:inset 0 0 0 1px rgba(24,19,34,.08),0 6px 16px -8px rgba(0,0,0,.55);
  transition:transform .12s var(--ease)}
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-branche:active{transform:translateY(1px)}
:is(#s-game,#s-classic-run)[data-carte="av"] .jn-av .jn-ou{
  display:block;font-size:var(--t-1);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--jn-gris)}
/* la phrase pleine largeur n'a pas lieu d'etre : le choix la remplace */
:is(#s-game,#s-classic-run)[data-carte="av"] .cardtext{display:none}
/* ⚠️ SOUS UNE CARTE SERREE, LES BRANCHES CEDENT comme les options de « Tu preferes » :
   c'est le texte qui rend, la pastille ne fait que le porter. */
:is(#s-game,#s-classic-run)[data-carte="av"] .gamecard.jn-court .jn-branche,
:is(#s-game,#s-classic-run)[data-carte="av"] .gamecard.jn-mini .jn-branche{font-size:var(--t-3);min-height:52px}

/* ═══════════════════════════════════════════════════════════════════════════
   CRÉER UN COMPTE : LE CODE           [09/08] rendu compte-creer-code v5
   ═══════════════════════════════════════════════════════════════════════════
   ⚠️⚠️ UN SEUL AXE. Intitules, carte, cases et bouton partent du MEME bord. Le rendu le pose
      comme son principe : quatre pixels de retrait sur un seul objet d'une colonne suffisent
      a la faire paraitre de travers, on ne les voit pas, on sent que quelque chose ne tombe
      pas juste.
   ⚠️ TOUT EST PREFIXE `ac-` ET SCOPE PAR `data-vue` : le rendu nomme ses blocs `.lab`,
      `.carte`, `.case`, `.grille`, `.exp`, `.rec` — six noms qu'aucune app ne garde nus.
      Quatre collisions ont deja ete payees en une session (`.mu-tete`, `.jr-champ`, `.jeu`,
      `muEnVol`), et la regle qui en est sortie est « prefixer, toujours ».
   ⚠️ LA BARRE DU HAUT EXISTE DEJA sur cet ecran : on lui porte les valeurs du rendu sous ce
      scope, on n'en ajoute pas une seconde. */
/* ⚠️ LE REMBOURRAGE HAUT DE L'ECRAN PASSE A 8, celui du rendu. Il valait 18 : mesure, tout
   l'ecran tombait 10 px trop bas, en cascade depuis le titre. Le rendu le dit lui-meme,
   « le contenu doit tenir haut, clavier leve ». */
#s-compte[data-vue="activation"]{padding-top:calc(env(safe-area-inset-top,0px) + var(--e-2))}
#s-compte[data-vue="activation"]>.topbar{min-height:40px;margin:0 0 var(--e-2);padding:0}
#s-compte[data-vue="activation"] #cp-title{
  font-size:var(--t-4);font-weight:600;letter-spacing:-.015em;line-height:1.2;color:var(--c-texte)}
/* ⚠️ LE RETOUR MAIGRIT : 32 au lieu de 36, rayon 10, glyphe 11. Il pesait plus que le titre
   qu'il accompagne. SA CIBLE RESTE A 44 par un `::after` : on reduit ce qui se voit, jamais
   ce qui se touche. */
#s-compte[data-vue="activation"] #cp-back{
  width:32px;height:32px;min-width:32px;min-height:32px;border-radius:var(--r-1);padding:0;
  background:rgba(255,255,255,.05);display:grid;place-items:center;position:relative}
#s-compte[data-vue="activation"] #cp-back::after{content:'';position:absolute;inset:-6px}
#s-compte[data-vue="activation"] #cp-back svg{width:11px;height:11px;stroke:#B7B0C6;fill:none;stroke-width:2.1}

/* ── les intitules de section ──────────────────────────────────────────────
   ⚠️ 12/600 A .04em, ET SANS RETRAIT. A un interlettrage plus large, six lettres occupent la
      largeur de neuf : l'intitule cesse d'etre une etiquette et concurrence ce qu'il annonce.
      Un intitule se lit APRES ce qu'il nomme ; s'il attire l'oeil en premier, il est trop fort.
   ⚠️ 30 AU-DESSUS, 8 EN DESSOUS : un intitule appartient a ce qui le SUIT. Les ecarts internes
      et les ecarts de bloc ne se reglent pas ensemble — tout reduire du meme nombre ne compacte
      pas, ca aplatit. */
#s-compte[data-vue="activation"] .ac-lab{
  line-height:normal;flex:0 0 auto;font-size:var(--t-1);font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--c-texte-3);margin:var(--e-5) 0 var(--e-2)}
/* ⚠️⚠️ PAS D'EXCEPTION SUR LE PREMIER INTITULE, ET C'EST UNE MESURE QUI LE DIT. Le rendu
   porte bien une regle ``.lab:first-of-type{margin-top:0}``, mais elle NE S'APPLIQUE JAMAIS
   chez lui : ``:first-of-type`` compte par type d'element, et son premier ``div`` est
   l'en-tete. Le premier intitule y garde donc ses 30 px. Chez nous le corps ne contient que
   les intitules, la regle aurait mordu, et l'ecran entier serait remonte de 30 px.
   ON PORTE CE QUE LE RENDU REND, PAS CE QU'IL ECRIT. */
/* ⚠️ 20 ENTRE L'EXPIRATION ET « RIEN REÇU ? » : les deux parlent du meme sujet, le temps du
   code. L'ecart devient une information. Mais 20 et non 8 : un ecart qui porte une
   information doit rester un ecart, sinon ce n'est plus qu'un collage. */
#s-compte[data-vue="activation"] .ac-exp+.ac-lab{margin-top:var(--e-4)}

/* ── la carte de l'adresse ─────────────────────────────────────────────────
   ⚠️ ELLE SE FOND AU LIEU DE SE POSER : un voile et un filet, pas un aplat. Une carte qui
      contient une seule ligne n'a pas besoin d'etre une surface pleine, il lui suffit d'un
      bord ; son chevron dit qu'elle se touche.
   ⚠️ LA TUILE EST UN RELEVE, PAS UN CHOIX : c'est celle de la rangee « Email » de l'ecran
      d'acces, fortement desaturee. Sur une rangee, le signe ANNONCE l'information : des qu'il
      se voit avant elle, il a cesse de l'annoncer. */
#s-compte[data-vue="activation"] .ac-carte{
  position:relative;flex:0 0 auto;display:flex;align-items:center;gap:var(--e-3);width:100%;
  /* ⚠️⚠️ 58 ET NON 52, ET C'EST UNE MESURE QUI LE DIT. Le rendu declare 52 mais en REND 58 :
     sa hauteur vient de son contenu (adresse 21 + 1 + « Modifier » 16, plus 20 de
     rembourrage). Or ces trois nombres dependent de la POLICE, et une pile qui retombe sur un
     autre caractere donne 53. En figeant 58, la carte tient la cote validee quel que soit le
     caractere servi — et sur l'appareil, ou la pile resout comme le rendu, rien ne change.
     ON PORTE CE QUE LE RENDU REND, PAS CE QU'IL DECLARE. */
  min-height:58px;padding:var(--e-2) var(--e-3) var(--e-2) var(--e-3);border-radius:var(--r-2);
  text-align:left;cursor:pointer;border:0;
  background:rgba(255,255,255,.045);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.13);
  transition:background .16s var(--ease)}
#s-compte[data-vue="activation"] .ac-carte:active{background:rgba(255,255,255,.09)}
#s-compte[data-vue="activation"] .ac-tu{
  width:26px;height:26px;border-radius:var(--r-1);flex:0 0 auto;display:grid;place-items:center;
  background:linear-gradient(180deg,#565483 0%,#4A4870 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
#s-compte[data-vue="activation"] .ac-tu svg{width:15px;height:15px;fill:none;stroke:#FFFFFF;stroke-width:1.85;
  stroke-linecap:round;stroke-linejoin:round}
#s-compte[data-vue="activation"] .ac-carte .ac-txt{flex:1 1 auto;min-width:0}
#s-compte[data-vue="activation"] .ac-carte b{
  line-height:normal;display:block;font-size:var(--t-2);font-weight:600;letter-spacing:-.012em;color:var(--c-texte);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#s-compte[data-vue="activation"] .ac-carte small{
  line-height:normal;display:block;font-size:var(--t-1);font-weight:400;margin-top:1px;color:var(--c-texte-3)}
#s-compte[data-vue="activation"] .ac-chev{width:7px;height:11px;flex:0 0 auto;fill:none;stroke:#5C5670;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ── les six cases ─────────────────────────────────────────────────────────
   ⚠️⚠️ UN SEUL CHAMP, PAS SIX. Un `input` unique, invisible, pose sur les cases. C'est la
      seule facon d'obtenir le remplissage automatique d'iOS, et c'est aussi ce qui rend le
      COLLAGE possible sans une ligne de code : a six champs separes, le premier prend un
      caractere et les cinq autres sont perdus. Le retour arriere devient gratuit lui aussi.
   ⚠️ COTES FIXES ET ALIGNEES A GAUCHE, pas reparties : six objets qui touchent les deux bords
      se lisent comme une barre segmentee, pas comme six cases. 6 x 46 + 5 x 10 = 326 sur 353,
      la rangee s'arrete 27 avant le bord droit — c'est ce qui prouve qu'elle est un objet et
      non la page elle-meme.
   ⚠️⚠️ AUCUN VIOLET SUR LES CASES REMPLIES : un accent qui marque cinq objets sur six ne
      marque plus rien. Une case remplie porte exactement la matiere d'une case vide ; ce qui
      la distingue, c'est le chiffre. Le violet ne marque QUE la case ou l'on ecrit. */
#s-compte[data-vue="activation"] .ac-grille{
  position:relative;flex:0 0 auto;display:flex;gap:var(--e-2);align-self:flex-start}
#s-compte[data-vue="activation"] .ac-saisie{
  position:absolute;inset:0;width:100%;height:100%;opacity:0;font-size:var(--t-2);
  cursor:pointer;z-index:2}
#s-compte[data-vue="activation"] .ac-case{
  width:46px;height:50px;border-radius:var(--r-1);flex:0 0 auto;display:grid;place-items:center;
  font-size:var(--t-4);font-weight:500;letter-spacing:-.02em;color:var(--c-texte);
  background:rgba(255,255,255,.05);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.11);
  transition:box-shadow .18s var(--ease),background .18s var(--ease)}
#s-compte[data-vue="activation"] .ac-case.active{
  background:rgba(255,255,255,.07);box-shadow:inset 0 0 0 1.2px rgba(167,139,250,.90)}
#s-compte[data-vue="activation"] .ac-case.active::after{
  content:'';width:1.5px;height:21px;border-radius:var(--r-1);background:#A78BFA;
  animation:acbat 1.05s steps(1,end) infinite}
@keyframes acbat{0%,50%{opacity:1}50.01%,100%{opacity:0}}

/* ── la mention d'expiration ───────────────────────────────────────────────
   ⚠️ A 6 DES CASES : une mention qui qualifie un objet lui appartient, elle se pose CONTRE
      lui, pas a cote. Elle se lit en un coup d'oeil ou ne se lit pas — ni sujet, ni mot ecrit
      en entier.
   ⚠️ ELLE PORTE AUSSI LA VERIFICATION ET L'ERREUR. Quand on retire le bouton de validation,
      on retire la preuve que quelque chose s'est passe : il faut la remettre ailleurs, mais
      discretement.
   ⚠️ ET L'ERREUR NE COLORE QUE LE BLOC DU CODE : ce qui est faux, c'est le code, pas l'ecran. */
#s-compte[data-vue="activation"] .ac-exp{
  flex:0 0 auto;min-height:17px;margin:var(--e-2) 0 0;
  font-size:var(--t-1);font-weight:400;line-height:1.4;color:var(--c-texte-3)}
#s-compte[data-vue="activation"] .ac-exp.verif{color:#A78BFA}
#s-compte[data-vue="activation"] .ac-exp.faux{color:#E5484D}
#s-compte[data-vue="activation"] .ac-grille.faux .ac-case{box-shadow:inset 0 0 0 1.4px rgba(229,72,77,.75)}

/* ── le renvoi ─────────────────────────────────────────────────────────────
   ⚠️⚠️ SON ETAT ACTIF EST ARDOISE, PAS VIOLET. Le violet est deja pris sur cet ecran : il
      marque la case ou l'on ecrit. Deux accents violets sur un meme ecran, c'est un accent
      qui designe deux endroits, donc aucun.
   ⚠️ LE DECOMPTE EST DANS LE BOUTON, separe par un point median. Un compteur pose a cote
      oblige a faire le lien soi-meme ; a zero, le point et le nombre disparaissent et le
      libelle ne change pas — un bouton dont seul l'etat change n'oblige jamais a le relire.
   ⚠️ AUCUNE ICONE : « Renvoyer le code » se lit sans aide, et un glyphe qu'il faut deviner
      coute plus qu'il ne rapporte.
   ⚠️ L'ETAT ETEINT GARDE SON BORD ET PERD TOUTE TRACE DE VIOLET. Un bouton desactive qu'on ne
      peut pas lire ne dit pas qu'il est desactive, il dit qu'il est casse ; et un accent pose
      sur ce qui ne marche pas ment deux fois, sur l'etat et sur l'accent. */
#s-compte[data-vue="activation"] .ac-rec{
  position:relative;flex:0 0 auto;align-self:flex-start;
  display:flex;align-items:center;gap:var(--e-2);
  min-height:42px;padding:0 var(--e-4);border-radius:999px;cursor:pointer;border:0;
  font-size:var(--t-2);font-weight:600;letter-spacing:-.01em;
  background:rgba(142,154,176,.14);color:var(--c-texte-3);
  transition:transform .16s var(--ease),background .16s var(--ease)}
#s-compte[data-vue="activation"] .ac-rec:active{transform:scale(.97);background:rgba(142,154,176,.22)}
#s-compte[data-vue="activation"] .ac-rec i{font-style:normal;font-weight:400;opacity:.55}
#s-compte[data-vue="activation"] .ac-rec.inerte{
  background:rgba(255,255,255,.028);color:var(--c-texte-3);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.10);
  cursor:default;pointer-events:none}

/* le corps de cette vue est une colonne : sans quoi les sections ne s'empilent pas et les
   marges de bloc ne veulent plus rien dire. */
/* ⚠️ LE CORPS PERD SON REMBOURRAGE HAUT DE 6 : il vient de la classe prof-scroll, partagee avec les
   ecrans de profil qui defilent sous un en-tete flottant. Ici l'en-tete ne flotte pas, et ces
   6 px decalaient tout le haut de la page sans que rien ne les reclame. Mesure : premier
   intitule a 92 au lieu de 86.
   ⚠️ ET C'EST UN ECART D'HERITAGE, PAS UN OUBLI DU RENDU : une valeur posee pour un autre
      ecran suit la classe partagee jusqu'ici. */
#s-compte[data-vue="activation"] #cp-body{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding-top:0}

/* ═══════════════════════════════════════════════════════════════════════════════
   [09/08] FIN D'UNE SOIREE : L'ECRAN NU (rendu `soireefin.html`)
   Trois niveaux d'action, pas un de plus : Rejouer, Accueil, Partage. Aucune
   statistique, aucun score, aucune gorgee comptee.
   ⚠️ AUCUN EN-TETE, AUCUN RETOUR. On ne revient pas dans une partie terminee, et le seul
      retour possible est ecrit en toutes lettres au milieu de l'ecran : une fleche qui
      ramene la ou le bouton du dessous ramene est une porte de trop.
   ⚠️ LE TITRE EST EN HAUT, PAS AU CENTRE. L'ecran `s-defi` porte deux ressorts qui centrent
      son corps ; le premier est neutralise ICI et seulement ici. On ne touche pas au
      balisage partage par les trois bilans.
   ═══════════════════════════════════════════════════════════════════════════════ */
/* ⚠️⚠️ [11/08] LE MODE TIENT DANS DEUX JETONS, ET NULLE PART AILLEURS. Le rendu de Theo le
   pose comme regle : « un ecran qui change de mode ne doit avoir qu'un endroit a changer ».
   Le halo est un TRIPLET et non une couleur : il sert dans cinq `rgba()` a cinq opacites, et
   une variable de couleur ne peut pas y entrer.
   ⚠️ ET LE HALO SE REGLE EN LUMINANCE, PAS EN TEINTE : le fuchsia moyen et le violet moyen
      ont des luminances voisines, la nappe garde donc exactement la meme pente. Pour une
      famille plus claire (l'or), il faudrait rebaisser les cinq opacites. */
/* [26/10, Romain] DIRECTION G5 ETOILEE, choisie sur planche (design/fin-partie/) : « j'aime bien que le fond
   soit plus eclaire a la fin de la partie, ca donne un second souffle d'energie », puis « j'aime le G5, ajoute en
   plus les etoiles du G6 ». Tout l'ecran dans la couleur du mode, le dessin du mode (celui de l'accueil) au-dessus
   du titre, les trinkeurs en grand avec leur prenom, Rejouer creme, quelques etoiles nettes dans les marges.
   ⚠️ TOUJOURS AUCUN CHIFFRE (conformite, decision du 09/08) : on nomme la table, on ne compte rien.
   ⚠️ L'ANCIEN HALO CENTRAL EST PARTI : une lumiere de fond ne se montre pas (regle du 20/10).
   ⚠️ CONTRASTE MESURE sur capture dans les trois modes : texte blanc au moins 4,5 pour 1. L'orange des Mini-jeux
      (Braise, 28/10) est mesure pour cette raison ; ne pas l'eclaircir sans remesurer. */
:is(#s-defi.fin-nue,#s-multi.mu-scene){--fn-plein:linear-gradient(180deg,#6E33F0 0%,#3A1CA8 48%,#160A52 100%);
  padding-top:calc(var(--e-5) + env(safe-area-inset-top,0px))}
/* [28/10, Romain, direction B « Framboise de nuit » choisie sur planche] le rose descend vers la nuit, comme le violet de la
   Soiree. Texte blanc mesure a 6,23 au pire (ligne des reglages). */
:is(#s-defi.fin-nue,#s-multi.mu-scene)[data-mode="classiques"]{--fn-plein:linear-gradient(180deg,#DB2777 0%,#8E1350 42%,#3E0A26 75%,#180510 100%)}
/* [28/10, Romain : « le orange de cette page est pas beau », direction B « Braise » choisie sur planche] assombri, l'orange
   tournait au marron : il descend maintenant vers un rouge sombre. Texte blanc mesure a 4,96 au pire (ligne des reglages). */
#s-turn.mu-fini-on,:is(#s-defi.fin-nue,#s-multi.mu-scene)[data-mode="minijeux"]{--fn-plein:linear-gradient(180deg,#D2580A 0%,#A8320C 42%,#6A170B 75%,#3A0C07 100%)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .topbar{display:none}
#s-defi.fin-nue > .grow:nth-child(4){flex-grow:1.15}
#s-defi.fin-nue #df-body{width:100%;position:relative;z-index:1}
#s-defi.fin-nue .bottom{position:relative;z-index:1}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-haut{display:flex;flex-direction:column;align-items:center;text-align:center}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-blason{display:flex;justify-content:center;margin-bottom:var(--e-4)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-blason .fn-illu svg{display:block;width:176px;height:auto;filter:drop-shadow(0 12px 18px rgba(12,4,40,.45))}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-blason .fn-tuile{display:grid;place-items:center;width:76px;height:76px;border-radius:var(--r-3);
  background:rgba(255,255,255,.16);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.55),0 10px 24px -8px rgba(0,0,0,.4)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-blason .fn-tuile svg{width:58%;height:58%}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-haut h1{margin:0;font-family:ui-rounded,"SF Pro Rounded",-apple-system,"Helvetica Neue",sans-serif;
  font-size:var(--t-7);font-weight:800;letter-spacing:-.03em;line-height:1;color:var(--c-texte)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-haut h1 i{font-style:normal;color:inherit}   /* « terminee » droit et blanc, comme sur la planche validee */
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-haut p{margin:var(--e-2) 0 0;font-size:var(--t-3);color:rgba(255,255,255,.94)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-table{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-3) var(--e-2);margin-top:var(--e-5)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-j{display:flex;flex-direction:column;align-items:center;gap:var(--e-2);width:62px}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-j .cl-av{width:48px;height:48px;font-size:var(--t-4);font-weight:700}
/* aux valeurs de « Qui joue ? » : creme pour les autres, le violet de la marque pour le connecte, SA teinte s'il en a
   choisi une (jumelle `html.teinte`, exigee par outils/test-teinte-avatar.js) */
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-j .cl-av{background:#DDD5C7;color:#170B20}
#s-defi.fin-nue .fn-j .cl-av.moi,#s-multi.mu-scene .fn-j .cl-av.moi{background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);
  color:var(--accent-ink)}
html.teinte #s-defi.fin-nue .fn-j .cl-av.moi,html.teinte #s-multi.mu-scene .fn-j .cl-av.moi{
  background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 55%,
                                     hsl(var(--av-h) var(--av-s) calc(var(--av-llo) - 11%)) 100%)}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-j b{max-width:62px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:var(--t-1);font-weight:600;color:rgba(255,255,255,.94)}
:is(#s-defi,#s-multi,#s-turn) .fn-ciel{position:absolute;inset:0;z-index:0;pointer-events:none}
/* trop de trinkeurs pour la hauteur (10 a 664 pt, Safari barres ouvertes) : le dessin rapetisse et l'air se resserre
   plutot que de faire defiler. Pose par finEtoiles() sur mesure, pas par une hauteur fixe : Grand texte compris. */
:is(#s-defi.fin-nue,#s-multi.mu-scene).fn-serre{padding-top:calc(var(--e-3) + env(safe-area-inset-top,0px))}
:is(#s-defi.fin-nue,#s-multi.mu-scene).fn-serre .fn-blason{margin-bottom:var(--e-3)}
:is(#s-defi.fin-nue,#s-multi.mu-scene).fn-serre .fn-blason .fn-illu svg{width:128px}
:is(#s-defi.fin-nue,#s-multi.mu-scene).fn-serre .fn-blason .fn-tuile{width:60px;height:60px}
:is(#s-defi.fin-nue,#s-multi.mu-scene).fn-serre .fn-table{margin-top:var(--e-4);row-gap:var(--e-2)}
:is(#s-defi.fin-nue,#s-multi.mu-scene,#s-turn.mu-fini-on) .fn-etoile{position:absolute;z-index:0;fill:#F3EEE6;opacity:.7;pointer-events:none}
/* ⚠️ UN TRAIT NE SEPARE PAS DEUX BLOCS, IL SEPARE DEUX SUJETS : partout ailleurs un vide
   suffit. Filet a UN PIXEL PHYSIQUE : height 1 ecrase par scaleY(.34). */
#s-defi.fin-nue .fn-sep{display:block;width:100%;height:1px;margin:var(--e-5) 0 0;
  transform:scaleY(.34);background:rgba(255,255,255,.14)}
#s-defi.fin-nue .fn-invite{display:flex;align-items:center;gap:var(--e-3);width:100%;
  margin:var(--e-4) 0 0;padding:var(--e-3);border:0;border-radius:var(--r-3);text-align:left;cursor:pointer;
  background:rgba(255,255,255,.035);
  box-shadow:inset 0 0 0 .34px rgba(255,255,255,.11);
  transition:background .16s cubic-bezier(.22,.9,.25,1)}
#s-defi.fin-nue .fn-invite:active{background:rgba(255,255,255,.07)}
/* ⚠️ LE QR EST SUR BLANC AVEC SA MARGE : les lecteurs echouent sur un module sombre pose sur
   du clair, et la marge fait partie du code, pas de sa presentation. */
#s-defi.fin-nue .fn-qr{width:52px;height:52px;flex:0 0 auto;border-radius:var(--r-1);
  background:#FFFFFF;padding:var(--e-1)}
#s-defi.fin-nue .fn-qr svg{display:block;width:100%;height:100%}
#s-defi.fin-nue .fn-txt{flex:1 1 auto;min-width:0}
/* ⚠️ `--ink` ET NON `--text` : dans CETTE feuille, `--ink` est le jeton du texte
   principal (#f4f4f7). Le dossier appelle `--ink` l'encre des surfaces violettes et
   `--text` l'encre principale : deux usages sous un meme nom, ecart deja signale le
   08/08. Une variable inconnue ne declenche AUCUN repli, elle rend la declaration
   invalide en silence — le texte serait retombe sur l'encre heritee. */
#s-defi.fin-nue .fn-invite b{display:block;font-size:var(--t-2);font-weight:600;
  letter-spacing:-.01em;color:var(--ink)}
#s-defi.fin-nue .fn-invite small{display:block;font-size:var(--t-1);font-weight:400;
  margin-top:2px;color:var(--c-texte-3)}
/* le geste appartient au systeme : on emprunte SON signe, on n'en dessine pas un autre. */
#s-defi.fin-nue .fn-part{width:34px;height:34px;flex:0 0 auto;border-radius:var(--r-1);
  display:grid;place-items:center;background:rgba(255,255,255,.06);margin-right:2px}
#s-defi.fin-nue .fn-part svg{width:18px;height:18px;fill:none;stroke:#C6BFD6;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* ══════════════════════════════════════════════════════════════════════════════
   [11/08] LES REGLAGES RAPIDES DE L'ACCUEIL — portage de `reglages-rapides.html`.
   ⚠️⚠️ TOUTES LES CLASSES SONT PREFIXEES `set-`, ET CE N'EST PAS DU ZELE. Le rendu les
      nomme `.rg`, `.tu`, `.sw`, `.txt`, `.lab`, `.tete` : trois de ces noms EXISTENT DEJA
      dans cette feuille. Ce projet a paye cinq collisions de nom en une semaine, dont une
      qui ecrasait une regle entiere en silence.
   ⚠️ LA POIGNEE DIT QUE LA FEUILLE SE TIRE. Sans elle, le seul moyen de savoir qu'on peut
      la glisser vers le bas serait de l'essayer.
   ══════════════════════════════════════════════════════════════════════════════ */
#m-settings .set-feuille{padding:var(--e-2) var(--e-3) calc(max(env(safe-area-inset-bottom,0px),var(--e-3)) + var(--e-3));
  border-radius:var(--r-4) var(--r-4) 0 0;background:#141419;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 -18px 40px -20px rgba(0,0,0,.7)}
#m-settings .set-poignee{width:36px;height:5px;margin:0 auto var(--e-3);border-radius:999px;
  background:rgba(255,255,255,.18)}
/* ⚠️ 19 ET NON 34 : le titre dominait la feuille qu'il annonce. Et 4 SOUS LUI, si pres
   parce que « Réglages » et « PARTIE » ne sont pas deux blocs qui se suivent : le second
   est le premier rang du premier. */
#m-settings .set-tete{margin:0 0 var(--e-1);padding:0 2px;font-size:var(--t-3);font-weight:600;
  letter-spacing:-.015em;line-height:1.2;color:var(--c-texte);text-align:left}
#m-settings .set-lab{font-size:var(--t-1);font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--dim);margin:var(--e-3) 0 var(--e-2);padding-left:2px}
#m-settings .set-lab:first-of-type{margin-top:0}
#m-settings .set-groupe{border-radius:var(--r-3);overflow:hidden;background:var(--card-2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07)}
/* ⚠️ LA RANGEE ENTIERE EST L'INTERRUPTEUR : la pastille seule faisait 51 x 31, sous le
   plancher de cible, et la moitie gauche ne repondait a rien. */
#m-settings .set-rg{position:relative;display:flex;align-items:center;gap:var(--e-3);width:100%;
  min-height:58px;padding:var(--e-2) var(--e-3) var(--e-2) var(--e-3);text-align:left;border:0;background:none;
  color:inherit;font:inherit;cursor:pointer}
/* [10/10, audit] `hidden` doit gagner sur le display:flex du dessus : le Mode clair, retire le 07/10, restait affiche */
#m-settings .set-rg[hidden]{display:none}
/* ⚠️ LE FILET COMMENCE APRES LA TUILE (60), il ne traverse pas la rangee : un trait qui
   passe sous une icone separe l'icone de son texte. Un pixel PHYSIQUE, comme partout. */
#m-settings .set-rg+.set-rg::before{content:"";position:absolute;left:60px;right:0;top:0;
  height:1px;transform:scaleY(.34);background:rgba(255,255,255,.17)}
#m-settings .set-tu{width:30px;height:30px;border-radius:var(--r-1);flex:0 0 auto;display:grid;
  place-items:center;box-shadow:inset 0 1px 0 rgba(255,255,255,.18)}
/* ⚠️ LA COULEUR SE JUSTIFIE PAR UN DECOUPAGE, PAS PAR RANGEE : un domaine, une teinte. */
#m-settings .set-tu.violet{background:linear-gradient(180deg,#9A70F8 0%,#8B5CF6 100%)}
#m-settings .set-tu.ardoise{background:linear-gradient(180deg,#6A7386 0%,#5B6478 100%)}
#m-settings .set-gl{width:17px;height:17px;fill:none;stroke:#FFFFFF;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
/* « Aa » est du texte dans une tuile, deuxieme cas de l'app apres « 18+ » : aucun glyphe ne
   dit « plus gros » aussi bien que deux lettres de tailles differentes. */
#m-settings .set-aa{font-size:var(--t-1);font-weight:700;letter-spacing:-.02em;color:var(--c-texte)}
#m-settings .set-aa i{font-style:normal;font-size:var(--t-1)}
#m-settings .set-txt{flex:1 1 auto;min-width:0}
#m-settings .set-rg b{display:block;font-size:var(--t-2);font-weight:400;letter-spacing:-.01em;
  color:var(--ink)}
#m-settings .set-rg small{display:block;font-size:var(--t-1);margin-top:2px;line-height:1.3;
  color:var(--c-texte-3)}
#m-settings .set-sw{position:relative;flex:0 0 auto;width:51px;height:31px;border-radius:999px;
  background:rgba(120,120,128,.32);transition:background .2s var(--ease)}
/* ⚠️ LE GENOU EST BLANC DANS LES DEUX ETATS : un genou gris se lit comme « indisponible »,
   alors que l'interrupteur est simplement eteint. */
#m-settings .set-sw i{position:absolute;top:2px;left:2px;width:27px;height:27px;
  border-radius:50%;background:#FFFFFF;
  box-shadow:0 3px 8px rgba(0,0,0,.15),0 1px 1px rgba(0,0,0,.16);
  transition:transform .2s var(--ease)}
#m-settings .set-rg.on .set-sw{background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%)}
#m-settings .set-rg.on .set-sw i{transform:translateX(20px)}

/* [02/10, Romain] L'atelier d'avatar et le dessin des avatars sont sortis de l'app : branche archive/avatar sur GitHub. */

/* le dessin dans une pastille de discussion et dans l'onglet du bas : meme regle, la
   pastille garde sa forme et sa teinte, le dessin la remplit. */
.mu-pas{position:relative;overflow:hidden}
/* [24/09] SANS `display` : sur un identifiant, il battait `.ong.compte .ong-av{display:none}` et le
   rond violet vide s'affichait DECONNECTE, au-dessus de la silhouette qui deborde de la barre.
   L'affichage appartient a `.connecte` ; ici on ne pose que ce que le dessin demande. */
#ong-ini{position:relative;overflow:hidden;place-items:center}

/* le dessin dans une pastille de salon : elle est petite, le dessin la remplit quand meme */
.dis-av{position:relative;overflow:hidden}

/* les deux derniers ronds qui recoivent un dessin : la bulle et la rangee de l'accueil */
.ln-av{position:relative;overflow:hidden}
.hav{position:relative;overflow:hidden}

/* le dernier rond qui recoit un dessin : la liste « Qui joue » */
.cl-av{position:relative;overflow:hidden}

/* MENU-VERRE:DEBUT */
/* [23/09, Romain] accueil menu verre, porte par outils/porter-menu-verre.py : ne pas editer a la main */
#mv-canvas{width:941px;height:1672px;transform-origin:top left;
    position:relative;overflow:hidden;border-radius:0;
    font-family:-apple-system,"SF Pro Text","SF Pro Display","Helvetica Neue",Inter,system-ui,sans-serif;
    color:#F4F0F8;-webkit-font-smoothing:antialiased;
    background:#020106}
#mv-canvas::before{content:"";position:absolute;inset:0;
    background:
      radial-gradient(560px 420px at 760px 330px, rgba(80,30,160,.42), transparent 70%),
      radial-gradient(420px 300px at 900px 140px, rgba(0,120,170,.28), transparent 70%),
      radial-gradient(700px 300px at 400px 1300px, rgba(35,20,120,.48), transparent 70%),
      radial-gradient(500px 160px at 300px 1420px, rgba(20,30,140,.30), transparent 70%),
      radial-gradient(420px 220px at 720px 1230px, rgba(60,25,140,.35), transparent 70%),
      radial-gradient(320px 110px at 880px 1250px, rgba(255,80,20,.22), transparent 70%),
      radial-gradient(240px 120px at 40px 1400px, rgba(255,70,20,.16), transparent 70%),
      radial-gradient(300px 90px at 700px 1625px, rgba(255,80,30,.18), transparent 70%),
      linear-gradient(#000102, #01030F);}
#mv-canvas>*{position:absolute}
#mv-canvas .mv-heure{left:108px;top:24px;font-size:2.375rem;font-weight:600;letter-spacing:-.5px;color:#fff;display:flex;align-items:center;gap:10px}
#mv-canvas .mv-heure svg{width:30px;height:30px}
#mv-canvas .mv-etat{right:88px;top:26px;display:flex;align-items:center;gap:14px;color:#fff;font-size:1.875rem;font-weight:600}
#mv-canvas .mv-barres{display:flex;align-items:flex-end;gap:4px;height:26px}
#mv-canvas .mv-barres i{display:block;width:7px;border-radius:2px;background:#fff}
#mv-canvas .mv-barres i:nth-child(3),#mv-canvas .mv-barres i:nth-child(4){background:#5a5a5e}
#mv-canvas .mv-batt{width:56px;height:30px;border-radius:9px;background:#f4f4f4;color:#111;font-size:1.5rem;font-weight:700;
    display:grid;place-items:center;position:relative}
#mv-canvas .mv-batt::after{content:"";position:absolute;right:-6px;top:10px;width:4px;height:10px;border-radius:0 3px 3px 0;background:#f4f4f4}
#mv-canvas .mv-reglages{left:42px;top:100px;width:78px;height:78px;border-radius:20px;background:#EFE9DF;display:grid;place-items:center;
    box-shadow:0 0 0 1px rgba(255,255,255,.35) inset}
#mv-canvas .mv-reglages svg{width:42px;height:38px}
#mv-canvas .mv-titre{left:0;right:0;top:88px;text-align:center;font-family:ui-rounded,"SF Pro Rounded",-apple-system,"Helvetica Neue",sans-serif;
    font-size:5.5rem;font-weight:800;letter-spacing:-1.5px;line-height:1;
    background:linear-gradient(180deg,#FFFFFF 0%,#F1EAFB 50%,#DCCCF3 100%);-webkit-background-clip:text;background-clip:text;color:transparent;
    filter:drop-shadow(0 0 16px rgba(190,80,255,.7)) drop-shadow(0 0 4px rgba(230,150,255,.9))}
#mv-canvas .mv-titre-lueur{left:300px;top:70px;width:340px;height:120px;border-radius:50%;
    background:radial-gradient(closest-side, rgba(140,60,255,.45), transparent);filter:blur(10px)}
#mv-canvas .mv-etincelles{left:572px;top:82px;width:56px;height:46px}
#mv-canvas .mv-etincelles path{stroke:#fff;stroke-width:4.5;stroke-linecap:round;filter:drop-shadow(0 0 4px rgba(200,160,255,.9))}
#mv-canvas .mv-moi-haut{left:820px;top:102px;width:72px;height:72px;border-radius:50%;
    background:radial-gradient(circle at 50% 40%, #1F5FE0, #0B2E8C);display:grid;place-items:center;
    font-size:2.0rem;font-weight:500;color:#fff;
    box-shadow:0 0 0 4px #2EB7FF, 0 0 18px 4px rgba(46,183,255,.75)}
#mv-canvas .mv-trinq{left:42px;top:210px;width:856px;height:118px;border-radius:34px;background:#0A0B27;
    display:flex;align-items:center}
#mv-canvas .mv-trinq::before{content:"";position:absolute;inset:-3px;border-radius:37px;padding:3px;
    background:linear-gradient(90deg,#26C6F5 0%,#3F7BFF 30%,#8A3BFF 62%,#E23CC8 100%);
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;
    filter:drop-shadow(0 0 10px rgba(120,80,255,.55))}
#mv-canvas .mv-trinq .mv-av{position:absolute;top:22px;width:74px;height:74px;border-radius:50%;display:grid;place-items:center;font-size:2.25rem;font-weight:500;color:#fff}
#mv-canvas .mv-trinq .mv-av1{left:30px;background:radial-gradient(circle at 50% 40%,#1E62E0,#0C2F8E);box-shadow:0 0 0 3px #2FB6FF,0 0 14px rgba(46,182,255,.7);z-index:2}
#mv-canvas .mv-trinq .mv-av2{left:84px;background:radial-gradient(circle at 50% 40%,#2E9BFF,#1668E0);box-shadow:0 0 0 3px #1C7BFF,0 0 14px rgba(28,123,255,.6)}
#mv-canvas .mv-trinq .mv-lib{position:absolute;left:180px;top:0;height:118px;display:flex;align-items:center;font-size:2.5rem;font-weight:400;color:#F6F2FC}
#mv-canvas .mv-trinq .mv-gerer{position:absolute;right:42px;top:0;height:118px;display:flex;align-items:center;gap:36px;font-size:2.125rem;font-weight:400;color:#CDBAF7}
#mv-canvas .mv-trinq .mv-gerer svg{width:22px;height:34px}
#mv-canvas .mv-soiree{left:42px;top:355px;width:856px;height:410px;border-radius:42px;
    background:linear-gradient(160deg,#120838 0%,#0A0522 45%,#070620 100%);
    box-shadow:0 0 60px 10px rgba(110,50,255,.30), inset 0 0 60px rgba(110,60,255,.22)}
#mv-canvas .mv-soiree::before{content:"";position:absolute;inset:-4px;border-radius:46px;padding:4px;
    background:conic-gradient(from 200deg at 50% 50%,#3A5CFF 0%,#7A3BFF 22%,#C43BE8 45%,#E23CC8 55%,#8A3BFF 72%,#3A4DFF 88%,#3A5CFF 100%);
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;
    filter:drop-shadow(0 0 14px rgba(140,70,255,.75)) drop-shadow(0 0 4px rgba(200,120,255,.8))}
#mv-canvas .mv-soiree h1{position:absolute;left:58px;top:70px;margin:0;font-size:4.125rem;font-weight:500;letter-spacing:-.5px;color:#F8F4FF}
#mv-canvas .mv-soiree p{position:absolute;left:58px;top:150px;margin:0;font-size:2.375rem;font-weight:300;line-height:47px;color:#93C4F9;letter-spacing:-.2px}
#mv-canvas .mv-soiree .mv-illu{position:absolute;left:428px;top:17px;width:420px;height:278px}
#mv-canvas .mv-lancer{position:absolute;left:158px;top:300px;width:538px;height:80px;border-radius:40px;
    background:linear-gradient(90deg,#7A36FF 0%,#4A2BFF 45%,#1C1BFF 100%);
    box-shadow:0 0 0 2px rgba(120,120,255,.45), 0 0 26px rgba(90,60,255,.6), inset 0 2px 0 rgba(255,255,255,.35), inset 0 -8px 16px rgba(0,0,60,.35);
    display:flex;align-items:center;justify-content:center;gap:56px;font-size:2.3125rem;font-weight:400;color:#fff}
#mv-canvas .mv-lancer svg{width:34px;height:30px}
#mv-canvas .mv-section{left:46px;top:806px;font-size:1.5625rem;font-weight:500;letter-spacing:.16em;color:#EEE9F6;display:flex;align-items:center;gap:26px}
#mv-canvas .mv-section::after{content:"";width:80px;height:2px;background:#3A3742;margin-left:6px}
#mv-canvas .mv-mode{top:853px;width:274px;height:325px;border-radius:34px;overflow:hidden}
#mv-canvas .mv-mode .mv-tuile{position:absolute;left:20px;top:30px;width:70px;height:70px;border-radius:17px;display:grid;place-items:center}
#mv-canvas .mv-mode .mv-tuile svg{width:40px;height:40px}
#mv-canvas .mv-mode h2{position:absolute;left:105px;top:30px;height:70px;display:flex;align-items:center;margin:0;font-size:1.875rem;font-weight:500;color:#F8F5FA;white-space:nowrap}
#mv-canvas .mv-mode p{position:absolute;left:21px;top:120px;margin:0;font-size:1.6875rem;line-height:37px;font-weight:400;color:#F5F1F6}
#mv-canvas .mv-mode .mv-jouer{position:absolute;left:21px;top:240px;width:233px;height:62px;border-radius:31px;
    display:flex;align-items:center;justify-content:center;gap:34px;font-size:1.875rem;font-weight:400;color:#fff}
#mv-canvas .mv-mode .mv-jouer svg{width:28px;height:24px}
#mv-canvas .mv-m1{left:42px;background:linear-gradient(180deg,#DD1560 0%,#8E0842 55%,#7C0535 100%);
    box-shadow:0 0 0 2px #FF4A88,0 0 22px 6px rgba(255,40,110,.6),0 0 50px rgba(255,40,110,.25),inset 0 0 0 2px rgba(255,150,190,.35),inset 0 0 30px rgba(255,60,120,.35)}
#mv-canvas .mv-m1 .mv-tuile{background:linear-gradient(180deg,#FF2F78,#D40E5B);box-shadow:0 0 14px rgba(255,60,130,.6)}
#mv-canvas .mv-m1 .mv-jouer{background:linear-gradient(90deg,#FF2E6B,#D50E5B);box-shadow:0 0 0 2px rgba(255,120,170,.45),0 0 18px rgba(255,40,110,.55),inset 0 2px 0 rgba(255,255,255,.3)}
#mv-canvas .mv-m2{left:335px;background:linear-gradient(180deg,#E4820A 0%,#8F4A02 55%,#7A3E02 100%);
    box-shadow:0 0 0 2px #FFAE2A,0 0 22px 6px rgba(255,150,20,.6),0 0 50px rgba(255,150,20,.25),inset 0 0 0 2px rgba(255,210,140,.35),inset 0 0 30px rgba(255,170,60,.35)}
#mv-canvas .mv-m2 .mv-tuile{background:linear-gradient(180deg,#FFB020,#F08A00);box-shadow:0 0 14px rgba(255,170,40,.6)}
#mv-canvas .mv-m2 .mv-jouer{background:linear-gradient(90deg,#FFA51A,#EF8500);box-shadow:0 0 0 2px rgba(255,200,120,.45),0 0 18px rgba(255,150,20,.55),inset 0 2px 0 rgba(255,255,255,.3)}
#mv-canvas .mv-m3{left:626px;background:linear-gradient(180deg,#0E62C9 0%,#073F8C 55%,#053A7C 100%);
    box-shadow:0 0 0 2px #3AA4FF,0 0 22px 6px rgba(40,140,255,.6),0 0 50px rgba(40,140,255,.25),inset 0 0 0 2px rgba(150,200,255,.35),inset 0 0 30px rgba(60,150,255,.35)}
#mv-canvas .mv-m3 .mv-tuile{background:linear-gradient(180deg,#3FA3FF,#1470E0);box-shadow:0 0 14px rgba(60,160,255,.6)}
#mv-canvas .mv-m3 .mv-jouer{background:linear-gradient(90deg,#2F9AFF,#1468DD);box-shadow:0 0 0 2px rgba(120,190,255,.45),0 0 18px rgba(40,140,255,.55),inset 0 2px 0 rgba(255,255,255,.3)}
#mv-canvas .mv-bas{left:38px;top:1454px;width:865px;height:124px;border-radius:62px;background:#EDE6DC;
    box-shadow:0 0 0 1px rgba(255,255,255,.5) inset, 0 6px 30px rgba(0,0,0,.6)}
#mv-canvas .mv-bas .mv-moi{position:absolute;left:734px;top:22px;width:80px;height:80px;border-radius:50%;
    background:radial-gradient(circle at 50% 35%,#FF9A4A,#F26A1B);display:grid;place-items:center;
    font-size:2.375rem;font-weight:700;color:#2A1108;
    box-shadow:0 0 0 4px #FFB070,0 0 16px 4px rgba(255,150,60,.75)}
#mv-canvas .mv-m1{box-shadow:0 0 0 2px #FF4A88}
#mv-canvas .mv-m2{box-shadow:0 0 0 2px #FFAE2A}
#mv-canvas .mv-m3{box-shadow:0 0 0 2px #3AA4FF}
#mv-canvas .mv-mode .mv-tuile{box-shadow:none}
#mv-canvas .mv-m1 .mv-jouer{box-shadow:0 0 0 2px rgba(255,120,170,.55)}
#mv-canvas .mv-m2 .mv-jouer{box-shadow:0 0 0 2px rgba(255,200,120,.55)}
#mv-canvas .mv-m3 .mv-jouer{box-shadow:0 0 0 2px rgba(120,190,255,.55)}
#mv-canvas .mv-titre{font-size:5.625rem;font-weight:900;letter-spacing:-2px;
    filter:drop-shadow(0 0 18px rgba(215,90,255,.8)) drop-shadow(0 0 5px rgba(240,160,255,.95))}
#mv-canvas .mv-titre-lueur{background:radial-gradient(closest-side, rgba(180,70,255,.5), transparent)}
#mv-canvas .mv-mode .mv-jouer{overflow:hidden;
    
    background:linear-gradient(180deg,rgba(255,255,255,.18) 0%,rgba(255,255,255,.06) 50%,rgba(255,255,255,.03) 100%), var(--teinte);
    -webkit-backdrop-filter:blur(12px) saturate(1.4);backdrop-filter:blur(12px) saturate(1.4);
    box-shadow:0 0 0 1.5px rgba(255,255,255,.55), inset 0 1.5px 0 rgba(255,255,255,.8), inset 0 -10px 18px rgba(0,0,0,.20)}
#mv-canvas .mv-mode .mv-jouer::before{content:"";position:absolute;left:8px;right:8px;top:3px;height:46%;
    border-radius:28px 28px 14px 14px;background:linear-gradient(180deg,rgba(255,255,255,.28),rgba(255,255,255,0));pointer-events:none}
#mv-canvas .mv-m1 .mv-jouer{--teinte:rgba(255,70,140,.22)}
#mv-canvas .mv-m2 .mv-jouer{--teinte:rgba(255,160,40,.22)}
#mv-canvas .mv-m3 .mv-jouer{--teinte:rgba(60,160,255,.22)}
#mv-canvas .mv-mode .mv-jouer{background:linear-gradient(rgba(255,255,255,.10),rgba(255,255,255,.10)), var(--teinte);
    box-shadow:0 0 0 1.5px rgba(255,255,255,.55)}
#mv-canvas .mv-mode .mv-jouer::before{display:none}
#mv-canvas .mv-titre{font-size:4.625rem;top:101px;letter-spacing:-1.5px;
    filter:drop-shadow(0 0 10px rgba(190,90,255,.35))}
#mv-canvas .mv-titre{filter:drop-shadow(0 0 6px rgba(215,130,255,.55)) drop-shadow(0 0 18px rgba(170,70,255,.45))}
#mv-canvas .mv-titre{background:linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 60%,#F3EEFA 100%);-webkit-background-clip:text;background-clip:text}
#mv-canvas .mv-trinq{top:223px;height:92px;border-radius:28px}
#mv-canvas .mv-trinq::before{inset:-2px;padding:2px;border-radius:30px;
    background:linear-gradient(90deg,#6E62FF 0%,#7C5CFF 50%,#8A5CFF 100%);
    filter:drop-shadow(0 0 8px rgba(130,90,255,.45))}
#mv-canvas .mv-trinq .mv-av{top:16px;width:60px;height:60px;font-size:1.875rem}
#mv-canvas .mv-trinq .mv-av1{left:26px}
#mv-canvas .mv-trinq .mv-av2{left:70px}
#mv-canvas .mv-trinq .mv-lib{left:154px;height:92px;font-size:2.125rem}
#mv-canvas .mv-trinq .mv-gerer{height:92px;font-size:1.875rem;gap:30px}
#mv-canvas .mv-trinq .mv-gerer svg{width:19px;height:30px}
#mv-canvas .mv-trinq{top:217px;height:105px;border-radius:30px}
#mv-canvas .mv-trinq::before{border-radius:32px}
#mv-canvas .mv-trinq .mv-av{top:18px;width:68px;height:68px;font-size:2.0625rem}
#mv-canvas .mv-trinq .mv-av2{left:76px}
#mv-canvas .mv-trinq .mv-lib{left:166px;height:105px;font-size:2.3125rem}
#mv-canvas .mv-trinq .mv-gerer{height:105px;font-size:2.0rem}
#mv-canvas .mv-moi-haut,#mv-canvas .mv-bas .mv-moi{width:64px;height:64px;border-radius:50%;
    background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);
    color:#170B20;font-size:1.875rem;font-weight:800;
    box-shadow:0 0 0 3.5px rgba(250,249,252,.95), 0 0 0 7px #8B5CF6}
#mv-canvas .mv-moi-haut{left:824px;top:106px}
#mv-canvas .mv-bas .mv-moi{left:742px;top:30px}
#mv-canvas .mv-bas{display:flex;align-items:center;padding:13px;box-sizing:border-box}
#mv-canvas .mv-bas .mv-ong{flex:1 1 0;min-width:0;height:98px;border-radius:999px;position:relative;
    display:grid;place-items:center;color:#332C40}
#mv-canvas .mv-bas .mv-ong svg{width:59px;height:59px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
#mv-canvas .mv-bas .mv-ong.mv-majeur svg{width:68px;height:68px;stroke-width:1.85}
#mv-canvas .mv-bas .mv-ong.mv-actif{background:rgba(23,11,32,.07)}
#mv-canvas .mv-bas .mv-ong.mv-actif svg .mv-p{fill:currentColor;fill-opacity:.14}
#mv-canvas .mv-bas .mv-ong .mv-moi{position:static}
#mv-canvas .mv-bas.mv-app{left:53px;right:53px;width:auto;top:auto;bottom:74px;height:118px;border-radius:999px;
    background:rgba(250,249,252,.74);
    -webkit-backdrop-filter:blur(40px) saturate(1.9);backdrop-filter:blur(40px) saturate(1.9);
    box-shadow:0 26px 66px -22px rgba(0,0,0,.62), 0 7px 18px -9px rgba(0,0,0,.4), inset 0 2px 0 rgba(255,255,255,.9)}
#mv-canvas .mv-bas.mv-app .mv-ong{height:92px}
#mv-canvas{font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
#mv-canvas .mv-mode h2{font-weight:700}
#mv-canvas .mv-soiree h1{font-weight:600}
#mv-canvas .mv-trinq .mv-av{font-weight:700;font-size:1.875rem;box-shadow:0 0 0 4.5px #0A0B27}
#mv-canvas .mv-trinq .mv-av1{background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);color:#170B20;
    box-shadow:0 0 0 4.5px #0A0B27, 0 0 0 8px #A78BFA;z-index:2}
#mv-canvas .mv-trinq .mv-av2{left:74px;background:#DDD5C7;color:#170B20}
#mv-canvas .mv-etincelles{left:552px;top:80px;width:56px;height:44px}
#mv-canvas .mv-etincelles{left:515px;top:88px;width:92px;height:60px}
#mv-canvas .mv-etincelles{left:509px}
#mv-canvas .mv-etincelles{left:500px;top:90px;width:108px;height:64px}
#mv-canvas .mv-etincelles path{stroke-width:3.5}
#mv-canvas .mv-reglages.mv-app{left:50px;top:108px;width:61px;height:61px;border-radius:20px;
    background:rgba(255,255,255,.045);color:#D8D1E6;box-shadow:none}
#mv-canvas .mv-reglages.mv-app svg{width:57px;height:57px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
#mv-canvas .mv-moi-haut{display:none}
#mv-canvas.mv-compte-haut .mv-moi-haut{display:grid}
#mv-canvas .mv-reglages .mv-pic-app{display:none}
#mv-canvas .mv-bas .mv-ong svg{stroke-width:2.1}
#mv-canvas .mv-bas .mv-ong.mv-majeur svg{stroke-width:2.2}
#mv-canvas .mv-reglages.mv-app .mv-pic-beige{display:none}
#mv-canvas .mv-reglages.mv-app .mv-pic-app{display:block}
#mv-canvas .mv-titre-lueur{display:none}
#mv-canvas .mv-etincelles{left:556px;top:92px;width:48px;height:40px}
#mv-canvas [role="button"],#mv-canvas [role="tab"]{cursor:pointer;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;
    transition:transform .14s cubic-bezier(.2,.7,.2,1)}
#mv-canvas [role="button"].mv-enfonce,#mv-canvas [role="tab"].mv-enfonce{transform:scale(.94)}
#mv-canvas .mv-trinq.mv-enfonce{transform:scale(.985)}
#mv-canvas .mv-mode .mv-jouer::after,#mv-canvas .mv-trinq::after{content:"";position:absolute;left:0;right:0;top:-17px;bottom:-17px}
#mv-canvas [role="button"]:focus-visible,#mv-canvas [role="tab"]:focus-visible{outline:3px solid #A78BFA;outline-offset:4px}
#mv-canvas .mv-maq-toast{left:50%;bottom:190px;transform:translateX(-50%) translateY(12px);padding:14px 26px;border-radius:999px;
    background:rgba(250,249,252,.92);color:#170B20;font-size:1.5rem;font-weight:600;opacity:0;pointer-events:none;
    transition:opacity .18s,transform .18s;white-space:nowrap}
#mv-canvas .mv-maq-toast.mv-on{opacity:1;transform:translateX(-50%) translateY(0)}
#mv-canvas .mv-titre,#mv-canvas .mv-etincelles,#mv-canvas .mv-titre-lueur{pointer-events:none}
#mv-canvas .mv-bas .mv-ong.mv-actif svg .mv-p{fill:none}
#mv-canvas .mv-soiree .mv-formes{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;clip-path:inset(0 round 42px)}
#mv-canvas .mv-soiree{background:linear-gradient(135deg,#17104d 0%,#09082a 54%,#10104a 100%);box-shadow:inset 0 0 34px rgba(65,25,165,.40), 0 0 18px rgba(107,39,255,.60)}
#mv-canvas .mv-bas .mv-ong svg.mv-amis{width:60px;height:60px}
#mv-canvas .mv-soiree{height:525px}
#mv-canvas .mv-soiree .mv-illu{left:430px;top:70px}
#mv-canvas .mv-lancer{top:405px}
#mv-canvas .mv-section{top:921px}
#mv-canvas .mv-mode{top:968px}
#mv-canvas .mv-soiree h1{font-size:6.875rem;font-weight:800;letter-spacing:-3.5px;line-height:1;left:48px;top:109px}
#mv-canvas .mv-soiree p{font-size:2.375rem;font-weight:400;line-height:44px;left:51px;top:220px}
#mv-canvas .mv-badge{position:absolute;left:47px;top:43px;height:49px;padding:0 24px;box-sizing:border-box;border-radius:25px;
    display:flex;align-items:center;font-weight:600;font-size:1.5rem;line-height:1;color:#E6DDFF;letter-spacing:.2px;   
    background:rgba(255,255,255,.08);border:1.5px solid rgba(255,255,255,.22)}
#mv-canvas .mv-etiquettes{position:absolute;left:47px;top:295px;display:flex;gap:12px}
#mv-canvas .mv-etiquette{height:60px;padding:0 24px 0 20px;box-sizing:border-box;border-radius:30px;display:flex;align-items:center;gap:12px;
    font-weight:600;font-size:1.375rem;line-height:1;color:#EDE7FF;background:rgba(255,255,255,.08);border:1.5px solid rgba(255,255,255,.22)}
#mv-canvas .mv-etiquette svg{width:30px;height:30px;stroke:#EDE7FF;stroke-width:2.2;fill:none;stroke-linecap:round;stroke-linejoin:round}
#mv-canvas .mv-lancer{left:147px;top:391px;width:586px;height:95px;border-radius:48px;font-size:2.5rem}
#mv-canvas .mv-lancer svg{width:36px;height:32px}
#mv-canvas .mv-lancer{box-shadow:
      inset 0 1.5px 0 rgba(255,255,255,.72),
      inset 1.5px 0 0 rgba(255,255,255,.55),
      inset -1.5px 0 0 rgba(255,255,255,.40),
      inset 0 -1.5px 0 rgba(255,255,255,.12),
      inset 0 0 14px rgba(255,255,255,.16),
      0 0 24px rgba(90,60,255,.55)}
#mv-canvas .mv-lancer{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);font-size:2.4375rem}
#mv-canvas .mv-lancer{gap:0;justify-content:flex-start;padding-left:126px;box-sizing:border-box}
#mv-canvas .mv-lancer svg{position:absolute;left:473px;top:50%;transform:translateY(-50%)}
#mv-canvas .mv-etiquette{background:rgba(38,22,110,.62);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border-color:rgba(255,255,255,.26)}
#mv-canvas .mv-soiree .mv-illu{width:525px;height:347px;left:380px;top:6px}
#mv-canvas .mv-soiree .mv-illu{top:-18px}
#mv-canvas .mv-soiree p{color:#CFCBE3}
#mv-canvas .mv-etiquette svg{width:38px;height:38px;stroke-width:2.5}
#mv-canvas .mv-etiquette{gap:11px;padding-left:18px}
#mv-canvas .mv-soiree::before{filter:drop-shadow(0 0 3px rgba(200,120,255,.45))}
#mv-canvas .mv-soiree{box-shadow:inset 0 0 34px rgba(65,25,165,.40), 0 0 46px 8px rgba(120,60,255,.50)}
#mv-canvas .mv-mode .mv-filigrane{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;fill:rgba(255,255,255,.12);stroke:rgba(255,255,255,.16);stroke-width:1.5}
#mv-canvas .mv-mode .mv-filigrane text{stroke:none}
#mv-canvas .mv-mode{top:965px;width:282px;height:400px;border-radius:34px}
#mv-canvas .mv-m1{left:30px}
#mv-canvas .mv-m2{left:330px}
#mv-canvas .mv-m3{left:628px}
#mv-canvas .mv-mode .mv-tuile{left:27px;top:30px;width:100px;height:100px;border-radius:24px}
#mv-canvas .mv-mode .mv-tuile svg{width:56px;height:56px}
#mv-canvas .mv-mode h2{left:27px;top:138px;height:auto;font-size:2.5rem;font-weight:700;line-height:1.1}
#mv-canvas .mv-mode p{left:28px;top:196px;font-size:1.75rem;line-height:31px}
#mv-canvas .mv-mode .mv-jouer{left:22px;top:307px;width:240px;height:68px;border-radius:34px;font-size:2.0rem;gap:30px}
#mv-canvas .mv-mode .mv-jouer svg{width:30px;height:26px}
#mv-canvas .mv-m1{background:linear-gradient(180deg,#CE1170 0%,#A00D57 20%,#8A0A4C 30%,#6F043B 50%,#640336 100%)}
#mv-canvas .mv-m2{background:linear-gradient(180deg,#AC680D 0%,#97600A 20%,#7F4A06 30%,#6A3D04 50%,#643903 100%)}
#mv-canvas .mv-m3{background:linear-gradient(180deg,#0060D5 0%,#0057C2 20%,#00429B 30%,#00357D 50%,#002B66 100%)}
#mv-canvas .mv-m1 .mv-tuile{background:linear-gradient(180deg,#FB2F8B,#E8207A)}
#mv-canvas .mv-m2 .mv-tuile{background:linear-gradient(180deg,#FCAD16,#F09A0C)}
#mv-canvas .mv-m3 .mv-tuile{background:linear-gradient(180deg,#28A8FC,#1590F0)}
#mv-canvas .mv-mode .mv-tuile svg{width:60px;height:60px}
#mv-canvas .mv-mode .mv-jouer{-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:0 0 0 1.5px rgba(255,255,255,.28)}
#mv-canvas .mv-m1 .mv-jouer{background:#B8175E}
#mv-canvas .mv-m2 .mv-jouer{background:#AD6510}
#mv-canvas .mv-m3 .mv-jouer{background:#0E5BB4}
#mv-canvas .mv-mode h2{font-size:2.1875rem;top:142px}
#mv-canvas .mv-m1{box-shadow:0 0 0 2px #B01A66}
#mv-canvas .mv-m2{box-shadow:0 0 0 2px #AA6E12}
#mv-canvas .mv-m3{box-shadow:0 0 0 2px #1078BC}
#mv-canvas .mv-m1{background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)),linear-gradient(180deg,#CE1170 0%,#A00D57 20%,#8A0A4C 30%,#6F043B 50%,#640336 100%)}
#mv-canvas .mv-m2{background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)),linear-gradient(180deg,#AC680D 0%,#97600A 20%,#7F4A06 30%,#6A3D04 50%,#643903 100%)}
#mv-canvas .mv-m3{background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)),linear-gradient(180deg,#0060D5 0%,#0057C2 20%,#00429B 30%,#00357D 50%,#002B66 100%)}
#mv-canvas .mv-mode .mv-filigrane{fill:rgba(255,255,255,.045);stroke:rgba(255,255,255,.13);stroke-width:2.5}
#mv-canvas .mv-mode .mv-filigrane .mv-plein{fill:rgba(255,255,255,.13);stroke:none}
#mv-canvas .mv-mode .mv-filigrane-chatgpt{fill:none;stroke:none;stroke-width:1}
#mv-canvas .mv-mode .mv-filigrane .mv-trait{fill:none;stroke:rgba(255,255,255,.27);stroke-width:12;stroke-linecap:round;stroke-linejoin:round}
#mv-canvas .mv-m1 .mv-tuile{background:linear-gradient(180deg,#FA2380,#C20E5D)}
#mv-canvas .mv-m2 .mv-tuile{background:linear-gradient(180deg,#F49E15,#B56F0B)}
#mv-canvas .mv-m3 .mv-tuile{background:linear-gradient(180deg,#1E9CFE,#0266E7)}
#mv-canvas .mv-mode .mv-tuile{box-shadow:0 6px 14px rgba(0,0,0,.22)}
#mv-canvas .mv-mode .mv-tuile svg{width:61px;height:61px}
#mv-canvas .mv-mode .mv-jouer{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.80), 0 0 0 1px rgba(255,255,255,.14)}
#mv-canvas .mv-mode .mv-jouer{border:1.25px solid transparent;box-shadow:none}
#mv-canvas .mv-m1 .mv-jouer{background:linear-gradient(#B8175E,#B8175E) padding-box, linear-gradient(140deg,#ffd8e8,#f79dc7) border-box}
#mv-canvas .mv-m2 .mv-jouer{background:linear-gradient(#AD6510,#AD6510) padding-box, linear-gradient(140deg,#ffe7bc,#ffd293) border-box}
#mv-canvas .mv-m3 .mv-jouer{background:linear-gradient(#0E5BB4,#0E5BB4) padding-box, linear-gradient(140deg,#e4f8ff,#b9d5ff) border-box}
#mv-canvas .mv-reglages svg{width:46px;height:42px}
#mv-canvas .mv-section::after{display:none}
#mv-canvas .mv-soiree p{display:none}
#mv-canvas .mv-trinq{top:228px;height:84px;border-radius:26px}
#mv-canvas .mv-trinq::before{border-radius:28px}
#mv-canvas .mv-trinq .mv-av{top:15px;width:54px;height:54px;font-size:1.5rem;box-shadow:0 0 0 3.5px #0A0B27}
#mv-canvas .mv-trinq .mv-av1{left:24px}
#mv-canvas .mv-trinq .mv-av2{left:62px}
#mv-canvas .mv-trinq .mv-lib{left:140px;height:84px;font-size:1.875rem}
#mv-canvas .mv-trinq .mv-gerer{height:84px;font-size:1.6875rem;gap:24px;right:36px}
#mv-canvas .mv-trinq .mv-gerer svg{width:16px;height:26px}
#mv-canvas .mv-soiree h1{top:74px}
#mv-canvas .mv-mode{box-sizing:border-box;border:2px solid transparent}
#mv-canvas .mv-m1{box-shadow:none;background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)) padding-box,linear-gradient(180deg,#CE1170 0%,#A00D57 20%,#8A0A4C 30%,#6F043B 50%,#640336 100%) padding-box,linear-gradient(150deg,#ffa1d3 0%,#fa258d 33%,#f8007c 100%) border-box}
#mv-canvas .mv-m2{box-shadow:none;background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)) padding-box,linear-gradient(180deg,#AC680D 0%,#97600A 20%,#7F4A06 30%,#6A3D04 50%,#643903 100%) padding-box,linear-gradient(150deg,#fff740 0%,#f4b22c 38%,#ffae08 100%) border-box}
#mv-canvas .mv-m3{box-shadow:none;background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)) padding-box,linear-gradient(180deg,#0060D5 0%,#0057C2 20%,#00429B 30%,#00357D 50%,#002B66 100%) padding-box,linear-gradient(145deg,#08f3ff 0%,#00caff 38%,#008bff 100%) border-box}
#mv-canvas .mv-etiquettes{top:322px;left:52px;gap:0;align-items:center}
#mv-canvas .mv-etiquette{height:auto;padding:0;background:none;border:0;-webkit-backdrop-filter:none;backdrop-filter:none;
    font-size:1.625rem;font-weight:500;color:#CFCBE3;gap:9px}
#mv-canvas .mv-etiquette svg{width:28px;height:28px;stroke:#CFCBE3;stroke-width:2.3}
#mv-canvas .mv-etiquette + .mv-etiquette::before{content:"·";margin:0 16px;color:rgba(207,203,227,.55);font-weight:700}
#mv-canvas .mv-mode h2{top:144px}
#mv-canvas .mv-mode .mv-jouer{padding-left:10px;box-sizing:border-box}
#mv-canvas .mv-soiree h1{top:54px}
#mv-canvas .mv-soiree p{top:165px}
/* ---- adaptation a l'app ---- */
#s-home .mv-cadre{position:relative;margin:0 -18px;width:calc(100% + 36px);overflow:hidden;flex:0 0 auto;
  height:calc(var(--mvh,1230) * var(--mvs,.45) * 1px)}
/* [24/09, Romain : « tu as oublie les lumieres en bas, les trois modes sont plus sombres en bas »]
   Le fond de la maquette (la nebuleuse et ses lueurs bleues et orange) est peint par tout l'ECRAN,
   plus par la toile. La toile est coupee sous les modes, et ses lueurs du bas (y 1230 a 1625) vivaient
   sous la coupe ; un fondu vers le noir posé a la place eteignait en plus le bas des trois cartes.
   Chaque valeur reprend celle de la maquette, a l'echelle de la toile (--mvs) et calee sur son haut
   (--mvtop, le haut du cadre ; 88 = le haut de toile retire). Un fond ne cree aucun defilement. */
#s-home.menu-verre{background-color:#020106;background-attachment:local;background-image:radial-gradient(calc(560 * var(--mvs,.45) * 1px) calc(420 * var(--mvs,.45) * 1px) at calc(760 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (330 - 88) * var(--mvs,.45) * 1px), rgba(80,30,160,.42), transparent 70%), radial-gradient(calc(420 * var(--mvs,.45) * 1px) calc(300 * var(--mvs,.45) * 1px) at calc(900 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (140 - 88) * var(--mvs,.45) * 1px), rgba(0,120,170,.28), transparent 70%), radial-gradient(calc(700 * var(--mvs,.45) * 1px) calc(300 * var(--mvs,.45) * 1px) at calc(400 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1300 - 88) * var(--mvs,.45) * 1px), rgba(35,20,120,.48), transparent 70%), radial-gradient(calc(500 * var(--mvs,.45) * 1px) calc(160 * var(--mvs,.45) * 1px) at calc(300 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1420 - 88) * var(--mvs,.45) * 1px), rgba(20,30,140,.30), transparent 70%), radial-gradient(calc(420 * var(--mvs,.45) * 1px) calc(220 * var(--mvs,.45) * 1px) at calc(720 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1230 - 88) * var(--mvs,.45) * 1px), rgba(60,25,140,.35), transparent 70%), radial-gradient(calc(320 * var(--mvs,.45) * 1px) calc(110 * var(--mvs,.45) * 1px) at calc(880 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1250 - 88) * var(--mvs,.45) * 1px), rgba(255,80,20,.22), transparent 70%), radial-gradient(calc(240 * var(--mvs,.45) * 1px) calc(120 * var(--mvs,.45) * 1px) at calc(40 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1400 - 88) * var(--mvs,.45) * 1px), rgba(255,70,20,.16), transparent 70%), radial-gradient(calc(300 * var(--mvs,.45) * 1px) calc(90 * var(--mvs,.45) * 1px) at calc(700 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1625 - 88) * var(--mvs,.45) * 1px), rgba(255,80,30,.18), transparent 70%), linear-gradient(#000102, #01030F)}
#mv-canvas{background:transparent}
#mv-canvas::before{display:none}
#s-home.menu-verre .hsp{display:none}
/* [24/09, Romain] « Soiree » ne doit pas etre plus gros que « Trinke » : 110 -> 80 px de toile, puis 88 quand Trinke grandit */
#mv-canvas .mv-soiree h1{font-size:5.5rem;letter-spacing:-2.8px;top:116px;left:66px}   /* [24/09] decale a droite (maquette : 48) */
/* [24/09, Romain] « agrandis aussi le Trinke » : x1,22 (74 -> 90 px de toile), RETIRE le meme jour (« trop epais, gonfle a l'air, remets le fin comme avant ») : l'agrandissement epaississait d'autant le trait d'une graisse 900 ; reste le decalage a droite. Le mot et ses etincelles
   grandissent autour du MEME point (centre du mot, a 62 % de sa hauteur), sinon les etincelles glissent
   sur le « i » : essai du 24/09. Les etincelles sont un <svg> sans offsetTop, leur origine se calcule
   depuis leur left/top de toile (500, 88). Le tout decale de 14 px de toile a droite (Romain 24/09). */
/* [24/09, Romain : « il est encore en gras, c'est horrible »] Safari rend ui-rounded, la police ARRONDIE
   d'Apple, en graisse 900 : un trait gonfle que Chromium et WebKit de test ne montrent pas (ils n'ont pas
   cette police). Le titre prend la police systeme, celle de « Soiree », en 700. */
#mv-canvas .mv-titre{font-family:-apple-system,"SF Pro Display","Helvetica Neue",sans-serif;font-weight:700}
#mv-canvas .mv-titre{transform:translateX(14px);transform-origin:470.5px 45.9px}
#mv-canvas .mv-etincelles{transform:translateX(14px);transform-origin:-29.5px 58.9px}
#mv-canvas{position:absolute;left:0;top:0;transform:scale(var(--mvs,.45)) translateY(-88px);transform-origin:top left}
#mv-canvas .mv-trinq .mv-av[hidden]{display:none}
#s-home.menu-verre #home-top,#s-home.menu-verre .hterr{display:none}

/* MENU-VERRE:FIN */

/* PARCOURS-SOIREE:DEBUT — « Qui joue ? » et la fiche Soiree prennent la langue de l'accueil (25/09).
   ⚠️ P1 A P5 (« Qui joue ? ») VALIDES ET FIGES PAR ROMAIN LE 25/09 : ne plus y toucher sans demande.
   Un bloc numerote par changement, chacun retirable seul. Proposition, rien de valide. */

/* P1. Fond : le ciel de nuit de l'accueil, memes teintes et memes intensites, mais ses lumieres
   reposees aux bords de CET ecran (copiees telles quelles, les taches orange flottaient au milieu,
   car elles sont placees pour les cartes de mode de l'accueil) */
#s-joueurs{background-color:#020106;background-image:
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(60% 14% at 70% 100%, rgba(60,25,140,.35), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}

/* P2. Bouton retour : le carre creme du bouton reglages de l'accueil */
:is(#s-joueurs,#s-home) .jr-retour{background:#EFE9DF;color:#170B20;border:0;border-radius:var(--r-1);
  box-shadow:0 0 0 1px rgba(255,255,255,.35) inset;font-size:var(--t-4);font-weight:600}

/* P3. Lignes des trinkeurs : verre teinte violet, filet clair plus vif en haut (bord des cartes de l'accueil) */
#s-joueurs .jr-row{background:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10));
  border:1px solid transparent;border-radius:var(--r-3);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
#s-joueurs .jr-row b{font-weight:600}
/* la croix quitte son anneau rouge : un signe discret, la zone de toucher de 44 px reste */
#s-joueurs .jr-row .jr-x{border:0;background:rgba(255,255,255,.06);color:var(--c-texte-2)}

/* P4. Champ d'ajout : meme verre, filet violet du bouton « Lancer », « + » en degrade du bouton */
:is(#s-joueurs,#m-players) .jr-saisie{background:rgba(10,11,39,.72);border:1.5px solid rgba(140,110,255,.55);border-radius:var(--r-3)}
:is(#s-joueurs,#m-players) .jr-plus{background:linear-gradient(90deg,#A468EE,#5933FC)}
:is(#s-joueurs,#m-players) .jr-plus svg{stroke:#fff}

/* P5. Bouton principal : celui de « Lancer une Soiree » (degrade violet vers bleu, filet interieur clair, texte blanc) */
#s-joueurs #jr-ok{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  color:var(--c-texte);font-weight:500;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
/* halo tire vers le bas, sans etalement lateral : la zone qui defile le coupait en rectangle */
#s-joueurs #jr-ok:disabled{opacity:.38;box-shadow:inset 0 1.5px 0 rgba(255,255,255,.4)}

/* S1 à S6 : la fiche Soiree (s-sreg) prend la meme langue que « Qui joue ? » (25/09). Proposition, rien de valide. */
/* S1. Fond : le ciel de « Qui joue ? » (copie de P1) */
#s-sreg{background-color:#020106;background-image:
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(60% 14% at 70% 100%, rgba(60,25,140,.35), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}
/* S2. Retour : le carre creme de P2 */
#s-sreg .topbar .iconbtn{background:#EFE9DF;color:#170B20;border:0;border-radius:var(--r-1);
  box-shadow:0 0 0 1px rgba(255,255,255,.35) inset;font-size:var(--t-4);font-weight:600}
/* S3. Selecteurs : rail en verre sombre a filet clair, choix actif = le degrade du bouton « Lancer » */
#s-sreg .sreg-seg{background:rgba(10,11,39,.72);border:1px solid var(--filet-verre-leger);border-radius:var(--r-2);padding:var(--e-1);gap:var(--e-1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10)}
#s-sreg .sreg-seg button{color:var(--c-texte-2);border-radius:var(--r-1)}
#s-sreg .sreg-seg button[aria-pressed="true"]{color:var(--c-texte);font-weight:600;
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 30%,#5933FC 65%,#3528FB 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.6),inset 0 0 10px rgba(255,255,255,.12),0 4px 12px -4px rgba(90,60,255,.7)}
#s-sreg .sreg-seg button[aria-pressed="true"] svg{stroke:#fff}
/* S4. Phrase d'explication sous chaque selecteur : gris lavande de l'accueil */
#s-sreg .sreg-dit{color:var(--c-texte-3)}
#s-sreg .sreg-dit b{color:var(--c-texte);font-weight:600}
/* S5. Reglages avances : la ligne en verre de « Qui joue ? » (P3) */
#s-sreg .sreg-avance{border:1px solid transparent;border-radius:var(--r-3);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
#s-sreg .sreg-pastille{background:rgba(255,255,255,.08)}
/* S6. Valider : le bouton de P5 */
#s-sreg #sreg-valider{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  color:var(--c-texte);font-weight:500;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
/* S7. Titre « Soiree » agrandi (Romain 25/09) : la taille du titre de « Qui joue ? » (21 px, 600) */
#s-sreg .topbar b{font-size:var(--t-4);font-weight:600;letter-spacing:-.015em}
/* PARCOURS-SOIREE:FIN */

/* PARTIE-PLEINE:DEBUT — l'ecran de partie de la Soiree en « carte pleine » (Romain, 25/09).
   Plus de cadre ni d'eventail : la carte EST l'ecran, posee sur le ciel de nuit de l'accueil.
   La DISPOSITION de l'eventail est gardee telle quelle (badge, phrase, condition, trait a
   l'etoile, chiffre, puis « Suivant ») : elle avait ete travaillee et validee, seul le decor
   change. Les onze types passent par elle (JN_PORTES etendu dans app.js).
   Couleur = famille de la carte, celle des tuiles de l'accueil (data-famille pose par app.js) :
   classiques en rose, quiz en bleu, ce qui est propre a la Soiree (defis, lois, bingo, joker)
   en violet. Prefixe `html body` : il faut passer au-dessus du cadre (:is(...)[data-carte]).
   Proposition, rien de valide. */

/* G1. Les trois familles : teinte de base, ton clair (textes), degrade du bouton */
html body #s-game[data-famille="soiree"]{--pf:#8B5CF6;--pf-clair:#C4B5FD;--pf-lueur:rgba(110,70,255,.30);
  --pf-bouton:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);--pf-halo:rgba(90,60,255,.75)}
html body #s-game[data-famille="classiques"]{--pf:#EC4899;--pf-clair:#F9A8D4;--pf-lueur:rgba(236,72,153,.26);
  --pf-bouton:linear-gradient(90deg,#F786C3 0%,#E81F82 45%,#B61E61 100%);--pf-halo:rgba(232,31,130,.7)}
/* [14/10, Romain] une couleur par type propre a la Soiree, choisie parmi celles que l'app n'utilise
   pas deja : Defi orange, Bingo vert pomme, Loi de table rouge, Joker multicolore (le joker
   remplace n'importe quelle carte). Le bouton garde un ton fonce au milieu pour que « Suivant »
   en blanc reste lisible ; la teinte de repli du Joker est un lilas clair. */
html body #s-game[data-famille="defi"]{--pf:#FF7A30;--pf-clair:#FFB283;--pf-lueur:rgba(255,122,48,.26);
  --pf-bouton:linear-gradient(90deg,#FF9F63 0%,#EE6118 45%,#B8440C 100%);--pf-halo:rgba(238,97,24,.7)}
html body #s-game[data-famille="bingo"]{--pf:#8FE04A;--pf-clair:#C2F09A;--pf-lueur:rgba(143,224,74,.22);
  --pf-bouton:linear-gradient(90deg,#8FD456 0%,#5DAA22 45%,#3B7D0F 100%);--pf-halo:rgba(110,200,40,.65)}
html body #s-game[data-famille="loi"]{--pf:#E8CF96;--pf-clair:#F5E6C2;--pf-lueur:rgba(232,207,150,.18);
  --pf-bouton:linear-gradient(90deg,#B8954F 0%,#8A6A2E 45%,#5E4820 100%);--pf-halo:rgba(210,180,110,.55)} /* [16/10] texte blanc lisible : 5 pour 1 au centre (avant 3), le clair E6D3A4 passait sous 1,5 */
html body #s-game[data-famille="joker"]{--pf:#B69CFF;--pf-clair:#D9CCFF;--pf-lueur:rgba(182,156,255,.20);
  --pf-bouton:linear-gradient(90deg,#E8661F 0%,#5DAA22 25%,#3F7FD0 50%,#7B3EFC 75%,#D6337F 100%);--pf-halo:rgba(170,130,255,.7)}
html body #s-game[data-famille="quiz"]{--pf:#5A9BE0;--pf-clair:#A9CDF5;--pf-lueur:rgba(70,140,230,.28);
  --pf-bouton:linear-gradient(90deg,#8CC0F5 0%,#4A8BE0 45%,#2458B8 100%);--pf-halo:rgba(60,130,230,.7)}
/* [20/10, Romain : « le carré autour du titre "loi de table" a une couleur fade [...] on dirait du gris, presque
   ressemblant avec les ronds des initiales »] le champagne a 22 % sur le bleu nuit donnait un taupe gris. Le badge
   de la Loi prend l'or du bouton « Suivant » (B8954F vers 5E4820), liseré champagne : il se lit doré, et les
   initiales creme restent d'une autre matiere.
   ⚠️ EXCEPTION VOULUE a la regle des badges (verre sombre teinte, plus discret que le bouton) : Romain, 20/10,
   « c'est ok que ce soit une exception, puisque c'est une loi qui reste tout le temps ». Ne pas « harmoniser ». */
html body #s-game[data-famille="loi"] #c-tag{background:linear-gradient(160deg,#B8954F 0%,#8A6A2E 55%,#5E4820 100%)!important;
  color:var(--c-texte)!important;box-shadow:inset 0 1px 0 rgba(255,240,200,.55),inset 0 0 0 1px rgba(232,207,150,.75),0 0 18px -4px var(--pf-halo)!important}

/* G2. Fond : le ciel de « Qui joue ? », plus une nappe de la couleur de la famille derriere la phrase */
html body #s-game[data-famille]{background-color:#020106;background-image:
  radial-gradient(80% 42% at 50% 46%, var(--pf-lueur), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.18), transparent 70%),
  linear-gradient(#000102,#01030F)}

/* [14/10] le Joker : une nappe de toutes les couleurs de l'app derriere la phrase */
html body #s-game[data-famille="joker"]{background-image:
  radial-gradient(40% 24% at 32% 40%, rgba(255,122,48,.16), transparent 72%),
  radial-gradient(40% 24% at 68% 42%, rgba(90,155,224,.18), transparent 72%),
  radial-gradient(44% 26% at 50% 54%, rgba(139,92,246,.22), transparent 72%),
  radial-gradient(36% 20% at 40% 60%, rgba(236,72,153,.14), transparent 72%),
  radial-gradient(36% 20% at 62% 34%, rgba(143,224,74,.12), transparent 72%),
  linear-gradient(#000102,#01030F)}

/* G3. Plus de carte : ni cadre, ni matiere, ni eventail. Le paquet prend toute la scene. */
html body #s-game[data-famille] .jn-paquet{aspect-ratio:auto!important;width:100%!important;height:100%!important;max-width:none!important;max-height:none!important}
html body #s-game[data-famille] .jn-paquet::before,
html body #s-game[data-famille] .jn-paquet::after{display:none}
html body #s-game[data-famille] .jn-paquet>.gamecard{background:none!important;border:0!important;box-shadow:none!important;border-radius:0}
html body #s-game[data-famille] .jn-paquet>.gamecard::before,
html body #s-game[data-famille] .jn-paquet>.gamecard::after{display:none}

/* G4. Badge du type : il garde sa place et sa forme de pastille, en verre teinte de la famille */
html body #s-game[data-famille] #c-tag{background:color-mix(in srgb,var(--pf) 22%,rgba(10,11,39,.6));color:var(--c-texte);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),inset 0 0 0 1px color-mix(in srgb,var(--pf) 55%,transparent),0 0 18px -4px var(--pf-halo)}
/* [14/10, Romain] le badge du Joker : un liseré de toutes les couleurs qui tourne autour de lui.
   Seule la position du degrade bouge (pas de filtre anime : l'ecran reste allume toute la soiree). */
html body #s-game[data-famille="joker"] #c-tag{border:2px solid transparent!important;
  background:linear-gradient(#17122A,#17122A) padding-box,
    linear-gradient(90deg,#FF7A30,#8FE04A,#5A9BE0,#8B5CF6,#EC4899,#FF7A30,#8FE04A,#5A9BE0,#8B5CF6,#EC4899,#FF7A30) border-box!important;
  background-size:100% 100%,200% 100%!important;animation:jokerLisere 3s linear infinite}
@keyframes jokerLisere{from{background-position:0 0,0 0}to{background-position:0 0,-100% 0}}
/* l'entree de la carte (vieEntre) reste en tete de liste, sinon ce badge la perdrait */
html body #s-game[data-famille="joker"] .gamecard.anim.anim #c-tag{animation:vieEntre var(--m-moyen) var(--m-sortie) backwards,jokerLisere 3s linear infinite}
@media (prefers-reduced-motion:reduce){html body #s-game[data-famille="joker"] #c-tag,html body #s-game[data-famille="joker"] .gamecard.anim.anim #c-tag{animation:none}}

/* G5. La phrase en blanc, le chiffre et l'etoile dans le ton clair de la famille */
html body #s-game[data-famille] #c-text{color:var(--c-texte)}
html body #s-game[data-famille] #c-quand{color:var(--c-texte-2)}
html body #s-game[data-famille] #c-trait svg{color:var(--pf-clair);fill:var(--pf-clair)}
html body #s-game[data-famille] #c-valeur b{color:var(--pf-clair)}
html body #s-game[data-famille] #c-valeur span{color:var(--c-texte-2)}

/* G6. Commandes du haut : le carre creme de l'accueil (menu et passer) */
html body #s-game[data-famille] #menu-btn,
html body #s-game[data-famille] #c-passer{background:none!important;color:var(--c-texte)!important;border:0!important;
  box-shadow:none!important}   /* [25/09, Romain] glyphe seul, creme */
html body #s-game[data-famille] #menu-btn svg,html body #s-game[data-famille] #c-passer svg{stroke:#EFE9DF}
html body #s-game[data-famille] .jn-titre{color:var(--c-texte)}
html body #s-game[data-famille] #g-prog{background:var(--pf-clair)}

/* G7. « Suivant » : la recette du bouton « Lancer une Soirée », dans le degrade de la famille */
html body #s-game[data-famille] #btn-next{background:var(--pf-bouton)!important;color:var(--c-texte)!important;font-weight:600;border:0!important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px var(--pf-halo)!important}
/* G7 bis. Exception voulue (Romain, 20/10, direction A) : le « Suivant » du Joker est en verre sombre,
   contour arc-en-ciel fin comme son badge, texte blanc */
html body #s-game[data-famille="joker"] #btn-next{border:2px solid transparent!important;color:var(--c-texte)!important;
  background:linear-gradient(#0d0b22,#0d0b22) padding-box,
    linear-gradient(90deg,#FF9A5C,#A7EA6E,#7DB5EA,#A78BFA,#F472B6) border-box!important;
  box-shadow:0 8px 20px -10px rgba(170,130,255,.45)!important}

/* G8. Les autres boutons de la carte (Action / Verite, Voir la reponse, Je me degonfle, options) :
   verre sombre bordé de la famille, pour ne pas concurrencer « Suivant » */
html body #s-game[data-famille] .jn-branche,
html body #s-game[data-famille] #c-reveal:not(.shown),
html body #s-game[data-famille] #btn-degonfle{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;
  border:1.5px solid color-mix(in srgb,var(--pf) 70%,transparent)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 16px -6px var(--pf-halo)!important}
html body #s-game[data-famille] #c-reveal.shown{color:var(--pf-clair)!important}
/* [20/10, Romain : « la bulle grise qui donne la réponse à un quiz est parfois trop petite pour la réponse
   affichée », « légèrement plus grande qu'aujourd'hui »] la pastille suit son texte : marge de chaque cote,
   retour a la ligne permis, jamais plus large que la carte ; corps un cran au-dessus (.95 -> 1.0625rem). */
html body #s-game #c-reveal.shown{padding:var(--e-2) var(--e-3)!important;font-size:var(--t-3)!important;line-height:1.3;
  white-space:normal;max-width:100%;height:auto;min-height:0;text-align:center;box-sizing:border-box;overflow:visible}
/* [20/10, Romain : « remets un encadré propre comme avant »] l'encadre ne change pas de forme en s'ouvrant : le meme
   verre borde de la famille avant et apres, seul le texte change, en fondu (.ouvre). Il reste a sa place. */
html body #s-game[data-famille] #c-reveal{padding:var(--e-2) var(--e-3)!important;font-size:var(--t-3)!important;line-height:1.3;border-radius:var(--r-2)!important;
  white-space:normal;max-width:100%;text-align:center;box-sizing:border-box}
html body #s-game[data-famille] #c-reveal.shown{background:rgba(10,11,39,.62)!important;
  border:1.5px solid color-mix(in srgb,var(--pf) 70%,transparent)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 16px -6px var(--pf-halo)!important;opacity:1}
html body #s-game #c-reveal.ouvre{animation:repFondu var(--m-moyen) var(--m-sortie) both}
@keyframes repFondu{from{opacity:.15}to{opacity:1}}
@media (prefers-reduced-motion:reduce){html body #s-game #c-reveal.ouvre{animation:none}}
/* G9. Deux objets que la regle du cadre (« ce que la carte ne porte pas », 08/08) masquait a tort
   des que tous les types sont passes par lui :
   - la reponse du Quiz (« Voir la réponse ») : sans elle le Quiz n'a plus de reponse ;
   - le « Juge final » (Romain, 23/09), ajoute APRES cette regle et donc jamais vu a l'ecran.
   « À toi, X » reste masque : un narrateur lit la carte, le prenom est deja dans la phrase. */
html body #s-game[data-famille] #c-reveal:not([style*="none"]){display:inline-flex!important;align-self:center}
html body #s-game[data-famille] .g-turn:has(.juge){display:flex!important;justify-content:center}
html body #s-game[data-famille] .g-turn .juge{max-width:none;overflow:visible;background:none;border:0;box-shadow:none;padding:0;
  color:var(--c-texte-2);font-size:var(--t-2);font-weight:500}
html body #s-game[data-famille] .g-turn .juge b{color:var(--pf-clair);font-weight:700}
/* G10. Le Juge final ne pousse pas le badge (la disposition validee ne bouge pas d'une carte a
   l'autre) : il se pose sous le chiffre, au pied de la carte, et son prenom n'est jamais coupe. */
html body #s-game[data-famille] .jn-paquet>.gamecard{position:relative}
/* [25/09, Romain] remplace : il se pose sous la question (voir G12), plus au pied de la carte */
html body #s-game[data-famille] .g-turn .juge b{max-width:none;overflow:visible;text-overflow:clip;white-space:nowrap;display:inline}
/* G11. Quiz (Romain, 25/09) : « Voir la réponse » juste sous la question. La phrase cesse de
   remplir la bande du milieu, et le groupe question + reponse s'y centre a sa place. */
html body #s-game[data-carte="quiz"] #c-text{flex:0 0 auto!important;margin-top:auto!important}
html body #s-game[data-carte="quiz"] #c-reveal:not([style*="none"]){margin-top:var(--e-4)!important;margin-bottom:auto!important}
/* G12. Juge final (Romain, 25/09) : juste sous la question, au-dessus des gorgées, comme la
   reponse du Quiz. La question cesse de remplir la bande du milieu, le groupe s'y centre. */
html body #s-game[data-carte="balance"] #c-text:has(+ .g-turn .juge){flex:0 0 auto!important;margin-top:auto!important}
html body #s-game[data-carte="preferes"] #c-choix:has(+ .g-turn .juge){flex:0 0 auto!important;margin-top:auto!important}
html body #s-game[data-famille] .g-turn:has(.juge){position:static;margin:var(--e-4) 0 auto!important}
/* G13. Chrono des defis en temps limite (Romain, 25/09) : un rond de verre sous la phrase, l'anneau
   dans le ton clair de la famille se vide pendant le decompte. On appuie sur le rond, pas de bouton. */
html body #s-game[data-famille] #c-text:has(+ #c-chrono:not([style*="none"])){flex:0 0 auto!important;margin-top:auto!important}
html body #s-game .jn-chrono{position:relative;width:96px;height:96px;flex:0 0 auto;align-self:center;margin:var(--e-4) 0 auto!important;padding:0;border:0;
  border-radius:50%;background:rgba(10,11,39,.62);color:var(--c-texte);cursor:pointer;font-family:inherit;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 24px -8px var(--pf-halo,rgba(90,60,255,.6))}
html body #s-game .jn-chrono[style*="none"]{display:none!important}
html body #s-game .jn-chrono svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
html body #s-game .jn-chrono circle{fill:none;stroke-width:5}
html body #s-game .jn-chrono .ch-fond{stroke:rgba(255,255,255,.10)}
html body #s-game .jn-chrono .ch-arc{stroke:var(--pf-clair,#C4B5FD);stroke-linecap:round}
html body #s-game .jn-chrono b{position:relative;font-size:var(--t-5);font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
html body #s-game .jn-chrono .ch-s{position:relative;font-size:var(--t-2);font-weight:600;color:var(--c-texte-3);margin-left:1px}
html body #s-game .jn-chrono.fini{box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 0 3px var(--pf-clair,#C4B5FD),0 0 30px -4px var(--pf-halo,rgba(90,60,255,.8))}
html body #s-game .jn-chrono.fini b{color:var(--pf-clair,#C4B5FD)}
/* PARTIE-PLEINE:FIN */

/* REPRISE-VERRE:DEBUT — la banniere « Reprendre la partie » dans le menu verre (Romain, 25/09).
   Place : entre la carte Soiree (355 a 880 de toile) et « Autres modes de jeu ». Quand elle est la,
   la section et les trois modes descendent de 134 px de toile. Matiere : celle de la barre
   Trinkeurs (fond nuit #0A0B27, filet degrade), le filet et la tuile d'icone prennent la couleur
   du mode repris. Fin de l'aplat violet a encre sombre de la v1. Proposition, rien de valide. */
#mv-canvas #home-resume{position:absolute;left:42px;top:918px;width:856px;height:96px;margin:0;display:block}
#s-home.accroche #mv-canvas .mv-section{top:1055px}
#s-home.accroche #mv-canvas .mv-mode{top:1099px}
#mv-canvas #btn-resume{--rep-a:#A468EE;--rep-b:#5933FC;--rep-c:#2526FC;--rep-halo:rgba(90,60,255,.45);
  position:relative;width:100%;height:100%;box-sizing:border-box;border-radius:30px;padding:0 34px 0 26px;gap:24px;
  display:flex;align-items:center;text-align:left;background:#0A0B27;color:#F7F5FA;border:0;
  box-shadow:0 0 30px -8px var(--rep-halo)}
#mv-canvas #btn-resume.rep-minijeux{--rep-a:#F5C04A;--rep-b:#D4A304;--rep-c:#9F7403;--rep-halo:rgba(212,163,4,.40)}
/* le filet : degrade du mode, 3 px de toile comme celui de la barre Trinkeurs */
#mv-canvas #btn-resume::before{content:"";position:absolute;inset:0;border-radius:30px;padding:3px;pointer-events:none;
  background:linear-gradient(90deg,var(--rep-a),var(--rep-b) 55%,var(--rep-c));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
/* la tuile d'icone : la matiere des tuiles de mode (degrade plein, arete claire en haut) */
#mv-canvas #btn-resume .hmi{flex:0 0 auto;width:66px;height:66px;border-radius:20px;display:grid;place-items:center;
  background:linear-gradient(135deg,var(--rep-a),var(--rep-b) 60%,var(--rep-c));
  box-shadow:inset 0 2px 0 rgba(255,255,255,.35),0 4px 14px -4px var(--rep-halo)}
#mv-canvas #btn-resume .hmi svg{width:36px;height:36px;fill:none;stroke:#fff;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
#mv-canvas #btn-resume .htx{display:flex;flex-direction:column;min-width:0;flex:1}
#mv-canvas #btn-resume b{font-size:2.125rem;font-weight:700;color:#F7F5FA;line-height:1.15}
#mv-canvas #btn-resume small{font-size:1.625rem;font-weight:500;color:#A8A0BA;opacity:1;margin-top:2px}
#mv-canvas #btn-resume .hchev{margin-left:auto;width:16px;height:28px;fill:none;stroke:#CFC9DA;stroke-width:2.6;opacity:1}
/* [25/09, Romain] depuis l'accueil, la fenetre offre deux vrais choix : « Nouvelle partie » en verre */
html body #m-arret.choix-accueil .btn.ghost{background:rgba(10,11,39,.62)!important;border:1px solid var(--filet-verre)!important;
  border-radius:var(--r-4);color:var(--c-texte)!important;min-height:52px;margin-top:var(--e-2);width:100%;box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
/* REPRISE-VERRE:FIN */

/* SOIREE-SUITE:DEBUT — le reste du parcours Soiree dans la langue de l'accueil (Romain, 25/09) :
   reglages avances, menu de partie, « Arreter la soiree ? », les deux mini-jeux intercales (La
   bombe, Le doigt du destin) et « Partie terminee ». Meme vocabulaire que « Qui joue ? » et la
   carte pleine : ciel de nuit, carres creme, verre sombre a filet clair, bouton principal fait
   comme « Lancer une Soiree » dans l'accent de l'ecran (--accent / --accent2, poses par show()).
   Les OBJETS des mini-jeux (la bombe, le cercle du doigt) gardent leur couleur : c'est leur
   identite, seul l'habillage change. Prefixe `html body` : passer au-dessus des regles d'ecran.
   Proposition, rien de valide. */

/* T1. Fond : le ciel de nuit, avec une nappe de l'accent de l'ecran au centre */
html body :is(#s-savances,#s-bomb,#s-finger,#s-defi){background-color:#020106;background-image:
  radial-gradient(80% 40% at 50% 48%, color-mix(in srgb,var(--accent) 16%,transparent), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.18), transparent 70%),
  linear-gradient(#000102,#01030F)}

/* T2. Commandes carrees : le carre creme (retour, menu, « ? ») */
html body :is(#s-bomb,#s-finger,#s-defi) .iconbtn,
html body :is(#s-bomb,#s-finger) .helpbtn,
html body #menu-btn{background:#EFE9DF!important;color:#170B20!important;border:0!important;
  box-shadow:0 0 0 1px rgba(255,255,255,.35) inset!important}
html body #menu-btn svg{stroke:#170B20}
html body :is(#s-bomb,#s-finger) .helpbtn{width:36px;height:36px;min-width:36px;border-radius:var(--r-1);font-weight:700}
html body :is(#s-bomb,#s-finger,#s-defi) .topbar b{color:var(--c-texte);font-size:var(--t-4);font-weight:600;letter-spacing:-.015em}

/* T3. Bouton principal : la recette de « Lancer une Soirée », degrade de l'accent, texte blanc */
html body :is(#s-bomb,#s-finger,#s-defi,#m-menu,#m-arret) .btn:not(.sec):not(.ghost),
html body #s-savances #sav-ok{
  background:linear-gradient(90deg,var(--accent2) 0%,var(--accent) 55%,color-mix(in srgb,var(--accent) 70%,#1a0a40) 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0!important;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),
             0 8px 20px -8px color-mix(in srgb,var(--accent) 80%,transparent)!important}
/* la Soiree (violet) prend exactement le degrade du bouton de l'accueil */
html body :is(#s-defi[data-accent^="#8b5cf6"],#s-savances) :is(.btn:not(.sec):not(.ghost),#sav-ok),
html body :is(#m-menu,#m-arret) .btn:not(.sec):not(.ghost){
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%)!important}

/* T4. Bouton secondaire : verre sombre a filet clair, jamais une surface pleine */
html body :is(#s-defi,#m-menu) .btn.sec:not(.danger),
html body #s-savances .sav-annuler{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;
  border:1px solid var(--filet-verre)!important;border-radius:var(--r-4);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)!important}
/* « Terminer la partie » reste rouge (l'irreversible, socle) mais dans le meme verre ; [21/10, audit V2] aussi dans « Arrêter la soirée ? » */
html body :is(#m-menu,#m-arret) .btn.sec.danger,html body #m-menu #menu-end{background:rgba(40,8,16,.55)!important;border-radius:var(--r-4);
  border:1px solid rgba(248,113,113,.55)!important;color:#FCA5A5!important}

/* T5. Feuilles (menu de partie, arret) : panneau de verre nuit, filet clair en haut */
html body #m-menu .sheet{background:linear-gradient(180deg,#12112E 0%,#0A0B27 100%);border:0;border-radius:var(--r-4) var(--r-4) 0 0;
  box-shadow:inset 0 1.5px 0 var(--filet-verre),0 -20px 60px -20px rgba(90,60,255,.45)}
html body #m-menu .sheet h2{color:var(--c-texte);font-size:var(--t-4);font-weight:700}
html body #m-menu .sheet .mut{color:var(--c-texte-3)}
html body :is(#m-menu,#m-arret){background:rgba(2,1,10,.62);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
html body #m-arret .sheet{background:linear-gradient(180deg,#12112E 0%,#0A0B27 100%)!important;border-radius:var(--r-4)!important;
  padding:var(--e-4) var(--e-4) var(--e-3)!important;box-shadow:inset 0 1.5px 0 var(--filet-verre),0 20px 60px -20px rgba(90,60,255,.5)!important}
html body #m-arret .sheet h2{color:var(--c-texte)}
html body #m-arret .sheet .dim{color:var(--c-texte-2)}
html body #m-arret .sheet .mut{color:var(--c-texte-3)}
html body #m-arret .btn.ghost{color:var(--c-texte-2)}

/* T6. Reglages avances : sections en verre (la ligne de « Qui joue ? »), titre blanc */
html body #s-savances .sav-titre{color:var(--c-texte)}
html body #s-savances .sav-sec{border:1px solid transparent;border-radius:var(--r-3);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
html body #s-savances .sav-dit{color:var(--c-texte-3)}
html body #s-savances .sav-case{border-color:var(--filet-verre)}
html body #s-savances .sav-nom{color:var(--c-texte-3)}

/* T7. Mini-jeux intercales : le bandeau « X commence / Au tour de X » devient une pastille de verre
   bordee de l'accent (texte blanc) ; la categorie de La bombe, un panneau de verre */
html body #turn-badge{background:rgba(10,11,39,.72)!important;color:var(--c-texte)!important;font-weight:700;
  border:1.5px solid color-mix(in srgb,var(--accent) 80%,transparent)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 0 22px -6px var(--accent),var(--o-2)!important}
html body #s-bomb #bomb-cat{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
html body :is(#s-bomb,#s-finger) .dim{color:var(--c-texte-2)}

/* T8. Partie terminee : l'invitation passe en verre */
html body #s-defi.fin-nue .fn-invite{background:rgba(10,11,39,.62)!important;border:1px solid var(--filet-verre)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)!important}
html body #s-defi.fin-nue .fn-part{background:#EFE9DF!important;color:#170B20!important;border:0!important}
html body #s-defi.fin-nue .fn-part svg{stroke:#170B20}
/* [26/10] G5 etoilee : le fond plein du mode remplace le ciel de nuit ; Rejouer creme, Retour sans fond et plus leger
   (il ne dispute plus l'oeil a Rejouer), invitation inchangee (verre sombre), plus de filet au-dessus d'elle */
html body #s-turn.mu-fini-on,html body :is(#s-defi.fin-nue,#s-multi.mu-scene){background-color:#160A52;background-image:var(--fn-plein)!important}
html body #s-defi.fin-nue #df-action{background:#EFE9DF!important;color:#151515!important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.8),0 8px 20px -8px rgba(0,0,0,.6)!important}
html body #s-defi.fin-nue #df-secondary{background:transparent!important;border:1px solid rgba(255,255,255,.45)!important;
  font-weight:500;box-shadow:none!important}

html body #s-defi.fin-nue .fn-sep{background:transparent;margin:var(--e-3) 0 0}
/* [27/10, Romain, direction B de la planche « Jouer avec un ami »] LA SALLE D'ATTENTE DU MULTIJOUEUR EST LA SCENE DE LA FIN
   (« la présentation doit etre presque la meme entre partie en ligne oou partie en local »). Les regles de la scene sont
   PARTAGEES par :is(#s-defi.fin-nue,#s-multi.mu-scene), jamais recopiees ; ne vivent ici que ce que la salle a en plus : son
   corps qui defile (#mu-body, la ou la fin a #df-body), l'ami attendu (pali ET nomme, jamais la couleur seule), le temps qui
   reste, les reglages en une ligne, et ses commandes aux valeurs de Rejouer (creme) et de Retour (sans fond). Rouge pour
   « Annuler la partie » seul : il annule pour tout le monde. */
#s-multi.mu-scene #mu-body{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;position:relative;z-index:1;
  padding-bottom:calc(var(--e-4) + env(safe-area-inset-bottom,0px))}
#s-multi.mu-scene #mu-body>.grow{flex:1 1 0;min-height:var(--e-3)}
#s-multi.mu-scene .fn-corps{width:100%}
:is(#s-defi.fin-nue,#s-multi.mu-scene) .fn-j.fn-absent{opacity:.45}
#s-multi.mu-scene .fn-reg{margin:var(--e-2) 0 0;text-align:center;font-size:var(--t-2);color:rgba(255,255,255,.82)}
#s-multi.mu-scene .fn-chrono{margin:var(--e-4) 0 0;text-align:center;font-size:var(--t-1);color:rgba(255,255,255,.78)}
#s-multi.mu-scene .fn-chrono b{font-weight:600;font-variant-numeric:tabular-nums;color:#fff}
#s-multi.mu-scene .fn-bas{display:flex;flex-direction:column;gap:var(--e-2);width:100%}
html body #s-multi.mu-scene .fn-a{background:#EFE9DF!important;color:#151515!important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.8),0 8px 20px -8px rgba(0,0,0,.6)!important}
html body #s-multi.mu-scene .fn-a:disabled{background:rgba(255,255,255,.14)!important;color:rgba(255,255,255,.75)!important;box-shadow:none!important}
html body #s-multi.mu-scene .fn-b{background:transparent!important;border:1px solid rgba(255,255,255,.45)!important;
  font-weight:500;box-shadow:none!important;color:#fff!important}
/* le message de succes (« X debloque : ... ») ne recouvre plus « Retour a l'accueil » : en haut sur l'ecran de fin */
html body:has(#s-defi.on) #toast{top:calc(env(safe-area-inset-top,0px) + var(--e-3));bottom:auto}
/* [28/10] la meme chose sur la fin d'une partie a plusieurs : le succes debloque au moment ou la partie se termine se posait sur « Rejouer » */
html body:has(#mu-rejoue) #toast{top:calc(env(safe-area-inset-top,0px) + var(--e-3));bottom:auto}
/* T9. Passer un mini-jeu (Romain, 25/09) : le carre creme du « passer » des cartes, a droite du « ? ».
   La barre passe en grille 1fr/auto/1fr pour que le titre reste centre avec deux boutons a droite. */
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .topbar.avec-passer{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;column-gap:var(--e-2)}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .topbar.avec-passer>:first-child{justify-self:start}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .topbar.avec-passer>b{grid-column:2}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .topbar.avec-passer>.iconbtn:not(:first-child){grid-column:3;grid-row:1;justify-self:end;margin-right:52px;width:44px;height:44px;border-radius:var(--r-1)}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .topbar.avec-passer>.mini-passer{grid-column:3;grid-row:1;justify-self:end}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .mini-passer{position:static!important;margin:0!important;inset:auto!important;transform:none!important;width:44px;height:44px;border-radius:var(--r-1);display:grid;place-items:center;
  background:#EFE9DF;color:#170B20;border:0;box-shadow:0 0 0 1px rgba(255,255,255,.35) inset;cursor:pointer}
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .mini-passer svg{width:15px;height:15px}
/* cible tactile de 44 px sans changer la taille visible */
html body :is(#s-bomb,#s-finger,#s-roulette,#s-wheel) .mini-passer{position:relative}
/* T10. Menu de partie (Romain, 25/09 : « pas cohérent avec l'app ») : panneau de nuit, un seul bouton
   plein (Reprendre), les autres actions en lignes de verre comme « Réglages avancés », Terminer en
   texte rouge au pied. Remplace, pour ce menu, les boutons empiles de T3/T4. */
html body #m-menu .sheet.mn{padding:var(--e-2) var(--e-4) calc(var(--e-3) + env(safe-area-inset-bottom,0px));display:flex;flex-direction:column}
html body #m-menu .mn-poignee{align-self:center;width:40px;height:5px;border-radius:var(--r-1);background:rgba(255,255,255,.22);margin-bottom:var(--e-3)}
html body #m-menu .sheet.mn h2{margin:0}
html body #m-menu .sheet.mn #menu-sub{margin:var(--e-1) 0 var(--e-3)}
html body #m-menu #menu-resume{margin:0;width:100%;min-height:54px;font-size:var(--t-3)}
html body #m-menu .mn-liste{display:flex;flex-direction:column;gap:var(--e-2);margin-top:var(--e-3)}
html body #m-menu .mn-ligne{display:flex;align-items:center;gap:var(--e-3);width:100%;min-height:58px;padding:0 var(--e-3) 0 var(--e-2);text-align:left;
  font-family:inherit;color:var(--c-texte);cursor:pointer;border:1px solid transparent;border-radius:var(--r-3);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
html body #m-menu .mn-ligne b{flex:1;font-size:var(--t-2);font-weight:600}
html body #m-menu .mn-ico{flex:0 0 auto;width:38px;height:38px;border-radius:var(--r-1);display:grid;place-items:center;background:rgba(255,255,255,.08)}
html body #m-menu .mn-ico svg{width:20px;height:20px;fill:none;stroke:#CFC9DA;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
html body #m-menu .mn-ch{width:8px;height:14px;fill:none;stroke:#8A82A6;stroke-width:2}
html body #m-menu .mn-terminer{margin-top:var(--e-3);align-self:center;background:none;border:0;padding:var(--e-3) var(--e-3);min-height:44px;
  font-family:inherit;font-size:var(--t-2);font-weight:600;color:#F87171;cursor:pointer}
html body #m-menu #menu-end.mn-terminer{background:none!important;border:0!important;box-shadow:none!important;color:#F87171!important;width:auto}
/* « Terminer après ce jeu » est affiche par le JS en display:block : la ligne garde sa mise en page */
html body #m-menu .mn-ligne:not([style*="none"]){display:flex!important}
/* T11. Reglages (Romain, 25/09 : « des boutons qui ne font pas du tout la meme taille que le reste
   de l'app ») : le panneau reprend les mesures exactes du menu de partie qui l'ouvre. Panneau de
   nuit, lignes de verre separees de 58 px, tuile d'icone neutre de 38 px, libelle 16 px en 600,
   sous-texte gris lavande, interrupteur au degrade du bouton principal. */
html body #m-settings{background:rgba(2,1,10,.62);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
html body #m-settings .sheet.set-feuille{background:linear-gradient(180deg,#12112E 0%,#0A0B27 100%);border:0;border-radius:var(--r-4) var(--r-4) 0 0;
  padding:var(--e-2) var(--e-4) calc(var(--e-3) + env(safe-area-inset-bottom,0px));
  box-shadow:inset 0 1.5px 0 var(--filet-verre),0 -20px 60px -20px rgba(90,60,255,.45)}
html body #m-settings .set-poignee{width:40px;height:5px;background:rgba(255,255,255,.22);margin:0 auto var(--e-3)}
html body #m-settings .set-tete{color:var(--c-texte);font-size:var(--t-4);font-weight:700;margin:0 0 var(--e-1);padding:0}
html body #m-settings .set-lab{color:var(--c-texte-3);font-size:var(--t-1);font-weight:600;letter-spacing:.16em;text-transform:uppercase;margin:var(--e-3) 0 var(--e-2);padding:0}
html body #m-settings .set-groupe{background:none!important;border:0!important;box-shadow:none!important;border-radius:0;overflow:visible;
  display:flex;flex-direction:column;gap:var(--e-2)}
html body #m-settings .set-rg{min-height:58px;padding:0 var(--e-3) 0 var(--e-2);border:1px solid transparent;border-radius:var(--r-3);color:var(--c-texte);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
html body #m-settings .set-rg+.set-rg::before{display:none}
html body #m-settings .set-tu,html body #m-settings .set-tu.violet,html body #m-settings .set-tu.ardoise{width:38px;height:38px;border-radius:var(--r-1);background:rgba(255,255,255,.08)}
html body #m-settings .set-gl{width:20px;height:20px;stroke:#CFC9DA;stroke-width:1.7}
html body #m-settings .set-aa{color:var(--c-texte-2)}
html body #m-settings .set-rg b{font-size:var(--t-2);font-weight:600;color:var(--c-texte)}
html body #m-settings .set-rg small{font-size:var(--t-1);color:var(--c-texte-3)}
html body #m-settings .set-sw{background:rgba(255,255,255,.12)}
html body #m-settings .set-rg.on .set-sw{background:linear-gradient(90deg,#A468EE 0%,#5933FC 60%,#2526FC 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45)}
/* T12. Tuiles d'icone des lignes en CREME (Romain, 25/09) : le carre creme des commandes de l'app
   (#EFE9DF, glyphe encre #170B20), dans le menu de partie, les Reglages et la ligne « Réglages avancés ». */
html body #m-menu .mn-ico,
html body #m-settings .set-tu,html body #m-settings .set-tu.violet,html body #m-settings .set-tu.ardoise,
html body #s-sreg .sreg-pastille{background:#EFE9DF!important;box-shadow:0 0 0 1px rgba(255,255,255,.35) inset}
html body #m-menu .mn-ico svg,html body #m-settings .set-gl{stroke:#170B20!important}
html body #s-sreg .sreg-pastille svg{stroke:#170B20;color:#170B20}
html body #m-settings .set-aa{color:#170B20!important}
/* T13. Le doigt du destin (Romain, 25/09) : plus de cercle central interdit. Un rectangle en pointilles
   borde la zone ou poser les doigts ; la consigne et le decompte montent en haut, hors de portee des doigts. */
html body #finger-zone::before{top:12px;left:12px;right:12px;bottom:12px;width:auto;height:auto;margin:0;border-radius:var(--r-4);
  border:2px dashed rgba(74,222,128,.5);animation:none}
html body #finger-zone::after{display:none}
html body #finger-zone>.finger-mid{position:absolute;top:34px;left:28px;right:28px}
/* T14. Le doigt designe garde SA couleur (Romain, 25/09 : il passait au blanc) : pastille pleine de sa
   couleur, anneau blanc fin pour le contraste, halo large de sa couleur, un peu plus grande. Les autres
   s'eteignent deja (.fdot.out), c'est ce qui fait ressortir le designe. */
html body .fdot.win{background:var(--fc,#fff)!important;border-color:#fff!important;
  box-shadow:0 0 0 3px var(--fc,#fff),0 0 34px 8px var(--fc,#fff),0 0 90px 20px color-mix(in srgb,var(--fc,#fff) 55%,transparent)!important;
  filter:brightness(1.15) saturate(1.2);transform:scale(1.4)}
/* SOIREE-SUITE:FIN */
/* [02/11, Romain, direction B] LE DOIGT DU DESTIN A DISTANCE : un rond par trinkeur, son initiale, son prenom dessous ;
   en pointilles tant qu'il n'a pas pose. Le designe garde SA couleur (Romain, 02/11 : « le résultat en couleur pas en
   blanc crème »), comme le doigt designe du jeu local (T14 ci-dessus). */
#finger-zone.ft-table .finger-ico{opacity:0}
.ft-rond{position:absolute;width:74px;height:74px;margin:-37px 0 0 -37px;border-radius:50%;display:grid;place-items:center;z-index:2;pointer-events:none;
  border:3px solid var(--fc);background:color-mix(in srgb,var(--fc) 23%,transparent);box-shadow:0 0 20px color-mix(in srgb,var(--fc) 60%,transparent);
  transition:transform .18s ease,opacity .3s,box-shadow .2s,background .15s}
.ft-rond b{font-size:var(--t-5);font-weight:900;color:#fff;line-height:1}
.ft-rond .ft-nom{position:absolute;top:calc(100% + 8px);left:50%;transform:translateX(-50%);font-size:var(--t-2);font-weight:700;color:#fff;
  white-space:nowrap;text-shadow:0 1px 6px rgba(0,0,0,.6)}
.ft-rond.vide{border-style:dashed;background:transparent;box-shadow:none}
.ft-rond.vide b{color:var(--c-texte-3)}
.ft-rond.sel{transform:scale(1.2);filter:brightness(1.55)}
.ft-rond.win{background:var(--fc);border-color:#fff;transform:scale(1.35);z-index:3;filter:brightness(1.15) saturate(1.2);
  box-shadow:0 0 0 3px var(--fc),0 0 34px 8px var(--fc),0 0 90px 20px color-mix(in srgb,var(--fc) 55%,transparent)}
.ft-rond.win b{color:#170B20}
.ft-rond.out{opacity:.12;transform:scale(.8)}
.ft-attend{display:block;margin-top:var(--e-2);font-size:var(--t-2);font-weight:600;color:var(--c-texte-2)}
@media (prefers-reduced-motion:reduce){ .ft-rond{transition:none} }

/* [25/09, Romain, capture sur Mac] LES PANNEAUX QUI MONTENT DU BAS RESTENT DANS LA COLONNE DE L'APP.
   La fenetre (.modal) couvre tout l'ecran, et la feuille y prenait width:100% : sur un grand ecran,
   menu et reglages s'etalaient sur toute la largeur alors que l'app fait 560 px au plus (.app).
   Invisible sur iPhone, ou l'ecran est plus etroit que la colonne. */
.modal{justify-content:center}
.modal .sheet{max-width:560px;margin-left:auto;margin-right:auto}

/* AGE-VERRE:DEBUT — la porte d'age dans la langue de l'accueil (Romain, 25/09 : « elle est pas belle »).
   Ciel de nuit, « Trinke » en lettres blanches au halo violet avec ses trois etincelles (le titre de
   l'accueil), mentions legales dans une ligne de verre, badge 18+ en carre creme, bouton principal
   fait comme « Lancer une Soirée », refus en verre. Textes et ordre inchanges (conformite). */
html body #s-age{background-color:#020106;background-image:
  radial-gradient(70% 34% at 50% 30%, rgba(110,60,255,.30), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-age .home-bg{display:none}
html body #s-age .age-logo{color:#C4B5FD;filter:drop-shadow(0 0 10px rgba(170,70,255,.6))}
/* le titre de l'accueil : blanc, halo violet, trois etincelles en orbite du « e » */
html body #s-age .wm{position:relative;width:fit-content;margin:0 auto;
  font-family:-apple-system,"SF Pro Display","Helvetica Neue",sans-serif;font-weight:700;letter-spacing:-.02em;
  background:none!important;-webkit-text-fill-color:#fff;color:var(--c-texte);animation:none!important;
  filter:drop-shadow(0 0 6px rgba(215,130,255,.55)) drop-shadow(0 0 18px rgba(170,70,255,.45))}
html body #s-age .wm::after{content:"";position:absolute;right:-.5em;top:-.13em;width:.95em;height:.52em;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 116 64'%3E%3Cg fill='none' stroke='%23fff' stroke-width='5' stroke-linecap='round'%3E%3Cpath d='M46.4 26.5 L44 12.7'/%3E%3Cpath d='M67.2 28.7 L73.7 16.3'/%3E%3Cpath d='M82.8 43.6 L95.5 37.7'/%3E%3C/g%3E%3C/svg%3E") no-repeat center/contain}
html body #s-age .home-tag{color:var(--c-texte-2)}
/* les mentions legales : une ligne de verre, badge 18+ en carre creme */
html body #s-age .age-legal{border:1px solid transparent;border-radius:var(--r-3);
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),
                   linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;
  box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
html body #s-age .age-legal p{color:var(--c-texte-2)}
html body #s-age .age-badge{background:#EFE9DF;color:#170B20;border:0;box-shadow:0 0 0 1px rgba(255,255,255,.35) inset;font-weight:800}
/* J'ai 18 ans : le bouton « Lancer une Soirée » ; Je suis mineur : verre */
html body #s-age #btn-age{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #s-age #btn-age-no{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;border:1px solid var(--filet-verre)!important;
  border-radius:var(--r-4);box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
html body #s-age .age-trust{color:var(--c-texte-3)}
/* AGE-VERRE:FIN */

/* INTRO-VERRE (Romain, 25/09) : la presentation de la premiere visite prend le panneau du menu de
   partie. Panneau de nuit, points de progression au degrade principal, « Suivant » fait comme
   « Lancer une Soirée », « Passer » en verre. Textes inchanges. */
html body #m-intro{background:rgba(2,1,10,.62);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
html body #m-intro .sheet{background:linear-gradient(180deg,#12112E 0%,#0A0B27 100%);border:0;border-radius:var(--r-4) var(--r-4) 0 0;
  padding:var(--e-4) var(--e-4) calc(var(--e-3) + env(safe-area-inset-bottom,0px));
  box-shadow:inset 0 1.5px 0 var(--filet-verre),0 -20px 60px -20px rgba(90,60,255,.45)}
html body #m-intro #intro-title{color:var(--c-texte);font-size:var(--t-4);font-weight:700;letter-spacing:-.015em}
html body #m-intro #intro-desc{color:var(--c-texte-2)}
html body #m-intro .intro-dots>*{background:rgba(255,255,255,.16)}
html body #m-intro .intro-dots>.on,html body #m-intro .intro-dots>[aria-current],html body #m-intro .intro-dots>.active{
  background:linear-gradient(90deg,#A468EE,#5933FC)!important;box-shadow:0 0 10px rgba(120,80,255,.6)}
html body #m-intro #intro-next{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #m-intro #intro-skip{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;border:1px solid var(--filet-verre)!important;
  border-radius:var(--r-4);box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}

/* CLASSIQUES-PLEINE:DEBUT — copie de PARTIE-PLEINE pour #s-classic-run (Romain, 25/09 : « refait le design de classique »). Genere, ne pas editer a la main : refaire la copie.
 — l'ecran de partie de la Soiree en « carte pleine » (Romain, 25/09).
   Plus de cadre ni d'eventail : la carte EST l'ecran, posee sur le ciel de nuit de l'accueil.
   La DISPOSITION de l'eventail est gardee telle quelle (badge, phrase, condition, trait a
   l'etoile, chiffre, puis « Suivant ») : elle avait ete travaillee et validee, seul le decor
   change. Les onze types passent par elle (JN_PORTES etendu dans app.js).
   Couleur = famille de la carte, celle des tuiles de l'accueil (data-famille pose par app.js) :
   classiques en rose, quiz en bleu, ce qui est propre a la Soiree (defis, lois, bingo, joker)
   en violet. Prefixe `html body` : il faut passer au-dessus du cadre (:is(...)[data-carte]).
   Proposition, rien de valide. */

/* G1. Les trois familles : teinte de base, ton clair (textes), degrade du bouton */
html body #s-classic-run[data-famille="soiree"]{--pf:#8B5CF6;--pf-clair:#C4B5FD;--pf-lueur:rgba(110,70,255,.30);
  --pf-bouton:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);--pf-halo:rgba(90,60,255,.75)}
html body #s-classic-run[data-famille="classiques"]{--pf:#EC4899;--pf-clair:#F9A8D4;--pf-lueur:rgba(236,72,153,.26);
  --pf-bouton:linear-gradient(90deg,#F786C3 0%,#E81F82 45%,#B61E61 100%);--pf-halo:rgba(232,31,130,.7)}
html body #s-classic-run[data-famille="quiz"]{--pf:#5A9BE0;--pf-clair:#A9CDF5;--pf-lueur:rgba(70,140,230,.28);
  --pf-bouton:linear-gradient(90deg,#8CC0F5 0%,#4A8BE0 45%,#2458B8 100%);--pf-halo:rgba(60,130,230,.7)}

/* G2. Fond : le ciel de « Qui joue ? », plus une nappe de la couleur de la famille derriere la phrase */
html body #s-classic-run[data-famille]{background-color:#020106;background-image:
  radial-gradient(80% 42% at 50% 46%, var(--pf-lueur), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.18), transparent 70%),
  linear-gradient(#000102,#01030F)}

/* G3. Plus de carte : ni cadre, ni matiere, ni eventail. Le paquet prend toute la scene. */
html body #s-classic-run[data-famille] .jn-paquet{aspect-ratio:auto!important;width:100%!important;height:100%!important;max-width:none!important;max-height:none!important}
html body #s-classic-run[data-famille] .jn-paquet::before,
html body #s-classic-run[data-famille] .jn-paquet::after{display:none}
html body #s-classic-run[data-famille] .jn-paquet>.gamecard{background:none!important;border:0!important;box-shadow:none!important;border-radius:0}
html body #s-classic-run[data-famille] .jn-paquet>.gamecard::before,
html body #s-classic-run[data-famille] .jn-paquet>.gamecard::after{display:none}

/* G4. Badge du type : il garde sa place et sa forme de pastille, en verre teinte de la famille */
html body #s-classic-run[data-famille] #cl-tag{background:color-mix(in srgb,var(--pf) 22%,rgba(10,11,39,.6));color:var(--c-texte);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),inset 0 0 0 1px color-mix(in srgb,var(--pf) 55%,transparent),0 0 18px -4px var(--pf-halo)}

/* G5. La phrase en blanc, le chiffre et l'etoile dans le ton clair de la famille */
html body #s-classic-run[data-famille] #cl-text{color:var(--c-texte)}
html body #s-classic-run[data-famille] #cl-quand{color:var(--c-texte-2)}
html body #s-classic-run[data-famille] #cl-trait svg{color:var(--pf-clair);fill:var(--pf-clair)}
html body #s-classic-run[data-famille] #cl-valeur b{color:var(--pf-clair)}
html body #s-classic-run[data-famille] #cl-valeur span{color:var(--c-texte-2)}

/* G6. Commandes du haut : le carre creme de l'accueil (menu et passer) */
html body #s-classic-run[data-famille] #menu-btn,
html body #s-classic-run[data-famille] #c-passer{background:none!important;color:var(--c-texte)!important;border:0!important;
  box-shadow:none!important}   /* [25/09, Romain] glyphe seul, creme */
html body #s-classic-run[data-famille] #menu-btn svg,html body #s-classic-run[data-famille] #c-passer svg{stroke:#EFE9DF}
html body #s-classic-run[data-famille] .jn-titre{color:var(--c-texte)}
html body #s-classic-run[data-famille] #g-prog{background:var(--pf-clair)}

/* G7. « Suivant » : la recette du bouton « Lancer une Soirée », dans le degrade de la famille */
html body #s-classic-run[data-famille] #cl-next{background:var(--pf-bouton)!important;color:var(--c-texte)!important;font-weight:600;border:0!important;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px var(--pf-halo)!important}

/* G8. Les autres boutons de la carte (Action / Verite, Voir la reponse, Je me degonfle, options) :
   verre sombre bordé de la famille, pour ne pas concurrencer « Suivant » */
html body #s-classic-run[data-famille] .jn-branche,
html body #s-classic-run[data-famille] #c-reveal:not(.shown),
html body #s-classic-run[data-famille] #cl-bu{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;
  border:1.5px solid color-mix(in srgb,var(--pf) 70%,transparent)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 16px -6px var(--pf-halo)!important}
html body #s-classic-run[data-famille] #c-reveal.shown{color:var(--pf-clair)!important}
/* G9. Deux objets que la regle du cadre (« ce que la carte ne porte pas », 08/08) masquait a tort
   des que tous les types sont passes par lui :
   - la reponse du Quiz (« Voir la réponse ») : sans elle le Quiz n'a plus de reponse ;
   - le « Juge final » (Romain, 23/09), ajoute APRES cette regle et donc jamais vu a l'ecran.
   « À toi, X » reste masque : un narrateur lit la carte, le prenom est deja dans la phrase. */
html body #s-classic-run[data-famille] #c-reveal:not([style*="none"]){display:inline-flex!important;align-self:center}
html body #s-classic-run[data-famille] .g-turn:has(.juge){display:flex!important;justify-content:center}
html body #s-classic-run[data-famille] .g-turn .juge{max-width:none;overflow:visible;background:none;border:0;box-shadow:none;padding:0;
  color:var(--c-texte-2);font-size:var(--t-2);font-weight:500}
html body #s-classic-run[data-famille] .g-turn .juge b{color:var(--pf-clair);font-weight:700}
/* G10. Le Juge final ne pousse pas le badge (la disposition validee ne bouge pas d'une carte a
   l'autre) : il se pose sous le chiffre, au pied de la carte, et son prenom n'est jamais coupe. */
html body #s-classic-run[data-famille] .jn-paquet>.gamecard{position:relative}
/* [25/09, Romain] remplace : il se pose sous la question (voir G12), plus au pied de la carte */
html body #s-classic-run[data-famille] .g-turn .juge b{max-width:none;overflow:visible;text-overflow:clip;white-space:nowrap;display:inline}
/* G11. Quiz (Romain, 25/09) : « Voir la réponse » juste sous la question. La phrase cesse de
   remplir la bande du milieu, et le groupe question + reponse s'y centre a sa place. */
html body #s-classic-run[data-carte="quiz"] #cl-text{flex:0 0 auto!important;margin-top:auto!important}
html body #s-classic-run[data-carte="quiz"] #c-reveal:not([style*="none"]){margin-top:var(--e-4)!important;margin-bottom:auto!important}
/* G12. Juge final (Romain, 25/09) : juste sous la question, au-dessus des gorgées, comme la
   reponse du Quiz. La question cesse de remplir la bande du milieu, le groupe s'y centre. */
html body #s-classic-run[data-carte="balance"] #cl-text:has(+ .g-turn .juge){flex:0 0 auto!important;margin-top:auto!important}
html body #s-classic-run[data-carte="preferes"] #cl-choix:has(+ .g-turn .juge){flex:0 0 auto!important;margin-top:auto!important}
html body #s-classic-run[data-famille] .g-turn:has(.juge){position:static;margin:var(--e-4) 0 auto!important}
/* G13. Chrono des defis en temps limite (Romain, 25/09) : un rond de verre sous la phrase, l'anneau
   dans le ton clair de la famille se vide pendant le decompte. On appuie sur le rond, pas de bouton. */
html body #s-classic-run[data-famille] #cl-text:has(+ #c-chrono:not([style*="none"])){flex:0 0 auto!important;margin-top:auto!important}
html body #s-classic-run .jn-chrono{position:relative;width:96px;height:96px;flex:0 0 auto;align-self:center;margin:var(--e-4) 0 auto!important;padding:0;border:0;
  border-radius:50%;background:rgba(10,11,39,.62);color:var(--c-texte);cursor:pointer;font-family:inherit;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 24px -8px var(--pf-halo,rgba(90,60,255,.6))}
html body #s-classic-run .jn-chrono[style*="none"]{display:none!important}
html body #s-classic-run .jn-chrono svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
html body #s-classic-run .jn-chrono circle{fill:none;stroke-width:5}
html body #s-classic-run .jn-chrono .ch-fond{stroke:rgba(255,255,255,.10)}
html body #s-classic-run .jn-chrono .ch-arc{stroke:var(--pf-clair,#C4B5FD);stroke-linecap:round}
html body #s-classic-run .jn-chrono b{position:relative;font-size:var(--t-5);font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
html body #s-classic-run .jn-chrono .ch-s{position:relative;font-size:var(--t-2);font-weight:600;color:var(--c-texte-3);margin-left:1px}
html body #s-classic-run .jn-chrono.fini{box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 0 0 3px var(--pf-clair,#C4B5FD),0 0 30px -4px var(--pf-halo,rgba(90,60,255,.8))}
html body #s-classic-run .jn-chrono.fini b{color:var(--pf-clair,#C4B5FD)}
/* CLASSIQUES-PLEINE:FIN */

/* MODES-VERRE:DEBUT — Les classiques et Mini-jeux dans la langue de l'app (Romain, 25/09). Le vocabulaire
   deja valide en Soiree, dans la couleur du mode : rose (#E81F82) pour les Classiques, or (#D4A304) pour
   les Mini-jeux. Les objets des mini-jeux gardent la couleur de chaque jeu, seul l'habillage change. */
/* M1. Fond : le ciel de nuit, avec une nappe de la couleur de l'ecran */
html body :is(#s-clhub,#s-clreg,#s-clavances,#s-mjhub,#s-mreg,#s-mavances,#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix){background-color:#020106;background-image:
  radial-gradient(80% 40% at 50% 46%, color-mix(in srgb,var(--accent) 14%,transparent), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.18), transparent 70%),
  linear-gradient(#000102,#01030F)}
/* M2. Commandes : le carre creme (retour, menu, « ? ») */
html body :is(#s-clhub,#s-clreg,#s-mjhub,#s-mreg,#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .iconbtn{background:#EFE9DF!important;color:#170B20!important;border:0!important;
  border-radius:var(--r-1);box-shadow:0 0 0 1px rgba(255,255,255,.35) inset!important}
html body :is(#s-clreg,#s-mreg,#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .topbar b{color:var(--c-texte);font-size:var(--t-4);font-weight:600;letter-spacing:-.015em}
/* M3. Selecteurs des fiches : le rail de verre de la fiche Soiree, le choix actif au degrade du mode */
html body :is(#s-clreg,#s-mreg) .sreg-seg{background:rgba(10,11,39,.72);border:1px solid var(--filet-verre-leger);border-radius:var(--r-2);padding:var(--e-1);gap:var(--e-1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10)}
html body :is(#s-clreg,#s-mreg) .sreg-seg button{color:var(--c-texte-2);border-radius:var(--r-1)}
html body #s-clreg .sreg-seg button[aria-pressed="true"]{background:linear-gradient(90deg,#F786C3 0%,#E81F82 55%,#B61E61 100%)!important;color:var(--c-texte)!important;font-weight:600;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.6),inset 0 0 10px rgba(255,255,255,.12),0 4px 12px -4px rgba(232,31,130,.7)}
html body #s-mreg .sreg-seg button[aria-pressed="true"]{background:linear-gradient(90deg,#F5C04A 0%,#D4A304 55%,#9F7403 100%)!important;color:var(--c-texte)!important;font-weight:600;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.6),inset 0 0 10px rgba(255,255,255,.12),0 4px 12px -4px rgba(212,163,4,.7)}
html body :is(#s-clreg,#s-mreg) .sreg-seg button[aria-pressed="true"] svg{stroke:#fff}
html body :is(#s-clreg,#s-mreg) .sreg-dit{color:var(--c-texte-3)}
html body :is(#s-clreg,#s-mreg) .sreg-dit b{color:var(--c-texte);font-weight:600}
/* M4. « Réglages avancés » et les sections des avances : la ligne de verre, tuile creme */
html body :is(#s-clreg,#s-mreg) .sreg-avance,html body :is(#s-clavances,#s-mavances) .sav-sec{border:1px solid transparent;
  background-image:linear-gradient(180deg,rgba(120,90,255,.16),rgba(40,30,120,.10)),linear-gradient(180deg,rgba(255,255,255,.30),rgba(170,150,255,.10));
  background-origin:border-box;background-clip:padding-box,border-box;box-shadow:inset 0 0 0 999px rgba(6,6,24,.55)}
html body :is(#s-clreg,#s-mreg) .sreg-avance{border-radius:var(--r-3)}
html body :is(#s-clreg,#s-mreg) .sreg-pastille{background:#EFE9DF!important;box-shadow:0 0 0 1px rgba(255,255,255,.35) inset}
html body :is(#s-clreg,#s-mreg) .sreg-pastille svg{stroke:#170B20;color:#170B20}
html body :is(#s-clavances,#s-mavances) .sav-titre{color:var(--c-texte)}
html body :is(#s-clavances,#s-mavances) .sav-dit,html body :is(#s-clavances,#s-mavances) .sav-nom{color:var(--c-texte-3)}
/* M5. Bouton principal : la recette de « Lancer une Soirée » dans le degrade du mode ; secondaire en verre */
html body :is(#s-clreg,#s-clavances) :is(.sreg-go,#clreg-go,.btn.sreg-go){background:linear-gradient(90deg,#F786C3 0%,#E81F82 45%,#B61E61 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0!important;border-radius:var(--r-4);box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(232,31,130,.7)!important}
html body :is(#s-mreg,#s-mavances) .sreg-go{background:linear-gradient(90deg,#F5C04A 0%,#D4A304 45%,#9F7403 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0!important;border-radius:var(--r-4);box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(212,163,4,.7)!important}
html body :is(#s-clavances,#s-mavances) .sav-annuler{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;border:1px solid var(--filet-verre)!important;border-radius:var(--r-4)}
html body :is(#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .btn:not(.sec):not(.ghost){background:linear-gradient(90deg,var(--accent2) 0%,var(--accent) 55%,color-mix(in srgb,var(--accent) 70%,#1a0a40) 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0!important;border-radius:var(--r-4);box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px color-mix(in srgb,var(--accent) 80%,transparent)!important}
html body :is(#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .btn.sec{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;border:1px solid var(--filet-verre)!important;border-radius:var(--r-4)}
html body :is(#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .dim{color:var(--c-texte-2)}
/* M6. « À qui le tour » (mode Mini-jeux) : la carte en verre sombre, filet clair */
html body #s-turn .turn-card,html body #s-turn .tc{background:rgba(10,11,39,.62)!important;border:1px solid var(--filet-verre)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)!important}
/* M7. Les lanceurs : titre blanc, tuiles du catalogue en verre borde de la couleur du mode */
html body :is(#s-clhub,#s-mjhub) .mjh-titre h1{color:var(--c-texte)}
html body :is(#s-clhub,#s-mjhub) .mjh-chapo,html body :is(#s-clhub,#s-mjhub) .mjh-sep{color:var(--c-texte-2)}
html body :is(#s-clhub,#s-mjhub) .arcade-list .jeu{background:rgba(10,11,39,.62)!important;
  border:1px solid color-mix(in srgb,var(--accent) 45%,transparent)!important;box-shadow:inset 0 1px 0 rgba(255,255,255,.12)!important}
/* MODES-VERRE:FIN */

/* [25/09, Romain] le bouton Reglages de l'accueil : plus de carre ni de contour, seule la roue crantee,
   en creme, sans fond. La zone de toucher garde ses 78 px de toile (36 px a l'ecran, 44 avec la marge). */
#mv-canvas .mv-reglages{background:none!important;box-shadow:none!important;border:0!important}
#mv-canvas .mv-reglages svg{width:54px;height:49px}   /* [27/09, Romain] entre l'ancienne (62 x 56) et la reduite (46 x 42) */
#mv-canvas .mv-reglages svg path,#mv-canvas .mv-reglages svg circle{stroke:#EFE9DF}
#mv-canvas .mv-reglages svg{filter:drop-shadow(0 0 6px rgba(239,233,223,.25))}

/* GLYPHES-SEULS (Romain, 25/09 : « fais la meme chose ici ») : comme la roue de l'accueil, les tuiles
   d'icone des lignes et les commandes du haut perdent leur carre creme. Il ne reste que le glyphe, en
   creme, sans fond ni contour. Les zones de toucher (36 a 44 px) ne changent pas. */
html body #m-menu .mn-ico,
html body #m-settings .set-tu,html body #m-settings .set-tu.violet,html body #m-settings .set-tu.ardoise,
html body :is(#s-sreg,#s-clreg,#s-mreg) .sreg-pastille{background:none!important;box-shadow:none!important;border:0!important}
html body #m-menu .mn-ico svg,html body #m-settings .set-gl,
html body :is(#s-sreg,#s-clreg,#s-mreg) .sreg-pastille svg{stroke:#EFE9DF!important;color:var(--c-texte)!important;width:24px;height:24px}
html body #m-settings .set-aa{color:var(--c-texte)!important;font-size:var(--t-2)}
html body #menu-btn,html body #c-passer,html body .mini-passer,html body .jr-retour,
html body :is(#s-joueurs,#s-sreg,#s-clreg,#s-mreg,#s-clhub,#s-mjhub,#s-defi,#s-bomb,#s-finger,#s-turn,#s-circle,#s-wheel,#s-reflex,#s-tap,#s-timing,#s-roulette,#s-casino,#s-blind,#s-target,#s-cashout,#s-math,#s-intrus,#s-gonogo,#s-dix) .iconbtn{
  background:none!important;box-shadow:none!important;border:0!important;color:var(--c-texte)!important}
html body #menu-btn svg,html body #c-passer svg,html body .mini-passer svg{stroke:#EFE9DF!important;color:var(--c-texte);width:22px;height:22px}
html body .jr-retour,html body :is(#s-sreg,#s-clreg,#s-mreg,#s-clhub,#s-mjhub,#s-defi) .topbar .iconbtn,html body :is(#s-clhub,#s-mjhub) .mjh-top .iconbtn{font-size:var(--t-5)!important;font-weight:400!important;line-height:1}
/* la regle de la carte pleine (G6, id + attribut) l'emportait : l'identifiant est double pour passer devant */
html body #menu-btn#menu-btn,html body #c-passer#c-passer,html body .mini-passer.mini-passer.mini-passer{
  background:none!important;box-shadow:none!important;border:0!important;color:var(--c-texte)!important}
html body #menu-btn#menu-btn svg,html body #c-passer#c-passer svg{stroke:#EFE9DF!important}

/* LANCEURS-VERRE (Romain, 25/09 : « la bannière en haut n'est pas belle », icônes du catalogue) :
   la carte « Série aléatoire » et les tuiles des jeux prennent la matiere des cartes de mode de
   l'accueil. Degrade sombre du mode, bord lumineux en degrade, tuile d'icone pleine au degrade vif
   avec glyphe blanc, filigrane en blanc tres leger. Or pour Mini-jeux, rose pour Les classiques. */
html body #s-mjhub .mjh-alea{border:2px solid transparent!important;box-shadow:0 10px 30px -12px rgba(240,154,12,.45)!important;
  background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)) padding-box,
             linear-gradient(160deg,#AC680D 0%,#97600A 25%,#7F4A06 45%,#643903 100%) padding-box,
             linear-gradient(150deg,#fff740 0%,#f4b22c 38%,#ffae08 100%) border-box!important}
html body #s-clhub .clh-alea{border:2px solid transparent!important;box-shadow:0 10px 30px -12px rgba(250,37,141,.45)!important;
  background:linear-gradient(90deg,rgba(255,255,255,.06),rgba(0,0,0,0) 40%,rgba(0,0,0,.10)) padding-box,
             linear-gradient(160deg,#CE1170 0%,#A00D57 25%,#8A0A4C 45%,#640336 100%) padding-box,
             linear-gradient(150deg,#ffa1d3 0%,#fa258d 33%,#f8007c 100%) border-box!important}
html body #s-mjhub .mjh-alea .mjh-mi{background:linear-gradient(180deg,#F49E15,#B56F0B)!important;box-shadow:var(--o-1)}
html body #s-clhub .clh-alea .mjh-mi{background:linear-gradient(180deg,#FA2380,#C20E5D)!important;box-shadow:var(--o-1)}
html body :is(#s-mjhub,#s-clhub) .mjh-carte .mjh-mi svg{stroke:#fff!important}
html body :is(#s-mjhub,#s-clhub) .mjh-carte .mjh-fil{stroke:rgba(255,255,255,.10)!important}
html body :is(#s-mjhub,#s-clhub) .mjh-carte p{color:rgba(255,255,255,.82)}
html body :is(#s-mjhub,#s-clhub) .mjh-carte .mjh-ch{stroke:#EFE9DF!important}
/* [25/09, Romain] les tuiles des jeux gardent leur fond sombre (M7) : seule la banniere change */

/* PURPLE (Romain, 25/09) : table de nuit, carte creme au centre, pile bien visible, cinq annonces. */
html body #s-purple{background-color:#020106;background-image:
  radial-gradient(80% 40% at 50% 38%, rgba(236,72,153,.16), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-purple .topbar b{color:var(--c-texte);font-size:var(--t-4);font-weight:600}
html body #s-purple .topbar .iconbtn{background:none!important;border:0!important;box-shadow:none!important;color:var(--c-texte)!important;font-size:var(--t-5)}
.pu-table{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--e-3);min-height:0}
.pu-cartes{position:relative;width:200px;height:240px}
.pu-carte{transition:transform .35s cubic-bezier(.2,.8,.2,1);position:absolute;left:44px;top:26px;width:140px;height:200px;transform:translate(var(--dx,0),var(--dy,0)) rotate(var(--r,0deg));border-radius:var(--r-2);background:#EFE9DF;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.6),0 14px 30px rgba(0,0,0,.55);display:grid;place-items:center}
.pu-carte.rouge{color:#D23A4B}.pu-carte.noire{color:#170B20}
.pu-carte b{font-size:4.2rem;line-height:1}
.pu-carte i{position:absolute;left:10px;top:8px;font-style:normal;font-weight:800;font-size:var(--t-3);line-height:1.05;text-align:center}
.pu-carte i.bas{left:auto;top:auto;right:10px;bottom:8px;transform:rotate(180deg)}
.pu-carte.retourne{animation:puRetourne .42s cubic-bezier(.2,.8,.2,1) backwards}
@keyframes puRetourne{0%{transform:translate(var(--dx,0),calc(var(--dy,0px) - 40px)) rotate(var(--r,0deg)) rotateY(90deg) scale(.92)}100%{transform:translate(var(--dx,0),var(--dy,0)) rotate(var(--r,0deg)) rotateY(0) scale(1)}}
/* les cartes du dessous : un peu dans l'ombre des suivantes */
.pu-carte:not(:last-child){box-shadow:inset 0 0 0 1px rgba(255,255,255,.6),0 6px 14px rgba(0,0,0,.45);filter:brightness(.93)}
/* ramassage du tas apres une perte : [17/10, Romain] toutes les cartes partent, la table se vide */
.pu-cartes.ramasse .pu-carte{transition:transform .3s ease-in,opacity .3s;transform:translate(0,0) rotate(0) scale(.96);opacity:0}
.pu-pile{display:flex;align-items:baseline;gap:var(--e-2);color:var(--c-texte-2)}
.pu-pile b{font-size:var(--t-6);font-weight:800;color:#F9A8D4;font-variant-numeric:tabular-nums}
.pu-dit{min-height:2.8em;margin:0 18px;text-align:center;color:var(--c-texte);font-size:var(--t-3);font-weight:600;line-height:1.35}
/* [17/10, Romain] le message en deux parties : le prenom en haut, la consigne dessous */
.pu-dit b{display:block;font-size:var(--t-4);font-weight:800;color:var(--c-texte);margin-bottom:var(--e-1)}
.pu-dit span{display:block;color:var(--c-texte-2);font-weight:600}
.pu-annonces{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);padding:0 var(--e-3) var(--e-2)}
.pu-b{min-height:54px;border-radius:var(--r-3);font-family:inherit;font-size:var(--t-3);font-weight:700;cursor:pointer;color:var(--c-texte);border:0;
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.45),inset 0 0 12px rgba(255,255,255,.10)}
.pu-rouge{background:linear-gradient(180deg,#E0485A,#A51E30)}
.pu-noir{background:linear-gradient(180deg,#18181B,#000000);box-shadow:inset 0 1.5px 0 rgba(255,255,255,.35),0 0 0 1px rgba(255,255,255,.22)}   /* [25/09, Romain] un vrai noir, plus de gris */
.pu-plus,.pu-moins{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte)}
.pu-purple{grid-column:1/-1;background:linear-gradient(90deg,#E0485A 0%,#8A3BFF 50%,#050507 100%);letter-spacing:.06em}
.pu-b:active{transform:scale(.98)}
/* [16/10, Romain] premier coup rouge ou noir : Moins, Plus et Purple attendent la premiere carte */
.pu-b:disabled{opacity:.32;cursor:default}
.pu-b:disabled:active{transform:none}
.pu-passer{margin:0 18px calc(14px + env(safe-area-inset-bottom,0px));width:calc(100% - 36px)}
html body #s-purple .pu-passer{background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;border:1px solid var(--filet-verre)!important;border-radius:var(--r-4)}

/* COURSE (Romain, 25/09 : « le PMU ») : meme table de nuit que Purple ; une piste de huit places
   (depart, six obstacles, arrivee), un couloir par As. La place se lit dans --p, de 0 a 7. */
html body #s-course{background-color:#020106;background-image:
  radial-gradient(80% 40% at 50% 34%, rgba(236,72,153,.14), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-course .topbar b{color:var(--c-texte);font-size:var(--t-4);font-weight:600}
html body #s-course .topbar .iconbtn{background:none!important;border:0!important;box-shadow:none!important;color:var(--c-texte)!important;font-size:var(--t-5)}
.cda-paris,.cda-course{flex:1;display:flex;flex-direction:column;min-height:0;padding:0 var(--e-3) calc(var(--e-3) + env(safe-area-inset-bottom,0px))}
.cda-paris[hidden],.cda-course[hidden]{display:none}
.cda-titre{margin:var(--e-2) 0 2px;color:var(--c-texte);font-size:var(--t-3);font-weight:700}
.cda-aide{margin:0 0 var(--e-3);color:var(--c-texte-3);font-size:var(--t-2)}
.cda-liste{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--e-2)}
.cda-ligne{display:flex;flex-wrap:wrap;align-items:center;gap:var(--e-2) var(--e-2);padding:var(--e-2) var(--e-3) var(--e-2);border-radius:var(--r-2);background:rgba(10,11,39,.62);border:1px solid rgba(190,175,255,.18)}
.cda-nom{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--c-texte);font-weight:600}
.cda-coul{flex-basis:100%;display:grid;grid-template-columns:repeat(4,1fr);gap:var(--e-2)}
.cda-s{height:42px;border-radius:var(--r-1);border:0;background:#EFE9DF;font-size:var(--t-3);line-height:1;cursor:pointer;opacity:.38;font-family:inherit}
.cda-s.rouge{color:#D23A4B}.cda-s.noire{color:#170B20}
.cda-s.on{opacity:1;box-shadow:0 0 0 2px #F9A8D4,0 0 14px rgba(249,168,212,.45)}
.cda-mise{display:flex;align-items:center;gap:var(--e-1);color:#F9A8D4}
.cda-mise b{min-width:1.4em;text-align:center;font-size:var(--t-3);font-variant-numeric:tabular-nums}
.cda-m{width:30px;height:40px;border:0;background:none;color:var(--c-texte);font-size:var(--t-4);font-family:inherit;cursor:pointer}
.cda-go,.cda-suite{margin-top:var(--e-3);width:100%}
/* la piste */
.cda-piste{position:relative;margin-top:var(--e-2);display:flex;flex-direction:column;gap:var(--e-2)}
.cda-rang{position:relative;height:58px;border-radius:var(--r-1)}
.cda-couloir{background:rgba(10,11,39,.55);border:1px solid rgba(190,175,255,.14)}
.cda-place{position:absolute;top:50%;left:calc(4px + var(--p,0) * (100% - 48px) / 7);width:40px;transform:translateY(-50%);
  transition:left .42s cubic-bezier(.2,.8,.2,1)}
.cda-arrivee{position:absolute;top:64px;bottom:0;left:calc(100% - 50px);width:4px;border-radius:var(--r-1);
  background:repeating-linear-gradient(#EFE9DF 0 6px,#170B20 6px 12px);opacity:.8}
.cda-c{position:relative;width:40px;height:54px;border-radius:var(--r-1);background:#EFE9DF;display:grid;place-items:center;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.6),0 6px 14px rgba(0,0,0,.5)}
.cda-c.rouge{color:#D23A4B}.cda-c.noire{color:#170B20}
.cda-c b{font-size:var(--t-4);line-height:1;margin-top:var(--e-2)}
.cda-c i{position:absolute;left:5px;top:3px;font-style:normal;font-weight:800;font-size:var(--t-1)}
.cda-c.dos{background:linear-gradient(135deg,#8A3BFF,#3A1780);box-shadow:inset 0 0 0 3px #EFE9DF,0 6px 14px rgba(0,0,0,.5)}
.cda-cheval.gagne .cda-c{box-shadow:0 0 0 3px #F9A8D4,0 0 22px rgba(249,168,212,.7)}
.cda-c.retourne{animation:coRetourne .4s cubic-bezier(.2,.8,.2,1) backwards}
@keyframes coRetourne{0%{transform:rotateY(90deg) scale(.9)}100%{transform:rotateY(0) scale(1)}}
/* la carte tiree et ce qui se passe */
.cda-bas{display:flex;align-items:center;gap:var(--e-3);margin-top:var(--e-3);min-height:48px}
.cda-bas .cda-c{width:80px;height:112px;border-radius:var(--r-1);flex:none}
.cda-bas .cda-c b{font-size:var(--t-7);margin-top:var(--e-3)}
.cda-bas .cda-c i{font-size:var(--t-3);left:8px;top:6px}
.cda-dit{margin:0;color:var(--c-texte);font-size:var(--t-3);font-weight:600;line-height:1.35}
.cda-fin{flex:1;min-height:0;overflow-y:auto;margin-top:var(--e-2)}
.cda-fin{display:flex;flex-direction:column;gap:var(--e-2)}
.cda-personne{margin:0 0 2px;color:var(--c-texte-3);font-size:var(--t-2)}
.cda-res{display:flex;align-items:center;gap:var(--e-2);min-height:44px;padding:var(--e-1) var(--e-3) var(--e-1) var(--e-2);border-radius:var(--r-2);
  background:rgba(10,11,39,.62);border:1px solid rgba(190,175,255,.16)}
.cda-res.cda-ok{background:linear-gradient(90deg,rgba(236,72,153,.26),rgba(138,59,255,.16));border-color:rgba(249,168,212,.6);
  box-shadow:0 0 16px rgba(236,72,153,.22)}
.cda-mini{flex:none;width:28px;height:36px;border-radius:var(--r-1);background:#EFE9DF;display:grid;place-items:center;font-size:var(--t-3);line-height:1}
.cda-mini.rouge{color:#D23A4B}.cda-mini.noire{color:#170B20}
.cda-qui{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--c-texte);font-size:var(--t-2);font-weight:600}
.cda-quoi{display:flex;align-items:baseline;gap:var(--e-2);color:var(--c-texte-3);font-size:var(--t-2)}
.cda-quoi strong{font-size:var(--t-3);font-weight:800;color:var(--c-texte);font-variant-numeric:tabular-nums}
.cda-ok .cda-quoi{color:#F9A8D4}.cda-ok .cda-quoi strong{color:#F9A8D4}
@media (prefers-reduced-motion:reduce){.cda-place{transition:none}.cda-c.retourne{animation:none}}
/* a l'arrivee (Romain, 25/09 : un recap lisible pour tout le monde) : piste resserree */
.cda-course.fini .cda-rang{height:40px}
.cda-course.fini .cda-piste .cda-c{transform:scale(.7)}
.cda-course.fini .cda-arrivee{top:46px}
.cda-course.fini .cda-bas{margin-top:var(--e-2);min-height:0}

/* ROUE (Romain, 26/09 : aux couleurs de l'app) : halo violet de marque, pointeur creme. */
html body #s-wheel #wheel{filter:drop-shadow(0 12px 26px rgba(0,0,0,.6)) drop-shadow(0 0 22px rgba(139,92,246,.30))}
html body #s-wheel .wpointer{border-top-color:#EFE9DF;filter:drop-shadow(0 3px 4px rgba(0,0,0,.6)) drop-shadow(0 0 8px rgba(167,139,250,.5))}

/* [26/09, Romain, capture sur Mac] LE MENU SUIT LA COLONNE DE L'APP. Il etait fixe au coin de la
   FENETRE : sur un iPhone c'est le meme coin, sur un ordinateur il flottait tout a gauche, loin du
   jeu, et on croyait qu'il n'y avait aucune sortie. La colonne fait 560 px au plus, centree. Meme
   chose pour le chrono des mini-jeux, a droite. Hors du cadre des cartes (jn-carte), qui le range
   dans sa barre. */
html body:not(.jn-carte) #menu-btn{left:max(12px, calc(50% - 268px))}
html body #mini-timer{right:max(12px, calc(50% - 268px))}

/* le « clac » : l'arme encaisse la cartouche */

/* ce qui reste a l'ecran : l'arme EST chargee, sans dire ou */

/* [27/09, Romain : « comment faire pour que l'app s'adapte a tous les telephones »] L'ETIQUETTE
   « Au tour de » est FIXE sous la barre du haut ; les ecrans de jeu la laissaient flotter par-dessus
   leur contenu, ce qui passait sur les grands ecrans et mordait sur les petits (iPhone 14 : consigne de
   la roue ; iPhone SE : roue du casino, categorie de la bombe). Quand elle est la, l'ecran lui reserve
   sa place (52 px) sous la barre ; les ressorts .grow absorbent la difference. Les cartes (Soiree,
   Classiques) affichent le tour DANS la carte et ne sont pas concernees. */
body.badge-on .screen.on:not(#s-game):not(#s-classic-run)>.topbar{margin-bottom:var(--e-7)}

/* [27/09] sur les ecrans courts (iPhone SE : 553 px utiles dans Safari), les deux roues suivent aussi la
   HAUTEUR : sinon le bouton sortait de l'ecran (La roue : 57 px, La roulette : 10 px). */
html body #s-wheel #wheel{width:min(80vw,344px,calc(100dvh - 315px));min-width:200px}
@media (max-height:600px){html body #s-casino .roul-wrap{zoom:.88}}

/* [27/09, Romain] jeux de precision : « Commencer » et « Stop » au MEME endroit, au milieu de l'ecran,
   juste sous l'element qu'on vise (barre, chrono, cadran, multiplicateur). Le bouton n'est plus pousse
   en bas : les deux ressorts entourent maintenant le groupe entier. */
html body :is(#s-timing,#s-dix,#s-blind,#s-cashout) .bottom.tm-proche{position:static;margin-top:var(--e-3);padding-top:var(--e-3);padding-bottom:0;background:none}   /* padding fixe : « cta-mid » ajoutait 8 px avant le lancement, le bouton bougeait */

/* [27/09] le chapo de Mini-jeux est retire : le titre reprend l'air qu'il laissait avant la carte */
html body :is(#s-mjhub,#s-clhub) .mjh-titre{margin-bottom:var(--e-4)}

/* [27/09] la roue de l'accueil rend 32 px a l'ecran : la zone touchable est etendue a 44 (plancher tactile) sans changer le dessin */
#mv-canvas .mv-reglages::after{content:"";position:absolute;inset:-18px}
/* [21/10, audit V2] le rond du compte (haut a droite) : meme extension de la zone touchable, au-dela de 44 px reels ;
   ma teinte de profil comme mon rond des Trinkeurs ; la silhouette quand l'initiale manque (hors connexion) */
#mv-canvas .mv-moi-haut::after{content:"";position:absolute;inset:-32px -32px -42px}
html.teinte #mv-canvas .mv-moi-haut{background:linear-gradient(180deg,var(--av-hi) 0%,var(--av-lo) 100%)}
#mv-canvas .mv-moi-haut svg{width:34px;height:34px;fill:none;stroke:currentColor;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
/* [02/11, Romain, sur capture de l'accueil : « en haut le rond utilisateur est trop gros »] 64 -> 50 (bagues 3 + 6 au lieu
   de 3,5 + 7) : 62 unites avec ses bagues, la boite de l'engrenage d'en face (61). Le centre ne bouge pas (856, 138),
   aligne sur l'engrenage ; la zone du toucher garde 44 px et plus (::after). */
#mv-canvas .mv-moi-haut{left:831px;top:113px;width:50px;height:50px;font-size:1.5rem;
  box-shadow:0 0 0 3px rgba(250,249,252,.95), 0 0 0 6px #8B5CF6}

/* LA CASE PIEGEE (Romain, 28/09) : remplace la roulette russe. Six cases en verre, deux colonnes.
   Vide = la case se creuse et s'eteint (elle reste lisible : on voit ce qui reste). Piegee = rouge plein,
   le rouge du jeu. L'etat ne repose pas sur la couleur seule : aria-label et verdict ecrit. */
html body #s-roulette .cp-grille{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--e-3);width:min(78vw,300px);margin:0 auto var(--e-3)}
html body #s-roulette .cp-case{aspect-ratio:1.25;border-radius:var(--r-3);border:1px solid rgba(255,255,255,.14);
  background:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.035));color:var(--c-texte);
  font-weight:700;font-size:var(--t-5);line-height:1;font-family:inherit;font-variant-numeric:tabular-nums;box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 8px 20px rgba(0,0,0,.35);
  transition:transform var(--m-court) var(--m-sortie),opacity var(--m-court) var(--m-sortie);cursor:pointer;-webkit-tap-highlight-color:transparent}
html body #s-roulette .cp-case:active,html body #s-roulette .cp-case.ouvre{transform:scale(.93)}
/* [28/09, Romain] une case sure passe en fond, en VERT PALE : on voit qu'elle etait sure (le vert = le succes) */
html body #s-roulette .cp-case.vide{background:rgba(74,222,128,.12);border-color:rgba(74,222,128,.32);color:rgba(187,247,208,.62);
  box-shadow:inset 0 3px 10px rgba(0,0,0,.45);cursor:default}
/* la piegee evitee, montree en fin de partie gagnee : contour rouge, eteinte */
html body #s-roulette .cp-case.revele{background:rgba(248,113,113,.08);border:1.5px dashed rgba(248,113,113,.7);color:#F87171;box-shadow:none}
html body #s-roulette .cp-case.piege{background:#F87171;border-color:#F87171;color:#2A0A0A;box-shadow:0 0 26px rgba(248,113,113,.55);
  animation:cpPiege var(--m-long) var(--m-sortie)}   /* [21/10, Romain, direction B, sans le tremblement] */
/* [21/10, Romain, direction B] une case sure se repose avec un petit rebond, son vert arrive en fondu */
html body #s-roulette .cp-case.vide{animation:cpSure var(--m-moyen) var(--m-ressort)}
@keyframes cpSure{from{transform:scale(.93);opacity:.5}}
html body #s-roulette .cp-case:disabled:not(.vide):not(.piege):not(.revele){opacity:.55}
html body #s-roulette .cp-case:focus-visible{outline:2px solid #A78BFA;outline-offset:3px}
@keyframes cpPiege{0%{transform:scale(.9)}40%{transform:scale(1.08)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){html body #s-roulette .cp-case{transition:none;animation:none!important}}
/* [28/09, Romain] en Soiree la grille suit la table (jusqu'a 14 cases) : trois colonnes au-dela de six */
/* flex centre plutot que grille : la derniere rangee incomplete (10, 11, 13, 14 cases) reste au milieu */
html body #s-roulette .cp-grille.large{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-2);width:min(86vw,330px)}
html body #s-roulette .cp-grille.large .cp-case{width:calc((100% - 20px) / 3)}
html body #s-roulette .cp-grille.large .cp-case{aspect-ratio:1.15;font-size:var(--t-4);border-radius:var(--r-2)}
/* le prenom de celle ou celui tombe sur la case piegee, sous le numero */
html body #s-roulette .cp-case.piege[data-qui]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}
html body #s-roulette .cp-case.piege[data-qui]::after{content:attr(data-qui);font-size:var(--t-1);font-weight:700;line-height:1.1;max-width:92%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* compteur des cases piegees restantes, sous le titre */
html body #s-roulette .cp-restant{margin-top:var(--e-2);font-size:var(--t-2);font-weight:600;color:rgba(255,255,255,.72);text-align:center}
html body #s-roulette .cp-restant b{color:#F87171;font-size:var(--t-3);font-variant-numeric:tabular-nums;margin-right:2px}
html body #s-roulette .cp-restant.zero b{color:rgba(255,255,255,.5)}
/* [28/09, Romain] plus d'explication sous les barres de reglage, sur toutes les fiches (Soiree,
   Classiques, Mini-jeux) : le choix se lit sur la barre. Les descriptions restent calculees (la fenetre
   « On y va ? » s'en sert), elles ne s'affichent plus sous les barres. */
html body .sreg-grp .sreg-dit{display:none!important}

/* SEQUENCE (Romain, 28/09) : quatre cases en verre qui s'allument en or, la couleur des Mini-jeux.
   La position et la note portent l'information, pas la couleur (les quatre couleurs de l'app sont
   celles des modes). Erreur : la case touchee en rouge, la case attendue cernee d'or. */
html body #s-seq .sq-grille{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--e-3);width:min(76vw,300px);margin:var(--e-3) auto var(--e-3)}
html body #s-seq .sq-case{aspect-ratio:1;border-radius:var(--r-3);border:1px solid rgba(255,255,255,.14);
  background:linear-gradient(180deg,rgba(255,255,255,.08),rgba(255,255,255,.03));color:var(--c-texte);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 8px 20px rgba(0,0,0,.35);transition:transform .1s ease,background .1s,box-shadow .1s;
  cursor:pointer;-webkit-tap-highlight-color:transparent;padding:0}
html body #s-seq .sq-case:disabled{cursor:default}
html body #s-seq .sq-case.lit{background:#FBBF24;border-color:#FCD34D;transform:scale(1.06);box-shadow:0 0 34px rgba(251,191,36,.75),0 0 10px rgba(251,191,36,.9)}
html body #s-seq .sq-case.bad{background:rgba(248,113,113,.85);border-color:#F87171}
html body #s-seq .sq-case.attendu{border:2px dashed #FBBF24;box-shadow:0 0 18px rgba(251,191,36,.45)}
html body #s-seq .sq-case:focus-visible{outline:2px solid #A78BFA;outline-offset:3px}
@media (prefers-reduced-motion:reduce){html body #s-seq .sq-case{transition:none}html body #s-seq .sq-case.lit{transform:none}}
html body #s-seq #sq-result{font-size:var(--t-4)}

/* COULEUR PIEGEE (Romain, 28/09) : le mot en grand, dans sa couleur d'encre ; des pastilles rondes et
   nettes, melangees a chaque question. Deux colonnes a 4 couleurs, trois au-dela. */
html body #s-stroop .cr-mot{font-size:var(--t-7);font-weight:900;letter-spacing:.04em;line-height:1.1;min-height:1.2em;margin:var(--e-2) 0 var(--e-3);text-align:center}
html body #s-stroop .cr-pastilles{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-3);width:min(80vw,320px);margin:var(--e-3) auto var(--e-3)}
html body #s-stroop .cr-pastille{width:calc((100% - 28px) / 3);aspect-ratio:1;border-radius:50%;border:3px solid rgba(255,255,255,.18);
  box-shadow:0 6px 16px rgba(0,0,0,.4);cursor:pointer;padding:0;-webkit-tap-highlight-color:transparent;transition:transform .1s,opacity .2s}
html body #s-stroop .cr-pastilles[data-n="4"] .cr-pastille{width:calc((100% - 14px) / 2 * .72)}
html body #s-stroop .cr-pastille:active{transform:scale(.92)}
html body #s-stroop .cr-pastille.good{border-color:#F7F5FA;box-shadow:0 0 0 4px rgba(247,245,250,.35),0 6px 16px rgba(0,0,0,.4)}
html body #s-stroop .cr-pastille.bad{opacity:.3}
html body #s-stroop .cr-pastille:focus-visible{outline:2px solid #A78BFA;outline-offset:3px}
html body #s-stroop #cr-result{font-size:var(--t-4)}

/* VRAI OU FAUX (Romain, 28/09) : l'affirmation en grand, deux gros boutons cote a cote. La bonne reponse
   se montre apres coup (contour clair), la mauvaise s'eteint. */
html body #s-vf .vf-num{font-size:var(--t-2);font-weight:700;color:rgba(255,255,255,.6);font-variant-numeric:tabular-nums;min-height:1.2em}
html body #s-vf .vf-texte{font-size:var(--t-4);font-weight:800;line-height:1.3;text-align:center;text-wrap:balance;min-height:3.9em;display:flex;align-items:center;justify-content:center;margin:var(--e-2) 0 var(--e-3);padding:0 var(--e-2)}
html body #s-vf .vf-reps{display:flex;gap:var(--e-3);width:100%;margin:var(--e-3) 0 var(--e-2)}
html body #s-vf .vf-reps[hidden]{display:none!important}
html body #s-vf .vf-rep{flex:1;min-height:64px;border-radius:var(--r-3);font:inherit;font-size:var(--t-3);font-weight:800;color:var(--c-texte);
  background:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.035));border:1px solid rgba(255,255,255,.16);cursor:pointer;-webkit-tap-highlight-color:transparent}
html body #s-vf .vf-rep:active{transform:scale(.97)}
/* [21/10, Romain, tri du rouge, teinte B] le bord en dégradé des cases de l'app : vert la bonne, rouge la mauvaise */
html body #s-vf .vf-rep.good{background:linear-gradient(160deg,#0f2a1b,#0a1a12) padding-box,linear-gradient(160deg,rgba(74,222,128,.85),rgba(74,222,128,.25) 45%,rgba(74,222,128,.6)) border-box;border:1.5px solid transparent;color:#BBF7D0}
html body #s-vf .vf-rep.bad{background:linear-gradient(160deg,#2a1216,#160a0d) padding-box,linear-gradient(160deg,rgba(248,113,113,.85),rgba(248,113,113,.25) 45%,rgba(248,113,113,.6)) border-box;border:1.5px solid transparent;color:#FECACA}
html body #s-vf .vf-rep:focus-visible{outline:2px solid #A78BFA;outline-offset:3px}
html body #s-vf #vf-result{font-size:var(--t-4)}
/* [28/09, Romain] le resultat de chaque reponse (Vrai ou faux, Couleur piegee) : vert ou rouge ET un mot */
html body .qz-fb{min-height:1.5em;font-size:var(--t-3);font-weight:800;text-align:center;margin-top:var(--e-1)}
html body .qz-fb.ok{color:#4ADE80}
html body .qz-fb.ko{color:#F87171}
/* [28/09, Romain] la pastille du verdict de Vrai ou faux descend : elle collait a la barre de temps */
html body #s-vf #vf-result{margin-top:var(--e-5)}
html body #s-vf #vf-result:not(:empty) ~ .grow{flex-grow:.6}

/* LE PALMIER (Romain, 28/09) : la table de nuit de Purple, une carte a la fois, sa regle dessous.
   En haut, les etats qui durent (maitre du freeze, couple de Cupidon). */
html body #s-palmier{background-color:#020106;background-image:
  radial-gradient(80% 40% at 50% 38%, rgba(236,72,153,.16), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-palmier .topbar b{color:var(--c-texte);font-size:var(--t-4);font-weight:600}
html body #s-palmier .topbar .iconbtn{background:none!important;border:0!important;box-shadow:none!important;color:var(--c-texte)!important;font-size:var(--t-5)}
.pm-etat{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-2);padding:0 var(--e-3);min-height:30px;margin-top:var(--e-6)}
.pm-puce{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);border-radius:999px;padding:var(--e-1) var(--e-3);font-size:var(--t-2);color:var(--c-texte-2)}
.pm-puce b{color:#F9A8D4;font-weight:700}
.pm-table{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--e-2);min-height:0;padding:0 var(--e-3)}
.pm-cartes{height:230px}
.pm-titre{margin:0;font-size:var(--t-4);font-weight:800;color:var(--c-texte);text-align:center}
.pm-dit{margin:0;min-height:2.8em;text-align:center;color:var(--c-texte);font-size:var(--t-3);font-weight:600;line-height:1.4;max-width:34ch}
.pm-reste{margin:var(--e-1) 0 0;font-size:var(--t-1);color:var(--c-texte-3)}
.pm-cupidon{display:flex;flex-direction:column;gap:var(--e-2);align-items:center;width:100%}
.pm-cupidon[hidden]{display:none}
.pm-noms{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--e-2)}
.pm-nom{border:1px solid var(--filet-verre);background:rgba(10,11,39,.62);color:var(--c-texte);border-radius:999px;padding:var(--e-2) var(--e-3);font:inherit;font-weight:600;min-height:40px;cursor:pointer}
.pm-nom[aria-pressed="true"]{background:#EC4899;border-color:#F9A8D4;color:#2A0A19}
.pm-bas{display:flex;flex-direction:column;gap:var(--e-2);padding:0 var(--e-3) calc(var(--e-3) + env(safe-area-inset-bottom,0px))}
.pm-fin{display:flex;flex-direction:column;gap:var(--e-2)}
.pm-fin[hidden]{display:none}
/* [28/09, Romain] la carte remonte pour laisser de l'air aux consignes ; les regles en liste */
.pm-table{justify-content:flex-start;padding-top:var(--e-2)}
.pm-cartes{height:214px;margin-bottom:var(--e-2)}
.pm-dit{min-height:0;max-width:36ch;width:100%}
.pm-liste{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--e-2);text-align:left}
.pm-liste li{position:relative;padding-left:var(--e-4);line-height:1.35}
.pm-liste li::before{content:"";position:absolute;left:4px;top:.55em;width:7px;height:7px;border-radius:50%;background:#F9A8D4}
.pm-reste{font-size:var(--t-2);font-weight:700;color:var(--c-texte-3);font-variant-numeric:tabular-nums;letter-spacing:.02em}
/* [28/09, Romain] le compteur « 12 / 52 » en haut a droite, dans la barre du titre */
html body #s-palmier .topbar{position:relative}
html body #s-palmier .pm-compte{position:absolute;right:18px;top:50%;transform:translateY(-50%);font-size:var(--t-2);font-weight:700;color:var(--c-texte-2);font-variant-numeric:tabular-nums;white-space:nowrap}
/* [28/09, Romain] la carte tombe droite, au centre ; les consignes respirent (« trop rapproche, ca fait mal aux yeux ») */
html body #s-palmier .pm-cartes{width:140px;height:214px}
html body #s-palmier .pm-cartes .pu-carte{left:0;top:6px;--r:0deg;--dx:0px;--dy:0px}
html body #s-palmier .pm-dit{max-width:none;width:100%;margin-top:var(--e-2)}
html body #s-palmier .pm-liste{gap:var(--e-3);padding:0 var(--e-2)}
html body #s-palmier .pm-liste li{line-height:1.55;font-weight:500;font-size:var(--t-3);padding-left:var(--e-4)}
html body #s-palmier .pm-liste li::before{top:.62em}
/* le dos du paquet, au lancement : une carte face cachee aux couleurs de Trinke, qui respire doucement */
html body #s-palmier .pm-dos{position:absolute;left:0;top:6px;width:140px;height:200px;border-radius:var(--r-2);cursor:pointer;padding:0;
  border:3px solid #EFE9DF;background:
  repeating-linear-gradient(45deg,rgba(255,255,255,.07) 0 6px,transparent 6px 14px),
  linear-gradient(160deg,#EC4899,#8B5CF6);
  box-shadow:0 14px 30px rgba(0,0,0,.55),0 0 34px rgba(236,72,153,.35);display:grid;place-items:center;
  animation:pmRespire 2.4s ease-in-out infinite}
html body #s-palmier .pm-dos span{width:54px;height:54px;border-radius:50%;background:rgba(2,1,6,.55);border:2px solid rgba(239,233,223,.8);
  color:var(--c-texte);font-weight:900;font-size:var(--t-4);display:grid;place-items:center}
@keyframes pmRespire{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@media (prefers-reduced-motion:reduce){html body #s-palmier .pm-dos{animation:none}}
/* [28/09, Romain] ecran de depart « Règles » et bouton (?) ; le compteur se range a gauche du (?) */
html body #s-palmier .pm-aide{position:absolute;right:12px;top:50%;transform:translateY(-50%);width:36px;height:36px;border-radius:50%!important;
  border:1px solid var(--filet-verre)!important;background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;font-size:var(--t-3)!important;font-weight:800}
html body #s-palmier .pm-compte{right:60px}
html body #s-palmier.pm-accueil .pm-table{justify-content:center}
html body #s-palmier.pm-accueil .pm-cartes{display:none}
html body #s-palmier.pm-accueil .pm-titre{font-size:var(--t-5);letter-spacing:.02em;margin-bottom:var(--e-2)}
html body #s-palmier.pm-accueil .pm-liste{align-items:center;text-align:center;gap:var(--e-3)}
html body #s-palmier.pm-accueil .pm-liste li{padding-left:0;font-size:var(--t-3)}
html body #s-palmier.pm-accueil .pm-liste li::before{display:none}
.pm-aide-l{display:block;margin-bottom:var(--e-2);line-height:1.45}
.pm-aide-l b{color:#F9A8D4}
html body #s-palmier .topbar .pm-aide{font-size:var(--t-3)!important;border:1px solid var(--filet-verre)!important;background:rgba(10,11,39,.62)!important}
/* [28/09, Romain] « Règles : » en haut de l'ecran, pas au milieu */
html body #s-palmier.pm-accueil .pm-table{justify-content:flex-start;padding-top:var(--e-5)}
/* [28/09, Romain] l'icone du palmier au-dessus de « Règles : », sur l'ecran de depart seulement */
.pm-ico{display:none}
html body #s-palmier.pm-accueil .pm-ico{display:block;width:84px;height:84px;color:#F9A8D4;filter:drop-shadow(0 0 18px rgba(236,72,153,.45));margin-bottom:var(--e-1)}
/* [28/09, Romain : « le rose en fond fait mal aux yeux, ca empeche de lire les consignes »] plus de halo rose
   derriere le texte : fond de nuit, seul le voile violet en haut a droite reste */
html body #s-palmier{background-image:
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.36), transparent 70%),
  linear-gradient(#000102,#01030F)!important}
html body #s-palmier.pm-accueil .pm-ico{filter:none;object-fit:contain}   /* [02/10, Romain] palmier illustré (palmier.webp) à la place du pictogramme */
/* [28/09, Romain] le nom de la carte AU-DESSUS de la carte ; les consignes centrees, sans puces */
html body #s-palmier .pm-ico{order:-2}
html body #s-palmier .pm-titre{order:-1;margin-bottom:var(--e-1)}
html body #s-palmier .pm-liste{align-items:center;text-align:center}
html body #s-palmier .pm-liste li{padding-left:0}
html body #s-palmier .pm-liste li::before{display:none}
/* [28/09, Romain : « enleve l'effet de rebond, il est insupportable »] le bandeau « Au tour de » ne pulse plus, nulle part */
html body #turn-badge{animation:none!important;transform:translateX(-50%)!important}
/* [28/09, Romain] le rappel freeze / Cupidon vit en tete du « ? » */
.pm-aide-memo{display:flex;flex-direction:column;gap:var(--e-1);margin:0 0 var(--e-3);padding:var(--e-2) var(--e-3);border-radius:var(--r-1);background:rgba(236,72,153,.1);border:1px solid rgba(249,168,212,.3);color:var(--c-texte)}
.pm-aide-memo b{color:#F9A8D4}
/* [28/09, Romain : « c'etait mieux avant, juste l'encadre "Au tour de" etait trop pres du titre du jeu »]
   On garde la mise en page d'avant (carte pleine taille, consignes aerees) ; seul le bandeau descend,
   pour se detacher du titre. La table defile si une regle est trop longue : rien ne passe sous le bouton. */
body:has(#s-palmier.on) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 80px)}
html body #s-palmier .pm-etat{display:none}
html body #s-palmier .pm-table{padding-top:var(--e-5)}   /* le nom de la carte ~22 px sous le bandeau descendu, sans vide mort */
html body #s-palmier .pm-table{overflow-y:auto;overscroll-behavior:contain}
/* [10/10, audit] dans une table qui defile, les enfants ne doivent plus retrecir : sur petit ecran (375 x 553)
   la carte se tassait par-dessus la 1re consigne, et les prenoms de Cupidon passaient sous le bouton */
html body #s-palmier .pm-table>*{flex-shrink:0}
/* la plus longue regle (le freeze, 4 consignes) doit tenir au-dessus du bouton a 390 x 714 : interligne et ecart
   un peu resserres, taille du texte inchangee */
html body #s-palmier:not(.pm-accueil) .pm-liste{gap:var(--e-2)}
html body #s-palmier:not(.pm-accueil) .pm-liste li{line-height:1.42}
html body #s-palmier .pm-table{padding-bottom:var(--e-3)}
/* [28/09, Romain : « un petit trait pour mieux separer les elements »] ecran de depart : un court trait
   rose entre chaque consigne ; la derniere (« Amusez-vous bien ! ») en rose, comme une conclusion */
html body #s-palmier.pm-accueil .pm-liste{gap:0}
html body #s-palmier.pm-accueil .pm-liste li{padding:var(--e-3) 0}
html body #s-palmier.pm-accueil .pm-liste li + li::before{display:block;content:"";position:static;width:40px;height:2px;border-radius:var(--r-1);
  background:rgba(249,168,212,.45);margin:0 auto var(--e-3)}
/* [02/10, Romain] « Amusez-vous bien ! » retiré : la dernière ligne reste en blanc, comme les autres (l’accent rose servait à cette phrase) */
/* [28/09, Romain] « Au tour de » descend encore (80 -> 100) ; la table suit de 14 px seulement */
body:has(#s-palmier.on) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 100px)}
html body #s-palmier:not(.pm-accueil) .pm-table{padding-top:var(--e-6)}
/* [28/09, Romain] « Au tour de » descend encore (100 -> 116) et un GRAND ecart le separe du nom de la carte.
   Sur les ecrans courts (Safari d'iPhone, <= 760 px de haut) la carte passe a 80 % pour que la plus longue
   regle tienne au-dessus du bouton ; au-dela, pleine taille. */
body:has(#s-palmier.on) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 116px)}
html body #s-palmier:not(.pm-accueil) .pm-table{padding-top:104px}
@media (max-height:760px){ html body #s-palmier .pm-cartes{zoom:.8} }
/* ajuste a la mesure : la derniere consigne du freeze touchait le bouton (630 / 631) */
html body #s-palmier:not(.pm-accueil) .pm-table{padding-top:94px}
@media (max-height:760px){ html body #s-palmier .pm-cartes{zoom:.76} }
/* 4 consignes longues (le pouce) : l'ecart sous le bandeau passe de 46 a 32 px pour tout garder au-dessus du bouton */
html body #s-palmier:not(.pm-accueil) .pm-table{padding-top:80px}
/* [10/10, audit] la table qui defile commence SOUS le bandeau du prenom (bas a 165 px) : en defilant vers
   Cupidon, la regle passait sous le bandeau. Meme position du titre (198 px), le decalage passe en marge. */
html body #s-palmier:not(.pm-accueil) .pm-table{margin-top:var(--e-7);padding-top:var(--e-4)}
html body #s-palmier #pm-tirer:disabled{opacity:.4;filter:grayscale(.4);cursor:default}
/* [28/09, Romain] au Palmier, le bandeau porte le prenom seul, sans « Au tour de » */
body:has(#s-palmier.on) #turn-badge::before{content:none}

/* [28/09, Romain] Classiques : jeux longs en haut, jeux courts en dessous */
#s-clhub #cl-longs{flex:0 0 auto}
#s-clhub #cl-longs .cat-fam{margin:0 2px var(--e-3)}
#s-clhub .cat-courts{flex:0 0 auto;margin:var(--e-5) 2px var(--e-3)}
html body #s-palmier .pm-ico{stroke-width:1.2}   /* [28/09] le palmier en grand : trait plus fin, les noix restent lisibles */
#s-clhub #cl-longs.arcade-list{padding-bottom:0}   /* [28/09] meme case que les jeux courts, sans le vide du bas de liste */
html body #s-clhub #clh-alea-s{max-width:none;white-space:nowrap}   /* [28/09, Romain] le sous-titre de la serie tient sur une ligne */
#s-clhub #cl-longs .cat-fam{margin-top:var(--e-5)}   /* [28/09] remplace le vide que portait « Ou choisis ton jeu » */
#s-mjhub #arcade-grid{margin-top:var(--e-5)}   /* [28/09] remplace le vide que portait « Ou choisis ton jeu » */
/* [28/09, Romain] Classiques et Mini-jeux : le titre monte sur la ligne du bouton retour, centre */
html body :is(#s-clhub,#s-mjhub) .mjh-top{position:relative;z-index:2}
html body :is(#s-clhub,#s-mjhub) .mjh-titre{margin-top:-58px;min-height:44px;display:flex;align-items:center;justify-content:center;pointer-events:none}

/* [29/09, Romain] CASH OUT : la mise en gorgees, reglee avant de lancer la courbe */
#s-cashout .co-mise{display:flex;align-items:center;justify-content:center;gap:var(--e-3);margin:var(--e-2) 0 var(--e-2)}
#s-cashout .co-mise b{min-width:7.5em;text-align:center;font-size:var(--t-3);color:var(--c-texte);font-variant-numeric:tabular-nums}
#s-cashout .co-pas{width:44px;height:44px;border-radius:50%;border:1px solid rgba(52,211,153,.55);background:rgba(10,11,39,.62);color:var(--c-texte);font:inherit;font-size:var(--t-4);line-height:1;display:grid;place-items:center;cursor:pointer}
#s-cashout .co-pas:disabled{opacity:.35;cursor:default}
#s-cashout .co-mise.verrou .co-pas{visibility:hidden}   /* la mise reste lisible pendant le vol, sans pouvoir la changer */
/* [29/09, Romain] CASH OUT organise comme le Palmier : bandeau, titre, objet central, lignes, bouton en bas */
html body #s-cashout .co-table{justify-content:flex-start;padding-top:var(--e-5);gap:var(--e-3)}
html body #s-cashout .co-ico{width:84px;height:84px;color:#34d399;margin-bottom:var(--e-1);display:none}
html body #s-cashout.co-avant .co-ico{display:block}
html body #s-cashout.co-avant #co-mult{display:none}
html body #s-cashout .co-titre{font-size:var(--t-4)}
html body #s-cashout.co-avant .co-titre{font-size:var(--t-5);letter-spacing:.02em}
html body #s-cashout #co-mult{margin:var(--e-3) 0 var(--e-2);line-height:1}
html body #s-cashout .co-mise{margin:0}
html body #s-cashout .co-gain{margin:0;min-height:1.4em;font-size:var(--t-3);font-weight:700;color:#34d399;text-align:center;font-variant-numeric:tabular-nums}
html body #s-cashout.co-avant .co-gain{display:none}
html body #s-cashout .co-dit{max-width:none;width:100%;margin-top:var(--e-2)}
html body #s-cashout .co-dit .pm-liste{gap:var(--e-3);padding:0 var(--e-2);align-items:center;text-align:center}
html body #s-cashout .co-dit .pm-liste li{padding-left:0;line-height:1.55;font-weight:500;font-size:var(--t-3)}
html body #s-cashout .co-dit .pm-liste li::before{display:none}
html body #s-cashout.co-fin .co-mise .co-pas{visibility:hidden}
.sreg-sp.sp-0{flex-grow:.4;min-height:24px}   /* [29/09, Romain] fiches Mini-jeux et Classiques : la premiere barre etait collee au titre */
/* [29/09, Romain] Crash out : une courbe qui decolle, le multiplicateur pose dessus en plus petit */
html body #s-cashout .co-scene{position:relative;width:100%;height:230px;margin:var(--e-2) 0 var(--e-1)}
html body #s-cashout.co-avant .co-scene{display:none}
html body #s-cashout #co-courbe{position:absolute;inset:0;width:100%;height:100%;display:block}
html body #s-cashout .co-scene #co-mult{position:absolute;left:14px;top:6px;margin:0;font-size:var(--t-6);text-shadow:0 0 18px rgba(52,211,153,.35);animation:none}
html body #s-cashout .co-scene #co-mult.shake{animation:coshake .42s}
/* [29/09, Romain] Crash out comme le Palmier : prenom seul dans le bandeau, bandeau descendu, table dessous */
body:has(#s-cashout.on) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 116px)}
body:has(#s-cashout.on) #turn-badge::before{content:none}
html body #s-cashout .co-table{padding-top:80px;padding-bottom:var(--e-3);overflow-y:auto;overscroll-behavior:contain}
@media (max-height:760px){ html body #s-cashout .co-scene{height:170px} html body #s-cashout.co-avant .co-ico{width:64px;height:64px} }   /* Safari d'iPhone : tout tient au-dessus du bouton */
/* [29/09, Romain] Crash out : on arrive sur la courbe prete a partir. Plus d'icone ni de titre ni de regles a
   l'ecran (elles sont dans le « ? ») : bandeau, courbe qui prend la place, mise, gain, bouton. */
html body #s-cashout .co-ico, html body #s-cashout .co-titre{display:none!important}
html body #s-cashout.co-avant .co-scene{display:block}
html body #s-cashout.co-avant #co-mult{display:block}
html body #s-cashout .co-scene{flex:1 1 auto;height:auto;min-height:190px;max-height:380px;margin:var(--e-1) 0 var(--e-2)}
html body #s-cashout .co-mise b{min-width:9em}
html body #s-cashout.co-avant .co-gain{display:block;visibility:hidden}
@media (max-height:760px){ html body #s-cashout .co-scene{min-height:150px} }
/* [29/09, Romain] Crash out aux couleurs des Mini-jeux : l'or. Le vert ne reste que pour le resultat encaisse. */
html body #s-cashout .co-scene #co-mult{font-weight:800;font-size:var(--t-6);left:18px;top:12px;letter-spacing:.01em;text-shadow:0 0 18px rgba(251,191,36,.35)}
html body #s-cashout .co-gain{color:#FCD34D}
html body #s-cashout .co-pas{border-color:rgba(251,191,36,.55)}
/* [29/09, Romain] Crash out organise comme Stake : le multiplicateur au centre du graphique, les graduations
   sur les bords, l'historique en pastilles, et un panneau Mise / Gain sous le jeu (le verdict y vit aussi). */
html body #s-cashout .co-centre{position:absolute;left:0;right:0;top:34%;transform:translateY(-50%);display:flex;flex-direction:column;align-items:center;gap:2px;pointer-events:none}
html body #s-cashout .co-scene .co-centre #co-mult{position:static;font-size:var(--t-7);font-weight:800;letter-spacing:.01em;line-height:1;text-shadow:0 0 22px rgba(251,191,36,.35)}
html body #s-cashout .co-sous{min-height:1.2em;font-size:var(--t-1);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--c-texte-2)}
html body #s-cashout.co-fin .co-sous{color:inherit}
html body #s-cashout .co-histo{position:absolute;right:10px;top:8px;display:flex;gap:var(--e-2);flex-wrap:wrap;justify-content:flex-end;max-width:70%}
html body #s-cashout .co-pastille{font-size:var(--t-1);font-weight:700;font-variant-numeric:tabular-nums;padding:var(--e-1) var(--e-2);border-radius:999px;background:rgba(251,191,36,.14);color:#FCD34D;border:1px solid rgba(251,191,36,.3)}
html body #s-cashout .co-pastille.bas{background:rgba(248,113,113,.12);color:#FCA5A5;border-color:rgba(248,113,113,.3)}
html body #s-cashout .co-panneau{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin-top:2px}
html body #s-cashout .co-champ{background:rgba(10,11,39,.62);border:1px solid rgba(251,191,36,.28);border-radius:var(--r-3);padding:var(--e-2) var(--e-3);display:flex;flex-direction:column;align-items:center;gap:var(--e-2);min-width:0;box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-cashout .co-lab{font-size:var(--t-1);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--c-texte-3);white-space:nowrap}
html body #s-cashout .co-champ .co-mise{gap:var(--e-2);margin:0}
html body #s-cashout .co-champ .co-mise b{min-width:0;font-size:var(--t-3)}
html body #s-cashout .co-champ .co-pas{width:36px;height:36px;font-size:var(--t-3);position:relative}
html body #s-cashout .co-champ .co-pas::after{content:"";position:absolute;inset:-4px}
html body #s-cashout .co-champ .co-gain{display:flex;align-items:center;justify-content:center;min-height:36px;visibility:visible;font-size:var(--t-3);color:#FCD34D;margin:0}
html body #s-cashout .co-gain.gagne{color:#34D399}
html body #s-cashout .co-gain.perdu{color:#F87171}
html body #s-cashout #co-inst{display:none!important}   /* le verdict s'affiche dans le panneau ; miniVerdict y compte toujours les gorgees */
html body #s-cashout.co-vol .co-champ:first-child{opacity:.75}
html body #s-cashout .co-centre{top:22%}
html body #s-cashout .co-histo{left:46px;right:auto;top:2px;justify-content:flex-start;max-width:calc(100% - 56px)}
html body #s-cashout .co-champ .co-mise b{white-space:nowrap;font-size:var(--t-2)}
html body #s-cashout .co-champ .co-pas{width:34px;height:34px;flex:0 0 auto}
/* [29/09, Romain] historique lisible : titre + trois dernieres manches (prenom, multiplicateur), vert / rouge */
html body #s-cashout .co-histo{left:46px;right:10px;top:0;max-width:none;display:flex;flex-direction:column;align-items:flex-start;gap:var(--e-1)}
html body #s-cashout .co-histo[hidden]{display:none}
html body #s-cashout .co-histo-t{font-size:var(--t-1);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--c-texte-3)}
html body #s-cashout .co-histo-l{display:flex;gap:var(--e-2);flex-wrap:nowrap;max-width:100%;overflow:hidden}
html body #s-cashout .co-pastille{display:inline-flex;align-items:baseline;gap:var(--e-2);min-width:0;padding:var(--e-1) var(--e-2);border-radius:999px;font-size:var(--t-1)}
html body #s-cashout .co-pastille em{font-style:normal;font-weight:600;color:var(--c-texte);max-width:5.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-cashout .co-pastille b{font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
html body #s-cashout .co-pastille.gagne{background:rgba(52,211,153,.12);border:1px solid rgba(52,211,153,.35)}
html body #s-cashout .co-pastille.gagne b{color:#34D399}
html body #s-cashout .co-pastille.perdu{background:rgba(248,113,113,.12);border:1px solid rgba(248,113,113,.35)}
html body #s-cashout .co-pastille.perdu b{color:#F87171}
/* l'historique sort de la scene : une ligne a part au-dessus de la courbe, alignee sur elle */
html body #s-cashout .co-histo{position:static;width:100%;padding-left:var(--e-5);margin:-6px 0 -4px}
/* [29/09, Romain] aucun mouvement dans l'apercu du « ? » : l'illustration reste, figee */
.rules-preview,.rules-preview *,.rules-preview::before,.rules-preview::after{animation:none!important;transition:none!important}
.rules-preview .rp-draw-svg circle{stroke-dasharray:none!important;stroke-dashoffset:0!important}   /* le cercle se montre trace, puisqu'il ne se dessine plus */
.rp-mult{color:#FCD34D!important;text-shadow:0 0 18px rgba(251,191,36,.5)!important}   /* [29/09] Crash out est dore */
.rules-preview.rp-climb::before{background:radial-gradient(circle at 50% 45%,#FBBF24,transparent 62%)!important}
/* [29/09, Romain] TOUS LES MINI-JEUX AUX COULEURS DE L'APP. L'or des Mini-jeux remplace la couleur propre a
   chaque jeu (data-accent, index.html) ; le bandeau porte le prenom seul et descend, comme au Palmier et a
   Crash out. Les couleurs qui ont un SENS dans un jeu (feu rouge/vert, Vert ou rouge, Couleur piegee,
   rouge/noir de la roulette) ne dependent pas de l'accent et restent. */
body:has(:is(#s-circle.on,#s-timing.on,#s-dix.on,#s-blind.on,#s-tap.on,#s-math.on,#s-intrus.on,#s-seq.on,#s-stroop.on,#s-vf.on,#s-wheel.on,#s-roulette.on,#s-casino.on,#s-bomb.on,#s-finger.on)) #turn-badge::before{content:none}
/* ---- couleurs propres a chaque jeu, ramenees a l'or (29/09) ---- */
#pc-canvas{background:radial-gradient(circle at center,rgba(251,191,36,.06),transparent 68%),var(--card)!important;border-color:rgba(251,191,36,.3)!important}
.tmtarget{background:linear-gradient(180deg,rgba(251,191,36,.42),rgba(251,191,36,.16))!important;border-left-color:#FBBF24!important;border-right-color:#FBBF24!important;box-shadow:0 0 22px rgba(251,191,36,.45)!important}
#dx-clock{color:var(--c-texte)!important;text-shadow:0 0 28px rgba(255,255,255,.22)!important;font-family:inherit!important;font-weight:800!important;letter-spacing:.02em!important}
.bl-clock{filter:drop-shadow(0 6px 16px rgba(251,191,36,.3))!important}
#finger-zone::before{border-color:rgba(251,191,36,.45)!important}
#finger-zone::after{background:radial-gradient(circle,rgba(251,191,36,.14),transparent 70%)!important}
html body :is(#s-seq,#s-stroop,#s-vf) .btn:not(.sec):not(.ghost){background:linear-gradient(90deg,var(--accent2) 0%,var(--accent) 55%,color-mix(in srgb,var(--accent) 70%,#1a0a40) 100%)!important;
  color:var(--c-texte)!important;font-weight:600;border:0!important;border-radius:var(--r-4)}
/* [29/09, Romain] compte a rebours sur un voile : le jeu ne se voit plus derriere le chiffre */
.countfx.actif{opacity:1;background:rgba(2,1,6,.95);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:opacity .15s}
.countfx .cn{display:inline-block;opacity:0;color:var(--c-texte);text-shadow:0 0 36px rgba(255,255,255,.28);font-weight:800;font-variant-numeric:tabular-nums}
.countfx .cn.tick{animation:cnt .55s ease-out}
@media (prefers-reduced-motion:reduce){.countfx .cn.tick{animation:none;opacity:1}}
/* [29/09, Romain] LA BOMBE illustree (image ChatGPT detouree, outils/bombe-illustree) a la place de la boule
   orange. Le battement (.on) et son acceleration restent ; l'etincelle de l'image scintille par-dessus. */
#bomb-pulse{width:176px!important;height:176px!important;border-radius:0!important;background:url(/img/bombe/bombe.webp) center/contain no-repeat!important;box-shadow:none!important;filter:drop-shadow(0 10px 28px rgba(0,0,0,.55)) drop-shadow(0 0 22px rgba(251,191,36,.18))}
#bomb-pulse::before{display:none!important}
#bomb-pulse::after{top:15%!important;right:9%!important;left:auto!important;width:26px!important;height:26px!important;margin:-13px -13px 0 0!important;background:radial-gradient(circle,rgba(255,255,255,.95),rgba(252,211,77,.55) 40%,transparent 70%)!important;box-shadow:none!important;mix-blend-mode:screen}
/* la meche allumee (canvas) deborde de la bombe pour que les etincelles aient de la place ; la bombe gonfle
   et se retracte pendant la partie (le JS accelere la cadence a l'approche de l'explosion) */
#bomb-pulse{overflow:visible}
#bomb-pulse canvas.bomb-meche{position:absolute;left:-70px;top:-70px;width:calc(100% + 140px);height:calc(100% + 140px);pointer-events:none}
#bomb-pulse.on{animation:bombeSouffle .5s ease-in-out infinite!important}
@keyframes bombeSouffle{0%,100%{transform:scale(1)}50%{transform:scale(1.1,1.12)}}
@media (prefers-reduced-motion:reduce){#bomb-pulse.on{animation:none!important}}
/* [29/09, Romain] les confettis s'eteignent avant le bas de l'ecran : ils ne recouvrent plus le resultat ni le bouton */
@keyframes confall{0%{transform:translateY(0) rotate(0);opacity:1}55%{opacity:1}100%{transform:translateY(68vh) translateX(calc(var(--dx)*90px)) rotate(520deg);opacity:0}}
/* [29/09] Reflexe : la consigne de depart a la taille des autres consignes ; « Attends le vert » et « MAINTENANT » restent gros */
#reflex-inst.consigne{font-size:var(--t-3)!important;font-weight:600!important;color:var(--c-texte);max-width:30ch;margin-left:auto;margin-right:auto;line-height:1.45}
/* [29/09] Doigt du destin : un grand doigt dore et discret au centre du cadre, efface des que les doigts se posent */
#finger-zone .finger-ico{position:absolute;left:50%;top:50%;width:120px;height:120px;margin:-60px 0 0 -60px;color:#FBBF24;opacity:.5;filter:drop-shadow(0 0 18px rgba(251,191,36,.35));pointer-events:none;transition:opacity .2s}
body:has(.fdot) #finger-zone .finger-ico{opacity:0}
#bomb-pulse::after{display:none!important}   /* [29/09] l'etincelle est entierement dessinee et animee par le canvas de la meche */
/* [29/09, Romain] REFLEXE facon F1 : une rangee de trois feux, rouges un par un, puis tous verts d'un coup.
   Au repos le fond est sombre ; il rougit pendant l'allumage et verdit au depart. */
#reflex-zone{background:radial-gradient(circle at 50% 40%,#1c1822,#0c0a10)!important}
#reflex-zone.arming{background:radial-gradient(circle at 50% 40%,#3a1212,#1c0808)!important}
#reflex-zone.go{background:radial-gradient(circle at 50% 40%,#0f5a28,#07331a)!important}
#reflex-feu.f1{width:auto;flex-direction:row;gap:clamp(8px,2.6vw,14px);padding:16px clamp(14px,4vw,20px);border-radius:var(--r-3)}
/* [21/10, Romain, direction B] lampes en relief : éteintes en verre sombre, allumées avec un reflet */
#reflex-feu .f1-l{width:clamp(40px,12vw,54px);height:clamp(40px,12vw,54px);border-radius:50%;background:radial-gradient(circle at 35% 30%,#2a2638,#121019 70%);border:1px solid rgba(255,255,255,.08);box-shadow:inset 0 3px 8px rgba(0,0,0,.6);transition:background .06s,box-shadow .06s}
#reflex-feu .f1-l.rouge{background:radial-gradient(circle at 35% 30%,#FCA5A5,#EF4444 70%);border-color:transparent;box-shadow:0 0 24px rgba(239,68,68,.55),inset 0 -5px 10px rgba(0,0,0,.25),inset 0 2px 3px rgba(255,255,255,.35)}
#reflex-zone.go #reflex-feu .f1-l{background:radial-gradient(circle at 35% 30%,#BBF7D0,#22C55E 70%);border-color:transparent;box-shadow:0 0 24px rgba(34,197,94,.55),inset 0 -5px 10px rgba(0,0,0,.25),inset 0 2px 3px rgba(255,255,255,.35)}
/* [29/09, Romain] plus de voile noir avant le jeu : le compte a rebours s'affiche directement par-dessus */
.countfx.actif{background:transparent!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
/* [29/09, Romain] le bandeau du prenom descend dans les mini-jeux, comme au Palmier et a Crash out.
   Sauf La cible, Reflexe et Vert ou rouge : leur zone de jeu commence sous le titre, le bandeau y cacherait ce qu'on touche. */
body:has(:is(#s-circle.on,#s-timing.on,#s-dix.on,#s-blind.on,#s-tap.on,#s-math.on,#s-intrus.on,#s-seq.on,#s-stroop.on,#s-vf.on,#s-wheel.on,#s-roulette.on,#s-casino.on,#s-bomb.on,#s-target.on)) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 116px)}
html body #s-roulette #cp-restant{margin-top:var(--e-7)}
@media (max-height:760px){ html body #s-seq #sq-inst{margin-top:var(--e-4)} html body #s-wheel #w-inst{margin-top:var(--e-6)} }   /* petit ecran : sous le bandeau descendu */
/* [29/09, Romain] REGLAGES : l'option choisie en CONTOUR (fond sombre, bord et texte a la couleur de la
   section), pour que le seul bloc plein de l'ecran soit le bouton d'action. Avant : les deux en aplat,
   « trop monotone ». Or pour les Mini-jeux, rose pour les Classiques. */
html body #s-mreg .sreg-seg button[aria-pressed="true"]{background:rgba(252,211,77,.08)!important;color:#FCD34D!important;box-shadow:inset 0 0 0 1.125px #E0AE1C!important}
html body #s-mreg .sreg-seg button[aria-pressed="true"] svg{stroke:#FCD34D!important}
html body #s-clreg .sreg-seg button[aria-pressed="true"]{background:rgba(247,134,195,.08)!important;color:#F9A8D4!important;box-shadow:inset 0 0 0 1.125px #E81F82!important}
html body #s-clreg .sreg-seg button[aria-pressed="true"] svg{stroke:#F9A8D4!important}
/* [29/09, Romain] meme regle pour « Lancer une soirée » : l'option choisie en contour violet, le bouton
   « Lancer » reste seul en aplat. */
/* [29/09, Romain] le contour reprend le DEGRADE du bouton « Valider » (violet vers bleu) : fond sombre
   legerement teinte en padding-box, degrade en border-box sous un bord transparent. Le bord transparent
   est pose sur TOUS les boutons du rail, sinon l'option choisie grandirait de 3 px. */
html body #s-sreg .sreg-seg button{border:1.125px solid transparent}   /* [29/09, Romain] contour 25 % plus fin (1,5 vers 1,125 px), les trois fiches */
html body #s-sreg .sreg-seg button[aria-pressed="true"]{color:#D3C2FF!important;
  background:linear-gradient(90deg,rgba(164,104,238,.16),rgba(53,40,251,.16)) padding-box,linear-gradient(#0B0A1E,#0B0A1E) padding-box,
    linear-gradient(90deg,#A468EE 0%,#7B3EFC 30%,#5933FC 65%,#3528FB 100%) border-box!important;
  box-shadow:none!important}   /* [29/09, Romain] plus de halo : du flou inutile */
html body #s-sreg .sreg-seg button[aria-pressed="true"] svg{stroke:#C9B2FF!important}
/* [29/09, Romain] COURSE DES AS plus vivante : les gorgees de la carte s'affichent en ligne sous le commentaire */
/* [29/09, Romain] pas de marque sur le cheval de tete (filet rose retire) */
.cda-dit .cda-gorg{display:block;margin-top:var(--e-1);color:#F9A8D4;font-size:var(--t-2);font-weight:600}
/* [29/09, Romain] STOP PARFAIT : un coeur (tiers central de la zone, or plus franc) ; consigne et verdict
   empiles dans une meme case de hauteur fixe, la barre et le bouton ne bougent plus au Stop */
html body #s-timing .tm-coeur{position:absolute;top:0;bottom:0;left:33.333%;width:33.334%;background:rgba(252,211,77,.55);border-left:1px solid #FDE68A;border-right:1px solid #FDE68A}
html body #s-timing .tm-txt{display:grid;width:100%;min-height:124px;align-items:start}
html body #s-timing .tm-txt>*{grid-area:1/1}
/* [29/09, Romain] le « ? » de la course des As reprend celui du Palmier */
html body #s-course .topbar,html body #s-purple .topbar{position:relative}
html body #s-course .pm-aide,html body #s-purple .pm-aide{position:absolute;right:12px;top:50%;transform:translateY(-50%);width:36px;height:36px;border-radius:50%!important;
  border:1px solid var(--filet-verre)!important;background:rgba(10,11,39,.62)!important;color:var(--c-texte)!important;font-size:var(--t-3)!important;font-weight:800}
/* [29/09, audit] La case piegee : « Toutes les cases sures ! Toute la table… » etait coupe par des points de
   suspension sur petit ecran ; le resultat passe a la ligne au lieu d'etre tronque */
html body #rl-result{white-space:normal;overflow:visible;text-overflow:clip}
/* [29/09, audit] Cercle parfait sur petit ecran (hauteur 714) : le canevas de 354 px poussait « Continuer »
   sous le bas de l'ecran ; il plafonne a 300 px, centre */
@media (max-height:760px){ html body #pc-canvas{width:min(100%,300px);margin-left:auto;margin-right:auto} }
/* [29/09, audit] Trouve l'intrus sur petit ecran : la grille remontait de 60 px au verdict et passait sous le
   bandeau du prenom ; elle est plus compacte, le verdict tient dessous sans rien pousser */
@media (max-height:760px){ html body #s-intrus #in-grid{flex:0 0 auto;max-width:330px;margin:0 auto;padding-top:var(--e-2);padding-bottom:var(--e-2)} html body #s-intrus #in-result{min-height:112px} }
/* [29/09, audit] « Fin du palmier » restait affiche a la fin : .btn{display:inline-flex} ecrasait l'attribut hidden */
html body .btn[hidden]{display:none!important}
html body #s-game[data-carte="preferes"].pref-vide .cardtext{display:block}   /* [29/09, audit] « Carte à écrire. » visible */

/* [30/09, audit] LE QUIZ N'EXISTE PAS ENCORE, ET SON BOUTON NE LE CACHE PLUS. Il disait « Jouer »
   avec une fleche, pleine couleur comme les deux autres, puis ne menait qu'a « Bientôt disponible » :
   un bouton qui promet une destination et n'en a pas. Il dit ce qu'il est, sans fleche, en creux
   (contour seul, fond retire). Le toucher garde le toast, qui confirme. */
#mv-canvas .mv-m3 .mv-jouer.mv-bientot{background:transparent;box-shadow:0 0 0 1.5px rgba(255,255,255,.35);color:rgba(255,255,255,.78)}

/* VERROU-VERRE (Romain, 07/10) : LES ECRANS SANS COMPTE (Amis, Discussions, Classement, Compte)
   PRENNENT LES BOUTONS DE LA DA. Leurs trois issues dataient du dossier du 08/08 (rectangle
   arrondi 16, lavande a encre sombre, seconde issue en gris plat) : c'est l'ancienne matiere, qui
   ne ressemble plus a rien dans l'app depuis le menu verre. Recette = celle deja posee le 25/09
   sur la porte d'age (AGE-VERRE) et l'intro (INTRO-VERRE), donc trois ecrans de premiere visite
   avec les memes trois objets :
   - issue pleine = le bouton « Lancer une Soirée » (degrade violet -> bleu, texte blanc 600,
     filets de lumiere interieurs, lueur violette courte) ;
   - seconde issue = verre teinte nuit, filet lavande ;
   - troisieme issue (invite) = verre plus sourd, filet blanc faible, encre --dim : elle se passe
     du compte, elle ne porte pas sa couleur (regle du 08/08 conservee).
   Geometrie, ecarts (12 dans le couple, 24 avant l'invite), glyphes et cascade d'entree
   inchanges ; seuls la matiere et le rayon changent (26 : a 50 de haut c'est la gelule de la DA).
   La regle « encre sombre pour le contraste » du 08/08 tombe : le degrade de la DA est assez
   fonce pour du blanc (le meme couple est deja en production sur la porte d'age). */
html body .vq-issue{border-radius:var(--r-4)}
html body .vq-issue.vq-creer{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  color:var(--c-texte);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body .vq-issue.vq-creer:active{background:linear-gradient(90deg,#945BDC 0%,#6D34E8 20%,#4E2BE6 38%,#3B26E4 56%,#2E23E4 76%,#2021E6 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.5),inset 0 0 14px rgba(255,255,255,.10),0 4px 12px -8px rgba(90,60,255,.5)}
html body .vq-issue.vq-deja{background:rgba(10,11,39,.62);color:var(--c-texte);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.12)}
html body .vq-issue.vq-deja:active{background:rgba(22,24,64,.74);color:var(--c-texte)}
html body .vq-issue.vq-invite{background:rgba(10,11,39,.40);color:var(--dim);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
html body .vq-issue.vq-invite:active{background:rgba(22,24,64,.56);color:var(--c-texte-2)}
/* VERROU-VERRE:FIN */

/* VERROU-NUIT (Romain, 07/10, « corrige le décalage des pages ») : LE RESTE DES ECRANS SANS COMPTE
   REJOINT LA DA, apres leurs boutons (VERROU-VERRE). Deux ecarts restaient :
   1. le fond etait le noir plat du socle, quand l'accueil, la porte d'age et l'intro vivent sous
      le ciel de nuit bleu-violet. Le ciel est CELUI DE LA PORTE D'AGE (AGE-VERRE), repris tel quel :
      memes six lueurs aux memes places, les ecrans etant tous pleine fenetre, le ciel tombe au meme
      endroit d'un ecran a l'autre. Les encres de l'accroche et des etiquettes montent d'un cran
      (#CFC9DA, l'encre des textes secondaires de l'intro) : sur un fond qui n'est plus noir, le gris
      --mut du socle s'eteignait.
   2. les quatre tuiles de territoires de l'onglet Compte etaient des aplats pastel a glyphe sombre,
      d'une autre matiere que les tuiles des cartes de mode de l'accueil (degrade vertical sature,
      glyphe blanc, ombre portee courte). Elles prennent cette recette ; le sarcelle, absent des
      modes, est derive sur le meme modele. Tailles, rayon, grille, textes inchanges. */
html body #s-classement.vq-on,
html body #s-amis.vq-on,
html body #s-multi.vq-on,
html body #s-compte.vq-on,
html body #s-boutique{background-color:#020106;background-image:
  radial-gradient(70% 34% at 50% 30%, rgba(110,60,255,.30), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F);background-attachment:local}
html body .vq-on .vq-accroche p{color:var(--c-texte-2)}
html body .vq-on .vq-ouvre b{color:var(--c-texte-2)}
html body .vq-on .vq-legal{color:var(--c-texte-3)}
html body .vq-on .vq-tu{box-shadow:var(--o-1),inset 0 1px 0 rgba(255,255,255,.20)}
html body .vq-on .vq-tu svg{stroke:#fff}
html body .vq-on .vq-tu-fuchsia{background:linear-gradient(180deg,#FA2380,#C20E5D)}
html body .vq-on .vq-tu-or{background:linear-gradient(180deg,#F49E15,#B56F0B)}
html body .vq-on .vq-tu-bleu{background:linear-gradient(180deg,#1E9CFE,#0266E7)}
html body .vq-on .vq-tu-sarcelle{background:linear-gradient(180deg,#2FD2C0,#0E9C8C)}
/* VERROU-NUIT:FIN */

/* VERROU-VIOLET (Romain, 07/10, capture des quatre tuiles : « ces couleurs n'ont rien à faire là »).
   SUR L'ONGLET COMPTE, LE VIOLET EST LA SEULE COULEUR. Les teintes sarcelle, bleu, fuchsia, or sont
   celles des modes de jeu de l'accueil et de rien d'autre ; posees sur les territoires du compte
   (VERROU-NUIT, meme jour) elles faisaient un second accueil. Les quatre tuiles deviennent du verre
   violet, la matiere des commandes de la DA (barre « Qui joue ? », bouton « Se connecter ») : fond
   nuit translucide, filet lavande, glyphe lavande, lueur violette courte. Une seule couleur, celle
   du compte, qui est celle de Trinke. Grille, tailles, rayon, textes inchanges. */
html body .vq-on .vq-tu,
html body .vq-on .vq-tu-sarcelle,
html body .vq-on .vq-tu-bleu,
html body .vq-on .vq-tu-fuchsia,
html body .vq-on .vq-tu-or{
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.02)),rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.14),
             0 6px 16px -8px rgba(90,60,255,.55)}
html body .vq-on .vq-tu svg{stroke:#C4B5FD}
/* VERROU-VIOLET:FIN */

/* BARRE-SANS-CLASSEMENT (Romain, 07/10) : l'onglet Classement est retire de la barre du bas, « cette
   partie ne sert plus a rien pour l'instant ». Le bouton garde sa place dans le balisage (contrat et
   branchements inchanges) et disparait a l'ecran ; les quatre autres se repartissent la largeur par
   le flex de .ong, rien d'autre ne bouge. Pour le remettre : retirer `hidden` dans index.html et
   cette regle. */
html body #barre #ong-classement[hidden]{display:none!important}
/* BARRE-SANS-CLASSEMENT:FIN */

/* COMPTE-VERRE (Romain, 07/10, « la page se connecter a encore l'ancienne DA ») : TOUT L'ECRAN DU
   COMPTE (#s-compte, toutes ses vues : se connecter, code par email, creer, activation, menu connecte)
   parle la langue de l'accueil. Les ecrans verrouilles l'avaient recue le matin (VERROU-*), mais des
   qu'on touchait « Se connecter » on retombait dans le socle noir d'aout : champs gris, bouton lavande
   a encre sombre, pas de ciel. Recette = celle de la porte d'age : ciel de nuit, bouton plein violet
   -> bleu a texte blanc (le « Lancer une Soirée »), secondaire et champs en verre nuit a filet lavande,
   flèche retour en verre. Textes, ordre, gestes et contrats inchanges ; l'etat desactive garde son
   fond neutre lisible (UI-08). */
html body #s-compte{background-color:#020106;background-image:
  radial-gradient(70% 34% at 50% 30%, rgba(110,60,255,.30), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-compte .topbar b{color:var(--c-texte)}
html body #s-compte .iconbtn{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte);border-radius:var(--r-2)}
html body #s-compte .wiz-tete h2{color:var(--c-texte)}
html body #s-compte .wiz-tete p,html body #s-compte .mut,html body #s-compte .cp-dispo{color:var(--c-texte-2)}
html body #s-compte .cp-dispo.ok{color:#4ade80}
html body #s-compte .cp-dispo.ko{color:#f87171}
html body #s-compte .ou{color:var(--c-texte-3)}
html body #s-compte .ou::before,html body #s-compte .ou::after{background:rgba(190,175,255,.22)}
/* champs : verre nuit, filet lavande, texte clair ; la mise au point reprend le filet en plus vif */
html body #s-compte input[type=text],html body #s-compte input[type=email],html body #s-compte input[type=tel],
html body #s-compte input[type=search],html body #s-compte input[type=password],html body #s-compte input[type=date],
html body #s-compte .jr-champ,html body #s-compte .code6{
  background:rgba(10,11,39,.62);color:var(--c-texte);border:1px solid var(--filet-verre);border-radius:var(--r-2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-compte input::placeholder,html body #s-compte .code6::placeholder{color:var(--c-texte-3)}
html body #s-compte input:focus{outline:none;border-color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 0 0 3px rgba(120,80,255,.22)}
/* bouton plein = « Lancer une Soirée » ; secondaire = verre ; desactive = neutre du socle, inchange */
html body #s-compte .btn{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  color:var(--c-texte);font-weight:600;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #s-compte .btn.sec{background:rgba(10,11,39,.62);color:var(--c-texte);border:1px solid var(--filet-verre);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
html body #s-compte .btn.ghost{background:transparent;border:0;color:var(--c-texte-3);box-shadow:none}
html body #s-compte .btn:disabled{background:rgba(255,255,255,.08);color:var(--c-texte-2);border:0;box-shadow:none}
html body #s-compte .intro-dots i{background:rgba(255,255,255,.16)}
html body #s-compte .intro-dots i.on{background:linear-gradient(90deg,#A468EE,#5933FC);box-shadow:0 0 10px rgba(120,80,255,.6)}
/* COMPTE-VERRE:FIN */

/* COMPTE-VERRE, suite (07/10, apres capture de « Créer un compte ») : LE FILET VA SUR L'ENVELOPPE, PAS
   SUR L'INPUT QU'ELLE CONTIENT. Sur la page de creation, chaque champ est un `.cr-champ` (signe +
   input) : la regle de champ du bloc precedent peignait un second bord sur l'input interieur, double
   ligne. L'input redevient nu, l'enveloppe prend le verre, et le focus reste porte par l'enveloppe
   (regle du 08/08 conservee). Le bouton « Créer mon compte » (`.cr-valider`, qui n'est pas un .btn)
   prend le plein de la DA quand il est actif, et garde un fond neutre lisible quand il est inerte. */
html body #s-compte #cp-body .cr-champ input{background:none;border:0;box-shadow:none;border-radius:0;color:var(--c-texte)}
html body #s-compte #cp-body .cr-champ input:focus{box-shadow:none;border:0}
html body #s-compte #cp-body .cr-champ{background:rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-compte #cp-body .cr-champ:focus-within{box-shadow:inset 0 0 0 1px #fff,0 0 0 3px rgba(120,80,255,.22)}
html body #s-compte #cp-body .cr-champ>span{color:var(--c-texte)}
html body #s-compte #cp-body .cr-champ>span.cr-vide,html body #s-compte #cp-body .cr-champ input::placeholder{color:var(--c-texte-3)}
html body #s-compte #cp-body .cr-lab{color:var(--c-texte)}
html body #s-compte #cp-body .cr-aide,html body #s-compte #cp-body .cr-legal{color:var(--c-texte-3)}
html body #s-compte #cp-body .cr-aide.faux{color:#F87171}
html body #s-compte #cp-body .cr-valider{border-radius:var(--r-4);color:var(--c-texte);
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #s-compte #cp-body .cr-valider.inerte{background:rgba(255,255,255,.07);color:var(--c-texte-2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.10)}
/* COMPTE-VERRE suite:FIN */

/* DISCUSSIONS-VERRE (Romain, 07/10, « refais la page de discussion selon notre DA ») : L'ONGLET
   DISCUSSIONS, CONNECTE, PARLE LA LANGUE DE L'ACCUEIL. Il vivait en sarcelle et cyan (halo, bouton
   plus, bulles, envoi, cases cochees) par une regle du socle d'aout, « le violet est la couleur de la
   Soiree, pas d'autre usage ». La DA du 07/10 (Romain) dit l'inverse : les teintes de mode ne vivent
   que sur les cartes de mode, et le violet est la couleur de Trinke, donc des commandes. Recette =
   celle de l'accueil, de la porte d'age et du Compte : ciel de nuit, verre nuit a filet lavande pour
   les capsules, cartes et bulles recues, plein violet -> bleu a texte blanc pour mes bulles et les
   actions (plus, envoi, valider, case cochee), lavande pour les glyphes et les accents. Les bulles de
   PARTIE gardent la couleur de leur mode (.m-soiree, .m-classiques, .m-minijeux) : c'est un mode.
   Trois vues couvertes : liste, fil, nouveau groupe (et le menu, l'invitation). Modes, salon et
   partie a distance ne sont pas touches ici. Geometrie et textes inchanges. */
html body #s-multi{background-color:#020106;background-image:
  radial-gradient(70% 34% at 50% 30%, rgba(110,60,255,.30), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}
html body #s-multi::before{background:
    radial-gradient(118% 52% at 82% -6%,rgba(139,92,246,.14) 0,transparent 62%),
    radial-gradient(150% 62% at 40% 0%,rgba(90,60,255,.10) 0,transparent 66%)}
html body #s-multi .topbar b{color:var(--c-texte)}
html body #s-multi .iconbtn{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte);border-radius:var(--r-2)}
/* ── liste ── */
html body :is(#s-amis,#s-multi) .am-apercu{background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.015)),rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08),0 20px 40px -18px rgba(0,0,0,.8)}
html body #s-multi .mu-rech{background:rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .mu-rech:focus-within{box-shadow:inset 0 0 0 1px #fff,0 0 0 3px rgba(120,80,255,.22)}
html body #s-multi .mu-rech:focus-within svg{stroke:#C4B5FD}
html body #s-multi .mu-plus{background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);color:var(--c-texte);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 6px 14px -6px rgba(90,60,255,.7)}
html body #s-multi .mu-plus svg{stroke:#fff}
html body #s-multi .mu-menu{background:rgba(10,11,39,.90);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08),0 12px 30px -10px rgba(0,0,0,.65)}
html body #s-multi .mu-mit svg{stroke:#C4B5FD}
html body #s-multi .mu-mit:active{background:rgba(120,80,255,.16)}
html body #s-multi .mu-fil::after,html body #s-multi .mu-liste>.premier::before,html body #s-multi .mu-invit::after,
html body #s-multi .mu-mit+.mu-mit::before{background:rgba(190,175,255,.20)}
html body #s-multi .mu-fil.nl{background:rgba(120,80,255,.08)}
html body #s-multi .mu-fil:active{background:rgba(120,80,255,.15)}
html body #s-multi .mu-fil.nl .mu-heure,html body #s-multi .mu-etiq{color:#C4B5FD}
html body #s-multi .mu-heure{color:var(--c-texte-3)}
html body #s-multi .mu-ligne span,html body #s-multi .mu-sous{color:var(--c-texte-3)}
/* ── fil ── */
html body #s-multi.au-fil #mu-back,html body #s-multi.au-fil .mu-tt{background:rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre)}
html body #s-multi .bul{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte)}
html body #s-multi .bul.moi{color:var(--c-texte);border-color:transparent;
  background:linear-gradient(135deg,#A468EE 0%,#7B3EFC 32%,#5933FC 62%,#2526FC 100%)}
html body #s-multi .bul.moi .bul-h{color:rgba(255,255,255,.62)}
html body #s-multi .bul-qui,html body #s-multi .chat-tape{color:#C4B5FD}
html body #s-multi .bul-cite{border-color:var(--filet-verre);color:var(--c-texte-2)}
html body #s-multi .ln-av{background:rgba(10,11,39,.72);box-shadow:inset 0 0 0 1px rgba(190,175,255,.38);color:#C4B5FD}
html body #s-multi .ln-av.moi{background:linear-gradient(135deg,#A468EE,#5933FC);box-shadow:none;color:var(--c-texte)}
html body #s-multi .ln-av.vide{background:none;box-shadow:none}
html body #s-multi .chat-jour span{color:var(--c-texte-3)}
html body #s-multi .chat-saisie textarea{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte)}
html body #s-multi .chat-saisie textarea::placeholder{color:var(--c-texte-3)}
html body #s-multi .chat-saisie textarea:focus{outline:none;border-color:#fff;box-shadow:0 0 0 3px rgba(120,80,255,.22)}
html body #s-multi .chat-env{background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);color:var(--c-texte)}
html body #s-multi .chat-env svg{stroke:#fff}
html body #s-multi .chat-jeu{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:#C4B5FD}
/* ── nouveau groupe ── */
html body #s-multi .ng-nom,html body #s-multi .ng-rech{background:rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .ng-nom:focus-within,html body #s-multi .ng-rech:focus-within{box-shadow:inset 0 0 0 1px #fff,0 0 0 3px rgba(120,80,255,.22)}
html body #s-multi .ng-nom>svg{stroke:#C4B5FD}
html body #s-multi .ng-lab{color:var(--c-texte-3)}
html body #s-multi .ng-groupe{background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .ng-ami+.ng-ami::before{background:rgba(190,175,255,.20)}
html body #s-multi .ng-ami:active{background:rgba(120,80,255,.12)}
html body #s-multi .ng-ck{box-shadow:inset 0 0 0 1.4px var(--filet-verre)}
html body #s-multi .ng-ami.on .ng-ck{background:linear-gradient(180deg,#A468EE 0%,#5933FC 100%);box-shadow:none}
html body #s-multi .ng-ami.on .ng-ck svg{stroke:#fff}
html body #s-multi .ng-valider{border-radius:var(--r-4);color:var(--c-texte);
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #s-multi .ng-ancre{background:linear-gradient(180deg,rgba(2,1,6,0) 0%,rgba(2,1,6,.86) 34px,#01030F 62px)}
/* DISCUSSIONS-VERRE:FIN */

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DA-GLOBALE (Romain, 07/10, « refais toutes les pages qui ne sont pas dans la bonne DA »).
   ═══════════════════════════════════════════════════════════════════════════════════════════
   Une seule couche, en fin de feuille, qui pose la langue de l'accueil sur TOUT ce qui parlait
   encore le socle d'aout : 46 ecrans, les feuilles modales et leurs composants partages. Plutot
   qu'un bloc par ecran (il y en aurait vingt), on change CE QUE LES ECRANS LISENT :
   1. les jetons du socle. --card devient le verre nuit, --line et --line2 le filet lavande, --accent
      et --accent2 les deux bouts du degrade « Lancer une Soirée », --accent-ink le blanc, --dim et
      --mut le gris lavande. Soixante-dix-sept cartes, cent quarante filets et soixante accents
      changent d'un coup, sans toucher a une seule geometrie ;
   2. le ciel de nuit sur tous les ecrans sauf l'accueil (qui a le sien) ;
   3. les quelques composants ecrits en dur : .btn, .iconbtn, champs, feuilles, barre de titre, toast ;
   4. le sarcelle et le cyan du Multijoueur hors #s-multi (salon, partie, modes, bandeaux) ramenes
      au violet, puisque la DA du 07/10 reserve les teintes de mode aux cartes de mode.
   Ce qui NE change PAS, et c'est voulu : les couleurs de MODE (Soiree, Classiques, Mini-jeux, Quiz)
   la ou elles designent un mode ; le vert de presence ; l'or des recompenses ; les verts et rouges
   de verdict (ok / ko), qui sont du sens, pas de la matiere ; les ecrans deja portes (accueil,
   porte d'age, intro, Qui joue, reglages, ecrans sans compte, Compte, Discussions), que cette couche
   rejoint sans les contredire : ce sont les memes valeurs. */
/* `:root`, PAS `html` : les jetons d'origine sont declares sur :root (specificite 0,1,0), une
   redeclaration sur html (0,0,1) perdait, et tout ce qui lit var(--card) restait gris (vu sur le
   menu du Compte en v924). A specificite egale, la derniere ecrite gagne : c'est celle-ci. */
:root{--bg:#01030F;--card:rgba(10,11,39,.62);--line:rgba(190,175,255,.18);--line2:rgba(190,175,255,.30);
  --dim:#A19CAB;--mut:#A19CAB;--accent:#A468EE;--accent2:#5933FC;--accent-ink:#FFFFFF}
html body{background:#01030F}
html body .screen:not(#s-home){background-color:#020106;background-image:
  radial-gradient(70% 34% at 50% 30%, rgba(110,60,255,.30), transparent 72%),
  radial-gradient(62% 26% at 88% 6%, rgba(80,30,160,.42), transparent 70%),
  radial-gradient(44% 16% at 100% 0%, rgba(0,120,170,.28), transparent 70%),
  radial-gradient(95% 22% at 40% 102%, rgba(35,20,120,.48), transparent 70%),
  radial-gradient(36% 9% at 92% 99%, rgba(255,80,20,.20), transparent 70%),
  radial-gradient(28% 9% at 4% 100%, rgba(255,70,20,.15), transparent 70%),
  linear-gradient(#000102,#01030F)}
/* ── commandes ── */
html body .btn{background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  color:var(--c-texte);font-weight:600;border:0;border-radius:var(--r-4);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body .btn.sec{background:rgba(10,11,39,.62);color:var(--c-texte);border:1px solid var(--filet-verre);box-shadow:inset 0 1px 0 rgba(255,255,255,.12)}
html body .btn.sec.danger{border-color:rgba(248,113,113,.55);color:#FCA5A5}
html body .btn.ghost{background:transparent;border:0;color:var(--c-texte-3);box-shadow:none}
html body .btn.sm{border-radius:var(--r-3)}
html body .btn:disabled{background:rgba(255,255,255,.08);color:var(--c-texte-2);border:0;box-shadow:none}
html body .iconbtn{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:var(--c-texte);border-radius:var(--r-2)}
html body .topbar b{color:var(--c-texte)}
html body .helpbtn{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:#C4B5FD}
/* ── champs ── */
html body input[type=text],html body input[type=number],html body input[type=email],html body input[type=tel],
html body input[type=search],html body input[type=password],html body input[type=date],html body textarea,html body select{
  background:rgba(10,11,39,.62);color:var(--c-texte);border:1px solid var(--filet-verre)}
html body input::placeholder,html body textarea::placeholder{color:var(--c-texte-3)}
html body input:focus,html body textarea:focus{outline:none;border-color:#fff;box-shadow:0 0 0 3px rgba(120,80,255,.22)}
/* ── feuilles, fenetres, toast ── */
html body .sheet{background:linear-gradient(180deg,#12112E 0%,#0A0B27 100%);border-top:0;
  box-shadow:inset 0 1.5px 0 var(--filet-verre),0 -20px 60px -20px rgba(90,60,255,.45)}
html body .modal.milieu .sheet{background:none;box-shadow:none}
html body .modal{background:rgba(2,1,10,.62)}
html body #toast{background:rgba(10,11,39,.92);border:1px solid var(--filet-verre);color:var(--c-texte);
  box-shadow:var(--o-3)}
html body .setup-cta{background:rgba(2,1,10,.86);border-top:1px solid rgba(190,175,255,.18)}
html body .progress{background:rgba(255,255,255,.10)}
/* ── le sarcelle et le cyan du Multijoueur hors #s-multi : salon, partie, modes, bandeaux ── */
html body .mu-btn.cyan,html body .mu-ban-a,html body .bp-a,html body .mp-p.on,html body .sel-case.on,html body .dis.on .dis-check{
  background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);color:var(--c-texte);border-color:transparent}
html body .dis.on{border-color:#fff;background:rgba(120,80,255,.12)}
html body .dis.neuf .dis-q,html body .sal-quoi,html body .sal-reg b,html body .bf-l i b,html body .bul-rep b,
html body .chat-tape,html body .chat-note i,html body .bul-qui{color:#C4B5FD}
html body .sal-dots i{background:#A78BFA}
html body .dis-av.grp{background:linear-gradient(135deg,#6A3BFC,#A468EE);color:var(--c-texte)}
html body .chat-jeu{background:rgba(10,11,39,.62);border:1px solid var(--filet-verre);color:#C4B5FD}
html body .chat-env{background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);color:var(--c-texte)}
html body .ln-av{background:rgba(10,11,39,.72);box-shadow:inset 0 0 0 1px rgba(190,175,255,.38);color:#C4B5FD}
html body .ln-av.moi{background:linear-gradient(135deg,#A468EE,#5933FC);box-shadow:none;color:var(--c-texte)}
html body .ln-av.vide{background:none;box-shadow:none}
html body #s-amis .am-mit svg{stroke:#C4B5FD}
/* DA-GLOBALE:FIN */

/* DA-GLOBALE, retouches apres tour de controle sur l'apercu (07/10, v924) :
   · le menu du Compte connecte lisait un second jeton de carte, --card-2, reste gris : il rejoint
     le verre nuit, avec le filet lavande sur les groupes et la carte du profil ;
   · l'onglet Amis gardait son bleu de territoire (bouton plus, « Accepter », etats) : il passe au
     violet des commandes, comme Discussions. Rien d'autre ne bouge. */
:root{--card-2:rgba(10,11,39,.62)}
html body #s-compte .c-groupe,html body #s-compte .c-moi{box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-compte .c-ligne+.c-ligne::before{background:rgba(190,175,255,.20)}
html body #s-compte .c-ligne:active{background:rgba(120,80,255,.12)}
html body #s-compte .c-pied,html body #s-compte .c-lab{color:var(--c-texte-3)}
html body #s-amis .am-ajout{background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);color:var(--c-texte);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 6px 14px -6px rgba(90,60,255,.7)}
html body #s-amis .am-ajout svg{stroke:#fff}
html body .am-act.oui,html body #s-amis .am-etat.oui{background:linear-gradient(180deg,#A468EE 0%,#5933FC 100%);color:var(--c-texte)}
html body #s-amis .am-lab.recu svg{stroke:#C4B5FD}
/* DA-GLOBALE retouches:FIN */

/* BULLES-CREME (Romain, 07/10, « ce thème bleu violet est trop présent partout ») : MES BULLES
   QUITTENT LE VIOLET DES COMMANDES. Le meme degrade servait aux boutons, au plus, a l'envoi et a mes
   messages : un fil de discussion devenait un mur de boutons. Mes bulles prennent le creme de la
   barre du bas (#EFE9DF, deja dans la DA, et qui n'est la couleur d'aucun mode), encre sombre
   #170B20, comme les bulles de l'expediteur dans Messages. Les bulles recues restent en verre nuit :
   deux matieres, deux locuteurs. L'envoi et le plus restent violets : ce sont des actions. */
html body #s-multi .bul.moi{color:#170B20;border:0;
  background:linear-gradient(180deg,#F7F2E9 0%,#EDE6DA 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 8px 18px -10px rgba(0,0,0,.6)}
html body #s-multi .bul.moi .bul-h{color:rgba(23,11,32,.55)}
html body #s-multi .bul.moi .bul-etat{color:rgba(23,11,32,.55)}
html body #s-multi .bul.moi .bul-etat.ko{color:#B42318}
html body #s-multi .ln-av.moi{background:linear-gradient(180deg,#F7F2E9,#EDE6DA);color:#170B20;box-shadow:inset 0 0 0 1px rgba(23,11,32,.12)}
/* BULLES-CREME:FIN */

/* AVATARS-VERRE (07/10) : le filet lavande des pastilles d'amis, partout ou la source unique est lue. */
html body :is(#s-amis,#s-multi) .am-av,html body #s-multi .mu-pas,html body #s-multi .ng-av,html body #s-compte .c-grand.ami{
  box-shadow:inset 0 0 0 1.5px rgba(190,175,255,.45)}
html body #s-compte .c-grand.ami{box-shadow:inset 0 0 0 1.5px rgba(190,175,255,.45),0 0 0 2px rgba(250,249,252,.95),0 0 0 4.5px rgba(190,175,255,.45)}
/* AVATARS-VERRE:FIN */

/* DISCUSSIONS-ACCUEIL (Romain, 07/10, « le menu Discussions n'est pas cohérent avec la page d'accueil,
   c'est trop éloigné ») : DISCUSSIONS ET AMIS PARLENT LA GRAMMAIRE DE L'ACCUEIL. L'accueil est fait de
   PANNEAUX arrondis (rayon ~16 a l'ecran), de LIBELLES DE SECTION en petites capitales espacees suivis
   d'un trait, et d'une CAPSULE « Qui joue ? » de 38-42 px sur fond #0A0B27. Discussions etait une
   liste a filets fins qui saignait sur les bords, une recherche de 36 px en gelule et un petit carre.
   Ici : la liste entre dans un panneau de verre nuit (meme matiere que les cartes du Compte et du
   nouveau groupe), un libelle « Mes discussions » au-dessus dans le style des sections de l'accueil,
   la recherche et le « + » prennent les cotes de la capsule (42, rayon 13). Amis suit pour que les
   deux onglets voisins aient le meme pas. Rien ne change dans les textes ni les gestes. */
html body #s-multi .mu-liste{margin:0;background:rgba(10,11,39,.62);border-radius:var(--r-2);overflow:hidden;
  box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .mu-liste::before{content:"Mes discussions";display:block;margin:0 0 var(--e-2);padding-left:var(--e-1);
  font-size:var(--t-1);font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:var(--c-texte)}
html body #s-multi .mu-liste{background:none;box-shadow:none;overflow:visible}
html body #s-multi .mu-liste>.mu-fil,html body #s-multi .mu-liste>.mu-invit{background:rgba(10,11,39,.62)}
html body #s-multi .mu-liste>.mu-fil:first-of-type,html body #s-multi .mu-liste>.premier{border-radius:var(--r-2) var(--r-2) 0 0}
html body #s-multi .mu-liste>.mu-fil:last-child{border-radius:0 0 var(--r-2) var(--r-2)}
html body #s-multi .mu-liste>.mu-fil:first-of-type:last-child{border-radius:var(--r-2)}
html body #s-multi .mu-liste>.premier::before{display:none}
html body #s-multi .mu-liste>.mu-fil:last-child::after{display:none}
html body #s-multi .mu-fil::after,html body #s-multi .mu-invit::after{left:70px;right:16px}
html body #s-multi .mu-fil{padding:var(--e-2) var(--e-3) var(--e-4)}
html body #s-multi .mu-fil.nl{background:rgba(120,80,255,.16)}
html body #s-multi .mu-rech,html body :is(#s-amis,#s-multi) .am-rech{min-height:42px;border-radius:var(--r-2);background:#0A0B27;
  box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.06)}
html body #s-multi .mu-rech input,html body :is(#s-amis,#s-multi) .am-rech input{min-height:42px}
html body #s-multi .mu-plus,html body #s-amis .am-ajout{width:42px;height:42px;border-radius:var(--r-2)}
html body #s-multi .mu-barre{margin:0 0 var(--e-3)}
html body :is(#s-amis,#s-multi) .am-apercu{border-radius:var(--r-2)}
html body #s-amis .am-groupe{border-radius:var(--r-2);box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
/* DISCUSSIONS-ACCUEIL:FIN */

/* DISCUSSIONS-AMIS (Romain, 07/10, « on les fusionne, Discussions c'est mieux ») : l'onglet Amis
   quitte la barre ; ses demandes recues s'affichent en tete de Discussions, sa pastille passe sur
   l'onglet Discussions, l'ajout d'un ami vit dans « Nouvelle discussion ». */
html body #barre #ong-amis[hidden]{display:none!important}
html body #ong-discussions{position:relative}
html body #s-multi .mu-dem{display:flex;flex-direction:column;gap:var(--e-2);margin:0 0 var(--e-4)}
html body #s-multi .am-dem{display:grid;grid-template-columns:46px 1fr;grid-template-rows:auto auto;align-items:center;
  column-gap:var(--e-3);row-gap:var(--e-3);width:100%;padding:var(--e-3) var(--e-3);border-radius:var(--r-2);text-align:left;
  background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .am-dem .am-av{grid-area:1/1/3/2;align-self:start;margin-top:2px;width:46px;height:46px;font-size:var(--t-3);
  border-radius:50%;display:grid;place-items:center;font-weight:700;background-color:var(--ami-fond);color:var(--ami-encre);
  box-shadow:inset 0 0 0 1.5px rgba(190,175,255,.45)}
html body #s-multi .am-dem .am-txt{grid-area:1/2/2/3;min-width:0}
html body #s-multi .am-dem b{display:block;font-size:var(--t-3);font-weight:600;color:var(--c-texte);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-multi .am-dem small{display:block;font-size:var(--t-1);margin-top:var(--e-1);color:var(--c-texte-3)}
html body #s-multi .am-actions{grid-area:2/2/3/3;display:flex;flex-wrap:wrap;gap:var(--e-2);min-width:0}
html body #s-multi .am-act.non{background:rgba(10,11,39,.62);color:var(--c-texte);box-shadow:inset 0 0 0 1px var(--filet-verre)}
html body #s-multi .ng-ajout-ami{display:flex;align-items:center;gap:var(--e-3);width:100%;min-height:50px;margin:var(--e-3) 0 var(--e-1);
  padding:0 var(--e-3);border:0;border-radius:var(--r-2);font:inherit;font-size:var(--t-2);font-weight:600;color:var(--c-texte);text-align:left;cursor:pointer;
  background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1.5px var(--filet-verre)}
html body #s-multi .ng-ajout-ami svg{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:#C4B5FD;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
html body #s-multi .ng-ajout-ami:active{transform:scale(.985)}
html body #s-multi .ln-av[data-p]:not(.moi):not(.vide){cursor:pointer}
/* DISCUSSIONS-AMIS:FIN */

/* AMIS-CHATGPT (Romain, 07/10) : L'ONGLET AMIS TRANSCRIT DEPUIS LE RENDU CHATGPT VALIDE PAR ROMAIN
   (Desktop/IA/TRINKE/33 Amis ChatGPT (07-10)/reference-chatgpt.png, 853 px de large, ramene a 430 par
   0,504). Cotes mesurees sur l'image, en points :
   titre « Amis » 30, gras, halo lavande leger ; panneau « Connectes recemment » rayon 15, libelle 11
   en capitales espacees .22em, sans pictogramme ; ronds 60 a pas de 96, initiale 22 gras, duree 13 ;
   recherche 41 de haut, « + » 42, rayon 12 ; « Mes discussions » meme libelle ; rangees de 78, rond
   50, nom 17 gras, apercu 14,5, heure 12,5 ; groupe = deux ronds de 32 en diagonale. Couleurs : deja
   celles de la DA (verre nuit, filet lavande, degrade violet-bleu). Textes et gestes inchanges. */
html body #s-multi.racine>.topbar>#mu-title{font-size:var(--t-5);font-weight:800;letter-spacing:-.02em;color:var(--c-texte);
  text-shadow:0 0 18px rgba(170,140,255,.35)}
html body #s-multi .am-apercu{border-radius:var(--r-2);padding:var(--e-4) 0 var(--e-1)}
html body #s-multi .am-apercu-tete{padding:0 var(--e-4) var(--e-3);font-size:var(--t-1);font-weight:600;letter-spacing:.22em;color:var(--c-texte)}
html body #s-multi .am-apercu-tete svg{display:none}
html body #s-multi .am-ruban{gap:var(--e-5);padding:0 var(--e-4) var(--e-3)}
html body #s-multi .am-rec{width:60px}
html body #s-multi .am-rec .am-av{width:60px;height:60px;font-size:var(--t-4);font-weight:700}
html body #s-multi .am-rec .am-heure{font-size:var(--t-1);font-weight:500;color:var(--c-texte-2);margin-top:var(--e-2)}
html body #s-multi .mu-rech{min-height:41px;border-radius:var(--r-1)}
html body #s-multi .mu-plus{width:42px;height:42px;border-radius:var(--r-1)}
html body #s-multi .mu-barre{margin:0 0 var(--e-4)}
html body #s-multi .mu-liste::before{font-size:var(--t-1);font-weight:600;letter-spacing:.22em;margin:0 0 var(--e-3);padding-left:var(--e-1)}
html body #s-multi .mu-liste>.mu-fil:first-of-type,html body #s-multi .mu-liste>.premier{border-radius:var(--r-2) var(--r-2) 0 0}
html body #s-multi .mu-liste>.mu-fil:last-child{border-radius:0 0 var(--r-2) var(--r-2)}
html body #s-multi .mu-liste>.mu-fil:first-of-type:last-child{border-radius:var(--r-2)}
html body #s-multi .mu-fil{grid-template-columns:50px 1fr auto 12px;column-gap:var(--e-3);min-height:78px;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3)}
html body #s-multi .mu-fil::after{left:12px;right:0}
html body #s-multi .mu-fil>.mu-ava{margin-top:0;align-self:center}
html body #s-multi .mu-ava{width:50px;height:50px;margin-left:0}
html body #s-multi .mu-ava.un .mu-pas{width:50px;height:50px;font-size:var(--t-3);font-weight:700}
html body #s-multi .mu-ava.deux .mu-pas{width:32px;height:32px;font-size:var(--t-1)}
html body #s-multi .mu-ava.deux .mu-pas+.mu-pas{margin-left:-14px;margin-top:var(--e-3)}
html body #s-multi .mu-fil .mu-nom{font-size:var(--t-3);font-weight:700;color:var(--c-texte)}
html body #s-multi .mu-fil .mu-ligne{margin-top:var(--e-1)}
html body #s-multi .mu-fil .mu-ligne span{font-size:var(--t-2);color:var(--c-texte-3)}
html body #s-multi .mu-fil .mu-heure{font-size:var(--t-1);color:var(--c-texte-2)}
html body #s-multi .mu-fil.nl{background:rgba(70,60,140,.38)}
html body #s-multi .mu-fil.nl .mu-heure{color:#C4B5FD}
/* AMIS-CHATGPT:FIN */
/* AMIS-CHATGPT, passe 2 apres comparaison a l'image : ronds plats sans reflet, filets plus francs,
   contour du panneau des discussions, heures en graisse normale. */
html body #s-multi .am-rec .am-av{background-image:none;box-shadow:inset 0 0 0 2px rgba(190,175,255,.55)}
html body #s-multi .am-apercu{box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.06)}
html body #s-multi .mu-rech{box-shadow:inset 0 0 0 1.5px var(--filet-verre)}
html body #s-multi .mu-ava .mu-pas{box-shadow:inset 0 0 0 2px rgba(190,175,255,.55)}
html body #s-multi .mu-liste>.mu-fil{box-shadow:inset 1.5px 0 0 var(--filet-verre),inset -1.5px 0 0 var(--filet-verre)}
html body #s-multi .mu-liste>.mu-fil:first-of-type{box-shadow:inset 1.5px 0 0 var(--filet-verre),inset -1.5px 0 0 var(--filet-verre),inset 0 1.5px 0 var(--filet-verre)}
html body #s-multi .mu-liste>.mu-fil:last-child{box-shadow:inset 1.5px 0 0 var(--filet-verre),inset -1.5px 0 0 var(--filet-verre),inset 0 -1.5px 0 var(--filet-verre)}
html body #s-multi .mu-liste>.mu-fil:first-of-type:last-child{box-shadow:inset 0 0 0 1.5px var(--filet-verre)}
html body #s-multi .mu-fil .mu-heure{font-weight:400}
/* AMIS-CHATGPT passe 2:FIN */

/* BARRE-COURTE (Romain, 07/10, « la barre avec trois onglets fait trop vide ») : la capsule gardait la
   largeur prevue pour cinq onglets. Elle se resserre a la largeur de trois (3 x 72 + marges), centree,
   comme les barres flottantes d'iOS. Les onglets gardent leur taille ; seul le vide entre eux part. */
html body #barre{left:0;right:0;margin-left:auto;margin-right:auto;width:340px;max-width:calc(100% - 48px)}   /* v939 : 236 jugé trop étroit ; v942 : 300 encore un peu étroit (Romain) */
/* BARRE-COURTE:FIN */

/* LISTE-SANS-ROND (Romain, 07/10, « enlève le rond dans Mes discussions, juste le nom et le dernier
   message ») : les rangees de la liste perdent leur rond ; nom et apercu prennent toute la place. Les
   ronds restent dans « Connectes recemment » et en haut d'un fil. */
html body #s-multi .mu-liste .mu-fil>.mu-ava{display:none}
html body #s-multi .mu-liste .mu-fil{grid-template-columns:1fr auto 12px;column-gap:var(--e-3);min-height:68px;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3)}
html body #s-multi .mu-liste .mu-fil>.mu-tete{grid-area:1/1/2/2}
html body #s-multi .mu-liste .mu-fil>.mu-heure{grid-area:1/2/2/3}
html body #s-multi .mu-liste .mu-fil>.mu-ch{grid-area:1/3/3/4}
html body #s-multi .mu-liste .mu-fil>.mu-ligne{grid-area:2/1/3/3}
html body #s-multi .mu-liste .mu-fil::after,html body #s-multi .mu-liste .mu-invit::after{left:18px;right:0}
/* LISTE-SANS-ROND:FIN */

/* LANCER-REDUIT (Romain, 07/10, « réduis la taille du Lancer une Soirée ») : le bouton perd 18 %
   (586 x 95 -> 480 x 78 dans la toile), meme centre, texte et fleche a la meme echelle. */
#mv-canvas .mv-lancer{left:200px;top:399px;width:480px;height:78px;border-radius:39px;font-size:2rem;padding-left:103px}
#mv-canvas .mv-lancer svg{left:388px;width:30px;height:27px}
/* LANCER-REDUIT:FIN */

/* BARRE-REMONTEE (Romain, 07/10, « sur mon ordinateur la barre est quasiment collée en bas ») : sans
   encoche (ordinateur, vieux iPhone) la barre etait a 6 px du bord. Elle garde l'ecart de l'encoche
   quand il existe, et au moins 18 px sinon. Les ecrans a barre reservent la place en consequence. */
html body #barre{bottom:max(env(safe-area-inset-bottom,0px), 18px)}
html body .screen.avec-barre{padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 74px)}
/* BARRE-REMONTEE:FIN */

/* SOIREE-TROIS-LIGNES (Romain, 07/10, « mets Classiques, Mini-jeux et Défis en trois lignes sous le
   nom Soirée ») : la ligne d'etiquettes devient une colonne alignee sur le titre, dans l'ordre dit par
   Romain ; le titre remonte pour leur laisser la place au-dessus du bouton. */
#mv-canvas .mv-soiree h1{top:88px}
#mv-canvas .mv-etiquettes{top:204px;left:68px;flex-direction:column;align-items:flex-start;gap:18px}
#mv-canvas .mv-etiquette{font-size:1.8125rem}
#mv-canvas .mv-etiquette svg{width:31px;height:31px}
#mv-canvas .mv-etiquette + .mv-etiquette::before{content:none}
#mv-canvas .mv-etiquette:nth-child(1){order:1}
#mv-canvas .mv-etiquette:nth-child(3){order:2}
#mv-canvas .mv-etiquette:nth-child(2){order:3}
/* SOIREE-TROIS-LIGNES:FIN */

/* SOIREE-MOINS-HAUTE (Romain, 07/10, « réduis un peu la hauteur du rectangle Soirée ») : la carte perd
   55 px de toile (525 -> 470) ; titre, trois lignes et bouton se resserrent dedans, et tout ce qui
   suit (titre de section, cartes de mode) remonte d'autant. */
#mv-canvas .mv-soiree{height:470px}
#mv-canvas .mv-soiree h1{top:68px}
#mv-canvas .mv-etiquettes{top:180px;gap:14px}
#mv-canvas .mv-lancer{top:356px}
#mv-canvas .mv-section{top:866px}
#mv-canvas .mv-mode{top:910px}
#s-home.accroche #mv-canvas .mv-section{top:1000px}
#s-home.accroche #mv-canvas .mv-mode{top:1044px}
/* SOIREE-MOINS-HAUTE:FIN */

/* SOIREE-IMAGE-ROMAIN (07/10) : la carte Soirée recomposée d'après l'image fournie par Romain
   (Desktop/IA/TRINKE/34 Carte Soiree (07-10)/reference.png, carte de 1490 px ramenee a 856 de toile,
   facteur 0,575). Mesures : carte 507 de haut ; titre a 68 du bord, ~150 de haut d'oeil ; trois lignes
   a pas de 55, pictogramme 34, 25 entre pictogramme et texte ; bouton plein-largeur (34 de marge),
   85 de haut, texte CENTRE, fleche a droite ; illustration plus basse, centree sur la hauteur des lignes.
   Tout ce qui suit la carte redescend d'autant. Remplace SOIREE-TROIS-LIGNES et SOIREE-MOINS-HAUTE. */
#mv-canvas .mv-soiree{height:507px}
#mv-canvas .mv-soiree h1{top:76px;left:66px}
#mv-canvas .mv-etiquettes{top:188px;left:68px;gap:20px}
#mv-canvas .mv-etiquette{font-size:1.9375rem;gap:25px;color:#D6CEF5}
#mv-canvas .mv-etiquette svg{width:36px;height:36px;stroke:#D6CEF5}
#mv-canvas .mv-lancer{left:34px;top:376px;width:788px;height:85px;border-radius:43px;font-size:2.375rem;font-weight:500;
  justify-content:center;padding-left:0}
#mv-canvas .mv-lancer svg{left:auto;right:52px;width:36px;height:32px}
#mv-canvas .mv-soiree .mv-illu{left:368px;top:12px;width:546px;height:361px}
#mv-canvas .mv-section{top:903px}
#mv-canvas .mv-mode{top:947px}
#s-home.accroche #mv-canvas .mv-section{top:1037px}
#s-home.accroche #mv-canvas .mv-mode{top:1081px}
/* SOIREE-IMAGE-ROMAIN:FIN */
/* v946 (Romain : « bouton de la taille d'avant, pas toute la largeur ») : retour aux cotes de v940
   (480 x 78, texte et fleche comme avant), centre dans la carte, a la hauteur de la nouvelle mise en page. */
#mv-canvas .mv-lancer{left:188px;top:380px;width:480px;height:78px;border-radius:39px;font-size:2rem;font-weight:400;
  justify-content:flex-start;padding-left:103px}
#mv-canvas .mv-lancer svg{left:388px;right:auto;width:30px;height:27px}

/* MV-AV-MOI (Romain, 07/10, « la couleur de l'utilisateur ne se met pas à jour dans la barre
   Trinkeurs ») : mon rond de la barre de l'accueil lit ma teinte de profil, comme celui de la barre
   du bas ; sans teinte choisie, il reste violet. */
#mv-canvas .mv-av.mv-av-moi{background:#8B5CF6;color:#FFFFFF}
html.teinte #mv-canvas .mv-av.mv-av-moi{background:linear-gradient(180deg,var(--av-hi) 0%,var(--av-lo) 100%);color:#170B20}
/* MV-AV-MOI:FIN */
/* v948 (Romain : « réduis la taille des trois lignes Classiques, Mini-jeux, Défis dans la carte Soirée ») : -20 %. */
#mv-canvas .mv-etiquettes{top:196px;gap:18px}
#mv-canvas .mv-etiquette{font-size:1.5625rem;gap:20px}
#mv-canvas .mv-etiquette svg{width:29px;height:29px}
/* v949 (Romain : « mets en graisse 650 pour voir ») : le titre Soirée s'allège (800 -> 650), lettres
   moins serrees, blanc legerement lavande. La police systeme d'Apple est variable : 650 est rendu tel
   quel sur iPhone et Mac ; ailleurs le navigateur arrondit a 600 ou 700. */
#mv-canvas .mv-soiree h1{font-weight:650;letter-spacing:-1px;color:#F4F0FF}
/* v950 (Romain : « l'icône en bas à droite a un petit liseré blanc, en haut dans la barre Trinkeurs il
   n'y en a pas ») : le rond du compte dans la barre du bas perd son liseré blanc et son anneau, pour
   etre le meme objet que mon rond de la barre Trinkeurs. */
/* v951 (Romain : « remets le liseré blanc plutôt et applique-le pour tous les ronds d'icône joueur ») :
   v950 annulee. Tout rond de joueur porte le liseré du rond du compte : filet blanc 1,5 px puis anneau
   de 3 px dans la couleur du joueur (la sienne pour moi, le fond du rond pour un ami). Les ronds de la
   barre Trinkeurs gardent en plus leur bague nuit de 4,5 px qui les detache quand ils se chevauchent.
   Hors champ : le « + » de la barre, la place vide, l'icone de groupe. */
html body .ong-av,html body.teinte .ong-av,html.teinte .ong-av,
html body .cl-av,html body .dis-av:not(.grp),html body .ln-av,html body .am-av,
html body .cm-av:not(.cm-vacant),html body .c-moi-av,html body .ng-av,html body .fr-av,
html body #s-compte .c-grand{
  box-shadow:0 0 0 1.5px rgba(250,249,252,.95),0 0 0 3px var(--anneau,var(--ami-fond,#15163A))!important}
html.teinte body .ong-av,html.teinte body .cl-av.moi,html.teinte body .dis-av.moi,html.teinte body .ln-av.moi,html.teinte body .cm-av.estmoi,
html.teinte body .c-moi-av,html.teinte body #s-compte .c-grand:not(.ami){--anneau:var(--av-lo,#15163A)}
html body #s-compte .c-grand{box-shadow:0 0 0 2px rgba(250,249,252,.95),0 0 0 4.5px var(--anneau,var(--ami-fond,#15163A))!important}
html body #mv-canvas .mv-trinq .mv-av:not(.mv-av-plus){
  box-shadow:0 0 0 1.5px rgba(250,249,252,.95),0 0 0 3px var(--anneau,var(--ami-fond,#15163A)),0 0 0 6px #0A0B27!important}
html.teinte body #mv-canvas .mv-trinq .mv-av.mv-av-moi{--anneau:var(--av-lo,#15163A)}
/* [26/10, Romain : « la barre en haut de trinkeur est entouree de violet, ce n'est pas les memes boutons dans profil,
   ca fait une incoherence »] LA BARRE DES TRINKEURS PREND LA CARTE DE « MON COMPTE » : verre nuit (--card-2), contour
   blanc a 60 % d'un pixel (choisi sur planche : « garde le blanc moyen », applique aussi au menu de Mon compte), reflet
   en haut, plus de contour violet ni de lueur. La toile de l'accueil est mise a l'echelle
   (--mvs) : les epaisseurs sont divisees par elle pour rester d'un pixel reel, comme sur Mon compte. */
html body #mv-canvas .mv-trinq{background:var(--card-2);
  box-shadow:inset 0 0 0 calc(1px / var(--mvs,1)) var(--filet-verre),inset 0 calc(1px / var(--mvs,1)) 0 rgba(255,255,255,.08)}
html body #mv-canvas .mv-trinq::before{display:none}
/* v952 (Romain : « le bouton retour n'est pas encore modifié partout, par endroits il y a encore un cadre
   autour ») : toute flèche de retour prend la forme des 16 écrans de jeu, chevron crème nu, sans fond,
   contour ni ombre. Zones de toucher inchangées. Hors champ : les boutons texte « Retour » / « Revenir ». */
html body .iconbtn[id$="-back"],html body .iconbtn[id$="-back"]:active,html body .iconbtn[data-back],html body .iconbtn[data-back]:active,html body #cp-back,html body #s-compte .c-retour,html body #s-compte .c-retour:active{
  background:none!important;box-shadow:none!important;border:0!important;color:var(--c-texte)!important}
html body .iconbtn[id$="-back"],html body .iconbtn[data-back]{font-size:var(--t-5)!important;font-weight:400!important;line-height:1}
html body #cp-back svg,html body #s-compte .c-retour svg{stroke:#EFE9DF!important;width:22px!important;height:22px!important}
/* v953 (Romain : le haut du rond est coupé dans « Connectés récemment ») : la piste défile en x et coupe
   en y, et le ruban n'avait aucune marge haute ; le liseré de v951 (3 px hors du rond) passait dessous.
   4 px de marge haute dans le ruban, repris sur la carte : les ronds ne bougent pas d'un pixel. */
html body #s-multi .am-apercu{padding-top:var(--e-3)}
html body #s-multi .am-ruban{padding-top:var(--e-1)}
html body #s-amis .am-ruban{padding-top:var(--e-1)}
html body #s-amis .am-apercu{padding-top:var(--e-2)}
/* v954 (audit du 07/10, banc test-tailles-ecran) : le 29/09 l'etiquette du prenom est descendue a
   116 px dans quatorze mini-jeux, mais la place reservee sous la barre du haut etait restee a 56 px
   (calee sur l'ancienne position, 66 px). Sur iPhone SE et iPhone 14 dans Safari, l'etiquette mordait
   sur la consigne. La reserve suit desormais l'etiquette : 116 + 49 de haut - 62 de barre + 8 d'air.
   Les marges de consigne posees a la main pour les petits ecrans deviennent inutiles. */
body.badge-on:has(:is(#s-circle.on,#s-timing.on,#s-dix.on,#s-blind.on,#s-tap.on,#s-math.on,#s-intrus.on,#s-seq.on,#s-stroop.on,#s-vf.on,#s-wheel.on,#s-roulette.on,#s-casino.on,#s-bomb.on,#s-target.on)) .screen.on>.topbar{margin-bottom:111px!important}
html body #s-seq #sq-inst,html body #s-wheel #w-inst{margin-top:0!important}
/* v954, suite : la reserve monte de 55 px, les zones de jeu suivent la HAUTEUR pour que le bouton reste
   a l'ecran sur iPhone SE (553 px utiles dans Safari). Elasticite d'abord ; seule la roulette du casino,
   dessinee en pixels fixes, passe par un zoom sous 680 px. */
html body #s-wheel #wheel{width:min(80vw,344px,calc(100dvh - 370px))!important;min-width:170px}
html body #s-seq .sq-grille{width:min(76vw,300px,calc(100dvh - 365px));min-width:170px}
html body #s-roulette #cp-restant{margin-top:0}
html body #s-roulette .cp-grille{width:min(78vw,300px,calc((100dvh - 400px) * 1.2));min-width:190px}   /* 400 : la consigne (20/10) prend ~70 px */
@media (max-height:680px){html body #s-casino .roul-wrap{zoom:.86}}
@media (max-height:600px){html body #s-casino .roul-wrap{zoom:.7}}
/* v955 (audit, suite de v952) : la fleche de retour est nue partout, mais six « ? » de jeu gardaient
   leur cadre de verre a cote d'elle (Soiree, Classiques en partie, Vrai ou faux, Couleur piegee,
   Sequence, Palmier). Ils prennent la forme des dix-huit autres : glyphe creme, sans fond ni contour. */
html body :is(#s-game,#s-classic-run,#s-vf,#s-stroop,#s-seq) .topbar .iconbtn:not([id$="-back"]):not([data-back]),
html body #s-palmier #pm-aide{background:none!important;box-shadow:none!important;border:0!important;color:var(--c-texte)!important}
/* [08/10, audit] la toile reduite par la hauteur se centre (mvEchelle pose --mvx) ; et si meme a 80 %
   elle depasse, l'accueil defile au lieu de cacher ses boutons sous la barre. */
html body #mv-canvas{left:var(--mvx,0px)}
html body #s-home.menu-verre{overflow-y:auto}
/* [08/10, audit] sur les telephones courts, « Fermer » des regles tombait sous le bord de l'ecran : il
   fallait faire defiler une feuille dont on ne sait pas qu'elle defile. Le bouton reste colle au bas de
   la feuille, sur un fondu de la couleur du fond ; quand tout tient, il est a sa place habituelle. */
html body #m-rules #rules-close{position:sticky;bottom:calc(env(safe-area-inset-bottom,0px) + 4px);z-index:2;
  background:#16173C!important;box-shadow:inset 0 0 0 1px var(--filet-verre),0 -8px 10px 0 #0A0B27,0 14px 0 10px #0A0B27!important}
/* [08/10] le « ? » de l'etiquette du type : retire du nom du jeu le 13/10 (Romain), il vit desormais
   en bouton en haut a droite, dans les trois ecrans (regles en fin de feuille). */
/* [10/10, audit] ecrans courts (iPhone SE, 553 px utiles) : « Se connecter » passait 4 px sous la barre du bas
   sur l'ecran « Il te faut un compte ». L'embleme se reduit, les boutons ne bougent pas. */
@media (max-height:600px){ html body .vq-scene{width:120px;height:120px;margin-bottom:var(--e-3)} }

/* ══ [13/10, Romain] BOUTIQUE ET CADENAS ══════════════════════════════════════════════════════
   L'ecran prend le ciel de nuit des ecrans sans compte (selecteur ajoute a VERROU-NUIT, plus haut :
   une seule copie du ciel), leur barre de titre (.vq-titre), leur accroche (.vq-accroche) et la
   cascade d'entree (.vq-in). Les offres sont des tuiles de verre violet ; les boutons d'achat ont le
   traitement du bouton Quiz « Bientôt » de l'accueil (contour seul, fond retire).
   ⚠️ LA RESERVE DE LA BARRE EST SUR L'ID, PAS SUR LA CLASSE : `.screen.avec-barre` pese (0,2,0) et
      perdrait contre toute regle d'ecran posee par ID (lecon BARRE-05b). Elle est donc reecrite ici. */
#s-boutique{padding:calc(var(--e-2) + env(safe-area-inset-top,0px))
          calc(var(--e-3) + env(safe-area-inset-right,0px))
          calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + 74px)
          calc(var(--e-3) + env(safe-area-inset-left,0px))}
#s-boutique>#bq-body{display:flex;flex-direction:column;flex:1 0 auto}
/* [14/10 19 h 55] sur un téléphone court (714), la grande carte cède jusqu'à 26 px au lieu de faire défiler : élastique, pas de seuil */
#s-boutique>#bq-body:has(.bq-vip){flex:1 1 auto;min-height:0}
#bq-body .bq-vip{flex:1 1 auto;min-height:0}
#s-boutique .vq-titre{margin-bottom:var(--e-3)}
.bq-bloc{flex:1 0 auto;display:flex;flex-direction:column;justify-content:center;gap:0}
.bq-scene{position:relative;align-self:center;width:84px;height:84px;margin:0 0 var(--e-3);display:grid;place-items:center}
.bq-scene::before{content:'';position:absolute;inset:-60px;pointer-events:none;
  background:radial-gradient(circle at 50% 50%,rgba(139,92,246,.16) 0%,rgba(139,92,246,.06) 18%,rgba(139,92,246,.018) 36%,rgba(139,92,246,0) 64%)}
.bq-scene svg{position:relative;width:78px;height:78px;fill:none;stroke:#FCD34D;stroke-width:.9;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 9px rgba(252,211,77,.42)) drop-shadow(0 0 22px rgba(252,211,77,.15))}
.bq-accroche{margin-bottom:var(--e-3)}
.bq-accroche p{color:var(--c-texte-2)}
.bq-liste{list-style:none;margin:0 0 var(--e-3);padding:var(--e-2) var(--e-3);border-radius:var(--r-3);
  background:rgba(10,11,39,.55);box-shadow:inset 0 0 0 1px rgba(190,175,255,.22),inset 0 1px 0 rgba(255,255,255,.10)}
.bq-liste li{display:flex;align-items:center;gap:var(--e-3);padding:var(--e-2) 0}
.bq-liste li+li{border-top:1px solid rgba(190,175,255,.12)}
.bq-tu{flex:0 0 auto;width:34px;height:34px;border-radius:var(--r-1);display:grid;place-items:center;color:var(--c-texte);
  background:linear-gradient(180deg,#9A6BFF 0%,#6D3FE0 100%);box-shadow:var(--o-1),inset 0 1px 0 rgba(255,255,255,.20)}
.bq-tu svg{width:20px;height:20px;stroke-width:1.75}
.bq-tx{min-width:0;display:flex;flex-direction:column}
.bq-tx b{font-size:var(--t-2);font-weight:600;color:var(--c-texte);letter-spacing:-.01em}
.bq-tx small{margin-top:2px;font-size:var(--t-1);line-height:1.3;color:var(--c-texte-3)}
.bq-offres{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-3)}
.bq-offres.bq-seule{grid-template-columns:minmax(0,220px);justify-content:center;margin-bottom:var(--e-2)}
.bq-offre{min-width:0;display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--e-3) var(--e-2) var(--e-3);border-radius:var(--r-3);
  background:linear-gradient(180deg,rgba(124,82,255,.30) 0%,rgba(40,26,110,.42) 100%);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1.5px 0 rgba(255,255,255,.22),0 10px 24px -14px rgba(90,60,255,.8)}
.bq-nom{font-size:var(--t-1);font-weight:600;color:var(--c-texte-2);letter-spacing:-.005em}
.bq-prix{margin-top:var(--e-2);font-size:var(--t-5);font-weight:700;line-height:1;color:var(--c-texte);letter-spacing:-.03em}
.bq-rythme{margin-top:var(--e-1);font-size:var(--t-1);color:var(--c-texte-3)}
.bq-bientot{margin-top:var(--e-3);align-self:stretch;min-height:44px;display:grid;place-items:center;border-radius:var(--r-3);cursor:default;
  background:transparent;box-shadow:0 0 0 1.5px rgba(255,255,255,.35);color:rgba(255,255,255,.78);font-size:var(--t-2);font-weight:600}
.bq-note{margin:var(--e-3) 0 0;text-align:center;font-size:var(--t-1);color:var(--c-texte-3)}
.bq-choisir{margin-top:var(--e-3);align-self:stretch;min-height:44px;border:0;border-radius:var(--r-3);cursor:pointer;font:inherit;
  font-size:var(--t-2);font-weight:600;color:var(--c-texte);background:linear-gradient(180deg,#9A6BFF 0%,#6D3FE0 100%);
  box-shadow:0 8px 18px -10px rgba(90,60,255,.9),inset 0 1px 0 rgba(255,255,255,.22)}
.bq-choisir:disabled{opacity:.6;cursor:default}
/* [14/10] paiement ouvert : la case prend sa place, l'ecran se resserre comme sous 700 pt */
.bq-ouvert .bq-scene{width:60px;height:60px;margin-bottom:var(--e-2)} .bq-ouvert .bq-scene svg{width:56px;height:56px}
.bq-ouvert .bq-accroche{margin-bottom:var(--e-3)} .bq-ouvert .bq-accroche h2{font-size:var(--t-5)}
.bq-ouvert .bq-liste{margin-bottom:var(--e-2);padding:2px var(--e-3)} .bq-ouvert .bq-liste li{padding:var(--e-2) 0}
.bq-ouvert .bq-offre{padding:var(--e-2) var(--e-2) var(--e-2)} .bq-ouvert .bq-prix{font-size:var(--t-5)} .bq-ouvert .bq-choisir{margin-top:var(--e-2)}
.bq-ouvert .bq-note{margin-top:var(--e-2)}
#s-boutique:has(.bq-ouvert) .vq-titre{margin-bottom:var(--e-1)}
.bq-gerer{display:block;width:100%;min-height:44px;margin-top:var(--e-1);border:0;border-radius:var(--r-3);cursor:pointer;font:inherit;
  font-size:var(--t-2);font-weight:600;color:var(--c-texte);background:transparent;box-shadow:0 0 0 1.5px rgba(255,255,255,.35)}
.bq-gerer:disabled{opacity:.6;cursor:default}
/* [14/10 soir, Romain] LE PASS VIP (maquette retenue, IA/TRINKE/boutique/trinke-boutique-pass-vip-RETENUE.html) */
#s-boutique:has(.bq-vip) .vq-titre{margin-bottom:0;min-height:40px}
.bq-vip{flex:1 0 auto;display:flex;flex-direction:column;justify-content:flex-start;width:100%;max-width:24.375rem;margin:0 auto} /* [14/10 19 h 50, Romain : « les proportions »] largeur de la maquette (390), le bloc reste groupé sous le titre comme dans la maquette */
.bq-vip>*{flex-shrink:0}
.bq-vip-titre{text-align:center;font-size:var(--t-4);font-weight:800;letter-spacing:-.01em;color:var(--c-texte)}
.bq-vip-titre i{font-style:normal;background:linear-gradient(90deg,#F9A8D4,#A78BFA);-webkit-background-clip:text;background-clip:text;color:transparent}
.bq-sous{margin:var(--e-1) 0 0;text-align:center;color:var(--c-texte-3);font-size:var(--t-2);line-height:1.35}.bq-sous b{color:var(--c-texte)}
.bq-hero{position:relative;height:auto;flex:0 1 122px!important;min-height:96px;margin:var(--e-2) 0 var(--e-2);border-radius:var(--r-3);background:linear-gradient(160deg,#261a3d,#141018);box-shadow:inset 0 0 0 1.5px rgba(167,139,250,.5)}
.bq-hc{position:absolute;inset:16px 18px;opacity:0;transform:translateY(10px);transition:opacity .45s,transform .45s}
.bq-hc.on{opacity:1;transform:none}
.bq-hb{display:inline-block;font-size:var(--t-1);font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:var(--e-1) var(--e-2);border-radius:var(--r-1);color:var(--c);box-shadow:inset 0 0 0 1px var(--c)}
.bq-hc p{margin:var(--e-2) 0 0;font-size:var(--t-3);font-weight:700;line-height:1.22;color:var(--c-texte)}
.bq-ruban{overflow:hidden;margin:0 -18px var(--e-2);-webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.bq-piste{display:flex;gap:var(--e-2);width:max-content;animation:bqDefile 45s linear infinite}
@keyframes bqDefile{to{transform:translateX(-50%)}}
.bq-mi{width:auto;min-width:118px;white-space:nowrap;border-radius:var(--r-1);padding:var(--e-2) var(--e-2);background:#151319;box-shadow:inset 0 0 0 1px #2C2736,inset 3px 0 0 var(--c,#B69CFF);font-size:var(--t-1)}
.bq-mi small{display:block;font-size:var(--t-1);font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--c,#B69CFF);margin-bottom:var(--e-1)}
.bq-mi span{filter:blur(3.5px);color:var(--c-texte-3)}
.bq-mi[data-iris] small{background:linear-gradient(90deg,#FF9A5C,#A7EA6E,#7DB5EA,#A78BFA,#F472B6);-webkit-background-clip:text;background-clip:text;color:transparent}
.bq-plusmj{margin:var(--e-1) 0 var(--e-2);font-size:var(--t-2);font-weight:800;color:#FCD34D;text-align:center}
.bq-jeux{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--e-2);margin-bottom:var(--e-4)}
.bq-jeu{aspect-ratio:1;border-radius:var(--r-1);background:linear-gradient(150deg,#FCD34D,#B07A04);display:grid;place-items:center}
.bq-jeu svg{width:16px;height:16px;stroke:#2A1B02;fill:none;stroke-width:2.2;stroke-linecap:round}
.bq-brs{display:grid;grid-template-columns:1fr 1fr;gap:var(--e-2);margin:0 0 var(--e-2)}
.bq-br{position:relative;min-height:92px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:var(--e-3) var(--e-2) var(--e-2);border:0;border-radius:var(--r-3);
  cursor:pointer;font:inherit;text-align:center;color:var(--c-texte);background:linear-gradient(160deg,#3a3346,#231F2E);box-shadow:inset 0 0 0 1px #2C2736;-webkit-tap-highlight-color:transparent}
.bq-br.on{background:linear-gradient(160deg,#F5EFE6,#E3D8C6);color:#5B21B6;box-shadow:0 0 0 2px #fff,0 10px 30px -12px rgba(239,231,218,.35)}
.bq-br small{font-size:var(--t-1);font-weight:800;letter-spacing:.03em;text-transform:uppercase;white-space:nowrap}
.bq-px{display:block;margin-top:var(--e-1);font-size:var(--t-4);font-weight:800;line-height:1.1}
.bq-px s{text-decoration:none;display:block;font-size:var(--t-1);font-weight:600;opacity:.75;margin-top:1px;line-height:1.25}
.bq-pastille{position:absolute;top:-9px;left:50%;transform:translateX(-50%);white-space:nowrap;font-size:var(--t-1);font-weight:800;padding:var(--e-1) var(--e-2);border-radius:var(--r-1);background:#EC4899;color:var(--c-texte);z-index:2}
.bq-brc{position:relative;display:block;align-self:stretch;flex:0 0 18px;height:18px;margin:0 6px var(--e-2);border-radius:var(--r-1);
  background:repeating-linear-gradient(135deg,rgba(255,255,255,.22) 0 4px,transparent 4px 9px),linear-gradient(90deg,#EC4899,#8B5CF6);box-shadow:inset 0 0 0 1px rgba(0,0,0,.15);transition:filter .3s,opacity .3s}
.bq-brc i{position:absolute;right:12px;top:-3px;width:14px;height:24px;border-radius:var(--r-1);background:linear-gradient(180deg,#FDE68A,#E0A40C 55%,#A86F04);box-shadow:0 1px 3px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.5)}
.bq-brc.argent i{background:linear-gradient(180deg,#FFFFFF,#C9CDD6 50%,#8A909C)}
.bq-brc em{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-style:normal;font-size:var(--t-1);font-weight:900;letter-spacing:.16em;color:var(--c-texte);line-height:1}
.bq-br:not(.on) .bq-brc{filter:grayscale(1);opacity:.8}
.bq-cta{display:grid;place-items:center;width:100%;min-height:44px;border:0;border-radius:var(--r-3);font:inherit;font-size:var(--t-2);font-weight:700;
  background:#EFE7DA;color:#5B21B6;box-shadow:0 10px 24px -10px rgba(239,231,218,.35),inset 0 1px 0 rgba(255,255,255,.25);margin:0}
button.bq-cta{cursor:pointer}
.bq-bientot.bq-cta{opacity:.55;cursor:default}
.bq-vip{--m1:#FDE68A;--m2:#E0A40C;--m3:#A86F04}
.bq-vip[data-choix=argent]{--m1:#FFFFFF;--m2:#C9CDD6;--m3:#8A909C}
.bq-vip .bq-cta{position:relative;box-shadow:0 0 0 2.5px var(--m2);transition:box-shadow .2s ease}
.bq-lingot{position:absolute;right:18px;top:50%;width:14px;height:24px;margin-top:-12px;border-radius:var(--r-1);background:linear-gradient(180deg,var(--m1),var(--m2) 55%,var(--m3));box-shadow:0 1px 3px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.5)}
.bq-vip .bq-note{margin:var(--e-2) 0 0;font-size:var(--t-1);color:var(--c-texte-3)}
@media (prefers-reduced-motion:reduce){.bq-piste{animation:none}}
@media (max-height:700px){ .bq-scene{width:60px;height:60px;margin-bottom:var(--e-2)} .bq-scene svg{width:56px;height:56px}
  .bq-accroche{margin-bottom:var(--e-3)} .bq-accroche h2{font-size:var(--t-5)} .bq-liste{margin-bottom:var(--e-3);padding:2px var(--e-3)} .bq-liste li{padding:var(--e-2) 0}
  .bq-prix{font-size:var(--t-5)} .bq-bientot{margin-top:var(--e-2)} #s-boutique .vq-titre{margin-bottom:var(--e-2)} }
/* ⚠️ LE CADENAS EST DISCRET ET NE DEPLACE RIEN : pose en absolu dans le coin du contenu verrouille,
   il ne change ni sa taille ni la place de son texte. Le contenu reste lisible (opacite .75 a .78), le
   cadenas dit le reste ; l'information ne repose donc pas sur la couleur seule. */
.verrouille{position:relative}
html body .verrouille>svg.cadenas{position:absolute;top:7px;right:8px;width:14px;height:14px;margin:0;
  fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;opacity:.9;pointer-events:none}
html body .sreg-seg button.verrouille>svg.cadenas{top:4px;right:5px;width:12px;height:12px}
html body .jeu.verrouille>svg.cadenas{top:10px;right:10px;stroke:#CFC9DA}
html body .jeu.verrouille>b, html body .jeu.verrouille>small, html body .jeu.verrouille>svg:first-child{opacity:.78}
html body .sav-cel.verrouille .sav-nom, html body .sav-cel.verrouille .sav-case{opacity:.75}
html body .sreg-seg button.verrouille{color:rgba(255,255,255,.78)}

/* ══ AMIS-PISTE-A (v969, Romain 13/10) ═══════════════════════════════════════════════════════════
   L'onglet Amis porte les maquettes du 13/10 (Desktop/IA/TRINKE/amis-2026-10-13) : liste = piste A,
   ecran sans ami = carte de la piste B sans la rangee « Ta bande », ajouter un ami = piste A. Jetons
   de la DA du 07/10 : verre nuit rgba(10,11,39,.62), filet lavande .28, separateurs .16, lavande
   #C4B5FD, plein violet-bleu pour les commandes. Classes `ax-` neuves pour ne rien heriter des
   couches precedentes de la liste (mu-liste, am-apercu, mu-barre).
   ⚠️ LES HUIT TEINTES D'AMI SE DISTINGUENT A NOUVEAU (elles etaient toutes #15163A depuis le 07/10) :
      un rond par ami, sur l'arc 205-250, degrade clair vers fonce, initiale blanche. Le filet blanc
      et l'anneau de v951 lisent --ami-fond, donc l'anneau prend la teinte du joueur. */
html body :is(#s-amis,#s-multi) .am-av{background-image:linear-gradient(160deg,var(--ami-hi,var(--ami-fond)),var(--ami-lo,var(--ami-fond)));color:var(--ami-encre)}

/* ── la barre de titre : celle de la Boutique, 44 de haut, titre 21/600 centre, bouton a droite */
html body #s-multi.racine>.topbar{grid-template-columns:44px minmax(0,1fr) 44px;margin-bottom:var(--e-3)}
html body #s-multi.racine>.topbar>#mu-title{font-size:var(--t-4);font-weight:600;letter-spacing:-.01em;text-shadow:none}
html body #s-multi.racine>.topbar>.mu-act{min-width:0;justify-self:end}
html body #s-multi .ax-ico{width:40px;height:40px;border:0;border-radius:var(--r-2);display:grid;place-items:center;padding:0;cursor:pointer;
  position:relative;color:#C4B5FD;background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .ax-ico::after{content:'';position:absolute;inset:-2px}
html body #s-multi .ax-ico:active{transform:scale(.95)}
html body #s-multi .ax-ico svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* ── intitule de section : un seul style dans tout l'ecran */
html body :is(#s-multi,#s-amis) .ax-lab,html body #s-amis #am-res-zone .am-lab{display:flex;align-items:center;justify-content:space-between;
  font-size:var(--t-1);font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--c-texte-3);margin:0 4px var(--e-2);min-height:22px}
html body :is(#s-multi,#s-amis) .ax-n{color:#C4B5FD;letter-spacing:.04em}
html body #s-multi .ax-nouvelle{display:flex;align-items:center;gap:var(--e-2);border:0;background:none;padding:0;margin:-11px -4px -11px 0;
  min-height:44px;font:inherit;text-transform:none;letter-spacing:0;font-size:var(--t-2);font-weight:600;color:#C4B5FD;cursor:pointer}
html body #s-multi .ax-nouvelle svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
html body #s-multi .ax-bloc{margin-bottom:var(--e-4)}

/* ── le verre : un contenant, un filet */
html body #s-multi .ax-verre,html body #s-amis #am-res-zone .am-groupe{border-radius:var(--r-2);overflow:hidden;
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012)),rgba(10,11,39,.62);
  box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08),0 20px 40px -18px rgba(0,0,0,.8)}

/* ── la recherche : UN seul filet, celui de la capsule */
html body #s-multi .ax-rech{display:flex;align-items:center;gap:var(--e-2);height:46px;padding:0 var(--e-3);margin-bottom:var(--e-4);border-radius:var(--r-2);
  background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-multi .ax-rech:focus-within{box-shadow:inset 0 0 0 1px #fff,0 0 0 3px rgba(120,80,255,.22)}
html body #s-multi .ax-rech svg{width:19px;height:19px;flex:none;fill:none;stroke:#A8A0BA;stroke-width:1.8;stroke-linecap:round}
html body #s-multi .ax-rech:focus-within svg{stroke:#C4B5FD}
html body #s-multi .ax-rech input{flex:1;min-width:0;height:44px;border:0;outline:none;background:none;box-shadow:none;padding:0;
  font:inherit;font-size:1rem;color:var(--c-texte);-webkit-appearance:none;appearance:none}
html body #s-multi .ax-rech input::placeholder{color:var(--c-texte-3)}

/* ── Tes amis : cinq ronds par largeur, rien de coupe (4 px d'air pour le filet et l'anneau) */
html body #s-multi .ax-amis{display:flex;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;margin:-4px -4px var(--e-4);padding:var(--e-1) var(--e-1) 2px;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
html body #s-multi .ax-amis::-webkit-scrollbar{display:none}
html body #s-multi .ax-ami{flex:0 0 20%;min-width:62px;display:flex;flex-direction:column;align-items:center;gap:var(--e-2);padding:0 2px;
  border:0;background:none;font:inherit;cursor:pointer;color:var(--c-texte-3)}
html body #s-multi .ax-ami b{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--t-1);font-weight:500;color:var(--c-texte-3)}
html body #s-multi .ax-ami.on b{font-weight:600;color:var(--c-texte-2)}
html body #s-multi .ax-ami:active .ax-av{transform:scale(.95)}
html body #s-multi .ax-ami .ax-av{width:54px;height:54px;font-size:var(--t-4)}
html body :is(#s-multi,#s-amis) .ax-av{position:relative;flex:none;border-radius:50%;display:grid;place-items:center;font-weight:700}
html body :is(#s-multi,#s-amis) .ax-av .am-dessin{display:block;width:100%;height:100%;border-radius:50%;overflow:hidden}
html body :is(#s-multi,#s-amis) .ax-pr{position:absolute;right:-1px;bottom:-1px;width:28%;height:28%;min-width:11px;min-height:11px;border-radius:50%;
  background:#34D399;box-shadow:0 0 0 2.5px #0A0B27}

/* ── À traiter : demandes et invitations, meme rangee, memes deux ronds */
html body #s-multi .ax-ligne{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--e-3);padding:var(--e-3) var(--e-3);position:relative}
html body #s-multi .ax-ligne+.ax-ligne::before{content:'';position:absolute;left:16px;right:0;top:0;height:1px;background:rgba(190,175,255,.16)}
html body #s-multi .ax-ligne .ax-av{width:44px;height:44px;font-size:var(--t-3)}
html body #s-multi .ax-grp{background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre);color:#C4B5FD}
html body #s-multi .ax-grp svg{width:58%;height:58%;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
html body #s-multi .ax-txt{min-width:0}
html body #s-multi .ax-txt b{display:block;font-size:var(--t-2);font-weight:600;color:var(--c-texte);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-multi .ax-txt span{display:block;margin-top:2px;font-size:var(--t-2);color:var(--c-texte-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-multi .ax-acts{display:flex;gap:var(--e-2)}
html body #s-multi .ax-rond{position:relative;width:38px;height:38px;border:0;padding:0;border-radius:50%;display:grid;place-items:center;flex:none;cursor:pointer}
html body #s-multi .ax-rond::after{content:'';position:absolute;inset:-3px}
html body #s-multi .ax-rond svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
html body #s-multi .ax-rond.oui{color:var(--c-texte);background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 6px 14px -6px rgba(90,60,255,.7)}
html body #s-multi .ax-rond.non{color:var(--c-texte-3);background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre)}
html body #s-multi .ax-rond:active{transform:scale(.94)}
html body #s-multi .ax-rond:disabled{opacity:.5}

/* ── Discussions : la rangee sans rond (LISTE-SANS-ROND garde), point lavande pour le non-lu */
html body #s-multi .ax-disc .mu-fil{display:grid;grid-template-columns:minmax(0,1fr) auto 14px;column-gap:var(--e-2);row-gap:var(--e-1);align-items:center;
  width:100%;min-height:0;margin:0;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);border:0;border-radius:0;background:none;box-shadow:none;text-align:left;position:relative}
html body #s-multi .ax-disc .mu-fil::after{content:none}
html body #s-multi .ax-disc .mu-fil+.mu-fil::before{content:'';position:absolute;left:18px;right:0;top:0;height:1px;background:rgba(190,175,255,.16);transform:none}
html body #s-multi .ax-disc .mu-fil>.mu-ava{display:none}
html body #s-multi .ax-disc .mu-fil>.mu-tete{grid-area:1/1/2/2;display:flex;align-items:baseline;gap:var(--e-2);min-width:0}
html body #s-multi .ax-disc .mu-fil>.mu-heure{grid-area:1/2/2/3;display:flex;align-items:center;gap:var(--e-2);font-size:var(--t-1);font-weight:400;color:var(--c-texte-3)}
html body #s-multi .ax-disc .mu-fil>.mu-ch{grid-area:1/3/3/4;width:8px;height:14px;justify-self:center;stroke:#8A82A6}
html body #s-multi .ax-disc .mu-fil>.mu-ligne{grid-area:2/1/3/3;margin:0;min-width:0}
html body #s-multi .ax-disc .mu-fil .mu-nom{font-size:var(--t-2);font-weight:600;color:var(--c-texte-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-multi .ax-disc .mu-fil .ax-nb{flex:none;font-size:var(--t-1);font-weight:500;color:var(--c-texte-3)}
html body #s-multi .ax-disc .mu-fil .mu-ligne span{display:block;font-size:var(--t-2);color:var(--c-texte-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html body #s-multi .ax-disc .mu-fil.nl{background:none}
html body #s-multi .ax-disc .mu-fil.nl .mu-nom{color:var(--c-texte)}
html body #s-multi .ax-disc .mu-fil.nl .mu-ligne span{color:var(--c-texte-2)}
html body #s-multi .ax-disc .mu-fil.nl .mu-heure{color:#C4B5FD}
html body #s-multi .ax-disc .mu-fil.nl .mu-heure::after{content:'';width:8px;height:8px;border-radius:50%;background:#C4B5FD}
html body #s-multi .ax-disc .mu-fil:active{background:rgba(120,80,255,.12)}

/* ── sans ami : la carte de la piste B, puis le pseudo a donner */
html body #s-multi .ax-hero{position:relative;overflow:hidden;margin-bottom:var(--e-4);padding:var(--e-4) var(--e-4) var(--e-4);border-radius:var(--r-3);text-align:center;
  background:radial-gradient(80% 60% at 70% 0%,rgba(164,104,238,.35),transparent 70%),linear-gradient(160deg,#1A1250 0%,#0D0B30 60%,#090A26 100%);
  box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.18),0 24px 50px -20px rgba(90,60,255,.65)}
html body #s-multi .ax-ronds{position:relative;height:96px;display:flex;justify-content:center;align-items:center;margin-bottom:var(--e-3)}
html body #s-multi .ax-ronds>span{margin:0 -10px;border-radius:50%;display:grid;place-items:center;font-weight:700}
html body #s-multi .ax-f{width:62px;height:62px;font-size:var(--t-4);font-weight:600!important;color:var(--c-texte-3);background:rgba(10,11,39,.8);
  box-shadow:0 0 0 1.5px rgba(190,175,255,.55)}
html body #s-multi .ax-moi{position:relative;z-index:2;width:76px;height:76px;font-size:var(--t-5);color:#170B20;overflow:hidden;
  background:linear-gradient(180deg,#A788FF 0%,#8B5CF6 100%);box-shadow:0 0 0 1.5px rgba(250,249,252,.95),0 0 0 3px #8B5CF6}
html.teinte body #s-multi .ax-moi{background:linear-gradient(180deg,var(--av-hi) 0%,var(--av-lo) 100%);box-shadow:0 0 0 1.5px rgba(250,249,252,.95),0 0 0 3px var(--av-lo)}
html body #s-multi .ax-moi .am-dessin{display:block;width:100%;height:100%}
html body #s-multi .ax-ronds em{position:absolute;display:block}
html body #s-multi .ax-ronds em svg{width:100%;height:100%;fill:#E9DDFF;stroke:none;filter:drop-shadow(0 0 5px rgba(190,160,255,.9))}
html body #s-multi .ax-ronds .e1{left:calc(50% - 132px);top:2px;width:15px;height:15px}
html body #s-multi .ax-ronds .e2{left:calc(50% + 78px);top:12px;width:10px;height:10px}
html body #s-multi .ax-ronds .e3{left:calc(50% + 91px);bottom:0;width:17px;height:17px}
html body #s-multi .ax-hero h2{margin:0 0 var(--e-2);font-size:var(--t-4);font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--c-texte)}
html body #s-multi .ax-hero p{margin:0 4px var(--e-4);font-size:var(--t-2);line-height:1.45;color:var(--c-texte-2)}
html body #s-multi .ax-btn{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--e-2);height:52px;border:0;border-radius:var(--r-4);cursor:pointer;
  font:inherit;font-size:var(--t-3);font-weight:600;color:var(--c-texte);
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.40),
             inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(90,60,255,.75)}
html body #s-multi .ax-btn:active{transform:scale(.985)}
html body #s-multi .ax-btn svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
html body #s-multi .ax-pseudo{margin:0;text-align:center;font-size:var(--t-2);color:var(--c-texte-3)}
html body #s-multi .ax-pseudo b{color:#C4B5FD;font-weight:600}

/* ── Ajouter un ami (piste A) : chevron nu (v952), un seul filet sur le champ, aide, resultats en verre */
html body #s-amis .am-entete{grid-template-columns:44px 1fr 44px;min-height:44px;margin-bottom:var(--e-3)}
html body #s-amis .am-entete h1{font-size:var(--t-4);font-weight:600;letter-spacing:-.01em}
html body #s-amis .am-retour,html body #s-amis .am-retour:active{width:44px;height:44px;margin:0;background:none!important;border:0!important;
  box-shadow:none!important;color:var(--c-texte);display:grid;place-items:center;transform:none}
html body #s-amis .am-retour svg{width:22px!important;height:22px!important;stroke:#EFE9DF!important;stroke-width:2!important}
html body #s-amis .am-champ{height:46px;min-height:46px;margin:0 0 var(--e-2);padding:0 var(--e-3);gap:var(--e-2);border:0;border-radius:var(--r-2);
  background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px var(--filet-verre),inset 0 1px 0 rgba(255,255,255,.08)}
html body #s-amis .am-champ:focus-within{box-shadow:inset 0 0 0 1px #fff,0 0 0 3px rgba(120,80,255,.22)}
html body #s-amis .am-champ svg{width:19px;height:19px;stroke:#A8A0BA}
html body #s-amis .am-champ:focus-within svg{stroke:#C4B5FD}
html body #s-amis .am-champ input,html body #s-amis .am-champ input:focus,html body #s-amis .am-champ input:focus-visible{height:44px;min-height:0;margin:0;padding:0;
  border:0!important;border-radius:0;outline:none!important;background:none!important;box-shadow:none!important;font-size:1rem;color:var(--c-texte)}
html body #s-amis .ax-aide{margin:0 4px var(--e-4);font-size:var(--t-1);line-height:1.4;color:var(--c-texte-3)}
html body #s-amis #am-res-zone .am-lab svg{display:none}
html body #s-amis #am-res-zone .am-lab{padding:0}
html body #s-amis #am-res-zone .am-groupe{display:block;padding:0;gap:0}
html body #s-amis #am-res-zone .am-res{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:var(--e-3);margin:0;
  padding:var(--e-3) var(--e-3);min-height:0;border:0;border-radius:0;background:none;box-shadow:none;position:relative}
html body #s-amis #am-res-zone .am-res+.am-res::before{content:'';position:absolute;left:16px;right:0;top:0;height:1px;background:rgba(190,175,255,.16)}
html body #s-amis #am-res-zone .am-res::after{content:none}
html body #s-amis #am-res-zone .am-res .am-av{width:44px;height:44px;font-size:var(--t-3)}
html body #s-amis #am-res-zone .am-res b{font-size:var(--t-2);font-weight:600;color:var(--c-texte)}
html body #s-amis #am-res-zone .am-etat{height:34px;min-height:0;padding:0 var(--e-3);border:0;border-radius:var(--r-3);font-size:var(--t-2);font-weight:600;gap:var(--e-2)}
html body #s-amis #am-res-zone .am-etat svg{width:15px;height:15px;stroke-width:2.2}
html body #s-amis #am-res-zone .am-etat.oui{color:var(--c-texte);background:linear-gradient(135deg,#A468EE 0%,#6A3BFC 55%,#3528FB 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 6px 14px -6px rgba(90,60,255,.7)}
html body #s-amis #am-res-zone .am-etat.fait{color:#C4B5FD;background:rgba(120,80,255,.12);box-shadow:inset 0 0 0 1px var(--filet-verre)}
html body #s-amis #am-res-zone .am-deja{padding:0 var(--e-1);font-size:var(--t-2);font-weight:600;color:var(--c-texte-3)}
/* ── marges : 22 de chaque cote, celles des maquettes, sur la liste et sur « Ajouter un ami » */
html body #s-multi.racine{padding-left:calc(var(--e-3) + env(safe-area-inset-left,0px));padding-right:calc(var(--e-3) + env(safe-area-inset-right,0px))}
html body #s-multi.racine>#mu-body{padding-left:var(--e-1);padding-right:var(--e-1)}
html body #s-multi.racine>.topbar{padding-left:var(--e-1);padding-right:var(--e-1)}
html body #s-amis:has(#am-pseudo){padding-left:calc(var(--e-4) + env(safe-area-inset-left,0px));padding-right:calc(var(--e-4) + env(safe-area-inset-right,0px))}
/* ── cotes verticales relevees contre les maquettes (meme navigateur, 390 x 844) */
html body #s-multi.racine{padding-top:calc(var(--e-3) + env(safe-area-inset-top,0px))}
html body #s-multi.racine>.topbar{height:44px;min-height:44px}
html body #s-multi .ax-rech{box-sizing:border-box;min-height:46px;flex:none}
html body :is(#s-multi,#s-amis) .ax-lab,html body #s-amis #am-res-zone .am-lab{min-height:0;line-height:15px;align-items:baseline}
html body #s-multi .ax-nouvelle{margin:-12px -4px -12px 0;line-height:20px}
html body #s-multi .ax-amis{padding:var(--e-2) var(--e-1) 0;margin-bottom:var(--e-4)}
html body #s-multi .ax-ami b{line-height:16px}
html body #s-multi .ax-txt b,html body #s-amis #am-res-zone .am-res b{line-height:19px}
html body #s-multi .ax-txt span{line-height:17px}
html body #s-multi .ax-disc .mu-fil .mu-nom{line-height:19px}
html body #s-multi .ax-disc .mu-fil .mu-ligne span{line-height:17px;font-weight:400}
html body #s-multi .ax-disc .mu-fil .mu-heure{line-height:15px}
html body #s-multi .ax-hero h2{line-height:28px}
html body #s-multi .ax-hero p{line-height:22px}
html body #s-multi .ax-pseudo{line-height:17px}
html body #s-amis:has(#am-pseudo){padding-top:calc(var(--e-3) + env(safe-area-inset-top,0px))}
html body #s-amis .am-entete{height:44px;margin-top:0}
html body #s-amis .ax-aide{line-height:18px}
/* ⚠️ #mu-body est une colonne flexible qui defile : sans flex-shrink:0, a hauteur d'ecran reelle,
   les intitules et les prenoms s'ecrasaient (releve : « Tes amis » a 4 px, prenoms a 0). */
html body #s-multi.racine>#mu-body{padding-top:0}
html body #s-multi.racine>#mu-body>*{flex-shrink:0}
html body #s-amis #am-res-zone .am-res .am-txt{margin:0;padding:0;line-height:19px}
html body #s-multi .ax-disc .mu-fil .mu-ligne span{line-height:16px}
html body #s-multi .ax-amis{margin:-4px -2px var(--e-4);padding:var(--e-2) var(--e-1) 0;gap:calc((100% - 290px) / 4)}
html body #s-multi .ax-ami{flex:0 0 58px;min-width:58px;padding:0}
html body #s-multi .ax-disc .mu-fil .mu-tete{line-height:19px;height:19px}
html body #s-multi .ax-disc .mu-fil .ax-nb{line-height:15px}
html body #s-amis #am-res-zone .am-res .am-txt{min-height:0;height:auto;display:block}
html body #s-amis #am-res-zone .am-res .am-txt b{margin:0;padding:0}
html body #s-multi .ax-disc .mu-fil>.mu-ligne{display:block;height:16px;min-height:0;line-height:16px;overflow:hidden}
html body #s-multi .ax-hero h2{text-wrap:balance}
@media (max-width:380px){ html body #s-multi .ax-hero h2{font-size:var(--t-4)} html body #s-multi .ax-hero{padding-left:var(--e-3);padding-right:var(--e-3)} }
/* AMIS-PISTE-A:FIN */

/* [13/10, Romain] le « ? », rond jumeau de « passer la carte », juste a sa gauche : Soiree et Classiques
   partagent le meme « passer » (et donc le meme « ? »), deplace d'une barre a l'autre */
html body :is(#s-game,#s-classic-run) .card-aide{right:58px;font-size:var(--t-3);font-weight:700;line-height:1;color:var(--ink)}
html body :is(#s-game,#s-classic-run)>.topbar>#c-aide{position:relative;right:auto;top:auto;grid-column:3;grid-row:1;justify-self:end;margin-right:40px;
  width:36px;height:36px;background:none!important;border:0!important;box-shadow:none!important;color:var(--c-texte)!important;font-size:var(--t-4);font-weight:600}
html body :is(#s-game,#s-classic-run)>.topbar>#c-passer{grid-row:1}
/* [13/10, Romain] en Multijoueur il n'y a pas de « passer » : le « ? » se pose en haut a droite, a gauche
   de « Terminer » / « Quitter », meme glyphe et meme taille qu'en Soiree. Cible tactile 44 px par ::after. */
html body #s-multi .mu-act{align-items:center;gap:var(--e-1)}
html body #s-multi .mu-act>#mp-aide{position:relative;flex:0 0 auto;width:36px;height:36px;padding:0;display:grid;place-items:center;
  background:none!important;border:0!important;box-shadow:none!important;color:var(--c-texte)!important;font:inherit;font-size:var(--t-4);font-weight:600;line-height:1;cursor:pointer}
html body #s-multi .mu-act>#mp-aide::after{content:'';position:absolute;inset:-4px}
/* [13/10] aux Classiques, le titre long touchait le « ? » et se lisait « LES CLASSIQUES ? » :
   lettres moins espacees et corps un peu plus petit, pour laisser un vrai blanc avant le bouton */
html body #s-classic-run[data-carte] .jn-titre{letter-spacing:.08em;font-size:var(--t-3)}

/* ═══ [14/10, Romain] LA SOIREE PREND VIE ═══════════════════════════════════════════════
   Maquette B validee (colonne « Sans cadre, mais vivant »), charte DA sections 4 et 5.
   Tout est borne a #s-game : les Classiques, les mini-jeux et le Multijoueur ne changent pas.
   [14/10, Romain] v977 : LES CLASSIQUES PRENNENT VIE A LEUR TOUR. Les memes regles servent
   #s-classic-run par `:is(#s-game,#s-classic-run)`, pas une seconde copie : un `:is()` prend la
   specificite de son identifiant, aucune regle ne change de rang (meme choix que le cadre commun
   du 08/08). La jauge y passe aussi a scaleY(3), sinon le banc test-cadre-identique mesurait
   3 px d'un cote et 0 de l'autre. Le coup de theatre, plus bas, reste borne a #s-game.
   Les jeux longs (Purple, la course des As, le Palmier) ont leurs propres ecrans : non touches.
   Pas de color-mix ici (Safari d'avant 16.2 jette la declaration) : les teintes viennent des
   variables de famille deja posees (--pf, --pf-halo, --pf-lueur). */
html body :is(#s-game,#s-classic-run){isolation:isolate}

/* 1. Changement de carte. La sortie (220 ms, vers le haut, floue) est posee par app.js avant le
   geste ; l'entree (460 ms depuis le bas) est decalee en trois temps : type, phrase, sanction.
   Les images-cles d'entree n'ont pas de « to » : chaque objet revient a SA valeur de repos,
   aucun transform ni filtre propre n'est ecrase une fois l'entree finie. Remplissage `backwards`
   et non `both` : fini, l'objet ne garde rien de l'animation (WebKit laissait un `blur(0px)` colle). */
@keyframes vieSort{to{opacity:0;transform:translateY(-26px);filter:blur(8px)}}
@keyframes vieEntre{from{opacity:0;transform:translateY(34px);filter:blur(6px)}}
@keyframes vieNombre{0%{opacity:0;transform:scale(.4)}70%{opacity:1;transform:scale(1.15)}}
html body :is(#s-game,#s-classic-run) .gamecard.vie-sort>*{animation:vieSort var(--m-court) var(--m-depart) both}
html body :is(#s-game,#s-classic-run) .gamecard.anim.anim .tag{animation:vieEntre var(--m-moyen) var(--m-sortie) backwards}
html body :is(#s-game,#s-classic-run) .gamecard.anim.anim :is(.cardtext,.g-turn,.jn-choix,.jn-av,.jn-chrono,.reveal){animation:vieEntre var(--m-moyen) var(--m-sortie) .07s backwards}
html body :is(#s-game,#s-classic-run) .gamecard.anim.anim :is(.jn-cond,.jn-trait,.jn-valeur,.sanction,.designe){animation:vieEntre var(--m-moyen) var(--m-sortie) .14s backwards}
html body :is(#s-game,#s-classic-run) .gamecard.anim.anim .jn-valeur>b{display:inline-block;animation:vieNombre .5s cubic-bezier(.2,.7,.3,1) .38s backwards}

/* la lueur du type qui pulse une fois (620 ms) ; au repos elle est invisible, la nappe du fond
   (G2) reste la seule lueur permanente */
html body :is(#s-game,#s-classic-run)>.vie-lueur{position:absolute;left:50%;top:46%;width:130vmin;height:130vmin;z-index:-1;pointer-events:none;
  border-radius:50%;transform:translate(-50%,-50%);opacity:0;
  background:radial-gradient(closest-side,var(--pf-lueur,rgba(110,70,255,.30)),transparent)}
html body :is(#s-game,#s-classic-run)>.vie-lueur.pulse{animation:viePulse .62s cubic-bezier(.2,.7,.3,1)}
@keyframes viePulse{0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}45%{opacity:1;transform:translate(-50%,-50%) scale(1.08)}100%{opacity:0;transform:translate(-50%,-50%) scale(1)}}

/* 2. Le prenom vise, mis en lumiere par une lueur de la couleur du type, sans gras de plus */
html body :is(#s-game,#s-classic-run) .vie-prenom{color:var(--c-texte);text-shadow:0 0 14px var(--pf-halo,rgba(90,60,255,.75)),0 0 2px #fff}

/* 3. La rangee des joueurs : ronds creme (matiere de la barre Trinkeurs), initiale a l'encre. 26 px et
   non les 30 de la barre Trinkeurs : sous 700 pt de haut, l'etiquette du type n'est qu'a 46 px sous la
   jauge, et un rond de 30 la touchait presque.
   Hors de la colonne (position absolue, `top` pose par app.js sous la jauge). */
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee{position:absolute;left:18px;right:18px;top:0;z-index:2;display:flex;justify-content:center;gap:var(--e-2);pointer-events:none}
html body :is(#s-game,#s-classic-run):not([data-carte])>.vie-rangee{display:none!important}
html body :is(#s-game,#s-classic-run,.gscreen) .vie-av{flex:0 0 auto;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  font-weight:800;font-size:var(--t-1);line-height:1;color:#2A2431;
  background:linear-gradient(160deg,#F6EFE2,#E3D9C8 55%,#D4C8B3);opacity:.45;
  transition:opacity .45s cubic-bezier(.2,.7,.3,1),transform .45s cubic-bezier(.2,.7,.3,1),box-shadow .45s cubic-bezier(.2,.7,.3,1)}
html body :is(#s-game,#s-classic-run,.gscreen) .vie-av.tous{opacity:1;box-shadow:0 0 0 2px var(--pf,#8B5CF6)}
html body :is(#s-game,#s-classic-run,.gscreen) .vie-av.vise{opacity:1;transform:scale(1.18);position:relative;z-index:1;
  box-shadow:0 0 0 2px var(--pf,#8B5CF6),0 0 16px var(--pf-halo,rgba(90,60,255,.75))}
/* quand la rangee ne tient plus sur la largeur (8 ronds des 320 px), les ronds se chevauchent comme
   sur la barre Trinkeurs ; le chevauchement (--vie-chev) est calcule par app.js pour la largeur reelle */
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre{gap:0}
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre>.vie-av{margin-left:calc(-1 * var(--vie-chev,8px));box-shadow:0 0 0 1.5px #0A0816}
/* chevauches, des ronds translucides laisseraient lire l'initiale du voisin a travers : on les eteint
   par la luminosite, ils restent opaques */
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre>.vie-av:not(.vise):not(.tous){opacity:1;filter:brightness(.42)}
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre>.vie-av:first-child{margin-left:0}
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre>.vie-av.tous{box-shadow:0 0 0 1.5px #0A0816,0 0 0 3px var(--pf,#8B5CF6)}
html body :is(#s-game,#s-classic-run,.gscreen)>.vie-rangee.serre>.vie-av.vise{box-shadow:0 0 0 2px var(--pf,#8B5CF6),0 0 16px var(--pf-halo,rgba(90,60,255,.75))}

/* 4. La jauge se voit : 3 px au lieu d'un filet d'un pixel physique, et elle avance en 500 ms.
   ⚠️ LA BOITE GARDE SON PIXEL, C'EST LE DESSIN QUI S'EPAISSIT (scaleY(3) au lieu de scaleY(.34)) :
      une boite de 3 px poussait la carte de 2 px vers le bas, et le cadre ne serait plus celui des
      Classiques (test-cadre-identique). Ainsi seul le trait change, rien ne bouge dessous. */
html body :is(#s-game,#s-classic-run)[data-carte]>.progress{transform:scaleY(3)}
html body :is(#s-game,#s-classic-run)[data-carte]>.progress>span{transition:width .5s cubic-bezier(.2,.7,.3,1)}

/* 5. prefers-reduced-motion : aucun mouvement, le contenu s'affiche directement */
@media (prefers-reduced-motion:reduce){
  html body :is(#s-game,#s-classic-run) .gamecard.vie-sort>*,
  html body :is(#s-game,#s-classic-run) .gamecard.anim.anim :is(.tag,.cardtext,.g-turn,.jn-choix,.jn-av,.jn-chrono,.reveal,.jn-cond,.jn-trait,.jn-valeur,.sanction,.designe),
  html body :is(#s-game,#s-classic-run) .gamecard.anim.anim .jn-valeur>b,
  html body :is(#s-game,#s-classic-run)>.vie-lueur.pulse{animation:none!important}
  html body :is(#s-game,#s-classic-run,.gscreen) .vie-av,html body :is(#s-game,#s-classic-run,.gscreen)[data-carte]>.progress>span{transition:none!important}
}
/* le temps 1 d'« Action ou vérité » nomme la personne : meme lueur que dans la phrase */
html body :is(#s-game,#s-classic-run) .jn-av .jn-prenom{text-shadow:0 0 14px var(--pf-halo,rgba(90,60,255,.75)),0 0 2px #fff}

/* ═══ [14/10, Romain] LE COUP DE THEATRE (maquette B, « .coup ») ═══════════════════════════════
   Plein ecran noir au-dessus de la carte, petit libelle, gros titre qui entre en sortant du flou,
   une ligne de detail, un rai de lumiere creme qui traverse une fois. « Suivant » (le pied) et la
   rangee des joueurs restent au-dessus : le premier referme le coup, la seconde montre qui il touche. */
html body #s-game>.coup{position:absolute;inset:0;container-type:inline-size;z-index:8;display:none;flex-direction:column;align-items:center;justify-content:center;
  gap:var(--e-3);padding:0 var(--e-5);background:#050507;overflow:hidden;pointer-events:none;text-align:center}
html body #s-game.coup-on>.coup{display:flex;animation:uiVoileFonce .35s ease both}
html body #s-game.coup-on>.vie-rangee{z-index:9}
html body #s-game.coup-on>.bottom{position:relative;z-index:10}
html body #s-game.coup-on .jn-scene{visibility:hidden}
html body #s-game.coup-on.vie-sortant>.coup{opacity:0;transition:opacity .22s ease-in}
@keyframes uiVoileFonce{from{opacity:0}}
html body #s-game>.coup .coup-rai{position:absolute;top:0;bottom:0;width:120px;left:-420px;transform:skewX(-14deg);
  background:linear-gradient(90deg,transparent,rgba(244,239,228,.22),transparent)}
html body #s-game.coup-on>.coup .coup-rai{animation:coupRai 1.1s .25s ease-out both}
/* le rai part et finit HORS de l'ecran : incline, il deborde de 1/4 de la hauteur de chaque cote */
@keyframes coupRai{to{transform:translateX(calc(100cqw + 796px)) skewX(-14deg)}}   /* [20/10] glisse au lieu de left : meme course (-420 px a 100 % + 320 px ; 100cqw ne compte pas les 2 x 28 px de marge) */
html body #s-game>.coup .coup-mot{font-size:var(--t-1);letter-spacing:.32em;text-transform:uppercase;color:var(--c-texte-2);font-weight:700}
html body #s-game>.coup .coup-gros{font-size:var(--t-6);font-weight:900;line-height:1.1;color:var(--c-texte);text-wrap:balance}
html body #s-game.coup-on>.coup .coup-gros{animation:coupGros .7s cubic-bezier(.2,.7,.3,1) .3s backwards}
@keyframes coupGros{from{opacity:0;transform:scale(1.4);filter:blur(10px)}}
html body #s-game>.coup .coup-detail{font-size:var(--t-2);line-height:1.4;color:var(--c-texte-2);max-width:300px}
/* la mention sous la condition de la carte suivante (« · doublé », « · au choix de Romain ») */
html body #s-game .coup-mention{white-space:nowrap}
@media (prefers-reduced-motion:reduce){
  html body #s-game.coup-on>.coup,html body #s-game.coup-on>.coup .coup-rai,html body #s-game.coup-on>.coup .coup-gros{animation:none!important}
  html body #s-game.coup-on>.coup .coup-rai{display:none}
  html body #s-game.coup-on.vie-sortant>.coup{transition:none}
}
/* [14/10] correctifs (branche soiree-v2-correctifs) */
/* [14/10] « Tes amis » a 320 px : l'ecart calc((100% - 290px) / 4) devenait negatif (rangee de 280 px pour
   cinq ronds de 58) et les ronds se touchaient. 12 px d'ecart au minimum : la rangee defile, le cinquieme
   rond coupe au bord dit qu'il y a une suite. A 390 px l'ecart calcule (15 px) reste celui de la maquette. */
html body #s-multi .ax-amis{gap:max(12px, calc((100% - 290px) / 4))}
/* [14/10] l'ancienne liste #s-amis s'affiche encore : Ajouter un ami, une recherche qui trouve quelqu'un
   qui t'a demande, « Répondre ». Deux defauts y restaient :
   - dans une demande recue, le pseudo etait colle a la date (« Maeil y a 1 h ») : `#s-amis .am-txt` est
     une rangee flexible, le pseudo et la date passent l'un sous l'autre ;
   - la pastille rouge des amis hors ligne, retiree de la liste piste A le 13/10 : hors ligne, aucun point. */
html body #s-amis .am-dem .am-txt{flex-direction:column;align-items:flex-start;justify-content:center}
html body #s-amis .am-rec .am-av.off .am-pt{display:none}

/* [14/10, Romain : « le tour qui s'éclaire à chaque fois qu'on tire une carte est trop violet, ça fait un léger
   flash assez désagréable surtout à la longue »] la lueur ne pulse plus au changement de carte. Le mouvement
   de la carte (sortie floutée, entrée en trois temps, chiffre qui tombe) suffit à dire « nouvelle carte » ;
   la nappe de fond reste la seule lueur, fixe. */
html body :is(#s-game,#s-classic-run)>.vie-lueur,
html body :is(#s-game,#s-classic-run)>.vie-lueur.pulse{animation:none!important;opacity:0!important}

/* ═══ [14/10, Romain] LES MINI-JEUX SE JOUENT SUR LA NUIT (maquette « 2 · Les mini-jeux sur la nuit, et un
   vrai passage de tour », colonne Proposé) ════════════════════════════════════════════════════════════
   1. Le fond. Chaque ecran de mini-jeu portait le ciel violet commun (`.screen:not(#s-home)`) et, pour
      Reflexe et Vert ou rouge, une plaque grise par-dessus (#reflex-zone #1c1822, #gn-zone var(--card)).
      La charte dit « noir profond, jamais gris » : le jeu se joue sur le fond de partie #08080B, avec une
      lueur ambre FIXE derriere la zone de jeu. On corrige a la source commune : `.gscreen`, posee par
      app.js sur les dix-neuf ecrans de GAMES, et son ::before (l'ancien halo a l'accent, 13 %, en haut).
      ⚠️ LA LUEUR NE BOUGE JAMAIS : ni pulsation ni changement d'intensite (Romain, 14/10 : « un leger
         flash assez desagreable »). Aucune `filter` animee. */
html body .screen.gscreen:not(#s-home){background-color:#08080B;background-image:none;
  --pf:#FF9A2B;--pf-halo:rgba(255,154,43,.7)}
html body .screen.gscreen::before{content:"";position:absolute;left:50%;top:52%;width:140vmin;height:140vmin;max-width:780px;max-height:780px;
  transform:translate(-50%,-50%);border-radius:50%;opacity:1;filter:none;animation:none;z-index:0;pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,154,43,.24),rgba(255,154,43,.08) 55%,transparent)}
/* les plaques grises des zones de jeu s'effacent ; ce qui a un SENS garde sa couleur : le feu de Reflexe
   rougit puis verdit (en lueur sur la nuit, plus en aplat), Vert ou rouge garde ses aplats, c'est le jeu.
   Le vert du depart s'allume d'un coup, comme avant : c'est le signal qu'on chronometre. */
html body #reflex-zone{background:transparent!important}
html body #reflex-zone.arming{background:radial-gradient(circle closest-side at 50% 46%,rgba(239,68,68,.22),transparent)!important}
html body #reflex-zone.go{background:radial-gradient(circle closest-side at 50% 46%,rgba(34,197,94,.34),transparent)!important}
/* [21/10, Romain, direction B] le boîtier en verre de l'app, bord or en dégradé comme les cases des jeux */
html body #reflex-feu{background:linear-gradient(160deg,#16132e,#0b0a1c) padding-box,linear-gradient(160deg,rgba(252,211,77,.85),rgba(217,160,6,.25) 45%,rgba(252,211,77,.6)) border-box;border:1.5px solid transparent;box-shadow:0 12px 30px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,255,255,.14)}
html body #gn-zone:not(.green):not(.red){background:transparent}

/* 2. La rangee des joueurs : celle de la Soiree (.vie-rangee, .vie-av, vieJoueurs), etendue plus haut a
   `.gscreen` et allumee en ambre par --pf. Elle est posee par mjPlaceRangee (app.js) et ne prend aucun
   toucher : la zone de jeu dessous reste entiere. */
html body .gscreen>.mj-rangee{pointer-events:none}

/* 3. Le passage de tour : plein ecran noir, « À toi de jouer », disque creme a l'initiale (anneau et lueur
   ambre), prenom en lumiere, consigne. Il entre en fondu (300 ms), le disque se pose, le prenom sort du
   flou une fois. Au-dessus de la barre du haut, du bandeau (60) et du menu (65). */
.mj-passage{position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--e-3);
  padding:max(var(--e-4),env(safe-area-inset-top,0px)) max(var(--e-5),env(safe-area-inset-right,0px)) max(var(--e-4),env(safe-area-inset-bottom,0px)) max(var(--e-5),env(safe-area-inset-left,0px));
  background:#050507;text-align:center;cursor:pointer;outline:none;-webkit-tap-highlight-color:transparent;
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .3s ease,visibility 0s linear .3s}
.mj-passage.on{opacity:1;visibility:visible;pointer-events:auto;transition:opacity .3s ease}
.mj-passage .mjp-mot{font-size:var(--t-1);letter-spacing:.3em;text-transform:uppercase;font-weight:700;color:var(--c-texte-2)}
.mj-passage .mjp-disque{width:110px;height:110px;border-radius:50%;display:grid;place-items:center;font-size:var(--t-7);font-weight:900;line-height:1;
  color:#2A2431;background:linear-gradient(160deg,#F6EFE2,#E3D9C8 55%,#D4C8B3);box-shadow:0 0 0 3px #FF9A2B,0 0 40px rgba(255,154,43,.6)}
.mj-passage .mjp-nom{font-size:var(--t-6);font-weight:900;line-height:1.1;color:var(--c-texte);text-shadow:0 0 18px rgba(255,154,43,.9);max-width:100%;overflow-wrap:anywhere}
.mj-passage .mjp-tape{margin-top:var(--e-3);font-size:var(--t-1);line-height:1.4;color:var(--c-texte-3)}
.mj-passage.on .mjp-disque{animation:mjpPose .6s cubic-bezier(.2,.7,.3,1) backwards}
.mj-passage.on .mjp-nom{animation:mjpNom .6s cubic-bezier(.2,.7,.3,1) .15s backwards}
@keyframes mjpPose{from{opacity:0;transform:scale(.4) rotate(-30deg)}}
@keyframes mjpNom{from{opacity:0;transform:translateY(16px);filter:blur(6px)}}

/* 4. Le resultat d'une manche tombe : petite echelle, leger rebond, comme le chiffre des cartes en Soiree
   (vieNombre). Pose par miniVerdict (app.js), commun aux dix-neuf jeux, et retire a la fin de l'animation.
   Il remplace le petit « pop » de reveal() sur ces elements ; aucun n'est a opacity:0 au repos, rien ne
   peut donc rester cache. Pas de « to » : l'element revient a son propre transform. */
/* [20/10, Romain, direction B] le verdict d'un mini-jeu monte et se pose (0,34 s), il ne tombe plus en grossissant */
@keyframes mjPose{from{opacity:0;transform:translateY(14px)}}
html body .gscreen .mj-tombe{animation:mjPose var(--m-moyen) var(--m-sortie) backwards}

@media (prefers-reduced-motion:reduce){
  .mj-passage,.mj-passage.on{transition:none}
  .mj-passage.on .mjp-disque,.mj-passage.on .mjp-nom,html body .gscreen .mj-tombe{animation:none!important}
}
/* sur la nuit, « Attends le vert » et « MAINTENANT » se lisent en creme (ils etaient poses sur un aplat colore) */
html body #reflex-zone:is(.arming,.go) #reflex-inst{color:var(--c-texte)}
/* [14/10] accueil vivant (branche soiree-v2-correctifs) */
/* [14/10, Romain] L'ACCUEIL RESPIRE, maquette « trinke-vie-minijeux-accueil », colonne « Proposé ».
   Cinq mouvements, tous lents et sans montee de lumiere (Romain a fait retirer le 14/10 une lueur qui
   pulsait : « un léger flash assez désagréable ») :
   ① trois lumieres du fond derivent, ② les trois cartes de la banniere Soiree flottent, ③ ses quatre
   etoiles scintillent, ④ un reflet passe sur « Lancer une Soirée », ⑤ les trois modes montent a l'ouverture.
   ⚠️ RIEN QUE transform ET opacity EN BOUCLE (CLAUDE.md) : une filter ou un background-position anime
      repeint l'ecran en permanence, et l'accueil reste allume toute une soiree. */

/* ① LES LUMIERES. Elles vivaient dans le fond de l'ecran (#s-home.menu-verre, bloc MENU-VERRE), et un
   fond ne se deplace pas sans repeindre. Les trois plus visibles en sortent, chacune dans une boite qui,
   elle, se deplace par transform : la violette du haut, la sarcelle du coin, la bleue sous les modes.
   Memes couleurs, memes tailles, memes places au repos : chaque degrade garde son rayon et son centre,
   et la boite s'arrete la ou il s'eteignait (70 % du rayon). Les cinq autres restent peintes dans le
   fond : la liste ci-dessous est celle du bloc MENU-VERRE moins ces trois-la.
   ⚠️ AUCUNE BOITE NE DEPASSE LE BORD DROIT, ET C'EST CE QUI A DECIDE DU MOUVEMENT. Les trois taches
      debordent de l'ecran a droite ; une boite qui deborde, ou qu'une translation pousse dehors, cree un
      defilement horizontal (mesure sur la premiere ecriture : 495 px de large pour 390, l'accueil se
      laissait decaler de 105 px). Chaque boite s'arrete donc au bord droit (right:0), coupee la ou
      l'ecran la coupait deja, et derive par une echelle ancree sur ce bord (transform-origin a droite)
      plus une translation VERTICALE : le bord coupe ne quitte jamais le bord de l'ecran.
   ⚠️ ET AUCUNE NE DESCEND SOUS L'ECRAN : la bleue du bas ne derive que vers le haut.
   ⚠️ isolation:isolate : sans contexte d'empilement propre, une couche en z-index:-1 passerait SOUS le
      fond de l'ecran et ne se verrait plus. La troisieme boite est le ::before de .hstack, qui n'est pas
      positionne : sa boite se cale donc sur l'ecran, comme les deux autres. */
html body #s-home.menu-verre{isolation:isolate;
  background-image:radial-gradient(calc(500 * var(--mvs,.45) * 1px) calc(160 * var(--mvs,.45) * 1px) at calc(300 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1420 - 88) * var(--mvs,.45) * 1px), rgba(20,30,140,.30), transparent 70%), radial-gradient(calc(420 * var(--mvs,.45) * 1px) calc(220 * var(--mvs,.45) * 1px) at calc(720 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1230 - 88) * var(--mvs,.45) * 1px), rgba(60,25,140,.35), transparent 70%), radial-gradient(calc(320 * var(--mvs,.45) * 1px) calc(110 * var(--mvs,.45) * 1px) at calc(880 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1250 - 88) * var(--mvs,.45) * 1px), rgba(255,80,20,.22), transparent 70%), radial-gradient(calc(240 * var(--mvs,.45) * 1px) calc(120 * var(--mvs,.45) * 1px) at calc(40 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1400 - 88) * var(--mvs,.45) * 1px), rgba(255,70,20,.16), transparent 70%), radial-gradient(calc(300 * var(--mvs,.45) * 1px) calc(90 * var(--mvs,.45) * 1px) at calc(700 * var(--mvs,.45) * 1px) calc(var(--mvtop,8px) + (1625 - 88) * var(--mvs,.45) * 1px), rgba(255,80,30,.18), transparent 70%), linear-gradient(#000102, #01030F)}
html body #s-home.menu-verre::before,html body #s-home.menu-verre::after,html body #s-home.menu-verre .hstack::before{
  content:"";position:absolute;right:0;z-index:-1;pointer-events:none;transform-origin:100% 50%}
/* violette, 560 x 420 a (760, 330) de la toile : la boite part a 760 - 392 */
html body #s-home.menu-verre::before{left:calc(368 * var(--mvs,.45) * 1px);top:calc(var(--mvtop,8px) - 52 * var(--mvs,.45) * 1px);
  height:calc(588 * var(--mvs,.45) * 1px);
  background:radial-gradient(calc(392 * var(--mvs,.45) * 1px) calc(294 * var(--mvs,.45) * 1px) at calc(392 * var(--mvs,.45) * 1px) 50%,rgba(80,30,160,.42),transparent);
  animation:accDeriv1 18s ease-in-out infinite alternate}
/* sarcelle, 420 x 300 a (900, 140) : son centre est deja hors de l'ecran */
html body #s-home.menu-verre::after{left:calc(606 * var(--mvs,.45) * 1px);top:calc(var(--mvtop,8px) - 158 * var(--mvs,.45) * 1px);
  height:calc(420 * var(--mvs,.45) * 1px);
  background:radial-gradient(calc(294 * var(--mvs,.45) * 1px) calc(210 * var(--mvs,.45) * 1px) at calc(294 * var(--mvs,.45) * 1px) 50%,rgba(0,120,170,.28),transparent);
  animation:accDeriv2 22s ease-in-out infinite alternate}
/* bleue, 700 x 300 a (400, 1300) */
html body #s-home.menu-verre .hstack::before{left:calc(-90 * var(--mvs,.45) * 1px);top:calc(var(--mvtop,8px) + 1002 * var(--mvs,.45) * 1px);
  height:calc(420 * var(--mvs,.45) * 1px);
  background:radial-gradient(calc(490 * var(--mvs,.45) * 1px) calc(210 * var(--mvs,.45) * 1px) at calc(490 * var(--mvs,.45) * 1px) 50%,rgba(35,20,120,.48),transparent);
  animation:accDeriv3 16s ease-in-out infinite alternate}
@keyframes accDeriv1{to{transform:translateY(12px) scale(1.06)}}
@keyframes accDeriv2{to{transform:translateY(12px) scale(.95)}}
@keyframes accDeriv3{to{transform:translateY(-10px) scale(1.05)}}

/* [14/10, Romain] « réduit un peu l'animation de la page d'accueil, surtout les cartes qui flottent, le
   mouvement doit être très léger » : cartes 3 fois moins amples et plus lentes (montee 1,5 a 2,5 unites,
   rotation sous 1 degre), lumieres deux fois moins, etoiles qui s'eteignent a peine, reflet toutes les 9 s. */
/* ② LES CARTES DE LA BANNIERE. Chaque carte est un <g> du dessin qui porte deja son inclinaison dans son
   attribut transform (rotate(-10 155 150)...). Une propriete CSS transform l'ECRASERAIT : la carte se
   redresserait d'un coup. Les proprietes individuelles translate et rotate, elles, s'ajoutent a
   l'attribut. Elles tournent autour du coin du dessin (0, 0) ; pour qu'une carte pivote sur son propre
   centre c, le translate compense : c - R(angle).c, plus la montee voulue. Valeurs calculees pour
   chaque carte, en unites du dessin (1 unite = 0,56 px a l'ecran de 390). Ordre du dessin : la carte du
   fond, celle du milieu, celle de devant. */
html body #s-home #mv-canvas .mv-illu>g:nth-of-type(1){animation:accFlotteFond 6s ease-in-out .7s infinite}
html body #s-home #mv-canvas .mv-illu>g:nth-of-type(2){animation:accFlotteMilieu 6s ease-in-out .35s infinite}
html body #s-home #mv-canvas .mv-illu>g:nth-of-type(3){animation:accFlotteAvant 6s ease-in-out infinite}
/* [15/10, Romain] amplitude triplee depuis le 14/10, etoiles a 50 % ; « fais bouger les cartes en cascade » :
   meme periode de 6 s pour les trois, la carte de devant part, puis celle du milieu (.35 s), puis celle du fond (.7 s). */
@keyframes accFlotteAvant{0%,100%{translate:0 0;rotate:0deg}50%{translate:-6.24px -.96px;rotate:-2.4deg}}     /* centre (155, 150), monte de 2,5 */
@keyframes accFlotteMilieu{0%,100%{translate:0 0;rotate:0deg}50%{translate:4.8px -13.44px;rotate:1.8deg}}     /* centre (238, 152), monte de 2 */
@keyframes accFlotteFond{0%,100%{translate:0 0;rotate:0deg}50%{translate:4.35px -12.27px;rotate:1.5deg}}      /* centre (298, 165), monte de 1,5 */

/* ③ LES QUATRE ETOILES autour des cartes (les <use> enfants directs du dessin ; les deux petites etoiles
   DANS la carte de devant flottent avec elle). Elles ne s'allument JAMAIS au-dela du repos : elles
   s'eteignent un peu et reviennent (opacite 1 -> .45, echelle 1 -> .8). Une etoile qui grossit et
   s'eclaire, c'est un flash ; une etoile qui respire, non. Meme compensation que les cartes : scale
   agit depuis (0, 0), le translate c.(1 - .8) garde chaque etoile sur son centre c. */
html body #s-home #mv-canvas .mv-illu>use{animation:5s ease-in-out infinite}
html body #s-home #mv-canvas .mv-illu>use:nth-of-type(1){animation-name:accScint1}
html body #s-home #mv-canvas .mv-illu>use:nth-of-type(2){animation-name:accScint2;animation-delay:1.1s}
html body #s-home #mv-canvas .mv-illu>use:nth-of-type(3){animation-name:accScint3;animation-delay:2s}
html body #s-home #mv-canvas .mv-illu>use:nth-of-type(4){animation-name:accScint4;animation-delay:.6s}
@keyframes accScint1{0%,100%{opacity:1;scale:1;translate:0 0}50%{opacity:.5;scale:.8;translate:10.4px 24px}}   /* (52, 120) */
@keyframes accScint2{0%,100%{opacity:1;scale:1;translate:0 0}50%{opacity:.5;scale:.8;translate:15.2px 37.2px}}   /* (76, 186) */
@keyframes accScint3{0%,100%{opacity:1;scale:1;translate:0 0}50%{opacity:.5;scale:.8;translate:65.2px 10.4px}}   /* (326, 52) */
@keyframes accScint4{0%,100%{opacity:1;scale:1;translate:0 0}50%{opacity:.5;scale:.8;translate:70.4px 16.8px}}   /* (352, 84) */

/* ④ LE REFLET DE « Lancer une Soirée » : une bande claire inclinee traverse la pastille toutes les 6 s
   (passage en 1,7 s, puis 4,3 s de repos hors de la pastille). Blanc a 16 % au plus fort, la maquette
   en mettait 35 : sur le vrai degrade, plus clair se lisait comme un eclair. Elle glisse par transform
   (la maquette animait left, qui recalcule la mise en page a chaque image). Au repos, et sans
   animation, elle attend a gauche, hors de la pastille, que overflow:hidden coupe. */
html body #s-home #mv-canvas .mv-lancer{overflow:hidden}
html body #s-home #mv-canvas .mv-lancer::after{content:"";position:absolute;top:0;bottom:0;left:0;width:130px;pointer-events:none;
  background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.16),rgba(255,255,255,0));
  transform:translateX(-180px) skewX(-18deg);animation:accReflet 9s ease-in-out 1.5s infinite}
@keyframes accReflet{0%,81%{transform:translateX(-180px) skewX(-18deg)}100%{transform:translateX(760px) skewX(-18deg)}}

/* ⑤ LES TROIS MODES MONTENT l'un apres l'autre a l'ouverture. Memes regles que l'entree orchestree
   (.h-in, 30/07) : l'etat de REPOS est visible, l'etat cache ne vit que dans le from des keyframes et
   `both` le tient pendant le delai ; .entree-jouee (posee 950 ms apres le premier affichage) eteint la
   sequence, les retours sur l'accueil affichent les modes tout de suite. Dernier mode : 340 + 500 =
   840 ms, la sequence finit avant que .entree-jouee ne tombe. Aucune entree n'existait sur ces cartes
   (seul l'ecran entier glisse, uiEcran) : rien a reprendre en tete de liste. 26 px de toile = 12 px a
   l'ecran de 390. */
html body #s-home #mv-canvas .mv-mode{animation:accModeMonte var(--m-long) var(--m-sortie) .18s both}
html body #s-home #mv-canvas .mv-m2{animation-delay:.26s}
html body #s-home #mv-canvas .mv-m3{animation-delay:.34s}
html body #s-home.entree-jouee #mv-canvas .mv-mode{animation:none}
@keyframes accModeMonte{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}

/* LE KICK DU RETOUR (app.js, majAccesProfil) : certains WebKit ne relancent pas les animations d'un
   sous-arbre repasse de display:none a visible (bug iPhone 30/07, reflet du mot-symbole mort au retour).
   Le JS pose .acc-relance le temps d'un calcul de mise en page, puis la retire : les boucles repartent.
   Les modes n'y sont pas, leur entree est jouee une fois pour toutes. */
html body #s-home.acc-relance::before,html body #s-home.acc-relance::after,html body #s-home.acc-relance .hstack::before,
html body #s-home.acc-relance #mv-canvas .mv-illu>g,html body #s-home.acc-relance #mv-canvas .mv-illu>use,
html body #s-home.acc-relance #mv-canvas .mv-lancer::after{animation:none!important}

/* REDUCED-MOTION : tout s'arrete, tout reste a sa place de repos, donc visible (charte DA). !important parce
   que les regles des cartes et des etoiles passent par :nth-of-type et pesent plus lourd que celle-ci :
   sans lui, mesure, les trois cartes flottaient encore en mouvement reduit. */
@media (prefers-reduced-motion:reduce){
  html body #s-home.menu-verre::before,html body #s-home.menu-verre::after,html body #s-home.menu-verre .hstack::before,
  html body #s-home #mv-canvas .mv-illu>g,html body #s-home #mv-canvas .mv-illu>use,
  html body #s-home #mv-canvas .mv-lancer::after,html body #s-home #mv-canvas .mv-mode{animation:none!important}
}

/* [15/10, Romain] bouton « ! » de l'apercu et sa page de retour (app.js, avisApercu). Design 2
   « papier creme » choisi par Romain sur la planche des 9 (WATCH, 15/10) : une fiche claire qui
   tranche avec le jeu sombre, encre --ink, bouton encre a texte creme. */
/* pose a droite du menu, hors de la grille de la barre (3 colonnes deja prises) ; pas a cote de « passer » : le « ? » de certaines cartes y vient */
#s-game>.topbar:has(.avis-bt){position:relative}
/* meme glyphe que le « ? » de la barre (#c-aide) : texte, creme, 1.375rem, 600, sans fond ni bord */
.avis-bt{position:absolute;left:44px;top:50%;transform:translateY(-50%);width:36px;height:36px;border:0;background:none;padding:0;
  color:var(--c-texte);font:inherit;font-size:var(--t-4);font-weight:600;line-height:1;display:flex;align-items:center;justify-content:center;z-index:5;cursor:pointer}
.avis-bt::after{content:"";position:absolute;inset:-4px}
.avis-fond{position:fixed;inset:0;z-index:99999;background:rgba(2,1,10,.62);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  display:flex;align-items:flex-start;justify-content:center;padding:max(96px,calc(env(safe-area-inset-top) + 64px)) var(--e-4) var(--e-4);
  animation:uiVoileFonce var(--m-court) var(--m-sortie) both}
.avis-boite{position:relative;width:100%;max-width:360px;box-sizing:border-box;border-radius:var(--r-3);padding:var(--e-4) var(--e-4) var(--e-4);
  background:#EFE9DF;color:#170B20;box-shadow:0 24px 60px -20px rgba(0,0,0,.8);
  display:flex;flex-direction:column;gap:0;animation:avisMonte var(--m-moyen) var(--m-sortie) both}
.avis-x{position:absolute;right:8px;top:8px;width:44px;height:44px;border:0;background:none;color:#6C6178;font:inherit;font-size:var(--t-4);line-height:1;cursor:pointer}
.avis-titre{font-size:var(--t-4);font-weight:800;letter-spacing:-.01em;margin:0 36px var(--e-1) 0}
.avis-carte{margin:0 0 var(--e-3);font-size:var(--t-2);line-height:1.4;font-style:italic;color:#6C6178;max-height:16vh;overflow:auto}
.avis-carte:empty{display:none}
.avis-champ{width:100%;box-sizing:border-box;font:inherit;font-size:var(--t-2);line-height:1.45;color:#170B20;
  background:#fff;border:1px solid #DDD3C4;border-radius:var(--r-2);padding:var(--e-3);resize:none;
  -webkit-user-select:text;user-select:text;outline:none;transition:border-color .15s,box-shadow .15s}
.avis-champ::placeholder{color:var(--c-texte-3)}
.avis-champ:focus{border-color:#B9A9CF;box-shadow:0 0 0 3px rgba(139,92,246,.14)}
.avis-etat{margin:var(--e-2) 0 0;font-size:var(--t-1);color:#B4235F}
.avis-etat:empty{display:none}
.avis-envoie{margin-top:var(--e-3);min-height:52px;border:0;border-radius:var(--r-2);background:#170B20;color:var(--c-texte);font:inherit;font-size:var(--t-3);font-weight:700;cursor:pointer}
.avis-envoie:disabled{opacity:.55}
.avis-merci{display:none;flex-direction:column;align-items:center;gap:var(--e-2);padding:var(--e-3) 0 var(--e-2);text-align:center}
.avis-ok{width:52px;height:52px;border-radius:50%;background:#170B20;display:flex;align-items:center;justify-content:center;margin-bottom:var(--e-1)}
.avis-ok svg{width:26px;height:26px;fill:none;stroke:#EFE9DF;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.avis-merci b{font-size:var(--t-4);font-weight:800}
.avis-merci span{font-size:var(--t-2);color:#6C6178}
.avis-boite.merci>:not(.avis-merci){display:none}
.avis-boite.merci .avis-merci{display:flex;animation:avisMonte var(--m-moyen) var(--m-sortie) both}

@keyframes avisMonte{from{opacity:0;transform:translateY(14px) scale(.98)}}
@media (prefers-reduced-motion:reduce){.avis-fond,.avis-boite,.avis-boite.merci .avis-merci{animation:none}}


/* [15/10, Romain] LA FICHE « COMMENT ON JOUE » (toutes les fenetres du « ? » : cartes, mini-jeux, modes,
   reglages) passe au design 1 de la planche du 15/10 : fiche creme comme la page de retour, surtitre,
   consignes numerotees, bouton « Compris » a l'encre. L'apercu anime est masque. Le selecteur porte
   `html body` et des !important parce que la feuille de nuit (html body .sheet, #rules-close) les pose. */
html body #m-rules{align-items:flex-start;justify-content:center;padding:max(96px,calc(env(safe-area-inset-top) + 64px)) var(--e-4) var(--e-4);
  background:rgba(2,1,10,.62);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
html body #m-rules .sheet{position:relative;width:100%;max-width:360px;max-height:calc(100dvh - 130px);overflow-y:auto;
  background:#EFE9DF!important;color:#170B20;border:0!important;border-radius:var(--r-3)!important;padding:var(--e-4) var(--e-4) var(--e-4)!important;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.8)!important}   /* [20/10] entree commune des fenetres (bloc FENETRES-MOUVEMENT) */
html body #m-rules .rules-preview{display:none}
html body #m-rules .rules-x{position:absolute;right:8px;top:8px;width:44px;height:44px;border:0;background:none;color:#6C6178;font:inherit;font-size:var(--t-4);line-height:1;cursor:pointer}
html body #m-rules #rules-title{margin:0 36px var(--e-3) 0;font-size:var(--t-4);font-weight:800;letter-spacing:-.01em;color:#170B20!important;line-height:1.15}
html body #m-rules #rules-text{color:#170B20!important;margin:0}
html body #m-rules .rules-un{margin:0 0 var(--e-2);font-size:var(--t-2);line-height:1.45}
html body #m-rules .rules-etapes{list-style:none;margin:0;padding:0}
html body #m-rules .rules-etapes li{display:flex;gap:var(--e-3);align-items:flex-start;font-size:var(--t-2);line-height:1.4;margin-bottom:var(--e-3)}
html body #m-rules .rules-etapes li b{flex:none;width:26px;height:26px;border-radius:50%;background:#170B20;color:var(--c-texte);font-size:var(--t-1);
  display:flex;align-items:center;justify-content:center;margin-top:-1px}
html body #m-rules .pm-aide-l{color:#170B20}
html body #m-rules .pm-aide-l b{color:#B4235F}
html body #m-rules #rules-close{position:static;margin-top:var(--e-2);width:100%;min-height:52px;border:0!important;border-radius:var(--r-2)!important;
  background:#170B20!important;color:var(--c-texte)!important;box-shadow:none!important;font-size:var(--t-3);font-weight:700}

/* [15/10, Romain] le Duel prend le rouge qu'avait la Loi de table, la Loi passe en champagne.
   Meme style que les autres familles : seules les variables changent. */
html body #s-game[data-famille="duel"]{--pf:#F0384F;--pf-clair:#FF8C9A;--pf-lueur:rgba(240,56,79,.24);
  --pf-bouton:linear-gradient(90deg,#FF6F80 0%,#E0243C 45%,#A8152A 100%);--pf-halo:rgba(224,36,60,.7)}

/* [16/10, Romain] « les boutons en haut du mode soirée ne sont pas égaux » + « le point d'exclamation est
   légèrement gros » : les quatre signes de la barre (☰, « ! », « ? », ») prennent la meme hauteur
   d'encre, environ 11 px. Avant : ☰ et » faisaient 8 px de haut, « ! » et « ? » 16 px.
   Les places ne bougent pas : ☰ + « ! » a gauche, « ? » + » a droite, a 8 px l'un de l'autre. */
body.jn-carte #s-game ~ #menu-btn svg,body.jn-carte #menu-btn#menu-btn svg{width:20px;height:20px}
/* [21/10, audit V2] le meme « passer » vit aussi dans la barre des Classiques : 17 px des deux cotes (13 px aux Classiques avant, mesure) */
html body :is(#s-game,#s-classic-run)>.topbar>#c-passer#c-passer svg{width:17px;height:17px;stroke-width:2.1}
html body #s-game>.topbar>.avis-bt,
html body :is(#s-game,#s-classic-run)>.topbar>#c-aide#c-aide{font-size:var(--t-3);font-weight:700}
/* [16/10, Romain] « l'intitulé de la carte doit être descendu un peu, il est trop haut » :
   14 px d'air de plus entre la rangee des joueurs et le badge du type. */
html body #s-game[data-famille] #c-tag{margin-top:var(--e-3)}
/* [16/10, Romain] « descends le bouton avec écrit le type de carte, il est trop haut encore » : 14 -> 30 px,
   et le meme ecart aux Classiques, qui ont le meme badge */
html body #s-game[data-famille] #c-tag{margin-top:var(--e-5)}
html body #s-classic-run[data-famille] #cl-tag{margin-top:var(--e-5)}
/* [16/10, Romain] « augmente un peu la taille du carré » : le badge du type passe de 18,5 a 20 px, et de 39 a 46 px de haut */
html body #s-game[data-famille] #c-tag,html body #s-classic-run[data-famille] #cl-tag{font-size:var(--t-3);padding:var(--e-3) var(--e-4);border-radius:var(--r-2)}
/* meme ecart que « ? » / » a droite (4 px) : ☰ 18-54 et « ! » 58-94 repondent a « ? » 296-332 et » 336-372 */
html body #s-game>.topbar>.avis-bt{left:40px}

/* [16/10, Romain : « la page de boutique a encore des proportions trop moches », puis « le 6 »]
   Variante 6 de ~/Desktop/WATCH/trinke-boutique-proportions : « Boutique » garde sa place, « Pass VIP »
   passe au-dessus en taille (2rem contre 1.3125rem : une hierarchie, plus deux titres egaux), la grande
   carte prend la place libre (texte centre dans sa hauteur), mini-jeux sur toute la largeur, prix plus
   gros, pastille « Le meilleur prix » hors du bracelet, bouton decolle des bracelets.
   ⚠️ ELASTIQUE, PAS DE SEUIL UNIQUE : le bloc s'etale jusqu'a la barre du bas (space-between) et la
      grande carte cede en premier (flex-shrink) ; sous 740 de haut, cases, bracelets et bouton
      se resserrent pour que « Paiement sécurisé par Stripe » reste au-dessus de la barre (375 × 667). */
#s-boutique .bq-vip{justify-content:space-between}
#s-boutique .bq-vip-titre{font-size:var(--t-5);line-height:1.1;margin-top:2px}
#s-boutique .bq-hero{flex:1 1 170px!important;min-height:104px;max-height:200px;margin:var(--e-3) 0}
#s-boutique .bq-hc{display:flex;flex-direction:column;justify-content:center;align-items:flex-start}
#s-boutique .bq-hc p{margin-top:var(--e-3);font-size:var(--t-3)}
#s-boutique .bq-plusmj{margin:0 0 var(--e-2)}
#s-boutique .bq-jeux{grid-template-columns:repeat(5,52px);justify-content:space-between;margin:0 0 var(--e-3)}
#s-boutique .bq-brs{margin:0}
#s-boutique .bq-br{min-height:120px;justify-content:flex-start;padding:var(--e-4) var(--e-2) var(--e-3)}
#s-boutique .bq-pastille{top:-11px}
#s-boutique .bq-px{font-size:var(--t-5);margin-top:var(--e-2)}
#s-boutique .bq-cta{min-height:52px;border-radius:var(--r-4);margin-top:var(--e-3)}
@media (max-height:740px){
  #s-boutique .bq-vip-titre{font-size:var(--t-5)}
  #s-boutique .bq-hero{flex-basis:120px!important;min-height:96px;margin:var(--e-2) 0}
  #s-boutique .bq-hc p{font-size:var(--t-3)}
  #s-boutique .bq-ruban{margin-bottom:var(--e-2)}
  #s-boutique .bq-plusmj{margin-bottom:var(--e-2)}
  #s-boutique .bq-jeux{grid-template-columns:repeat(5,44px);margin-bottom:var(--e-3)}
  #s-boutique .bq-br{min-height:106px;padding-top:var(--e-4)}
  #s-boutique .bq-px{font-size:var(--t-4);margin-top:var(--e-1)}
  #s-boutique .bq-cta{min-height:46px;margin-top:var(--e-2)}
  #s-boutique .bq-note{margin-top:var(--e-2)}
}

/* [16/10, Romain : « la barre de progression et les ronds de joueurs en haut c'est bien faut garder ça. juste cette
   barre doit être bien juste en dessous du titre », « la taille de la carte actuellement dans l'app est bien on garde
   ça, juste faut qu'elle soit tirée en haut puis laisser une bonne place pour l'explication »]
   PALMIER : jauge collee sous la barre du titre, ronds des joueurs (celui qui a tire est allume), la carte a sa taille
   d'avant remonte sous les ronds, puis le prenom, le nom de la regle et l'explication. Le bandeau flottant du prenom
   n'est plus pose : la rangee et la ligne du prenom le remplacent. */
body:has(#s-palmier.on) #turn-badge{display:none!important}
html body #s-palmier .pm-prog{flex:0 0 auto;height:3px;margin:2px 18px 0;background:rgba(255,255,255,.1);border-radius:var(--r-1);overflow:hidden}
html body #s-palmier .pm-prog i{display:block;height:100%;width:0;background:#D22C96;transition:width .35s ease}
html body :is(#s-palmier,#s-purple) .pm-rangee{flex:0 0 auto;display:flex;justify-content:center;gap:var(--e-2);margin:var(--e-3) 18px 0}
html body :is(#s-palmier,#s-purple) .pm-av{flex:0 0 auto;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:var(--t-1);font-weight:800;color:#2A2431;
  background:linear-gradient(160deg,#F6EFE2,#E3D9C8 55%,#D4C8B3);opacity:.38;transition:opacity .25s ease,box-shadow .25s ease}
html body :is(#s-palmier,#s-purple) .pm-av.tous{opacity:1}
html body :is(#s-palmier,#s-purple) .pm-av.vise{opacity:1;box-shadow:0 0 0 2px #EC4899,0 0 14px rgba(236,72,153,.6)}
html body #s-palmier:not(.pm-accueil) .pm-table{margin-top:0;padding-top:var(--e-3)}
html body #s-palmier:not(.pm-accueil) .pm-cartes{order:1}
html body #s-palmier:not(.pm-accueil) .pm-qui{order:2}
html body #s-palmier:not(.pm-accueil) .pm-titre{order:3;margin:2px 0 0}
html body #s-palmier:not(.pm-accueil) .pm-dit{order:4;margin-top:var(--e-2)}
html body #s-palmier:not(.pm-accueil) .pm-cupidon{order:5}
html body #s-palmier .pm-qui{margin:var(--e-1) 0 0;font-size:var(--t-2);font-weight:700;color:#F9A8D4;text-align:center}
html body #s-palmier .pm-qui:empty,html body #s-palmier.pm-accueil .pm-qui{display:none}
html body #s-palmier.pm-accueil .pm-table{padding-top:var(--e-4)}
/* [16/10, Romain] apres le lien de Cupidon : « Les trinkeurs sont désormais liés ! » au-dessus du bouton */
html body #s-palmier .pm-lies{margin:0 0 2px;text-align:center;font-size:var(--t-3);font-weight:700;color:#F9A8D4}
html body #s-palmier .pm-lies[hidden]{display:none}
html body #s-palmier #pm-tirer[hidden]{display:none}
/* [16/10, Romain : « entre le bouton et l'affichage de la règle, là il est affiché trop bas »] la phrase suit la regle */
html body #s-palmier:not(.pm-accueil) .pm-lies{order:6;margin:var(--e-3) 0 0}

/* [16/10, Romain : « refais les designs des jeux qui ne sont pas bien dans le thème de Trinke »] PURPLE ET COURSE DES AS
   sur le modele du Palmier valide le meme soir : au Purple, les ronds des joueurs sous la barre du titre (celui qui
   annonce est allume) remplacent la pastille flottante « Au tour de » ; la phrase « Fanny, à toi » reste.
   A la course, les six obstacles faces cachees prennent le dos de carte du Palmier (rose vers violet, raye, liseré
   creme), au lieu de blocs violets pleins. */
body:has(#s-purple.on) #turn-badge{display:none!important}
html body #s-purple .pu-table{justify-content:flex-start;padding-top:var(--e-6)}   /* l'eventail des cartes monte de 14 px a gauche : il ne touche plus les ronds */
.cda-c.dos{background:repeating-linear-gradient(45deg,rgba(255,255,255,.08) 0 4px,transparent 4px 9px),linear-gradient(160deg,#EC4899,#8B5CF6);
  box-shadow:inset 0 0 0 2px #EFE9DF,0 6px 14px rgba(0,0,0,.5),0 0 14px rgba(236,72,153,.3)}
/* les obstacles ne se touchent plus : 6 px d'air entre deux dos */
.cda-obst .cda-c.dos,.cda-obst .cda-c{width:34px;height:46px;margin:0 auto}
/* [16/10 nuit] iPhone SE 1re generation (320 × 568) : les bracelets debordaient de 32 px a droite (libelle
   en nowrap qui imposait sa largeur a la grille) et le bouton passait sous la barre du bas. Colonnes qui
   peuvent retrecir, libelle sur deux lignes, et un cran de plus de resserrement sous 600 de haut. */
#s-boutique .bq-brs{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
@media (max-width:359px){
  #s-boutique .bq-br small{white-space:normal;line-height:1.2}
  #s-boutique .bq-br{padding-left:var(--e-2);padding-right:var(--e-2)}
  #s-boutique .bq-brc{margin-left:2px;margin-right:2px}
}
@media (max-height:600px){
  #s-boutique .vq-titre{min-height:32px}
  #s-boutique .bq-vip-titre{font-size:var(--t-4)}
  #s-boutique .bq-sous{margin-top:2px}
  #s-boutique .bq-hero{flex-basis:84px!important;min-height:84px;margin:var(--e-2) 0}
  #s-boutique .bq-hc{inset:12px 16px}
  #s-boutique .bq-hc p{font-size:var(--t-2);margin-top:var(--e-2)}
  #s-boutique .bq-ruban{margin-bottom:var(--e-1)}
  #s-boutique .bq-mi{padding:var(--e-2) var(--e-2)}
  #s-boutique .bq-plusmj{margin-bottom:var(--e-1);font-size:var(--t-2)}
  #s-boutique .bq-jeux{grid-template-columns:repeat(5,36px);margin-bottom:var(--e-3)}
  #s-boutique .bq-br{min-height:96px;padding-top:var(--e-3);padding-bottom:var(--e-2)}
  #s-boutique .bq-brc{margin-bottom:var(--e-2)}
  #s-boutique .bq-px{font-size:var(--t-3);margin-top:2px}
  #s-boutique .bq-cta{min-height:44px;margin-top:var(--e-2)}
  #s-boutique .bq-note{margin-top:var(--e-1)}
}
@media (max-height:600px){
  #s-boutique:has(.bq-vip) .vq-titre{display:none}   /* « Pass VIP » porte le titre ; le sac de la barre du bas dit deja ou l'on est */
  #s-boutique .bq-vip-titre{margin-top:var(--e-2)}
}
@media (max-width:359px){ #s-boutique .bq-br small{letter-spacing:0;text-wrap:balance} }
/* [16/10 nuit, Romain : « refais les designs des jeux qui ne sont pas bien dans le thème »]
   LA CIBLE avant de jouer : l'ecran n'avait qu'une phrase au milieu et le bouton tout en bas, 300 px plus
   loin. La cible se montre (meme dessin que la vraie, en veille) avec sa consigne au centre.
   [16/10 matin, Romain : « laisse le bouton en bas »] le bouton Commencer reste en bas, pas au centre. */
#s-target:has(#tg-btn:not([style*="none"])) #tg-zone{flex-direction:column;gap:var(--e-3)}
#s-target #tg-inst:not([style*="none"])::before{content:"";display:block;width:96px;height:96px;margin:0 auto var(--e-3);border-radius:50%;
  background:radial-gradient(circle at 50% 50%,#fca5a5 0 16%,#dc2626 16% 34%,#fff 34% 46%,#dc2626 46% 64%,#fff 64% 76%,#dc2626 76% 100%);
  border:2px solid #fff;box-sizing:border-box;box-shadow:0 0 28px rgba(220,38,38,.45),inset 0 0 10px rgba(0,0,0,.35);opacity:.6}
/* Reflexe et La cible : le bandeau porte le prenom seul, comme dans les seize autres mini-jeux
   (il reste en haut : leur zone de jeu commence sous le titre, choix du 29/09) */
body:has(:is(#s-reflex.on,#s-target.on)) #turn-badge::before{content:none}
/* [16/10, poste-b, Romain : « refait les designs des jeux qui ne sont pas bien dans le theme »] Les mini-jeux
   a consigne (Calcul express, Intrus, Sequence, Couleur piegee, Vrai ou faux, Le 5 parfait, Vert ou rouge,
   Doigt du destin) prennent la tenue de Crash out et du Palmier : titre a la taille des autres jeux, consigne
   en creme lisible comme la regle du Palmier, barre de temps cachee avant le debut. */
html body :is(#s-math,#s-intrus,#s-seq,#s-stroop,#s-vf,#s-dix,#s-gonogo,#s-finger) .topbar b{font-size:var(--t-4)}
html body :is(#ma-inst,#in-inst,#sq-inst,#cr-inst,#vf-inst,#dx-inst,#finger-inst){font-size:var(--t-3)!important;font-weight:600;line-height:1.45;
  color:var(--c-texte)!important;max-width:33ch;margin-left:auto!important;margin-right:auto!important;text-align:center;padding:0 var(--e-4)!important}
html body :is(#s-math:has(#ma-inst[style*="block"]) #ma-prog,#s-stroop:has(#cr-inst[style*="block"]) #cr-prog,#s-vf:has(#vf-inst[style*="block"]) #vf-prog){visibility:hidden}
html body :is(#s-math:has(#ma-inst[style*="block"]),#s-stroop:has(#cr-inst[style*="block"]),#s-vf:has(#vf-inst[style*="block"])) .progress{visibility:hidden}
/* Vert ou rouge rejoint les autres : prenom seul dans le bandeau, bandeau sous la rangee des joueurs (v1052, poste-a) */
body:has(#s-gonogo.on) #turn-badge::before{content:none}
body:has(#s-gonogo.on) #turn-badge{top:calc(env(safe-area-inset-top,0px) + 116px)}
html body #gn-zone:not(.green):not(.red) #gn-inst{color:var(--c-texte)}
/* le halo sous Commencer de Sequence, Couleur piegee et Vrai ou faux restait violet (couleur fixe de la Soiree) : or, comme les autres */
html body :is(#s-seq,#s-stroop,#s-vf) .bottom .btn:not(.sec):not(.ghost){box-shadow:inset 0 1.5px 0 rgba(255,255,255,.72),inset 1.5px 0 0 rgba(255,255,255,.55),inset -1.5px 0 0 rgba(255,255,255,.4),
  inset 0 -1.5px 0 rgba(255,255,255,.12),inset 0 0 14px rgba(255,255,255,.16),0 8px 20px -8px rgba(251,191,36,.7)!important}
/* [16/10, Romain : « la boutique n'a pas la bonne largeur appliquee »] la Boutique prend la largeur des autres menus
   (Compte, Amis, Classement : toute la colonne de l'app) au lieu du plafond de 390 px du 14/10, visible sur grand ecran. */
html body .bq-vip{max-width:none}
/* [16/10, Romain : « regroupe les 5 cases de mini-jeux, reduit l'espace entre eux »] les cases se serrent au centre au lieu de s'etaler sur toute la largeur */
html body #s-boutique .bq-jeux{justify-content:center;gap:var(--e-3)}
/* [16/10, Romain] « +700 cartes dans tous les modes » entre la grande carte et le ruban : la grande carte remonte sous « Pass VIP » */
html body #s-boutique .bq-hero{margin-top:var(--e-2)}
html body #s-boutique .bq-sous{margin:0 0 var(--e-2)}
/* [16/10, CGV] lien vers les conditions de vente : discret sous « Paiement sécurisé par Stripe », et une ligne de Conditions */
html body a.bq-cgv{color:var(--c-texte-3);text-decoration:underline;text-underline-offset:0.1875rem}
html body a.c-cgv{display:block;color:inherit;text-decoration:none}
/* la ligne « Pass VIP » est un lien : le trait entre deux lignes (.c-dit+.c-dit) ne la voyait plus */
#s-compte .c-dit+a.c-cgv>.c-dit::before{content:"";position:absolute;left:60px;right:0;
  top:0;height:1px;transform:scaleY(.34);background:rgba(255,255,255,.17)}

/* ══════════════════════════════════════════════════════════════════════════════════════
   [16/10, Romain : « les pages quand on a pas de compte sont pas belles; refait les »]
   UN SEUL GABARIT POUR LES ECRANS SANS COMPTE (Amis, Mon compte, Classement), CALE SUR LA
   BOUTIQUE : titre de l'onglet au meme endroit partout, embleme de 84 px avec son halo,
   accroche de 1,75 rem, liste en verre de ce qu'un compte ouvre, deux boutons, puis « Jouer
   en tant qu'invite » en lien discret. Avant : titre de Mon compte 15 px plus bas que celui
   d'Amis, embleme de 152 px qui laissait le haut d'Amis vide, rangee de tuiles qui coupait
   « Classe-ments », trois gros boutons empiles.
   ══════════════════════════════════════════════════════════════════════════════════════ */
#s-compte.vq-on>.topbar{display:none}
html body #s-compte.vq-on{padding-top:calc(var(--e-2) + env(safe-area-inset-top,0px))}
html body #s-compte.vq-on>#cp-body{display:flex;flex-direction:column;flex:1 0 auto}
html body .vq-on .vq-titre{margin:2px 0 var(--e-3)}
html body .vq-on .vq-scene{width:84px;height:84px;margin:0 0 var(--e-3)}
html body .vq-on .vq-scene::before{inset:-60px}
html body .vq-on .vq-embleme{width:76px;height:76px}
html body .vq-on .vq-gr{display:none}
html body .vq-on .vq-accroche{margin:0 0 var(--e-3)}
html body .vq-on .vq-accroche h2{font-size:var(--t-5)}
html body .vq-on .vq-accroche p{max-width:300px}
html body .vq-on .vq-liste{margin:0 0 var(--e-4)}
html body .vq-on .vq-issue{min-height:52px}
html body .vq-on .vq-issue+.vq-issue{margin-top:var(--e-3)}
html body .vq-on .vq-issue.vq-invite{min-height:44px;margin-top:var(--e-2);background:none;box-shadow:none;border:0;
  color:var(--c-texte-2);font-size:var(--t-2);font-weight:600}
html body .vq-on .vq-issue.vq-invite .vq-g{width:18px;height:18px}
html body .vq-on .vq-issue.vq-invite:active{background:none;color:var(--c-texte)}
html body .vq-on .vq-legal{margin-top:var(--e-3)}
@media (max-height:740px){
  html body .vq-on .vq-scene{width:60px;height:60px;margin-bottom:var(--e-2)}
  html body .vq-on .vq-embleme{width:54px;height:54px}
  html body .vq-on .vq-accroche{margin-bottom:var(--e-3)} html body .vq-on .vq-accroche h2{font-size:var(--t-4)}
  html body .vq-on .vq-liste{margin-bottom:var(--e-3);padding:2px var(--e-3)} html body .vq-on .vq-liste li{padding:var(--e-2) 0}
  html body .vq-on .vq-issue{min-height:48px}
}
/* Se connecter : meme matiere que Creer un compte, bouton au meme gabarit */
#cp-body .cr.cr-cnx{margin-top:var(--e-4)}
#cp-body .cr-cnx .cp-dispo{margin:var(--e-2) 2px 0;text-align:left;font-size:var(--t-1)}
#cp-body .cr-cnx-go{width:100%;min-height:52px;border-radius:var(--r-4);margin-top:var(--e-1)}
/* la zone de toucher de « politique de confidentialité » (−13 px) couvrait « Conditions
   d'utilisation », une ligne plus haut : le premier lien ne s'ouvrait plus. */
html body .vq-on .vq-legal{line-height:1.75}
html body .vq-on .vq-lien::after{inset:-4px -2px}
@media (max-height:700px){ html body #s-compte.vq-on .vq-scene{display:none} html body .vq-on .vq-legal{margin-top:var(--e-2)} }
/* [16/10 soir] le Joker n'a pas de teinte : son badge prend l'irisé du ruban, comme sa carte en jeu */
.bq-hc[data-iris] .bq-hb{background:linear-gradient(90deg,#FF9A5C,#A7EA6E,#7DB5EA,#A78BFA,#F472B6);-webkit-background-clip:text;background-clip:text;color:transparent;box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}
/* [16/10 soir, Romain : « les icones violettes sont trop fades »] les tuiles de liste (sans compte et
   Boutique ouverte) prennent le dégradé du bouton « Créer un compte », du violet au bleu électrique,
   avec un halo, et un trait de glyphe plus franc */
html body .bq-tu{background:linear-gradient(160deg,#C26BFF 0%,#8A2BFF 50%,#5B12F5 100%);
  box-shadow:0 0 0 1px rgba(214,170,255,.55),0 0 18px rgba(150,60,255,.75),0 6px 14px rgba(0,0,0,.30),inset 0 1px 0 rgba(255,255,255,.40)}
html body .bq-tu svg{stroke-width:2}
/* [16/10] champs du trousseau (pseudo + code de secours) : presents pour le navigateur, invisibles a l'oeil */
html body .cle-cachee{position:absolute;width:0.0625rem;height:0.0625rem;opacity:0;pointer-events:none;overflow:hidden;border:0;padding:0;margin:0;left:-62.5rem}
/* ══ [16/10 soir, Romain : « les boutons sont trop différenciés, l'un est noir et l'autre vraiment très lumineux »]
   « Se connecter » quitte le noir : verre violet éclairé (la matière des offres de la Boutique), texte blanc,
   liseré lavande. Il reste en retrait du dégradé de « Créer un compte » sans avoir l'air d'une sortie. */
html body .vq-on .vq-issue.vq-deja{color:var(--c-texte);
  background:linear-gradient(180deg,rgba(124,82,255,.34) 0%,rgba(52,34,140,.50) 100%);
  box-shadow:inset 0 0 0 1.5px var(--filet-verre),inset 0 1.5px 0 rgba(255,255,255,.22),0 8px 20px -12px rgba(110,70,255,.8)}
html body .vq-on .vq-issue.vq-deja:active{background:linear-gradient(180deg,rgba(124,82,255,.46) 0%,rgba(52,34,140,.62) 100%);color:var(--c-texte)}
/* « Créer mon compte » pas encore rempli : le même dégradé, éteint, au lieu d'un bouton noir */
html body #s-compte #cp-body .cr-valider.inerte{color:rgba(255,255,255,.72);
  background:linear-gradient(90deg,rgba(164,104,238,.38) 0%,rgba(91,51,252,.38) 50%,rgba(37,38,252,.38) 100%);
  box-shadow:inset 0 0 0 1px var(--filet-verre)}
/* compte obligatoire : pas de barre d'onglets, sa place revient à l'écran (le bloc se recentre) */
html.compte-exige body #s-compte.vq-on{padding-bottom:calc(max(env(safe-area-inset-bottom,0px), var(--e-3)) + var(--e-3))}
/* [16/10 soir] porte du compte : « Pas encore de compte ? Créer un compte » sous le grand bouton « Se connecter » */
html body .vq-on .vq-ou{margin:var(--e-3) 0 0;text-align:center;font-size:var(--t-2);color:var(--c-texte-2)}
html body .vq-on .vq-lien.vq-lien-fort{font:inherit;font-weight:700;color:#C4B5FD;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1.5px;cursor:pointer}
html body .vq-on .vq-lien.vq-lien-fort::after{inset:-12px -6px}
/* [16/10 soir] connexion : le recours (code de secours, ou retour à l'e-mail) en lien sous le bouton */
#cp-body .cr-autre{margin:var(--e-3) 0 0;text-align:center;font-size:var(--t-2);color:var(--c-texte-2)}
#cp-body .cr-autre .cr-lien{font:inherit;font-weight:700;color:#C4B5FD;text-decoration:underline;text-underline-offset:3px;background:none;border:0;padding:0;cursor:pointer}
/* bouton de connexion pas encore utilisable : le dégradé éteint, comme « Créer mon compte » */
html body #s-compte #cp-body .btn.cr-cnx-go:disabled{opacity:1;color:rgba(255,255,255,.72);
  background:linear-gradient(90deg,rgba(164,104,238,.38) 0%,rgba(91,51,252,.38) 50%,rgba(37,38,252,.38) 100%);
  box-shadow:inset 0 0 0 1px var(--filet-verre)}
/* ══ [16/10 soir, Romain : « j'aime bien le 4 »] LA PORTE DU COMPTE, MAQUETTE TYPOGRAPHIQUE ══
   Ciel de nuit (fond de #s-compte.vq-on), trois lueurs qui dérivent et un halo sous le mot-symbole, cinq
   étoiles de l'accueil qui scintillent, « Trinke » en très grand avec ses étincelles, une phrase, puis en
   bas « Crée ton compte, c'est gratuit. », le bouton, le lien et les mentions. */
html.compte-exige body #s-compte.vq-on>#cp-body{padding-bottom:0}
#cp-body>.vq-blobs,#cp-body>.vq-etoiles{position:absolute;inset:0;z-index:0;pointer-events:none}
#cp-body>.vq-blobs{overflow:hidden}
.vq-blobs span,.vq-blobs i{position:absolute;border-radius:50%;filter:blur(62px)}
.vq-blobs span:nth-child(1){width:270px;height:270px;background:#8b5cf6;opacity:.36;top:-50px;left:-80px;animation:vqFlt1 9s ease-in-out infinite}
.vq-blobs span:nth-child(2){width:230px;height:230px;background:#ff5da2;opacity:.22;bottom:70px;right:-80px;animation:vqFlt2 11s ease-in-out infinite}
.vq-blobs span:nth-child(3){width:190px;height:190px;background:#22d3ee;opacity:.18;bottom:-60px;left:18%;animation:vqFlt1 13s ease-in-out infinite}
.vq-blobs i{width:560px;height:360px;left:50%;margin-left:-280px;top:calc(33% - 180px);filter:blur(12px);
  background:radial-gradient(closest-side,rgba(139,92,246,.46),rgba(139,92,246,.14) 52%,transparent 74%)}
@keyframes vqFlt1{0%,100%{transform:translate(0,0)}50%{transform:translate(18px,-22px)}}
@keyframes vqFlt2{0%,100%{transform:translate(0,0)}50%{transform:translate(-20px,16px)}}
#cp-body>.vq-etoiles use{fill:#D9A7FF;animation:scintille 4s ease-in-out infinite}
#cp-body>.vq-etoiles use:nth-child(2n){animation-delay:-1.3s}#cp-body>.vq-etoiles use:nth-child(3n){animation-delay:-2.6s}
@keyframes scintille{0%,100%{opacity:1}50%{opacity:.4}}
.vq-porte{position:relative;z-index:1;flex:1 1 auto;display:flex;flex-direction:column;align-items:center;width:100%}
.vq-esp1{flex:1.4 1 0}.vq-esp2{flex:1.6 1 0}
.vq-haut{display:flex;flex-direction:column;align-items:center}
.vq-wm{position:relative;width:fit-content;font-family:-apple-system,"SF Pro Display","Helvetica Neue",sans-serif;
  font-size:4.75rem;font-weight:700;letter-spacing:-.03em;line-height:1;color:var(--c-texte);
  filter:drop-shadow(0 0 8px rgba(215,130,255,.6)) drop-shadow(0 0 28px rgba(170,70,255,.5)) drop-shadow(0 0 60px rgba(120,40,255,.35))}
.vq-wm::after{content:"";position:absolute;right:-.5em;top:-.13em;width:.95em;height:.52em;animation:scintille 3.4s ease-in-out infinite;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 116 64'%3E%3Cg fill='none' stroke='%23fff' stroke-width='5' stroke-linecap='round'%3E%3Cpath d='M46.4 26.5 L44 12.7'/%3E%3Cpath d='M67.2 28.7 L73.7 16.3'/%3E%3Cpath d='M82.8 43.6 L95.5 37.7'/%3E%3C/g%3E%3C/svg%3E") no-repeat center/contain}

.vq-tag{margin:var(--e-4) 0 0;text-align:center;color:var(--c-texte-2);font-size:var(--t-3);letter-spacing:-.01em;max-width:260px;line-height:1.35}
.vq-soustitre{margin:0 0 var(--e-3);text-align:center;color:var(--c-texte-2);font-size:var(--t-3);line-height:1.4}
#cp-body>.vq-etoiles{width:100%;height:100%}
.vq-porte{padding:0 var(--e-2);box-sizing:border-box}
/* le bouton de la maquette : gele de 56, rayon 28, encre blanche sur un degrade horizontal violet → indigo,
   lisere de lumiere en haut, lueur de sa teinte dessous (celle de l'accueil, pas le mauve mat du gabarit) */
html body .vq-porte .vq-issue.vq-creer{min-height:56px;width:100%;border-radius:var(--r-4);color:var(--c-texte);font-weight:700;
  background:linear-gradient(90deg,#A468EE 0%,#7B3EFC 20%,#5933FC 38%,#442CFB 56%,#3528FB 76%,#2526FC 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.55),0 12px 28px -10px rgba(110,70,255,.95),0 0 26px rgba(110,70,255,.28)}
html body .vq-porte .vq-issue.vq-creer:active{background:linear-gradient(90deg,#9A5EE4 0%,#7036F0 20%,#4F2CF0 38%,#3C26EE 56%,#2F22EE 76%,#2020EE 100%);
  box-shadow:inset 0 1.5px 0 rgba(255,255,255,.4),0 6px 14px -10px rgba(110,70,255,.7)}
html body .vq-porte .vq-issue.vq-creer .vq-g{stroke-width:1.9}
html body .vq-porte .vq-ou{margin:var(--e-1) 0 0;color:var(--c-texte-2);font-size:var(--t-2)}
html body .vq-porte .vq-legal{margin:var(--e-3) auto 0;color:var(--c-texte-3)}
/* liens en ligne qui se coupent comme du texte ; la cible de toucher vient d'un rembourrage vertical
   (invisible, sans effet sur la hauteur de ligne), pas du ::after absolu, mal defini sur un inline casse */
html body .vq-porte .vq-legal .vq-lien-txt{display:inline;padding:var(--e-2) 0;color:#A78BFA;text-decoration:none;
  cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}
html body .vq-porte .vq-legal .vq-lien-txt::after{content:none}
html body .vq-porte .vq-legal .vq-lien-txt:active{opacity:.55}
@media (max-height:700px){ .vq-wm{font-size:3.9rem} .vq-tag{margin-top:var(--e-3)} }
@media (prefers-reduced-motion:reduce){ .vq-blobs span,.vq-wm::after,#cp-body>.vq-etoiles use{animation:none} }

/* [16/10, Romain : mot de passe + trousseau] L'OEIL DU CHAMP MOT DE PASSE : un bouton de 2.75rem (44 px) collé
   au bord droit du champ, glyphe 1.25rem, encre discrète, qui montre ce qu'on tape. Le champ garde sa place :
   l'oeil est dans le flex de .cr-champ, après l'input. */
html body #cp-body .cr-champ>.cr-oeil{flex:0 0 auto;width:2.75rem;height:2.75rem;margin:-0.5rem -0.75rem -0.5rem -0.25rem;
  display:flex;align-items:center;justify-content:center;background:none;border:0;color:var(--c-texte-3);cursor:pointer;border-radius:0.75rem}
html body #cp-body .cr-champ>.cr-oeil>svg{width:1.25rem;height:1.25rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
html body #cp-body .cr-champ>.cr-oeil[aria-pressed="true"]{color:#A78BFA}
html body #cp-body .cr-champ>.cr-oeil:focus-visible{outline:0.125rem solid #A78BFA;outline-offset:-0.125rem}

/* [16/10, Romain, capture iPhone : « le bouton lancer la soirée est trop petit »] LE BOUTON GRANDIT SANS
   PRENDRE TOUTE LA LARGEUR (refusee le 07/10, v946). Mesure avant a 393 pt : 200 x 33 pt, texte 13,4 pt,
   56 % de la carte, a peine plus que les « Jouer » (100 x 28). Apres : 640 x 100 sur la toile, soit
   267 x 42 pt (75 % de la carte), texte 2.5rem = 16,7 pt, graisse 500, fleche dans le flux ; cale en bas
   de la carte (bottom) pour ne dependre d'aucune hauteur, centre par calc. */
html body #s-home #mv-canvas .mv-lancer{left:calc(50% - 320px);top:auto;bottom:44px;width:640px;height:100px;border-radius:50px;
  font-size:2.5rem;font-weight:500;justify-content:center;padding-left:0;gap:26px}
html body #s-home #mv-canvas .mv-lancer svg{position:static;left:auto;right:auto;transform:none;width:38px;height:34px}


/* [16/10, Romain] PURPLE : LE PRENOM SOUS LES RONDS. « avec l'initiale on sait pas si deux joueurs ont la même
   initiale ». Meme ligne qu'au Palmier (#pm-qui), posee entre la rangee et la table. */
html body #s-purple .pm-qui{flex:0 0 auto;margin:var(--e-2) 18px 0;font-size:var(--t-3);font-weight:700;color:#F9A8D4;text-align:center}
html body #s-purple .pm-qui:empty{display:none}
/* [17/10] anti-robot Cloudflare Turnstile : invisible tant que Cloudflare ne doute pas ; s'il doute, sa case
   apparait en bas au centre, au-dessus de tout (la barre d'onglets et les feuilles comprises) */
#ts-boite{position:fixed;left:50%;bottom:calc(16px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:9999}
#ts-boite:empty{display:none}

/* ══ [20/10, Romain] LA ROUE, DIRECTION D (« D c'est top ») ══════════════════════════════════════
   La consigne detachee de la roue par un vrai espace ; repere blanc de l'app. */
html body #s-wheel #w-inst{text-align:center;padding:0 var(--e-4);margin-bottom:var(--e-5)!important}
html body #s-wheel #w-inst1{display:block;font-size:var(--t-4);font-weight:700;color:var(--c-texte);letter-spacing:-.01em;line-height:1.2}
html body #s-wheel #w-inst2{margin:var(--e-2) 0 0;font-size:var(--t-2);color:var(--c-texte-2);line-height:1.35}
html body #s-wheel .wpointer{border-top-color:#F7F5FA;filter:drop-shadow(0 3px 4px rgba(0,0,0,.6))}
html body #s-wheel #wheel{filter:drop-shadow(0 12px 26px rgba(0,0,0,.6)) drop-shadow(0 0 22px rgba(139,92,246,.28))}
/* [20/10, Romain : « dans mini-jeux le bouton doit être or »] le bouton de la Girouette garde l'or des mini-jeux
   (regle M de MODES-VERRE) : la direction D change la roue, pas le bouton. Voir docs/REGLES-PAR-ZONE.md. */

/* [20/10] Multijoueur a distance : la reponse du Quiz, la meme bulle que sur un telephone (#c-reveal.shown) */
.mp-rep{display:block;align-self:center;margin:var(--e-3) auto 0;max-width:100%;box-sizing:border-box;padding:var(--e-2) var(--e-3);border-radius:var(--r-2);
  background:rgba(10,11,39,.62);border:1.5px solid rgba(90,155,224,.7);color:var(--c-texte);font:inherit;font-weight:700;
  font-size:var(--t-3);line-height:1.3;text-align:center;white-space:normal;-webkit-tap-highlight-color:transparent}
.mp-rep:disabled{color:#A9CDF5;opacity:1}
.mp-rep.ouvre{animation:repFondu var(--m-moyen) var(--m-sortie) both}
@media (prefers-reduced-motion:reduce){.mp-rep.ouvre{animation:none}}

/* ══ [20/10, Romain] LUMIERE DES MINI-JEUX : AUX BORDS, LEGERE, SYMETRIQUE (choix F) ═══════════════════════
   « la tache de couleur en plein milieu c'est pas très agréable […] dans la vraie vie on ne regarde pas une source
   de lumière forte en plein dans les yeux », « fais des trucs symétriques […] au niveau des positions des halos »,
   « reste léger sur les touches de couleur ». Le rond ambre du 14/10 (.gscreen::before) et la nappe centrale de M1
   disparaissent ; quatre lueurs sur les bords lateraux, en miroir : violet en haut, ambre en bas.
   Vaut pour tout ecran de mini-jeu (.gscreen, Soiree comprise) et pour le catalogue et les reglages des mini-jeux.
   Regle generale dans docs/REGLES-PAR-ZONE.md. */
html body .screen.gscreen::before{display:none!important}
html body :is(.screen.gscreen:not(#s-home),#s-mjhub,#s-mreg,#s-mavances){background-color:#020106!important;background-image:
  radial-gradient(30% 34% at -8% 22%, rgba(123,62,252,.11), transparent 72%),
  radial-gradient(30% 34% at 108% 22%, rgba(123,62,252,.11), transparent 72%),
  radial-gradient(30% 34% at -8% 78%, rgba(255,170,60,.08), transparent 72%),
  radial-gradient(30% 34% at 108% 78%, rgba(255,170,60,.08), transparent 72%),
  linear-gradient(#000102,#01030F)!important}

/* [20/10, Romain] La bombe : la consigne au-dessus du jeu, lisible, comme la Girouette et les autres mini-jeux */
html body #s-bomb #bomb-inst,html body #s-bomb #bomb-inst2{margin:0 0 var(--e-3);padding:0 var(--e-4);text-align:center;color:var(--c-texte);font-size:var(--t-3);font-weight:600;line-height:1.4}
/* un espace entre les deux phrases (Romain, 20/10) */
html body #s-bomb #bomb-inst{margin-bottom:var(--e-2)}
/* deux phrases, une par ligne ; la premiere tient sur une ligne (taille calculee sur sa largeur) (Romain, 20/10) */
html body #s-bomb #bomb-inst,html body #s-bomb #bomb-inst2{text-wrap:balance;padding:0 var(--e-2);font-size:min(1.0625rem,calc((100vw - 60px) / 22.4))}   /* [21/10] e-2 et non e-3 : a 16 px la premiere phrase passait sur deux lignes (REGLES-PAR-ZONE, une ligne) */

/* ══ [20/10, Romain] BOUTIQUE, TOUT EST DEBLOQUE : le pass en haut (F), ce qu'il ouvre a toucher (D) ══════════
   « j'aime bien les trucs à cliquer qui te renvoient dans l'app, comme dans le D, mais j'aime aussi le haut du F,
   qui montre l'achat et à quelle date ». Lumiere aux bords, en miroir et legere (regle du 20/10) : la nappe
   centrale du ciel de la Boutique est eteinte sur cet etat seulement ; la page d'achat garde la sienne. */
html body #s-boutique:has(.bq-a){background-image:
  radial-gradient(60% 34% at -8% 18%,rgba(139,92,246,.13),transparent 70%),
  radial-gradient(60% 34% at 108% 18%,rgba(139,92,246,.13),transparent 70%),
  radial-gradient(70% 30% at -10% 88%,rgba(236,72,153,.08),transparent 70%),
  radial-gradient(70% 30% at 110% 88%,rgba(236,72,153,.08),transparent 70%),
  linear-gradient(#000102,#01030F)}
#s-boutique .bq-a{justify-content:center;gap:0;padding-bottom:var(--e-2)}
#s-boutique .bq-a .bq-vip-titre{margin:0 0 var(--e-3)}
/* le bracelet qu'on a : la carte creme de la page d'achat, sa date en violet */
#s-boutique .bq-a .bq-br{cursor:default;min-height:0;padding:var(--e-4) var(--e-3) var(--e-3)}
#s-boutique .bq-a .bq-brc{align-self:stretch;margin:0 18px var(--e-3)}
#s-boutique .bq-a-seul{width:100%}
#s-boutique .bq-a-seul .bq-brc{margin:0 34px var(--e-3)}
#s-boutique .bq-a-date{display:block;margin-top:var(--e-1);font-size:var(--t-2);font-weight:600;opacity:.85}
#s-boutique .bq-a-mien .bq-brc{filter:none;opacity:1}
#s-boutique .bq-a-brs button.bq-br{cursor:pointer}
#s-boutique .bq-a .bq-px{font-size:var(--t-4)}
.bq-a-lab{margin:var(--e-4) 2px var(--e-2);font-size:var(--t-1);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--c-texte-3)}
/* les tuiles : le dessin de l'accueil (pastille d'icone, titre, sous-titre, « Jouer » en verre) */
.bq-tuiles{display:flex;flex-direction:column;gap:var(--e-2)}
.bq-t{position:relative;display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;column-gap:var(--e-3);align-items:center;min-height:72px;padding:var(--e-3) var(--e-3) var(--e-3) var(--e-3);border:0;border-radius:var(--r-3);
  cursor:pointer;font:inherit;text-align:left;color:var(--c-texte);overflow:hidden;-webkit-tap-highlight-color:transparent}
.bq-t-ico{grid-row:1/3;width:42px;height:42px;border-radius:var(--r-1);display:grid;place-items:center}
.bq-t-ico svg{width:26px;height:26px;fill:none;stroke:#fffaf5;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.bq-t b{grid-column:2;align-self:end;font-size:var(--t-3);font-weight:700;line-height:1.15}
.bq-t small{grid-column:2;align-self:start;font-size:var(--t-1);color:var(--c-texte);opacity:.85;margin-top:2px}
.bq-t-jouer{grid-column:3;grid-row:1/3;display:flex;align-items:center;justify-content:center;gap:var(--e-2);height:36px;padding:0 var(--e-3);border-radius:var(--r-3);
  font-size:var(--t-2);color:var(--c-texte);background:linear-gradient(rgba(255,255,255,.10),rgba(255,255,255,.10)),var(--teinte);box-shadow:0 0 0 1.5px rgba(255,255,255,.55)}
.bq-t-jouer svg{width:16px;height:14px;fill:none;stroke:#fff;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round}
/* [20/10, Romain : « enlève les couleurs, le violet est associé à Soirée »] les lignes ne portent pas de teinte
   de mode : verre nuit a filet lavande du socle, cadenas lavande, « Jouer » en verre */
.bq-t{background:rgba(10,11,39,.62);box-shadow:inset 0 0 0 1px rgba(196,181,253,.22),inset 0 1px 0 rgba(255,255,255,.06);--teinte:rgba(196,181,253,.10)}
.bq-t .bq-t-ico{background:rgba(196,181,253,.12);box-shadow:inset 0 0 0 1px rgba(196,181,253,.25)}
.bq-t .bq-t-ico svg{stroke:#C4B5FD}
.bq-t small{color:var(--c-texte-3);opacity:1}
.bq-t .bq-t-jouer{box-shadow:0 0 0 1.5px rgba(196,181,253,.45)}
/* [20/10, Romain : « remets des couleurs, mais fais ça mieux »] la couleur dit CE QUI EST OUVERT, pas un mode, et
   reprend la page d'achat : l'arc-en-ciel des familles de cartes pour « +700 cartes » (son ruban), l'or des cadenas
   pour les mini-jeux (ses cases), la chaleur (orange vers rouge) pour les ambiances qui piquent. Seule la pastille
   est pleine ; la ligne reste en verre, a peine teintee sur son bord. */
.bq-t-cartes{box-shadow:inset 0 0 0 1px rgba(236,72,153,.32),inset 0 1px 0 rgba(255,255,255,.06)}
/* [20/10, Romain : « remplace le multicolore »] le rose vers violet du bracelet VIP : les cartes sont le coeur du pass */
.bq-t-cartes .bq-t-ico{background:linear-gradient(150deg,#EC4899,#8B5CF6);box-shadow:none}
.bq-t-amb{box-shadow:inset 0 0 0 1px rgba(251,113,80,.32),inset 0 1px 0 rgba(255,255,255,.06)}
.bq-t-amb .bq-t-ico{background:linear-gradient(150deg,#FF9A3C,#F0384F);box-shadow:none}
.bq-t-minis{box-shadow:inset 0 0 0 1px rgba(252,211,77,.32),inset 0 1px 0 rgba(255,255,255,.06)}
.bq-t-minis .bq-t-ico{background:linear-gradient(150deg,#FCD34D,#B07A04);box-shadow:none}
.bq-t-minis .bq-t-ico svg{stroke:#2A1B02}
.bq-t-cartes .bq-t-ico svg{stroke:#fff}
.bq-t-amb .bq-t-ico svg{stroke:#fff}
.bq-t:active{transform:scale(.985)}
@media (prefers-reduced-motion:reduce){.bq-t:active{transform:none}}
#s-boutique .bq-a .bq-gerer{margin-top:var(--e-3)}
/* un reflet de sa couleur part de la pastille et s'eteint avant le milieu de la ligne */
.bq-t-cartes{background:linear-gradient(90deg,rgba(236,72,153,.16),rgba(139,92,246,.06) 40%,transparent 62%),rgba(10,11,39,.62)}
.bq-t-amb{background:linear-gradient(90deg,rgba(255,122,60,.17),rgba(240,56,79,.06) 40%,transparent 62%),rgba(10,11,39,.62)}
.bq-t-minis{background:linear-gradient(90deg,rgba(252,211,77,.15),rgba(224,164,12,.05) 40%,transparent 62%),rgba(10,11,39,.62)}

/* ===== CASE PIEGEE, DIRECTION A (Romain, 20/10 : « le A est bien, juste enlève les halos derrière les cases ») =====
   Verre nuit a filet or et reflet en haut, sans halo derriere ; sure = vert, piegee = rouge (inchanges). */
html body #s-roulette .cp-case{position:relative;overflow:hidden;color:var(--c-texte);border:1.5px solid transparent;
  background:linear-gradient(160deg,#16132e,#0b0a1c) padding-box,
    linear-gradient(160deg,rgba(252,211,77,.85),rgba(217,160,6,.25) 45%,rgba(252,211,77,.6)) border-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
html body #s-roulette .cp-case::before{content:"";position:absolute;inset:3px 3px 50% 3px;border-radius:var(--r-1) var(--r-1) var(--r-4) var(--r-4);
  background:linear-gradient(180deg,rgba(255,255,255,.10),transparent);pointer-events:none}
html body #s-roulette .cp-case.vide{color:rgba(187,247,208,.75);
  background:linear-gradient(160deg,#0f2a1b,#0a1a12) padding-box,linear-gradient(160deg,rgba(74,222,128,.7),rgba(74,222,128,.2)) border-box;
  box-shadow:inset 0 3px 10px rgba(0,0,0,.5)}
html body #s-roulette .cp-case.vide::before,html body #s-roulette .cp-case.piege::before,html body #s-roulette .cp-case.revele::before{content:none}
html body #s-roulette .cp-case.revele{background:rgba(248,113,113,.08);border:1.5px dashed rgba(248,113,113,.7)}
/* [21/10, Romain, tri du rouge, teinte B] le bord en dégradé des cases, en rouge, sur un fond rouge sombre */
html body #s-roulette .cp-case.piege{background:linear-gradient(160deg,#2a1216,#160a0d) padding-box,linear-gradient(160deg,rgba(248,113,113,.85),rgba(248,113,113,.25) 45%,rgba(248,113,113,.6)) border-box;border:1.5px solid transparent;color:var(--c-texte);box-shadow:none}
/* la phrase du tour : pastille de verre, prenom en or */
html body #s-roulette #rl-result.cp-pastille{display:inline-block;width:auto;max-width:calc(100% - 32px);padding:var(--e-2) var(--e-3);border-radius:999px;
  background:rgba(10,11,39,.62);border:1px solid rgba(196,181,253,.25);font-size:var(--t-2)}
html body #s-roulette #rl-result.cp-pastille b{color:#FCD34D}
/* La case piegee : la regle au-dessus de la grille, une phrase par ligne (Romain, 20/10, direction B) */
html body #s-roulette .cp-inst{margin:var(--e-3) 0 0;padding:0 var(--e-3);text-align:center;color:var(--c-texte);font-weight:600;line-height:1.4;
  font-size:min(1.0625rem,calc((100vw - 60px) / 20))}
html body #s-roulette .cp-inst+.cp-inst{margin-top:var(--e-2)}
/* petits ecrans (iPhone SE, 553 px utiles) : la consigne se resserre pour que la pastille du tour reste visible */
@media (max-height:620px){
  html body #s-roulette .cp-inst{margin-top:var(--e-2)}
  html body #s-roulette .cp-inst+.cp-inst{margin-top:2px}
  html body #s-roulette .cp-grille{min-width:170px;margin-bottom:var(--e-3)}
}
/* La case piegee, message apres une case sure (Romain, 20/10, direction E) : encadre vert pale, comme la case sure */
html body #s-roulette #rl-result.cp-pastille{background:rgba(74,222,128,.10);border:1px solid rgba(74,222,128,.35);border-radius:var(--r-3);font-weight:700;line-height:1.4}
/* Gorgees en bas de TOUS les mini-jeux (Romain, 20/10, direction C, d'abord Girouette et case piegee puis « oui vasy » pour tous) : une seule ligne dans la pastille
   du prenom (fond nuit, contour or), « Tu distribues · 2 gorgées » ; un nom long passe a la ligne sans deborder */
html body .sanction.mv-pastille{flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:baseline;
  gap:2px var(--e-2);background:#0d0b22;border:1.5px solid #D9A006;border-radius:999px;padding:var(--e-2) var(--e-4);max-width:calc(100vw - 48px)}
html body .sanction.mv-pastille .s-label{color:var(--c-texte);font-size:var(--t-2);font-weight:700;opacity:1}
html body .sanction.mv-pastille .s-label::after{content:" ·";color:var(--c-texte-3)}
html body .sanction.mv-pastille .s-count{font-size:var(--t-2);font-weight:800;color:#FCD34D}
html body #s-roulette #rl-result.cp-pastille b{white-space:nowrap}
html body .sanction.mv-pastille:has(.s-count:empty) .s-label::after{content:none}
html body .sanction.mv-pastille .s-count:empty{display:none}
/* [20/10, Romain : « la réponse des quiz disparaît pas comme la carte, ça fait un effet chelou »] l'encadre ouvert
   portait son fondu d'ouverture (repFondu, regle a id) qui ecrasait la sortie de la carte : il part maintenant avec elle */
html body #s-game .gamecard.vie-sort #c-reveal{animation:vieSort var(--m-court) var(--m-depart) both}
@media (prefers-reduced-motion:reduce){html body #s-game .gamecard.vie-sort #c-reveal{animation:none}}
/* [20/10, Romain : « le bouton lancer une soirée est trop gros », direction A] 15 % plus petit, centre garde ;
   `scale` (propriete a part) se combine avec un eventuel transform d'appui sans l'ecraser */
html body #s-home #mv-canvas .mv-lancer{scale:.85}

/* ===== ACCUEIL PLUS VIVANT (Romain, 20/10 : « met B doux et A », puis 2C) =====
   Reflet de « Lancer une Soirée » (blanc a 38 %) et eclats des tuiles passent A TOUR DE ROLE, toutes les 9 s :
   le reflet balaie le bouton (1 s a 2,6 s du cycle), les eclats prennent le relais pendant sa fin (2 s a 6 s).
   Jamais deux accents au meme instant au-dela du relais (docs/MOUVEMENT.md, budget par ecran).
   B doux : la carte Soirée respire, lueur violette qui monte et descend en 7 s, legere. */
html body #s-home #mv-canvas .mv-lancer::after{background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.38),rgba(255,255,255,0));
  animation:accReflet2 var(--acc-cycle) ease-in-out 1s infinite}
@keyframes accReflet2{0%{transform:translateX(-180px) skewX(-18deg)}17.5%,100%{transform:translateX(760px) skewX(-18deg)}}
html body #s-home #mv-canvas .mv-soiree{animation:accRespire 7s ease-in-out infinite}
@keyframes accRespire{0%,100%{filter:drop-shadow(0 0 0 rgba(164,104,238,0))}50%{filter:drop-shadow(0 0 12px rgba(164,104,238,.32))}}
html body #s-home.acc-relance #mv-canvas .mv-soiree,html body #s-home.acc-relance #mv-canvas .mv-lancer::after{animation:none!important}
@media (prefers-reduced-motion:reduce){html body #s-home #mv-canvas .mv-soiree,html body #s-home #mv-canvas .mv-lancer::after{animation:none!important}}

/* ===== TUILES CLASSIQUES, MINI-JEUX, QUIZ : DEUX ECLATS QUI FONT LE TOUR DE LA BORDURE (Romain, 20/10, D lent tres fin, puis 2C) =====
   Deux lueurs face a face (pointe blanche, couleur claire de la tuile) font UN tour en 4 s puis s'eteignent,
   une fois par cycle de 9 s, 1 s apres le depart du reflet (relais).
   ⚠️ ELLES NE FONT QUE GLISSER (transform), COMME LE REFLET. Romain, 20/10 : « l'effet reflet est superfluide, ce
      n'est pas le cas d'éclats ». L'ancien eclat (degrade conique tournant, @property) etait redessine a chaque
      image par le processeur et accrochait dans Safari ; un angle constant donnait en plus une vitesse irreguliere
      le long d'une tuile haute. Ici : .mv-eclats est un anneau (masque, 1,5 px de toile) ; chaque <i> glisse
      d'un coin a l'autre, a vitesse constante (temps de chaque cote proportionnel a sa longueur, tuile 282 x 400),
      et porte une lueur ronde que seul l'anneau laisse voir. Ne pas revenir a une animation de peinture. */
html body #s-home #mv-canvas .mv-eclats{position:absolute;inset:0;border-radius:inherit;padding:1.5px;pointer-events:none;z-index:4;overflow:hidden;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;
  opacity:0;animation:accEclatVoile var(--acc-cycle) linear 2s infinite}
html body #s-home #mv-canvas .mv-eclats>i{position:absolute;left:10px;top:10px;right:10px;bottom:10px;will-change:transform}
html body #s-home #mv-canvas .mv-eclats>i:nth-child(1){animation:accEclatA var(--acc-cycle) linear 2s infinite}
html body #s-home #mv-canvas .mv-eclats>i:nth-child(2){animation:accEclatB var(--acc-cycle) linear 2s infinite}
html body #s-home #mv-canvas .mv-eclats>i::before{content:"";position:absolute;left:-60px;top:-60px;width:120px;height:120px;border-radius:50%;
  background:radial-gradient(circle,#fff 0,#fff 12%,var(--accEclat) 30%,transparent 64%)}
html body #s-home #mv-canvas{--acc-cycle:9s}   /* reflet et eclats partagent ce cycle : ils restent cales l'un sur l'autre */
html body #s-home #mv-canvas .mv-m1{--accEclat:#FFB3D0}
html body #s-home #mv-canvas .mv-m2{--accEclat:#FFE0A0}
html body #s-home #mv-canvas .mv-m3{--accEclat:#B8DCFF}
@keyframes accEclatVoile{0%{opacity:0}3%{opacity:1}40%{opacity:1}44.4%,100%{opacity:0}}
@keyframes accEclatA{0%{transform:translate(0,0)}9.18%{transform:translate(100%,0)}22.2%{transform:translate(100%,100%)}31.38%{transform:translate(0,100%)}44.4%,100%{transform:translate(0,0)}}
@keyframes accEclatB{0%{transform:translate(100%,100%)}9.18%{transform:translate(0,100%)}22.2%{transform:translate(0,0)}31.38%{transform:translate(100%,0)}44.4%,100%{transform:translate(100%,100%)}}
html body #s-home.acc-relance #mv-canvas .mv-eclats,html body #s-home.acc-relance #mv-canvas .mv-eclats>i{animation:none!important}
@media (prefers-reduced-motion:reduce){html body #s-home #mv-canvas .mv-eclats,html body #s-home #mv-canvas .mv-eclats>i{animation:none!important;opacity:0}}
/* ================= DECOR-CALME (20/10, Romain, choix 1A) =================
   Reglage « Decor anime » (fiche Reglages). Eteint, il coupe les boucles de decor : accueil,
   ecrans a verrou, defile de la boutique. WCAG 2.2.2 : un mouvement automatique de plus de 5 s
   doit pouvoir s'arreter. Les objets et signaux de jeu ne sont jamais concernes (mouvement
   essentiel). On coupe le NOM de l'animation : chaque element s'affiche a son etat de repos. */
html.decor-calme #s-home,html.decor-calme #s-home::before,html.decor-calme #s-home::after,
html.decor-calme #s-home *,html.decor-calme #s-home *::before,html.decor-calme #s-home *::after,
html.decor-calme .vq-blobs span,html.decor-calme .vq-scene::before,html.decor-calme .vq-wm::after,
html.decor-calme #cp-body>.vq-etoiles use,html.decor-calme .bq-piste,html.decor-calme .home-bg span{animation:none!important}
/* ================= FENETRES-MOUVEMENT (20/10, Romain, choix D) =================
   Releve du 20/10 : 13 fenetres sur 14 apparaissaient et disparaissaient d'un coup. Toutes suivent
   maintenant le meme geste, en CSS seul (les 32 ouvertures et fermetures d'app.js n'ont pas change) :
   - le fond s'assombrit en fondu ;
   - une fiche du bas monte depuis le bas de l'ecran, avec un leger rebond a l'arrivee (--m-ressort) ;
   - une fenetre centree (milieu, Regles) grandit de 90 a 100 %, meme rebond ;
   - entree --m-moyen, sortie --m-court (on ne fait pas attendre qui veut partir).
   display s'anime grace a transition-behavior:allow-discrete et @starting-style (Safari 17.4+, Chrome 117+) ;
   un navigateur plus ancien affiche et retire la fenetre d'un coup, comme avant : rien ne casse. */
html body .modal{opacity:0;transition:opacity var(--m-court) var(--m-depart),display var(--m-court) allow-discrete,overlay var(--m-court) allow-discrete}
html body .modal.on{opacity:1;transition:opacity var(--m-moyen) var(--m-sortie),display var(--m-moyen) allow-discrete,overlay var(--m-moyen) allow-discrete}
@starting-style{html body .modal.on{opacity:0}}
html body .modal:not(.milieu):not(#m-rules)>.sheet{transform:translateY(100%);transition:transform var(--m-court) var(--m-depart)}
html body .modal.on:not(.milieu):not(#m-rules)>.sheet{transform:none;transition:transform var(--m-moyen) var(--m-ressort)}
@starting-style{html body .modal.on:not(.milieu):not(#m-rules)>.sheet{transform:translateY(100%)}}
html body :is(.modal.milieu,#m-rules)>.sheet{transform:scale(.9);transition:transform var(--m-court) var(--m-depart)}
html body :is(.modal.milieu,#m-rules).on>.sheet{transform:none;transition:transform var(--m-moyen) var(--m-ressort)}
@starting-style{html body :is(.modal.milieu,#m-rules).on>.sheet{transform:scale(.9)}}
@media (prefers-reduced-motion:reduce){html body .modal>.sheet,html body .modal.on>.sheet{transform:none!important;transition:none!important}}
/* [20/10, Romain] paragraphe dans le texte d'une carte (« \n » dans cartes-fr.json, posePhrase) : petit espace */
html body :is(#s-game,#s-classic-run) .pp-bloc{display:block}
html body :is(#s-game,#s-classic-run) .pp-suite{margin-top:.6em}


/* [20/10, Romain : « vasy aligne »] SOIREE ET CLASSIQUES A DISTANCE : meme changement de carte que sur un telephone
   (docs/MOUVEMENT.md, famille « vie ») : sortie vieSort en --m-court, entree vieEntre en cascade (badge, phrase a .07 s,
   sanction et reponse a .14 s), 0,5 s en tout. Remplace cardPop/popIn sur cet ecran. */
html body #s-multi .mp-carte.anim .tag{animation:vieEntre var(--m-moyen) var(--m-sortie) backwards}
html body #s-multi .mp-carte.anim .cardtext{animation:vieEntre var(--m-moyen) var(--m-sortie) .07s backwards}
html body #s-multi .mp-carte.anim .sanction,html body #s-multi .mp-carte.anim~.mp-rep{animation:vieEntre var(--m-moyen) var(--m-sortie) .14s backwards}
html body #s-multi .mp-carte.vie-sort>*{animation:vieSort var(--m-court) var(--m-depart) both}
@media (prefers-reduced-motion:reduce){
  html body #s-multi .mp-carte.anim :is(.tag,.cardtext,.sanction),html body #s-multi .mp-carte.anim~.mp-rep,
  html body #s-multi .mp-carte.vie-sort>*{animation:none}
}

/* [20/10, Romain, direction E sur planche] L'EXPLOSION DE LA BOMBE : elle gonfle et disparait sous le BOUM plein ecran
   (bigMoment), l'ecran tremble un tiers de seconde. uiEcran reste en tete de liste : meme nom a la meme place,
   l'entree de l'ecran n'est ni rejouee a l'ajout ni au retrait de la classe. Mouvement reduit : la bombe s'efface net. */
#bomb-pulse.explose{animation:bombeExplose var(--m-court) ease-in forwards!important}
@keyframes bombeExplose{60%{opacity:1;transform:scale(1.28)}to{opacity:0;transform:scale(1.5)}}
#s-bomb.on.tremble{animation:uiEcran var(--m-moyen) var(--m-sortie) both,bombeTremble var(--m-moyen) linear}
@keyframes bombeTremble{20%{transform:translate(-6px,3px)}40%{transform:translate(5px,-4px)}60%{transform:translate(-4px,2px)}80%{transform:translate(3px,-1px)}}
@media (prefers-reduced-motion:reduce){#bomb-pulse.explose{animation:none!important;opacity:0}#s-bomb.on.tremble{animation:none}}

/* [21/10, Romain] La roulette : la bille se pose n'importe ou sur le cylindre ; la fleche du haut aurait montre un autre
   numero que celui de la bille, elle est retiree. Le numero sorti s'affiche au centre (#ca-num). */
html body #s-casino .roul-ptr{display:none}

/* [21/10, Romain] Le 5 parfait : le chrono reste blanc, et passe au vert seulement si on tombe dans la marge. Pas de rouge :
   « le rouge annonce un peu "tu as mal fait", il faut limiter son utilisation dans les jeux ». */
html body #dx-clock.proche{color:#4ADE80!important;text-shadow:0 0 28px rgba(74,222,128,.45)!important}

/* [21/10, Romain, direction B3] Le stop parfait : au Stop, choc lumineux doux du curseur, zone touchee eclairee */
/* [21/10, Romain] le curseur n'a pas de halo pendant qu'il court : la lueur ne vient qu'au Stop */
html body #s-timing .tmmark{box-shadow:none}
html body #s-timing .tmmark.tm-choc{animation:tmChoc var(--m-moyen) var(--m-sortie)}
@keyframes tmChoc{0%{transform:scaleX(1.6);box-shadow:0 0 14px 2px rgba(255,255,255,.55)}100%{transform:scaleX(1)}}
html body #s-timing .tmtarget.tm-touche{animation:tmTouche var(--m-moyen) var(--m-sortie)}
@keyframes tmTouche{0%{filter:brightness(1)}35%{filter:brightness(1.3)}100%{filter:brightness(1)}}
@media (prefers-reduced-motion:reduce){html body #s-timing .tmmark.tm-choc,html body #s-timing .tmtarget.tm-touche{animation:none}}
/* [21/10] Tape le plus vite : « TAPE ! » et le verdict en grand et blanc (ils etaient petits et gris) ;
   hauteur reservee pour que le cercle ne bouge pas entre la consigne, la manche et le verdict */
html body #s-tap #tap-inst{min-height:84px;margin:18px 0 0;display:flex;flex-direction:column;align-items:center;justify-content:flex-start}
html body #s-tap #tap-inst.tap-fort{font-size:var(--t-5);font-weight:800;color:var(--c-texte);letter-spacing:-.01em}
/* [21/10] La cible comme les autres jeux : avatars en haut, prenom dessous (le bandeau descend ; moveDot
   evite deja le bandeau et la rangee). La cible passe a l'or de l'app : le rouge est garde pour peu de
   choses dans les jeux (Romain, 21/10). Un compteur dit combien de touches il reste. */
html body #tg-dot,html body #mu-face .mf-cible,html body #s-target #tg-inst:not([style*="none"])::before{background:radial-gradient(circle at 50% 50%,#FFF4C7 0 16%,#FBBF24 16% 34%,#1a1230 34% 46%,#FBBF24 46% 64%,#1a1230 64% 76%,#FBBF24 76% 100%);border:2px solid #FDE68A;box-shadow:0 0 26px rgba(251,191,36,.5),inset 0 0 10px rgba(0,0,0,.35)}
html body #s-target #tg-compte{text-align:center;font-size:var(--t-5);font-weight:800;color:var(--c-texte);font-variant-numeric:tabular-nums;padding:var(--e-1) 0 var(--e-2)}
html body #s-target #tg-compte b{color:#FCD34D}
/* [21/10] Timer aveugle : la consigne et le verdict ont la meme place, le cadran ne remonte plus au verdict */
html body #s-blind #bl-inst,html body #s-blind #bl-result:not(:empty){min-height:136px;margin-top:var(--e-3)}
html body #s-blind #bl-result:empty{display:none}
/* [21/10] Calcul express : bonne et mauvaise reponse comme a Vrai ou faux (bord degrade, plus de rouge plein) ;
   place du verdict reservee pendant la question, l'operation ne remonte plus */
html body #s-math .ans.good{background:linear-gradient(160deg,#0f2a1b,#0a1a12) padding-box,linear-gradient(160deg,rgba(74,222,128,.85),rgba(74,222,128,.25) 45%,rgba(74,222,128,.6)) border-box;border:1.5px solid transparent;color:#BBF7D0}
html body #s-math .ans.bad{background:linear-gradient(160deg,#2a1216,#160a0d) padding-box,linear-gradient(160deg,rgba(248,113,113,.85),rgba(248,113,113,.25) 45%,rgba(248,113,113,.6)) border-box;border:1.5px solid transparent;color:#FECACA}
html body #s-math:has(#ma-answers .ans) #ma-result{min-height:96px}
/* [21/10] Trouve l'intrus : cases ratees et cases eteintes visibles (l'animation d'entree les gardait a 1) ;
   bonne case comme a Vrai ou faux ; l'intrus revele quand le temps est ecoule en or (il montre, il ne punit pas :
   rouge avec parcimonie) ; place du verdict reservee pendant la grille, elle ne remonte plus */
html body #in-grid .icell.rate{animation:none;opacity:.3}
html body #in-grid .icell.dimmed{animation:none;opacity:.22}
html body #in-grid .icell.good{background:linear-gradient(160deg,#0f2a1b,#0a1a12) padding-box,linear-gradient(160deg,rgba(74,222,128,.85),rgba(74,222,128,.25) 45%,rgba(74,222,128,.6)) border-box;border:1.5px solid transparent;color:#BBF7D0}
html body #in-grid .icell.reveal{background:linear-gradient(180deg,#3a2c08,#1f1704);border-color:#FBBF24;color:#FFF4C7;font-size:var(--t-5);padding:0;width:auto;margin:0;border-radius:var(--r-1);box-shadow:0 0 0 3px rgba(251,191,36,.4),0 0 24px rgba(251,191,36,.45)}
html body #s-intrus:has(#in-grid .icell) #in-result{min-height:96px}
/* [21/10] Sequence : la consigne et le verdict ont une place fixe, la grille ne saute plus quand la consigne s'efface ni au verdict */
html body #s-seq #sq-inst{min-height:72px;display:flex;align-items:flex-end;justify-content:center;margin-bottom:var(--e-3)}
html body #s-seq #sq-result{min-height:96px}
/* [21/10] Couleur piegee : « Mauvaise reponse » et « Trop tard » en blanc, le rouge annonce « tu as mal fait » (Romain, 21/10) */
html body #s-stroop #cr-fb.ko{color:var(--c-texte)}

/* [22/10, Romain] « la barre "suivant" des mini jeux est beaucoup trop grande, elle fait mal aux yeux » :
   les « Continuer » de fin de mini-jeu (#xx-done, 94 % de la largeur, 60 de haut) prennent la forme du
   « Suivant » de la Soiree (#btn-next plus haut) : pastille centree, 200 de large au moins, 46 de haut.
   Le JS les montre en display:block, d'ou fit-content et marges auto plutot que width:auto. */
html body .screen .btn[id$="-done"]{width:fit-content;min-width:min(47vw,200px);max-width:100%;margin-left:auto;margin-right:auto;
  min-height:46px;border-radius:999px;padding:var(--e-3) var(--e-6);font-size:var(--t-2);font-weight:700;line-height:1}
/* [22/10, Romain] « le haut du mini jeu n'est pas beau, les informations ne sont pas lisibles parfaitement » :
   le compteur passe du gris .72 au texte clair ; partie finie, compteur et regle s'effacent (sans que la
   grille bouge) : le verdict sous la grille est la seule information qui compte encore. */
html body #s-roulette .cp-restant{color:var(--c-texte)}
html body #s-roulette.cp-fini .cp-restant,html body #s-roulette.cp-fini .cp-inst{visibility:hidden}
/* [26/10, Romain] « met en blanc léger c'est mieux. En revanche garde blanc moyen pour menu de partie, reglages, areter la partie et présentation (ce qu'on pourraiit appeler des menus secondaires) ».
   Le contour par défaut passe au blanc léger (35 %) ; ces quatre fenêtres redéfinissent le jeton pour tout ce qu'elles contiennent, feuille comprise. */
/* [26/10, Romain, bouton de la page en cours] les fenêtres Trinkeurs, partie en cours et suppression aussi : « Les passer en blanc moyen ». */
html body :is(#m-menu,#m-settings,#m-arret,#m-intro,#m-players,#m-reprise,#m-suppr){--filet-verre:var(--filet-verre-menu)}
/* [26/10, Romain] CHARTE DES BOUTONS, système A. « Il faut que comme on a fait pour la taille des écritures, la charte
   graphique, on doit la faire pour tous les boutons du jeu, là y a trop de boutons différents c'est le bordel », puis
   « pour les petits boutons le mieux est de mettre pour ceux où c'est possible juste le fond noir avec l'icône en beige,
   sauf pour ceux qui doivent obligatoirement avoir de la couleur », puis, sur planche de trois systèmes, « je préfère
   le système A ». Le relevé du 26/10 trouvait 190 boutons et 53 formes ; il reste :
   - principal (l'action de l'écran) : capsule, 52 px, --t-3 graisse 700, la couleur du mode inchangée ;
   - secondaire : même capsule, verre sombre et contour --filet-verre ; « Terminer la partie » garde son rouge ;
   - bouton dans le contenu (Je me dégonfle, Ajouter) : capsule, 44 px, --t-2 ;
   - choix dans une barre : barre et choix en capsule, 44 px ;
   - rangée qu'on touche (menu de partie, Réglages avancés, Réglages) : 56 px, --r-3 ;
   - petit bouton : l'icône seule, crème #EFE9DF, sans rond ni fond ; la zone qu'on touche garde 40 px.
     [02/11, Romain, sur capture de l'écran Amis : « le bouton en haut pour ajouter un ami doit etre comme dans le reste
     de l'app, couleur creme et sans bord »] le bouton d'ajout d'ami (#mu-ajout-ami) rejoint la liste.
   Gardent leur dessin : l'accueil dessiné (#mv-canvas), la page de fin (validée le 26/10), « Voir la réponse », les ronds d'avatar, les
   onglets, les commandes propres à un mini-jeu, les liens texte.
   Rangé dans une couche (@layer) : une déclaration !important d'une couche l'emporte sur toutes les déclarations
   !important hors couche, quelle que soit leur précision. Une seule règle de charte gagne donc sur les dizaines de
   réglages au cas par cas (html body #ecran .btn{…!important}) sans les réécrire un par un. Pour qu'un bouton échappe
   à la charte, il faut l'exclure ICI, pas lui écrire une règle plus précise ailleurs : elle ne gagnerait pas. */
@layer charte-boutons{
  /* principal */
  .btn:not(.sec):not(.ghost):not(.sm):not(.age-non):not(#s-defi.fin-nue .btn,#s-multi.mu-scene .btn){
    min-height:52px!important;height:auto!important;border-radius:999px!important;font-size:var(--t-3)!important;font-weight:700!important;
    padding-top:0!important;padding-bottom:0!important;line-height:1.15!important}
  /* secondaire */
  /* [26/10, Romain] « pour les cartes quiz, le rectangle de couleur est beaucoup plus beau », « pour voir la réponse » :
     « Voir la réponse » (#c-reveal) garde son rectangle au contour de la couleur du jeu, hors charte. Exclu dans la même
     liste que la page de fin, pour ne pas alourdir la règle face au rouge de « Terminer » et à l'exception crème. */
  :is(.btn.sec,.btn.ghost,.sav-annuler,.btn.age-non):not(#s-defi.fin-nue .btn,#s-multi.mu-scene .btn,#c-reveal){
    min-height:52px!important;height:auto!important;border-radius:999px!important;font-size:var(--t-3)!important;font-weight:600!important;
    padding-top:0!important;padding-bottom:0!important;line-height:1.15!important;
    background:rgba(10,11,39,.62)!important;border:1px solid var(--filet-verre)!important;box-shadow:none!important;color:var(--c-texte)!important}
  /* même exclusion que le secondaire, sinon il pèse plus lourd que le rouge et que l'exception crème */
  /* [26/10, Romain] irréversible = capsule rouge, « mais texte blanc » ; « Supprimer » : « le passer en rouge, comme Terminer » */
  .btn.sec.danger:not(#s-defi.fin-nue .btn){color:#fff!important;border-color:rgba(248,113,113,.55)!important;background:rgba(60,10,20,.45)!important}
  /* « Terminer la partie » du Menu était un lien rouge de 158 × 50 : il prend la capsule, sur toute la largeur comme ses voisins */
  #m-menu #menu-end.mn-terminer{width:100%!important;align-self:stretch!important;margin-top:var(--e-3)!important}
  /* la fenêtre des règles est crème : le verre sombre y donnait un bouton gris illisible, il garde son encre pleine */
  #m-rules .btn.sec:not(#s-defi.fin-nue .btn){background:#170B20!important;border-color:transparent!important;color:#fff!important}
  /* bouton dans le contenu */
  :is(.btn.sm,#btn-degonfle,.jr-add .btn,.cl-vide .btn){
    min-height:44px!important;height:auto!important;border-radius:999px!important;font-size:var(--t-2)!important;font-weight:600!important}
  /* [26/10, Romain] « 52 px partout » pour tout ce qu'on touche : boutons, rangées, barres de choix (la barre faisait 54,
     les rangées 56). La barre garde 4 px de marge et 1 px de filet autour des choix : 42 + 8 + 2 = 52. */
  /* choix dans une barre. [27/10, Romain] « Coins doux, comme je propose » : la barre sert à choisir, pas à avancer,
     elle quitte donc la capsule des boutons qui avancent. La maquette disait 12 et 8 ; l'échelle des arrondis
     (CHARTE-02) n'a que 10, 16, 24, 32 : barre et choix actif aux coins de 10 (--r-1). */
  .sreg-seg{border-radius:var(--r-1)!important}
  .sreg-seg button{min-height:42px!important;height:42px!important;border-radius:var(--r-1)!important}
  /* rangée qu'on touche */
  :is(#m-menu .mn-ligne,.sreg-avance,.set-rg){min-height:52px!important;height:52px!important;border-radius:var(--r-3)!important}
  /* petit bouton : l'icône seule. [26/10, Romain] sur capture de « Qui joue ? » : « les boutons de après c'est non, ils
     sont horribles », « je t'ai dit tu mets pas de fond, juste l'icône ». Le rond noir de la première version est retiré
     partout ; la boîte garde 40 px pour le doigt, seul le dessin disparaît. */
  :is(.iconbtn,#menu-btn,.jr-retour,.jr-x,.jr-plus,.card-passer,.card-aide,.avis-bt,.helpbtn,.rules-x,.pm-aide,#mu-ajout-ami,.co-pas){
    background:none!important;background-image:none!important;color:#EFE9DF!important;border:0!important;box-shadow:none!important;
    width:40px!important;height:40px!important;min-width:0!important;min-height:0!important;border-radius:50%!important;padding:0!important}
  :is(.iconbtn,#menu-btn,.jr-retour,.jr-x,.jr-plus,.card-passer,.card-aide,.avis-bt,.helpbtn,.rules-x,.pm-aide,#mu-ajout-ami,.co-pas) svg [stroke]:not([stroke=none]){stroke:currentColor!important}
  :is(.iconbtn,#menu-btn,.jr-retour,.jr-x,.jr-plus,.card-passer,.card-aide,.avis-bt,.helpbtn,.rules-x,.pm-aide,#mu-ajout-ami,.co-pas) svg [fill]:not([fill=none]){fill:currentColor!important}
  /* [26/10, Romain] sur un fond clair, l'icône passe au noir : « met le bouton en noir sur fond blanc ». Relevé sur 46 écrans
     et 13 fenêtres : seule la fenêtre crème des règles (#m-rules) porte un petit bouton. Une nouvelle surface claire s'ajoute
     à cette liste. */
  :is(#m-rules) :is(.iconbtn,#menu-btn,.jr-retour,.jr-x,.jr-plus,.card-passer,.card-aide,.avis-bt,.helpbtn,.rules-x,.pm-aide,#mu-ajout-ami,.co-pas){
    background:none!important;color:#170B20!important}
  /* [27/10, Romain] CINQ TAILLES, choisies sur une planche de directions posées sur les vrais écrans : « 358 écran, 342
     fenêtres du bas et du milieu. 190x56 pour bouton suivant et bouton de choix. hauteur 36 pour petit. »
     Écran : 358 (règle du 27/10, plus haut). Fenêtre : 342. Carte et choix : 190 × 56. Petit : 36 de haut.
     Restent hors de ces tailles, déjà tranchés : petit bouton icône (40), « Voir la réponse » (160 × 42), accueil dessiné,
     onglets, commandes propres aux mini-jeux, champs de saisie. */
  /* « Arrêter la soirée ? » quitte le milieu de l'écran pour le bas (Romain, 27/10 : « toujours une fenêtre en bas pour
     reprendre/terminer/continuer ») : elle prend la matière de « Une partie est en cours », sa jumelle. */
  #m-arret .sheet{border-radius:var(--r-3) var(--r-3) 0 0!important;padding-bottom:calc(var(--e-4) + env(safe-area-inset-bottom,0px))!important;
    box-shadow:inset 0 1.5px 0 var(--filet-verre),0 -20px 60px -20px rgba(90,60,255,.45)!important}
  #m-arret .bottom>.btn{margin-top:0!important} #m-arret .bottom>.btn+.btn{margin-top:var(--e-2)!important}
  /* fenêtre du milieu : ses boutons prennent la largeur de ceux de la fenêtre du bas. Elle s'ouvre à 8 px des bords et
     son rembourrage passe à 16 : titre et boutons tombent aux mêmes bords (24) que dans la fenêtre du bas. Au-delà d'un
     téléphone, 544 de large, soit les boutons de la fenêtre du bas (560 moins 2 × 24). */
  :is(#m-minor,#m-rules) .sheet{max-width:544px!important;width:calc(100vw - 16px)!important;flex:0 0 auto!important;
    padding-left:var(--e-3)!important;padding-right:var(--e-3)!important}
  /* carte : « Suivant », « Réponse », et les « Continuer » de fin de mini-jeu qui ont sa forme depuis le 22/10 */
  :is(#s-game,#s-classic-run)[data-carte] :is(#btn-next,#cl-next),.screen .btn[id$="-done"]{
    width:190px!important;min-width:190px!important;max-width:100%!important;height:56px!important;min-height:56px!important}
  /* [05/11, Romain] « Commencer » des mini-jeux à la taille de « Suivant » : « ça permet au joueur d'avoir que les
     éléments importants qui changent pendant une partie ». Banc : outils/test-commencer-comme-suivant.py.
     Quelques jeux (Blind, Dix secondes, Minuteur) gardent ce même bouton pour « Stop » : il ne change pas de taille entre les deux. */
  /* les :not reprennent ceux du bouton principal ci-dessus : sinon sa hauteur l'emporte en spécificité */
  html body .screen .btn:not(.sec):not(.ghost):not(.sm):not(.age-non):not(#s-defi.fin-nue .btn):is(#bomb-start,#tap-btn,#bl-btn,#tg-btn,#vf-btn,#cr-btn,#sq-btn,#ma-btn,#in-btn,#gn-btn,#dx-btn,#tm-btn,#w-spin,#ca-spin,#co-btn,#mreg-valider){
    padding-top:0!important;padding-bottom:0!important;width:190px!important;min-width:190px!important;max-width:100%!important;height:56px!important;min-height:56px!important;
    margin-left:auto!important;margin-right:auto!important;align-self:center!important}
  /* [27/10, Romain] tuiles (jeu, série aléatoire, offre de la Boutique, Local ou Multijoueur) : coins de 24 partout,
     choisi sur planche (« B ») ; la grande tuile « Série aléatoire » à 180 de haut aux deux endroits (178 aux Classiques).
     L'écran « Choisis un mode » n'est pas touché : il est mis de côté (À TRANCHER). */
  :is(.jeu,.mjh-carte,.bq-lance,#s-play .mode){border-radius:var(--r-3)!important}
  .mjh-carte{height:180px!important;min-height:180px!important}
  /* choix sur une carte (Action, Vérité) : déjà 190 × 56 */
  /* petit : dans une rangée ou une barre de filtres */
  :is(#s-amis .am-act,#s-classement :is(.cm-f,.cm-seg,.cm-periode),#s-multi :is(.ax-rond,.ax-nouvelle)){height:36px!important;min-height:36px!important}
  :is(#s-classement .cm-f:not(.tout),#s-multi .ax-rond){width:36px!important;min-width:36px!important}
}

/* [27/10, Romain] bouton principal : « tout à la même largeur » (page de tous les boutons). Sur un écran, l'action
   principale fait toute la largeur, 358 px à 390 : la marge de page (16) et rien d'autre. Quatre boutons perdaient
   des pixels dans un conteneur qui ajoutait sa propre marge : « Commencer » de Qui joue ? (354, bord de 2 px gardé
   pour l'anneau du champ), « Lancer » de Crash out, « Lancer la course » et « Tirer une carte » de Palmier (326,
   conteneur de 16). Ils débordent de cette marge, le conteneur garde la sienne pour le reste. */
html body #s-joueurs .jr-body>.bottom{margin-left:-2px;margin-right:-2px}
html body :is(#cda-go,#pm-tirer){width:calc(100% + 32px);max-width:none;margin-left:-16px;margin-right:-16px}

/* [27/10, Romain, direction B (2/4)] LA SOIREE MULTIJOUEUR SE JOUE DANS L'ECRAN DE LA SOIREE : rien a dessiner de plus,
   sauf la phrase de celui qui attend son tour, posee a la place de « Suivant », a sa hauteur, avec le rond de celui qui
   joue (le nom est ecrit : jamais la couleur seule) */
:is(#s-game,#s-classic-run,#s-turn,#s-cashout) .mu-tour-phrase{display:flex;align-items:center;justify-content:center;gap:var(--e-2);min-height:56px;margin:0;
  font-size:var(--t-3);font-weight:600;line-height:1.2;color:var(--c-texte-2);text-align:center}
:is(#s-game,#s-classic-run,#s-turn,#s-cashout) .mu-tour-phrase .cl-av{width:28px;height:28px;font-size:var(--t-1);font-weight:700;flex:0 0 auto}

/* [27/10, Romain, direction B (4/4)] LE CHOIX DU JEU D'UNE PARTIE MULTIJOUEUR EST L'ACCUEIL. Ce qui ne concerne que le
   telephone seul s'efface (reglages, compte, Trinkeurs, la marque et ses etincelles) ; l'en-tete de « Qui joue ? » se
   pose a sa place, a la meme hauteur que sur « Qui joue ? ». Il vit HORS du canvas mis a l'echelle (#mv-canvas) : dedans,
   il grandirait et descendrait avec lui. */
#s-home #mu-choix-tete{display:none}
#s-home.mu-choix #mu-choix-tete{display:grid;position:absolute;z-index:5;left:16px;right:16px;
  top:calc(16px + env(safe-area-inset-top))}   /* mesure de « Qui joue ? » a 390 : 16, 16, 358 de large */
#s-home.mu-choix :is(.mv-reglages,.mv-moi-haut,.mv-trinq,.mv-titre,.mv-etincelles){display:none!important}

/* [27/10, Romain, direction B] LES MINI-JEUX MULTIJOUEUR : le classement des points sous la carte « Au tour de », a la
   largeur des fenetres (342), pendant la partie seulement (retire par muJeuSort) */
#s-turn .mu-mj-tableau{width:min(342px,100%);margin:var(--e-4) auto 0}

/* [27/10, Romain] le message d'arrivee de l'ami (« Romain a rejoint la partie : touche ici pour commencer. ») se touche :
   il ouvre la salle. Un toast ordinaire reste inerte. */
#toast.a-toucher.on{pointer-events:auto;cursor:pointer}

/* [28/10, Romain, direction E « Face à face », essayee sur Le 5 parfait] pendant la manche de l'autre : son ecran en haut,
   le mien en bas, un filet entre les deux. Valeurs en chiffres de meme largeur (le chrono ne danse pas). */
#s-turn #mu-face{display:none}
#s-turn.mu-face-on>:not(.topbar):not(#mu-face){display:none!important}
#s-turn.mu-face-on #mu-face{display:flex;flex:1;width:100%;flex-direction:column;align-items:center;min-height:0}
.mu-face :is(.mf-lui,.mf-moi){width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center}
.mu-face .mf-lui{flex:1.1;gap:var(--e-4)}
.mu-face .mf-moi{flex:.9;gap:var(--e-3)}
.mu-face .mf-qui{display:flex;align-items:center;gap:var(--e-2);font-size:var(--t-3);font-weight:700;color:var(--c-texte)}
.mu-face .mf-qui .cl-av{width:28px;height:28px;font-size:var(--t-1);font-weight:700;flex:0 0 auto}
.mu-face .mf-qui-moi{color:var(--c-texte-2)}
.mu-face .mf-val{font-size:6rem;font-weight:800;font-variant-numeric:tabular-nums;line-height:1;letter-spacing:-.01em;color:var(--c-texte)}
.mu-face .mf-val.mf-attente{opacity:.3}
.mu-face .mf-val.mf-vert{color:#4ADE80}
.mu-face .mf-moi .mf-val{font-size:var(--t-7);color:#FCD34D}
.mu-face .mf-sous{font-size:var(--t-2);font-weight:600;color:var(--c-texte-2)}
.mu-face .mf-etat{min-height:38px;display:flex;align-items:center}
:is(.mu-face,.mf-mir-tete) .mf-direct{display:inline-flex;align-items:center;gap:var(--e-2);font-size:var(--t-1);font-weight:800;letter-spacing:.12em;color:#FCD34D;text-transform:uppercase}
:is(.mu-face,.mf-mir-tete) .mf-direct::before{content:"";width:7px;height:7px;border-radius:50%;background:#FCD34D;box-shadow:0 0 0 3px rgba(252,211,77,.18)}
:is(.mu-face,.mf-mir-tete) .mf-attend{font-size:var(--t-1);font-weight:800;letter-spacing:.12em;color:var(--c-texte-3);text-transform:uppercase}
:is(.mu-face,.mf-mir-tete) .mf-pts{display:inline-flex;align-items:center;padding:var(--e-2) var(--e-3);border-radius:999px;background:rgba(252,211,77,.12);
  border:1px solid rgba(252,211,77,.45);color:#FCD34D;font-weight:800;font-size:var(--t-2)}
.mu-face .mf-filet{width:calc(100% - 48px);height:1px;flex:none;background:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent)}
.mu-face .mf-pied{height:calc(26px + env(safe-area-inset-bottom));flex:none}
/* [28/10, Romain : « configure les autres jeux comme le 5 parfait »] le face a face des quatorze jeux : une ligne sous la
   valeur (ce que c'est : « sur 5 cibles touchées », « secondes pour l'arrêter »), la taille suit la longueur (un chrono a
   96 px, un mot moins grand, un verdict sur deux lignes au plus), vert et rouge pour un feu, un crash, un « Trop tôt ». */
.mu-face .mf-unite{min-height:1.4em;max-width:min(342px,100%);font-size:var(--t-2);font-weight:600;color:var(--c-texte-2);text-align:center}
.mu-face .mf-val.mf-moyen{font-size:4rem}
.mu-face .mf-val.mf-mot{font-size:var(--t-7)}
.mu-face .mf-val.mf-phrase{font-size:var(--t-6);line-height:1.1;max-width:min(342px,100%);text-align:center;text-wrap:balance}
.mu-face .mf-val.mf-rouge{color:#F87171}
.mu-face .mf-moi .mf-val.mf-moyen{font-size:var(--t-6)}
.mu-face .mf-moi .mf-val.mf-mot{font-size:var(--t-5)}
.mu-face .mf-moi .mf-val.mf-phrase{font-size:var(--t-4)}

/* [02/11, Romain, direction C « Son écran avec ses traces », planche du 02/11 (page-en-cours/images/cible-miroir/c.png)]
   LE MIROIR DE LA CIBLE chez celui qui regarde : son prénom et « En direct » dans la barre du haut, son écran dans la
   zone (la cible au dessin de #tg-dot, une trace numérotée par touche réussie, une croix par touche ratée, le rond blanc
   de son doigt), son compte dessous comme sur son écran, puis ma ligne, plus petite. */
#mu-face .mf-mir{display:none}
#mu-face.mf-mir-on .mf-lui{display:none}
#mu-face.mf-mir-on .mf-mir{display:flex;flex:1;flex-direction:column;width:100%;min-height:0}
.mf-mir-zone{position:relative;flex:1;min-height:0;overflow:hidden}
.mf-mir-zone .mf-cible{position:absolute;border-radius:50%}
/* [02/11, Romain, direction A] Vert ou rouge : la zone prend la couleur du feu (celles de #gn-zone), son mot au centre,
   puis la rangée des feux */
.mf-mir-zone{display:flex;align-items:center;justify-content:center}
/* [05/11, Romain, direction B] Trouve l'intrus : sa grille, l'intrus entouré, ses essais ratés éteints */
.mi-grille{display:grid;gap:var(--e-2);width:100%;max-width:358px;padding:0 var(--e-3);box-sizing:content-box;align-content:center}
.mi-case{aspect-ratio:1;display:flex;align-items:center;justify-content:center;background:linear-gradient(180deg,#1b1b21,var(--card));
  border:1px solid var(--line);border-radius:var(--r-1);font-size:var(--t-5);font-weight:800;color:var(--c-texte)}
.mi-case.mi-rate{opacity:.3}
.mi-case.mi-indice{box-shadow:0 0 0 2px #FCD34D}
.mi-case.mi-trouve{background:#14532d;border-color:#22c55e}
/* [05/11, Romain, direction C] Calcul express : son écran, la bonne réponse signalée */
.mm{width:100%;padding:0 var(--e-3);display:flex;flex-direction:column;align-items:center;gap:var(--e-4);box-sizing:border-box}
.mm-q{font-size:var(--t-7);font-weight:900;color:var(--c-texte);font-variant-numeric:tabular-nums}
.mm-temps{width:100%;max-width:340px;height:6px;border-radius:999px;background:rgba(255,255,255,.1);overflow:hidden}
.mm-temps span{display:block;height:100%;background:#FCD34D;border-radius:999px}
.mm-reps{display:flex;gap:var(--e-2);width:100%;max-width:340px;min-height:64px}
.mm-rep{flex:1;display:flex;align-items:center;justify-content:center;border:1px solid var(--line2);border-radius:var(--r-2);background:var(--card);
  font-size:var(--t-3);font-weight:800;color:var(--c-texte)}
.mm-rep.mm-juste{background:#0f2a1b;border-color:rgba(74,222,128,.85)}
.mm-rep.mm-faux{background:#2a1216;border-color:rgba(248,113,113,.85)}
.mm-rep.mm-indice{box-shadow:0 0 0 2px #FCD34D}
/* [05/11, Romain, direction A] Le stop parfait : sa barre, son curseur */
.mt{width:100%;padding:0 var(--e-3);display:flex;flex-direction:column;align-items:center;gap:var(--e-4);box-sizing:border-box}
.mt-temps{width:100%;max-width:340px;height:6px;border-radius:999px;background:rgba(255,255,255,.1);overflow:hidden}
.mt-temps span{display:block;height:100%;background:#FCD34D;border-radius:999px}
.mt-barre{position:relative;width:100%;max-width:340px;height:64px;border-radius:var(--r-2);background:var(--card);border:1px solid var(--line2);overflow:hidden}
.mt-cible{position:absolute;top:0;bottom:0;background:rgba(251,191,36,.34);box-shadow:inset 0 0 0 1px rgba(252,211,77,.7)}
.mt-cur{position:absolute;top:0;bottom:0;width:4px;margin-left:-2px;background:#fff}
.mt-cur.mt-ok{background:#FCD34D}
/* [05/11, Romain, direction B] Cercle parfait : son trait et le rond idéal */
.mc{display:block;background:var(--card);border:2px solid rgba(251,191,36,.3);border-radius:var(--r-3);overflow:hidden}
.mf-mir-zone[data-feu="vert"]{background:#14532d}
.mf-mir-zone[data-feu="rouge"]{background:#4c1414}
.mf-mir-zone .mf-mot{font-size:var(--t-7);font-weight:900;letter-spacing:.1em;color:#fff;text-shadow:0 0 24px rgba(0,0,0,.4)}
.mf-mir-rang{display:flex;justify-content:center;flex-wrap:wrap;gap:var(--e-2);padding:var(--e-3) var(--e-3) var(--e-1)}
.mf-mir-rang[hidden]{display:none}
.mf-mir-rang i{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-style:normal;font-size:var(--t-1);font-weight:900;color:#fff;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.28)}
.mf-mir-rang i.v{background:#15803d;box-shadow:none}
.mf-mir-rang i.r{background:#b91c1c;box-shadow:none}
.mf-mir-rang i.faute{box-shadow:0 0 0 2px #fff}
.mf-mir-rang i.encours{box-shadow:inset 0 0 0 2px #FCD34D}
.mf-mir-zone .mf-trace{position:absolute;width:24px;height:24px;margin:-12px 0 0 -12px;border-radius:50%;box-shadow:inset 0 0 0 2px #FCD34D;
  color:#FCD34D;font-size:var(--t-1);font-weight:800;display:grid;place-items:center;z-index:1}
.mf-mir-zone .mf-rate{position:absolute;width:18px;height:18px;margin:-9px 0 0 -9px;z-index:1;opacity:.7}
.mf-mir-zone .mf-rate::before,.mf-mir-zone .mf-rate::after{content:"";position:absolute;left:8px;top:0;width:2px;height:18px;background:#F3EEE6}
.mf-mir-zone .mf-rate::before{transform:rotate(45deg)}
.mf-mir-zone .mf-rate::after{transform:rotate(-45deg)}
.mf-mir-zone .mf-doigt{position:absolute;width:52px;height:52px;margin:-26px 0 0 -26px;border-radius:50%;background:rgba(23,11,32,.38);
  box-shadow:inset 0 0 0 3px #fff,0 0 0 2px rgba(12,4,40,.7),0 6px 16px rgba(0,0,0,.5);z-index:2}
.mf-mir-cpt{margin:0;text-align:center;font-size:var(--t-5);font-weight:800;color:var(--c-texte);font-variant-numeric:tabular-nums;padding:var(--e-1) 0 var(--e-2)}
.mf-mir-cpt b{color:#FCD34D}
.mf-mir-cpt span{font-size:var(--t-2);font-weight:600;color:var(--c-texte-2)}
#mu-face.mf-mir-on .mf-filet{width:100%;background:rgba(255,255,255,.14)}
#mu-face.mf-mir-on .mf-moi{flex:none;flex-direction:row;gap:var(--e-2);padding:var(--e-3) 0}
#mu-face.mf-mir-on .mf-moi .mf-qui{font-size:var(--t-2)}
#mu-face.mf-mir-on .mf-moi .mf-qui .cl-av{width:24px;height:24px}
#mu-face.mf-mir-on .mf-moi .mf-sous{order:1}
#mu-face.mf-mir-on .mf-moi .mf-val{order:2;font-size:var(--t-3)}
.mf-mir-tete{display:inline-flex;align-items:center;gap:var(--e-2);font-size:var(--t-3);font-weight:700;color:var(--c-texte);letter-spacing:0}
.mf-mir-tete .cl-av{width:28px;height:28px;font-size:var(--t-1);font-weight:700;flex:0 0 auto}
.mf-mir-tete .mf-pts{padding:var(--e-1) var(--e-2)}

/* [02/11, Romain, TRIR du 30/10 : M2 « Le classement », direction B « Avec le dessin du mode »] TES MANCHES SONT JOUÉES
   sur la scène de la fin des Mini-jeux : fond Braise (--fn-plein, une seule source plus haut), dessin du mode, étoiles
   (finEtoiles), le classement en grand. La barre du haut garde son menu, sans fond ni titre. Contraste mesuré le 30/10
   sur la planche (poste-jeux) : texte blanc et or au moins 4,5 pour 1 sur le Braise. */
#s-turn #mu-fini{display:none}
#s-turn.mu-fini-on>:not(.topbar):not(#mu-fini):not(.fn-ciel){display:none!important}
#s-turn.mu-fini-on #mu-fini{display:flex;flex:1;flex-direction:column;align-items:center;width:min(342px,100%);margin:0 auto;
  min-height:0;position:relative;z-index:1;padding-bottom:calc(var(--e-4) + env(safe-area-inset-bottom,0px))}
#s-turn.mu-fini-on>.topbar{background:transparent!important;border:0!important;box-shadow:none!important;position:relative;z-index:1}
#s-turn.mu-fini-on>.topbar b{visibility:hidden}
.mu-fini .grow{flex:1}
.mu-fini .fn-blason{display:flex;justify-content:center;margin-bottom:var(--e-4)}
.mu-fini .fn-blason svg{display:block;width:128px;height:auto;filter:drop-shadow(0 12px 18px rgba(12,4,40,.45))}
#s-turn.mu-fini-on.fn-serre .mu-fini .fn-blason{margin-bottom:var(--e-3)}
#s-turn.mu-fini-on.fn-serre .mu-fini .fn-blason svg{width:96px}
.mu-fini .mfi-kick{font-size:var(--t-1);font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.86);margin:0 0 var(--e-2);text-align:center}
.mu-fini h2{margin:0 0 var(--e-5);font-family:ui-rounded,"SF Pro Rounded",-apple-system,"Helvetica Neue",sans-serif;
  font-size:var(--t-6);font-weight:800;letter-spacing:-.03em;line-height:1.05;color:#fff;text-align:center;text-wrap:balance}
.mu-fini .mfi-board{width:100%;border:1.5px solid rgba(255,255,255,.22);border-radius:var(--r-3);background:rgba(24,6,3,.26);overflow:hidden}
.mu-fini .mfi-l{display:flex;align-items:center;gap:var(--e-3);padding:var(--e-3) var(--e-4)}
.mu-fini .mfi-l+.mfi-l{border-top:1px solid rgba(255,255,255,.16)}
.mu-fini .mfi-rang{width:16px;flex:0 0 auto;font-size:var(--t-2);font-weight:800;color:rgba(255,255,255,.72);font-variant-numeric:tabular-nums}
.mu-fini .mfi-l .cl-av{width:36px;height:36px;font-size:var(--t-2);flex:0 0 auto;background:#DDD5C7;color:#170B20}
.mu-fini .mfi-l .cl-av.moi{background:linear-gradient(135deg,#A78BFA 0%,#8B5CF6 55%,#7431E8 100%);color:var(--accent-ink)}
html.teinte .mu-fini .mfi-l .cl-av.moi{background:linear-gradient(135deg, var(--av-hi) 0%, var(--av-lo) 55%,
                                                hsl(var(--av-h) var(--av-s) calc(var(--av-llo) - 11%)) 100%)}
.mu-fini .mfi-nom{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--e-1);text-align:left}
.mu-fini .mfi-nom b{font-size:var(--t-3);font-weight:800;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mu-fini .mfi-p{font-size:var(--t-3);font-weight:800;color:#fff;font-variant-numeric:tabular-nums}
.mu-fini .mfi-sur{font-size:var(--t-1);font-weight:700;color:rgba(255,255,255,.86);font-variant-numeric:tabular-nums}
.mu-fini .mfi-ronds{display:flex;gap:var(--e-1);flex:0 0 auto}
.mu-fini .mfi-ronds i{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.24)}
.mu-fini .mfi-ronds i.f{background:#F3EEE6}
.mu-fini .mfi-note{font-size:var(--t-2);font-weight:600;color:rgba(255,255,255,.94);text-align:center;margin:var(--e-4) 0 0;text-wrap:balance}

/* [28/10, Romain : direction B] LES CLASSIQUES A DISTANCE, CHACUN REPOND : les options de Tu préfères se touchent dans
   la carte. Un cadre de verre ; la mienne s'allume (blanc, rose), l'autre pâlit ; a la fin, celle de la minorite se
   borde de rose et porte ses ronds dessous. */
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt{padding:var(--e-3) var(--e-4);border-radius:var(--r-3);
  border:1.5px solid var(--filet-verre);background:rgba(255,255,255,.06);cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:opacity .2s,border-color .2s,background-color .2s}
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt[aria-disabled="true"]{cursor:default}
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt:focus-visible{outline:2px solid #fff;outline-offset:3px}
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt.choisi{border-color:#fff;background:rgba(244,114,182,.22);box-shadow:0 0 0 3px rgba(244,114,182,.18)}
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt.pale{opacity:.4}
#s-classic-run[data-carte="preferes"] .jn-option.cl-vopt.mino{border-color:#F472B6;background:rgba(244,114,182,.16)}
#s-classic-run .cl-vligne{display:flex;align-items:center;justify-content:center;gap:var(--e-1);margin-top:var(--e-2);min-height:26px}
#s-classic-run .cl-vligne .cl-av{width:24px;height:24px;font-size:var(--t-1);font-weight:800}
#s-classic-run .cl-vbas{width:min(342px,100%);margin:0 auto}
#s-classic-run .cl-vronds{display:inline-flex;gap:var(--e-1);align-items:center}
#s-classic-run .cl-vbas .cl-av{width:28px;height:28px;font-size:var(--t-1);font-weight:700;flex:0 0 auto}
@media (prefers-reduced-motion:reduce){ #s-classic-run[data-carte="preferes"] .jn-option.cl-vopt{transition:none} }

/* [29/10, Romain, page TRIR : J2 et Q1] LES CLASSIQUES A DISTANCE, JE N'AI JAMAIS ET QUI POURRAIT : la zone de reponses
   sous la phrase (#cl-vzone, posee par muClVoteDessine). Le meme cadre de verre que les options de Tu préfères, les
   memes etats ; « Je l'ai fait » et « Jamais » cote a cote, un cadre par joueur pour Qui pourrait (rond, prenom, et a la
   fin les ronds de ceux qui l'ont designe, a droite). */
#s-classic-run .cl-vzone{display:flex;flex-direction:column;align-items:center;gap:var(--e-2);width:100%;margin:var(--e-3) 0 var(--e-2)}
#s-classic-run .cl-vzone.cote{flex-direction:row;align-items:stretch}
#s-classic-run .cl-vzone.cote .cl-vrep{flex:1 1 0;font-size:var(--t-3);white-space:nowrap;padding:var(--e-3) var(--e-2)}
#s-classic-run .cl-vrep{display:block;width:100%;padding:var(--e-3) var(--e-4);border-radius:var(--r-3);border:1.5px solid var(--filet-verre);
  background:rgba(255,255,255,.06);font-size:var(--t-4);font-weight:800;line-height:1.2;letter-spacing:-.02em;color:var(--jn-metal);text-align:center;
  cursor:pointer;-webkit-tap-highlight-color:transparent;transition:opacity .2s,border-color .2s,background-color .2s}
#s-classic-run .cl-vrep[aria-disabled="true"]{cursor:default}
#s-classic-run .cl-vrep:focus-visible{outline:2px solid #fff;outline-offset:3px}
#s-classic-run .cl-vrep.choisi{border-color:#fff;background:rgba(244,114,182,.22);box-shadow:0 0 0 3px rgba(244,114,182,.18)}
#s-classic-run .cl-vrep.pale{opacity:.4}
#s-classic-run .cl-vrep.mino{border-color:#F472B6;background:rgba(244,114,182,.16)}
#s-classic-run .cl-vrep.nom{display:flex;align-items:center;gap:var(--e-3);text-align:left;font-size:var(--t-3);padding:var(--e-2) var(--e-4)}
#s-classic-run .cl-vrep.nom>.cl-av{width:32px;height:32px;font-size:var(--t-2);flex:0 0 auto}
#s-classic-run .cl-vrep.nom .cl-vligne{margin:0 0 0 auto}
@media (prefers-reduced-motion:reduce){ #s-classic-run .cl-vrep{transition:none} }
/* [04/11, banc test-tailles-ecran] Sequence : la place fixe de la consigne et du verdict (21/10, +100 px) n'avait pas ete retiree
   de la reserve de v954, « Commencer » tombait sous le bas de l'ecran a toutes les tailles d'iPhone. Girouette : un prenom long
   passe la consigne sur deux lignes et poussait « Tourner » contre le bas. Seule la hauteur de la zone de jeu suit. */
html body #s-seq .sq-grille{width:min(76vw,300px,calc(100dvh - 465px));min-width:130px}
html body #s-wheel #wheel{width:min(80vw,344px,calc(100dvh - 405px))!important}
@media (max-height:620px){html body #s-seq #sq-result{min-height:56px}html body #s-seq #sq-inst{min-height:60px;margin-bottom:var(--e-2)}html body #s-wheel #wheel{min-width:150px}}
/* [04/11, banc test-tailles-en-partie] « Continuer » sous le bas de l'ecran une fois le verdict affiche : Cercle parfait (55 px a 390 x 664,
   166 px a 375 x 553), Trouve l'intrus (69 px a 375 x 553), Girouette (4 a 6 px). La zone de jeu suit la hauteur, le verdict se tasse en tres petit ecran. */
@media (max-height:760px){html body #pc-canvas{width:min(100%,300px,calc(100dvh - 420px));min-width:170px}}
html body #s-wheel #wheel{width:min(80vw,344px,calc(100dvh - 415px))!important}
@media (max-height:620px){html body #pc-score{font-size:var(--t-7);line-height:1.1}html body #s-wheel #w-inst{margin-bottom:var(--e-3)!important}
html body #s-intrus:has(#in-grid .icell) #in-result{min-height:86px}html body #s-intrus #in-grid{width:min(100%,calc(100dvh - 348px));gap:var(--e-1);padding-top:0;padding-bottom:0}}
/* La grille de l'intrus n'avait pas de largeur sous 760 px de haut : 180 px pour des cases de 283, elle debordait a droite, decentree. */
@media (min-height:621px) and (max-height:760px){html body #s-intrus #in-grid{width:min(100%,330px,calc(100dvh - 375px))}}
@media (max-height:760px){html body #s-intrus #in-grid .icell{min-width:0;min-height:0}}
@media (max-height:620px){html body #s-intrus #in-grid{padding-left:0;padding-right:0}html body #s-intrus #in-grid .icell{font-size:var(--t-4)}}

/* [05/11, Romain] « Commencer » des mini-jeux, suite : centré comme « Suivant ». Hors de la couche de la charte, car le
   .btn sans couche (inline-flex) y gagne, et sans !important, car le JS cache ces boutons par style.display. */
html body .screen .btn:is(#bomb-start,#tap-btn,#bl-btn,#tg-btn,#vf-btn,#cr-btn,#sq-btn,#ma-btn,#in-btn,#gn-btn,#dx-btn,#tm-btn,#w-spin,#ca-spin,#co-btn,#mreg-valider){display:flex}
/* [05/11, Romain, direction C de la planche du 25/10] Couleur piégée : le mot au centre, les couleurs en couronne, en verre.
   --cr-r : le rayon, réduit si l'écran est étroit ; la pastille fait 72 px et garde 8 px de marge au bord. */
html body #s-stroop .cr-pastille{background-image:radial-gradient(circle at 50% 26%,rgba(255,255,255,.42),rgba(255,255,255,0) 58%),linear-gradient(180deg,rgba(0,0,0,0) 45%,rgba(0,0,0,.28))!important;   /* !important : la couleur est posée en ligne par « background », qui remet l'image à zéro */
  border:0;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.5),inset 0 -2px 0 rgba(0,0,0,.18),0 6px 14px rgba(0,0,0,.45)}
html body #s-stroop .cr-pastille.good{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.5),0 0 0 3px #F7F5FA}
html body #s-stroop.cr-couronne{--cr-r:min(140px,calc(50vw - 44px));justify-content:flex-start}
html body #s-stroop.cr-couronne .topbar{margin:0;flex:0 0 auto}
html body #s-stroop.cr-couronne :is(.grow,.bottom){display:none}
html body #s-stroop.cr-couronne .cr-mot{position:absolute;left:0;right:0;top:46%;margin:-30px 0 0;text-align:center;font-size:var(--t-5)}
html body #s-stroop.cr-couronne .progress{position:absolute;left:50%;top:46%;width:120px!important;margin:var(--e-4) 0 0 -60px}
html body #s-stroop.cr-couronne #cr-fb{position:absolute;left:0;right:0;top:46%;margin:200px 0 0;text-align:center}
html body #s-stroop.cr-couronne #cr-pastilles{position:absolute;left:50%;top:46%;width:0;height:0;display:block;padding:0;margin:0}
html body #s-stroop.cr-couronne #cr-pastilles .cr-pastille{position:absolute;width:72px;height:72px;margin:0;left:calc(var(--cr-r)*var(--cx) - 36px);top:calc(var(--cr-r)*var(--cy) - 36px)}
