/* Fairline - feuille unique.
 *
 * Trois formats, une seule grille. Le rail est une colonne au-dela de
 * 1024 px et un tiroir en deca ; la barre du bas n'existe que la ou le rail
 * n'est plus visible. Aucun ecran n'a de mise en page a lui : ce qui change
 * d'un format a l'autre est declare ici, une fois, en bas de fichier.
 *
 * Deux regles tenues partout :
 *   - un blason d'equipe ne disparait sur AUCUN format. Il retrecit, il ne
 *     s'efface pas : c'est le seul reperage immediat dans une liste de
 *     rencontres, et le premier a sauter quand on masque "l'accessoire" ;
 *   - une rencontre se lit sur deux lignes des que la largeur manque
 *     (recoit / visiteur empiles, scores alignes a droite) plutot que de
 *     tronquer deux noms pour tenir sur une seule.
 */

/* --- 1. Jetons -------------------------------------------------------- */
:root {
  --ground:#ECEFEE; --surface:#FFFFFF; --surface-2:#E9EDEC; --surface-3:#D7DEDC;
  --sunken:#F4F6F5;
  --line:#C7D1CE; --line-soft:#E0E6E4;
  --ink:#111B19; --ink-2:#43524E; --ink-3:#78857F;
  --accent:#9C6B24; --accent-ink:#7C5318; --accent-soft:#F3E7D3;
  --edge:#2C6B4E; --edge-soft:#DCEBE2;
  --warn:#96671A; --warn-soft:#F4E7CE;
  --crit:#94382C; --crit-soft:#F3DED9;
  --market:#3A5A78; --market-soft:#DEE7EF;
  --btn-ink:#FFFFFF;
  /* --ok reste le nom historique de --edge : les pastilles ecrites avant la
     maquette continuent de fonctionner sans etre reecrites. */
  --ok:var(--edge); --ok-soft:var(--edge-soft);
  /* Fond glisse sous les blasons : les PNG du fournisseur sont transparents
     et dessines pour du papier blanc. */
  --plaque:#FFFFFF;
  --ombre-1:0 1px 2px rgba(16,27,25,.05);
  --ombre-2:0 10px 30px rgba(16,27,25,.16);

  --mono:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;
  --sans:"IBM Plex Sans",-apple-system,"Segoe UI",Roboto,sans-serif;

  --r1:4px; --r2:7px; --r3:12px;
  --haut:52px;              /* hauteur de la barre du haut */
  --rail:238px;             /* largeur du rail en colonne */
  --blason:20px;            /* cote d'un blason de liste */

  /* Densite. Trois reglages parce que trois usages : lire un tableau au
     calme, travailler, ou surveiller le direct sur un ecran plein. */
  --rowpy:10px; --rowpx:12px; --fs-row:13.5px; --cardgap:16px; --ligne-h:26px;
}
:root[data-densite="confort"]  { --rowpy:13px; --rowpx:15px; --fs-row:14.5px; --cardgap:20px; --ligne-h:30px; }
:root[data-densite="terminal"] { --rowpy:4px;  --rowpx:9px;  --fs-row:12.5px; --cardgap:10px; --ligne-h:22px; --blason:17px; }

/* Le theme suit le systeme par defaut, et se force par data-theme. Les deux
   blocs disent la meme chose : le premier pour « systeme = sombre », le
   second pour un choix explicite. */
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) {
    --ground:#0D1211; --surface:#151D1B; --surface-2:#131A19; --surface-3:#242E2C;
    --sunken:#111817;
    --line:#2A3633; --line-soft:#212B29;
    --ink:#E8EEEC; --ink-2:#A3B1AD; --ink-3:#76837E;
    --accent:#D3A05B; --accent-ink:#E6BC81; --accent-soft:#33291A;
    --edge:#6FBF93; --edge-soft:#1B2E25;
    --warn:#D9A94F; --warn-soft:#302716;
    --crit:#DE8A7B; --crit-soft:#331F1B;
    --market:#87ACCD; --market-soft:#17222D;
    --btn-ink:#12191A;
    --plaque:#F1F4F3;
    --ombre-1:0 1px 2px rgba(0,0,0,.35);
    --ombre-2:0 12px 34px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"] {
  --ground:#0D1211; --surface:#151D1B; --surface-2:#131A19; --surface-3:#242E2C;
  --sunken:#111817;
  --line:#2A3633; --line-soft:#212B29;
  --ink:#E8EEEC; --ink-2:#A3B1AD; --ink-3:#76837E;
  --accent:#D3A05B; --accent-ink:#E6BC81; --accent-soft:#33291A;
  --edge:#6FBF93; --edge-soft:#1B2E25;
  --warn:#D9A94F; --warn-soft:#302716;
  --crit:#DE8A7B; --crit-soft:#331F1B;
  --market:#87ACCD; --market-soft:#17222D;
  --btn-ink:#12191A;
  --plaque:#F1F4F3;
  --ombre-1:0 1px 2px rgba(0,0,0,.35);
  --ombre-2:0 12px 34px rgba(0,0,0,.55);
}

/* --- 2. Socle --------------------------------------------------------- */
* { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
body { margin:0; background:var(--ground); color:var(--ink);
       font-family:var(--sans); font-size:15px; line-height:1.55;
       /* Rien ne doit pouvoir pousser la page de cote sur telephone.
          `clip` et non `hidden` : `hidden` ferait du <body> un conteneur de
          defilement, et la barre du haut cesserait d'etre collante. Un
          navigateur qui ignore `clip` perd le rognage, pas la barre. */
       overflow-x:clip; }
body.rail-ouvert { overflow:hidden; }
a { color:var(--accent-ink); }
img, svg { max-width:100%; }
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; white-space:nowrap;
      clip:rect(0 0 0 0); clip-path:inset(50%); }
.saut { position:absolute; left:-9999px; }
.saut:focus { left:8px; top:8px; z-index:60; padding:8px 12px; border-radius:var(--r1);
              background:var(--surface); color:var(--ink); border:1px solid var(--accent); }
.sprite { position:absolute; width:0; height:0; overflow:hidden; }

/* --- 3. Barre du haut -------------------------------------------------
   Presente sur tous les formats. Elle porte le repere du lieu (marque +
   ecran actif) et, a droite, le seul chiffre qui merite d'etre sous les
   yeux en permanence : le nombre de matchs en direct. */
.topbar { position:sticky; top:0; z-index:30; display:flex; align-items:center; gap:12px;
          height:var(--haut); padding:0 18px; background:var(--surface);
          border-bottom:1px solid var(--line); box-shadow:var(--ombre-1); }
