/* ═══════════════════════════════════════════════════════════════════════
   Chatistiques — feuille de style.

   Registre : imprimé. Fond crème, encre chaude, filets fins, titres en
   romain. On s'éloigne volontairement du tableau de bord sombre : le sujet
   est un rituel populaire, physique et coloré, pas un outil d'analyse. Et
   on consulte ce site dehors, en plein jour, sur un téléphone.

   Écrit en mobile d'abord : le style de base vise 375 px, les media queries
   ajoutent de la largeur. L'ancienne feuille faisait l'inverse, d'où une
   barre de navigation qui s'empilait sur 480 px avant le moindre contenu.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* Papier et encre */
  --paper:      #faf7f2;
  --paper-2:    #ffffff;
  --paper-3:    #f3efe7;
  --ink:        #14110e;
  --ink-2:      #4a443c;
  --ink-3:      #8a8078;
  --rule:       #e5ded3;
  --rule-2:     #d3c9ba;

  /* Accent : réécrit par jeu depuis config.js (Keno turquoise, Loto rouge…) */
  --accent:     #00a79d;

  /* Sémantique. Vert assombri : le #2ecc71 de la version sombre passait
     sous le seuil de contraste sur fond clair. */
  --found:      #10713f;
  --found-bg:   #e3f2e8;
  --warn:       #a8600a;
  --danger:     #b3261e;

  /* Le code couleur du site, dit une fois dans le bandeau puis partout :
     gris ardoise = comme le hasard, vert = au-dessus, rouge = en dessous.
     L'ardoise est froide pour ne pas se confondre avec le gris chaud de
     l'encre secondaire. */
  --hasard:     #66727f;
  --hasard-bg:  #e8edf2;
  --plus:       var(--found);
  --plus-bg:    var(--found-bg);
  --moins:      var(--danger);
  --moins-bg:   #fbe6e3;

  --radius:     10px;
  --radius-lg:  14px;

  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", "Times New Roman", serif;
  --sans:  system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;

  --nav-h: 58px;
  /* Teinte de survol : assez pâle pour ne pas écraser le code couleur des
     cases, assez nette pour suivre une ligne des yeux. */
  --survol: rgba(20, 17, 14, .07);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { margin: 0; }

body {
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.55 var(--sans);
  min-height: 100vh;
  /* Dégage la barre de navigation basse (mobile) + encoches iOS. */
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
}

h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -.01em; }
h2 { font-size: 1.25rem; line-height: 1.25; margin: 0 0 4px; }
h3 { font-size: 1rem; margin: 0 0 4px; }

/* Chiffres alignés : indispensable quand on empile des scores. */
.score, .big, .num, .val, .mpct, .mavg, table, .tt-ball, .ball, .bn-n, .bn-v {
  font-variant-numeric: tabular-nums;
}

.sub, .note, .desc, .mode-desc { color: var(--ink-2); font-size: .875rem; margin: 0 0 10px; }
/* Seul le TEXTE reçoit une mesure. Les tableaux, grilles de boules et graphes
   profitent au contraire de toute la largeur disponible. */
.sub, .note, .desc, .mode-desc, .advice p, .honesty, .cd-date { max-width: 78ch; }
.note { font-size: .8125rem; color: var(--ink-3); }
.empty { color: var(--ink-3); font-style: italic; }
b, strong { font-weight: 650; }
a { color: inherit; }

/* ── En-tête ──────────────────────────────────────────────────────────
   Sur mobile, l'en-tête ne porte plus que la marque et le compte. Les jeux
   descendent dans une barre basse, dans la zone du pouce. */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
  position: sticky; top: 0; z-index: 30;
}
.brand {
  font-family: var(--serif); font-size: 1.125rem; font-weight: 600;
  letter-spacing: -.02em; display: flex; align-items: baseline; gap: 6px;
  white-space: nowrap;
}
.brand .brand-nom { color: var(--accent); }
/* La tête du chat : la marque se reconnaît à elle seule, avant même le nom.
   Le badge crème est dans le dessin, pas dans le CSS, pour qu'un chat noir
   reste visible sur l'en-tête sombre. */
.brand { align-items: center; }
.brand-chat { display: inline-block; width: 32px; height: 32px; flex: 0 0 32px; }
.brand-chat svg, .brand-chat img { display: block; width: 100%; height: 100%; }

