/* BookmakerCup - feuille de style mobile-first */
/* Police Inter, auto-hebergee (fichier variable = toutes les graisses dans un seul .woff2).
   Plus pleine et lisible que la police systeme (Segoe UI) sur Windows. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('../fonts/InterVariable.woff2') format('woff2');
}
@font-face {
    font-family: 'Inter';
    font-style: italic;
    font-weight: 100 900;
    font-display: swap;
    src: url('../fonts/InterVariable-Italic.woff2') format('woff2');
}
:root {
    /* Thème SOMBRE par défaut : dit au navigateur de rendre les controles NATIFS (scrollbars, selects, date-pickers)
       en sombre. Effet visé : le scrollbar horizontal (chips J1/J2, frises) a une PISTE fondue au fond sombre + un
       ascenseur/flèches CLAIRS, au lieu du scrollbar clair par défaut du navigateur (piste blanche moche sur fond
       sombre). Garde le scrollbar CLASSIQUE (avec flèches), juste re-teinté. Symétrique 'light' plus bas. */
    color-scheme: dark;
    --accent: #1f8a4c;
    --accent-2: #2bb061;       /* vert vif : FONDS (boutons actifs, pastilles) */
    --accent-ink: #33c06e;     /* vert TEXTE sombre : 8:1 sur --bg (avant #2bb061 6.7:1) ; clair garde #137a3a */
    --on-accent: #fff;         /* couleur du TEXTE pose SUR un fond --accent : blanc par defaut (vert Mondial,
                                  rouge Vuelta, bleu CL) ; le Tour (jaune clair) la passe a #1a1a1a. */
    --scoremigos-yellow: #f5c518; /* jaune VIF du logo ScoreMigos (le "Migos") : boutons du Tour */
    --bg: #0f1115;
    --card: #171a21;
    --card-2: #1e222b;
    --text: #d9dee6;           /* off-white ~87% (norme Material high-emphasis) : 14:1 sur --bg, sans l'eblouissement/halation du blanc quasi pur #e7e9ee (avant 15.6:1) */
    --muted: #bcc4d1;          /* secondaire : 9.9:1 sur --card, deja ideal (au-dela du medium-emphasis) */
    --border: #707b96;         /* contours nettement visibles : 4.1:1 vs --card, 3.8:1 vs --card-2, 4.5:1 vs --bg (au-dela du mini WCAG 1.4.11 = 3:1 ; avant #646e88 3.4:1, #3f4756 1.9:1) */
    --danger: #d9534f;
    --warn: #d9a441;
    --ok: #1f8a4c;
    --radius: 12px;
}
/* ── THÈMES COULEUR PAR COMPÉTITION (data-comp sur <html>, posé par le layout via Sport::themeKey()) ──
   On ne surcharge QUE les variables d'accent : tout le design (composants, layout) reste COMMUN, donc
   améliorer un composant profite à TOUTES les compétitions ; seule la couleur d'identité change ici.
   --accent-2 (remplissages/boutons) volontairement VIF -> le texte foncé des boutons reste lisible sans
   toucher une seule règle de bouton ; l'identité profonde est portée par --accent-ink (texte/liens/titres).
   Contraste vérifié en SOMBRE (défaut) et CLAIR (--accent-ink foncé en light). Tour=jaune, Vuelta=rouge, CL=bleu. */
/* Remplissages VIFS (le texte foncé des boutons vélo, herité de .theme-cyc, reste lisible sans changer une
   regle). Tour = valeurs EXACTES de l'ancien .theme-tour (aucun changement visuel Tour). Vuelta = rouge vif,
   CL = bleu vif. L'identite profonde est aussi portee par --accent-ink (texte/liens). */
html[data-comp="tour"]   { --accent: var(--scoremigos-yellow); --accent-2: #e6b800; --accent-ink: #f2c94c; --on-accent: #1a1a1a; }
html[data-comp="vuelta"] { --accent: #ff5a6b; --accent-2: #ff4d5e; --accent-ink: #ff6b7d; }
html[data-comp="cl"]     { --accent: #5b9bff; --accent-2: #4d8bff; --accent-ink: #6ba4ff; }
/* COMPTE À REBOURS teinté PAR COMPÉTITION (Jonathan 21/07 : le vert fixe jurait, ex CL toute bleue).
   Le compteur garde son fond SOMBRE premium (identique clair/sombre) : les couleurs restent donc VIVES
   (lisibles sur sombre) et indépendantes du thème -> définies ici sans variante [data-theme]. Défaut
   (Mondial, sans data-comp) = vert historique, posé en fallback dans .cd-box. */
html[data-comp="tour"]   { --cd-fg: #f2c94c; --cd-glow: rgba(242,201,76,.55); --cd-bg: linear-gradient(165deg,#4a3a0c,#12100a); --cd-border: rgba(230,184,0,.5);  --cd-sep: rgba(242,201,76,.5); }
html[data-comp="vuelta"] { --cd-fg: #ff6b7d; --cd-glow: rgba(255,90,107,.55); --cd-bg: linear-gradient(165deg,#4d1c24,#130a0c); --cd-border: rgba(255,77,94,.5);  --cd-sep: rgba(255,107,125,.5); }
html[data-comp="cl"]     { --cd-fg: #6ba4ff; --cd-glow: rgba(91,155,255,.55); --cd-bg: linear-gradient(165deg,#16305d,#0a0f1a); --cd-border: rgba(77,139,255,.5); --cd-sep: rgba(107,164,255,.5); }
/* US Open : chartreuse (balle de tennis). Sur html[data-comp] ET le wrapper .tennis-wrap[data-comp="usopen"]
   (la carte concours tennis) pour que le compteur soit bien aux tons usopen. (Jonathan 25/07.) */
html[data-comp="usopen"], [data-comp="usopen"] { --cd-fg: #d7e84e; --cd-glow: rgba(204,221,51,.5); --cd-bg: linear-gradient(165deg,#3a400d,#12130a); --cd-border: rgba(182,199,42,.5); --cd-sep: rgba(215,232,78,.5); }
/* MODE CLAIR : il FAUT redéfinir --accent aussi (sinon html[data-theme="light"] plus bas, même
   spécificité, repose --accent au vert par défaut -> Tour/CL/Vuelta redevenaient VERTS en clair,
   bug 19/07). Spécificité (0,2,1) > (0,1,1) : gagne quel que soit l'ordre. */
html[data-theme="light"][data-comp="tour"]   { --accent: var(--scoremigos-yellow); --accent-2: #c79a00; --accent-ink: #9c7500; --on-accent: #1a1a1a; }
html[data-theme="light"][data-comp="vuelta"] { --accent: #d81f3a; --accent-2: #d10a2a; --accent-ink: #c00020; }
html[data-theme="light"][data-comp="cl"]     { --accent: #2f6fd0; --accent-2: #2f6fd0; --accent-ink: #0a3fa0; }
/* Signal PROMINENT par competition (visible sur TOUTES les pages, impossible a rater) : liseré coloré de
   3px sous la barre de nav. Couleur = --accent-2 de la competition (rouge Vuelta, jaune Tour, bleu CL). */
html[data-comp] .topbar { border-bottom: 3px solid var(--accent-2); }
/* Immersion douce : le contour des boutons 'ghost' (actions en contour) se teinte de la couleur de la
   competition (rougeatre Vuelta, doré Tour, bleu CL), plus franc au survol. Mondial (sans data-comp) = neutre. */
html[data-comp] .btn-ghost { border-color: color-mix(in srgb, var(--accent-2) 45%, var(--border)); }
html[data-comp] .btn-ghost:hover { border-color: var(--accent-2); }
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
    font-family: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 1.08rem;   /* texte de lecture plus grand (moins fatigant) */
    font-weight: 450;     /* un peu moins fin que le 400 par defaut */
    line-height: 1.6;
    /* Garde-fou anti-decalage horizontal : si un element deborde d'un poil (ex. carte de pool a beaucoup de chips
       sur mobile etroit), on CLIPPE le debordement au lieu de decaler toute la page. 'clip' (et pas 'hidden') ne
       cree PAS de conteneur de defilement -> le header position:sticky reste intact. Repli 'visible' si non supporte. */
    overflow-x: clip;
}
a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Barre de navigation */
.topbar {
    display: flex; align-items: center; justify-content: flex-start;
    gap: 1rem; padding: .7rem 1rem; background: #050505; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; z-index: 10; flex-wrap: wrap;
}
.brand { font-weight: 700; font-size: 1.15rem; color: var(--text); display: flex; align-items: center; }
.brand-logo { height: 44px; width: auto; display: block; } /* 54 -> 44 (13/07 soir) : le header standard tient sur UNE ligne */
.nav { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin-left: auto; }
.topbar-actions { display: flex; align-items: center; gap: .7rem; } /* .5 -> .7rem (14/07) : plus d'air entre megaphone / theme / etoile pour que le "A" auto et les pastilles en coin ne touchent plus le bouton voisin */
/* Fenetre moyenne : la nav descend seule sur sa ligne (centree), profil+icones restent en haut a droite */
@media (max-width: 1520px) and (min-width: 641px) {
    .topbar { row-gap: .4rem; }
    .nav { order: 5; flex-basis: 100%; margin-left: 0; justify-content: center; border-top: 1px solid rgba(255,255,255,.07); padding-top: .45rem; }
    .topbar-actions { margin-left: auto; }
}
/* BARRE super-admin (13/07 soir) : tout l'outillage super (pills de vue, oeil panneaux, chrono voyage
   dans le temps) sur SA ligne dediee du header -> la 1re ligne reste celle de tout le monde. */
.sa-head-switch { display: inline-flex; align-items: center; gap: .12rem; padding: .12rem .28rem; border: 1px solid #b45309; border-radius: 8px; background: rgba(180,83,9,.10); }
.topbar > .sa-head-switch { order: 30; flex-basis: 100%; flex-wrap: wrap; gap: .3rem; }
.sa-head-switch .tt-switch { width: 32px; height: 30px; font-size: .95rem; margin-left: .15rem; }
.sa-head-switch .sa-hideprev { margin-left: auto; } /* oeil + chrono ranges a droite de la barre super */
.sa-head-eye { font-size: .8rem; margin: 0 .12rem; opacity: .85; background: none; border: none; cursor: pointer; padding: .05rem .15rem; border-radius: 5px; line-height: 1; }
.sa-head-eye:hover { opacity: 1; background: rgba(180,83,9,.18); }
.sa-head-pills { display: inline-flex; align-items: center; gap: .12rem; }
/* Replie : seul l'oeil reste (header compact, ancrages nickel). Clic sur l'oeil = re-deplie. */
.sa-head-switch.sa-collapsed { padding: .05rem .1rem; }
.sa-head-switch.sa-collapsed .sa-head-pills { display: none; }
.sa-head-switch.sa-collapsed .sa-head-eye { opacity: .55; }
.sa-hbtn { font-size: .72rem; font-weight: 800; padding: .12rem .42rem; border-radius: 6px; color: var(--muted); text-decoration: none; line-height: 1.5; }
.sa-hbtn.on { background: #b45309; color: #fff; }
.sa-nostats { border: 1px solid var(--border); }
.sa-nostats.on { background: #b91c1c; color: #fff; border-color: #b91c1c; } /* compte exclu des stats : rouge */
.sa-hbtn:hover { color: var(--text); text-decoration: none; }
@media (max-width: 700px) { .sa-head-switch { order: -1; padding: .1rem .2rem; } .sa-hbtn { padding: .1rem .34rem; font-size: .68rem; } }
.topbar-tools { display: flex; align-items: center; gap: .4rem; }
/* Connexion / Inscription : toujours visibles dans le header (hors hamburger), y compris deconnecte sur mobile.
   La barre est sombre dans les deux themes -> on force des couleurs claires pour le bouton fantome. */
.topbar-auth { display: inline-flex; align-items: center; gap: .4rem; }
.topbar-auth .btn-ghost { color: #dfe4ec; border-color: rgba(255,255,255,.28); background: transparent; }
.topbar-auth .btn-ghost:hover { color: #fff; border-color: rgba(255,255,255,.5); background: rgba(255,255,255,.06); }
/* Bouton super-admin : afficher / masquer le panneau « Voyage dans le temps » (beta) */
.tt-switch { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #e7e9ee; cursor: pointer; padding: 0; font-size: 1.05rem; line-height: 1; -webkit-tap-highlight-color: transparent; }
.tt-switch:hover { border-color: var(--accent-2); }
.tt-switch.on { background: rgba(235,87,87,.22); border-color: #eb5757; color: #fff; }
/* Etoile « concours favori » dans le header (barre sombre dans les 2 modes) */
.fav-btn { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #c6ccd6; -webkit-tap-highlight-color: transparent; }
.fav-btn:hover { border-color: var(--accent-2); color: #fff; text-decoration: none; }
.fav-btn.on { color: #f2c94c; } /* etoile favorite : chrome NEUTRE comme les 3 autres boutons (coherence header) ; le remplissage dore de l'etoile suffit a marquer l'etat favori */
/* Oeil de REVEIL super-admin (#7) : apparait pres de l'etoile quand tout le mode super est masque (bouton singe).
   Teinte ambre pour le distinguer, discret mais reperable. Clic -> re-affiche toute l'UI super. */
.sa-reveal { color: #fbbf24; border-color: rgba(180,83,9,.5); background: rgba(180,83,9,.12); }
.sa-reveal:hover { color: #fff; border-color: var(--accent-2); background: rgba(180,83,9,.2); }
/* Point d'interrogation AIDE (header, desktop). Meme gabarit que les autres icones. Masque en mobile
   (.hide-mobile) : la version mobile passe par le lien "Aide" du menu deroulant. */
.help-btn { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #c6ccd6; -webkit-tap-highlight-color: transparent; }
.help-btn:hover { border-color: var(--accent-2); color: #fff; text-decoration: none; }
/* Déconnexion : petite icône (porte + flèche) à côté du profil, même gabarit que le point d'aide. */
.nav-logout-form { display: inline-flex; margin: 0; }
.nav-logout { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #c6ccd6; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.nav-logout:hover { border-color: var(--accent-2); color: #fff; }
/* Le header est TOUJOURS sombre (#050505) dans les DEUX themes : le bouton logout garde donc EXACTEMENT le
   meme style clair-sur-sombre en mode clair qu'en mode sombre (comme .help-btn/.fav-btn/.nav-bell, sans
   override clair). Avant : un override clair rendait son interieur trop sombre sur le header sombre. */
@media (max-width: 640px) { .hide-mobile { display: none !important; } }
/* Inverse de .hide-mobile : visible UNIQUEMENT sur mobile (dans le menu burger). Sert a la Deconnexion :
   icone a cote du profil sur DESKTOP (place gagnee), en toutes lettres dans le MENU sur mobile (les gens se
   deconnectent rarement -> pas la peine de manger de la place dans le header mobile). Demande Jonathan 14/07. */
.show-mobile { display: none !important; } /* !important comme .hide-mobile : sinon .inline (form Deconnexion) le reaffiche sur PC (bug Jonathan 15/07) */
@media (max-width: 640px) { .show-mobile { display: block !important; } }
.nav .nav-logout-menu-btn { background: none; border: none; cursor: pointer; font: inherit; color: var(--muted); text-align: left; }
/* Cloche de notification (header) : demandes d'acces en attente sur mes concours. Pastille rouge + compteur. */
.nav-bell { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18); color: #c6ccd6;
    -webkit-tap-highlight-color: transparent; }
.nav-bell:hover { border-color: var(--accent-2); color: #fff; text-decoration: none; }
.nav-bell-count { position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: #e0414b;
    color: #fff; font-size: .64rem; font-weight: 800; line-height: 1; box-shadow: 0 0 0 2px var(--bg); }
/* Banniere "Demandes d'acces" tout en haut de Mes concours : une ligne par demande + Accepter / Refuser. */
.access-req-dash .access-req-item { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: .6rem; padding: .55rem 0; border-top: 1px solid var(--border); }
.access-req-dash .access-req-item:first-of-type { border-top: 0; }
.access-req-dash .access-req-who { min-width: 0; }
.access-req-dash .access-req-btns { display: flex; gap: .4rem; white-space: nowrap; }
.access-req-dash .access-msg { font-style: italic; }
/* Bouton « definir comme favori » sur la page concours */
.fav-toggle { display: inline-flex; align-items: center; gap: .3rem; background: var(--card-2);
    border: 1px solid var(--border); border-radius: 999px; padding: .25rem .6rem; color: var(--muted);
    cursor: pointer; font: inherit; font-size: .82rem; font-weight: 600; white-space: nowrap; }
.fav-toggle:hover { border-color: #f2c94c; color: var(--text); }
.fav-toggle.on { color: #f2c94c; border-color: rgba(242,201,76,.6); background: rgba(242,201,76,.14); }
/* (12/07) PURGE CSS MORT : les pastilles lettrees de l'ancien groupe Communication (comm-dot-n/c/d/i/di,
   comm-grp-badges, cgb-*, comm-dot-plain) n'etaient plus emises par aucune vue depuis la refonte "boutons
   de carte". Remplacees par les pastilles NUMERIQUES (.n-badge, plus bas). */
/* Onglet Information de l'administrateur : formulaire de publication + articles */
.info-post-form { margin: .4rem 0 .9rem; }
.info-post-form textarea { width: 100%; resize: vertical; }
.info-item { border-top: 1px solid var(--border); padding: .6rem 0; }
.info-item-meta { font-size: .8rem; opacity: .7; margin-bottom: .25rem; }
.info-item-body { line-height: 1.5; }
/* Pastille "Vu par N" : admin de groupe = nombre seul (span) ; super-admin = bouton cliquable -> popup.
   Reservee a l'admin (Info admin + Comptes rendus) et au super-admin (partout). */
.seen-widget { display: inline-flex; align-items: center; gap: .3rem; margin: .5rem 0 .2rem; font-size: .82rem;
    color: var(--muted); font-weight: 600; }
.seen-eye { opacity: .75; }
.seen-count { /* admin : non cliquable */ }
button.seen-trigger { cursor: pointer; border: 1px solid var(--border); background: var(--card, transparent);
    border-radius: 999px; padding: .15rem .6rem; color: var(--muted); font: inherit; font-weight: 600; }
button.seen-trigger:hover { border-color: #5b8def; color: var(--text); }
.seen-section { margin-top: 1rem; }
/* Modale "Qui a consulte" (super-admin) : reutilise l'overlay .inv-modal, contenu rempli par JS. */
.seen-modal-card { max-width: 460px; }
.seen-modal-title { margin: 0 0 .6rem; }
.seen-modal-count { font-weight: 700; margin: 0 0 .5rem; }
.seen-modal-body { max-height: 60vh; overflow-y: auto; }
/* Une entree PAR PERSONNE : "nom (nb)" depliable -> tous ses horaires (avec secondes). */
.seen-person { border-bottom: 1px solid var(--border); }
.seen-person > summary { cursor: pointer; display: flex; align-items: baseline; gap: .5rem;
    padding: .35rem 0; list-style: none; }
.seen-person > summary::-webkit-details-marker { display: none; }
.seen-person > summary .seen-name { font-weight: 600; }
.seen-person > summary .seen-person-count { color: var(--muted); font-weight: 700; }
.seen-person > summary::after { content: '\25BE'; margin-left: auto; color: var(--muted); transition: transform .15s; }
.seen-person[open] > summary::after { transform: rotate(180deg); }
.seen-person-times { list-style: none; margin: 0 0 .45rem; padding: 0 0 0 .3rem;
    display: flex; flex-direction: column; gap: .12rem; }
.seen-person-times li { font-size: .82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.seen-modal-trunc { margin: .5rem 0 0; font-size: .76rem; color: var(--muted); font-style: italic; }
/* Note "entree tardive" depliable dans la page Long terme. */
.futures-late-note { margin: .2rem 0 .8rem; border: 1px solid var(--border); border-radius: 8px; padding: .4rem .7rem; background: var(--card-2); }
.futures-late-note > summary { cursor: pointer; font-weight: 700; font-size: .86rem; color: #5b8def; list-style: none; }
.futures-late-note > summary::-webkit-details-marker { display: none; }
.futures-late-note > summary::before { content: '\2139\FE0F'; margin-right: .35rem; }
.futures-late-note p { margin: .45rem 0 .1rem; line-height: 1.5; }
/* Banniere URGENCE sur la page Long terme : le joueur peut encore saisir mais ne l'a pas (complètement) fait. */
.futures-urgent { margin: .2rem 0 1rem; border: 2px solid #ef4444; border-radius: 10px; padding: .7rem .9rem;
    background: rgba(239,68,68,.12); animation: futures-urgent-pulse 1.1s ease-in-out infinite; }
.futures-urgent-title { font-weight: 800; font-size: 1.02rem; color: #ef4444; letter-spacing: .01em; }
.futures-urgent-body { margin: .3rem 0 0; line-height: 1.5; font-weight: 600; }
@keyframes futures-urgent-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239,68,68,.0); border-color: #ef4444; }
    50%      { box-shadow: 0 0 0 4px rgba(239,68,68,.18); border-color: #f87171; }
}
@media (prefers-reduced-motion: reduce) { .futures-urgent { animation: none; } }
/* Variante ACCUEIL (nouveau venu) : verte, positive, sans pulsation rouge -> "commence par ici". */
.futures-urgent-welcome { border-color: var(--accent-2); background: rgba(43,176,97,.10); animation: none; }
.futures-urgent-welcome .futures-urgent-title { color: var(--accent-ink); }
/* Etape suivante (onboarding) : pronos du tournoi complets -> bouton vers les matchs. */
.futures-next { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .7rem;
    margin: .2rem 0 1rem; border: 2px solid var(--accent-2); border-radius: 10px; padding: .7rem .9rem; background: rgba(43,176,97,.12); }
.futures-next.is-hidden { display: none; }
.futures-next-txt { font-weight: 800; color: var(--accent-ink); }
.futures-next-btn { background: var(--accent-2); color: #04130a; font-weight: 800; white-space: nowrap; }
.futures-next-btn:hover { background: var(--accent); color: var(--on-accent); text-decoration: none; }
/* Page d'inscription = page de CHOIX : le compte complet (e-mail) est replie, discret. */
.reg-full summary { cursor: pointer; color: var(--accent-ink); font-weight: 700; text-align: center; padding: .55rem; list-style: none; border: 1px solid var(--border); border-radius: 8px; }
html[data-theme="light"] .reg-full summary { border-color: #97a3b2; }
.reg-full summary:hover { border-color: var(--accent-2); }
.reg-full summary::-webkit-details-marker { display: none; }
.reg-full[open] summary { margin-bottom: .2rem; }
/* Rappel GLOBAL (toutes les pages) : pronos du tournoi non remplis + saisie encore possible. Fermable. */
.futures-nudge { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .7rem;
    margin: .7rem auto 0; max-width: 1100px; padding: .55rem .9rem; border-radius: 10px;
    background: rgba(239,68,68,.14); border: 2px solid #ef4444; animation: futures-urgent-pulse 1.2s ease-in-out infinite; }
.futures-nudge[hidden] { display: none; }
.futures-nudge-txt { font-weight: 700; }
/* Point A.3 : font/line-height explicites + border transparent (box-border) pour que le <button> "Ne plus
   afficher" ait EXACTEMENT la meme taille que les <a> voisins (un <button> herite sinon d'une font plus petite). */
.futures-nudge-btn { background: #ef4444; color: #fff; text-decoration: none; padding: .38rem .9rem; border-radius: 8px; font-family: inherit; font-size: 1rem; font-weight: 800; line-height: 1.4; white-space: nowrap; cursor: pointer; border: 1.5px solid transparent; box-sizing: border-box; }
.futures-nudge-btn:hover { background: #dc2626; text-decoration: none; }
.futures-nudge-close { background: none; border: none; color: var(--muted); font-size: 1.35rem; cursor: pointer; line-height: 1; padding: 0 .15rem; }
@media (prefers-reduced-motion: reduce) { .futures-nudge { animation: none; } }
/* Variante ADMIN du rappel : ambre (pas rouge urgent), sans pulsation -> "tu peux rouvrir les pronos". */
/* Banniere d'ACCUEIL (nouveau venu) : verte, positive, sans pulsation rouge. Bienvenue + mets tes pronos. */
.futures-nudge-welcome { background: rgba(43,176,97,.16); border-color: var(--accent-2); animation: none; }
.futures-nudge-welcome .futures-nudge-btn { background: var(--accent-2); color: #04130a; }
.futures-nudge-welcome .futures-nudge-btn:hover { background: var(--accent); color: var(--on-accent); }
.futures-nudge-admin { background: rgba(245,158,11,.14); border-color: #f59e0b; animation: none; }
.futures-nudge-admin .futures-nudge-btn { background: #f59e0b; color: #3a2600; }
.futures-nudge-admin .futures-nudge-btn:hover { background: #d97706; color: #3a2600; }
/* 2e action de la banniere admin (Voir les membres) : secondaire, en contour. */
.futures-nudge-admin .futures-nudge-btn-ghost { background: transparent; color: #7a4f00; border: 1.5px solid #d97706; }
.futures-nudge-admin .futures-nudge-btn-ghost:hover { background: rgba(217,119,6,.14); color: #7a4f00; }
html:not([data-theme="light"]) .futures-nudge-admin .futures-nudge-btn-ghost,
html:not([data-theme="light"]) .futures-nudge-admin .futures-nudge-btn-ghost:hover { color: #fbbf24; } /* 13/07 : ambre clair lisible sur fond sombre */
/* Rappel NON BLOQUANT de verification e-mail (1B) : ambre, sobre, fermable. */
.verify-nudge { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .7rem;
    margin: .7rem auto 0; max-width: 1100px; padding: .5rem .9rem; border-radius: 10px;
    background: rgba(245,158,11,.13); border: 1px solid #f59e0b; }
.verify-nudge[hidden] { display: none; }
.verify-nudge-txt { font-weight: 600; }
.verify-nudge-btn { background: #f59e0b; color: #3a2600; text-decoration: none; padding: .3rem .8rem; border-radius: 8px; font-weight: 800; white-space: nowrap; }
.verify-nudge-btn:hover { background: #d97706; color: #3a2600; text-decoration: none; }
.verify-nudge-close { background: none; border: none; color: var(--muted); font-size: 1.3rem; cursor: pointer; line-height: 1; padding: 0 .15rem; }
.verify-nudge-link { color: inherit; font-weight: 700; text-decoration: underline; white-space: nowrap; }
/* SUR TELEPHONE, UNE LIGNE (03/09). Vu sur les captures de la campagne URSIB : ce rappel plus la
   banniere Champions League remplissaient tout le premier ecran, zero contenu avant de scroller.
   Ici : texte court, bouton court, et JAMAIS deux bannieres empilees : tant que ce rappel est visible,
   la promo attend la page suivante (:has, ignore par les vieux navigateurs : ils gardent l'ancien
   empilement, rien ne casse). Le grand ecran garde la version complete. */
.verify-nudge-txt-m, .verify-nudge-btn-m { display: none; }
@media (max-width: 640px) {
    .verify-nudge { flex-wrap: nowrap; gap: .45rem; margin-top: .4rem; padding: .35rem .6rem; font-size: .84rem; }
    .verify-nudge-txt, .verify-nudge-link, .verify-nudge-btn-full { display: none; }
    .verify-nudge-txt-m { display: inline; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                          min-width: 0; flex: 1 1 auto; }
    .verify-nudge-btn { padding: .25rem .6rem; font-size: .8rem; flex: 0 0 auto; }
    .verify-nudge-btn-m { display: inline; }
    body:has(.verify-nudge:not([hidden])) :is(.clp-promo, .tp-promo, .tp-small) { display: none; }
}
/* Banniere d'information globale (super-admin) : tout en haut, bien visible, fermable. */
.site-banner { display: flex; align-items: flex-start; gap: .6rem; margin: .7rem auto 0; max-width: 1100px; padding: .65rem .9rem;
    border-radius: 10px; background: rgba(43,176,97,.14); border: 1px solid var(--accent-2); line-height: 1.4; }
.site-banner[hidden] { display: none; }
.site-banner-ico { font-size: 1.15rem; line-height: 1.3; flex: 0 0 auto; }
.site-banner-txt { flex: 1 1 auto; font-weight: 600; }
.site-banner-ok { background: var(--accent-2); color: #04130a; border: 1px solid var(--accent-2); border-radius: 8px; font-weight: 800; padding: .25rem .85rem; cursor: pointer; flex: 0 0 auto; white-space: nowrap; align-self: center; }
.site-banner-ok:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.site-banner-close { background: none; border: none; color: var(--muted); font-size: 1.3rem; cursor: pointer; line-height: 1; padding: 0 .15rem; flex: 0 0 auto; }
.site-banner-blink { animation: site-banner-pulse 1.3s ease-in-out infinite; }
@keyframes site-banner-pulse { 0%, 100% { border-color: var(--accent-2); box-shadow: 0 0 0 0 rgba(43,176,97,.0); } 50% { border-color: #6ee7a8; box-shadow: 0 0 0 3px rgba(43,176,97,.22); } }
@media (prefers-reduced-motion: reduce) { .site-banner-blink { animation: none; } }
/* Onboarding "invite-first" (page d'arrivee) : coche Mondial, encart recap, lien "jouer direct", bandeau apercu. */
.onb-mondial-check { display: flex; align-items: flex-start; gap: .5rem; margin: .2rem 0 .8rem; font-size: .92rem; cursor: pointer; }
.onb-mondial-check input { margin-top: .2rem; flex: 0 0 auto; }
.onb-recap-note { display: flex; gap: .4rem; align-items: flex-start; margin: .9rem 0 .3rem; padding: .5rem .7rem; border-radius: 8px;
    background: rgba(43,176,97,.1); border: 1px solid var(--accent-2); font-size: .88rem; }
.onb-alt { text-align: center; margin: .4rem 0 0; font-size: .9rem; }
.onb-preview-banner { margin: 0 0 .6rem; padding: .35rem .6rem; border-radius: 8px; background: rgba(245,158,11,.15);
    border: 1px solid #f59e0b; font-weight: 700; font-size: .85rem; text-align: center; }
/* Resume "N avec du nouveau" sur l'en-tete du dashboard : cliquable (mene au concours clignotant le plus
   haut). MOINS intrusif : la pastille ne clignote PLUS, seul un petit dot orange pulse (meme rythme 1s). */
.dash-new-pill { display: inline-flex; align-items: center; gap: .35rem; font-size: .72rem; font-weight: 800; vertical-align: middle;
    margin-left: .5rem; padding: .14rem .6rem; border-radius: 999px; background: #ea580c; border: 1px solid #c2410c; color: #fff;
    white-space: nowrap; text-decoration: none; transition: background .1s ease; }
.dash-new-pill:hover { background: #c2410c; color: #fff; text-decoration: none; }
.dash-new-dot { width: 8px; height: 8px; border-radius: 50%; background: #fff; flex: 0 0 auto; animation: md-dot-blink 1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .dash-new-dot { animation: none; } }
/* Notif ADMIN "un membre a ecrit" sur la carte (orange plein, bien visible, cliquable, clignote). */
.admin-chat-alert { display: inline-flex; align-items: center; gap: .35rem; margin: .55rem 0 0; padding: .35rem .75rem;
    border-radius: 8px; font-weight: 800; font-size: .9rem; text-decoration: none; color: #fff;
    background: #ea580c; border: 1px solid #c2410c; animation: admin-chat-pulse 1.1s ease-in-out infinite; }
.admin-chat-alert:hover { background: #c2410c; color: #fff; text-decoration: none; }
@keyframes admin-chat-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(234,88,12,0); } 50% { box-shadow: 0 0 0 4px rgba(234,88,12,.32); } }
@media (prefers-reduced-motion: reduce) { .admin-chat-alert { animation: none; } }
/* Garde anti-typo e-mail (inscription) : mismatch en rouge, suggestion "tu voulais dire" cliquable. */
[data-email-warn].email-warn-err { color: var(--danger); font-weight: 600; }
[data-email-warn].email-warn-sug { color: var(--text); }
[data-email-warn].email-warn-sug a { font-weight: 800; text-decoration: underline; cursor: pointer; }
/* Champ mot de passe avec bouton "afficher / masquer". */
.pw-wrap { display: flex; gap: .4rem; align-items: stretch; }
.pw-wrap input { flex: 1 1 auto; }
.pw-toggle { flex: 0 0 auto; background: var(--card-2); border: 1px solid var(--border); border-radius: 8px;
    color: var(--accent-ink); font-weight: 700; font-size: .85rem; padding: 0 .7rem; cursor: pointer; white-space: nowrap; }
.pw-toggle:hover { border-color: var(--accent-2); }
/* Honeypot anti-bot (inscription) : retire du flux visuel, inaccessible au clavier humain. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
/* Bouton "Inviter mon groupe WhatsApp" (V2, levier viral) : vert WhatsApp, bien visible. */
.wa-invite-btn { background: #25d366 !important; border-color: #1da851 !important; color: #04130a !important; font-weight: 800; animation: wa-pulse 1.5s ease-in-out infinite; }
.wa-invite-btn:hover { background: #1da851 !important; color: #04130a !important; text-decoration: none; }
.wa-invite-btn svg { fill: #04130a; }
@keyframes wa-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(37,211,102,0); }
    50%      { box-shadow: 0 0 0 6px rgba(37,211,102,.38); }
}
@media (prefers-reduced-motion: reduce) { .wa-invite-btn { animation: none; } }
/* Bandeau "Garde ta place" (V2, Bloc 4) : invite ayant joue, ancrage d'identite non bloquant. */
/* Bandeau de sécurisation (compte pseudo). Fond ambré FIXE + texte foncé FIXE : c'est un composant
   à fond propre, il ne doit pas changer d'aspect entre clair et sombre (règle design), et l'ambre
   dit « attention » sans crier « erreur ». Lisibilité garantie par nous, pas laissée aux vars de thème. */
.claim-nudge { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .7rem;
    margin: .7rem auto 0; max-width: 1100px; padding: .6rem .95rem; border-radius: 10px;
    background: #fef3c7; border: 1px solid #f59e0b; color: #5a3e00; }
.claim-nudge[hidden] { display: none; }
.claim-nudge-txt { font-weight: 700; color: #5a3e00; }
.claim-nudge-btn { background: #f59e0b; color: #3a2600; text-decoration: none; padding: .34rem .9rem; border-radius: 8px; font-weight: 800; white-space: nowrap; }
.claim-nudge-btn:hover { background: #d97706; color: #fff; text-decoration: none; }
.claim-nudge-close { background: none; border: none; color: #9a7b3a; font-size: 1.3rem; cursor: pointer; line-height: 1; padding: 0 .15rem; }
.claim-nudge-blink { animation: claim-nudge-pulse 1.5s ease-in-out infinite; }
@keyframes claim-nudge-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(245,158,11,0); } 50% { box-shadow: 0 0 0 3px rgba(245,158,11,.35); } }
@media (prefers-reduced-motion: reduce) { .claim-nudge-blink { animation: none; } }

/* « Place ton champion » : essai sans compte sur la landing avant-saison. La grille et les écussons
   gardent le même aspect en clair et en sombre (les couleurs de club sont propres au composant) ; seuls
   le fond de carte et le texte suivent le thème via les variables. */
.pick-card { text-align: center; }
.pick-h { margin: .1rem 0 .2rem; font-size: 1.25rem; }
.pick-sub { margin: 0 0 .8rem; }
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: .5rem; }
.pick-team { display: flex; flex-direction: column; align-items: center; gap: .35rem; padding: .6rem .3rem;
    border: 1.5px solid var(--border); border-radius: 10px; background: var(--card-2); color: var(--text);
    cursor: pointer; font: inherit; transition: border-color .12s, transform .12s, box-shadow .12s; }
.pick-team:hover { border-color: #5b9bff; transform: translateY(-2px); }
.pick-team.is-picked { border-color: #2f6fd0; box-shadow: 0 0 0 2px rgba(47,111,208,.4); background: rgba(47,111,208,.12); }
.pick-crest { width: 40px; height: 40px; font-size: 1rem; }
.pick-team-name { font-size: .78rem; font-weight: 700; line-height: 1.15; }
.pick-cta { margin: 1rem 0 .1rem; }
.pick-cta[hidden] { display: none; }
.pick-chosen { margin: 0 0 .5rem; font-size: 1.05rem; }
@media (max-width: 480px) { .pick-grid { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); } .pick-crest { width: 34px; height: 34px; } }

/* 3 étapes « comment on joue » (aligné sur l'accueil vélo). */
.hiw-steps { display: flex; flex-direction: column; gap: .7rem; }
.hiw-step { display: flex; gap: .7rem; align-items: flex-start; text-align: left; }
.hiw-num { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; background: var(--accent-2);
    color: #04130a; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.hiw-step p { margin: .1rem 0 0; }
/* Page "Garde ta place" : boutons sociaux + separateur. */
/* Encart "Securise ta place" (page futures, invite ayant complete ses pronos) : bloc vert proeminent. */
.secure-card { border: 1.5px solid var(--accent-2); background: rgba(43,176,97,.10); border-radius: 12px; padding: .9rem 1rem; margin: 0 0 1rem; }
.secure-card-title { font-weight: 800; color: var(--accent-ink); margin-bottom: .15rem; }
.secure-card-sub { color: var(--muted); font-size: .9rem; margin: 0 0 .7rem; }
/* Page Connexion : porte "pas de compte ? joue tout de suite" (capte les arrivees froides). */
.login-play { border: 1.5px solid var(--accent-2); background: rgba(43,176,97,.10); border-radius: 12px; padding: .9rem 1rem; margin: 0 0 .4rem; text-align: center; }
.login-play strong { color: var(--accent-ink); }
.claim-social { margin-bottom: .5rem; font-weight: 700; color: #fff !important; }
.claim-fb { background: #1877f2 !important; border-color: #1877f2 !important; }
.claim-fb:hover { background: #0f5ed7 !important; }
/* Bouton Google au format officiel : fond blanc, bordure discrete, logo "G" 4 couleurs, texte sombre. */
.claim-google { display: flex !important; align-items: center; justify-content: center; gap: 10px; background: #fff !important; border: 1px solid #9aa0a6 !important; color: #3c4043 !important; }
.claim-google::before { content: ""; flex: 0 0 18px; width: 18px; height: 18px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill='%23FFC107' d='M43.611 20.083H42V20H24v8h11.303c-1.649 4.657-6.08 8-11.303 8-6.627 0-12-5.373-12-12s5.373-12 12-12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 12.955 4 4 12.955 4 24s8.955 20 20 20 20-8.955 20-20c0-1.341-.138-2.65-.389-3.917z'/%3E%3Cpath fill='%23FF3D00' d='M6.306 14.691l6.571 4.819C14.655 15.108 18.961 12 24 12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 16.318 4 9.656 8.337 6.306 14.691z'/%3E%3Cpath fill='%234CAF50' d='M24 44c5.166 0 9.86-1.977 13.409-5.192l-6.19-5.238A11.91 11.91 0 0 1 24 36c-5.202 0-9.619-3.317-11.283-7.946l-6.522 5.025C9.505 39.556 16.227 44 24 44z'/%3E%3Cpath fill='%231976D2' d='M43.611 20.083H42V20H24v8h11.303a12.04 12.04 0 0 1-4.087 5.571l.003-.002 6.19 5.238C36.971 39.205 44 34 44 24c0-1.341-.138-2.65-.389-3.917z'/%3E%3C/svg%3E") no-repeat center / 18px 18px; }
.claim-google:hover { background: #f7f8f8 !important; }
.claim-sep { display: flex; align-items: center; text-align: center; color: var(--muted); margin: .7rem 0; gap: .6rem; }
.claim-sep::before, .claim-sep::after { content: ""; flex: 1; height: 1px; background: var(--border); }
/* Encart d'entree dans le concours PUBLIC officiel (CTA "1 clic", accueil + /groups). */
.public-cta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .9rem;
    border: 2px solid var(--accent-2); background: linear-gradient(135deg, rgba(43,176,97,.16), rgba(43,176,97,.05)); }
.public-cta-title { margin: 0 0 .25rem; font-size: 1.3rem; }
.public-cta-sub { margin: 0; color: var(--muted); }
.public-cta-late { margin: .4rem 0 0; font-weight: 700; color: var(--accent-ink); }
.public-cta-count { margin: .35rem 0 0; }
.public-cta-action { flex: 0 0 auto; }
.public-cta-action .btn { white-space: nowrap; }
.public-cta-slim { justify-content: center; gap: .6rem; padding: .7rem .9rem; }
.public-cta-slim .muted { flex: 0 1 auto; }
.public-cta-badges { display: flex; gap: .4rem; flex-wrap: wrap; margin: .5rem 0 0; }
.public-cta-badges .badge { background: var(--accent-2); border-color: var(--accent-2); color: #04130a; font-weight: 800; font-size: .82rem; }
.badge-public { background: var(--accent-2); color: #04130a; font-weight: 800; }
/* Filet de secours "partie publique" (V2 : presente discretement sous le CTA principal). */
.public-fallback { text-align: center; margin: .5rem 0 0; }
.public-fallback .inline { display: inline; }
.public-fallback-link { color: var(--accent-ink); font-weight: 700; background: none; border: none; padding: 0; cursor: pointer; font: inherit; }
.public-fallback-link:hover { text-decoration: underline; }
/* Demonstration de valeur sur l'accueil (3B) : 3 etapes "comment ca marche". */
.hiw-home-title { margin: 0 0 .8rem; text-align: center; }
.hiw-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.hiw-step { text-align: center; padding: .6rem; }
.hiw-step-ic { font-size: 2rem; line-height: 1; margin-bottom: .35rem; }
.hiw-step h3 { margin: .2rem 0 .3rem; font-size: 1.05rem; }
.hiw-home-cta { text-align: center; margin: 1rem 0 0; }
@media (max-width: 640px) { .hiw-steps { grid-template-columns: 1fr; gap: .5rem; } }
/* « Comment ca marche » de l'accueil (home_cycling .hiw-home) : vraies CARTES centrees (icone en haut, titre,
   texte), 3 colonnes -> 1 sur mobile. Corrige le rendu « flex » cramponne (icone|titre|texte cote a cote) (#5c). */
.hiw-home .hiw-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.hiw-home .hiw-step { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .25rem;
    background: var(--card-2); border: 1px solid var(--border); border-radius: 12px; padding: 1.1rem .85rem; }
.hiw-home .hiw-step-ic { font-size: 2rem; line-height: 1; margin-bottom: .25rem; }
.hiw-home .hiw-step h3 { margin: .1rem 0 .2rem; font-size: 1.02rem; }
.hiw-home .hiw-step p { margin: 0; }
@media (max-width: 760px) { .hiw-home .hiw-steps { grid-template-columns: 1fr; gap: .6rem; } }
/* Banniere ENJEU (carte du concours) : il manque des enjeux et la deadline approche. Rouge, voyante. */
.stake-banner { margin: .8rem 0 0; border: 2px solid #ef4444; border-radius: 10px; padding: .7rem .9rem;
    background: rgba(239,68,68,.12); animation: futures-urgent-pulse 1.2s ease-in-out infinite; }
.stake-banner-title { font-weight: 800; color: #ef4444; font-size: 1.02rem; }
.stake-banner-body { margin: .35rem 0 0; line-height: 1.5; font-weight: 600; }
.stake-banner-you { margin: .55rem 0 0; padding: .5rem .65rem; border-radius: 8px; background: rgba(239,68,68,.18); font-weight: 700; }
.stake-banner-granted { background: rgba(34,197,94,.16); }
/* Demande de delai 24/48h + message, repliee derriere un summary cliquable */
.stake-delay-ask { margin-top: .5rem; }
.stake-delay-ask > summary { display: inline-block; cursor: pointer; font-weight: 700; padding: .35rem .7rem;
    border: 1px solid #ef4444; border-radius: 999px; background: #fff; color: #ef4444; list-style: none; }
.stake-delay-ask > summary::-webkit-details-marker { display: none; }
.stake-delay-ask[open] > summary { background: #ef4444; color: #fff; }
.stake-delay-hours { display: flex; gap: 1.2rem; margin: .2rem 0 .5rem; font-weight: 600; }
.stake-delay-hours label { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }
.stake-delay-hours input { width: auto; margin: 0; }
.stake-delay-textarea { width: 100%; resize: vertical; margin-bottom: .5rem; }
.stake-delay-msg { display: block; margin-top: .25rem; font-style: italic; color: #b45309; }
.stake-ask-help { margin: .45rem 0 .55rem; color: var(--muted); line-height: 1.45; }
/* Toggle "quitter le concours" : neutre au repos, vire au rouge une fois deplie (action irreversible-ish) */
.stake-leave-ask { margin-top: .5rem; }
.stake-leave-ask > summary { display: inline-block; cursor: pointer; font-weight: 600; padding: .3rem .7rem;
    border: 1px solid var(--border); border-radius: 999px; background: #fff; color: var(--muted); list-style: none; }
.stake-leave-ask > summary::-webkit-details-marker { display: none; }
.stake-leave-ask[open] > summary { border-color: var(--danger); color: var(--danger); }
@media (prefers-reduced-motion: reduce) { .stake-banner { animation: none; } }
/* Items du changelog (Communication > Nouveautes) */
.news-item { padding: .75rem 0; border-bottom: 1px solid var(--border); }
.news-item:last-child { border-bottom: none; }
/* Nouveaute mise en avant (clignote doucement, ex : la preuve par email quand le super-admin l'active). */
.news-blink { padding: .75rem .8rem; border-radius: 10px; animation: newsblink 1.5s ease-in-out infinite; }
/* ══ ÉCRAN AVANT-SAISON (20/07) : 3 étapes lisibles au lieu de 19 boutons. Une action par bloc. ══ */
.ps-wrap { display: flex; flex-direction: column; gap: .7rem; margin: 0 0 1rem; }
.ps-step { border: 1px solid var(--border); border-radius: 12px; padding: .85rem 1rem; background: var(--card); }
.ps-step-head { display: flex; align-items: center; gap: .5rem; font-size: 1.02rem; }
.ps-num { display: inline-flex; align-items: center; justify-content: center; min-width: 26px; height: 26px;
  border-radius: 999px; background: var(--accent); color: var(--on-accent); font-weight: 900; font-size: .82rem; flex: 0 0 auto; }
.ps-step.is-done .ps-num { background: var(--accent-2); }
.ps-step-sub { margin: .35rem 0 .7rem; color: var(--muted); font-size: .9rem; line-height: 1.5; }
.ps-cta { font-weight: 800; }
.ps-link { font-weight: 700; color: var(--accent-ink); text-decoration: none; font-size: .9rem; }
/* Rappels : bloc à 2 boutons. Il PULSE tant que le joueur n'a pas répondu -> le clignotement appelle
   une action réelle (jamais sur une case déjà cochée, ce qui pousserait au refus). */
.ps-remind.is-asking { border-color: var(--accent-2); animation: ps-pulse 1.9s ease-in-out infinite; }
@keyframes ps-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); }
  50%      { box-shadow: 0 0 0 4px rgba(43,176,97,.22); }
}
@media (prefers-reduced-motion: reduce) { .ps-remind.is-asking { animation: none; } }
.ps-remind-actions, .ps-invite-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.btn-plain { background: none; border: 0; color: var(--muted); text-decoration: underline; cursor: pointer;
  font-size: .88rem; font-family: inherit; padding: .3rem 0; }
.ps-remind-set { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 .2rem;
  font-size: .88rem; color: var(--muted); }
.ps-toggle { background: none; border: 0; color: var(--accent-ink); text-decoration: underline; cursor: pointer;
  font-size: .84rem; font-family: inherit; font-weight: 700; }
.ps-wa { background: #25d366; color: #08331b; font-weight: 800; }
.ps-wa:hover { background: #1eb958; }
/* « Voir le concours en détail » : tout reste accessible, juste replié. */
.ps-more { margin: 0 0 1rem; }
.ps-more > summary { cursor: pointer; color: var(--accent-ink); font-weight: 700; font-size: .92rem;
  padding: .55rem .8rem; border: 1px dashed var(--border); border-radius: 10px; list-style: none; }
.ps-more > summary::-webkit-details-marker { display: none; }
.ps-more > summary::after { content: ' ▾'; }
.ps-more[open] > summary::after { content: ' ▴'; }
.ps-preview-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .55rem; margin: 0 0 .7rem;
  padding: .45rem .7rem; border: 1px dashed var(--accent-2); border-radius: 10px; font-size: .8rem; color: var(--muted); }
.ps-preview-bar a { color: var(--accent-ink); font-weight: 700; }
.ps-preview-bar .ps-preview-off { text-decoration: underline; }
/* ── Lien nav mis en avant (lancement CL/Vuelta 19/07) : gras + accent + halo doux. ── */
.nav .nav-hot { font-weight: 800; color: var(--accent-ink); border-radius: 8px; padding: .15rem .45rem; animation: navhot 1.8s ease-in-out infinite; }
@keyframes navhot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(91,155,255,0); background: transparent; }
  50%      { box-shadow: 0 0 0 3px rgba(91,155,255,.20); background: rgba(91,155,255,.08); }
}
@media (prefers-reduced-motion: reduce) { .nav .nav-hot { animation: none; background: rgba(91,155,255,.08); } }
/* ── Compte a rebours COMPACT de la carte du concours (avant-saison). PC : a droite du titre
      (margin-left:auto dans la title-row flex-wrap) ; mobile : pleine largeur sous le titre. ── */
.contest-cd { margin-left: auto; margin-right: 2.2rem; margin-top: .5rem; display: flex; align-items: center; gap: .5rem; flex: 0 1 auto; flex-wrap: wrap; }
.contest-cd-label { font-size: .78rem; font-weight: 700; color: var(--accent-ink); white-space: nowrap; }
@media (max-width: 640px) { .contest-cd { margin-left: 0; margin-right: 0; flex-basis: 100%; } }
/* Compte a rebours des CARTES /competitions (inscriptions ouvertes) : centre dans la carte. */
/* Compte a rebours des cartes : resserre (24/08). Il est utile, mais il poussait le bouton du
   concours trop bas, jusqu'a le faire sortir de l'ecran sur la carte « Inscriptions ouvertes ». */
.cp-cd { display: flex; justify-content: center; margin: .2rem 0 .05rem; }
.cp-card .cp-cd .cd-box { padding: .18rem .3rem; }
.cp-card .cp-cd .cd-box b { font-size: 1rem; }
.cp-card .cp-cd-label { margin: .1rem 0 0; font-size: .78rem; }
/* LA PROCHAINE ECHEANCE (29/08) : la carte vedette de la home vit HORS de la grille, pleine largeur,
   liseret accent. Les media queries de .cp-card la bornent a 360px : on les annule explicitement. */
.cp-card-featured { flex: none; max-width: none; width: 100%; margin: .1rem 0 .2rem; border: 2px solid var(--accent, #e0a800); }
@media (min-width: 860px) { .cp-card-featured { flex-basis: auto; max-width: none; } }
@media (min-width: 1400px) { .cp-card-featured { flex-basis: auto; max-width: none; } }
.cp-card-featured .cp-name { font-size: 1.25rem; }
/* Sur PC (Jonathan 29/08, capture) : la vedette se presente en BANNIERE CENTREE : pastille au-dessus,
   badges, textes, compteur et CTA au centre horizontal. Le mobile garde sa lecture a gauche. */
@media (min-width: 860px) {
    .cp-card-featured { align-items: center; text-align: center; }
    .cp-card-featured .cp-head { flex-direction: column; align-items: center; justify-content: center; gap: .45rem; }
    .cp-card-featured .cp-badges { justify-content: center; }
    .cp-card-featured .cp-name { font-size: 1.45rem; }
}
/* ── Compteur MINI : reprend a l'IDENTIQUE le look premium du hero (.cd-box : fond verre vert-noir,
      bordure + glow verts, chiffre #44e08a, deux-points .cd-sep) mais en PETIT. Reutilise partout
      (cartes /competitions, carte concours). Memes couleurs voulues (Jonathan 19/07). ── */
.cd-mini { display: inline-flex; align-items: center; gap: .26rem; flex-wrap: nowrap; }
.cd-mini .cd-box { min-width: clamp(32px, 10.5vw, 46px); padding: .26rem .28rem; border-radius: 9px; }
.cd-mini .cd-box b { display: block; font-size: clamp(1.05rem, 5vw, 1.5rem); font-weight: 900; line-height: 1;
    color: var(--cd-fg, #44e08a); font-variant-numeric: tabular-nums; text-shadow: 0 0 10px var(--cd-glow, rgba(68,224,138,.55)); }
.cd-mini .cd-box span { display: block; font-size: .46rem; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-top: .12rem; }
.cd-mini .cd-sep { display: inline-block; font-size: 1rem; font-weight: 800; color: var(--cd-sep, rgba(68,224,138,.5)); line-height: 1; }
/* Teinte du compteur PAR CARTE (page /competitions : chaque carte a sa compétition, data-comp global ne
   suffit pas). Mêmes couleurs que les thèmes data-comp. Le vert reste le défaut (Mondial / sans tint). */
.cd-tint-blue   { --cd-fg: #6ba4ff; --cd-glow: rgba(91,155,255,.55); --cd-bg: linear-gradient(165deg,#16305d,#0a0f1a); --cd-border: rgba(77,139,255,.5); --cd-sep: rgba(107,164,255,.5); }
.cd-tint-red    { --cd-fg: #ff6b7d; --cd-glow: rgba(255,90,107,.55); --cd-bg: linear-gradient(165deg,#4d1c24,#130a0c); --cd-border: rgba(255,77,94,.5); --cd-sep: rgba(255,107,125,.5); }
.cd-tint-yellow { --cd-fg: #f2c94c; --cd-glow: rgba(242,201,76,.55); --cd-bg: linear-gradient(165deg,#4a3a0c,#12100a); --cd-border: rgba(230,184,0,.5); --cd-sep: rgba(242,201,76,.5); }
@keyframes newsblink {
  0%, 100% { box-shadow: 0 0 0 0 rgba(60,160,90,0); background: transparent; }
  50%      { box-shadow: 0 0 0 4px rgba(60,160,90,.22); background: rgba(60,160,90,.07); }
}
@media (prefers-reduced-motion: reduce) { .news-blink { animation: none; background: rgba(60,160,90,.07); } }
/* Lien "Mes pronos" du menu (desktop + hamburger) : action primaire = acces direct aux pronostics. Discretement
   mis en avant (couleur accent) ; clignote tant que la nouveaute "Mes pronos" n'a pas ete consultee (.is-new). */
.nav a.nav-mespronos { color: var(--accent-ink, #2bb061); font-weight: 700; }
.nav a.nav-mespronos.is-new { border-radius: 8px; animation: newsblink 1.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .nav a.nav-mespronos.is-new { animation: none; background: rgba(60,160,90,.07); } }
.news-item-date { font-size: .78rem; color: var(--muted); font-weight: 700; }
.news-item-title { font-weight: 800; font-size: 1.05rem; margin: .1rem 0 .2rem; }
.news-item-body { color: var(--text); }
.news-inline-link { color: var(--accent-ink); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.news-inline-link:hover { text-decoration: none; }
/* Collapsable : la plus recente est <details open>, les autres repliees (clic sur date+titre pour deplier). */
.news-item > summary.news-item-head { list-style: none; cursor: pointer; display: flex; align-items: baseline;
    flex-wrap: wrap; gap: .1rem .55rem; }
.news-item > summary.news-item-head::-webkit-details-marker { display: none; }
.news-item-head .news-item-title { margin: 0; }
.news-item-head:hover .news-item-title { color: var(--accent-ink); }
.news-item:not([open]) .news-item-head .news-item-title { font-weight: 700; }
.news-item-caret { margin-left: auto; align-self: center; color: var(--muted); font-size: .85rem; transition: transform .15s ease; }
.news-item[open] > .news-item-head .news-item-caret { transform: rotate(180deg); }
.news-item[open] > .news-item-body { margin-top: .4rem; }
/* Cible d'ancrage : laisse la place du header sticky quand on saute dessus (#md-go, #autres-go) */
/* Ancrages sous le header STICKY : on decale tous les sauts d'ancre de la hauteur reelle du header.
   Fallback CSS = 80px ; JS (bcSetScrollPad) ecrase avec la hauteur exacte de .topbar (qui varie selon la
   barre super-admin Membre/Admin/Super-admin, le wrap mobile, etc.) -> la carte se cale pile dessous. */
html { scroll-padding-top: 86px; }
/* Marge d'ancre DE BASE sur la cible elle-meme (desktop) : le saut d'ancre NATIF a deja le bon decalage des le
   1er rendu (le JS ne fait plus qu'affiner) -> plus de "le bouton retour colle au header puis le padding se remet". */
.scroll-anchor { scroll-margin-top: 86px; }
.nav a { color: var(--muted); font-size: .95rem; }
.nav a:hover { color: var(--text); text-decoration: none; }
.nav-profile { display: inline-flex; align-items: center; gap: .45rem; background: var(--card-2); border: 1px solid var(--border); padding: .15rem .7rem; border-radius: 999px; }
.nav-profile:hover { border-color: var(--accent-ink); }
.nav-profile .avatar { width: 26px; height: 26px; margin: 0; vertical-align: 0; border-color: var(--accent); }
.nav-pseudo { color: var(--accent-ink); font-weight: 700; }
.inline { display: inline; margin: 0; }
/* Bouton hamburger (mobile uniquement, revele dans la media query) */
.nav-toggle { display: none; align-items: center; justify-content: center; width: 42px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #e7e9ee; cursor: pointer; padding: 0; -webkit-tap-highlight-color: transparent; }
.nav-toggle:hover { border-color: var(--accent-2); }
.nav-toggle svg { width: 23px; height: 23px; display: block; }

/* Conteneur */
.container { max-width: 1040px; margin: 0 auto; padding: 1rem; }
.foot { text-align: center; color: var(--muted); font-size: .85rem; padding: 2rem 1rem; }
.foot-legal { display: flex; justify-content: center; flex-wrap: wrap; gap: .3rem .9rem; margin-top: .5rem; }
.foot-legal a { color: var(--muted); text-decoration: underline; }
.foot-legal a:hover { color: var(--text); }
/* Page legale : lecture confortable + sommaire */
.legal { max-width: 52rem; margin-left: auto; margin-right: auto; line-height: 1.6; }
.legal h2 { margin: 1.8rem 0 .6rem; padding-top: .6rem; border-top: 1px solid var(--border); }
.legal h2:first-of-type { border-top: none; padding-top: 0; }
.legal h3 { margin: 1.1rem 0 .35rem; font-size: 1.05rem; }
.legal p, .legal li { color: var(--text); }
.legal ul { margin: .3rem 0 .3rem 1.1rem; }
.legal hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
.legal-toc { display: flex; flex-wrap: wrap; gap: .5rem .9rem; margin: .6rem 0 1.4rem; padding: .7rem .9rem; background: var(--card-2); border: 1px solid var(--border); border-radius: 10px; }
.legal-toc a { font-weight: 600; }

/* Cartes */
/* CAPTURE D'ADRESSE PAR LE SERVICE (02/08) : bloc discret mais present, pose la ou le joueur est
   deja (classement, sous le formulaire de pronos). Un champ, un bouton, sur une ligne des qu'il y a
   la place. Volontairement PAS un bandeau : les bandeaux du haut ne sont plus lus (3 vues de /claim
   en six semaines). */
.ec-card { margin: .8rem 0 0; padding: .8rem .9rem; background: var(--card-2);
    border: 1.5px solid var(--accent); border-radius: var(--radius); box-shadow: 0 2px 12px rgba(0,0,0,.08); }
.ec-head { display: flex; align-items: flex-start; gap: .6rem; }
.ec-ic { font-size: 1.25rem; line-height: 1.1; flex: 0 0 auto; }
.ec-t { margin: 0; font-weight: 800; font-size: .95rem; line-height: 1.25; }
.ec-s { margin: .18rem 0 0; font-size: .82rem; color: var(--muted); line-height: 1.4; }
.ec-form { display: flex; flex-wrap: wrap; gap: .45rem; margin: .6rem 0 0; }
.ec-input { flex: 1 1 12rem; min-width: 0; padding: .5rem .65rem; font-size: .92rem;
    background: var(--card); color: inherit; border: 1px solid var(--border); border-radius: 8px; }
.ec-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.ec-btn { flex: 0 0 auto; white-space: nowrap; }
.ec-note { margin: .45rem 0 0; font-size: .74rem; color: var(--muted); }
/* « Entree tardive ? » : bloc depliable sobre, meme place sur les 3 sports (pages concours + landings). */
.le-info { margin: .8rem 0 0; padding: .55rem .8rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card-2); }
.le-info-sum { cursor: pointer; font-weight: 800; font-size: .92rem; list-style: none; }
.le-info-sum::-webkit-details-marker { display: none; }
.le-info-sum::after { content: "\25BE"; float: right; color: var(--muted); }
.le-info[open] .le-info-sum::after { content: "\25B4"; }
.le-info-list { margin: .5rem 0 0; padding-left: 1.1rem; font-size: .86rem; line-height: 1.45; color: var(--text); }
.le-info-list li { margin: 0 0 .3rem; }
/* Alternative « un tap » Google dans l'encart : separateur fin + bouton compact a l'identite Google
   (logo + fond blanc via .claim-google). Ne s'affiche que si le provider OAuth est actif (beta/prod). */
.ec-or { display: flex; align-items: center; text-align: center; color: var(--muted); font-size: .78rem; margin: .55rem 0 .45rem; gap: .55rem; }
.ec-or::before, .ec-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.ec-google { padding: .5rem .7rem; border-radius: 8px; font-size: .9rem; font-weight: 700; text-decoration: none; }
@media (max-width: 520px) {
    .ec-btn { flex: 1 1 100%; }
}

/* PAGE ANONYME (31/07) : l'argumentaire qui remplace la nav a onglets pour les visiteurs.
   Le lot d'abord, le mode d'emploi, la preuve sociale vivante, l'action. Le tout doit tenir
   d'un coup d'oeil sur un ecran de telephone : c'est la derniere impression avant la decision. */
.anon-landing { margin: 1rem 0; display: flex; flex-direction: column; gap: .85rem; }
/* La vitrine du visiteur (02/08) : Classement + Recruteurs, sous l'argumentaire, au-dessus du prono. */
.al-peek { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; }
.al-prize { display: flex; align-items: center; gap: .7rem; background: var(--card-2);
    border: 2px solid var(--accent); border-radius: var(--radius); padding: .85rem 1rem; }
.al-prize-ic { font-size: 1.9rem; line-height: 1; flex: 0 0 auto; }
.al-prize-t { margin: 0; font-weight: 800; font-size: 1.08rem; line-height: 1.25; }
.al-prize-s { margin: .22rem 0 0; font-size: .86rem; color: var(--muted); line-height: 1.35; }
.al-how { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: .85rem 1rem; }
.al-how-t { margin: 0 0 .5rem; font-weight: 800; font-size: .98rem; }
.al-steps { margin: 0; padding-left: 1.25rem; display: flex; flex-direction: column; gap: .38rem; }
.al-steps li { font-size: .93rem; line-height: 1.4; }
.al-prize-n { margin: .3rem 0 0; font-size: .9rem; font-weight: 700; color: var(--accent-ink); line-height: 1.35; }
/* LA PHOTO DU LOT : le visiteur voit l'objet au lieu de lire une promesse. Pleine largeur, bords
   arrondis, fond sombre du studio qui se fond dans la carte. */
.al-shot { margin: 0; }
.al-shot img { display: block; width: 100%; height: auto; border-radius: var(--radius); background: #0b0b0d; }
.al-shot figcaption { margin: .4rem 0 0; text-align: center; font-size: .82rem; color: var(--muted); }
/* LE LOT DANS LA COLONNE DROITE DE LA CARTE, sous le compte a rebours : l'espace etait vide tant
   que le visiteur n'avait pas reserve sa place. Cede la place aux boutons de compte des qu'il clique. */
/* « public » / « privé » accole a « Concours » dans l'entete, dans la couleur d'accent de la
   competition : remplace le badge qui prenait une ligne entiere pour la meme information. */
.contest-eyebrow .ce-vis { color: var(--accent-ink); font-weight: 800; }
/* UNE SEULE PAIRE DE COLONNES (Jonathan 01/08). Chaque cote coule a son propre rythme :
   a gauche titre, Description/Membres, prono ; a droite chrono, badge des lots, maillot.
   Un bandeau au-dessus des colonnes avait ete essaye : sa hauteur etait imposee par le plus haut
   des deux cotes (le chrono), ce qui creusait un vide sous les boutons et repoussait le prono.
   Le passage en pile mobile est gere par `order` dans la media query 700 px, sans duplicata :
   le script du chrono cible UN element, le rendre deux fois aurait fige l'un des deux. */
.contest-head-cd .contest-cd { display: flex; flex-direction: column; align-items: center; gap: .35rem; text-align: center; }
/* Respiration entre le badge des lots et la photo du maillot (Jonathan 01/08 : « l'image doit
   descendre plus bas »). */
.card-side-col .przl-v2 { margin: 0 0 .35rem; }
/* Replays : « ex Inconnu-XXXX » a cote du pseudo quand le visiteur s'est inscrit pendant sa visite.
   Discret mais visible : c'est le marqueur d'une conversion, le parcours le plus precieux a revoir. */
.rr-j-exanon { display: inline-block; margin-left: .4rem; padding: .08rem .4rem; border-radius: 999px;
    font-size: .74rem; font-weight: 700; color: var(--accent-ink); border: 1px solid var(--accent);
    background: rgba(31, 138, 76, .10); vertical-align: middle; }
/* Page « N maillots floques a gagner » : la photo dos + face en entier, la page a la largeur pour ca.
   Placee AVANT le paragraphe d'explication : c'est l'objet qu'on vient voir. */
.jp-hero-shot { margin: .2rem 0 .8rem; }
.jp-hero-shot img { display: block; width: 100%; max-width: 620px; height: auto; margin: 0 auto;
    border-radius: 14px; background: #0b0b0d; }
.jp-hero-shot figcaption { margin: .45rem 0 0; text-align: center; }
.card-side-prize { padding: 0; margin-top: 0; }
.card-side-prize img { display: block; width: 100%; height: auto; border-radius: 12px; background: #0b0b0d; }
/* L'IMAGE NE DEPASSE JAMAIS LA COLONNE DE GAUCHE (Jonathan 01/08). Une hauteur figee ne peut pas
   convenir : elle depend du bloc prono, qui n'a pas la meme taille d'un sport a l'autre. La colonne
   droite est deja etiree a la hauteur de la gauche (.card-2col est en align-items:stretch) ; on
   laisse donc la photo consommer EXACTEMENT la place restante, sans deborder ni laisser de vide.
   object-fit:contain plutot que cover : on ne recadre pas un maillot pour gagner trois pixels. */
@media (min-width: 701px) {
    .card-side-col > .card-side-prize { flex: 1 1 auto; min-height: 0; display: flex; }
    .card-side-col > .card-side-prize > a { display: flex; min-height: 0; width: 100%; }
    .card-side-col > .card-side-prize picture { display: flex; min-height: 0; width: 100%; }
    .card-side-col > .card-side-prize img { height: 100%; min-height: 0; object-fit: contain; object-position: top; }
}
/* Vignette du lot pour les MEMBRES : repliee par defaut, elle ne mange pas la carte de ceux qui
   viennent juste pronostiquer, mais l'objet reste a un clic. */
.prize-shot { margin: .5rem 0 0; border: 1px solid var(--border); border-radius: var(--radius); padding: .5rem .7rem; background: var(--card-2); }
.prize-shot > summary { cursor: pointer; font-weight: 700; font-size: .93rem; list-style: none; }
.prize-shot > summary::-webkit-details-marker { display: none; }
.prize-shot img { display: block; width: 100%; height: auto; border-radius: 10px; margin: .55rem 0 .35rem; background: #0b0b0d; }
.prize-shot p { margin: 0; text-align: center; }
.al-social { margin: 0; text-align: center; font-size: .95rem; }
.al-today { color: var(--accent-ink); font-weight: 700; margin-left: .35rem; }
.al-cta { display: block; text-align: center; font-weight: 800; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.1rem; margin: 1rem 0; }
.card h2, .card h3 { margin-top: 0; }
.muted { color: var(--muted); }
.small { font-size: .9rem; }
.center { text-align: center; }

/* Stats */
.stat { display: flex; gap: 1rem; flex-wrap: wrap; }
.stat > div { flex: 1; min-width: 72px; text-align: center; }
.stat strong { display: block; font-size: 1.5rem; color: var(--accent-ink); }

/* Formulaires */
form { margin: 0; }
.field { margin: .7rem 0; }
label { display: block; margin-bottom: .25rem; color: var(--muted); font-size: .9rem; }
input[type=text], input[type=password], input[type=email], input[type=number]:not(.score-in), select, textarea {
    width: 100%; padding: .6rem .7rem; background: var(--card-2); color: var(--text);
    border: 1px solid var(--border); border-radius: 8px; font-size: 1rem;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); }
/* Cases et radios : JAMAIS le carre de selection (26/08, Jonathan) : l'outline generique est
   pour les champs texte. Au clavier (focus-visible), un anneau doux epouse leur forme. */
input[type="radio"]:focus, input[type="checkbox"]:focus { outline: none; }
input[type="radio"]:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 50%; }
input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 4px; }
.help { color: var(--muted); font-size: .85rem; margin-top: .2rem; }
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 2.4rem; }
.pw-eye { position: absolute; right: .5rem; top: 50%; transform: translateY(-50%); background: none; border: none; padding: .1rem; margin: 0; cursor: pointer; color: var(--muted); line-height: 0; display: flex; }
.pw-eye:hover { color: var(--text); }

/* Boutons */
.btn {
    display: inline-flex; align-items: center; justify-content: center; background: var(--accent); color: var(--on-accent); border: none;
    padding: .6rem 1rem; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; text-align: center;
}
.btn:hover { background: var(--accent-2); text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-block { display: block; width: 100%; }
.btn-sm { padding: .35rem .7rem; font-size: .9rem; }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-danger { background: var(--danger); }
/* Bouton "J'ai fini" (clore sa reouverture) : clairement un bouton, encadre + un peu colore, mais
   distinct du vert plein des CTA principaux (action secondaire optionnelle). Plein vert au survol. */
.btn-done { background: rgba(56,210,122,.12); border: 2px solid var(--accent); color: var(--text); font-weight: 700; }
.btn-done:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.btn-link { background: none; border: none; color: var(--muted); cursor: pointer; font: inherit; padding: 0; }
.btn-link:hover { color: var(--text); }

/* Messages flash */
.flash { padding: .7rem 1rem; border-radius: 8px; margin: .6rem 0; border: 1px solid transparent; }
.flash-success { background: rgba(31,138,76,.15); border-color: var(--ok); }
.flash-error { background: rgba(217,83,79,.15); border-color: var(--danger); }
.flash-info { background: rgba(43,176,97,.1); border-color: var(--border); }

/* Toasts : bannieres flottantes en bas (confirmation sans faire bouger la page) */
.toasts { position: fixed; left: 50%; bottom: 1.2rem; transform: translateX(-50%); z-index: 9999; display: flex; flex-direction: column; gap: .5rem; align-items: center; max-width: 92vw; pointer-events: none; }
.toast { pointer-events: auto; padding: .7rem 1.1rem; border-radius: 10px; border: 1px solid var(--border); background: var(--card-2); color: var(--text); box-shadow: 0 6px 24px rgba(0,0,0,.45); font-size: .95rem; max-width: 92vw; text-align: center; animation: toast-in .28s ease both; }
.toast-success { border-color: var(--ok); background: rgba(31,138,76,.94); color: #fff; }
.toast-error { border-color: var(--danger); background: rgba(217,83,79,.94); color: #fff; }
.toast-info { border-color: var(--border); }
.toast-out { animation: toast-out .4s ease forwards; }
@keyframes toast-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(14px); } }

/* Onglets */
.tabs {
    display: flex;
    flex-wrap: wrap;
    align-items: center; /* tous les onglets a la meme hauteur, centres (l'encadre Pronos ne les etire plus) */
    gap: .4rem;
    margin: 1rem 0;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--border);
}
.tabs a {
    display: inline-flex;
    align-items: center;
    justify-content: center; /* libelle toujours centre dans la pilule */
    padding: .45rem .8rem;
    color: var(--muted);
    background: var(--card-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    line-height: 1.1;
    white-space: nowrap;
    font-weight: 600; /* poids constant : l'onglet actif ne change pas de largeur (pas de decalage au clic) */
    transition: color .12s, background .12s, border-color .12s;
}
.tabs a:hover {
    color: var(--text);
    border-color: var(--accent-ink);
    text-decoration: none;
}
.tabs a.active {
    color: var(--on-accent);
    background: var(--accent);
    border-color: var(--accent);
}
/* Onglets de journees colores par phase (poules = gris par defaut) */
.tabs a.tab-stage-r32:not(.active) { border-color: rgba(242,201,76,.55); color: #f2c94c; }   /* 16es - jaune */
.tabs a.tab-stage-r16:not(.active) { border-color: rgba(242,153,74,.6); color: #f2994a; }    /* 8es - orange */
.tabs a.tab-stage-qf:not(.active) { border-color: rgba(235,87,87,.6); color: #eb5757; }      /* quarts - rouge */
.tabs a.tab-stage-sf:not(.active) { border-color: rgba(155,81,224,.6); color: #bb6bd9; }     /* demies - violet */
.tabs a.tab-stage-third_place:not(.active) { border-color: rgba(86,204,242,.6); color: #56ccf2; } /* 3e place - cyan */
.tabs a.tab-stage-final:not(.active) { border-color: rgba(43,176,97,.75); color: var(--accent-ink); background: rgba(43,176,97,.1); } /* finale - vert vif */
.tabs a.tab-today { box-shadow: 0 0 0 3px var(--accent-2); } /* la journee du jour : anneau a l'accent de la competition (plus de halo vert fige) */

/* Pastilles d'etat sur les onglets (md-dot en absolute -> ancetre positionne) */
.tabs a { position: relative; }
/* Groupe "Pronos" : encadre Match + Long terme pour signaler que ce sont les paris */
.tab-group { display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap; padding: .45rem .6rem; border: 1px dashed var(--accent-2); border-radius: 16px; background: transparent; } /* fond neutre : le contour dashed a l'accent suffit (fin du vert fige, suit la competition) */
/* Contour clair sur Match / Long terme : on voit bien que ce sont des boutons dans l'encadre vert */
.tab-group a:not(.active) { border-color: rgba(231,233,238,.5); color: var(--text); }
.tab-group a:not(.active):hover { border-color: #fff; background: rgba(255,255,255,.05); }
.tab-group-label { color: var(--accent-ink); font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; padding-left: .15rem; white-space: nowrap; }
/* Numero de la prochaine journee a pronostiquer, affiche dans le bouton "Match" */
.tab-day-num { font-size: .74rem; font-weight: 800; color: var(--accent-ink); margin-left: .2rem; }
.tabs a.active .tab-day-num { color: var(--on-accent); }
/* (12/07) PURGE CSS MORT : .tab-blink (onglet "Inviter" clignotant) n'etait plus emis par aucune vue. */

/* --- Refonte navigation concours : onglets sur 2 lignes --- */
.tabs.tabs-2row { flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: .55rem; }
.tabs-primary, .tabs-secondary { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.tabs-primary > a, .tabs-primary .tab-group a { font-size: 1.02rem; padding: .5rem .95rem; } /* ligne 1 : plus presente */
.tabs-primary .tab-invite:not(.active) { border-color: var(--accent-ink); color: var(--accent-ink); font-weight: 700; }
.tabs-secondary > a:not(.active), .tabs-secondary .tab-group a:not(.active) { font-size: .9rem; color: var(--muted); } /* ligne 2 : plus discrete */
.tab-group-autres { border-style: dotted; }
.tabs-more-btn { display: none; cursor: pointer; align-items: center; gap: .3rem; padding: .45rem .85rem; border: 1px solid var(--border); border-radius: 999px; background: var(--card-2); color: var(--text); font-weight: 700; font-family: inherit; }
.tabs-more-btn .more-caret { transition: transform .15s; font-size: .8em; }
.tabs-more-btn[aria-expanded="true"] .more-caret { transform: rotate(180deg); }

/* Bandeau "Concours" au-dessus du nom (petit, pas gras outre mesure, vert discret) */
.contest-eyebrow { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--accent-ink); margin: 0 0 .12rem; }
/* Infos-cles du concours dans la carte d'en-tete (membres, enjeu, langue, echeances) */
.contest-meta { display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin: .5rem 0 .15rem; }
.cmeta { font-size: .85rem; color: var(--muted); display: inline-flex; align-items: center; gap: .25rem; }
.cmeta strong { color: var(--text); font-weight: 700; }
/* Petit "?" d'aide dans une metadonnee de la carte (ex : X/20 verificateurs) -> mene a la nouveaute. */
.cmeta-help { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
    border-radius: 999px; background: rgba(46,204,113,.16); color: #1c8a4e; border: 1px solid rgba(46,204,113,.45);
    font-weight: 800; font-size: .7rem; line-height: 1; text-decoration: none; margin-left: .15rem; }
.cmeta-help:hover { background: rgba(46,204,113,.3); }
/* LE « ? » SE DEPLIE (06/09) : le bouton ouvre un panneau sous la ligne, la carte grandit avec lui
   (grille 0fr -> 1fr, animable) puis se referme. Le padding est sur la boite INTERIEURE : a 0fr,
   une boite qui porterait elle-meme du padding garderait la hauteur de ce padding. */
button.cmeta-help { cursor: pointer; padding: 0; font-family: inherit; }
/* Ouvert : rond plein, « ? » blanc. Un vert sombre sur le vert du rond disparaissait en mode sombre. */
.cmeta-help[aria-expanded="true"] { background: #2ecc71; border-color: #2ecc71; color: #fff; }
.entry-help { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .25s ease; flex: 1 0 100%; }
.entry-help[hidden] { display: none; }
.entry-help.is-open { grid-template-rows: 1fr; }
.entry-help-in { overflow: hidden; min-height: 0; }
.entry-help-box { margin: .4rem 0 0; padding: .55rem .75rem; font-size: .85rem; line-height: 1.45; color: var(--muted);
    background: var(--card-2); border: 1px solid var(--border); border-radius: 8px; }
.entry-help-box a { color: var(--accent-ink); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
/* Compteur de membres cliquable (carte concours) -> page Membres */
.cmeta-link { text-decoration: none; cursor: pointer; }
.cmeta-link .cmeta-u { text-decoration: underline; text-underline-offset: 2px; } /* un seul trait continu, emoji exclu */
.cmeta-link:hover { color: var(--accent-ink); text-decoration: none; } /* pas de 2e trait global au survol */
.cmeta-link strong { color: inherit; }
/* Boutons toggle de la carte (description / modifier / reglages) : ouvert = vert + texte blanc + chevron retourne */
.card-toggles { margin-top: .55rem; display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* ====================================================================
   CARTE CONCOURS : en-tete responsive (classe DEDIEE .contest-head-actions
   pour ne PAS entrer en collision avec .contest-card-actions du dashboard).
   MOBILE-FIRST (<640px) : une colonne, meta aeree, badge ancre en haut a
   droite, barre Favori + Inviter pleine largeur. DESKTOP (>=640px) : la mise
   en page d'origine (2 colonnes, actions reparties sur la hauteur a droite).
   ==================================================================== */
.contest-head { display: flex; flex-direction: column; gap: .25rem; position: relative; }
.contest-head-main { min-width: 0; width: 100%; }

/* Badge Admin/Membre : ancre en haut a droite de l'en-tete (pres du titre),
   bien qu'il vive dans la barre d'actions dans le DOM. */
.contest-head .contest-head-actions .badge { position: absolute; top: 0; right: 0; z-index: 3; }
.contest-head-main > .contest-eyebrow,
.contest-head-main > h2 { padding-right: 5.5rem; }

/* Meta : liste compacte, pleine largeur. */
.contest-head .contest-meta { gap: .3rem .8rem; margin: .5rem 0 .1rem; }

/* Toggles (Description / Modifier / Reglages) : barre qui wrap, tap targets confortables. */
.contest-head .card-toggles { margin-top: .6rem; gap: .45rem; width: 100%; }
.contest-head .card-toggles .btn-toggle { min-height: 40px; display: inline-flex; align-items: center; }

/* Barre Favori + Inviter : pleine largeur, separee par un trait doux,
   chaque bouton ~moitie (flex 1 1 9rem), gros et centres. */
.contest-head .contest-head-actions {
    display: flex; flex-direction: row; flex-wrap: wrap; align-items: stretch;
    gap: .5rem; width: 100%; margin-top: .8rem; padding-top: .75rem;
    border-top: 1px solid var(--border);
}
.contest-head .contest-head-actions form.inline { flex: 1 1 9rem; margin: 0; display: flex; }
.contest-head .contest-head-actions .card-invite-btn { flex: 1 1 9rem; }
.contest-head .contest-head-actions .fav-toggle,
.contest-head .contest-head-actions .card-invite-btn {
    width: 100%; justify-content: center; min-height: 44px; box-sizing: border-box;
}
/* Barre sans aucune action (ni favori ni invite) -> pas de trait orphelin. */
.contest-head .contest-head-actions:not(:has(form.inline, .card-invite-btn)) {
    border-top: 0; padding-top: 0; margin-top: 0;
}

/* --- DESKTOP (>=640px) : mise en page d'origine restituee ---------------- */
@media (min-width: 640px) {
    .contest-head {
        flex-direction: row; justify-content: space-between; align-items: flex-start;
        gap: 1rem; flex-wrap: wrap; position: static;
    }
    .contest-head-main { flex: 1; min-width: 0; width: auto; }
    .contest-head .contest-head-actions .badge { position: static; z-index: auto; }
    .contest-head-main > .contest-eyebrow,
    .contest-head-main > h2 { padding-right: 0; }
    .contest-head .contest-meta { gap: .35rem .9rem; margin: .5rem 0 .15rem; }
    .contest-head .card-toggles { margin-top: .55rem; gap: .5rem; width: auto; }
    .contest-head .card-toggles .btn-toggle { min-height: 0; }
    .contest-head .contest-head-actions {
        flex-direction: column; flex-wrap: nowrap; align-items: flex-end;
        justify-content: space-between; align-self: stretch; gap: .5rem; width: auto;
        margin-top: 0; padding-top: 0; border-top: 0;
    }
    .contest-head .contest-head-actions form.inline { flex: 0 0 auto; display: inline-flex; margin: 0; }
    .contest-head .contest-head-actions .card-invite-btn { flex: 0 0 auto; }
    .contest-head .contest-head-actions .fav-toggle,
    .contest-head .contest-head-actions .card-invite-btn {
        width: auto; justify-content: center; min-height: 0; box-sizing: border-box;
    }
}
.btn-toggle .toggle-caret { transition: transform .15s; opacity: .85; }
.btn-toggle[aria-expanded="true"] { background: var(--accent-2); color: var(--on-accent); border-color: var(--accent-2); }
.btn-toggle[aria-expanded="true"] .toggle-caret { transform: rotate(180deg); }
/* Collapsed : reste blanc meme quand le :hover reste colle apres un tap mobile (pas de vert) */
.btn-toggle:not([aria-expanded="true"]):hover { background: transparent; color: var(--text); border-color: var(--accent-ink); }
/* Hover des boutons fantomes lisible (en mobile le :hover reste apres le tap : texte blanc sur fond vert) */
.btn-ghost:hover { color: var(--on-accent); }
/* Panneaux pleine largeur de la carte concours (description, edition, reglages) */
.card-panel { margin-top: .8rem; }
.contest-desc-full.card-panel { padding: .7rem .85rem; border: 1px solid var(--border); border-left: 3px solid var(--accent-2); border-radius: 8px; background: var(--card-2); }
/* Bouton "Plus" (mobile) : plus visible + etat ouvert vert/blanc (comme les toggles) */
.tabs-more-btn { font-size: 1rem; font-weight: 800; }
.tabs-more-btn[aria-expanded="true"] { background: var(--accent-2); color: var(--on-accent); border-color: var(--accent-2); }
/* En-tetes de table triables (analytics admin) */
.th-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sortable:hover { color: var(--accent-ink); }
.th-sortable.sort-asc::after { content: ' \2191'; }
.th-sortable.sort-desc::after { content: ' \2193'; }

/* Boutons "pub" Inviter + Lance un nouveau concours : groupes a droite de la ligne 1, fond bleute
   (PAS vert : le vert = onglet selectionne), contour qui clignote doucement, meme style pour les deux. */
.tabs-promo { margin-left: auto; display: inline-flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.tabs a.tab-promo:not(.active) {
    display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; font-weight: 800;
    background: rgba(91, 141, 239, .16); border: 1px solid rgba(91, 141, 239, .55); color: #5b8def;
    animation: cta-pulse-blue 1.8s ease-in-out infinite;
}
.tabs a.tab-promo:not(.active):hover { background: rgba(91, 141, 239, .26); border-color: #5b8def; color: #3a6fd0; }
.tab-cta-spark { font-size: .9em; }
@keyframes cta-pulse-blue { 0%, 100% { box-shadow: 0 0 0 0 rgba(91,141,239,0); } 50% { box-shadow: 0 0 0 3px rgba(91,141,239,.32); } }
@media (prefers-reduced-motion: reduce) { .tabs a.tab-promo:not(.active) { animation: none; box-shadow: 0 0 0 2px rgba(91,141,239,.5); } }
/* Mobile : Lance un nouveau concours coule comme un onglet normal apres le bouton Plus */
@media (max-width: 640px) { .tabs-promo { display: contents; } }

/* Bouton "Invite des amis" dans la carte du concours (sous Favori), bleu clignotant (meme code couleur que les CTA) */
.card-invite-btn { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; padding: .3rem .7rem; border-radius: 999px; font-weight: 800; font-size: .9rem; background: rgba(91,141,239,.16); border: 1px solid rgba(91,141,239,.55); color: #5b8def; animation: cta-pulse-blue 1.8s ease-in-out infinite; }
.card-invite-btn:hover { background: rgba(91,141,239,.26); border-color: #5b8def; color: #3a6fd0; text-decoration: none; }
@media (prefers-reduced-motion: reduce) { .card-invite-btn { animation: none; box-shadow: 0 0 0 2px rgba(91,141,239,.5); } }
/* Boutons AU-DESSUS de la carte concours : Inviter + Lance un concours [tardif], format IDENTIQUE (taille, couleur, contour, police). */
/* LA CIBLE DE #contest-top (24/08) : elle ne comptait que sur le scroll-padding de <html>, respecte
   de facon inegale selon les navigateurs quand l'ancre est suivie AU CHARGEMENT (le cas ici : on
   arrive depuis /j/<code>). Une marge d'ancrage posee sur la cible elle-meme est fiable partout, et
   elle degage aussi la barre super-admin, plus haute que le header d'un visiteur. */
#contest-top { scroll-margin-top: 96px; }
@media (max-width: 700px) { #contest-top { scroll-margin-top: 118px; } }
.contest-top-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin: 0 0 .65rem; }
.contest-top-actions .top-action-btn { flex: 0 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: .35rem; white-space: nowrap; padding: .5rem .95rem; border-radius: 999px; font-weight: 800; font-size: .92rem; line-height: 1.2; background: rgba(91,141,239,.16); border: 1px solid rgba(91,141,239,.55); color: #5b8def; text-decoration: none; animation: cta-pulse-blue 1.8s ease-in-out infinite; }
.contest-top-actions .top-action-btn:hover { background: rgba(91,141,239,.26); border-color: #5b8def; color: #3a6fd0; text-decoration: none; }
@media (prefers-reduced-motion: reduce) { .contest-top-actions .top-action-btn { animation: none; box-shadow: 0 0 0 2px rgba(91,141,239,.5); } }
@media (max-width: 560px) {
    .contest-top-actions { flex-direction: column; align-items: stretch; }
    .contest-top-actions .top-action-btn { width: 100%; white-space: normal; line-height: 1.2; }
}
/* --- Reorg carte concours : Classement a gauche (vedette), Description a cote du titre, zone admin en bas --- */
.contest-title-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
/* « Je m'inscris » (24/08) : sur la ligne du titre, la seule qui soit vide sur toutes les cartes, et
   assez marque pour qu'on le trouve sans le chercher. Pas de clignotement : il est deja seul sur sa
   ligne, et le badge pulsant est reserve au parcours guide plus bas dans la carte. */
.contest-title-row .cmeta-join-btn {
    flex: 0 0 auto; display: inline-flex; align-items: center; gap: .35rem;
    height: 2.1rem; padding: 0 .95rem; border-radius: 999px; font-size: .92rem; font-weight: 800;
    line-height: 1; white-space: nowrap; background: var(--accent); color: var(--on-accent);
    border: 1px solid var(--accent); box-shadow: 0 2px 8px rgba(34, 161, 92, .28);
}
.contest-title-row .cmeta-join-btn:hover { background: var(--accent-2); border-color: var(--accent-2); text-decoration: none; }
.contest-title-row .contest-desc-toggle { flex: 0 0 auto; }
/* Actions de la carte EN LIGNE SOUS le titre (Description / Membres / Recruteurs), puis Regles sur sa
   propre ligne. flex-wrap -> joli sur PC (une rangee) ET sur mobile (enroulement propre). */
.contest-actions-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .55rem; }
.contest-rules-row { margin-top: .45rem; }
.card-primary-actions { margin-top: .7rem; display: flex; flex-wrap: wrap; gap: .5rem; }
.card-primary-actions .card-standings-btn { display: inline-flex; align-items: center; gap: .35rem; font-size: .98rem; font-weight: 800; padding: .5rem 1.1rem;
    transition: transform .1s ease, box-shadow .1s ease, border-color .1s ease; }
/* Feedback au survol : le bouton devient VERT (comme avant) + leger soulevement. */
.card-primary-actions .card-standings-btn:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); transform: translateY(-1px); box-shadow: 0 3px 9px rgba(0,0,0,.15); text-decoration: none; }
.card-primary-actions .card-standings-btn:active { transform: translateY(0); box-shadow: 0 1px 3px rgba(0,0,0,.18); }
/* MODE SOMBRE : les boutons d'action de la carte concours (foot + velo) avaient un contour (--border sombre)
   quasi invisible sur le fond de carte, et paraissaient eteints. On les "blanchit" : contour clair net, leger
   fond, caption bien lisible -> boutons evidents et beaux en sombre. (Prod = clair only pour l'instant.) */
html[data-theme="dark"] .card-primary-actions .btn-ghost {
    border-color: rgba(255,255,255,.32);
    background: rgba(255,255,255,.07);
    color: #f2f5fb;
}
html[data-theme="dark"] .card-primary-actions .btn-ghost:hover,
html[data-theme="dark"] .card-primary-actions .btn-ghost:focus-visible {
    background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
/* Sur les cartes du dashboard, le titre du concours pose un overlay .card-link::after (z-index:1) sur TOUTE
   la carte. Les boutons d'action doivent passer AU-DESSUS, sinon le clic va au concours (pas a la sous-page)
   et le hover ne se voit pas. */
.contest-card .card-primary-actions { position: relative; z-index: 2; }
/* Rappel du nom du concours dans les titres de section (Classement / Chat / Comptes rendus / Info). */
.title-contest { color: var(--accent-2); font-weight: 800; margin-left: .5rem; }
.recap-gen-date { font-size: .8rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
/* Mobile : les 3 boutons (Compte rendu / Classement / Chat) s'EMPILENT verticalement, pleine largeur,
   centres, avec un espacement propre. Le texte revient a la ligne dans le bouton (aucun debordement,
   aucune troncature). Desktop inchange (rangee horizontale qui wrappe). */
@media (max-width: 560px) {
    .card-primary-actions { flex-direction: column; align-items: stretch; gap: .5rem; flex-wrap: nowrap; }
    .card-primary-actions .card-standings-btn { width: 100%; justify-content: center; text-align: center; padding: .62rem 1rem; font-size: .92rem; white-space: normal; line-height: 1.2; }
    .card-primary-actions .card-standings-btn > span { overflow: visible; text-overflow: clip; white-space: normal; }
    /* MOBILE uniquement : un bouton qui clignote (action attendue / non-lu) REMONTE en haut ; il reprend sa
       place d'origine des qu'il ne clignote plus. Sur PC, ordre fixe (DOM) -> aucun saut de position. */
    .card-primary-actions .ccn-blink { order: -1; }
}
.card-comm-btn { display: inline-flex; align-items: center; gap: .3rem; }
.card-admin-zone { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; margin-top: .8rem; padding-top: .65rem; border-top: 1px dashed var(--border); }
/* Titre "ADMIN" de l'encart : MEME format de police que les titres de blocs (PRONOS / LES AUTRES /
   COMMUNICATION = .tab-group-label) -> .7rem, 800, majuscules, meme interlettrage, couleur accent. */
.card-admin-label { font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--accent-ink); }
.fav-toggle.fav-toggle-sm { font-size: .8rem; padding: .25rem .55rem; gap: .25rem; }
/* Badge "Toi" a cote de soi-meme dans la liste des membres (chaque joueur se voit en tete) */
.you-badge { display: inline-block; margin-left: .4rem; padding: .04rem .42rem; border-radius: 999px; font-size: .7rem; font-weight: 800; background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent-ink); border: 1px solid var(--accent); vertical-align: middle; letter-spacing: .02em; }
/* Badge "bidon" (faux compte/concours de vitrine) : visible uniquement par le super-admin en vue super */
.bidon-badge { display: inline-block; margin-left: .4rem; padding: .04rem .42rem; border-radius: 999px; font-size: .68rem; font-weight: 800; background: rgba(180,83,9,.18); color: #b45309; border: 1px solid rgba(180,83,9,.5); vertical-align: middle; text-transform: uppercase; letter-spacing: .03em; }
html[data-theme="dark"] .bidon-badge { color: #fcd34d; border-color: #b45309; background: rgba(180,83,9,.25); }
/* Compte de TEST (ni reel ni bidon, super-admin seul) : meme pastille, teinte BLEUE pour ne jamais le confondre avec un bidon (ambre). */
.bidon-badge.test-badge, .lb-bidon-badge.test-badge { background: rgba(37,99,235,.14); color: #1d4ed8; border-color: rgba(37,99,235,.5); }
html[data-theme="dark"] .bidon-badge.test-badge, html[data-theme="dark"] .lb-bidon-badge.test-badge { color: #93c5fd; border-color: #2563eb; background: rgba(37,99,235,.25); }

/* ============ Uniformisation des boutons (carte + onglets) ============ */
/* Boutons DANS LA CARTE : tous le MEME format -> rectangle a coins arrondis, MEME hauteur. */
.card .contest-title-row .btn-toggle,
.card .contest-actions-row .btn-toggle,
.card .contest-actions-row .card-standings-btn,
.card .contest-actions-row .cmeta-membres-btn,
.card .contest-actions-row .cmeta-recruiters-btn,
.card .card-primary-actions .card-standings-btn,
.card .contest-head-actions .fav-toggle,
.card .card-admin-zone .btn-toggle,
.card .card-admin-zone .card-comm-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    height: 2.3rem; box-sizing: border-box; padding: 0 .9rem;
    border-radius: 10px; font-size: .9rem; font-weight: 700; line-height: 1; white-space: nowrap;
}
.card .card-primary-actions .card-standings-btn { font-weight: 800; }
/* Lien « voir ma place » de la ligne epinglee (23/08) : discret, a cote du titre, il emmene a la
   vraie ligne du joueur dans le classement (bonne page comprise). */
.lb-pinned-jump { margin-left: .5rem; font-size: .78rem; font-weight: 700; }
/* Ligne epinglee du classement velo : meme intention, rendue dans le tableau lui-meme. */
.cyc-lb .lb-pinned td { border-bottom: 2px solid var(--border); }
/* Rangee « La competition » (23/08) : sous celle du concours, meme format de boutons, precedee d'un
   petit intitule qui dit de quoi on parle. Elle passe a la ligne comme les autres sur mobile. */
.card .contest-comp-row { margin-top: .4rem; }
.card .comp-row-label { color: var(--muted); font-size: .7rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .04em; padding-right: .1rem; white-space: nowrap; }
@media (max-width: 640px) { .card .comp-row-label { width: 100%; } }
/* Pastille de POSITION (23/08) : « Classement 206e ». Ce n'est pas une alerte, c'est un rappel :
   ton rappel, pas un compteur de non-lus. Donc discrete, jamais chaude, jamais clignotante. */
.nav-chip { display: inline-block; margin-left: .35rem; padding: .05rem .4rem; border-radius: 999px;
    background: var(--card-2); border: 1px solid var(--border); color: var(--muted);
    font-size: .72rem; font-weight: 800; line-height: 1.5; }
/* « Mes pronos » (22/08) : le seul bouton COLORE de la rangee. Description et Membres renseignent,
   celui-ci fait jouer : il doit se voir du premier coup d'oeil sans hurler. */
.card .contest-actions-row .cmeta-picks-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    height: 2.3rem; box-sizing: border-box; padding: 0 .95rem;
    border-radius: 10px; font-size: .9rem; font-weight: 800; line-height: 1; white-space: nowrap;
    background: var(--accent); color: var(--on-accent); border: 1px solid var(--accent);
}
.card .contest-actions-row .cmeta-picks-btn:hover { background: var(--accent-2); border-color: var(--accent-2); }
/* Bouton Classement : blanc (ghost) par defaut, VERT seulement quand on est sur l'onglet classement.
   is-active explicite (plutot que dependre de l'ordre .btn/.btn-ghost) -> jamais vert sur les autres onglets. */
.card .card-primary-actions .card-standings-btn.is-active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.card .card-primary-actions .card-standings-btn.is-active:hover { background: var(--accent-2); border-color: var(--accent-2); }
.card .contest-head-actions .fav-toggle .toggle-caret,
.card .contest-title-row .btn-toggle .toggle-caret,
.card .contest-actions-row .btn-toggle .toggle-caret { margin-left: -.05rem; }

/* Onglets SOUS LA CARTE : MEME taille de bouton + MEME police (ligne 1 = ligne 2). Forme ovale conservee. */
.tabs-primary .tab-group a, .tabs-primary .points-info,
.tabs-secondary .tab-comm, .tabs-secondary .tab-group a {
    font-size: .95rem; padding: .5rem .95rem;
}
.tabs-secondary > a:not(.active), .tabs-secondary .tab-comm:not(.active) { color: var(--text); }
.tabs .tab-main { font-weight: 800; }  /* Matchs + Long terme : les deux principaux, en gras */
/* "Plus" supprime (seulement 3 groupes : Pronos, Les autres, Communication) : tout reste visible. */
.tabs-more-btn { display: none !important; }
.tabs-secondary { display: flex !important; flex-wrap: wrap; align-items: center; gap: .4rem; }

/* COMMUNICATION = 3e GROUPE du nav (BLEU, centre), contenant ses 6 sous-onglets, comme PRONOS/LES AUTRES.
   REPLIE par defaut (PC ET mobile) : on clique sur le label "COMMUNICATION" pour DEROULER le menu complet
   (aucun sous-onglet selectionne tant qu'on n'en choisit pas un). Natif via <details>, accessible a tous. */
.tabs-primary, .tabs-secondary { justify-content: center; } /* les 3 groupes centres dans la carte */
.tab-group-comm { display: inline-flex; align-items: center; flex-wrap: wrap; gap: .4rem; border-color: #5b8def; background: rgba(91,141,239,.07); }
.tab-group-comm > summary { list-style: none; cursor: pointer; user-select: none; display: inline-flex; align-items: center; gap: .3rem; }
.tab-group-comm > summary::-webkit-details-marker { display: none; }
.tab-group-comm > summary:hover .tab-group-label { text-decoration: underline; }
.tab-group-comm .tab-group-label { color: #5b8def; }
.tab-group-comm .comm-caret { font-size: .8em; color: #5b8def; transition: transform .15s; }
.tab-group-comm[open] .comm-caret { transform: rotate(180deg); }
/* (12/07) purge : .comm-grp-dot (point du groupe Communication) n'etait plus emis. */
/* Sous-onglets : visibles seulement quand DEROULE ; meme taille que Matchs/Long terme + theme bleu */
.tab-group-comm[open] > .comm-items { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.tab-group-comm .comm-items a { font-size: .95rem; padding: .5rem .95rem; position: relative; /* ancre le point d'angle */ }
.tab-group-comm .comm-items a:not(.active) { border-color: rgba(91,141,239,.5); color: #5b8def; }
.tab-group-comm .comm-items a:not(.active):hover { border-color: #5b8def; background: rgba(91,141,239,.12); }
.tab-group-comm .comm-items a.active { background: #5b8def; border-color: #5b8def; color: #fff; }

/* --- MOBILE : encart admin centre + Communication en 2 colonnes de 3 boutons --- */
@media (max-width: 640px) {
    /* Encart admin : titre centre (pleine largeur), 3 boutons EMPILES et centres, meme espacement
       a gauche et a droite de chaque bouton (largeur auto, centres dans le cadre). */
    .card-admin-zone { flex-direction: column; align-items: center; gap: .5rem; }
    .card-admin-label { width: 100%; text-align: center; padding-left: 0; }
    .card .card-admin-zone .btn-toggle,
    .card .card-admin-zone .card-comm-btn { width: auto; min-width: 14rem; justify-content: center; }

    /* Communication deroulee : grille 2 colonnes egales x 3 lignes. Chaque bouton remplit sa colonne
       (texte centre), les 2 colonnes coupent le cadre en deux sans bordure visible. */
    .tabs-secondary .tab-group-comm[open] { width: 100%; }
    .tab-group-comm[open] > .comm-items {
        display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; width: 100%; margin-top: .5rem;
    }
    .tab-group-comm[open] > .comm-items a {
        display: inline-flex; align-items: center; justify-content: center; text-align: center;
        width: 100%; box-sizing: border-box; margin: 0;
    }
    .tab-group-comm > summary { justify-content: center; width: 100%; }
}

/* Cartes "Mes concours" entierement cliquables (stretched-link) + enfoncement au clic */
.contest-card { position: relative; cursor: pointer; transition: border-color .12s, transform .08s, box-shadow .12s; }
.contest-card:hover { border-color: var(--accent-ink); }
.contest-card:active { transform: scale(.99); box-shadow: 0 1px 4px rgba(0,0,0,.25) inset; }
.contest-card .card-link { text-decoration: none; }
.contest-card .card-link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.contest-card-actions { position: relative; z-index: 2; }

/* ===== Mes concours : VUE COMPACTE (lignes repliees par defaut) =====
   Chaque concours = une ligne compacte (titre + etoile favori + nb membres + jusqu'a 3 mini-boutons a
   initiales). La carte detaillee existante vit dans .contest-full (repliee par defaut, depliee au clic). */
/* Mes concours SANS expand : cliquer la carte -> concours. 2 rangs : (1) .crh-main = titre (prend la place, WRAP
   si trop long) + statut/membres a DROITE ; (2) .crh-btns = les 3 boutons a ORDRE + LARGEURS FIXES -> ils
   s'ALIGNENT parfaitement d'une carte a l'autre (memes 3 boutons, memes colonnes). Lot (pool) apres, wrap. */
/* Carte en COLONNE (une ligne par FAMILLE) : nom · infos groupe · actions+lot · ta position. Chaque bloc passe à la
   ligne tout seul -> aucun débordement horizontal quelle que soit la longueur du nom, la carte grandit en hauteur. */
.contest-row { padding: .8rem 1rem; cursor: pointer; display: flex; flex-direction: column; gap: .5rem; align-items: stretch; }
/* Label "Tu es cite dedans" : sa propre ligne. Le gap de la carte gère l'espacement (plus de margin-top). */
.crh-cited { display: block; margin: 0; max-width: 100%; }
.crh-cited .recap-cited-note { margin: 0; max-width: 100%; }
.contest-row:hover { border-color: var(--accent-ink); }
.contest-row .card-link::after { content: none; }
.crh-main { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .6rem; } /* (héritage, plus utilisé) */
.crh-title { align-self: flex-start; max-width: 100%; display: inline-flex; align-items: center; gap: .4rem; min-width: 0; box-sizing: border-box; font-weight: 800; font-size: 1.12rem; line-height: 1.25; text-decoration: none; color: inherit; border: 1px solid var(--border); border-radius: 8px; padding: .4rem .68rem; transition: border-color .12s, background .12s, color .12s; } /* L1 nom : bouton = taille de son texte, wrap si long, jamais étiré */
.crh-title:hover, .crh-title:focus-visible { border-color: var(--accent); background: var(--card-2); color: var(--accent-ink); text-decoration: none; }
.crh-title-txt { white-space: normal; overflow-wrap: anywhere; min-width: 0; }
.crh-star { flex: 0 0 auto; color: #f5c518; }
.crh-meta { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: .5rem; } /* (héritage, plus utilisé) */
/* L2 : infos du GROUPE (rôle + membres + inscriptions) -> une rangée de chips qui passe proprement à la ligne. */
.crh-group { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .5rem; }
/* L4 : TA position perso, mise à part du reste par un filet fin en tête. */
.crh-mypos { border-top: 1px dashed var(--border); padding-top: .5rem; }
/* LABELS de carte = BADGES plats (14/07 soir) : plus de bordure grise identique aux boutons -> on les distingue
   clairement des vrais boutons (qui, eux, gagnent une ombre plus bas). */
.crh-status { font-size: .8rem; font-weight: 800; padding: .14rem .58rem; border-radius: 999px; background: rgba(148,158,178,.16); border: none; color: var(--muted); white-space: nowrap; }
/* Rôle Admin : vert ScoreMigos (plus l'orange). Défaut sombre -> vert TEXTE clair (--accent-ink 8:1). */
.crh-status-admin { color: var(--accent-ink); border-color: rgba(43,176,97,.5); background: rgba(43,176,97,.12); }
html[data-theme="light"] .crh-status-admin { color: #137a3a; border-color: rgba(43,176,97,.65); background: rgba(43,176,97,.12); }
.crh-members { color: var(--muted); font-size: .9rem; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* "Inscriptions closes" (Mes concours) : chip informatif sobre, jamais un CTA (13/07 soir). */
.crh-closed { font-size: .78rem; font-weight: 800; padding: .14rem .55rem; border-radius: 999px; background: rgba(107,114,128,.16); border: none; color: var(--muted); white-space: nowrap; display: inline-flex; align-items: center; gap: .25rem; }
/* Notice "Inscriptions closes" (onglet Inviter) + en-tete du detail de points d'UNE journee. */
.entry-closed-note { display: flex; align-items: center; gap: .4rem; margin: .3rem 0 0; font-size: 1rem; color: var(--text); }
.pts-md-head { margin: 0 0 .5rem; font-weight: 800; font-size: .95rem; color: var(--accent-ink); }
/* Bonus tiercé du podium (formulaire Tour) : petite ligne mise en avant + bouton "?" explicatif. */
/* "Comment gagner des points" du podium (formulaire Tour) : ligne COMPACTE visible + panneau détaillé à badges. */
/* Bloc "comment gagner" : marge basse pour NE PAS coller le 1er sélecteur de coureur (surtout quand le panneau "?" est ouvert). */
.podium-explain { margin: 0 0 .75rem; }
.podium-earn { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; color: var(--muted); margin: .2rem 0 .35rem; }
.pb-help { width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--border); background: var(--card-2); color: var(--muted); font-weight: 800; cursor: pointer; line-height: 1; padding: 0; flex: 0 0 auto; }
.pb-help:hover { color: var(--text); border-color: var(--accent-2); }
.podium-help { margin: .4rem 0 0; padding: .55rem .7rem; background: var(--card-2); border: 1px solid var(--border); border-radius: 10px; }
.podium-help[hidden] { display: none; }
.ph-title { display: block; margin: 0 0 .4rem; color: var(--text); }
.podium-help-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.podium-help-list li { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.ph-badge { flex: 0 0 auto; font-weight: 800; border-radius: 999px; padding: .1rem .55rem; background: var(--card); border: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.ph-badge.ph-bonus { color: #7a5c00; background: rgba(245,197,24,.18); border-color: #e5c100; }
.ph-d { color: var(--muted); }
.podium-help-story { margin: .5rem 0 0; color: var(--muted); line-height: 1.5; }
/* Fiche de synthese d'un joueur (clic sur les points, classement cyclisme) : repartition maillots/etapes. */
.cyc-stats-card { text-align: left; }
/* padding-right : réserve la place de la croix de fermeture (sinon "91 Points" passe DESSOUS la croix). */
.csc-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; flex-wrap: wrap; margin: 0 0 .55rem; padding-right: 1.8rem; }
.csc-head strong { font-size: 1.05rem; }
.csc-total { font-weight: 800; color: var(--accent-ink); white-space: nowrap; }
.csc-split-labels { display: flex; justify-content: space-between; gap: .6rem; font-size: .9rem; margin: 0 0 .25rem; }
.csc-split-labels strong { font-variant-numeric: tabular-nums; }
.csc-bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: var(--card-2); border: 1px solid var(--border); }
.csc-bar-j { background: #f5c518; }
.csc-bar-s { background: var(--accent-2); }
.csc-list { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; font-size: .92rem; }
.csc-hint { margin: .6rem 0 0; }
.crh-pos { color: var(--text); font-size: .9rem; font-weight: 800; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* 2e rang : les boutons (alignes) + le lot (pool) qui wrap apres. */
.crh-btns { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem .55rem; margin-top: 0; }
.crh-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }
/* Badge « lot à gagner » (maillots) : couleurs ScoreMigos OR (plus l'orange/rouge). Défaut = sombre -> texte OR CLAIR. */
.crh-prize { display: inline-flex; align-items: center; gap: .25rem; font-size: .85rem; font-weight: 800; color: #ffd23a; background: rgba(245,197,24,.13); border: 1px solid rgba(245,197,24,.55); border-radius: 999px; padding: .16rem .68rem; white-space: nowrap; max-width: 100%; }
html[data-theme="light"] .crh-prize { color: #8a6512; background: rgba(245,197,24,.2); border-color: rgba(214,158,20,.85); }
/* Etoile "concours favori" sur la carte du dashboard (Couche 1) : toggle POST, PLEINE (or) si favori, vide sinon.
   Poussee a droite de la ligne groupe (crh-group est flex). */
.crh-fav-form { margin-left: auto; }
.crh-fav-btn { background: none; border: none; cursor: pointer; padding: .05rem .3rem; font-size: 1.25rem; line-height: 1; color: var(--muted); border-radius: 6px; -webkit-tap-highlight-color: transparent; }
.crh-fav-btn:hover { background: rgba(245,197,24,.14); color: #f5c518; }
.crh-fav-btn.on { color: #f5c518; }
/* Banniere onboarding "concours favori" (Couche 3) : bord gauche or. Ne cible QUE les joueurs multi-concours
   sans favori (le mono-concours a son favori pose d'office par la Couche 2). */
.fav-onboard { display: flex; align-items: center; gap: .7rem; border-left: 4px solid #f5c518; }
.fav-onboard-ico { font-size: 1.6rem; line-height: 1; flex: 0 0 auto; }
.fav-onboard-body { flex: 1 1 auto; }
.fav-onboard-body p { margin: .15rem 0 0; color: var(--muted); font-size: .92rem; }
.fav-onboard-ok { flex: 0 0 auto; }
.crh-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .2rem; padding: .4rem .78rem; border: 1px solid var(--border); border-radius: 7px; background: var(--card-2); color: var(--text); font-size: .9rem; font-weight: 800; text-decoration: none; white-space: nowrap; line-height: 1.2; max-width: 100%; box-sizing: border-box; box-shadow: 0 1px 2px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.05); }
html[data-theme="light"] .crh-btn { box-shadow: 0 1px 2px rgba(0,0,0,.14); } /* ombre = effet BOUTON, distinct des badges plats (labels) */
.crh-btn:hover { box-shadow: 0 2px 6px rgba(0,0,0,.3); }
.crh-btn:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); text-decoration: none; }
.crh-btn.ccn-blink { animation: ccn-border-blink 1s ease-in-out infinite; }
.crh-btn .ccn-dot { width: 7px; height: 7px; margin-left: 1px; }
/* Point H/J : DESKTOP = libelle COMPLET ; petit ecran = ABREVIATION par langue (Class., etc.). Bascule a 767px. */
.crh-abbr { display: none; }
/* LARGEURS FIXES des 3 boutons (>= 641px) -> colonnes identiques d'une carte a l'autre (le "Compte rendu J20"
   vs "J9" ne decale plus rien). En dessous, les boutons prennent leur taille (abreviations, ecran etroit). */
@media (min-width: 641px) {
    .crh-bw-recap .crh-btn { min-width: 11.5rem; }
    .crh-bw-classement .crh-btn { min-width: 7.5rem; }
    .crh-bw-chat .crh-btn { min-width: 5.25rem; }
    .crh-bw-ig .crh-btn { min-width: 6rem; } /* bouton "IG" (n'apparait que quand une info generale importante est non lue) */
}
/* Point B : MODE CLAIR - les mini-boutons et libelles etaient trop pales/illisibles -> couleurs bien foncees. */
html[data-theme="light"] .crh-btn { color: #1b2330; background: #eef1f6; border-color: #b7c1cf; }
html[data-theme="light"] .crh-btn:hover { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
html[data-theme="light"] .crh-members { color: #454e5d; }
html[data-theme="light"] .crh-chevron, html[data-theme="light"] .crh-toggle { color: #58616f; }
html[data-theme="light"] .crh-toggle:hover { color: #131922; background: rgba(0,0,0,.05); }
html[data-theme="light"] .crh-title { color: #131922; border-color: #c3ccd8; }
html[data-theme="light"] .crh-title:hover, html[data-theme="light"] .crh-title:focus-visible { color: var(--accent); border-color: var(--accent); background: #eef1f6; }
/* Badge super-admin "clic N" a cote de chaque bouton (page Mes concours) + popover qui/quand. */
.crh-btn-wrap { display: inline-flex; align-items: center; gap: .18rem; max-width: 100%; }
.clk-badge { display: inline-flex; align-items: center; gap: .15rem; padding: .08rem .3rem; border: 1px solid #b45309; border-radius: 6px; background: rgba(180,83,9,.16); color: #f0a35a; font-size: .72rem; font-weight: 800; line-height: 1.3; cursor: pointer; font-family: inherit; }
.clk-badge:hover { background: rgba(180,83,9,.3); }
html[data-theme="light"] .clk-badge { color: #9a5b09; background: rgba(245,158,11,.16); }
.clk-pop { position: absolute; z-index: 1200; min-width: 210px; max-width: 320px; max-height: 340px; overflow: auto; background: var(--card, #171a21); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 28px rgba(0,0,0,.45); padding: .55rem .65rem; font-size: .85rem; }
html[data-theme="light"] .clk-pop { background: #fff; }
.clk-pop-head { font-weight: 800; margin-bottom: .35rem; color: var(--accent-ink, #2bb061); }
.clk-pop-empty { color: var(--muted); font-style: italic; }
.clk-pop-list { list-style: none; margin: 0; padding: 0; }
.clk-pop-list li { display: flex; justify-content: space-between; gap: .7rem; padding: .2rem 0; border-top: 1px solid var(--border); }
.clk-pop-who { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clk-pop-at { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
html[data-theme="light"] .contest-row-muted .crh-title { color: #5b6472; }
/* Mondial abandonne : carte de-emphasee, tout en bas, jamais de clignotement. De-emphase par un
   fond LEGEREMENT retrait uniquement (13/07) - PLUS d'opacity globale (elle assombrissait texte,
   contours ET boutons -> carte illisible en sombre) : le titre et les textes restent PLEINEMENT
   clairs, comme les autres cartes. */
.contest-row-muted { background: color-mix(in srgb, var(--card) 82%, var(--bg)); }
.contest-row-muted .crh-title { font-weight: 700; color: var(--text); }
/* Bandeau + bouton APERCU super-admin (voir comme un membre a confirmer). */
.sa-preview-bar { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; background: rgba(180,83,9,.14); border-color: #b45309; color: #f0a35a; font-weight: 700; }
html[data-theme="light"] .sa-preview-bar { color: #9a5b09; background: rgba(245,158,11,.14); }
.sa-preview-bar .sa-preview-exit { margin-left: auto; color: inherit; text-decoration: underline; font-weight: 800; }
.sa-preview-note { font-size: .8rem; color: var(--muted); font-style: italic; align-self: center; }
/* Point D : phrases CLIGNOTANTES de la banniere pool (le lot + l'incitation "ca ne coute rien"). */
.pool-cta-nudge { margin: .5rem 0 .6rem; font-weight: 800; font-size: 1.02rem; color: #ea580c; }
/* Point D : le TEXTE lui-meme clignote (pas juste un cadre) -> pulsation d'opacite + couleur, attire l'oeil. */
.pool-cta-txt-blink { animation: pool-cta-txt-blink 1.15s ease-in-out infinite; }
@keyframes pool-cta-txt-blink { 0%, 100% { opacity: 1; } 50% { opacity: .38; } }
@media (prefers-reduced-motion: reduce) { .pool-cta-txt-blink { animation: none; } }
/* En-tete STATIQUE de la banniere confirm (pas de repli) : meme allure que le head cliquable, sans curseur. */
.pool-cta-head-static { width: 100%; display: flex; align-items: center; gap: .6rem; cursor: default; }
/* Bannière pool : les 2 choix (Confirmer / Me retirer) alignes et clairement lisibles. */
.pool-cta-confirm-choices { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .7rem; margin-top: .2rem; }
.pool-cta-leave-btn { font-weight: 700; }
/* Page règles : pastille « Nouveau » sur la règle de départage (13/07) + note d'équité datée. */
.hiw-new-pill { display: inline-block; vertical-align: middle; margin-left: .45rem; font-size: .62rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .06em; color: #fff; background: #ea580c; border-radius: 999px; padding: .12rem .5rem; }
.hiw-tie-fairness { font-size: .86rem; color: var(--muted); border-left: 3px solid var(--border); padding-left: .7rem; margin-top: .55rem; }
.hiw-tie-h { margin: .9rem 0 .3rem; font-size: 1rem; }
/* Page règles datée (17/07) : date de rédaction en tête + petit "(ajouté le ...)" sur les règles ajoutées
   en cours de route + précision malus buteur anticipé. Muted -> lisible en sombre ET clair. */
.hiw-dated { margin: .3rem 0 0; font-style: italic; }
.hiw-added { font-size: .72rem; font-weight: 500; color: var(--muted); font-style: italic; white-space: nowrap; }
.hiw-malus-early { display: inline-block; margin-top: .15rem; }
/* Citation de la regle D'ORIGINE (maillot jaune, 17/07) : la phrase historique montree verbatim. */
.hiw-orig-rule { margin: .35rem 0 .6rem; padding: .5rem .8rem; border-left: 4px solid #f5c518; background: rgba(245,197,24,.06); font-style: italic; border-radius: 0 8px 8px 0; }
/* Disclaimer argent (groupes a enjeu) : encadre discret mais net, meme allure sur la cagnotte et ailleurs. */
.stakes-money-note { border-left: 4px solid #f5c518; background: rgba(245,197,24,.06); }
.stakes-money-note p { margin: .3rem 0; }
.stakes-money-note p:first-child { font-size: 1.02rem; }
/* Détail des points : ligne bonus Roi / Dauphin du Perfect (fin de tournoi), déjà ajouté au total. */
.pts-perfect-bonus { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
    background: rgba(245,197,24,.09); border: 1px solid rgba(245,197,24,.35); border-radius: 10px;
    /* padding droit 0 : le cadre vert du Perfect atterrit PILE sur la colonne des deux sous-totaux
       (la bande beige decalait la valeur de .7rem vers la gauche, Jonathan 18/07). */
    padding: .5rem 0 .5rem .7rem; margin: .2rem 0; }
.pts-perfect-live { padding-right: .7rem; } /* etat "en jeu" : pas de cadre, le texte garde sa respiration */
.pts-pb-label { font-weight: 800; }
.pts-pb-perfects { font-weight: 600; color: var(--muted); font-size: .85em; }
.pts-pb-total { font-weight: 800; color: #16a34a; white-space: nowrap; }
.pts-pb-note { margin: .25rem 0 .1rem; font-size: .8rem; color: var(--muted); font-style: italic; }
/* Boutons responsive (Jonathan 13/07) : labels COMPLETS tant qu'il y a la place (tablette, carte verticale large).
   Quand ça se resserre, c'est « Compte rendu » (le plus long) qui abrège en « CR » EN PREMIER ; Classement et Chat
   restent en toutes lettres (ils passent à la ligne si besoin, jamais de débordement horizontal). */
@media (max-width: 480px) {
    .crh-bw-recap .crh-full { display: none; }
    .crh-bw-recap .crh-abbr { display: inline; }
}
@media (max-width: 560px) {
    /* Ecran etroit : boutons compacts mais lisibles, ET garantie anti-debordement (chaque bouton peut wrapper,
       aucune largeur fixe ne s'applique sous 641px). Tout reste visible sans scroll horizontal. */
    .crh-btn { padding: .34rem .6rem; font-size: .86rem; white-space: normal; text-align: center; }
    .crh-main { gap: .35rem .45rem; }
    .contest-row { padding: .65rem .8rem; }
    .crh-actions { gap: .4rem; }
}

/* Lignes "Tous les concours" : membre = cliquable + teinte verte (reconnaissable) ; non-membre = grise, non cliquable */
.row-clickable { cursor: pointer; }
/* Annuaire (13/07 soir) : la table ne deborde plus de sa carte (scroll interne si trop large) ET les
   separateurs courent d'un bord a l'autre du cadre (marge negative = padding 1.1rem de .card, la
   respiration revient via le padding des cellules de bout). */
.gk-desktop { overflow-x: auto; margin: 0 -1.1rem; }
.groups-table th:first-child, .groups-table td:first-child { padding-left: 1.1rem; }
.groups-table th:last-child, .groups-table td:last-child { padding-right: 1.1rem; }
/* « voir Regles » TOUJOURS sous la pastille d'entree tardive : agencement identique sur toutes les lignes */
.groups-table .late-rules-link { display: block; margin-top: .2rem; }
.groups-table tbody tr.row-member { background: rgba(43,176,97,.08); }
.groups-table tbody tr.row-clickable:hover { background: rgba(43,176,97,.16); }
.groups-table tbody tr.row-clickable:active { background: rgba(43,176,97,.26); }
.groups-table tbody tr.row-locked { opacity: .6; }
.groups-table tbody tr.row-locked .grp-name { color: var(--muted); }
/* Super-admin : concours non rejoint mais accessible en observateur -> cliquable, leger liseré bleu. */
.groups-table tbody tr.row-super { background: rgba(91,141,239,.06); }
.groups-table tbody tr.row-super:hover { background: rgba(91,141,239,.14); }

/* Panneau "Reglages du concours" dans la carte d'en-tete (admin) : boite a part, reglages separes */
.reglages-panel { margin-top: .9rem; padding: .85rem 1rem .5rem; border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); }
.reglages-row { margin: 0; padding: .8rem 0; border-top: 1px solid var(--border); }
.reglages-row:last-child { padding-bottom: .2rem; }
.reglages-label { display: block; font-weight: 700; font-size: .92rem; margin-bottom: .25rem; }
.reglages-danger { padding-top: .8rem; }
/* Interrupteur (concours a enjeu) : remplace la case a cocher invisible */
.switch { display: inline-flex; align-items: center; gap: .5rem; cursor: pointer; border: 1px solid var(--border); background: var(--card-2); border-radius: 999px; padding: .25rem .7rem .25rem .3rem; font-family: inherit; font-weight: 700; font-size: .9rem; color: var(--muted); }
.switch .switch-knob { width: 34px; height: 20px; border-radius: 999px; background: var(--border); position: relative; transition: background .15s; flex: 0 0 auto; }
.switch .switch-knob::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: transform .15s; }
.switch.is-on { color: var(--accent-ink); border-color: var(--accent-2); }
.switch.is-on .switch-knob { background: var(--accent); }
.switch.is-on .switch-knob::after { transform: translateX(14px); }

.tabs-more-btn { position: relative; }
.more-dot { width: 9px; height: 9px; border-radius: 50%; background: #f59e0b; display: inline-block; margin-left: .15rem; animation: md-dot-blink 1.1s ease-in-out infinite; } /* qqch a voir dans le "Plus" */
@media (prefers-reduced-motion: reduce) { .more-dot { animation: none; box-shadow: 0 0 0 2px rgba(245,158,11,.5); } }

@media (max-width: 640px) {
    .tabs-more-btn { display: inline-flex; }
    .tabs-secondary { display: none; }
    .tabs-secondary.is-open { display: flex; flex-direction: column; align-items: stretch; }
    .tabs-secondary.is-open .tab-group { flex-direction: column; align-items: stretch; }
    .tabs.tabs-locked .tabs-secondary { display: flex; flex-direction: column; align-items: stretch; } /* membre retire : Membres reste accessible */
}
/* Encadre "preuve anti-fraude" en tete de la grille des pronostics */
.grid-antifraud { border: 1px solid var(--border); border-left: 3px solid var(--accent-2); border-radius: 8px; background: var(--card-2); padding: .55rem .75rem; margin: .2rem 0 .6rem; }
.grid-antifraud strong { color: var(--accent-ink); }
/* Bandeau de phase au-dessus des journees : grand et colore par phase (on voit vite poules/demie/finale) */
.md-head-lg { text-align: center; margin: .2rem 0 .7rem; }
.md-head-lg .md-phase { display: block; font-size: 1.35rem; font-weight: 800; }
.md-head-lg .md-head-meta { display: block; font-size: 1.15rem; font-weight: 700; color: var(--text); margin-top: .15rem; } /* journee + date bien lisibles (presque comme la phase) */
.md-head-lg .md-phase-group { color: var(--accent-ink); }
.md-head-lg .md-phase-r32 { color: #f2c94c; }
.md-head-lg .md-phase-r16 { color: #f2994a; }
.md-head-lg .md-phase-qf { color: #eb5757; }
.md-head-lg .md-phase-sf { color: #bb6bd9; }
.md-head-lg .md-phase-third_place { color: #56ccf2; }
.md-head-lg .md-phase-final { color: var(--accent-ink); }
/* Badge sous l'en-tete : precise si la journee affichee est "aujourd'hui" ou juste "selectionnee"
   (evite de croire que le jour consulte est aujourd'hui alors qu'il est passe). */
.md-tag { display:inline-block; margin:.1rem 0 .35rem; font-size:.72rem; font-weight:700; padding:.1rem .6rem; border-radius:999px; letter-spacing:.02em; }
.md-tag-today { color:#0c1a12; background:var(--accent-2); }
.md-tag-selected { color:var(--muted); border:1px solid var(--border); }

/* Cellule joueur : avatar + drapeau + nom toujours sur une ligne (drapeau a gauche, jamais au-dessus) */
.player-cell { display: inline-flex; align-items: center; gap: .4rem; }
.grid-table .col-player { white-space: nowrap; }
/* Boutons d'action compacts dans la liste des membres, alignes a droite */
.btn-xs { padding: .25rem .55rem; font-size: .8rem; line-height: 1.15; }
.member-actions-cell, .stake-action-cell { white-space: nowrap; }
/* Case "A fourni l'enjeu" (toggle compact a la place des boutons approuver/remettre en attente) */
.stake-toggle { display: inline-flex; align-items: center; gap: .4rem; cursor: pointer; white-space: nowrap; }
.stake-toggle input { width: auto; margin: 0; }
.member-actions { display: flex; gap: .35rem; align-items: center; }
.member-actions .inline { display: inline-flex; margin: 0; }
/* Colonne "Enjeu fourni" : badge au-dessus, action (approuver / remettre en attente) en dessous */
.stake-cell { display: inline-flex; flex-direction: column; align-items: flex-start; gap: .3rem; }
.stake-cell .inline { display: inline-flex; margin: 0; }
/* Bouton "Remettre en attente" : teinte orange (mene vers l'etat en attente), plus lisible */
.btn-warn-ghost { background: transparent; border: 1px solid var(--warn); color: #f0c777; }
.btn-warn-ghost:hover { background: rgba(217,164,65,.14); color: #f0c777; }
/* Zoom des courbes (plage de journees) */
.curves-zoom { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin: .2rem 0 .7rem; }
.curves-zoom select { width: auto; padding: .35rem .5rem; }
.curves-legend { display: flex; flex-wrap: wrap; gap: .55rem .9rem; margin-top: .6rem; }
/* Menu de selection des joueurs des courbes (depliable). */
.curves-players { margin: 0 0 .7rem; border: 1px solid var(--border); border-radius: 10px; padding: .4rem .6rem; background: var(--card-2); }
.curves-players > summary { cursor: pointer; font-weight: 700; font-size: .9rem; list-style: none; }
.curves-players > summary::-webkit-details-marker { display: none; }
.curves-players > summary::before { content: '\25B8'; display: inline-block; margin-right: .4rem; transition: transform .15s; }
.curves-players[open] > summary::before { transform: rotate(90deg); }
.curves-players-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .5rem 0; }
.curves-players-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .15rem .6rem; max-height: 230px; overflow-y: auto; margin-bottom: .5rem; }
.curves-player { display: flex; align-items: center; gap: .35rem; cursor: pointer; font-size: .85rem; white-space: nowrap; }
.curves-player input { width: auto; margin: 0; flex: 0 0 auto; }
.curves-swatch { width: 10px; height: 10px; border-radius: 2px; flex: 0 0 auto; }
.curves-player-name { overflow: hidden; text-overflow: ellipsis; }
.curves-top-badge { color: #f2c94c; flex: 0 0 auto; }
.curves-none { margin-top: .6rem; }
/* Export CSV de la grille */
.grid-export { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.grid-export select { width: auto; max-width: 13rem; padding: .35rem .5rem; }

/* Tableaux */
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: .55rem .5rem; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 600; font-size: .85rem; }
.rank { color: var(--muted); width: 2.4rem; font-weight: 700; }
tbody tr:nth-child(even) { background: rgba(255,255,255,.022); }
.lb-1 td, .lb-2 td, .lb-3 td { font-weight: 700; }
.lb-1 { background: rgba(242,201,76,.10) !important; }
.lb-2 { background: rgba(200,205,215,.06) !important; }
.lb-3 { background: rgba(205,127,50,.08) !important; }
.lb-muted td { opacity: .55; }
.lb-banned td { opacity: .5; text-decoration: line-through; }

/* Encart "Felicitations aux gagnants" (fin de tournoi, classement definitif ; tous concours) */
.prize-winners { border: 1px solid var(--warn); background: linear-gradient(180deg, rgba(242,201,76,.10), rgba(242,201,76,.03)); }
.prize-winners .pw-title { margin: 0 0 .15rem; }
.prize-winners .pw-sub { margin: 0 0 .7rem; }
.pw-table { width: 100%; border-collapse: collapse; }
.pw-table th, .pw-table td { padding: .45rem .5rem; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.pw-table th { font-size: .8rem; color: var(--muted); font-weight: 600; }
.pw-table .rank, .pw-table .pw-pts-col, .pw-table .pw-pts, .pw-table .pw-share-col, .pw-table .pw-share { text-align: center; white-space: nowrap; }
.pw-table .pw-pts { font-weight: 700; }
.pw-table .pw-share strong { font-size: 1.05rem; } /* part en couleur de texte normale (lisible), plus le jaune pale */
.pw-share-note { margin: .5rem 0 0; }
.pw-row.pw-1 td { background: rgba(242,201,76,.12); font-weight: 700; }
.pw-row.pw-2 td { background: rgba(200,205,215,.07); }
.pw-row.pw-3 td { background: rgba(205,127,50,.09); }

/* Encart "Roi du Perfect" (honneur pur, sans incidence cagnotte) */
.perfect-honor { border: 1px solid rgba(242,201,76,.45); background: linear-gradient(180deg, rgba(124,58,237,.06), rgba(124,58,237,.02)); }
.perfect-honor .ph-title { margin: 0 0 .15rem; }
.perfect-honor .ph-sub { margin: 0 0 .7rem; }
.ph-table { width: 100%; border-collapse: collapse; }
.ph-table th, .ph-table td { padding: .45rem .5rem; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.ph-table th { font-size: .8rem; color: var(--muted); font-weight: 600; }
.ph-table .rank, .ph-table .ph-count-col, .ph-table .ph-count { text-align: center; white-space: nowrap; }
.ph-table .ph-count strong { font-size: 1.05rem; }
.ph-row.ph-1 td { background: rgba(242,201,76,.10); font-weight: 700; }
.ph-tag { display: inline-block; font-size: .7rem; font-weight: 700; padding: .04rem .4rem; border-radius: 999px; vertical-align: middle; }
.ph-tag-roi { background: rgba(242,201,76,.22); color: #b5852b; }
.ph-tag-dauphin { background: rgba(200,205,215,.18); color: var(--muted); }
.ph-note { margin: .5rem 0 0; }

/* Classement : colonne "Points anterieurs" (entree tardive) - barree, ne compte pas */
.lb-table .lb-prior-col, .lb-table .lb-prior { text-align: center; white-space: nowrap; }
.lb-table .lb-prior s { color: var(--muted); }

/* Classement : sous-onglets de tri (General / A la moyenne) + bande "Par journee" */
/* Sous-onglets du classement (General + J1..Jn) : frise scrollable horizontalement A TOUTES LES LARGEURS (PC inclus)
   -- le rang d'un jour passe est secondaire, donc 1 ligne scrollable plutot que d'occuper 2-3 lignes verticalement. */
.vote-subtabs.lb-subtabs { margin: .2rem 0 .5rem; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; padding-bottom: .35rem; }
.lb-subtabs .vote-subtab { flex: 0 0 auto; }
.lb-byday { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: 0 0 .55rem; }
.lb-byday-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; white-space: nowrap; }
.lb-byday .md-strip { margin: 0; }
.lb-byday-head { margin: 0 0 .4rem; font-weight: 600; }
/* "Explication du classement" repliable : encart leger, summary cliquable + chevron, corps indente, baremes en bas. */
.lb-explain { margin: .1rem 0 .7rem; border: 1px solid var(--border); border-radius: 9px; background: var(--card-2); }
.lb-explain > summary { cursor: pointer; list-style: none; padding: .5rem .7rem; font-weight: 700; font-size: .92rem; color: var(--text); display: flex; align-items: center; gap: .4rem; }
.lb-explain > summary::-webkit-details-marker { display: none; }
.lb-explain > summary::after { content: '\25BE'; margin-left: auto; color: var(--muted); transition: transform .15s ease; }
.lb-explain[open] > summary::after { transform: rotate(180deg); }
.lb-explain-body { padding: 0 .7rem .6rem; }
.lb-explain-body > :first-child { margin-top: 0; }
.lb-explain-points { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem .5rem; margin: .55rem 0 0; padding-top: .55rem; border-top: 1px solid var(--border); }
.lb-explain-points-lbl { width: 100%; font-size: .85rem; font-weight: 600; color: var(--muted); margin-bottom: .05rem; }
.lb-md-leader { margin: .1rem 0 .25rem; font-weight: 700; font-size: .92rem; }
/* Colonnes additionnelles : Entre le / Moyenne / Journees en tete */
.lb-table .lb-joined-col, .lb-table .lb-joined { text-align: center; white-space: nowrap; }
.lb-table .lb-leads-col, .lb-table .lb-leads { text-align: center; white-space: nowrap; }
.lb-table .lb-avg { text-align: center; white-space: nowrap; }
/* Classement large (jusqu'a 7 colonnes) : scroll horizontal propre quand ca deborde, + compaction mobile. */
.lb-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch;
    /* PAS DE REBOND (08/09/2026) : sur iOS, un conteneur defilable rebondit au bord et montre le fond
       de part et d'autre, meme pour un depassement de quelques pixels ; Jonathan : « je ne devrais pas
       pouvoir swiper pour voir ce padding blanc ». On garde le defilement quand le tableau est
       vraiment plus large (sept colonnes), sans elastique ni transmission du geste a la page. */
    overscroll-behavior-x: none; }
/* --- POPUP STATS des points (11/07 soir) : les colonnes "Entre le" et Moy./jour ont quitte TOUS les
   tableaux de classement -> police d'ORIGINE retrouvee, memes colonnes que les concours normaux partout
   (foot, general, velo, tardifs). Les points sont un BOUTON discret (halo) qui ouvre la popup. --- */
/* Bouton du total : VRAIE affordance (relief coherent avec le bouton Evolution), sobre. Cellule centree :
   score au-dessus, chip buteur en dessous, meme axe vertical. */
.lb-pts-btn { font: inherit; color: inherit; cursor: pointer; padding: .18rem .55rem; min-height: 30px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--card-2); border: 1px solid color-mix(in srgb, var(--accent-2, #2bb061) 70%, transparent);
    border-radius: 999px; box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
    transition: box-shadow .15s ease, border-color .15s ease, transform .1s ease; white-space: nowrap;
    /* LARGEUR PLANCHER COMMUNE (18/07, demande Jonathan) : « 964 », « 942,5 » et « 1018,5 » occupent
       la même pastille (l'oeil scanne une colonne aux bords alignés ; un « ,5 » ne pèse plus davantage
       qu'un plus grand nombre). Chiffres à chasse fixe. Un score à 5 chiffres élargit sa pastille tout
       seul (min-width, jamais de troncature). */
    min-width: 4.35em; font-variant-numeric: tabular-nums; }
.lb-pts-btn:hover, .lb-pts-btn:focus-visible { border-color: var(--accent-2, #2bb061);
    box-shadow: 0 2px 5px rgba(0, 0, 0, .22), 0 0 0 3px rgba(43, 176, 97, .15); outline: none; }
.lb-pts-btn:active { transform: translateY(1px); box-shadow: 0 0 1px rgba(0, 0, 0, .2); }
.lb-table .lb-pts { text-align: center; padding-top: .45rem; padding-bottom: .45rem; }
/* Conteneur vertical commun de la cellule points : total au-dessus, chip buteur en dessous. Le gap est
   choisi proche du padding vertical de la cellule -> espace bouton/bouton = espace bouton/bords. */
.lb-pts-stack { display: inline-flex; flex-direction: column; align-items: center; gap: .45rem; }
.lb-table .lb-pts .lb-buteur-chip { margin: 0; }
/* Groupe pseudo + fleche de depli : SOLIDAIRES (jamais de fleche orpheline) ; pseudo tres long -> ellipsis. */
.lb-name-grp { display: inline-flex; align-items: center; gap: .18rem; white-space: nowrap; max-width: 100%; vertical-align: bottom; }
/* PLAFOND RESPONSIVE de la largeur du NOM (13/07) : la colonne n'est plus dictee par le pseudo le plus long
   du classement. Le nom se tronque proprement (ellipsis), drapeau/avatar/fleche restent alignes et jamais
   pousses hors cellule. Nom complet : title (desktop) + toujours affiche en entier dans la popup de detail. */
.lb-name-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 15rem; }
@media (max-width: 700px) { .lb-name-txt { max-width: 10rem; } }
@media (max-width: 520px) { .lb-name-txt { max-width: 8rem; } }
@media (max-width: 400px) { .lb-name-txt { max-width: 6.2rem; } }
@media (max-width: 340px) { .lb-name-txt { max-width: 5rem; } }
/* ─── LE CLASSEMENT TIENT DANS LA LARGEUR DU TELEPHONE (08/09/2026) ────────────────────────────
   Jonathan, sur son iPhone : « le classement ne fit pas sur la largeur de l'ecran, la derniere
   colonne est cropped et on doit swiper gauche droite ». Mesure a 375 px : le classement tennis
   reclamait 349 px pour 327 disponibles. La cause n'etait pas le nombre de colonnes, c'etait le NOM,
   qui imposait sa largeur au lieu de ceder. Le foot le savait depuis le 13/07 (lb-name-txt) ; le
   tennis et le velo l'ignoraient, leur nom etant un texte nu dans la cellule.
   LA REGLE, desormais commune aux trois sports : la colonne du nom absorbe ce qui reste et tronque
   proprement, les colonnes chiffrees gardent leur largeur, et plus rien ne deborde. max-width: 0 avec
   width: 100% est la facon standard de dire a une colonne de tableau « prends le reste, et cede ».
   inline-block est indispensable : sur un span inline, overflow et max-width ne s'appliquent pas, et
   la troncature ne se voyait qu'au foot parce que le nom y vit deja dans un conteneur flex. */
.lb-name-txt { display: inline-block; vertical-align: bottom; }
/* LA DATE D'ECRITURE, EN TETE DE CHAQUE COMPTE RENDU (08/09/2026). Discrete : elle informe, elle ne
   doit pas concurrencer le titre ni le recit lui-meme. */
.recap-genere { margin: 0 0 .5rem; font-size: .82rem; color: var(--muted); }
@media (max-width: 700px) {
    .lb-name-cell { max-width: 0; width: 100%; }
    .lb-tennis .tn-lb-open { min-width: 0; max-width: 100%; }
    .lb-tennis .tn-lb-open .lb-name-txt { min-width: 0; }
}
/* Badge buteur CLIQUABLE : zone tactile etendue a ~44px (pseudo-element invisible), affordances discretes. */
a.lb-buteur-chip { cursor: pointer; text-decoration: none; position: relative;
    transition: box-shadow .12s ease, transform .1s ease; }
a.lb-buteur-chip::after { content: ""; position: absolute; inset: -8px -10px; border-radius: 999px; }
a.lb-buteur-chip:hover { box-shadow: 0 2px 5px rgba(0, 0, 0, .22), 0 0 0 3px rgba(111, 156, 42, .25); }
a.lb-buteur-chip:focus-visible { outline: 2px solid var(--accent, #2bb061); outline-offset: 2px; }
a.lb-buteur-chip:active { transform: translateY(1px); box-shadow: 0 0 1px rgba(0, 0, 0, .2); }
.lb-pts-hint { margin: .3rem 0 0; }
.lbs-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, .55); z-index: 9998;
    display: flex; align-items: center; justify-content: center; padding: 1rem; }
.lbs-backdrop[hidden] { display: none; }
.lbs-sheet { position: relative; background: var(--card); border: 1px solid var(--border); border-radius: 14px;
    width: min(470px, 94vw); max-height: 88vh; overflow-y: auto; padding: .9rem 1rem 1rem; }
.lbs-close { position: absolute; top: .3rem; right: .5rem; background: none; border: none; font-size: 1.6rem;
    line-height: 1; color: var(--muted); cursor: pointer; padding: .15rem .3rem; z-index: 2; }
.lbs-head { padding-right: 1.6rem; }
.lbs-contest { font-size: .74rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--accent-ink, #1f8a4c); }
.lbs-title { font-weight: 800; font-size: 1.12rem; margin-top: .05rem; }
.lbs-sub { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; margin-top: .25rem; }
.lbs-rankpill { display: inline-block; font-weight: 800; font-size: .9rem; padding: .1rem .55rem; border-radius: 6px;
    background: var(--card-2); color: var(--text); }
.lbs-rankpill.is-1 { color: #b8912b; } .lbs-rankpill.is-2 { color: #8c9bb0; } .lbs-rankpill.is-3 { color: #b46a32; }
/* VRAI bouton (seul element interactif du haut) : relief discret, hover, enfoncement. */
.lbs-hist { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; font-weight: 700;
    padding: .34rem .75rem; border-radius: 9px; text-decoration: none; color: var(--on-accent);
    background: var(--accent-2, #2bb061); border: 1px solid color-mix(in srgb, var(--accent-2, #2bb061) 70%, #000 12%);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transition: transform .12s ease, box-shadow .12s ease, filter .12s ease; }
.lbs-hist:hover, .lbs-hist:focus-visible { filter: brightness(1.07); box-shadow: 0 2px 6px rgba(0, 0, 0, .3); transform: translateY(-1px); }
.lbs-hist:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, .25); }
.lbs-hist { flex-wrap: wrap; row-gap: .05rem; }
.lbs-hist [data-f="histmove"] { font-weight: 600; opacity: .92; white-space: nowrap; }
.lbs-flag-late { font-size: .7rem; font-weight: 600; padding: .08rem .5rem; border-radius: 6px;
    background: var(--card-2); color: var(--muted); }
.lbs-joinline { margin-top: .3rem; font-size: .8rem; color: var(--muted); }
.lbs-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: .4rem; margin: .65rem 0; }
.lbs-card { background: var(--card-2); border: 1px solid var(--border); border-radius: 9px; padding: .4rem .45rem; text-align: center; }
.lbs-card[hidden] { display: none; }
.lbs-c-v { font-weight: 800; font-size: 1.02rem; line-height: 1.15; }
.lbs-c-l { font-size: .6rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-top: .12rem; }
.lbs-c-total .lbs-c-v { font-size: 1.18rem; color: var(--accent-ink, #1f8a4c); }
/* Sections de decomposition : sobres, un seul liseré discret, maths alignees. */
.lbs-sec { border: 1px solid var(--border); border-left: 3px solid var(--accent-2, #2bb061); border-radius: 9px;
    padding: .45rem .65rem; margin: 0 0 .45rem; background: var(--card); }
.lbs-sec[hidden] { display: none; }
.lbs-sec-head { display: flex; align-items: baseline; gap: .5rem; }
.lbs-sec-t { font-weight: 800; font-size: .88rem; }
.lbs-sec-n { font-size: .72rem; color: var(--muted); }
.lbs-sec-pts { margin-left: auto; font-weight: 800; font-size: 1rem; white-space: nowrap; }
.lbs-line { display: flex; align-items: baseline; gap: .5rem; margin: .18rem 0 0; padding-left: .2rem;
    font-size: .8rem; color: var(--muted); }
.lbs-line[hidden] { display: none; }
.lbs-line-l { flex: 1 1 auto; min-width: 0; }
.lbs-line-v { font-weight: 700; color: var(--text); white-space: nowrap; }
.lbs-inplay { margin-left: auto; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    padding: .08rem .5rem; border-radius: 6px; background: var(--card-2); color: var(--muted); }
.lbs-scorer { flex-wrap: wrap; }
.lbs-scorer-rank { font-size: .7rem; font-weight: 600; color: var(--muted); }
.lbs-preds { display: flex; flex-direction: column; gap: .25rem; margin-top: .35rem; }
.lbs-pred { display: flex; align-items: center; gap: .45rem; font-size: .82rem; }
.lbs-pred-l { flex: 1 1 auto; color: var(--text); }
.lbs-b { font-weight: 700; font-size: .76rem; padding: .06rem .5rem; border-radius: 6px; white-space: nowrap; }
.lbs-b-ok { background: rgba(43, 176, 97, .1); color: #43c078; }
.lbs-b-ko { background: rgba(200, 60, 60, .09); color: #d98a8a; }
html[data-theme="light"] .lbs-b-ok { color: #1f8a4c; }
html[data-theme="light"] .lbs-b-ko { color: #b91c1c; }
.lbs-help { margin: .5rem 0 0; }
body.lbs-open { overflow: hidden; }
/* Mobile : BOTTOM SHEET scrollable (l'essentiel en haut, le detail defile). */
@media (max-width: 640px) {
    .lbs-backdrop { align-items: flex-end; padding: 0; }
    .lbs-sheet { width: 100%; max-height: 86vh; border-radius: 16px 16px 0 0; border-bottom: none;
        animation: lbs-up .22s ease; padding-top: 1.1rem; }
    .lbs-sheet::before { content: ""; position: absolute; top: .42rem; left: 50%; width: 40px; height: 4px;
        margin-left: -20px; border-radius: 999px; background: var(--border); }
}
@keyframes lbs-up { from { transform: translateY(28px); opacity: .6; } to { transform: translateY(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .lbs-sheet { animation: none; } }
/* Bouton REFRESH manuel des classements : rond discret en haut a droite de la card, HORS de .lb-wrap (ne scrolle
   pas avec la table). L'icone tourne pendant le fetch. Le titre garde un peu de padding a droite pour ne pas
   passer sous le bouton sur petit ecran. */
[data-lb-refresh] { position: relative; }
[data-lb-refresh] > h2, [data-lb-refresh] > h3 { padding-right: 2.6rem; }
.lb-refresh { position: absolute; top: .5rem; right: .55rem; z-index: 3; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 1px solid var(--border); border-radius: 8px; background: var(--card-2); color: var(--muted); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.lb-refresh:hover, .lb-refresh:focus-visible { color: var(--accent-ink); border-color: var(--accent); }
.lb-refresh svg { width: 16px; height: 16px; display: block; }
.lb-refresh.is-spinning { pointer-events: none; opacity: .65; }
.lb-refresh.is-spinning svg { animation: lb-spin .8s linear infinite; transform-origin: 50% 50%; }
@keyframes lb-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .lb-refresh.is-spinning svg { animation: none; } }
/* Toast "Enregistre" cyclisme : notification FLOTTANTE visible (le form etape est long, le badge inline en bas
   passe inapercu). Fixe en bas-centre, apparait puis s'estompe -> memes regles que le "Enregistre" du foot. */
.cyc-toast { position: fixed; left: 50%; bottom: 1.1rem; transform: translateX(-50%) translateY(.6rem); z-index: 60;
    display: inline-flex; align-items: center; gap: .3rem; max-width: calc(100vw - 1.5rem); padding: .5rem .95rem;
    border-radius: 999px; font-weight: 700; font-size: .92rem; box-shadow: 0 6px 22px rgba(0,0,0,.28);
    opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease; }
.cyc-toast.is-show { opacity: 1; transform: translateX(-50%) translateY(0); }
.cyc-toast.is-ok { background: var(--ok); color: #fff; }
.cyc-toast.is-err { background: var(--danger, #eb5757); color: #fff; }
.cyc-toast svg { display: block; }
@media (prefers-reduced-motion: reduce) { .cyc-toast, .cyc-toast.is-show { transition: opacity .2s ease; transform: translateX(-50%); } }
@media (max-width: 560px) {
    .lb-table { font-size: .88rem; }
    .lb-table th, .lb-table td { padding-left: .35rem; padding-right: .35rem; }
}
/* Pagination du classement (concours massifs) + ligne separateur avant la ligne du viewer hors tranche */
.lb-pager { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; margin: .5rem 0 .2rem; }
.lb-pager-btns { display: flex; gap: .4rem; }
.lb-table .lb-sep td { text-align: center; color: var(--muted); padding: .15rem; letter-spacing: .25em; }
/* En-tetes de colonne triables (Points / Moyenne / Perfects / Entre le) */
.lb-table th.lb-sortable { white-space: nowrap; }
.lb-table th.lb-sortable a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: .2rem; cursor: pointer; }
.lb-table th.lb-sortable a:hover { text-decoration: underline; }
.lb-table th.lb-sortable.is-sort a { color: var(--accent-ink); font-weight: 800; } /* tri actif : vert TEXTE lisible (pas le vert de fond --accent trop sombre) */
.lb-sort-arr { font-size: .72em; }
/* Depliant "Resultat des poules" (expand-collapse natif <details>) */
.poules-recap > summary { cursor: pointer; list-style: none; font-size: 1.02rem; display: flex; align-items: center; gap: .4rem; }
.poules-recap > summary::-webkit-details-marker { display: none; }
.poules-recap-caret { font-size: .8em; color: var(--muted); transition: transform .15s; margin-left: auto; }
.poules-recap[open] .poules-recap-caret { transform: rotate(180deg); }
.poules-recap-intro { margin: .45rem 0 .5rem; }
.poules-recap-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.poules-recap-item { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.poules-recap-ic { font-size: 1.1rem; }
.poules-recap-lbl { color: var(--muted); min-width: 13rem; }
.poules-recap-who { font-weight: 600; }
@media (max-width: 560px) { .poules-recap-lbl { min-width: 0; } }

/* Match */
.match { background: var(--card-2); border: 1px solid var(--border); border-radius: 10px; padding: .8rem; margin: .7rem 0; position: relative; }
.match .teams { display: flex; align-items: center; gap: .5rem; font-weight: 600; }
.match .ko { color: var(--muted); font-size: .85rem; }
.score-inputs { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.score-inputs input { width: 4.3rem; text-align: center; font-size: 1.5rem; font-weight: 800; padding: .45rem .3rem; line-height: 1.1; }
.score-inputs input::-webkit-inner-spin-button { opacity: 1; height: 2rem; }

/* Bloc de saisie de pronostic centre : [drapeau XL] [stepper] - [stepper] [drapeau XL] */
.score-board { display: flex; align-items: center; justify-content: center; gap: .55rem; flex-wrap: nowrap; margin: 1rem 0 .2rem; } /* un peu d'air au-dessus (place pour les points une fois le match fini) */
.flag.flag-xl { width: 44px; height: 33px; margin: 0; border-radius: 4px; vertical-align: middle; flex: 0 0 auto; box-shadow: 0 0 0 1px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.3); }
.stepper { display: flex; flex-direction: column; align-items: stretch; width: 3.4rem; flex: 0 0 auto; background: #161a22; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.stepper:focus-within { border-color: var(--accent-ink); box-shadow: 0 0 0 2px rgba(43,176,97,.35); }
.stp-btn { appearance: none; -webkit-appearance: none; border: 0; background: transparent; color: var(--muted); padding: .28rem 0; margin: 0; cursor: pointer; display: flex; align-items: center; justify-content: center; line-height: 0; transition: color .12s, background .12s; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.stp-btn:hover { color: var(--text); }
.stp-btn:active { background: rgba(43,176,97,.18); color: var(--accent-ink); }
.stp-btn:disabled { opacity: .4; cursor: not-allowed; }
.stp-btn:disabled:hover { color: var(--muted); }
.stepper .stp-input:disabled { opacity: .7; }
.stepper .stp-input { width: 100%; border: 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); border-radius: 0; background: transparent; color: var(--text); text-align: center; font-size: 2rem; font-weight: 800; line-height: 1; padding: .15rem 0; caret-color: transparent; }
.stepper .stp-input:focus { outline: none; background: rgba(43,176,97,.14); } /* leger surlignage, la police reste blanche */
.stepper .stp-input::placeholder { color: var(--muted); opacity: .6; font-weight: 700; }
.stepper .stp-input::-webkit-outer-spin-button, .stepper .stp-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper .stp-input::selection { background: rgba(43,176,97,.45); color: #fff; } /* selection verte (pas le bleu systeme) */
.score-sep { font-size: 1.6rem; font-weight: 800; color: var(--muted); flex: 0 0 auto; padding: 0 .1rem; }
.ht-row { display: flex; align-items: center; justify-content: center; gap: .5rem; margin: .8rem 0 .1rem; flex-wrap: wrap; } /* plus d'air entre le score et le vainqueur a la mi-temps */
.ht-label { margin: 0; color: var(--muted); font-size: .82rem; }
.ht-select { width: auto; max-width: 100%; padding: .32rem 2rem .32rem .8rem; border-radius: 999px; font-size: .9rem; font-weight: 600; color: var(--text); cursor: pointer; }
.ht-select:disabled { cursor: not-allowed; opacity: .85; }
/* Champ "equipe qualifiee" : meme rendu que le vainqueur a la mi-temps (ht-row/ht-select, centre, semi-gras).
   Explication au-dessus, note "Remplissage automatique" REPLIABLE : le "?" deplie l'explication (clic fiable). */
.qual-field { margin-top: .2rem; }
.qual-field .qual-extra-help { text-align: center; margin: 1.15rem 0 .15rem; } /* plus d'air -> la phrase se lit comme un intitule explicatif, detachee de la mi-temps */
.qual-auto-note { margin: .3rem 0 0; text-align: center; }
.qual-auto-note > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .35rem; color: var(--muted); }
.qual-auto-note > summary::-webkit-details-marker { display: none; }
.qual-auto-note > p { text-align: left; margin: .45rem auto 0; max-width: 34rem; background: rgba(127,127,127,.08); border-left: 3px solid var(--accent); border-radius: 0 7px 7px 0; padding: .55rem .75rem; }
/* Petit tiret-separateur central : marque la transition entre les 3 categories du prono (score / mi-temps / qualifie). */
.match-mini-sep { width: 2.4rem; height: 0; border-top: 2px solid var(--border); border-radius: 2px; margin: .7rem auto .5rem; }
.md-head { text-align: center; margin: .25rem 0 .1rem; font-size: .95rem; }
.md-phase { color: var(--accent-ink); font-weight: 700; }

/* Mode edition / verrouille des formulaires de pronostic (vue puis edition explicite) */
.pred-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .5rem; }
/* Auto-save : indicateur de statut par match (3 etats), plus de bouton ni mode lecture/Modifier. */
.pred-status { font-size: .9rem; font-weight: 600; display: inline-flex; align-items: center; gap: .25rem; min-height: 1.2em; transition: opacity .5s ease; }
.pred-status.is-faded { opacity: 0; }
.pred-status > span { display: none; align-items: center; gap: .25rem; }
.pred-status.is-saved .ps-saved { display: inline-flex; color: var(--accent-ink); }
.pred-status.is-saving .ps-saving { display: inline-flex; color: var(--muted); }
.pred-status.is-error .ps-error { display: inline-flex; color: var(--danger); }
/* Indice mot de passe (inscription) : vert quand la politique est respectee. */
.pw-hint.pw-ok { color: var(--accent-ink); }
.pw-hint.pw-ok::before { content: '\2713\00a0'; }
@media (max-width: 360px) {
    .score-board { gap: .35rem; }
    .stepper { width: 3rem; }
    .stepper .stp-input { font-size: 1.7rem; }
    .score-in { width: 3rem; font-size: 1.6rem; }
    .score-in-sm { width: 2.4rem; }
    .flag.flag-xl { width: 38px; height: 28px; }
}
.locked { opacity: .65; }
.badge { display: inline-block; padding: .1rem .5rem; border-radius: 999px; font-size: .75rem; background: var(--card-2); border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.badge-bonus { background: rgba(217,161,65,.18); border-color: var(--warn); color: #f0c777; }
.badge-locked { background: rgba(217,83,79,.15); border-color: var(--danger); color: #e8908d; }
.badge-late { background: rgba(124,58,237,.18); border-color: #7c3aed; color: #c4b5fd; } /* concours entree tardive */
.badge-normal { background: var(--card-2); border-color: var(--border); color: var(--muted); }
.late-rules-link { white-space: nowrap; }
/* En-tete de liste (titre + boutons d'action au-dessus de la liste). */
.list-header { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.list-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.vote-abstain-joke { font-style: italic; }
/* Selecteur de pays custom (drapeaux images dans la liste deroulante). */
.cpick { position: relative; }
.cpick-btn { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: .5rem; text-align: left; background: var(--card-2); border: 1px solid var(--border); border-radius: 8px; padding: .55rem .7rem; color: var(--text); cursor: pointer; font: inherit; }
.cpick-btn:hover { border-color: var(--accent-ink); }
.cpick-cur { display: inline-flex; align-items: center; gap: .5rem; min-width: 0; }
.cpick-caret { color: var(--muted); flex: 0 0 auto; }
.cpick-pop { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40; overflow-y: auto; background: var(--card); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 14px 34px rgba(0,0,0,.5); }
.cpick-pop.up { top: auto; bottom: calc(100% + 4px); }
.cpick-opt { width: 100%; display: flex; align-items: center; gap: .5rem; text-align: left; background: none; border: 0; padding: .45rem .7rem; color: var(--text); cursor: pointer; font: inherit; }
.cpick-opt:hover { background: var(--card-2); }
.cpick .flag { border-radius: 2px; }
.match-meta .badge { margin-left: .5rem; } /* un peu d'air avant "Match bonus" / "Verrouille" */
.badge-danger { background: rgba(217,83,79,.15); border-color: var(--danger); color: #e8908d; }
/* Enjeu fourni : vrai petit fond vert + coche (defini APRES .badge pour ne pas etre ecrase) */
.badge-ok { background: rgba(43,176,97,.28); border-color: rgba(46,204,113,.65); color: #8fe3b0; font-weight: 700; }
/* "en attente" : discret, juste un texte orange doux (ni fond ni bordure, ne fait pas bouton) */
.badge-wait { background: transparent; border: 0; color: #d9a441; font-weight: 600; padding: .1rem .2rem; }
/* Pilotage, cinquieme feu (09/09/2026) : « se regle seul ». Un bleu franc, qui ne se confond ni avec
   le vert du calme ni avec l'orange de ce qui attend un geste. Le calme, mais pas le vert. */
.badge-patience { background: rgba(45,156,219,.16); border-color: rgba(45,156,219,.55); color: #7fc4ea; font-weight: 600; }
.chat-thread { margin: .3rem 0; }
.chat-msg:first-child { border-top: none !important; }
.chip-box { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; padding: .4rem; border: 1px solid var(--border); border-radius: 8px; background: var(--card-2); cursor: text; }
.chip { display: inline-flex; align-items: center; gap: .3rem; background: rgba(45,156,219,.18); border: 1px solid #2d9cdb; color: #bfe3f7; border-radius: 999px; padding: .1rem .2rem .1rem .55rem; font-size: .8rem; }
.chip-bad { background: rgba(217,83,79,.18); border-color: var(--danger); color: #e8908d; }
.chip-x { background: none; border: none; color: inherit; cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 .2rem; }
.chip-entry { flex: 1; min-width: 8rem; border: none; background: transparent; outline: none; color: inherit; font: inherit; padding: .2rem; }

/* Grille des pronos (transparence). Largeur de la colonne NOM = variable --cg-name-w (13/07) : sert a la
   fois de largeur FIXE de .col-player ET de decalage sticky de .col-pts -> les deux restent alignes quand
   on la reduit sur mobile pour liberer de la place aux colonnes de matchs. */
.grid-wrap { overflow: auto; max-height: 75vh; border: 1px solid var(--border); border-radius: 8px; }
.grid-table { border-collapse: separate; border-spacing: 0; font-size: .72rem; width: max-content; --cg-name-w: 8rem; }
.grid-table th, .grid-table td { padding: .25rem .45rem; white-space: nowrap; text-align: center; border-bottom: 1px solid rgba(255,255,255,.05); border-right: 1px solid rgba(255,255,255,.04); }
.grid-table thead th { position: sticky; top: 0; background: var(--card); z-index: 2; font-weight: 600; }
.grid-table .col-player { position: sticky; left: 0; background: var(--card); text-align: left; z-index: 1; width: var(--cg-name-w); min-width: var(--cg-name-w); max-width: var(--cg-name-w); overflow: hidden; }
.grid-table .col-pts { position: sticky; left: var(--cg-name-w); background: var(--card); z-index: 1; }
.grid-table thead th.col-player, .grid-table thead th.col-pts { z-index: 3; }
.grid-table .col-player .pc-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; } /* nom tronque proprement -> largeur previsible */
/* Mobile : colonne nom + marges resserrees pour afficher PLUS de colonnes de matchs, sans perdre d'info. */
@media (max-width: 640px) {
    .grid-table { --cg-name-w: 6rem; font-size: .7rem; }
    .grid-table th, .grid-table td { padding: .22rem .3rem; }
    .grid-table .col-player .player-cell { gap: .22rem; }
}
@media (max-width: 400px) {
    .grid-table { --cg-name-w: 5rem; }
    .grid-table th, .grid-table td { padding: .2rem .22rem; }
    .grid-table .col-player .player-cell .avatar { display: none; } /* tres petit ecran : on garde drapeau + nom (l'avatar est decoratif) */
}
.cell-ok { background: rgba(39,174,96,.32); }
.cell-res { background: rgba(242,201,76,.30); }
.cell-miss { background: rgba(217,83,79,.26); }
.cell-pending { color: var(--muted); }
.cell-hidden, .cell-empty { color: var(--muted); opacity: .55; }
/* Marqueurs de cellule accessibles : la FORME (✓/≈/✗) et la lettre P (perfect) portent l'info, pas seulement la couleur (daltonien rouge-vert). 3 couleurs de fond seulement. */
.grid-table td.cell-ok, .grid-table td.cell-res, .grid-table td.cell-miss,
.grid-cells td.cell-ok, .grid-cells td.cell-res, .grid-cells td.cell-miss { position: relative; }
.cg-tag { position: absolute; top: 0; left: 0; font-size: .5rem; line-height: 1.05; font-weight: 800; padding: 1px 2px; border-bottom-right-radius: 4px; }
.cg-tag.cg-p { background: #0a5a2c; color: #eafff1; }
.cg-gly { position: absolute; top: -1px; right: 1px; font-size: .62rem; line-height: 1; font-weight: 700; color: #fff; text-shadow: 0 0 2px rgba(0,0,0,.9); }
.cg-tag-inline { display: inline-block; font-size: .62rem; font-weight: 800; padding: 0 3px; border-radius: 3px; vertical-align: middle; }
.cg-tag-inline.cg-p { background: #0a5a2c; color: #eafff1; }
.cg-gly-inline { font-weight: 700; letter-spacing: 1px; }
@media print { .cg-gly { color: #111; text-shadow: none; } }
/* Chargement progressif (13/07) : bouton "charger les matchs precedents" a gauche de la zone chargee. */
.grid-loadprev-wrap { display: flex; align-items: center; gap: .5rem; margin: 0 0 .4rem; }
/* Pagination verticale (13/07 soir) : bouton "joueurs suivants" pleine largeur sous la grille */
.grid-loadrows-wrap { margin: .55rem 0 0; }
.grid-loadrows { width: 100%; justify-content: center; }
.glr-count { opacity: .75; font-weight: 600; }
.grid-loadprev { display: inline-flex; align-items: center; gap: .35rem; min-height: 38px; padding: .35rem .8rem;
    border-radius: 8px; border: 1px solid var(--border); background: var(--card-2); color: var(--text);
    font: inherit; font-size: .9rem; font-weight: 700; cursor: pointer; box-shadow: 0 1px 2px rgba(0,0,0,.18); }
.grid-loadprev:hover:not(:disabled) { border-color: var(--accent-2); }
.grid-loadprev:active:not(:disabled) { transform: translateY(1px); }
.grid-loadprev:disabled { opacity: .5; cursor: default; }
.grid-loadprev .glp-spin { width: 14px; height: 14px; border: 2px solid var(--muted); border-top-color: transparent;
    border-radius: 50%; animation: glp-rot .7s linear infinite; display: none; }
.grid-loadprev.is-loading .glp-spin { display: inline-block; }
.grid-loadprev.is-loading .glp-arrow { display: none; }
@keyframes glp-rot { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .grid-loadprev .glp-spin { animation: none; } }
/* Page d'IMPRESSION dediee de la grille : fond clair, tables lisibles a l'ecran ET a l'impression. */
.grid-print-page { background: #fff; color: #111; padding: 1rem; border-radius: 10px; }
.grid-print-page .pdf-head h1 { font-size: 1.2rem; margin: 0 0 .3rem; color: #111; }
.grid-print-page .pdf-day { margin: 0 0 1.1rem; }
.grid-print-page .pdf-day h2 { font-size: 1rem; margin: 1rem 0 .3rem; border-bottom: 1px solid #999; padding-bottom: .2rem; color: #111; }
.grid-print-page .pdf-table { width: 100%; border-collapse: collapse; font-size: .72rem; }
.grid-print-page .pdf-table th, .grid-print-page .pdf-table td { border: 1px solid #bbb; padding: 2px 5px; text-align: center; color: #111; }
.grid-print-page .pdf-table th { background: #eee; }
.grid-print-page .pdf-table .pdf-player { text-align: left; white-space: nowrap; }
.grid-print-page .pdf-res { display: block; font-weight: 700; color: #444; font-size: .66rem; }
/* Popover "info prono" (clic sur une case de la grille) */
.cell-peek { cursor: pointer; }
.cell-peek:hover, .cell-peek:focus { outline: 2px solid rgba(255,255,255,.4); outline-offset: -2px; }
.grid-live { display: inline-block; color: #ff5b5b; font-weight: 800; font-size: .58rem; letter-spacing: .03em; text-transform: uppercase; animation: pkpulse 1.2s infinite; }
/* Case surlignee dans le cadre de replay au moment ou le joueur a clique (montre QUELLE carte) */
.sr-cell-hl { outline: 3px solid #ff8a00 !important; outline-offset: -2px; background: rgba(255,138,0,.30) !important; }
/* Cadre du replay de scroll (iframe ?srreplay=1) : on masque le CHROME (en-tete qui montre l'identite/les
   badges de l'admin connecte, banniere, pied de page) -> on rejoue le CONTENU vu par le joueur, pas la
   session de l'admin. La page est deja rendue en vue "membre" cote serveur (sm_view_as). */
body.srreplay .topbar, body.srreplay .site-banner, body.srreplay footer, body.srreplay .site-footer { display: none !important; }
body.srreplay { padding-top: 0 !important; }
/* Dans le cadre de replay, la grille NE doit PAS etre plafonnee a 75vh : sinon elle defile EN INTERNE, hors
   champ, sous l'en-tete du concours qui reste fige -> on la laisse pleine hauteur pour que la fenetre de
   l'iframe defile a travers (en-tete puis grille), exactement comme la capture mobile. L'horizontal reste
   scrollable (overflow-x auto via la regle de base). */
body.srreplay .grid-wrap { max-height: none !important; }
.pk-modal { position: fixed; inset: 0; z-index: 140; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; padding: 1rem; }
.pk-modal[hidden] { display: none; }
.pk-box { position: relative; background: var(--card,#161b22); border: 1px solid var(--border); border-radius: 14px; width: min(380px,94vw); padding: 1rem 1.1rem; box-shadow: 0 18px 50px rgba(0,0,0,.5); }
.pk-close { position: absolute; top: .45rem; right: .55rem; background: none; border: 0; color: var(--muted); font-size: 1.05rem; cursor: pointer; line-height: 1; }
.pk-content { font-size: .9rem; }
.pk-head { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; margin: 0 1.2rem .35rem 0; }
.pk-pred { display: flex; align-items: center; gap: .4rem; margin: .15rem 0 .5rem; flex-wrap: wrap; }
.pk-score { font-size: 1.5rem; font-weight: 800; }
.pk-pred-tag { font-size: .68rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.pk-real { font-size: .82rem; color: var(--muted); margin: -.2rem 0 .5rem; }
.pk-real strong { color: var(--text); font-size: .95rem; }
.pk-proj { font-weight: 600; margin: .3rem 0; }
.pk-status { font-size: .85rem; margin: .2rem 0; }
.pk-points { display: flex; align-items: center; gap: .35rem; font-weight: 700; margin: .3rem 0; flex-wrap: wrap; }
.pk-points.pk-ok { color: #46d07f; }
.pk-points.pk-res { color: #f0c34c; }
.pk-points.pk-miss { color: #ff6b6b; }
.pk-gly { font-weight: 800; }
.pk-live { color: #ff6b6b; font-weight: 700; }
.pk-livedot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #ff3b3b; animation: pkpulse 1s infinite; vertical-align: middle; }
@keyframes pkpulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
.pk-chips { display: flex; flex-wrap: wrap; gap: .25rem; margin: .25rem 0 .4rem; }
.pk-meta { border-top: 1px solid var(--border); margin-top: .5rem; padding-top: .45rem; display: flex; flex-direction: column; gap: .25rem; font-size: .82rem; }
.pk-msg { padding: 1rem .4rem; text-align: center; }
.legend { display: inline-block; padding: .05rem .45rem; border-radius: 4px; margin-right: .3rem; }
.grid-clickhint { display: inline-block; background: rgba(58,209,122,.12); border: 1px solid rgba(58,209,122,.4); border-radius: 8px; padding: .35rem .6rem; color: var(--text); }
/* Grille : encodage des autres paris sur le score */
.ht-mark { text-decoration: underline; text-decoration-color: #4aa3ff; text-decoration-thickness: 2px; text-underline-offset: 2px; }
/* Qualifie PRONO (equipe que le joueur voit passer) : surlignage PLEIN mais SOBRE du chiffre (fond vert-gris
   discret, pas fluo), au lieu d'un simple soulignement vert (une COULEUR seule se confondait avec le bleu
   mi-temps pour les daltoniens). Le fond PLEIN se distingue par sa FORME du soulignement bleu .ht-mark, qui
   reste : un chiffre a la fois vainqueur mi-temps ET qualifie cumule les deux (souligne bleu + fond vert-gris).
   Fond solide -> lisible sur theme clair ET sombre. Le PDF force les fonds (.grid-pdf print-color-adjust:exact). */
.qual-mark { display: inline-block; vertical-align: baseline; background: #5f7a6b; color: #f2f7f4; border-radius: 4px; padding: .04em .32em; font-weight: 700; }
/* Cumul mi-temps + qualifie : MEME soulignement (text-decoration) qu'en temps normal mais en BLANC (le bleu ne
   ressort pas sur le fond sage), place un peu plus BAS via padding-bottom pour qu'il tombe DANS le fond sage et
   reste bien visible (sans padding il debordait sous le chip, sur le fond de ligne, et disparaissait). */
.ht-mark.qual-mark { text-decoration-color: #ffffff; text-underline-offset: 2px; padding-bottom: .3em; }
/* Score REEL : souligne le chiffre du vainqueur de la MI-TEMPS (currentColor -> lisible theme clair/sombre),
   avec un petit ecart sous le chiffre, pour comparer d'un coup d'oeil avec le prono. */
.rs-dig { display: inline-block; vertical-align: baseline; }
.rs-ht-dig { border-bottom: 2px solid currentColor; padding-bottom: 1px; }
/* Mi-temps REELLE nulle : "=" entre les scores (currentColor, comme le souligne reel -> discret, lisible clair/sombre),
   symetrique du "=" bleu du prono. Montre que la mi-temps s'est finie sur un nul. */
.rs-ht-draw { font-weight: 800; padding: 0 1px; }
.ht-draw { color: #4aa3ff; font-weight: 800; padding: 0 1px; }
/* AFFICHAGE DU RESULTAT reel (pas le prono) : leader mi-temps souligne (res-ht, comme les pronos), equipe
   REELLEMENT qualifiee encadree (res-qual), eliminee barree subtilement (res-out). Cadre/barre = phase finale
   uniquement. Pur affichage, zero impact sur les points. */
.res-team { display: inline-block; line-height: 1.25; }
.res-ht { border-bottom: 2px solid #4aa3ff; padding-bottom: 1px; }
.res-qual { border: 1.5px solid #38d27a; border-radius: 6px; padding: 0 .3rem; background: rgba(56,210,122,.14); font-weight: 700; }
/* Pays HORS COMPETITION (elimine) : nom grise + BARRE ROUGE EPAISSE et FONCEE, bien visible (Jonathan 16/07).
   text-decoration-color independant de la couleur du texte -> la barre reste franche meme si le nom est grise. */
.res-out { color: var(--muted); text-decoration: line-through; text-decoration-color: #e23b46; text-decoration-thickness: 3px; text-decoration-skip-ink: none; }
html[data-theme="light"] .res-ht { border-bottom-color: #1d6fd1; }
html[data-theme="light"] .res-qual { border-color: #1a9e54; background: rgba(26,158,84,.10); }
/* PETITE FINALE (3e place) : le vainqueur en ORANGE clair (meme encadre que le vert, mais orange -> il gagne mais
   n'est PAS qualifie pour un tour suivant). Orange leger pour que le texte (noir en clair) reste lisible. */
.res-qual-third { border: 1.5px solid #e0871a; border-radius: 6px; padding: 0 .3rem; background: rgba(245,165,36,.18); font-weight: 700; }
html[data-theme="light"] .res-qual-third { border-color: #b9660a; background: rgba(232,140,20,.16); }
/* CHAMPION (vainqueur de la FINALE, ligne de la finale) : le label vert (res-qual) ZOOME facon battement de coeur
   (jusqu'a ~150%, douce, pas agressive) + petits confettis autour. "Un petit truc incroyable" (Jonathan 16/07). */
.res-champ { display: inline-block; position: relative; z-index: 3; transform-origin: center; will-change: transform; animation: res-champ-beat 1.6s ease-in-out infinite; }
@keyframes res-champ-beat { 0%,100% { transform: scale(1); } 18% { transform: scale(1.5); } 32% { transform: scale(1.07); } 46% { transform: scale(1.38); } 60% { transform: scale(1); } }
.res-champ::after { content: ''; position: absolute; left: 50%; top: 0; width: 3px; height: 3px; border-radius: 50%; pointer-events: none; opacity: 0;
    box-shadow: -15px -5px 0 0 #f5c518, 13px -7px 0 0 #38d27a, -9px 6px 0 0 #ef4d5e, 17px 3px 0 0 #4aa3ff, 3px -11px 0 0 #f59e0b, -19px 1px 0 0 #a855f7, 9px 8px 0 0 #f5c518;
    animation: res-champ-confetti 1.6s ease-in-out infinite; }
@keyframes res-champ-confetti { 0% { opacity: 0; transform: translateY(-2px) scale(.5); } 20% { opacity: 1; transform: translateY(-8px) scale(1); } 65% { opacity: .45; transform: translateY(5px) scale(.9); } 100% { opacity: 0; transform: translateY(12px) scale(.5); } }
@media (prefers-reduced-motion: reduce) { .res-champ { animation: none; } .res-champ::after { display: none; } }
html[data-theme="light"] .res-out { text-decoration-color: #b31217; } /* barre encore plus foncee sur fond clair */
.grid-joker { display: inline-block; margin-left: 2px; padding: 0 3px; border-radius: 4px; background: rgba(124,58,237,.22); border: 1px solid #7c3aed; color: #c4b5fd; font-size: .82em; font-weight: 800; vertical-align: baseline; }
.grid-joker.grid-joker-x3 { background: rgba(245,158,11,.22); border-color: #f59e0b; color: #fcd34d; }
.grid-legend2 { display: flex; flex-wrap: wrap; gap: .15rem .4rem; align-items: center; }
.grid-legend2 .lg-num { display: inline-block; min-width: 1ch; text-align: center; }
.grid-md { color: var(--accent-ink); font-weight: 700; font-size: .92em; }
/* Version "preuve" decoupee par journee : cachee a l'ecran, seule visible a l'impression/PDF */
.grid-pdf { display: none; }
@media print {
  @page { size: landscape; margin: 9mm; }
  body { background: #fff; color: #000; }
  .topbar, .foot, .toasts, .tabs, .no-print, .grid-screen, .container > .card { display: none !important; }
  .grid-pdf { display: block !important; }
  .container { max-width: none; margin: 0; padding: 0; }
  .pdf-head h1 { font-size: 15pt; margin: 0 0 4pt; }
  .pdf-head p { font-size: 8.5pt; color: #333; margin: 2pt 0; }
  .pdf-day { margin: 0 0 9pt; }
  .pdf-day h2 { font-size: 11pt; margin: 9pt 0 3pt; border-bottom: 1px solid #999; padding-bottom: 2pt; page-break-after: avoid; }
  .pdf-table { width: 100%; border-collapse: collapse; font-size: 8pt; }
  .pdf-table thead { display: table-header-group; } /* en-tete repete sur chaque page */
  .pdf-table th, .pdf-table td { border: 1px solid #bbb; padding: 2pt 4pt; text-align: center; }
  .pdf-table th { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .pdf-table tr { page-break-inside: avoid; }
  .pdf-table .pdf-player { text-align: left; white-space: nowrap; }
  .pdf-res { display: block; font-weight: 400; color: #555; font-size: 7.5pt; }
  .pdf-sub { font-weight: 700; font-size: 10pt; margin: 2pt 0; }
  .pdf-legend { display: flex; flex-wrap: wrap; gap: 2pt 8pt; font-size: 8pt; margin: 4pt 0 0; }
  /* PDF en couleur : on force l'impression des fonds (resultats), soulignements, drapeaux et jokers */
  .grid-pdf, .grid-pdf * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .pdf-table .grid-joker { color: #5b21b6; border-color: #7c3aed; }
  .pdf-table .grid-joker.grid-joker-x3 { color: #b45309; border-color: #f59e0b; }
  .pdf-table .ht-draw { color: #1d4ed8; }
  .pdf-player .flag { width: 15px; height: 11px; vertical-align: -1px; }
}
.crown { color: #f2c94c; }
.flag { display: inline-block; width: 20px; height: 15px; border-radius: 2px; vertical-align: -2px; margin-right: .35rem; box-shadow: 0 0 0 1px rgba(0,0,0,.35); object-fit: cover; }
.flag-r { margin-right: 0; margin-left: .35rem; }
/* Pastille CLUB (competitions de clubs, ex CL : pas d'ecussons = marques deposees) : trigramme sur fond
   couleur du club (teams.color), meme gabarit/rythme que .flag. Lisible sur couleur claire via text-shadow. */
/* ÉCUSSON de club : forme blason (bas arrondi), split diagonal aux 2 VRAIES couleurs du club
   (--c1/--c2, mig 102), trigramme à l'encre calculée pour le contraste (--ink, cf bc_ink_on).
   Couleurs autonomes -> rendu IDENTIQUE en clair et sombre. Jamais d'écusson officiel (marques). */
.team-dot { display: inline-flex; align-items: center; justify-content: center; min-width: 30px; height: 19px;
  padding: 0 5px; margin-right: .38rem; vertical-align: -4px;
  background: linear-gradient(90deg, var(--c1, #64748b) 0 72%, var(--c2, #475569) 72% 100%);
  color: var(--ink, #fff); text-shadow: var(--ink-sh, 0 1px 2px rgba(0,0,0,.5));
  font-size: .58rem; font-weight: 900; letter-spacing: .5px; line-height: 1;
  border-radius: 4px 4px 8px 8px / 4px 4px 11px 11px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.28), 0 1px 2px rgba(0,0,0,.18); }
.team-dot.flag-r { margin-right: 0; margin-left: .38rem; }
.avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; vertical-align: -7px; margin-right: .35rem; border: 1px solid var(--border); }
.avatar-lg { width: 76px; height: 76px; }
.countdown { font-size: .8rem; color: var(--muted); }
.countdown-red { color: #ff7a73; font-weight: 700; }
.countdown-locked { color: var(--danger); }

@media (min-width: 640px) {
    .container { padding: 1.5rem; }
}

/* Selecteur de langue */
.lang-switch { margin-left: .3rem; font-size: .8rem; }
.lang-switch a { color: var(--muted); padding: 0 .2rem; }
.lang-switch a.active { color: var(--text); font-weight: 700; }

/* Selecteur d'emojis (description + chat) */
.emoji-bar { position: relative; display: inline-block; vertical-align: middle; margin-left: .45rem; }
.emoji-btn { background: var(--card-2); border: 1px solid var(--border); border-radius: 6px; padding: .15rem .45rem; cursor: pointer; font-size: 1.1rem; line-height: 1; }
.emoji-btn:hover { border-color: var(--accent-ink); }
.emoji-pop { display: none; }
.emoji-pop.open { position: absolute; z-index: 60; top: 100%; right: 0; left: auto; margin-top: .35rem; display: grid; grid-template-columns: repeat(8, 1fr); gap: .15rem; background: var(--card-2); border: 1px solid var(--border); border-radius: 8px; padding: .55rem; box-shadow: 0 12px 30px rgba(0,0,0,.45); width: 340px; max-width: 92vw; }
.emoji-pop button { background: none; border: none; cursor: pointer; font-size: 1.2rem; padding: .2rem; border-radius: 4px; line-height: 1; }
.emoji-pop button:hover { background: rgba(43,176,97,.18); }
/* Bouton emoji ENFONCE quand le panneau est ouvert (toggle visible). */
.emoji-btn-active, .emoji-btn-active:hover { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
/* Mobile : le panneau emoji devient un bottom-sheet pleine largeur (toujours ENTIEREMENT visible, plus de
   crop a gauche du a l'ancrage sur un bouton etroit). Desktop inchange (pop ancree sous le bouton). */
@media (max-width: 560px) {
    .emoji-pop.open { position: fixed; left: 8px; right: 8px; top: auto; bottom: 12px; margin: 0; width: auto; max-width: none; max-height: 44vh; overflow-y: auto; box-shadow: 0 -8px 30px rgba(0,0,0,.5); grid-template-columns: repeat(auto-fill, minmax(34px, 1fr)); }
}

/* Description de concours repliable */
.contest-desc.collapsed { max-height: 4.3em; overflow: hidden; }
.desc-toggle { background: none; border: none; color: var(--accent-ink); cursor: pointer; font-size: .82rem; padding: .15rem 0; font-weight: 600; }
.desc-toggle:hover { text-decoration: underline; }

/* Jokers : choix = boutons PLEINS (incitatifs) ; final = badge CONTOUR colore (raffine) */
.badge-joker { background: linear-gradient(135deg,#7c3aed,#a855f7); color:#fff; }
.joker-box { display:flex; align-items:center; justify-content:flex-end; gap:.4rem; flex-wrap:wrap; margin-top:.45rem; }
.joker-prompt { font-size:.85rem; color:var(--muted); font-weight:600; }
/* Choix de joker PAS encore selectionne : sobre (contour, fond leger) */
.joker-btn { border:1px solid #7c3aed; color:#c4b5fd; background:rgba(124,58,237,.12); font-weight:700; box-shadow:none; }
.joker-btn:hover:not(:disabled) { background:rgba(124,58,237,.22); }
.joker-btn-x3 { border-color:#f59e0b; color:#fcd34d; background:rgba(245,158,11,.12); }
.joker-btn-x3:hover:not(:disabled) { background:rgba(245,158,11,.22); }
.joker-btn:disabled { opacity:.4; cursor:not-allowed; }
/* Joker SELECTIONNE : badge plein et vibrant (on voit clairement qu'il est choisi) */
.joker-active { text-align:center; font-weight:800; font-size:.86rem; border-radius:8px; border:1px solid #7c3aed; color:#fff; background:linear-gradient(135deg,#7c3aed,#a855f7); box-shadow:0 2px 9px rgba(124,58,237,.35); }
.joker-active-x3 { border-color:#f59e0b; color:#fff; background:linear-gradient(135deg,#d97706,#f59e0b); box-shadow:0 2px 9px rgba(245,158,11,.35); }
.joker-bar { display:flex; flex-direction:column; align-items:flex-start; gap:.35rem; background:var(--card-2); border:1px solid var(--border); border-radius:8px; padding:.55rem .75rem; margin:.5rem 0 .3rem; font-size:.9rem; }
.joker-hint { margin:0; font-size:.84rem; color:var(--muted); }
.joker-remaining { display:flex; align-items:center; gap:.3rem; flex-wrap:wrap; }
.joker-remaining-label { font-weight:700; font-size:.88rem; margin-right:.1rem; }
/* Badge "joker restant" : MEME visuel que le joker une fois place (solide, texte blanc) -> lisible en clair ET sombre */
.joker-badge { display:inline-flex; align-items:center; justify-content:center; min-width:1.7rem; height:1.45rem; padding:0 .5rem; border-radius:999px; font-weight:800; font-size:.82rem; color:#fff; border:0; }
.joker-badge-x2 { background:linear-gradient(135deg,#7c3aed,#a855f7); }
.joker-badge-x3 { background:linear-gradient(135deg,#d97706,#f59e0b); }
.joker-count { font-weight:700; }
.joker-count-x2 { color:#c4b5fd; }
.joker-count-x3 { color:#fcd34d; }
.joker-alert { background:rgba(245,158,11,.14); border-left:3px solid #f59e0b; border-radius:6px; padding:.55rem .8rem; margin:.3rem 0 .5rem; font-size:.9rem; color:#fde68a; }

/* Badge de completion sur les onglets de journee + navigation entre journees */
.tabs a { position: relative; }
/* Membre retire : tous les onglets sauf "Membres" sont grises et non cliquables. */
.tabs.tabs-locked a:not(.tab-members) { opacity: .4; pointer-events: none; }
.tabs.tabs-locked .tab-group-label { opacity: .4; }
.md-dot { position:absolute; top:-4px; right:-4px; min-width:13px; height:13px; padding:0 1px; border-radius:50%; font-size:9px; line-height:13px; text-align:center; font-weight:800; box-shadow:0 0 0 2px var(--bg); }
.md-dot-full { background:var(--accent-2); color:#04210f; }
.md-dot-partial { background:#f59e0b; color:#3a2600; }
.md-dot-locked { background:#6b7280; color:#e5e7eb; } /* incomplet mais VERROUILLE (coup d'envoi passe) : gris statique, plus d'action */
.md-dot-req { background:#ef4444; color:#fff; animation:md-dot-blink 1.1s ease-in-out infinite; } /* demandes d'acces : compteur clignotant */
@media (prefers-reduced-motion: reduce) { .md-dot-req { animation:none; box-shadow:0 0 0 2px var(--bg), 0 0 0 4px rgba(239,68,68,.5); } }
.access-msg { font-style:italic; color:var(--muted); margin-top:.2rem; }
/* Pastille "vote a faire" : rouge, clignote pour attirer l'oeil (appel a l'action). */
.md-dot-blink { background:#ef4444; color:#fff; animation:md-dot-blink 1.1s ease-in-out infinite; }
@keyframes md-dot-blink { 0%,100% { opacity:1; transform:scale(1); } 50% { opacity:.3; transform:scale(.78); } }
@media (prefers-reduced-motion: reduce) { .md-dot-blink { animation:none; box-shadow:0 0 0 2px var(--bg), 0 0 0 4px rgba(239,68,68,.5); } }
/* Pastille jaune clignotante : pronos du tournoi non remplis (garde la couleur de md-dot-partial) */
.md-dot-flash { animation:md-dot-blink 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .md-dot-flash { animation:none; box-shadow:0 0 0 2px var(--bg), 0 0 0 4px rgba(245,158,11,.55); } }
/* Pastille de recap RECENT non lu : pulse vert pour attirer l'oeil (ex. J12 republie en retard). */
.md-dot.recap-blink { animation:recapdot 1s ease-in-out infinite; }
@keyframes recapdot { 0%,100% { transform:scale(1); box-shadow:0 0 0 2px var(--bg), 0 0 0 0 rgba(58,209,122,.0); } 50% { transform:scale(1.28); box-shadow:0 0 0 2px var(--bg), 0 0 9px 3px rgba(58,209,122,.95); } }
@media (prefers-reduced-motion: reduce) { .md-dot.recap-blink { animation:none; box-shadow:0 0 0 2px var(--bg), 0 0 0 4px rgba(58,209,122,.6); } }
/* Eyebrow "Vote 1 / Vote 2" en tete de chaque bloc de l'onglet Vote. */
.vote-eyebrow { margin:0 0 .15rem; font-size:.7rem; font-weight:800; text-transform:uppercase; letter-spacing:.06em; color:var(--accent-ink); }
/* Grappe de pastilles d'etat sur le BOUTON d'onglet Vote (1 par vote, au coin, comme les
   autres onglets). Le mot "Vote" reste a l'interieur ; les pastilles debordent au coin et
   peuvent passer a la ligne s'il y a beaucoup de votes. */
.tabs a.tab-has-dots { padding-right:1.1rem; }
.vote-dots { position:absolute; top:-5px; right:-5px; display:flex; flex-wrap:wrap; gap:2px; max-width:42px; justify-content:flex-end; }
.vdot { width:13px; height:13px; border-radius:50%; box-shadow:0 0 0 2px var(--bg); display:flex; align-items:center; justify-content:center; font-size:9px; line-height:1; font-weight:800; }
.vdot-done { background:var(--accent-2); color:#04210f; }   /* vote fait (vert, petit check noir) */
.vdot-todo { background:#f59e0b; animation:md-dot-blink 1.1s ease-in-out infinite; } /* a faire (orange clignotant) */
.vdot-off  { background:#4b5563; }                          /* clos / fige (gris) */
@media (prefers-reduced-motion: reduce) { .vdot-todo { animation:none; box-shadow:0 0 0 2px var(--bg), 0 0 0 3px rgba(245,158,11,.55); } }

/* Sous-onglets de vote (Cagnotte / Visibilite / ...) : on n'affiche qu'un vote a la fois. */
.vote-subtabs { display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .8rem; }
.vote-subtab { position:relative; display:inline-flex; align-items:center; gap:.4rem; padding:.4rem .8rem; border:1px solid var(--border); border-radius:999px; background:var(--card-2); color:var(--text); font-weight:700; font-size:.9rem; }
.vote-subtab:hover { border-color:var(--accent-ink); }
/* Etat ACTIF commun (frise Général/J1..Jn, Aujourd'hui, tous les vote-subtabs) : texte BLANC sur le fond
   vert, lisible en mode clair COMME sombre (le vert fonce rendait le texte sombre illisible en clair). */
.vote-subtab.active { background:var(--accent-2); color:var(--on-accent); border-color:var(--accent-ink); }
.vote-subtab.active svg, .vote-subtab.active .ico { color:#fff; fill:currentColor; }
.vsub-dot { width:9px; height:9px; border-radius:50%; background:#4b5563; flex:0 0 auto; }
.vote-subtab.vsub-done .vsub-dot { background:var(--accent-2); }
.vote-subtab.active.vsub-done .vsub-dot { background:#04210f; }
.vote-subtab.vsub-todo .vsub-dot { background:#f59e0b; animation:md-dot-blink 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .vote-subtab.vsub-todo .vsub-dot { animation:none; } }

/* Bloc abstention sous le tableau de vote. */
.vote-abstain { display:flex; align-items:center; gap:.6rem; margin:.5rem 0 0; }
.md-nav { display:flex; justify-content:space-between; align-items:center; gap:.6rem; margin-top:1rem; padding-top:.7rem; border-top:1px solid var(--border); }
.md-nav a { color:var(--accent-ink); font-weight:600; font-size:.92rem; }
.md-nav a:hover { text-decoration:underline; }
.md-nav-next { margin-left:auto; }
/* Navigation prev/suiv AUSSI en haut, de part et d'autre du titre de journee. */
/* En-tete journee/phase (13/07) : fleches sur une ligne dediee (prev gauche / next droite), bloc central
   phase+date en dessous -> plus JAMAIS de collision libelle/fleches, robuste a toutes les langues. */
.md-head-row { display:flex; flex-direction:column; gap:.15rem; }
.md-head-navline { display:flex; justify-content:space-between; align-items:center; gap:.5rem; width:100%; }
.md-head-row .md-head-lg { min-width:0; }
.md-head-nav { color:var(--accent-ink); font-weight:600; font-size:.92rem; white-space:nowrap; max-width:48%; overflow:hidden; text-overflow:ellipsis; }
.md-head-nav-next { text-align:right; margin-left:auto; } /* colle a droite meme si prev absent */
.md-head-nav:hover { text-decoration:underline; }

/* --- Frise temporelle : entete (date du jour + prochain match) --- */
.matches-head { display:block; }
.matches-head h3 { margin:0; }
.matches-head-row { display:flex; align-items:center; gap:.65rem; flex-wrap:wrap; } /* titre + "aujourd'hui" sur une ligne, fini le vide a droite */
.today-chip { display:inline-flex; align-items:center; gap:.35rem; font-size:.78rem; font-weight:700; color:var(--text); background:var(--card-2); border:1px solid var(--border); border-radius:999px; padding:.15rem .55rem; }
.today-dot { width:7px; height:7px; border-radius:50%; background:#eb5757; box-shadow:0 0 6px rgba(235,87,87,.9); }
.next-match { display:flex; flex-direction:column; align-items:flex-end; gap:.1rem; border:1px solid var(--border); border-left:3px solid #eb5757; border-radius:8px; padding:.35rem .7rem; background:var(--card-2); max-width:20rem; font-variant-numeric: tabular-nums; }
.next-match-center { align-items:center; text-align:center; margin:.6rem auto 0; } /* carte "prochain match" centree sous le titre */
.next-match-label { font-size:.64rem; text-transform:uppercase; letter-spacing:.05em; color:#ff9a8c; font-weight:800; }
.next-match-teams { font-size:.86rem; font-weight:700; }
.next-match-meta { font-size:.74rem; }
.next-match-cd { font-size:.74rem; white-space:nowrap; }
.next-match-cd:empty { display:none; }

/* Bloc "EN DIRECT" (remplace le compte a rebours quand un match joue) : score live + TON prono. Affichage seul. */
.live-now-wrap { display:flex; flex-direction:column; gap:.4rem; margin:.6rem auto 0; max-width:24rem; }
.live-now { display:flex; flex-direction:column; align-items:center; text-align:center; gap:.15rem; border:1px solid var(--border); border-left:3px solid #eb5757; border-radius:8px; padding:.45rem .7rem; background:var(--card-2); font-variant-numeric:tabular-nums; }
.live-now-label { display:inline-flex; align-items:center; gap:.35rem; font-size:.64rem; text-transform:uppercase; letter-spacing:.05em; color:#ff5a5a; font-weight:800; }
.live-now-label .live-dot { width:9px; height:9px; border-radius:50%; background:#eb5757; box-shadow:0 0 6px rgba(235,87,87,.9); animation:hero-blink 1.6s ease-in-out infinite; }
.live-now-minute { color:var(--muted); font-weight:700; }
.live-now-teams { font-size:.9rem; font-weight:700; display:flex; align-items:center; justify-content:center; gap:.35rem; flex-wrap:wrap; }
.live-now-score { font-size:1.15rem; font-weight:800; padding:0 .3rem; }
.live-now-pred { font-size:.76rem; }
@media (prefers-reduced-motion: reduce) { .live-now-label .live-dot { animation:none; } }

/* Variante HERO (accueil) : meme bloc en plus grand, tout en haut de page, pour happer le visiteur. */
.live-now-hero { max-width:34rem; margin:0 auto .9rem; }
.live-now-hero .live-now { border-left-width:4px; padding:.7rem 1.1rem; gap:.25rem; box-shadow:0 2px 14px rgba(235,87,87,.18); }
.live-now-hero .live-now-label { font-size:.74rem; }
.live-now-hero .live-now-label .live-dot { width:11px; height:11px; }
.live-now-hero .live-now-teams { font-size:1.12rem; }
.live-now-hero .live-now-score { font-size:1.65rem; }

/* Carte match : score EN DIRECT (remplace "match en cours" tant que le resultat officiel n'est pas saisi). */
.match-live-score { display:flex; flex-direction:column; align-items:center; gap:.15rem; margin:.55rem 0 0; font-variant-numeric:tabular-nums; }
.match-live-score .live-now-label { display:inline-flex; align-items:center; gap:.35rem; font-size:.64rem; text-transform:uppercase; letter-spacing:.05em; color:#ff5a5a; font-weight:800; }
.match-live-score .live-now-label .live-dot { width:9px; height:9px; border-radius:50%; background:#eb5757; box-shadow:0 0 6px rgba(235,87,87,.9); animation:hero-blink 1.6s ease-in-out infinite; }
.match-live-board { display:flex; align-items:center; justify-content:center; gap:.4rem; font-weight:700; }
.match-live-board .live-now-score { font-size:1.35rem; font-weight:800; padding:0 .3rem; }
@media (prefers-reduced-motion: reduce) { .match-live-score .live-now-label .live-dot { animation:none; } }

/* Etat temporel des boutons de journee : passe (attenue), futur/en cours (neutres).
   Le "en cours" n'a plus de fond rouge -> il est repere par la tete de lecture .md-playhead. */
.tabs.md-strip { align-items:stretch; position:relative; } /* relative : ancre la tete de lecture .md-playhead */
.tabs a.md-past:not(.active) { opacity:.45; }
.tabs a.md-past:not(.active):hover { opacity:.85; }
/* Journee "en direct" : plus aucun fond rouge/rose. La selection reste verte (.active) et le jour
   courant garde son anneau vert (.tab-today) ; "on est ici" est porte par la tete de lecture. */

/* Pastilles grisees quand la journee est passee ; marque discrete pour une journee passee non jouee */
.tabs a.md-past .md-dot-full { background:#6b7280; color:#1f2430; }
.tabs a.md-past .md-dot-partial { background:#6b7280; }
.md-dot-skip { position:absolute; top:-4px; right:-4px; width:11px; height:11px; border-radius:50%; background:transparent; border:1.5px solid #6b7280; box-shadow:0 0 0 2px var(--bg); }

/* Tete de lecture "on est ici" : posee en JS au-dessus de la frise. Elle peut traverser une
   pastille (corps translucide pour ne pas masquer le libelle) ou se garer entre deux journees
   (variante .is-gap : pleine, rien a masquer). Les pics depassent en haut/bas, bien rouges. */
.md-playhead {
    position:absolute; width:3px; height:1.9rem; border-radius:2px;
    transform:translateX(-50%);                 /* x = centre du trait */
    background:rgba(235,87,87,.42);             /* corps translucide quand il couvre une pastille */
    pointer-events:none; z-index:3;
}
.md-playhead.is-gap { background:#eb5757; }     /* entre deux journees : plein */
.md-playhead::before, .md-playhead::after {
    content:''; position:absolute; left:0; width:3px; height:7px;
    background:#eb5757; border-radius:2px; box-shadow:0 0 7px rgba(235,87,87,.9);
    animation:md-now-pulse 1.8s ease-in-out infinite;
}
.md-playhead::before { top:-7px; }              /* pic haut (depasse la pastille) */
.md-playhead::after  { bottom:-7px; }           /* pic bas */
@keyframes md-now-pulse { 0%,100% { box-shadow:0 0 5px rgba(235,87,87,.55); } 50% { box-shadow:0 0 11px rgba(235,87,87,1); } }
@media (prefers-reduced-motion: reduce) { .md-playhead::before, .md-playhead::after { animation:none; } }

/* Renfort visuel du figement (pari verrouille au coup d'envoi) */
.lock-ic { vertical-align:-1px; }
.match.locked { opacity:.9; }
.frozen-note { display:flex; align-items:center; gap:.35rem; color:#ff9a8c; font-size:.74rem; font-weight:700; margin:.2rem 0 0; }

/* Panneau "Voyage dans le temps" (dev only, jamais rendu en production) */
.time-travel { position:fixed; bottom:12px; right:12px; z-index:9999; width:236px; background:#161a23; border:1px solid var(--border); border-radius:10px; padding:.55rem .6rem; font-size:.8rem; box-shadow:0 8px 24px rgba(0,0,0,.5); }
.time-travel.tt-on { border-color:#eb5757; box-shadow:0 0 0 2px rgba(235,87,87,.4), 0 8px 24px rgba(0,0,0,.5); }
.time-travel.tt-collapsed .tt-body { display:none; }
.tt-toggle { position:absolute; top:-13px; left:-13px; width:30px; height:30px; border-radius:50%; border:1px solid var(--border); background:#161a23; color:var(--text); cursor:pointer; font-size:15px; line-height:1; }
.time-travel.tt-on .tt-toggle { border-color:#eb5757; }
.tt-title { font-weight:800; margin-bottom:.3rem; display:flex; align-items:center; gap:.35rem; }
.tt-badge { font-size:.62rem; padding:1px 6px; border-radius:6px; background:#333a47; color:#cdd3df; font-weight:700; }
.time-travel.tt-on .tt-badge { background:#eb5757; color:#fff; }
.tt-now { color:var(--text); margin-bottom:.45rem; font-weight:600; }
.tt-row { display:flex; gap:.25rem; margin-bottom:.35rem; }
.tt-row button, .tt-reset { padding:.28rem .2rem; border:1px solid var(--border); background:#222834; color:var(--text); border-radius:6px; cursor:pointer; font-size:.75rem; }
.tt-row > button { flex:1; }
.tt-row button:hover, .tt-reset:hover { border-color:var(--accent-ink); }
.tt-tourn-row .muted { flex:0 0 auto; align-self:center; }
.tt-row button.tt-act { background:var(--accent); color:var(--on-accent); border-color:var(--accent); font-weight:700; }
.tt-row input[type=datetime-local] { flex:2; min-width:0; background:#0e1118; color:var(--text); border:1px solid var(--border); border-radius:6px; padding:.22rem; font-size:.72rem; }
.tt-reset { width:100%; margin-top:.1rem; }
.tt-help { color:var(--muted); font-size:.66rem; margin-top:.4rem; line-height:1.3; }
@media print { .time-travel { display:none !important; } }

/* Joker : encadre fixe dans le coin haut-droit de la carte (choix empile, ou badge + retrait) */
/* Carte de match : equipes + date/heure CENTREES. Jokers en COLONNE a droite sur PC (hors flux ->
   ne pousse pas la hauteur de la carte, et libere la place sous la date pour les POINTS). */
.match-head { display: block; }
.match-head-main { text-align: center; }
.match.has-joker .match-head-main { padding: 0 7.8rem; } /* garde le titre centre, degage la colonne joker a droite */
.match .teams { justify-content: center; flex-wrap: wrap; }
.match-meta { text-align: center; margin-top: .25rem; }
.joker-side { position: absolute; top: .8rem; right: .8rem; width: 7rem; display: flex; flex-direction: column; align-items: stretch; gap: .4rem; z-index: 2; }
.joker-side form { display: block; margin: 0; }
/* Tous les boutons/badges joker a la MEME hauteur -> la carte ne change pas de taille au choix/retrait */
.joker-side .joker-btn, .joker-side .joker-active, .joker-side .joker-remove-btn {
    display: flex; align-items: center; justify-content: center; box-sizing: border-box;
    width: 100%; min-height: 2.1rem; padding: .3rem .55rem; font-size: .84rem; line-height: 1.1; border-radius: 8px; margin: 0;
}
.joker-mini-label { font-size: .82rem; color: var(--muted); font-weight: 700; text-align: center; }
/* Ecran etroit : jokers en rangee centree EN DESSOUS, le titre reprend toute la largeur. */
@media (max-width: 700px) {
    .match.has-joker .match-head-main { padding: 0; }
    .joker-side { position: static; width: auto; flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; margin: .6rem 0 0; gap: .45rem; }
    .joker-side form { display: inline; }
    .joker-side .joker-btn, .joker-side .joker-active, .joker-side .joker-remove-btn { width: auto; padding: .3rem .8rem; }
}

/* --- Match termine : points gagnes (grand, cliquable -> detail), resultat, badge Perfect --- */
.match-pts-row { display: flex; align-items: center; justify-content: center; gap: .6rem; flex-wrap: wrap; margin: .1rem 0 .2rem; }
.match-pts { display: inline-flex; align-items: center; gap: .3rem; background: none; border: none; font-family: inherit; font-weight: 800; cursor: pointer; padding: .1rem .2rem; color: var(--muted); }
.match-pts .match-pts-val { font-size: 1.7rem; line-height: 1; }
.match-pts svg { opacity: .55; }
.match-pts.pts-pos { color: var(--accent-ink); }
.match-pts.pts-neg { color: var(--danger); }
.match-pts:hover { filter: brightness(1.1); }
.badge-perfect { background: linear-gradient(135deg, #f59e0b, #fcd34d); color: #3a2a00; font-weight: 800; border: none; }
.score-result .score-final { font-size: 2rem; font-weight: 800; min-width: 1.4ch; text-align: center; font-variant-numeric: tabular-nums; }
/* La pop-up de la carte de match est cachee via l'attribut [hidden] (pas via .pts-detail, qui est
   AUSSI la classe du detail deplie dans le classement -> ne pas la mettre en display:none). */
.match .pts-detail[hidden] { display: none; }
/* Modale "Detail des points" */
.pts-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.62); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 1rem; }
.pts-modal { position: relative; background: var(--card-2); border: 1px solid var(--border); border-radius: 12px; padding: 1.2rem 1.3rem; max-width: 26rem; width: 100%; max-height: 85vh; overflow: auto; box-shadow: 0 12px 44px rgba(0,0,0,.55); }
.pts-modal-close { position: absolute; top: .35rem; right: .6rem; background: none; border: none; color: var(--muted); font-size: 1.7rem; line-height: 1; cursor: pointer; }
.pts-modal-close:hover { color: var(--text); }
.pts-detail-title { margin: 0 0 .7rem; font-size: 1.1rem; }
.pts-detail-list { list-style: none; margin: 0; padding: 0; }
.pts-detail-list li { display: flex; justify-content: space-between; gap: 1rem; padding: .38rem 0; border-bottom: 1px solid var(--border); }
.pts-detail-list li.pts-note { color: var(--muted); font-size: .88rem; border-bottom: none; padding: .2rem 0; }
.pts-detail-list li.pts-sep-note { display: block; border-bottom: none; color: var(--muted); font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: .55rem 0 .1rem; }
.pts-detail-sub { font-size: .75rem; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .03em; margin: .1rem 0 .15rem; }
.pts-detail-list .pts-calc { font-size: .82rem; color: var(--muted); font-weight: 600; margin-left: .15rem; }
.pts-detail-list li.pts-ingredient { color: var(--muted); border-bottom: none; padding: .18rem 0; }
.pts-detail-list li.pts-ingredient .pts-ing { color: var(--muted); font-weight: 600; white-space: nowrap; }
.pts-detail-list li.pts-mult { border-top: 1px dashed var(--border); }
/* Titre "Roi du Perfect" : couronne juste a cote du NOMBRE, centree verticalement (grande = Roi, petite = Dauphin) */
.lb-perfects { text-align: center; white-space: nowrap; }
.pf-cell { display: inline-flex; align-items: center; justify-content: center; gap: .3rem; }
.crown { line-height: 1; }
.crown-lg { font-size: 1.45em; }
.crown-sm { font-size: 1em; opacity: .8; }
/* Membre dont le compte a ete supprime (donnees anonymisees) : ligne teintee + texte attenue */
.member-deleted td { color: var(--muted); font-style: italic; background: rgba(150,150,150,.07); }
/* Membres aux pronos du tournoi incomplets (remontes en tete via "Voir les membres") : signales en ambre. */
.member-incomplete td { background: rgba(245,158,11,.13); }
.member-incomplete td:first-child { box-shadow: inset 3px 0 0 #f59e0b; }
.members-incomplete-note { background: rgba(245,158,11,.13); border: 1px solid rgba(245,158,11,.45); border-radius: 8px; padding: .5rem .7rem; margin: 0 0 .6rem; font-size: .9rem; font-weight: 600; }

/* Module d'invitation unifie : modale + lignes de partage (Copier / WhatsApp / Facebook / Partager) */
.inv-modal { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.55); }
.inv-modal[hidden] { display: none; }
.inv-modal-box { position: relative; width: 100%; max-width: 32rem; max-height: 90vh; overflow-y: auto; background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 1.1rem; }
.inv-modal-close { position: absolute; top: .3rem; right: .55rem; background: none; border: none; font-size: 1.7rem; line-height: 1; color: var(--muted); cursor: pointer; }
body.inv-modal-open { overflow: hidden; }

/* Confirmation generique (modale du site, remplace window.confirm) : centree, par-dessus tout. */
.bc-confirm { position: fixed; inset: 0; z-index: 1100; display: flex; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.55); }
.bc-confirm[hidden] { display: none; }
.bc-confirm-box { width: 100%; max-width: 22rem; background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 1.1rem; box-shadow: 0 10px 40px rgba(0,0,0,.35); }
.bc-confirm-msg { margin: 0 0 1rem; line-height: 1.4; }
.bc-confirm-actions { display: flex; gap: .5rem; justify-content: flex-end; }
body.bc-confirm-open { overflow: hidden; }
.inv-link { background: var(--card-2); border: 1px solid var(--border); border-radius: 8px; padding: .6rem; margin: .5rem 0; }
.inv-link-head { font-weight: 700; font-size: .9rem; }
.inv-row { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; margin-top: .35rem; }
.inv-url { flex: 1; min-width: 12rem; }
.inv-share { display: flex; gap: .35rem; flex-wrap: wrap; align-items: center; }
.btn.inv-ch { color: #fff; border-color: transparent; }
.btn.inv-wa { background: #25d366; }
.btn.inv-fb { background: #1877f2; }
.btn.inv-native { background: var(--accent-2); }

/* Bouton INFO "Points" dans le groupe PRONOS : ressemble a une info (pas a un onglet ni un CTA) +
   contenu de la modale bareme. */
.points-info { display: inline-flex; align-items: center; gap: .25rem; padding: .25rem .5rem; font-size: .92rem;
    color: var(--muted); background: none; border: none; cursor: pointer; border-radius: 6px; line-height: 1.2; }
.points-info:hover { color: var(--accent-ink, var(--accent)); background: var(--card-2); }
.points-info svg { opacity: .85; }
/* Mobile : "PRONOS" passe en TITRE au-dessus (width:100%) -> Matches / Long terme / Points
   s'alignent ensemble sur la ligne d'en dessous (au lieu que Points tombe orphelin). */
@media (max-width: 640px) { .tab-group-label { width: 100%; } }
.sc-help .sc-sec { margin: .5rem 0; }
.sc-help .sc-sec + .sc-sec { border-top: 1px solid var(--border); padding-top: .55rem; }
.sc-sec-h { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-bottom: .3rem; }
.sc-table { width: 100%; border-collapse: collapse; }
.sc-table td { padding: .18rem 0; }
.sc-table td:last-child { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sc-list { margin: .1rem 0; padding-left: 1.1rem; }
.sc-list li { margin: .18rem 0; }
.sc-mult { display: flex; flex-wrap: wrap; gap: .35rem; }
.sc-mchip { font-size: .82rem; padding: .15rem .5rem; background: var(--card-2); border: 1px solid var(--border); border-radius: 6px; white-space: nowrap; }

/* Vue super-admin (lecture seule) : barre de bascule 3 vues + 2e ligne membres. Couleur AMBRE
   dediee = ce que SEUL le super-admin voit (emails, analytics), reperable au premier coup d'oeil. */
.sa-switch { border-color: #b45309; background: rgba(180,83,9,.06); display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.sa-switch-btns { display: flex; gap: .35rem; flex-wrap: wrap; }
.btn.sa-on { background: #b45309; color: #fff; border-color: #b45309; }
.sa-row > td { background: rgba(180,83,9,.07); border-top: none; padding: .25rem .6rem .5rem; }
.sa-info { display: flex; flex-wrap: wrap; gap: .3rem .5rem; align-items: center; }
.sa-chip { font-size: .76rem; color: #92400e; background: rgba(180,83,9,.1); border: 1px solid rgba(180,83,9,.25); border-radius: 999px; padding: .05rem .45rem; }
.sa-chip strong, .sa-email strong { color: #7c2d12; }
html[data-theme="dark"] .sa-switch { border-color: #b45309; background: rgba(251,191,36,.08); }
html[data-theme="dark"] .sa-row > td { background: rgba(251,191,36,.07); }
html[data-theme="dark"] .sa-chip { color: #fbbf24; background: rgba(251,191,36,.1); border-color: rgba(251,191,36,.3); }
html[data-theme="dark"] .sa-chip strong, html[data-theme="dark"] .sa-email strong { color: #fcd34d; }

/* Bouton theme en mode Auto : petit "A" en coin (l'horaire 8h-22h pilote clair/sombre). */
.theme-toggle { position: relative; }
/* Indicateur "A" (mode AUTO du theme) : un peu plus grand qu'avant (.56 -> .74rem) et pose en coin, avec une petite
   plaque de fond + liseré pour bien se detacher. Reste TOUJOURS juste un "A". Le hover du bouton explique l'auto. */
.theme-toggle[data-mode="auto"]::after { content: "A"; position: absolute; top: -6px; right: -6px; font-size: .74rem; font-weight: 800; line-height: 1; color: var(--accent-ink); background: var(--bg); border-radius: 5px; padding: 0 3px; box-shadow: 0 0 0 2px var(--bg); }

/* Decimale des points dans le classement : ".0" / ".5" en meme police, juste un peu plus petits que l'entier (plus de "½"). */
/* Décimale des points : un peu plus petite que l'entier mais MEME graisse et pleine encre
   (18/07, demande Jonathan : l'opacité réduite la faisait paraître moins grasse). */
.pts-dec { font-size: .8em; font-weight: inherit; letter-spacing: 0; }

/* Pronos des autres : sa propre ligne mise en avant ("toi") + finalistes empiles en colonne */
.is-self > td { background: rgba(43,176,97,.10); }
.badge-you { background: #2bb061; color: #fff; font-size: .7rem; }
.fut-finalist { white-space: nowrap; }
.fut-finalist + .fut-finalist { margin-top: .15rem; }
/* Grille des pronos du tournoi : colonnes a gauche (noms d'equipes lisibles) + statut colore */
.fut-grid th, .fut-grid td { text-align: left; }
.fut-grid .col-player { min-width: 9rem; }
.fut-status { font-weight: 600; white-space: nowrap; }
.fut-ok { color: var(--ok); }
.fut-miss { color: var(--danger); }
.fut-part { color: #f0c777; }

/* En-tetes de region dans la dropdown pays (profil) */
.cpick-group { padding: .45rem .7rem .15rem; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); pointer-events: none; }
.cpick-group:not(:first-of-type) { border-top: 1px solid var(--border); margin-top: .25rem; }
.pts-detail-list .pts-p { font-weight: 700; color: var(--accent-ink); white-space: nowrap; }
.pts-detail-total { display: flex; justify-content: space-between; gap: 1rem; margin-top: .8rem; font-size: 1.1rem; font-weight: 700; }
.pts-detail-total strong { color: var(--accent-ink); white-space: nowrap; }
/* Carte terminee : TON prono en grand (score + mi-temps + qualif), resultat reel plus petit dessous */
.pred-recap { text-align: center; margin: .2rem 0 0; }
.pred-recap-head { display: flex; align-items: center; justify-content: center; gap: .5rem; }
.pred-recap-label { font-size: .85rem; color: var(--muted); font-weight: 700; }
.score-mine { margin: .2rem 0 0; } /* moins d'espace entre "Ton prono" et le score */
.pred-missing { text-align: center; margin: .15rem 0 0; color: var(--muted); font-style: italic; font-size: .85rem; }
.pred-missing-inline { font-style: italic; }
.score-mine .score-final { font-size: 2rem; font-weight: 800; min-width: 1.4ch; text-align: center; font-variant-numeric: tabular-nums; }
.score-final.sc-hit { color: var(--accent-ink); }
/* Gros check / croix a cote du score (juste = vert, rate = rouge) */
/* Pastilles a cote du score : 1er signal = resultat (bon vainqueur/nul), 2e = score exact (plus gros). */
.pred-check { display: inline-flex; align-items: center; justify-content: center; width: 1.95rem; height: 1.95rem; border-radius: 50%; margin-left: .35rem; flex: 0 0 auto; vertical-align: middle; }
.pred-check svg { width: 60%; height: 60%; }
.pred-check.ok { background: var(--accent-2); color: #04210f; }
.pred-check.ko { background: var(--danger); color: #fff; }
.pred-check.pc-sm { width: 1.6rem; height: 1.6rem; }      /* bon resultat (ou raté) : petit */
.pred-check.pc-md { width: 1.95rem; height: 1.95rem; }
.pred-check.pc-xl { width: 2.8rem; height: 2.8rem; }      /* score exact : BEAUCOUP plus grand (l'exploit) */
.pred-check-sm { font-weight: 800; font-size: 1.2rem; margin-left: .25rem; }
.pred-check-sm.ok { color: var(--accent-ink); }
.pred-check-sm.ko { color: var(--danger); }
.pred-bonus { display: flex; flex-wrap: wrap; justify-content: center; gap: .15rem 1.1rem; margin-top: .4rem; }
.pred-bonus strong { color: var(--text); }
.match-result { text-align: center; margin: .55rem 0 0; color: var(--muted); }
.match-result .mr-score { color: var(--text); font-weight: 700; }
/* Match commence mais pas encore de resultat : "Match en cours" qui clignote (orange) */
.match-live { display: flex; align-items: center; justify-content: center; gap: .4rem; margin: .55rem 0 0; font-weight: 700; color: #f59e0b; animation: hero-blink 1.6s ease-in-out infinite; }
.match-live .live-dot { width: 9px; height: 9px; border-radius: 50%; background: #f59e0b; box-shadow: 0 0 6px rgba(245,158,11,.9); }
@media (prefers-reduced-motion: reduce) { .match-live { animation: none; } }
.joker-remove-btn { display:block; width:100%; background:var(--card-2); border:1px solid var(--border); border-radius:8px; padding:.32rem .4rem; color:var(--muted); cursor:pointer; font-size:.8rem; line-height:1.2; }
.joker-remove-btn:hover { color:var(--text); border-color:var(--accent-ink); }

/* Detail des points (transparence) : ligne de classement cliquable + feuille depliee */
.lb-table .lb-row { cursor: pointer; }
.lb-table .lb-row:hover td { background: rgba(255,255,255,.04); }
.lb-table .lb-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.lb-caret { display:inline-block; margin-left:.3rem; color:var(--muted); font-size:.72rem; transition: transform .15s ease; }
.lb-row.lb-open .lb-caret { transform: rotate(180deg); color: var(--accent-ink); }
.pts-row > td { padding: 0; background: var(--bg); }
.pts-detail { padding: .6rem .7rem; border-left: 3px solid var(--accent); border-radius: 0 0 8px 8px; }
.pts-loading { color: var(--muted); padding: .4rem; text-align: center; }
.pts-section-title { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; margin: .5rem 0 .25rem; }
.pts-section-title:first-child { margin-top: 0; }
/* En-tete de section avec bouton info "Points" a droite (panneau deplie d'un joueur). */
.pts-section-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.points-info-sm { padding: .1rem .4rem; font-size: .76rem; text-transform: none; letter-spacing: 0; font-weight: 700; }
.points-info-sm svg { width: 13px; height: 13px; }
/* Detail des points : UNE ligne par match (equipes + prono + chips + total), passe a la ligne si besoin */
/* Separateurs de TOUR dans le detail des points (Seiziemes, Huitiemes, Quarts... + multiplicateur).
   Une ligne de chaque cote du libelle pour marquer nettement le changement d'etage. */
.pts-stage-sep { display: flex; align-items: center; gap: .55rem; margin: .75rem 0 .35rem; }
.pts-stage-sep:first-child { margin-top: .2rem; }
.pts-stage-sep::before, .pts-stage-sep::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.pts-stage-name { font-weight: 800; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text); white-space: nowrap; }
.pts-stage-mult { font-weight: 700; font-size: .78rem; color: var(--muted); white-space: nowrap; }
.pts-match { display: flex; align-items: center; flex-wrap: wrap; gap: .25rem .45rem; padding: .4rem 0; border-bottom: 1px solid rgba(255,255,255,.05); }
.pts-match-head { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .45rem; } /* (futures) */
.pts-mh-teams { font-weight: 700; font-size: .88rem; white-space: nowrap; }
.pts-mh-total { font-weight: 800; color: var(--accent-ink); white-space: nowrap; margin-left: auto; }
.pts-chips { display: flex; flex-wrap: wrap; gap: .25rem; align-items: center; }
.pts-pred { font-size: .78rem; color: var(--muted); white-space: nowrap; }
/* Score reel du match en badge : le differencie nettement des codes pays (ex MEX [1-2] SOU) */
.pts-score-badge { display: inline-block; padding: .02rem .35rem; margin: 0 .18rem; border-radius: 6px; background: var(--card-2); border: 1px solid var(--border); font-weight: 800; font-size: .82em; line-height: 1.4; vertical-align: baseline; }
/* Prono marque dans le detail du classement : memes soulignements que la grille, bien lisible (pas grise) */
.pts-pred-mark { color: var(--text); font-weight: 700; margin-left: .15rem; }
.pts-pred-mark .grid-joker { font-size: .72em; }
.pts-chip { display: inline-block; font-size: .76rem; font-weight: 600; padding: .08rem .4rem; border-radius: 999px; background: var(--card-2); border: 1px solid var(--border); white-space: nowrap; }
.pts-chip.pts-perfect-badge { background: linear-gradient(135deg, #f59e0b, #fcd34d); color: #3a2a00; border-color: #f59e0b; font-weight: 800; }
.pts-match.pts-prior { opacity: .6; } /* entree tardive : match anterieur a l'arrivee, ne compte pas */
/* --- Cadre MATCH EN DIRECT (detail joueur) : "EN DIRECT" centre AU-DESSUS d'une ligne de match IDENTIQUE aux
   autres (memes colonnes, meme responsive) -> aucun scroll horizontal sur mobile. Le cadre porte la bordure +
   le pulse ; la ligne interne se comporte comme une ligne normale. Disparait quand le match est note. --- */
.pts-live-frame { width: 100%; max-width: 100%; margin: .15rem 0 .45rem; padding: .3rem .4rem .35rem; border: 1px solid rgba(235,87,87,.32); border-left: 3px solid #eb5757; border-radius: 8px; background: rgba(235,87,87,.07); animation: pts-live-glow 2s ease-in-out infinite; }
@keyframes pts-live-glow { 0%, 100% { box-shadow: 0 0 0 0 rgba(235,87,87,0); } 50% { box-shadow: 0 0 0 3px rgba(235,87,87,.16); } }
.pts-live-banner { display: flex; align-items: center; justify-content: center; gap: .35rem; font-size: .64rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 800; color: #ff5a5a; margin-bottom: .1rem; }
.pts-live-banner .live-dot { width: 8px; height: 8px; border-radius: 50%; background: #eb5757; box-shadow: 0 0 6px rgba(235,87,87,.9); animation: hero-blink 1.6s ease-in-out infinite; }
.pts-live-min { color: var(--muted); font-weight: 800; }
/* ligne interne = comme les autres lignes de match, sans la bordure du bas (portee par le cadre). flex-wrap
   herite de .pts-match -> le prono passe a la ligne plutot que de deborder sur mobile etroit. */
.pts-match-live-row { border-bottom: 0; padding: .15rem 0 0; }
/* Mobile etroit : on AUTORISE le retour a la ligne propre des equipes plutot qu'un debordement horizontal de
   la table (zero scroll). Le score reste insecable. Sur ecran normal, tout tient sur une ligne comme une J9.
   min-width:0 = indispensable pour que les items flex puissent retrecir sous leur largeur de contenu. */
.pts-match-live-row .pts-mh-teams { white-space: normal; min-width: 0; font-size: .88rem; }
.pts-match-live-row .pts-pred { min-width: 0; }
.pts-match-live-row .pts-pred-mark { font-weight: 800; }
/* score live : plus gros, rouge, leger pulse pour signaler immediatement le direct */
.pts-score-live { display: inline-block; white-space: nowrap; background: rgba(235,87,87,.18); border-color: rgba(235,87,87,.55); color: #ff6b6b; font-weight: 800; font-size: .94em; padding: .02rem .38rem; animation: pts-score-blink 1.6s ease-in-out infinite; }
@keyframes pts-score-blink { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .pts-live-frame { animation: none; } .pts-live-banner .live-dot { animation: none; } .pts-score-live { animation: none; opacity: 1; } }
/* --- Detail deplie d'un joueur : ZERO scroll horizontal sur mobile, meme quand le CLASSEMENT a assez de
   colonnes pour deborder (ex. Best Friends en entree tardive -> colonne "Entre le" en plus). Le deplie est une
   cellule colspan qui herite de la largeur (large) de la table ; on cale donc sa largeur sur l'ecran pour que
   les calculs + le total restent visibles a droite. Le classement lui-meme peut toujours scroller (par
   conception via .lb-wrap), mais plus le detail. Desktop intact (regle mobile uniquement). --- */
@media (max-width: 640px) {
    tr.pts-row > td { padding: 0; }
    tr.pts-row > td > .pts-detail { box-sizing: border-box; width: calc(100vw - 3.5rem); max-width: calc(100vw - 3.5rem); }
}
.pts-chip.pts-prior-badge { background: var(--card-2); color: var(--muted); border-color: var(--border); font-style: italic; font-weight: 600; }
.pts-prior-note { margin: .1rem 0 .25rem; }
.pts-chip.pts-pos { color: #7ee2a8; border-color: rgba(43,176,97,.5); background: rgba(43,176,97,.14); }
.pts-chip.pts-neg { color: #f0a0a0; border-color: rgba(200,60,60,.5); background: rgba(200,60,60,.14); }
.pts-chip.pts-zero { color: #f0a0a0; border-color: rgba(200,60,60,.5); background: rgba(200,60,60,.14); } /* Rate : rouge (echec) */
/* Petits paris AUTO-deduits (O/U, BTTS) : verdatre mais d'un vert TEAL distinct des bonus choisis (pts-pos). */
.pts-chip.pts-side { color: #5fe3c8; border-color: rgba(20,170,150,.5); background: rgba(20,170,150,.13); }
/* Buteur (modele additif) : points qui s'ajoutent, sans multiplicateur. 3e vert distinct (lime SOLIDE,
   texte fonce + contour fonce -> lisible en mode clair ET sombre). */
.pts-chip.pts-buteur { color: #173a08; border-color: #6f9c2a; background: #c3e88a; font-weight: 800; }
/* Pronos du tournoi (detail joueur) : une ligne par prono, MEME format que les matchs (prono a gauche,
   "N pts" a droite). Champion/finalistes : pas de points potentiels affiches -> "en jeu" (muted) tant que rien
   n'est decide, "0 pts" rouge si elimine, "N pts" vert si acquis. Buteur : badge "+N" lime + total "N pts". */
.pts-fut-list { display: flex; flex-direction: column; }
.pts-fut-row { display: flex; align-items: center; flex-wrap: wrap; gap: .2rem .5rem; padding: .35rem 0; border-bottom: 1px solid rgba(255,255,255,.05); font-size: .84rem; }
.pts-fut-row:last-child { border-bottom: 0; }
.pts-fut-label { color: var(--muted); font-weight: 700; min-width: 4.9rem; flex-shrink: 0; }
.pts-fut-pick { font-weight: 700; color: var(--text); display: inline-flex; align-items: center; gap: .3rem; min-width: 0; flex-wrap: wrap; }
.pts-fut-goals { color: var(--muted); font-weight: 600; font-size: .92em; }
.pts-fut-row-out .pts-fut-name { color: var(--muted); text-decoration: line-through; text-decoration-color: #e23b46; text-decoration-thickness: 3px; text-decoration-skip-ink: none; }   /* equipe eliminee : nom barre ROUGE epais (pas le drapeau) */
html[data-theme="light"] .pts-fut-row-out .pts-fut-name { text-decoration-color: #b31217; }
.pts-fut-total { font-weight: 800; white-space: nowrap; margin-left: auto; min-width: 5.4em; text-align: right; font-variant-numeric: tabular-nums; }
.pts-fut-total.pts-fut-won  { color: var(--accent-ink); }                                  /* acquis (gagnant / finaliste atteint) */
.pts-fut-total.pts-fut-out  { color: var(--danger); }                                      /* elimine -> 0 pts */
.pts-fut-total.pts-fut-live { color: var(--muted); font-weight: 600; font-size: .8rem; font-style: italic; } /* encore en jeu */
/* Subdivision Pronos du tournoi | Matchs : titres soulignes (trait accent) + ligne separatrice entre les deux. */
.pts-uline { display: inline-block; border-bottom: 2px solid var(--accent-ink); padding-bottom: .14rem; }
.pts-sep { border: 0; border-top: 1px solid var(--border); margin: .55rem 0 .15rem; }
/* Ligne INFO "jokers restants" (detail joueur) : encadre pointille pour la distinguer des lignes de match. */
.pts-jokers-left { display: flex; align-items: center; flex-wrap: wrap; gap: .2rem .35rem; margin: .2rem 0 .4rem; padding: .28rem .5rem;
    border-radius: 6px; background: var(--card-2); border: 1px dashed var(--border); font-size: .82rem; }
.pts-jokers-left-label { color: var(--muted); font-weight: 700; }
/* Chip "ballon" du classement : points buteur deja compris dans le total (meme lime que le badge detail). */
.lb-buteur-chip { display: inline-flex; align-items: center; justify-content: center; font-size: .78rem; font-weight: 800; line-height: 1;
    padding: .3rem .7rem; min-height: 28px; border-radius: 999px;
    color: #173a08; border: 1px solid #6f9c2a; background: #c3e88a; white-space: nowrap; vertical-align: middle; margin-left: .25rem;
    box-shadow: 0 1px 0 rgba(0, 0, 0, .18), inset 0 1px 0 rgba(255, 255, 255, .35);
    /* Même plancher que les points (18/07) : « ⚽ 5 » = « ⚽ 40 », bords alignés dans la colonne. */
    min-width: 4.1em; font-variant-numeric: tabular-nums; }
.lb-buteur-legend { display: flex; align-items: center; gap: .4rem; margin: .1rem 0 .5rem; }
/* Badge "bidon" (compte factice) dans le classement : visible super-admin uniquement, mauve discret. */
.lb-bidon-badge { display: inline-block; font-size: .62rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    padding: .04rem .3rem; border-radius: 5px; color: #c4b5fd; background: rgba(124,58,237,.16); border: 1px solid #7c3aed;
    vertical-align: middle; margin-left: .25rem; }
.pts-chip.pts-mult { color: var(--text); font-weight: 800; }
.pts-chip.pts-joker { color: #c4b5fd; border-color: #7c3aed; background: rgba(124,58,237,.18); }
/* Groupement du calcul quand il y a un multiplicateur (joker poules / etage KO) : ( noyau ) x facteur + petits paris */
.pts-paren { color: var(--muted); font-weight: 800; font-size: .95rem; align-self: center; }
.pts-op { color: var(--muted); font-weight: 800; align-self: center; padding: 0 .04rem; }

/* Compte rendu de la journee (recap IA) — repliable, toggle toujours en haut (<details>) */
.recap-block { background: var(--card-2); border: 1px solid var(--border); border-radius: 10px; padding: .55rem .8rem; margin: .3rem 0 .9rem; }
.recap-block > summary { cursor: pointer; list-style: none; display: block; }
.recap-block > summary::-webkit-details-marker { display: none; }
.recap-block > summary::marker { content: ""; }
.recap-block-title { font-weight: 700; display: block; }
.recap-teaser { color: var(--muted); margin-top: .15rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.recap-toggle { color: var(--accent-ink); font-weight: 600; font-size: .85rem; display: inline-block; margin-top: .25rem; }
.recap-block[open] .recap-teaser, .recap-block[open] .recap-more { display: none; }
.recap-block:not([open]) .recap-less { display: none; }
.recap-content { margin-top: .45rem; line-height: 1.5; }
.recap-content strong { color: var(--text); }
/* Onglet Comptes rendus : le recap deplie comme un article (pas de clic pour ouvrir) */
.recap-ai-note { font-size: .7rem; color: var(--muted); font-style: italic; margin: .15rem 0 .5rem; }
.recap-end { display: block; height: 1px; } /* marqueur de fin du recap (observe pour "lu jusqu'au bout") */
.seen-person-dwell { color: var(--muted); font-size: .85em; } /* duree de lecture (super-admin) */
.seen-person-full { color: #2bb061; font-weight: 800; }      /* a scrolle jusqu'au bout */

/* Page d'arrivee d'un lien d'invitation : choix entrer / creer / naviguer (+ avertissement enjeu) */
.join-choice-block { border-top: 1px solid var(--border); padding: .8rem 0 .2rem; }
.join-choice-block:first-of-type { border-top: none; }
.join-choice-h { margin: 0 0 .25rem; font-size: 1rem; }
/* Carte du partageur montree sur la page d'un groupe ferme (sa fierte = l'accroche) */
.join-shared-card { display: block; width: 100%; max-width: 300px; height: auto; margin: .2rem auto .4rem; border-radius: 12px; border: 1px solid var(--border); }
/* Carte du partageur en HERO sur la landing /j/ : grande, cliquable (agrandir), avec sa phrase de frime dessous. */
.join-card-hero { display: block; margin: 0 auto .45rem; line-height: 0; border-radius: 14px; overflow: hidden; box-shadow: 0 6px 22px rgba(0,0,0,.4); }
.join-card-hero img { width: 100%; height: auto; display: block; border-radius: 14px; }
.join-card-phrase { text-align: center; font-weight: 800; color: var(--accent-ink); margin: 0 0 .9rem; font-size: 1.02rem; line-height: 1.3; }
/* Rang + phrase de frime AU-DESSUS de la carte sur la landing /j/ : en grand, le rang en vert. */
.join-hero-phrase { text-align: center; font-weight: 800; font-size: 1.22rem; line-height: 1.34; margin: .1rem 0 .65rem; color: var(--text); }
.join-hero-rank { color: var(--accent-ink); }
/* Encadre d'explication (groupe ferme) : "tu as encore le temps de pronostiquer jusqu'au ...". */
.join-explain { background: rgba(217,161,65,.12); border: 1px solid var(--warn); border-radius: 8px; padding: .5rem .7rem; margin: 0 0 .8rem; font-size: .9rem; line-height: 1.4; }
/* Groupe ferme : compteur de membres a cote du titre + ligne "inscriptions fermees le ...". */
.join-title-count { color: var(--muted); font-weight: 600; font-size: .72em; }
.join-closed-since { color: var(--muted); font-size: .9rem; margin: 0 0 .55rem; }
.join-stake-warn { border: 1px solid var(--warn); background: rgba(217,161,65,.12); border-radius: 8px; padding: .6rem .8rem; margin: 0 0 .8rem; font-size: .9rem; color: #e8c382; }
.join-stake-warn strong { display: block; margin-bottom: .1rem; }
.recap-article { margin: .2rem 0 .9rem; }
/* Partage du compte rendu (bouton sous le recit) + page publique /r/<code> */
.recap-share-row { margin: .2rem 0 .8rem; }
.recap-public-cta { margin: 1rem 0 .2rem; padding: .9rem; border: 1px solid rgba(46,204,113,.3); border-radius: 12px; background: rgba(46,204,113,.06); text-align: center; }
.recap-public-cta-h { margin: 0 0 .5rem; font-weight: 800; font-size: 1.05rem; }
.recap-article .recap-block-title { font-size: 1.05rem; margin: 0 0 .5rem; }
.recap-article .recap-content { margin-top: 0; }
/* Page super-admin de suivi des bidons */
.admin-bidons .bidon-kpis { display: flex; gap: 1.6rem; flex-wrap: wrap; align-items: flex-end; }
.admin-bidons .bidon-kpi { display: flex; flex-direction: column; }
.admin-bidons .bidon-kpi-num { font-size: 1.5rem; font-weight: 700; }
.admin-bidons .bidon-kpi-lbl { font-size: .85rem; opacity: .7; }
.admin-bidons .bidon-warn { font-size: .78rem; color: #c47f00; }
.admin-bidons .bidon-table { width: 100%; border-collapse: collapse; margin-top: .3rem; }
.admin-bidons .bidon-table th, .admin-bidons .bidon-table td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid var(--border); font-size: .9rem; vertical-align: top; }
.admin-bidons .bidon-bar { background: var(--card-2); border-radius: 6px; height: 7px; overflow: hidden; margin-bottom: .2rem; max-width: 170px; }
.admin-bidons .bidon-bar > span { display: block; height: 100%; background: #2e9e5b; }
.admin-bidons tr.bidon-late { background: rgba(220,150,0,.12); }
/* Reactions a chaud sous le recap */
.recap-reactions { margin: .2rem 0 .9rem; padding: .5rem .8rem; border: 1px solid var(--border); border-left: 3px solid #2bb061; border-radius: 8px; background: var(--card); }
.recap-reactions-head { font-weight: 600; font-size: .85rem; color: var(--muted); margin-bottom: .35rem; }
/* Fil de reactions REPLIE par defaut (page Classement) : on ne voit que le nombre, on deplie pour repondre. */
.recap-react-collapse > summary { cursor: pointer; font-weight: 600; font-size: .85rem; color: var(--accent-ink);
    list-style: none; display: inline-flex; align-items: center; gap: .3rem; padding: .15rem 0; }
.recap-react-collapse > summary::-webkit-details-marker { display: none; }
.recap-react-collapse > summary::before { content: '\25B8'; font-size: .8em; transition: transform .15s; display: inline-block; }
.recap-react-collapse[open] > summary::before { transform: rotate(90deg); }
.recap-react-collapse > summary:hover { text-decoration: underline; }
/* Page trafic detaille (super-admin) : tableaux + chips joueurs */
/* Feed d'activite super-admin : reveals en rouge, rouge plein pendant un match en cours. */
.act-filters { display: flex; gap: .6rem 1rem; flex-wrap: wrap; align-items: flex-end; }
.act-filters label { display: flex; flex-direction: column; gap: .15rem; font-size: .8rem; color: var(--muted); font-weight: 700; }
.act-filters select { max-width: 13rem; }
.act-filters .act-check { flex-direction: row; align-items: center; gap: .35rem; }
.act-feed { width: 100%; border-collapse: collapse; font-size: .86rem; }
.act-feed th, .act-feed td { padding: .3rem .5rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.act-feed th { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; }
.act-time { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); }
.act-actor { font-weight: 700; white-space: nowrap; }
/* Reveal (consultation des pronos d'autrui / grille) : fond rouge leger + bord gauche rouge. */
.act-feed tr.act-reveal td { background: rgba(201,48,44,.08); }
.act-feed tr.act-reveal td:first-child { border-left: 3px solid rgba(201,48,44,.55); }
/* Reveal PENDANT un match en cours : rouge plein, c'est le cas le plus grave. */
.act-feed tr.act-live td { background: rgba(201,48,44,.20); }
.act-feed tr.act-live td:first-child { border-left: 3px solid var(--danger); }
.act-live-badge { display: inline-block; font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    padding: .03rem .32rem; border-radius: 5px; color: #fff; background: var(--danger); vertical-align: middle; white-space: nowrap; }
.act-legend { display: inline-block; padding: .02rem .3rem; border-radius: 5px; font-weight: 700; }
.act-reveal-chip { background: rgba(201,48,44,.14); color: #e89a96; border: 1px solid rgba(201,48,44,.5); }
.act-live-chip { background: var(--danger); color: #fff; }
.act-pager { display: flex; gap: .5rem; align-items: center; margin-top: .7rem; flex-wrap: wrap; }
.traffic-wins { display: flex; gap: .4rem; flex-wrap: wrap; }
.traffic-table { width: 100%; border-collapse: collapse; }
.traffic-table th, .traffic-table td { padding: .3rem .5rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.traffic-table th a { color: var(--muted); text-decoration: none; }
.traffic-table th a:hover { color: var(--text); }
.traffic-times { max-height: 220px; overflow: auto; margin-top: .25rem; }
.traffic-users { display: flex; flex-wrap: wrap; gap: .4rem; }
.traffic-user-chip { display: inline-flex; align-items: center; gap: .25rem; padding: .2rem .6rem; border: 1px solid var(--border);
    border-radius: 999px; background: var(--card-2); text-decoration: none; font-size: .9rem; }
.traffic-user-chip:hover { border-color: var(--accent-ink); }
.recap-seen-row { display: flex; flex-wrap: wrap; gap: .4rem; margin: .1rem 0 .3rem; }
.chat-thread-compact .chat-msg { padding: .35rem 0; border-top: 1px solid rgba(125,125,125,.12); }
.chat-thread-compact .chat-msg:first-child { border-top: none; }
.chat-actions { display: flex; gap: .4rem; margin-top: .2rem; flex-wrap: wrap; }
.recap-react-form { margin-top: .5rem; }
.recap-react-form textarea { width: 100%; box-sizing: border-box; }
.recap-react-form button { margin-top: .35rem; }
/* Reactions facon Facebook sous chaque message (Discussion + reponses au compte rendu) */
.msg-react { margin: .25rem 0 .1rem; }
.msg-react-bar { display: inline-flex; flex-wrap: wrap; gap: .2rem; margin: 0; }
.msg-react-btn { display: inline-flex; align-items: center; gap: .15rem; padding: .1rem .35rem; border: 1px solid transparent;
    background: var(--card-2); border-radius: 999px; cursor: pointer; font-size: .95rem; line-height: 1.2; opacity: .75; transition: opacity .12s, border-color .12s, background .12s; }
.msg-react-btn:hover { opacity: 1; border-color: var(--border); }
.msg-react-btn.has { opacity: 1; }
.msg-react-btn.on { opacity: 1; border-color: var(--accent); background: rgba(91,141,239,.16); }
.msg-react-emo { font-size: 1rem; line-height: 1; }
.msg-react-n { font-size: .78rem; font-weight: 700; color: var(--muted); min-width: .8em; text-align: center; }
.msg-react-btn.on .msg-react-n { color: var(--accent-ink); }
.msg-react-who { margin-top: .15rem; }
.msg-react-who > summary { display: inline-block; cursor: pointer; font-size: .76rem; color: var(--muted); list-style: none; }
.msg-react-who > summary::-webkit-details-marker { display: none; }
.msg-react-who > summary:hover { color: var(--text); text-decoration: underline; }
.msg-react-who-list { margin: .2rem 0 0; font-size: .82rem; display: flex; flex-direction: column; gap: .12rem; }
.msg-react-who-list .msg-react-emo { margin-right: .25rem; }
/* Citation d'un message (rappel au-dessus d'une reponse + bouton Citer + apercu dans le formulaire) */
.msg-quote { border-left: 3px solid var(--accent); background: var(--card-2); border-radius: 0 6px 6px 0;
    padding: .25rem .55rem; margin: .15rem 0 .3rem; font-size: .85rem; }
.msg-quote-author { font-weight: 700; color: var(--accent-ink); }
.msg-quote-body { color: var(--muted); }
.msg-quote-btn { background: none; border: none; cursor: pointer; padding: .05rem .25rem; font-size: .76rem;
    color: var(--muted); border-radius: 5px; }
.msg-quote-btn:hover { color: var(--accent-ink); background: var(--card-2); text-decoration: underline; }
.chat-quote-preview { display: flex; align-items: flex-start; gap: .4rem; border-left: 3px solid var(--accent);
    background: var(--card-2); border-radius: 0 6px 6px 0; padding: .3rem .55rem; margin-bottom: .4rem; font-size: .84rem; }
.chat-quote-preview[hidden] { display: none; } /* cache l'apercu tant qu'on n'a pas clique "Citer" */
.chat-quote-pv-txt { flex: 1; color: var(--muted); }
.chat-quote-cancel { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 1.1rem; line-height: 1; padding: 0 .2rem; }
.chat-quote-cancel:hover { color: var(--danger); }
.pts-subtotal { font-size: .82rem; color: var(--muted); margin: .35rem 0 .1rem; }
.pts-total { margin-top: .5rem; padding-top: .4rem; border-top: 1px solid var(--border); font-size: .95rem; }
/* Sous-totaux EN TETE de section (fiche points) : ligne discrete, label fort (texte du theme, jamais un noir
   en dur) + NOMBRE en vert accent (meme vert que les points futures acquis .pts-fut-won). Sombre ET clair. */
/* Rangee "argent" COMMUNE (17/07) : sous-total matchs, sous-total pronos du tournoi et points Roi/Dauphin
   du Perfect partagent LA MEME colonne numerique a droite (position, police, taille, graisse, couleur
   identiques, chiffres tabulaires) : l'alignement vient de la grille, pas de marges bricolees. */
.pts-mrow { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; flex-wrap: nowrap; }
.pts-mrow-label { min-width: 0; }
.pts-mrow-val { flex: 0 0 auto; min-width: 5.4em; text-align: right; font-size: .9rem; font-weight: 800;
    color: var(--accent-ink); white-space: nowrap; font-variant-numeric: tabular-nums;
    /* ENCADRE comme le pays qualifie (.res-qual, demande Jonathan 18/07) : ces TROIS valeurs (sous-total
       pronos du tournoi + Roi/Dauphin du Perfect + sous-total matchs) sont celles qui s'ADDITIONNENT pour
       le total : le cadre les distingue des points de detail en dessous. */
    border: 1.5px solid #38d27a; border-radius: 6px; padding: .02rem .45rem; background: rgba(56,210,122,.14); }
html[data-theme="light"] .pts-mrow-val { border-color: #1a9e54; background: rgba(26,158,84,.10); }
.pts-mrow-val-live { color: var(--muted); font-weight: 600; font-size: .8rem; font-style: italic;
    border: none; background: none; padding: 0; }
html[data-theme="light"] .pts-mrow-val-live { border: none; background: none; }
.pts-subhead-total { font-size: .8rem; color: var(--muted); margin: .05rem 0 .3rem;
    /* Label COLLE au cadre de points, le tout aligne a droite (Jonathan 18/07) : on lit
       "Sous-total ... : [N pts]" d'un bloc, dans la meme colonne que le cadre du Perfect
       (dont la bande porte deja son propre titre a gauche, rien a repeter). */
    justify-content: flex-end; gap: .45rem; }
.pts-subhead-total strong { color: var(--text); font-weight: 800; }
.pts-subhead-num { color: var(--accent-ink); font-weight: 800; white-space: nowrap; }
/* Ligne malus buteur (fiche points) : rappel de la regle en rouge discret (couleur erreur du theme). */
.pts-malus-note { font-size: .78rem; color: var(--danger); margin: .05rem 0 .35rem; }
/* Petit lien "voir la regle" (fiche -> /how-it-works#ancre) : discret, souligne. */
.pts-rule-link { font-size: .74rem; color: var(--accent-ink); text-decoration: underline; white-space: nowrap; }
.pts-rule-link.pts-rule-link-neg { color: inherit; } /* dans la note malus : reste rouge, coherent */
/* Bonus des Perfects "en jeu" (pendant le tournoi) : meme cadre que le bonus final pour le Roi/Dauphin
   provisoire (sans points ajoutes), ligne neutre discrete pour les autres joueurs. */
.pts-perfect-live .pts-pb-label { font-weight: 700; }
.pts-perfect-neutral { font-size: .78rem; color: var(--muted); font-style: italic; margin: .15rem 0 .1rem; }
@media (max-width: 560px) {
  .pts-mh-teams { font-size: .84rem; }
  .pts-chip { font-size: .72rem; }
}

/* ===== Accueil : hero + grand compte a rebours ===== */
.hero { text-align: center; padding: 2.4rem 1.1rem 2.6rem; margin-bottom: 1rem;
    background: radial-gradient(130% 120% at 50% -10%, rgba(31,138,76,.28), transparent 62%), var(--card);
    border: 1px solid var(--border); border-radius: 18px; }
/* PASTILLES DU HERO (#5c, 26/07) : le hero est une surface TOUJOURS sombre -> ses pastilles FIGENT leurs encres
   (couleurs explicites, jamais de var() de thème) pour un rendu IDENTIQUE en clair et en sombre (Jonathan : le
   « 100% gratuit » ne doit pas changer selon le thème, le prix ne doit plus être jaune sur jaune). */
.hero-pill { display: inline-flex; align-items: center; gap: .35rem; background: rgba(255,255,255,.09);
    border: 1px solid rgba(255,255,255,.22); color: #f3f5f8; font-weight: 800; border-radius: 999px;
    padding: .34rem .8rem; font-size: .92rem; text-decoration: none; line-height: 1.2; }
a.hero-pill:hover { background: rgba(255,255,255,.17); border-color: rgba(255,255,255,.38); color: #fff; }
.hero-pill-prize { background: rgba(245,197,24,.20); border-color: rgba(245,197,24,.62); color: #fff5d6; }
.hero-pill-count b { font-variant-numeric: tabular-nums; margin-right: .1rem; }
/* Petit MAILLOT (au lieu du rond jaune) coloré PAR COMPÉTITION, couleurs FIGÉES (masque SVG). */
.hero-pill-jersey { display: inline-block; width: 18px; height: 18px; flex: 0 0 auto; background-color: #f5c518;
    -webkit-mask: url('../icons/jersey-icon.svg') center / contain no-repeat; mask: url('../icons/jersey-icon.svg') center / contain no-repeat; }
[data-comp="cl"] .hero-pill-jersey { background-color: #5b9bff; }
[data-comp="vuelta"] .hero-pill-jersey { background-color: #ff6b7d; }
[data-comp="usopen"] .hero-pill-jersey { background-color: #ccdd33; }
/* Bulle COLORISÉE de la compétition avant « coup d'envoi / tirage / départ dans » (au lieu du ⚽/🚴 générique). */
.hero-cd-bubble { width: 22px; height: 22px; vertical-align: middle; margin-right: .25rem; }
/* Statut « Inscriptions clôturées » (pastille figée) + PORTE DE SECOURS aux couleurs de la prochaine course
   (Vuelta = rouge), quand une compétition cycliste est terminée (#5c). */
.hero-closed-line { display: inline-flex; align-items: center; gap: .35rem; margin: .5rem 0 0; font-weight: 800;
    color: #f3f5f8; background: rgba(0,0,0,.30); border: 1px solid rgba(255,255,255,.22); border-radius: 999px; padding: .3rem .85rem; }
.btn.hero-nextdoor { background: linear-gradient(160deg, #e11d3a, #a5122a); border: 1px solid #ff5a6e; color: #fff; }
.btn.hero-nextdoor:hover { background: linear-gradient(160deg, #f02742, #b3142e); border-color: #ff7d8c; color: #fff; }
.hero-nextdoor-when { margin: .35rem 0 0; font-size: .85rem; font-weight: 700; color: #f3c0c8; }
.ss-grp-h.ss-fam-finished { color: var(--muted); }
/* Logo ScoreMigos (wordmark blanc/vert sur transparent) : pose directement sur le hero sombre,
   sans le cadre blanc d'avant (qui rendait le "Score" blanc invisible). Largeur responsive. */
.hero-logo-wrap { display: inline-block; margin-bottom: .6rem; }
.hero-logo { display: block; width: clamp(210px, 60vw, 360px); height: auto; max-width: 100%; }
.hero-title { font-size: clamp(2rem, 7vw, 3.4rem); font-weight: 900; letter-spacing: .01em; line-height: 1.08; margin: .2rem 0 .35rem; }
.hero-sub { color: var(--muted); font-size: clamp(.88rem, 2.2vw, 1.02rem); max-width: 40rem; margin: 0 auto .8rem; }
.hero-belgian { display: inline-block; font-size: .78rem; font-weight: 800; color: #ffd24a; background: rgba(0,0,0,.28); border: 1px solid var(--border); border-radius: 999px; padding: .12rem .7rem; margin: -.6rem 0 1rem; }
.hero-cd { margin: 1rem 0 .9rem; }
.hero-cd-label { color: var(--accent-ink); font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; margin-bottom: .6rem; }
.hero-cd-boxes { display: flex; justify-content: center; align-items: center; gap: .45rem; flex-wrap: wrap; }
/* Prochain match au-dessus du compte a rebours (hero toujours sombre -> textes clairs) */
.hero-cd-match { display: inline-flex; align-items: center; gap: .3rem; font-weight: 800; color: #f3f5f8; }
.hero-cd-date { font-size: .82rem; color: #c4cad4; font-weight: 600; white-space: nowrap; }
.hero-cd-when { font-size: .82rem; color: #c4cad4; margin-top: .55rem; }
.cd-box { min-width: clamp(66px, 18vw, 104px); padding: .7rem .5rem; border-radius: 14px; text-align: center;
    /* Fond OPAQUE sombre TEINTÉ par compétition (--cd-bg, défaut vert-noir) : rendu IDENTIQUE clair/sombre
       (avant : translucide -> délavé sur fond clair). Le compteur garde partout son look premium. */
    background: var(--cd-bg, linear-gradient(165deg, #1c4d34, #0c1310));
    border: 1px solid var(--cd-border, rgba(58,209,122,.55)); box-shadow: 0 0 20px rgba(31,138,76,.25), inset 0 0 14px rgba(31,138,76,.12); }
.cd-box b { display: block; font-size: clamp(2rem, 9vw, 3.6rem); font-weight: 900; line-height: 1;
    color: var(--cd-fg, #44e08a); font-variant-numeric: tabular-nums; text-shadow: 0 0 16px var(--cd-glow, rgba(68,224,138,.6)); }
.cd-box span { font-size: .68rem; color: var(--muted); text-transform: uppercase; letter-spacing: .1em; }
.cd-sep { display: none; font-size: clamp(1.4rem, 5vw, 2.4rem); font-weight: 800; color: var(--cd-sep, rgba(68,224,138,.5)); }
@media (min-width: 480px) { .cd-sep { display: block; } }
.hero-cd-boxes .cd-box:last-child b { animation: cd-pulse 1s ease-in-out infinite; }
@keyframes cd-pulse { 0%,100% { text-shadow: 0 0 16px var(--cd-glow, rgba(68,224,138,.55)); } 50% { text-shadow: 0 0 26px var(--cd-glow, rgba(68,224,138,1)); filter: brightness(1.25); } }
.hero-cd-live { font-size: clamp(1.4rem, 5vw, 2.2rem); font-weight: 900; color: #44e08a; text-shadow: 0 0 18px rgba(68,224,138,.6); }
.hero-cta { display: flex; justify-content: center; gap: .6rem; flex-wrap: wrap; margin: 1.3rem 0 .7rem; }
.btn-lg { font-size: 1.08rem; padding: .75rem 1.5rem; border-radius: 12px; }
.hero-urgency { font-size: .95rem; margin: .4rem 0 0; }
a.hero-urgency { display: inline-block; cursor: pointer; }
a.hero-urgency:hover { text-decoration: underline; }
.hero-blink { color: var(--accent-ink); font-weight: 700; animation: hero-blink 1.2s ease-in-out infinite; }
@keyframes hero-blink { 0%,100% { opacity: 1; } 50% { opacity: .4; } }
@media (prefers-reduced-motion: reduce) { .hero-cd-boxes .cd-box:last-child b, .hero-blink { animation: none; } }

/* Recherche de groupe (page « Tous les concours ») : filtre live par nom. */
.group-search { width: 100%; box-sizing: border-box; margin: 0 0 .8rem; padding: .55rem .8rem;
    border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); color: var(--text); font-size: 1rem; }
/* Cartes « Mes concours » : badges et ligne de type espaces (plus de chevauchement). */
.contest-card-badges { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.contest-card-type { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: .55rem; }

/* 3 boutons proeminents de la carte (Membres / Compte rendu JN / Classement). z-index:2 pour passer
   AU-DESSUS de l'overlay .card-link::after (sinon le clic irait au concours au lieu du bouton). */
.contest-card-nav { display: flex; flex-direction: column; gap: .4rem; margin-top: .7rem; position: relative; z-index: 2; }
.ccn-btn { display: flex; align-items: center; justify-content: center; gap: .4rem; position: relative; padding: .55rem .7rem; border-radius: 8px; border: 1px solid var(--border); background: var(--card-2); color: var(--text); font-weight: 700; font-size: .92rem; text-decoration: none; }
.ccn-btn:hover { border-color: var(--accent-ink); }
/* Clignotement nouveautes : MEME pulsation propre PARTOUT (md-dot-blink, celle des pastilles a lettre).
   A fond (0/100%) = contour PLEIN + pastille grande/coloree ; au creux (50%) = contour efface + pastille
   petite/claire. Le contour du bouton et la pastille pulsent EN PHASE (meme duree 1s, meme rythme). */
.ccn-btn.ccn-blink, .card-standings-btn.ccn-blink { animation: ccn-border-blink 1s ease-in-out infinite; }
@keyframes ccn-border-blink {
    0%, 100% { border-color: #ea580c;             box-shadow: 0 0 0 3px rgba(234,88,12,.32); }
    50%      { border-color: rgba(234,88,12,.18); box-shadow: 0 0 0 0 rgba(234,88,12,0); }
}
/* "Tu es cite dedans" / "Le recap a ete mis a jour" : LABEL non cliquable (pas un 2e bouton) au-dessus des
   boutons de la carte, qui clignote EN MEME TEMPS que le bouton Compte rendu (meme animation ccn-border-blink
   1s). L'action reste le bouton Compte rendu ; ce badge ne fait qu'attirer l'oeil. */
.recap-cited-note { display: inline-flex; align-items: center; gap: .3rem; margin: 0 0 .5rem; padding: .28rem .7rem; border-radius: 999px; background: rgba(234,88,12,.12); color: #ea580c; border: 1.5px solid #ea580c; font-weight: 700; font-size: .84rem; line-height: 1.2; cursor: default; animation: ccn-border-blink 1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .recap-cited-note { animation: none; } }
/* Variante CLIQUABLE de "Tu es cite dedans" : mene au meme compte rendu que le bouton dedie. */
a.recap-cited-note { cursor: pointer; text-decoration: none; }
a.recap-cited-note:hover, a.recap-cited-note:focus-visible { background: rgba(234,88,12,.22); text-decoration: none; }
/* Bandeau "voir comme un joueur" (super-admin, lecture seule) : pleine largeur tout en haut, tres visible. */
.sa-view-as-bar { display: block; background: #b45309; color: #fff; text-align: center; padding: .45rem .8rem; font-weight: 700; font-size: .92rem; text-decoration: none; }
.sa-view-as-bar strong { text-decoration: underline; }
.sa-view-as-exit { text-decoration: underline; }
.sa-view-as-bar:hover { background: #92400e; text-decoration: none; }
.ccn-dot { width: 12px; height: 12px; border-radius: 50%; background: #ea580c; box-shadow: 0 0 0 2px var(--bg), 0 0 7px 1px rgba(234,88,12,.7); animation: md-dot-blink 1s ease-in-out infinite; }
/* Badge LETTRE (i/N/D) sur le bouton "Info generale" de la carte : dit QUEL canal a du neuf, et clignote. */
.ccn-letter { display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding: 0 3px; border-radius: 999px;
    background: #ea580c; color: #fff; font-size: .64rem; font-weight: 800; line-height: 1; box-shadow: 0 0 0 2px var(--bg);
    animation: md-dot-blink 1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .ccn-dot, .ccn-letter, .ccn-btn.ccn-blink, .card-standings-btn.ccn-blink { animation: none; } }
/* ══ PASTILLES NUMERIQUES (12/07) : badges chiffres STATIQUES a deux temperatures, en remplacement des
   clignotements "nouveaute" (analyse du 11/07 : la simultaneite tue le clic, 8,2 % a 1 signal -> 2,3 % a 5+ ;
   un nombre se lit en une saccade ; le langage badge est pre-appris par tous). CHAUD = orange + halo
   statique (l'ombre fait la hierarchie, pas le mouvement) ; TIEDE = gris discret (l'information reste, la
   pression s'arrete, extinction a 48 h ou budget de 2 chauds/page depasse). Seule animation : l'APPARITION
   (250 ms, une fois). Kill-switch BADGES_V2=0 : ces classes ne sont plus emises, ccn-blink/ccn-dot reprennent. */
.n-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 999px; font-size: 11px; font-weight: 800; line-height: 1;
    vertical-align: middle; box-shadow: 0 0 0 2px var(--bg); animation: nb-in .25s ease-out; }
.nb-hot  { background: #f59e0b; color: #231600; box-shadow: 0 0 0 2px var(--bg), 0 1px 6px 1px rgba(245,158,11,.65); }
.nb-warm { background: #6b7280; color: #fff; }
/* Variation de places SIGNEE (classement) : vert = gagne, rouge = perdu ; version tiede desaturee. */
.nb-up   { background: #16a34a; color: #fff; }
.nb-down { background: #dc2626; color: #fff; }
.nb-up.nb-warm   { background: rgba(22,163,74,.55); }
.nb-down.nb-warm { background: rgba(220,38,38,.55); }
.nb-dot { min-width: 12px; width: 12px; height: 12px; padding: 0; }
/* ── Pastille en COIN sur les boutons-icones (style notification Facebook, demande Jonathan 14/07). Avant, la
   pastille etait INLINE a cote de l'icone -> elle cramait le padding du bouton (cas du megaphone). Desormais
   elle SORT du flux et se colle en haut a droite du bouton, comme la cloche (.nav-bell-count) le fait deja.
   Le bouton porteur passe position:relative. Gabarit cloche (16px, .64rem) : plus petit mais lisible, 2 chiffres OK.
   .nb-corner = opt-in generique (boutons de carte, demo) : ajoute la pastille en coin sur n'importe quel bouton
   marque position:relative (voir .has-corner-badge). ── */
.fav-btn, .help-btn, .nav-logout, .theme-toggle, .urgent-clock, .nav-toggle,
.crh-btn, .card-standings-btn, .has-corner-badge { position: relative; }
.fav-btn > .n-badge, .help-btn > .n-badge, .nav-bell > .n-badge, .theme-toggle > .n-badge,
.urgent-clock > .n-badge, .nav-toggle > .n-badge, .crh-btn > .n-badge, .card-standings-btn > .n-badge,
.has-corner-badge > .n-badge, .n-badge.nb-corner {
    position: absolute; top: -7px; right: -6px; margin: 0; /* un peu HORS du bouton (touchait parfois le libelle) ; debord < gap des rangees (~9px) -> pas de chevauchement du voisin */
    min-width: 16px; height: 16px; padding: 0 4px; font-size: .64rem;
}
/* HEADER : boutons-icones PETITS (38px) -> pastille poussee PLUS HAUT et un peu a droite pour ne pas recouvrir le
   pictogramme (surtout les rares nombres a 2 chiffres). Reste dans le gap (~8px) cote droit. Cartes inchangees (Jonathan 14/07). */
.fav-btn > .n-badge, .help-btn > .n-badge, .nav-bell > .n-badge, .theme-toggle > .n-badge,
.urgent-clock > .n-badge, .nav-toggle > .n-badge, .nav-bell-count { top: -9px; right: -7px; }
/* Deadline (pronos manquants) : la SEULE pastille numerique encore animee (appel a l'action date, le
   moteur mesure qui marche) : jaune + le NOMBRE de pronos restants (l'effort est borne). */
.nb-deadline { background: #e5c100; color: #231600; animation: md-dot-blink 1.1s ease-in-out infinite; }
.nb-check { background: #16a34a; color: #fff; font-size: .72rem; font-weight: 900; } /* pastille "Mes pronos" : prochaine journee remplie -> check vert statique (vs nb-deadline orange clignotant si des pronos manquent) */
@keyframes nb-in { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .n-badge { animation: none; }
    .nb-deadline { animation: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px rgba(229,193,0,.5); }
}
/* "Tu es cite" : saillance STATIQUE (halo) a la place du clignotement ; tiede apres 48 h / hors budget. */
.recap-cited-note.nb-note-hot  { animation: none; box-shadow: 0 0 0 3px rgba(234,88,12,.35), 0 1px 8px 1px rgba(234,88,12,.5); }
.recap-cited-note.nb-note-warm { animation: none; border-color: rgba(234,88,12,.45); background: rgba(234,88,12,.07); }
/* "Tout marquer comme vu" : balai discret a cote de l'en-tete "N avec du nouveau" (analyse 11/07). */
.dash-markseen-form { display: inline; margin-left: .55rem; vertical-align: middle; }
.dash-markseen { background: none; border: none; padding: 0; cursor: pointer; font: inherit; font-size: .78rem;
    font-weight: 400; color: var(--muted, #9aa3b2); text-decoration: underline; text-underline-offset: 2px; }
.dash-markseen:hover { color: var(--text); }
/* En-tete "N avec du nouveau" : le point ne clignote plus (le compteur fait le travail). */
.dash-new-dot-static { animation: none; }
/* Cloche demandes d'acces : garde son compteur, halo statique CHAUD a la place du clignotement. */
.nav-bell-hot .nav-bell-count { box-shadow: 0 0 0 2px var(--bg), 0 1px 6px 1px rgba(239,68,68,.65); }
/* ── FILET GLOBAL : quand les pastilles numeriques sont actives (body[data-badges="1"]), les petits
   clignotements "nouveaute" secondaires s'eteignent SANS toucher chaque vue (sous-onglets Votes, point du
   menu Plus, items news, nav Mes pronos, recap dots poses par le JS, et tout ccn-* encore emis, ex. pills
   d'etapes velo). Les URGENCES A DEADLINE (pool-cta-*, hero-blink, tour-deadline, saveBlink, ucblink,
   md-dot-flash, nb-deadline) restent animees : autre metier, c'est le moteur qui marche. ── */
body[data-badges="1"] .ccn-blink { animation: none; }
body[data-badges="1"] .ccn-dot { animation: none; }
body[data-badges="1"] .ccn-letter { animation: none; }
body[data-badges="1"] .vote-subtab.vsub-todo .vsub-dot { animation: none; box-shadow: 0 0 0 2px var(--bg), 0 0 5px 1px rgba(245,158,11,.55); }
body[data-badges="1"] .more-dot { animation: none; box-shadow: 0 0 5px 1px rgba(245,158,11,.5); }
body[data-badges="1"] .news-blink { animation: none; background: rgba(60,160,90,.07); }
body[data-badges="1"] .nav a.nav-mespronos.is-new { animation: none; background: rgba(60,160,90,.12); }
/* Coche de compte rendu NON LU : le clignotement est REAFFIRME meme avec les pastilles numeriques
   (13/07 soir, demande Jonathan). Il etait eteint quand il venait du localStorage/96 h (bruyant et faux) ;
   depuis la mig 090 il est pilote par le VRAI etat non-lu par journee -> il redevient legitime et s'arrete
   des la lecture de la journee. */
body[data-badges="1"] .md-dot.recap-blink { animation: recapdot 1s ease-in-out infinite; }
body[data-badges="1"] .dash-new-dot { animation: none; }
body[data-badges="1"] .vdot-todo { animation: none; }
body[data-badges="1"] .md-dot-req { animation: none; }
body[data-badges="1"] .md-dot-flash { animation: md-dot-blink 1.1s ease-in-out infinite; } /* deadline Long terme : REAFFIRMEE animee (prime sur toute extinction future) */
/* Bulle "Inviter des amis / Creer un concours" : compacte, a gauche (pas pleine largeur), accent vert. */
.invite-card { max-width: 24rem; padding: .9rem 1rem; border-color: var(--accent-2); background: rgba(58,209,122,.07); }
.invite-card strong { display: block; }
.invite-card .small { font-size: .82rem; }
.invite-card-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .6rem; }
.js-share { cursor: pointer; }
/* Pulse doux des appels a l'action (en jette sans deranger). */
.cta-pulse { animation: cta-pulse 2.6s ease-in-out infinite; }
@keyframes cta-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(58,209,122,0); } 50% { box-shadow: 0 0 0 4px rgba(58,209,122,.30); } }
@media (prefers-reduced-motion: reduce) { .cta-pulse { animation: none; } }

/* ===== Responsive : header + tableaux denses sur petit ecran ===== */
@media (max-width: 640px) {
    .topbar { flex-wrap: wrap; gap: .4rem .6rem; padding: .6rem .8rem; }
    .brand-logo { height: 40px; }
    /* On exploite plus de largeur d'ecran sur mobile (cadres moins epais) */
    .container { padding: .6rem; }
    .card { padding: .85rem; margin: .8rem 0; }
    th, td { padding: .5rem .32rem; }
    body { font-size: 1.12rem; }   /* texte encore un peu plus grand sur mobile */
    /* Header mobile sur 2 lignes : logo centre (ligne 1) ; profil+theme a gauche, outils a droite (ligne 2) */
    .brand { flex-basis: 100%; justify-content: center; }
    .topbar-actions { order: 1; flex-basis: 100%; width: 100%; gap: .6rem; } /* .4 -> .6rem : idem sur mobile, le "A" ne touche plus l'etoile */
    .topbar-tools { margin-left: auto; }
    .scroll-anchor { scroll-margin-top: 112px; }   /* header mobile 2 lignes : on degage bien sous la barre */
    .nav-toggle { display: inline-flex; }
    .nav { order: 5; margin-left: 0; display: none; flex-basis: 100%; width: 100%; flex-direction: column;
        align-items: stretch; gap: .1rem; margin-top: .5rem; padding-top: .4rem; border-top: 1px solid var(--border); }
    .nav.open { display: flex; }
    .nav a, .nav .btn-link { display: block; width: 100%; padding: .65rem .45rem; font-size: 1.08rem; border-radius: 8px; text-align: left; }
    .nav a:hover, .nav .btn-link:hover { background: rgba(255,255,255,.07); }
    .nav .inline, .nav form { display: block; width: 100%; margin: 0; }
    .nav .lang-switch { margin: .4rem 0 0; padding-top: .45rem; border-top: 1px solid var(--border); font-size: 1.02rem; }
    .nav .lang-switch a { padding: .25rem .6rem; }
    .nav-pseudo { max-width: 5.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    h2 { font-size: 1.4rem; }
    h3 { font-size: 1.15rem; }
    /* Hero mobile : moins de padding haut + logo plus petit pour que la phrase d'urgence ne soit pas coupee en bas (iPhone 11). */
    .hero { padding: 1.1rem .9rem 1.4rem; }
    .hero-logo-wrap { margin-bottom: .5rem; }
    .hero-logo { width: clamp(180px, 64vw, 300px); }
    .hero-title { margin: .1rem 0 .25rem; }
    .hero-cd { margin: .9rem 0; }
    .hero-cta { margin: .9rem 0 .5rem; }
    .hero-urgency { margin: .3rem 0 0; }
    /* Tableaux larges (classement, analytics) : scroll horizontal au lieu de deborder la page */
    .card > table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
    /* Frise des journees : scroll horizontal sur UNE ligne (au lieu de plusieurs) ; recentree par JS sur la barre rouge */
    .tabs.md-strip { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; padding: .55rem .15rem .5rem; }
    .tabs.md-strip a { flex: 0 0 auto; }
    /* Cartes de mise : plus de hauteur + textes secondaires plus grands (tout visible, quitte a descendre) */
    .match { padding: 1rem .8rem; }
    .match .teams { font-size: 1.06rem; }
    .match .ko { font-size: .92rem; }
    .score-board { margin: 1rem 0 .5rem; }
    .ht-row { margin: .55rem 0 .3rem; gap: .55rem; }
    .ht-label { font-size: .95rem; }
    .ht-select { font-size: 1rem; padding: .42rem 2rem .42rem .85rem; }
    .pred-actions { margin-top: .7rem; }
    .pred-status, .frozen-note, .pred-frozen { font-size: .95rem; }
    /* Tableau Membres : 1 carte par personne (nom ligne 1, role/statut/enjeu ligne 2, actions admin dessous) -> aucun scroll horizontal */
    .members-table, .members-table tbody { display: block; white-space: normal; }
    .members-table thead { display: none; }
    .members-table tr { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .55rem;
        border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); padding: .55rem .7rem; margin: .5rem 0; }
    .members-table td { display: inline-flex; align-items: center; width: auto; padding: 0; border: none; }
    .members-table td:first-child { flex-basis: 100%; font-weight: 700; font-size: 1.05rem; }
    .members-table td:nth-child(2) { color: var(--muted); font-size: .92rem; }
    .members-table .stake-action-cell,
    .members-table .member-actions-cell { flex-basis: 100%; }
    .members-table .member-actions { flex-wrap: wrap; gap: .4rem; }
    /* Tableau « Tous les concours » : 1 carte par concours, chaque info sur SA ligne (espacees). */
    .groups-table, .groups-table tbody { display: block; white-space: normal; }
    .groups-table thead { display: none; }
    .groups-table tr { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
        border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); padding: .7rem .8rem; margin: .6rem 0; }
    .groups-table td { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; width: 100%; padding: 0; border: none; }
    .groups-table td.rank { display: none; }                                  /* le rang n'a pas de sens en carte */
    .groups-table td.grp-name { font-weight: 700; font-size: 1.12rem; }
    .groups-table td.grp-name a { color: var(--text); }
    .groups-table td[data-label]::before { content: attr(data-label) " : "; color: var(--muted); font-size: .85rem; font-weight: 600; }
    .groups-table td.grp-type { font-size: .92rem; }                          /* badge + « Figé... » sur leur propre ligne */
}

/* ===== Selecteur de meilleur buteur (recherche + drapeau + couleur par pays) ===== */
.scorer-picker { position: relative; }
/* Pronos du tournoi VERROUILLES (coup d'envoi passe -> fieldset disabled) : non interactifs, MAIS le
   choix du joueur reste bien LISIBLE et FONCE (c'est SA selection, on la met en avant). On signale le
   verrou par la fleche delavee + le fond legerement grise + le curseur, pas en delavant la valeur.
   Le serveur refuse de toute facon toute ecriture apres le coup d'envoi. */
fieldset:disabled .scorer-picker { pointer-events: none; }
fieldset:disabled .scorer-input {
    opacity: 1;
    color: var(--text);
    -webkit-text-fill-color: var(--text); /* iOS/Safari : sinon le texte d'un input desactive est force en gris pale */
    font-weight: 600;                     /* renforce "c'est mon choix" */
    background: rgba(127, 127, 127, .10); /* leger fond grise = verrouille (neutre sur theme clair ET sombre) */
    cursor: not-allowed;
}
fieldset:disabled .scorer-caret { opacity: .4; }
.scorer-input { width: 100%; box-sizing: border-box; padding-right: 2rem; }
/* Cyclisme : drapeau du coureur SELECTIONNE, superpose a gauche de l'input (un <input> ne peut pas contenir d'image).
   Affiche uniquement quand un coureur est choisi (.has-flag) -> l'input reserve la place a gauche. */
.rider-picker .rp-selflag { position: absolute; left: .55rem; top: 50%; transform: translateY(-50%); line-height: 0; pointer-events: none; z-index: 1; }
.rider-picker .rp-selflag:empty { display: none; }
.rider-picker .rp-selflag img { width: 1.35rem; height: auto; border-radius: 2px; display: block; }
.rider-picker.has-flag .scorer-input { padding-left: 2.3rem; }
.scorer-caret { position: absolute; right: .7rem; top: 50%; transform: translateY(-50%); color: var(--muted);
    cursor: pointer; font-size: .7rem; line-height: 1; user-select: none; }
.scorer-pop { position: absolute; z-index: 55; left: 0; right: 0; top: 100%; margin-top: .25rem;
    max-height: 320px; overflow-y: auto; overscroll-behavior: contain; background: var(--card-2);
    border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 14px 32px rgba(0,0,0,.5); padding: .3rem; }
.scorer-pop.up { top: auto; bottom: 100%; margin-top: 0; margin-bottom: .25rem; }
.scorer-grp-h { background: var(--card-2); display: flex; align-items: center; gap: .45rem;
    font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--text);
    padding: .35rem .5rem; margin: .35rem 0 .1rem; border-left: 4px solid hsl(var(--ghue, 200) 60% 55%); border-radius: 3px; }
.scorer-opt { display: flex; align-items: center; gap: .5rem; width: 100%; text-align: left; background: none;
    border: none; color: var(--text); padding: .4rem .6rem; border-radius: 7px; cursor: pointer; font-size: .92rem; }
.scorer-opt:hover, .scorer-opt.active { background: rgba(31,138,76,.22); }
.scorer-opt.active { box-shadow: inset 0 0 0 1px rgba(58,209,122,.5); }
.scorer-opt img, .scorer-grp-h img { width: 20px; height: auto; border-radius: 2px; flex: 0 0 auto; }
.scorer-empty { padding: .55rem .6rem; color: var(--muted); font-size: .9rem; }

/* Pastille "?" d'aide (deadlines du concours) : info au survol via title= */
.qhint { display: inline-flex; align-items: center; justify-content: center; width: 1.05rem; height: 1.05rem;
    border-radius: 50%; border: 1px solid var(--border); font-size: .72rem; line-height: 1; color: var(--muted);
    cursor: help; vertical-align: middle; margin-left: .15rem; }
.qhint:hover { color: var(--text); border-color: var(--accent-ink); }

/* Bouton "Copier" : retour visuel facon ChatGPT (s'enfonce au clic, puis check + "Copie !") */
.copy-btn { transition: background .12s ease, transform .08s ease; }
.copy-btn:active { transform: translateY(1px); }
.copy-btn.copied { background: var(--accent-2); border-color: var(--accent-ink); color: #04210f; animation: copyPulse .85s ease; }
.copy-btn .copy-check { vertical-align: -2px; }
@keyframes copyPulse { 0% { transform: scale(1); } 30% { transform: scale(1.07); } 100% { transform: scale(1); } }

/* Saisie des resultats en admin : meme look que le score-board des cartes joueurs (gros chiffres
   + drapeaux XL), mais avec des champs nombre (un score peut depasser 9). Ligne mi-temps plus petite. */
.score-in { width: 3.4rem; border: 1px solid var(--border); border-radius: 12px; background: #161a22; color: var(--text);
    text-align: center; font-size: 2rem; font-weight: 800; line-height: 1; padding: .3rem 0; flex: 0 0 auto; -moz-appearance: textfield; }
.score-in:focus { outline: none; border-color: var(--accent-ink); box-shadow: 0 0 0 2px rgba(43,176,97,.35); background: rgba(43,176,97,.10); }
.score-in::-webkit-outer-spin-button, .score-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.admin-ht-row { display: flex; align-items: center; justify-content: center; gap: .4rem; margin: .25rem 0 .1rem; }
/* Formulaire knockout combine (assigner equipes + saisir resultat) */
.admin-ko-teams { display: flex; flex-direction: column; gap: .25rem; margin: .2rem 0 .55rem; }
.admin-ko-teams label { margin: 0; }
.admin-ko-actions { display: flex; gap: .5rem; flex-wrap: wrap; justify-content: center; margin-top: .6rem; }
.score-in-sm { width: 2.6rem; font-size: 1.2rem; padding: .2rem 0; }
.score-sep-sm { font-size: 1.1rem; }
.match.admin-done { border-color: rgba(43,176,97,.4); }

/* Ligne "Abstentions" dans les tableaux de vote : comptee mais discrete (hors decompte majoritaire) */
.vote-abstain-row td { color: var(--muted); border-top: 1px dashed var(--border); font-style: italic; }

/* Compteur de membres dans le titre de l'onglet Membres */
.member-count { font-size: .8rem; font-weight: 700; color: var(--accent-ink); background: rgba(43,176,97,.14);
    border: 1px solid rgba(43,176,97,.3); border-radius: 999px; padding: .08rem .6rem; vertical-align: middle; margin-left: .35rem; }

/* Bouton "Enregistrer" en attente (.save-state-btn.blink) : clignote en orange tant que non sauve */
.save-state-btn .copy-check { vertical-align: -2px; }
.save-state-btn.blink { background: #d9822b; border-color: #d9822b; color: #fff; animation: saveBlink 1.1s ease-in-out infinite; }
@keyframes saveBlink { 0%, 100% { box-shadow: 0 0 0 0 rgba(217,130,43,.55); } 50% { box-shadow: 0 0 0 5px rgba(217,130,43,0); } }

/* Bandeau « Ajouter a l'ecran d'accueil » (A2HS) : discret, en bas, fermable, masque par defaut (revele par main.js sur mobile) */
.a2hs { position: fixed; left: .6rem; right: .6rem; bottom: .6rem; z-index: 1200;
    display: flex; align-items: center; gap: .7rem; padding: .7rem 2rem .7rem .8rem;
    background: var(--card); border: 1px solid var(--border); border-radius: 14px;
    box-shadow: 0 10px 34px rgba(0,0,0,.5); transform: translateY(150%); opacity: 0;
    transition: transform .28s ease, opacity .28s ease; }
.a2hs.a2hs-in { transform: translateY(0); opacity: 1; }
.a2hs-icon { width: 46px; height: 46px; border-radius: 11px; flex: 0 0 auto; }
.a2hs-body { flex: 1 1 auto; min-width: 0; }
.a2hs-title { font-weight: 700; font-size: .92rem; color: var(--text); }
.a2hs-text { font-size: .8rem; color: var(--muted); margin-top: .12rem; }
.a2hs-install { flex: 0 0 auto; background: var(--accent-2); color: #06210f; border: none;
    border-radius: 999px; padding: .5rem .9rem; font-weight: 700; font-size: .85rem; cursor: pointer; }
.a2hs-install:hover { background: #34c873; }
.a2hs-close { position: absolute; top: .35rem; right: .5rem; background: none; border: none;
    color: var(--muted); font-size: 1.25rem; line-height: 1; cursor: pointer; padding: .1rem .25rem; }
.a2hs-close:hover { color: var(--text); }
.a2hs-never { display: inline-block; margin-top: .3rem; background: none; border: none; padding: 0;
    color: var(--muted); font-size: .8rem; text-decoration: underline; cursor: pointer; }
.a2hs-never:hover { color: var(--text); }
@media (min-width: 720px) { .a2hs { left: auto; max-width: 430px; } }
/* Glyphe « Partager » iOS dans le bandeau (affiche par main.js uniquement sur iOS Safari) */
.a2hs-share { flex: 0 0 auto; vertical-align: -2px; margin-right: .2rem; color: var(--accent-2); }

/* ===== Bascule de theme (lune/soleil) : vit dans la topbar qui reste sombre dans les 2 modes ===== */
/* Format UNIFIE des 4 boutons du header (megaphone .fav-btn = reference : 38px, rayon 9px, bordure neutre) :
   theme + horloge alignes dessus (15/07). L'oeil super-admin (.sa-reveal) garde sa teinte ambre a part. */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px;
    border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #cdd3df; cursor: pointer; padding: 0; -webkit-tap-highlight-color: transparent; } /* plus de margin-left : espacement UNIFORME via le seul gap du conteneur (fix asymetrie megaphone/theme, 15/07) */
.theme-toggle:hover { color: #fff; border-color: var(--accent-2); }
.theme-toggle svg { width: 17px; height: 17px; display: block; }
/* Sombre : on montre le SOLEIL (cliquer = aller vers le clair). Clair : on montre la LUNE.
   Specificite .theme-toggle .ic-* > .theme-toggle svg, sinon les deux s'affichaient. */
.theme-toggle .ic-moon { display: none; }
.theme-toggle .ic-sun { display: block; }
html[data-theme="light"] .theme-toggle .ic-sun { display: none; }
html[data-theme="light"] .theme-toggle .ic-moon { display: block; }

/* =========================================================================
   MODE CLAIR. Corps/cartes/formulaires/tableaux passent en clair. La topbar
   et le hero restent sombres (le logo est un wordmark blanc/vert, invisible
   sur fond clair). Tout texte vif est re-contraste pour le fond clair.
   Auto 8h-22h via un script inline dans le <head> ; bascule manuelle persistee.
   ========================================================================= */
html[data-theme="light"] {
    color-scheme: light;      /* mode clair : scrollbar clair (piste fondue au blanc, flèches/ascenseur gris) - déjà joli, on le garde */
    --accent: #1b7d44;        /* fond de bouton : blanc lisible dessus */
    --accent-2: #2bb061;      /* vert vif conserve pour les FONDS a texte sombre */
    --accent-ink: #137a3a;    /* vert fonce pour le TEXTE sur fond clair */
    --bg: #eef1f5;
    --card: #ffffff;
    --card-2: #f2f4f8;
    --text: #1b1f27;
    --muted: #3a4452;         /* gris bien fonce sur fond clair (~8.5:1), proche du corps de texte */
    --border: #c8cfd9;        /* un peu plus marque pour definir cartes / champs */
    --danger: #c9302c;
    --warn: #a1670a;    /* 22/07 : etait le seul code semantique sans variante claire (contours ambre a 2,2:1) */
    --ok: #1b7d44;
}
/* SOMBRE (theme par defaut) : detacher les CARTES du fond (13/07) - la bordure vient de --border
   eclairci ci-dessus, on ajoute une legere elevation (ombre basse + liseret interne) pour la
   profondeur. Aucun effet en clair (:not light). */
html:not([data-theme="light"]) .card {
    box-shadow: 0 1px 3px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .035);
}
/* 12/07 soir : verts fonces #1f8a4c en TEXTE sur fond sombre (sans override) -> vert texte lisible
   (--accent-ink) en mode sombre uniquement (le clair garde ses valeurs). Complete les rk-btn/hist-*
   qui avaient deja leur override sombre #4fd58a. */
html:not([data-theme="light"]) .tour-pill .tp-ok,   /* 22/07 : .pool-decide-eyebrow retiree du groupe,
   elle vit sur le degrade CLAIR fixe du bandeau (ilot C) et son vert #1f8a4c y est deja contraste */
html:not([data-theme="light"]) .tour-stage-when .tsw-ok,
html:not([data-theme="light"]) .cyo-stagepts { color: var(--accent-ink); }
/* Surfaces sombres codees en dur -> claires */
html[data-theme="light"] .stepper,
html[data-theme="light"] .score-in { background: var(--card-2); }
html[data-theme="light"] tbody tr:nth-child(even) { background: rgba(0,0,0,.035); }
html[data-theme="light"] .lb-table .lb-row:hover td,
html[data-theme="light"] .lb-table .lb-row:hover + .pts-row td { background: rgba(0,0,0,.05); }
html[data-theme="light"] .grid-table th,
html[data-theme="light"] .grid-table td { border-bottom-color: rgba(0,0,0,.08); border-right-color: rgba(0,0,0,.06); }
html[data-theme="light"] .pts-match { border-bottom-color: rgba(0,0,0,.06); }
/* Onglets « Pronos » : la bordure claire des boutons devient grise visible */
html[data-theme="light"] .tab-group a:not(.active) { border-color: var(--border); }
html[data-theme="light"] .tab-group a:not(.active):hover { border-color: var(--accent-2); background: rgba(43,176,97,.08); }
/* Boutons a contour (Demander l'acces, Rejoindre...) : bordure bien marquee en clair */
html[data-theme="light"] .btn-ghost { border-color: #97a3b2; }
html[data-theme="light"] .btn-ghost:hover { border-color: var(--accent-2); }

/* ═══ R1 (22/07) : LE BANDEAU EST SOMBRE DANS LES DEUX MODES, DONC RIEN DEDANS NE BASCULE ═══
   Regle posee par Jonathan : « si le header est deja fonce, et qu'on a decide qu'il resterait fonce,
   rien ne doit changer quand on passe du fond clair au fond sombre. »
   Avant, chaque element du bandeau lisait les variables GLOBALES (--text, --muted, --border, --accent),
   qui basculent avec data-theme. En mode clair les pastilles Membre/Admin passaient a #3a4452 sur du
   noir (1,9:1, illisibles), le pseudo virait au bleu sombre, la mise en avant « Competitions » /
   « Mes pronos » disparaissait, et les anneaux var(--bg) des pastilles devenaient des cercles blancs.
   On corrige la CAUSE, pas les symptomes : le bandeau redeclare sur lui-meme le jeu SOMBRE, et ses
   enfants n'ont plus une seule regle a eux. Portee limitee a [data-theme="light"] : le mode sombre,
   qui est la reference, n'est pas touche.
   Les 3 declinaisons data-comp sont OBLIGATOIRES : une declaration posee sur .topbar bat celle heritee
   de html[data-comp], donc sans elles toutes les competitions redeviendraient vertes. */
html[data-theme="light"] .topbar {
    background: #050505;              /* meme fond que la l.93 : la barre etait la seule chose a changer */
    --bg: #0f1115; --card: #171a21; --card-2: #1e222b;
    --text: #d9dee6; --muted: #bcc4d1; --border: #707b96;
    --accent: #1f8a4c; --accent-2: #2bb061; --accent-ink: #33c06e; --on-accent: #fff;
}
html[data-theme="light"][data-comp="tour"]   .topbar { --accent: var(--scoremigos-yellow); --accent-2: #e6b800; --accent-ink: #f2c94c; --on-accent: #1a1a1a; }
html[data-theme="light"][data-comp="vuelta"] .topbar { --accent: #ff5a6b; --accent-2: #ff4d5e; --accent-ink: #ff6b7d; --on-accent: #fff; }
html[data-theme="light"][data-comp="cl"]     .topbar { --accent: #5b9bff; --accent-2: #4d8bff; --accent-ink: #6ba4ff; --on-accent: #fff; }
/* Le panneau hamburger et le menu de competition PENDENT sous la barre mais deviennent volontairement
   clairs en mode clair : on leur rend le jeu clair, sinon l'ilot ci-dessus les noircirait. */
html[data-theme="light"] .topbar .nav.open,
html[data-theme="light"] .topbar .sport-menu {
    --bg: #eef1f5; --card: #ffffff; --card-2: #f2f4f8;
    --text: #1b1f27; --muted: #3a4452; --border: #c8cfd9;
    --accent: #1b7d44; --accent-2: #2bb061; --accent-ink: #137a3a; --on-accent: #fff;
}
/* Valeur litterale de la l.2926, insensible aux variables et plus specifique : on rejoue le dessin
   d'origine du bouton Connexion, qui garde ainsi sa teinte de competition. */
html[data-theme="light"] .topbar .btn-ghost { border-color: color-mix(in srgb, var(--accent-2) 45%, var(--border)); }
/* Menu hamburger OUVERT en mode clair : le panneau deroulant devient clair (la barre, elle, reste sombre) */
html[data-theme="light"] .nav.open { background: var(--card); border: 1px solid var(--border); border-top: none;
    border-radius: 0 0 12px 12px; box-shadow: 0 12px 26px rgba(20,30,50,.16); padding: .35rem .55rem .55rem; }
html[data-theme="light"] .topbar .nav.open a,
html[data-theme="light"] .topbar .nav.open .btn-link { color: var(--text); }
html[data-theme="light"] .nav.open a:hover,
html[data-theme="light"] .nav.open .btn-link:hover { background: rgba(0,0,0,.05); }
html[data-theme="light"] .nav.open .lang-switch a { color: var(--muted); }
html[data-theme="light"] .topbar .nav.open .lang-switch a.active { color: var(--text); }

/* ═══ R2, ilot B : surfaces a fond SOMBRE fixe (22/07) ═══
   Le hero d'accueil et la modale de partage de ceremonie gardent un fond nuit dans les DEUX modes.
   Leurs enfants doivent donc lire les encres SOMBRES en permanence. Meme mecanique que l'ilot du
   bandeau : on corrige la surface, pas ses enfants un par un. Les rustines ponctuelles qui
   existaient (.hero-title, .hero-sub, .cd-box span) avaient d'ailleurs oublie .match-live et les
   pastilles de home_cycling.php : c'est la preuve que le cas par cas ne tient pas. */
.hero, .share-panel {
    --text: #f3f5f8; --muted: #c4cad4; --border: rgba(255,255,255,.22);
    --card: rgba(255,255,255,.08); --card-2: rgba(255,255,255,.08);
    --accent-ink: #33c06e;
}
html[data-comp="tour"]   .hero, html[data-comp="tour"]   .share-panel { --accent-ink: #f2c94c; }
html[data-comp="vuelta"] .hero, html[data-comp="vuelta"] .share-panel { --accent-ink: #ff6b7d; }
html[data-comp="cl"]     .hero, html[data-comp="cl"]     .share-panel { --accent-ink: #6ba4ff; }

/* ═══ R2, ilot C : surfaces a fond CLAIR fixe (22/07) ═══
   Le bandeau « prends ta decision » (degrade clair fixe, l.3430) et l'encart de rattrapage du pool
   (fond #f9fafb pose en inline dans contest.php) restent clairs dans les deux modes. En mode sombre
   leur croix de fermeture et leur texte secondaire lisaient --muted = #bcc4d1 : 1,7:1, le joueur ne
   pouvait meme plus fermer le bandeau. */
.pool-decide-banner, #pool-excluded {
    --text: #1a1a1a; --muted: #4b5563; --border: #d1d5db; --accent-ink: #137a3a;
}

/* Le hero reste un encart sombre (logo + scoreboard lisibles) */
html[data-theme="light"] .hero { background: radial-gradient(130% 120% at 50% -10%, rgba(31,138,76,.30), transparent 62%), #11151b; border-color: #232b35; }
html[data-theme="light"] .hero-title { color: #f3f5f8; }
html[data-theme="light"] .hero-sub,
html[data-theme="light"] .cd-box span { color: #c4cad4; }
html[data-theme="light"] .hero-cd-label,
html[data-theme="light"] .hero-blink { color: var(--accent-2); }

/* Textes vifs re-contrastes pour le fond clair (badges, chips, jokers, phases) */
html[data-theme="light"] .badge-ok { color: #137a3a; }
html[data-theme="light"] .badge-patience { color: #14618f; }
html[data-theme="light"] .badge-late { color: #6d28d9; }
html[data-theme="light"] .badge-bonus,
html[data-theme="light"] .badge-wait,
html[data-theme="light"] .btn-warn-ghost,
html[data-theme="light"] .joker-alert { color: #8a5a00; }
html[data-theme="light"] .badge-danger,
html[data-theme="light"] .badge-locked,
html[data-theme="light"] .countdown-red,
html[data-theme="light"] .frozen-note,
html[data-theme="light"] .next-match-label,
html[data-theme="light"] .pts-chip.pts-neg,
html[data-theme="light"] .chip-bad { color: #b3261e; }
html[data-theme="light"] .pts-chip.pts-pos { color: #137a3a; }
html[data-theme="light"] .pts-chip.pts-zero { color: #b3261e; }
/* Badge rouge (buteur 0 but / Rate) : fond+contour un peu plus marques en clair, sinon trop pale sur fond blanc. */
html[data-theme="light"] .pts-chip.pts-neg,
html[data-theme="light"] .pts-chip.pts-zero { background: rgba(201,48,44,.10); border-color: rgba(201,48,44,.5); }
html[data-theme="light"] .pts-chip.pts-side { color: #0f766e; }
html[data-theme="light"] .pts-chip.pts-joker,
html[data-theme="light"] .joker-count-x2,
html[data-theme="light"] .grid-joker { color: #6d28d9; }
html[data-theme="light"] .joker-count-x3 { color: #b45309; }
html[data-theme="light"] .grid-joker.grid-joker-x3 { color: #b45309; }
/* Boutons de CHOIX de joker (sobres) : texte assez fonce pour rester lisible en theme clair */
html[data-theme="light"] .joker-btn { color: #6d28d9; }
html[data-theme="light"] .joker-btn-x3 { color: #b45309; }
html[data-theme="light"] .chip { color: #1d6fa5; }
html[data-theme="light"] .ht-draw { color: #1d4ed8; }
html[data-theme="light"] .crown,
html[data-theme="light"] .fav-toggle.on,
html[data-theme="light"] .md-head-lg .md-phase-r32,
html[data-theme="light"] .tabs a.tab-stage-r32:not(.active) { color: #9a7d00; }
html[data-theme="light"] .md-head-lg .md-phase-r16,
html[data-theme="light"] .tabs a.tab-stage-r16:not(.active) { color: #b85c12; }
html[data-theme="light"] .md-head-lg .md-phase-qf,
html[data-theme="light"] .tabs a.tab-stage-qf:not(.active) { color: #c0322c; }
html[data-theme="light"] .md-head-lg .md-phase-sf,
html[data-theme="light"] .tabs a.tab-stage-sf:not(.active) { color: #7c3aed; }
html[data-theme="light"] .md-head-lg .md-phase-third_place,
html[data-theme="light"] .tabs a.tab-stage-third_place:not(.active) { color: #0e7490; }
/* Encart d'affiliation (inerte par defaut) : lisible aussi en clair une fois active */
html[data-theme="light"] .aff-link { color: #0c4a2a; }
html[data-theme="light"] .aff-link-stream { color: #14366b; }
html[data-theme="light"] .aff-box-label { color: #5b6573; }
html[data-theme="light"] .aff-note { color: #6b7380; }
/* Panneau dev « Voyage dans le temps » : fond sombre code en dur -> texte clair maintenu en mode clair */
html[data-theme="light"] .time-travel,
html[data-theme="light"] .tt-toggle,
html[data-theme="light"] .tt-now,
html[data-theme="light"] .tt-row button,
html[data-theme="light"] .tt-reset,
html[data-theme="light"] .tt-row input[type=datetime-local] { color: #e7e9ee; }
html[data-theme="light"] .tt-help { color: #9aa3b2; }
/* Ombres plus douces sur fond clair */
html[data-theme="light"] .card,
html[data-theme="light"] .a2hs { box-shadow: 0 6px 20px rgba(20,30,50,.10); }

/* ===== Hero (volontairement sombre dans les 2 modes) : contenu identique quel que soit le theme.
   Les boutons « ghost » et le badge belge gardent texte blanc + contour clair, sinon ils
   deviennent illisibles en mode clair (le hero reste noir). ===== */
.hero-cta .btn-ghost,
html[data-theme="light"] .hero-cta .btn-ghost { color: #fff; border-color: rgba(255,255,255,.55); background: transparent; }
.hero-cta .btn-ghost:hover,
html[data-theme="light"] .hero-cta .btn-ghost:hover { color: #fff; border-color: #fff; background: rgba(255,255,255,.1); }
.hero-belgian { border-color: rgba(255,255,255,.22); }

/* ---- Bouton "Nouveaute" clignotant en tete du classement (acces remonte depuis l'onglet Communication) ---- */
/* Pill compacte (meme gabarit que .vote-subtab : padding .4/.8, radius 999, .9rem) mais verte + clignotante. */
.news-cta { display: inline-flex; align-items: center; gap: .4rem; margin: .1rem 0 .7rem; padding: .4rem .8rem;
    border-radius: 999px; border: 1px solid rgba(43,176,97,.55); background: rgba(43,176,97,.14); color: #1c8a4e;
    font-weight: 700; font-size: .9rem; text-decoration: none; animation: news-cta-pulse 1.4s ease-in-out infinite; }
.news-cta:hover { background: rgba(43,176,97,.24); border-color: var(--accent-ink); }
.news-cta-bell { font-size: 1rem; line-height: 1; }
@keyframes news-cta-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); } 50% { box-shadow: 0 0 0 4px rgba(43,176,97,.26); } }
@media (prefers-reduced-motion: reduce) { .news-cta { animation: none; } }

/* ---- Preuve par email : zone opt-in en haut du classement (a cote du bouton partage) ---- */
/* Sans .has-proof (joueur exclu ou groupe sans enjeu) : rien ne change, le bouton partage reste centre. */
.lb-top-row.has-proof { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: 12px 18px; margin: 14px 0 18px; }
.lb-top-row.has-proof .share-row { margin: 0; flex: 0 0 auto; } /* le partage se decale a gauche, la zone preuve a droite */
.proof-optin-bar { flex: 1 1 320px; min-width: 260px; max-width: 460px; text-align: left;
    background: rgba(46,204,113,.08); border: 1px solid rgba(46,204,113,.28); border-radius: 12px; padding: 10px 14px; }
.proof-optin-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.proof-optin-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600;
    line-height: 1.25; flex: 1 1 auto; }
.proof-optin-check input { width: auto; margin: 0; flex: 0 0 auto; accent-color: #2ecc71; transform: scale(1.15); }
.proof-optin-check.is-disabled { opacity: .6; cursor: not-allowed; }
.proof-optin-text { font-size: .9rem; }
.proof-help { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 999px; background: rgba(46,204,113,.18); color: #1c8a4e;
    border: 1px solid rgba(46,204,113,.45); font-weight: 800; font-size: .8rem; text-decoration: none; }
.proof-help:hover { background: rgba(46,204,113,.32); }
.proof-optin-meta { margin: 6px 0 0; line-height: 1.3; }
.proof-counter { color: #1c8a4e; font-weight: 600; }
/* Pulse d'incitation doux sur le compteur tant qu'il reste des places (halo vert, meme style que les autres pulses). */
.proof-counter.is-nudge { display: inline-block; padding: 1px 9px; border-radius: 999px;
    background: rgba(46,204,113,.14); border: 1px solid rgba(46,204,113,.40);
    animation: proof-counter-pulse 1.6s ease-in-out infinite; }
@keyframes proof-counter-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(46,204,113,0); } 50% { box-shadow: 0 0 0 4px rgba(46,204,113,.26); } }
@media (prefers-reduced-motion: reduce) { .proof-counter.is-nudge { animation: none; } }
.proof-full-note { display: block; color: #b9770b; font-weight: 600; margin-top: 2px; }
.proof-report { margin-top: 7px; }
.proof-report-link { cursor: pointer; color: var(--muted); font-size: .8rem; text-decoration: underline;
    list-style: none; display: inline-block; }
.proof-report-link::-webkit-details-marker { display: none; }
.proof-report:open .proof-report-link { color: var(--text); font-weight: 600; }
.proof-report-form { display: flex; flex-direction: column; gap: 7px; margin-top: 8px; }
.proof-report-intro { margin: 0 0 2px; }
.proof-report-field { display: flex; flex-direction: column; gap: 3px; }
.proof-report-field > span { font-weight: 600; color: var(--muted); }
.proof-report-field input, .proof-report-field select, .proof-report-field textarea { width: 100%; box-sizing: border-box; }
.proof-report-send { align-self: flex-start; }
.proof-verifier-badge { white-space: nowrap; position: relative; cursor: help; }
/* Infobulle au survol/focus du badge Verificateur : explique le role + invite a devenir verificateur. */
.proof-verifier-tip { display: none; position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 60;
    width: max-content; max-width: min(280px, 80vw); padding: .55rem .7rem; border-radius: 9px;
    background: var(--card); color: var(--text); border: 1px solid var(--border); box-shadow: 0 10px 28px rgba(0,0,0,.45);
    font-weight: 400; font-size: .8rem; line-height: 1.4; white-space: normal; text-align: left; }
.proof-verifier-badge:hover .proof-verifier-tip, .proof-verifier-badge:focus .proof-verifier-tip,
.proof-verifier-badge:focus-within .proof-verifier-tip { display: block; }
@media (max-width: 640px) {
    .lb-top-row.has-proof { flex-direction: column; align-items: stretch; }
    .lb-top-row.has-proof .share-row { text-align: center; }
    .proof-optin-bar { max-width: none; width: 100%; box-sizing: border-box; }
}

/* ---- Partage viral (bouton + pop-up modale) ---- */
.share-row { margin: 14px 0 18px; text-align: center; }
.share-box { position: relative; display: inline-block; max-width: 100%; }
.share-controls { display: inline-flex; align-items: center; gap: 8px; }
/* Petit oeil "apercu" a cote du bouton : sur PC il signale le survol ; sur mobile il ouvre la modale (carte en grand) */
.share-eye { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; font-weight: 700; font-size: .82rem;
    color: #2ecc71; background: transparent; border: 1px solid rgba(46,204,113,.45); border-radius: 999px; padding: 6px 12px; }
.share-eye svg { width: 15px; height: 15px; fill: currentColor; }
.share-eye:hover { background: rgba(46,204,113,.12); }
/* Accroche de frime (sous-titre modale + survol) EN GRAND : c'est elle qui donne envie de publier */
.share-brag { margin: 2px 30px 14px 2px; font-size: 1.45rem; line-height: 1.2; font-weight: 800; color: #2ecc71; }
/* Apercu au SURVOL (desktop, pointeur fin) : la carte ASSEZ GRANDE pour etre lue + le petit mot, au-dessus du bouton */
.share-hover { position: absolute; left: 50%; bottom: calc(100% + 12px); transform: translateX(-50%) translateY(6px);
    width: min(340px, 82vw); padding: 9px; background: #0a1a10; border: 1px solid rgba(46,204,113,.4); border-radius: 14px;
    box-shadow: 0 18px 44px rgba(0,0,0,.55); opacity: 0; visibility: hidden; pointer-events: none; z-index: 50;
    transition: opacity .14s ease, transform .14s ease; }
.share-hover::after { content: ''; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
    border: 8px solid transparent; border-top-color: #0a1a10; }
.share-hover-card { display: block; width: 100%; height: auto; border-radius: 8px; }
.share-hover-brag { display: block; margin-top: 8px; text-align: center; font-size: 1.05rem; line-height: 1.25; font-weight: 800; color: #2ecc71; }
/* AU DOIGT, CET APERCU N'EXISTE PAS : ON LE RETIRE DE LA PAGE (08/09/2026). Il ne s'ouvre qu'au survol,
   donc jamais sur un telephone, mais il restait dans la mise en page, invisible et large de 308 px sur
   un ecran de 375 : la mesure voyait un debordement de 68 px la ou l'oeil ne voyait rien. Jonathan :
   « la page entiere ne devrait jamais flotter et bien fit ». display:none le retire pour de bon, sans
   toucher au survol du bureau, qui vit dans la requete ci-dessous. */
@media (hover: none), (pointer: coarse) {
    .share-hover { display: none; }
}
@media (hover: hover) and (pointer: fine) {
    .share-box:hover .share-hover { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
}
.btn-share { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; cursor: pointer;
    color: #06210f; background: #2ecc71; border: 1px solid #29b765; border-radius: 999px; padding: 7px 16px; font-size: .9rem; }
.btn-share svg { width: 16px; height: 16px; fill: currentColor; }
.btn-share:hover { background: #34d97a; }
/* --- Incitation visuelle au partage (douce, contextuelle) : une SALVE de pulses a l'arrivee + quand le bouton
   entre dans le viewport au scroll (jamais un stroboscope permanent). Au repos, un leger glow vert garde le
   bouton "vivant". Tout s'arrete des le 1er partage (classe retiree en JS + flag localStorage). --- */
.share-cta-hot { box-shadow: 0 0 0 1px rgba(46,204,113,.55), 0 0 12px rgba(46,204,113,.22); }
.share-pulse { animation: share-pulse 1.4s ease-in-out 4; }
@keyframes share-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(46,204,113,0); transform: scale(1); }
    50%      { box-shadow: 0 0 0 7px rgba(46,204,113,.30); transform: scale(1.045); }
}
@media (prefers-reduced-motion: reduce) { .share-pulse { animation: none; transform: none; } }
.share-overlay { position: fixed; inset: 0; z-index: 2000; display: flex; align-items: center; justify-content: center;
    padding: 16px; background: rgba(0,0,0,.74); }
.share-overlay[hidden] { display: none; }
body.share-open { overflow: hidden; }
.share-panel { position: relative; width: 100%; max-width: 440px; max-height: 92vh; overflow-y: auto;
    padding: 22px 18px 18px; border: 1px solid rgba(46,204,113,.3); border-radius: 18px;
    background: #0a1a10; box-shadow: 0 20px 60px rgba(0,0,0,.5); }
.share-close { position: absolute; top: 8px; right: 10px; width: 36px; height: 36px; line-height: 32px;
    font-size: 1.7rem; color: #fff; background: rgba(255,255,255,.1); border: 0; border-radius: 50%; cursor: pointer; }
.share-close:hover { background: rgba(255,255,255,.22); }
.share-hint { margin: 0 34px 14px 2px; font-size: 1rem; font-weight: 700; color: #fff; }
.share-preview { display: block; width: 100%; height: auto; border-radius: 12px; border: 1px solid rgba(255,255,255,.1); }
/* Bouton de partage NATIF (mobile) : envoie la carte en grand + le texte en un tap. Mis en avant. */
.btn-share-native { display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; cursor: pointer;
    margin-top: 16px; font-weight: 800; font-size: 1.02rem; color: #06210f; background: #2ecc71;
    border: 1px solid #29b765; border-radius: 14px; padding: 15px 16px; }
.btn-share-native svg { width: 20px; height: 20px; fill: currentColor; }
.btn-share-native:hover { background: #34d97a; }
.share-or { margin: 14px 0 4px; text-align: center; font-size: .82rem; font-weight: 600; color: rgba(255,255,255,.55); }
.share-channels { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
/* Mise en page selon le contexte (classe posee en JS). Defaut = PC : pas de bouton natif factice. */
.btn-share-native, .share-or { display: none; }
.share-box.is-native .btn-share-native { display: flex; }
.share-box.is-native .share-or { display: block; }
.share-box.is-native .share-ch.fb { display: none; }   /* Facebook masque sur mobile (sharer bancal) */
.share-ch { display: inline-flex; align-items: center; justify-content: center; gap: 9px; cursor: pointer;
    font-weight: 700; font-size: .95rem; color: #fff; border: 0; border-radius: 12px; padding: 13px 14px; text-decoration: none; }
.share-ch svg { width: 20px; height: 20px; fill: currentColor; flex: 0 0 auto; }
.share-ch.wa { background: #25d366; color: #053b1b; }
.share-ch.fb { background: #1877f2; }
.share-ch.ig { background: linear-gradient(45deg, #f58529, #dd2a7b, #8134af); }
.share-ch.copy { background: rgba(255,255,255,.13); }
.share-ch:hover { filter: brightness(1.07); }

/* Pool phase finale : joueur courant epingle en tete du classement + recherche de joueurs + badge "Toi" */
.lb-viewer-pinned { margin: 0 0 .5rem; }
.lb-pinned-title { margin: 0 0 .2rem; font-size: .68rem; font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); }
.lb-viewer-pinned .lb-table { border: 1px solid var(--accent-2); border-radius: 8px; background: rgba(91,141,239,.10); }
.lb-pinned-note { margin: .2rem 0 .6rem; }
.lb-you-badge { display: inline-block; font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    padding: .05rem .35rem; border-radius: 5px; color: var(--accent-ink); background: rgba(43,176,97,.16); border: 1px solid var(--accent);
    vertical-align: middle; margin-left: .25rem; }
.lb-search { width: 100%; box-sizing: border-box; padding: .5rem .7rem; margin: 0 0 .5rem; border: 1px solid var(--border);
    border-radius: 8px; background: var(--card-2); color: var(--text); font-size: .95rem; }
.lb-search:focus { outline: 2px solid var(--accent-2); outline-offset: -1px; }
.lb-search-empty { margin: 0 0 .6rem; }
/* Delta de places (+N vert / -N rouge) a droite du rang : classements + cartes de concours. */
.lb-delta { display: inline-block; font-size: .72rem; font-weight: 800; margin-left: .1rem; vertical-align: middle; }
.lb-delta.up { color: #2bb061; }
.lb-delta.down { color: #e05252; }
/* Recherche repliee sous un bouton discret (tous les classements, foot + velo). */
.lb-search-wrap { margin: 0 0 .55rem; }
.lb-search-wrap > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .3rem;
    font-size: .82rem; font-weight: 700; color: var(--muted); padding: .28rem .75rem; border: 1px solid var(--border);
    border-radius: 999px; background: var(--card-2); user-select: none; }
.lb-search-wrap > summary::-webkit-details-marker { display: none; }
.lb-search-wrap > summary:hover { color: var(--text); }
.lb-search-wrap[open] > summary { color: var(--text); border-color: var(--accent-2); margin-bottom: .45rem; }

/* ===== Pool phase finale : confirmation (alerte clignotante), explication pronos, filtre membres ===== */
/* Banniere "confirmer ou se retirer" : clignote tant que le choix n'est pas fait. Le serveur retire la
   banniere des que confirmed_at est pose (confirmation) ou que le membre se retire -> le clignotement cesse. */
.pool-confirm-card { border-color: var(--accent-2); background: rgba(43,176,97,.08); animation: pool-confirm-pulse 1.5s ease-in-out infinite; }
@keyframes pool-confirm-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); border-color: var(--accent-2); }
    50%      { box-shadow: 0 0 0 4px rgba(43,176,97,.22); border-color: #6ee7a8; }
}
.pool-confirm-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: 0 0 .4rem; font-weight: 700; }
.pool-confirm-title { display: inline-flex; align-items: center; }
.pool-confirm-pill { display: inline-flex; align-items: center; gap: .35rem; font-size: .72rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .03em; padding: .12rem .45rem; border-radius: 999px;
    color: #fff; background: #eb5757; }
.pool-confirm-dot { width: .5rem; height: .5rem; border-radius: 50%; background: #fff; animation: pool-confirm-dot 1.1s ease-in-out infinite; }
@keyframes pool-confirm-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(1.25); } }
@media (prefers-reduced-motion: reduce) { .pool-confirm-card, .pool-confirm-dot { animation: none; } }

/* Explication des pronostics (toujours visible, en tete des regles). */
.pool-pred-intro { border-color: var(--accent-2); background: rgba(43,176,97,.05); }
.pool-pred-intro-title { margin: 0 0 .4rem; font-weight: 700; }
.pool-pred-intro-body { line-height: 1.5; }
.pool-pred-intro-body br + br { display: none; } /* nl2br donne <br><br> entre paragraphes : on garde un seul saut visuel */

/* Filtre Confirmes / Tout le monde au-dessus de la liste des membres (pool). */
.mb-filter { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; margin: 0 0 .5rem; }
.mb-filter-label { font-size: .85rem; color: var(--muted); }
.mb-filter-btn { padding: .3rem .7rem; border: 1px solid var(--border); border-radius: 999px; background: var(--card-2);
    color: var(--text); font-size: .85rem; font-weight: 600; cursor: pointer; line-height: 1.2; }
.mb-filter-btn:hover { border-color: var(--accent-2); }
.mb-filter-btn.is-active { background: var(--accent-2); border-color: var(--accent-2); color: var(--on-accent); }

/* CTA accueil : concours phases finales (sous les scores live). */
.pool-home-cta { display: flex; flex-direction: column; align-items: stretch; gap: .55rem;
    border-color: var(--accent-2); background: rgba(43,176,97,.07); }
.pool-home-cta-text { flex: 1 1 auto; }
.pool-home-cta-title { margin: 0 0 .25rem; font-weight: 800; }
.pool-home-cta-body { margin: 0; font-size: .9rem; color: var(--muted); }
.pool-home-cta .btn { align-self: center; width: max-content; max-width: 100%; }
@media (max-width: 560px) { .pool-home-cta .btn { width: 100%; } }
/* Carte d'accueil pool en mode URGENCE (visiteur / inscrit hors concours) : liseré rouge doux + compte a rebours. */
.pool-home-cta-urgent { border-color: #ef4444; background: rgba(239,68,68,.07); }
.pool-home-cta-cd { margin: .35rem 0 0; font-size: .9rem; font-weight: 700; color: var(--ink); }
.pool-home-cta-cd .next-match-cd { color: #ef4444; font-weight: 800; }
.pool-home-cta-btn-blink { animation: pool-cta-pulse 1.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pool-home-cta-btn-blink { animation: none; } }
/* Switch super-admin (jorabino) sous la carte : previsualise chaque profil d'arrivee. */
.pool-cta-preview { display: flex; flex-wrap: wrap; align-items: center; gap: .15rem .55rem; margin: -.4rem 0 1rem;
    padding: .35rem .6rem; font-size: .8rem; border: 1px dashed var(--border); border-radius: 8px; background: rgba(127,127,127,.05); }
.pool-cta-preview a { color: var(--accent-ink); text-decoration: none; }
.pool-cta-preview a:hover { text-decoration: underline; }
.pool-cta-preview a.on { font-weight: 800; text-decoration: underline; }

/* ====================================================================
   ENCART D'APPEL A L'ACTION du pool (partial pool_cta) : repliable (replie par
   defaut), accroche "2 maillots a gagner" bien visible (bordure doree + fond
   chaud). Home (sous les scores live) + page concours (au-dessus de la carte).
   ==================================================================== */
.pool-cta-card { padding: 0; overflow: hidden; border: 2px solid #f5b301;
    background: linear-gradient(180deg, rgba(245,179,1,.13), rgba(245,179,1,.04)); }
.pool-cta-card.pool-cta-urgent { border-color: #ef4444; }
.pool-cta-head { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    padding: .8rem 1rem; background: none; border: 0; cursor: pointer; font-family: inherit; text-align: left; color: var(--text); }
.pool-cta-head:hover { background: rgba(245,179,1,.1); }
.pool-cta-head-main { display: flex; align-items: center; gap: .6rem; min-width: 0; }
.pool-cta-emoji { font-size: 1.6rem; line-height: 1; flex: 0 0 auto; }
.pool-cta-head-txt { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.pool-cta-title { font-weight: 800; font-size: 1.02rem; line-height: 1.2; }
.pool-cta-cd { font-size: .85rem; font-weight: 700; color: var(--muted); }
.pool-cta-cd .next-match-cd { color: #ef4444; font-weight: 800; }
.pool-cta-toggle-lbl { flex: 0 0 auto; display: inline-flex; align-items: center; gap: .3rem; font-weight: 700;
    font-size: .85rem; color: var(--accent-ink); white-space: nowrap; }
.pool-cta-caret { transition: transform .15s; }
.pool-cta-card[data-collapsed="0"] .pool-cta-caret { transform: rotate(180deg); }
.pool-cta-card[data-collapsed="1"] .pcl-less { display: none; }
.pool-cta-card[data-collapsed="0"] .pcl-more { display: none; }
.pool-cta-body { padding: 0 1rem 1rem; }
.pool-cta-lead { margin: 0 0 .6rem; font-weight: 600; }
/* Regle d'eligibilite (pool apres le coup d'envoi) : ligne explicative discrete sous l'accroche. */
.pool-cta-rule { margin: -.2rem 0 .7rem; font-size: .82rem; color: var(--muted); line-height: 1.35; }
.join-pool-eligible-note { margin: .2rem 0 .55rem; font-size: .9rem; font-weight: 600; color: #2ea043; }
/* Carte Mes concours : rappel "2 maillots a gagner" (lien vers le reglement). */
.dash-pool-prize { display: inline-block; margin: .3rem 0 .15rem; color: #d98b1f; font-weight: 700; text-decoration: none; }
a.dash-pool-prize:hover { text-decoration: underline; }
/* Concours special : bouton Confirmer ROUGE (attire l'oeil) + explication "inscrit d'office". */
.card-confirm-red { background: #e0414b; border-color: #e0414b; color: #fff; }
.card-confirm-red:hover { background: #c8323c; border-color: #c8323c; color: #fff; }
.dash-confirm-row .card-confirm-msg { display: flex; flex-direction: column; gap: .12rem; }
.card-confirm-explain { font-size: .78rem; color: var(--muted); font-weight: 400; line-height: 1.3; }
/* Live phase finale : ligne de detail "90' : 1-1 · Prolong. 0-0" / "1-1 a.p. · T.a.b. 4-3" sous le score. */
.pts-live-detail { margin-top: .25rem; font-size: .8rem; color: var(--muted); font-weight: 600; }
.live-now-detail { display: block; font-size: .78rem; color: var(--muted); font-weight: 600; margin-top: .1rem; }
.pool-cta-btns { display: flex; flex-wrap: wrap; gap: .5rem; }
.pool-cta-btn-blink { animation: pool-cta-pulse 1.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pool-cta-btn-blink { animation: none; } }
/* CTA de CROISSANCE (bannieres : rejoindre, inviter, jouer un concours) : halo pulse + envie de cliquer
   au survol. A poser sur tout bouton dont le clic fait GRANDIR ScoreMigos. Coupe si reduced-motion. */
/* Tips Tour : action explicite "ne plus afficher pendant la competition", distincte de la croix (snooze 6 h).
   Lien texte discret sous le tip : clair, jamais confondu avec une fermeture temporaire. */
.tp-tip-optout { display: block; margin: .25rem 0 0; background: none; border: none; padding: 0;
    color: var(--muted); font-size: .72rem; text-decoration: underline; cursor: pointer; opacity: .85; }
.tp-tip-optout:hover { color: var(--text); opacity: 1; }
.bn-cta-grow { animation: bn-cta-grow-pulse 1.5s ease-in-out infinite; transition: transform .15s ease, box-shadow .15s ease, filter .15s ease; will-change: transform; }
.bn-cta-grow:hover, .bn-cta-grow:focus-visible { transform: translateY(-1px) scale(1.05); animation-play-state: paused; box-shadow: 0 5px 16px rgba(31,138,76,.42); filter: brightness(1.06); }
.bn-cta-grow:active { transform: translateY(0) scale(.98); }
@keyframes bn-cta-grow-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(31,138,76,0); } 50% { box-shadow: 0 0 0 5px rgba(31,138,76,.30); } }
@media (prefers-reduced-motion: reduce) { .bn-cta-grow { animation: none; } }
.pool-cta-invite-inline { margin-top: .2rem; }
/* Etat 'confirm' de l'encart : bouton de confirmation MIS EN AVANT (pleine largeur, clignote) ; le retrait
   reste possible mais en lien DISCRET (jamais l'action principale du marketing). */
.pool-cta-confirm-form { margin: 0; }
.pool-cta-confirm-form .pool-cta-btn { width: 100%; box-sizing: border-box; text-align: center; font-size: 1.05rem; padding: .7rem 1rem; }
.pool-cta-leave-form { margin: .55rem 0 0; text-align: center; }
.pool-cta-leave-link { background: none; border: none; color: var(--muted); font: inherit; font-size: .82rem; text-decoration: underline; cursor: pointer; padding: .2rem; }
.pool-cta-leave-link:hover { color: var(--text); }

/* Pronos du tournoi : encart "Comment ça marche" (les 2 finalistes = equipes de la finale, champion = vainqueur). */
.futures-howto { border: 1px solid var(--accent-2); background: rgba(43,176,97,.07); border-radius: 8px;
    padding: .6rem .75rem; margin: .2rem 0 .9rem; }
.futures-howto-title { margin: 0 0 .3rem; font-weight: 800; }
.futures-field-hint { display: block; font-size: .82rem; color: var(--muted); margin: -.15rem 0 .35rem; }
.futures-finalists-group { border: 1px solid var(--border); border-radius: 8px; padding: .55rem .7rem .15rem;
    margin: 0 0 1rem; background: rgba(91,141,239,.05); }
.futures-finalists-head { margin: 0 0 .45rem; font-weight: 700; font-size: .92rem; color: var(--accent-ink); }

/* ===== Pool phase finale : harmonisation visuelle (palette accent verte, premium) + invitation ===== */
/* En-tete : aligne sur la palette accent. (pool-pred-intro / pool-confirm-card / keyframes definis plus haut.) */
.pool-header-info { border-color: var(--accent-2); background: rgba(43,176,97,.06); }
/* Apres le coup d'envoi : teinte ambre (la regle a change, pronos du tournoi verrouilles). */
.pool-header-info.pool-header-after { border-color: #f59e0b; background: rgba(245,158,11,.08); }
/* Banniere fenetre de GRACE 24h (pool) : ambre, mise en avant, bouton direct vers les pronos du tournoi. */
.pool-grace-banner { border-color: #f59e0b; background: rgba(245,158,11,.12); }
.pool-grace-msg { margin: 0 0 .5rem; font-weight: 700; }
/* Banniere INVITEUR (compte invite bloque) : transmettre le lien de reacces. Champ lien + copier. */
.relink-banner { position: relative; border-color: #f59e0b; background: rgba(245,158,11,.12); }
.relink-x { position: absolute; top: .35rem; right: .5rem; background: none; border: none; font-size: 1.5rem; line-height: 1; color: var(--muted); cursor: pointer; padding: .1rem .3rem; }
.relink-x:hover { color: var(--text); }
/* Banniere RECRUTEUR (pool) : recrues sans pronos du tournoi, a prevenir avant 19h (WhatsApp + lien de reacces). */
.recruiter-alert { border-color: #dc2626; background: rgba(220,38,38,.10); }
/* Annonce (pool phase finale) : maillot recruteurs quasi acquis + rappel deadline. Encart dore (trophee). */
.recruiter-announce { border-color: #f59e0b; background: rgba(245,158,11,.12); }
.recruiter-announce .ra-announce-title { margin: 0 0 .3rem; font-weight: 800; font-size: 1.05rem; }
.recruiter-announce .ra-announce-p { margin: .35rem 0 0; font-size: .95rem; line-height: 1.45; }
.recruiter-announce .ra-announce-deadline { margin-top: .55rem; font-weight: 600; }
.player-alert { border-color: var(--accent-2, #5b8def); background: rgba(91,141,239,.12); }
.ra-deadline { color: #b91c1c; }
.ra-list { list-style: none; margin: .5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.ra-item { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; background: rgba(127,127,127,.07); border-radius: 8px; padding: .35rem .55rem; }
.ra-name { font-weight: 700; }
.ra-noemail { display: inline-block; font-size: .72rem; font-weight: 600; color: #b91c1c; background: rgba(220,38,38,.12); border-radius: 999px; padding: .05rem .45rem; margin-left: .3rem; white-space: nowrap; }
.ra-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.ra-wa { background: #25d366; border-color: #25d366; color: #ffffff; font-weight: 700; }
.ra-wa:hover { filter: brightness(1.05); color: #ffffff; }
.relink-title { margin: 0 1.6rem .3rem 0; font-weight: 800; }
.relink-copy-row { display: flex; gap: .4rem; margin: .5rem 0 0; flex-wrap: wrap; }
.relink-url { flex: 1; min-width: 180px; font-size: .82rem; padding: .45rem .5rem; border: 1px solid var(--border); border-radius: 6px; background: var(--card-2); color: var(--text); }
/* Banniere de grace INLINE (onglet Pronos des autres) : message clignotant + "?" d'aide repliable. */
.pool-grace-inline { margin-bottom: .8rem; }
.pool-grace-help { margin-top: .5rem; }
.pool-grace-help summary::-webkit-details-marker { display: none; }
.pool-grace-help summary .cmeta-help { display: inline-flex; }
/* Classement RECRUTEUR expandable : ligne cliquable -> detail des invites (pronos tournoi / matchs / finale). */
.recruiter-row.recruiter-expandable { cursor: pointer; }
.recruiter-row.recruiter-expandable:hover { background: var(--card-2); }
.recruiter-caret { display: inline-block; margin-right: .3rem; transition: transform .15s; font-size: .7rem; color: var(--muted); }
.recruiter-row.rec-open .recruiter-caret { transform: rotate(90deg); }
.recruiter-detail > td { background: var(--card-2); padding: .5rem .7rem; }
.recruiter-invitees { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.recruiter-invitee { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; justify-content: space-between; }
.ri-name { font-weight: 600; }
.ri-badges { display: flex; flex-wrap: wrap; gap: .3rem; }
.ri-badge { font-size: .78rem; padding: .12rem .45rem; border-radius: 6px; white-space: nowrap; font-weight: 600; }
.ri-badge.ok { background: rgba(43,176,97,.18); color: var(--accent-ink); }
.ri-badge.no { background: rgba(120,120,120,.16); color: var(--muted); }

/* Compte a rebours du concours special : MEME design que la home (fond SOMBRE -> les .cd-box ressortent comme
   sur l'accueil, chiffres verts lisibles ; plus de clair-sur-clair). On reprend exactement le fond du hero. */
.pool-cd-card { text-align: center; color: #e8eef0; border-color: var(--border);
    background: radial-gradient(130% 120% at 50% -10%, rgba(31,138,76,.30), transparent 62%), #11151b; }
.pool-cd-label { font-weight: 700; color: var(--accent-ink); text-transform: uppercase; letter-spacing: .08em; font-size: .82rem; }
.pool-cd-card .hero-cd-boxes { justify-content: center; margin-top: .55rem; }
.pool-cd-card .pool-countdown-urgency, .pool-cd-card p { color: #cfd6e0; }
/* Bouton d'accueil dynamique vers le concours special : clignotement DOUX, seulement quand une action est attendue. */
.pool-hero-btn-blink { animation: hero-blink 1.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pool-hero-btn-blink { animation: none; } }

/* Bloc d'invitation dedie au pool (lien ?from -> attribution recruteur). */
.pool-invite { border-color: var(--accent-2); background: rgba(43,176,97,.06); }
.pool-invite-title { margin: 0 0 .2rem; font-weight: 800; }
.pool-invite-actions { margin: 0 0 .55rem; }
.pool-invite-wa { display: inline-flex; align-items: center; background: #25d366; color: #04130a !important;
    font-weight: 800; border: none; }
.pool-invite-wa:hover { background: #1ebe5a; text-decoration: none; }
.pool-confirm-links a { font-weight: 700; white-space: nowrap; }

/* Emplacement "photos des maillots bientot" : encadre pointille, aucune fausse image. */
.pool-maillot-soon { border: 1px dashed var(--accent-2); background: rgba(43,176,97,.04);
    text-align: center; font-weight: 600; color: var(--muted); padding: .7rem .8rem; }

/* Pilule de confirmation a clignoter sur le dashboard (carte du pool). */
.dash-pool-confirm { display: inline-flex; align-items: center; gap: .4rem; margin: .1rem 0 .5rem;
    padding: .3rem .7rem; border-radius: 999px; background: #eb5757; color: #fff; font-weight: 800;
    font-size: .82rem; text-decoration: none; animation: pool-confirm-pulse 1.5s ease-in-out infinite; }
.dash-pool-confirm:hover { color: #fff; text-decoration: none; filter: brightness(1.05); }
.dash-pool-confirm .pool-confirm-dot { width: .5rem; height: .5rem; border-radius: 50%; background: #fff; }
@media (prefers-reduced-motion: reduce) { .dash-pool-confirm { animation: none; } }

/* Note des dates limites du concours special (confirmation jusqu'au 5/07, pronos du tournoi figes le 28/06 21h). */
.pool-deadlines { margin: .6rem 0 0; padding: .5rem .7rem; border-radius: 8px; background: rgba(245,158,11,.10);
    border: 1px solid rgba(245,158,11,.35); color: var(--text); font-weight: 600; line-height: 1.45; }
/* Dashboard : CTA "rejoindre le concours special" (non-membres) + pilule "completer ses pronos du tournoi". */
.dash-pool-join { border-color: var(--accent-2); background: rgba(43,176,97,.07); display: flex; align-items: center;
    gap: .8rem; flex-wrap: wrap; justify-content: space-between; }
.dash-pool-join .btn { flex: 0 0 auto; }
.dash-pool-futures { display: inline-flex; align-items: center; gap: .4rem; margin: .1rem 0 .5rem; padding: .3rem .7rem;
    border-radius: 999px; background: #f59e0b; color: #1a1205; font-weight: 800; font-size: .82rem; text-decoration: none;
    animation: pool-confirm-pulse 1.5s ease-in-out infinite; }
.dash-pool-futures:hover { color: #1a1205; text-decoration: none; filter: brightness(1.05); }
@media (prefers-reduced-motion: reduce) { .dash-pool-futures { animation: none; } }

/* Page d invitation : lot du concours special mis en avant. */
.join-pool-prize { margin: .2rem 0 .6rem; padding: .55rem .7rem; border-radius: 8px; text-align: center;
    background: rgba(43,176,97,.10); border: 1px solid var(--accent-2); color: var(--text); }

/* ===== Rappel global "prends ta decision" + CTA "Commence ici" + bouton home plus visible ===== */
/* Barre fine clignotante (toutes pages) pour les indecis : membre non confirme ou connecte non-membre. */
.pool-decide-banner { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem .6rem; max-width: 1100px; margin: .6rem auto 0;
    padding: .55rem .8rem; border-radius: 12px; background: linear-gradient(90deg, #e8f7ee, #f9fdf4);
    border: 1px solid #2bb061; border-left: 4px solid #1f8a4c;
    color: #15331f; font-weight: 700; font-size: .9rem; text-decoration: none; overflow: hidden; max-width: 100%;
    animation: pool-decide-pulse 1.6s ease-in-out infinite; }
.pool-decide-sport { font-size: 1.15rem; line-height: 1; flex: 0 0 auto; }
.pool-decide-eyebrow { color: #1f8a4c; margin-right: .25rem; }
.pool-decide-go { flex: 0 0 auto; background: #1f8a4c; color: #fff; font-weight: 800; border-radius: 999px;
    padding: .3rem .8rem; white-space: nowrap; font-size: .84rem; }
@media (max-width: 520px) { .pool-decide-go { flex: 1 1 100%; text-align: center; } }
.pool-decide-banner:hover { text-decoration: none; filter: brightness(1.03); }
.pool-decide-dot { width: .6rem; height: .6rem; border-radius: 50%; background: #1f8a4c; flex: 0 0 auto;
    animation: pool-decide-dot 1.1s ease-in-out infinite; }
.pool-decide-txt { flex: 1 1 auto; }
.pool-decide-x { flex: 0 0 auto; background: transparent; border: none; color: var(--muted); font-size: 1.2rem;
    line-height: 1; cursor: pointer; padding: 0 .2rem; }
@keyframes pool-decide-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); } 50% { box-shadow: 0 0 0 3px rgba(43,176,97,.22); } }
@keyframes pool-decide-dot { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(1.3); } }
@media (prefers-reduced-motion: reduce) { .pool-decide-banner, .pool-decide-dot { animation: none; } }
@media (max-width: 640px) { .pool-decide-banner { margin: .5rem .6rem 0; font-size: .84rem; } }

/* CTA "Commence ici" en tete de la page concours : 2 boutons courts (pronos tournoi / matchs). */
.pool-start-cta { border-color: var(--accent-2); background: rgba(43,176,97,.06); }
.pool-start-cta-title { margin: 0 0 .5rem; font-weight: 800; }
.pool-start-cta-btns { display: flex; gap: .5rem; flex-wrap: wrap; }
.pool-start-cta-btns .btn { flex: 1 1 auto; text-align: center; white-space: nowrap; }

/* Req 3 : bouton d'accueil sous le compte a rebours -> cadre accent clair, contraste sur fond sombre, glow percu. */
.pool-hero-btn { border-color: var(--accent-2) !important; background: rgba(43,176,97,.16); color: #eafff3 !important;
    box-shadow: 0 0 0 1px rgba(43,176,97,.45); }
.pool-hero-btn:hover { background: rgba(43,176,97,.30); border-color: #6ee7a8 !important; color: #fff !important; }
.pool-hero-btn-blink { animation: pool-hero-glow 1.5s ease-in-out infinite; }
@keyframes pool-hero-glow {
    0%,100% { box-shadow: 0 0 0 1px rgba(43,176,97,.5), 0 0 0 0 rgba(43,176,97,0); border-color: var(--accent-2); }
    50%     { box-shadow: 0 0 0 1px rgba(43,176,97,.8), 0 0 18px 3px rgba(43,176,97,.55); border-color: #6ee7a8; }
}
@media (prefers-reduced-motion: reduce) { .pool-hero-btn-blink { animation: none; } }

/* ===== Acquisition pool (page d'invitation) : inscription EN PREMIER + apercu super-admin ===== */
.join-pool-acq { margin-bottom: .6rem; }
.join-pool-acq-title { margin: 0 0 .4rem; font-size: 1.3rem; text-align: center; line-height: 1.2; }
.join-pool-acq-sub { margin: .2rem 0 .7rem; text-align: center; color: var(--muted); font-size: .92rem; }
.join-acq-form { border: 1px solid var(--accent-2); border-radius: 10px; padding: .85rem; background: rgba(43,176,97,.07); }
.join-acq-form .field { margin: 0 0 .5rem; }
.sa-aqview-panel { max-width: 520px; margin: .4rem auto 0; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
    padding: .4rem .6rem; border: 1px dashed var(--accent-2); border-radius: 8px; background: rgba(91,141,239,.06); font-size: .82rem; }
.sa-aqview-lbl { font-weight: 800; color: var(--accent-ink); }
.sa-aqview-panel a { padding: .15rem .55rem; border-radius: 999px; border: 1px solid var(--border); white-space: nowrap; }
.sa-aqview-panel a.on { background: var(--accent-2); color: var(--on-accent); border-color: var(--accent-2); }
.sa-preview-banner { max-width: 520px; margin: .3rem auto 0; padding: .35rem .6rem; border-radius: 8px;
    background: rgba(245,158,11,.14); border: 1px solid rgba(245,158,11,.4); font-weight: 700; font-size: .85rem; text-align: center; }

/* ===== Bloc haut du pool (lot + statut + membres) + clignotement des CTA pronos ===== */
.pool-top { border-color: var(--accent-2); background: rgba(43,176,97,.07); }
.pool-top-prize { margin: 0 0 .3rem; font-weight: 800; font-size: 1.05rem; }
.pool-top-invite { margin: 0 0 .55rem; font-weight: 600; }
.pool-top-status { margin: .2rem 0 .6rem; font-size: .92rem; line-height: 1.5; }
.pool-top-ok { color: var(--accent-ink); font-weight: 700; }
.pool-top-no { color: #eb5757; font-weight: 700; }
.pool-top-sep { color: var(--muted); }
/* Bouton "Inviter dans ce concours" : vert standard (comme les autres), centre, clignotement doux (pool-cta-blink). */
.pool-top-invite-wrap { text-align: center; margin-top: .55rem; }
.pool-top-cd { margin: 0 0 .4rem; font-size: .85rem; font-weight: 600; color: var(--ink); }
.pool-top-cd .next-match-cd { color: #ef4444; font-weight: 800; }
/* Maillot "a gagner" qui pulse doucement (lueur verte) pour attirer l'oeil sans agresser. */
.pool-prize-blink strong { animation: pool-prize-glow 1.7s ease-in-out infinite; }
@keyframes pool-prize-glow { 0%,100% { text-shadow: 0 0 0 rgba(43,176,97,0); } 50% { text-shadow: 0 0 13px rgba(43,176,97,.6); } }
@media (prefers-reduced-motion: reduce) { .pool-prize-blink strong { animation: none; } }
/* Compteur de confirmes qui PULSE (preuve sociale + incite a confirmer). */
.pool-top-confirmed { color: var(--accent-ink); font-weight: 800; animation: pool-confirmed-pulse 1.6s ease-in-out infinite; }
@keyframes pool-confirmed-pulse { 0%,100% { text-shadow: 0 0 0 rgba(43,176,97,0); } 50% { text-shadow: 0 0 11px rgba(43,176,97,.65); } }
@media (prefers-reduced-motion: reduce) { .pool-top-confirmed { animation: none; } }
/* Invitation FUSIONNEE en tete (un seul bloc) : lead + WhatsApp (large) + Messenger + lien copiable + Facebook + partage natif. */
.pool-inv-lead { margin: .2rem 0 .35rem; font-weight: 700; }
.pool-inv-tools { display: flex; flex-direction: column; gap: .5rem; }
/* Deux canaux de MEME TAILLE cote a cote (WhatsApp vert, Facebook bleu) -> cohErent et lisible. */
.pool-inv-channels { display: flex; gap: .5rem; }
.pool-inv-ch { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; padding: .65rem .5rem;
    border-radius: 10px; font-weight: 800; font-size: .95rem; text-decoration: none; min-width: 0; white-space: nowrap; }
.pool-inv-ch:hover { text-decoration: none; filter: brightness(1.06); }
.pool-inv-wa { background: #25d366; color: #04130a !important; }
.pool-inv-fb { background: #1877f2; color: #fff !important; }
@media (max-width: 360px) { .pool-inv-ch { font-size: .82rem; padding: .6rem .3rem; } }
/* Bouton "Retour au concours" en tete des pages atteintes depuis un bouton de la carte. */
.pool-back-link { display: inline-flex; align-items: center; gap: .3rem; margin: 0 0 .8rem; padding: .4rem .8rem;
    border: 1px solid var(--border); border-radius: 999px; background: var(--card-2); color: var(--accent-ink);
    font-weight: 700; font-size: .9rem; text-decoration: none; }
.pool-back-link:hover { border-color: var(--accent-ink); text-decoration: none; }
/* Zone de contenu : hauteur mini pour qu'une page courte puisse quand meme scroller le bouton RETOUR (#comm-go) tout en haut. */
.contest-content-zone { min-height: calc(100vh - 150px); }

/* LES AUTRES : groupe REPLIABLE + theme TURQUOISE (distinct du vert de PRONOS) -> on voit la difference. */
/* LES AUTRES : encart DEPLOYE (comme PRONOS), theme TURQUOISE (distinct du vert de PRONOS). */
.tab-group-autres { border-color: #0fb5ae; background: rgba(15,181,174,.07); border-style: dashed; }
.tab-group-autres .tab-group-label { color: #0a8f89; }
.tab-group-autres a:not(.active) { border-color: rgba(15,181,174,.35); }
.tab-group-autres a.active { background: #0fb5ae; border-color: #0fb5ae; color: #04130a; }

/* Favori = juste une petite ETOILE sous le badge Membre/Admin (jaune si favori), plus de cellule "Concours favori". */
/* Favori = juste une ETOILE (tooltip "Concours favori" au survol), placee EN DESSOUS du badge Membre/Admin, dans le
   coin HAUT-DROITE de la carte (le badge y est deja en absolute). Stack vertical badge -> etoile, ZERO espace pris
   dans le flux (donc jamais en plein milieu du titre). Meme rendu PC/tablette/mobile. */
/* ====================================================================
   EN-TETE CARTE : "Concours" (eyebrow) a GAUCHE + badge Membre/Admin et etoile
   favori a DROITE, sur la MEME ligne, AU-DESSUS du titre. Annule les regles
   historiques .contest-head-actions (ancienne barre Favori+Inviter : position
   absolute / width:100% / border-top / colonne) qui dessinaient un trait pleine
   largeur en travers du titre et collaient le badge dans un titre long.
   ==================================================================== */
.contest-eyebrow-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: nowrap; }
.contest-eyebrow-row .contest-eyebrow { margin: 0; min-width: 0; }
.contest-head .contest-head-actions {
    position: static; width: auto; margin: 0; padding: 0; border-top: 0; z-index: auto;
    flex: 0 0 auto; display: inline-flex; flex-direction: row; flex-wrap: nowrap; align-items: center; gap: .4rem;
    pointer-events: auto;
}
.contest-head .contest-head-actions .badge { position: static; z-index: auto; }
/* L'etoile favori reste compacte (annule le flex:1 1 9rem de l'ancienne barre Favori+Inviter). */
.contest-head .contest-head-actions form.inline { flex: 0 0 auto; margin: 0; display: inline-flex; }
/* Un peu d'air sous le titre (le trait parasite a disparu, on garde une marge propre). */
.contest-card-merged .contest-title-row { margin-bottom: .15rem; }
.fav-star-form { margin: 0; line-height: 0; }
.fav-star-btn { background: none; border: none; cursor: pointer; padding: .15rem; color: var(--muted); line-height: 0; }
.fav-star-btn:hover { color: #f2c94c; }
.fav-star-btn.on { color: #f2c94c; }
.fav-star-label { display: none; } /* juste l'etoile + le tooltip (attribut title) partout */

/* Bouton "Points" deplace dans les pages Matches + Pronos du tournoi (retire de l'encart pour ne pas casser la ligne sur mobile). */
.points-info-inline { background: var(--card-2); border: 1px solid var(--border); border-radius: 999px; padding: .25rem .6rem;
    font-size: .85rem; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: .25rem; white-space: nowrap; }
.points-info-inline:hover { border-color: var(--accent-ink); color: var(--text); }
.ft-head-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; margin-bottom: .3rem; }

/* MOBILE : quand les boutons d'un groupe passent a la ligne, on les CENTRE (sinon c'est moche, colle a gauche).
   LES AUTRES : "Pronos des autres" seul sur la 1ere ligne (centre), "Courbes" + "Grille" sur la 2e (centres). */
@media (max-width: 640px) {
    .tab-group { justify-content: center; width: 100%; }
    .tab-group-autres a:first-of-type { flex-basis: 100%; justify-content: center; }
}

/* REFONTE carte concours : les onglets (Pronos / Les autres) prolongent VISUELLEMENT la carte (un seul cadre).
   La carte perd sa marge + son arrondi du bas (sa bordure basse sert de separateur), les onglets se collent
   dessous avec les memes bordures laterales et un arrondi en bas. Ne s'applique QUE si les onglets suivent
   immediatement la carte (cas pool ou concours sans banniere d'enjeu intercalee). */
/* Bouton header "Communication generale" : meme rond que l'etoile, affiche la LETTRE du canal non-lu (IG/N/D)
   et CLIGNOTE. N'apparait que s'il y a du non-lu. Mene a /infos sur le bon onglet. */
.hdr-comm-btn { position: relative; font-weight: 800; font-size: 1.05rem; letter-spacing: .02em; color: var(--accent-ink); }
.hdr-comm-btn.ccn-blink { animation: pool-cta-pulse 1.4s ease-in-out infinite; }
/* La lettre du canal non-lu (i/N/D) en PASTILLE de coin sur le rond (ne deforme pas le chip 38x38). */
.hdr-comm-btn .ccn-letter { position: absolute; top: -5px; right: -5px; }
@media (prefers-reduced-motion: reduce) { .hdr-comm-btn.ccn-blink { animation: none; } }
/* Page /infos : vrais ONGLETS (barre a soulignement), pas des boutons separes. */
.infos-tabs { display: flex; gap: .2rem; margin: .3rem 0 1rem; border-bottom: 2px solid var(--border); flex-wrap: nowrap; }
.infos-tab { flex: 1 1 0; min-width: 0; text-align: center; padding: .5rem .5rem; border: none; border-bottom: 2px solid transparent; margin-bottom: -2px; border-radius: 6px 6px 0 0;
    color: var(--muted); background: none; font-weight: 700; font-size: .92rem; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.infos-tab:hover { color: var(--text); text-decoration: none; background: var(--card-2); }
.infos-tab.active { color: var(--accent-ink); border-bottom-color: var(--accent); }

.contest-card-merged:has(+ .tabs) { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.contest-card-merged + .tabs {
    margin-top: 0; margin-bottom: 1rem;
    background: var(--card);
    border: 1px solid var(--border); border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    padding: .85rem 1.1rem 1rem;
}
/* Rangee des boutons utilitaires (Compte rendu/Classement/Chat/Info/Vote), re-affichee APRES l'encart PRONOS,
   separee par un filet -> PRONOS reste la 1ere chose visible, les utilitaires suivent. */
.card-comm-row { width: 100%; padding-top: .7rem; margin-top: .25rem; border-top: 1px solid var(--border); }
.card-comm-row .card-primary-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .45rem; margin: 0; }
.pool-top-invite-btn { display: inline-flex; align-items: center; gap: .35rem; font-weight: 800; }
.pool-top-admin-note { color: var(--muted); font-size: .85rem; font-style: italic; }
/* Boutons "Commence ici" : clignotement doux (rouge) quand le prono correspondant est INCOMPLET (urgent). */
.pool-cta-btn { font-weight: 700; }
.pool-cta-blink { animation: pool-cta-pulse 1.4s ease-in-out infinite; }
@keyframes pool-cta-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(235,87,87,0); } 50% { box-shadow: 0 0 0 4px rgba(235,87,87,.30); } }
@media (prefers-reduced-motion: reduce) { .pool-cta-blink { animation: none; } }
/* Carte concours special "pas encore vu" (dashboard) : bordure verte pulsante pour attirer les non-visiteurs. */
.contest-card-new { border-color: var(--accent-ink, #2bb061); animation: contest-new-pulse 1.7s ease-in-out infinite; }
@keyframes contest-new-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); } 50% { box-shadow: 0 0 0 5px rgba(43,176,97,.26); } }
@media (prefers-reduced-motion: reduce) { .contest-card-new { animation: none; } }

/* Ligne de CONFIRMATION dans la carte concours (pool, membre pas encore confirme) : rappel 2 maillots + boutons
   Confirmer / Me retirer, le message et le bouton vert clignotant doucement (.pool-cta-blink). */
.card-confirm-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem .7rem;
    margin-top: .7rem; padding: .55rem .7rem; border: 1px solid #f5b301; border-radius: 8px;
    background: linear-gradient(180deg, rgba(245,179,1,.15), rgba(245,179,1,.05)); }
.card-confirm-msg { font-weight: 800; font-size: .92rem; color: #92500a; }
html:not([data-theme="light"]) .card-confirm-msg { color: #fcd34d; } /* 13/07 : ambre clair lisible sur le bandeau sombre */
.card-confirm-btns { display: inline-flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.card-confirm-btns form { margin: 0; }
.card-confirm-yes { background: #16a34a; border-color: #16a34a; color: #fff; }
.card-confirm-yes:hover { background: #15803d; border-color: #15803d; color: #fff; }
/* Apercu super-admin (vue 'membre') de la ligne de confirmation : tag discret + liisere pointille, boutons inertes. */
.card-confirm-tag { font-weight: 600; font-size: .78rem; opacity: .65; }
.card-confirm-preview { outline: 1px dashed rgba(146,80,10,.45); outline-offset: 1px; }
/* Reglement aere (#pool-rules) : sous-titres de section + points espaces (rendu par le parser "## "). */
.pool-rules-body { margin-top: .5rem; }
.pool-rule-h { font-weight: 800; color: var(--text); font-size: .92rem; margin: .9rem 0 .2rem; }
.pool-rule-h:first-child { margin-top: 0; }
.pool-rule-p { margin: 0 0 .5rem; line-height: 1.5; }

/* Note depliable "?" sous le classement des recruteurs (tappable mobile, precise que le compteur ne fait pas foi). */
.recruiters-q { margin: -.2rem 0 .6rem; }
.recruiters-q > summary { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; font-size: .85rem; color: var(--accent-ink); font-weight: 600; list-style: none; }
.recruiters-q > summary::-webkit-details-marker { display: none; }
.recruiters-q > summary::before { content: "?"; display: inline-grid; place-items: center; width: 1.15rem; height: 1.15rem; border-radius: 50%; background: var(--accent-2); color: #04130a; font-weight: 800; font-size: .78rem; }
.recruiters-q[open] > summary { margin-bottom: .35rem; }
.recruiters-q > p { margin: 0; }

/* Renvoi croise entre onglets pronos (tournoi <-> matchs) dans le concours phase finale. */
.pool-cross { border-color: var(--accent-2); background: rgba(91,141,239,.07); text-align: center; }
.pool-cross-note { margin: 0 0 .55rem; font-size: .92rem; color: var(--ink); }

/* ============================================================================
   THEME TOUR DE FRANCE (cyclisme). Ne cree PAS de nouveau design : reutilise les
   composants existants (.card, .tabs, .btn, .muted) et surcharge seulement l'accent
   en JAUNE/NOIR sur un wrapper .theme-tour. Le cyclisme herite donc du design foot.
   ============================================================================ */
/* Les COULEURS d'accent du cyclisme viennent DESORMAIS de html[data-comp] (theming PAR COMPETITION :
   Tour=jaune identique a avant, Vuelta=rouge, CL=bleu) et non plus d'un jaune fige sur .theme-tour.
   .theme-tour ne conserve que les regles STRUCTURELLES ci-dessous, communes a tout le velo. */
/* Sur un fond d'accent vif, le texte blanc manque de contraste -> encre sombre (lisibilite). */
/* Texte sur fond --accent : lisible selon la teinte (noir sur jaune Tour, blanc sur rouge/bleu). Les
   boutons PLEINS uniquement (:not(.btn-ghost)) : les ghost (fond transparent) gardent var(--text). */
/* 22/07 : les 3 rustines .theme-tour d'ici sont supprimees. Elles ne couvraient que les pages velo,
   laissant /aide, Mes concours, le foot et la CL en blanc sur jaune. Les lignes 625 et 687 portent
   desormais var(--on-accent) et couvrent tout le site. */
.theme-tour select, .theme-tour input[type="text"]:not(.scorer-input) {
    width: 100%; max-width: 420px; padding: .55rem .6rem; background: var(--card-2);
    color: var(--text); border: 1px solid var(--border); border-radius: 8px; font-size: 1rem;
}
.tour-head { border-left: 4px solid var(--accent-2); }
.tour-maplink { color: var(--accent-ink); font-weight: 600; font-size: .9rem; }
.rider-locked { display: flex; align-items: center; gap: .4rem; padding: .5rem 0; color: var(--text); font-weight: 600; }
.rider-locked .flag { flex: 0 0 auto; }
.rp-team { color: var(--muted); font-weight: 500; }
.rp-fav { font-size: .85em; }
/* Frise HORIZONTALE des etapes (redesign 02/07 : remplace l'accordeon vertical -> moins de scroll, style frise foot). */
.tour-strip { display: flex; flex-wrap: nowrap; gap: .4rem; overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding: .15rem .1rem .5rem; margin: 0 0 .1rem; scrollbar-width: thin;
    scroll-snap-type: x proximity; scroll-padding-left: .1rem; } /* accroche les cartes par leur bord gauche (pas de demi-carte) */
.tour-pill { scroll-snap-align: start; }
/* Spacer de fin : réserve une largeur scrollable pour que N'IMPORTE QUELLE étape (même les dernières) puisse
   s'ancrer TOUT À GAUCHE, avec du blanc à droite quand il reste peu d'étapes -> lecture directe du "reste à jouer". */
.tour-strip::after { content: ''; flex: 0 0 calc(100% - 4rem); pointer-events: none; }
.tour-pill { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: .05rem;
    min-width: 4.1rem; padding: .35rem .5rem; border: 1px solid var(--border); border-radius: 10px;
    background: var(--card-2); color: var(--text); text-decoration: none; line-height: 1.15; text-align: center; }
/* ETAPE ANNULEE : elle doit se lire d'un coup d'oeil comme DIFFERENTE d'une etape courue. Contour
   discontinu (rien ne s'y est joue) + jour barre, sans rouge criard : ce n'est pas une alerte, c'est
   un fait. Le pictogramme remplace l'heure de depart dans le markup. */
.tour-pill-void { border-style: dashed !important; opacity: .82; }
.tour-pill-void .tp-day { text-decoration: line-through; text-decoration-thickness: 1px; }
.tour-pill .tp-day { font-weight: 700; font-size: .82rem; white-space: nowrap; }
.tour-pill .tp-time { color: var(--muted); font-size: .68rem; white-space: nowrap; margin-top: -.05rem; }
.tour-pill.active .tp-time { color: var(--on-accent); opacity: .72; }
.tour-pill .tp-no { color: var(--muted); font-size: .72rem; }
.tour-pill.past { opacity: .55; }
.tour-pill.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); opacity: 1; }
.tour-pill.active .tp-no { color: var(--on-accent); opacity: .72; }
/* "Aujourd'hui" : lisere rouge en bas de la pill (rappel de la ligne rouge "on est ici" du foot). */
.tour-pill.today { border-color: #e0322f; box-shadow: inset 0 -3px 0 0 #e0322f; opacity: 1; }
.tour-pill .tp-ok { color: #1f8a4c; }
.tour-pill.active .tp-ok { color: #0b6b34; }
.tour-stage-panel { border-top: 1px solid var(--border); padding-top: .55rem; margin-top: .1rem; }
.tour-stage-head { font-weight: 800; font-size: 1.02rem; margin: 0 0 .1rem; }
.tour-stage-head .no { color: var(--muted); margin-right: .2rem; }
.tour-stage-head .tsh-type { font-weight: 600; margin-left: .3rem; }
/* Ligne HEURE DE DÉPART + compte à rebours + état de complétude (sous le titre de l'étape). Responsive : wrap. */
.tour-stage-when { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .7rem; margin: .1rem 0 .55rem; font-size: .9rem; }
.tour-stage-when .tsw-start { font-weight: 700; white-space: nowrap; }
.tour-stage-when .tsw-cd { background: var(--card-2); border-radius: 999px; padding: .1rem .55rem; font-weight: 700; font-size: .8rem; white-space: nowrap; }
.tour-stage-when .tsw-cd.countdown-locked { color: var(--muted); }
.tour-stage-when .tsw-ok { color: #1f8a4c; font-weight: 800; font-size: .84rem; white-space: nowrap; }
.tour-stage-when .tsw-warn { background: rgba(255,171,77,.18); color: #b45309; border-radius: 999px; padding: .1rem .6rem;
    font-weight: 700; font-size: .82rem; animation: tour-nudge-blink 1.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .tour-stage-when .tsw-warn { animation: none; } }
/* Étapes en accordéon (<details>) : cliquer déplie INLINE, aucune navigation -> jamais de saut d'ancrage. */
/* overflow VISIBLE (pas hidden) : sinon le menu deroulant "Choisir un coureur" (.scorer-pop, position absolute)
   etait clippe par l'accordeon et ne pouvait pas passer par-dessus les etapes suivantes. Le fond de summary
   (rgba 6%) qui deborde des coins arrondis est imperceptible. */
.tour-acc { border: 1px solid var(--border); border-radius: 9px; margin-bottom: .4rem; overflow: visible; }
.tour-acc[open] { border-color: var(--accent-2); }
.tour-acc > summary { list-style: none; cursor: pointer; padding: .6rem .7rem; display: flex;
    justify-content: space-between; gap: .6rem; align-items: baseline; }
.tour-acc > summary::-webkit-details-marker { display: none; }
.tour-acc > summary:hover { color: var(--accent-ink); }
.tour-acc[open] > summary { background: rgba(255,212,0,.06); }
.tour-acc-body { padding: .45rem .7rem .8rem; border-top: 1px solid var(--border); }
.tour-acc .no { font-weight: 800; color: var(--muted); min-width: 2em; display: inline-block; }
.tour-bet { margin: .9rem 0; }
.tour-bet .q { display: block; font-weight: 700; margin-bottom: .35rem; }
.tour-bet .pts { color: #1a1a1a; font-weight: 800; font-size: .82rem; margin-left: .3rem; }
.tour-radio { display: inline-flex; align-items: center; gap: .3rem; margin: .2rem .85rem .2rem 0; }
/* Pronos VERROUILLÉS (retour Jonathan 18/07) : le choix coché doit rester bien lisible. Éditable =
   accent VERT (invite au clic) ; verrouillé coché = encre NEUTRE pleine opacité (visible, pas invitant)
   + libellé en gras ; les options non retenues restent pâles. */
.tour-radio input[type="radio"] { accent-color: var(--accent); }
.tour-radio input[type="radio"]:disabled { opacity: .35; }
.tour-radio input[type="radio"]:disabled:checked { opacity: 1; accent-color: var(--text); }
html[data-theme="light"] .tour-radio input[type="radio"]:disabled:checked { accent-color: #1a1a2e; }
.tour-radio:has(> input[type="radio"]:disabled:checked) { font-weight: 800; }
.tour-radio:has(> input[type="radio"]:disabled:not(:checked)) { color: var(--muted); }
/* Pari "nationalité du vainqueur" : chips drapeau groupés par palier de points (favoris/solides/outsiders). */
.tour-nat { display: flex; flex-direction: column; gap: .5rem; }
.tour-nat-grp { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }
.tour-nat-lbl { font-size: .82rem; font-weight: 700; color: var(--muted); flex: 0 0 5.5rem; }
.tour-nat-lbl .pts { color: #1a1a1a; font-weight: 800; }
.tour-nat-chips { display: inline-flex; flex-wrap: wrap; gap: .35rem; }
.tour-nat-chip { display: inline-flex; align-items: center; padding: .25rem .4rem; border: 2px solid var(--border); border-radius: 9px; cursor: pointer; background: var(--card-2); line-height: 0; }
.tour-nat-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.tour-nat-chip img { width: 1.6rem; height: auto; display: block; border-radius: 2px; }
.tour-nat-chip.on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-2); }
.tour-jerseys { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; align-items: stretch; }
@media (max-width: 520px) { .tour-jerseys { grid-template-columns: 1fr; } }
/* Aligner les listes deroulantes d'une meme rangee (ex. Maillot Jaune 3 lignes de description vs Maillot Vert
   1 ligne) : la cellule est une colonne flex, la DESCRIPTION grandit -> pousse le picker tout en bas. Comme la
   grille etire les cellules d'une rangee a la meme hauteur, les pickers se retrouvent au meme niveau vertical. */
.tour-jerseys > .tour-bet { display: flex; flex-direction: column; margin: 0; }
.tour-jerseys > .tour-bet > p { flex: 1 1 auto; }
/* Rappel clignotant ROUGE au-dessus des onglets : "maillots a remplir avant le 4 juillet" (fleche vers l'onglet). */
.tour-maillots-nudge { display: flex; align-items: center; gap: .5rem; margin: 0 0 .55rem; padding: .5rem .8rem;
    background: linear-gradient(90deg, #fff3bf, #fffbe8); border: 1.5px solid #e5c100; border-radius: 10px; color: #4a3c00;
    font-weight: 700; text-decoration: none; animation: tour-nudge-blink 1.15s ease-in-out infinite; }
.tour-maillots-nudge:hover { background: #ffefaa; color: #4a3c00; }
.tour-maillots-nudge .tmn-arrow { font-size: 1.15rem; line-height: 1; color: #b58900; }
@keyframes tour-nudge-blink { 0%,100% { border-color: #e5c100; box-shadow: 0 0 0 0 rgba(229,193,0,0); }
    50% { border-color: #f5c518; box-shadow: 0 0 0 3px rgba(245,197,24,.3); } }
@media (prefers-reduced-motion: reduce) { .tour-maillots-nudge { animation: none; } }

/* ===== BANNIÈRES INTELLIGENTES Tour (étape à compléter + maillots à remplir), au-dessus des onglets =====
   Compactes, lisibles, sans overflow ; sur mobile le bouton passe pleine largeur sous le texte. */
.tour-banners { display: flex; flex-direction: column; gap: .45rem; margin: .2rem 0 .55rem; }
.tour-banner { display: flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--text);
    padding: .6rem .75rem; border-radius: 12px; border: 1px solid var(--border); line-height: 1.35; box-sizing: border-box; }
.tour-banner .tb-ico { font-size: 1.2rem; flex: 0 0 auto; }
.tour-banner .tb-txt { flex: 1 1 auto; font-size: .92rem; min-width: 0; overflow-wrap: anywhere; }
.tour-banner .tb-txt strong { font-weight: 800; }
.tour-banner .tb-sub { display: block; font-size: .82rem; color: var(--muted); margin-top: .1rem; }
.tour-banner .tb-soon { color: #e0322f; font-weight: 800; }
.tour-banner .tb-btn { flex: 0 0 auto; background: #1f8a4c; color: #fff; font-weight: 800; font-size: .86rem;
    border-radius: 9px; padding: .5rem .9rem; white-space: nowrap; }
.tour-banner-stage    { background: linear-gradient(180deg, rgba(255,171,77,.18), rgba(255,171,77,.10)); border-color: rgba(224,127,0,.55); }
.tour-banner-maillots { background: linear-gradient(180deg, rgba(245,197,24,.16), rgba(245,197,24,.08)); border-color: rgba(224,168,0,.55); }
.tour-banner-flash { animation: tour-nudge-blink 1.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .tour-banner-flash { animation: none; } }
@media (max-width: 480px) {
  .tour-banner { flex-wrap: wrap; }
  .tour-banner .tb-ico { order: 1; }
  .tour-banner .tb-txt { order: 2; flex: 1 1 100%; }
  .tour-banner .tb-btn { order: 3; flex: 1 1 100%; text-align: center; margin-top: .35rem; }
}
/* Boutons d'invitation MODERNES (carte concours cyclisme) : pilules aux couleurs actuelles des marques,
   icône + libellé, même gabarit pour les quatre. Remplacent les aplats "cheap". */
.inv-btn { display: inline-flex; align-items: center; gap: .45rem; padding: .55rem 1.05rem; border-radius: 999px;
    font-weight: 800; font-size: .92rem; text-decoration: none; border: none; cursor: pointer; color: #fff;
    box-shadow: 0 1px 2px rgba(0,0,0,.18); transition: transform .12s ease, box-shadow .12s ease; line-height: 1.15; }
.inv-btn:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(0,0,0,.22); color: #fff; text-decoration: none; }
.inv-btn svg { width: 17px; height: 17px; flex: 0 0 auto; fill: currentColor; }
.inv-wa   { background: linear-gradient(135deg, #25d366, #128c7e); }
.inv-msgr { background: linear-gradient(135deg, #0498fa, #7a42fb 55%, #fa54a5); }
.inv-mail { background: linear-gradient(135deg, #334155, #111827); }
/* « Inviter autrement » : MEME rendu clair/sombre (Jonathan 31/07 : en clair le texte blanc
   flottait sur fond clair, illisible). Fond nuit fixe comme inv-mail, dans les DEUX themes. */
.inv-other { background: linear-gradient(135deg, #334155, #111827); }
.inv-copy { background: #fff; color: #10131a !important; border: 1.5px solid #d1d5db; }
.inv-copy:hover { color: #10131a !important; border-color: #9ca3af; }
/* Podium (étape / général) : 3 lignes rang + liste déroulante, alignées. */
.tour-podium { display: flex; flex-direction: column; gap: .35rem; }
.tour-pod-row { display: flex; align-items: center; gap: .5rem; }
.tour-pod-row select { flex: 1 1 auto; min-width: 0; }
.tour-pod-rank { flex: 0 0 2rem; display: inline-flex; align-items: center; justify-content: center; height: 1.5rem;
  border-radius: 999px; background: var(--accent); color: var(--accent-ink); font-weight: 800; font-size: .78rem; }
.theme-tour .tour-pod-rank { color: var(--on-accent); }
/* Carte INTERACTIVE du parcours (Mapbox GL JS) : départ vert -> arrivée rouge, zoomable/déplaçable. */
.tour-map { height: 280px; margin: .2rem 0 .1rem; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); background: #eef0f3; }
.tour-map .mapboxgl-ctrl-logo { opacity: .5; }
/* Carte STATIQUE (image cachée) affichée direct + bouton Zoom qui charge la carte interactive à la demande :
   plus de Mapbox GL (tuiles + Directions) pour chaque joueur -> chargement instantané + quasi zéro appel API. */
.tour-map-box { position: relative; margin: .2rem 0 .1rem; }
/* Image statique = MÊME gabarit que la carte interactive (hauteur fixe 280px, pleine largeur) : avant, height:auto
   la faisait grimper à ~800px sur grand écran (« trop grande »), et le passage au Zoom faisait un saut de cadre.
   object-fit: cover -> l'image remplit le cadre comme la carte live ; le parcours est centré (padding Mapbox). */
.tour-map-img { display: block; width: 100%; height: 280px; object-fit: cover; object-position: center; border-radius: 10px; border: 1px solid var(--border); background: #eef0f3; }
/* Bouton AU-DESSUS de la carte (plus en superposition) : bascule image figée <-> carte interactive, toujours visible. */
.tour-map-toggle { display: inline-flex; align-items: center; gap: .3rem; margin: 0 0 .35rem; background: var(--card-2); color: var(--text); font-weight: 700; border: 1px solid var(--border); border-radius: 999px; padding: .34rem .8rem; font-size: .82rem; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.tour-map-toggle:hover { border-color: var(--accent-2); }
.tour-map-toggle[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #1a1a1a; }
.tour-map-box .tour-map { margin: 0; }
/* Vignette carte statique (héritage, plus utilisé). */
.tour-map-thumb { display: block; margin: .2rem 0 .1rem; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); line-height: 0; }
.tour-map-thumb img { width: 100%; height: auto; display: block; }
.tour-lock { color: var(--danger); font-weight: 600; font-size: .92rem; }
/* Étape figée : boutons "Voir les pronos des autres" / "Voir le classement de l'étape" (dépliage à la demande). */
.tour-stage-links { display: flex; flex-wrap: wrap; gap: .4rem; margin: .15rem 0 .3rem; }
.tour-slink { display: inline-flex; align-items: center; gap: .3rem; padding: .34rem .72rem; font-size: .85rem; font-weight: 700;
    border-radius: 999px; line-height: 1.2; cursor: pointer; background: var(--card-2); border: 1px solid var(--border); color: var(--text);
    transition: border-color .15s, background .15s; }
.tour-slink:hover { border-color: var(--accent-2); background: rgba(245,197,24,.12); }
.tour-slink[aria-expanded="true"] { border-color: var(--accent-2); background: rgba(245,197,24,.14); }
.tour-others-box, .tour-board-box { margin: .5rem 0 .2rem; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tour-others-box .tour-others, .tour-board-box .tour-others { margin: 0; }
/* "Pronos des autres" V2 : cartes joueur riches (drapeaux, popularité par champ, checks/points après résultats).
   100% responsive : cartes empilées mobile / grille 2 colonnes desktop, tout en flex-wrap -> zéro scroll horizontal. */
.cyo-summary { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .7rem; margin: .1rem 0 .6rem; font-size: .82rem; color: var(--muted); }
.cyo-sum-badge { font-weight: 800; border-radius: 999px; padding: .12rem .6rem; white-space: nowrap; }
.cyo-sum-lock { background: var(--card-2); color: var(--text); }
.cyo-sum-done { background: #1f8a4c; color: #fff; }
.cyo-sum-n { font-weight: 700; color: var(--text); }
.cyo-sum-sort { margin-left: auto; font-style: italic; }
.cyo-offwin { margin: .1rem 0 .55rem; font-size: .92rem; }
.cyo-offwin .flag { vertical-align: -2px; margin-right: .25rem; }
.cyo-cards { display: grid; grid-template-columns: 1fr; gap: .5rem; }

/* ── LES PRONOS DES AUTRES, EN LISTE (31/08) ─────────────────────────────────────────────────────
   « Il ne faut pas mettre deux cartes cote a cote. Tous les joueurs en une seule ligne, dans l'ordre
   du classement, tous depliables, avec une petite recherche. » Deux cartes cote a cote sur un
   telephone, ce sont deux colonnes de cent cinquante pixels ou les noms se coupent et ou l'on ne
   compare personne. Quatre cents joueurs demandent une liste : une ligne, un rang, un pseudo, et
   l'on ouvre celle qu'on veut. Le repli passe par <details> : le navigateur s'en charge, aucun
   script a executer, et c'est la seule mecanique qui ait fonctionne du premier coup aujourd'hui. */
.cyo-search { display: block; margin: .1rem 0 .5rem; }
.cyo-search input { width: 100%; box-sizing: border-box; padding: .45rem .6rem; border-radius: 8px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; }
.cyo-list { display: flex; flex-direction: column; gap: .25rem; }
.cyo-row { border: 1px solid var(--border); border-radius: .55rem; background: var(--card); }
.cyo-row[hidden] { display: none !important; }
.cyo-row > .cyo-head { display: flex; align-items: center; gap: .4rem; flex-wrap: nowrap;
    margin: 0; padding: .4rem .55rem; border-bottom: 0; cursor: pointer; list-style: none;
    white-space: nowrap; overflow: hidden; }
.cyo-row > .cyo-head::-webkit-details-marker { display: none; }
.cyo-row[open] > .cyo-head { border-bottom: 1px dashed var(--border); }
.cyo-row .cyo-name { overflow: hidden; text-overflow: ellipsis; }
/* Le chevron dit qu'on peut ouvrir, et devient un moins quand c'est ouvert. Meme signe que partout
   ailleurs sur le site, ecrit une seule fois pour ne pas se casser a moitie. */
.cyo-chev { margin-left: auto; opacity: .7; font-weight: 900; flex: 0 0 auto; }
.cyo-chev::after { content: '+'; }
.cyo-row[open] .cyo-chev::after { content: '\2212'; }
.cyo-row .cyo-picks { padding: .45rem .55rem .5rem; }
.cyo-row.cyo-me { border-color: var(--accent); }
.cyo-vide { margin-top: .5rem; }
@media (min-width: 760px) { .cyo-cards { grid-template-columns: 1fr 1fr; } }
.cyo-card { border: 1px solid var(--border); border-radius: .65rem; padding: .5rem .6rem; background: var(--card); overflow: hidden; }
.cyo-card.cyo-me { border-color: var(--accent-2); background: rgba(245,197,24,.08); box-shadow: inset 0 0 0 1px var(--accent-2); }
.cyo-head { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-bottom: .4rem; padding-bottom: .35rem; border-bottom: 1px dashed var(--border); }
.cyo-pos { font-weight: 800; color: var(--muted); font-size: .82rem; min-width: 1.7rem; flex: 0 0 auto; }
.cyo-head .flag { vertical-align: -2px; flex: 0 0 auto; }
.cyo-name { font-weight: 800; overflow-wrap: anywhere; }
.cyo-you { background: var(--accent-2); color: #1a1a1a; font-size: .66rem; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; border-radius: 999px; padding: .05rem .45rem; flex: 0 0 auto; }
.cyo-stagepts { margin-left: auto; font-weight: 800; color: #1f8a4c; white-space: nowrap; }
.cyo-picks { display: flex; flex-direction: column; gap: .3rem; }
.cyo-pick { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; font-size: .86rem; line-height: 1.35; }
.cyo-lbl { color: var(--muted); flex: 0 0 auto; }
.cyo-val { font-weight: 600; overflow-wrap: anywhere; }
.cyo-val .flag { vertical-align: -2px; margin-right: .15rem; }
.cyo-sel { font-weight: 700; }
.cyo-sep { color: var(--muted); font-weight: 400; }
.cyo-pop { color: var(--muted); font-size: .74rem; font-weight: 600; white-space: nowrap; }
.cyo-mark { margin-left: auto; font-weight: 800; font-size: .76rem; border-radius: 999px; padding: .04rem .45rem; white-space: nowrap; flex: 0 0 auto; }
.cyo-hit { background: #1f8a4c; color: #fff; }
.cyo-miss { background: rgba(217,83,79,.18); color: var(--danger); }
.cyo-pending { color: var(--muted); }
.cyo-legend { margin: 0 0 .5rem; font-size: .8rem; color: var(--muted); font-style: italic; }
/* Rappel clignotant "à remplir avant le 4 juillet" au-dessus des maillots (avant-Tour). */
/* Encart deadline (post-it « alerte ») : fond OPAQUE + texte sombre FIXES -> rendu IDENTIQUE en mode clair
   ET sombre (avant : fond translucide rgba -> olive illisible en sombre). Règle : un composant à fond propre
   ne s'inverse jamais avec le thème ; couleurs autonomes, contraste garanti par nous. */
.tour-deadline { background: #fdf3c4; border: 1px solid #e5c100; border-radius: 9px; padding: .5rem .75rem; margin: 0 0 .7rem; font-size: .95rem; color: #1a1a1a; animation: tour-deadline-blink 1.5s ease-in-out infinite; }
@keyframes tour-deadline-blink { 0%,100% { box-shadow: 0 0 0 0 rgba(217,168,0,.55); } 50% { box-shadow: 0 0 0 5px rgba(217,168,0,.12); } }
@media (prefers-reduced-motion: reduce) { .tour-deadline { animation: none; } }
.tour-recap { background: rgba(255,212,0,.07); border-left: 3px solid var(--accent-2); border-radius: 8px; padding: .55rem .7rem; margin: .2rem 0 .6rem; font-size: .95rem; line-height: 1.5; }
.tour-recap-lbl { display: block; font-weight: 800; font-size: .74rem; text-transform: uppercase; letter-spacing: .03em; color: var(--accent-ink); margin-bottom: .25rem; }

/* ── Paliers du maillot jaune (fiche points vélo, 17/07) : une ligne par jalon sous le pick.
      Uniquement des variables de thème (--border/--muted) + le vert gagnant déjà utilisé partout
      (#1f8a4c sur blanc) -> lisible en sombre ET en clair. ── */
.cy-ms-box { margin: .2rem 0 .1rem; font-size: .8rem; line-height: 1.4; }
.cy-ms-line { overflow-wrap: anywhere; }
.cy-ms-future { color: var(--muted); }
.cy-ms-chip { display: inline-block; border-radius: 999px; padding: 0 .45rem; font-weight: 800; font-size: .72rem; white-space: nowrap; vertical-align: 1px; }
.cy-ms-win { background: #1f8a4c; color: #fff; }
.cy-ms-zero { border: 1px solid var(--border); color: var(--muted); }
.cy-ms-note { margin-top: .15rem; color: var(--muted); font-size: .74rem; }

/* ============================================================================
   SWITCHER DE SPORT (header global) : menu deroulant Foot / Cyclisme -> evenements.
   Additif ; suit le theme sombre de la topbar. Le logo suit le sport courant (Sport::logoPath).
   ============================================================================ */
.sport-switch { position: relative; }
.sport-switch > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: .3rem;
    padding: .28rem .6rem; border-radius: 999px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18);
    color: #e7e9ee; font-weight: 700; font-size: .9rem; -webkit-tap-highlight-color: transparent; }
.sport-switch > summary::-webkit-details-marker { display: none; }
.sport-switch > summary:hover { border-color: var(--accent-2); }
.sport-switch .ss-caret { opacity: .7; font-size: .8rem; }
/* Pastille image du sport (la vraie balle pour le foot, la bulle cycliste pour le Tour) dans le switcher. */
.ss-ic { width: 20px; height: 20px; object-fit: contain; vertical-align: middle; flex: 0 0 auto; }
.ss-grp-h .ss-ic { width: 15px; height: 15px; margin-right: .15rem; }
/* IL DOIT DEFILER, ET NE PAS ENTRAINER LA PAGE AVEC LUI (29/08, Jonathan : « on ne peut pas
   scroller dedans, donc on perd toutes les competitions en bas de l'ecran »). Sans hauteur maximale,
   le menu depassait simplement l'ecran : les competitions passees etaient inatteignables. Et sans
   overscroll-behavior, le geste de defilement traversait le menu pour aller faire defiler la page
   DERRIERE lui, ce qui donnait l'impression que le menu etait fige. */
.sport-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; min-width: 220px;
    background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: .5rem;
    box-shadow: 0 8px 24px rgba(0,0,0,.35);
    max-height: min(72vh, calc(100vh - 5.5rem)); overflow-y: auto; overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch; }
/* ─── LE MENU À DEUX TEMPS : LE SPORT, PUIS SES COMPÉTITIONS (08/09/2026) ──────────────────────
   Jonathan : « on les met par sport, et quand on clique dessus on a un deuxième sous-menu qui montre
   en cours, à venir et passé ». Un repli natif par sport : rien à charger, rien à scripter, et le
   menu ne fait que trois lignes tant qu'on n'a pas ouvert un sport. C'est ce qui lui permet de
   grandir sans se dégrader quand le calendrier de la saison ouvrira une vingtaine de compétitions. */
.ss-sport > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .5rem;
    padding: .5rem .55rem; border-radius: 8px; font-weight: 800; font-size: .95rem;
    -webkit-tap-highlight-color: transparent; }
.ss-sport > summary::-webkit-details-marker { display: none; }
.ss-sport > summary:hover { background: var(--card-2); }
.ss-sport > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ss-sport-nom { flex: 1 1 auto; min-width: 0; }
.ss-ic-emo { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; font-size: 1rem; }
/* La bulle du SPORT, un poil plus grande que celle d'une compétition : c'est un titre de section. */
.ss-ic-sport { width: 22px; height: 22px; }
/* Le chevron dit lequel est ouvert, sans avoir à lire. */
.ss-sport > summary .ss-caret { flex: 0 0 auto; opacity: .55; font-size: .8rem; transition: transform .15s ease; }
.ss-sport[open] > summary .ss-caret { transform: rotate(180deg); }
/* LA PETITE NOTIFICATION : combien de compétitions de ce sport n'ont pas encore commencé. C'est la
   seule chose qui appelle un geste (s'inscrire avant le départ), donc la seule qui se compte ici. */
.ss-soon { flex: 0 0 auto; min-width: 1.15rem; padding: .05rem .35rem; border-radius: 999px;
    background: var(--accent); color: var(--on-accent); font-size: .7rem; font-weight: 800;
    text-align: center; font-variant-numeric: tabular-nums; }
/* Les compétitions d'un sport sont EN RETRAIT : on voit d'un coup d'oeil qu'elles lui appartiennent. */
.ss-sport > .ss-grp { padding-left: .55rem; }
.ss-sport > .ss-grp:first-of-type { margin-top: .1rem; }
.ss-sport + .ss-sport { border-top: 1px solid var(--border); margin-top: .3rem; padding-top: .3rem; }
.ss-grp { padding: .1rem 0; }
.ss-grp + .ss-grp { border-top: 1px solid var(--border); margin-top: .35rem; padding-top: .45rem; }
/* Le lien « voir toutes les compétitions » ferme la liste des terminées : c'est une sortie, pas une
   compétition de plus. Il n'a donc ni bulle ni couleur. */
.ss-grp a.ss-txt-only .ss-txt { font-size: .82rem; color: var(--muted); font-weight: 700; }
.ss-grp-h { display: block; font-size: .74rem; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 0 0 .25rem .2rem; }
.ss-grp a { display: block; padding: .45rem .6rem; border-radius: 8px; color: var(--text); font-weight: 600;
    border: 1px solid transparent; -webkit-tap-highlight-color: transparent; }
/* ÉTATS INTERACTIFS = MÊME RECTANGLE QUE LA SÉLECTION (Jonathan 26/07) : hover, focus clavier, tap et
   pressed surlignent .ss-txt (le NOM seul, exactement le rectangle final), JAMAIS le <a> entier -> la
   bulle-logo n'est plus englobée pendant le clic. La HITBOX reste le <a> complet (zone tactile intacte). */
.ss-grp a:hover { text-decoration: none; color: var(--text); }
.ss-grp a:hover .ss-txt, .ss-grp a:active .ss-txt { background: var(--card-2); box-shadow: inset 0 0 0 1px var(--border); }
.ss-grp a:focus-visible { outline: none; }
.ss-grp a:focus-visible .ss-txt { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Sélectionné (Jonathan 26/07) : le fond couleur-compétition est porté par .ss-txt (le NOM seul),
   plus JAMAIS par le <a> entier -> la bulle-logo reste posée sur le fond du menu (blanc en clair,
   sombre en sombre) et ne se noie plus dans sa propre couleur (bulle Vuelta rouge sur fond rouge). */
.ss-grp a.on { font-weight: 800; }
/* HEADER 3 FAMILLES (#5) : sports meles -> bulle ADAPTATIVE colorisee de la compet devant chaque entree
   (cercle sombre en sombre, blanc en clair -> logo toujours visible, y compris sur l'item selectionne). */
.ss-grp a { display: flex; align-items: center; gap: .5rem; }
.ss-grp a .ss-ic { width: 24px; height: 24px; flex: 0 0 auto; background-size: contain; background-repeat: no-repeat; background-position: center; }
/* Le nom porte un padding CONSTANT (sélectionné ou non) -> aucun décalage de texte entre les entrées ;
   la marge verticale négative compense pour ne pas grossir la ligne. */
.ss-grp a .ss-txt { padding: .18rem .5rem; margin: -.18rem 0; border-radius: 7px; }
.ss-grp a.on .ss-txt { background: var(--accent); color: var(--on-accent); }
.ss-grp-h.ss-fam-running { color: #2bb061; }
/* Item SELECTIONNE : nom surligné de la couleur PROPRE de la competition, FIGEE (identique clair/sombre) :
   jaune Tour, rouge Vuelta, bleu CL, chartreuse US Open. Défaut (World Cup...) = accent du thème courant. */
.ss-grp a.on[data-ck="tour"] .ss-txt   { background: #f5c518; color: #1a1a1a; }
.ss-grp a.on[data-ck="vuelta"] .ss-txt { background: #d81f3a; color: #fff; }
.ss-grp a.on[data-ck="cl"] .ss-txt     { background: #2f6fd0; color: #fff; }
.ss-grp a.on[data-ck="usopen"] .ss-txt { background: #b6c72a; color: #182100; }
/* Pastille de STATUT (« en cours / à venir / terminé ») : on voit où est l'action sans clic supplémentaire.
   Couleurs SÉMANTIQUES, volontairement indépendantes de l'accent de la compétition (sinon la pastille
   changerait de sens d'une compétition à l'autre). */
.ss-st { display: inline-block; margin-left: .35rem; padding: .05rem .4rem; border-radius: 999px;
    font-size: .64rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
    vertical-align: middle; border: 1px solid transparent; }
.ss-st-running  { background: rgba(31,138,76,.18); color: #43c37e; border-color: rgba(67,195,126,.45); }
.ss-st-upcoming { background: rgba(90,140,255,.16); color: #8ab0ff; border-color: rgba(138,176,255,.42); }
.ss-st-finished { background: var(--card-2); color: var(--muted); border-color: var(--border); }
/* Sur l'entrée SÉLECTIONNÉE (pilule pleine accent, texte blanc), la pastille doit rester lisible : sans
   cette règle elle devenait illisible sur les accents clairs (jaune Tour). */
.ss-grp a.on .ss-st { background: rgba(255,255,255,.22); color: #fff; border-color: rgba(255,255,255,.45); }

/* ── Frise du Tour : pastille de statut d'étape (é1 é2...) : espacée du numéro, dégradé subtil,
      ombre douce ; la jaune « à remplir » respire pour attirer l'œil sans agresser. ── */
.tp-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%;
  margin-left: .32rem; vertical-align: middle;
  color: #fff; font-size: 9px; font-weight: 900; line-height: 1;
  box-shadow: inset 0 -1px 2px rgba(0,0,0,.22), 0 1px 2px rgba(0,0,0,.18);
}
.tp-badge-past   { background: linear-gradient(145deg, #b8c0bd, #8f9995); }
.tp-badge-filled { background: linear-gradient(145deg, #2fae66, #187a43); }
.tp-badge-tofill { background: linear-gradient(145deg, #ffab4d, #e67e00); animation: tp-tofill-pulse 1.2s ease-in-out infinite; }
/* Sur l'étape ACTIVE (pill jaune), l'orange collait au jaune : un anneau blanc sépare nettement les 2 couleurs. */
.tour-pill.active .tp-badge-tofill { box-shadow: 0 0 0 2px #fff, 0 1px 2px rgba(0,0,0,.25); }
@keyframes tp-tofill-pulse {
  0%, 100% { opacity: 1; transform: scale(1); box-shadow: inset 0 -1px 2px rgba(0,0,0,.22), 0 0 0 0 rgba(245,197,24,.35); }
  50%      { opacity: .82; transform: scale(.9); box-shadow: inset 0 -1px 2px rgba(0,0,0,.22), 0 0 0 3px rgba(245,197,24,.18); }
}

/* ── Bannière promo Tour (espace foot) : ZÉRO overflow horizontal, boutons courts wrappables,
      croix de fermeture avec vraie zone tactile. Mobile : boutons pleine largeur l'un sous l'autre. ── */
.tp-promo { position: relative; background: linear-gradient(90deg,#fff6cf,#fffdf5); border: 1px solid #e5c100; border-left: 4px solid #f5c518; border-radius: 12px; padding: .7rem 2.7rem .75rem .9rem; margin: 0 0 .85rem; max-width: 100%; overflow: hidden; }
/* ── Promo CHAMPIONS LEAGUE (espace foot, 19/07) : bleu CL fixe (independant du theme courant). ── */
.clp-promo { position: relative; background: linear-gradient(90deg, rgba(47,111,208,.16), rgba(47,111,208,.05)); border: 1px solid rgba(91,155,255,.45); border-left: 4px solid #2f6fd0; border-radius: 12px; padding: .7rem 2.7rem .75rem .9rem; margin: 0 0 .85rem; max-width: 100%; overflow: hidden; }
.clp-close { position: absolute; top: .3rem; right: .45rem; background: none; border: 0; color: var(--muted); font-size: 1.25rem; line-height: 1; cursor: pointer; padding: .2rem .35rem; }
.clp-head { display: flex; gap: .6rem; align-items: flex-start; }
.clp-ball { font-size: 1.6rem; line-height: 1.2; }
.clp-title { font-weight: 800; }
.clp-sub { color: var(--muted); margin-top: .1rem; }
.clp-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .55rem; }
.clp-join { display: inline-block; background: #2f6fd0; color: #fff; font-weight: 800; border-radius: 9px; padding: .45rem .8rem; text-decoration: none; }
.clp-join:hover { background: #275fb5; }
.clp-visit { color: var(--accent-ink); text-decoration: none; font-weight: 600; }
.clp-nothanks { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: .85rem; text-decoration: underline; }
/* SUR TELEPHONE, UNE LIGNE (03/09) : la balle, le titre court et le bouton, rien d'autre. Le sous-titre,
   « Decouvrir » et « Non merci » reviennent sur grand ecran ; la croix reste. La banniere garde ses
   impressions (le cross-sell ligue URSIB -> Champions League est voulu), elle cesse d'occuper l'ecran. */
.clp-title-m { display: none; }
@media (max-width: 640px) {
    .clp-promo { display: flex; align-items: center; gap: .5rem; padding: .4rem 2rem .4rem .6rem; margin-bottom: .55rem; }
    .clp-head { flex: 1 1 auto; min-width: 0; align-items: center; gap: .4rem; }
    .clp-ball { font-size: 1.25rem; }
    .clp-title { font-size: .86rem; line-height: 1.2; }
    .clp-title-full, .clp-sub, .clp-visit, .clp-nothanks { display: none; }
    .clp-title-m { display: inline; }
    .clp-actions { margin-top: 0; flex: 0 0 auto; }
    .clp-join { padding: .3rem .6rem; font-size: .8rem; border-radius: 7px; white-space: nowrap; }
}
.tp-promo-head { display: flex; align-items: flex-start; gap: .55rem; min-width: 0; }
.tp-promo-title { font-weight: 800; color: #7a5c00; overflow-wrap: anywhere; }
.tp-promo-sub { color: #555; margin-top: .15rem; overflow-wrap: anywhere; }
.tp-promo-actions { display: flex; flex-wrap: wrap; gap: .45rem .5rem; align-items: center; margin-top: .6rem; min-width: 0; }
.tp-promo-actions > a { max-width: 100%; box-sizing: border-box; }
.tp-promo-join { background: #f5c518; color: #10131a; font-weight: 800; text-decoration: none; padding: .5rem 1.05rem; border-radius: 999px; white-space: nowrap; }
.tp-promo-visit { background: transparent; color: #7a5c00; border: 1px solid #e5c100; font-weight: 700; text-decoration: none; padding: .5rem .95rem; border-radius: 999px; white-space: nowrap; }
.tp-promo-close { position: absolute; top: .25rem; right: .25rem; width: 42px; height: 42px; display: flex; align-items: center; justify-content: center; background: none; border: none; color: #5f4a0e; font-size: 1.6rem; line-height: 1; cursor: pointer; border-radius: 50%; }
.tp-promo-close:hover, .tp-promo-close:active { background: rgba(0,0,0,.07); }
@media (max-width: 520px) {
  .tp-promo-actions > a { flex: 1 1 100%; text-align: center; }
}

/* ── Petite bannière Tour (2e exposition, non-membres) : discrète, 3 actions courtes, zéro overflow. ── */
.tp-small { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .7rem; background: var(--card-2, #f7f8fa); border: 1px solid #e5c100; border-radius: 10px; padding: .5rem .7rem; margin: 0 0 .85rem; max-width: 100%; overflow: hidden; }
.tp-small-txt { display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .45rem; min-width: 0; }
.tp-small-txt > * { overflow-wrap: anywhere; }
.tp-small-actions { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; margin-left: auto; }
.tp-small-join { background: #f5c518; color: #10131a; font-weight: 800; text-decoration: none; padding: .32rem .8rem; border-radius: 999px; white-space: nowrap; font-size: .86rem; }
.tp-small-visit { color: #7a5c00; border: 1px solid #e5c100; font-weight: 700; text-decoration: none; padding: .32rem .7rem; border-radius: 999px; white-space: nowrap; font-size: .86rem; background: transparent; }
.tp-small-no { background: none; border: none; color: var(--muted, #777); font-size: .84rem; cursor: pointer; padding: .32rem .45rem; text-decoration: underline; white-space: nowrap; }
/* Bouton OK des bannières info (13/07) : un VRAI bouton, même gabarit que la CTA (plus le petit lien souligné). */
.tp-small-ok { background: #3a4150; color: #fff; font-weight: 800; border: none; cursor: pointer; padding: .32rem .95rem; border-radius: 999px; white-space: nowrap; font-size: .86rem; }
.tp-small-ok:hover { background: #2b313d; }
html[data-theme="light"] .tp-small-ok { background: #3a4150; color: #fff; }
@media (max-width: 520px) {
  .tp-small-actions { margin-left: 0; width: 100%; }
  .tp-small-join, .tp-small-visit, .tp-small-ok { flex: 1 1 auto; text-align: center; }
}

/* ── Mini-rappel maillots (membres du Tour, espace foot) : une ligne, utile, pas une pub. ── */
.tp-mini { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; background: rgba(245,197,24,.08); border: 1px dashed #e5c100; border-radius: 10px; padding: .42rem .65rem; margin: 0 0 .85rem; font-size: .88rem; max-width: 100%; overflow: hidden; }
.tp-mini-txt { min-width: 0; overflow-wrap: anywhere; }
.tp-mini-btn { margin-left: auto; background: #f5c518; color: #10131a; font-weight: 800; text-decoration: none; padding: .3rem .75rem; border-radius: 999px; white-space: nowrap; font-size: .84rem; }
@media (max-width: 520px) { .tp-mini-btn { margin-left: 0; flex: 1 1 100%; text-align: center; } }

/* hidden DOIT gagner sur nos display:flex (sinon l'attribut est ignoré et les 2 bannières s'affichent). */
.tp-promo[hidden], .tp-small[hidden], .tp-mini[hidden] { display: none !important; }

/* En-têtes de groupe dans les pickers coureur (Têtes de série / Le peloton). */
.scorer-grp { padding: .35rem .65rem .2rem; font-size: .7rem; font-weight: 800; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); border-top: 1px solid var(--border); }
.scorer-grp:first-child { border-top: none; }

/* Paliers de favoris (10/07) : hint pédagogique en tête du menu + ligne "Favoris du jour" sur la fiche étape. */
.scorer-hint { padding: .45rem .65rem; font-size: .74rem; line-height: 1.35; color: var(--muted);
    border-bottom: 1px solid var(--border); font-style: italic; }
.fav-day { margin: .15rem 0 .55rem; line-height: 1.45; }
.fav-day .muted { font-weight: 400; }

/* Badge T/P (tête de série / peloton) sur chaque coureur des pickers. */
.rp-tier { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px;
    border-radius: 4px; font-size: 9px; font-weight: 900; margin-left: .35rem; vertical-align: 1px; }
.rp-tier-t { background: #f5c518; color: #10131a; }
.rp-tier-p { background: var(--border, #d9dde2); color: var(--muted, #667); }

/* « Pourquoi ? » dépliable + vote « texte rigolo » de la bannière Tour. */
.tp-why { margin: .3rem 0 0; color: #6b5c22; }
.tp-why summary { cursor: pointer; font-weight: 700; display: inline-block; }
.tp-why p { margin: .3rem 0 0; color: #555; max-width: 60ch; overflow-wrap: anywhere; }
.tp-funny { background: none; border: 1px dashed #d8c069; color: #8a7522; border-radius: 999px;
    padding: .3rem .7rem; font-size: .8rem; cursor: pointer; white-space: nowrap; }
.tp-funny:hover { background: rgba(245,197,24,.10); }

/* « Les 2 maillots ? » : aide dépliable sous le hero du Tour. */
.hero-prizes { margin: .25rem auto .1rem; max-width: 640px; color: var(--muted); font-size: .86rem; }
.hero-prizes summary { cursor: pointer; display: inline-block; font-weight: 700; color: #f5c518; }
/* Explication en blanc quasi plein : le muted se noyait dans le fond sombre du hero (retour Jonathan 03/07). */
.hero-prizes p { margin: .35rem 0 0; overflow-wrap: anywhere; color: rgba(255, 255, 255, .95); }

/* Étape ciblée par l'horloge (?urgent=1) : cadre orange clignotant quelques secondes pour montrer où jouer. */
/* Cadre orange clignotant sur le BORD EXTÉRIEUR de la carte : anneau net (0 flou) qui épouse le rayon du .card
   (pas de border-radius forcé) et déborde vers l'extérieur, jamais à l'intérieur. z-index pour passer au-dessus
   des cartes voisines et ne pas être masqué. */
.tour-urgent-flash { position: relative; z-index: 3; animation: tourUrgentFlash 1.1s ease-in-out 5; }
@keyframes tourUrgentFlash { 0%, 100% { box-shadow: 0 0 0 0 rgba(224, 168, 0, 0); } 50% { box-shadow: 0 0 0 4px rgba(224, 168, 0, .75); } }

/* (.tour-recap-dot supprimée le 10/07 : pastille verte redondante au milieu du bouton Étapes ;
   le signal « compte rendu non lu » vit sur le bouton Compte rendu de la carte + la frise.) */

/* Frise d'étapes GÉNÉRIQUE cyclisme : toujours scrollable en X, jamais de wrap (compte rendu : récaps + à venir).
   Même recette que .tour-strip. À utiliser systématiquement pour toute liste d'étapes en pastilles. */
.cyc-strip { display: flex; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; gap: .4rem; padding-bottom: .35rem; }
.cyc-strip > a, .cyc-strip > span { flex: 0 0 auto; white-space: nowrap; }
/* Check « rempli » de la nav Tour : forcé VERT (le thème .theme-tour passe --accent-2 en or/jaune, mais un
   check de complétude se lit mieux en vert, cohérent avec la frise des 21 étapes tp-badge-filled). */
.theme-tour .md-dot-full { background: #2bb061; color: #04210f; }
/* Classement Tour (desktop) : le nom passe à la ligne si besoin, colonnes chiffrées jamais coupées. */
.cyc-lb td:nth-child(2) { overflow-wrap: anywhere; }
.cyc-lb .cyc-col-metric { white-space: nowrap; }

/* Compteurs 🏆/👑 cliquables (pop-up pédagogique, 10/07) : chiffre souligné pointillé = « explicable ». */
.cyc-mx-btn { background: none; border: none; padding: .1rem .3rem; margin: 0; font: inherit; font-weight: 700;
    color: inherit; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; border-radius: 6px; }
.cyc-mx-btn:hover { background: rgba(245, 197, 24, .14); }
.cyc-mx-overlay { position: fixed; inset: 0; background: rgba(8, 10, 14, .62); z-index: 1200;
    display: flex; align-items: center; justify-content: center; padding: 1rem; }
.cyc-mx-overlay[hidden] { display: none; }
.cyc-mx-card { position: relative; background: var(--card); border: 1px solid var(--border); border-radius: 14px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .45); max-width: 430px; width: 100%; max-height: 76vh; overflow-y: auto;
    padding: .9rem 1rem; animation: cycMxIn .16s ease-out; }
@keyframes cycMxIn { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
.cyc-mx-x { position: absolute; top: .15rem; right: .35rem; background: none; border: none; color: var(--muted);
    font-size: 1.5rem; line-height: 1; cursor: pointer; padding: .2rem .4rem; }
.cyc-mx-x:hover { color: var(--text); }

/* ===== RESPONSIVE du CLASSEMENT GÉNÉRAL Tour .cyc-lb (refonte 10/07, retour Jonathan) =====
   Sur mobile on GARDE un VRAI tableau 5 colonnes (# / joueur / 🏆 / 👑 / pts) : EN-TÊTES VISIBLES,
   colonnes alignées d'une ligne à l'autre, compacté pour tenir dans la largeur de l'écran (paddings
   serrés, delta de places SOUS le rang, nom qui wrappe, caret masqué). L'ancien empilement flex par
   ligne n'alignait rien verticalement et n'avait aucun header.
   Aligné sur le breakpoint 640px du motif générique « .card > table » (display:block + nowrap +
   scroll X), qu'on annule ici : même spécificité, l'ordre (plus bas) gagne. */
@media (max-width: 640px) {
  table.cyc-lb { display: table; width: 100%; table-layout: auto; white-space: normal; font-size: .88rem; }
  .cyc-lb thead { display: table-header-group; }
  .cyc-lb tbody { display: table-row-group; }
  .cyc-lb tr { display: table-row; }
  .cyc-lb tr[hidden] { display: none !important; }
  .cyc-lb th, .cyc-lb td { display: table-cell; }
  .cyc-lb thead th { padding: .3rem .12rem !important; font-size: .72rem; }
  .cyc-lb td { padding: .5rem .12rem !important; }
  /* Respiration latérale (retour Jonathan 10/07) : le rang ne colle plus au bord gauche, les points
     ne collent plus au bord droit. Un demi-rem de chaque côté, sans élargir le conteneur. */
  .cyc-lb thead th:first-child, .cyc-lb td:first-child { padding-left: .55rem !important; }
  .cyc-lb thead th:last-child, .cyc-lb td:last-child { padding-right: .55rem !important; }
  /* # : rang en haut, delta (+N/-N) DESSOUS -> colonne étroite (bat le nowrap inline posé pour desktop). */
  .cyc-lb td:nth-child(1) { white-space: normal !important; font-size: .84rem; }
  .cyc-lb td:nth-child(1) .lb-delta { display: block; margin-left: 0; line-height: 1.1; }
  /* Joueur : prend la place restante, wrap propre (le caret ▸ garde son style inline : il tient et
     signale que la ligne s'ouvre). */
  .cyc-lb td:nth-child(2) { overflow-wrap: anywhere; }
  .cyc-lb .cyc-col-metric { white-space: nowrap; text-align: center; }
  .cyc-lb .cyc-lb-pts { white-space: nowrap; font-weight: 800; }
  /* Détail déplié (AJAX, colspan 5) : pleine largeur, jamais de débordement. */
  .cyc-lb tr.lb-detail-row td { padding: .4rem .5rem !important; background: var(--card-2); overflow-x: hidden; overflow-wrap: anywhere; }
}
/* ===== RESPONSIVE des RECRUTEURS .cyc-recr-tbl : lignes empilées 2 niveaux (inchangé, adapté à ses
   colonnes hétérogènes : ligne 1 = rang + nom + points ; ligne 2 = recrues valides avec libellé). ===== */
@media (max-width: 560px) {
  .cyc-recr-tbl, .cyc-recr-tbl tbody { display: block; width: 100%; }
  table.cyc-recr-tbl { white-space: normal; } /* annule le nowrap du motif « .card > table » (ordre) */
  .cyc-recr-tbl tr[hidden] { display: none !important; }
  .cyc-recr-tbl thead { display: none; }
  .cyc-recr-tbl tr {
    display: flex; flex-wrap: wrap; align-items: baseline; column-gap: .55rem; row-gap: .1rem;
    width: 100%; box-sizing: border-box; padding: .55rem .15rem; border-bottom: 1px solid var(--border);
  }
  .cyc-recr-tbl td { border: none !important; padding: 0 !important; text-align: left !important; }
  .cyc-recr-tbl td:nth-child(1) { order: 1; font-weight: 700; color: var(--muted); flex: 0 0 auto; min-width: 1.4rem; }
  .cyc-recr-tbl td:nth-child(2) { order: 2; flex: 1 1 auto; overflow-wrap: anywhere; }
  .cyc-recr-tbl td:nth-child(4) { order: 3; flex: 0 0 auto; font-weight: 800; white-space: nowrap; }
  .cyc-recr-tbl td:nth-child(4)::before { content: none !important; }
  .cyc-recr-tbl td:nth-child(3) { order: 4; flex: 1 1 100%; margin-top: .15rem; font-size: .82rem; color: var(--muted); }
  .cyc-recr-tbl td:nth-child(3)::before { content: attr(data-label) "\00a0: "; font-weight: 600; }
  .cyc-recr-tbl tr.recr-detail-row { padding: 0; }
  .cyc-recr-tbl tr.recr-detail-row td {
    flex: 1 1 100%; width: 100%; max-width: 100%; box-sizing: border-box; padding: .4rem .5rem !important;
    background: var(--card-2); overflow-x: hidden;
  }
}
/* DÉTAIL des RECRUES d'un recruteur (AJAX) : cartes empilées, 100% responsive (mobile + PC), zéro scroll.
   Une carte par recrue : nom + points sur une ligne, statut (valide / en cours) + étapes en dessous.
   La MEILLEURE recrue (celle qui fait le score du recruteur) est mise en avant en doré. */
.recr-list { display: flex; flex-direction: column; gap: .4rem; margin: .1rem 0 .2rem; }
.recr-card { border: 1px solid var(--border); border-radius: 10px; padding: .5rem .6rem; background: var(--card); }
.recr-card-best { background: rgba(245, 197, 24, .12); border-color: #e0a800; }
.recr-card-main { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem; }
.recr-name { font-weight: 700; overflow-wrap: anywhere; }
.recr-best-tag { display: inline-block; background: #e0a800; color: #1a1a1a; font-size: .66rem; font-weight: 800;
    border-radius: 999px; padding: .06rem .45rem; white-space: nowrap; vertical-align: middle; }
.recr-pts { font-weight: 800; white-space: nowrap; }
.recr-pts-u { font-weight: 400; color: var(--muted); font-size: .8rem; }
.recr-card-sub { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin-top: .3rem; }
.recr-badge { font-size: .74rem; font-weight: 800; border-radius: 999px; padding: .06rem .5rem; white-space: nowrap; }
.recr-badge-ok { background: #1f8a4c; color: #fff; }
.recr-badge-wait { background: var(--card-2); color: var(--muted); }
/* DÉTAIL des points (AJAX) : sur MOBILE, le tableau 4 colonnes s'EMPILE en blocs -> zéro scroll horizontal.
   Chaque pari = un bloc : nom du marché en gras, puis « Ton prono : X », « Résultat officiel : Y », « Points : +N ». */
.cyc-det-tbl { max-width: 100%; }
@media (max-width: 560px) {
  .cyc-det-tbl thead { display: none; }
  .cyc-det-tbl tr { display: block; border-bottom: 1px solid var(--border); padding: .4rem 0; }
  .cyc-det-tbl td { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
      border: none !important; padding: .1rem .15rem !important; white-space: normal !important; text-align: left !important; }
  .cyc-det-tbl td.cdt-mkt { font-weight: 800; color: var(--text) !important; margin-bottom: .1rem; }
  .cyc-det-tbl td[data-label]::before { content: attr(data-label); font-weight: 700; color: var(--muted); flex: 0 0 auto; }
  .cyc-det-tbl td[data-label] { justify-content: flex-start; }
}

/* Horloge URGENTE du header : un prono se verrouille dans < 6h (Tour) et n'est pas rempli. Clignote,
   mène directement à l'étape concernée. */
.urgent-clock { position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 9px; border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.06);
    color: #f5c518; text-decoration: none; font-size: 1.02rem; line-height: 1; } /* chrome NEUTRE (coherence header) ; l'or reste sur l'icone qui clignote */
.urgent-clock svg { display: block; animation: ucblink 1.1s ease-in-out infinite; } /* l'HORLOGE interieure clignote (pas le bord) */
.urgent-clock .uc-ic { position: absolute; top: -6px; right: -6px; font-size: .72rem; }
/* Pastille COMPTEUR de l'horloge (multi-sport, 15/07) : nb de competitions avec un prono urgent. Orange, et clignote
   EN PHASE avec l'horloge (md-dot-blink 1.1s, override du nb-in) ; positionnee en coin par .urgent-clock > .n-badge. */
.uc-count { background: #e5820c; color: #fff; animation: md-dot-blink 1.1s ease-in-out infinite; }
/* Pastille SPORT de l'horloge (15/07) : UNE seule competition urgente -> picto du sport a la place du chiffre.
   Ballon Coupe du Monde (foot) ou cycliste BLANC (velo) = memes assets que la ceremonie. Clignote en phase, coin. */
.uc-sport { position: absolute; top: -8px; right: -7px; width: 17px; height: 17px; object-fit: contain;
    filter: drop-shadow(0 0 1.5px rgba(0,0,0,.7)); animation: md-dot-blink 1.1s ease-in-out infinite; pointer-events: none; }
/* Clignotement de l'HORLOGE (MAJ 15/07) : c'est l'icone SVG A L'INTERIEUR qui clignote (opacite), pas le bord ni un
   halo. Meme vitesse (1.1s ease-in-out) que la pastille "il manque des pronos", en phase avec .uc-count. */
@keyframes ucblink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* Tip rotatif des membres du Tour : une ligne discrète dorée, fermable session. */
.tp-tip { display: flex; align-items: center; gap: .5rem; background: rgba(245,197,24,.07); border: 1px dashed #d8c069;
    border-radius: 10px; padding: .45rem .65rem; margin: 0 0 .6rem; font-size: .86rem; max-width: 100%; overflow: hidden; }
.tp-tip[hidden] { display: none !important; }
.tp-tip-txt { min-width: 0; overflow-wrap: anywhere; }
.tp-tip-actions { margin-left: auto; display: flex; gap: .25rem; align-items: center; flex: 0 0 auto; }
.tp-tip-x { background: none; border: none; color: var(--muted); font-size: 1.15rem; cursor: pointer; padding: .1rem .35rem; }
.tp-tip-wa { background: #25d366; color: #fff; font-weight: 800; text-decoration: none; border-radius: 999px;
    padding: .3rem .75rem; font-size: .82rem; white-space: nowrap; }

/* ══════════ Variations de position (08/07) : boutons delta cliquables + rang lisible ══════════ */
/* Deux boutons compacts a cote du rang : delta "dernier match/etape" et delta "journee complete".
   Caption = le delta seul (+4 / -2 / 0). Vert = places gagnees, rouge = perdues, neutre = stable.
   Police volontairement plus grande que l'ancien .lb-delta (0.72rem -> 0.82rem) : lisible mobile. */
.rk-pos { display:inline-flex; align-items:center; gap:.3rem; vertical-align:middle; }
.rk-rank { font-weight:800; font-size:1.02rem; color:inherit; text-decoration:none; font-variant-numeric:tabular-nums; }
a.rk-rank:hover { text-decoration:underline; }
.rk-cell { display:inline-flex; align-items:center; gap:.25rem; margin-left:.3rem; vertical-align:middle; }
.rk-btn {
    display:inline-flex; align-items:center; justify-content:center;
    min-width:1.9em; padding:.14em .42em; border-radius:999px;
    font-size:.82rem; font-weight:800; line-height:1.15; text-decoration:none;
    border:1px solid transparent; font-variant-numeric:tabular-nums;
    transition:transform .08s ease, box-shadow .08s ease;
}
.rk-btn:hover { transform:translateY(-1px); box-shadow:0 1px 4px rgba(0,0,0,.18); text-decoration:none; }
.rk-btn.up   { color:#1e8a4c; background:rgba(43,176,97,.14);  border-color:rgba(43,176,97,.45); }
.rk-btn.down { color:#c43d3d; background:rgba(224,82,82,.12);  border-color:rgba(224,82,82,.45); }
.rk-btn.flat { color:var(--muted); background:rgba(128,128,128,.12); border-color:rgba(148,158,178,.55); } /* 13/07 : contour lisible en sombre */
/* Sombre : fond NEUTRE (plus de vert-sur-vert / rouge-sur-rouge), le texte coloré ressort mieux (retour Jonathan). */
[data-theme="dark"] .rk-btn.up   { color:#4fd58a; background:rgba(148,158,178,.14); border-color:rgba(79,213,138,.5); }
[data-theme="dark"] .rk-btn.down { color:#ff8b8b; background:rgba(148,158,178,.14); border-color:rgba(255,139,139,.5); }
.rk-ranklink { color:inherit; text-decoration:none; }
.rk-ranklink:hover { text-decoration:underline; }
td.rank .rk-cell { display:inline-flex; }
@media (max-width:640px) {
    .rk-btn { font-size:.86rem; padding:.16em .46em; } /* mobile : cible tactile confortable */
    .rk-rank { font-size:1.06rem; }
}

/* ══════════ Page historique des positions (08/07) : courbe verticale ══════════ */
.hist-page { max-width:860px; margin:0 auto; }
.hist-head { display:flex; align-items:flex-start; gap:.8rem; margin:.2rem 0 .6rem; }
.hist-back { flex:none; white-space:nowrap; }
.hist-title-wrap { min-width:0; }
.hist-title { margin:0; font-size:1.25rem; line-height:1.25; }
.hist-sub { color:var(--muted); font-size:.92rem; margin-top:.15rem; }
.hist-now { color:inherit; font-size:1.02rem; }
.hist-tabs { display:flex; gap:.4rem; margin:.5rem 0 .6rem; }
.hist-tab {
    padding:.42em .95em; border-radius:999px; font-weight:700; font-size:.92rem;
    border:1px solid var(--border); color:var(--muted); text-decoration:none; background:var(--card);
}
.hist-tab.on { color:var(--on-accent); background:var(--accent, #2bb061); border-color:transparent; }
.hist-tab:not(.on):hover { color:inherit; }
.hist-summary { display:flex; flex-wrap:wrap; gap:.45rem; margin:0 0 .7rem; }
.hist-chip {
    display:inline-flex; align-items:center; gap:.4rem; padding:.32em .6em;
    border:1px solid var(--border); border-radius:10px; background:var(--card); font-size:.88rem;
}
.hist-chip .hc-k { color:var(--muted); }
.hist-chip .hc-v { font-weight:800; font-variant-numeric:tabular-nums; }
.hist-chip .hc-v.good { color:#1e8a4c; }
.hist-chip .hc-v.bad  { color:#c43d3d; }
[data-theme="dark"] .hist-chip .hc-v.good { color:#4fd58a; }
[data-theme="dark"] .hist-chip .hc-v.bad  { color:#ff8b8b; }
.hist-chip small { color:var(--muted); font-weight:600; }
.hist-card { padding:.7rem .8rem .9rem; }
.hist-scale { display:flex; justify-content:space-between; align-items:center; color:var(--muted);
    font-size:.8rem; padding:0 .2rem .35rem calc(var(--hist-lab-w, 92px) + 6px); }
.hist-scale .hs-best { font-weight:800; color:inherit; }
/* Grille : chaque item (titre de phase OU ligne) a la MEME hauteur -> le SVG overlay (viewBox en
   unites de lignes) reste exactement aligne sur les pastilles. */
.hist-graph-wrap { --hist-lab-w:92px; --hist-rh:36px; position:relative; }
.hist-lines {
    position:absolute; top:0; left:calc(var(--hist-lab-w) + 6px + 14px);
    width:calc(100% - var(--hist-lab-w) - 6px - 14px - 18px); height:100%;
    color:var(--accent, #2bb061); pointer-events:none;
}
.hist-row, .hist-phase { height:var(--hist-rh); display:flex; align-items:center; }
.hist-phase { justify-content:flex-start; }
.hist-phase span {
    font-size:.78rem; font-weight:800; letter-spacing:.03em; text-transform:uppercase;
    color:var(--muted); background:var(--card-2, rgba(128,128,128,.08));
    padding:.18em .6em; border-radius:6px;
}
.hist-lab { width:var(--hist-lab-w); flex:none; display:flex; align-items:baseline; gap:.35rem; min-width:0; }
.hist-md { font-size:.74rem; font-weight:800; color:var(--muted); flex:none; }
.hist-ev { font-size:.84rem; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hist-track { flex:1; position:relative; margin-left:calc(6px + 14px); margin-right:18px; height:100%; }
.hist-dot {
    position:absolute; top:50%; transform:translate(-50%,-50%);
    min-width:26px; height:26px; padding:0 .3em; border-radius:999px;
    display:inline-flex; align-items:center; justify-content:center;
    font-size:.8rem; font-weight:800; font-variant-numeric:tabular-nums;
    color:var(--on-accent); background:var(--accent, #2bb061); box-shadow:0 1px 3px rgba(0,0,0,.25);
    z-index:1;
}
[data-theme="dark"] .hist-dot { color:#08130c; }
@media (max-width:640px) {
    .hist-graph-wrap { --hist-lab-w:72px; --hist-rh:34px; }
    .hist-ev { font-size:.8rem; }
    .hist-dot { min-width:24px; height:24px; font-size:.76rem; }
    .hist-head { flex-direction:column; gap:.4rem; }
    .hist-scale { padding-left:calc(72px + 6px); }
}

/* ══════════ Page « Tous les concours » fusionnée (08/07) ══════════ */
/* KPIs cliquables (filtres par sport) + chips de filtres + tableau desktop / cartes mobile. */
.gk-kpis { display:flex; flex-wrap:wrap; gap:.5rem; margin:.6rem 0 .35rem; }
.gk-kpi {
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.1rem;
    min-width:96px; padding:.55rem .9rem; border-radius:12px; text-decoration:none;
    border:1px solid var(--border); background:var(--card); color:inherit;
    transition:transform .08s ease, box-shadow .08s ease;
}
a.gk-kpi:hover { transform:translateY(-1px); box-shadow:0 2px 8px rgba(0,0,0,.14); }
.gk-kpi.on { border-color:var(--accent, #2bb061); box-shadow:0 0 0 1px var(--accent, #2bb061) inset; }
.gk-kpi .gk-n { font-size:1.22rem; font-weight:800; font-variant-numeric:tabular-nums; }
.gk-kpi .gk-l { font-size:.78rem; color:var(--muted); font-weight:700; }
.gk-kpi-static { cursor:default; }
.gk-filters { display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .6rem; }
.gk-chip {
    padding:.34em .8em; border-radius:999px; font-size:.86rem; font-weight:700;
    border:1px solid var(--border); background:var(--card); color:var(--muted); text-decoration:none;
}
.gk-chip.on { color:var(--on-accent); background:var(--accent, #2bb061); border-color:transparent; }
.gk-chip:not(.on):hover { color:inherit; }
.gk-open   { color:#1e8a4c; font-weight:700; }
.gk-closed { color:var(--muted); font-weight:600; }
[data-theme="dark"] .gk-open { color:#4fd58a; }
.badge-warn { background:rgba(224,82,82,.14); color:#c43d3d; border:1px solid rgba(224,82,82,.4); }
[data-theme="dark"] .badge-warn { color:#ff8b8b; }
/* Bascule desktop / mobile : le tableau ne s'affiche qu'au-dela de 720px ; en dessous, cartes. */
.gk-mobile { display:none; }
@media (max-width:720px) {
    .gk-desktop { display:none; }
    .gk-mobile { display:flex; flex-direction:column; gap:.5rem; }
}
.gk-card { border:1px solid var(--border); border-radius:12px; padding:.6rem .7rem; background:var(--card); }
.gk-card-top { display:flex; align-items:flex-start; justify-content:space-between; gap:.6rem; }
.gk-card-name { font-weight:800; font-size:.98rem; min-width:0; line-height:1.3; }
.gk-card-name a { color:inherit; text-decoration:none; }
.gk-card-name a:hover { text-decoration:underline; }
.gk-card-cta { flex:none; }
.gk-card-meta { display:flex; flex-wrap:wrap; gap:.35rem .7rem; margin-top:.4rem; font-size:.84rem; align-items:center; }

/* ══════════ Ajustements 08/07 soir : deltas differencies + historique allege + concours ══════════ */
/* Mini indicateur de TYPE dans les boutons delta : ballon = apres le dernier match, velo = apres la
   derniere etape, "J" = journee complete. Un seul bouton visible a la fois (RankMoves). */
.rk-ico { font-size:.72em; line-height:1; opacity:.85; margin-right:.28em; font-weight:800; }
.rk-btn-journee .rk-ico { font-style:normal; letter-spacing:0; }
/* (13/07) contour pointille retire : les 3 boutons du classement partagent le meme langage (plein + relief). */

/* Page historique : en-tete compact (mobile d'abord), concours bien visible, stats = labels discrets. */
.hist-head { margin:.15rem 0 .45rem; }
.hist-title { font-size:1.12rem; }
.hist-contest {
    display:inline-block; margin-top:.2rem; padding:.14em .55em; border-radius:8px;
    font-size:.9rem; font-weight:800; color:var(--accent, #2bb061);
    background:rgba(43,176,97,.1); border:1px solid rgba(43,176,97,.35);
}
.hist-sub { margin-top:.2rem; }
.hist-statline {
    display:flex; flex-wrap:wrap; gap:.25rem .9rem; margin:.1rem 0 .55rem;
    font-size:.82rem; color:var(--muted);
}
.hist-statline strong { font-weight:800; font-variant-numeric:tabular-nums; color:inherit; }
.hist-statline strong.good { color:#1e8a4c; }
.hist-statline strong.bad  { color:#c43d3d; }
[data-theme="dark"] .hist-statline strong.good { color:#4fd58a; }
[data-theme="dark"] .hist-statline strong.bad  { color:#ff8b8b; }
.hist-statline small { color:var(--muted); }
.hist-tab-j { font-weight:900; font-size:.9em; }
.hist-lines { overflow:visible; } /* les reperes des bords (rang 1 / pire) ne sont pas rognes */
@media (max-width:640px) {
    .hist-title { font-size:1.02rem; }
    .hist-back { align-self:flex-start; }
    .hist-tabs { position:sticky; top:0; z-index:2; background:var(--bg); padding:.25rem 0; margin-top:.25rem; }
}

/* Tous les concours : badges Officiel / Prive + ancrage des filtres sous le header sticky. */
.badge-official { background: color-mix(in srgb, #c99a3d 16%, transparent); color: color-mix(in srgb, #a67c1e 88%, var(--text)); border: none; font-weight: 800; } /* ambre plat (coherent avec les autres badges) */
[data-theme="dark"] .badge-official { color:#e6c169; }
.badge-private { color:var(--muted); border:1px solid var(--border); background:transparent; }
#gk-list { scroll-margin-top:76px; } /* l'ancre atterrit sous le header : filtres + premieres cartes visibles */

/* ══════════ Ajustements 08/07 nuit : "+4 (J)/(M)/(E)", bandeau contexte, retour ancre ══════════ */
/* Suffixe de type du delta : le delta reste le texte principal, "(J)/(M)/(E)" discret mais lisible. */
.rk-suf { font-size:.82em; font-weight:700; opacity:.72; margin-left:.18em; letter-spacing:.02em; }
/* (13/07) idem : plus de pointille sur la pilule journee (langage commun des boutons). */
.rk-btn-static { cursor:default; pointer-events:none; } /* pilule de rappel (bandeau) : non cliquable */
.hist-ctx-txt { color:var(--muted); font-size:.86rem; }
/* Retour au classement ancre : la ligne du joueur (#lb-u<uid>) se surligne brievement -> on retrouve
   exactement l'endroit quitte.
   A MI-HAUTEUR, PAS SOUS LE HEADER (24/08, Jonathan : « le joueur au milieu de la page, avec autour de
   lui les joueurs qui sont autour de lui »). Collee en haut de l'ecran, la ligne arrivait sans ses
   voisins : on voyait le joueur et ceux d'apres, jamais ceux qu'il vient de doubler. 40vh de marge de
   defilement la posent au premier tiers, avec du classement au-dessus et en dessous. Le repli 86px
   (hauteur du header) reste pour les navigateurs sans unites relatives dans scroll-margin. */
tr[id^="lb-u"] { scroll-margin-top:86px; scroll-margin-top:40vh; }
tr[id^="lb-u"]:target { animation: lbTargetFlash 2.4s ease-out 1; }
@keyframes lbTargetFlash {
    0%   { background:rgba(255,212,0,.4); }
    60%  { background:rgba(255,212,0,.18); }
    100% { background:transparent; }
}

/* ══════════ Ajustements 09/07 : legende bas, labels journee/match separes, deltas mobiles ══════════ */
/* Legende d'echelle dupliquee en bas de la courbe (memes alignements que celle du haut). */
.hist-scale-b { padding-top:.35rem; padding-bottom:0; }
/* Ligne de JOURNEE (mode par match) : sa propre ligne, differenciee des matchs (gras + teinte douce). */
.hist-day { height:var(--hist-rh); display:flex; align-items:center; }
.hist-day span {
    font-size:.8rem; font-weight:800; color:var(--accent, #2bb061);
    background:rgba(43,176,97,.09); border:1px solid rgba(43,176,97,.28);
    padding:.12em .5em; border-radius:6px; letter-spacing:.02em;
}
/* Boutons delta : desktop = colonne rang ; mobile = 2e ligne compacte SOUS le nom du joueur
   (les colonnes rang/nom/points restent entieres, aucun debordement horizontal). */
.rk-cell-mob { display:none; }
@media (max-width:640px) {
    .rk-cell-desk { display:none !important; }
    .rk-cell-mob { display:inline-flex; width:100%; margin:.18rem 0 0; gap:.25rem; }
    td.rank { white-space:nowrap; }
}

/* ══════════ Ajustements 09/07 v2 : glow des boutons delta, comparaison, note retires ══════════ */
/* CLIGNOTEMENT SUBTIL des boutons de variation : contour/ombre qui respire, ~2x plus lent et bien
   plus doux que les pastilles de notification (ccn 1s pleine intensite) -> invite au clic sans agresser.
   La pilule statique du bandeau (rk-btn-static) ne clignote pas (ce n'est pas un bouton). */
/* (09/07) plus d animation GLOBALE : seule .rk-attn (bouton du joueur, mouvement reel) respire. */
@keyframes rk-glow-up {
    0%, 100% { box-shadow: 0 0 0 0 rgba(43,176,97,0); }
    50%      { box-shadow: 0 0 0 3px rgba(43,176,97,.20); }
}
@keyframes rk-glow-down {
    0%, 100% { box-shadow: 0 0 0 0 rgba(224,82,82,0); }
    50%      { box-shadow: 0 0 0 3px rgba(224,82,82,.18); }
}
@keyframes rk-glow-flat {
    0%, 100% { box-shadow: 0 0 0 0 rgba(128,128,128,0); }
    50%      { box-shadow: 0 0 0 3px rgba(128,128,128,.16); }
}
@media (prefers-reduced-motion: reduce) { a.rk-btn.rk-attn { animation: none; } }

/* Comparaison (une personne) : selecteur + legende + tracés distincts mais sobres. */
.hist-cmp { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; margin:.1rem 0 .45rem; }
.hist-cmp-lbl { font-size:.86rem; color:var(--muted); font-weight:700; }
.hist-cmp select {
    max-width:min(320px, 70vw); padding:.32em .5em; border-radius:8px;
    border:1px solid var(--border); background:var(--card); color:inherit; font-size:.88rem;
}
.hist-legend { display:flex; gap:1rem; flex-wrap:wrap; margin:.1rem 0 .5rem; font-size:.85rem; }
.hist-leg-item { display:inline-flex; align-items:center; gap:.35rem; font-weight:700; }
.hist-leg-swatch { width:18px; height:0; border-top:3px solid; border-radius:2px; display:inline-block; }
.hist-leg-main { border-color:var(--accent, #2bb061); }
.hist-leg-cmp { border-color:#6c8ce0; border-top-style:dashed; }
.hist-cmp-line { stroke:#6c8ce0; }
.hist-dot-cmp {
    background:#6c8ce0; color:#fff; min-width:22px; height:22px; font-size:.72rem;
    opacity:.92; z-index:0; box-shadow:0 1px 2px rgba(0,0,0,.2);
}
[data-theme="dark"] .hist-dot-cmp { color:#0b1224; }
.hist-dot-under { transform:translate(-50%, calc(-50% + 9px)); } /* chevauchement : la pastille comparee glisse dessous */
/* Note "joueurs retires" : bandeau discret au-dessus de la courbe (verite d'epoque expliquee). */
.hist-departed {
    margin:.1rem 0 .5rem; padding:.45em .7em; border-radius:8px; font-size:.84rem;
    color:var(--muted); background:rgba(128,128,128,.08); border:1px dashed var(--border);
}
.hist-back-bottom { margin:.7rem 0 .2rem; }

/* ══════════ Ajustements 09/07 v3 : ancre haut, ordre inverse, vues super-admin ══════════ */
/* Ancre d'arrivee : le haut utile (retour + titre + modes) atterrit sous le header du site. */
#hist-top { scroll-margin-top: 70px; }
/* Consultations de la courbe (SUPER-ADMIN seulement) : bloc discret en bas, replie par defaut. */
.hist-seen { margin:.6rem 0 .2rem; font-size:.84rem; color:var(--muted); }
.hist-seen summary { cursor:pointer; font-weight:700; }
.hist-seen-list {
    margin:.4rem 0 0; padding:.4rem .6rem; list-style:none; max-height:260px; overflow-y:auto;
    border:1px dashed var(--border); border-radius:8px;
}
.hist-seen-list li { padding:.12rem 0; }

/* Fleches de chronologie (09/07) : au sommet des barres verticales de bord, le temps remonte. */
.hist-axis-arrow {
    position:absolute; top:1px; z-index:1; font-size:.74rem; line-height:1;
    color:var(--accent, #2bb061); opacity:.65; pointer-events:none;
}
.hist-axis-arrow-r { right:18px; transform:translateX(50%); }
.hist-axis-arrow-l { left:calc(var(--hist-lab-w) + 6px + 14px); transform:translateX(-50%); }
@media (max-width:640px) { .hist-axis-arrow { font-size:.7rem; } }

/* Decouverte faite (bouton de variation deja clique / page evolution deja vue) : plus de clignotement.
   Le glow n'est qu'un teaser de decouverte ; les boutons restent pleinement visibles et cliquables. */
.rk-seen a.rk-btn.up, .rk-seen a.rk-btn.down, .rk-seen a.rk-btn.flat { animation: none; }

/* Comparaison multi (jusqu'a 3, 09/07) : pastilles couleur par joueur + retrait individuel. */
.hist-leg-cmpx { border-top-style:dashed; }
.hist-leg-rm {
    display:inline-flex; align-items:center; justify-content:center;
    width:1.25em; height:1.25em; margin-left:.15em; border-radius:50%;
    font-weight:800; text-decoration:none; color:var(--muted);
    border:1px solid var(--border); line-height:1; font-size:.9em;
}
.hist-leg-rm:hover { color:#c43d3d; border-color:#c43d3d; }

/* ══════════ Parcours de navigation (super-admin, 09/07) + tableaux admin responsive ══════════ */
.nj-kpi { font-size:.92rem; }
.nj-filters { display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; margin:0 0 .6rem; }
.nj-list { display:flex; flex-direction:column; gap:.5rem; }
.nj-card {
    display:block; padding:.55rem .7rem; border:1px solid var(--border); border-radius:10px;
    background:var(--card); color:inherit; text-decoration:none;
}
.nj-card:hover { border-color:var(--accent, #2bb061); }
.nj-card-top { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.nj-card-meta { display:block; margin-top:.2rem; line-height:1.45; }
.nj-pager { display:flex; align-items:center; gap:.6rem; margin:.7rem 0 0; }
.nj-steps { list-style:none; margin:.4rem 0 0; padding:0; }
.nj-step {
    display:flex; gap:.6rem; padding:.4rem 0; border-bottom:1px dashed var(--border);
    align-items:baseline;
}
.nj-time { flex:none; width:86px; font-variant-numeric:tabular-nums; font-size:.84rem; font-weight:700; }
.nj-page { min-width:0; }
.nj-path { display:block; font-size:.78rem; word-break:break-all; }
.nj-dwell {
    display:inline-block; margin-left:.4rem; font-size:.78rem; font-weight:700;
    color:var(--accent, #2bb061);
}
.nj-replay {
    display:inline-block; margin-left:.4rem; padding:.05em .5em; border-radius:999px;
    font-size:.78rem; font-weight:800; text-decoration:none;
    color:#6c8ce0; border:1px solid #6c8ce0;
}
.nj-replay:hover { background:rgba(108,140,224,.12); }
@media (max-width:640px) {
    .nj-time { width:64px; font-size:.78rem; }
    .nj-step { gap:.45rem; }
}
/* Tables des consoles admin : jamais de debordement de page -> conteneur scrollable + compact mobile.
   (Classe OPT-IN .adm-scroll : pas de regle globale sur .card > table, cf. piege nowrap cyclisme.) */
.adm-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch; max-width:100%; }
.adm-scroll > table { min-width:100%; }
@media (max-width:720px) {
    .adm-scroll > table { font-size:.82rem; }
    .adm-scroll th, .adm-scroll td { padding:.3rem .4rem; }
}

/* ══════════ Affordance des boutons de variation (09/07) : VRAIS boutons ══════════ */
/* Rectangle arrondi compact avec leger relief (degrade + ombre basse), hover qui souleve, focus
   visible clavier, pressed qui s'enfonce. Elegant, jamais criard ; les couleurs delta restent. */
.rk-btn {
    border-radius: 7px;
    background-image: linear-gradient(180deg, rgba(255,255,255,.14), rgba(0,0,0,.05));
    box-shadow: 0 1px 0 rgba(0,0,0,.22), inset 0 1px 0 rgba(255,255,255,.18);
    cursor: pointer;
}
a.rk-btn:hover { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0,0,0,.22), inset 0 1px 0 rgba(255,255,255,.18); }
a.rk-btn:focus-visible { outline: 2px solid var(--accent, #2bb061); outline-offset: 2px; }
a.rk-btn:active { transform: translateY(1px); box-shadow: 0 0 0 rgba(0,0,0,.2), inset 0 2px 3px rgba(0,0,0,.22); }
.rk-btn-static { box-shadow: none; background-image: none; cursor: default; }
.rk-cta-lbl { font-weight: 800; font-size: .92em; }
/* Animation d'ATTENTION : UNIQUEMENT le bouton du joueur connecte avec un mouvement reel (.rk-attn),
   halo doux, s'arrete tout seul (12 cycles ~26 s), et disparait definitivement apres decouverte
   (html.rk-seen, pose par main.js au premier clic / premiere visite de la page evolution). */
a.rk-btn.rk-attn.up   { animation: rk-glow-up 2.2s ease-in-out 12; }
a.rk-btn.rk-attn.down { animation: rk-glow-down 2.2s ease-in-out 12; }
.rk-seen a.rk-btn.rk-attn { animation: none; }
/* Tip pedagogique du classement (explications depliables). */
.lb-tip-moves {
    display: flex; align-items: center; gap: .45rem; flex-wrap: wrap;
    margin: .1rem 0 .5rem; padding: .4em .6em; border-radius: 8px;
    background: rgba(43,176,97,.07); border: 1px dashed rgba(43,176,97,.35);
}
.lb-tip-moves a { font-weight: 700; }

/* Mini-popover des points de la courbe (clic/Entree sur un point) : discrete, une seule bulle. */
.hist-pop {
    position: absolute; z-index: 5; max-width: 240px; padding: .5em .7em;
    border-radius: 9px; font-size: .84rem; line-height: 1.45;
    background: var(--card); border: 1px solid var(--border);
    box-shadow: 0 4px 14px rgba(0,0,0,.22);
}
.hist-pop .good { color: #1e8a4c; }
.hist-pop .bad { color: #c43d3d; }
[data-theme="dark"] .hist-pop .good { color: #4fd58a; }
[data-theme="dark"] .hist-pop .bad { color: #ff8b8b; }
.hist-dot-main { cursor: pointer; }
.hist-dot-main:focus-visible { outline: 2px solid var(--accent, #2bb061); outline-offset: 2px; }

/* Refus durable d'une banniere (12/07) : bouton SECONDAIRE visible sous le CTA (plus le micro-lien). */
.tp-optout-btn { display: inline-block; margin-top: .3rem; padding: .4rem .8rem; border-radius: 9px;
    border: 1px solid var(--border); background: var(--card-2); color: var(--muted); font-size: .8rem;
    font-weight: 600; cursor: pointer; }
.tp-optout-btn:hover { color: var(--text); border-color: var(--muted); }

/* Rang de phase (fiche) : vraie presence visuelle, sans devenir un bouton. Aide (?) discrete au tap. */
.lbs-line-rank { margin-top: .3rem; align-items: center; }
.lbs-phase-rank { font-size: .88rem; color: var(--text); }
.lbs-phase-rank strong { font-size: .95rem; }
.lbs-qm { width: 1.15rem; height: 1.15rem; border-radius: 50%; border: 1px solid var(--border); background: var(--card-2);
    color: var(--muted); font-size: .68rem; font-weight: 700; line-height: 1; cursor: pointer; flex: 0 0 auto; }
.lbs-qm:hover { color: var(--text); }
.lbs-phase-help { margin: .2rem 0 0 .2rem; padding: .35rem .55rem; border-radius: 7px; background: var(--card-2);
    font-size: .74rem; color: var(--muted); }
.lbs-phase-help[hidden] { display: none; }
.lbs-overall-note { font-size: .76rem; color: var(--muted); }
.lbs-overall-note strong { color: var(--text); }

/* Bascule de vue du classement (concours tardifs) : segmented control sobre, etat actif net. */
.lb-viewswitch { display: inline-flex; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; margin: 0 0 .45rem; }
.lb-viewswitch a { padding: .32rem .8rem; font-size: .82rem; font-weight: 700; text-decoration: none; color: var(--muted); background: var(--card-2); }
.lb-viewswitch a + a { border-left: 1px solid var(--border); }
.lb-viewswitch a.on { background: var(--accent-2, #2bb061); color: var(--on-accent); }
.lb-avgnote { margin: 0 0 .5rem; }
.lb-avg-unranked { color: var(--muted); font-weight: 700; }
.lbs-avg-rankline { font-size: .76rem; color: var(--muted); margin: -.3rem 0 .5rem; }
.lbs-avg-rankline strong { color: var(--text); }

/* Page des buteurs du tournoi (clic sur le chip ballon). */
.scb-table { width: 100%; border-collapse: collapse; }
.scb-table th, .scb-table td { padding: .4rem .5rem; border-bottom: 1px solid var(--border); text-align: left; }
.scb-table th { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.scb-table td.n { text-align: right; font-weight: 700; white-space: nowrap; }
.scb-mine td { background: rgba(111, 156, 42, .12); border-top: 1px solid #6f9c2a; border-bottom: 1px solid #6f9c2a; }
.scb-mine td:first-child { border-left: 3px solid #6f9c2a; }

/* ===== Pronos des autres : la table ne doit JAMAIS deborder de la carte (fix 15/07, replay Gouze mobile).
   Cause : table en largeur naturelle + .badge nowrap ("cache jusqu'au coup d'envoi") -> largeur minimale
   superieure a la carte sur petit ecran -> scroll horizontal. table-layout:fixed borne la table a 100%,
   le pseudo se tronque en ellipsis, et sur mobile le badge verrou passe sur 2 lignes DANS sa cellule. ===== */
.others-table { table-layout: fixed; width: 100%; }
.others-table td { vertical-align: middle; }
.others-table .col-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.others-table .col-who .who-name { vertical-align: middle; }
.others-table .col-pred { overflow-wrap: anywhere; }
.others-table .badge-locked { max-width: 100%; box-sizing: border-box; }
.others-table-fut .col-who { width: 30%; }
@media (max-width: 640px) {
    .others-table .col-who { width: 45%; }
    .others-table-fut .col-who { width: 34%; }
    .others-table .badge-locked { white-space: normal; display: inline-block; text-align: center; line-height: 1.3; padding: .16rem .5rem; font-size: .72rem; }
    .others-table th, .others-table td { padding-left: .35rem; padding-right: .35rem; }
}

/* ===== Récap statique de la cérémonie finale (partial ceremony_recap, 17/07) : version FIGÉE du podium
   (marches or/argent/bronze, parts des enjeux, drapeaux) + maillots vélo + mentions condensées + partage.
   Compatible sombre/clair : fonds/contours via var(--card-2)/var(--border), or #f5c518/#c9a40f identiques
   à la carte cyc-final historique (lisibles sur les deux thèmes). ===== */
.cer-recap { text-align: center; scroll-margin-top: .8rem; } /* cible de #palmares-final : petite marge d'ancrage */
.cer-recap-trophy { font-size: 2.4rem; line-height: 1; }
.cer-recap-title { margin: .2rem 0 .1rem; }
.cer-recap-sub { margin: 0 0 .15rem; }
.cer-recap-stake { margin: 0; color: #c9a40f; font-weight: 800; font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; }
/* Podium : marches alignées en bas, même rang (ex aequo) = même hauteur via --hr (1 = plus haute). */
.cer-recap-podium { display: flex; justify-content: center; align-items: flex-end; flex-wrap: wrap; gap: .5rem; max-width: 640px; margin: .6rem auto 1rem; }
.cer-recap-col { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; flex: 1 1 0; min-width: 96px; max-width: 160px; }
.cer-recap-ava { margin-bottom: .25rem; }
.cer-recap-ava .avatar { width: 34px; height: 34px; }
.cer-recap-name { font-weight: 800; font-size: .92rem; max-width: 100%; overflow-wrap: anywhere; }
.cer-recap-name .flag { margin-right: .28rem; vertical-align: -2px; }
.cer-recap-pts { font-weight: 700; color: #c9a40f; }
.cer-recap-pts-lbl { font-size: .78rem; color: var(--muted); font-weight: 600; }
.cer-recap-share { font-size: .8rem; color: var(--muted); line-height: 1.2; }
.cer-recap-share b { color: #c9a40f; font-size: .92rem; }
/* La marche : hauteur interpolée (mêmes proportions que la carte cyc-final), or pour le 1er. */
.cer-recap-step { width: 100%; margin-top: .35rem; border: 1px solid var(--border); border-bottom: 0; border-radius: 8px 8px 0 0;
    background: var(--card-2); height: calc(40px + 66px * var(--hr, 1)); display: flex; flex-direction: column;
    align-items: center; justify-content: flex-start; padding-top: .3rem; gap: .05rem; }
.cer-recap-col.is-first .cer-recap-step { border-color: #e0a800; background: rgba(245, 197, 24, .22); }
.cer-recap-medal { font-size: 1.5rem; line-height: 1; }
.cer-recap-ranknum { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem;
    border-radius: 50%; border: 1px solid var(--border); background: var(--card); font-size: .82rem; font-weight: 800; }
.cer-recap-ord { font-size: .74rem; font-weight: 800; color: var(--muted); }
/* Beaucoup de marches (groupes à enjeu, jusqu'à 10) : marches plus étroites, retour à la ligne propre. */
.cer-recap-podium.cer-recap-many .cer-recap-col { min-width: 84px; max-width: 130px; }
.cer-recap-podium.cer-recap-many .cer-recap-name { font-size: .8rem; }
/* Les deux maillots jaunes du vélo (pronostiqueur + recruteur ; recruteur non décerné = carte neutre). */
.cer-recap-jerseys { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin: 0 0 1rem; }
.cer-recap-jersey { flex: 1; min-width: 230px; max-width: 340px; border: 1px solid #e0a800; border-radius: 12px;
    padding: .7rem .9rem; background: rgba(245, 197, 24, .10); }
.cer-recap-jersey.is-rec { border-color: var(--accent); background: rgba(31, 138, 76, .10); }
.cer-recap-jersey.is-rec.is-none { border-color: var(--border); background: var(--card-2); }
.cer-recap-jersey-ic { font-size: 1.4rem; line-height: 1.2; }
.cer-recap-jersey-t { font-weight: 800; }
.cer-recap-jersey-n { font-size: 1.05rem; font-weight: 800; margin-top: .15rem; }
.cer-recap-jersey-n .flag { margin-right: .28rem; vertical-align: -2px; }
.cer-recap-jersey-none { margin-top: .25rem; }
/* Mentions spéciales condensées (mêmes données que « ils ont brillé aussi », sans animation). */
.cer-recap-specials-h { margin: 0 0 .5rem; font-weight: 800; color: #c9a40f; text-transform: uppercase;
    letter-spacing: .07em; font-size: .8rem; }
.cer-recap-specials-grid { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; }
.cer-recap-award { display: flex; align-items: center; gap: .55rem; text-align: left; background: var(--card-2);
    border: 1px solid var(--border); border-radius: 12px; padding: .45rem .65rem; flex: 1 1 200px; max-width: 320px; min-width: 0; }
.cer-recap-award-ic { font-size: 1.5rem; line-height: 1; flex: 0 0 auto; }
.cer-recap-award-txt { display: flex; flex-direction: column; min-width: 0; }
.cer-recap-award-t { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.cer-recap-award-n { font-weight: 800; font-size: .92rem; line-height: 1.25; overflow-wrap: anywhere; }
.cer-recap-award-v { font-size: .8rem; color: #c9a40f; font-weight: 700; }
.cer-recap-award-note { font-size: .72rem; color: var(--accent-ink); font-weight: 700; margin-top: .05rem; }
/* Pied : « Revoir la cérémonie » (bouton doré, même or que la cérémonie) + rangée de partage. */
.cer-recap-actions { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; align-items: center; margin-top: 1rem; }
.cer-recap-actions .btn.cer-recap-watch { background: #f5c518; border-color: #e0a800; color: #1a1a1a; font-weight: 800; }
.cer-recap-actions .btn.cer-recap-watch:hover { background: #ffd23a; }
/* Les 3 boutons EN HAUT de la carte recap (18/07) : Rejouer / Partager / S'inscrire aux prochaines. */
.cer-recap-actions-top { margin: .2rem 0 .8rem; }
.cer-recap-actions .btn.cer-recap-next { border-color: #f5c518; color: inherit; font-weight: 700; }
/* Famille .cer-pill (18/07) : LES boutons de la ceremonie ET du recap, identiques partout (pilule sombre,
   partage en vert plein). Volontairement les MEMES dans les deux themes : c'est l'identite ceremonie. */
.cer-pill { display: inline-flex; align-items: center; gap: .45rem; border-radius: 999px; padding: .55rem 1.05rem;
    font-weight: 800; font-size: .92rem; line-height: 1; cursor: pointer; text-decoration: none;
    background: #232a3b; color: #fff; border: 1px solid rgba(255,255,255,.22); }
.cer-pill:hover { filter: brightness(1.15); text-decoration: none; }
.cer-pill svg { width: 16px; height: 16px; fill: currentColor; }
.cer-pill-share { background: #1f8a4c; border-color: #1f8a4c; }
/* Modale de partage de la ceremonie : au-dessus de l'overlay plein ecran (.cer-stage z-index 2000). */
.cer-sh { display: inline-flex; }
.cer-sh-overlay { z-index: 2100; }
.cer-sh-title { margin: 0 0 .3rem; font-size: 1.05rem; }
.cer-sh-p { margin: 0 0 .8rem; font-size: .88rem; color: var(--muted); }
.cer-sh-panel .share-ch.native { background: #232a3b; color: #fff; border: 1px solid rgba(255,255,255,.22); }
@media (max-width: 520px) {
    .cer-recap-podium { gap: .35rem; }
    .cer-recap-col { min-width: 88px; }
    .cer-recap-name { font-size: .8rem; }
    .cer-recap-award { max-width: none; }
}

/* ══════════ MAILLOTS FLOQUÉS ScoreMigos (18/07) ══════════ */
/* Badge « Maillot floqué gagné » : clignote, cliquable par tout le monde -> page maillot du concours.
   Version PARTAGÉE (récap du classement, page maillot) ; la cérémonie plein écran a sa copie inline.
   Pilule sombre volontairement identique dans les deux thèmes (identité cérémonie, comme .cer-pill). */
.cer-jersey-b { display: inline-flex; align-items: center; gap: .28rem; font-size: .72rem; font-weight: 800;
    color: #ffe9a8; background: rgba(13, 20, 48, .85); border: 1px solid rgba(245, 197, 24, .6);
    border-radius: 999px; padding: .26rem .55rem; text-decoration: none; line-height: 1.15; text-align: center;
    max-width: 100%; animation: cerJerseyBlinkR 1.6s ease-in-out infinite; }
a.cer-jersey-b:hover { background: rgba(13, 20, 48, 1); color: #fff; text-decoration: none; }
@keyframes cerJerseyBlinkR { 0%, 100% { box-shadow: 0 0 0 0 rgba(245, 197, 24, 0); } 50% { box-shadow: 0 0 14px 2px rgba(245, 197, 24, .55); } }
@media (prefers-reduced-motion: reduce) { .cer-jersey-b { animation: none; } }
.cer-recap-jersey-claim { margin-top: .4rem; }
/* Pictogramme MAILLOT maison (jersey-icon.svg) : badge, cartes du récap, page maillot. */
.cer-jb-ic { width: 13px; height: 13px; object-fit: contain; }
.cer-recap-jersey-img { width: 32px; height: 32px; object-fit: contain; }
/* « Conditions remplies » (pool KO, exception unique) : lien vert vers la règle du 2e maillot. */
.cer-rec-cond-r, .jp-cond-link { color: var(--accent-ink); font-weight: 800; text-decoration: none;
    border-bottom: 1px dashed rgba(31, 138, 76, .5); padding-bottom: 1px; }
a.cer-rec-cond-r:hover, a.jp-cond-link:hover { filter: brightness(1.2); }

/* Page MAILLOT (/contests/<slug>/maillot) : gagnants + formulaire réservé aux gagnants. */
.jp-hero { text-align: center; }
.jp-hero-ic { line-height: 1; }
.jp-hero-img { width: 54px; height: 54px; object-fit: contain; }
.jp-win-ico { width: 20px; height: 20px; object-fit: contain; vertical-align: -4px; }
.jp-preview { margin-top: .6rem; }
.jp-preview summary { display: inline-flex; cursor: pointer; list-style: none; }
.jp-preview summary::-webkit-details-marker { display: none; }
.jp-admin-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap;
    padding: .5rem 0; border-top: 1px solid var(--border); }
.jp-admin-row:first-of-type { border-top: 0; }
.jp-admin-txt { min-width: 0; font-size: .9rem; }
.jp-admin-ordered { display: block; color: var(--accent-ink); font-weight: 700; font-size: .82rem; }
.jp-admin-act { margin: 0; }
/* line-height resserre (Jonathan 01/08) : sur telephone le titre passe sur deux lignes et
   l'interligne par defaut creusait un trou entre « 2 maillots floques » et « a gagner ». */
.jp-hero-t { margin: .1rem 0 .1rem; line-height: 1.12; }
.jp-hero-sub { margin: 0 0 .5rem; }
.jp-hero-p { max-width: 640px; margin: 0 auto; font-size: .92rem; }
.jp-h { margin: 0 0 .6rem; }
.jp-winners { display: flex; flex-wrap: wrap; gap: .6rem; }
.jp-win { flex: 1; min-width: 240px; border: 1px solid #e0a800; border-radius: 12px; padding: .7rem .9rem;
    background: rgba(245, 197, 24, .10); }
.jp-win-t { font-weight: 800; font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; }
.jp-win-n { font-size: 1.05rem; font-weight: 800; margin: .2rem 0 .1rem; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.jp-win-n .avatar { width: 28px; height: 28px; }
.jp-notfinal { text-align: center; }
.jp-preview-note p { margin: 0; }
.jp-claim-done { color: var(--accent-ink); font-weight: 700; }
.jp-form { display: flex; flex-direction: column; gap: .45rem; max-width: 420px; }
.jp-form .jp-lbl { font-weight: 700; font-size: .85rem; margin-top: .3rem; }
.jp-form select, .jp-form input, .jp-form textarea { width: 100%; }
.jp-form button { align-self: flex-start; margin-top: .5rem; }
.jp-reserved { margin: .3rem 0 0; }
/* Note « ce que tu reçois » + avertissement taille (offert, floqué sur mesure, non échangeable). Fond
   ambré fixe = même aspect clair/sombre (composant à fond propre). */
.jp-floc-note { margin: 0 0 .5rem; font-weight: 600; }
.jp-size-warn { margin: 0 0 .7rem; padding: .5rem .7rem; border-radius: 8px; background: #fef3c7;
    border: 1px solid #f59e0b; color: #5a3e00; font-weight: 600; font-size: .9rem; }

/* Page COMPÉTITIONS (/competitions) v2 (18/07) : hero SOMBRE compact avec le logo ScoreMigos (les logos
   ont « Score » en blanc -> bandeau nuit assumé dans les 2 thèmes, même identité que la cérémonie),
   pastilles rondes teintées par compétition, chips sobres sans MAJUSCULES criardes. */
/* BANDEAU RESSERRE (24/08) : il occupait le haut de l'ecran alors que les cartes sont ce que le
   visiteur vient voir. Moins de hauteur, et le sous-titre tient sur UNE ligne sur ordinateur (c'est
   le max-width de 560px qui le cassait en deux, pas la place disponible). */
.cp-hero { text-align: center; padding: .7rem 1rem .65rem; color: #fff; border-color: #232a3b;
    background: radial-gradient(130% 130% at 50% 0%, #1b2a5b 0%, #0d1430 72%); }
.cp-hero-logo { display: block; height: 40px; width: auto; max-width: min(78vw, 300px); object-fit: contain; margin: 0 auto .35rem; }
.cp-hero-t { margin: 0 0 .1rem; font-size: .95rem; font-weight: 800; color: #ffe9a8; text-transform: uppercase; letter-spacing: .12em; }
/* Pas de max-width sur grand ecran : la phrase tient sur une ligne, le bandeau reste bas. La borne
   revient sous 900px, ou une ligne unique deviendrait illisible. */
.cp-hero-p { margin: 0 auto; color: #c7d0ea; font-size: .88rem; line-height: 1.35; }
@media (max-width: 900px) { .cp-hero-p { max-width: 560px; } }
.cp-h { margin: 1.1rem 0 .5rem; font-size: 1.05rem; }
/* Grille UNIQUE sans chapitres (18/07) : colle directement sous le hero, tout visible sans scroller. */
.cp-grid { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: .8rem; }
/* TROIS CARTES PAR LIGNE sur un ecran d'ordinateur (24/08, deuxieme passe). Premier essai : reduire
   la base flex a 210px en esperant qu'il en tienne trois. Ca ne suffisait pas, et c'etait previsible :
   une base flexible n'est qu'un souhait, le contenu incompressible d'une carte (compteur en quatre
   boites, bouton, badges) la repousse au-dela. Jonathan voyait donc toujours deux cartes larges avec
   du vide a droite. On passe a une largeur EXACTE en pourcentage : trois colonnes, un tiers chacune,
   moins les gouttieres. Rien ne peut plus la faire deborder ; `min-width: 0` neutralise la largeur
   minimale automatique des elements flex, qui est ce qui faisait echouer la base souple. */
.cp-card { flex: 1 1 210px; max-width: 360px; min-width: 0; display: flex; flex-direction: column; align-items: flex-start;
    gap: .3rem; text-decoration: none; color: inherit; position: relative; padding-top: .9rem; }
/* Gouttiere .7rem = 11.2px : (100% - 2 gouttieres) / 3 = 33.333% - .47rem. Idem 4 colonnes au-dela. */
@media (min-width: 860px) { .cp-card { flex-basis: calc(33.333% - .47rem); max-width: calc(33.333% - .47rem); } }
@media (min-width: 1400px) { .cp-card { flex-basis: calc(25% - .53rem); max-width: calc(25% - .53rem); } }
a.cp-card:hover { border-color: #e0a800; text-decoration: none; }
/* Pastille ronde sombre teintée par compétition (lisible dans les 2 thèmes, accueille les pictos blancs). */
/* Chaque carte /competitions porte desormais sa BULLE ScoreMigos par competition (Sport::bubbleFor) : la bulle
   EST deja un cercle colore -> plus aucun anneau exterieur, elle remplit. Les classes .cp-ic-<tint> deviennent
   sans effet (couleur portee par la bulle elle-meme). */
.cp-ic { width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.cp-ic img { width: 100%; height: 100%; object-fit: contain; }
/* 30/07 : les DEUX badges empiles (Inscriptions ouvertes + membres) descendent jusqu'a ~4.3rem :
   le titre respire en dessous (marge haute) et on resserre legerement dates/compteur en compensation. */
/* Lien « La ligue » du nav (26/08) : libelle COURT et insecable, le header ne casse plus en NL. */
.nav-ligue { white-space: nowrap; font-weight: 700; }
/* BASCULE PUBLIC / LIGUES PRIVEES du switcher (26/08) : deux mondes, un seul menu. */
.ss-mode { display: flex; gap: .3rem; padding: .3rem .4rem .45rem; border-bottom: 1px solid var(--border); }
.ss-mode-btn { flex: 1 1 0; border: 1px solid var(--border); background: var(--card-2); color: var(--muted);
    border-radius: 8px; padding: .28rem .4rem; font-size: .78rem; font-weight: 700; cursor: pointer; }
.ss-mode-btn.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* LE PETIT « J » DU JOUEUR DE LIGUE (25/08 soir) : badge des comptes associes a un joueur d'une
   ligue communautaire par leur capitaine. Le survol dit l'equipe et la ligue. */
.lb-j-badge { display: inline-flex; align-items: center; justify-content: center; width: 1.05rem; height: 1.05rem;
    border-radius: 50%; background: var(--accent); color: var(--on-accent); font-size: .62rem; font-weight: 900;
    vertical-align: 1px; cursor: help; }
/* Chapitre « Ligues privees » (25/08) : titre de section entre les grandes competitions et les
   ligues locales de nos joueurs. */
.cp-fam-h { margin: 1.4rem 0 .15rem; font-size: 1.15rem; }
.cp-fam-sub { margin: 0 0 .6rem; font-size: .9rem; }
.cp-name { font-weight: 800; font-size: 1.05rem; margin-top: .7rem; }
.cp-dates { font-size: .82rem; margin-top: -.1rem; }
/* Chips sobres : point de statut + libellé fin (le « BIENTÔT » criard devient la période, ex. « Août 2026 »). */
/* PILE DE BADGES (24/08) : une carte peut en porter trois (« En cours », « Inscriptions ouvertes »,
   le nombre de membres). Ils etaient positionnes un par un a des hauteurs fixes, ce qui ne tenait
   plus au-dela de deux. Un conteneur en colonne les empile tout seul, alignes a droite, et le titre
   se decale du nombre de badges reellement presents. */
/* RANGEE DE TETE : la bulle a gauche, la pile de badges a droite, les deux DANS LE FLUX (24/08,
   troisieme passe). Tant que les badges etaient en position absolue, le titre ne pouvait pas savoir
   jusqu'ou ils descendaient : on lui donnait une marge devinee, juste pour une seule combinaison de
   nombre de badges, de largeur de carte et de langue. A quatre cartes par ligne, la pile faisait
   trois rangees et mordait le titre. Dans le flux, la rangee de tete pousse le titre d'elle-meme. */
.cp-head { display: flex; width: 100%; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.cp-badges { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: flex-start;
    gap: .3rem; min-width: 0; }
.cp-badges .cp-chip, .cp-badges .cp-members { position: static; top: auto; right: auto; }
/* EN LIGNE, PAS EN COLONNE (24/08, Jonathan : « le en cours a la gauche de l'inscription ouverte »).
   Cote a cote, les badges tiennent sur une rangee et repassent a la ligne d'eux-memes quand la carte
   est trop etroite. La bulle garde sa place a gauche parce que .cp-head les separe en flex, sans
   largeur maximale a calculer. */
/* Le titre suit la rangee de tete, qui a deja pris sa hauteur reelle : une petite respiration suffit,
   la meme quel que soit le nombre de badges. Les cartes « bientot » et « terminee » n'ont pas de
   rangee de tete (leur chip unique reste en absolu) et gardent le .7rem de .cp-name. */
.cp-head + .cp-name { margin-top: .35rem; }
.cp-chip { position: absolute; top: .65rem; right: .65rem; display: inline-flex; align-items: center; gap: .34rem;
    font-size: .72rem; font-weight: 600; border-radius: 8px; padding: .22rem .55rem; border: 1px solid var(--border);
    background: var(--card-2); color: var(--muted); }
.cp-dot { width: 7px; height: 7px; border-radius: 50%; background: #22a15c;
    animation: cpDotPulse 2.2s ease-out infinite; }
@keyframes cpDotPulse { 0% { box-shadow: 0 0 0 0 rgba(34, 161, 92, .45); } 70% { box-shadow: 0 0 0 6px rgba(34, 161, 92, 0); } 100% { box-shadow: 0 0 0 0 rgba(34, 161, 92, 0); } }
@media (prefers-reduced-motion: reduce) { .cp-dot { animation: none; } }
.cp-chip-live { border-color: rgba(34, 161, 92, .45); color: var(--accent-ink); }
.cp-chip-soon { border-color: rgba(224, 168, 0, .5); color: #c9a40f; }
/* Badge membres cliquable, SOUS le chip d'etat (30/07) : meme famille visuelle, curseur lien. */
.cp-members { position: absolute; top: 2.85rem; right: .65rem; display: inline-flex; align-items: center; gap: .3rem;
    font-size: .72rem; font-weight: 600; border-radius: 8px; padding: .22rem .55rem; border: 1px solid var(--border);
    background: var(--card-2); color: var(--muted); cursor: pointer; }
.cp-members:hover, .cp-members:focus-visible { color: var(--text); border-color: var(--accent); text-decoration: underline; }
/* Le CTA des cartes porte un libelle long : police reduite et retour a la ligne autorise, pour qu'il
   n'impose pas la largeur de la carte (24/08). */
.cp-cta { margin-top: .45rem; font-size: .84rem; padding: .48rem .6rem; line-height: 1.25;
    white-space: normal; text-align: center; }
/* Le badge « Inscriptions ouvertes » devient cliquable : il doit se voir comme tel. */
.cp-chip-go { cursor: pointer; }
.cp-chip-go:hover { border-color: #e0a800; color: var(--text, inherit); }
/* Bouton « Jouer » du catalogue : BLEU fixe (famille du hero .cp-hero), PAS var(--accent) qui prenait la
   couleur de l'évènement courant en session (rouge quand on est sur la Vuelta). Neutre = cohérent partout. */
.cp-card .btn-primary { background: #2f6fd0; color: #fff; border-color: #2f6fd0; }
.cp-card .btn-primary:hover { background: #275fb5; border-color: #275fb5; }
.cp-card-done { opacity: .85; }
/* Inscriptions clôturées : information nette sur la carte, jamais d'invitation à jouer (Tour). */
.cp-closed { font-size: .78rem; font-weight: 700; color: var(--muted); }
.cp-cta-soon { margin-top: .45rem; font-weight: 700; font-size: .82rem; color: #c9a40f; border: 1px dashed #e0a800;
    border-radius: 999px; padding: .38rem .8rem; }
.cp-soon-note { font-size: .74rem; }
/* Pages de RÈGLES (18/07) : (1) bouton retour FLOTTANT bas-gauche (zone du pouce) affiché seulement
   en navigation interne, history.back() = retour exact ; (2) tables à l'abri du débordement mobile :
   chaque table défile dans SON conteneur, la page ne scrolle jamais horizontalement. */
.rules-back { position: fixed; left: .8rem; bottom: calc(.9rem + env(safe-area-inset-bottom, 0px)); z-index: 60;
    display: inline-flex; align-items: center; gap: .35rem; padding: .55rem 1rem; border-radius: 999px;
    font: inherit; font-weight: 800; font-size: .9rem; cursor: pointer;
    border: 1px solid var(--border); background: var(--card-2); color: var(--text);
    box-shadow: 0 3px 12px rgba(0, 0, 0, .35); }
.rules-back:hover, .rules-back:focus-visible { border-color: var(--accent-2, #2bb061); }
html[data-theme="light"] .rules-back { background: #ffffff; box-shadow: 0 3px 12px rgba(0, 0, 0, .18); }
.howto-tbl { overflow-x: auto; }
.howto-tbl > table { width: 100%; }

/* Marks de points CLIQUABLES (cartes/classement d'étape) : relief « c'est un bouton » (18/07). */
.cyo-mark[data-pts-exp] { box-shadow: 0 1px 3px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .14);
    border-radius: 999px; }
.cyo-mark[data-pts-exp]:hover { filter: brightness(1.08); }

/* Affordance PARTAGÉE des chips/marks déroulables (19/07) : curseur + chevron ▾, une seule source
   pour la fiche points ET les cartes d'étape (avant : 2 snippets HTML divergents). */
.pts-clk { cursor: pointer; }
.pts-clk::after { content: "\25BE"; font-size: .6em; margin-left: .24rem; opacity: .85; }

/* Détail de calcul AFFICHÉ D'OFFICE dans la fiche points (podium ligne-par-ligne, joker, malus) :
   même famille visuelle que .cy-ms-box (jalons maillot jaune), uniquement des variables de thème. */
.cdl-inline-exp { margin: .25rem 0 .05rem; padding: .3rem .5rem; background: var(--card);
    border-left: 3px solid var(--border); border-radius: 6px; font-size: .8rem; color: var(--muted);
    line-height: 1.5; }

/* Chrono EN COURSE dans la fiche d'étape figée (18/07) : même contenu que le classement, rouge vif. */
.tour-live-chip { margin: .2rem 0 .1rem; }
.tour-live-chip span { font-weight: 800; font-size: .86rem; color: #e05252; font-variant-numeric: tabular-nums; }

/* CADEAUX (18/07) : annonce permanente des maillots floqués dans la carte concours vélo. Doré discret
   (même esprit que l'encart du pool), pas de clignotement agressif : visible tout le Tour. */
/* Encart maillots : prend la couleur de la COMPETITION (color-mix sur --accent-2) -> rouge Vuelta, jaune
   Tour, bleu CL, sans valeur figee. color-mix largement supporte (2023+). */
/* Encart maillots : fond PASTEL OPAQUE (mix avec du BLANC, pas transparent) + texte sombre FIXE. Teinté
   par compétition (rouge Vuelta, doré Tour, bleu CL) MAIS rendu IDENTIQUE en clair et sombre -> fini le
   « rouge sur noir » qui bavait. Contour à la couleur pleine de la compétition, bien visible. */
.cyc-prize-line { margin: .45rem 0 0; padding: .5rem .7rem;
    border: 1px solid var(--accent-2);
    background: color-mix(in srgb, var(--accent-2) 13%, #ffffff);
    color: #1a1a1a;
    border-radius: 10px; font-size: .88rem; line-height: 1.45; }
.cyc-prize-line > strong { color: var(--accent-ink); }
.cyc-prize-sub { display: block; }
.cyc-prize-more { font-weight: 700; white-space: nowrap; color: var(--accent-ink);
    text-decoration: underline; text-underline-offset: 2px; }   /* la teinte ne porte plus seule le lien */

/* ═══ R2 (22/07) : UN ENCART A FOND PROPRE FIGE SES ENCRES ═══
   Le fond de cet encart etait deja stable (creme opaque, l.4835) et le commentaire d'origine en
   concluait qu'il n'y avait plus rien a faire. Le fond, non ; les ENCRES, si : > strong et
   .cyc-prize-more lisaient var(--accent-ink), qui bascule avec le theme. En mode sombre le titre
   « 2 maillots floques a gagner » passait donc au jaune vif (1,5:1) ou au rose (2,2:1) sur du creme.
   Regle posee par Jonathan : « tout ce qui est a l'interieur de la banniere ne doit pas bouger ».
   On fige donc, sur l'encart lui-meme, les valeurs que le MODE CLAIR affiche deja : rien de nouveau
   n'est invente, on empeche seulement le mode sombre de les ecraser. */
.cyc-prize-line { --accent-ink: #137a3a; --text: #1a1a1a; --muted: #4b5563; }
html[data-comp="tour"]   .cyc-prize-line { --accent-ink: #9c7500; }
html[data-comp="vuelta"] .cyc-prize-line { --accent-ink: #c00020; }
html[data-comp="cl"]     .cyc-prize-line { --accent-ink: #0a3fa0; }

/* Étape future (pronos des autres) : bandeau verrouillé + compteur + ROSTER NOMINATIF (18/07,
   décision finale : les bidons remplissent désormais aux heures de la courbe réelle, le roster
   les crédibilise ; les valeurs des pronos restent secrètes jusqu'au départ). */
.cyo-locked-note { font-weight: 700; margin: .2rem 0 .4rem; }
.cyo-ready-count { font-weight: 700; color: var(--accent-ink); margin: .2rem 0 .3rem; }
.cyo-roster { display: flex; flex-wrap: wrap; gap: .3rem .35rem; margin: .15rem 0 .3rem; }
.cyo-roster-pill { display: inline-flex; align-items: center; gap: .28rem; font-size: .78rem; font-weight: 600;
    border: 1px solid var(--border); border-radius: 999px; padding: .18rem .55rem; background: var(--card-2, rgba(255,255,255,.03)); }
.cyo-roster-pill .muted { font-weight: 700; font-size: .72rem; }
html[data-theme="light"] .cyo-roster-pill { background: #f4f6f9; }

/* Podium VERTICAL 1/2/3 dans « Pronos des autres » (18/07) : le tiercé se lit de haut en bas, numéroté,
   avec un alinéa. Le mark de points est cliquable quand un calcul se décompose (data-pts-exp). */
.cyo-pod { display: flex; flex-direction: column; gap: .12rem; margin: .1rem 0 0 .55rem; }
.cyo-pod-line { display: flex; align-items: center; gap: .3rem; }
.cyo-pod-n { font-weight: 800; color: var(--muted); min-width: 1.05em; }

/* Frise des étapes (onglet recaps vélo, 18/07) : pill active CONTRASTÉE dans les 2 thèmes
   (l'or clair #c9a40f se lisait mal une fois sélectionné, surtout en thème clair). */
.cyc-strip-pill { text-decoration: none; font-weight: 800; font-size: .86rem; border-radius: 999px;
    padding: .3rem .7rem; border: 1px solid var(--border); background: var(--card-2); color: var(--text); }
.cyc-strip-pill.cyc-strip-on { font-weight: 900; border-color: #e0a800; background: rgba(245, 197, 24, .24); color: #ffe07a; }
html[data-theme="light"] .cyc-strip-pill.cyc-strip-on { background: rgba(245, 197, 24, .30); color: #6b5300; }

/* Traduction à la lecture (18/07) : message d'attente sous le recap en langue source. */
.recap-translating { margin: .5rem 0 0; font-size: .82rem; font-style: italic; color: var(--muted);
    animation: rtPulse 1.4s ease-in-out infinite; }
@keyframes rtPulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .recap-translating { animation: none; } }

/* Note « Inscriptions clôturées » (home cyclisme, carte concours, bannière anonyme) : remplace TOUT
   bouton d'inscription une fois la deadline du Tour passée (Jonathan 18/07). */
.cyc-entry-closed { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; font-size: .9rem;
    color: var(--muted); border: 1px solid var(--border); border-radius: 999px; padding: .5rem .95rem;
    background: var(--card-2); }

/* ═══ « Le maillot le plus accessible » (22/07) : dire au joueur ses VRAIES chances ═══
   Surface a FOND PROPRE : elle fige donc ses encres (regle R2), sinon son titre basculerait avec le
   theme comme l'encart des maillots le faisait. Declinaison data-comp obligatoire des qu'on touche
   --accent* : une declaration posee sur l'element bat celle heritee de html[data-comp]. */
.ro-card { position: relative; border: 1px solid var(--accent); border-radius: 14px; padding: 1rem 1.1rem;
    background: color-mix(in srgb, var(--accent) 10%, #ffffff); color: #16181d;
    --text: #16181d; --muted: #4b5563; --border: #d1d5db; --accent-ink: #137a3a; }
html[data-comp="tour"]   .ro-card { --accent-ink: #9c7500; }
html[data-comp="vuelta"] .ro-card { --accent-ink: #c00020; }
html[data-comp="cl"]     .ro-card { --accent-ink: #0a3fa0; }
.ro-card.ro-in { border-width: 2px; }
.ro-eyebrow { margin: 0 0 .25rem; font-size: .68rem; font-weight: 800; letter-spacing: .14em;
    text-transform: uppercase; color: var(--accent-ink); }
.ro-hook { margin: 0 0 .8rem; font-size: 1.08rem; font-weight: 800; line-height: 1.25; letter-spacing: -.01em; }
/* Les deux nombres cote a cote : c'est la comparaison qui parle, pas les nombres pris isolement. */
.ro-nums { display: flex; align-items: center; gap: .9rem; margin: 0 0 .8rem; }
.ro-num { display: flex; flex-direction: column; line-height: 1.1; }
.ro-num b { font-size: 1.9rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.ro-num span { font-size: .72rem; color: #4b5563; max-width: 15ch; }
.ro-num-hot b { color: var(--accent-ink); }
.ro-vs { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .1em; color: #8a93a0; }
.ro-gauge { position: relative; height: 22px; border-radius: 999px; background: rgba(0,0,0,.08);
    overflow: hidden; margin: 0 0 .7rem; }
.ro-gauge-fill { height: 100%; background: var(--accent); transition: width .4s ease; }
.ro-gauge-txt { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: .72rem; font-weight: 800; font-variant-numeric: tabular-nums; color: #16181d; }
.ro-rule { margin: 0 0 .7rem; font-size: .86rem; color: #4b5563; }
.ro-guar { margin: 0 0 .8rem; padding: .5rem .7rem; border-radius: 9px; font-size: .84rem; font-weight: 700;
    background: rgba(0,0,0,.05); border-left: 3px solid var(--accent); }
.ro-guar-done { background: rgba(31,138,76,.14); border-left-color: #1f8a4c; color: #14532d; }
.ro-cta { width: 100%; justify-content: center; }
@media (max-width: 420px) { .ro-num b { font-size: 1.55rem; } .ro-nums { gap: .6rem; } }

/* ═══════════════════ TENNIS — US OPEN (habillage par competition + tableau/bracket) ═══════════════════
   Accent = jaune optique de la balle de tennis (distinct du jaune OR du Tour et du bleu CL). Le layout pose
   html[data-comp="usopen"] via Sport::themeKey(). PIEGE (cf feedback theming) : --accent* ET --on-accent
   DOIVENT etre definis en SOMBRE et en CLAIR, sinon retour au vert par defaut / texte illisible sur l'accent. */
html[data-comp="usopen"] { --accent: #ccdd33; --accent-2: #b6c72a; --accent-ink: #d7e84e; --on-accent: #182100; }
html[data-comp="usopen"] { --cd-fg: #d7e84e; --cd-glow: rgba(204,221,51,.55); --cd-bg: linear-gradient(165deg,#2f3a0c,#10120a); --cd-border: rgba(182,199,42,.5); --cd-sep: rgba(215,232,78,.5); }
html[data-theme="light"][data-comp="usopen"] { --accent: #7f9109; --accent-2: #6d7d06; --accent-ink: #566500; --on-accent: #ffffff; }
html[data-theme="light"][data-comp="usopen"] .topbar { --accent: #ccdd33; --accent-2: #b6c72a; --accent-ink: #d7e84e; --on-accent: #182100; }
html[data-comp="usopen"] .hero, html[data-comp="usopen"] .share-panel { --accent-ink: #d7e84e; }
html[data-theme="light"][data-comp="usopen"] .hero, html[data-theme="light"][data-comp="usopen"] .share-panel { --accent-ink: #566500; }

/* ── Coquille + header ── */
/* Flux STANDARD (28/07) : le gap flex s'ADDITIONNAIT aux marges .card (1rem 0) -> espacements
   doubles vs foot/velo. En block, les marges des cartes gouvernent, identiques partout. */
.tennis-wrap { display: block; }
.tn-head { background: radial-gradient(130% 150% at 100% 0%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 60%), var(--card); }
.tn-head-top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.tn-eyebrow { display: inline-flex; align-items: center; gap: .35rem; font-size: .8rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--accent-ink); }
.tn-badge { font-size: .72rem; font-weight: 800; padding: .18rem .5rem; border-radius: 999px; background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent-ink); border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); }
.tn-title { margin: .4rem 0 .15rem; font-size: 1.5rem; font-weight: 900; line-height: 1.1; text-wrap: balance; }
.tn-sub { margin: 0; color: var(--muted); font-size: .95rem; }

/* ── Onglets ── */
.tb-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .85rem; }
.tb-tab { display: inline-flex; align-items: center; gap: .3rem; padding: .4rem .7rem; border-radius: 999px; font-size: .86rem; font-weight: 700; text-decoration: none; color: var(--text); background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid var(--border); }
.tb-tab:hover { border-color: var(--accent-2); }
.tb-tab.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent-2); }

/* ── Encore en lice ── */
.tb-stillin-list { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
.tb-chip { display: inline-flex; align-items: center; gap: .35rem; padding: .25rem .55rem; border-radius: 999px; font-size: .85rem; font-weight: 600; background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid var(--border); }
.tb-chip img { width: 18px; height: auto; border-radius: 2px; }
.tb-seed { color: var(--muted); font-size: .8rem; font-weight: 700; }

/* ── Tableau (bracket) : tours en colonnes, scroll horizontal, convergence par espacement ── */
.tb-scroll { overflow-x: auto; padding-bottom: .5rem; -webkit-overflow-scrolling: touch; }
.tb-bracket { display: flex; gap: 1.4rem; align-items: stretch; min-width: min-content; padding: .25rem; }
.tb-round { display: flex; flex-direction: column; justify-content: space-around; gap: .7rem; min-width: 208px; }
.tb-round-title { font-size: .72rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); text-align: center; }
.tb-match { position: relative; background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: .15rem; display: flex; flex-direction: column; }
.tb-done { opacity: .94; }
.tb-p { display: flex; align-items: center; gap: .45rem; padding: .4rem .55rem; border-radius: 7px; font-size: .9rem; }
.tb-p img { width: 20px; height: auto; border-radius: 2px; flex: 0 0 auto; }
.tb-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.tb-win { font-weight: 800; }
.tb-win .tb-name { color: var(--accent-ink); }
.tb-win::before { content: "\2713"; color: var(--accent-ink); font-weight: 900; font-size: .8rem; }
.tb-lost .tb-name { color: var(--muted); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--muted) 55%, transparent); }
/* MON PICK (Jonathan 27-28/07) : un HIGHLIGHT discret, SANS coche (la coche est reservee au RESULTAT :
   elle n'apparait qu'avec les points gagnes une fois le match joue). */
.tb-mine { background: color-mix(in srgb, var(--accent) 16%, transparent); border-radius: 7px; }
/* CARTE ACCORDEON OUVERTE (27-28/07) : on ne montre QUE les paris ; la barre du haut devient un
   « Replier » EVIDENT, pleine largeur, cliquable. */
.tb-acc[open] > .tb-acc-sum .tb-acc-main { display: none; }
.tb-acc[open] > .tb-acc-sum { padding: .3rem .6rem; opacity: .9; background: var(--card-2); border-bottom: 1px dashed var(--border); border-radius: 10px 10px 0 0; }
.tb-acc-close { display: none; font-size: .8rem; font-weight: 800; color: var(--accent-ink); }
.tb-acc[open] > .tb-acc-sum .tb-acc-close { display: inline-flex; align-items: center; gap: .3rem; }
/* Ligne joueur du resume : nom a gauche, points GAGNABLES a droite (« +3 pts » / « +14 pts »). */
.tb-acc-row { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.tb-acc-row .tb-p { flex: 1 1 auto; min-width: 0; }
.tb-sum-pts { flex: 0 0 auto; font-size: .8rem; font-weight: 800; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
/* Badge de completude / points gagnes : COIN SUPERIEUR DROIT de la carte (28/07). */
.tb-acc { position: relative; }
.tb-acc .tb-badge.tb-badge-corner { position: absolute; top: -8px; right: -7px; z-index: 3; } /* bat le static de la regle generique accordeon */
.tb-badge.is-zero { background: var(--card-2); color: var(--muted); border-color: var(--border); }
/* Marches secondaires VISIBLES d'office (plus de depliable « Plus de paris »). */
.tb-more-open { display: flex; flex-direction: column; gap: .4rem; padding-top: .2rem; }
/* Chaque pari affiche ce qu'il RAPPORTE (28/07). */
.tb-fld-pts { font-style: normal; font-size: .76rem; font-weight: 800; color: var(--accent-ink); margin-left: .3rem; }
/* Detail gagne/perdu par pari (match joue) + fiche points du classement. */
.tt-bd { display: flex; flex-direction: column; gap: .25rem; padding: .3rem .2rem; }
.tt-bd-round { font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-top: .45rem; }
.tt-bd-row { display: flex; justify-content: space-between; gap: .8rem; font-size: .9rem; padding: .18rem .3rem; border-radius: 6px; }
.tt-bd-row.is-win  { background: rgba(31,138,76,.12); }
.tt-bd-row.is-win .tt-bd-pts { color: #2bb061; font-weight: 800; }
.tt-bd-row.is-lose .tt-bd-pts { color: var(--muted); font-weight: 700; }
.tt-bd-total { border-top: 1px solid var(--border); margin-top: .3rem; font-weight: 800; }
.tt-bd-pts { font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.tn-lb-link { text-decoration: none; color: inherit; }
.tn-lb-link:hover { text-decoration: underline; }
.tb-tbd .tb-name { color: var(--muted); font-style: italic; font-weight: 500; }
.tb-score { text-align: center; font-size: .8rem; font-weight: 800; color: var(--muted); padding: .05rem 0; font-variant-numeric: tabular-nums; }
.tb-games { font-weight: 600; font-size: .72rem; }

/* ── Champion ── */
.tb-champ-col { justify-content: center; min-width: 168px; }
.tb-champ { background: radial-gradient(120% 120% at 50% 0%, color-mix(in srgb, var(--accent) 24%, transparent), var(--card)); border: 2px solid var(--accent-2); border-radius: 12px; padding: 1rem .8rem; text-align: center; box-shadow: 0 0 26px color-mix(in srgb, var(--accent) 30%, transparent); }
.tb-champ img { width: 34px; height: auto; border-radius: 3px; margin-bottom: .3rem; }
.tb-champ-name { font-weight: 900; font-size: 1rem; }
.tb-champ-tbd { font-size: 2rem; opacity: .5; }

/* ── Formulaire de prono par match ── */
.tb-form { display: flex; flex-direction: column; gap: .4rem; padding: .45rem; border-top: 1px dashed var(--border); margin-top: .1rem; }
.tb-pick { display: grid; grid-template-columns: 1fr 1fr; gap: .35rem; }
.tb-pick-btn { position: relative; display: flex; flex-direction: column; align-items: center; gap: .1rem; padding: .4rem .3rem; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; text-align: center; font-size: .82rem; font-weight: 700; transition: border-color .12s, background .12s; }
.tb-pick-btn input { position: absolute; opacity: 0; width: 0; height: 0; }
.tb-pick-btn:hover { border-color: var(--accent-2); }
.tb-pick-btn.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent-2); }
.tb-pick-pts { font-size: .72rem; font-weight: 800; color: var(--accent-ink); }
.tb-pick-btn.on .tb-pick-pts { color: var(--on-accent); }
.tb-more { font-size: .82rem; }
.tb-more > summary { cursor: pointer; color: var(--accent-ink); font-weight: 700; padding: .2rem 0; list-style: none; }
.tb-more > summary::-webkit-details-marker { display: none; }
.tb-more > summary::before { content: "\FF0B\00A0"; font-weight: 800; }
.tb-more[open] > summary::before { content: "\FF0D\00A0"; }
.tb-fld { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: .3rem 0; }
.tb-fld > span { color: var(--muted); font-weight: 600; }
.tb-fld select { flex: 0 0 auto; max-width: 55%; padding: .25rem .4rem; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--text); }
.tb-bool label { display: inline-flex; align-items: center; gap: .2rem; margin-left: .5rem; font-weight: 600; }
.tb-save { align-self: stretch; margin-top: .2rem; }
.tb-picked { text-align: center; font-size: .82rem; font-weight: 700; color: var(--accent-ink); padding: .35rem; }
.tb-anon-cta { display: block; text-align: center; font-size: .82rem; font-weight: 800; padding: .4rem; color: var(--on-accent); background: var(--accent); border-radius: 7px; text-decoration: none; margin: .1rem; }

@media (max-width: 640px) { .tb-round { min-width: 176px; } .tb-bracket { gap: 1.1rem; } .tn-title { font-size: 1.3rem; } }

/* Tennis dans le catalogue /competitions (icone + compte a rebours teinte usopen) */
/* La bulle tennis EST deja un cercle chartreuse -> pas de cercle EXTERIEUR redondant : on retire le ring et
   on agrandit la bulle pour qu'elle fasse toute la taille (Jonathan). */
.cp-ic-usopen { border: none; background: none; }
.cp-ic-usopen img { width: 100%; height: 100%; }
.cd-tint-usopen { --cd-fg: #d7e84e; --cd-glow: rgba(204,221,51,.55); --cd-bg: linear-gradient(165deg,#2f3a0c,#10120a); --cd-border: rgba(182,199,42,.5); --cd-sep: rgba(215,232,78,.5); }

/* Tennis C+D : clic immédiat (surbrillance sans rechargement), pastille de complétion, statut auto-save */
.tb-pick-btn:has(input:checked) { background: var(--accent); color: var(--on-accent); border-color: var(--accent-2); }
.tb-pick-btn:has(input:checked) .tb-pick-pts { color: var(--on-accent); }
.tb-bool label:has(input:checked) { font-weight: 800; color: var(--accent-ink); }
.tb-badge { position: absolute; top: -8px; right: -7px; z-index: 3; min-width: 20px; height: 20px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; font-size: .72rem; font-weight: 800; line-height: 1; border: 2px solid var(--card); font-variant-numeric: tabular-nums; }
.tb-badge.is-complete { background: #1f8a4c; color: #fff; }
.tb-badge.is-partial { background: #e08a1e; color: #fff; }
.tb-form-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: .25rem; }
.tb-status { font-size: .76rem; font-weight: 700; color: #1f8a4c; opacity: 0; transition: opacity .25s; }
.tb-status::before { content: "✓ "; }
.tb-status.is-saved { opacity: 1; }
.tb-status.is-faded { opacity: 0; }
.tb-status.is-saving { opacity: .55; }
.tb-status.is-error { opacity: 1; color: #d64545; }
.tb-status.is-error::before { content: "⚠ "; }
.tb-more > summary.tb-more-partial::after { content: " ●"; color: #e08a1e; font-size: .7rem; vertical-align: middle; }

/* FRISE DES TOURS US Open (#5, 26/07) : ligne du temps au-dessus du bracket. Reutilise .cyc-strip generique.
   Tout est scope [data-comp="usopen"] (accent chartreuse ; la surface fige ses encres). */
[data-comp="usopen"] .tn-rounds { margin: 0 0 .7rem; }
[data-comp="usopen"] .tn-round-pill { display: inline-flex; align-items: center; gap: .4rem; }
[data-comp="usopen"] .tn-round-pill.tn-round-past { opacity: .5; }
[data-comp="usopen"] .tn-round-pill.tn-round-future { opacity: .55; border-style: dashed; }
/* Pill active : chartreuse usopen (et non l'or generique .cyc-strip-on du velo). */
[data-comp="usopen"] .cyc-strip-pill.cyc-strip-on { border-color: var(--accent-2); background: rgba(204, 221, 51, .20); color: var(--accent-ink); }
html[data-theme="light"][data-comp="usopen"] .cyc-strip-pill.cyc-strip-on { background: rgba(127, 145, 9, .16); color: var(--accent-ink); }
/* La pastille "restants" passe INLINE dans la pill (position absolue seulement dans le bracket). */
[data-comp="usopen"] .tn-round-pill .tb-badge { position: static; top: auto; right: auto; border-width: 1px; min-width: 18px; height: 18px; }

/* DEUX VUES US Open (#5) : toggle « Je parie » / « Le tableau » + vue Resultats (lecture seule). */
[data-comp="usopen"] .tn-view-toggle { display: flex; gap: .4rem; margin: 0 0 .6rem; }
[data-comp="usopen"] .tn-vt { text-decoration: none; font-weight: 800; font-size: .86rem; border-radius: 999px; padding: .3rem .8rem; border: 1px solid var(--border); background: var(--card-2); color: var(--text); }
[data-comp="usopen"] .tn-vt.on { border-color: var(--accent-2); background: rgba(204, 221, 51, .20); color: var(--accent-ink); }
html[data-theme="light"][data-comp="usopen"] .tn-vt.on { background: rgba(127, 145, 9, .16); color: var(--accent-ink); }
[data-comp="usopen"] .tn-results { display: flex; flex-direction: column; gap: 1rem; }

/* ═══ LE TABLEAU EN COLONNES (28/08) : un vrai bracket de tennis. Un tour par colonne, defilement
   horizontal (~4 tours visibles), colonnes etirees a la meme hauteur (space-around) : les matchs
   d'un tour s'alignent entre leurs deux sources. Une case est CLIQUABLE vers la saisie du match. */
.tnb-bar { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: .2rem 0 .4rem; }
.tnb-arrow { border: 1px solid var(--border); background: var(--card); color: inherit; border-radius: 999px;
    width: 2.1rem; height: 2.1rem; font-size: 1.05rem; cursor: pointer; }
.tnb-arrow:hover { border-color: var(--accent); }
.tnb-scroll { display: flex; align-items: stretch; gap: 14px; overflow-x: auto; padding: .2rem .1rem .6rem;
    scroll-snap-type: x proximity; }
.tnb-col { flex: 0 0 250px; width: 250px; display: flex; flex-direction: column; scroll-snap-align: start; }
/* VOLET FIGE : la rangee des titres, sticky sous le header du site (top pose en JS), suit le
   defilement horizontal du tableau par synchronisation. */
.tnb-heads { position: sticky; z-index: 7; display: flex; gap: 14px; overflow: hidden;
    background: var(--card); padding: .4rem .5rem .35rem; border: 1px solid var(--border);
    border-bottom: 2px solid color-mix(in srgb, currentColor 55%, var(--border));
    border-radius: 8px 8px 0 0; box-shadow: 0 2px 8px rgba(0, 0, 0, .10); }
.tnb-head { flex: 0 0 250px; width: 250px; font-weight: 800; font-size: .82rem;
    text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.tnb-head-champ { flex-basis: 230px; width: 230px; }
.tnb-head.tnb-hiddencol { display: none; }
.tnb-card > .help { margin-top: 0; }
.tnb-col-list { flex: 1; display: flex; flex-direction: column; justify-content: space-around; gap: 8px; }
.tnb-match { display: block; border: 1px solid var(--border); border-radius: 10px; background: var(--card-2);
    padding: .42rem .55rem; text-decoration: none; color: inherit; position: relative; }
a.tnb-match:hover { border-color: var(--accent); box-shadow: 0 1px 6px rgba(0,0,0,.08); }
.tnb-row { display: flex; align-items: center; gap: .35rem; min-height: 1.35rem; font-weight: 600; font-size: .88rem; }
.tnb-row .flag { width: 18px; height: auto; border-radius: 2px; flex: 0 0 auto; }
.tnb-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tnb-tbd .tnb-name { color: var(--muted); font-weight: 500; font-style: italic; }
.tnb-win .tnb-name { color: var(--ok, #16a34a); }
/* LE PERDANT EST VRAIMENT BARRE (31/08) : un trait d'un pixel, de la couleur d'un texte deja
   attenue, ne se voyait pas. Trois pixels, et la barre garde SA couleur pleine pendant que le nom
   reste attenue : c'est la barre qui doit sauter aux yeux, pas le nom. */
/* LA BARRE DU PERDANT (31/08, troisieme passe). Un pixel suffit : ce qui manquait a l'origine
   n'etait pas l'epaisseur mais la COULEUR. Elle prenait celle du nom, deja attenue, donc elle se
   fondait dedans. Elle prend desormais la couleur du TEXTE du theme (--text) : noire en mode clair,
   blanche en mode sombre, dans les deux cas franche sur un nom gris. */
.tnb-lost .tnb-name { color: var(--muted); text-decoration: line-through;
    text-decoration-thickness: 1px; text-decoration-color: var(--text); }
.tnb-meta { display: flex; align-items: center; justify-content: space-between; gap: .4rem;
    margin-top: .15rem; font-size: .74rem; color: var(--muted); }
.tnb-score { font-weight: 800; color: inherit; }
.tnb-check { border: 1px solid var(--border); border-radius: 999px; padding: .04rem .45rem; font-weight: 700; }
.tnb-check.is-full { background: var(--ok, #16a34a); border-color: var(--ok, #16a34a); color: #fff; }
.tnb-check.is-part { border-color: var(--accent); color: var(--accent); }
.tnb-mine-full { border-color: color-mix(in srgb, var(--ok, #16a34a) 55%, var(--border)); }
.tnb-wait { opacity: .78; }
.tnb-done { background: color-mix(in srgb, var(--accent) 5%, var(--card-2)); }
.tnb-champ { border-style: dashed; }
.tnb-col-champ { flex-basis: 230px; width: 230px; }
/* Pas de surlignage ni de soulignement au clic (28/08) : la case est un BOUTON, pas du texte. */
.tnb-match, .tnb-match * { user-select: none; -webkit-user-select: none; }
a.tnb-match, a.tnb-match:hover, a.tnb-match:focus, a.tnb-match *, a.tnb-match:hover * { text-decoration: none !important; }
/* Le hover SOULEVE le bouton Pronostiquer : on comprend ou le clic mene. */
.tnb-check { transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
a.tnb-match:hover .tnb-check, .tnb-match.tnb-active .tnb-check {
    transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 0, 0, .18); border-color: var(--accent); }
.tnb-match.tnb-active { border-color: var(--accent); }
/* NAVIGATION PAR TOUR DE REFERENCE : la colonne active se compacte, celles d'avant disparaissent. */
.tnb-col.tnb-hiddencol { display: none; }
.tnb-col.tnb-ref .tnb-col-list { justify-content: flex-start; }
/* Fleches FLOTTANTES : centre vertical de l'ecran, hors de tout scroll. */
/* BARRE DE NAVIGATION (28/08 soir) : sous le titre, AU-DESSUS du tableau. Les fleches occupent
   les deux extremites, le tour courant se lit au centre. Elles ne touchent plus la rangee des
   titres, qui redevient un simple volet fige. */
/* FLECHES FLOTTANTES (28/08 nuit) : hors du flux (aucune ligne perdue), fixes juste sous le
   bandeau du site, aux deux bords du tableau. z-index SOUS le menu du site (qui vaut 30). */
.tnb-fly { position: fixed; z-index: 8; display: flex; width: 2.1rem; height: 2.1rem;
    border-radius: 999px; border: 1px solid var(--border); background: var(--card); color: inherit;
    font-size: 1rem; cursor: pointer; align-items: center; justify-content: center;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .18); }
.tnb-fly-l { left: .35rem; }
.tnb-fly-r { right: .35rem; }
.tnb-sim { position: fixed; z-index: 8; right: .35rem; }
.tnb-fly:disabled { opacity: .25; cursor: default; }
.tnb-fly:not(:disabled):hover { border-color: var(--accent); }
/* Le tour COURANT se lit surligne dans la rangee des titres (plus de libelle separe). */
.tnb-head.on { color: var(--accent); }
.tnb-head.on .tnb-head-prog { border-color: var(--accent); }
.tnb-head-prog { margin-left: .4rem; border: 1px solid var(--border); border-radius: 999px;
    padding: .02rem .4rem; font-size: .72rem; text-transform: none; letter-spacing: 0; }
.tnb-head-prog.done { background: var(--ok, #16a34a); border-color: var(--ok, #16a34a); color: #fff; }
/* ANNONCE DE LA JOURNEE DE DEPART (29/08, ligues URSIB). Ton calme et informatif : ce n'est pas une
   alerte, c'est une regle du jeu. Elle disparait d'elle-meme une fois la journee atteinte. */
.bw-banner { padding: .7rem .9rem; border-left: 4px solid var(--accent); }
.bw-banner-title { margin: 0 0 .3rem; font-weight: 800; }
.bw-banner-body { margin: 0 0 .5rem; font-size: .93rem; }
.bw-banner-rules > summary { cursor: pointer; font-size: .85rem; opacity: .8; }
.bw-banner-rules > summary:hover { opacity: 1; }
.bw-banner-cta { margin-top: .55rem; }
/* JOURNEES SUSPENDUES (29/08, ligues URSIB). La carte du match ne propose pas de saisie et dit
   quand les pronos ouvrent. Ton neutre et non alarmant : ce n'est pas une panne, c'est un choix. */
.match-bwoff { display: flex; align-items: center; gap: .45rem; margin: .4rem 0 .2rem;
    padding: .45rem .6rem; border-radius: 8px; font-size: .9rem;
    border: 1px dashed var(--border); background: color-mix(in srgb, var(--accent) 7%, transparent); }
.match-bwoff-lead { font-weight: 700; }
.match-bwoff-help { flex: 0 0 auto; width: 1.35rem; height: 1.35rem; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--border); background: transparent; color: inherit; font: inherit;
    font-size: .8rem; line-height: 1; padding: 0; }
.match-bwoff-help:hover { border-color: var(--accent); color: var(--accent); }
.match-bwoff-why { margin: .1rem 0 .4rem; padding: .45rem .6rem; border-radius: 8px;
    background: color-mix(in srgb, var(--fg, #111) 5%, transparent); }
/* L'attribut hidden doit gagner : une regle d'affichage l'a deja emporte sur lui le 28/08. */
.match-bwoff-why[hidden] { display: none; }
.match-bwoff-past { margin: .3rem 0; font-style: italic; }
/* URGENCE (29/08). Depuis que les vraies heures arrivent, les affiches d'un meme tour ne se ferment
   plus ensemble : le rouge dit lesquelles partent dans moins de 12 h. Il ne parait que s'il y a
   quelque chose a faire, sinon il ne voudrait plus rien dire. */
.tnb-head-urg { margin-left: .35rem; border: 1px solid var(--danger, #dc2626); border-radius: 999px;
    padding: .02rem .4rem; font-size: .72rem; font-weight: 800; text-transform: none; letter-spacing: 0;
    background: var(--danger, #dc2626); color: #fff; cursor: pointer; font-family: inherit; }
.tnb-head-urg:hover { filter: brightness(1.1); }
.tnb-urg-note { margin: .3rem 0 .5rem; padding: .4rem .6rem; border-radius: 8px; font-size: .85rem;
    border: 1px solid var(--danger, #dc2626); color: var(--danger, #dc2626);
    background: color-mix(in srgb, var(--danger, #dc2626) 10%, transparent); }
/* L'attribut hidden doit gagner : une regle d'affichage l'a deja emporte sur lui le 28/08, et
   l'encart « ton prono est complet » s'affichait sur une carte vide. */
.tnb-urg-note[hidden] { display: none; }
/* La carte qui presse : un liseré, pas un fond, pour ne pas rendre le tableau illisible quand la
   moitie des affiches devient urgente le meme soir. */
.tnb-match.tnb-urg { border-color: var(--danger, #dc2626); }
.tnb-when.urg { color: var(--danger, #dc2626); font-weight: 700; }
.tnb-in { font-weight: 800; }
/* LE BOUTON CLIGNOTE EN ROUGE (Jonathan, 29/08). Battement lent et opacite qui ne descend pas au
   point de rendre le mot illisible : c'est un appel, pas une alarme. Coupe net pour qui a demande
   moins d'animations, la couleur rouge suffit alors a le distinguer. */
.tnb-match.tnb-urg .tnb-act { border-color: var(--danger, #dc2626); background: var(--danger, #dc2626);
    color: #fff; animation: tnbUrg 1.6s ease-in-out infinite; }
.tnb-match.tnb-urg .tnb-act:hover { filter: brightness(1.1); }
@keyframes tnbUrg { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .tnb-match.tnb-urg .tnb-act { animation: none; } }
/* Carte ouverte : les joueurs deviennent les choix (le bouton, lui, reste et dit « Replier »). */
.tnb-pick-row { border: 1px solid var(--border); border-radius: 8px; padding: .3rem .45rem;
    cursor: pointer; margin: .12rem 0; }
.tnb-pick-row:hover, .tnb-pick-row:focus-visible { border-color: var(--accent); outline: none; }
.tnb-pick-row.on { border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, transparent); font-weight: 800; }
.tnb-row-pts { margin-left: auto; font-size: .78rem; font-weight: 800; color: var(--accent); }
/* L'ORDRE DANS LA LIGNE (31/08, capture Jonathan). La ligne est une boite flexible et la marque est
   un ::after, donc toujours DERNIERE dans le document : elle atterrissait apres les points, ce qui
   cassait leur alignement en colonne et eloignait la croix du joueur qu'elle juge. On la remet a sa
   place par l'ordre d'affichage, sans toucher au document : joueur, marque, puis les points, qui
   restent colles a droite par leur marge automatique. */
.tnb-row.tnb-choix-ok::after, .tnb-row.tnb-choix-ko::after { order: 1; }
.tnb-row-pts { order: 2; }
/* Le fragment sans duo vainqueur colle a la case au-dessus. */
.tnb-inline-card .tb-more { margin-top: 0; }
/* Le formulaire vit DANS la carte : elle grandit, il n'y a jamais deux cartes. */
.tnb-inline-card { border-top: 1px dashed var(--border); margin: .3rem 0 0; padding: .3rem 0 0; }
/* UN SEUL filet : le formulaire n'ajoute pas le sien par-dessus celui de la carte. */
.tnb-inline-card .tb-more, .tnb-inline-card .tb-form { border-top: 0; margin-top: 0; padding-top: 0; }
.tnb-inline-card .tb-more-open { border: 0; padding: 0; margin: 0; }
/* Formulaire en DEUX LIGNES (28/08 soir) : « Score en sets +6 pts » tient sur UNE ligne, le champ
   vient dessous, pleine largeur. Les libelles ne se cassent plus en trois. */
.tnb-inline-card .tb-fld { display: block; margin: .3rem 0; font-size: .84rem; }
.tnb-inline-card .tb-fld > span { display: block; white-space: nowrap; margin-bottom: .12rem; }
.tnb-inline-card .tb-fld select { display: block; width: 100%; max-width: none;
    padding: .2rem .3rem; font-size: .84rem; }
/* Tie-break : la question et ses points sur une ligne, Oui / Non / ? juste dessous. */
.tnb-inline-card .tb-bool { display: block; margin: .3rem 0 0; font-size: .84rem; }
.tnb-inline-card .tb-bool > span { display: block; white-space: nowrap; margin-bottom: .12rem; }
.tb-bool-opts { display: flex; align-items: center; gap: .9rem; }
.tb-bool-opts label { display: inline-flex; align-items: center; gap: .2rem; white-space: nowrap; }
/* Le pied du formulaire (temoin « Enregistre ») disparait DANS le tableau : le temoin vit en tete
   de carte (28/08 nuit, « il ne devrait pas y avoir deux fois le bouton enregistre »), et le bas
   de carte colle au dernier pari. */
/* PRONOS DES AUTRES DANS LA CARTE (28/08 nuit) : une porte discrete sous le formulaire, qui dit
   combien de joueurs ont deja joue ce match, et la liste qui se deplie dessous. */
/* ESSAI SANS COMPTE SUR LE TABLEAU (28/08 nuit). La ligne du joueur EST le bouton : elle doit donc
   se comporter comme tel, y compris au clavier et au survol. Le choix retenu reprend exactement
   l'aspect « selectionne » de la saisie des membres : ce que le visiteur essaie doit ressembler a ce
   qu'il aura, sinon l'essai ment. */
.tnb-anon-pick { cursor: pointer; border-radius: 8px; padding: .12rem .25rem; }
.tnb-anon-pick:hover { background: rgba(255,255,255,.06); }
.tnb-anon-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tnb-anon-pick.on { background: rgba(43,176,97,.16); box-shadow: inset 0 0 0 1px var(--accent); font-weight: 800; }

/* PRONOS DES AUTRES DANS LA CARTE (28/08 nuit) : une porte discrete sous le formulaire, qui dit
   combien de joueurs ont deja joue ce match, et la liste qui se deplie dessous. */
/* ESSAI SANS COMPTE SUR LE TABLEAU (28/08 nuit). La ligne du joueur EST le bouton : elle doit donc
   se comporter comme tel, y compris au clavier et au survol. Le choix retenu reprend exactement
   l'aspect « selectionne » de la saisie des membres : ce que le visiteur essaie doit ressembler a ce
   qu'il aura, sinon l'essai ment. */
.tnb-anon-pick { cursor: pointer; border-radius: 8px; padding: .12rem .25rem; }
.tnb-anon-pick:hover { background: rgba(255,255,255,.06); }
.tnb-anon-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tnb-anon-pick.on { background: rgba(43,176,97,.16); box-shadow: inset 0 0 0 1px var(--accent); font-weight: 800; }

/* La barre n'apparait qu'APRES le premier prono : elle ne demande pas d'essayer, elle propose de
   garder. Collante en bas comme la barre d'inscription visiteur, dont elle prend la place. */
.tn-anon-bar { position: sticky; bottom: 0; z-index: 8; display: flex; align-items: center; gap: .6rem;
    justify-content: space-between; flex-wrap: wrap; margin: .6rem 0 0; padding: .55rem .8rem;
    border: 1px solid var(--accent); border-radius: 12px; background: var(--card-2);
    box-shadow: 0 -6px 18px rgba(0,0,0,.28); }
.tn-anon-txt { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; font-size: .9rem; }
.tn-anon-n { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem;
    height: 1.5rem; padding: 0 .35rem; border-radius: 999px; background: var(--accent);
    color: var(--on-accent); font-weight: 800; font-size: .82rem; }
@media (max-width: 520px) {
    .tn-anon-bar { flex-direction: column; align-items: stretch; text-align: center; }
    .tn-anon-bar .btn { width: 100%; }
}

/* « INSCRIS-TOI POUR SAUVEGARDER » DANS LA CARTE (28/08 nuit) : il apparait quand le pari est
   complet, et pas avant. Rouge, parce qu'il annonce une PERTE possible (le pari disparait avec le
   navigateur), pas une invitation de plus : c'est la seule couleur du site qui dise ca. */
/* [hidden] D'ABORD, ET CE N'EST PAS UN DETAIL (29/08) : « display: flex » sur l'element ECRASE la
   regle « [hidden] { display: none } » du navigateur. L'encadre s'affichait donc alors qu'il etait
   marque masque, et annoncait « ton pari est complet » sur une carte a 0/4. Toute regle d'affichage
   posee sur un element qu'on masque par attribut doit etre neutralisee explicitement. */
.tn-card-cta[hidden] { display: none; }
.tn-card-cta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: space-between;
    margin: .4rem 0 0; padding: .5rem .6rem; border-radius: 10px;
    border: 1px solid var(--danger, #dc2626); background: rgba(220,38,38,.12); }
.tn-card-cta-txt { font-size: .82rem; font-weight: 700; line-height: 1.25; }
.tn-card-cta-btn { background: var(--danger, #dc2626); border-color: var(--danger, #dc2626); color: #fff;
    font-weight: 800; white-space: nowrap; }
.tn-card-cta-btn:hover { filter: brightness(1.08); }
@media (max-width: 520px) { .tn-card-cta { flex-direction: column; align-items: stretch; }
    .tn-card-cta-btn { width: 100%; text-align: center; } }

.tnb-oth { margin: .35rem 0 0; border-top: 1px dashed var(--border); padding-top: .35rem; }
.tnb-oth-btn { display: inline-flex; align-items: center; gap: .35rem; background: none; border: 0;
    color: var(--muted); font: inherit; font-size: .82rem; font-weight: 700; cursor: pointer; padding: .15rem 0; }
.tnb-oth-btn:hover { color: var(--text); text-decoration: underline; }
.tnb-oth-btn[disabled] { opacity: .55; cursor: progress; }
.tnb-oth-n { display: inline-block; min-width: 1.15rem; text-align: center; padding: 0 .3rem;
    border-radius: 999px; background: var(--card-2); border: 1px solid var(--border);
    font-size: .72rem; font-weight: 800; color: var(--text); }
.tnb-oth-body { margin-top: .3rem; max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }
.tnb-oth-body .cyo-match-title { display: none; }

.tnb-inline-card .tb-form-foot { display: none; }
.tnb-inline-card .tb-form, .tnb-inline-card .tb-more, .tnb-inline-card .tb-more-open { padding-bottom: 0; margin-bottom: 0; }
/* BANNIERE NEUTRE (29/08) : meme encombrement qu'un drapeau (20x15), pour que les noms restent
   alignes, et un aspect volontairement sobre qui ne ressemble a aucun pays. */
.flag-neutral { display: inline-block; width: 20px; height: 15px; vertical-align: -2px;
    border-radius: 2px; border: 1px solid var(--border);
    background: repeating-linear-gradient(135deg, rgba(255,255,255,.10) 0 3px, rgba(255,255,255,.02) 3px 6px); }

/* LA BULLE D'AIDE TIENT TOUTE LA PHRASE (29/08, Jonathan : « il n'y a qu'une petite partie qui est
   encadree »). Elle s'ancrait sur le point d'interrogation, large de 1,1 rem : le cadre se calait sur
   ce point minuscule et la phrase debordait a cote de lui, encadree sur un tiers. Elle s'ancre
   desormais sur la CARTE : bord gauche a bord droit, le texte va a la ligne dedans, et le cadre
   entoure ce qu'il annonce. */
.tnb-inline-card .tb-form { position: relative; }
/* LE « ? » EST UNE CASE A COCHER, PLUS UN <details> (31/08, deuxieme passe). Trois defauts tenaient
   au meme choix. Un <details> est un bloc : dans une etiquette d'une seule ligne il tombait SOUS le
   titre au lieu de rester a cote de « +6 pts ». Son panneau, coince dans cette etiquette, collait au
   menu deroulant. Et il vivait dans le <label> qui enveloppait ce menu : le toucher ouvrait le menu.
   La case a cocher separe les deux : la pastille se pose ou l'on veut, sur la ligne du titre, et le
   panneau reste un bloc plein sous elle.
   AU PASSAGE, LE GLYPHE : a l'ouverture s'affichait un « 2 » (capture Jonathan 31/08). C'etait un
   \2212, le signe moins, dont l'antislash avait disparu dans une edition passee par le shell. */
.tb-q-cb { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; margin: 0; }
/* CENTRE PAR LA BOITE, PAS PAR UNE HAUTEUR DE LIGNE (31/08, releve par Jonathan). Un line-height
   calcule a la main ne centre juste que pour une police et une taille donnees : le « ? » penchait
   vers le haut et le « - » vers le bas. Une boite flexible centre ses deux axes toute seule, quelle
   que soit la police du visiteur. */
.tb-fld-q { display: inline-flex; align-items: center; justify-content: center;
    vertical-align: middle; margin-left: .35rem; cursor: pointer;
    width: 1.15rem; height: 1.15rem; border: 1px solid var(--border); border-radius: 999px;
    line-height: 1; font-size: .75rem; font-weight: 700;
    color: var(--muted); background: var(--card); flex: 0 0 auto; }
.tb-fld-q::after { content: '?'; }
.tb-q-cb:checked ~ * .tb-fld-q { color: var(--accent); border-color: var(--accent); }
.tb-q-cb:checked ~ * .tb-fld-q::after { content: '\2212'; }
.tb-q-cb:focus-visible ~ * .tb-fld-q { outline: 2px solid var(--accent); outline-offset: 2px; }
/* L'AIDE POUSSE, ELLE NE RECOUVRE PAS : en position absolue elle se posait PAR DESSUS le prono
   suivant, on ouvrait une explication et l'on cachait la question d'a cote. Elle occupe sa place
   dans le flux, et garde un vrai blanc avant le menu qu'elle explique (Jonathan 31/08 : « un
   meilleur padding entre l'explication et la drop down list »). */
.tb-fld .tb-fld-help { display: none; }
.tb-q-cb:checked ~ .tb-fld-help { display: block; }
.tnb-inline-card .tb-fld-help, .tb-fld .tb-fld-help { position: static; width: auto; max-width: none;
    white-space: normal; margin: .35rem 0 .6rem; background: var(--card);
    border: 1px solid var(--border); border-radius: 8px; padding: .45rem .6rem;
    font-size: .78rem; line-height: 1.5; color: var(--muted); }
/* LES LIGNES DE LA CASE : statut EN TETE, puis les joueurs, puis date + bouton. */
.tnb-meta { min-height: 1.4rem; }
.tnb-l1 { display: flex; align-items: center; justify-content: space-between; gap: .4rem;
    min-height: 1rem; font-size: .74rem; margin-bottom: .38rem; }
/* Pastille n/N : meme langage que les badges de tour (orange -> vert a la completude). */
.tnb-badge { border: 1px solid var(--warn, #d97706); color: var(--warn, #d97706); font-weight: 800;
    border-radius: 999px; padding: .02rem .4rem; font-size: .7rem; }
.tnb-badge.ok { background: var(--ok, #16a34a); border-color: var(--ok, #16a34a); color: #fff; }
.tnb-pot { color: var(--muted); font-weight: 700; }
/* Le temoin vit sur la ligne de l'heure. Sa hauteur est bornee par celle de la ligne (min-height
   1.4rem) : qu'il apparaisse ou non, rien ne bouge autour. */
.tnb-saved { color: var(--ok, #16a34a); font-weight: 700; margin-left: auto; white-space: nowrap; }
.tnb-meta .tnb-saved + .tnb-score { margin-left: .4rem; }
.tnb-rules-link { margin-left: .4rem; text-decoration: underline; }
/* Simulation super-admin d'un tour termine (rien n'est ecrit en base). */
.tnb-sim { border: 1px dashed var(--border); border-radius: 999px; padding: .05rem .45rem;
    text-decoration: none; font-size: .95rem; line-height: 1.5; }
.tnb-sim.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); }
.tnb-sim-note { margin: 0 0 .35rem; font-size: .76rem; color: var(--muted);
    border-left: 3px solid var(--accent); padding-left: .5rem; }
/* LE BOUTON EN HAUT A DROITE (28/08 nuit) : il ne doit pas etre ecrase par la pastille n/N quand
   la ligne est chargee, ni sauter quand son libelle passe de « Pronostiquer » a « Replier ». */
.tnb-l1-right { flex: 0 0 auto; display: inline-flex; align-items: center; gap: .35rem; }
.tnb-l1-left { min-width: 0; display: inline-flex; align-items: center; gap: .3rem; flex-wrap: wrap; }
.tnb-meta .tnb-score { font-size: .95rem; }
.tnb-won { font-weight: 800; color: var(--muted); }
.tnb-won.ok { color: var(--ok, #16a34a); }
/* Le bouton d'etat : toujours la, il change de role. */
.tnb-act { border: 1px solid var(--border); border-radius: 999px; padding: .1rem .5rem;
    font-size: .74rem; font-weight: 700; text-decoration: none; color: inherit; white-space: nowrap;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.tnb-match:hover .tnb-act { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 0, 0, .18);
    border-color: var(--accent); }
/* UN BOUTON N'EST PAS UN LIEN (31/08, Jonathan : « il ne faut jamais souligner le caption »). Ces
   boutons d'etat sont des <a> pour rester ouvrables dans un nouvel onglet, et la regle generale
   « a:hover { text-decoration: underline } » l'emportait sur leur text-decoration: none, plus faible
   d'un cran. Le survol garde ce qui a du sens sur un bouton : il se souleve, et son fond bouge. */
.tnb-act:hover, .tnb-act:focus, .tnb-act:active { text-decoration: none; }
.tnb-match:hover .tnb-act { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.tnb-match:hover .tnb-act-done { background: #475569; }
.tnb-match:hover .tnb-act.is-save { background: var(--accent); }
.tnb-act.is-save { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.tnb-act-live { border-color: var(--danger, #dc2626); color: var(--danger, #dc2626);
    animation: sm-live-pulse 3s ease-in-out infinite; }
/* MATCH TERMINE (30/08) : une autre couleur, et surtout PAS de clignotement. Ce qui clignote appelle
   un geste ; ici il n'y en a plus a faire, on peut seulement relire ses pronos. Le badge de points
   gagnes, juste a gauche, porte deja la couleur du resultat : ce bouton doit rester discret. */
/* MATCH TERMINE : une autre tete, pas une nuance de gris (31/08). Dans une colonne de soixante
   cases, on doit voir sans lire lesquelles sont jouees. Fond plein et sobre, tres loin du contour
   clair de « Pronostiquer » et du rouge clignotant de « Match en cours ». */
/* UN BADGE QUI NE CHANGE PAS DE NATURE AVEC LE THEME (31/08, deux passes).
   Son fond etait var(--muted), c'est-a-dire un gris CLAIR en mode sombre et un gris FONCE en mode
   clair : il fallait donc une encre differente dans chaque theme, et l'une des deux etait forcement
   fausse. Le matin, Jonathan voyait du blanc sur gris clair ; le soir, du noir sur gris fonce. On
   fige le fond a une ardoise sombre, la meme partout, et le blanc se lit dans les deux thèmes
   (contraste 7:1). Un seul reglage au lieu de deux qui divergent. */
.tnb-act-done { border-color: transparent; background: #475569; color: #fff;
    font-weight: 800; animation: none; }
.tnb-act-done:hover { filter: brightness(1.12); }
@media (prefers-reduced-motion: reduce) { .tnb-act-live { animation: none; } }
/* Encadrement des joueurs : SEULEMENT carte ouverte (on ne peut choisir que la). */
.tnb-match:not(.tnb-active) .tnb-row-pts { display: none; }
.tnb-match:not(.tnb-active) .tnb-pick-row { border-color: transparent; padding-left: 0; padding-right: 0; }
.tnb-match.tnb-active .tnb-pick-row { border-color: var(--border); }
/* La carte ouverte reste COMPACTE : pas de blanc en bas. */
.tnb-match.tnb-active { padding-bottom: .25rem; }
.tnb-inline-card .tb-more-open > *:last-child { margin-bottom: 0; }
@media (max-width: 640px) {
    /* MOBILE (28/08, capture Photo 15:30) : rien ne depasse, le tableau arrive vite. */
    .tnb-col, .tnb-col-champ { flex-basis: min(76vw, 320px); width: min(76vw, 320px); }
    .tnb-head, .tnb-head-champ { flex-basis: min(76vw, 320px); width: min(76vw, 320px); }
    .tnb-card { padding: .5rem .45rem; }
    .tnb-scroll { padding-left: 0; padding-right: 0; }
    .tnb-upd { display: block; margin-top: .1rem; }        /* la date sur SA ligne */
    .tnb-help-extra, .tnb-rules-link { display: none; }     /* l'essentiel seulement */
    .tnb-heads { gap: 10px; }
    .tnb-scroll { gap: 10px; }
    /* LE BALAYAGE CALE TOUJOURS UNE COLONNE ENTIERE A GAUCHE (06/09 soir, Jonathan : « on peut rester
       au milieu d'un tour, on coupe les cartes en deux, ca n'a pas de sens »). Sur PC on voit plusieurs
       colonnes et l'aimantation reste souple ; sur telephone elle est obligatoire : un petit geste
       amene le tour suivant a sa place, jamais entre deux. */
    .tnb-scroll { scroll-snap-type: x mandatory; scroll-padding-left: 0; }
    /* CHAQUE TOUR SE LIT COMPACT (Jonathan 06/09/2026, sur son telephone : « le deuxieme tour reste
       aere [...] toutes ces cartes doivent se compresser avec la premiere en haut et il ne doit plus y
       avoir de blanc »). Le space-around sert l'alignement de l'arbre quand on voit plusieurs colonnes
       cote a cote ; ici on n'en voit qu'une, et il ne faisait qu'etirer trente-deux cases sur la
       hauteur de soixante-quatre. Le premier match de chaque tour est en haut, sans trous. */
    .tnb-col-list { justify-content: flex-start; }
}

[data-comp="usopen"] .tn-res-match { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: .5rem; padding: .4rem .2rem; border-bottom: 1px solid var(--border); }
[data-comp="usopen"] .tn-res-match:last-child { border-bottom: 0; }
[data-comp="usopen"] .tn-res-match .tr-p { display: inline-flex; align-items: center; gap: .35rem; min-width: 0; }
[data-comp="usopen"] .tn-res-match .tr-p:last-child { justify-content: flex-end; text-align: right; }
[data-comp="usopen"] .tr-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
[data-comp="usopen"] .tr-win { font-weight: 800; }
[data-comp="usopen"] .tr-lost { opacity: .5; }
[data-comp="usopen"] .tr-tbd { opacity: .5; font-style: italic; }

/* VUE MATCHS EN ACCORDEON (Jonathan 26/07) : liste VERTICALE des matchs du tour selectionne. Carte fermee =
   compacte et identifiable (2 joueurs + drapeaux + seeds + score si fini + pastille n/N) ; ouverte = TOUS
   les pronos du match. 1 colonne partout (clarte > densite) ; largeur bornee sur grand ecran. */
.tb-rlist { display: flex; flex-direction: column; gap: .55rem; max-width: 700px; }
.tb-acc { border: 1px solid var(--border); border-radius: 10px; background: var(--card); }
.tb-acc[open] { border-color: var(--accent-2); }
.tb-acc-sum { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .45rem .6rem; cursor: pointer; list-style: none; }
.tb-acc-sum::-webkit-details-marker { display: none; }
.tb-acc-main { display: flex; flex-direction: column; gap: .1rem; min-width: 0; flex: 1 1 auto; }
.tb-acc-meta { display: inline-flex; align-items: center; gap: .5rem; flex: 0 0 auto; }
/* La pastille n/N vit EN FLUX dans la ligne (l'absolu ne vaut que dans le bracket .tb-match). */
.tb-acc .tb-badge { position: static; top: auto; right: auto; border-width: 1px; }
.tb-acc-lock { font-size: .95rem; opacity: .75; }
.tb-acc-chev { font-size: .8rem; opacity: .6; transition: transform .18s ease; }
.tb-acc[open] .tb-acc-chev { transform: rotate(180deg); }
.tb-acc-body { border-top: 1px dashed var(--border); padding: .35rem .45rem .45rem; }
.tb-acc-body .tb-form { border-top: 0; margin-top: 0; }
/* Etats : un lisere discret a gauche (vert = complet, orange = a faire/partiel, gris = verrouille/fini). */
.tb-acc-todo, .tb-acc-partial { border-left: 3px solid #e08a1e; }
.tb-acc-done { border-left: 3px solid #1f8a4c; }
.tb-acc-locked, .tb-acc-finished { border-left: 3px solid var(--border); }
.tb-acc-finished .tb-acc-sum { opacity: .85; }
/* CREER UN CONCOURS : cartes-radio d'evenement avec la BULLE de la competition (28/07). */
.cc-ev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: .5rem; }
.cc-ev { display: flex; align-items: center; gap: .55rem; padding: .55rem .7rem; border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); cursor: pointer; font-weight: 700; }
.cc-ev input { position: absolute; opacity: 0; width: 0; height: 0; }
.cc-ev.on { border-color: var(--accent-2); box-shadow: inset 0 0 0 1px var(--accent-2); }
.cc-ev-bub { width: 26px; height: 26px; display: inline-block; flex: 0 0 auto; }
.cc-ev-name { min-width: 0; }

/* LE MOT DES GAGNANTS + REACTIONS (27/07) */
.wn-cta-wrap { text-align: center; margin: .8rem 0 .2rem; }
.wn-cta { font-weight: 800; }
.wn-cta-done { opacity: .85; }
.wn-quotes { margin-top: .9rem; }
.rx-list { display: flex; flex-direction: column; gap: .7rem; }
.rx-item { border: 1px solid var(--border); border-radius: 10px; padding: .6rem .7rem; background: var(--card-2); }
.rx-head { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.rx-role { font-size: .74rem; font-weight: 800; padding: .1rem .5rem; border-radius: 999px; background: rgba(43,176,97,.16); color: var(--accent-ink); border: 1px solid rgba(43,176,97,.4); }
.rx-note { margin: .45rem 0 0; padding: 0 0 0 .7rem; border-left: 3px solid var(--accent-2); font-style: italic; line-height: 1.5; }
.cer-recap-jersey.is-g2 { border-color: #27ae60; }
.cer-recap-jersey.is-g2 .cer-recap-jersey-t { color: #27ae60; }

/* EVENEMENT TERMINE (27/07) : un bouton par concours officiel, compteur integre. Encres FIGEES (hero sombre). */
.hero-done-btn { display: inline-flex; align-items: center; gap: .5rem; }
.hero-done-btn .hero-done-n { font-size: .78rem; font-weight: 700; padding: .12rem .55rem; border-radius: 999px; background: rgba(255,255,255,.16); color: #fff; }

/* PRONOS DU TOURNOI tennis (27/07) : carre final -> finalistes -> champion, en cascade. */
.tt-wrap { max-width: 700px; }
/* Le prix de l'entree tardive (30/08) : annonce avant de remplir, jamais decouvert apres coup. */
.tt-late { margin: 0 0 .6rem; padding: .55rem .7rem; border: 1px solid var(--warn, #d08b1e);
           border-left-width: 4px; border-radius: 8px; background: rgba(208,139,30,.10);
           font-size: .88rem; line-height: 1.45; }
.tt-late strong { display: block; margin-bottom: .15rem; font-size: .95rem; }
.tt-form { border-top: 0; margin-top: 0; padding: 0; gap: .8rem; }
.tt-sec { border: 1px solid var(--border); border-radius: 10px; padding: .6rem .7rem; background: var(--card); }
.tt-h { margin: 0 0 .15rem; font-size: 1rem; }
.tt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .5rem .8rem; }
.tt-sec .tb-fld select { width: 100%; }

/* CHIPS DE FILTRE (tous / a pronostiquer / completes / termines) au-dessus de la liste. */
.tb-flt { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 .6rem; }
/* Chips CARREES (radius 9px, Jonathan 28/07 : les pilules « font tres IA ») : filtres sport, bracket... */
.tb-flt-chip { font: inherit; font-size: .8rem; font-weight: 800; padding: .28rem .7rem; border-radius: 9px; border: 1px solid var(--border); background: var(--card-2); color: var(--text); cursor: pointer; display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }
.tb-flt-chip.on { border-color: var(--accent-2); background: rgba(204, 221, 51, .20); color: var(--accent-ink); }
html[data-theme="light"] .tb-flt-chip.on { background: rgba(127, 145, 9, .16); }
[data-comp="usopen"] .tn-res-mid { text-align: center; font-variant-numeric: tabular-nums; }
[data-comp="usopen"] .tn-res-score { font-weight: 800; }
[data-comp="usopen"] .tn-res-tag { font-size: .7rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); border: 1px solid var(--border); border-radius: 999px; padding: .05rem .4rem; }
[data-comp="usopen"] .tn-res-vs { color: var(--muted); }
[data-comp="usopen"] .tn-res-champ { display: flex; align-items: center; gap: .6rem; padding-top: .3rem; }

/* Barre CTA en tête d'une page concours (contest_cta_bar) : 2 boutons pleins thémés, icône dans la couleur du texte */
.cta-bar { display: flex; flex-wrap: wrap; gap: .6rem; margin: 0 0 1rem; }
/* BARRE D'INVITATION MOBILE (25/08, Jonathan) : deux boutons au-dessus de la carte, MOBILE SEULEMENT.
   En desktop, la colonne d'invitation de la carte est visible d'emblee : la barre serait du bruit. */
.cta-bar-invite { display: none; }
@media (max-width: 860px) {
  .cta-bar-invite { display: flex; flex-wrap: nowrap; }
  .cta-bar-invite .cta-inv { flex: 1 1 0; justify-content: center; min-width: 0; white-space: nowrap;
      overflow: hidden; text-overflow: ellipsis; }
}
.cta-inv-wa { background: #1faf53; color: #fff; border: none; font-weight: 800; }
.cta-inv-wa:hover { background: #178f43; color: #fff; }
.cta-bar .btn { display: inline-flex; align-items: center; gap: .45rem; }
.cta-fill { background: var(--accent); color: var(--on-accent); border: 1.5px solid var(--accent); font-weight: 800; }
.cta-fill:hover { background: var(--accent-2); border-color: var(--accent-2); color: var(--on-accent); }
.cta-line { background: transparent; color: var(--accent-ink); border: 1.5px solid var(--accent-2); font-weight: 800; }
/* Hover SECONDAIRE : voile teinte + bordure pleine, texte encre foncE conserve (JAMAIS d'aplat plein
   qui ferait fondre le texte dans le fond). On DOIT redefinir background sinon .btn:hover le remplit. */
.cta-line:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); border-color: var(--accent); color: var(--accent-ink); }
.cta-plus { font-weight: 900; font-size: 1.2em; color: currentColor; } /* le + prend la couleur du texte (fini le + bleu) */
@media (max-width: 520px) { .cta-bar { flex-direction: column; } .cta-bar .btn { width: 100%; justify-content: center; } }

/* Encart « compétition en préparation » (upcoming_notice) : info prominente en tête des concours à venir. */
.up-notice { border: 1.5px solid color-mix(in srgb, var(--accent-2) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 7%, var(--card)); }
.up-notice-head { display: flex; gap: .6rem; align-items: flex-start; }
.up-notice-ic { font-size: 1.5rem; flex: 0 0 auto; line-height: 1.15; }
.up-notice-title { display: block; font-size: 1.05rem; }
.up-notice-body { margin: .3rem 0 0; color: var(--text); }
.up-notice-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .55rem .8rem; margin-top: .75rem; }
.up-notice-remind-on { color: var(--accent-ink); font-weight: 700; }
.up-notice-more { margin-left: auto; }
.up-notice-more summary { cursor: pointer; color: var(--muted); font-size: .9rem; font-weight: 600; }
.up-notice-more p { margin: .5rem 0 0; color: var(--muted); font-size: .9rem; line-height: 1.5; max-width: 60ch; }
@media (max-width: 520px) { .up-notice-more { margin-left: 0; flex-basis: 100%; } }

/* Reglage expert du concours : UN curseur Competence<->Chance (3 crans) + phrase live + repli.
   Piste degradee semantique bleu(skill)->ambre(chance), independante de l'accent de la competition. */
.xdial { margin: .35rem 0 .1rem; }
.xdial-range { -webkit-appearance: none; appearance: none; width: 100%; height: 8px; border-radius: 999px; outline: none;
    margin: .5rem 0 .35rem; background: linear-gradient(90deg,#4a5bd6,#b9bcc7 50%,#d99414); cursor: pointer; }
.xdial-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%;
    background: var(--accent); border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.35); cursor: pointer; }
.xdial-range::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: var(--accent);
    border: 3px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.35); cursor: pointer; }
.xdial-range:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent); }
.xdial-stops { display: flex; justify-content: space-between; font-size: .82rem; color: var(--muted); font-weight: 700; }
.xdial-stops span { transition: color .15s; flex: 1; }
.xdial-stops span[data-v="1"] { text-align: center; }
.xdial-stops span[data-v="2"] { text-align: right; }
.xdial-stops span.on { color: var(--accent-ink); }
.xdial-live { margin: .55rem 0 0; padding: .55rem .7rem; border-radius: 8px; border: 1px solid var(--border);
    background: rgba(120,130,150,.10); font-size: .92rem; line-height: 1.45; min-height: 2.7em; }
.xdial[data-mode="competence"] .xdial-live { background: rgba(74,91,214,.12); border-color: color-mix(in srgb, #4a5bd6 40%, var(--border)); }
.xdial[data-mode="chance"] .xdial-live { background: rgba(217,148,20,.13); border-color: color-mix(in srgb, #d99414 45%, var(--border)); }
.xdial-how { margin: .5rem 0 0; }
.xdial-how summary { cursor: pointer; color: var(--accent-ink); font-weight: 700; font-size: .9rem; list-style: none; }
.xdial-how summary::-webkit-details-marker { display: none; }
.xdial-how summary::before { content: '▸ '; }
.xdial-how[open] summary::before { content: '▾ '; }
.xdial-how .help { margin-top: .4rem; }
.xdial-note { margin: .2rem 0 .1rem; font-weight: 600; }
/* Barème concret des 3 réglages (chiffres du vrai moteur) : montre que le cadran change le score.
   Cartes cliquables = selectionnent le mode et synchronisent le curseur. */
.xbareme-btn { display: inline-block; margin: .6rem 0 0; background: transparent; border: 1px solid var(--border);
    color: var(--accent-ink); font-weight: 700; font-size: .9rem; padding: .45rem .8rem; border-radius: 8px; cursor: pointer; }
.xbareme-btn:hover { border-color: var(--accent); }
.xbareme { margin: .65rem 0 0; }
.xbareme-intro { margin: 0 0 .55rem; font-size: .9rem; color: var(--muted); line-height: 1.4; }
.xbareme-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: .55rem; }
@media (max-width: 560px) { .xbareme-cards { grid-template-columns: 1fr; } }
.xbareme-card { display: flex; flex-direction: column; gap: .45rem; text-align: left; padding: .7rem .75rem;
    border: 1.5px solid var(--border); border-radius: 10px; background: var(--bg); cursor: pointer;
    transition: border-color .15s, background .15s, box-shadow .15s; font: inherit; }
.xbareme-card:hover { border-color: var(--accent-2); }
.xbareme-card.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--bg));
    box-shadow: 0 0 0 1px var(--accent) inset; }
.xbareme-name { font-weight: 800; font-size: 1rem; color: var(--accent-ink); }
.xbareme-pts { display: flex; flex-direction: column; gap: .2rem; }
.xbareme-row { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; font-size: .9rem; color: var(--muted); }
.xbareme-row b { font-size: 1.2rem; font-variant-numeric: tabular-nums; color: var(--text); }
.xbareme-why { font-size: .82rem; line-height: 1.42; color: var(--muted); }
.xbareme-choose { align-self: flex-start; margin-top: .05rem; font-size: .78rem; font-weight: 800; color: var(--accent-ink);
    border: 1px solid var(--accent-2); border-radius: 6px; padding: .2rem .55rem; }
.xbareme-card.on .xbareme-choose { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* Lien « Pour les matheux » (dans le fold Comment ca marche) -> page simulateur complet. */
.xmatheux-link { display: inline-block; margin: .55rem 0 0; font-size: .86rem; font-weight: 700; color: var(--accent-ink);
    text-decoration: none; border-bottom: 1px dashed var(--accent-2); padding-bottom: 1px; }
.xmatheux-link:hover { border-bottom-style: solid; }

/* Accordeon 2 NIVEAUX « Mes concours » (spec NAV-ACQUISITION-COHERENCE) : Sport (encadre, repliable, fleche
   AVANT) -> Competition (indentee, repliable, une seule ouverte a la fois) -> cartes. */
.mc-caret { color: var(--muted); transition: transform .18s; display: inline-block; font-size: .82em; flex: 0 0 auto; }
[data-open="1"] > .mc-sport-head > .mc-caret, [data-open="1"] > .mc-comp-head > .mc-caret { transform: rotate(90deg); }
/* Niveau SPORT : encadre comme une carte, fleche AVANT le nom. */
.mc-sport { border: 1px solid var(--border); border-radius: 12px; background: var(--card); margin: 0 0 .8rem; overflow: hidden; }
.mc-sport-head { display: flex; align-items: center; gap: .55rem; width: 100%; background: none; border: none;
    cursor: pointer; padding: .8rem .9rem; font: inherit; color: var(--text); text-align: left; }
.mc-sport-name { font-weight: 800; font-size: 1.05rem; }
.mc-sport-emoji { font-size: 1.14rem; }
.mc-sport-ic { width: 27px; height: 27px; object-fit: contain; vertical-align: middle; flex: 0 0 auto; } /* bulle ENTIERE avec sa pointe (contain, jamais cover/cercle) : marque de fabrique */
.mc-sport-count { color: var(--muted); font-size: .85rem; font-weight: 600; margin-left: auto; }
.mc-sport-body { display: none; padding: 0 .9rem .6rem; }
.mc-sport[data-open="1"] .mc-sport-body { display: block; }
/* Niveau COMPETITION : indente sous le sport, repliable. Couleur portee par --cc (data-comp). */
.mc-comp { --cc: #2bb061; } /* defaut foot = vert ScoreMigos */
.mc-comp[data-comp="tour"]   { --cc: #e6b800; }
.mc-comp[data-comp="vuelta"] { --cc: #ff5a6b; }
.mc-comp[data-comp="cl"]     { --cc: #5b9bff; }
.mc-comp[data-comp="usopen"] { --cc: #b6c72a; }
.mc-comp-head { display: flex; align-items: center; gap: .5rem; width: 100%; background: none; border: none;
    cursor: pointer; padding: .55rem .1rem; font: inherit; color: var(--text); text-align: left; border-top: 1px solid var(--border); }
.mc-comp:first-child .mc-comp-head { border-top: none; }
/* Nom de la competition teinte dans SA couleur (melangee au texte pour rester lisible) : indice de couleur
   discret, sans le petit point rond « IA ». */
.mc-comp-label { display: inline-flex; align-items: center; gap: .45rem; font-weight: 800; font-size: .95rem; color: color-mix(in srgb, var(--cc) 42%, var(--text)); }
.mc-comp-ic { width: 22px; height: 22px; object-fit: contain; flex: 0 0 auto; }
/* Bulle THEME-ADAPTATIVE (helper sm_bubble) : rendue en <span> a double background (--bd sombre / --bl clair).
   Encre CLAIRE (flocage « foncé ») par defaut = mode sombre ; en mode clair (data-theme="light") on bascule sur
   l'encre SOMBRE (flocage « clair ») — les vraies versions dessinees, pas une inversion. L'app est SOMBRE par
   defaut (:root), le clair vient TOUJOURS d'un data-theme="light" explicite : on ne keye donc PAS sur
   prefers-color-scheme (sinon un OS clair sans bascule ferait de l'encre sombre sur une page restee sombre). */
/* REGLE DE MARQUE (Jonathan 28/07) : la bulle ScoreMigos s'affiche TOUJOURS ENTIERE, pointe en bas a
   gauche comprise (c'est la marque de fabrique). Fond transparent du PNG, JAMAIS de cercle qui rogne
   (border-radius) ni de zoom qui coupe (cover). Les !important sont le verrou : une classe de taille
   ne doit pas pouvoir re-couper la pointe par heritage. */
.sm-bub { display: inline-block; background-image: var(--bd); background-size: contain !important; background-position: center;
    background-repeat: no-repeat; vertical-align: middle; flex: 0 0 auto; border-radius: 0 !important; }
html[data-theme="light"] .sm-bub { background-image: var(--bl); }
/* Bulle de la COMPETITION dans l'eyebrow de la carte concours (Jonathan 27/07) : systematique 3 sports. */
.ce-bub { width: 18px; height: 18px; display: inline-block; vertical-align: -4px; }
.cp-ic .sm-bub { width: 100%; height: 100%; }
.mc-comp-count { color: var(--muted); font-size: .82rem; font-weight: 600; margin-left: auto; }
/* Pastille « du nouveau » (25/07) : posee sur l'en-tete SPORT puis COMPETITION concernee (remplace l'ancien badge
   global « N avec du nouveau »). Discrete, orange, pulsation douce. Placee AVANT le compteur (margin-left:auto). */
.mc-newdot { width: 9px; height: 9px; border-radius: 50%; background: #ff7a1a; flex: 0 0 auto; margin: 0 .15rem;
    box-shadow: 0 0 0 0 rgba(255, 122, 26, .5); animation: mcNewPulse 2.2s ease-out infinite; }
@keyframes mcNewPulse { 0% { box-shadow: 0 0 0 0 rgba(255, 122, 26, .5); } 70% { box-shadow: 0 0 0 6px rgba(255, 122, 26, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 122, 26, 0); } }
@media (prefers-reduced-motion: reduce) { .mc-newdot { animation: none; } }
.mc-comp-body { display: none; padding: .15rem 0 .7rem; }
.mc-comp[data-open="1"] .mc-comp-body { display: block; }
.mc-comp-flat .mc-comp-body { display: block; } /* mono-competition : jamais repliee */
/* Badges de carte HARMONISES : meme forme plate, FAIBLE saturation (fini l'arc-en-ciel). La teinte est
   melangee au texte -> lisible en clair comme en sombre, look coherent et pro. */
.cc-status, .crh-entry { font-size: .74rem; font-weight: 800; padding: .13rem .55rem; border-radius: 999px; white-space: nowrap; border: none; }
.cc-status-upcoming { background: color-mix(in srgb, #5b7fa6 16%, transparent); color: color-mix(in srgb, #5b7fa6 72%, var(--text)); }
.cc-status-running, .crh-entry-open { background: color-mix(in srgb, #2e9e6a 16%, transparent); color: color-mix(in srgb, #2e9e6a 74%, var(--text)); }
.cc-status-finished { background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--muted); }
.crh-entry-closed { background: color-mix(in srgb, #c0605f 17%, transparent); color: color-mix(in srgb, #c0605f 78%, var(--text)); }
/* La CARTE prend la couleur de sa competition : CONTOUR plein + fond legerement teinte (herite --cc). */
.mc-comp .contest-card { border: 1.5px solid color-mix(in srgb, var(--cc) 58%, var(--border));
    background: color-mix(in srgb, var(--cc) 8%, var(--card)); }
.mc-comp .contest-card + .contest-card { margin-top: .6rem; }
/* Ligne 3 : ta position + « Tu es cite dans le compte rendu » sur la MEME ligne (pas de ligne en plus). */
.crh-foot { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem .8rem; border-top: 1px dashed var(--border); padding-top: .5rem; margin-top: .1rem; }
.crh-foot .crh-mypos { border-top: none; padding-top: 0; }
/* « Cite dans le compte rendu » : meme hauteur que les boutons de la ligne 2 -> aligne verticalement. */
.crh-cited-btn { display: inline-flex; align-items: center; align-self: center; gap: .3rem; padding: .4rem .7rem; line-height: 1.2; font-size: .84rem; font-weight: 800; text-decoration: none; }
/* Ligne 3 : qui organise le concours (admin), tout a DROITE. */
.crh-admin { margin-left: auto; color: var(--muted); font-size: .85rem; font-weight: 600; white-space: nowrap; }
.crh-admin b { color: var(--text); }
/* Indentation des competitions sous leur sport (retrait de chapitre). */
.mc-comp-head, .mc-comp-body { padding-left: 1rem; }
/* « Tous les concours » : la carte n'est pas cliquable en entier (les CTA le sont) -> curseur normal. */
.gk-card2 { cursor: default; }
.gk-card2:active { transform: none; box-shadow: var(--shadow, 0 1px 2px rgba(0,0,0,.14)); }
/* Concours PRIVE sans acces : carte GRISEE (on montre le titre/statut/participants/admin, pas les contenus). */
.gk-locked { opacity: .82; }
.mc-comp .gk-locked.contest-card { border-color: var(--border); background: color-mix(in srgb, var(--muted) 8%, var(--card)); }
.gk-noaccess { font-size: .85rem; color: var(--muted); font-weight: 700; }
.crh-btn-req { background: transparent; border-color: color-mix(in srgb, var(--accent-2) 55%, var(--border)); }
.crh-btn-req:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* (Le bouton Compte rendu a deja une largeur fixe -- .crh-bw-recap .crh-btn min-width -- donc le badge cite reste aligne.) */
/* Carte refonte (Jonathan 24/07) : L1 = TITRE (vrai heading, remplit la largeur) + meta a DROITE sur la meme
   ligne -> robuste quelle que soit la longueur du titre, plus de titre-bouton qui s'etire. */
.crh-headline { display: flex; align-items: baseline; justify-content: space-between; gap: .35rem 1rem; flex-wrap: wrap; }
h3.crh-title { flex: 1 1 12rem; min-width: 0; margin: 0; border: none; padding: 0; background: none; font-weight: 800; font-size: 1.14rem; line-height: 1.3; color: var(--text); }
h3.crh-title:hover { background: none; border: none; }
h3.crh-title .crh-title-txt { white-space: normal; overflow-wrap: anywhere; }
/* Le groupe de meta (statut/role/membres/inscription/etoile) peut RETRECIR et est plafonne a la largeur de la
   carte : sinon, sur MOBILE, le badge « Inscription ouverte » debordait a droite au lieu de passer a la ligne
   (Jonathan 25/07). min-width:0 + max-width:100% -> le flex-wrap interne se declenche dans la carte. */
.crh-headline .crh-group { flex: 0 1 auto; min-width: 0; max-width: 100%; }
/* Bouton « Acceder au concours » : action reine (open) -> plein accent, le plus visible de la ligne. */
.crh-btn-access { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 800; }
.crh-btn-access:hover { background: var(--accent-2); border-color: var(--accent-2); color: var(--on-accent); text-decoration: none; }

/* ── PODIUM FINAL + navigation recompenses (28/07) : lien CONCOURS du recap (gras, souligne,
   hover/focus visibles, clavier OK). Seul le nom est cliquable, pas la phrase. ── */
.cer-recap-contest-link { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.cer-recap-contest-link:hover { color: var(--accent); }
.cer-recap-contest-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Croix du panneau voyage dans le temps (28/07) : masque persistant (chrono super-admin = re-affiche). */
.time-travel .tt-close { position: absolute; top: 4px; right: 6px; width: 22px; height: 22px; border: none;
    background: transparent; color: var(--muted); font-size: 1.05rem; line-height: 1; cursor: pointer; border-radius: 6px; }
.time-travel .tt-close:hover { color: var(--text); background: rgba(255, 255, 255, .08); }
.time-travel .tt-body { position: relative; }

/* Bloc podium DANS le classement (28/07) : alternatifs empiles + « Voir le classement ». */
.pd-actions { display: flex; flex-direction: column; align-items: flex-start; gap: .45rem; margin: 0 0 .55rem; }
.pd-actions .pool-back-link { margin: 0; }
.pd-alt-btn { display: inline-flex; align-items: center; gap: .4rem; }

/* MENU EN DEUX GROUPES (28/07) : ilot de la COMPETITION COURANTE (cadre + bulle) puis liens globaux. */
.nav-grp { display: inline-flex; align-items: center; gap: .7rem; }
.nav-grp-ctx { padding: .18rem .6rem; border: 1px solid var(--border); border-radius: 999px; background: var(--card-2); }
.nav-ctx-ic { width: 17px; height: 17px; flex: 0 0 auto; }
.nav-grp-global { margin-left: .35rem; }
@media (max-width: 700px) {
  .nav-grp { display: flex; flex-wrap: wrap; gap: .55rem .8rem; }
  .nav-grp-ctx { padding: .3rem .6rem; width: fit-content; }
  .nav-grp-global { margin-left: 0; }
}
/* MOBILE panneau burger (<=640, Jonathan 27/07) : PLUS de pilule autour du groupe (l'ovale etirait
   un vilain cercle autour des liens empiles) : l'appartenance a la competition se lit par un LEGER
   fond a sa couleur (accent data-comp) sur chaque lien du groupe. L'etoile SVG laisse sa place au
   lien texte "Mon concours favori" (.show-mobile), qui vit dans le groupe et recoit le meme fond. */
@media (max-width: 640px) {
  .nav-grp { display: contents; }        /* les liens s'empilent comme les globaux, la boite pilule disparait */
  .nav-ctx-ic { display: none; }         /* la bulle : le fond accent marque deja le groupe */
  /* L'etoile mobile DISPARAIT vraiment (Jonathan 28/07 : le lien texte « Mon concours favori » suffit).
     !important : la regle de base .nav-fav-star arrive PLUS BAS dans le fichier et regagnait sinon. */
  .nav .nav-fav-star { display: none !important; }
  /* FONDS de l'ilot : couleur de LA competition, EXPLICITE par comp (fini var(--accent) : en mode
     clair la cascade retombait sur le vert du theme, Jonathan 28/07). Translucide : marche sur le
     panneau sombre ET le panneau blanc du mode clair. */
  .nav .nav-grp-ctx > a { background: rgba(43, 176, 97, .16); border-radius: 8px; } /* defaut : vert (Mondial / sans comp) */
  html[data-comp="tour"] .nav .nav-grp-ctx > a   { background: rgba(245, 197, 24, .22); }
  html[data-comp="vuelta"] .nav .nav-grp-ctx > a { background: rgba(255, 90, 107, .20); }
  html[data-comp="cl"] .nav .nav-grp-ctx > a     { background: rgba(91, 155, 255, .20); }
  html[data-comp="usopen"] .nav .nav-grp-ctx > a { background: rgba(204, 221, 51, .22); }
}

/* Nav : « Competitions » = BLANC + GRAS (jamais la couleur de la competition) ; le header est
   toujours sombre -> blanc constant (regle theme : la surface fige ses encres). */
.nav .nav-plainbold { color: #fff; font-weight: 800; }
/* Accordeons : une competition NON courante est un LIEN (bascule ?event=), meme habillage que le bouton. */
.mc-comp-link { display: flex; align-items: center; gap: .45rem; width: 100%; text-decoration: none; color: inherit; }
.mc-comp-link:hover { text-decoration: none; filter: brightness(1.15); }

/* Etoile CONTEXTUELLE de l'ilot (28/07) : la couleur de LA competition (accent data-comp), plus jamais
   le jaune fixe. Pleine = concours prefere resolu ; vide = rien dans cette competition. */
.nav-fav-star { display: inline-flex; align-items: center; color: var(--accent); flex: 0 0 auto; }
.nav-fav-star:hover { filter: brightness(1.2); }

/* PHRASE CADEAUX commune (28/07, moteur 3 sports) : le cadeau de la carte est un LIEN vers la page
   /maillot ; même encre que le texte fort, soulignement au survol seulement. */
.przl-link { color: inherit; text-decoration: none; }
.przl-link:hover strong, .przl-link:focus-visible strong { text-decoration: underline; }

/* BANNIERE « en preparation » v2 (28/07) : UNE ligne de haut, depliable ; le chevron pivote. */
.up-notice-v2 { padding: .5rem .8rem; }
.up-notice-v2 > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .5rem; }
.up-notice-v2 > summary::-webkit-details-marker { display: none; }
.up-notice-v2 .up-notice-ic { font-size: 1.1rem; }
.up-notice-line-txt { flex: 1 1 auto; min-width: 0; }
.up-notice-chev { flex: 0 0 auto; color: var(--muted); transition: transform .15s ease; }
.up-notice-v2[open] .up-notice-chev { transform: rotate(180deg); }
.up-notice-open { margin-top: .55rem; border-top: 1px solid var(--border); padding-top: .55rem; }
.up-notice-open .up-notice-body { margin: 0 0 .35rem; }
.up-notice-roster { margin: .2rem 0 0; }
.up-notice-v2 .up-notice-actions { margin-top: .55rem; }
@media (prefers-reduced-motion: reduce) { .up-notice-chev { transition: none; } }

/* Page maillot : section « comment les gagner » (28/07). */
.jp-how-list { margin: .3rem 0 .2rem 1.1rem; display: flex; flex-direction: column; gap: .35rem; }
.jp-how .ro-card { margin-top: .6rem; }

/* Carte des chances recruteur : la regle tennis en 3 puces courtes (28/07). */
.ro-rules-list { list-style: none; margin: .55rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.ro-rules-list li { display: flex; gap: .5rem; align-items: baseline; font-size: .95rem; line-height: 1.45; }
.ro-rules-list li > span:first-child { flex: 0 0 auto; }

/* LABEL PRIX compact v2 (28/07) : sous les boutons de la carte, couleurs de la competition,
   pulse discret « pour que ca en jette » ; la page /maillot porte toutes les explications. */
.przl-v2 { display: flex; align-items: center; gap: .65rem; flex-wrap: wrap; margin: .6rem 0 0; }
.przl-badge { display: inline-flex; align-items: center; gap: .45rem; font-weight: 800; font-size: 1.02rem;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent); border-radius: 999px;
  padding: .32rem .85rem; text-decoration: none; animation: przlPulse 2.4s ease-in-out infinite; }
.przl-badge:hover, .przl-badge:focus-visible { filter: brightness(1.12); text-decoration: none; }
.przl-expl { font-weight: 700; font-size: .93rem; white-space: nowrap; }
@keyframes przlPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 40%, transparent); }
  55% { box-shadow: 0 0 0 7px transparent; }
}
@media (prefers-reduced-motion: reduce) { .przl-badge { animation: none; } }

/* Switch mail dans la ligne de la banniere en preparation (28/07). */
.un-mail-sw { flex: 0 0 auto; border: 1px solid var(--border); background: var(--card-2); color: var(--text);
  font: inherit; font-size: .82rem; font-weight: 700; border-radius: 999px; padding: .22rem .65rem; cursor: pointer; }
.un-mail-sw.on { border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.un-mail-sw:hover { filter: brightness(1.1); }
@media (max-width: 640px) { .un-mail-sw { font-size: .78rem; } }

/* Compte a rebours remplace par « A commence le » pendant la competition (28/07). */
.contest-cd-started .contest-cd-label { font-weight: 700; }

/* PIPELINE des cadeaux (/admin/cadeaux v2, 28/07) : 5 etapes Gagne -> Infos -> Commande -> Envoye -> Photo. */
.pz-pipe { display: inline-flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.pz-step { display: inline-flex; align-items: center; gap: .28rem; color: var(--muted); font-size: .78rem; }
.pz-step .pz-dot { width: 1.15rem; height: 1.15rem; border-radius: 50%; border: 1.5px solid var(--border);
  display: inline-flex; align-items: center; justify-content: center; font-size: .68rem; font-weight: 800; }
.pz-step.on { color: var(--text); }
.pz-step.on .pz-dot { background: #1f8a4c; border-color: #1f8a4c; color: #fff; }
@media (max-width: 640px) { .pz-step .pz-lbl { display: none; } }

/* HUB competitions : le compteur dit SA cible (« Tirage au sort dans »...), 28/07. */
.cp-cd-label { display: block; text-align: center; margin: .2rem 0 0; font-weight: 600; }
/* 30/07 (Jonathan) : label + compteur + bouton Jouer centres AUSSI sur desktop (la carte est en flex
   colonne alignee a gauche : sans align-self, text-align ne suffit pas, l'enfant est shrink-to-fit). */
.cp-card .cp-cd-label, .cp-card .cp-cd, .cp-card .cp-cta, .cp-card .cp-cta-soon { align-self: center; }
/* MOBILE : cartes et actions CENTREES (elles collaient a gauche), Jonathan 28/07. */
@media (max-width: 640px) {
  .cp-grid { justify-content: center; }
  .cp-card { align-items: center; text-align: center; margin-left: auto; margin-right: auto; }
  .cp-card .cp-cta, .cp-card .cp-cta-soon { align-self: center; }
  /* La BULLE reste a GAUCHE (Jonathan 28/07) : centree, elle passait SOUS le chip absolu
     « Inscriptions ouvertes » du coin droit. Le reste de la carte demeure centre. */
  .cp-card .cp-ic { align-self: flex-start; }
}

/* Invitation au mot sous le podium (28/07). */
.word-invite { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.word-invite .wi-line { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .7rem; }
.word-invite .wi-cta { flex: 0 0 auto; }

/* Photo jointe a un mot publie (page reactions). */
.rx-photo { max-width: 180px; max-height: 180px; border-radius: 10px; border: 1px solid var(--border); display: block; margin: .45rem 0 .2rem; }
.rx-photo-link { display: inline-block; font-size: .85rem; margin: .3rem 0 .1rem; opacity: .85; }

/* LISTE DES MEMBRES sur mobile (28/07) : la ligne WRAPPE (le « inscrit le » debordait a droite). */
@media (max-width: 640px) {
  .member-line { flex-wrap: wrap; }
  .member-line .mb-joined { margin-left: auto; white-space: nowrap; font-size: .78rem; }
}
/* Banniere en preparation : la rangee de LA ligne (texte + 3 actions) respire et wrappe proprement. */
.up-notice-line { flex-wrap: wrap; row-gap: .4rem; }
.un-help { flex: 0 0 auto; width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 1px solid var(--border);
  background: var(--card-2); color: var(--text); font-weight: 800; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center; }
.un-roster-btn { flex: 0 0 auto; font-size: .82rem; font-weight: 700; border: 1px solid var(--border);
  border-radius: 9px; padding: .22rem .65rem; background: var(--card-2); color: var(--text); text-decoration: none; }
.un-roster-btn:hover { border-color: var(--accent); text-decoration: none; }

/* Badge promesse gratuite des landings pub (30/07) : reprend le vocabulaire exact des ads. */
.pick-free-badge { display: inline-block; margin: .15rem 0 .6rem; padding: .3rem .7rem; border-radius: 999px; font-size: .85rem; font-weight: 700; background: rgba(245, 197, 24, .14); border: 1px solid rgba(245, 197, 24, .45); color: #c9a40f; }

/* Bouton M'inscrire sous le Retour de la liste des membres (30/07) + ancre calee sous le header sticky. */
.mb-join-btn { display: inline-block; margin: .3rem 0 .55rem .6rem; font-weight: 800; }
.scroll-anchor { scroll-margin-top: 84px; }

/* Composant d'etat d'adhesion sous le compte a rebours (30/07) : un seul CTA, ou l'etat inscrit. */
/* Ligne membre « Tu es inscrit » : HAUTEUR COMMUNE IMPOSEE a chaque element (Jonathan 31/07 :
   les reglages fins fuyaient a cause des metriques d'emoji et des paddings de form/button :
   ici chaque enfant est une boite inline-flex de MEME hauteur, contenu centre, line-height 1 :
   plus rien ne peut flotter d'un pixel). */
.join-state { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: .55rem; }
.join-state > * { display: inline-flex; align-items: center; min-height: 1.75rem; line-height: 1; margin: 0; }
.join-state > script { display: none; } /* le reset ci-dessus rendait VISIBLE le JS inline de la
    checkbox (un script n'est masque que par le style navigateur, que > * ecrasait) - bug 31/07 */
.join-state .js-registered, .join-state .js-remind-ck { font-size: 1.02rem; }
.join-state .js-unsub-btn { padding-top: 0; padding-bottom: 0; line-height: 1; }
.join-state .js-remind-help { position: relative; }
.js-registered { font-weight: 800; color: var(--accent-ink, #22a15c); }
.js-unsub-btn { background: none; border: none; color: var(--muted); font-size: .8rem; text-decoration: underline; cursor: pointer; padding: 0; }
.js-claim-link { font-size: .85rem; }
.js-leave-form { display: inline; }

/* Barre collante d'inscription du visiteur anonyme foot/tennis (30/07) : parite avec la barre velo. */
.anon-join-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; background: #0f1115; color: #fff;
    padding: .75rem 1rem; display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    border-top: 1.5px solid rgba(255, 255, 255, .28); box-shadow: 0 -4px 16px rgba(0, 0, 0, .35); }
.anon-join-bar .ajb-txt { font-weight: 700; font-size: .9rem; min-width: 0; }
/* MEME BARRE, AUTRE DISCOURS (28/08 nuit) : quand le visiteur a des pronos d'essai en cours, elle
   passe du « c'est gratuit » au compte de ce qu'il va perdre, et se teinte de l'accent pour qu'on
   voie qu'elle a change. */
.anon-join-bar.has-picks { border-top: 2px solid var(--accent); }
.anon-join-bar .ajb-txt[hidden], .anon-join-bar .ajb-picks[hidden] { display: none; }  /* meme piege */
.anon-join-bar .ajb-picks { display: inline-flex; align-items: center; gap: .4rem; }
.anon-join-bar .ajb-n { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem;
    height: 1.5rem; padding: 0 .35rem; border-radius: 999px; background: var(--accent);
    color: var(--on-accent); font-weight: 800; font-size: .82rem; }
/* MOBILE (Jonathan 31/07) : la barre ne garde QUE le bouton : le texte wrappait sur 6 lignes,
   pave noir violent. Le bouton dit deja tout (« M'inscrire gratuitement »). */
@media (max-width: 700px) {
    .anon-join-bar .ajb-txt { display: none; }
    .anon-join-bar { justify-content: center; padding: .55rem .75rem; }
    .anon-join-bar .btn { width: min(92%, 340px); justify-content: center; }
}

/* Trio d'inscription du visiteur dans la carte (30/07) : Google / email / connexion. */
.join-state-anon { width: 100%; flex-direction: row; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: .5rem; margin-top: .7rem; }
.join-state-anon .js-compact { width: auto; padding: .45rem .85rem; font-size: .88rem; }
.join-state-anon .claim-social { display: inline-flex; align-items: center; }
.js-login-link { font-size: .85rem; color: var(--muted); text-decoration: underline; }

/* Demo pre-tirage tennis (30/07) : un match d'exemple cliquable, le geste explique le jeu. */
.tn-demo-match { display: flex; align-items: center; gap: .7rem; justify-content: center; margin: .6rem 0; }
.tn-demo-p { flex: 1 1 0; max-width: 220px; padding: .7rem .6rem; border-radius: 10px; border: 1.5px solid var(--border);
    background: var(--card-2); color: inherit; font-weight: 700; cursor: pointer; }
.tn-demo-p.is-picked { border-color: var(--accent); background: rgba(43, 176, 97, .14); }
.tn-demo-vs { color: var(--muted); font-weight: 700; }
.tn-demo-done { font-weight: 700; color: var(--accent-ink, #22a15c); }

/* ═══ MODE DECOUVERTE tennis (16/08) : le tableau seede est un TABLEAU D'ESSAI tant que le vrai tirage
   (27/08) n'est pas importe. Banniere au-dessus de la zone de pronos + chip « Match fictif » sur chaque
   affiche + note d'essai pres du statut d'autosave. AMBRE volontairement hors de l'accent competition
   (chartreuse) : la couleur seule dit « pas officiel ». Fond teinte LEGER (rgba) -> les encres restent
   celles du theme ; seuls les chips pleins figent leurs encres (regle « surface fige ses encres »). */
.tn-demo-banner { border-left: 4px solid #e8930c; background: rgba(232, 147, 12, .10); }
.tn-demo-banner-head { margin: 0 0 .4rem; }
/* (17/08, retour Jonathan) : fond plein #e8930c trop fonce pour une encre noire -> fond PALE fige
   (#ffdf9e) + encre brune figee (#4a3203) + lisere ambre : lisible sur les deux themes. */
.tn-demo-chip, .tb-demo-chip { display: inline-flex; align-items: center; gap: .3rem; background: #ffdf9e;
    color: #4a3203; border: 1px solid #e8930c; border-radius: 999px; padding: .1rem .55rem; font-size: .72rem;
    font-weight: 800; letter-spacing: .02em; text-transform: uppercase; }
.tn-demo-banner-body { margin: 0 0 .35rem; font-size: .92rem; line-height: 1.5; }
.tn-demo-banner-wipe { margin: 0; font-size: .8rem; color: var(--muted); line-height: 1.45; }
/* Chip par affiche : a cheval sur le bord haut de la carte FERMEE, discret (petit, sans emoji).
   Carte OUVERTE : masque (17/08 : il empietait sur « Replier ») : la note « Prono d'essai » du
   formulaire porte deja le message a l'interieur. */
.tb-acc { position: relative; }
.tb-acc .tb-demo-chip { position: absolute; top: -.5rem; left: .55rem; z-index: 2; font-size: .6rem;
    padding: .04rem .45rem; }
.tb-acc[open] > .tb-acc-sum .tb-demo-chip { display: none; }
.tb-rlist { padding-top: .4rem; } /* respiration : le chip a cheval de la 1re carte ne touche pas la frise */
.tb-demo-note { font-size: .74rem; font-weight: 700; color: #f0a83c; }
html[data-theme="light"] .tb-demo-note { color: #9a6205; }
/* Aide courte d'un prono Oui/Non (tie-break) : sous la ligne des radios. */
.tb-fld-help { margin: -.15rem 0 .35rem; font-size: .74rem; color: var(--muted); line-height: 1.4; }
/* QUARTS DE TABLEAU (16/08) : chips de navigation quand un tour depasse 16 affiches (1er tour : 64).
   Reutilise le style .tb-flt-chip ; ce sont des LIENS (GET ?sec=), pas des filtres JS. */
.tb-sec-bar { margin-bottom: .35rem; }
.tb-sec-bar .tb-flt-chip { text-decoration: none; display: inline-flex; align-items: center; gap: .35rem; }
.tb-sec-count { font-size: .68rem; font-weight: 800; border-radius: 999px; padding: .05rem .4rem;
    background: var(--card-2); border: 1px solid var(--border); }
.tb-sec-count.done { background: rgba(43, 176, 97, .18); border-color: #2bb061; }
/* TRANSITION apres l'import du vrai tirage : meme structure, accent vert « c'est parti ». */
.tn-real-banner { border-left: 4px solid #2bb061; background: rgba(43, 176, 97, .10); }
.tn-real-chip { display: inline-flex; align-items: center; gap: .3rem; background: #2bb061; color: #06230f;
    border-radius: 999px; padding: .12rem .6rem; font-size: .74rem; font-weight: 800;
    letter-spacing: .02em; text-transform: uppercase; }

/* v4.3 (30/07) : DEUX COLONNES DE MEME HAUTEUR dans la carte. Chaque colonne repartit ses
   lignes verticalement (space-between) : aucun vide en bas a gauche ni en haut a droite.
   Les boutons de droite partagent l'axe central du compteur (colonne centree). */
.card-2col { display: flex; align-items: stretch; gap: 1.1rem; }
/* flex-start et non space-between : la colonne porte maintenant le titre et les boutons en tete,
   space-between les aurait ecartes du prono en etirant les vides (defaut releve par Jonathan). */
.card-main-col { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: .5rem; }
.card-side-col { flex: 0 0 300px; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: .8rem; }
.card-side-col .contest-cd { display: flex; flex-direction: column; align-items: center; gap: .4rem; text-align: center; }
/* margin-top:auto RETIRE (01/08) : il servait a coller les boutons SOUS le compte a rebours quand
   celui-ci partageait la colonne. Le chrono est remonte dans la lecture principale et la decoupe
   2 colonnes ne commence qu'au prono : la colonne droite doit donc se caler EN HAUT, a hauteur du
   prono. Avec margin-top:auto, le maillot etait pousse tout en bas d'une colonne devenue tres haute
   (et ma regle .card-side-prize{margin-top:0}, declaree 5000 lignes plus tot a specificite egale,
   perdait la cascade : le defaut ne se voyait pas dans le CSS mais dans le rendu). */
.card-side-actions { display: flex; flex-direction: column; align-items: stretch; gap: .55rem; width: 100%; max-width: 292px; }
.card-side-actions .btn, .card-side-actions .inv-btn { width: 100%; justify-content: center; text-align: center;
    box-sizing: border-box; display: inline-flex; align-items: center; gap: .45rem;
    border-radius: 9px !important; padding: .55rem .8rem !important; font-size: .88rem !important; font-weight: 700; }
.card-side-actions .inv-btn { animation: none; }
.card-side-actions .claim-social { display: inline-flex; }
/* Le CTA unique au-dessus de la carte, centre (Jonathan 30/07). */
.cta-bar { justify-content: center; }
@media (max-width: 700px) {
    /* MOBILE : l'ordre valide par Jonathan est titre, Description/Membres, chrono, lot, prono,
       maillot. Or le chrono et le lot vivent dans la colonne de DROITE (indispensable sur PC pour
       qu'ils coiffent le maillot sans creuser de vide a gauche). On efface donc les deux conteneurs
       de colonnes (display:contents) : tous leurs enfants deviennent freres dans .card-2col, et
       `order` retablit la lecture voulue. Les selecteurs `>` continuent de fonctionner : contents
       ne supprime que la BOITE, pas le noeud de l'arbre. */
    .card-2col { flex-direction: column; gap: .5rem; }
    .card-main-col, .card-side-col { display: contents; }
    .card-main-col > * { order: 6; }
    .card-side-col > * { order: 7; }
    .card-main-col > .contest-title-row   { order: 1; }
    .card-main-col > .contest-actions-row { order: 2; }
    .card-main-col > .contest-desc-full   { order: 3; }
    .card-side-col > .contest-head-cd     { order: 4; }
    .card-side-col > .przl-v2             { order: 5; }
    .card-side-actions { max-width: 320px; width: 100%; margin-left: auto; margin-right: auto; }
    /* RYTHME VERTICAL MOBILE (Jonathan 01/08). Les marges par defaut de chaque bloc s'ajoutaient au
       gap de la colonne : 17 px sous le titre (trop), 10 px avant le badge (trop peu), 25 px entre
       le badge et le prono (trop, alors que le badge annonce le prono). On regle chaque intervalle. */
    .card-main-col > .contest-actions-row { margin-top: 0; }      /* titre -> boutons : gap seul */
    .card-side-col > .przl-v2 { margin: .35rem 0 0; }             /* chrono -> badge : respire */
    .card-main-col > .fp-wrap { margin-top: 0; }                  /* badge -> prono : colles, ils vont ensemble */
}

/* CTA visiteur SOUS LE TITRE, aligne a gauche comme le reste de la colonne (Jonathan 30/07 :
   meme position dans les 3 sports, fini le bouton qui flotte au centre ou en bas). */
.join-state.js-center { align-self: flex-start; margin: .2rem 0 .1rem; }
/* « TON PREMIER PRONO » (GO Jonathan 30/07) : l'essai sans compte au centre de la carte concours.
   PC : toujours ouvert, summary masque. Mobile : replie derriere une ligne « essaie sans compte ». */
.fp-wrap { margin: .55rem 0 .25rem; }
.fp-summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: .4rem;
    padding: .5rem .85rem; border: 1.5px dashed var(--accent, #2bb061); border-radius: 10px;
    font-weight: 800; font-size: .95rem; color: var(--accent-ink, var(--accent, #2bb061)); }
.fp-summary::-webkit-details-marker { display: none; }
.fp-card { border: 1.5px solid color-mix(in srgb, var(--accent, #2bb061) 45%, transparent);
    background: color-mix(in srgb, var(--accent, #2bb061) 7%, transparent);
    border-radius: 12px; padding: .7rem .85rem .8rem; margin-top: .45rem; }
.fp-title { margin: 0 0 .1rem; font-weight: 800; font-size: 1rem; }
.fp-q { margin: .15rem 0 .5rem; font-size: 1.06rem; font-weight: 700; }
/* LA QUESTION DOMINE + options = BOUTONS DE JEU (visionnages 31/07 : le bloc etait vu mais pas
   joue : il ressemblait a de l'information, pas a un jeu). */
.fp-q-big { font-size: 1.3rem; font-weight: 800; margin: 0 0 .15rem; }
.fp-sub { margin: .1rem 0 .55rem; }
.fp-opt { border-width: 2px; background: var(--card-2, rgba(255,255,255,.85)); box-shadow: 0 1px 3px rgba(0,0,0,.14); }
.fp-opt:active { transform: scale(.97); }
.fp-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .45rem; }
.fp-opt { display: flex; align-items: center; gap: .45rem; padding: .45rem .55rem; cursor: pointer;
    border: 1px solid var(--border, #3f4756); border-radius: 9px; background: var(--card, transparent);
    font: inherit; font-size: .92rem; font-weight: 600; color: inherit; text-align: left; min-width: 0; }
.fp-opt:hover { border-color: var(--accent, #2bb061); }
.fp-opt.is-picked { border-color: var(--accent, #2bb061); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #2bb061) 45%, transparent);
    background: color-mix(in srgb, var(--accent, #2bb061) 14%, transparent); }
.fp-opt-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fp-opt img, .fp-opt .pick-crest { flex: 0 0 auto; }
.fp-more { margin-top: .5rem; width: 100%; padding: .45rem .55rem; border-radius: 9px;
    border: 1px solid var(--border, #3f4756); background: var(--card, transparent); color: inherit; font: inherit; font-size: .92rem; }
.fp-done { margin-top: .5rem; display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
    animation: fpDoneIn .35s ease-out; } /* le message s'ajoute SOUS le bouton fixe : rien ne se deplace */
@keyframes fpDoneIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .fp-done { animation: none; } }
/* BADGE CENTRE SUR SON BOUTON (Jonathan 03/08) : aligne a gauche, le badge designait le bord du
   bouton ; centre, il le montre du doigt. Le conteneur passe en inline-flex pour epouser la largeur
   du bouton (et non celle de la carte), sinon « centre » voudrait dire centre de la page.
   A n'appliquer QUE lorsque le badge surmonte un BOUTON : au-dessus d'un formulaire pleine largeur,
   un badge centre flotterait au milieu de nulle part. */
.ga-stack { display: inline-flex; flex-direction: column; align-items: center; gap: .5rem; }
.fp-cta { margin-top: .55rem; display: inline-flex; flex-direction: column; align-items: center; gap: .5rem; }

/* FLECHES GUIDES (Jonathan 31/07) : LA fleche rouge inclinee qui montre l'action a faire
   MAINTENANT (prono -> compte -> continuer). Pulsation douce, jamais stroboscopique. */
/* BADGE D'ACTION plein (Jonathan 31/07 : « les fleches ne sont pas assez convaincantes ») :
   pastille rouge pleine, texte blanc, halo qui respire : l'autorite d'un guide de jeu mobile. */
/* TAILLE (Jonathan 02/08) : le badge et le bouton se ressemblaient trop, on ne savait plus lequel
   cliquer. Le badge est desormais nettement PLUS PETIT que le bouton qu'il designe : il annonce,
   il n'agit pas. Curseur par defaut et texte non selectionnable pour finir de le desamorcer. */
.ga { display: inline-flex; align-items: center; gap: .35rem; background: #e11d48; color: #fff;
    font-weight: 800; font-size: .82rem; letter-spacing: .01em; padding: .24rem .7rem;
    border-radius: 999px; cursor: default; user-select: none;
    box-shadow: 0 2px 8px rgba(225, 29, 72, .40); animation: gaPulse 1.5s ease-in-out infinite;
    /* Respiration sous le badge (Jonathan 31/07, renforcee le 02/08) : l'animation descend de 3 px.
       La marge basse doit ABSORBER ces 3 px, sinon le badge vient toucher l'element du dessous au
       point bas de la pulsation. Jamais moins que l'amplitude de l'animation. */
    margin: .1rem 0 .75rem; }
/* Rangee « badge + bouton » : le gap tient les deux axes (la rangee passe en colonne sur mobile),
   donc plus besoin d'annuler la marge du badge — c'est cette annulation qui le collait au bouton. */
.js-continue-row .ga { margin: 0; }
.ga[hidden] { display: none !important; } /* SANS ce garde-fou, display bat [hidden] : les DEUX
    fleches restaient visibles en meme temps (bug releve par Jonathan 31/07 sur mobile) */
.ga .ga-arr { display: inline-block; font-size: 1.05rem; line-height: 1; transform: rotate(38deg); }
@keyframes gaPulse {
    0%, 100% { transform: translateY(0); box-shadow: 0 2px 10px rgba(225, 29, 72, .45); }
    50% { transform: translateY(3px); box-shadow: 0 5px 18px rgba(225, 29, 72, .75); }
}
@media (prefers-reduced-motion: reduce) { .ga { animation: none; } }
.card-side-actions .ga { align-self: center; }
.js-continue-row { display: inline-flex; flex-direction: column; align-items: center; gap: .6rem; margin-top: .5rem; }
.js-continue { border-radius: 9px !important; font-weight: 800; }
.login-pick-note { border: 1.5px solid #2ecc71; background: rgba(46, 204, 113, .1); border-radius: 10px;
    padding: .55rem .8rem; font-weight: 700; margin: 0 0 .7rem; }

/* Invitation COMPACTE sous chaque carte de prono (Jonathan 31/07) : le moment de la mise est le
   moment du defi. Une ligne discrete, jamais une carte de plus. */
.invite-inline { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; margin: .5rem 0 1rem; }
.invite-inline-txt { font-weight: 700; font-size: .95rem; }
.inv-btn-sm { padding: .4rem .8rem !important; font-size: .85rem !important; }

/* LA RANGEE D'INVITATION (28/08 nuit) : les memes 4 boutons partout, « en ligne sur desktop et
   l'un sur l'autre sur mobile » (Jonathan). Elle remplace les CTA « Inviter mes amis » qui
   menaient vers une page au lieu d'inviter. */
.invite-row { display: flex; flex-wrap: wrap; gap: .45rem; margin: .1rem 0 0; }
.invite-row .inv-btn { flex: 1 1 auto; justify-content: center; }
.ro-invite-lbl { margin: .6rem 0 .35rem; font-weight: 700; font-size: .95rem; text-align: center; }
@media (max-width: 620px) {
    .invite-row { flex-direction: column; }
    .invite-row .inv-btn { width: 100%; }
}
.fp-done[hidden] { display: none; } /* [hidden] perd contre display:flex sans ce garde-fou */
.join-state[hidden] { display: none; } /* idem : un seul « M'inscrire » a la fois (pick fait -> bouton du bloc) */

/* Bandeau « en preparation » : checkbox changements de liste (verte succes, comme la carte) + seuil. */
.un-roster-ck { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
.un-roster-ck input { width: 1rem; height: 1rem; accent-color: #2ecc71; cursor: pointer; }
.un-roster-days select { padding: .15rem .35rem; border-radius: 7px; border: 1px solid var(--border, #3f4756);
    background: var(--card, transparent); color: inherit; font: inherit; }
.js-cancel-resa { display: block; text-align: center; margin-top: .15rem; text-decoration: underline; opacity: .8; }
.fp-saved { margin: 0; font-weight: 800; color: var(--accent-ink, #22a15c); }
.fp-join { border-radius: 9px !important; }
.fp-summary { display: none; } /* DEPLIE PARTOUT (Jonathan 31/07 : le repli mobile n'etait pas
    compris ; le prono doit etre visible d'emblee, PC comme telephone) */
@media (max-width: 700px) {
    .fp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Espace du message RESERVE des le depart : quand « Prono enregistre : X » apparait, RIEN ne
   descend (le bouton reste exactement ou il etait). */
.fp-done { min-height: 1.75rem; }

/* Cartes competitions : le bouton principal tient sur UNE ligne a 100% de zoom, + espace apres le +. */
.cp-cta { white-space: nowrap; font-size: .93rem; }
.cta-plus { margin-right: .4rem; }

/* Bloc central « place reservee / finalise » + checkbox rappel (30/07 soir). */
.join-state.js-center { flex-direction: row; align-items: center; text-align: left; }
.js-finalize .btn { width: 100%; max-width: 330px; justify-content: center; display: inline-flex; align-items: center; border-radius: 9px; }
.js-reserved { font-weight: 800; font-size: 1.05rem; color: var(--accent-ink, #22a15c); margin: 0; }
.js-remind-ck { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; cursor: pointer; }
.js-remind-ck input { width: 1.05rem; height: 1.05rem; accent-color: #2ecc71; cursor: pointer; align-self: center; }
.js-remind-help { display: inline-block; position: relative; }
.js-remind-help summary { list-style: none; cursor: pointer; width: 1.35rem; height: 1.35rem; border-radius: 50%;
    border: 1.5px solid var(--border); display: inline-flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: .8rem; color: var(--muted); }
.js-remind-help summary::-webkit-details-marker { display: none; }
.js-remind-help[open] .js-remind-help-body { display: block; }
.js-remind-help-body { position: absolute; z-index: 40; top: 1.7rem; left: 50%; transform: translateX(-50%);
    width: 300px; background: var(--card, #171a21); border: 1px solid var(--border); border-radius: 10px;
    padding: .6rem .75rem; font-size: .85rem; font-weight: 500; text-align: left; box-shadow: 0 6px 22px rgba(0,0,0,.35); }

/* Cartes competitions : etat membre (badge inscrit centre) + membres des editions terminees. */
.cp-you-in { align-self: center; font-weight: 800; color: var(--accent-ink, #22a15c); font-size: .9rem; margin-top: .3rem; }
/* « Tu n'es pas inscrit » (24/08) : meme place, meme taille, mais en gris et sans gras. Ce n'est pas
   un reproche ni une alerte, c'est un etat ; le vert reste la recompense de celui qui a franchi le pas. */
.cp-you-out { font-weight: 600; color: var(--muted); }
.cp-done-members { display: block; align-self: center; }
.js-finalize .js-reserved { text-align: center; }

/* Retour en arriere depuis la connexion (Jonathan 02/08) : arriver ici n'est pas une decision prise. */
.lg-back-row { margin: 0 0 .6rem; }
/* Retour au concours au-dessus de la rangee d onglets (Jonathan 02/08) : il sort du cadre pointille
   des pronos, il ne s intercale plus entre l intention et le formulaire. */
.cyc-back-top { margin: 0 0 .5rem; }

/* ── LE CLASSEMENT DÉROULÉ À ZÉRO (Jonathan 03/08) ─────────────────────────────────────────────────
   Rendu partagé foot + tennis du détail d'un joueur avant le coup d'envoi : les groupes du futur,
   repliés, chacun annonçant ce qu'il vaut, toutes leurs lignes à 0. Aucune couleur propre : la
   surface d'accueil (carte foot, carte tennis) fige ses encres, ce bloc ne fait que les porter. */
.zd-wrap { margin: .2rem 0 0; }
.zd-grp { border-top: 1px solid var(--border); }
.zd-grp:first-child { border-top: 0; }
.zd-sum { cursor: pointer; padding: .42rem .1rem; font-size: .9rem; font-weight: 700;
          display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap; }
.zd-title { font-weight: 800; }
.zd-chip { border: 1px solid var(--border); color: var(--muted); border-radius: 999px;
           padding: .06rem .5rem; font-weight: 800; white-space: nowrap; }
.zd-stake { white-space: nowrap; }
.zd-line { display: flex; align-items: flex-start; gap: .55rem; padding: .3rem 0;
           border-bottom: 1px solid var(--border); }
.zd-line:last-child { border-bottom: 0; }
.zd-left { flex: 1 1 0; min-width: 0; }
.zd-right { flex: 0 0 auto; margin-top: .15rem; }
.zd-lbl { font-size: .76rem; line-height: 1.25; }
.zd-tbd { font-style: italic; }
.zd-pick { font-size: .92rem; overflow-wrap: anywhere; }
.zd-empty { font-style: italic; }
.zd-note { margin: .1rem 0 0; }
.zd-total { margin: .45rem 0 .1rem; text-align: right; font-weight: 800; }
.zd-total-stake { font-weight: 600; }

/* ── LE PSEUDO SE SAISIT DANS LA CARTE (Jonathan 03/08) ────────────────────────────────────────────
   Avant, « M'inscrire gratuitement » etait un lien qui expediait sur /j/ : une carte entierement
   differente qui redemandait « Ton pseudo » sans jamais montrer le prono qu'il venait de poser.
   Le champ vit desormais sous son prono. Meme largeur que le bouton, pour lire comme un seul geste. */
.fp-signup { display: flex; flex-direction: column; gap: .4rem; width: 100%; max-width: 320px; margin: 0 auto; }
.fp-pseudo { width: 100%; padding: .62rem .7rem; font-size: 1rem; text-align: center;
             border: 1.5px solid var(--border); border-radius: 9px;
             background: var(--card); color: inherit; }
.fp-pseudo:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.fp-signup .fp-join { width: 100%; }
.fp-signup-note { margin: .35rem 0 0; text-align: center; max-width: 320px; }
.fp-signup-alt { margin: .3rem 0 0; text-align: center; }
.fp-signup-alt a { color: var(--muted); text-decoration: underline; }

/* ── L'APPEL AU RECRUTEMENT (Jonathan 05/08) ───────────────────────────────────────────────────────
   Les quatre boutons de partage vivaient déjà en haut de page et servaient 12 fois par mois pour
   408 joueurs : il ne manquait pas de la place, il manquait une phrase et un compteur. Ce bloc les
   précède. Aucune couleur propre : la carte qui l'accueille fige ses encres. */
.rc-call { border: 2px solid var(--accent); border-radius: 12px; padding: .7rem .8rem; margin: 0 0 .6rem;
           background: var(--card-2); }
.rc-call.rc-done { border-color: #1f8a4c; }
.rc-promise { margin: 0 0 .5rem; font-weight: 800; font-size: .95rem; line-height: 1.3; }
.rc-count { display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; margin: 0 0 .35rem; }
.rc-dot { width: 13px; height: 13px; border-radius: 50%; border: 2px solid var(--border); flex: 0 0 auto; }
.rc-dot-on { background: var(--accent); border-color: var(--accent); }
.rc-done .rc-dot-on { background: #1f8a4c; border-color: #1f8a4c; }
.rc-count-txt { font-weight: 800; font-size: .86rem; margin-left: .25rem; }
.rc-left { margin: 0 0 .5rem; }
.rc-actions { display: flex; flex-direction: column; align-items: stretch; gap: .35rem; }
/* Un seul bouton mis en avant : deux boutons de même poids, c'est un choix à faire, donc une décision
   reportée. WhatsApp domine, le reste devient un lien. */
.rc-btn { display: inline-flex; align-items: center; justify-content: center; padding: .6rem .8rem;
          border-radius: 9px; font-weight: 800; text-decoration: none; background: #25D366; color: #fff; }
.rc-link { background: none; border: 0; padding: .15rem; color: var(--muted); text-decoration: underline;
           font-size: .82rem; cursor: pointer; align-self: center; }
.rc-note { margin: .45rem 0 0; line-height: 1.3; }

/* ── LA FRIME (05/08) : se vanter, pas inviter ─────────────────────────────────────────────────────
   Deux morceaux. .brag-* = le bouton du membre dans la colonne latérale, volontairement plus discret
   que le bloc recruteur au-dessus (la frime est un geste gratuit, pas un objectif). .vg-* = la page
   publique /v/ que voient les destinataires WhatsApp : une carte, deux portes, aucune distraction. */
.brag-cta { margin: .5rem 0 .6rem; padding: .55rem .7rem; border: 1px dashed var(--border);
            border-radius: 10px; text-align: center; }
.brag-title { margin: 0 0 .4rem; font-size: .84rem; font-weight: 700; color: var(--muted); }
.brag-btn { display: inline-flex; align-items: center; justify-content: center; width: 100%;
            padding: .5rem .7rem; border-radius: 9px; font-weight: 800; text-decoration: none;
            background: var(--card-2); color: inherit; border: 1.5px solid #25D366; }
.brag-btn:hover { background: rgba(37, 211, 102, .12); }
.brag-copy { display: block; margin: .35rem auto 0; background: none; border: 0; padding: .1rem;
             color: var(--muted); text-decoration: underline; font-size: .8rem; cursor: pointer; }

.vg-wrap { max-width: 520px; margin: 1rem auto; padding: 0 .6rem; }
.vg-card { text-align: center; padding: 1.2rem 1rem 1.1rem; }
.vg-comp { margin: 0 0 .2rem; letter-spacing: .06em; }
.vg-name { margin: 0 0 .8rem; font-weight: 800; font-size: 1.05rem; }
.vg-big { margin: .1rem 0; font-size: 2.6rem; font-weight: 900; line-height: 1.1; color: var(--accent); }
.vg-pick { font-size: 1.9rem; }
.vg-sub { margin: .2rem 0; font-weight: 700; }
.vg-rank { margin: .25rem 0 0; }
.vg-doors { margin: .9rem 0 0; text-align: center; }
.vg-join { width: 100%; }
.vg-count { margin: .4rem 0 0; }
.vg-create { width: 100%; margin: .45rem 0 0; background: var(--card-2); color: inherit;
             border: 1.5px solid var(--border); }
.vg-create-sub { margin: .3rem 0 0; }

/* ── TEASER « Pronos du tournoi » au tennis (audit 05/08) : l'entrée dit où on en est et l'enjeu. ── */
/* Marges laterales (22/08) : « Pronos du tournoi 0/7 jusqu'a 91 pts » etait colle, les trois
   informations se lisaient comme un seul mot. */
.tn-tour-badge { display: inline-block; border: 1.5px solid #d97706; color: #d97706; border-radius: 999px;
                 padding: .05rem .5rem; margin: 0 .3rem 0 .35rem; font-size: .74rem; font-weight: 800; vertical-align: 1px; }
.tn-tour-badge.is-done { border-color: #1f8a4c; color: #1f8a4c; }
.tn-tour-pts { font-size: .74rem; color: var(--muted); font-weight: 700; white-space: nowrap; margin-left: .2rem; }
/* SUR L'ENTREE ACTIVE, L'ENCRE CHANGE AVEC LE FOND (28/08 nuit, Jonathan : « on ne voit pas la
   police du jusqu'a 91 points »). L'entree selectionnee prend le fond accent, mais ce sous-libelle
   etait reste en --muted : un gris clair pose sur du jaune vif, illisible en theme sombre. Meme
   correction que .tab-day-num juste au-dessus, et meme regle generale : une surface qui pose son
   propre fond doit poser ses propres encres. L'opacite garde la hierarchie (l'enjeu reste
   secondaire par rapport au titre de l'entree) sans sacrifier la lisibilite. */
.tabs a.active .tn-tour-pts { color: var(--on-accent); opacity: .8; }

/* ── LE BADGE « C'EST UNE BLAGUE » (Jonathan 05/08) : la bulle taquine + le CTA .ga en lien.
      PC : centre, la bulle respire ; mobile : compact en haut de page, jamais de debordement. */
.blague { text-align: center; margin: .2rem 0 1rem; padding: .75rem .9rem;
    background: var(--card, #171a10); border: 1.5px dashed #e11d48; border-radius: 14px; }
.blague-taunt { margin: 0 0 .6rem; font-size: 1.06rem; line-height: 1.4; overflow-wrap: anywhere; }
.blague-taunt strong { color: #e11d48; }
/* PREMIERE VISITE (24/08) : meme bulle, ton pose. Le pointille rouge d'alerte laisse la place a la
   bordure ordinaire des cartes : on informe un inconnu, on ne l'interpelle pas. */
.blague-soft { border: 1.5px solid var(--border, #2a2f22); }
a.blague-cta { cursor: pointer; text-decoration: none; margin: 0; }
a.blague-cta:hover { filter: brightness(1.08); }
@media (max-width: 700px) {
    .blague { padding: .55rem .7rem; margin: .15rem 0 .7rem; }
    .blague-taunt { font-size: .93rem; margin: 0 0 .45rem; }
}

/* ── « INCARNER » (05/08) : le select du menu de roles dans la barre super-admin. */
select.sa-role-sel { appearance: auto; font: inherit; font-size: .78rem; font-weight: 700;
    background: #1c2028; color: #ffd400; border: 1px solid #3f4756; border-radius: 999px;
    padding: .12rem .5rem; cursor: pointer; max-width: 12rem; }

/* ── DIALOG DU SITE (05/08) : confirmation au format ScoreMigos (remplace le confirm() navigateur). */
.sm-dialog { border: 1.5px solid var(--border, #3f4756); border-radius: 14px; background: var(--card, #171a10);
    color: inherit; padding: 1.1rem 1.2rem; max-width: 22rem; width: calc(100vw - 2.4rem); }
.sm-dialog::backdrop { background: rgba(8, 10, 6, .62); backdrop-filter: blur(2px); }
.sm-dialog-t { margin: 0 0 .35rem; font-weight: 800; font-size: 1.02rem; }
.sm-dialog-p { margin: 0 0 .85rem; line-height: 1.45; }
.sm-dialog-row { display: flex; gap: .55rem; justify-content: flex-end; }
.sm-dialog-danger { background: #b3261e; color: #fff; }

/* ── OVERLAY MODAL MAISON (06/08, remplace le <dialog> natif qui rendait casse) : plein ecran,
      flex centre, au-dessus de tout. La boite reutilise les classes internes .sm-dialog-*. */
.sm-modal { position: fixed; inset: 0; z-index: 12000; display: flex; align-items: center;
    justify-content: center; background: rgba(8, 10, 6, .62); backdrop-filter: blur(2px); padding: 1.2rem; }
.sm-modal[hidden] { display: none !important; }
.sm-modal-box { background: var(--card, #171a10); color: inherit; border: 1.5px solid var(--border, #3f4756);
    border-radius: 14px; padding: 1.1rem 1.2rem; max-width: 22rem; width: 100%;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .45); }

/* ── BANNIERE « CREE TON COMPTE » (06/08, 3 sports, generalisee du velo) : joueur au pseudo seul. */
.js-claim-banner { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    border: 1px solid #e0a800; background: rgba(245, 197, 24, .10); border-radius: 10px;
    padding: .5rem .75rem; margin: .5rem 0 0; width: 100%; }

/* ═══ FIN DE FICHIER : verrous de contraste (26/08). Un bouton PLEIN garde son encre --on-accent
   dans LES DEUX themes, meme si une regle d'ancre generique ou une variante par competition
   essaie de la voler (onglet selectionne noir sur vert en mode clair, retoque Jonathan).
   .cta-line EXCLU (31/08) : c'est un bouton de CONTOUR, fond transparent, encre --accent-ink
   choisie pour se lire sur le fond de la PAGE. Le verrou lui imposait l'encre des fonds pleins,
   c'est-a-dire du blanc en mode clair sur une carte blanche et une encre sombre en mode sombre sur
   une carte sombre : « Inviter autrement » etait illisible dans les deux themes. Un bouton sans
   fond n'a rien a faire dans un verrou qui parle d'encre SUR un fond. ═══ */
a.btn:not(.btn-ghost):not(.btn-warn-ghost):not(.inv-btn):not(.cta-line),
button.btn:not(.btn-ghost):not(.btn-warn-ghost):not(.cta-line) { color: var(--on-accent); }
a.btn:not(.btn-ghost):not(.cta-line):hover { color: var(--on-accent); }
html[data-theme="light"] .btn:not(.btn-ghost):not(.btn-warn-ghost):not(.cta-line) { color: #ffffff; }
/* Et son encre est dite APRES les verrous, pour qu'aucune variante par competition ne la reprenne.
   --accent-ink est justement la variable definie theme par theme pour du texte sur fond de page. */
.cta-line, .cta-line:hover, html[data-theme="light"] .cta-line { color: var(--accent-ink); }

/* Icone-image en MASQUE (26/08) : le PNG (dessin plein sur transparent) est decoupe et rempli par
   currentColor -> suit la couleur du texte et les deux themes, comme les icones SVG maison.
   DEUX masques (26/08 soir, retour Jonathan « t'as inverse tout ») : au repos (fond clair, encre
   sombre) le ballon = ses TRAITS (--icm-line) ; sur un bouton PLEIN (fond accent, encre claire)
   le ballon = disque MOINS traits (--icm-full), les coutures laissant voir le fond. */
.sm-ic-mask { display: inline-block; background-color: currentColor; vertical-align: -0.12em;
    --icm: var(--icm-line);
    -webkit-mask: var(--icm) no-repeat center / contain; mask: var(--icm) no-repeat center / contain; }
.btn:not(.btn-ghost) .sm-ic-mask,
.btn-primary .sm-ic-mask { --icm: var(--icm-full, var(--icm-line)); }

/* QUI EST ENCORE EN LICE (30/08) : une ligne a l'arrivee, la liste sur demande, un repli en haut ET
   en bas. Deroulee sur cent noms, remonter chercher le bouton du haut serait absurde. */
.tnb-alive { margin: 0 0 .5rem; }
/* <details> natif : le marqueur par defaut du navigateur est masque, le + / - le remplace. */
.tnb-alive-line { display: flex; align-items: center; gap: .4rem; width: 100%; list-style: none;
    background: var(--card); border: 1px solid var(--border); border-radius: 8px;
    padding: .4rem .6rem; font-size: .86rem; font-weight: 600; color: inherit;
    cursor: pointer; text-align: left; }
.tnb-alive-line::-webkit-details-marker { display: none; }
.tnb-alive[open] .tnb-alive-line { border-radius: 8px 8px 0 0; }
.tnb-alive[open] .tnb-alive-chev { visibility: hidden; }
.tnb-alive[open] .tnb-alive-chev::after { content: '\2212'; visibility: visible; }
.tnb-alive-line:hover { border-color: var(--accent); }
.tnb-alive-chev { margin-left: auto; opacity: .7; }
.tnb-alive-body { border: 1px solid var(--border); border-top: 0; border-radius: 0 0 8px 8px;
    padding: .5rem .6rem; background: var(--card); }
.tnb-alive-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: .2rem .7rem; max-height: 46vh; overflow-y: auto; margin-bottom: .5rem; }
.tnb-alive-p { display: flex; align-items: center; gap: .35rem; font-size: .82rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tnb-alive-bottom { border-radius: 8px; }

/* PRONOS FIGES (30/08) : la carte rouverte pendant ou apres le match. Les champs sont desactives,
   donc le navigateur les grise deja ; ce bandeau dit POURQUOI, et ce que le match a rapporte. */
.tb-fige { margin: 0 0 .5rem; padding: .45rem .6rem; border-radius: 8px; font-size: .84rem;
    border: 1px solid var(--border); border-left-width: 4px; line-height: 1.45; }
.tb-fige-live { border-left-color: var(--danger, #dc2626); }
.tb-fige-done { border-left-color: var(--muted, #94a3b8); }
.tb-fige strong { display: block; }
.tb-fige-tot { font-weight: 700; }
.tb-fige-none, .tb-fige-wait { opacity: .85; }
.tb-form-fige .tb-fld, .tb-form-fige .tb-bool { opacity: .85; }
/* Le score set par set : les tie-breaks en exposant, sans casser la hauteur de ligne. */
.tnb-score-sets { font-variant-numeric: tabular-nums; }
.tnb-score-sets sup { font-size: .62em; line-height: 0; margin-left: .05em; opacity: .85; }

/* NOTE D'INCIDENT sur la carte du concours (30/08). Elle ne se contente plus d'informer : elle
   previent que les points affiches sont FAUX pour l'instant. Un joueur qui voit zero sur un prono
   gagnant doit comprendre tout de suite que c'est nous, pas lui. Elle clignote pour cette raison,
   et pour cette raison seulement : c'est une alerte, pas une decoration. */
.tn-notice { margin: .5rem 0; padding: .55rem .7rem; border: 1px solid var(--border);
    border-left: 4px solid var(--danger, #dc2626); border-radius: 8px;
    background: rgba(220,38,38,.10); font-size: .87rem; line-height: 1.5;
    animation: tnNotice 1.8s ease-in-out infinite; }
.tn-notice strong { display: block; margin-bottom: .1rem; }
@keyframes tnNotice {
    0%, 100% { border-left-color: var(--danger, #dc2626); background: rgba(220,38,38,.10); }
    50%      { border-left-color: var(--warn, #d08b1e);   background: rgba(220,38,38,.02); }
}
/* Le clignotement reste une aide, jamais une gene : qui a demande moins d'animation garde le fond. */
@media (prefers-reduced-motion: reduce) { .tn-notice { animation: none; } }

/* LE CLASSEMENT QUI SE DEPLIE (30/08, modele Coupe du monde) : le joueur, puis chacun de ses matchs. */
.lb-tennis .tn-lb-open { display: flex; align-items: center; gap: .35rem; background: none; border: 0;
    padding: 0; color: inherit; font: inherit; cursor: pointer; text-align: left; width: 100%; }
/* ── CLASSEMENT TENNIS : recherche, ma ligne, pages (31/08) ──────────────────────────────────────
   Quatre cent quarante-deux lignes rendues d'un coup pesent et defilent mal. On en montre cent, on
   epingle la ligne du visiteur quand elle n'est pas dans la page affichee, et l'on cherche par
   pseudo. Les trois sont des formulaires et des liens : ils marchent sans script, et le lien de
   page se partage. */
.tn-lb-search { display: flex; gap: .4rem; margin: .1rem 0 .6rem; }
.tn-lb-search input { flex: 1 1 auto; min-width: 0; padding: .45rem .6rem; border-radius: 8px;
    border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; }
/* Ma ligne epinglee : elle doit se voir comme un raccourci, pas comme une ligne de plus. */
.tn-lb-moi { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: 0 0 .6rem;
    padding: .5rem .7rem; border: 2px solid var(--accent); border-radius: 10px;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    color: inherit; text-decoration: none; font-size: .9rem; }
.tn-lb-moi:hover { text-decoration: none; background: color-mix(in srgb, var(--accent) 14%, transparent); }
.tn-lb-moi-rk { font-weight: 900; font-variant-numeric: tabular-nums; }
.tn-lb-moi-nom { font-weight: 800; }
.tn-lb-moi-tag { font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    padding: .05rem .4rem; border-radius: 999px; background: var(--accent); color: var(--on-accent); }
.tn-lb-moi-pts { margin-left: auto; font-weight: 800; font-variant-numeric: tabular-nums; }
.tn-lb-moi-go { flex: 1 0 100%; font-size: .76rem; color: var(--accent-ink); }
.lb-row-moi > td { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.tn-lb-pager { display: flex; align-items: center; justify-content: center; gap: .6rem; margin: .7rem 0 .2rem; }
.tn-lb-pager-txt { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.lb-tennis .tn-lb-chev { margin-left: .25rem; opacity: .6; font-size: .8em; transition: transform .15s ease; }
.lb-tennis .tn-lb-open[aria-expanded="true"] .tn-lb-chev { transform: rotate(180deg); }
/* Une ligne depliee ne doit JAMAIS elargir le classement (08/09) : ce qui depasserait est coupe,
   comme au velo, plutot que de rendre tout le tableau defilable. */
.lb-detail-row > td { padding: 0 !important; background: var(--card); overflow-x: hidden; }
.tn-lb-body { padding: .5rem .6rem; }
.lbd-round { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
    margin: .55rem 0 .2rem; font-weight: 700; font-size: .88rem;
    border-bottom: 1px solid var(--border); padding-bottom: .18rem; }
.lbd-round-pts { font-variant-numeric: tabular-nums; opacity: .85; }
.lbd-day { display: flex; justify-content: space-between; gap: .6rem; margin: .35rem 0 .15rem;
    font-size: .8rem; opacity: .8; }
.lbd-day-pts { font-variant-numeric: tabular-nums; }
.lbd-match { display: flex; align-items: center; gap: .5rem; width: 100%; background: none;
    border: 1px solid transparent; border-radius: 7px; padding: .28rem .35rem; color: inherit;
    font: inherit; cursor: pointer; text-align: left; flex-wrap: wrap; row-gap: .15rem; }
.lbd-match:hover { border-color: var(--border); }
/* UN NOM NE SE COUPE PAS EN DEUX, ET CHAQUE CHOSE A SA PLACE (31/08, deux passes).
   D'abord : le prenom restait en haut, le nom tombait en dessous, et la rature traversait le vide
   entre les deux. Un nom propre est une unite.
   Ensuite, l'ordre de lecture demande par Jonathan : PREMIERE LIGNE l'heure, les deux noms, et tout
   a droite les points, alignes d'une affiche a l'autre ; DEUXIEME LIGNE le score, sous les noms.
   C'est l'ordre des questions : quelle affiche, combien ca m'a rapporte, et pourquoi. */
.lbd-m-names { flex: 1 1 8rem; font-size: .84rem; min-width: 0; }
.lbd-m-names > span { white-space: nowrap; }
.lbd-m-pts { order: 1; margin-left: auto; }
/* flex-basis 100 % : le score prend une ligne pour lui, toujours, et se cale sous les noms en
   sautant la colonne de l'heure. Aligne a gauche, il se lit en descendant la liste. */
/* ET IL CEDE (08/09/2026, Jonathan sur son iPhone : « je peux swiper gauche et droite le classement
   et voir le blanc de part et d'autre »). flex-basis 100 % PLUS une marge de 3,35 rem, sans droit de
   retrecir (flex-shrink 0) : le score depassait le bouton de 37 px des qu'une ligne du classement
   etait depliee, et ce depassement rendait tout le classement defilable de 37 px, avec le rebond
   blanc d'iOS des deux cotes. Mesure a 414 px (iPhone 11) : classement 366 px, contenu 403 px.
   Avec flex-shrink 1 et min-width 0, le score prend la ligne moins la marge, jamais plus. */
.lbd-m-score { order: 2; flex: 1 1 100%; min-width: 0; margin-left: 3.35rem; text-align: left; }
.lbd-m-score:empty { display: none; }
/* La pastille EN COURS n'est pas un score : elle reste sur la premiere ligne, a cote des points,
   parce qu'elle repond a « ou en est cette affiche » et non a « comment elle s'est finie ». */
.lbd-m-score.est-live { order: 0; flex: 0 0 auto; margin-left: auto; }
.lbd-vs { opacity: .5; margin: 0 .2rem; }
.lbd-lost { text-decoration: line-through; opacity: .6; }
.lbd-m-score { font-size: .78rem; font-variant-numeric: tabular-nums; opacity: .85; white-space: nowrap; }
.lbd-m-score sup { font-size: .62em; line-height: 0; }
.lbd-m-pts { font-size: .82rem; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 2.6em; text-align: right; }
.lbd-m-pts.ok { color: var(--ok, #16a34a); }
.lbd-picks { padding: .1rem 0 .35rem 1rem; border-left: 2px solid var(--border); margin-left: .35rem; }

/* ── LE CLASSEMENT PARLE LA LANGUE DU TABLEAU (31/08) ────────────────────────────────────────────
   Jonathan, en depliant un match : « highlight celui qu'on a highlighte, et si apres il a perdu,
   l'autre est barre ». On reprend donc EXACTEMENT les marques de la carte du tableau, y compris la
   regle qui a demande trois passes la-bas : la coche et la croix sont a MOI, jamais au vainqueur,
   que le vert du nom et la rature de l'adversaire disent deja. Une seule grammaire sur tout le site. */
.lbd-mon-choix { background: color-mix(in srgb, var(--accent) 14%, transparent);
    border-radius: 6px; padding: .05rem .3rem; font-weight: 800; }
.lbd-choix-ok::after { content: '\2713'; margin-left: .3rem; color: var(--ok, #16a34a); font-weight: 900; }
.lbd-choix-ko::after { content: '\2715'; margin-left: .3rem; color: var(--danger, #dc2626); font-weight: 900; }
/* LA CROIX N'EST PAS BARREE (Jonathan 06/09) : la rature du perdant traversait aussi le symbole,
   qui vit dans le meme span. Une boite inline-block n'herite pas du trait de son parent : la barre
   s'arrete au nom, la croix rouge reste entiere. Meme traitement pour la coche, par symetrie. */
.lbd-choix-ok::after, .lbd-choix-ko::after { display: inline-block; text-decoration: none; }
/* Un match qui se joue EN CE MOMENT clignote : c'est le seul de la liste dont le resultat peut
   encore changer pendant qu'on le regarde. */
.lbd-match.lbd-live { border-left: 3px solid var(--danger, #dc2626); padding-left: .35rem; }
.lbd-live-dot { display: inline-block; padding: .05rem .4rem; border-radius: 999px; font-size: .68rem;
    font-weight: 800; text-transform: uppercase; letter-spacing: .02em;
    color: var(--danger, #dc2626); border: 1px solid currentColor;
    animation: sm-live-pulse 3s ease-in-out infinite; }
/* ── LE SCORE EN DIRECT (31/08) ──────────────────────────────────────────────────────────────────
   « Une autre couleur que les scores finaux, et un clignotement leger pour bien comprendre que
   c'est du live. » Leger est le mot : ce battement vit a cote d'une liste qu'on lit, il doit se
   remarquer sans happer. Une opacite qui descend a 55 % en trois secondes suffit ; en dessous, cela
   devient un stroboscope et l'on ne lit plus rien autour. */
.tnb-score-live { color: var(--danger, #dc2626) !important; font-weight: 800;
    animation: sm-live-pulse 3s ease-in-out infinite; }
.tnb-live-tag { font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    opacity: .9; }
/* UN SEUL BATTEMENT, LENT, PARTAGE PAR LES TROIS MARQUES DU DIRECT (31/08, deuxieme passe).
   Jonathan : « ca devrait rester plus longtemps affiche avant de clignoter, on n'arrive pas a bien
   lire ». Il avait raison sur les deux points. Le rythme d'abord : un aller-retour toutes les une
   seconde et demie est un stroboscope, on ne lit pas un score qui palpite. Le cycle dure six
   secondes et le texte reste PLEIN pendant plus de cinq : la respiration ne prend que le dernier
   sixieme, ce qui suffit a dire « ce nombre va changer » sans empecher de le lire.
   Et la synchronisation : le score en direct, la pastille « en cours » du classement et le bouton
   « Match en cours » partagent maintenant la MEME animation, donc le meme rythme et la meme phase.
   Trois marques du meme fait qui battaient chacune a son tempo donnaient une page nerveuse. */
@keyframes sm-live-pulse {
    0%, 66% { opacity: 1; }   /* deux secondes pleines : le temps de lire le score sans effort */
    83%     { opacity: .5; }  /* une seconde de respiration, pas davantage */
    100%    { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .tnb-score-live, .lbd-live-dot { animation: none; }
}
@media (prefers-reduced-motion: reduce) { .lbd-live-dot { animation: none; } }
/* QUAND se joue l'affiche : sa propre encre, en tete du deplie, avant les quatre pronos. */
.lbd-when { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    margin: .1rem 0 .35rem; font-size: .76rem; color: var(--accent-ink); }
.lbd-when-t { opacity: .75; }
.lbd-when-v { font-weight: 700; font-variant-numeric: tabular-nums; }
.lbd-go { margin-left: auto; }
/* Le formulaire deplie DANS le classement : encadre, decale, pour qu'on voie qu'il appartient a
   l'affiche au-dessus et pas a la liste. */
.lbd-form-slot:empty { display: none; }
.lbd-form-slot { margin: .4rem 0 .5rem; }
.lbd-form { border: 1px solid var(--accent); border-radius: 10px; padding: .55rem .7rem;
    background: color-mix(in srgb, var(--accent) 6%, transparent); }
.lbd-form .tb-fld { display: block; margin: .35rem 0; }
.lbd-form .tb-fld select { display: block; width: 100%; max-width: none; margin-top: .15rem; }

/* ── LA JOURNEE EST UNE SEPARATION (31/08, deuxieme passe) ───────────────────────────────────────
   « J4, au-dessus il doit y avoir une ligne qui separe. Et le J3 doit etre en gras et dans une
   autre couleur. » Dans une liste de cent vingt affiches, la date est le seul reperage qui tienne :
   elle ne peut pas se lire comme un match de plus. */
.lbd-day { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
    margin: 1.1rem 0 .35rem; padding-top: .55rem; border-top: 2px solid var(--border); }
.lbd-day:first-of-type { margin-top: .4rem; }
.lbd-day-lab { font-size: 1rem; font-weight: 800; color: var(--accent-ink);
    letter-spacing: .01em; }
.lbd-day-pts { font-size: .8rem; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.lbd-day-pts.ok { color: var(--accent); }
/* L'heure devant l'affiche : colonne fixe, chiffres alignes, pour que l'oeil descende droit. */
.lbd-m-h { flex: 0 0 3.1rem; font-size: .74rem; font-weight: 700; color: var(--muted);
    font-variant-numeric: tabular-nums; }
/* Ce qui vient porte la marque de l'accent, ce qui se joue celle du direct : deux etats, deux
   encres, et rien du tout pour ce qui est deja joue, que le cadre du vainqueur signale. */
.lbd-match.lbd-soon { border-left: 3px solid var(--accent); padding-left: .35rem; }
/* ON ENCADRE LE VAINQUEUR, comme au foot : sur une liste longue, l'oeil cherche ce qui est marque. */
.lbd-win { border: 1px solid var(--ok, #16a34a); border-radius: 6px; padding: .02rem .3rem;
    color: var(--ok, #16a34a); }
/* Ce qui ne compte pas, dit une fois, en bas, sans crier. */
.lbd-exclus { margin: .9rem 0 .1rem; padding: .5rem .65rem; border: 1px dashed var(--border);
    border-radius: 8px; font-size: .78rem; color: var(--muted); line-height: 1.5; }
/* « Pronos caches » : une ligne discrete, pas une alerte. Ce n'est pas un incident, c'est la regle
   du jeu, et elle vaut pour tout le monde dans les deux sens. */
.lbd-secret { margin: .2rem 0 .35rem; font-size: .78rem; color: var(--muted); font-style: italic; }
/* Le tarif des pronos de tournoi : vert quand il est plein, sobre quand il est ampute. */
.tt-late-full { border-color: var(--ok, #16a34a) !important;
    background: color-mix(in srgb, var(--ok, #16a34a) 8%, transparent) !important; }
.tt-late-fige { display: block; margin-top: .3rem; font-size: .76rem; opacity: .8; }
.lbd-match[disabled] { opacity: .82; cursor: default; }

/* ── « IL EST ENCORE TEMPS » (31/08) ─────────────────────────────────────────────────────────────
   C'est le premier bloc que voit un visiteur venu d'un fil de discussion pendant le tournoi. Il doit
   se lire en trois secondes et finir sur un bouton : le titre, la regle en une phrase avec son
   chiffre, le lot, le bouton. Rien d'autre, et surtout aucune animation : ce qui clignote a cote
   d'un appel a l'action lui vole l'attention qu'il demande. */
.tn-still { margin: .6rem 0 .5rem; padding: .75rem .9rem; border: 2px solid var(--accent);
    border-radius: 12px; background: color-mix(in srgb, var(--accent) 8%, transparent); }
.tn-still-h { margin: 0 0 .25rem; font-size: 1.02rem; }
.tn-still-b { margin: .18rem 0 0; font-size: .87rem; line-height: 1.5; color: var(--text); }
.tn-still-prize { color: var(--accent-ink); font-weight: 700; }
.tn-still-cta { margin: .6rem 0 0; }
.tn-still-btn { font-weight: 800; padding: .5rem 1.1rem; }
/* « C'est repare » : sobre, sans clignotement. La note qui la precedait clignotait parce qu'elle
   annoncait un defaut ; celle-ci annonce sa fin, et ce qui clignote a cote d'une bonne nouvelle la
   fait lire comme une mauvaise. */
.tn-fixed { margin: .55rem 0; padding: .7rem .85rem; border: 1px solid var(--ok, #16a34a);
    border-radius: 10px; background: color-mix(in srgb, var(--ok, #16a34a) 7%, transparent); }
.tn-fixed-h { margin: 0 0 .2rem; font-size: .95rem; }
.tn-fixed-b { margin: .15rem 0 0; font-size: .84rem; line-height: 1.5; color: var(--text); }
.tn-fixed-cta { margin: .5rem 0 0; }
/* La nouveaute se detache du reste : c'est la seule ligne de cette carte qui apporte quelque chose
   au joueur plutot que de s'excuser, et elle doit se lire meme en diagonale. */
.tn-fixed-neuf { margin: .5rem 0 .1rem; padding: .5rem .65rem; border-radius: 9px;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border-left: 3px solid var(--accent); font-size: .89rem; line-height: 1.5; }
.tn-fixed-l { margin: .35rem 0 0; padding-left: 1.1rem; font-size: .87rem; line-height: 1.55; }
.tn-fixed-l li { margin: .3rem 0; }
.tn-fixed-pc { color: var(--accent-ink); white-space: nowrap; }
.tn-fixed-cta { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

.lbd-pick { display: flex; align-items: baseline; gap: .45rem; font-size: .8rem; padding: .12rem 0; }
.lbd-pick-t { flex: 0 0 auto; opacity: .7; min-width: 7.5em; }
.lbd-pick-v { font-weight: 600; }
.lbd-pick-v.barre { text-decoration: line-through; opacity: .65; font-weight: 400; }
.lbd-pick-r { opacity: .9; }
.lbd-pick-p { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 700; }
.lbd-pick.ok .lbd-pick-p { color: var(--ok, #16a34a); }
.lbd-pick.ko .lbd-pick-p { opacity: .55; }

/* LES COMPTES RENDUS DE JOURNEE (30/08) : une frise de pastilles, puis le recit. */
.trc-strip { margin: 0 0 .7rem; }
.trc-date { opacity: .65; font-size: .82em; margin-left: .25rem; }
.trc-body h3 { font-size: 1.02rem; margin: .2rem 0 .5rem; }
.trc-body h4 { font-size: .92rem; margin: .9rem 0 .3rem; opacity: .9; }
.trc-body ul { margin: .2rem 0 .6rem; padding-left: 1.1rem; }
.trc-body li { margin: .18rem 0; font-size: .88rem; line-height: 1.5; }
.trc-body p { margin: .3rem 0; font-size: .88rem; line-height: 1.55; }

/* LA LISTE DES JOUEURS ENCORE EN LICE (31/08) : une seule colonne sur mobile, ou deux colonnes
   tronquees ne montrent que des noms coupes ; le rang mondial discret, la tete de serie en couleur
   parce que c'est une distinction du tournoi et non un classement. */
.tnb-alive-rank { opacity: .6; font-size: .82em; white-space: nowrap; }
.tnb-alive-seed { color: var(--accent); font-weight: 700; }
@media (max-width: 640px) {
    .tnb-alive-grid { grid-template-columns: 1fr; max-height: 60vh; }
    .tnb-alive-p { white-space: normal; }
}

/* MON CHOIX DE VAINQUEUR, VISIBLE CARTE FERMEE (31/08). Il n'apparaissait qu'a l'ouverture, pose par
   le JavaScript : impossible de relire sa grille d'un coup d'oeil, ce qui est pourtant l'usage
   principal d'un tableau. Marque desormais cote serveur, dans tous les etats. */
/* MON CHOIX : un fond franchement plus sombre, qui se lit d'un coup d'oeil sans rien annoncer sur le
   resultat. AUCUN symbole ici : la coche veut dire « a gagne », et la poser sur une selection
   reviendrait a feliciter quelqu'un d'avoir clique. */
/* Teinte d'ACCENT et non un voile noir (31/08, deuxieme passe) : le noir a 32 % assombrissait toute
   la ligne et ecrasait le nom. On revient a la teinte d'origine, a peine renforcee (8 % -> 14 %) :
   assez pour reperer sa selection d'un coup d'oeil, pas assez pour peser sur le texte.
   La premiere declaration sert de repli aux navigateurs sans color-mix. */
/* Le fond seul (31/08, troisieme passe) : le lisere vert a gauche alourdissait la ligne pour ne
   rien dire de plus que la teinte. Quand deux marques disent la meme chose, on en garde une. */
.tnb-row.tnb-mon-choix { position: relative; background: rgba(163, 230, 53, .14); border-radius: 6px; }
.tnb-row.tnb-mon-choix { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.tnb-row.tnb-mon-choix .tnb-name { font-weight: 800; }
/* LES DEUX MARQUES SONT A MOI, ET SEULEMENT A MOI (Jonathan 31/08, capture a l'appui : « je vois
   que tu mets des checks a cote du joueur gagnant par defaut »). Le vainqueur est deja dit par le
   vert de son nom et par la rature de son adversaire : une coche de plus n'ajoutait rien, et elle
   entrait en concurrence avec la seule chose que la coche doit vouloir dire ici, qui est « TU avais
   vu juste ». La coche verte parait donc sur MA selection quand elle a gagne, la croix rouge sur MA
   selection quand elle a perdu, et rien nulle part ailleurs. */
.tnb-row.tnb-choix-ok::after { content: '\2713'; margin-left: .35rem; color: var(--ok, #16a34a);
    font-weight: 900; font-size: .95em; }
.tnb-row.tnb-choix-ko::after { content: '\2715'; margin-left: .35rem; color: var(--danger, #dc2626);
    font-weight: 900; font-size: .95em; }

/* L'ETAT DE LA CARTE SE LIT A SON CONTOUR (31/08) : dans une colonne de soixante cases, il faut voir
   sans lire quelles affiches sont jouees, lesquelles sont en cours, lesquelles attendent. Un liseré
   a gauche suffit et n'entre en concurrence avec rien d'autre dans la carte. */
.tnb-match.tnb-st-done { border-left: 3px solid var(--muted, #64748b); }
.tnb-match.tnb-st-live { border-left: 3px solid var(--danger, #dc2626); }
/* « resultat en attente » (01/09) : commence, sans resultat, et depuis trop longtemps pour qu'on
   parle encore d'un direct. Un ambre neutre, ni le rouge du direct ni le gris du termine. */
.tnb-match.tnb-st-wait { border-left: 3px solid #b45309; }
.tnb-match.tnb-st-todo { border-left: 3px solid var(--accent); }

/* LA BONNE REPONSE, une fois le match joue (31/08). La fiche disait « 0 pts » et s'arretait la : on
   savait qu'on avait perdu, jamais de combien on s'etait trompe. */
/* LA BONNE REPONSE : une pastille, pas une phrase (31/08). « la bonne reponse : 3-0 » prenait une
   ligne entiere pour deux caracteres utiles. Entouree de vert, elle se lit sans etre lue. */
.tb-fld-vrai { display: inline-block; margin-left: .4rem; font-style: normal; font-size: .76rem;
    color: var(--ok, #16a34a); font-weight: 800; border: 1px solid var(--ok, #16a34a);
    border-radius: 999px; padding: .02rem .45rem; white-space: nowrap; }
/* LE TIE-BREAK SUIT LA MEME REGLE QUE LES AUTRES (31/08, deuxieme passe). On entourait « Oui » ou
   « Non » directement, c'est-a-dire les cases que le joueur a cochees : on marquait SON geste au
   lieu de donner LA reponse. La bonne reponse se reecrit desormais au-dessus, dans la meme pastille
   que partout ailleurs, et les deux options restent telles qu'il les a laissees. */

/* La carte fermee se clique en entier (31/08) : le curseur doit le dire, sinon on continue de viser
   le petit bouton. Ouverte, elle redevient une zone de saisie ordinaire. */
.tnb-match:not(.tnb-active):not(.tnb-st-tbd) { cursor: pointer; }
.tnb-match.tnb-active { cursor: default; }

/* LE FILTRE PAR ETAT, dans l'entete de chaque tour (31/08). Discret tant qu'il ne filtre rien, net
   des qu'il agit : sinon on oublie qu'une colonne est filtree et l'on croit des cartes disparues. */
.tnb-head-filtre { margin-left: .35rem; font-size: .72rem; padding: .05rem .3rem;
    border: 1px solid var(--border); border-radius: 6px; background: var(--card);
    color: var(--muted); max-width: 8.5rem; }
.tnb-head-filtre.est-actif { border-color: var(--accent); color: var(--accent); font-weight: 700; }
/* La parenthese d'une tete de serie se distingue par la couleur, sans changer l'ordre de la liste. */
.tnb-alive-rank.est-serie { color: var(--accent); opacity: 1; font-weight: 700; }

/* LA CARTE QUI EXPLIQUE UN FILTRE ACTIF (31/08) : sans elle, une colonne vide passerait pour un
   tableau casse. C'est la difference entre cacher et expliquer. */
.tnb-filtre-note { border: 1px dashed var(--accent); border-radius: 10px; padding: .6rem .7rem;
    background: var(--card-2); font-size: .82rem; line-height: 1.5; }
.tnb-filtre-note p { margin: 0 0 .5rem; }

/* MASQUER UNE CARTE DU TABLEAU (31/08). L'attribut hidden ne suffit pas : « .tnb-match { display:
   block } » l'ecrase, et le filtre semblait mort alors qu'il faisait son travail. */
.tnb-match.tnb-masque, .tnb-filtre-note.tnb-masque { display: none !important; }


/* « ENCORE EN LICE » : REPLIEE PAR DEFAUT (31/08). Cent onze pastilles occupaient plusieurs ecrans
   de telephone AVANT le tableau. <details> natif : aucun script, donc cela marche partout. */
.tb-stillin > .tb-stillin-sum { display: flex; align-items: center; gap: .4rem; cursor: pointer;
    list-style: none; font-weight: 700; font-size: 1rem; margin: 0; }
.tb-stillin > .tb-stillin-sum::-webkit-details-marker { display: none; }
/* LE MEME « 2 » QUE LE « ? » DES PRONOS (31/08) : un \2212 dont l'antislash avait disparu dans une
   edition passee par le shell, ce qui laissait un caractere de controle suivi d'un « 2 ». Les deux
   etats passent desormais par ::after, et le glyphe n'existe qu'a un seul endroit : on ne peut plus
   en reparer un et oublier l'autre. */
.tb-stillin-chev { margin-left: auto; opacity: .7; font-weight: 900; }
.tb-stillin-chev::after { content: '+'; }
.tb-stillin[open] .tb-stillin-chev::after { content: '\2212'; }
.tb-stillin[open] .tb-stillin-list { margin-top: .6rem; max-height: 60vh; overflow-y: auto; }
/* La tete de serie se signale par la COULEUR, le simple classe reste discret. */
.tb-seed.est-serie { color: var(--accent); font-weight: 700; }
.tb-seed.est-rang { opacity: .65; font-weight: 400; }
@media (max-width: 640px) { .tb-stillin-list { display: flex; flex-direction: column; } }

/* ------------------------------------------------------------------------------------------------
   LE FUSEAU HORAIRE, DIT AU-DESSUS DES HEURES (02/09/2026).
   Discret par construction : c'est une precision, pas une annonce. Il ne doit jamais concurrencer
   du regard le classement ou le tableau sous lequel il se trouve. Le selecteur reste plie.
   ------------------------------------------------------------------------------------------------ */
.tz-note { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem;
           margin: 0 0 .7rem; font-size: .82rem; color: var(--muted); }
.tz-note-lab { white-space: nowrap; }
.tz-note-go { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
.tz-pick > summary { cursor: pointer; list-style: none; opacity: .8; text-decoration: underline;
                     text-underline-offset: 2px; }
.tz-pick > summary::-webkit-details-marker { display: none; }
.tz-pick[open] > summary { opacity: 1; }
.tz-form { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-top: .45rem; }
.tz-form select { max-width: 16rem; }
/* 11/09 : la note gardait .82rem partout SAUF sur telephone, ou elle descendait a 12,5 px. C'est
   exactement l'inverse de ce qu'il faut : discrete ne veut pas dire illisible, et c'est sur le petit
   ecran qu'on a le plus de mal. Elle garde sa taille ; seul le selecteur s'etale. */
@media (max-width: 480px) { .tz-form select { max-width: 100%; } }

/* ------------------------------------------------------------------------------------------------
   AFFICHE CHANGEE APRES LE TIRAGE (02/09/2026). Un joueur ne s'est pas presente, un lucky loser a
   pris sa place, et les pronos de l'affiche sont annules. Le dire est le seul moyen d'eviter que
   quatre pronos a zero d'affilee passent pour une erreur de comptage.
   ------------------------------------------------------------------------------------------------ */
.lbd-subst { margin: .35rem 0 .5rem; font-size: .82rem; line-height: 1.45; color: var(--muted);
             border-left: 3px solid var(--warn, #d99a2b); padding: .35rem 0 .35rem .6rem; }
.tnb-subst { font-size: .68rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
             color: var(--warn, #d99a2b); border: 1px solid currentColor; border-radius: .5rem;
             padding: 0 .3rem; white-space: nowrap; cursor: help; }

/* ------------------------------------------------------------------------------------------------
   LES COMPTES RENDUS ECRITS PAR DES HUMAINS (02/09/2026).
   La hierarchie est le sujet : le texte signe est ouvert, lisible, avec une vraie mesure de lecture ;
   le resume automatique reste derriere son bouton et s'annonce comme automatique ; les notes des
   joueurs sont une liste courte, clairement secondaire. On recompense celui qui ecrit.
   ------------------------------------------------------------------------------------------------ */
.lg-rep { margin: .35rem 0 .2rem .8rem; }
.lg-rep-ai-lab { margin: .1rem .2rem 0 .8rem; font-size: .74rem; font-style: italic; opacity: .7; }
.lg-rep-notes-lab { margin: .5rem .2rem .1rem .8rem; font-size: .74rem; font-weight: 700;
                    letter-spacing: .02em; text-transform: uppercase; opacity: .7; }
.lg-rep-del { background: none; border: 0; padding: 0 0 0 .3rem; font-size: .74rem; cursor: pointer;
              color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.lg-rep-new > summary { cursor: pointer; font-size: .8rem; opacity: .8;
              text-decoration: underline; text-underline-offset: 2px; list-style: none; }
.lg-rep-new > summary::-webkit-details-marker { display: none; }
.lg-rep-new { margin: .3rem 0; }
.lg-rep-new textarea { width: 100%; max-width: 62ch; display: block; margin: .3rem 0; }
.lg-rep-notes { margin: .3rem 0 .5rem; padding-left: 1.1rem; font-size: .84rem; line-height: 1.5; }
.lg-rep-notes li { margin: .15rem 0; }
.lg-rep-note-who { font-weight: 700; opacity: .85; }
.lg-rep-note-who::after { content: ' :'; font-weight: 400; }

/* ------------------------------------------------------------------------------------------------
   SOUS QUEL NOM TU APPARAIS (02/09/2026). Deplie tant que le joueur n'a pas repondu, replie ensuite
   en une ligne qui rappelle son choix : la question doit se voir une fois, pas tous les jours.
   ------------------------------------------------------------------------------------------------ */
.pnc { margin: .5rem 0 0; }
.pnc-sum { cursor: pointer; list-style: none; font-size: .84rem; display: flex; flex-wrap: wrap;
           align-items: center; gap: .4rem; }
.pnc-sum::-webkit-details-marker { display: none; }
.pnc-now { font-weight: 700; }
.pnc-todo { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
            color: var(--on-accent, #fff); background: var(--accent); border-radius: .6rem; padding: 0 .4rem; }
.pnc-why { margin: .4rem 0 .5rem; max-width: 56ch; }
.pnc-form { display: flex; flex-direction: column; gap: .3rem; }
.pnc-opt { display: flex; align-items: baseline; gap: .45rem; font-size: .86rem; cursor: pointer; }
.pnc-opt-v { font-weight: 700; }
.pnc-opt-l { opacity: .7; font-size: .78rem; }
.pnc-pub { display: flex; align-items: baseline; gap: .45rem; margin-top: .45rem; font-size: .86rem; cursor: pointer; }
.pnc-pub-help { margin: .1rem 0 .5rem 1.5rem; max-width: 56ch; }
.pnc-form button { align-self: flex-start; }

/* ------------------------------------------------------------------------------------------------
   LES ECUSSONS DE CLUB (02/09/2026, demande URSIB). Rapatries de leur site, heberges chez nous,
   redimensionnes a 128 px. Les clubs sans logo portent un monogramme dans leurs couleurs : une ligne
   de calendrier ne doit jamais avoir de trou a la place d'une equipe.
   ------------------------------------------------------------------------------------------------ */
.tc { width: 1.35em; height: 1.35em; flex: 0 0 auto; vertical-align: -.32em; margin-right: .3em;
      object-fit: contain; border-radius: 3px; }
.tc-mono { display: inline-flex; align-items: center; justify-content: center;
           background: var(--tcb, #556); color: var(--tci, #fff); border-radius: 4px;
           font-size: .58em; font-weight: 800; letter-spacing: .01em; line-height: 1;
           font-family: system-ui, sans-serif; }
.lg-eq { white-space: nowrap; }

/* ── LE CLASSEMENT D'UNE LIGUE SUR TELEPHONE (10/09/2026, Jonathan, capture de la Veterans 1) ──
   « Le nom long reparti en deux lignes pour rapetisser la colonne 1 sur mobile, eventuellement la
   mettre en volet pour garder les noms visibles quand on fait defiler horizontalement les autres. »
   PIEGE DES FONDS : une cellule en volet est peinte PAR-DESSUS le fond de sa ligne. Si on lui donne
   seulement la couleur de la carte, l'alternance des lignes et la teinte du leader disparaissent sous
   la colonne figee, qui apparait alors comme une bande blanche. On repeint donc ces deux fonds sur la
   cellule elle-meme, en calque au-dessus de la couleur de la carte : le rendu est identique a celui
   d'une ligne normale. LE TRAIT ENTRE LES LIGNES (11/09, Jonathan : « entre les noms on voit une
   double barre horizontale alors qu'entre les scores une seule ») : avec des bordures fusionnees, le
   trait d'une cellule figee appartient au tableau et ne suit pas le defilement ; on l'avait refait a
   l'ombre interieure, et les deux traits se voyaient l'un sous l'autre. Sur telephone le tableau garde
   donc ses bordures SEPAREES : chaque cellule possede son propre trait du bas, qui suit le volet, et
   c'est le meme trait, a la meme hauteur, sous les noms et sous les chiffres. */
.lg-tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; }
@media (max-width: 720px) {
    /* La largeur du rang sert DEUX fois : sa colonne, et le decalage du volet du nom. Une seule
       valeur, donc jamais de chevauchement quand la police change. */
    .lg-tbl { --lg-rk-w: 1.7rem; }
    .lg-tbl { border-collapse: separate; border-spacing: 0; }
    .lg-tbl th, .lg-tbl td { padding-left: .3rem; padding-right: .3rem; }
    .lg-tbl .lg-c-rk, .lg-tbl .lg-c-eq { position: sticky; z-index: 2; background-color: var(--card); }
    .lg-tbl .lg-c-rk { left: 0; width: var(--lg-rk-w); min-width: var(--lg-rk-w); }
    .lg-tbl .lg-c-eq { left: var(--lg-rk-w); border-right: 1px solid var(--border); }
    .lg-tbl tbody tr:nth-child(even) .lg-c-rk,
    .lg-tbl tbody tr:nth-child(even) .lg-c-eq { background-image: linear-gradient(rgba(255,255,255,.022), rgba(255,255,255,.022)); }
    html[data-theme="light"] .lg-tbl tbody tr:nth-child(even) .lg-c-rk,
    html[data-theme="light"] .lg-tbl tbody tr:nth-child(even) .lg-c-eq { background-image: linear-gradient(rgba(0,0,0,.035), rgba(0,0,0,.035)); }
    .lg-tbl .lb-1 .lg-c-rk, .lg-tbl .lb-1 .lg-c-eq { background-image: linear-gradient(rgba(242,201,76,.10), rgba(242,201,76,.10)); }
    /* Le nom se replie plutot que d'etirer la colonne ; la 2e ligne s'aligne sous la 1re, pas sous l'ecusson. */
    .lg-tbl .lg-c-eq { white-space: normal; line-height: 1.22; }
    .lg-tbl .lg-eq-nom { display: inline-block; max-width: 7.6rem; vertical-align: middle; overflow-wrap: anywhere; }
}
@media (max-width: 520px) { .tc { width: 1.2em; height: 1.2em; vertical-align: -.28em; } }

/* ------------------------------------------------------------------------------------------------
   UNE AFFICHE : DEUX EQUIPES, ET UN RETOUR A LA LIGNE QUI TOMBE JUSTE (02/09/2026).

   Le calendrier ecrivait « FC GECKO - <logo> » puis, a la ligne, « FC BELFIUS » : l'ecusson de la
   deuxieme equipe restait accroche a la premiere ligne, separe du nom qu'il designe. Ailleurs,
   c'etait le tiret qui ouvrait la ligne suivante. Regle posee par Jonathan :

     MOBILE      pas de tiret, la deuxieme equipe TOUJOURS a la ligne, ecusson en tete de ligne.
     ORDINATEUR  le tiret peut finir la premiere ligne, il ne la commence jamais ; la deuxieme
                 equipe part a la ligne AVEC son ecusson.

   Le tiret est ecrit DANS le bloc de la premiere equipe (cf. core/Fixture.php) : il ne peut donc pas
   commencer une ligne, quelle que soit la largeur. Ici on ne fait que la mise en forme.
   ------------------------------------------------------------------------------------------------ */
.fx { display: inline-flex; flex-wrap: wrap; align-items: center; column-gap: .4em; row-gap: .05em; }
/* Un bloc d'equipe = ecusson + nom. Le retour a la ligne se fait ENTRE les blocs, jamais dedans. */
.fx-t { display: inline-flex; align-items: center; gap: .3em; }
.fx-n { min-width: 0; }
.fx-vs { opacity: .5; font-weight: 400; margin-left: .1em; }
/* L'ecusson d'une affiche ne porte pas la marge de droite des ecussons de liste : c'est le gap du
   bloc qui espace, sinon l'ecart double. */
.fx .fx-c { margin-right: 0; vertical-align: baseline; }

@media (max-width: 640px) {
    /* UNE EQUIPE PAR LIGNE, et le tiret disparait : entre deux lignes il ne separe plus rien, il
       ajoute juste un caractere a lire. */
    .fx { display: flex; flex-direction: column; align-items: flex-start; row-gap: .1em; }
    .fx-vs { display: none; }
}

/* ------------------------------------------------------------------------------------------------
   LES ONGLETS DE LA LIGUE (02/09/2026). Sur ordinateur, deux groupes ecartes : la ligue a gauche,
   le monde des vestiaires a droite, separes par un ressort. Sur telephone ce ressort produisait un
   vide au milieu et des boutons alignes a gauche sur deux lignes bancales. Le meme element devient
   alors une COUPURE DE LIGNE de largeur pleine : deux rangees nettes, chacune centree.
   ------------------------------------------------------------------------------------------------ */
.lg-tabs-sep { flex: 1; }
@media (max-width: 640px) {
    .lg-tabs { justify-content: center; row-gap: .45rem; }
    .lg-tabs-sep { flex: 0 0 100%; height: 0; margin: 0; }
}

/* ------------------------------------------------------------------------------------------------
   LA PASTILLE DU COMPTE RENDU (02/09/2026). « Non lu » la premiere fois, « mis a jour » quand le
   recit a ete refait apres un changement de score. C'est elle qui donne envie d'aller lire, donc
   elle se voit ; mais elle reste une pastille, pas une alarme.
   ------------------------------------------------------------------------------------------------ */
/* 11/09 : .62rem faisait 9,9 px a l'ecran, la plus petite chose de toute la page. Une pastille se lit
   d'un coup d'oeil ou ne sert a rien. */
.lg-cr-dot { font-size: .72rem; font-weight: 800; letter-spacing: .02em; text-transform: uppercase;
             line-height: 1; padding: .18em .42em; border-radius: 999px; white-space: nowrap;
             background: var(--accent-2, #2bb061); color: #08130c; }
.lg-cr[disabled] { opacity: .5; cursor: default; }

/* ------------------------------------------------------------------------------------------------
   LE PANNEAU DE MISE A JOUR D'UNE LIGUE (02/09/2026). Reserve aux chefs de ligue : c'est un outil,
   pas une information. Sobre a dessein, il ne doit pas concurrencer le calendrier qui le suit.
   ------------------------------------------------------------------------------------------------ */
.lg-maj-slots > summary { cursor: pointer; font-size: .88rem; }
.lg-maj-slot { display: flex; gap: .4rem; align-items: center; margin: .25rem 0; flex-wrap: wrap; }
.lg-maj-slot select { min-width: 8.5rem; }
.lg-maj-slots form button { margin-top: .5rem; }

/* ------------------------------------------------------------------------------------------------
   « TA LIGUE PEUT ETRE ICI » (02/09/2026). Une mise en avant, pas une reclame : ton discret, un seul
   appel a l'action, et une croix qui la fait taire trente jours. Elle vit au-dessus d'une carte de
   concours et ne doit jamais lui passer devant.
   ------------------------------------------------------------------------------------------------ */
.lpb { position: relative; border-left: 3px solid var(--accent); padding-right: 2.2rem; }
.lpb-t { margin: 0 0 .25rem; font-weight: 800; font-size: .95rem; display: flex; align-items: center; gap: .35rem; }
.lpb-b { margin: 0 0 .55rem; font-size: .86rem; line-height: 1.5; max-width: 62ch; color: var(--muted); }
.lpb-x { position: absolute; top: .35rem; right: .45rem; background: none; border: 0; cursor: pointer;
         font-size: 1.2rem; line-height: 1; color: var(--muted); opacity: .7; padding: .1rem .3rem; }
.lpb-x:hover { opacity: 1; }

/* ------------------------------------------------------------------------------------------------
   LA LIGNE DEPLIEE DU CLASSEMENT TENNIS (02/09/2026). Deux demandes de Jonathan sur la meme ligne :
   le separateur ne commence jamais une ligne (il est ecrit DANS le bloc du premier joueur), et
   chaque joueur porte son drapeau, colle a son nom.

   « UN NOM EST UNE UNITE » (doctrine du 31/08), etendue au drapeau : le retour a la ligne se fait
   entre les deux joueurs, jamais entre un drapeau et son nom, jamais au milieu d'un nom.

   ET LES POINTS RESTENT VISIBLES. Premiere version : le bloc drapeau+nom ne pouvait pas retrecir,
   donc il poussait la colonne des points hors de l'ecran sur mobile. Les drapeaux elargissent chaque
   bloc de vingt pixels, et ca a suffi a faire disparaitre ce que le joueur venait justement lire.
   Un nom trop long finit desormais en points de suspension : mieux vaut un nom abrege qu'un score
   invisible.
   ------------------------------------------------------------------------------------------------ */
.lbd-m-p { display: inline-flex; align-items: baseline; max-width: 100%; vertical-align: top; }
.lbd-fl { flex: 0 0 auto; }
.lbd-m-p > span:not(.lbd-vs) { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lbd-vs { opacity: .45; margin-left: .25em; flex: 0 0 auto; }
@media (max-width: 640px) {
    /* Une affiche, deux lignes : entre deux lignes le separateur ne separe plus rien, on le retire.
       La colonne force l'empilement, donc le retirer est sans ambiguite. */
    .lbd-m-names { display: flex; flex-direction: column; align-items: flex-start; }
    .lbd-vs { display: none; }
}


/* ------------------------------------------------------------------------------------------------
   LE PANNEAU « DEUX ESPACES », COMPACT (02/09/2026).

   Jonathan : « on arrive sur cette page, avant de scroller on n'a rien vu ». Le panneau est tout en
   haut de la ligue ET de la page des pronos : il explique une distinction utile, mais il ne peut pas
   occuper le premier ecran a lui seul, sinon il empeche de voir ce qu'on est venu voir.

   TROIS CHOSES, ET LA PHRASE N'EN FAIT PAS PARTIE. Elle reste mot pour mot : c'est elle qui fait
   comprendre, et la raccourcir ferait perdre exactement ce qu'on a gagne.
     1. elle se lit PLUS PETIT et sur TOUTE LA LARGEUR. Elle etait dans une colonne etroite, coupee
        tous les cinq mots, ce qui l'etirait sur six lignes ;
     2. les deux boutons tiennent COTE A COTE a toutes les largeurs (flex-basis 0, min-width 0) : ils
        s'empilaient des 360 px et prenaient deux fois la hauteur ;
     3. leur titre et leur sous-titre font UNE ligne chacun. « La ligue » se repliait en deux lignes
        dans un bouton de 150 px, ce qui doublait encore la hauteur.
   Hauteur du bloc divisee par deux, comprehension inchangee.
   ------------------------------------------------------------------------------------------------ */
/* LA TAILLE DU TEXTE (11/09/2026, Jonathan sur son telephone : « le titre est trop petit, on n'arrive
   pas a lire, et c'est quand meme le truc important sur lequel les gens vont cliquer ; augmente la
   hauteur du bouton, agrandis la police des titres ; l'explication au-dessus pourrait etre un peu plus
   grande aussi, meme si ca rend le tout plus haut »).
   CE QUI CLOCHAIT. Le corps de texte du site est a 1.08rem ; ce panneau, lui, avait ete resserre a
   .76rem pour l'explication et .86rem pour les titres, du temps ou il fallait gagner de la hauteur.
   Resultat : le seul endroit de la page ou l'on doit CHOISIR etait ecrit plus petit que tout le reste.
   Les titres passent a 1.05rem (a un cheveu du corps de texte), l'explication a .92rem, les deux lignes
   secondaires suivent, et les boutons grandissent pour les accueillir. La hauteur perdue est le prix
   demande. */
.ls-spaces { padding: .5rem .65rem; }
.ls-explain { margin: 0 0 .5rem; font-size: .92rem; line-height: 1.45; color: var(--muted);
              text-align: left; max-width: none; }
.ls-tabs { display: flex; gap: .4rem; align-items: stretch; }
/* 03/09 : .btn est un conteneur inline-flex, donc ses deux spans (titre, sous-titre) se posaient sur la
   MEME ligne, colles l'un a l'autre (« La ligueCalendrier, scores, buteurs... » sur PC). Le titre
   au-dessus, le sous-titre en dessous, un souffle entre les deux : ce que le partiel promettait.

   11/09, Jonathan sur son telephone : « l'explication en dessous est peu lisible selon le fond du
   bouton en clair ou en sombre, et le padding ne rentre pas ; n'hesite pas a passer a la ligne et a
   agrandir le bouton, mais les deux boutons doivent avoir la meme taille. » Trois corrections :
     1. LA LIGNE D'EXPLICATION SE REPLIE. Elle etait tenue sur UNE ligne avec des points de suspension,
        donc « Calendrier, scores, buteurs, presences » sortait du bouton par les deux bords, padding
        compris, et disparaissait carrement sous 400 px. Elle passe a la ligne, le bouton grandit.
     2. SA COULEUR EST DECLAREE, plus une opacite. Du blanc a 80 % sur le vert tombait a 3,9:1 (sous le
        seuil lisible) ; l'encre d'accent pleine sur le bouton plein, et --muted sur le bouton vide, qui
        est calibre pour les deux themes.
     3. MEME GEOMETRIE POUR LES DEUX. Le bouton vide portait une bordure d'un pixel que le bouton plein
        n'avait pas : deux pixels d'ecart, visibles. Bordure transparente des deux cotes, box-sizing
        commun, et le contenu centre verticalement pour que la ligne du bas s'aligne. */
.ls-tab { flex: 1 1 0; min-width: 0; box-sizing: border-box; border: 1px solid transparent;
          text-align: center; padding: .6rem .5rem; line-height: 1.25;
          flex-direction: column; justify-content: center; row-gap: .15rem; }
.ls-tab-t { display: block; font-size: 1.05rem; font-weight: 700; white-space: nowrap;
            overflow: hidden; text-overflow: ellipsis; }
.ls-tab-s { display: block; font-size: .82rem; font-weight: 400; line-height: 1.3;
            white-space: normal; overflow-wrap: anywhere; }
.ls-tab.btn-primary .ls-tab-s { color: var(--on-accent); }
.ls-tab.btn-ghost .ls-tab-s { color: var(--muted); }
/* Au survol, le bouton vide se remplit de vert (et sur telephone le survol reste colle apres le tap) :
   sa ligne d'explication doit changer d'encre en meme temps, sinon elle passe du lisible a l'illisible. */
.ls-tab.btn-ghost:hover .ls-tab-s { color: var(--on-accent); }
/* Sur les telephones les plus etroits, le titre garde sa taille : c'est LE mot a lire. Seule
   l'explication du bouton se resserre d'un cheveu pour ne pas partir sur quatre lignes. */
@media (max-width: 380px) { .ls-tab-s { font-size: .78rem; } }
/* LA BARRE DES SERIES (10/09, onglets egaux le 11/09) : les series de la federation en tete du panneau,
   la courante pleine ; sous les deux boutons, les appels a l'action pour qui n'a pas encore de fiche.
   Elles se partagent la largeur en parts EGALES (flex-basis 0) : trois onglets alignes, jamais une
   pastille large a cote d'une etroite, jamais de retour a la ligne qui casse la rangee. Le nom est deja
   court (« Veterans 1 ») ; les points de suspension ne sont qu'un garde-fou si une federation en ouvrait
   beaucoup d'un coup. */
.ls-series { display: flex; align-items: stretch; justify-content: flex-start; gap: .3rem; margin: 0 0 .45rem; }
.ls-serie { flex: 1 1 0; min-width: 0; max-width: 12rem; box-sizing: border-box; text-align: center;
            font-size: .86rem; padding: .3rem .4rem; border-radius: 999px; border: 1px solid var(--border);
            text-decoration: none; color: inherit; white-space: nowrap; line-height: 1.4;
            overflow: hidden; text-overflow: ellipsis; }
.ls-serie:hover { border-color: var(--accent); }
.ls-serie.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 700; }
/* ------------------------------------------------------------------------------------------------
   LA CARTE « TU ES LA POUR QUOI ? » (11/09/2026, Jonathan : « les gens qui arrivent la-dessus doivent
   directement se reperer »). Elle remplace la ligne d'appels a l'action du panneau (.ls-cta, retiree) :
   des portes, une par role, celle du joueur d'abord, lisibles sur telephone (une par ligne) et en grille
   sur un grand ecran. Les tailles suivent la passe du 11/09 : rien sous 13 px a l'ecran.
   UNE SEULE ARRIVEE ANIMEE (l'analyse de juillet a retire les animations permanentes du site) : un halo
   qui s'ouvre puis s'eteint, et la porte principale qui respire une fois. Rien pour qui a demande moins
   de mouvement.
   ------------------------------------------------------------------------------------------------ */
.lc-card { padding: .6rem .7rem; animation: lc-arrive 1.4s ease-out 1; }
.lc-h { margin: 0 0 .45rem; font-size: 1.05rem; line-height: 1.3; }
.lc-p { margin: 0 0 .4rem; font-size: .95rem; line-height: 1.45; }
.lc-doors { display: grid; grid-template-columns: 1fr; gap: .4rem; }
.lc-doors-one { margin-top: .5rem; }
@media (min-width: 640px) { .lc-doors { grid-template-columns: 1fr 1fr; } .lc-doors-one { grid-template-columns: 1fr; } }
.lc-door { display: flex; align-items: center; gap: .6rem; padding: .55rem .65rem; border: 1px solid var(--border);
           border-radius: 10px; text-decoration: none; color: var(--text); background: var(--card); }
.lc-door:hover { border-color: var(--accent); text-decoration: none; }
.lc-door-main { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--card));
                animation: lc-door-in 1.4s ease-out 1; }
.lc-ic { font-size: 1.35rem; line-height: 1; flex: 0 0 auto; }
.lc-tx { display: flex; flex-direction: column; min-width: 0; }
.lc-tx b { font-size: .98rem; line-height: 1.25; }
.lc-tx span { font-size: .84rem; line-height: 1.3; color: var(--muted); }
.lc-acts { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; margin: 0 0 .35rem; }
.lc-out { margin: .45rem 0 0; text-align: right; }
.lc-out .btn-link { font-size: .84rem; text-decoration: underline; text-underline-offset: 2px; }
@keyframes lc-arrive {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
    60%  { box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes lc-door-in { 0%, 100% { transform: none; } 30% { transform: scale(1.015); } }
@media (prefers-reduced-motion: reduce) { .lc-card, .lc-door-main { animation: none; } }

/* LE CAPITAINE DE L'EQUIPE (11/09) : le bloc de l'onglet Joueurs, la case du formulaire d'association, les
   presences par joueur pour le capitaine, et les deux reponses dans la cloche. */
.lg-cap-claim { padding: .3rem 0; border-top: 1px solid var(--border); }
.lg-cap-st { font-size: .84rem; padding: .04rem .45rem; border-radius: 999px; border: 1px solid var(--border);
             margin-left: .25rem; font-weight: 600; white-space: nowrap; }
.lg-cap-frozen { border-color: var(--danger); }
.lg-cap-chk { display: inline-flex; align-items: center; gap: .3rem; border: 1px solid var(--border);
              border-radius: 999px; padding: .12rem .6rem; }
.lg-cap-att-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: .3rem;
                  padding: .25rem 0; border-top: 1px solid var(--border); }
/* Dans la cloche, les deux reponses passent SOUS la phrase : a cote, sur un telephone, elles ecrasaient
   le texte en colonne et se repliaient elles-memes sur quatre lignes (capture du 11/09). */
.nf-item:has(> .nf-acts) { flex-wrap: wrap; }
.nf-acts { display: flex; flex-wrap: wrap; gap: .35rem; flex: 1 1 100%; margin: .1rem 0 0; }

/* LE CODE DE VERIFICATION S'EXPLIQUE AVANT DE SE MONTRER (11/09, capture A09) : a quoi il sert, le code,
   le geste, puis le pourquoi detaille sous un « ? » qui se deplie sur place (composant .entry-help). */
.lg-code { border: 1px dashed var(--accent); border-radius: 10px; padding: .55rem .7rem; margin: 0 0 .55rem; }
.lg-code-h { margin: 0 0 .2rem; font-weight: 700; font-size: .98rem; line-height: 1.3; }
.lg-code-txt { margin: 0 0 .45rem; font-size: .92rem; line-height: 1.45; }
.lg-code-row { margin: 0 0 .45rem; display: flex; align-items: center; flex-wrap: wrap; gap: .45rem; font-size: .92rem; }
.lg-code-val { font-size: 1.25rem; letter-spacing: .12em; border: 1px dashed var(--accent); border-radius: 8px; padding: .1rem .55rem; }
.lg-code-foot { margin: .5rem 0 0; font-size: .86rem; line-height: 1.45; color: var(--muted); }
.lg-code-why { display: inline-flex; align-items: center; gap: .3rem; background: none; border: 0; padding: .15rem 0;
               font: inherit; font-weight: 700; color: var(--accent-ink); cursor: pointer; white-space: nowrap; }
.lg-code-why .cmeta-help { width: 20px; height: 20px; font-size: .8rem; margin-left: 0; }
.lg-code-why[aria-expanded="true"] .cmeta-help { background: #2ecc71; border-color: #2ecc71; color: #fff; }

/* TON APRES-MATCH (11/09) : buts, top, flop et note d'un match joue, au meme endroit
   (views/partials/league_after_match.php). Lisible sur telephone : rien sous 13 px, une section par geste. */
.lg-am { margin: .3rem 0 .15rem .5rem; border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border)); border-radius: 10px;
         background: var(--card); }
.lg-am-sum { cursor: pointer; padding: .45rem .6rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .5rem; list-style: none; }
.lg-am-sum::-webkit-details-marker { display: none; }
.lg-am-sum::before { content: "\25B8"; color: var(--accent-ink); font-size: .85rem; }
.lg-am[open] > .lg-am-sum::before { content: "\25BE"; }
.lg-am-t { font-weight: 700; font-size: .95rem; }
.lg-am-s { font-size: .84rem; color: var(--muted); }
.lg-am-flag { font-size: .8rem; font-weight: 700; color: var(--on-accent); background: var(--accent); border-radius: 999px; padding: .02rem .5rem; }
.lg-am-body { padding: 0 .6rem .55rem; }
.lg-am-sec { border-top: 1px solid var(--border); padding: .45rem 0 .35rem; }
.lg-am-h { margin: 0 0 .3rem; font-size: .92rem; line-height: 1.3; }
.lg-am-p { margin: 0 0 .3rem; font-size: .9rem; line-height: 1.4; }
.lg-am-help { margin: .3rem 0 0; font-size: .84rem; line-height: 1.45; color: var(--muted); }
.lg-am-list { margin: 0 0 .3rem; padding-left: 1.1rem; font-size: .9rem; line-height: 1.45; }
.lg-am-form { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; margin: .15rem 0 .1rem; }
.lg-am-form select { min-width: 160px; max-width: 100%; }
.lg-am-form-col { flex-direction: column; align-items: stretch; }
.lg-am-form-col .btn { align-self: flex-start; }
.lg-am-form .lg-am-min { width: 92px; flex: 0 0 92px; }
.lg-am-grow { flex: 1 1 170px; min-width: 0; }
/* La note s'ecrit dans la police du site : la zone prenait la police machine a ecrire du navigateur (capture M02). */
.lg-am textarea { font-family: inherit; font-size: .95rem; line-height: 1.4; width: 100%; }
.lg-am-chk { font-size: .88rem; border: 1px solid var(--border); border-radius: 999px; padding: .1rem .55rem; white-space: nowrap; }
.lg-am-quote { font-style: italic; }
.lg-am-row { display: flex; flex-wrap: wrap; gap: .35rem; }
.lg-am-ask { border: 1px solid var(--accent); border-radius: 8px; padding: .45rem .55rem; margin: 0 0 .45rem;
             background: color-mix(in srgb, var(--accent) 8%, var(--card)); }
.lg-am-ask-q { margin: 0 0 .2rem; font-weight: 700; font-size: .92rem; line-height: 1.4; }
.lg-am-when { margin: .35rem 0 0; font-size: .84rem; color: var(--muted); border-top: 1px dashed var(--border); padding-top: .4rem; }
/* L'URSIB sur le premier ecran de l'accueil (12/09) : une bande d'une ligne, sous le titre. */
.home-ursib { display: flex; align-items: center; gap: .6rem; padding: .55rem .75rem; text-decoration: none; color: var(--text);
              border: 1px solid color-mix(in srgb, var(--accent) 50%, var(--border)); }
.home-ursib:hover { text-decoration: none; border-color: var(--accent); }
.home-ursib-ic { font-size: 1.3rem; line-height: 1; flex: 0 0 auto; }
.home-ursib-tx { flex: 1 1 auto; min-width: 0; font-size: .92rem; line-height: 1.35; }
.home-ursib-tx span { color: var(--muted); }
.home-ursib-btn { flex: 0 0 auto; white-space: nowrap; }
/* Sur telephone (12/09, mesure a 375 px) : le bouton passait a cote du texte et l'etranglait (8 lignes en nl).
   Il descend sous le texte ; un mot trop long se coupe au lieu de deborder. */
@media (max-width: 560px) {
    .home-ursib { flex-wrap: wrap; }
    .home-ursib-ic { display: none; }   /* seul sur sa ligne, il ne faisait que pousser le texte */
    .home-ursib-tx { flex: 1 1 100%; overflow-wrap: anywhere; }
    .home-ursib-btn { margin-left: auto; }
}
/* Le nom : ce que voit son equipe, et la forme publique a cote de celle de la ligue (11/09). */
.pnc-pub { font-size: .82rem; color: var(--muted); font-weight: 400; }
.pnc-team { margin: .1rem 0 .35rem; }

/* L'adresse du compte associe, dans le noyau d'une equipe (02/09/2026). Discrete : c'est une preuve
   d'identite pour l'encadrement, pas une information a lire en diagonale. */
.enc-mail { font-size: .72rem; color: var(--muted); opacity: .85; word-break: break-all; }

/* Le bandeau « vue super-admin » (02/09/2026) : il doit se voir sans crier, parce qu'il change la
   nature de tout ce qui suit sur la page. */
.enc-superview { border-left: 3px solid var(--warn, #d99a2b); font-size: .84rem; color: var(--muted);
                 padding: .5rem .65rem; }

/* SIGNALER, SOUS LES ONGLETS DE TOUS LES CONCOURS (02/09/2026, cf views/partials/contest_tabs.php).
   Jonathan : « sans mettre un gros truc ». Ce n'est donc pas un bouton mais un lien discret, gris et
   souligne en pointille, aligne a droite sous la barre d'onglets. Il ne doit jamais entrer en
   concurrence du regard avec « Pronostiquer » : on le trouve quand on le cherche, au moment ou l'on
   vient de voir quelque chose d'anormal, et on ne le voit pas le reste du temps. */
.contest-report { margin: .35rem 0 .9rem; text-align: right; font-size: .78rem; line-height: 1.3; }
.contest-report a { color: var(--muted); text-decoration: underline dotted; text-underline-offset: 2px; }
.contest-report a:hover, .contest-report a:focus-visible { color: var(--text, inherit); text-decoration-style: solid; }
@media (max-width: 600px) {
    /* Sur telephone, centre et un peu plus aere : colle a droite il tombait sous le pouce du
       defilement, et se touchait par accident en faisant glisser la barre d'onglets. */
    .contest-report { text-align: center; margin: .5rem 0 1rem; }
}

/* « N AFFICHES A JOUER », DANS LA RANGEE DES TITRES DU TABLEAU TENNIS (02/09/2026, Jonathan).
   Il se loge dans le formulaire de filtre, qui occupait deja sa propre ligne sous le titre sans
   aucune regle CSS : le bouton ne coute donc PAS un pixel de hauteur, ce qui compte parce que cette
   rangee est collante et que sa hauteur est payee sur tous les ecrans, a tous les tours.
   Il porte l'encre d'accent et non le rouge de l'urgence : c'est une invitation, pas une alarme.
   Le rouge reste reserve au badge « N urgents », qui, lui, dit qu'une porte se ferme. */
.tnb-head-todo { display: inline-block; margin-left: .35rem; padding: .04rem .45rem; border-radius: 999px;
    font-size: .72rem; font-weight: 700; text-transform: none; letter-spacing: 0; white-space: nowrap;
    border: 1px solid var(--accent); color: var(--accent); background: transparent; cursor: pointer; }
.tnb-head-todo:hover, .tnb-head-todo:focus-visible { background: var(--accent); color: var(--on-accent, #fff); }
/* Filtre pose : l'encre s'inverse et une croix apparait devant le compte. Le NOMBRE RESTE LISIBLE
   pendant qu'on travaille : un bouton qui deviendrait « Tout afficher » supprimerait le seul
   compteur de progression du tour au moment precis ou l'on remplit ses affiches. */
.tnb-head-todo.est-actif { background: var(--accent); color: var(--on-accent, #fff); }
/* Le badge d'urgence est devenu un lien : il garde son allure de pastille, sans soulignement. */
.tnb-head-urg { display: inline-block; text-decoration: none; }
.tnb-head-urg.est-actif { box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger, #dc2626) 35%, transparent); }
/* Une colonne filtree qui ne garde aucune affiche. Discrete, mais elle porte toujours sa sortie. */
.tnb-vide { margin: .6rem .2rem; font-size: .82rem; color: var(--muted); line-height: 1.5; }
.tnb-vide .btn { margin-top: .35rem; }

/* La case « un seul lien pour mes N ligues » (02/09/2026) : les ligues couvertes en pastilles, et
   TOUTES, celle qu'on regarde comprise. Ce sont des droits qu'on donne a quelqu'un, ils doivent se
   lire d'un coup d'oeil et non comme une note de bas de page. */
.enc-alllg { display: flex; gap: .45rem; align-items: flex-start; margin: .15rem 0 .1rem; }
.enc-alllg-tags { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .25rem; }
.enc-lgtag { display: inline-block; font-size: .72rem; font-weight: 700; line-height: 1.5;
             padding: 0 .45rem; border-radius: 999px; background: color-mix(in srgb, var(--accent) 14%, transparent);
             border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }

/* LA LEGENDE DU COMPTEUR DE PRONOS (02/09/2026, Jonathan : « il faudrait juste dire pronos
   effectues sur les 64 matches »). « 256/256 » ne disait pas s'il comptait des matchs ou des
   reponses ; un joueur a 200/256 pouvait croire qu'il lui restait cinquante-six MATCHS.
   Ecrite en clair et pas seulement en title : un title n'existe pas sur un telephone, or c'est la
   que le nombre se lit le plus souvent. Onze pixels sur la rangee collante, en gris, sans casse
   forcee : elle explique, elle ne doit surtout pas attirer l'oeil avant le nombre qu'elle sert. */
.tnb-head-leg { display: block; font-size: .64rem; line-height: 1.25; color: var(--muted);
    font-weight: 400; text-transform: none; letter-spacing: 0; margin: .1rem 0 .05rem; }

/* ALIGNEMENT DE L'ARBRE (02/09/2026, Jonathan : « les niveaux suivants devraient etre alignes avec
   l'entre-deux matches du tour precedent »). Les marges sont posees par le script, qui mesure les
   hauteurs reelles ; le flex doit donc cesser de repartir l'espace tout seul, sinon il ecrase ces
   marges. On ne bascule que sur la classe posee par le script : sans lui, space-around reprend la
   main et l'affichage reste celui d'avant, ce qui est la degradation voulue. */
.tnb-scroll.tnb-arbre-on .tnb-col-list { justify-content: flex-start; }

/* LE MULTIPLICATEUR DU TOUR, dans la rangee des titres du tableau tennis (03/09/2026, Jonathan :
   « il doit le voir ce multiplicateur, pas juste dans les regles »). Encre d'accent et non rouge :
   c'est une information de bareme, pas une alerte. Il ne parait pas au 1er tour, ou il vaudrait x1
   et ne dirait rien. Discret volontairement : il explique le nombre voisin, il ne le concurrence pas. */
.tnb-head-mult { display: inline-block; margin-left: .3rem; padding: .02rem .32rem; border-radius: 999px;
    font-size: .68rem; font-weight: 800; text-transform: none; letter-spacing: 0; white-space: nowrap;
    border: 1px solid var(--accent); color: var(--accent); background: transparent; cursor: help; }

/* LE MULTIPLICATEUR SUR LA LIGNE D'UN TOUR, dans le detail de classement (03/09/2026, Jonathan :
   « je vois pas que c'est affiche dans le classement »). Meme forme que sur le tableau, en plus
   petit : c'est ici qu'on compare ses tours entre eux, donc ici qu'on se demande pourquoi le
   deuxieme rapporte plus que le premier a nombre egal de bons pronos. */
.lbd-round-mult { display: inline-block; margin-left: .3rem; padding: .01rem .3rem; border-radius: 999px;
    font-size: .66rem; font-weight: 800; vertical-align: middle; white-space: nowrap;
    border: 1px solid var(--accent); color: var(--accent); background: transparent; cursor: help; }

/* PERIMETRE DES ARBITRES GRISE (03/09/2026) : quand aucun role coche ne consomme le perimetre, le
   moteur le jette de toute facon. Un controle sans effet est pire qu'un controle absent, alors on
   le ferme et on dit pourquoi. La raison, elle, reste lisible : c'est la seule chose a lire ici. */
details.enc-scope-off > summary { opacity: .45; cursor: not-allowed; }
details.enc-scope-off > div { opacity: .45; pointer-events: none; }
details.enc-scope-off > .help[data-scope-off] { opacity: 1; }

/* LE TOUR OUVRE SON BLOC, IL NE LE FERME PAS (03/09/2026, Jonathan : « je ne comprends pas pourquoi
   en dessous du troisieme tour il y a toujours deux lignes horizontales [...] une seule grosse ligne
   suffit, et je la mettrais au-dessus du mot 3e tour. Au foot on voyait directement que le 3e tour
   appartenait a l'encart »).
   Les deux traits venaient de deux regles qui s'ignoraient : .lbd-round posait un border-bottom sous
   le titre du tour, et le premier .lbd-day un border-top au-dessus de sa date. Entre les deux, un
   millimetre de vide et l'impression d'un tableau casse.
   Le trait passe donc AU-DESSUS du tour, ou il separe vraiment deux blocs, et la date qui suit
   immediatement un titre de tour perd le sien : deux traits colles ne separent rien de plus qu'un. */
.lbd-round { border-bottom: none; border-top: 2px solid var(--border);
    margin: 1.3rem 0 .3rem; padding: .5rem 0 0; font-size: 1.05rem; font-weight: 800; }
.lbd-round:first-child { margin-top: .2rem; border-top: none; padding-top: 0; }
.lbd-round + .lbd-day { border-top: none; margin-top: .35rem; padding-top: 0; }
/* « barème ×2,6 » plutot que « ×2,6 » tout sec : le mot dit DE QUOI parle le nombre. Sans lui, colle
   au titre d'un tour, il pouvait se lire comme un coefficient applique au tour lui-meme. */
.lbd-round-mult { font-size: .7rem; font-weight: 700; padding: .05rem .4rem; }
.lbd-round-q { display: inline-block; width: 1.05em; height: 1.05em; line-height: 1.05em; text-align: center;
    border-radius: 50%; border: 1px solid var(--muted); color: var(--muted); font-size: .68rem;
    font-weight: 700; text-decoration: none; vertical-align: middle; margin-left: .25rem; }
.lbd-round-q:hover, .lbd-round-q:focus-visible { border-color: var(--accent); color: var(--accent); }
/* Le tour rappele sur chaque date : dans une liste longue, on ne voit plus le titre reste en haut. */
.lbd-day-round { font-weight: 600; font-size: .82rem; color: var(--muted); }

/* LE DEPLIANT « BAREME PAR TOUR », a cote de la note de fuseau horaire (03/09/2026).
   Meme forme que .tz-pick, dont il est le voisin immediat : deux explications du tableau, deux
   depliants identiques, aucune hierarchie inventee entre elles. Ferme, il ne coute qu'une ligne. */
.bareme-note { display: inline-block; margin: .15rem 0 .35rem .8rem; font-size: .82rem; vertical-align: middle; }
.bareme-note > summary { cursor: pointer; color: var(--muted); list-style: none; user-select: none; }
.bareme-note > summary::-webkit-details-marker { display: none; }
.bareme-note > summary:hover, .bareme-note[open] > summary { color: var(--accent); }
/* Le « ? » : un rond, comme partout ailleurs sur le site, pour qu'on sache que ca s'ouvre. */
.bareme-note-q { display: inline-block; width: 1.15em; height: 1.15em; line-height: 1.15em; text-align: center;
    border-radius: 50%; border: 1px solid currentColor; font-size: .78rem; font-weight: 700; }
.bareme-note-body { margin: .5rem 0 .2rem; padding: .6rem .75rem; border-radius: 9px;
    border: 1px solid var(--border); background: var(--card-2); max-width: 34rem; line-height: 1.5; }
.bareme-note-body p { margin: 0 0 .5rem; }
.bareme-note-list { list-style: none; margin: .1rem 0 .6rem; padding: 0;
    border-top: 1px solid var(--border); }
.bareme-note-list li { display: flex; justify-content: space-between; gap: 1rem;
    padding: .18rem .1rem; border-bottom: 1px solid var(--border); }
.bareme-note-m { font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* La phrase « deja inclus » est la plus importante du bloc : sans elle, on espere le double. */
.bareme-note-inc { color: var(--text, inherit); }
.bareme-note-why { color: var(--muted); font-size: .95em; margin-bottom: 0 !important; }

/* LE « ? » DU CLASSEMENT EXPLIQUE SUR PLACE (03/09/2026, Jonathan : « il ne faut pas revenir a la
   regle, ce n'est pas le but [...] c'est lourd »). Meme mecanique que le « ? » du formulaire de
   prono : une case a cocher et du CSS, aucun script. Trois versions JavaScript de suite n'avaient
   pas fonctionne sur son telephone le 31/08 ; celle-ci ne peut pas echouer de la meme facon. */
.lbd-q-cb { position: absolute; opacity: 0; pointer-events: none; }
.lbd-round-q { cursor: pointer; }
.lbd-q-cb:checked ~ .lbd-round .lbd-round-q { border-color: var(--accent); color: var(--accent); }
.lbd-round-help { display: none; margin: .1rem 0 .6rem; padding: .55rem .7rem; border-radius: 9px;
    border: 1px solid var(--border); background: var(--card-2); font-size: .84rem; line-height: 1.55; }
.lbd-q-cb:checked ~ .lbd-round-help { display: block; }
.lbd-round-help p { margin: 0 0 .4rem; }
.lbd-round-help ul { margin: .2rem 0 0; padding-left: 1.1rem; color: var(--muted); }
.lbd-round-help li { margin: .12rem 0; }

/* « Un seul lot par foyer » sur la page des Recompenses (03/09/2026). Discret mais present : une
   regle de dotation doit se lire AVANT la remise, pas se decouvrir au moment de gagner. */
.jw-house { max-width: 760px; margin: 1.6rem auto .4rem; padding: .7rem .9rem; text-align: center;
    border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2, transparent); }
.jw-house strong { color: var(--text); }

/* « Hors lot » au classement (03/09/2026) : le joueur est classe normalement, il ne concourt
   simplement pas pour les recompenses. Discret mais lisible par tous : c'est justement parce que
   les AUTRES joueurs doivent savoir qui est en lice que ce marqueur existe. */
.lb-noprize { display: inline-block; margin-left: .3rem; padding: .02rem .34rem; border-radius: 999px;
    font-size: .64rem; font-weight: 700; white-space: nowrap; vertical-align: middle; cursor: help;
    border: 1px solid var(--border); color: var(--muted); background: transparent; }

/* Rang d'un joueur « hors lot » : un tiret a la place du numero (03/09/2026). Il garde sa ligne a
   sa vraie position, mais il ne consomme plus de rang : le joueur suivant devient premier. */
.lb-norank { color: var(--muted); cursor: help; }

/* Le « ? » de la pastille « hors podium », et son explication sous le tableau (03/09/2026).
   Le texte est generique : il couvre l'organisateur du concours comme les comptes d'un meme foyer,
   sans designer personne. */
.lb-noprize-q { margin-left: .22rem; padding: 0 .18rem; border-radius: 999px; text-decoration: none;
    font-weight: 800; color: var(--muted); border: 1px solid var(--border); line-height: 1.1; }
.lb-noprize-q:hover { color: var(--accent); border-color: var(--accent); }
.lb-noprize-box { margin: .5rem 0 0; padding: .5rem .7rem; border: 1px solid var(--border);
    border-radius: 10px; max-width: 760px; }
.lb-noprize-box > summary { cursor: pointer; font-size: .84rem; font-weight: 700; color: var(--muted); }

/* NOTIFICATIONS (03/09/2026). La cloche ne s'affiche que s'il y a quelque chose (voir layout.php) :
   son seul etat visible est donc « il y a du neuf », ce qui rend la pastille lisible sans compter. */
.nf-bell { position: relative; }
.nf-pastille { position: absolute; top: -2px; right: -4px; min-width: 15px; height: 15px;
               padding: 0 3px; border-radius: 999px; background: #d92d20; color: #fff;
               font-size: .62rem; font-weight: 800; line-height: 15px; text-align: center; }
.nf-list { list-style: none; margin: .3rem 0 0; padding: 0; }
.nf-item { display: flex; gap: .6rem; align-items: baseline; justify-content: space-between;
           padding: .5rem .1rem; border-bottom: 1px solid var(--border); }
.nf-item:last-child { border-bottom: 0; }
.nf-quand { flex: 0 0 auto; }
/* Ce qui etait neuf en arrivant reste marque le temps de CETTE page, puis s'eteint tout seul. */
.nf-neuf { font-weight: 700; }
.nf-neuf::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: .35rem;
                   border-radius: 50%; background: var(--accent); flex: 0 0 auto; }

/* ===== LE BANDEAU DE LA LIGUE sous le header (03/09/2026) : presence, encodage, joueur a verifier. Une demande a la fois. ===== */
.nf-banner { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem .8rem; margin: .7rem auto 0; max-width: 1100px; padding: .55rem .9rem; border-radius: 10px; background: rgba(34,197,94,.13); border: 1px solid #22c55e; }
.nf-banner[hidden] { display: none; }
.nf-banner-q { font-weight: 800; }
.nf-banner-aff { display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap; font-weight: 700; }
.nf-banner-aff .fx { display: inline-flex; }
.nf-banner-acts { display: inline-flex; gap: .35rem; flex-wrap: wrap; align-items: center; margin-left: auto; }
.nf-banner-enc { background: rgba(245,158,11,.13); border-color: #f59e0b; }
.nf-banner-claim { background: rgba(59,130,246,.12); border-color: #3b82f6; }
.nf-banner-later { background: none; border: none; color: var(--muted); text-decoration: underline; cursor: pointer; font-size: .85rem; padding: 0 .2rem; }
@media (max-width: 640px) {
  .nf-banner { margin: .5rem .5rem 0; padding: .5rem .7rem; }
  .nf-banner-acts { margin-left: 0; width: 100%; }
  .nf-banner-acts .btn { flex: 1 1 auto; }
}
/* Sous un compte rendu (03/09) : le manque de buteurs, en gris, et les boutons de partage. */
.lg-rep-nogoal { margin: .15rem .2rem 0 .8rem; font-style: italic; }
.lg-share { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin: .45rem 0 .2rem .8rem; }
.lg-share-lab { width: 100%; }
.inv-btn.inv-fb { background: linear-gradient(135deg, #1877f2, #0c5ac4); }

/* ===== LE PARCOURS A ETAT (03/09/2026) : Ta ligue / Ton equipe en 3 etapes (views/partials/league_onboarding.php). ===== */
.lo { border-left: 4px solid var(--accent); }
.lo > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .8rem; }
.lo > summary::-webkit-details-marker { display: none; }
.lo-title { font-weight: 800; font-size: 1.05rem; }
.lo-prog { font-weight: 800; color: var(--accent); white-space: nowrap; }
.lo-bar { flex: 1 1 120px; min-width: 80px; height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 18%, transparent); overflow: hidden; }
.lo-bar i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.lo-all { flex-basis: 100%; }
.lo-steps { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.lo-step { display: flex; gap: .6rem; align-items: flex-start; padding: .5rem .6rem; border: 1px solid var(--border); border-radius: 10px; }
.lo-step.lo-done { opacity: .8; }
.lo-num { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; background: var(--border); }
.lo-done .lo-num { background: var(--accent); color: var(--on-accent); }
.lo-body { flex: 1 1 auto; min-width: 0; }
.lo-body h4 { margin: 0 0 .15rem; font-size: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; }
.lo-body p { margin: 0 0 .35rem; }
.lo-st { font-size: .72rem; border-radius: 999px; padding: .05rem .45rem; font-weight: 700; }
.lo-st-done { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.lo-st-todo { background: rgba(245,158,11,.16); color: #b45309; }
.lo-chip { display: inline-block; border: 1px solid var(--border); border-radius: 999px; padding: .05rem .5rem; margin: .1rem .2rem 0 0; font-size: .85rem; text-decoration: none; color: inherit; }
.lo-chip:hover { border-color: var(--accent); text-decoration: none; }
.lo-comm { margin-top: .7rem; border-top: 1px solid var(--border); padding-top: .5rem; }
.lo-comm ul { margin: .2rem 0 0; padding-left: 1.1rem; }
.lo-comm li { margin: .15rem 0; }

/* ===== ONGLET EQUIPES DE LA LIGUE : chaque ligne se deroule (05/09/2026). ===== */
.lg-eq-row:hover td { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.lg-eq-caret { display: inline-block; width: 1em; color: var(--muted); transition: transform .15s; margin-right: .1rem; }
.lg-eq-open .lg-eq-caret { transform: rotate(90deg); }
.lg-eq-detail td { background: color-mix(in srgb, var(--accent) 4%, transparent); padding: .45rem .6rem .5rem 1.6rem; }
.lg-eq-chip { display: inline-block; border: 1px solid var(--border); border-radius: 999px; padding: .05rem .5rem; margin: .1rem .15rem .1rem 0; font-size: .85rem; white-space: nowrap; }
.lg-eq-chip-linked { border-color: var(--accent); }
.lg-eq-chip-staff { border-style: dashed; }

.lo-chip-sent { border-color: var(--accent); }
.lo-chip-prep { border-style: dashed; }

/* ── COMPTES RENDUS DEPUIS LE CLASSEMENT + BARRE DU HAUT + BARRE DE NAVIGATION (06/09/2026, Jonathan) ── */
/* Liens secondaires de l'ilot (Regles, Tous les concours) : sans fond de couleur, moins de poids. */
.nav .nav-grp-ctx > a.nav-ctx-sec { background: transparent !important; font-weight: 500; opacity: .85; }
.nav .nav-grp-ctx > a.nav-ctx-sec:hover { opacity: 1; }
/* La barre du haut d'un compte rendu : retour + partage (ou appel a jouer), sur une ligne sur PC. */
.recap-topbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem .9rem; margin: 0 0 .8rem; }
.recap-topbar .recap-topbar-nav { display: flex; gap: .5rem; flex-wrap: wrap; }
.recap-topbar .pool-back-link { margin: 0; }
.recap-topbar .recap-share { margin: 0; flex: 1 1 320px; }
.recap-topbar .recap-share-h { margin: 0 0 .35rem; font-weight: 700; }
.recap-topbar .recap-topbar-cta { display: flex; gap: .5rem; flex-wrap: wrap; flex: 1 1 320px; justify-content: flex-end; }
@media (max-width: 620px) { .recap-topbar { flex-direction: column; align-items: stretch; } .recap-topbar .recap-topbar-cta { justify-content: stretch; } .recap-topbar .recap-topbar-cta .btn { flex: 1 1 auto; text-align: center; } }
/* Le bouton « Compte rendu » a cote du jour, et sa pastille « non lu ». */
/* LE BOUTON « COMPTE RENDU » DU CLASSEMENT (06/09 soir, deux passes de Jonathan : « timide, pas tres
   visible, le contour plus marque, une icone plus pro que l'emoji », puis « je ne suis pas un fanatique
   de ton clignotement : mets une petite pastille non lu dessus, tout simplement »). Contour de la
   couleur de la competition, icone SVG, et tant que le recit n'est pas lu, une pastille rouge posee sur
   le coin du bouton. Rien ne clignote. */
.recap-cta-wrap { display: inline-flex; align-items: center; margin-left: .5rem; vertical-align: middle; }
/* UN PEU MOINS IMPOSANT (07/09, Jonathan se demandait si le bouton ecrasait la serie des points) : meme
   place, a cote du jour ou l'oeil lit deja la date, mais plus petit et moins gras ; la pastille « non lu »
   garde l'attention pour elle. */
.recap-cta-inline { position: relative; display: inline-flex; align-items: center; gap: .32rem; padding: .16rem .58rem; border-radius: 999px; border: 1.5px solid var(--accent); background: var(--card-2); color: var(--text); font-size: .74rem; font-weight: 700; text-decoration: none; white-space: nowrap; }
.recap-cta-inline svg { width: 14px; height: 14px; flex: 0 0 auto; }
.recap-cta-inline:hover { text-decoration: none; background: color-mix(in srgb, var(--accent) 16%, var(--card-2)); }
/* La pastille chevauche le BORD du bouton, jamais son texte (vu en prod : elle mordait sur « rendu »). */
.recap-unread-pill { position: absolute; top: -1.15em; right: -.6em; padding: .08em .45em; border-radius: 999px; background: #ef4444; color: #fff; font-size: .6rem; font-weight: 800; letter-spacing: .03em; line-height: 1.5; text-transform: uppercase; box-shadow: 0 0 0 2px var(--bg); }
.lb-recap-cta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: .2rem 0 .7rem; }
.lb-recap-cta .recap-cta-wrap { margin-left: 0; }
.lbd-day-lab .recap-cta-wrap { margin-left: .45rem; }
/* LA JOURNEE DANS LA FICHE FOOT, L'ETAPE DANS LA FICHE VELO (06/09 soir) : une ligne par journee avec ses
   points et le bouton « Compte rendu » (pastille non lu), comme le jour au tennis. Sur telephone le bouton
   passe a la ligne (flex-wrap), Jonathan : « sur mobile il faudra peut-etre passer le bouton a la ligne ». */
.pts-md-sep { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem .55rem; margin: .55rem 0 .2rem; padding-top: .35rem; border-top: 1px dashed var(--border); }
.pts-md-lab { font-weight: 800; font-size: .92rem; color: var(--accent-ink); }
.pts-md-sum { font-weight: 700; font-size: .82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.pts-md-sep .recap-cta-wrap, .pts-md-head .recap-cta-wrap { margin-left: .15rem; }
.cyc-det-stage summary .recap-cta-wrap { margin-left: .35rem; vertical-align: middle; }
/* LE PARTAGE A LA FIN DU RECIT (06/09 soir, Jonathan : « les gens n'ont pas encore lu le compte rendu,
   ils n'ont pas encore envie de le partager »). Un bloc sous le texte, separe d'un trait, quatre canaux. */
.recap-share { margin: 1.1rem 0 .3rem; padding-top: .75rem; border-top: 1px dashed var(--border); }
.recap-share-h { margin: 0 0 .5rem; font-weight: 800; font-size: .95rem; }
/* LA LIGNE DE TETE des recits (06/09 soir) : le retour a gauche, le petit bouton WhatsApp a droite. */
.recap-head-row { display: flex; align-items: center; justify-content: space-between; gap: .5rem .8rem; flex-wrap: wrap; margin: 0 0 .4rem; }
.recap-head-row .pool-back-link { margin: 0; }
.recap-head-row .recap-wa-top { flex: 0 0 auto; }
/* QUI A PARTAGE (super-admin), sous l'oeil du recit. */
.recap-shares { margin-top: .35rem; color: var(--muted); }
.recap-shares > summary { cursor: pointer; }
.recap-shares ul { margin: .3rem 0 0; padding-left: 1.1rem; }
/* LE MIROIR DU CLASSEMENT REEL (06/09) : replie ; les zones de la phase de ligue a 36 se lisent par un
   liseré a gauche du rang et un trait entre deux zones. */
.lg-mirror > summary { cursor: pointer; list-style: none; }
.lg-mirror > summary::-webkit-details-marker { display: none; }
.lg-mirror > summary::after { content: " \25BE"; color: var(--muted); }
.lg-mirror[open] > summary::after { content: " \25B4"; }
.lg-mirror-t { width: 100%; font-size: .86rem; margin-top: .5rem; }
.lg-mirror-t tr.zone-direct td:first-child { box-shadow: inset 3px 0 0 var(--ok, #16a34a); }
.lg-mirror-t tr.zone-barrage td:first-child { box-shadow: inset 3px 0 0 var(--warn, #d97706); }
.lg-mirror-t tr.zone-elimine td:first-child { box-shadow: inset 3px 0 0 var(--muted); }
.lg-mirror-t tr.zone-direct + tr.zone-barrage td, .lg-mirror-t tr.zone-barrage + tr.zone-elimine td { border-top: 2px dashed var(--border); }
.lg-mirror-leg { margin: .5rem 0 0; display: flex; flex-wrap: wrap; gap: .3rem .9rem; align-items: center; }
.lg-zone-dot { display: inline-block; width: .7rem; height: .7rem; border-radius: 2px; vertical-align: -1px; margin-right: .3rem; }
.lg-zone-dot.zone-direct { background: var(--ok, #16a34a); }
.lg-zone-dot.zone-barrage { background: var(--warn, #d97706); }
.lg-zone-dot.zone-elimine { background: var(--muted); }

/* ===== ERREUR D INSCRIPTION, A COTE DU CHAMP (07/09/2026). ===== */
.reg-err { margin: .25rem 0 0; font-size: .88rem; font-weight: 600; color: #b91c1c; }
:root:not([data-theme="light"]) .reg-err { color: #fca5a5; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .reg-err { color: #fca5a5; } }
:root[data-theme="dark"] .reg-err { color: #fca5a5; }
.field.reg-field-bad input { border-color: #b91c1c; box-shadow: 0 0 0 2px rgba(185,28,28,.14); }

/* Le bouton du classement devient « Valider » des qu on modifie un prono (08/09/2026). */
.lbd-go.lbd-go-valid { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 700; }