.topbar svg, .tabbar svg, .rail-tete svg, .rail .ico {
          width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.6;
          stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
.marque { display:inline-flex; align-items:baseline; gap:5px; flex:0 0 auto;
          font-size:14.5px; font-weight:700; letter-spacing:-.01em; color:var(--ink);
          text-decoration:none; white-space:nowrap; }
.marque span { color:var(--ink-3); font-weight:500; }
/* La marque : le trait (le marche), la courbe (le modele), le point ou ils se croisent. */
.marque { align-items:center; gap:9px; }
.marque .marque-nom { color:var(--ink); font:600 13px var(--mono); letter-spacing:.2em; text-transform:uppercase; }
/* « .topbar svg » impose 20 x 20 aux icones : la marque, plus large que haute, reprend sa taille. */
/* Plus bas dans la feuille, « .marque » est aussi un badge de statut (display:inline-block) :
   la marque de la barre du haut se nomme donc par son lien, pas seulement par sa classe. */
a.marque { display:inline-flex; align-items:center; flex-wrap:nowrap; margin-left:0; vertical-align:baseline; }
a.marque .logo-marque, .topbar a.marque .logo-marque { width:34px; height:20px; stroke:none; flex:0 0 auto; overflow:visible; }
a.marque .logo-trait, a.marque .logo-courbe { stroke-width:20; }
.logo-marque { display:block; height:auto; flex:0 0 auto; overflow:visible; }
.logo-trait, .logo-courbe { fill:none; stroke-width:13; stroke-linecap:round; }
.logo-trait { stroke:var(--ink); } .logo-courbe { stroke:var(--accent); }
.logo-trou { fill:var(--logo-fond, var(--surface)); } .logo-point { fill:var(--edge); }
.connexion-marque { display:flex; flex-direction:column; align-items:center; gap:14px; margin-bottom:6px; text-align:center; }
.connexion-marque .logo-marque { width:96px; height:auto; }
.connexion-marque .marque-nom { margin:0; font:600 22px var(--mono); letter-spacing:.34em; text-transform:uppercase; padding-left:.34em; }
.fil { font-size:13px;
       color:var(--ink-3); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
       min-width:0; }
.fil::before { content:"/"; margin-right:9px; color:var(--line); }
.outils { margin-left:auto; display:flex; align-items:center; gap:10px;
          flex:0 0 auto; min-width:0; }
.jauge { display:inline-flex; align-items:center; gap:7px; white-space:nowrap;
         font-size:12.5px; font-weight:500; text-decoration:none; color:var(--ink-3);
         border:1px solid var(--line); border-radius:999px; padding:4px 12px; }
.jauge .point { width:6px; height:6px; border-radius:50%; background:var(--ink-3); flex:0 0 auto; }
.jauge.vif { color:var(--crit); border-color:var(--crit-soft); background:var(--crit-soft); }
.jauge.vif .point { background:var(--crit); animation:pouls 2.4s ease-in-out infinite; }
@keyframes pouls { 50% { opacity:.25; } }
@media (prefers-reduced-motion:reduce) { .jauge.vif .point { animation:none; } }
.burger, .tabbar button, .rail-tete .ferme {
          background:none; border:0; padding:0; font:inherit; color:inherit; cursor:pointer; }
.burger, .rail-tete, .voile, .tabbar { display:none; }

/* Reglage d'apparence : densite et theme, deux boutons segmentes. */
.reglage { display:inline-flex; border:1px solid var(--line); border-radius:var(--r1);
           overflow:hidden; background:var(--surface); }
.reglage button { font-family:var(--sans); font-size:12px;
                  padding:5px 10px; border:0; background:none; color:var(--ink-3);
                  cursor:pointer; white-space:nowrap; }
.reglage button + button { border-left:1px solid var(--line); }
.reglage button[aria-pressed="true"] { background:var(--surface-3); color:var(--ink);
                                       font-weight:600; }
.qui { font-size:12.5px; color:var(--ink-3); white-space:nowrap; }
.qui a { margin-left:6px; }

/* --- 4. Coque et rail -------------------------------------------------- */
.shell { display:grid; grid-template-columns:var(--rail) minmax(0,1fr);
         min-height:calc(100vh - var(--haut)); }
.rail { background:var(--surface-2); border-right:1px solid var(--line);
        padding:16px 0 24px; position:sticky; top:var(--haut); align-self:start;
        max-height:calc(100vh - var(--haut)); overflow-y:auto;
        overscroll-behavior:contain; }
.rail a { display:flex; align-items:center; gap:10px; padding:7px 16px;
          color:var(--ink-2); text-decoration:none; border-left:2px solid transparent;
          font-size:13.5px; }
.rail a .lib { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
               white-space:nowrap; }
.rail a .ico { color:var(--ink-3); }
.rail a:hover { background:var(--surface-3); color:var(--ink); }
.rail a.on { color:var(--ink); font-weight:600; border-left-color:var(--accent);
             background:var(--surface-3); }
.rail a.on .ico { color:var(--accent-ink); }
.rail .count { font-family:var(--mono); font-size:11px; font-variant-numeric:tabular-nums;
               color:var(--ink-3); background:var(--surface); border:1px solid var(--line);
               border-radius:999px; padding:0 7px; line-height:17px; flex:0 0 auto; }
.rail a.on .count { border-color:var(--accent-soft); }
.rail-label { font-size:11.5px; font-weight:600; color:var(--ink-3); padding:14px 16px 6px;
              margin:0; }
/* En colonne, le premier intitule n'a pas a doubler le rembourrage du
   rail : celui-ci le porte deja. */
.rail > .rail-label:first-of-type { padding-top:0; }
.rail-sep { height:1px; background:var(--line); margin:12px 16px; border:0; }
/* Pied du rail : apparence et session. Un choix fait une fois n'a pas sa
   place dans la barre du haut, sous les yeux en permanence. */
.rail-pied { display:block; padding:14px 16px 0; margin-top:14px;
             border-top:1px solid var(--line); }
.rail .rail-label-pied { padding:0 0 2px; }
.rail-pied .reglage { display:flex; width:100%; margin-top:8px; }
.rail-pied .reglage button { flex:1; padding:6px 4px; }
.rail-pied .qui { display:flex; justify-content:space-between; gap:8px; margin-top:12px;
                  overflow:hidden; text-overflow:ellipsis; }

main { padding:24px 28px 64px; min-width:0; }
h1 { font-size:23px; font-weight:600; margin:0 0 4px; letter-spacing:-.01em;
     display:flex; align-items:center; flex-wrap:wrap; gap:10px; }
h1 .blason { margin-right:0; }
h3 { font-size:15px; font-weight:600; margin:0 0 6px; }
.sub { font-size:13.5px; line-height:1.5; color:var(--ink-3); margin:0 0 18px; max-width:78ch; }

/* --- 5. Tableaux ------------------------------------------------------- */
.tscroll { overflow-x:auto; -webkit-overflow-scrolling:touch; }
table { width:100%; border-collapse:collapse; font-size:var(--fs-row); }
th { font-size:11.5px;
     color:var(--ink-3); font-weight:600; text-align:left;
     padding:0 var(--rowpx) 7px;
     border-bottom:1px solid var(--line); white-space:nowrap; }
td { padding:var(--rowpy) var(--rowpx); border-bottom:1px solid var(--line-soft);
     vertical-align:middle; }
tbody tr:hover td { background:var(--sunken); }
.num { font-family:var(--mono); font-variant-numeric:tabular-nums; }
.when { font-family:var(--mono); font-size:12.5px; color:var(--ink-2); white-space:nowrap; }
.pos { color:var(--edge); } .neg { color:var(--crit); }
.mieux { color:var(--edge); font-weight:600; }
.alerte { color:var(--warn); }

/* --- 6. Blasons -------------------------------------------------------
   Priorite absolue : un blason ne se masque sur aucun format. Il ne
   retrecit pas non plus sous la pression d'un nom long - `flex:0 0 auto`
   et `min-width` le protegent des voisins qui se disputent la place. */
.blason { display:inline-block; flex:0 0 auto;
          width:var(--blason); height:var(--blason); min-width:var(--blason);
          object-fit:contain; vertical-align:middle; margin-right:7px;
          background:var(--plaque); border-radius:3px; padding:1px;
          box-shadow:inset 0 0 0 1px var(--line-soft); }
.blason.grand { --blason:46px; margin-right:12px; border-radius:6px; padding:3px; }
/* La place tenue quand l'equipe n'a pas d'ecusson : invisible, mais elle
   garde les noms alignes d'une ligne a l'autre. */
.blason-vide { background:none; box-shadow:none; }
/* En contexte flex, l'ecart vient du `gap` du conteneur : la marge ferait double. */
.camp .blason, .duo .blason { margin-right:0; }

/* --- 7. Rencontres ----------------------------------------------------
   Le gabarit commun aux listes de matchs (liste, direct). Trois colonnes
   sur grand ecran - recoit / score / visiteur - et deux lignes des que la
   largeur manque : le score glisse alors dans une colonne a droite, un
   chiffre par camp, en face du nom auquel il appartient. */
.matchs { list-style:none; margin:0; padding:0;
          border:1px solid var(--line); border-radius:var(--r2);
          background:var(--surface); overflow:hidden; box-shadow:var(--ombre-1); }
.matchs > li { position:relative; padding:10px 14px;
               border-bottom:1px solid var(--line-soft); }
.matchs > li:last-child { border-bottom:0; }
.matchs > li:hover { background:var(--sunken); }

/* Toute la ligne ouvre la fiche. Le detail s'atteignait avant par un petit
   lien decale sous la rencontre, qu'il fallait viser ; la cible est
   desormais la carte entiere. Le lien est une couche transparente posee
   dessus : deux ancres imbriquees seraient du HTML invalide, cette
   superposition ne l'est pas, et les liens d'equipe repassent au-dessus
   d'elle pour garder leur propre destination. */
.matchs > li > .ouvrir { position:absolute; inset:0; z-index:0;
                         border-radius:var(--r1); }
.matchs > li > .ouvrir:focus-visible { outline:2px solid var(--accent);
                                       outline-offset:-3px; }
.matchs > li a:not(.ouvrir) { position:relative; z-index:1; }
.chevron { flex:0 0 auto; width:16px; height:16px; color:var(--ink-3);
           transition:transform .12s ease, color .12s ease; }
.matchs > li:hover .chevron { color:var(--accent-ink); transform:translateX(2px); }

.ligne { display:flex; align-items:center; gap:20px; }
.ligne .rencontre { flex:1; min-width:0; }
.rencontre { display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
             align-items:center; gap:12px; }
.camp { display:flex; align-items:center; gap:8px; min-width:0;
        min-height:var(--ligne-h); }
.camp.visiteur { justify-content:flex-end; }
.camp .nom, .camp a { min-width:0; overflow:hidden; text-overflow:ellipsis;
                      white-space:nowrap; color:var(--ink); text-decoration:none;
                      font-size:14px; }
.camp a:hover { color:var(--accent-ink); text-decoration:underline; }
.score { display:inline-flex; align-items:center; justify-content:center; gap:7px;
         font-family:var(--mono); font-weight:600; font-variant-numeric:tabular-nums;
         background:var(--surface-3); color:var(--ink); text-decoration:none;
         border-radius:var(--r1); padding:2px 10px; white-space:nowrap; }
.score .sep { font-style:normal; color:var(--ink-3); font-weight:400; }
a.score:hover { background:var(--accent-soft); color:var(--accent-ink); }
/* L'entete de la rencontre : quand, dans quel etat, dans quelle ligue.
   Au-DESSUS du duel et non plus dessous -- on lit d'abord de quoi il
   s'agit, ensuite qui joue. */
.meta { margin:0 0 7px; font-size:12px; color:var(--ink-3);
        display:flex; flex-wrap:wrap; gap:8px; align-items:center;
        min-height:var(--ligne-h); }
.meta .when { font-size:11.5px; }
.meta .ligue-nom { min-width:0; overflow:hidden; text-overflow:ellipsis;
                   white-space:nowrap; }

/* Les trois cotes 1/N/2 d'une rencontre en direct : a droite sur grand
   ecran, sur toute la largeur quand la rencontre passe sur deux lignes. */
.cotes { flex:0 0 auto; display:grid; grid-template-columns:repeat(3,minmax(58px,1fr));
         gap:5px; }
.cote { display:flex; flex-direction:column; align-items:center; gap:1px;
        border:1px solid var(--line); border-radius:var(--r1); padding:3px 6px;
        background:var(--surface); font-family:var(--mono);
        font-variant-numeric:tabular-nums; line-height:1.3; }
.cote b { font-family:var(--sans); font-size:10.5px; font-weight:500; color:var(--ink-3); }
.cote em { font-style:normal; font-size:12.5px; font-weight:600; color:var(--ink); }
.cote.vide { background:var(--sunken); }
.cote.vide em { color:var(--ink-3); font-weight:400; }
.derive-hausse { color:var(--ok); font-size:10px; }
.derive-baisse { color:var(--crit); font-size:10px; }

/* Un groupe de rencontres sous son titre de ligue. Un simple titre plutot
   qu'une carte : deux bordures imbriquees alourdissaient l'ecran du direct. */
.ligue { margin:0 0 20px; }
.ligue-tete { display:flex; align-items:baseline; flex-wrap:wrap; gap:7px;
              margin:0 0 8px; font-size:14px; }
.ligue-tete .sub { display:inline; margin:0; }

/* Ecran Matchs range comme chez le bookmaker : l'arbre des pays a gauche,
   les rencontres a droite, sous un titre de pays puis de ligue. Sous 1000px
   l'arbre passe au-dessus, replie (voir matchs.html). */
.h1-suite { font-weight:400; color:var(--ink-2); }
.parcours { display:grid; gap:20px; }
@media (min-width:1000px) {
  .parcours:has(> .arbre) { grid-template-columns:250px minmax(0,1fr); align-items:start; }
  .parcours > .arbre { position:sticky; top:calc(var(--haut) + 12px);
                       max-height:calc(100vh - var(--haut) - 24px); overflow-y:auto; }
  .parcours > .arbre > summary { pointer-events:none; }
  .parcours > .arbre > summary::marker, .parcours > .arbre > summary::-webkit-details-marker { content:""; display:none; }
}
.flux { min-width:0; }
.arbre { border:1px solid var(--line); border-radius:var(--r2); background:var(--surface);
         box-shadow:var(--ombre-1); padding:4px 0; font-size:13px;
         overscroll-behavior:contain; }
.arbre > summary { font-size:12px; font-weight:600; color:var(--ink-3); padding:8px 12px;
                   cursor:pointer; display:flex; align-items:center; gap:8px; }
.arbre a, .arbre-pays > summary { display:flex; align-items:center; gap:8px;
                   padding:5px 12px; color:var(--ink-2); text-decoration:none; }
.arbre .lib { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.arbre > summary { list-style:none; }
.arbre > summary::-webkit-details-marker { display:none; }
.arbre > summary::after { content:"▾ déplier"; margin-left:auto;
                          text-transform:none; }
.arbre[open] > summary::after { content:"▴ replier"; }
@media (min-width:1000px) { .arbre > summary::after { display:none; } }
.arbre-pays > summary { cursor:pointer; color:var(--ink); list-style:none; }
.arbre-pays > summary::-webkit-details-marker { display:none; }
.arbre-pays > summary::before { content:"▸"; color:var(--ink-3); font-size:10px; width:9px; }
.arbre-pays[open] > summary::before { content:"▾"; }
.arbre-pays > a { padding-left:29px; font-size:12.5px; align-items:flex-start; }
/* Une ligue se lit en entier, sur deux lignes s'il le faut : tronquee a
   vingt caracteres, « Deuxieme division RFEF. Groupe 3 » et « Groupe 5 »
   devenaient la meme entree. */
.arbre-pays > a .lib { white-space:normal; line-height:1.35; }
.arbre a:hover, .arbre-pays > summary:hover { background:var(--sunken); color:var(--ink); }
.arbre a.on { color:var(--ink); font-weight:600; background:var(--surface-3);
              box-shadow:inset 2px 0 0 var(--accent); }
.arbre .count { font-family:var(--mono); font-size:10.5px; color:var(--ink-3);
                font-variant-numeric:tabular-nums; flex:0 0 auto; }
/* Une ligue, une carte : l'entete porte le pays et la ligue, les
   rencontres suivent en lignes compactes. Une seule bordure par ligue --
   le bandeau de pays, le titre et la carte faisaient trois niveaux de
   decor pour une seule information. */
.ligue-carte { border:1px solid var(--line); border-radius:var(--r2);
               background:var(--surface); box-shadow:var(--ombre-1);
               overflow:hidden; margin:0 0 12px; }
.ligue-carte > header, .ligue-carte > summary { display:flex; align-items:center; gap:7px; min-width:0;
               padding:7px 12px; background:var(--surface-2);
               border-bottom:1px solid var(--line); font-size:12.5px; }
.ligue-carte > header a, .ligue-carte > summary a { text-decoration:none; white-space:nowrap; }
.ligue-carte > header .pays-lien, .ligue-carte > summary .pays-lien { color:var(--ink-3); flex:0 0 auto; }
.ligue-carte > header .ligue-lien, .ligue-carte > summary .ligue-lien { color:var(--ink); font-weight:600; min-width:0;
               overflow:hidden; text-overflow:ellipsis; }
.ligue-carte > header a:hover { color:var(--accent-ink); text-decoration:underline; }
.ligue-carte > header i, .ligue-carte > summary i { font-style:normal; color:var(--ink-3); }
.ligue-carte > header .count, .ligue-carte > summary .count { margin-left:auto; font-family:var(--mono); font-size:11px;
               color:var(--ink-3); font-variant-numeric:tabular-nums; }

/* La rencontre compacte : heure | equipes | periodes | score | chevron. */
.mc-liste { list-style:none; margin:0; padding:0; }
.mc { position:relative; display:grid; align-items:center; column-gap:14px;
      grid-template-columns:52px minmax(0,1fr) auto 34px 14px;
      padding:6px 12px; border-top:1px solid var(--line-soft); }
.mc:first-child { border-top:0; }
.mc:hover { background:var(--sunken); }
.mc > .ouvrir { position:absolute; inset:0; z-index:0; }
.mc > .ouvrir:focus-visible { outline:2px solid var(--accent); outline-offset:-2px; }
.mc a:not(.ouvrir) { position:relative; z-index:1; }
.mc:hover .chevron { color:var(--accent-ink); transform:translateX(2px); }
.mc-quand { display:flex; flex-direction:column; gap:1px; font-family:var(--mono);
            font-variant-numeric:tabular-nums; line-height:1.25; }
.mc-heure { font-size:12.5px; color:var(--ink); font-weight:500; }
.mc-etat { font-size:10px; color:var(--ink-3); white-space:nowrap; }
.mc-etat.direct { font-family:var(--sans); font-size:11px; color:var(--crit); font-weight:600; }
.mc-etat.direct::before { content:""; display:inline-block; width:6px; height:6px;
                  border-radius:50%; background:var(--crit); margin-right:4px;
                  vertical-align:1px; animation:pouls 1.6s ease-in-out infinite; }
@keyframes pouls { 50% { opacity:.3; } }
@media (prefers-reduced-motion:reduce) { .mc-etat.direct::before { animation:none; } }
.mc-equipes { display:flex; flex-direction:column; gap:2px; min-width:0; }
.mc-equipes .camp { min-height:0; gap:7px; }
.mc-equipes .camp a { font-size:13.5px; }
/* Le detail par periode en petit tableau : une colonne par periode, une
   ligne par equipe -- chaque chiffre en face du nom auquel il appartient. */
.mc-periodes { display:flex; gap:2px; font-family:var(--mono); font-size:11px;
               color:var(--ink-3); font-variant-numeric:tabular-nums; }
.mc-periodes span { display:flex; flex-direction:column; gap:2px; min-width:20px;
                    text-align:center; }
.mc-periodes i { font-style:normal; line-height:var(--blason); }
.mc-score { display:flex; flex-direction:column; gap:2px; align-items:center;
            font-family:var(--mono); font-variant-numeric:tabular-nums;
            background:var(--surface-3); border-radius:var(--r1); padding:3px 0; }
.mc-score b { font-size:13.5px; line-height:var(--blason); }
.mc-live .mc-score { background:var(--crit-soft); color:var(--crit); }
.mc-scheduled .mc-score b { color:var(--ink-3); font-weight:400; }
/* Dans le Direct, les trois cotes prennent une colonne de plus, avant le
   chevron ; sur telephone elles passent sous la rencontre. */
.mc.avec-cotes { grid-template-columns:52px minmax(0,1fr) auto 34px 186px 14px; }
.mc-cotes { display:grid; grid-template-columns:repeat(3,1fr); gap:4px; }
.mc-cotes .cote { flex-direction:row; justify-content:space-between; gap:4px; padding:3px 7px; }
.mc-cotes .cote b { font-size:11px; }
@media (max-width:640px) {
  .mc { column-gap:10px; padding:6px 10px; grid-template-columns:44px minmax(0,1fr) auto 30px; }
  .mc .chevron { display:none; }
  .mc.avec-cotes { grid-template-columns:44px minmax(0,1fr) auto 30px; }
  .mc.avec-cotes .mc-cotes { grid-column:2 / -1; margin-top:6px; }
  /* Au-dela de trois periodes (basket, volley), le detail mange le nom. */
  .mc-periodes span:nth-last-child(n+4) { display:none; }
}

/* Apercu tous sports : un titre par sport, puis ses cartes de ligue. */
.sport-bloc { margin:0 0 26px; }
.sport-tete { display:flex; align-items:baseline; gap:10px; font-size:16px;
              font-weight:600; margin:0 0 10px; }
.sport-tete .count { font-family:var(--mono); font-size:11px; font-weight:400;
                     color:var(--ink-3); }
.voir-tout { margin:2px 0 0; font-size:12.5px; }
.embleme { width:18px; height:18px; object-fit:contain; flex:0 0 auto;
           background:var(--plaque); border-radius:3px; padding:1px; }

/* Le duo « equipe A — equipe B » quand il vit dans une cellule de tableau. */
.duo { display:inline-flex; align-items:center; gap:7px; flex-wrap:wrap;
       min-width:0; }
.duo .tiret { color:var(--ink-3); }
/* Le score du match, en tete de fiche : a la taille du titre. */
.score-fiche { font-size:0.9em; padding:2px 12px; }

/* En-tete d'une fiche d'equipe : identite a gauche, forme recente a droite,
   l'une sous l'autre des que la ligne ne les tient plus. */
.tete-equipe { display:flex; align-items:flex-start; justify-content:space-between;
               gap:24px; flex-wrap:wrap; }

/* --- 8. Pastilles et blocs -------------------------------------------- */
.score, .per { font-family:var(--mono); }
.per { font-size:11px; padding:1px 6px; border:1px solid var(--line);
       border-radius:3px; color:var(--ink-2); white-space:nowrap; }
.pill { display:inline-block; font-family:var(--sans); font-size:11px; font-weight:600; padding:2px 7px; border-radius:3px; white-space:nowrap; }
.pill-final { background:var(--surface-3); color:var(--ink-3); }
.pill-live { background:var(--crit-soft); color:var(--crit); }
.pill-scheduled { background:var(--surface-3); color:var(--ink-2); }
.pill-postponed { background:var(--warn-soft); color:var(--warn); }
.pill-cancelled { background:var(--crit-soft); color:var(--crit); }
.pill-ok { background:var(--ok-soft); color:var(--ok); }
.pill-deduit { background:var(--warn-soft); color:var(--warn); margin-left:6px; }
.pill-warn { background:var(--warn-soft); color:var(--warn); }
.pill-crit { background:var(--crit-soft); color:var(--crit); }

.card { border:1px solid var(--line); border-radius:var(--r2); padding:15px 16px;
        background:var(--surface); box-shadow:var(--ombre-1); }
/* Deux cartes qui se suivent ne se touchent pas : sans cet ecart, les
   ecrans Modeles et Bilan empilaient des bordures collees. Dans une grille
   .cards, c'est le gap qui espace. */
.card + .card, .card + .cards, .cards + .card { margin-top:var(--cardgap); }
.cards > .card { margin-top:0; }
.card.retenu { border-color:var(--edge); box-shadow:inset 2px 0 0 var(--edge), var(--ombre-1); }
/* Deux colonnes quand la place existe, une seule sinon - sans point de
   rupture a declarer : c'est la largeur disponible qui decide. */
.cards { display:grid; gap:var(--cardgap);
         grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); }
.cards-4 { grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); }
.note { margin-top:16px; padding:14px 16px; border-radius:var(--r2);
        border:1px dashed var(--line); background:var(--surface-2); color:var(--ink-2);
        font-size:13.5px; }