.account { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.badge {
  font-size: .75rem; padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--rule-2); color: var(--ink-2);
  max-width: 40vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.badge.sub { border-color: var(--accent); color: var(--accent); font-weight: 600; }

.theme-toggle {
  background: none; border: 1px solid var(--rule-2); border-radius: 999px;
  width: 34px; height: 34px; flex: 0 0 auto; cursor: pointer;
  color: var(--ink-2); font-size: 1rem; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
.theme-toggle:hover { border-color: var(--ink-3); color: var(--ink); }

/* ── Navigation des jeux : barre basse sur mobile ─────────────────── */
.games {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: stretch;
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--paper-2);
  border-top: 1px solid var(--rule);
}
.games button {
  flex: 1 1 0; min-width: 0;
  background: none; border: 0; border-top: 2px solid transparent;
  color: var(--ink-3); font: inherit; font-size: .75rem; font-weight: 500;
  cursor: pointer; padding: 6px 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.games button.active {
  color: var(--accent); border-top-color: var(--accent); font-weight: 650;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

/* ── Sous-onglets ─────────────────────────────────────────────────── */
.subtabs {
  display: flex; gap: 0; padding: 0 16px;
  border-bottom: 1px solid var(--rule); background: var(--paper);
  overflow-x: auto; scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtabs button {
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--ink-3); font: inherit; font-size: .9375rem;
  padding: 12px 14px 10px; cursor: pointer; white-space: nowrap;
}
.subtabs button.active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 650; }

/* ── Boutons ──────────────────────────────────────────────────────── */
.modebtn {
  background: var(--paper-2); color: var(--ink-2);
  border: 1px solid var(--rule-2); border-radius: 999px;
  font: inherit; font-size: .8125rem; padding: 6px 12px; cursor: pointer;
  white-space: nowrap;
}
.modebtn:hover { border-color: var(--ink-3); color: var(--ink); }
.modebtn.active {
  background: var(--ink); color: var(--paper); border-color: var(--ink); font-weight: 600;
}
.modebtn.sm { font-size: .75rem; padding: 4px 9px; }
/* .cta est un CONTENEUR (texte + bouton), pas le bouton lui-même. */
.cta { margin-top: 14px; }
.cta p { margin: 0 0 12px; color: var(--ink-2); font-size: .9375rem; }
.cta button {
  background: var(--accent); color: #fff; border: 0; border-radius: 999px;
  font: inherit; font-weight: 650; font-size: .9375rem;
  padding: 13px 26px; cursor: pointer; width: 100%; max-width: 340px;
}

/* ── Mise en page ─────────────────────────────────────────────────── */
.app { padding: 16px; max-width: 1180px; margin: 0 auto; }
.view { display: grid; grid-template-columns: 1fr; gap: 14px; }
.view.hidden { display: none; }

/* L'en-tête est collant : sans cette marge, un ancrage place le titre de la
   carte DERRIÈRE lui et on lit un mot coupé en deux. */
.card, section[id] { scroll-margin-top: 64px; }

/* Texte de conduite entre les blocs de la vue avancée : c'est lui qui fait
   d'une pile de panneaux une démonstration. */
.view-lead {
  margin: 0; padding: 4px 2px 0;
  color: var(--ink-2); font-size: .9375rem; line-height: 1.6; max-width: 72ch;
}
.view-lead.separee { border-top: 1px solid var(--rule); padding-top: 18px; margin-top: 6px; }

/* Un élément de grille a `min-width: auto` : il refuse de descendre sous la
   largeur de son contenu. Un seul tableau large suffisait donc à élargir la
   colonne — et la page entière débordait de 1144 px sur mobile. On autorise
   les cartes à rétrécir, et ce qui ne rentre pas défile DANS la carte. */
.view > * { min-width: 0; }

.card {
  overflow-x: auto;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 16px;
}
.lead { margin-bottom: 12px; }

/* ── Boules : l'élément identitaire ───────────────────────────────
   Une boule de loterie est un objet physique. On la traite comme telle :
   pastille pleine, léger reflet, et non une case de tableau. */
.balls { display: flex; flex-wrap: wrap; gap: 6px; }
.ball {
  position: relative;
  width: 36px; height: 36px; flex: 0 0 auto;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: .9375rem; font-weight: 600;
  background: var(--paper-2); color: var(--ink-2);
  border: 1px solid var(--rule-2);
}
/* Numéro réellement sorti : encre pleine, c'est le fait établi. */
.ball.drawn {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
  box-shadow: inset 0 2px 5px rgba(255,255,255,.13);
}
/* Trouvé : le seul moment de fête de la page. */
.ball.hit {
  background: var(--found); color: #fff; border-color: var(--found);
  box-shadow: inset 0 2px 5px rgba(255,255,255,.2);
}
.ball.miss { opacity: .55; }
.ball.bonus { background: var(--accent); color: #fff; border-color: var(--accent); }
/* Les Étoiles de l'EuroMillions ont la forme de leur nom. On ÉVOQUE le jeu,
   on ne copie pas les visuels de la FDJ : une étoile dorée appartient à tout
   le monde, un dessin officiel non — et un site qui ressemble trop à la FDJ
   laisse croire qu'il en fait partie. Légèrement plus grande qu'une boule :
   une étoile n'offre au chiffre que son centre. */
body[data-jeu="EUROMILLIONS"] .ball.bonus {
  /* !important : les règles « boule déjà tirée » du thème sombre sont plus
     spécifiques et repeindraient l'étoile en blanc. Une étoile reste dorée. */
  background: #f2b705 !important; color: #1b1b1b !important; border: 0;
  width: 40px; height: 40px; font-size: .8125rem; font-weight: 700;
  clip-path: polygon(50% 0%, 61.5% 34.5%, 98% 35.5%, 69% 57.5%, 79.5% 92%,
                     50% 71.5%, 20.5% 92%, 31% 57.5%, 2% 35.5%, 38.5% 34.5%);
  padding-top: 3px;
}
body[data-jeu="EUROMILLIONS"] .fr-sortis .ball.bonus { width: 31px; height: 31px; font-size: .72rem; }
.ball .mark {
  position: absolute; top: -3px; right: -3px;
  font-size: .5625rem; line-height: 1;
  background: var(--ink); color: var(--paper);
  border-radius: 999px; padding: 2px 4px;
}
.balls.blurred { filter: blur(7px); user-select: none; }

/* ── Dernier tirage ───────────────────────────────────────────────── */
.ylbl {
  display: block; font-size: .6875rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--ink-3); margin-bottom: 6px;
}
.score { font-size: .9375rem; color: var(--ink-2); margin-top: 8px; }
.score b { font-family: var(--serif); font-size: 2rem; color: var(--found); }

/* ── Prédiction du prochain tirage (collante) ─────────────────────── */
/* ── Fraîcheur : une ligne, pas un écran ──────────────────────────
   Le joueur vient pour des numéros. Ces deux lignes lui disent quand il doit
   avoir choisi et sur quoi reposent les chiffres ; tout le reste tiendrait de
   la notice. */
/* ── Le bruit en toutes lettres (admin) ───────────────────────── */
.pgraph { width: 100%; max-width: 30rem; height: auto; display: block; margin: 6px 0 12px; }
.pline { fill: none; stroke: var(--accent); stroke-width: 2; }
.pz { stroke: var(--rule); stroke-width: 1; }
.pm { stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 3 3; }
.pc { fill: var(--accent); }
.pl { font-size: 8px; fill: var(--ink-3); }
.pl-t { max-width: 46rem; }
.pl-t td:first-child { width: 12rem; }
/* Le dernier résultat, juste sous la ligne du prochain tirage. Les boules
   reprennent le style du reste du site : c'est le même objet, il doit se
   reconnaître sans légende. */
.fr-sortis { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 6px 0 2px; }
.fr-lbl { font-size: .75rem; color: var(--ink-3); }
.fr-sortis .balls { display: flex; gap: 4px; flex-wrap: wrap; }
/* Plus petites qu'ailleurs, et c'est nécessaire : le Keno sort seize numéros,
   qui à la taille normale repoussaient la prédiction sous la ligne de
   flottaison sur téléphone. Le résultat passé s'annonce, il ne se joue pas. */
.fr-sortis .ball { width: 27px; height: 27px; font-size: .78rem; }

.cible-lib { margin: 14px 0 4px; font-weight: 600; }
.po-h { font-size: .9375rem; font-weight: 650; margin: 18px 0 4px; }
.se-liste { margin: 0 0 4px; padding-left: 1.1em; }
.se-liste li { margin: 0 0 9px; line-height: 1.5; max-width: 82ch; }
.se-liste sup { font-size: .7em; }
.se-plat { color: var(--ink-3); }
.se-net { color: var(--accent); font-weight: 650; }
.se-nc { color: var(--ink-3); font-style: italic; }

/* L'étiquette « c'est le cas » a disparu avec les faits inactifs : tout ce
   qui s'affiche a désormais sa condition remplie, donc un marqueur ne
   distinguerait plus rien. */
/* Les numéros d'un casier de fiabilité. Même pastille que le tableau croisé :
   c'est le même geste, « voici ce que ça vise ce soir ». */
.fi-n { margin: 6px 0 2px; }
.fi-n span small { font-weight: 400; opacity: .8; margin-left: 1px; }
.fi-plus { background: var(--ink-3) !important; }
.fi-vide { font-size: .75rem; color: var(--ink-3); margin: 6px 0 2px; }
/* Deux rangées de pastilles identiques ne se distinguent pas : sans étiquette
   ni couleur, « les plus vus » et « les moins vus » se lisent pareil. */
.fi-r { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.fi-lab { font-size: .6875rem; color: var(--ink-3); min-width: 6.5rem; }
.fi-bas .cx-n span { background: var(--ink-3); }

.fa-h { font-size: .8125rem; font-weight: 650; margin: 14px 0 4px; color: var(--ink-2); }

/* ── Les explications, à la demande ──────────────────────────────────────────
   Chaque tableau du panneau est accompagné d'un paragraphe qui dit ce que le
   chiffre vaut et ne vaut pas. Indispensable la première fois, encombrant la
   dixième — sur téléphone il repousse le tableau hors de l'écran. On les plie
   toutes d'un seul bouton et on retient le choix. */
body[data-expl="off"] .expl { display: none; }
.expl { max-width: 82ch; }

/* Les numéros du prochain tirage, dans la case du tableau croisé qui les
   décrit. C'est le seul endroit où la case devient actionnable. */
.cx-n { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 5px; }
.cx-n span {
  font-variant-numeric: tabular-nums; font-size: .6875rem; font-weight: 650;
  line-height: 1; padding: 3px 5px; border-radius: 3px;
  background: var(--accent); color: var(--paper);
}
.se-plat .cx-n span { background: var(--ink-3); }
/* Colonnes de largeur égale : les pastilles d'une case restent sur une ligne
   et les cases se comparent verticalement. Le tableau défile plutôt que de
   se tasser. */
.cx-t td, .cx-t th { vertical-align: top; min-width: 5.6rem; }
.cx-t td:first-child, .cx-t th:first-child { min-width: 4.5rem; }
.pl-t td small { display: block; color: var(--ink-3); font-size: .6875rem; }
.po-h small { font-weight: 400; color: var(--ink-3); font-size: .8125rem; }

/* « Au prochain tirage » : une grille, pas des phrases. Le numéro d'abord,
   puis l'accord, puis le taux — trois colonnes qui s'alignent et se comparent
   verticalement d'un seul regard. La phrase complète reste sous le petit
   texte, qui suit la bascule des explications. */
.pn-t { margin: 0 0 6px; max-width: 46rem; }
.pn-l {
  display: grid; grid-template-columns: 2.1rem 3.2rem 4.2rem auto; gap: 8px;
  align-items: baseline; padding: 6px 0; border-top: 1px solid var(--rule);
}
.pn-l small { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.pn-n {
  font-variant-numeric: tabular-nums; font-weight: 650; font-size: .8125rem;
  text-align: center; padding: 3px 0; border-radius: 3px;
  background: var(--accent); color: var(--paper);
}
.pn-a { color: var(--ink-3); font-variant-numeric: tabular-nums; font-size: .8125rem; }

/* Sur téléphone ces tableaux dépassent : plutôt que de les rétrécir jusqu'à
   l'illisible, on les laisse défiler dans leur propre boîte. Le reste de la
   page ne bouge pas. */
@media (max-width: 640px) {
  .pl-t { display: block; overflow-x: auto; max-width: 100%; }
  .pl-t td:first-child { width: auto; white-space: nowrap; }
  .pl-t th, .pl-t td { padding: 5px 7px 5px 0; white-space: nowrap; }
  .pl-t td small { white-space: nowrap; }
  .pgraph { max-width: 100%; }
}

.fraicheur { padding: 10px 16px 0; }
.fr-next { margin: 0; font-size: .9375rem; }
.fr-next b { font-weight: 650; }
.fr-reste {
  margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent); font-size: .8125rem; font-weight: 650;
  white-space: nowrap;
}
.fr-nom {
  margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  border: 1px solid var(--accent); color: var(--accent);
  font-size: .8125rem; font-weight: 650; white-space: nowrap;
}
.fr-maj { margin: 2px 0 0; font-size: .8125rem; color: var(--ink-3); }

.next-sticky {
  background: var(--paper-3);
  border-bottom: 1px solid var(--rule);
  padding: 14px 16px;
}
.next-sticky h2 { font-size: 1.0625rem; }
.teaser { position: relative; text-align: center; }
.teaser .balls { justify-content: center; pointer-events: none; }
.teaser .desc { margin: 12px 0 10px; }

/* ── « Bons jours » : la vitrine honnête ──────────────────────────── */

/* ── Graphes ──────────────────────────────────────────────────────
   Sur mobile le détail passe SOUS le graphe (il était à côté, ce qui
   écrasait les deux). Le SVG garde son ratio et reste tapable. */
.chart-row { display: flex; flex-direction: column; gap: 12px; }
.chart-main svg { width: 100%; height: auto; display: block; touch-action: manipulation; }
.chart-main { min-width: 0; }
.grid   { stroke: var(--rule); stroke-width: 1; }
.axis   { stroke: var(--rule-2); stroke-width: 1.5; }
.axlbl  { fill: var(--ink-3); font-size: 13px; font-family: var(--sans); }
.mline  { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.mline.composite { stroke-width: 4; }
.vline  { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 3 3; }
.hovcol { fill: transparent; cursor: pointer; }
.hovcol.sel { fill: color-mix(in srgb, var(--ink) 6%, transparent); }

/* La légende respirait si peu qu'elle semblait collée au bas de la grille, et
   chaque symbole touchait son propre texte. Deux espacements, et elle se lit. */
.legend2, .legend3 {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--rule);
  font-size: .75rem; color: var(--ink-2); line-height: 1.4;
}
.legend2 > span, .legend3 > span {
  display: inline-flex; align-items: center; gap: 8px;
}
.legend3 .gradbar + span { margin-left: -2px; }
.legend2 .li { cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.legend2 .li.off { opacity: .35; text-decoration: line-through; }
.sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: 0 0 auto; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block;
       background: var(--accent); flex: 0 0 auto; }

.serie-actions { margin-top: 10px; }
.serie-actions .modebtn { width: 100%; }

.chart-detail {
  border-top: 1px solid var(--rule); padding-top: 10px;
  font-size: .8125rem;
}
.cd-date { font-weight: 650; margin-bottom: 6px; }
.cd-row, .cd-actual {
  display: flex; gap: 8px; align-items: center;
  padding: 3px 0; flex-wrap: wrap;
}
.cd-row .k, .cd-actual .k {
  flex: 0 0 auto; min-width: 120px;
  display: inline-flex; align-items: center; gap: 5px; color: var(--ink-2);
}
.tt-balls { display: flex; flex-wrap: wrap; gap: 3px; }
.tt-ball {
  width: 24px; height: 24px; font-size: .6875rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--paper-3); color: var(--ink-2); border: 1px solid var(--rule);
}
.tt-ball.hit { background: var(--found); color: #fff; border-color: var(--found); }
.tt-ball.act { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* ── Panier stratégique ───────────────────────────────────────────── */
.basket-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; }
/* Grilles de numéros (panier, bonus). Le conteneur du panier portait la classe
   `.grid`, déjà utilisée par les lignes de grille des graphes SVG (`stroke`) :
   il n'héritait d'AUCUNE disposition et ses cases s'empilaient verticalement.

   Une fois réparé, le remplissage au fil de la largeur donnait 48 numéros sur
   une ligne et 8 sur la suivante : illisible. On impose donc une VRAIE grille,
   alignée sur les dizaines comme un bulletin de jeu. Dix colonnes font des
   rangées 1-10, 11-20… que l'œil parcourt sans effort ; cinq sur mobile
   conservent l'alignement en demi-dizaines. */
.num-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 5px;
}
.matrix-wrap { display: flex; flex-wrap: wrap; gap: 5px; }
.bonus-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }

@media (min-width: 520px) {
  .num-grid, .bonus-grid { grid-template-columns: repeat(10, minmax(0, 1fr)); }
}
/* Au-delà, on garde dix colonnes : élargir les cases sans fin les rendrait
   moins lisibles, pas plus. La grille se centre dans la carte. */
@media (min-width: 900px) {
  .num-grid, .bonus-grid { max-width: 620px; }
}
.bn {
  position: relative; width: auto; min-width: 0;
  padding: 6px 2px 5px; border-radius: 8px;
  background: var(--paper-3); border: 1px solid var(--rule); text-align: center;
}
/* Le numéro doit primer : c'est lui qu'on cherche. La statistique reste
   lisible mais recule d'un cran. */
.bn-n { display: block; font-weight: 700; font-size: .9375rem; line-height: 1.1; color: var(--ink); }
/* Le compte se lit PAR-DESSUS une teinte : en gris clair il disparaissait.
   Encre atténuée plutôt que gris, et un demi-gras pour tenir sur les fonds
   les plus saturés. */
.bn-v {
  display: block; font-size: .6875rem; line-height: 1.3;
  color: var(--ink-2); font-weight: 600;
}
.bn-v small { font-weight: 400; opacity: .75; }
/* Noir, pas la couleur du jeu : le rouge du Loto se lisait « en dessous du hasard ». */
.bn.inpick { box-shadow: 0 0 0 2px var(--ink); }

/* La dizaine en forme et la finale en forme étaient ANNONCÉES par la légende
   et n'avaient plus aucune règle : le HTML les posait, rien ne les dessinait.
   Une légende qui promet ce qu'on ne montre pas est pire que pas de légende. */
.bn.diz::before {
  content: ""; position: absolute; top: 2px; left: 24%; right: 24%;
  height: 3px; border-radius: 2px; background: var(--warn);
}
.bn .fin {
  position: absolute; bottom: 3px; right: 4px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}

/* « Une case à 45 %, ça vaut quoi ? » — deux barres par ligne. Tout le propos
   tient dans leur contraste : celle du haut monte au fil des lignes, celle du
   bas ne bouge pas. Aucun chiffre n'est nécessaire pour le voir, ils ne sont
   là que pour ceux qui veulent vérifier. */
.cyc { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.cyc-row {
  display: grid; grid-template-columns: 3.2rem 3.6rem 1fr 3.4rem;
  align-items: center; gap: 10px;
}
.avec-derive .cyc-row { grid-template-columns: 3.2rem 3.6rem 1fr 3.4rem 4.2rem; }
.cyc-derive {
  font-size: .75rem; font-variant-numeric: tabular-nums; text-align: right;
  color: var(--warn);
}
.cyc-hdr .cyc-derive { color: var(--ink-3); text-align: right; }

/* Sur mobile, les barres passent avant le décompte : à 375 px, garder la
   colonne « cases » les réduisait à 39 px, où le contraste ne se voyait plus.
   Le décompte reste dans l'infobulle de la ligne. */
@media (max-width: 560px) {
  .cyc-row, .avec-derive .cyc-row { grid-template-columns: 2.6rem 1fr 3rem; gap: 7px; }
  .avec-derive .cyc-row { grid-template-columns: 2.6rem 1fr 2.9rem 2.9rem; }
  .cyc-n { display: none; }
  .cyc-lab, .cyc-val, .cyc-derive { font-size: .6875rem; }
}
.cyc-lab, .cyc-val, .cyc-n {
  font-size: .75rem; font-variant-numeric: tabular-nums; color: var(--ink-2);
}
.cyc-lab { text-align: right; font-weight: 600; }
.cyc-n   { text-align: right; color: var(--ink-3); font-size: .6875rem; }
.cyc-val { color: var(--ink-3); }
.cyc-hdr {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); padding-bottom: 2px; border-bottom: 1px solid var(--rule);
}
.cyc-hdr .cyc-lab { font-weight: 600; }
.cyc-hdr .cyc-val { text-align: left; }
.cyc-bars { display: flex; flex-direction: column; gap: 3px; }
.cyc-bars .bar-track { height: 7px; }
.bar-fill.apres { background: var(--hasard); }

.cyc-head { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 10px; }
.cyc-leg {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .75rem; color: var(--ink-2);
}
.cyc-leg .sw {
  width: 18px; height: 7px; border-radius: 999px; background: var(--accent);
}
.cyc-leg .sw.apres { background: var(--hasard); }





/* ── Scope admin · une ligne par numéro ─────────────────────────────────────
   La grille méthode × position disait où un signal se loge ; celle-ci dit quel
   numéro le porte. Aucune colonne n'est un score composite : un score cache le
   raisonnement, et aucune de ces colonnes ne bat le hasard prise seule. */
.snum-wrap { max-height: 62vh; overflow: auto; border: 1px solid var(--rule); border-radius: var(--radius); }
.snum { border-collapse: collapse; width: 100%; font-size: .8125rem; }
.snum th, .snum td {
  padding: 5px 10px; text-align: right; border-bottom: 1px solid var(--rule);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.snum th {
  position: sticky; top: 0; z-index: 1; background: var(--paper-2);
  font-size: .625rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3); font-weight: 600;
}
.snum th.snum-h { cursor: pointer; }
/* La fenêtre de chaque colonne, sous son nom : elles n'ont pas la même, et
   c'est précisément ce qui prêtait à confusion. */
.snum th small {
  display: block; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--ink-3); opacity: .75; font-size: .9em;
}
.snum th { vertical-align: bottom; line-height: 1.25; }
.snum th.snum-h:hover { color: var(--ink); }
.snum tr.fort { background: var(--found-bg); }
.snum-n { font-weight: 700; text-align: left; color: var(--ink); }
/* La barre du consensus vit DERRIÈRE le chiffre : elle donne l'ordre de
   grandeur sans qu'on ait à lire la colonne ligne à ligne. */