.empty { text-align:center; padding:46px 20px; }
.resume { display:flex; flex-wrap:wrap; gap:10px 16px; margin:0 0 16px; }
.resume div { font-size:12.5px; line-height:1.35; color:var(--ink-3);
              flex:1 1 120px; }
.resume strong { display:block; font-family:var(--mono); font-size:22px; font-weight:600; letter-spacing:-.02em; color:var(--ink);
                 font-variant-numeric:tabular-nums; }
.fbandeau { display:flex; flex-wrap:wrap; gap:4px; margin:6px 0 14px; }
.fbox { display:inline-flex; align-items:center; justify-content:center;
        width:22px; height:22px; flex:0 0 auto;
        border-radius:3px; font-family:var(--mono); font-size:11px; font-weight:600;
        background:var(--surface-3); color:var(--ink-3); }
.fbox.v { background:var(--ok-soft); color:var(--ok); }
.fbox.d { background:var(--crit-soft); color:var(--crit); }
.fbox.n { background:var(--surface-3); color:var(--ink-3); }

.filtres { display:flex; flex-wrap:wrap; gap:5px; margin:0 0 16px; }
.filtres a, .filtres button {
             font-family:var(--sans); font-size:13px; color:var(--ink-2); text-decoration:none;
             padding:4px 11px; border-radius:var(--r1); border:1px solid var(--line);
             background:var(--surface); }
.filtres button { cursor:pointer; line-height:1.55; }
.filtres a:hover, .filtres button:hover { border-color:var(--ink-3); color:var(--ink); }
.filtres a.on, .filtres button.on {
             color:var(--ink); font-weight:600; background:var(--surface-3); border-color:var(--accent); }
.filtres a .count { margin-left:6px; color:var(--ink-3); }

/* Un bloc d'ecran : un titre, un compte, une phrase, puis le tableau. Le
   titre est un h2 -- la page n'en avait aucun, tout etait h3 sous le h1. */
.bloc { margin:0 0 18px; }
.bloc-tete { display:flex; align-items:baseline; gap:10px; margin:0 0 4px; }
h2 { font-size:16.5px; font-weight:600; margin:0; letter-spacing:-.005em; }
.bloc-compte { font-family:var(--mono); font-size:12px; color:var(--ink-3);
               font-variant-numeric:tabular-nums; }
.bloc > .sub { margin-bottom:10px; }
/* Le second niveau d'une cellule : sous la valeur, plus petit, jamais un
   paragraphe -- un <p> dans une cellule ajoutait ses marges a chaque ligne. */
.sous { display:block; margin-top:2px; font-family:var(--sans); font-size:12px;
        line-height:1.4; color:var(--ink-3); font-weight:400; }
td.nw, .nw { white-space:nowrap; }
td.pleine { min-width:260px; }
/* Trois probabilites 1 / N / 2 : trois colonnes alignees d'une ligne a
   l'autre, plutot qu'une chaine qui se casse au hasard de la largeur. */
.trio { display:inline-grid; grid-template-columns:repeat(3,auto); gap:0 14px;
        font-family:var(--mono); font-variant-numeric:tabular-nums; white-space:nowrap; }
.trio b { font-family:var(--sans); font-weight:600; color:var(--ink-3); margin-right:5px; }
.avis { display:block; white-space:nowrap; }
.avis-nom { font-family:var(--sans); color:var(--ink-3); }
/* L'explication qu'on lit une fois : repliee, a portee de clic. */
.aide { margin:0 0 10px; font-size:13px; color:var(--ink-2); }
.aide > summary { cursor:pointer; color:var(--ink-3); font-size:12.5px; width:max-content;
                  max-width:100%; }
.aide > summary:hover { color:var(--accent-ink); }
.aide > p, .aide > div { margin:6px 0 0; max-width:78ch; }
.aide.pied { margin-top:6px; }
.resume a { color:inherit; text-decoration-color:var(--line); }
.resume a:hover { color:var(--accent-ink); }

/* Onglets d'un ecran : des vues, pas des filtres -- ils se soulignent au
   lieu de se presenter en boutons, pour ne plus se confondre avec eux. */
.onglets { display:flex; gap:22px; margin:2px 0 16px; border-bottom:1px solid var(--line);
           overflow-x:auto; scrollbar-width:none; }
.onglets a { padding:8px 0 9px; color:var(--ink-3); text-decoration:none; font-size:14px;
             font-weight:500; white-space:nowrap; border-bottom:2px solid transparent;
             margin-bottom:-1px; }
.onglets a:hover { color:var(--ink); }
.onglets a.on { color:var(--ink); font-weight:600; border-bottom-color:var(--accent); }

/* Les filtres groupes et nommes : une ligne par critere, son nom a gauche.
   Quatre rangees de boutons anonymes ne disaient pas ce que chacune filtrait. */
.panneau-filtres { display:grid; grid-template-columns:auto minmax(0,1fr); gap:8px 14px;
                   align-items:center; margin:0 0 18px; }
.panneau-filtres .filtres { margin:0; }
.pf-lib { font-size:12.5px; font-weight:600; color:var(--ink-3); }
@media (max-width:640px) {
  .panneau-filtres { grid-template-columns:minmax(0,1fr); gap:2px; }
  .pf-lib { margin-top:6px; }

}

.bandeau-alerte { margin:0 0 10px; padding:9px 12px; border-radius:var(--r1);
                  background:var(--warn-soft); color:var(--ink); font-size:13.5px;
                  box-shadow:inset 3px 0 0 var(--warn); }

/* Un seul tableau, un groupe de lignes par match : l'entete des colonnes
   n'est plus repete sous chaque rencontre. */
.tableau-carte { padding:6px 4px 4px; }
table.prono tr.groupe td { padding-top:16px; background:none; border-bottom:1px solid var(--line-soft); }
table.prono tbody:first-of-type tr.groupe td { padding-top:10px; }
table.prono tr.groupe .sous { display:inline; margin-left:8px; }
.groupe-quand { font-family:var(--mono); font-size:12px; color:var(--ink-3); margin-right:8px; }
.groupe-match { font-weight:600; color:var(--ink); text-decoration:none; }
.groupe-match:hover { color:var(--accent-ink); text-decoration:underline; }
table.prono td.issue { padding-left:calc(var(--rowpx) + 10px); }
table.prono tbody tr:not(.groupe):last-child td { border-bottom:0; }
.pill-principal { background:var(--accent); color:var(--btn-ink); }
.pill-fort { background:var(--accent-soft); color:var(--accent-ink); }
.pill-seul { background:var(--surface-3); color:var(--ink-2); }
@media (max-width:640px) {
  table.prono tr.groupe { display:block; padding:16px 0 2px; border-bottom:0; }
  table.prono tbody:first-of-type tr.groupe { padding-top:6px; }
  table.prono tr.groupe td { padding:0; border:0; }
  table.prono tr.groupe .sous { display:block; margin:2px 0 0; }
  table.prono td.issue { padding-left:0; font-weight:600; }
  /* Ce qui decide d'abord (cote, marche, ecart, valeur), les modeles
     ensuite, plus petits : deux rangees de quatre au lieu de trois de trois. */
  table.prono tr:not(.groupe) { grid-template-columns:repeat(4,minmax(0,1fr)); gap:6px 10px; padding:10px 0; }
  table.prono td.modele { order:2; font-size:12px; color:var(--ink-2); }
  table.prono td.signal { grid-column:1 / -1; order:3; }
  table.prono td.signal:empty { display:none; }
  .tableau-carte { padding:2px 12px; }
}

/* Telephone : une rangee de filtres defile plutot que de s'empiler sur
   trois lignes (les onze durees de l'ecran Matchs en prenaient le tiers).
   Les formulaires .filtres (recherche + bouton) gardent leur retour a la ligne. */
@media (max-width:640px) {
  p.filtres { flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;
              margin-left:-12px; margin-right:-12px; padding:0 12px 2px; }
  p.filtres::-webkit-scrollbar { display:none; }
  p.filtres a, p.filtres button { white-space:nowrap; flex:0 0 auto; }
  .panneau-filtres p.filtres { margin-left:0; margin-right:0; padding-left:0; }
}

/* --- 9. Formulaires ---------------------------------------------------- */
.input, input[type="text"], input[type="search"], input[type="url"],
input[type="password"], input[type="number"], select, textarea {
         font-family:var(--sans); font-size:14px; padding:8px 11px;
         border:1px solid var(--line); border-radius:var(--r1);
         background:var(--surface); color:var(--ink); max-width:100%; }
.input { min-width:min(340px,100%); }
.btn { font-family:var(--sans); font-size:13.5px; font-weight:600; padding:9px 16px;
       border-radius:var(--r1); cursor:pointer;
       background:var(--accent); color:var(--btn-ink); border:1px solid var(--accent); }
.btn:hover { filter:brightness(1.06); }
/* Un formulaire Django rendu par as_p : libelle a gauche, champ a droite,
   tous alignes sur la meme colonne -- sans quoi chaque champ commencait la
   ou son libelle finissait, en escalier. */
.formulaire > p { display:grid; grid-template-columns:130px minmax(0,440px); gap:6px 14px;
                  align-items:center; margin:0 0 10px; }
.formulaire > p > label { font-size:13.5px; color:var(--ink-2); }
.formulaire > p > :is(input, select, textarea) { width:100%; }
.formulaire > p > textarea { min-height:72px; }
.formulaire > p > label:has(+ textarea) { align-self:start; padding-top:8px; }
.formulaire > p > .helptext, .formulaire > p > ul.errorlist { grid-column:2; }
.formulaire > .btn { margin-left:144px; }
@media (max-width:640px) {
  .formulaire > p { grid-template-columns:minmax(0,1fr); }
  .formulaire > p > .helptext, .formulaire > p > ul.errorlist { grid-column:1; }
  .formulaire > .btn { margin-left:0; width:100%; }
}
ul.errorlist { list-style:none; margin:4px 0 0; padding:0; color:var(--crit); font-size:13px; }
ul.errorlist li { margin:2px 0; }
.errors { color:var(--crit); font-size:13px; margin:4px 0 0; }

/* --- 10. Trajectoire des cotes ----------------------------------------
   uPlot dessine dans un canvas : seules la legende et le curseur sont du
   DOM, et c'est la qu'il faut reprendre le theme sombre, la feuille livree
   supposant un fond clair. */
.graphe { min-height:280px; }
.u-legend { font-family:var(--mono); font-size:11.5px; color:var(--ink-2); }
.u-legend .u-marker { border-radius:2px; }
.u-legend th { border:0; padding:0 6px; text-transform:none; letter-spacing:0;
               font-size:11.5px; color:var(--ink-2); }
.u-legend td { border:0; padding:0 10px 0 0; }
.u-legend tr:hover td { background:none; }
.u-cursor-x, .u-cursor-y { border-color:var(--line); }
.u-select { background:var(--accent-soft); }

/* --- 10 bis. Fiche : pronostic et adversaires communs ----------------
   Trois couleurs pour trois issues, les memes partout sur la fiche : 1
   (recoit) en ocre, N en gris, 2 (visiteur) en bleu marche. Dans la frise,
   les deux CAMPS reprennent l'ocre et le bleu : le meme code se lit d'une
   vue a l'autre. */
.issue-home { background:var(--accent); color:var(--btn-ink); }
.issue-draw { background:var(--ink-3); color:var(--btn-ink); }
.issue-away { background:var(--market); color:var(--btn-ink); }

.prono-tete .pill { white-space:normal; max-width:100%; }
.prono-tete { display:flex; justify-content:space-between; align-items:flex-start;
              gap:12px; flex-wrap:wrap; margin-bottom:14px; }
.prono-titre { margin:0 0 4px; font-size:12.5px; font-weight:600; color:var(--ink-3); }
.prono-choix { margin:0; font-size:20px; font-weight:600; display:flex;
               align-items:center; gap:10px; flex-wrap:wrap; }
.prono-choix .issue { display:inline-flex; align-items:center; justify-content:center;
                      min-width:30px; height:30px; border-radius:var(--r1);
                      font-family:var(--mono); font-size:16px; }

.legende { display:flex; flex-wrap:wrap; gap:6px 14px; margin:0 0 8px;
           font-size:12px; color:var(--ink-2); }
.legende > span, .leg-camp { display:inline-flex; align-items:center; gap:6px; }
.pastille { display:inline-block; width:10px; height:10px; border-radius:2px; }
.leg-camp { font:inherit; color:inherit; background:none; border:1px solid var(--line);
            border-radius:var(--r1); padding:2px 8px; cursor:pointer; }

.barres { margin-bottom:14px; }
.barre-ligne { display:grid; grid-template-columns:minmax(120px,190px) 1fr;
               gap:10px; align-items:center; margin:6px 0; }
.barre-nom { font-size:12.5px; color:var(--ink-2); display:flex; flex-direction:column; }
.barre-nom small { font-size:11.5px; color:var(--ink-3); }
.barre { display:flex; height:22px; border-radius:var(--r1); overflow:hidden;
         background:var(--surface-3); }
.barre-principale .barre { height:32px; }
.barre-principale .barre-nom { color:var(--ink); font-weight:600; }
.barre .seg { display:flex; align-items:center; justify-content:center; min-width:0;
              overflow:hidden; white-space:nowrap; font-family:var(--mono); font-size:11.5px;
              transition:opacity .15s; }
.barre-principale .seg { font-size:13px; font-weight:600; }
.barre.vide { justify-content:center; align-items:center; color:var(--ink-3); font-size:12px; }

.suggestions { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
               gap:8px; }
.sugg { border:1px solid var(--line-soft); border-radius:var(--r1); padding:8px 11px;
        display:flex; flex-direction:column; gap:2px; background:var(--sunken); }
.sugg-titre { font:600 12px var(--sans);
              color:var(--ink-3); margin-bottom:2px; }
.sugg-choix { font-size:14px; font-weight:600; }
.sugg-choix b { margin-right:4px; }
.sugg-chiffres { font:12px var(--mono); color:var(--ink-2); }
.sugg-chiffres + .sugg-choix { margin-top:6px; }
.sugg.ecart-marche { border-color:var(--warn); background:var(--warn-soft); }
.detail-chiffres { margin-top:14px; border-top:1px solid var(--line-soft); padding-top:10px; }
.detail-chiffres > summary, .adversaire > summary { cursor:pointer; }
.detail-chiffres > summary { font-size:13px; color:var(--ink-2); }

.estompe { opacity:.28; }
.proportions { display:flex; height:20px; border-radius:var(--r1); overflow:hidden;
               margin:6px 0 8px; max-width:420px; }
.proportions .seg { display:flex; align-items:center; justify-content:center;
                    font-family:var(--mono); font-size:11px; min-width:0; overflow:hidden; }
.proportions .seg.v { background:var(--ok-soft); color:var(--ok); }
.proportions .seg.n { background:var(--surface-3); color:var(--ink-3); }
.proportions .seg.d { background:var(--crit-soft); color:var(--crit); }
.proportions.mini { height:16px; margin:2px 0; width:100%; font-size:10px; }

.vue-titre { font-size:13px; color:var(--ink-3); font-weight:500; margin:18px 0 8px; }
.communs .vue-titre:first-of-type { margin-top:4px; }

/* Consolidation : une barre par adversaire, partant du centre. */
.div-axe, .div-ligne { display:grid; grid-template-columns:minmax(110px,200px) 1fr 52px;
                       gap:10px; align-items:center; }