.snum td { position: relative; }
.snum-bar {
  position: absolute; left: 0; top: 3px; bottom: 3px;
  background: var(--accent); opacity: .16; border-radius: 0 3px 3px 0;
}
.snum td b { position: relative; }
.snum .chaud { color: var(--found); font-weight: 700; }
.snum .retard { color: var(--warn); font-weight: 700; }
.snum-t { text-align: center; color: var(--ink-3); }

@media (max-width: 620px) {
  .snum th, .snum td { padding: 5px 6px; font-size: .75rem; }
  .snum th { font-size: .5625rem; }
}

/* Jumeaux : un même numéro désigné par plusieurs cases retenues. C'est ce
   qu'on cherchait à l'œil en balayant la grille ; autant l'encadrer. */
.scopeheat td.hcell.jumeau { outline: 2px solid var(--accent); outline-offset: -2px; }
.scopeheat td.hcell.vise { outline: 3px solid var(--ink); outline-offset: -3px; }
/* Survol : le même numéro s'allume dans toute la matrice. C'est la question
   qu'on se pose sans arrêt devant mille cases — où d'autre est-il ? */
.scopeheat td.hcell.echo-n {
  box-shadow: inset 0 0 0 2px var(--ink); font-weight: 700;
}
.scopeheat td.hcell[data-n] { cursor: pointer; }

/* Survol d'une LIGNE : retrouver de quelle méthode on parle demandait de
   remonter des yeux sur quarante colonnes. Une teinte légère suffit, et le nom
   de la méthode se détache en même temps. */
.scopeheat tr:hover td { background-image: linear-gradient(var(--survol), var(--survol)); }
.scopeheat tr:hover th.hsrc { background: var(--paper-3); color: var(--ink); font-weight: 650; }
.snum tr:hover td { background-image: linear-gradient(var(--survol), var(--survol)); }
.side-n.jumeau { box-shadow: inset 0 0 0 2px var(--accent); }
.side-n[data-sn] { cursor: pointer; }
.scope-side .note { margin-top: 8px; }


/* Repérer un numéro d'une grille à l'autre. Devant vingt grilles, la question
   n'est pas « laquelle choisir » mais « qui d'autre propose ce numéro ». Le
   survol répond ; le clic fige, parce qu'au doigt il n'y a pas de survol. */
.me-b[data-n] { cursor: pointer; transition: background .12s, color .12s; }
/* « +N sans ordre » : une croyance qui désigne plus de numéros qu'on n'en
   montre, ou qui ne dit rien du tout. Le dire vaut mieux que de compléter. */
.me-plus {
  font-size: .6875rem; color: var(--ink-3); font-style: italic;
  align-self: center; padding-left: 4px;
}

.me-b.echo {
  background: var(--accent); color: #fff; border-color: var(--accent);
}
.me-b.echo .rv { background: #fff; color: var(--accent); }
.me-b.epingle { box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--accent); }

/* ── Le tableau des méthodes ────────────────────────────────────────────────
   Il remplace un sélecteur où chaque méthode coûtait un clic et rechargeait
   la page. On ne compare pas de mémoire : tout est là, côte à côte. Le clic ne
   sert plus qu'à promouvoir une méthode en haut de page. */
.methodes { margin-top: 18px; }
.me-head, .me-row {
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 11rem 1fr 11rem;
}
.me-head {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); padding: 0 8px 6px; border-bottom: 1px solid var(--rule);
}
.me-bloc { border-bottom: 1px solid var(--rule); }
.me-bloc.active { background: var(--found-bg); box-shadow: inset 3px 0 0 var(--accent); }
.me-bloc.ouvert:not(.active) { background: var(--paper-3); }
.me-row {
  width: 100%; text-align: left; background: none; border: 0;
  padding: 10px 8px; cursor: pointer; font: inherit; color: inherit; border-radius: 6px;
}
.me-bloc:not(.active) .me-row:hover { background: var(--paper-3); }
.me-chev {
  display: inline-block; width: 1em; color: var(--ink-3);
  font-style: normal; font-size: .75rem;
}

/* Les en-têtes deviennent des boutons de tri : le curseur et la flèche le
   disent, rien d'autre ne change pour ne pas alourdir la ligne. */
.me-sort {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em;
  font-size: .625rem; text-align: inherit;
}
.me-sort:hover { color: var(--ink); }

/* La grille de la ligne : les boules ont désormais la place qu'occupait le
   bloc du haut, donc elles se lisent vraiment. */