.div-axe { font-size:11px; color:var(--ink-3); font-family:var(--mono); }
.div-axe-txt { display:flex; justify-content:space-between; gap:8px; }
.div-ligne { padding:3px 0; cursor:pointer; transition:opacity .15s; }
.div-nom { display:flex; align-items:center; gap:6px; font-size:12.5px; min-width:0;
           overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.div-piste { position:relative; height:16px; background:var(--sunken);
             border-radius:var(--r1); }
.div-piste::before { content:""; position:absolute; left:50%; top:-3px; bottom:-3px;
                     width:1px; background:var(--ink-3); }
.div-barre { position:absolute; top:2px; bottom:2px; border-radius:2px; }
.div-barre.pos { left:50%; background:var(--accent); }
.div-barre.neg { right:50%; background:var(--market); }
.div-val { text-align:right; font-size:12px; }

/* Frise : une case par mois, deux mini-barres par case (un camp chacune). */
.frise { overflow-x:auto; padding-bottom:4px; }
.frise-ligne { display:grid; align-items:center; gap:3px; transition:opacity .15s;
               grid-template-columns:minmax(120px,190px) repeat(var(--mois),minmax(30px,1fr));
               min-width:calc(130px + var(--mois) * 33px); }
.frise-ligne.active .frise-case { background:var(--accent-soft); }
.frise-nom { display:flex; align-items:center; gap:6px; font-size:12.5px; min-width:0;
             overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
             position:sticky; left:0; background:var(--surface); z-index:1; padding-right:6px; }
.frise-entete .frise-nom { background:var(--surface); }
.frise-mois { font-size:10.5px; font-family:var(--mono); color:var(--ink-3); text-align:center;
              line-height:1.2; }
.frise-mois small { display:block; font-size:9.5px; }
.frise-case { display:flex; flex-direction:column; gap:2px; padding:3px 2px;
              border-radius:var(--r1); }
.mini-bilan { position:relative; display:flex; height:13px; border-radius:2px; overflow:hidden;
              cursor:default; }
.mini-bilan.dom { box-shadow:inset 0 2px 0 var(--accent); }
.mini-bilan.ext { box-shadow:inset 0 -2px 0 var(--market); }
.mini-bilan.vide { background:var(--sunken); box-shadow:none; }
.mini-bilan i { display:block; min-width:0; }
.mini-bilan i.v { background:var(--ok-soft); }
.mini-bilan i.n { background:var(--surface-3); }
.mini-bilan i.d { background:var(--crit-soft); }
.mini-bilan b { position:absolute; inset:0; display:flex; align-items:center;
                justify-content:center; font:600 9.5px var(--mono); color:var(--ink); }
.mini-bilan.cache { visibility:hidden; }
.legende .point { display:inline-block; border-radius:50%; border:2px solid; }
.legende .point.dom, .point.statique.dom { border-color:var(--accent); }
.legende .point.ext, .point.statique.ext { border-color:var(--market); }
.point.statique, .legende .point { width:10px; height:10px; margin:0 6px 0 0;
                                   vertical-align:middle; display:inline-block;
                                   border-radius:50%; border:2px solid; }
.fbox.mini { width:16px; height:16px; font-size:9.5px; font-style:normal; margin-right:2px; }

/* Detail : un adversaire par ligne, les matchs au depli. */
.adversaire { border-top:1px solid var(--line-soft); transition:opacity .15s; }
.adversaire > summary { display:grid; grid-template-columns:minmax(110px,200px) 1fr 1fr 52px;
                        gap:12px; align-items:center; padding:8px 0; list-style:none; }
.adversaire > summary::-webkit-details-marker { display:none; }
.adversaire > summary { position:relative; }
.adversaire > summary::before { content:"▸"; position:absolute; left:-14px; top:11px;
                                color:var(--ink-3); font-size:11px; }
.adversaire[open] > summary::before { content:"▾"; }
.adversaires { padding-left:14px; }
.adv-nom { display:flex; align-items:center; gap:6px; min-width:0; overflow:hidden;
           white-space:nowrap; text-overflow:ellipsis; font-size:13px; }
.adv-camp { display:flex; flex-direction:column; min-width:0; }
.adv-camp small { font-size:10.5px; color:var(--ink-3); overflow:hidden;
                  text-overflow:ellipsis; white-space:nowrap; }
.adv-ecart { text-align:right; font-weight:600; }
.adv-matchs { padding:0 0 12px; }
.adv-matchs table { width:100%; }
.voir-plus { margin-top:8px; font:12.5px var(--sans); color:var(--accent-ink); background:none;
             border:1px solid var(--line); border-radius:var(--r1); padding:4px 10px; cursor:pointer; }
.voir-plus:hover { border-color:var(--accent); }
[x-cloak] { display:none !important; }

@media (max-width:640px) {
  .barre-ligne { grid-template-columns:1fr; gap:3px; }
  .div-axe, .div-ligne { grid-template-columns:1fr 44px; gap:2px 6px; }
  .div-axe > span:first-child { display:none; }
  .div-nom { grid-column:1 / -1; }
  .div-piste { grid-column:1; }
  .adversaire > summary { grid-template-columns:1fr 44px; }
  .adversaire > summary .adv-camp { grid-column:1 / -1; }
  .adversaire > summary .adv-ecart { grid-row:1; grid-column:2; }
  .prono-choix { font-size:17px; }
  /* La date passe au-dessus de la rencontre : toute la largeur pour les
     deux equipes, le resultat a droite. */
  .adversaires { padding-left:0; }
  .adversaire > summary { padding-left:14px; }
  .adversaire > summary::before { left:0; }
  .adv-matchs thead { display:none; }
  .adv-matchs tr { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center;
                   gap:0 8px; padding:6px 0; border-bottom:1px solid var(--line-soft); }
  .adv-matchs td { padding:0; border:0; }
  .adv-matchs td.when { grid-column:1 / -1; font-size:10.5px; }
  .adv-matchs .rencontre-ligne { min-width:0; gap:5px; font-size:12.5px; }
}

/* Une rencontre en une ligne dans une liste centree sur une equipe :
   recoit a droite du score, visiteur a gauche, l'equipe suivie en gras. */
.rencontre-ligne { display:inline-grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
                   align-items:center; gap:8px; width:100%; min-width:260px; }
.rl-camp { display:flex; align-items:center; gap:6px; min-width:0; }
.rl-recoit { justify-content:flex-end; text-align:right; }
.rl-camp a { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink-2); }
.rl-camp.soi a { color:var(--ink); font-weight:600; }

/* Nombre de buts. */
.buts-attendus { display:grid; grid-template-columns:1fr auto 1fr; align-items:end; gap:12px;
                 margin:6px 0 8px; }
.buts-camp { display:flex; flex-direction:column; gap:2px; min-width:0; }
.buts-camp:last-child { text-align:right; }
.buts-camp span, .buts-total span { font-size:12px; color:var(--ink-2); overflow:hidden;
                                     text-overflow:ellipsis; white-space:nowrap; }
.buts-camp strong { font-size:24px; }
.buts-total { display:flex; flex-direction:column; align-items:center; }
.buts-total strong { font-size:30px; line-height:1.1; }
.buts-total small { font:11px var(--mono); color:var(--ink-3); }
.buts-partage { height:8px; margin-bottom:6px; }
.buts-grille { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px 24px; }
.histo { display:flex; align-items:flex-end; gap:3px; height:130px; }
.histo-col { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
             height:100%; min-width:0; }
.histo-col i { display:block; width:100%; background:var(--surface-3); border-radius:2px 2px 0 0;
               min-height:1px; }
.histo-col.dessus i { background:var(--accent); }
.histo-col small { font:10px var(--mono); color:var(--ink-3); margin-bottom:2px; }
.histo-col b { font:600 11px var(--mono); color:var(--ink-2); margin-top:3px; }
.buts-seuils, .buts-constate { width:100%; font-size:12.5px; }
.buts-seuils th, .buts-seuils td { padding:4px 6px; white-space:nowrap; }
.buts-seuils tr.signale td { background:var(--warn-soft); }
.buts-seuils tr.principal td { background:var(--accent-soft); }
.buts-chiffres { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px;
                 align-content:start; margin-top:18px; }
.buts-chiffres > div { background:var(--sunken); border:1px solid var(--line-soft);
                       border-radius:var(--r1); padding:8px 10px; display:flex;
                       flex-direction:column; gap:4px; min-width:0; }
.buts-chiffres strong { font-size:18px; }
.buts-chiffres .sugg-titre { overflow:hidden; text-overflow:ellipsis; }
.scores-probables { display:flex; flex-wrap:wrap; gap:8px; margin:0; }
.scores-probables > span { display:flex; flex-direction:column; align-items:center; gap:2px; }
.scores-probables small { font-size:11px; color:var(--ink-3); }
.totaux { display:flex; flex-wrap:wrap; gap:3px; }
.totaux i { font:600 10.5px var(--mono); font-style:normal; min-width:20px; text-align:center;
            padding:2px 3px; border-radius:2px; background:var(--surface-3); color:var(--ink-2); }
.totaux i.dessus { background:var(--accent-soft); color:var(--accent-ink); }
@media (max-width:640px) {
  .buts-grille { grid-template-columns:1fr; }
  .buts-chiffres { grid-template-columns:1fr 1fr 1fr; margin-top:6px; }
  .buts-camp strong { font-size:20px; }
  .buts-constate thead th:last-child, .buts-constate td:last-child { display:none; }
  .buts-seuils th, .buts-seuils td { padding:4px 3px; font-size:12px; }
}

/* --- 10 ter. Apercu d'un match, en modale ----------------------------- */
.modale { border:1px solid var(--line); border-radius:var(--r3); padding:0;
          width:min(760px, calc(100vw - 32px)); max-height:calc(100vh - 48px);
          background:var(--surface); color:var(--ink); box-shadow:var(--ombre-2); }
.modale::backdrop { background:rgba(10,16,15,.55); }
.modale-corps { padding:20px 22px 18px; overflow:auto; }
.modale-fermer { position:sticky; top:0; float:right; margin:8px 8px 0 0; z-index:2;
                 width:32px; height:32px; border-radius:50%; border:1px solid var(--line);
                 background:var(--surface); color:var(--ink-2); font-size:20px; line-height:1;
                 cursor:pointer; }
.modale-fermer:hover { color:var(--ink); border-color:var(--ink-3); }
.modale-attente { margin:24px 0; text-align:center; }
.apercu-contexte { display:flex; flex-wrap:wrap; gap:4px 12px; align-items:center; margin:0 40px 14px 0;
                   font:12.5px var(--sans); color:var(--ink-3); }
.apercu-duel { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:14px; }
.apercu-camp { display:flex; flex-direction:column; align-items:center; gap:6px; text-align:center;
               color:var(--ink); text-decoration:none; font-weight:600; font-size:15px; min-width:0; }
.apercu-camp:hover span { text-decoration:underline; }
.apercu-score { font:700 30px var(--mono); font-variant-numeric:tabular-nums; white-space:nowrap;
                background:var(--surface-3); border-radius:var(--r2); padding:4px 16px; }
.apercu-score i { font-style:normal; color:var(--ink-3); margin:0 6px; font-weight:400; }
.apercu-details { display:flex; justify-content:center; flex-wrap:wrap; gap:6px; margin:10px 0 4px;
                  min-height:4px; }
.apercu-grille { display:grid; grid-template-columns:1fr 1fr; gap:18px; margin-top:12px;
                 border-top:1px solid var(--line-soft); padding-top:12px; }
.apercu h4 { font:600 12.5px var(--sans);
             color:var(--ink-3); margin:0 0 8px; }
.apercu h4 ~ h4 { margin-top:14px; }
.apercu-forme { display:flex; justify-content:space-between; align-items:center; gap:10px;
                margin:0 0 6px; font-size:13px; }
.apercu-forme > span:first-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.apercu-forme .fbandeau { flex-shrink:0; margin:0; }
.apercu-h2h { display:grid; grid-template-columns:auto 1fr auto 1fr; gap:8px; align-items:center;
              margin:0 0 5px; font-size:12.5px; }
.apercu-h2h > span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.apercu-h2h .when { font:11px var(--mono); color:var(--ink-3); }
.apercu-cotes { width:100%; margin-bottom:8px; font-size:12.5px; }
.apercu-cotes th, .apercu-cotes td { padding:4px 6px; }
.apercu-pied { margin:16px 0 0; text-align:right; }
.apercu-pied .btn { display:inline-block; text-decoration:none; }
@media (max-width:640px) {
  .modale { width:100vw; max-width:100vw; max-height:92vh; margin:auto 0 0;
            border-radius:var(--r3) var(--r3) 0 0; }
  .modale-corps { padding:16px 14px; }
  .apercu-grille { grid-template-columns:1fr; }
  .apercu-score { font-size:24px; padding:3px 10px; }
  .apercu-camp { font-size:13px; }
}