.me-b {
  display: inline-flex; align-items: center; justify-content: center; position: relative;
  min-width: 32px; height: 32px; padding: 0 6px; border-radius: 999px;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  font-size: .875rem; font-weight: 600; font-variant-numeric: tabular-nums;
}
.me-b.revient { border-color: var(--accent); }
.me-b.bonus { background: var(--accent); color: #fff; border-color: var(--accent); }
.me-b .rv {
  position: absolute; top: -6px; right: -4px; font-style: normal;
  font-size: .5625rem; line-height: 1; padding: 2px 3px; border-radius: 999px;
  background: var(--accent); color: #fff;
}

/* Le dépliant : la justification là où on la cherche. */
.me-detail { padding: 2px 8px 14px 2.1rem; }
.me-desc { font-size: .875rem; color: var(--ink-2); margin: 0 0 10px; line-height: 1.5; }
.me-why { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.me-wr { display: grid; grid-template-columns: 2.2rem 1fr; gap: 8px; font-size: .8125rem; }
.me-wr b { color: var(--accent); font-variant-numeric: tabular-nums; }
.me-wr span { color: var(--ink-2); }
.me-detail .note { margin-top: 6px; }

.me-bonus {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule);
}
.me-bonus-l { font-size: .8125rem; font-weight: 600; }
.me-bonus-l small { font-weight: 400; color: var(--ink-3); }
.me-nom { font-size: .8125rem; font-weight: 600; }
.me-next { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.me-vide { color: var(--ink-3); }
/* Les bons jours de la méthode, à côté de sa grille : le record d'abord, et
   dessous la fréquence du seuil qui compte sur ce jeu. */
.me-bj { display: flex; flex-direction: column; gap: 1px; text-align: right; }
.me-rec {
  font-family: var(--serif); font-size: 1.25rem; line-height: 1.1;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.me-rec small { font-size: .75rem; color: var(--ink-3); font-family: var(--sans); }
.me-bjd { font-size: .6875rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.me-bjd b { color: var(--ink); }
/* La référence du hasard, juste dessous et en retrait : elle doit être là sans
   voler la vedette au chiffre qu'elle sert à relativiser. */
.me-bjh {
  font-size: .625rem; color: var(--ink-3); font-variant-numeric: tabular-nums;
  font-style: italic;
}
.me-head .me-bj { text-align: right; }
.methodes .voir-tout { margin-top: 10px; }
/* Le mini-ballon du tableau : assez petit pour que quinze lignes tiennent,
   assez contrasté pour que le vert saute aux yeux. */
.mini.hit { background: var(--found); color: #fff; font-weight: 700; }

@media (max-width: 700px) {
  /* Sur mobile l'en-tête ne peut plus être un tableau, mais il porte le tri :
     le masquer rendait le tri inaccessible au doigt. Il devient donc une
     barre compacte des deux seuls boutons qui comptent. */
  .me-head {
    display: flex; justify-content: space-between; align-items: center;
    gap: 10px; padding: 0 8px 8px;
  }
  .me-head .me-next { display: none; }
  .me-head .me-sort { padding: 4px 0; }
  /* Trois lignes plutôt que deux colonnes : à 375 px, mettre le nom et les
     chiffres côte à côte réduisait « Inverse (anti-consensus) » à trois lignes
     de deux mots. Le nom prend donc toute la largeur, les chiffres suivent. */
  .me-row { grid-template-columns: 1fr; gap: 5px; padding: 10px 8px; }
  .me-nom, .me-bj, .me-next { grid-column: 1; }
  .me-bj {
    flex-direction: row; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
    text-align: left;
  }
  .me-rec { font-size: 1rem; }
  .me-chev { width: .9em; }
}


/* ── Trois tableaux, deux repliés ───────────────────────────────────────────
   Mélangés, vingt lignes noyaient les six qui sont notre proposition. Et voir
   « Phases de la lune » à côté de « Composite équilibré » laissait croire
   qu'on les met sur le même plan : on les publie, on ne les vend pas. */
.me-groupe + .me-groupe { margin-top: 20px; }
.me-gtitre {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; padding: 8px 0; cursor: pointer;
  font-family: var(--serif); font-size: 1.0625rem; color: var(--ink);
  border-bottom: 1px solid var(--rule-2); text-align: left;
}
.me-gtitre:hover { color: var(--accent); }
.me-gn {
  margin-left: auto; font-family: var(--sans); font-size: .6875rem;
  color: var(--ink-3); background: var(--paper-3);
  padding: 2px 8px; border-radius: 999px;
}
.me-gcorps { padding-top: 10px; }
.me-gcorps > .sub { margin: 0 0 10px; }

/* ── Le tableau des méthodes ────────────────────────────────────────────────
   Il remplace un sélecteur où chaque méthode coûtait un clic et rechargeait
   la page. On ne compare pas de mémoire : tout est là, côte à côte. Le clic ne
   sert plus qu'à promouvoir une méthode en haut de page. */
.methodes { margin-top: 18px; }
.me-head, .me-row {
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 11rem 1fr 11rem;
}
.me-head {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); padding: 0 8px 6px; border-bottom: 1px solid var(--rule);
}
.me-bloc { border-bottom: 1px solid var(--rule); }
.me-bloc.active { background: var(--found-bg); box-shadow: inset 3px 0 0 var(--accent); }
.me-bloc.ouvert:not(.active) { background: var(--paper-3); }
.me-row {
  width: 100%; text-align: left; background: none; border: 0;
  padding: 10px 8px; cursor: pointer; font: inherit; color: inherit; border-radius: 6px;
}
.me-bloc:not(.active) .me-row:hover { background: var(--paper-3); }
.me-chev {
  display: inline-block; width: 1em; color: var(--ink-3);
  font-style: normal; font-size: .75rem;
}

/* Les en-têtes deviennent des boutons de tri : le curseur et la flèche le
   disent, rien d'autre ne change pour ne pas alourdir la ligne. */
.me-sort {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em;
  font-size: .625rem; text-align: inherit;
}
.me-sort:hover { color: var(--ink); }

/* La grille de la ligne : les boules ont désormais la place qu'occupait le
   bloc du haut, donc elles se lisent vraiment. */
.me-b {
  display: inline-flex; align-items: center; justify-content: center; position: relative;
  min-width: 32px; height: 32px; padding: 0 6px; border-radius: 999px;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  font-size: .875rem; font-weight: 600; font-variant-numeric: tabular-nums;
}
.me-b.revient { border-color: var(--accent); }
.me-b.bonus { background: var(--accent); color: #fff; border-color: var(--accent); }
.me-b .rv {
  position: absolute; top: -6px; right: -4px; font-style: normal;
  font-size: .5625rem; line-height: 1; padding: 2px 3px; border-radius: 999px;
  background: var(--accent); color: #fff;
}

/* Le dépliant : la justification là où on la cherche. */
.me-detail { padding: 2px 8px 14px 2.1rem; }
.me-desc { font-size: .875rem; color: var(--ink-2); margin: 0 0 10px; line-height: 1.5; }
.me-why { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.me-wr { display: grid; grid-template-columns: 2.2rem 1fr; gap: 8px; font-size: .8125rem; }
.me-wr b { color: var(--accent); font-variant-numeric: tabular-nums; }
.me-wr span { color: var(--ink-2); }
.me-detail .note { margin-top: 6px; }

.me-bonus {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule);
}
.me-bonus-l { font-size: .8125rem; font-weight: 600; }
.me-bonus-l small { font-weight: 400; color: var(--ink-3); }
.me-nom { font-size: .8125rem; font-weight: 600; }
.me-next { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.me-vide { color: var(--ink-3); }
/* Les bons jours de la méthode, à côté de sa grille : le record d'abord, et
   dessous la fréquence du seuil qui compte sur ce jeu. */
.me-bj { display: flex; flex-direction: column; gap: 1px; text-align: right; }
.me-rec {
  font-family: var(--serif); font-size: 1.25rem; line-height: 1.1;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.me-rec small { font-size: .75rem; color: var(--ink-3); font-family: var(--sans); }
.me-bjd { font-size: .6875rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.me-bjd b { color: var(--ink); }
/* La référence du hasard, juste dessous et en retrait : elle doit être là sans
   voler la vedette au chiffre qu'elle sert à relativiser. */
.me-bjh {
  font-size: .625rem; color: var(--ink-3); font-variant-numeric: tabular-nums;
  font-style: italic;
}
.me-head .me-bj { text-align: right; }
.methodes .voir-tout { margin-top: 10px; }
/* Le mini-ballon du tableau : assez petit pour que quinze lignes tiennent,
   assez contrasté pour que le vert saute aux yeux. */
.mini.hit { background: var(--found); color: #fff; font-weight: 700; }

@media (max-width: 700px) {
  /* Sur mobile l'en-tête ne peut plus être un tableau, mais il porte le tri :
     le masquer rendait le tri inaccessible au doigt. Il devient donc une
     barre compacte des deux seuls boutons qui comptent. */
  .me-head {
    display: flex; justify-content: space-between; align-items: center;
    gap: 10px; padding: 0 8px 8px;
  }
  .me-head .me-next { display: none; }
  .me-head .me-sort { padding: 4px 0; }
  /* Trois lignes plutôt que deux colonnes : à 375 px, mettre le nom et les
     chiffres côte à côte réduisait « Inverse (anti-consensus) » à trois lignes
     de deux mots. Le nom prend donc toute la largeur, les chiffres suivent. */
  .me-row { grid-template-columns: 1fr; gap: 5px; padding: 10px 8px; }
  .me-nom, .me-bj, .me-next { grid-column: 1; }
  .me-bj {
    flex-direction: row; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
    text-align: left;
  }
  .me-rec { font-size: 1rem; }
  .me-chev { width: .9em; }
}


/* ── Trois tableaux, deux repliés ───────────────────────────────────────────
   Mélangés, vingt lignes noyaient les six qui sont notre proposition. Et voir
   « Phases de la lune » à côté de « Composite équilibré » laissait croire
   qu'on les met sur le même plan : on les publie, on ne les vend pas. */
.me-groupe + .me-groupe { margin-top: 20px; }
.me-gtitre {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; padding: 8px 0; cursor: pointer;
  font-family: var(--serif); font-size: 1.0625rem; color: var(--ink);
  border-bottom: 1px solid var(--rule-2); text-align: left;
}
.me-gtitre:hover { color: var(--accent); }
.me-gn {
  margin-left: auto; font-family: var(--sans); font-size: .6875rem;
  color: var(--ink-3); background: var(--paper-3);
  padding: 2px 8px; border-radius: 999px;
}
.me-gcorps { padding-top: 10px; }
.me-gcorps > .sub { margin: 0 0 10px; }

/* ── Keno · les pistes du moment ────────────────────────────────────────────
   Le seul bloc du site où une fouille alimente une proposition. L'étiquette
   « à l'épreuve » est là pour qu'on ne l'oublie jamais : elle fait partie du
   titre, pas d'une note de bas de page. */
.tag-epreuve {
  font-family: var(--sans); font-size: .625rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; vertical-align: middle;
  padding: 3px 9px; border-radius: 999px; margin-left: 10px;
  background: var(--warn); color: #fff;
}
.pi-nums { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 10px; }
.pi-n {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-width: 46px; height: 46px; border-radius: 999px; cursor: pointer;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  font: inherit; font-variant-numeric: tabular-nums;
}
.pi-n:hover, .pi-n.ouvert { border-color: var(--accent); }
.pi-n.ouvert { background: var(--found-bg); }
.pi-v { font-size: 1.0625rem; font-weight: 700; }
.pi-r {
  position: absolute; top: -5px; right: -4px;
  min-width: 18px; height: 18px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff; font-size: .625rem; font-weight: 700;
}
.pi-detail:empty { display: none; }
.pi-liste { display: flex; flex-direction: column; gap: 5px; margin-bottom: 10px; }
.pi-l {
  display: grid; grid-template-columns: 9rem 1fr 9rem; gap: 10px;
  font-size: .8125rem; padding: 5px 8px; border-radius: 6px; background: var(--paper-3);
}
.pi-l span { color: var(--ink-2); }
.pi-l em { font-style: normal; color: var(--ink-3); text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .pi-l { grid-template-columns: 1fr; gap: 2px; }
  .pi-l em { text-align: left; }
}

/* Les quarts du bloc 13 */
.mq { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px 28px; margin: 14px 0 12px; }
.mq-nom { font-size: .75rem; color: var(--ink-2); margin-bottom: 8px; font-weight: 600; }
.mq-row { display: grid; grid-template-columns: 1.8rem 1fr 3.6rem; align-items: center; gap: 8px; margin-bottom: 5px; }
.mq-q { font-size: .6875rem; color: var(--ink-3); }
.mq-row .bar-track { height: 10px; position: relative; }
.mq-base { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--ink); opacity: .6; }
.mq-v { font-size: .6875rem; color: var(--ink-3); text-align: right; font-variant-numeric: tabular-nums; }

/* ── Keno · choisir sa formule ──────────────────────────────────────────────
   Le seul jeu où le joueur choisit la taille de son pari, donc la seule carte
   propre à un jeu. Le rendement porte une barre parce que c'est la colonne
   qu'on compare ; les autres restent du texte, pour ne pas transformer un
   tableau de décision en tableau de bord. */
.kf, .kf-test { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
.kf-row {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: 3.6rem 3.6rem 1fr 5.2rem 5rem 5.4rem;
  padding: 5px 6px; border-radius: 6px;
}
.kf-trow {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: 3.6rem 1fr 6rem 4.6rem 5rem;
  padding: 4px 6px; border-radius: 6px;
}
.kf-row + .kf-row:nth-child(odd), .kf-trow + .kf-trow:nth-child(odd) {
  background: var(--paper-3);
}
.kf-row.best { background: var(--found-bg); }
.kf-hdr {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); background: none !important;
  border-bottom: 1px solid var(--rule); border-radius: 0; padding-bottom: 4px;
}
.kf-k { font-weight: 650; font-size: .8125rem; white-space: nowrap; }
.kf-k sup { font-size: .5625rem; }
.kf-rtp, .kf-freq, .kf-max, .kf-num {
  font-size: .8125rem; font-variant-numeric: tabular-nums;
}
.kf-rtp { font-weight: 650; }
.kf-freq.fort { color: var(--found); font-weight: 650; }
.kf-max, .kf-num.pale { color: var(--ink-3); }
.kf-vide, .kf-conf, .kf-ecart { font-size: .75rem; color: var(--ink-3); }
.kf-conf { color: var(--found); }
.kf-ecart { color: var(--warn); font-weight: 650; }
/* Le raisonnement du multiplicateur en trois pas. Il tient sans la
   distribution des valeurs, ce qui est contre-intuitif : on le montre donc
   comme une démonstration, numérotée, pas comme un paragraphe de plus. */
.kf-raison { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 16px; }
.kf-raison > div {
  display: flex; gap: 10px; align-items: baseline;
  font-size: .875rem; color: var(--ink-2); line-height: 1.5;
}
.kf-etape {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 999px;
  background: var(--accent); color: #fff;
  font-size: .6875rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.kf-row.kf-mrow { grid-template-columns: 3.6rem 4.4rem 1fr 8rem; }
.kf-row.kf-brow { grid-template-columns: 3.6rem 4rem 6rem 1fr 8rem; }
.kf-freq small { display: block; font-size: .625rem; color: var(--ink-3); font-weight: 400; }
/* Barre de PLAGE : elle ne part pas de zéro mais du rendement sans option, et
   sa longueur est le gain que l'option peut apporter. */
.bar-fill.plage { background: var(--accent); opacity: .85; }
.kf-plage .bar-track { position: relative; }
.kf-rtp.fort { color: var(--accent); }

.badge-vide {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  background: var(--warn); color: #fff; font-size: .6875rem; font-weight: 600;
  white-space: nowrap;
}

@media (max-width: 620px) {
  /* Sur mobile on garde ce qui décide : la taille, le rendement, sa barre, et
     le rang « 0 trouvé » qui n'existe nulle part ailleurs. Les colonnes
     masquées doivent l'être DANS L'EN-TÊTE AUSSI, sinon celui-ci garde six
     cellules pour quatre colonnes et se replie sur deux lignes. */
  .kf-row  { grid-template-columns: 3.2rem 3.4rem 1fr 4.6rem; gap: 8px; }
  .kf-row.kf-mrow { grid-template-columns: 3.2rem 1fr 6.6rem; gap: 8px; }
  .kf-row.kf-brow { grid-template-columns: 3.2rem 4.6rem 1fr; gap: 6px 8px; }
  .kf-row.kf-brow > .bar-track { display: none; }
  .kf-row.kf-brow.kf-hdr > :nth-child(2), .kf-row.kf-brow > :nth-child(2) { display: none; }
  .kf-row.kf-mrow > .kf-plage, .kf-row.kf-mrow.kf-hdr > :nth-child(3) { display: none; }
  .kf-trow { grid-template-columns: 3.2rem 1fr 3.2rem 4.4rem; gap: 8px; }
  /* Le masquage vise la vue « quelle formule jouer » : sans :not(.kf-mrow),
     il emportait aussi l'en-tête « avec option » de la vue multiplicateur,
     qui n'a pas les mêmes colonnes. */
  .kf-row .kf-freq, .kf-row .kf-max,
  .kf-row.kf-hdr:not(.kf-mrow) > :nth-child(4),
  .kf-row.kf-hdr:not(.kf-mrow) > :nth-child(5),
  .kf-trow > :nth-child(4) { display: none; }
  .kf-hdr { font-size: .5625rem; }
}

/* Tête de liste ou milieu : un trait vertical marque le taux normal du jeu.
   Sans lui, sept barres de longueurs voisines ne disent rien ; avec lui, on
   voit immédiatement qu'elles oscillent autour et non au-dessus. */
.rg { display: flex; flex-direction: column; gap: 7px; margin-bottom: 12px; }
.rg-row { display: grid; grid-template-columns: 2.2rem 1fr 3.4rem; align-items: center; gap: 10px; }
.rg-lab { text-align: right; font-size: .8125rem; font-weight: 600; color: var(--ink-2); }
.rg-val { font-size: .75rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.rg .bar-track { height: 12px; position: relative; }
.rg-base {
  position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--ink); opacity: .55; border-radius: 1px;
}

/* Les règles conditionnelles retenues. Volontairement sobres : ce sont des
   hypothèses sous surveillance, pas des conseils, et l'affichage ne doit pas
   leur donner l'allure d'un tableau de recommandations. */
.rgl { display: flex; flex-direction: column; gap: 2px; margin: 14px 0 12px; }
.rgl-row {
  display: grid; align-items: center; gap: 8px;
  grid-template-columns: 8rem 3rem 1fr 6rem 3rem 3.4rem 5rem;
  padding: 5px 8px; border-radius: 6px; font-size: .8125rem;
  font-variant-numeric: tabular-nums;
}
.rgl-row:nth-child(even) { background: var(--paper-3); }
.rgl-row.retenue { background: var(--found-bg); box-shadow: inset 3px 0 0 var(--found); }
.rgl-hdr {
  font-size: .625rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-3); background: none !important;
  border-bottom: 1px solid var(--rule); border-radius: 0;
}
.rgl-c { color: var(--ink-2); }
.rgl-row small { color: var(--ink-3); }
.rgl-tag { font-size: .625rem; color: var(--ink-3); text-align: right; }
.rgl-row.retenue .rgl-tag { color: var(--found); font-weight: 650; }

@media (max-width: 760px) {
  .rgl-row { grid-template-columns: 1fr 3rem 4.6rem; gap: 4px 8px; }
  .rgl-hdr { display: none; }
  .rgl-c { grid-column: 1 / -1; font-size: .75rem; }
  .rgl-row > :nth-child(5), .rgl-row > :nth-child(6) { display: none; }
}

/* Angle mort : un losange discret, pas une alerte. Ces numéros ne sont ni
   plus ni moins probables, ils sont seulement absents de toutes les grilles. */
.bn.angle-mort { box-shadow: inset 0 0 0 1.5px var(--warn); }
.oub { color: var(--warn); font-size: .6875rem; line-height: 1; }
.bn .oub { position: absolute; top: 2px; left: 4px; }
.bonus-sep { width: 100%; height: 1px; background: var(--rule); margin: 8px 0; }

/* ── Modèles / ROI / heatmap (vue avancée) ───────────────────────── */
.model-grid, .mode-selector { display: flex; flex-wrap: wrap; gap: 8px; }
.mhead { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.mname { font-weight: 600; }
.mpct, .mavg { color: var(--ink-2); font-size: .8125rem; }
.mini-balls { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 5px; }

.bars { display: flex; flex-direction: column; gap: 6px; }
.bar-row { display: grid; grid-template-columns: minmax(84px, 1fr) 2fr auto; gap: 8px; align-items: center; font-size: .8125rem; }
.bar-track { background: var(--paper-3); border-radius: 999px; height: 8px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 999px; }
.neg .bar-fill { background: var(--danger); }

.heat-wrap { overflow-x: auto; }
.posmatrix, .scopeheat, .sig-table { border-collapse: collapse; font-size: .75rem; width: 100%; }
.posmatrix td, .posmatrix th, .scopeheat td, .scopeheat th, .sig-table td, .sig-table th {
  border: 1px solid var(--rule); padding: 4px 6px; text-align: center;
}
.posmatrix th, .scopeheat th, .sig-table th { color: var(--ink-3); font-weight: 500; }

/* ── Tests d'aléa (bloc 1) ────────────────────────────────────────── */
.tests { display: flex; flex-direction: column; gap: 14px; margin-bottom: 12px; }
.test-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 5px; }
.test-nom { font-weight: 600; font-size: .9375rem; }
.test-verdict { font-size: .75rem; white-space: nowrap; }
.test-verdict.ok { color: var(--found); }
.test-verdict.alerte { color: var(--danger); font-weight: 600; }
.test-detail {
  font-size: .75rem; color: var(--ink-3); margin-top: 4px;
  /* Les détails contiennent des listes de tuples sans espace : sans ceci,
     elles s'étirent sur une seule ligne et poussent la carte. */
  overflow-wrap: anywhere;
}
.tests .bar-track { height: 6px; }

/* ── Classement du backtest (bloc 2) ──────────────────────────────── */
.bt-table { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.bt-table th { text-align: left; color: var(--ink-3); font-weight: 500; padding: 4px 8px 6px 0; }
.bt-table th.num, .bt-table td.num { text-align: right; }
.bt-table td { padding: 4px 8px 4px 0; border-top: 1px solid var(--rule); }
.bt-table tr.gagne td { font-weight: 650; }
.bt-table tr.gagne td:first-child::after { content: " ●"; color: var(--warn); }
/* Barre bipolaire : le zéro est au centre, la longueur dit l'écart au hasard. */
.zbar { position: relative; width: 100%; min-width: 90px; height: 12px; }
.zfill { position: absolute; top: 3px; height: 6px; border-radius: 3px; background: var(--found); }
.zfill.neg { background: var(--rule-2); }
.zmid { position: absolute; left: 50%; top: 0; width: 1px; height: 12px; background: var(--rule-2); }

/* ── Amis / ennemis ───────────────────────────────────────────────── */
.pair-cols { display: grid; grid-template-columns: 1fr; gap: 12px; }
.pair-list { display: flex; flex-direction: column; gap: 4px; font-size: .8125rem; }
.pair { display: flex; align-items: center; gap: 6px; }

/* ── Conseil du jeu : le seul vrai levier, donc mis en avant ─────── */
.advice { border-left: 3px solid var(--accent); }
.advice h2 { color: var(--accent); }

/* ── Scope admin ──────────────────────────────────────────────────── */
.scope-row { display: flex; flex-direction: column; gap: 12px; }
.scope-grid { display: flex; flex-wrap: wrap; gap: 4px; }
.scope-side { width: 100%; border-top: 1px solid var(--rule); padding-top: 12px; }
.side-list { display: flex; flex-direction: column; gap: 3px; font-size: .8125rem; }

/* ── Admin : éditeur de la bible ──────────────────────────────────── */
#admin-json {
  width: 100%; min-height: 320px; resize: vertical;
  font: 12px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  background: var(--paper-3); color: var(--ink);
  border: 1px solid var(--rule-2); border-radius: var(--radius); padding: 10px;
}
.admin-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.zspark { font-family: ui-monospace, Menlo, monospace; letter-spacing: -1px; }
.warn { color: var(--warn); }
.red  { color: var(--danger); }

/* ── Bandeau d'honnêteté : jamais en petit, jamais en gris clair ──
   C'est la promesse du produit et sa protection juridique. */
.honesty {
  margin: 10px 16px 4px;
  padding: 14px 16px;
  border: 1px solid var(--rule-2); border-radius: var(--radius);
  background: var(--paper-3);
  color: var(--ink-2); font-size: .875rem; line-height: 1.5;
}

/* ═══════════════════════════════════════════════════════════════════
   ≥ 640 px — deux colonnes pour les grilles compactes
   ═══════════════════════════════════════════════════════════════════ */
@media (min-width: 640px) {
  .pair-cols { grid-template-columns: 1fr 1fr; }
  .ball { width: 40px; height: 40px; font-size: 1rem; }
}

/* ═══════════════════════════════════════════════════════════════════
   ≥ 900 px — la navigation remonte dans l'en-tête, grille de 12 colonnes

   Un grand écran n'est pas un petit écran avec des marges : plafonner à
   1180 px centré laissait 740 px de vide sur un 1920, et la carte
   « Dernier tirage » occupait toute la largeur pour n'en remplir que la
   moitié. On passe à une grille de 12 colonnes, et les cartes larges
   réorganisent AUSSI leur contenu interne.
   ═══════════════════════════════════════════════════════════════════ */
@media (min-width: 900px) {
  body { padding-bottom: 0; }

  .topbar { padding: 12px 32px; gap: 28px; justify-content: flex-start; }
  .brand { font-size: 1.25rem; }

  .games {
    position: static; height: auto; padding: 0; border: 0;
    background: none; flex: 1 1 auto; gap: 4px; align-items: center;
  }
  .games button {
    flex: 0 0 auto; font-size: .875rem; padding: 7px 13px;
    border: 1px solid transparent; border-radius: 999px;
  }
  .games button:hover { color: var(--ink); background: var(--paper-3); }
  .games button.active {
    color: #fff; background: var(--accent); border-color: var(--accent);
  }
  .account { margin-left: auto; }

  /* Aucun plafond de largeur : sur un 27 pouces, 1680 px centré laissait
     encore 440 px de vide de chaque côté. C'est la MARGE qui grandit avec
     l'écran, pas le vide. La lisibilité des textes est protégée non pas en
     bridant la page, mais en donnant une mesure aux paragraphes (voir
     `.card p` plus bas) — un titre ou un tableau, lui, a tout à gagner à
     s'étendre. */
  .app { padding: 24px clamp(20px, 4vw, 160px); max-width: none; }
  .view { grid-template-columns: repeat(12, 1fr); gap: 20px; align-items: start; }

  /* Tableau de bord : toute tuile prend la pleine largeur, par sa CLASSE.
     Une liste d'identifiants oubliait les nouvelles cartes, qui tombaient
     dans une colonne sur douze (le chat s'y empilait mot par mot). */
  .tuile, .perso, .admin-card,
  #admin-scope  { grid-column: span 12; }
  #admin-scope  { order: 99; }

  /* Statistiques avancées — l'ordre porte la démonstration, il n'est pas
     décoratif. Chaque élément a une valeur UNIQUE : deux éléments partageant
     le même `order` se replacent selon le HTML et l'enchaînement se casse. */
  .view-lead        { grid-column: 1 / -1; }
  .view-lead        { order: 0; }
  .view-lead.separee { order: 11; }

  /* La démonstration. Toutes les cartes à moitié de largeur, deux par
     rangée et de même hauteur dans une rangée (05/10) : l'alternance 7/5
     colonnes, plus 5/4/3 au-delà de 2 100 px, faisait des rangées en dents
     de scie. */
  #view-stats { align-items: stretch; }
  #randomness { grid-column: span 6; order: 1; }
  #retards    { grid-column: span 6; order: 2; }
  #backtest   { grid-column: span 12; order: 3; }   /* 28 lignes : seul, sinon sa voisine s'étire dans le vide */
  #bruit      { grid-column: span 6; order: 4; }
  #ecartes    { grid-column: span 6; order: 5; }
  #cycles     { grid-column: span 6; order: 6; }
  #rangs      { grid-column: span 6; order: 7; }
  #regles     { grid-column: span 6; order: 8; }
  #roi        { grid-column: span 6; order: 9; }
  #heatmap    { grid-column: span 12; order: 10; }  /* une matrice : la largeur lui sert */

  /* Le descriptif, après la séparation : les grands tableaux en pleine
     largeur, les cartes courtes par deux. */
  #kenoform   { grid-column: span 12; order: 12; }
  #posmatrix  { grid-column: span 12; order: 13; }
  #dizaines   { grid-column: span 6;  order: 14; }
  #finales    { grid-column: span 6;  order: 15; }
  #affinity   { grid-column: span 12; order: 16; }
  #models     { grid-column: span 12; order: 17; }
  #melanges   { grid-column: span 6;  order: 18; }
  #fouille    { grid-column: span 6;  order: 19; }
  #moments    { grid-column: span 6;  order: 20; }
  /* Le conseil ferme « Le détail » : c'est une lecture, pas un geste. */
  #advice     { grid-column: span 6;  order: 21; }

  .card { padding: 22px 24px; }
  .fraicheur { padding: 14px clamp(20px, 4vw, 160px) 0; }
  .next-sticky { padding: 18px clamp(20px, 4vw, 160px); }
  .honesty { margin: 14px clamp(20px, 4vw, 160px) 32px; max-width: none; }

  /* Le détail revient à côté du graphe, où il y a enfin la place. */
  .chart-row { flex-direction: row; gap: 22px; }
  .chart-main { flex: 1 1 auto; }
  .chart-detail {
    flex: 0 0 300px; border-top: 0; border-left: 1px solid var(--rule);
    padding: 0 0 0 18px;
  }
  .axlbl { font-size: 11px; }
  .serie-actions .modebtn { width: auto; }
  .ball { width: 42px; height: 42px; font-size: 1.0625rem; }
}

/* ≥ 1300 px — on desserre, sans changer les répartitions : 5 + 4 sur 12
   laissait trois colonnes vides, ce qui est exactement le défaut qu'on
   cherche à corriger. */
@media (min-width: 1300px) {
  .app { padding: 28px clamp(28px, 4vw, 160px); }
  .view { gap: 24px; }
  #dizaines, #finales { grid-column: span 6; }
  .chart-detail { flex-basis: 340px; }
  .pair-cols { grid-template-columns: repeat(3, 1fr); }
}

/* ≥ 1600 px — deux cartes par ligne au lieu d'une pleine largeur suivie
   d'un vide. */
@media (min-width: 1600px) {
  #basket    { grid-column: span 12; order: 3; }
  #curve-modes  { order: 5; }
  #curve-models { order: 6; }
  #curve-bonus  { order: 7; }
  #admin-scope  { order: 8; }
  .chart-detail { flex-basis: 380px; }
}

/* ≥ 2100 px (27 pouces et au-delà) — trois cartes sur la première rangée, et
   les deux graphes côte à côte : à cette largeur, chacun dispose encore de
   plus de 1000 px, soit davantage qu'un écran d'ordinateur portable entier. */
@media (min-width: 2100px) {
  #basket       { grid-column: span 12; order: 4; }
  /* Les courbes restent l'une SOUS l'autre, même sur très grand écran : côte
     à côte, chaque graphe perdait la moitié de sa largeur et les points se
     tassaient au point de ne plus se lire. Un graphe large vaut mieux que
     deux graphes serrés. */
  #curve-modes  { grid-column: span 12; order: 5; }
  #curve-models { grid-column: span 12; order: 6; }
  #curve-bonus  { grid-column: span 12; order: 7; }

  #posmatrix          { grid-column: span 12; }
  .ball { width: 46px; height: 46px; font-size: 1.125rem; }
  .chart-detail { flex-basis: 400px; }
}

/* Respecte le réglage système « moins d'animations ». */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   Variante sombre — même registre imprimé, encre inversée.
   Aucun #hex n'est défini UNIQUEMENT ici : tout jeton existe d'abord sur
   :root nu, sinon un thème se retrouverait sans valeur de repli.
   ═══════════════════════════════════════════════════════════════════ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:   #14120f;
    --paper-2: #1c1a16;
    --paper-3: #23201a;
    --ink:     #f2ece3;
    --ink-2:   #b7aea1;
    --ink-3:   #857d70;
    --rule:    #2f2a22;
    --rule-2:  #443d32;
    --found:   #4ec27e;
    --found-bg:#16301f;
    --warn:    #d9a441;
    --danger:  #e2685f;
  --hasard:  #9eabb8;
    --hasard-bg: #232a31;
    --moins-bg: #3a1c19;
    --survol:  rgba(255, 255, 255, .09);
  }
}
:root[data-theme="dark"] {
  --paper:   #14120f;
  --paper-2: #1c1a16;
  --paper-3: #23201a;
  --ink:     #f2ece3;
  --ink-2:   #b7aea1;
  --ink-3:   #857d70;
  --rule:    #2f2a22;
  --rule-2:  #443d32;
  --found:   #4ec27e;
  --found-bg:#16301f;
  --warn:    #d9a441;
  --danger:  #e2685f;
  --hasard:  #9eabb8;
  --hasard-bg: #232a31;
  --moins-bg: #3a1c19;
  --survol:  rgba(255, 255, 255, .09);
}

/* La boule « sortie » est en encre pleine : sur fond sombre il faut
   l'inverse, sinon elle disparaît dans le papier. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ball.drawn { background: var(--ink); color: var(--paper); border-color: var(--ink); }
  :root:not([data-theme="light"]) .ball.hit,
  :root:not([data-theme="light"]) .tt-ball.hit { color: #0d2416; }
  :root:not([data-theme="light"]) .modebtn.active { background: var(--ink); color: var(--paper); }
}
:root[data-theme="dark"] .ball.hit,
:root[data-theme="dark"] .tt-ball.hit { color: #0d2416; }

/* ═══════════════════════════════════════════════════════════════════
   Composants restés sans style

   La réécriture de cette feuille a perdu les règles de plusieurs blocs
   construits en JavaScript : 71 classes étaient utilisées sans qu'aucune
   règle ne les vise. Les conteneurs retombaient sur `display: block` et
   leur contenu s'empilait verticalement sur toute la hauteur de la page.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Matrice de fiabilité positionnelle ───────────────────────────── */
.scopeheat th, .scopeheat td { padding: 3px 5px; font-size: .6875rem; }
.hsrc {
  text-align: left !important; white-space: nowrap;
  position: sticky; left: 0; z-index: 1;
  background: var(--paper-2); font-weight: 500;
}
.hpos { color: var(--ink-3); font-weight: 500; }
/* Les positions réellement montrées au joueur, distinguées du reste du pool. */
.hpos.indisp { color: var(--ink); font-weight: 700; border-bottom: 2px solid var(--accent); }
.hcell { cursor: pointer; min-width: 26px; }
.hcell.indisp { font-weight: 650; }
.hcell.sel { outline: 2px solid var(--ink); outline-offset: -2px; }

.heat-toggle, .heat-filter {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-bottom: 8px; font-size: .8125rem; color: var(--ink-2);
}
.heat-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  margin-top: 8px; font-size: .75rem; color: var(--ink-2);
}
.lgrad, .gradbar {
  display: inline-block; width: 88px; height: 9px;
  border-radius: 999px; border: 1px solid var(--rule);
}

/* ── Scope : classement complet et liste des numéros ──────────────── */
.scope-h, .side-h {
  font-family: var(--serif); font-size: .9375rem; font-weight: 600;
  margin: 16px 0 8px;
}
.side-h { margin-top: 0; }
/* Ces listes s'affichaient l'une sous l'autre faute de règle : un numéro
   par ligne sur toute la hauteur du pool. */
.side-list { flex-direction: row !important; flex-wrap: wrap; gap: 5px !important; }
.side-n, .scope-n {
  display: inline-flex; align-items: baseline; gap: 2px;
  padding: 4px 7px; border-radius: 7px;
  background: var(--paper-3); border: 1px solid var(--rule);
  font-size: .8125rem; font-variant-numeric: tabular-nums;
}
.side-n small, .scope-n small { color: var(--ink-3); font-size: .625rem; }
.side-n.full { background: color-mix(in srgb, var(--accent) 16%, var(--paper-3)); border-color: var(--accent); font-weight: 650; }
.scope-n.top { background: var(--ink); color: var(--paper); border-color: var(--ink); font-weight: 650; }

/* ── Détail par modèle ────────────────────────────────────────────── */
.model-card { border: 1px solid var(--rule); border-radius: var(--radius); padding: 12px; }
.model-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.mcell {
  width: 20px; height: 20px; padding: 0; text-align: center;
  font-size: .625rem; border: 1px solid var(--rule);
}
.mcell.hit { background: var(--found); color: #fff; }
.mcell.miss { background: var(--paper-3); color: var(--ink-3); }
/* La fenêtre chaude. Personne ne lit quinze colonnes de gauche à droite : on
   regarde ce qui vient de se passer. Autant l'assumer et le rendre lisible,
   plutôt que de laisser l'œil le reconstruire de travers. Le bloc 6 des
   statistiques avancées dit ce que ce mouvement vaut en prédiction : rien. */
.posmatrix th.chaud, .posmatrix td.dans-chaud { background: var(--paper-3); }
.posmatrix td.dans-chaud.hit { background: var(--found); }
.posmatrix th.rot.chaud { color: var(--ink-2); font-weight: 650; }
.posmatrix th.chaud:not(.rot) { color: var(--ink-2); font-weight: 600; white-space: nowrap; }
.mhot {
  text-align: center; font-variant-numeric: tabular-nums; font-weight: 650;
  color: var(--ink-2); background: var(--paper-3);
}
.mhot small { font-weight: 400; color: var(--ink-3); }
.mhot[data-i="2"] { color: var(--warn); }
.mhot[data-i="3"], .mhot[data-i="4"] { color: #fff; background: var(--warn); }
.mhot[data-i="3"] small, .mhot[data-i="4"] small { color: rgba(255,255,255,.75); }

.mcold { text-align: center; font-size: .6875rem; color: var(--ink-2); }
.mcold.overdue { color: var(--warn); font-weight: 650; }
.mnext { text-align: center; font-weight: 650; background: var(--paper-3); }
.tr { margin-left: 3px; color: var(--ink-3); }
.mini {
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-grid; place-items: center; font-size: .6875rem;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  font-variant-numeric: tabular-nums;
}
.duo { display: inline-flex; gap: 3px; }
.spark { width: 100%; height: 30px; fill: none; stroke: var(--accent); stroke-width: 2; }

/* Le sélecteur « un clic par modèle » a disparu au profit du tableau des
   méthodes : ses styles avec lui. Ne reste que le repli mobile, qui s'applique
   maintenant au tableau. */
.voir-tout { width: 100%; margin-top: 8px; }

@media (min-width: 900px) {
  /* Sur grand écran il y a la place : on montre TOUT et le bouton disparaît.
     C'est tout l'objet du tableau, ne rien demander pour comparer. */
  .voir-tout { display: none; }
}

/* ── Raisons d'un choix ───────────────────────────────────────────── */
.reasons-toggle { margin-top: 12px; font-size: .875rem; }
.reasons-toggle summary { cursor: pointer; color: var(--ink-2); }
.reasons { display: flex; flex-direction: column; gap: 5px; margin-top: 8px; }
.reason { font-size: .8125rem; color: var(--ink-2); }
.reason b { color: var(--ink); }

/* ── Suivi des signaux (admin) ────────────────────────────────────── */
.signal-block { border-top: 1px solid var(--rule); padding-top: 14px; margin-top: 14px; }
.signal-block:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.sig-head { font-size: .9375rem; margin-bottom: 4px; }
.sig-expl { font-size: .8125rem; color: var(--ink-2); margin: 0 0 10px; max-width: 78ch; }
.sig-next, .sig-hist { margin-top: 10px; }
.sig-hrow { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; flex-wrap: wrap; }
.sig-hrow .ylbl { margin-bottom: 0; min-width: 92px; }
.zthr { color: var(--ink-3); }

/* ── Étiquettes et états ──────────────────────────────────────────── */
.tag {
  display: inline-block; font-size: .6875rem; padding: 1px 7px;
  border-radius: 999px; border: 1px solid var(--rule-2); color: var(--ink-2);
}
.tag.red { color: var(--danger); border-color: var(--danger); }
.tag.div { color: var(--found); border-color: var(--found); }
.pos { color: var(--found); font-weight: 650; }
.neg { color: var(--danger); }
.follow, .follow-clear { font-size: .8125rem; }
.rot { writing-mode: vertical-rl; text-orientation: mixed; font-size: .625rem; }
.mid { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--rule-2); }
.bar-track { position: relative; }

@media (min-width: 900px) {
  .model-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
}


/* ── Le chat ────────────────────────────────────────────────────────────────
   Un assistant dans le coin de l'écran, sur toutes les vues (04/10). Il était
   une carte du tableau de bord, par crainte qu'une bulle fixe masque les
   numéros sur téléphone : d'où un bouton compact, posé AU-DESSUS de la barre
   des jeux, et une fenêtre qui ne s'ouvre qu'à la demande. */
.chat-flottant {
  position: fixed; z-index: 45; right: 14px;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px) + 12px);
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  pointer-events: none;
}
.chat-flottant > * { pointer-events: auto; }
@media (min-width: 900px) { .chat-flottant { right: 24px; bottom: 24px; } }
.chat-bouton {
  position: relative; width: 60px; height: 60px; padding: 0; border: 0; border-radius: 50%;
  background: var(--paper-2); cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .18), 0 0 0 1px var(--rule);
  transition: transform .15s ease;
}
/* Le grossissement au survol, seulement avec une souris : sur un écran
   tactile, le « survol » reste collé après un appui et décale le bouton. */
@media (hover: hover) { .chat-bouton:hover { transform: scale(1.05); } }
.chat-bouton img { display: block; width: 100%; height: 100%; border-radius: 50%; }
.chat-bouton[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--accent), 0 6px 18px rgba(0, 0, 0, .18); }
/* Une grille pas encore ouverte pour ce jeu et ce tirage. */
.chat-pastille {
  position: absolute; top: 1px; right: 1px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--paper);
}
.chat-pastille[hidden] { display: none; }
.chat-fenetre {
  width: min(380px, calc(100vw - 28px));
  max-height: min(68vh, 620px); overflow: auto; overscroll-behavior: contain;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: 16px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .22);
}
.chat-fenetre[hidden] { display: none; }
.chat-entete {
  position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: 10px;
  padding: 9px 10px 9px 12px; background: var(--paper-2); border-bottom: 1px solid var(--rule);
}
.chat-tete { width: 32px; height: 32px; flex: 0 0 32px; }
.chat-tete svg, .chat-tete img { display: block; width: 100%; height: 100%; }
.chat-nom { flex: 1; font-weight: 650; color: var(--ink); }
.chat-fermer {
  border: 0; background: none; color: var(--ink-2); cursor: pointer;
  font-size: 1.5rem; line-height: 1; padding: 2px 8px; border-radius: 8px;
}
.chat-fermer:hover { background: var(--paper-3); color: var(--ink); }
.chat-corps { padding: 12px 14px 14px; }
.chat-corps p { margin: 0 0 8px; line-height: 1.5; }
.chat-titre { font-weight: 650; font-size: 1.0625rem; color: var(--ink); }
.chat-petit { font-size: .8125rem; color: var(--ink-3); }
.chat-note { font-size: .875rem; color: var(--ink-2); font-style: italic; }
.chat-profils { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 10px; }
.chat-grille { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.chat-plus { margin: 6px 0 8px; }
.chat-plus summary { cursor: pointer; font-size: .875rem; color: var(--accent); font-weight: 600; }
.chat-plus[open] summary { margin-bottom: 6px; }
.chat-raisons { list-style: none; margin: 0; padding: 0; }
.chat-raisons li { display: flex; gap: 8px; align-items: baseline; padding: 5px 0;
  border-top: 1px solid var(--rule); font-size: .875rem; line-height: 1.45; }
.chat-raisons li .cx-n { flex: 0 0 auto; }
.chat-corps .cta button { width: 100%; }


/* ── Mon abonnement ─────────────────────────────────────────────────────────── */
.pied-liens { text-align: center; font-size: .8125rem; margin: 6px 16px 4px; }
/* La dernière ligne garde la marge qui la sort de sous les boutons flottants. */
.pied-mineurs { color: var(--ink-3); margin-bottom: 90px; }
.pied-liens a { color: var(--ink-3); }
.abo-dialog {
  /* Centrage explicite : une remise à zéro des marges plus haut dans la
     feuille décalait la fenêtre hors de l'écran sur téléphone. */
  position: fixed; inset: 0; margin: auto; height: fit-content;
  border: 1px solid var(--rule-2); border-radius: 14px; padding: 20px 22px;
  background: var(--paper); color: var(--ink); max-width: min(26rem, calc(100vw - 32px));
}
.abo-dialog::backdrop { background: rgb(0 0 0 / .45); }
.abo-dialog h2 { margin: 0 0 10px; font-size: 1.125rem; }
.abo-dialog p { margin: 0 0 10px; line-height: 1.5; }
.abo-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.abo-actions button:not(.modebtn) {
  font: inherit; font-weight: 600; padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--accent); background: var(--accent); color: #fff; cursor: pointer;
}
.abo-actions button.danger { background: #b3261e; border-color: #b3261e; }
.abo-actions button:disabled { opacity: .6; cursor: wait; }
.abo-erreur { color: #b3261e; }
.abo-case { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 12px;
  font-size: .9375rem; line-height: 1.45; color: var(--ink-2); cursor: pointer; }
.abo-case input { width: 18px; height: 18px; margin: 2px 0 0; flex: none; accent-color: var(--accent); }
.abo-email { font-size: .8125rem; color: var(--ink-3); margin-top: -4px; word-break: break-all; }
.compte-abonne { border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* ── Panier concentré ─────────────────────────────────────────────── */
/* Les signaux se cochent comme des filtres : un appui, le % de chaque case
   suit. Puce pleine = signal compté. */
.puces { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 12px; }
.puce {
  background: var(--paper-2); color: var(--ink-3);
  border: 1px dashed var(--rule-2); border-radius: 999px;
  font: inherit; font-size: .8125rem; padding: 5px 11px; cursor: pointer;
}
.puce.on { background: var(--ink); color: var(--paper); border: 1px solid var(--ink); font-weight: 600; }
/* Les cases deviennent des boutons (on touche pour lire le détail) : on
   efface l'habillage par défaut du navigateur. */
button.bn { font: inherit; color: inherit; cursor: pointer; }
.bn.choisi { outline: 2px solid var(--ink); outline-offset: 1px; }
.conc-aide { margin: 12px 0 0; font-size: .8125rem; color: var(--ink-3); }
.conc-detail {
  margin-top: 12px; padding: 10px 12px; border: 1px solid var(--rule);
  border-radius: 10px; background: var(--paper-2); font-size: .8125rem;
}
.conc-tete { display: flex; justify-content: space-between; font-size: 1rem; margin-bottom: 4px; }
.conc-ligne {
  display: grid; grid-template-columns: 7.5em 1fr 54px; gap: 8px; align-items: center;
  padding: 5px 0; border-top: 1px solid var(--rule);
}
.conc-ligne.off { opacity: .45; }
.conc-val { color: var(--ink-2); }
.conc-barre { height: 5px; border-radius: 3px; background: var(--rule); overflow: hidden; }
.conc-barre i { display: block; height: 100%; background: var(--accent); }
.conc-mesure { margin: 12px 0 0; font-size: .8125rem; color: var(--ink-2); }
.conc-bonus { margin: 0 0 8px; font-size: .75rem; color: var(--ink-2); }

/* ── Scope admin : ce qui échoue ─────────────────────────────────── */
.ec-verdict { margin: 10px 0 4px; font-size: .875rem; color: var(--ink); }
.ec-num { border-top: 1px solid var(--rule); padding: 6px 0; font-size: .8125rem; }
.ec-num summary { cursor: pointer; display: flex; gap: 10px; align-items: baseline; color: var(--ink-2); }
.ec-n { flex: 0 0 2.2em; height: 2.2em; border-radius: 50%; display: grid; place-items: center;
  background: var(--paper-3); border: 1px solid var(--rule); color: var(--ink); font-weight: 700; }
.ec-ex { margin: 6px 0 2px 2.6em; padding: 0; list-style: none; }
.ec-ex li { padding: 3px 0; color: var(--ink-2); }
.ec-ex small { display: block; color: var(--ink-3); }
.ec-t td small { display: block; white-space: nowrap; }


/* ── Code couleur : gris = comme le hasard, vert = au-dessus, rouge = en dessous ── */
.ton { display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: .75rem; font-weight: 650; white-space: nowrap; vertical-align: 1px; }
.ton-hasard { color: var(--hasard); background: var(--hasard-bg); }
.ton-plus   { color: var(--plus);   background: var(--plus-bg); }
.ton-moins  { color: var(--moins);  background: var(--moins-bg); }
.t-hasard { color: var(--hasard); }
.t-plus   { color: var(--plus); font-weight: 650; }
.t-moins  { color: var(--moins); font-weight: 650; }
.bar-fill.f-hasard, .zfill.f-hasard { background: var(--hasard); }
.bar-fill.f-plus,   .zfill.f-plus   { background: var(--plus); }
.bar-fill.f-moins,  .zfill.f-moins  { background: var(--moins); }
.verdict { margin: 12px 0 0; font-size: .875rem; color: var(--ink-2); }
.verdict .ton { margin-right: 6px; }
.honesty .legende { display: flex; flex-wrap: wrap; gap: 6px 10px; margin-top: 8px; }
h2.view-lead.separee { font-size: 1.125rem; margin: 18px 0 0; color: var(--ink-2); }
.me-stat { margin: 4px 0 0; font-size: .8125rem; color: var(--ink-2); }
.me-stat small { color: var(--ink-3); margin-left: 4px; }

/* ── Ma grille ───────────────────────────────────────────────────────────────
   Le miroir du chat, en bas à gauche. Vert, rouge et orange y sont les choix
   du joueur (je joue, j'écarte, pas sûr), pas le code « hasard » : c'est son
   brouillon, et ce sont les couleurs qu'il a demandées. */
.grille-flottante {
  position: fixed; z-index: 45; left: 14px;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px) + 12px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  pointer-events: none;
}
.grille-flottante > * { pointer-events: auto; }
@media (min-width: 900px) { .grille-flottante { left: 24px; bottom: 24px; } }
.grille-bouton {
  position: relative; display: flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 52px; height: 52px; padding: 0 14px; border: 0; border-radius: 999px;
  background: var(--paper-2); color: var(--ink); cursor: pointer; font: inherit; font-weight: 650;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .16), 0 0 0 1px var(--rule);
}
.grille-bouton[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--ink), 0 6px 18px rgba(0, 0, 0, .16); }
.grille-compte:empty { display: none; }
.grille-compte { color: var(--found); font-size: .9375rem; }
.grille-fenetre {
  width: min(380px, calc(100vw - 28px));
  max-height: min(64vh, 600px); overflow: auto; overscroll-behavior: contain;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: 16px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, .22);
}
.grille-fenetre[hidden] { display: none; }
.grille-fenetre .chat-nom small { color: var(--ink-3); font-weight: 500; }
.g-onglets { display: flex; gap: 4px; }
.g-onglet {
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--rule-2);
  background: var(--paper-2); color: var(--ink-2); font: inherit; font-size: .8125rem; cursor: pointer;
}
.g-onglet.actif { background: var(--ink); color: var(--paper); border-color: var(--ink); font-weight: 650; }
.g-corps { padding: 12px 12px 14px; }
.g-grille { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 4px; }
.g-titre { margin: 12px 0 6px; font-size: .8125rem; font-weight: 650; color: var(--ink-2); }
.g-case {
  aspect-ratio: 1; min-width: 0; padding: 0; border-radius: 50%;
  border: 1px solid var(--rule-2); background: var(--paper); color: var(--ink);
  font: inherit; font-size: .8125rem; font-weight: 600; cursor: pointer;
  display: inline-grid; place-items: center;
}
.g-case.g-oui  { background: var(--found); border-color: var(--found); color: #fff; }
.g-case.g-non  { background: var(--moins-bg); border-color: var(--danger); color: var(--danger);
  text-decoration: line-through; text-decoration-thickness: 2px; }
.g-case.g-peut { background: #f3a33a; border-color: #d98a1f; color: #2b1a04; }
.g-legende { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 12px 0 0;
  font-size: .75rem; color: var(--ink-3); }
.g-legende .g-case { width: 18px; height: 18px; font-size: .625rem; cursor: default; margin-left: 4px; }
.g-alerte { margin: 8px 0 0; font-size: .8125rem; color: var(--warn); font-weight: 600; }
.g-pied { display: flex; justify-content: space-between; align-items: center; gap: 8px;
  margin-top: 10px; font-size: .8125rem; color: var(--ink-2); }

/* ── Tableau de bord en tuiles ───────────────────────────────────────────── */
.tuile-masquee { display: none !important; }
.perso { order: 0; grid-column: 1 / -1; }
.perso:empty { display: none; }
.perso-bouton { float: right; }
.perso-panneau {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius-lg);
  padding: 12px 14px;
}
.perso-tete { display: flex; justify-content: space-between; align-items: center; gap: 8px;
  flex-wrap: wrap; margin-bottom: 8px; }
.perso-tete span { display: flex; gap: 6px; }
.perso-liste { list-style: none; margin: 0; padding: 0; }
.perso-ligne { display: flex; align-items: center; gap: 8px; padding: 7px 4px;
  border-top: 1px solid var(--rule); background: var(--paper-2); }
.perso-ligne.glisse { opacity: .4; }
.perso-ligne.cachee .perso-nom { color: var(--ink-3); text-decoration: line-through; }
.perso-poignee { cursor: grab; color: var(--ink-3); padding: 0 4px; user-select: none; }
.perso-nom { flex: 1; font-size: .9375rem; }
.perso-fl, .perso-oeil {
  border: 1px solid var(--rule-2); background: var(--paper); color: var(--ink-2);
  border-radius: 8px; font: inherit; font-size: .8125rem; cursor: pointer; padding: 3px 9px;
}
.perso-fl[disabled] { opacity: .3; cursor: default; }
.perso-oeil { min-width: 70px; }
@media (hover: none) { .perso-poignee { display: none; } }

/* ── Les constats du moment ──────────────────────────────────────────────── */
.tuile-vide { display: none !important; }
.cs-tete { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.cs-base { font-size: .75rem; color: var(--ink-3); white-space: nowrap; }
.cs-l { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center;
  padding: 7px 0; border-top: 1px solid var(--rule); }
.cs-l:first-of-type { border-top: 0; }
.cs-n { display: flex; flex-wrap: wrap; gap: 4px; max-width: 9.5rem; }
.cs-b {
  width: 30px; height: 30px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px solid var(--rule-2); background: var(--paper-3); color: var(--ink);
  font: inherit; font-size: .8125rem; font-weight: 650;
}
.cs-b.g-oui  { background: var(--found); border-color: var(--found); color: #fff; }
.cs-b.g-non  { background: var(--moins-bg); border-color: var(--danger); color: var(--danger);
  text-decoration: line-through; text-decoration-thickness: 2px; }
.cs-b.g-peut { background: #f3a33a; border-color: #d98a1f; color: #2b1a04; }
.cs-t { font-size: .875rem; color: var(--ink-2); line-height: 1.35; }
.cs-t small { display: block; color: var(--ink-3); font-size: .75rem; }
.cs-v { font-size: .9375rem; font-weight: 650; white-space: nowrap; text-align: right; }
.cs-v.t-hasard { color: var(--hasard); }
@media (min-width: 900px) {
  /* Sur ordinateur, les constats vont par deux : des listes courtes en
     pleine largeur laisseraient la moitié droite vide. */
  .constats.tuile { grid-column: span 6; }
}
/* Plus de deux numéros sur une ligne (un niveau d'accord) : ils prennent
   toute la largeur, et le texte passe dessous au lieu d'être écrasé. */
.cs-l.cs-multi .cs-n { grid-column: 1 / -1; max-width: none; }
.perso-barre { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.fen-choix { display: flex; gap: 4px; flex-wrap: wrap; }
.perso-barre .perso-bouton { float: none; }
.cs-portee { margin: -2px 0 6px; font-size: .75rem; color: var(--ink-3); }

/* ── Admin : comptes ─────────────────────────────────────────────────────── */
.cpt-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 12px 0; font-size: .875rem; }
.cpt-form input[type="email"], .cpt-q, .cpt-act input {
  font: inherit; font-size: .875rem; padding: 6px 9px; border-radius: 8px;
  border: 1px solid var(--rule-2); background: var(--paper); color: var(--ink);
}
.cpt-q { width: 100%; margin: 4px 0 8px; }
.cpt-l { border-top: 1px solid var(--rule); padding: 8px 0; }
.cpt-tete { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; }
.cpt-tete small { color: var(--ink-3); }
.cpt-gerer summary { cursor: pointer; font-size: .8125rem; color: var(--accent); margin-top: 4px; }
.cpt-act { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; font-size: .8125rem; }
.cpt-act span { min-width: 6.5em; color: var(--ink-2); }
.modebtn.danger { color: var(--danger); border-color: var(--danger); }

/* ── Admin : la bible en formulaire ──────────────────────────────────────── */
.bible-onglets { display: flex; flex-wrap: wrap; gap: 4px; margin: 10px 0 6px; }
.bf-onglet-ko { border-color: var(--danger) !important; color: var(--danger) !important; }
.bf-h { font-size: 1rem; margin: 18px 0 6px; color: var(--ink-2); }
h4.bf-h { font-size: .875rem; margin: 12px 0 4px; }
.bf-l { display: grid; grid-template-columns: minmax(9rem, 14rem) 1fr; gap: 6px 12px; align-items: center;
  padding: 6px 0; border-top: 1px solid var(--rule); }
.bf-lib { font-size: .875rem; color: var(--ink-2); }
.bf-saisie { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: .875rem; }
.bf-saisie input[type="text"], .bf-saisie input[type="url"], .bf-saisie input[type="number"],
.bf-saisie input[type="date"], .bf-saisie input[type="time"], #bible-message {
  font: inherit; font-size: .875rem; padding: 5px 8px; border-radius: 8px;
  border: 1px solid var(--rule-2); background: var(--paper); color: var(--ink); min-width: 0;
}
.bf-saisie input[type="number"] { width: 7.5rem; }
.bf-saisie input[type="url"], .bf-saisie input[type="text"] { flex: 1 1 14rem; }
.bf-jours { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.bf-jours label { display: inline-flex; gap: 3px; align-items: center; }
.bf-saisie small { color: var(--ink-3); }
.bf-extras { flex-direction: column; align-items: stretch; }
.bf-extra { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.bf-ko .bf-lib, .bf-extra.bf-ko input { color: var(--danger); border-color: var(--danger); }
.bf-ko input { border-color: var(--danger) !important; }
.bf-err { flex-basis: 100%; color: var(--danger); font-size: .75rem; }
.bf-gains { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); column-gap: 16px; }
.bf-gains .bf-l { grid-template-columns: 4rem 1fr; }
.bible-pied { position: sticky; bottom: 0; background: var(--paper-2); border-top: 1px solid var(--rule);
  padding: 10px 0 4px; margin-top: 14px; }
.bible-diff { font-size: .8125rem; color: var(--ink-2); max-height: 9rem; overflow: auto; }
.bible-diff ul { margin: 4px 0 8px; padding-left: 1.2em; }
.bible-diff s { color: var(--ink-3); }
#bible-message { width: 100%; margin: 4px 0 8px; }
.bible-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.bible-actions button[disabled] { opacity: .45; cursor: default; }
@media (max-width: 600px) { .bf-l { grid-template-columns: 1fr; } }

/* ── Téléphones pliants dépliés et petites tablettes (700-899 px) ─────────
   Un Galaxy Z Fold déplié fait ~830 × 750 px CSS : presque carré, trop étroit
   pour la mise en page ordinateur (barre des jeux en haut, 12 colonnes), trop
   large pour étirer chaque tuile sur toute la largeur. Les constats, des
   listes courtes, y vont par deux ; le reste garde la pleine largeur. */
@media (min-width: 700px) and (max-width: 899px) {
  #view-dash { grid-template-columns: 1fr 1fr; }
  #view-dash > .tuile, #view-dash > .perso, #view-dash > #admin-scope { grid-column: 1 / -1; }
  #view-dash > .constats.tuile { grid-column: auto; }
}

/* ── Scope admin pliable ─────────────────────────────────────────────────── */
.scope-tout > summary { cursor: pointer; font-family: var(--serif); font-size: 1.25rem; font-weight: 600; }
.scope-pli { border-top: 1px solid var(--rule); padding: 4px 0; }
.scope-pli > summary { cursor: pointer; padding: 8px 0; font-weight: 650; color: var(--ink-2); }
.scope-pli[open] > summary { color: var(--ink); }
.scope-pli > summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.pli-titre { font-weight: 650; }
.pli-resume { font-weight: 400; font-size: .8125rem; color: var(--ink-2); }
.pli-resume .ton { margin-right: 2px; }
.pli-raccourcis { display: flex; flex-wrap: wrap; gap: 4px; margin: 10px 0 6px; }

/* ── Grand écran : 2 ou 3 tuiles par ligne ──────────────────────────────── */
.col-choix { display: none; gap: 4px; }
@media (min-width: 1200px) {
  .col-choix { display: flex; }
  body[data-colonnes="3"] #view-dash > .constats.tuile { grid-column: span 4; }
}

/* ── Pliants dépliés et petites tablettes (700-899 px) : la barre des jeux
   en HAUT ─────────────────────────────────────────────────────────────────
   Sur le Fold déplié, Android affiche une barre des tâches en bas de l'écran
   qui grandit et rétrécit au défilement : la barre des jeux, fixée en bas,
   s'y faisait recouvrir puis réapparaissait ailleurs (Chrome et Vivaldi, 05/10).
   Un recalage par l'API VisualViewport a empiré les choses. On retire donc la
   cause : à cette largeur, plus rien n'est fixé contre le bas sauf les deux
   boutons ronds ; les jeux passent dans l'en-tête, sur une seconde ligne. */
@media (min-width: 700px) and (max-width: 899px) {
  body { padding-bottom: 0; }
  .topbar { flex-wrap: wrap; row-gap: 8px; }
  .games {
    position: static; order: 3; flex: 1 1 100%; height: auto; padding: 0;
    border: 0; background: none; justify-content: center; gap: 4px;
  }
  .games button {
    flex: 0 0 auto; font-size: .875rem; padding: 7px 13px;
    border: 1px solid transparent; border-radius: 999px;
  }
  .games button.active { color: #fff; background: var(--accent); border-color: var(--accent); }
  .chat-flottant, .grille-flottante { bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
}