/* --- 11. Tablette ------------------------------------------------------ */
@media (max-width:1100px) {
  :root { --rail:206px; }
  main { padding:20px 20px 60px; }
}

/* --- 12. Rail en tiroir, barre du bas ---------------------------------
   En dessous de 1024 px le rail cesse d'etre une colonne : il devient un
   tiroir, et la navigation courante passe a portee de pouce en bas. */
@media (max-width:1023px) {
  .shell { grid-template-columns:minmax(0,1fr); min-height:auto; }
  main { padding:18px 16px calc(78px + env(safe-area-inset-bottom)); }
  .topbar { padding:0 12px; gap:10px; }
  .burger { display:inline-flex; align-items:center; justify-content:center;
            width:36px; height:36px; margin-left:-6px; border-radius:var(--r1);
            color:var(--ink-2); }
  .burger:hover { background:var(--surface-3); }

  /* Ferme, le tiroir sort de l'ecran ET du parcours de tabulation - d'ou
     visibility, que le seul translate ne donne pas. */
  /* align-self:stretch annule le `start` de la colonne : sur un element
     fixe, `start` donne au tiroir la hauteur de son contenu au lieu de celle
     de l'ecran, et il n'a alors plus rien a faire defiler. */
  .rail { position:fixed; top:0; left:0; bottom:0; z-index:50; align-self:stretch;
          width:min(84vw,308px); max-height:none; padding:0 0 24px;
          border-right:1px solid var(--line);
          transform:translateX(-100%); visibility:hidden;
          transition:transform .22s ease, visibility .22s;
          padding-bottom:calc(24px + env(safe-area-inset-bottom)); }
  body.rail-ouvert .rail { transform:none; visibility:visible; box-shadow:var(--ombre-2); }
  .rail-tete { display:flex; align-items:center; justify-content:space-between;
               position:sticky; top:0; z-index:1; background:var(--surface-2);
               padding:13px 10px 12px 16px; border-bottom:1px solid var(--line);
               font-size:12.5px; font-weight:600; color:var(--ink-3); }
  .rail-tete .ferme { display:inline-flex; align-items:center; justify-content:center;
                      width:36px; height:36px; border-radius:var(--r1); color:var(--ink-2); }
  /* En tiroir le rail n'a plus de rembourrage propre : le premier
     intitule reprend le sien pour ne pas se coller a la tete. */
  .rail-label, .rail > .rail-label:first-of-type { padding-top:14px; }
  .rail a { padding:10px 16px; font-size:14.5px; }

  .voile { display:block; position:fixed; inset:0; z-index:40; background:rgba(0,0,0,.5);
           opacity:0; pointer-events:none; transition:opacity .22s; }
  body.rail-ouvert .voile { opacity:1; pointer-events:auto; }

  /* Barre du bas : les quatre ecrans plus l'ouverture du tiroir. Le
     compteur du direct s'y repete, c'est le seul appel a agir. */
  .tabbar { display:grid; grid-template-columns:repeat(5,1fr); position:fixed;
            left:0; right:0; bottom:0; z-index:35; background:var(--surface);
            border-top:1px solid var(--line); padding-bottom:env(safe-area-inset-bottom);
            box-shadow:0 -1px 3px rgba(16,27,25,.07); }
  .tabbar > a, .tabbar > button { position:relative; display:flex; flex-direction:column; align-items:center;
                justify-content:center; gap:3px; padding:9px 2px 8px; text-decoration:none;
                color:var(--ink-3); font-size:10.5px; font-weight:500; }
  .tabbar .on { color:var(--accent-ink); }
  .tabbar .on::before { content:""; position:absolute; top:0; left:24%; right:24%; height:2px;
                        background:var(--accent); border-radius:0 0 2px 2px; }
  .tabbar .bulle { position:absolute; top:4px; left:calc(50% + 6px); min-width:15px;
                   padding:0 4px; border-radius:999px; background:var(--crit);
                   color:var(--btn-ink); font-size:9px; line-height:15px; }
}

/* --- 13. Telephone : la rencontre passe sur deux lignes ----------------
   Sous 640 px, trois colonnes ne tiennent plus sans couper les deux noms.
   La rencontre se relit alors comme une feuille de match : le camp qui
   recoit, puis le visiteur, chacun avec son blason a gauche et son score
   aligne a droite, en face de lui. */
@media (max-width:640px) {
  :root { --blason:22px; }
  h1 { font-size:20px; }
  main { padding:16px 12px calc(78px + env(safe-area-inset-bottom)); }
  table { font-size:13px; }
  td, th { padding-left:8px; padding-right:8px; }
  .matchs > li { padding:9px 12px; }

  .ligne { flex-direction:column; align-items:stretch; gap:8px; }
  .rencontre { grid-template-columns:minmax(0,1fr) auto; gap:2px 12px; }
  .rencontre .camp { grid-column:1; }
  .rencontre .camp:first-child { grid-row:1; }
  /* Le visiteur reprend le sens de lecture normal : blason a gauche,
     comme celui qui recoit, pour que les deux ecussons s'alignent. */
  .rencontre .camp.visiteur { grid-row:2; flex-direction:row-reverse;
                              justify-content:flex-end; }
  .rencontre .score { grid-column:2; grid-row:1 / span 2;
                      flex-direction:column; align-items:flex-end; justify-content:center;
                      gap:0; padding:0 2px; background:none; }
  .rencontre .score .sep { display:none; }
  .rencontre .score .pt { display:block; line-height:var(--ligne-h); font-size:15px; }
  a.score:hover { background:none; }
  /* La rencontre passe en colonne : un chevron pose sous elle ne designe
     plus rien. Le doigt a la carte entiere, il n'a pas besoin de la fleche. */
  .chevron { display:none; }
  .cotes { grid-template-columns:repeat(3,minmax(0,1fr)); }
  .meta { gap:6px; font-size:11.5px; }
  .resume { display:grid; grid-template-columns:1fr 1fr; gap:10px 14px; }
  .resume strong { font-size:17px; }
  .card { padding:13px 13px; }
  .fil { display:none; }
}

/* Sous 640 px, un tableau marque .empile cesse d'etre un tableau : chaque
   ligne devient une petite fiche, la cellule .pleine (la rencontre) en tete
   sur toute la largeur, les autres valeurs sous leur libelle (data-libelle).
   Le defilement horizontal cachait justement les colonnes qui comptaient. */
@media (max-width:640px) {
  table.empile thead { display:none; }
  table.empile, table.empile tbody { display:block; }
  table.empile tr { display:grid; grid-template-columns:repeat(auto-fit,minmax(96px,1fr));
                    gap:8px 12px; padding:12px 0; border-bottom:1px solid var(--line-soft); }
  table.empile td { display:block; padding:0; border:0; min-width:0; white-space:normal; }
  table.empile td.nw { white-space:nowrap; }
  table.empile td.pleine { grid-column:1 / -1; order:-1; min-width:0; }
  table.empile td[data-libelle]::before { content:attr(data-libelle); display:block;
                    font-family:var(--sans); font-size:11px; font-weight:500;
                    color:var(--ink-3); margin-bottom:1px; }
  table.empile td.empty { grid-column:1 / -1; }
  /* L'heure coiffe la fiche, comme l'entete d'une rencontre. */
  table.empile td.tete { grid-column:1 / -1; order:-2; font-size:11.5px; color:var(--ink-3);
                         margin-bottom:-4px; }
  table.empile tbody tr:hover td { background:none; }
  .trio { gap:0 10px; }
}

/* Le pari d'appoint sous une rencontre : un total propose en second, qui ne
   doit ni se confondre avec la ligne principale ni disparaitre. */
tr.appoint > td { border-top: 0; padding-top: 0; opacity: .82; font-size: .94em; }
tr.appoint .pill { background: var(--fond-2, #eee); font-size: .85em; }

/* --- 12. Attente ------------------------------------------------------ */
/* Ce qui se montre pendant qu'on attend, et surtout QUAND.
 *
 * Mesure du 23/09/2026 sur cette machine : la plupart des pages repondent
 * entre 72 et 182 ms, /ligues/ en 727 et /backtest/ en 533. Un indicateur
 * qui apparait immediatement clignoterait donc sur douze ecrans sur
 * quatorze -- plus fatigant qu'informatif. Tout ce qui suit est retarde de
 * 180 ms : en dessous, l'echange a eu lieu et rien ne s'est affiche.
 */

/* La barre de progression, en haut, au-dessus de tout. Elle avance sans
 * jamais atteindre le bout : personne ne connait la duree restante, et
 * une barre qui pretend la connaitre ment. */
#progression {
  position:fixed; top:0; left:0; height:2px; width:0;
  background:var(--accent); z-index:9999;
  opacity:0; pointer-events:none;
  transition:width .2s ease-out, opacity .2s;
}
#progression.va { opacity:1; }

/* Le contenu qu'on remplace reste lisible, simplement en retrait : on a
 * deja quelque chose a montrer, l'effacer pour un squelette serait perdre
 * de l'information pour gagner une animation. */
#contenu[aria-busy="true"] { opacity:.55; transition:opacity .2s .18s; }

/* Le squelette, lui, sert la ou il n'y a RIEN a montrer : un fragment qui
 * se charge dans une zone vide. Il dessine la forme a venir, pas un
 * sablier. */
.squelette { display:flex; flex-direction:column; gap:10px; }
.squelette .barre {
  height:var(--ligne-h, 26px); border-radius:4px;
  background:linear-gradient(90deg, var(--surface-2) 25%,
             var(--surface-3) 37%, var(--surface-2) 63%);
  background-size:400% 100%;
  animation:squelette-glisse 1.4s ease-in-out infinite;
}
.squelette .barre:nth-child(2) { width:92%; }
.squelette .barre:nth-child(3) { width:78%; }
.squelette .barre:nth-child(4) { width:86%; }
.squelette .barre:nth-child(5) { width:64%; }

@keyframes squelette-glisse {
  from { background-position:100% 50%; }
  to   { background-position:0 50%; }
}

/* Le mouvement n'est pas une information : qui le refuse garde la forme
 * sans l'animation, et la barre sans son glissement. */
@media (prefers-reduced-motion:reduce) {
  .squelette .barre { animation:none; }
  #progression { transition:opacity .2s; }
}

/* Fiche : ligne de la synthese qui s'ecarte du marche. */
tr.signale td { background:var(--warn-soft); }

/* --- Aller et retour liste / fiche ------------------------------------ */
/* Le fondu de l'echange (hx-swap transition:true) : court, pour accompagner
   le changement de page sans le retarder. Seul le contenu change -- le rail
   et la barre du haut ne clignotent pas. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration:140ms; }
#contenu { view-transition-name:contenu; }
::view-transition-old(contenu), ::view-transition-new(contenu) { animation-duration:140ms; }
@media (prefers-reduced-motion:reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation:none !important; }
}

/* Le fil de la fiche : retour a la liste, sport, pays, ligue, voisins. */
.fil-fiche { display:flex; flex-wrap:wrap; align-items:center; gap:4px 0; margin:-6px 0 14px;
       font-size:12.5px; color:var(--ink-3); }
.fil-fiche > a { color:var(--ink-2); text-decoration:none; white-space:nowrap; }
.fil-fiche > a + a::before { content:"/"; color:var(--line); margin:0 8px; }
.fil-fiche > a:hover { color:var(--accent-ink); text-decoration:underline; }
.fil-retour { display:inline-flex; align-items:center; gap:3px; font-weight:600;
              color:var(--ink) !important; }
.fil-retour svg { width:14px; height:14px; transform:rotate(180deg); }
.fil-voisins { margin-left:auto; display:flex; gap:6px; }
.fil-voisins a { font-size:12.5px; color:var(--ink-2);
                 text-decoration:none; padding:3px 9px; border:1px solid var(--line);
                 border-radius:var(--r1); background:var(--surface); white-space:nowrap; }
.fil-voisins a:hover { border-color:var(--ink-3); color:var(--ink); }
@media (max-width:640px) {
  .fil-voisins { margin-left:0; width:100%; justify-content:space-between; margin-top:6px; }
}

/* La rencontre qu'on vient de lire, retrouvee au retour dans la liste. */
.mc.vu { box-shadow:inset 3px 0 0 var(--accent); animation:vu 1.8s ease-out; }
@keyframes vu { from { background:var(--accent-soft); } to { background:transparent; } }
@media (prefers-reduced-motion:reduce) { .mc.vu { animation:none; } }

/* --- 10 quater. Fiche : ce que la page statistique apporte ------------- */
.sub-inline { font-size:12px; color:var(--ink-3); }
.filtres-mini { margin:0 0 10px; }
.filtres-mini button { padding:3px 9px; font-size:11px; }

/* Statistiques : une ligne par mesure, la barre partage la largeur entre
   les deux equipes -- a gauche le recevant, a droite le visiteur. */
.stat-tete { display:flex; justify-content:space-between; font-size:12px; font-weight:600;
             margin:0 0 6px; }
.stat-tete span:first-child { color:var(--accent-ink); }
.stat-tete span:last-child { color:var(--market); }
.stat-ligne { display:grid; grid-template-columns:64px 1fr 64px; align-items:center;
              column-gap:8px; row-gap:3px; padding:4px 0; }
.stat-lib { text-align:center; font-size:12.5px; color:var(--ink-2); }
.stat-val { font-family:var(--mono); font-size:12.5px; font-variant-numeric:tabular-nums;
            color:var(--ink-2); }
.stat-val:last-of-type { text-align:right; }
.stat-val.mieux { color:var(--ink); font-weight:700; }
.stat-barre { grid-column:1 / -1; height:4px; border-radius:2px; background:var(--market);
              overflow:hidden; display:flex; }
.stat-barre.vide { background:var(--line-soft); }
.stat-barre i { display:block; height:100%; background:var(--accent);
                border-right:2px solid var(--surface); }
.stat-plus { margin-top:8px; }
.stat-plus > summary { cursor:pointer; font-size:12px; color:var(--ink-3); margin-bottom:6px; }

/* Deroule : une ligne par evenement, le recevant a gauche, le visiteur a
   droite ; la minute au centre, comme sur les feuilles de match. */
.chrono-liste { list-style:none; margin:0; padding:0; }
.chrono-liste li { display:grid; grid-template-columns:1fr 44px 1fr; align-items:center;
                   gap:8px; padding:5px 0; border-top:1px solid var(--line-soft); font-size:12.5px; }
.chrono-liste li:first-child { border-top:0; }
.chrono-min { grid-column:2; grid-row:1; text-align:center; font-family:var(--mono);
              font-size:11.5px; color:var(--ink-3); }
.chrono-ico { display:none; }
.chrono-liste li.dom .chrono-txt { grid-column:1; grid-row:1; text-align:right; }
.chrono-liste li.ext .chrono-txt { grid-column:3; grid-row:1; }
.chrono-txt b { font-weight:600; }
.chrono-liste li.f-but .chrono-txt b { color:var(--edge); }
.chrono-liste li.f-jaune .chrono-txt b { color:var(--warn); }
.chrono-liste li.f-rouge .chrono-txt b { color:var(--crit); }
.chrono-liste li.f-rempl .chrono-txt b { color:var(--ink-3); font-weight:500; }

/* Classement : les deux equipes du match surlignees, la zone en liseré. */
.table-defile { overflow-x:auto; }
.tab-classement { width:100%; border-collapse:collapse; font-size:12.5px; }
.tab-classement th { font-size:11.5px; color:var(--ink-3); font-weight:500;
                     text-align:left; padding:4px 6px; border-bottom:1px solid var(--line); }
.tab-classement td { padding:4px 6px; border-bottom:1px solid var(--line-soft); white-space:nowrap; }
.tab-classement td a { color:var(--ink); text-decoration:none; }
.tab-classement td a:hover { text-decoration:underline; }
.tab-classement tr.ici td { background:var(--accent-soft); font-weight:600; }
.tab-classement tr td:first-child { box-shadow:inset 3px 0 0 transparent; }
.tab-classement tr.z-haut td:first-child { box-shadow:inset 3px 0 0 var(--edge); }
.tab-classement tr.z-milieu td:first-child { box-shadow:inset 3px 0 0 var(--market); }
.tab-classement tr.z-bas td:first-child { box-shadow:inset 3px 0 0 var(--crit); }
.zones { display:flex; flex-wrap:wrap; gap:6px 14px; margin:10px 0 0; font-size:11.5px; color:var(--ink-3); }
.zones span::before { content:""; display:inline-block; width:8px; height:8px; border-radius:2px;
                      margin-right:5px; vertical-align:0; }
.zones .z-haut::before { background:var(--edge); }
.zones .z-milieu::before { background:var(--market); }
.zones .z-bas::before { background:var(--crit); }

/* Compositions : deux colonnes, les remplacants et absents au depli. */
.compos-grille { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:16px; }
.compo h4 { font-size:13px; margin:0 0 6px; }
.compo ul { list-style:none; margin:0 0 8px; padding:0; font-size:12.5px; }
.compo li { padding:2px 0; }
.compo li .num { display:inline-block; min-width:24px; color:var(--ink-3); }
.compo-titre { font-size:12px; font-weight:600; color:var(--ink-3); margin:6px 0 4px; cursor:pointer; }
.tab-classement .duo { flex-wrap:nowrap; max-width:190px; }
.tab-classement .duo a { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
@media (max-width:640px) {
  /* Les buts cedent la place : le rang et les points sont ce qu'on lit. */
  .tab-classement th:nth-child(7), .tab-classement td:nth-child(7) { display:none; }
  .tab-classement .duo { max-width:150px; }
}

/* Completude d'un match fini (core.completude_niveau) : un score incertain
   se signale d'un « ? », des donnees en attente d'un point. Un match
   complet ou partiel ne porte rien -- le partiel est le cas normal des
   petites ligues, le signaler partout serait du bruit. */
.marque { font-style:normal; display:inline-block; margin-left:4px; vertical-align:1px; }
.marque.m-incertain { color:var(--warn); font-weight:700; font-size:10.5px; }
.marque.m-attente { width:5px; height:5px; border-radius:50%; background:var(--ink-3); }
.completude { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 14px; }
.completude .c-item { font-size:12px; padding:2px 8px; border-radius:3px;
                      border:1px solid var(--line); color:var(--ink-2); background:var(--surface); }
.completude .c-present { border-color:var(--edge-soft); background:var(--edge-soft); color:var(--edge); }
.completude .c-attente { border-style:dashed; color:var(--ink-2); }
.completude .c-deduit, .completude .c-buts { background:var(--warn-soft); border-color:var(--warn-soft); color:var(--warn); }
.completude .c-non_publie, .completude .c-non_demande { color:var(--ink-3); }

/* Corners et cartons : l'estimation, jamais presentee comme un conseil. */
.speciaux .avertissement { font-size:12.5px; color:var(--ink-2); background:var(--warn-soft);
                           border-radius:var(--r1); padding:8px 10px; margin:0 0 12px; }
.speciaux-objet { font-size:13px; margin:12px 0 6px; }
.tab-speciaux { width:100%; border-collapse:collapse; font-size:12.5px; }
.tab-speciaux th { font-size:11.5px; color:var(--ink-3); font-weight:500; text-align:left;
                   padding:4px 6px; border-bottom:1px solid var(--line); white-space:nowrap; }
.tab-speciaux td { padding:5px 6px; border-bottom:1px solid var(--line-soft); white-space:nowrap; }
.tab-speciaux .marche { color:var(--ink-3); font-size:11.5px; }
@media (max-width:640px) {
  /* Une ligne par periode ne tient pas sur un telephone : chaque periode
     devient une petite carte, chaque valeur sous son libelle. */
  .tab-speciaux thead { display:none; }
  .tab-speciaux tr { display:grid; grid-template-columns:1fr 1fr; gap:4px 12px;
                     padding:8px 0; border-bottom:1px solid var(--line-soft); }
  .tab-speciaux td { border:0; padding:0; white-space:normal; }
  .tab-speciaux td.per-nom { grid-column:1 / -1; font-weight:600; }
  .tab-speciaux td[data-libelle]::before { content:attr(data-libelle); display:block;
                     font-size:11px; font-weight:500; color:var(--ink-3); }
  .tab-speciaux td[data-libelle] .seuil { display:none; }
  .tab-speciaux td[data-libelle^="Le plus"] { grid-column:1 / -1; }
}

/* ---- Tableau de bord : graphiques SVG rendus cote serveur ---- */
.grille-2 { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr)); gap:var(--cardgap); }
.grille-2 > .card { margin-top:0; }
.grille-2 + .card, .card + .grille-2 { margin-top:var(--cardgap); }
.graphique { display:block; width:100%; height:auto; max-height:300px; }
.graphique.petit { max-width:360px; margin:0 auto 6px; }
.gr-grille { stroke:var(--line-soft); stroke-width:1; }
.gr-zero { stroke:var(--ink-3); stroke-width:1; stroke-dasharray:3 3; }
.gr-diag { stroke:var(--ink-3); stroke-width:1.2; stroke-dasharray:4 4; }
.gr-axe { fill:var(--ink-3); font:11px var(--mono); }
.gr-ligne { fill:none; stroke:var(--market); stroke-width:2.2; stroke-linejoin:round; }
.gr-ligne.proj { stroke-dasharray:6 4; }
.gr-point { fill:var(--surface); stroke:var(--market); stroke-width:1.6; }
.gr-bande { fill:var(--market); opacity:.16; }
.gr-barre.pos { fill:var(--edge); } .gr-barre.neg { fill:var(--crit); }
.gr-barre-err { stroke:var(--ink-3); stroke-width:1.6; }
.gr-bulle { fill:var(--market); fill-opacity:.55; stroke:var(--market); stroke-width:1.5; }
.gr-bulle.sur { fill:var(--crit); fill-opacity:.55; stroke:var(--crit); }
/* ---- Consolidation : lignes cliquables, chargement de la suite, detail en modale ---- */
tr.clic { cursor:pointer; }
tr.clic:hover, tr.clic:focus-visible { background:var(--sunken); outline:none; }
tr.clic:focus-visible { box-shadow:inset 2px 0 0 var(--accent); }
tr.suite td { text-align:center; padding:14px; }
.lien-suite { font:inherit; color:var(--accent-ink); background:none; border:1px solid var(--line);
  border-radius:var(--r2); padding:7px 14px; cursor:pointer; }
.lien-suite:hover { background:var(--accent-soft); }
.consolidation-detail .card.interne { box-shadow:none; margin-top:12px; }
.apercu-titre { margin:2px 0 6px; font-size:19px; }

/* ---- Tickets : coupons, verdicts, recherche par code ---- */
.code-ticket { font-family:var(--mono); font-weight:600; letter-spacing:.02em; }
.code-ticket .sub { font-family:var(--sans); font-weight:400; letter-spacing:0; display:block; }
.verdict { display:inline-block; white-space:nowrap; font:600 11.5px var(--sans); padding:2px 8px; border-radius:999px;
  background:var(--surface-2); color:var(--ink-2); }
.verdict.won { background:var(--edge-soft); color:var(--edge); }
.verdict.lost { background:var(--crit-soft); color:var(--crit); }
.verdict.push { background:var(--warn-soft); color:var(--warn); }
.jambe-courte { display:block; font-size:12.5px; color:var(--ink-2); }
.cases-verdict { display:flex; flex-wrap:wrap; gap:6px 14px; align-items:center; margin:0; }
.cases-verdict label { display:inline-flex; gap:6px; align-items:center; cursor:pointer; }
.cases-verdict input[type=checkbox] { width:16px; height:16px; margin:0; accent-color:var(--ink-2); cursor:pointer; }
.cases-verdict a { font-size:12.5px; color:var(--ink-3); }
.cases-verdict a:hover { color:var(--ink); }
.recherche-code { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin:0; }
.recherche-code input[type=search] { font:13px var(--mono); padding:6px 10px; width:11em;
  border:1px solid var(--line); border-radius:var(--r2); background:var(--surface); color:var(--ink);
  text-transform:uppercase; }
.recherche-code button { font:inherit; padding:6px 12px; border:1px solid var(--line);
  border-radius:var(--r2); background:var(--surface); color:var(--ink); cursor:pointer; }
.coupon .jambe { display:grid; grid-template-columns:1fr auto auto; gap:12px; align-items:center;
  padding:10px 0; border-bottom:1px solid var(--line-soft); }
.coupon .jambe .sub { display:block; margin:2px 0 0; }
.totaux-coupon { display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:10px;
  margin:14px 0 0; }
.totaux-coupon dt { font-size:12px; color:var(--ink-3); }
.totaux-coupon dd { margin:2px 0 0; font:600 17px var(--mono); }

/* ---- Banque de graphiques (banque.py) -----------------------------------
   Six teintes categoriques, valides (script validate_palette) sur les fonds
   reels de la console : clair #FFFFFF, sombre #151D1B. Une teinte par ENTITE,
   jamais par rang. Au-dela de six series : « Autres », pas une septieme teinte. */
:root { --serie-1:#2a78d6; --serie-2:#eb6834; --serie-3:#1baf7a; --serie-4:#eda100; --serie-5:#e87ba4; --serie-6:#008300; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --serie-1:#3987e5; --serie-2:#d95926; --serie-3:#199e70; --serie-4:#c98500; --serie-5:#d55181; --serie-6:#008300; }
}
:root[data-theme="dark"] { --serie-1:#3987e5; --serie-2:#d95926; --serie-3:#199e70; --serie-4:#c98500; --serie-5:#d55181; --serie-6:#008300; }
.gr-s1 { --c:var(--serie-1); } .gr-s2 { --c:var(--serie-2); } .gr-s3 { --c:var(--serie-3); }
.gr-s4 { --c:var(--serie-4); } .gr-s5 { --c:var(--serie-5); } .gr-s6 { --c:var(--serie-6); }

.gr-fig { margin:0; position:relative; }
.gr-sous { font-size:12.5px; color:var(--ink-3); margin:0 0 6px; }
.gr-legende { display:flex; flex-wrap:wrap; gap:4px 16px; list-style:none; margin:0 0 6px; padding:0;
  font-size:12.5px; color:var(--ink-2); }
.gr-legende li { display:inline-flex; align-items:center; gap:6px; }
.gr-legende i { width:12px; height:3px; border-radius:2px; background:var(--c); display:inline-block; }
.gr-trait { fill:none; stroke:var(--c); stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.gr-aire { fill:var(--c); opacity:.10; stroke:none; }
.gr-fin { fill:var(--c); stroke:var(--surface); stroke-width:2; }
.gr-nom { fill:var(--ink-2); font:13px var(--sans); }
.gr-val { fill:var(--ink); font:600 13px var(--mono); }
.gr-seg { fill:var(--c); stroke:var(--surface); stroke-width:2; paint-order:stroke; }
.gr-barre-s { fill:var(--c); }
.gr-pt { fill:var(--c); stroke:var(--surface); stroke-width:2; fill-opacity:.85; }
.gr-croix { stroke:var(--ink-3); stroke-width:1; opacity:0; pointer-events:none; }
.gr-repere { stroke:var(--ink-2); stroke-width:1.5; stroke-dasharray:4 3; }
.gr-case { fill:color-mix(in srgb, var(--serie-1) var(--part, 8%), var(--surface)); }
.gr-case.vide { fill:none; stroke:var(--line-soft); stroke-width:1; }
.gr-hit { fill:transparent; outline:none; cursor:crosshair; }
.gr-hit:focus-visible { stroke:var(--accent); stroke-width:1.5; }
.gr-fig:hover .gr-seg, .gr-fig:hover .gr-barre-s { opacity:.92; }
.gr-tableau { margin-top:8px; font-size:12.5px; }
.gr-tableau summary { cursor:pointer; color:var(--ink-3); }
.gr-tableau table { margin-top:6px; }

.gr-tip { position:fixed; z-index:60; pointer-events:none; max-width:280px; padding:8px 10px;
  background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:var(--r2);
  box-shadow:0 4px 18px rgba(0,0,0,.14); font:12.5px/1.45 var(--sans); }
.gr-tip b { display:block; font:600 13px var(--mono); }
.gr-tip span { display:block; color:var(--ink-2); }

.spark { width:120px; height:32px; display:block; }
.gr-spark { fill:none; stroke:var(--ink-3); stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.gr-spark-fin { fill:var(--accent); stroke:var(--surface); stroke-width:2; }
.tuile { display:flex; flex-direction:column; gap:3px; padding:14px 16px; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r2); min-width:0; }
.tuile-lib { font-size:12.5px; color:var(--ink-3); }
.tuile-val { font:600 26px/1.1 var(--sans); letter-spacing:-.02em; }
.tuile-delta { font:600 12.5px var(--mono); color:var(--ink-2); }
.tuile-delta.bon { color:var(--edge); } .tuile-delta.mauvais { color:var(--crit); }
.tuile-note { font-size:12px; color:var(--ink-3); }
.tuiles { margin-bottom:var(--cardgap); display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:var(--cardgap); }

.gr-jauge { display:flex; flex-direction:column; gap:6px; }
.gr-jauge-tete { display:flex; justify-content:space-between; font-size:13px; }
.gr-jauge-piste { height:10px; border-radius:6px; background:var(--market-soft); overflow:hidden; }
.gr-jauge-plein { height:100%; border-radius:6px; background:var(--market); }
.gr-jauge-plein.alerte { background:var(--warn); } .gr-jauge-plein.critique { background:var(--crit); }
.gr-jauge-pied { font-size:12px; color:var(--ink-3); }
.grille-jauges { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:18px 24px; }
.exemple + .exemple { margin-top:var(--cardgap); }
.exemple-code { margin:12px 0 0; padding:9px 12px; background:var(--sunken); border:1px solid var(--line-soft);
  border-radius:var(--r2); font:12.5px/1.5 var(--mono); overflow-x:auto; color:var(--ink-2); }
.exemple .tuile { max-width:260px; } .exemple .gr-jauge { max-width:420px; }

.gr-fig .gr-axe { font-size:13px; }
tbody.suite .suite-cellule { text-align:center; padding:14px; }
.suite-bloc { text-align:center; padding:14px 0; }

/* --- Pages de compte (connexion, invitation, double facteur) ----------- */
.compte-page { max-width:440px; margin:8vh auto; padding:0 20px 40px; }
.compte-carte { margin-top:16px; }
.compte-carte h1, .compte-carte h2 { font-size:18px; margin:0 0 12px; }
.compte-carte p { margin:0 0 10px; }
.compte-carte label { display:block; font-size:13px; color:var(--ink-3); margin-bottom:4px; }
.compte-carte input:not([type=checkbox]):not([type=hidden]) { width:100%; box-sizing:border-box;
  padding:9px 10px; border:1px solid var(--line); border-radius:var(--r1);
  background:var(--surface); color:var(--ink); font:inherit; }
.compte-carte button, .compte-carte a[role=button] { width:100%; padding:10px; margin-top:6px; border:0;
  border-radius:var(--r1); background:var(--accent); color:var(--btn-ink); font:inherit; font-weight:600; cursor:pointer; }
.compte-menu { display:flex; flex-wrap:wrap; gap:6px 14px; margin-top:12px; font-size:13.5px; }
.compte-actions { display:flex; flex-wrap:wrap; gap:6px; }

/* --- Aujourd'hui, ligues repliables ------------------------------------ */
.ligue-carte > summary { cursor:pointer; list-style:none; }
.ligue-carte > summary::-webkit-details-marker { display:none; }
details.repli > summary.bloc-tete { cursor:pointer; list-style:none; }
details.repli > summary.bloc-tete::-webkit-details-marker { display:none; }
details.repli > summary.bloc-tete::after { content:"▾"; color:var(--ink-3); margin-left:8px; }
details.repli[open] > summary.bloc-tete::after { content:"▴"; }
.occasions { list-style:none; margin:0; padding:0; }
.occasions li + li { border-top:1px solid var(--line); }
.occasions a { display:flex; flex-wrap:wrap; justify-content:space-between; gap:2px 12px; padding:10px 0;
               text-decoration:none; color:inherit; }
.occasions .sous { flex:1 1 100%; }
.filtre-sport { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 12px; }
.filtre-sport button { padding:5px 11px; border:1px solid var(--line); border-radius:999px;
                       background:var(--surface); color:var(--ink-2); font:inherit; font-size:13px; cursor:pointer; }
.filtre-sport button.on { background:var(--accent-soft); border-color:var(--accent); color:var(--ink); font-weight:600; }
#direct:not(.tout) details.ligue-carte:nth-of-type(n+41) { display:none; }
#direct.tout .voir-tout { display:none; }
.voir-tout { display:block; width:100%; margin-top:10px; }

/* --- Fiche en onglets, grille des scores, barres ----------------------- */
.onglets-fiche { position:sticky; top:var(--haut); z-index:20; display:flex; gap:4px; margin:0 -4px 14px;
                 padding:6px 4px; background:var(--ground); overflow-x:auto; }
.onglets-fiche button { flex:0 0 auto; padding:7px 14px; border:0; border-radius:var(--r1); background:transparent;
                        color:var(--ink-2); font:inherit; font-size:14px; cursor:pointer; }
.onglets-fiche button.on { background:var(--surface-3); color:var(--ink); font-weight:600; }
.grille-scores { display:grid; grid-template-columns:auto repeat(6,minmax(28px,1fr)); gap:2px; font-size:11.5px;
                 font-family:var(--mono); margin:8px 0 12px; max-width:340px; }
.gs-axe { text-align:center; color:var(--ink-3); align-self:center; }
.gs-coin { font-size:10px; color:var(--ink-3); font-family:var(--sans); white-space:nowrap; align-self:center; }
.gs-case { text-align:center; padding:5px 0; border-radius:3px;
           background:color-mix(in srgb, var(--accent) calc(var(--p) * 75%), transparent); }
.duel { display:block; max-width:220px; margin-top:6px; }
.duel i { display:block; height:5px; border-radius:2px; margin-top:2px; max-width:100%; }
.duel .m { background:var(--accent); }
.duel .q { background:var(--ink-3); opacity:.55; }
.conf-forte { color:var(--edge); border-color:currentColor; }
.conf-moyenne { color:var(--ink-2); }
.conf-faible { color:var(--crit); border-color:currentColor; }

/* --- Recherche, filtres, pages publiques ------------------------------- */
.recherche-haut input { width:210px; padding:6px 10px; border:1px solid var(--line); border-radius:var(--r1);
                        background:var(--surface); color:var(--ink); font:inherit; font-size:13.5px; }
.filtres-repli > summary { display:none; }
.compte-page.large { max-width:980px; }
@media (max-width:1023px) {
  .recherche-haut { display:none; }
  .filtres-repli > summary { display:block; padding:8px 0; font-weight:600; cursor:pointer; }
}

.etoile-form { margin:0; }
.etoile { border:0; background:transparent; color:var(--ink-3); font-size:16px; line-height:1; cursor:pointer; padding:0 2px; }
.etoile.on { color:var(--accent); }
@media (max-width:1023px) {
  .alerte-detail { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
}
