/* ============================================================
   (Frontend)       Fortnite/CSS/fortnite.css
============================================================ */

button { cursor: pointer; }
.container { padding: 20px 30px; max-width: 1400px; margin: 0 auto; }

/* ===== SIDE NAV ===== */
.side-nav {
    position: fixed;
    top: 102px; left: 20px; bottom: 20px;
    width: 220px;
    display: flex; flex-direction: column;
    z-index: 998;
    border-radius: 24px;
    overflow: hidden;
    background: var(--z7-glass-fond);
    backdrop-filter: var(--z7-glass-flou);
    -webkit-backdrop-filter: var(--z7-glass-flou);
    border: 1px solid var(--z7-glass-bord);
    box-shadow: 0 16px 48px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.1);
}
.side-nav-logo {
    padding: 26px 20px 16px;
    display: flex; flex-direction: column; align-items: center; gap: 12px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.side-nav-logo-box {
    width: 56px; height: 56px; border-radius: 16px;
    background: rgba(0,0,0,0.35);
    border: 1px solid rgba(255,255,255,0.12);
    box-shadow: 0 4px 12px rgba(0,0,0,0.4);
    display: flex; align-items: center; justify-content: center;
}
.side-nav-logo-box img { height: 42px; width: auto; }
.side-nav-label {
    font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.5);
    letter-spacing: 1.5px; text-transform: uppercase;
    font-family: 'Arial Black', Arial, sans-serif;
}
.side-nav-items {
    flex: 1; display: flex; flex-direction: column;
    gap: 3px; padding: 12px; overflow-y: auto;
}
.side-nav-btn {
    width: 100%; display: flex; align-items: center; gap: 12px;
    padding: 12px 14px;
    border: 1px solid transparent;
    background: transparent;
    color: rgba(255,255,255,0.4);
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 12px; font-weight: 700;
    border-radius: 14px; cursor: pointer;
    transition: all 0.2s; text-align: left;
    text-transform: uppercase; letter-spacing: 0.5px;
}
.side-nav-btn svg { width: 16px; height: 16px; flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 2; }
.side-nav-btn:hover { background: rgba(255,255,255,0.07); border-color: rgba(255,255,255,0.1); color: rgba(255,255,255,0.85); }
.side-nav-btn.active {
    background: rgba(99,102,241,0.22);
    border-color: rgba(129,140,248,0.35);
    color: #c7d2fe;
    box-shadow: 0 1px 0 rgba(255,255,255,0.15) inset, 0 4px 12px rgba(99,102,241,0.2);
}
.side-nav-btn.active svg { stroke: #c7d2fe; }

/* ===== SIDE NAV BAS ===== */
.side-nav-bottom {
    padding: 12px 12px 18px;
    display: flex; flex-direction: column; gap: 4px;
    border-top: 1px solid rgba(255,255,255,0.06);
}
.side-nav-btn-profile {
    cursor: pointer;
    color: rgba(255,255,255,0.75);
    background: rgba(255,255,255,0.05);
    border-color: rgba(255,255,255,0.08);
    align-items: center;
}
.side-nav-btn-profile:hover { background: rgba(255,255,255,0.08); color: #fff; }
.side-nav-avatar {
    width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
    background: linear-gradient(135deg, #818cf8, #6366f1);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: #fff;
    border: 1px solid rgba(255,255,255,0.2);
    overflow: hidden;
}
.side-nav-profile-info { flex: 1; min-width: 0; }
.side-nav-profile-name { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.85); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-nav-profile-sub { font-size: 10px; color: rgba(255,255,255,0.3); margin-top: 1px; }
.side-nav-btn-back { color: rgba(255,255,255,0.55); border-color: rgba(255,255,255,0.08) !important; }
.side-nav-btn-back:hover { color: rgba(255,255,255,0.85) !important; background: rgba(255,255,255,0.07) !important; border-color: rgba(255,255,255,0.15) !important; }
.side-nav-btn-back svg { stroke: rgba(255,255,255,0.55); }
.side-nav-btn-panel {
    background: linear-gradient(135deg, rgba(99,102,241,0.35), rgba(139,92,246,0.35)) !important;
    border-color: rgba(139,92,246,0.4) !important;
    color: #e0e7ff !important;
}
.side-nav-btn-panel:hover {
    background: linear-gradient(135deg, rgba(99,102,241,0.55), rgba(139,92,246,0.55)) !important;
    border-color: rgba(167,139,250,0.55) !important;
    color: #fff !important;
}
.side-nav-btn-panel svg { stroke: #c7d2fe !important; }
.side-nav-panel-btn { width: 100% !important; height: 40px !important; border-radius: 12px !important; justify-content: center; margin-bottom: 4px; }
.side-nav-profile-pill { width: 100% !important; border-radius: 14px !important; padding: 10px 14px 10px 10px !important; justify-content: flex-start; min-height: 56px; }
.side-nav-profile-pill .nav-profile-pill-avatar { width: 38px !important; height: 38px !important; border-radius: 50% !important; flex-shrink: 0; }
.side-nav-profile-pill .nav-profile-pill-avatar img { border-radius: 50% !important; }
.side-nav-profile-pill .nav-profile-pill-name { font-size: 14px !important; font-weight: 700 !important; color: #fff !important; }
.side-nav-profile-info-block { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.side-nav-profile-role { font-size: 10px; color: rgba(255,255,255,0.3); font-family: 'Inter', Arial, sans-serif; font-weight: 500; letter-spacing: 0.3px; }

/* ===== SECTIONS ===== */
.fn-section { display: none; }
.fn-section.active { display: block; }
.fn-content {
    margin-left: calc(20px + 220px + 20px);
    margin-right: 20px;
    padding-top: 102px;
    min-height: 100vh;
    position: relative;
    z-index: 1;
}
#section-token, #section-bracket, #section-leaderboard, #section-wallet { padding-top: 0; }
.tournament-page { min-height: 100vh; }

/* ===== SUBNAV FIXE ===== */
.fn-subnav {
    position: fixed;
    top: 102px;
    left: calc(20px + 220px + 16px);
    right: 20px;
    height: 54px;
    z-index: 990;
    display: flex; align-items: center;
    background: rgba(255,255,255,0.03);
    backdrop-filter: blur(40px);
    -webkit-backdrop-filter: blur(40px);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 14px;
    padding: 0 16px;
    overflow: visible;
}
.subnav-content { display: none; width: 100%; align-items: center; gap: 12px; }
.subnav-content.active { display: flex; }
.subnav-left { display: flex; align-items: center; gap: 8px; flex: 1; }
.subnav-center { flex-shrink: 0; text-align: center; }
.subnav-right { display: flex; align-items: center; gap: 8px; flex: 1; justify-content: flex-end; }
.subnav-title { font-size: 15px; font-weight: 900; color: #fff; text-transform: uppercase; letter-spacing: 2px; white-space: nowrap; }
.subnav-title span { color: #33C6FF; }

/* Filtres select natif (cachés) */
.subnav-filter-group select {
    height: 32px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    color: rgba(255,255,255,0.7);
    font-size: 11px; font-weight: 700;
    font-family: 'Arial Black', Arial, sans-serif;
    padding: 0 10px;
    cursor: pointer; outline: none;
    transition: border-color 0.2s;
    white-space: nowrap;
}
.subnav-filter-group select:hover { border-color: rgba(255,255,255,0.2); }
.subnav-filter-group select option { background: #0d1117; }

/* Recherche */
.subnav-search {
    display: flex; align-items: center; gap: 7px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    padding: 0 12px;
    height: 32px;
    transition: border-color 0.2s;
    min-width: 160px;
}
.subnav-search:focus-within { border-color: rgba(255,255,255,0.2); }
.subnav-search svg { width: 13px; height: 13px; stroke: rgba(255,255,255,0.35); flex-shrink: 0; }
.subnav-search input { background: none; border: none; outline: none; color: #fff; font-size: 12px; font-family: Arial, sans-serif; width: 100%; }
.subnav-search input::placeholder { color: rgba(255,255,255,0.25); }

/* Bouton créer */
.subnav-btn-create {
    display: flex; align-items: center; gap: 6px;
    height: 32px; padding: 0 12px;
    background: rgba(99,102,241,0.2);
    border: 1px solid rgba(99,102,241,0.35);
    border-radius: 8px;
    color: #c7d2fe;
    font-size: 11px; font-weight: 700;
    font-family: 'Arial Black', Arial, sans-serif;
    cursor: pointer; transition: all 0.15s;
    white-space: nowrap; flex-shrink: 0;
}
.subnav-btn-create svg { width: 12px; height: 12px; }
.subnav-btn-create:hover { background: rgba(99,102,241,0.35); }

/* Tabs leaderboard */
.subnav-lb-tab {
    height: 32px; padding: 0 14px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    color: rgba(255,255,255,0.5);
    font-size: 12px; font-weight: 700;
    font-family: 'Arial Black', Arial, sans-serif;
    cursor: pointer; transition: all 0.15s; white-space: nowrap;
}
.subnav-lb-tab:hover { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.85); }
.subnav-lb-tab.active { background: rgba(99,102,241,0.25); border-color: rgba(99,102,241,0.45); color: #c7d2fe; }
.subnav-lb-tab { justify-content: center; }

/* Contenu décalé sous la subnav */
/*  Lot G1 - CDC-107 : « un peu plus d'espace vertical entre la barre
    superieure (filtres / recherche / Creer un defi) et Mes defis en
    cours ». La sous-navigation est fixee a 102 px et mesure 54 px : elle
    finit a 156 px. Le contenu commencait a 162 px, soit SIX pixels plus
    bas, et le titre de section semblait colle a la barre. */
.fn-content { padding-top: calc(102px + 54px + 18px) !important; }

/* Side nav droite */
.side-nav-right {
    position: fixed;
    top: 102px; right: 20px; bottom: 20px;
    width: 220px;
    border-radius: 24px;
    background: var(--z7-glass-fond);
    backdrop-filter: var(--z7-glass-flou);
    -webkit-backdrop-filter: var(--z7-glass-flou);
    border: 1px solid var(--z7-glass-bord);
    box-shadow: 0 16px 48px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.1);
    z-index: 998;
}
.fn-content { margin-right: calc(20px + 220px + 16px) !important; }

/* ============================================================
   LA COLONNE DE DROITE — l'emplacement, pas encore le contenu
   ============================================================
   Elle recevra les partenaires. AUCUN produit n'y est presente comme
   reel tant que l'integration n'est pas faite : ce qui s'y trouve est
   nomme « emplacement », et se voit comme tel. */
.fnt-pub { display: flex; flex-direction: column; gap: 10px; padding: 14px 12px; height: 100%; overflow: auto; }
.fnt-pub-titre {
    font-family: Arial, sans-serif;
    font-size: 9.5px; font-weight: 900;
    letter-spacing: 1.4px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.35);
}
.fnt-pub-case {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px;
    min-height: 150px;
    padding: 14px 10px;
    border-radius: 14px;
    border: 1px dashed rgba(255, 255, 255, 0.13);
    background: rgba(255, 255, 255, 0.02);
    text-align: center;
}
.fnt-pub-case svg { width: 20px; height: 20px; opacity: 0.35; }
.fnt-pub-case span {
    font-family: Arial, sans-serif;
    font-size: 10.5px; line-height: 1.5;
    color: rgba(255, 255, 255, 0.3);
}
.fnt-pub-note {
    margin-top: auto;
    font-family: Arial, sans-serif;
    font-size: 9.5px; line-height: 1.5;
    color: rgba(255, 255, 255, 0.22);
    text-align: center;
}
.fn-subnav { right: calc(20px + 220px + 16px) !important; }

/* ===== PAGE HEADER (legacy) ===== */
.page-header { display: flex; align-items: flex-end; justify-content: space-between; padding-bottom: 20px; margin-bottom: 20px; position: relative; min-height: 70px; }
.filters-bar { display: flex; gap: 10px; align-items: flex-end; flex: 1; }
.filter-group { display: flex; flex-direction: column; gap: 4px; }
.filter-group label { font-size: 10px; color: #fff; font-family: Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; }
.filter-group select { padding: 0 16px; height: 36px; width: 160px; background: #1a1a1a; border: 1px solid #3a3a3a; border-radius: 50px; color: #fff; font-size: 12px; font-family: Arial, sans-serif; font-weight: 700; cursor: pointer; transition: border-color 0.2s; outline: none; }
.filter-group select:hover { border-color: #33C6FF; }
.page-header-title { position: absolute; left: 50%; transform: translateX(-50%); text-align: center; pointer-events: none; white-space: nowrap; }
.page-title { font-size: 20px; font-weight: 900; color: #fff; text-transform: uppercase; letter-spacing: 2px; }
.page-title span { color: #33C6FF; }
.search-bar-wrap { display: flex; align-items: flex-end; gap: 10px; flex: 1; justify-content: flex-end; }
.search-bar { display: flex; align-items: center; gap: 8px; background: #1a1a1a; border: 1px solid #3a3a3a; border-radius: 50px; padding: 0 16px; height: 36px; width: 320px; transition: border-color 0.2s; }
.search-bar:focus-within { border-color: #33C6FF; }
.search-bar svg { width: 14px; height: 14px; flex-shrink: 0; }
.search-bar input { background: none; border: none; outline: none; color: #fff; font-size: 12px; font-family: Arial, sans-serif; width: 100%; }
.search-bar input::placeholder { color: #555; }
.btn-create-tournament { display: inline-flex; align-items: center; gap: 8px; padding: 0 20px; height: 36px; background: #1a1a1a; border: 1px solid #3a3a3a; border-radius: 50px; color: #fff; font-size: 12px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; white-space: nowrap; }
.btn-create-tournament:hover { border-color: #33C6FF; color: #33C6FF; }
.btn-create-tournament svg { width: 14px; height: 14px; }

/* ============================================================
   LES CARTES DE TOURNOI — refonte du 04/10/2026
   ============================================================
UNE SEULE AFFICHE PAR TOURNOI, ET UN SEUL CADRE POUR TOUTES.

   LE CADRE DE REFERENCE est celui de `Image/Tournois/image-random-tournois.png`,
   mesure dans le depot : 1080 x 1550, rapport 0,6968. C'est la decision
   du proprietaire, et elle a une consequence simple : une carte ne change
   ni de largeur ni de hauteur selon l'image qu'elle porte.

   LES AUTRES AFFICHES S'Y ADAPTENT. Elles ne font pas exactement ce
   rapport — 941x1672 (0,563) et 1024x1536 (0,667), les tournois en base
   480x720 et 502x720 (0,67). Elles remplissent le cadre
   (`object-fit: cover`) sans jamais etre deformees : l'ecart est pris
   symetriquement, 4 % pour les unes, 19 % pour la plus etroite.

   `aspect-ratio: 1080 / 1550` est ecrit tel quel, avec les deux nombres
   du fichier : le jour ou l'affiche de reference change, on lit ses
   dimensions et on remplace les deux nombres — rien d'autre.

   Les pastilles d'information viennent de `Common/CSS/tags.css`
   (`z7-tag`), validees sur l'Accueil le 04/10/2026. Rien n'est redefini
   ici : deux pages qui montrent la meme information doivent la dessiner
   au meme endroit.
   ============================================================ */

/* ---- ce que les trois cartes partagent ---- */
.fnt-ligne {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: Arial, sans-serif;
    font-size: 11.5px;
    color: rgba(255, 255, 255, 0.5);
    min-width: 0;
}
.fnt-ligne svg { width: 13px; height: 13px; flex-shrink: 0; opacity: 0.75; }
.fnt-lbl {
    color: rgba(255, 255, 255, 0.45);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    font-size: 10px;
}
/*  L'ENTREE EST CE QU'ON PAIE, LA CAGNOTTE CE QU'ON GAGNE. Les deux
    etaient en or et se confondaient : seule l'entree le reste. */
.fnt-ligne--entree { color: #FFB700; font-weight: 700; }
.fnt-ligne--lot    { color: #c3b5ff; font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; display: block; }
.fnt-ligne--lot .fnt-lbl { color: rgba(255, 255, 255, 0.45); }

/*  LA CAGNOTTE. Vert = garantie, c'est-a-dire reellement provisionnee
    dans le registre (`prizepoolGaranti`) ; or = annoncee seulement. */
.fnt-cash {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    max-width: 46%;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 3px 8px 3px 6px;
    border-radius: 7px;
    background: rgba(255, 183, 0, 0.1);
    border: 1px solid rgba(255, 183, 0, 0.4);
    color: #FFB700;
    font-family: Arial, sans-serif;
    font-size: 10px;
    font-weight: 900;
    white-space: nowrap;
    line-height: 1.4;
}
.fnt-cash svg { width: 11px; height: 11px; flex-shrink: 0; }
/*  UNE RECOMPENSE QUI N'EST PAS EN COINS. Elle porte sa propre couleur :
    ni le vert d'une cagnotte provisionnee, ni l'or d'une cagnotte
    annoncee — on ne fait pas passer un lot pour de l'argent. */
/*  Dans la carte mise en avant, la pastille partage sa ligne avec le nom
    du tournoi. 50 % : « 150 Coins » demande 86 px et la colonne en fait
    201 — en dessous, c'est la cagnotte qui se coupait ; au-dessus,
    c'etait le nom. */
/*  UN LOT PORTE UN TEXTE LIBRE, parfois tres long : il se contente de
    38 % et laisse le nom du tournoi tenir en deux lignes. Le texte entier
    reste dans l'infobulle. */
/*  L'ELLIPSE A BESOIN D'UN ELEMENT. Dans une boite `inline-flex`, un
    simple texte n'est pas coupe par `text-overflow` : « Pack Z7 + 1 mois
    de coaching » devenait « Pack Z7 + », sans rien qui le dise. */
.fnt-cash-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/*  Les boutons d'une carte etroite : un cran plus petit, et un
    remplissage lateral reduit. « INSCRIPTIONS » mesure 72 px a cette
    taille, la boite 69 : ce sont les 16 px de remplissage qui
    manquaient. On ne coupe pas les mots en deux — « INSCRIPTIO / NS »
    se lit plus mal qu'un mot un peu serre. */
/*  CHAQUE PIXEL DE HAUTEUR RENDU EST UN PIXEL DE LARGEUR GAGNE. L'affiche
    vaut `hauteur x 0,697` : resserrer les quatre cases du decompte de
    4 px retire 3 px a l'affiche et les donne au texte. */
.fnt-cash--lot {
    background: rgba(139, 92, 246, 0.14);
    border-color: rgba(139, 92, 246, 0.45);
    color: #c4b5fd;
}
.fnt-cash.est-garanti {
    background: rgba(40, 167, 69, 0.12);
    border-color: rgba(40, 167, 69, 0.45);
    color: #4ade80;
}

/*  LE DECOMPTE : quatre cases, comme sur l'Accueil. `minmax(0, 1fr)`
    empeche une piste de refuser de descendre sous la largeur de
    « SECONDES » ; `tabular-nums` fige les chiffres. */
.fnt-chrono {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
}
.fnt-chrono[hidden] { display: none; }
.fnt-case {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 0;
    padding: 3px 2px;
    border-radius: 6px;
    background: rgba(99, 102, 241, 0.1);
    border: 1px solid rgba(99, 102, 241, 0.25);
}
.fnt-case-val {
    font-family: Arial, sans-serif;
    font-size: 13px; font-weight: 900; line-height: 1.05;
    color: #c7cbff;
    font-variant-numeric: tabular-nums;
}
.fnt-case-lbl {
    margin-top: 1px;
    font-family: Arial, sans-serif;
    font-size: 6.5px; font-weight: 700;
    letter-spacing: 0.4px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.38);
    line-height: 1.1;
}

/*  LA JAUGE N'EXISTE QUE SI LE COMPTE EXISTE — voir `jaugeHtml`. */
.fnt-jauge { min-width: 0; }
.fnt-jauge-txt {
    font-family: Arial, sans-serif;
    font-size: 10.5px;
    color: rgba(255, 255, 255, 0.42);
    margin-bottom: 4px;
}
.fnt-barre { height: 5px; border-radius: 50px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.fnt-barre span { display: block; height: 100%; border-radius: 50px; background: linear-gradient(90deg, #6366f1, #8b5cf6); }

/*  LES ACTIONS. Le ton dit l'etat, et la grammaire est celle des
    pastilles : fond tres sombre, contour de la couleur du sens. */
.fnt-actions { display: flex; gap: 6px; margin-top: auto; padding-top: 8px; }
.fnt-btn {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 6px 8px;
    min-height: 36px;
    border-radius: 9px;
    border: 1px solid transparent;
    background: none;
    font-family: Arial, sans-serif;
    font-size: 10px; font-weight: 900;
    letter-spacing: 0.4px; text-transform: uppercase;
    text-decoration: none; line-height: 1.2;
    cursor: pointer;
}
.fnt-btn--voir   { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.16); color: rgba(255, 255, 255, 0.82); }
.fnt-btn--voir:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.fnt-btn--accent { background: linear-gradient(135deg, rgba(99, 102, 241, 0.9), rgba(139, 92, 246, 0.9)); border-color: rgba(139, 92, 246, 0.55); color: #fff; }
.fnt-btn--accent:hover { filter: brightness(1.12); }
.fnt-btn--succes { background: rgba(40, 167, 69, 0.14); border-color: rgba(40, 167, 69, 0.5); color: #4ade80; }
.fnt-btn--danger { background: rgba(220, 53, 69, 0.14); border-color: rgba(220, 53, 69, 0.5); color: #ef4444; }
button.fnt-btn--danger:hover { background: rgba(220, 53, 69, 0.22); }
.fnt-btn--alerte { background: rgba(255, 183, 0, 0.12); border-color: rgba(255, 183, 0, 0.45); color: #FFB700; }
.fnt-btn--neutre { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.14); color: rgba(255, 255, 255, 0.72); }
/*  Un ETAT n'est pas un bouton : rien a cliquer, et le curseur ne
    promet rien. */
.fnt-btn.est-inactif { cursor: default; opacity: 0.92; }

/* ============================================================
   MIS EN AVANT — LE CONTENEUR, ET RIEN D'AUTRE
   ============================================================
   LA CARTE N'EST PLUS DESSINEE ICI. Z7-TOURNAMENT-FEATURED vit dans
   `Common/CSS/carte-une.css`, et son gabarit dans
   `Common/JS/carte-une.js` : l'Accueil montre exactement la meme carte.
   Cette page ne pose que ce qui lui appartient — le carrousel, et
   l'ECHELLE de la variante « compact ».
   ============================================================ */
.featured-carousel-wrapper { position: relative; padding: 4px 44px 10px; overflow: visible; container-type: inline-size; }
.featured-carousel { display: flex; gap: 14px; overflow-x: auto; scroll-behavior: smooth; padding: 4px 2px 8px; scrollbar-width: none; }
.featured-carousel::-webkit-scrollbar { display: none; }
/*  Rien a faire defiler : les fleches n'ont pas lieu d'etre. */
.featured-carousel-wrapper.est-unique { padding-left: 4px; padding-right: 4px; }
.featured-carousel-wrapper.est-unique .carousel-nav-btn { display: none; }

/*  COMBIEN DE CARTES, ET POURQUOI. L'affiche vaut `hauteur x 0,6968` :
    ce qui reste va au texte. Trois cartes dans 1199 px donnent 228 px de
    texte par carte ; deux dans 719 en donnent 182 ; deux dans 645 n'en
    donneraient que 155, et c'est la colonne compressee qu'on a corrigee.
    Le plancher est donc une carte de ~340 px : en dessous, on en montre
    MOINS, pas de plus petites.

    LES SEUILS SONT CEUX DU CONTENEUR, pas de l'ecran : entre la barre
    laterale et la colonne partenaires, une fenetre de 1920 px ne laisse
    ici que 1199 px, et une fenetre de 1440 px n'en laisse que 719. Une
    regle en `@media` decrirait un espace qui n'existe pas. */
/*  ============================================================
    TROIS CARTES COMPLETES, ET C'EST LA CARTE QUI S'ADAPTE
    ============================================================
    PRIORITE 1 : trois cartes entieres visibles a 1920. La largeur d'une
    carte n'est donc pas un choix, c'est une consequence :

        largeur = (piste utile - 2 gouttieres) / 3

    A 1920 la piste utile fait 1199 px (le conteneur du carrousel, moins
    les 4 px de remplissage de la piste) : 1199 - 28 = 1171, divise par
    3 = 390 px.

    LA CARTE SE REDUIT POUR Y ENTRER, ELLE NE SE COMPRIME PAS. Son
    gabarit maitre fait 520 px : l'unite du composant vaut donc 390/520,
    soit 0,75, et TOUT suit ensemble -- polices, remplissages, cadre de
    l'affiche, hauteurs reservees. Le rapport interne, lui, ne bouge pas
    d'un point : l'affiche reste a 34 % de la carte et la colonne de
    texte a 66 %. C'est cela que << plus large >> voulait dire -- le
    RAPPORT INTERNE, pas la largeur exterieure.

    Une largeur fixe de 520 px faisait deborder la troisieme carte :
    deux cartes et demie dans la piste. Interdit.

    LE PIEGE DES UNITES DE CONTENEUR EST EVITE : `cqw` se resout sur le
    conteneur ANCETRE, et c'est `.featured-carousel-wrapper`. La carte
    n'est pas conteneur, donc elle, sa colonne de texte et le cadre de
    l'affiche lisent tous la MEME reference. C'est en declarant la carte
    elle-meme conteneur qu'on avait vu le rapport du cadre tomber de
    0,697 a 0,618.

    SOUS 760 px DE FENETRE, RIEN DE TOUT CECI NE S'APPLIQUE : la carte
    se redresse, l'affiche passe au-dessus, et elle n'a plus besoin de
    520 px de large -- son unite reste 1.
    ============================================================ */
/*  COMBIEN DE CARTES PAR VUE : une regle de MISE EN PAGE, et elle vaut
    a TOUTE largeur de fenetre. Elle etait un temps enfermee avec les
    regles d'echelle dans `@media (min-width: 760px)` : sur telephone
    elle ne s'appliquait plus, la piste revenait a trois cartes et
    chacune faisait 80 px de large. Les deux reglages sont donc separes.

    `min(part, gabarit)` : la carte prend sa part de la piste, mais ne
    depasse JAMAIS son gabarit maitre. Sans ce plafond, une piste de
    641 px posait une carte de 641 — l'affiche retombait a 27 % et la
    carte cessait d'etre la carte maitre. */
.featured-carousel .z7-une { flex: 0 0 min(calc((100% - 28px) / 3), calc(520 * var(--z7-u))); }
@container (max-width: 1141px) {
    .featured-carousel .z7-une { flex-basis: min(calc((100% - 14px) / 2), calc(520 * var(--z7-u))); }
}
@container (max-width: 757px) {
    .featured-carousel .z7-une { flex-basis: min(100%, calc(520 * var(--z7-u))); }
}

/*  L'ECHELLE, elle, ne concerne que le desktop : sous 760 px la carte
    se redresse, l'affiche passe au-dessus, et elle n'a plus besoin de
    520 px de large — son unite reste 1. */
@media (min-width: 760px) {
    /*  TROIS cartes : deux gouttieres de 14 px, plus les 4 px de
        remplissage de la piste. */
    .featured-carousel-wrapper .z7-une {
        --z7-u: min(1px, calc((100cqw - 32px) / 1560));
    }
    @container (max-width: 1141px) {
        .featured-carousel-wrapper .z7-une {
            --z7-u: min(1px, calc((100cqw - 18px) / 1040));
        }
    }
    @container (max-width: 757px) {
        .featured-carousel-wrapper .z7-une {
            --z7-u: min(1px, calc((100cqw - 4px) / 520));
        }
    }
}
/*  LE DESSIN DES FLECHES, RESTAURE A L'IDENTIQUE. Cette regle avait ete
    emportee par `e7238e7` : elle etait ecrite juste apres les regles
    `.fnt-*` de l'ancienne carte, et le bloc retire pour passer au
    composant commun l'a avalee avec elles. Les fleches ne gardaient
    alors que la taille que `Common/CSS/mobile.css` leur donne sur
    petit ecran — plus de rond, plus de position, plus de centrage.

    Elles appartiennent au CARROUSEL, pas a la carte : c'est la
    gouttiere de 44 px du conteneur qui leur fait leur place, et aucune
    dimension de `Z7-TOURNAMENT-FEATURED` n'entre dans ce calcul. */
.carousel-nav-btn {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 36px; height: 36px;
    background: rgba(255,255,255,0.08);
    border: 1px solid rgba(255,255,255,0.15);
    color: #fff; font-size: 18px; border-radius: 50%;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
    transition: all 0.2s; z-index: 10;
    backdrop-filter: blur(10px);
}
.carousel-nav-btn:hover:not(:disabled) { background: #33C6FF; border-color: #33C6FF; color: #000; }
/*  Une fleche au bout de sa course reste a sa place — un bouton qui
    disparait deplace les deux autres — mais elle dit qu'elle n'a plus
    rien a montrer. */
.carousel-nav-btn:disabled { opacity: 0.28; cursor: default; }
.carousel-btn-prev { left: 0; }
.carousel-btn-next { right: 0; }

/* ============================================================
   Z7-SELECTION — LES RECOMMANDATIONS PARTENAIRES
   ============================================================
   Composant UNIQUE de cette page : il ne vit que dans la colonne de
   droite. Le jour ou une deuxieme page en aura besoin, il demenagera
   dans `Common/` — pas avant, c'est la regle du registre.

   IL S'ADAPTE A LA COLONNE, ET NON L'INVERSE. La colonne fait 220 px,
   dont 174 utiles dans la carte : toutes les mesures ci-dessous en
   decoulent. Elargir la colonne aurait demande de deplacer le contenu
   de la page — c'est exactement ce qu'on refuse de faire.

   UNE FICHE HORIZONTALE, dans 174 px : le visuel a gauche (40 %), les
   informations a droite (60 %), le bouton sous les deux, et la
   signature du marchand en pied. C'est la composition d'une petite
   fiche produit, pas d'une vignette.

   LE DESSIN REPREND CE QUI EXISTE : fond, contour et survol viennent
   des jetons de `Z7-GLASS-STYLE` ; le violet du bouton est celui de la
   barre de progression des cartes de tournoi. Rien n'est redefini.
   ============================================================ */
.z7-selection { display: flex; flex-direction: column; gap: 9px; }
.z7-selection:empty { display: none; }

.z7-sel-source {
    font-family: Arial, sans-serif;
    font-size: 9px; font-weight: 900;
    letter-spacing: 1.1px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.22);
    margin-top: -7px;
}

/*  LA MENTION, DISCRETE MAIS LISIBLE. Elle occupait un encadre presque
    aussi haut que le produit ; elle tient maintenant en deux lignes de
    texte sous les cartes. Une information obligatoire n'a pas besoin
    d'etre encombrante pour etre honnete. */
.z7-sel-mention {
    font-family: Arial, sans-serif;
    font-size: 8.5px;
    line-height: 1.45;
    color: rgba(255, 255, 255, 0.26);
    padding: 0 2px;
}

/* ---- LA FICHE ---- */
/*  ELLE EST VERTICALE, et c'est la largeur de la colonne qui le decide.
    Une composition horizontale copiee d'une maquette large donnait, dans
    174 px utiles, un micro de 77 px a cote d'un texte de 90 : deux
    petites choses au lieu d'une grande. Ici le produit occupe toute la
    largeur et pres de la moitie de la hauteur. */
.z7-sel-carte {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 0 10px 10px;
    border-radius: 13px;
    overflow: hidden;
    text-decoration: none;
    background:
        linear-gradient(170deg, rgba(139, 92, 246, 0.08), rgba(139, 92, 246, 0) 55%),
        var(--z7-glass-fond);
    border: 1px solid var(--z7-glass-bord);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
    transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s;
}
.z7-sel-carte:hover {
    border-color: rgba(139, 92, 246, 0.5);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.3);
    transform: translateY(-2px);
}
.z7-sel-carte:focus-visible {
    outline: 2px solid rgba(139, 92, 246, 0.8);
    outline-offset: 2px;
}

/*  LE VISUEL : PLUS DE CADRE, ET LE VIDE DU FICHIER EST ROGNE.
    ============================================================
    Le micro n'occupe qu'environ 36 % de la largeur du fichier et 75 %
    de sa hauteur : le reste est du fond. Pose tel quel dans une boite
    de 174 px, il mesurait 63 px de haut — une vignette.

    On ne deforme pas et on ne rogne pas le PRODUIT : on rogne le VIDE.
    L'image est posee a 100 % de la largeur, ce qui lui donne 189 px de
    haut pour un fichier de rapport 750/816 ; la zone n'en montre que
    162, et les 13 px de trop, en haut comme en bas, ne contiennent que
    du fond. Mesure : le micro commence a 21 px du haut de l'image
    rendue et finit a 162 — il est donc entier, a l'interieur de la
    fenetre, avec de la marge des deux cotes.

    Le petit carre gris a disparu : le fichier porte deja son propre
    fond sombre, qui remplit maintenant la zone d'un bord a l'autre et
    tient lieu de banniere produit. Rien a recopier, rien a inventer. */
.z7-sel-visuel {
    position: relative;
    display: block;
    width: calc(100% + 20px);
    margin: 0 -10px 3px;
    height: 162px;
    overflow: hidden;
    color: rgba(255, 255, 255, 0.4);
}
.z7-sel-visuel img {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: auto;
    object-fit: contain;
    display: block;
}
/*  Le repli, pour un produit sans visuel autorise : l'icone generique
    de sa categorie, centree dans la meme zone. */
.z7-sel-visuel svg {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 42px; height: 42px;
}

.z7-sel-nom {
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 12px; font-weight: 900;
    line-height: 1.2;
    letter-spacing: 0.2px;
    text-transform: uppercase;
    color: #fff;
    overflow-wrap: anywhere;
}
.z7-sel-usage {
    font-family: Arial, sans-serif;
    font-size: 9px;
    line-height: 1.35;
    color: rgba(255, 255, 255, 0.38);
    margin-top: -4px;
}

/*  LE BOUTON NE DOIT PAS DOMINER. Le violet Z7 — celui de la barre de
    progression des cartes de tournoi — mais pose plus bas et plus
    mince que le produit : c'est le micro que l'oeil doit rencontrer en
    premier. */
.z7-sel-cta {
    display: flex; align-items: center; justify-content: center; gap: 5px;
    margin-top: 2px;
    padding: 6px 8px;
    border-radius: 8px;
    background: linear-gradient(90deg, #6366f1, #8b5cf6);
    border: 1px solid rgba(255, 255, 255, 0.12);
    font-family: Arial, sans-serif;
    font-size: 9px; font-weight: 900;
    letter-spacing: 0.6px; text-transform: uppercase;
    color: #fff;
    white-space: nowrap;
}
.z7-sel-cta svg { width: 9px; height: 9px; flex-shrink: 0; }
.z7-sel-carte:hover .z7-sel-cta { filter: brightness(1.12); }

/*  LA ZONE COMMERCIALE — compacte, et seulement si elle a quelque chose
    a dire. Chaque information disparait proprement en son absence : pas
    de tiret, pas de cadre vide. Une carte sans prix doit avoir l'air
    d'une carte sans prix, pas d'une carte cassee.

    ELLE NE DOIT PAS PRENDRE LE DESSUS. Le produit et son nom restent
    les deux premieres choses que l'oeil rencontre ; le prix vient
    apres, et le bouton apres lui. */
.z7-sel-commerce {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-top: 1px;
}
.z7-sel-prix-ligne {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 5px;
}
.z7-sel-prix {
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 14px; font-weight: 900;
    line-height: 1.1;
    color: #fff;
}
/*  La remise se voit sans crier : un vert sobre, pas un aplat rouge de
    site de soldes. */
.z7-sel-remise {
    font-family: Arial, sans-serif;
    font-size: 8.5px; font-weight: 900;
    letter-spacing: 0.3px;
    padding: 2px 5px;
    border-radius: 5px;
    background: rgba(74, 222, 128, 0.14);
    border: 1px solid rgba(74, 222, 128, 0.4);
    color: #4ade80;
    white-space: nowrap;
}
/*  L'ancien prix SITUE l'offre, il ne la vend pas : barre, efface, et
    sur la meme ligne pour ne pas couter une hauteur de plus. */
.z7-sel-ancien {
    font-family: Arial, sans-serif;
    font-size: 9px;
    text-decoration: line-through;
    color: rgba(255, 255, 255, 0.3);
    white-space: nowrap;
}
/*  La pastille de disponibilite : un point, et un mot. */
.z7-sel-dispo {
    display: flex; align-items: center; gap: 5px;
    font-family: Arial, sans-serif;
    font-size: 9px; font-weight: 700;
    color: rgba(74, 222, 128, 0.85);
}
.z7-sel-dispo::before {
    content: '';
    width: 5px; height: 5px;
    border-radius: 50%;
    background: #4ade80;
    flex-shrink: 0;
}
.z7-sel-livraison {
    font-family: Arial, sans-serif;
    font-size: 8.5px;
    color: rgba(255, 255, 255, 0.3);
}

/*  LE PIED : le logo du marchand, petit et discret. Il n'apparait que
    si le fichier existe — voir `Z7_SELECTION_LOGO`. */
.z7-sel-pied {
    display: flex; align-items: center; justify-content: flex-start;
    margin-top: 2px;
}
.z7-sel-logo {
    height: 13px; width: auto;
    opacity: 0.75;
    display: block;
}

/* ===== TOURNOIS ===== */
.tournaments-section { margin-bottom: 40px; }
.section-header-box { display: inline-block; padding: 8px 28px 8px 16px; margin-bottom: 24px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%); }
.section-header-box.soon, .section-header-box.ongoing, .section-header-box.bientot { background: #33C6FF; }
.section-header-box.finished { background: #dc3545; }
.section-header-box.encours { background: #FF6B35; }
.section-header-box.encours .section-title, .section-header-box.finished .section-title { color: #fff; }
.section-header-box.bientot .section-title { color: #000; }
.section-title { font-size: 15px; font-weight: 900; color: #000; text-transform: uppercase; letter-spacing: 2px; margin: 0; }
/* ============================================================
   BIENTOT / EN COURS — LA CARTE EST L'AFFICHE
   ============================================================
   C'est le principe de la maquette, et c'est ce qui manquait : l'affiche
   ne vit pas A COTE des informations, elle EST la carte. Le texte se pose
   dessus, dans la partie basse, sur un fondu progressif vers le noir.

   Le cadre est celui de reference (1080x1550) : toutes les cartes ont la
   meme forme, quelle que soit l'affiche qu'elles portent. Le texte etant
   POSE SUR l'image, la carte ne coute que la hauteur de l'affiche.
   ============================================================ */
.fnt-grille {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(max(208px, 17%), 1fr));
    gap: 14px;
    align-items: stretch;
}

.fnt-carte {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-width: 0;
    aspect-ratio: 1080 / 1550;
    border-radius: 14px;
    overflow: hidden;
    background: rgba(5, 8, 15, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.09);
    transition: border-color 0.2s, transform 0.2s;
}
.fnt-carte:hover { border-color: rgba(139, 92, 246, 0.5); transform: translateY(-2px); }
.fnt-carte.est-en-cours { border-color: rgba(255, 107, 53, 0.45); }

/*  L'affiche remplit la carte, derriere tout le reste. */
.fnt-carte-visuel { position: absolute; inset: 0; display: block; line-height: 0; }
.fnt-carte-affiche {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/*  LE FONDU. Il part du milieu et devient franc en bas : au-dessus,
    l'affiche se voit entierement ; en dessous, le texte se lit sur une
    surface quasi opaque. */
.fnt-carte-voile {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom,
        rgba(8, 11, 19, 0) 0%,
        rgba(8, 11, 19, 0.15) 28%,
        rgba(8, 11, 19, 0.75) 48%,
        rgba(8, 11, 19, 0.96) 66%,
        rgba(8, 11, 19, 1) 100%);
    pointer-events: none;
}

/*  La ligne du haut : l'etat « en cours » a gauche, la cagnotte a droite. */
.fnt-carte-haut {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 10px 10px 0;
    margin-bottom: auto;
}
/*  La cagnotte va A DROITE, qu'il y ait ou non une pastille « en cours »
    a sa gauche. `space-between` la collait au bord gauche des que le
    voisin manquait. */
/*  LA LIGNE DU HAUT EST POSEE SUR L'AFFICHE, LA OU LE FONDU NE FAIT
    ENCORE RIEN. Le fond translucide des pastilles suffit sur une affiche
    sombre ; sur une affiche claire — un fond violet vif, un ciel bleu —
    le texte vert ou orange s'y perd. On leur donne donc ICI, et
    seulement ici, un fond reellement opaque : la teinte de la pastille
    est conservee, elle est simplement posee sur du noir. */
.fnt-carte-haut .fnt-cash {
    margin-left: auto;
    background:
        linear-gradient(rgba(255, 183, 0, 0.14), rgba(255, 183, 0, 0.14)),
        rgba(6, 9, 16, 0.88);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
}
.fnt-carte-haut .fnt-cash.est-garanti {
    background:
        linear-gradient(rgba(40, 167, 69, 0.16), rgba(40, 167, 69, 0.16)),
        rgba(6, 9, 16, 0.88);
}
.fnt-carte-haut .fnt-direct {
    background:
        linear-gradient(rgba(255, 107, 53, 0.2), rgba(255, 107, 53, 0.2)),
        rgba(6, 9, 16, 0.88);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
}
.fnt-direct {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 8px 3px 6px;
    border-radius: 7px;
    background: rgba(255, 107, 53, 0.16);
    border: 1px solid rgba(255, 107, 53, 0.5);
    color: #ffb08a;
    font-family: Arial, sans-serif;
    font-size: 9px;
    font-weight: 900;
    letter-spacing: 0.8px;
    text-transform: uppercase;
}
.fnt-direct-point {
    width: 6px; height: 6px; border-radius: 50%;
    background: #FF6B35;
    box-shadow: 0 0 8px #FF6B35;
}

/*  Le corps est POSE SUR l'affiche, dans la partie basse. */
.fnt-carte-corps {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 0 11px 11px;
}
/*  LE NOM EST AU-DESSUS DES PASTILLES — c'est l'ordre valide sur
    l'Accueil. Deux lignes sont reservees pour que les cartes d'une
    rangee s'alignent, et un nom plus long est coupe proprement. */
.fnt-carte-nom {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
    text-decoration: none;
    color: #fff;
    font-size: 13px; font-weight: 900;
    text-transform: uppercase; letter-spacing: 0.3px;
    line-height: 1.2;
    min-height: 2.4em;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.8);
}

/* ============================================================
   TERMINE — des cartes horizontales compactes
   ============================================================
   LE GAGNANT N'EST PAS DANS LA LISTE : `GET /tournaments` ne porte aucun
   resultat. Il est demande par tournoi a la seule route publique qui en
   rend (`/leaderboard/tournament/:id`), et UNIQUEMENT pour les cartes
   affichees. Tant qu'on ne sait pas, la carte ne dit rien ; quand il n'y
   a pas de resultat publie, elle le dit. */
.fnt-mois { margin-bottom: 18px; }
.fnt-mois-titre {
    font-family: Arial, sans-serif;
    font-size: 11px; font-weight: 900;
    text-transform: uppercase; letter-spacing: 1.2px;
    color: rgba(255, 255, 255, 0.4);
    margin-bottom: 8px;
}
.fnt-fin-liste { display: flex; flex-direction: column; gap: 8px; }

.fnt-fin {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px 8px 8px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.035);
    border: 1px solid rgba(255, 255, 255, 0.07);
    transition: border-color 0.2s;
}
.fnt-fin:hover { border-color: rgba(255, 255, 255, 0.16); }

.fnt-fin-visuel { flex: 0 0 46px; line-height: 0; border-radius: 8px; overflow: hidden; background: rgba(5, 8, 15, 0.7); }
.fnt-fin-affiche {
    display: block;
    width: 100%;
    aspect-ratio: 1080 / 1550;
    object-fit: cover;
}

.fnt-fin-corps { flex: 1 1 40%; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.fnt-fin-nom-tournoi {
    text-decoration: none;
    color: rgba(255, 255, 255, 0.9);
    font-size: 12.5px; font-weight: 900;
    text-transform: uppercase; letter-spacing: 0.3px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fnt-fin-meta { font-family: Arial, sans-serif; font-size: 11px; color: rgba(255, 255, 255, 0.35); }

.fnt-fin-gagnant {
    flex: 0 1 220px;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: Arial, sans-serif;
    font-size: 12px;
    color: #FFB700;
}
.fnt-fin-gagnant svg { width: 14px; height: 14px; flex-shrink: 0; }
.fnt-fin-nom { font-weight: 900; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fnt-fin-pts { color: rgba(255, 255, 255, 0.45); font-weight: 700; flex-shrink: 0; }
.fnt-fin-vide { color: rgba(255, 255, 255, 0.28); font-style: italic; }

.fnt-fin-action { flex: 0 0 150px; min-height: 32px; }

.empty-msg { text-align: center; padding: 28px 20px; color: rgba(255, 255, 255, 0.3); font-family: Arial, sans-serif; font-size: 13px; }
/*  UNE PANNE N'EST PAS UN VIDE. Quand la liste n'a pas pu etre demandee,
    le message le dit, et il se voit. */
.empty-msg--panne {
    color: #FFB700;
    background: rgba(255, 183, 0, 0.07);
    border: 1px solid rgba(255, 183, 0, 0.3);
    border-radius: 12px;
    max-width: 760px;
    margin: 0 auto;
    line-height: 1.6;
}

/*  Les deux classes ci-dessous servent encore a la fiche du tournoi et a
    la page bracket, qui ont leur propre feuille : on ne les retire pas. */
.tournament-badges { display: flex; gap: 4px; flex-wrap: wrap; }
.tournament-badge { padding: 2px 6px; border-radius: 50px; font-size: 8px; font-weight: 700; color: #000; text-transform: uppercase; display: inline-block; }


/* ===== GLASS SECTION ===== */
.fn-glass-section { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 18px; padding: 18px 20px 14px; margin-bottom: 20px; overflow: visible; }
.fn-section-header { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.fn-section-title { font-size: 11px; font-weight: 900; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 2px; font-family: 'Arial Black', Arial, sans-serif; }
.fn-section-title-dot { width: 6px; height: 6px; border-radius: 50%; background: #FFB700; box-shadow: 0 0 8px #FFB700; flex-shrink: 0; }
.fn-section-title-line { flex: 1; height: 1px; background: rgba(255,255,255,0.06); }

/* ===== SECTION TERMINÉ ===== */
/*  `.finished-limited` a ete retire : il COUPAIT la liste en hauteur au
    lieu de la paginer. Toutes les cartes etaient dans le DOM, cachees
    sous un couvercle de 452 px, et le bouton censes le relever appelait
    une fonction inexistante. La limite est maintenant dans le JS, par
    lots de cartes reellement construites. */
.fn-voir-plus-btn { padding: 8px 24px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 50px; color: rgba(255,255,255,0.5); font-size: 12px; font-weight: 700; font-family: 'Arial Black', Arial, sans-serif; cursor: pointer; transition: all 0.2s; text-transform: uppercase; letter-spacing: 0.5px; }
.fn-voir-plus-btn:hover { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.8); border-color: rgba(255,255,255,0.2); }

/* ===== FOOTER ===== */
.fn-footer { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 20px 0 30px; font-size: 11px; color: rgba(255,255,255,0.25); font-family: Arial, sans-serif; }
.fn-footer-sep { color: rgba(255,255,255,0.15); }
.fn-footer-link { color: rgba(255,255,255,0.25); text-decoration: none; transition: color 0.2s; }
.fn-footer-link:hover { color: rgba(255,255,255,0.6); }

/* ===== LIVE TICKER ===== */
.live-ticker-wrap { display: flex; align-items: center; gap: 12px; background: linear-gradient(135deg, rgba(220,53,69,0.12), rgba(255,255,255,0.03)); border: 1px solid rgba(220,53,69,0.25); border-radius: 14px; padding: 10px 16px; margin-bottom: 12px; overflow: hidden; height: 46px; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); box-shadow: 0 4px 20px rgba(220,53,69,0.1), inset 0 1px 0 rgba(255,255,255,0.06); }
.live-ticker-label { display: flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 900; color: #fff; white-space: nowrap; flex-shrink: 0; background: rgba(220,53,69,0.15); border: 1px solid rgba(220,53,69,0.3); border-radius: 50px; padding: 3px 10px; letter-spacing: 1px; text-transform: uppercase; }
.live-ticker-label::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #dc3545; box-shadow: 0 0 6px #dc3545; animation: pulse-dot 1.2s ease-in-out infinite; flex-shrink: 0; }
@keyframes pulse-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.7); } }
.live-ticker { flex: 1; overflow: hidden; position: relative; }
.live-ticker-inner { display: flex; align-items: center; gap: 24px; animation: ticker 30s linear infinite; white-space: nowrap; width: max-content; }
.ticker-item { display: flex; align-items: center; gap: 8px; white-space: nowrap; flex-shrink: 0; }
.ticker-avatar { width: 26px; height: 26px; border-radius: 50%; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.15); display: flex; align-items: center; justify-content: center; font-size: 10px; color: #33C6FF; font-weight: 900; }
.ticker-name { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.8); }
.ticker-gain { font-size: 12px; font-weight: 900; color: #4ade80; }
.ticker-sep { color: rgba(255,255,255,0.15); font-size: 16px; }
@keyframes ticker { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }

/* ===== TOKEN ===== */
.section-title-bar { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
.section-heading { font-size: 18px; font-weight: 900; color: #fff; letter-spacing: 1px; }
.section-subheading { font-size: 12px; color: #666; font-family: Arial, sans-serif; }
/*  LA GRILLE ET LA CARTE SONT REDESSINEES PLUS BAS — voir
    « LA CARTE DE DEFI 1V1 ». */
/* ---------------------------------------------------------------
   Lot G1 - CDC-100 : « rien ne sort de son conteneur ».

   Mesure du 02/10/2026 : un titre de soixante caracteres sans espace
   faisait deborder la page de 165 px sur un telephone de 390 px. Le
   titre d'une carte porte un libelle choisi par le createur du defi, et
   la ligne du dessous porte son pseudo : les deux viennent d'un joueur,
   et un mot de quarante lettres sans espace y est permis.

   J'avais ajoute aussi `min-width: 0` sur la carte. La morsure a montre
   qu'il ne tenait rien - le retirer laisse les tests verts -, et il est
   parti : la coupure du mot suffit, parce qu'elle fait tomber la largeur
   minimale elle-meme.

   `anywhere` plutot que `break-word` parce que c'est `anywhere` dont la
   specification garantit qu'il reduit la largeur MINIMALE de la boite -
   celle qui dimensionne la piste de la grille. Mesure du 02/10/2026 :
   dans Chromium, `break-word` fait aujourd'hui disparaitre le
   debordement lui aussi (la morsure qui l'y substitue ne mord pas), mais
   c'est un comportement d'implementation, pas une garantie.
   --------------------------------------------------------------- */

.match-card:hover { background: rgba(255,255,255,0.07); }
.match-card-title { font-size: 14px; font-weight: 900; color: #fff; margin-bottom: 10px; text-transform: uppercase; }
/* ============================================================
   LA CARTE DE DEFI 1V1 — refonte visuelle du 06/10/2026
   ============================================================
   TOUT EST PORTE SOUS `.match-card`, et c'est deliberе : `.btn-join` et
   `.btn-view` servent AUSSI aux cartes de bracket. Les redessiner sans
   portee aurait modifie une page qu'on ne touche pas.

   L'ACCENT NE COLORE PAS LA CARTE. `--mode-accent` (la couleur du mode)
   ne sert qu'au cadre du pictogramme ; `--defi-accent` (la couleur du
   defi) ne sert qu'au liseré haut et aux boutons. Le fond reste sombre :
   une carte entierement teintee crie plus fort que ce qu'elle dit.

   LA DENSITE EST UNE CONTRAINTE, PAS UN RESTE. La carte devait devenir
   plus lisible SANS grandir : on a donc travaille les alignements, les
   graisses et un seul separateur, plutot que d'ajouter de la hauteur.
   ============================================================ */
.matches-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 16px;
}

.match-card {
    position: relative;
    display: flex;
    flex-direction: column;
    /*  LA HAUTEUR SE GAGNE DANS LES BLANCS, PAS DANS LES TEXTES. Ecart
        11 -> 9 px entre les quatre blocs, marges 15/15/14 -> 13/14/12 :
        14 px repris sans qu'une seule police ait diminue. */
    gap: 8px;
    padding: 13px 14px 12px;
    border-radius: 14px;

    /*  ============================================================
        UN SEUL LANGAGE SOMBRE POUR TOUTES LES CARTES  (08/10/2026)
        ============================================================
        AVANT, la carte portait la couleur du defi a trois endroits :
        un degrade en haut du fond, un lisere horizontal, et le
        contour au survol. Quatre modes donnaient quatre cartes
        differentes, et l'oeil lisait une difference de NATURE la ou
        il n'y avait qu'une difference de mode.

        DESORMAIS : le fond est neutre, et l'identite du mode est
        portee par son PICTOGRAMME — son cadre et sa teinte, par
        `--mode-accent`. Rien d'autre sur la carte ne change de
        couleur selon le defi.

        `--defi-accent` n'est plus pose par carte : il vaut l'accent
        Z7, ici, pour toutes. Les boutons le lisent encore et gardent
        donc exactement leur dessin — seule leur couleur cesse de
        varier d'une carte a l'autre. */
    --defi-accent: #33C6FF;

    background: rgba(255, 255, 255, 0.035);
    border: 1px solid rgba(255, 255, 255, 0.08);
    backdrop-filter: blur(10px);
    overflow-wrap: anywhere;
    transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
}
/*  LE LISERE HAUT A ETE RETIRE le 08/10/2026.

    `.match-card::before` dessinait une barre de 2 px a la couleur du
    defi, en haut de chaque carte. C'etait la trace la plus visible de
    l'ancienne personnalisation, et c'est elle qui faisait lire quatre
    familles de cartes la ou il n'y a qu'une famille et quatre modes.

    RIEN NE LA REMPLACE : ni bordure coloree, ni fond teinte. La carte
    est une surface sombre commune, et le mode se reconnait a son
    pictogramme. */
.match-card:hover {
    border-color: color-mix(in srgb, var(--defi-accent, #33C6FF) 45%, transparent);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3);
    transform: translateY(-2px);
}

/* ---- LA TETE : le mode, le titre, les pastilles ---- */
.m-tete { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
/*  LA VRAIE ZONE DU MODE. 52 px : assez grande pour qu'on reconnaisse le
    pictogramme d'un coup d'oeil, assez sobre pour ne pas voler la
    vedette au titre. `flex-shrink: 0` — elle ne se laisse pas ecraser
    par un titre long. */
.m-mode {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    width: 54px; height: 54px;
    border-radius: 13px;
    background: color-mix(in srgb, var(--mode-accent, rgba(255,255,255,0.4)) 13%, transparent);
    border: 1px solid color-mix(in srgb, var(--mode-accent, rgba(255,255,255,0.4)) 40%, transparent);
}
/*  40 px, contre 32 auparavant. La boite n'a grandi que de 2 px : c'est
    le PICTOGRAMME qui prend de la place, pas son cadre. Et cela ne
    coute aucune hauteur a la carte — la tete est deja plus haute que
    54 px des que le titre passe a deux lignes, ce qui est le cas
    courant a 325 px de large. Mesure avant/apres a l'appui. */
.m-mode img { width: 40px; height: 40px; object-fit: contain; display: block; }

/*  `min-width: 0` : sans lui, une boite flex refuse de se reduire sous
    la largeur de son texte, et le titre pousse le pictogramme dehors. */
.m-tete-textes { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1 1 auto; }
.match-card-title {
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 13px; font-weight: 900;
    line-height: 1.25;
    letter-spacing: 0.2px;
    text-transform: uppercase;
    color: #fff;
    margin: 0;
}
/*  La rangee de pastilles ne reserve plus de hauteur : elle est posee
    sous le titre, dans le flux de la tete, et les cartes restent
    alignees par la grille. */
.match-card-tags { display: flex; flex-wrap: wrap; gap: 3px; min-height: 0; margin: 0; }

/* ---- LES JOUEURS ---- */
/*  « 1 / 2 » ne disait pas de quoi il parlait. Le mot est maintenant la,
    avec l'icone, et le compte se detache. */
.m-joueurs {
    display: flex; align-items: center; gap: 6px;
    font-family: Arial, sans-serif;
    font-size: 10px;
    color: rgba(255, 255, 255, 0.4);
}
.m-joueurs svg { width: 13px; height: 13px; flex-shrink: 0; opacity: 0.8; }
.m-joueurs-lbl { text-transform: uppercase; letter-spacing: 0.7px; font-weight: 700; }
.m-joueurs-val { color: rgba(255, 255, 255, 0.85); font-weight: 900; font-size: 11px; }

/* ---- L'ARGENT ---- */
/*  LE SEUL SEPARATEUR DE LA CARTE. Il marque la frontiere entre ce
    qu'est le defi et ce qu'il coute \u2014 c'est la seule coupure qui
    meritait un trait. */
.m-argent {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 11px;
    border-radius: 11px;
    background: rgba(0, 0, 0, 0.26);
    border: 1px solid rgba(255, 255, 255, 0.06);
}
.m-bloc { flex: 1; min-width: 0; text-align: center; }
.m-bloc-lbl {
    font-family: Arial, sans-serif;
    font-size: 8.5px; font-weight: 700;
    letter-spacing: 1px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.32);
    margin-bottom: 3px;
}
.m-bloc-val {
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 15px; font-weight: 900;
    line-height: 1.1;
    color: #fff;
    white-space: nowrap;
}
/*  Le vert du gain est celui des succes du site. */
.m-bloc--gain .m-bloc-val { color: #4ade80; }
.m-fleche { flex: 0 0 auto; color: rgba(255, 255, 255, 0.2); font-size: 15px; line-height: 1; }

/*  GRATUIT : on ne met pas « 0 \u2192 0.00 ». Une mise nulle et un gain nul
    ne forment pas un echange : ils forment un mot. */
.m-argent--gratuit { justify-content: center; gap: 9px; flex-wrap: wrap; }
.m-gratuit-pastille {
    font-family: 'Arial Black', Arial, sans-serif;
    font-size: 13px; font-weight: 900;
    letter-spacing: 0.8px; text-transform: uppercase;
    color: #4ade80;
    padding: 3px 11px;
    border-radius: 7px;
    background: rgba(74, 222, 128, 0.12);
    border: 1px solid rgba(74, 222, 128, 0.4);
}
.m-gratuit-note {
    font-family: Arial, sans-serif;
    font-size: 9px;
    color: rgba(255, 255, 255, 0.3);
}

/* ---- LES INFORMATIONS SECONDAIRES : L'ADVERSAIRE ET LE TEMPS ---- */
/*  DEUX COLONNES, PAS DEUX RANGEES. Elles portent le meme nombre de
    lignes — un libelle, une valeur — et se tiennent donc d'elles-memes
    a la meme hauteur. */
.m-secondaire {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 8px; flex-wrap: wrap;
    padding-top: 8px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    margin: 0;
}
/*  `flex: 1 1 0` AVEC UN PLANCHER, et pas une base fixe. Avec une base
    de 100 px, la rangee demandait 100 + 8 + 185 = 293 px la ou elle en
    avait 294,8 : elle tenait a moins de deux pixels pres, et le moindre
    changement de police la faisait passer a la ligne — 43 px de hauteur
    en plus, par surprise. Une base nulle laisse l'adversaire prendre la
    place qui reste ; le plancher de 84 px dit a partir de quand il vaut
    mieux passer a la ligne, et c'est alors une decision, pas un
    accident. */
.m-adv { flex: 1 1 0; min-width: 84px; display: flex; flex-direction: column; gap: 4px; }
/*  `flex-shrink: 0` : le decompte ne se laisse pas ecraser par un pseudo
    long — il passe a la ligne, ce que la rangee autorise. C'est le meme
    piege que la note du CDC-121 decrivait plus bas : un item flex qui
    PEUT retrecir retrecit au lieu de passer a la ligne. */
.m-expire { flex: 0 0 auto; display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }

/*  « EXPIRE DANS / EXPIRE » ne veut rien dire. Quand le decompte est
    termine, son libelle disparait — la colonne garde sa place, et c'est
    le mot « Expire » seul qui porte l'information. `:has()` evite
    d'apprendre au composant commun qu'il a un libelle au-dessus de
    lui : la carte decide chez elle. */
.m-expire:has(.z7-cd.est-fini) .m-expire-lbl { visibility: hidden; }

.m-adv-lbl, .m-expire-lbl {
    font-family: Arial, sans-serif;
    font-size: 8.5px; font-weight: 700;
    letter-spacing: 0.7px; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.3);
    line-height: 1;
}
/*  L'IDENTITE DE L'ADVERSAIRE A SON PROPRE COMPOSANT  (08/10/2026)

    `.m-adv-ligne`, `.m-adv-pastille` et `.m-adv-nom` dessinaient ici
    une image de profil et un pseudo. Lenny a demande un mini-CADRE
    dedie, de geometrie identique avant et apres revelation : c'est
    `Z7-JOUEUR-MINI`, dans `Common/CSS/joueur-mini.css`.

    LE MASQUE A CHANGE DE DESSIN AVEC LUI. Il etait fait de quatre
    blocs separes de blancs — « ████ ███ ███ » — et ressemblait a un
    numero de telephone caviarde plutot qu'a un pseudo. C'est
    maintenant un seul trait continu, de largeur FIXE : une largeur
    proportionnelle au vrai pseudo en trahirait la longueur.

    `.m-adv` et `.m-adv-lbl` restent ici : ce sont la COLONNE et son
    libelle, qui appartiennent a la carte, pas au composant. */

/* ---- LES ACTIONS ---- */
.m-actions { margin-top: auto; display: flex; gap: 8px; padding-top: 0; }
/*  ---- LA RANGEE GARDE SA HAUTEUR QUAND LE MASQUE TOMBE ----

    MESURE DU 08/10/2026, sur une carte seule : rangee 30 px tant que
    l'adversaire est masque, 28 px apres revelation. Deux pixels, et la
    carte entiere passait de 253 a 251 px.

    LA CAUSE N'EST PAS UNE MARGE : c'est le PICTOGRAMME de la pastille
    de cout. Une boite de ligne qui porte un emoji fait 14 px la ou le
    libelle en Arial 10 n'en fait que 11. Le bouton revele perd cette
    pastille, donc deux pixels — et toute la grille sursaute au moment
    precis ou le joueur vient de depenser son Snipe.

    POURQUOI UN PLANCHER, ET PAS UNE `line-height` SERREE SUR LA
    PASTILLE : brider la boite de ligne corrigerait aussi l'ecart, mais
    en RETRECISSANT l'etat masque — celui qui est deja valide et sous
    les yeux de tout le monde. Un plancher ne fait grandir que l'etat
    revele, qui vient s'aligner sur lui. Rien de ce qui est decide ne
    bouge.

    30 px = 14 (la boite de ligne de la pastille) + 2 x 7 (le fond du
    bouton) + 2 x 1 (son contour). Les deux boutons le portent : ils se
    partagent la rangee, et c'est le plus haut qui la dicte. */
.match-card .btn-join,
.match-card .btn-view,
.mon-defi .btn-join { min-height: 30px; }
/*  PORTEE SOUS `.match-card` : ces deux classes servent aussi aux cartes
    de bracket, qu'on ne touche pas.
    `.mon-defi` (Z7-MY-MATCH-CARD, « Mes defis en cours ») EMPRUNTE le
    bouton principal tel quel : meme dessin, aucune valeur recopiee. */
.match-card .btn-join,
.mon-defi .btn-join {
    flex: 1 1 0; min-width: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    padding: 7px 7px;
    border-radius: 9px;
    background: var(--defi-accent, #33C6FF);
    border: none;
    color: #06080f;
    font-family: Arial, sans-serif;
    font-size: 10px; font-weight: 900;
    letter-spacing: 0.2px; text-transform: uppercase;
    cursor: pointer;
    transition: filter 0.18s;
}
.match-card .btn-join:hover,
.mon-defi .btn-join:hover { filter: brightness(1.12); opacity: 1; }
/*  L'action secondaire reste lisible sans se disputer la vedette : le
    contour prend la couleur du defi, le fond reste sombre. */
.match-card .btn-view {
    flex: 1 1 0; min-width: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    padding: 7px 7px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid color-mix(in srgb, var(--defi-accent, #33C6FF) 45%, transparent);
    color: rgba(255, 255, 255, 0.9);
    font-family: Arial, sans-serif;
    font-size: 10px; font-weight: 700;
    letter-spacing: 0.2px; text-transform: uppercase;
    cursor: pointer;
    transition: background 0.18s, border-color 0.18s;
}
.match-card .btn-view:hover { background: rgba(255, 255, 255, 0.09); filter: none; opacity: 1; }
/*  ---- CE QUE PORTENT LES BOUTONS ----
    Le libelle d'un cote, le chiffre de l'autre, separes d'un point
    median. Les deux boutons suivent la meme regle : on lit d'abord ce
    que fait le bouton, puis ce qu'il coute.

    `white-space: nowrap` sur les deux parts : un prix coupe en deux
    lignes ferait grandir la rangee, et c'est exactement la hauteur
    qu'on cherche a economiser. */
.m-btn-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.m-prix, .m-cout {
    flex: 0 0 auto;
    font-weight: 900;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
/*  PAS DE POINT MEDIAN. Il coutait 13 px dans un bouton qui en a 142,
    et c'est exactement ce qui tronquait « REJOINDRE · GRATUIT » en
    « REJOI... ». L'ecart de 5 px suffit a separer les deux parts. */
/*  Le prix est ECRIT SUR le bouton principal : il en prend l'encre, pas
    une couleur a lui. */
.m-prix { color: inherit; opacity: 0.85; }
/*  Le cout en Snipes garde l'or des Snipes, et reste affiche tel que le
    serveur le donne. */
.m-cout { color: #FFB700; }

/* ============================================================
   CARTE — MON DEFI 1V1  ·  Z7-MY-MATCH-CARD  ·  NON VALIDE
   ============================================================
   « Mes defis en cours », dessine par `renderMonDefi()`. Remise dans le
   langage des cartes 1V1 le 10/10/2026, SANS recopier leurs valeurs :
   elle COMPOSE ce qui existe deja.

     - la surface : les jetons du verre Z7 (`Common/CSS/glass.css`) ;
     - le pictogramme du mode : `.m-mode` et `--mode-accent`, comme la
       carte « Defi disponible » ;
     - le titre : `.match-card-title` ;
     - les pastilles : Z7-TAG (`Common/CSS/tags.css`) ;
     - Mise -> Gain : `.m-argent` / `.m-bloc` ;
     - « Acceder » : le bouton principal de la carte 1V1 (selecteur
       elargi plus haut).

   CE QUI RESTE PROPRE A CETTE CARTE, ET POURQUOI : sa GEOMETRIE. Elle
   est en LIGNE — identite, argent, actions — parce qu'elle porte des
   actions que la carte publique n'a pas, et s'empile dans une liste.

   LE STATUT (11/10/2026) : Z7-STATUT-DEFI (`Common/CSS/statut-defi.css`),
   toujours en haut a droite, distinct des Z7-TAG. Le code prive et les
   boutons Supprimer / Declarer forfait gardent leur dessin (styles en
   ligne dans `fortnite.js`) : la logique des boutons est validee.

   PLUS AUCUNE COULEUR PAR DEFI SUR LA CARTE : ni contour, ni liseré
   gauche, ni bouton a la couleur du mode. L'identite du mode est
   portee par son pictogramme, comme sur la carte publique. */
/*  ---- LA GEOMETRIE (11/10/2026) : UNE HAUTEUR PAR LARGEUR ----
    Toutes les cartes ont la MEME hauteur a une largeur donnee, quel que
    soit leur etat : chaque zone est REservee, aucune ne se dimensionne
    sur son texte.

        [mode] | TITRE ............................. ● STATUT
               | texte contextuel
               | Z7-TAG Z7-TAG Z7-TAG Z7-TAG (code prive)
        [ Mise -> Gain ]                      [ action ] [ ACCEDER ]

      - titre    : 1 ligne (2 sur telephone), points de suspension au-dela ;
      - contexte : 1 ligne (2 sur telephone) ;
      - tags     : une hauteur de rangee(s) reservee, sans rien couper
                   (`min-height`, jamais `overflow: hidden`) ;
      - statut   : TOUJOURS en haut a droite (Z7-STATUT-DEFI).

    Les hauteurs viennent des jetons ci-dessous ; un breakpoint ne change
    que les jetons. */
.mon-defi {
    --mdc-titre-lignes: 1;
    --mdc-ctx-lignes: 1;
    --mdc-tags-rangees: 1;
    --mdc-titre-lh: 16px;
    --mdc-ctx-lh: 15px;
    /*  21 px : la pastille du code prive (bouton « 🔒 code ⧉ ») est la
        plus haute de la rangee ; un Z7-TAG seul en fait 18. */
    --mdc-tag-rangee: 21px;
    /*  39 px : le plus haut des boutons d'action existants (la corbeille).
        La zone garde cette hauteur quels que soient les boutons presents. */
    --mdc-actions-h: 39px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "tete    tete"
        "argent  actions";
    align-items: center;
    gap: 10px 14px;
    padding: 12px 14px;
    margin-bottom: 8px;
    border-radius: 14px;
    background: var(--z7-glass-fond);
    border: 1px solid var(--z7-glass-bord);
}
.mon-defi-tete { grid-area: tete; align-items: flex-start; }
.mon-defi .m-tete-textes {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "titre   statut"
        "ctx     ctx"
        "tags    tags";
    align-items: start;
    gap: 5px 10px;
}
.mon-defi-statut { grid-area: statut; justify-self: end; }
.mon-defi-titre {
    grid-area: titre;
    height: calc(var(--mdc-titre-lh) * var(--mdc-titre-lignes));
    line-height: var(--mdc-titre-lh);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--mdc-titre-lignes);
    line-clamp: var(--mdc-titre-lignes);
    overflow: hidden;
    overflow-wrap: anywhere;
    align-self: center;
}
/*  Le resume de ce qu'attend le defi. Jamais le resultat declare par
    l'adversaire : seulement QU'il a declare. */
.mon-defi-contexte {
    grid-area: ctx;
    height: calc(var(--mdc-ctx-lh) * var(--mdc-ctx-lignes));
    line-height: var(--mdc-ctx-lh);
    font-family: Arial, sans-serif;
    font-size: 11px;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.62);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--mdc-ctx-lignes);
    line-clamp: var(--mdc-ctx-lignes);
    overflow: hidden;
}
.mon-defi-tags {
    grid-area: tags;
    align-content: flex-start;
    align-items: center;
    min-height: calc(var(--mdc-tag-rangee) * var(--mdc-tags-rangees) + 3px * (var(--mdc-tags-rangees) - 1));
}
.mon-defi .m-argent { grid-area: argent; justify-self: start; }
/*  Dans une rangee, les deux montants prennent la largeur de leur
    contenu : etires (`flex: 1`, comme dans la carte publique), ils
    tronquaient « 1.90 » des que la rangee manquait de place. */
.mon-defi .m-bloc { flex: 0 0 auto; min-width: 64px; }
.mon-defi-actions { grid-area: actions; justify-self: end; display: flex; align-items: center; gap: 8px; min-height: var(--mdc-actions-h); }
/*  Le bouton principal de la carte 1V1 s'etire dans sa rangee (`flex:
    1 1 0`) ; ici il est seul a droite et garde la largeur de son mot. */
.mon-defi-actions .btn-join { flex: 0 0 auto; padding: 7px 18px; }

/*  TELEPHONE : le statut prend la premiere rangee, a droite ; le titre
    et le contexte ont deux lignes, les tags deux rangees. L'argent et les
    actions prennent chacun toute la ligne, sous l'identite. */
@media (max-width: 600px) {
    .mon-defi {
        --mdc-titre-lignes: 2;
        --mdc-ctx-lignes: 2;
        --mdc-tags-rangees: 2;
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "tete"
            "argent"
            "actions";
        padding: 12px;
    }
    .mon-defi .m-tete-textes {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "statut"
            "titre"
            "ctx"
            "tags";
    }
    .mon-defi .m-argent { justify-self: stretch; }
    .mon-defi .m-bloc { flex: 1 1 0; }
    .mon-defi-actions { justify-self: stretch; }
    .mon-defi-actions > button,
    .mon-defi-actions .btn-join { flex: 1 1 0; }
}
/*  PETIT TELEPHONE : les tags (et le code prive) demandent une troisieme
    rangee, et « Declarer forfait » (dessin inchange) passe sur deux
    lignes dans sa demi-largeur (42 px) : les deux sont reserves pour
    toutes les cartes. */
@media (max-width: 370px) {
    .mon-defi { --mdc-tags-rangees: 3; --mdc-actions-h: 42px; }
}

/*  ---- CARTE LARGE : UNE SEULE RANGEE (correction du 11/10/2026) ----
    Des que la CARTE a la place (et non l'ecran : la largeur de la carte
    ne suit pas celle de la fenetre, la colonne de la page varie), tout
    tient sur une rangee :

        [mode] | TITRE / contexte / tags | [ Mise -> Gain ] |  ● STATUT
                                                             [ actions ]

    - Mise -> Gain occupe le CENTRE de la zone libre : sa colonne prend
      une part de la place (jamais moins de 216 px) et le bloc, inchange,
      s'y centre ; il est donc aligne d'une carte a l'autre ;
    - le statut reste en haut a droite ; les actions, en bas a droite ;
    - la hauteur reste UNIQUE a largeur donnee : les zones restent
      reservees par les memes jetons.

    790 px : la colonne de texte garde 200 px, assez pour un titre sur une
    ligne, le contexte sur deux et les tags (code prive compris) sur deux
    rangees. Des 1140 px, le contexte et les tags (code prive compris)
    tiennent sur une ligne. */
.mon-defi-liste { container: mes-defis / inline-size; }
.mon-defi { position: relative; }
@container mes-defis (min-width: 790px) {
    .mon-defi {
        --mdc-ctx-lignes: 2;
        --mdc-tags-rangees: 2;
        /*  L'argent a sa part de la place libre (jamais moins que son bloc
            le plus large, 216 px) : il se centre dans la zone vide entre le
            texte et les actions, au lieu de se coller aux actions. */
        grid-template-columns: minmax(0, 1.2fr) minmax(216px, 1fr) 242px;
        grid-template-areas: "tete argent actions";
        align-items: stretch;
    }
    .mon-defi .m-tete-textes {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "titre"
            "ctx"
            "tags";
    }
    .mon-defi-statut { position: absolute; top: 12px; right: 14px; }
    .mon-defi .m-argent { justify-self: center; align-self: center; }
    .mon-defi-actions { justify-self: end; align-self: end; }
}
@container mes-defis (min-width: 1140px) {
    .mon-defi {
        --mdc-ctx-lignes: 1;
        --mdc-tags-rangees: 1;
    }
}

/* ====================================================================
   LE DECOMPTE D'EXPIRATION A QUITTE CE FICHIER  (CDC-121)

   Ce qui se trouvait ici — `.match-creator-row`, `.match-expire-bloc`,
   `.match-expire`, `.cd-unit`, `.cd-num`, `.cd-label`, `.cd-sep` —
   dessinait un decompte « 00:04:59:55 » propre a la carte de defi, et
   a elle seule. Il est remplace par Z7-COUNTDOWN, variante compacte :
   `Common/CSS/compte-a-rebours.css`.

   CE QUI EST CONSERVE DE LA LECON DU CDC-121. Le piege n'etait pas le
   dessin, c'etait la rangee : un item flex qui PEUT retrecir retrecit
   au lieu de passer a la ligne, et « 06 » se coupait entre ses deux
   chiffres. `.m-expire` porte donc `flex: 0 0 auto`, et `.m-secondaire`
   garde son `flex-wrap: wrap` — les deux ensemble, jamais l'un sans
   l'autre.

   La rangee `.match-creator-row` portait en plus un `margin-bottom:
   10px` que `.m-secondaire` croyait avoir annule : ecrite plus bas dans
   ce fichier, a specificite egale, c'est elle qui gagnait. Dix pixels
   de hauteur rendus a la carte, et un doublon de moins.
   ==================================================================== */
.match-card-footer { display: flex; gap: 8px; margin-top: auto; }
.btn-join { flex: 1; padding: 9px 14px; background: #33C6FF; border: none; border-radius: 8px; color: #000; font-size: 11px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; transition: opacity 0.2s; text-transform: uppercase; }
.btn-join:hover { opacity: 0.85; }
.btn-view { flex: 1; padding: 9px 14px; background: #141414; border: 1px solid #3a3a3a; border-radius: 8px; color: #fff; font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; text-transform: uppercase; }
.btn-view:hover { opacity: 0.8; filter: brightness(1.2); }

         /* Top 3 à droite */



/* ====================================================================
   LE PODIUM DU MOIS A QUITTE CE FICHIER  ·  Z7-TOP3

   Tout ce qui dessinait `.top3-*` vit desormais dans
   `Common/CSS/podium-top3.css`, avec SES DEUX VARIANTES a comparer
   (`--banniere` et `--podium`).

   POURQUOI LE DEPLACER ET NON LE MODIFIER SUR PLACE. `fortnite.css`
   est chargee APRES la feuille du composant : une regle laissee ici
   gagnerait la cascade. Or deux des regles d'ici cassaient justement le
   ratio de la banniere que le composant garantit —
   `padding-bottom: 52%` pour le vainqueur, et des hauteurs fixes en
   pixels sous 640 px. Les laisser « au cas ou » aurait annule le
   correctif en silence.

   CE QUI A CHANGE DE COMPORTEMENT, dit franchement :
     · la banniere n'est plus rognee (`contain` au lieu de `cover`) ;
     · le vainqueur est mis en avant par la GRILLE (colonne 8 % plus
       large) et non par une boite plus haute ;
     · sous 640 px, les cartes s'EMPILENT au lieu de passer en portrait
       a hauteur fixe — l'empilement conserve le ratio, le portrait non.

   LE BLOC `@media (max-width: 640px)` QUI LE SUIVAIT EST PARTI AVEC,
   et son long commentaire aussi : il expliquait pourquoi la carte
   passait en PORTRAIT A HAUTEUR FIXE sur telephone. Ce raisonnement ne
   decrit plus rien — et il avait un cout qu'il ne disait pas, le ratio
   de la banniere. Les cartes s'empilent desormais.

   `.lb-top3-*` (le podium du Classement) et `.token-top3-*` sont
   d'AUTRES composants : ils restent ici, intacts.
   ==================================================================== */


.token-top3-card { border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; overflow: hidden; position: relative; cursor: pointer; transition: transform 0.2s, border-color 0.2s; min-height: 180px; isolation: isolate; }
.token-top3-card:hover { transform: scale(1.02); border-color: rgba(255,255,255,0.2); }
.token-top3-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 0; }
.token-top3-inner { position: relative; z-index: 1; display: flex; flex-direction: column; height: 100%; }
.token-top3-img-wrap { display: flex; flex-direction: column; align-items: center; padding: 18px 0 12px; gap: 10px; }
.token-top3-rank { font-size: 24px; line-height: 1; }
.token-top3-avatar { width: 60px; height: 60px; border-radius: 50%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; font-size: 22px; font-weight: 900; color: #fff; border: 2px solid rgba(255,255,255,0.2); overflow: hidden; }
.token-top3-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; background: #000; }
.token-top3-info { padding: 10px 14px 14px; background: rgba(0,0,0,0.5); border-top: 1px solid rgba(255,255,255,0.08); }
.token-top3-name { font-size: 13px; font-weight: 900; color: #fff; margin-bottom: 3px; }
.token-top3-earned { font-size: 14px; font-weight: 900; color: #FFB700; margin-bottom: 2px; }
.token-top3-stats { font-size: 10px; color: rgba(255,255,255,0.35); font-family: Arial, sans-serif; }

/* Défis actifs */
.defi-active-card { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.12); border-left: 3px solid; border-radius: 12px; padding: 14px 16px; transition: background 0.2s; backdrop-filter: blur(10px); }
.defi-active-card:hover { background: rgba(255,255,255,0.12); }
.defi-active-left { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; }
.defi-active-icon { width: 38px; height: 38px; border-radius: 50%; border: 2px solid; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.defi-active-title { font-size: 13px; font-weight: 900; color: #fff; margin-bottom: 2px; }
.defi-active-sub { font-size: 11px; color: rgba(255,255,255,0.5); font-family: Arial, sans-serif; }
.defi-active-sub strong { color: rgba(255,255,255,0.85); }
.defi-active-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.defi-status-badge { font-size: 11px; color: rgba(255,255,255,0.4); font-family: Arial, sans-serif; white-space: nowrap; }
.defi-reprendre-btn { padding: 7px 16px; border: none; border-radius: 50px; color: #000; font-size: 11px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; transition: opacity 0.2s; white-space: nowrap; }
.defi-reprendre-btn:hover { opacity: 0.85; }

/* Défis disponibles */
.defi-list { display: flex; flex-direction: column; gap: 8px; }
.defi-card { display: flex; align-items: center; gap: 16px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-left: 3px solid; border-radius: 12px; padding: 12px 16px; transition: background 0.2s; }
.defi-card:hover { background: rgba(255,255,255,0.07); }
.defi-card-creator { display: flex; align-items: center; gap: 10px; flex-shrink: 0; min-width: 130px; }
.defi-card-avatar { width: 36px; height: 36px; border-radius: 50%; border: 1.5px solid; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 900; color: #fff; flex-shrink: 0; }
.defi-card-creator-name { font-size: 12px; font-weight: 700; color: #fff; cursor: pointer; transition: color 0.2s; }
.defi-card-creator-name:hover { color: #33C6FF; }
.defi-card-expire { font-size: 10px; color: rgba(255,255,255,0.3); font-family: Arial, sans-serif; margin-top: 2px; }
.defi-card-center { flex: 1; min-width: 0; }
.defi-card-title { font-size: 13px; font-weight: 900; color: #fff; margin-bottom: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.defi-card-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.defi-tag { padding: 2px 8px; border-radius: 50px; font-size: 9px; font-weight: 700; background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.12); color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; }
.defi-card-right { display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
.defi-card-coins { display: flex; flex-direction: column; gap: 2px; }
.defi-coin-row { display: flex; align-items: center; gap: 6px; }
.defi-coin-label { font-size: 10px; color: rgba(255,255,255,0.3); font-family: Arial, sans-serif; width: 28px; }
.defi-coin-val { font-size: 12px; font-weight: 900; color: #fff; white-space: nowrap; }
.defi-card-btns { display: flex; gap: 6px; }
.defi-btn-join { padding: 7px 14px; border: none; border-radius: 8px; font-size: 11px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; transition: opacity 0.2s; white-space: nowrap; }
.defi-btn-join:hover { opacity: 0.85; }
.defi-btn-view { padding: 7px 12px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); border-radius: 8px; color: rgba(255,255,255,0.6); font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; white-space: nowrap; }
.defi-btn-view:hover { background: rgba(255,255,255,0.1); color: #fff; }

/* ===== BRACKET ===== */
.brackets-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.bracket-card { background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; overflow: hidden; transition: border-color 0.2s, background 0.2s; display: flex; flex-direction: column; backdrop-filter: blur(10px); }
.bracket-card:hover { background: rgba(255,255,255,0.1); border-color: #33C6FF; }
/*  LE TITRE RETRECIT, LE PRIX NON.

    MESURE, 390 px : `.bracket-card-prize` debordait son en-tete de 5 px.
    Le prix porte deja `flex-shrink: 0`, ce qui est juste — un montant
    coupe serait pire que tout. Mais le titre a sa gauche n'avait pas
    `min-width: 0` : il ne descendait donc pas sous la largeur de son
    plus long mot, et c'est lui qui poussait le prix dehors. */
.bracket-card-header { padding: 10px 14px !important; border-bottom: 2px solid #33C6FF; display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; min-height: 52px !important; }
.bracket-card-header > *:not(.bracket-card-prize) { min-width: 0; }
/*  UN TITRE LONG SE PLIE, IL NE SE COUPE PAS.

    MESURE, 390 px : « Bracket Z7 — inscriptions ouvertes » occupait
    105 px pour 82 disponibles. Le reste etait coupe NET, sans points de
    suspension : rien n'indiquait au lecteur qu'il manquait du texte.

    Deux lignes au maximum, et des points de suspension au-dela : un
    titre de carte n'a pas vocation a pousser la carte, mais il doit
    dire qu'il continue. `overflow-wrap: anywhere` evite qu'un mot
    unique tres long deborde a son tour. */
.bracket-card-title {
    font-size: 13px; font-weight: 900; color: #fff; text-transform: uppercase;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}
.bracket-card-prize { font-size: 15px; font-weight: 900; flex-shrink: 0; }
.bracket-card-body { padding: 10px 14px !important; flex: 1; display: flex; flex-direction: column; }
.bracket-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px !important; min-height: auto !important; height: auto !important; align-content: flex-start; }
.bracket-tag { padding: 3px 10px; border-radius: 50px; background: #1a1a1a; border: 1px solid #3a3a3a; font-size: 10px; font-weight: 700; color: #888; font-family: Arial, sans-serif; text-transform: uppercase; }
.bracket-progress { margin-bottom: 6px !important; }
.bracket-progress-label { display: flex; justify-content: space-between; font-size: 10px; color: #666; font-family: Arial, sans-serif; margin-bottom: 5px; }
.bracket-progress-bar { height: 4px; background: #1a1a1a; border-radius: 2px; overflow: hidden; }
.bracket-progress-fill { height: 100%; border-radius: 2px; }
.bracket-info { display: flex; justify-content: space-between; margin-bottom: 4px !important; }
.bracket-info-label { font-size: 11px; color: #666; font-family: Arial, sans-serif; }
.bracket-info-value { font-size: 11px; font-weight: 700; color: #fff; }
.bracket-card-footer { display: flex; gap: 8px; padding: 0 14px 12px !important; margin-top: auto; }
.bracket-card-footer .btn-join, .bracket-card-footer .btn-view { border-radius: 8px; font-size: 11px; }

/* ===== LEADERBOARD ===== */
.tabs-row { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.tab-btn { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: #141414; border: 1px solid #3a3a3a; border-radius: 50px; color: #888; font-size: 12px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; }
.tab-btn:hover { border-color: #33C6FF; color: #fff; }
.tab-btn.active { background: #33C6FF; border-color: #33C6FF; color: #000; }
.tab-count { background: rgba(0,0,0,0.3); border-radius: 50px; padding: 1px 7px; font-size: 10px; }
.lb-tabs { display: flex; gap: 8px; }
.lb-tab { padding: 6px 16px; background: #141414; border: 1px solid #3a3a3a; border-radius: 50px; color: #888; font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; text-transform: uppercase; }
.lb-tab:hover { border-color: #33C6FF; color: #fff; }
.lb-tab.active { background: #33C6FF; border-color: #33C6FF; color: #000; }
/* ---------------------------------------------------------------
   Lot G1 - CDC-140 : « garder la disposition : Top 1 au centre et un peu
   plus grand, Top 2 et Top 3 sur les cotes ».

   La disposition etait deja celle-la, mais obtenue par l'ordre du
   document (`order = [1, 0, 2]` dans fortnite.js) et par une grille
   `1fr 1.1fr 1fr` qui ne passe JAMAIS a une colonne : sur un telephone
   de 390 px, trois cartes de 118 px de large. Et si elle y passait, la
   pile se serait lue « deuxieme, premier, troisieme ».

   Meme remede que CDC-117 pour le Top 3 du Token : le document garde
   l'ordre du classement, la feuille de style place les cartes.
   --------------------------------------------------------------- */
.lb-top3-grid { display: grid; grid-template-columns: 1fr 1.1fr 1fr; gap: 12px; align-items: end; }
.lb-top3-grid > .lb-top3-card:nth-child(1) { order: 2; }   /* Top 1 au centre */
.lb-top3-grid > .lb-top3-card:nth-child(2) { order: 1; }   /* Top 2 a gauche */
.lb-top3-grid > .lb-top3-card:nth-child(3) { order: 3; }   /* Top 3 a droite */
.lb-top3-card--premier { transform: translateY(-8px); }
/*  Une case vide ne tient que la place : ni cadre, ni hauteur imposee. */
.lb-top3-card--vide { border: none; background: none; }

/*  LES INTERNES, EN FEUILLE DE STYLE — memes valeurs qu'en ligne.

    Les tailles du premier etaient calculees dans le gabarit
    (`${isFirst?'60px':'48px'}`) ; elles se decrivent desormais par
    `.lb-top3-card--premier`, ce qui permet de les redefinir sur
    telephone sans toucher au JavaScript. Le rendu PC est inchange. */
.lb-top3-banniere { width: 100%; padding-bottom: 38%; position: relative; }
.lb-top3-card--premier .lb-top3-banniere { padding-bottom: 45%; }
.lb-top3-voile { position: absolute; inset: 0; background: linear-gradient(to bottom, transparent 20%, rgba(10,12,20,0.95) 100%); }
.lb-top3-medaille { position: absolute; top: 8px; left: 10px; font-size: 18px; }
.lb-top3-card--premier .lb-top3-medaille { font-size: 22px; }
.lb-top3-ident { position: absolute; bottom: 8px; left: 10px; display: flex; align-items: center; gap: 8px; }
.lb-top3-avatar { width: 48px; height: 48px; border-radius: 50%; border: 2px solid; overflow: hidden; display: flex; align-items: center; justify-content: center; flex-shrink: 0; box-shadow: 0 2px 8px rgba(0,0,0,0.6); }
.lb-top3-card--premier .lb-top3-avatar { width: 60px; height: 60px; }
.lb-top3-initiale { font-size: 18px; font-weight: 900; color: #fff; }
.lb-top3-card--premier .lb-top3-initiale { font-size: 22px; }
.lb-top3-nom { font-size: 12px; font-weight: 900; color: #fff; line-height: 1.2; }
.lb-top3-card--premier .lb-top3-nom { font-size: 14px; }
.lb-top3-gain { font-size: 11px; font-weight: 900; }
.lb-top3-stats { font-size: 10px; color: rgba(255,255,255,0.4); font-family: Arial, sans-serif; }

/* ====================================================================
   SOUS 769 PX : MEME TRAITEMENT QUE LE TOP 3 DU MOIS.

   Mesure avant correction : 789 px de haut sur tablette, soit 77 % de
   l'ecran, en trois cartes empilees. La grille garde ses trois colonnes
   et la carte passe en portrait — mais seulement a partir de 640 px,
   pour la meme raison que le Top 3 du mois : a 768 px la tuile fait
   encore 194 px de large, et le format paysage y est plus compact.
   ==================================================================== */
@media (max-width: 640px) {
    .lb-top3-grid { grid-template-columns: 1fr 1.15fr 1fr; gap: 6px; align-items: end; }
    /*  Decalee vers le haut, la premiere carte mordrait sur le titre de
        la section au lieu de depasser ses voisines : c'est la banniere
        plus haute qui fait la marche, pas un deplacement. */
    .lb-top3-card--premier { transform: none; }
    /*  UNE HAUTEUR EN PIXELS, PAS EN POURCENTAGE.

        Un `padding-bottom` en pourcentage se calcule sur la LARGEUR : la
        tuile devenait tres haute des qu'elle etait large, pour un
        contenu qui ne change pas de taille. Mesure du defaut : a 640 px
        de fenetre le podium montait a 329 px, contre 100 px a 641 — un
        saut de trois cents pour cent pour un pixel.

        Le contenu occupe environ 95 px : medaille 15, avatar 34, pseudo
        12, gain 12, et les ecarts. 118 px suffisent, 142 pour le
        premier — vingt-quatre pixels de marche, a toutes les largeurs. */
    .lb-top3-banniere { padding-bottom: 0; height: 118px; }
    .lb-top3-card--premier .lb-top3-banniere { padding-bottom: 0; height: 142px; }
    .lb-top3-medaille,
    .lb-top3-card--premier .lb-top3-medaille { top: 5px; left: 50%; transform: translateX(-50%); font-size: 15px; }
    .lb-top3-ident {
        left: 4px;
        right: 4px;
        bottom: 6px;
        flex-direction: column;
        align-items: center;
        gap: 5px;
        text-align: center;
    }
    .lb-top3-avatar,
    .lb-top3-card--premier .lb-top3-avatar { width: 34px; height: 34px; }
    .lb-top3-initiale,
    .lb-top3-card--premier .lb-top3-initiale { font-size: 14px; }
    .lb-top3-textes { min-width: 0; max-width: 100%; }
    .lb-top3-nom,
    .lb-top3-card--premier .lb-top3-nom { font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .lb-top3-gain { font-size: 10px; }
    .lb-top3-stats { display: none; }
}

.lb-header-row { display: grid; margin-bottom: 8px; gap: 4px; }
.lb-hcell { background: #141414; border: 1px solid #3a3a3a; color: #888; font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; padding: 7px 12px; border-radius: 50px; }
.lb-entries { display: flex; flex-direction: column; gap: 4px; }
.lb-row { display: grid; background: #000; border-left: 1px solid #555; border-radius: 6px; transition: background 0.2s; overflow: hidden; }
.lb-row:hover { background: #1a1a1a; }
.lb-cell { padding: 12px 12px; font-size: 14px; color: #fff; font-family: Arial, sans-serif; display: flex; align-items: center; position: relative; }
.lb-cell + .lb-cell::before { content: ''; position: absolute; left: 0; top: 20%; height: 60%; width: 1px; background: rgba(255,255,255,0.15); }
.lb-cell.rank { font-weight: 900; }
.lb-cell.earned { font-weight: 900; color: #28a745; }
.lb-row-me { background: rgba(51,198,255,0.08) !important; border-left-color: #33C6FF !important; }
.lb-row-me:hover { background: rgba(51,198,255,0.14) !important; }
.lb-header-glass { display: grid; grid-template-columns: 70px 1fr 160px 120px 120px 110px; gap: 4px; margin-bottom: 8px; }
.lb-hcell-glass { font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.3); text-transform: uppercase; letter-spacing: 1px; font-family: Arial, sans-serif; padding: 6px 12px; }
.lb-row-glass { display: grid; grid-template-columns: 70px 1fr 160px 120px 120px 110px; gap: 0; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07); border-left: 3px solid rgba(255,255,255,0.06); border-radius: 12px; margin-bottom: 6px; transition: background 0.15s; overflow: hidden; }
.lb-row-glass:hover { background: rgba(255,255,255,0.08); }
.lb-cell-glass { padding: 14px 12px; font-size: 14px; color: rgba(255,255,255,0.8); font-family: Arial, sans-serif; display: flex; align-items: center; }
.lb-rank { font-size: 13px; font-weight: 900; justify-content: center; }
.lb-player { gap: 10px; font-weight: 700; color: #fff; }
.lb-avatar { width: 30px; height: 30px; border-radius: 50%; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.15); display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 900; color: #33C6FF; flex-shrink: 0; overflow: hidden; }
.lb-earned { font-weight: 900; color: #FFB700; }
.lb-winrate { color: #4ade80; font-weight: 700; }
.lb-me-badge { font-size: 9px; color: #33C6FF; margin-left: 6px; font-weight: 700; font-family: Arial, sans-serif; }
.lb-sort-btn { display: flex; align-items: center; justify-content: center; gap: 5px; height: 28px; padding: 0 12px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: rgba(255,255,255,0.4); font-size: 10px; font-weight: 700; font-family: 'Arial Black', Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; transition: all 0.15s; white-space: nowrap; }
.lb-sort-btn:hover { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.8); border-color: rgba(255,255,255,0.2); }
.lb-sort-btn.active { background: rgba(99,102,241,0.25); border-color: rgba(99,102,241,0.45); color: #c7d2fe; }
.lb-sort-btn.active::after { content: '↓'; font-size: 9px; opacity: 0.7; }
.lb-header-bar { display: flex; align-items: stretch; margin-bottom: 10px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; overflow: hidden; height: 38px; }
.lb-header-label { display: flex; align-items: center; justify-content: center; padding: 0 16px; font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.25); text-transform: uppercase; letter-spacing: 1px; font-family: Arial, sans-serif; border-right: 1px solid rgba(255,255,255,0.06); white-space: nowrap; flex-shrink: 0; width: 70px; }
.lb-header-player { flex: 1; justify-content: flex-start; padding-left: 20px; width: auto; }
.lb-sort-pill { flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px; background: transparent; border: none; border-left: 1px solid rgba(255,255,255,0.06); color: rgba(255,255,255,0.35); font-size: 10px; font-weight: 700; font-family: 'Arial Black', Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; cursor: pointer; transition: all 0.15s; white-space: nowrap; }
.lb-sort-pill:hover { background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.75); }
.lb-sort-pill.active { background: rgba(99,102,241,0.2); color: #c7d2fe; }
.lb-sort-pill.active::after { content: ' ↓'; opacity: 0.6; }
.lb-sort-static { cursor: default !important; }
.lb-sort-static:hover { background: transparent !important; color: rgba(255,255,255,0.35) !important; }
.lb-header-player { flex: 2 !important; }
/* ---------------------------------------------------------------
   Lot G1 - CDC-142 : « chaque valeur reste alignee sous son intitule
   (Joueur / Gains / Victoires / Matchs / Win Rate), sans debordement ni
   superposition ».

   L'en-tete et les lignes sont DEUX grilles distinctes. Elles ne
   s'alignent que si elles s'accordent sur TROIS choses : leurs
   colonnes, leur ecart, et leur retrait lateral. Elles repetaient les
   colonnes - la seule des trois - et divergeaient sur les deux autres :
   un ecart de 4 px contre 0, et une bordure gauche de 3 px sur la ligne
   seulement.

   Mesure du 02/10/2026 : 23 px de decalage sur un telephone, 8 px sur
   une tablette, 7 px sur un ecran de bureau. « Win Rate » ne
   surplombait pas le taux de victoire.

   Les trois valeurs vivent desormais ICI, et les deux grilles les
   lisent. Le point de rupture du telephone ne redefinit que les
   variables : une colonne changee d'un cote ne peut plus oublier
   l'autre.
   --------------------------------------------------------------- */
/*  `minmax(0, 1fr)` ET NON `1fr` : une unite `fr` ne distribue que
    l'espace LIBRE et respecte la largeur minimale de chaque element,
    or un element de grille a `min-width: auto`. Avec le meme gabarit,
    les deux grilles obtenaient six largeurs differentes - les cellules
    de la ligne (un avatar de 30 px, un pseudo, un montant) ont une
    largeur minimale bien plus grande que les intitules de l'en-tete.
    `minmax(0, ...)` rend la piste exactement proportionnelle, quel que
    soit son contenu. */
:root {
    --lb-colonnes: 70px minmax(0, 1fr) 160px 120px 120px 110px;
    --lb-ecart: 4px;
    --lb-retrait: 0px;
}
.lb-header-tabs, .lb-row-glass {
    grid-template-columns: var(--lb-colonnes);
    gap: var(--lb-ecart);
    padding-left: var(--lb-retrait);
    padding-right: var(--lb-retrait);
}
/*  La ligne porte une bordure de 1 px, et de 3 px a gauche : son contenu
    commence donc 3 px plus loin. Une bordure TRANSPARENTE donne a
    l'en-tete exactement le meme retrait, sans rien dessiner. */
.lb-header-tabs { border: 1px solid transparent; border-left-width: 3px; }
.lb-header-tabs { display: grid; margin-bottom: 8px; }
.lb-tab-static { cursor: default !important; }
.lb-tab-static:hover { background: rgba(255,255,255,0.06) !important; color: rgba(255,255,255,0.5) !important; }
.lb-col-rang { width: auto !important; justify-content: center; }
.lb-col-joueur { width: auto !important; justify-content: flex-start; padding-left: 16px !important; }
.lb-col-stat { width: auto !important; justify-content: center; }

/* ===== PORTEFEUILLE ===== */
.wallet-grid { display: grid; grid-template-columns: auto 1fr; gap: 24px; }
.wallet-balances { display: flex; flex-direction: column; gap: 12px; }
.wallet-balance-card { background: #000; border: 1px solid #3a3a3a; border-radius: 12px; padding: 24px; text-align: center; width: 260px; }
.balance-label { font-size: 12px; color: #888; font-family: Arial, sans-serif; margin-bottom: 12px; text-transform: uppercase; }
.balance-amount { font-size: 36px; font-weight: 900; color: #fff; margin-bottom: 6px; }
.balance-sub { font-size: 14px; color: #666; font-family: Arial, sans-serif; }
.wallet-btn-group { display: flex; gap: 8px; margin-top: 14px; }
.btn-withdraw, .btn-convert { flex: 1; padding: 8px 12px; border-radius: 50px; font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; text-transform: uppercase; }
.btn-withdraw { background: #141414; border: 1px solid #3a3a3a; color: #fff; display: block; width: 100%; margin-top: 14px; }
.btn-withdraw:hover { border-color: #33C6FF; color: #33C6FF; }
.wallet-btn-group .btn-withdraw { margin-top: 0; }
.btn-convert { background: #141414; border: 1px solid #28a745; color: #28a745; }
.btn-convert:hover { background: #28a745; color: #000; }
.wallet-balances-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.wallet-balance-glass { display: flex; align-items: center; gap: 16px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 20px; }
.wallet-balance-icon { font-size: 32px; flex-shrink: 0; }
.wallet-balance-info { flex: 1; }
.wallet-balance-label { font-size: 11px; color: rgba(255,255,255,0.4); text-transform: uppercase; letter-spacing: 1px; font-family: Arial, sans-serif; margin-bottom: 4px; }
.wallet-balance-amount { font-size: 28px; font-weight: 900; color: #fff; margin-bottom: 2px; }
.wallet-balance-sub { font-size: 12px; color: rgba(255,255,255,0.3); font-family: Arial, sans-serif; }
.wallet-balance-btns { display: flex; flex-direction: column; gap: 8px; flex-shrink: 0; }
.wallet-action-btn { padding: 8px 16px; border-radius: 8px; background: rgba(99,102,241,0.2); border: 1px solid rgba(99,102,241,0.35); color: #c7d2fe; font-size: 11px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.15s; white-space: nowrap; }
.wallet-action-btn:hover { background: rgba(99,102,241,0.35); }
.wallet-action-btn-outline { background: rgba(255,255,255,0.05); border-color: rgba(255,255,255,0.1); color: rgba(255,255,255,0.5); }
.wallet-action-btn-outline:hover { background: rgba(255,255,255,0.1); color: #fff; }
.shop-grid-glass { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.shop-card-glass { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); border-top: 2px solid var(--sc, #33C6FF); border-radius: 12px; padding: 16px 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; transition: all 0.2s; position: relative; }
.shop-card-glass:hover { background: rgba(255,255,255,0.08); transform: translateY(-2px); }
.shop-card-glass-coins { font-size: 16px; font-weight: 900; color: #fff; }
.shop-card-glass-chest { font-size: 36px; }
.shop-card-glass-btn { width: 100%; padding: 8px; border: none; border-radius: 8px; font-size: 12px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; color: #fff; transition: opacity 0.2s; }
.shop-card-glass-btn:hover { opacity: 0.85; }
.shop-card-best { border-top-width: 3px; }
.shop-best-badge { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); background: #FFB700; color: #000; font-size: 9px; font-weight: 900; padding: 2px 10px; border-radius: 50px; white-space: nowrap; font-family: Arial, sans-serif; }
.creator-code-glass { display: flex; flex-direction: column; gap: 12px; max-width: 500px; margin: 0 auto; }
.creator-code-current-glass { text-align: center; font-size: 18px; font-weight: 900; color: #fff; padding: 12px; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 10px; }
.creator-code-input-glass { display: flex; gap: 10px; }

/* ===== MODALS ===== */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.7); z-index: 2000; cursor: pointer; }
.modal-box { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0d0d0d; border: 1px solid #3a3a3a; border-radius: 16px; padding: 30px; z-index: 2001; min-width: 320px; }
.modal-close { position: absolute; top: 12px; right: 16px; background: none; border: none; color: #666; font-size: 18px; cursor: pointer; }
.modal-close:hover { color: #fff; }
.modal-title { font-size: 14px; font-weight: 900; color: #888; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 24px; text-align: center; }
.modal-players { display: flex; align-items: center; justify-content: center; gap: 20px; }
.modal-player { text-align: center; }
.modal-avatar { width: 64px; height: 64px; border-radius: 50%; background: #1a1a1a; border: 2px solid #3a3a3a; display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 900; color: #33C6FF; margin: 0 auto 10px; }
.modal-name { font-size: 15px; font-weight: 900; color: #fff; margin-bottom: 6px; }
.modal-vs { font-size: 20px; font-weight: 900; color: #3a3a3a; }
.player-modal-box { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0d0d0d; border: 1px solid #3a3a3a; border-radius: 16px; z-index: 2001; width: 520px; max-width: 95vw; max-height: 90vh; overflow-y: auto; }
.player-banner { height: 120px; border-radius: 16px 16px 0 0; position: relative; flex-shrink: 0; }
.player-banner-avatar { position: absolute; bottom: -40px; left: 24px; width: 80px; height: 80px; border-radius: 50%; background: #1a1a1a; border: 3px solid #0d0d0d; display: flex; align-items: center; justify-content: center; font-size: 26px; font-weight: 900; color: #fff; font-family: Arial, sans-serif; overflow: hidden; }
.player-banner-avatar img { width: 100%; height: 100%; object-fit: cover; }
.player-modal-body { padding: 50px 24px 24px; }
.player-pseudo-wrap { margin-bottom: 20px; }
.player-pseudo { font-size: 22px; font-weight: 900; color: #fff; margin-bottom: 4px; }
.player-bio { font-size: 13px; color: #888; font-family: Arial, sans-serif; }
.player-game-ids { display: flex; gap: 16px; margin-bottom: 20px; padding: 14px; background: #141414; border-radius: 10px; border: 1px solid #3a3a3a; flex-wrap: wrap; }
.player-game-id { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 130px; }
.player-game-icon { font-size: 18px; }
.player-game-label { font-size: 10px; color: #666; font-family: Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; }
.player-game-value { font-size: 13px; font-weight: 700; color: #fff; font-family: Arial, sans-serif; }
.player-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 20px; }
.player-stat-card { background: #141414; border: 1px solid #3a3a3a; border-radius: 10px; padding: 12px; text-align: center; }
.player-stat-value { font-size: 18px; font-weight: 900; color: #fff; margin-bottom: 4px; }
.player-stat-label { font-size: 10px; color: #666; font-family: Arial, sans-serif; text-transform: uppercase; }
.player-stats-detail { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.player-stats-section { background: #141414; border: 1px solid #3a3a3a; border-radius: 10px; padding: 12px; }
.player-stats-section-title { font-size: 12px; font-weight: 900; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
.player-stats-row { display: flex; justify-content: space-between; font-size: 12px; font-family: Arial, sans-serif; color: #ccc; padding: 4px 0; border-bottom: 1px solid #1a1a1a; }
.player-stats-row:last-child { border-bottom: none; }
.player-stats-row span:last-child { font-weight: 700; color: #fff; }

/* ===== SHOP/MISC ===== */
.shop-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-content: start; }
.shop-card { background: #0d0d0d; border: 2px solid #3a3a3a; border-radius: 12px; padding: 14px 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; position: relative; transition: transform 0.2s; cursor: pointer; }
.shop-card:hover { transform: scale(1.03); }
.shop-badge { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: #FFB700; color: #000; font-size: 10px; font-weight: 900; padding: 3px 12px; border-radius: 50px; font-family: Arial, sans-serif; text-transform: uppercase; white-space: nowrap; }
.shop-coins { font-size: 14px; font-weight: 900; color: #fff; font-family: Arial, sans-serif; }
.shop-chest { font-size: 44px; line-height: 1; filter: drop-shadow(0 4px 12px rgba(0,0,0,0.5)); }
.shop-btn { display: block; width: 100%; padding: 10px; border: none; border-radius: 8px; color: #fff; font-size: 13px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; transition: opacity 0.2s; text-transform: uppercase; letter-spacing: 0.5px; }
.shop-btn:hover { opacity: 0.85; }
.creator-code-box { background: #000; border: 1px solid #3a3a3a; border-radius: 12px; padding: 20px 30px; width: 500px; }
.creator-code-label { font-size: 20px; font-weight: 900; color: #fff; text-transform: uppercase; margin-bottom: 10px; text-align: center; letter-spacing: 1px; }
.creator-code-current { font-size: 18px; font-weight: 900; color: #fff; margin-bottom: 14px; font-family: Arial, sans-serif; text-align: center; }
.creator-code-input-wrap { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.creator-code-input-wrap .search-bar { flex: 1; width: auto; }
.creator-code-input-wrap button { padding: 0 16px; height: 36px; background: #33C6FF; border: none; border-radius: 50px; color: #000; font-size: 12px; font-weight: 900; font-family: Arial, sans-serif; cursor: pointer; transition: opacity 0.2s; text-transform: uppercase; white-space: nowrap; flex-shrink: 0; }
.creator-code-input-wrap button:hover { opacity: 0.85; }
.btn-creator-code { display: block; width: 100%; padding: 9px; background: #141414; border: 1px solid #3a3a3a; border-radius: 50px; color: #fff; font-size: 12px; font-weight: 700; font-family: Arial, sans-serif; cursor: pointer; transition: all 0.2s; text-transform: uppercase; }
.btn-creator-code:hover { border-color: #33C6FF; color: #33C6FF; }
.subnav-plus2-btn { height: 32px; padding: 0 12px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); border-radius: 8px; color: rgba(255,255,255,0.5); font-size: 12px; font-weight: 900; font-family: 'Arial Black', Arial, sans-serif; cursor: pointer; transition: all 0.15s; white-space: nowrap; flex-shrink: 0; }
.subnav-plus2-btn:hover { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.85); }
.subnav-plus2-btn.active { background: rgba(99,102,241,0.25); border-color: rgba(99,102,241,0.5); color: #c7d2fe; }
.filters-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.create-defi-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0d0d0d; border: 1px solid #3a3a3a; border-radius: 16px; padding: 30px; z-index: 2001; width: 620px; max-width: 95vw; max-height: 90vh; overflow-y: auto; }
.create-defi-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.create-defi-field { margin-bottom: 14px; }
.create-defi-field label { display: block; font-size: 11px; color: #888; font-family: Arial, sans-serif; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.create-defi-field input, .create-defi-field select { width: 100%; background: #141414; border: 1px solid #3a3a3a; border-radius: 8px; padding: 9px 12px; color: #fff; font-size: 13px; font-family: Arial, sans-serif; outline: none; transition: border-color 0.2s; }
.create-defi-field input:focus, .create-defi-field select:focus { border-color: #33C6FF; }
.create-defi-platforms { display: flex; flex-wrap: wrap; gap: 8px; }
.platform-check { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #ccc; font-family: Arial, sans-serif; cursor: pointer; padding: 5px 10px; background: #141414; border: 1px solid #3a3a3a; border-radius: 50px; transition: border-color 0.2s; }
.platform-check:hover { border-color: #33C6FF; }
.platform-check input { width: auto; accent-color: #33C6FF; }
.create-defi-colors { display: flex; gap: 8px; flex-wrap: wrap; }
/*  `.color-pick` a ete retiree le 08/10/2026 : elle habillait les six
    pastilles de couleur de la modale de creation d'un defi, qui n'existe
    plus. La couleur d'un defi vient desormais de son mode. Aucun
    balisage du depot ne porte plus cette classe. */
.create-defi-private { margin-top: 16px; }
.private-toggle { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #fff; font-family: Arial, sans-serif; cursor: pointer; }
.private-toggle input { accent-color: #33C6FF; width: auto; }
.match-page-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #0d0d0d; border: 1px solid #3a3a3a; border-radius: 16px; z-index: 2001; width: 780px; max-width: 95vw; max-height: 90vh; overflow-y: auto; }
.match-page-header { padding: 16px 24px; border-bottom: 2px solid #33C6FF; display: flex; justify-content: space-between; align-items: center; }
.match-page-title { font-size: 16px; font-weight: 900; color: #fff; }
.match-page-info { display: flex; gap: 6px; }
.match-page-body { display: grid; grid-template-columns: 1fr 300px; gap: 0; }
.match-page-results { padding: 24px; border-right: 1px solid #3a3a3a; }
.match-vs-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 20px; }
.match-player-block { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; }
.match-player-avatar { width: 56px; height: 56px; border-radius: 50%; border: 2px solid #33C6FF; background: #1a1a1a; display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: 900; color: #fff; }
.match-player-name { font-size: 13px; font-weight: 700; color: #fff; text-align: center; }
.match-score-input { display: flex; align-items: center; gap: 12px; }
.match-score-input button { width: 30px; height: 30px; background: #141414; border: 1px solid #3a3a3a; border-radius: 50%; color: #fff; font-size: 18px; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; }
.match-score-input button:hover { border-color: #33C6FF; color: #33C6FF; }
.match-score-input span { font-size: 32px; font-weight: 900; color: #fff; min-width: 40px; text-align: center; }
.match-vs-center { font-size: 22px; font-weight: 900; color: #3a3a3a; }
.match-page-chat { display: flex; flex-direction: column; height: 100%; }
.match-chat-title { padding: 14px 16px; font-size: 13px; font-weight: 700; color: #888; border-bottom: 1px solid #3a3a3a; }
.match-chat-messages { flex: 1; min-height: 250px; max-height: 350px; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 6px; }
.chat-msg { font-size: 12px; font-family: Arial, sans-serif; padding: 6px 10px; border-radius: 8px; max-width: 90%; }
.chat-msg.system { color: #555; font-style: italic; align-self: center; }
.chat-msg.mine { background: #141414; border: 1px solid #3a3a3a; align-self: flex-end; color: #fff; }
.match-chat-input { display: flex; gap: 6px; padding: 10px; border-top: 1px solid #3a3a3a; }
.match-chat-input input { flex: 1; background: #141414; border: 1px solid #3a3a3a; border-radius: 8px; padding: 8px 12px; color: #fff; font-size: 12px; font-family: Arial; outline: none; }

/* ===== RESPONSIVE ===== */
@media (max-width: 768px) {
    .side-nav { width: 70px; border-radius: 16px; top: 10px; left: 10px; bottom: 10px; }
    .side-nav-label, .side-nav-logo-box + .side-nav-label { display: none; }
    .side-nav-btn { justify-content: center; padding: 12px; }
    .side-nav-btn span { display: none; }
    .fn-content { margin-left: calc(10px + 70px + 16px); margin-right: 10px; }
    .page-header { flex-wrap: wrap; }
    .page-header-title { position: static; transform: none; }
    /*  `.top3-grid` : voir `Common/CSS/podium-top3.css`. Ses paliers y
        vivent avec la remise a zero de `order`, dont ils sont
        inseparables. */
    .wallet-grid { grid-template-columns: 1fr; }
    .recharge-grid { grid-template-columns: repeat(2, 1fr); }
    .tournaments-grid { grid-template-columns: repeat(2, 1fr); }
}

/*  LES FILTRES DE COMPETITION ONT DEMENAGE.
    `Z7-GAME-FILTERS` vit desormais dans `Common/CSS/filtres-competition.css` :
    il sert les trois barres de cette page — Tournois, 1V1 Token et
    Bracket — et n'appartient donc a aucune d'elles. Une page ne doit pas
    posseder sa propre copie du dessin d'un composant commun.
    Le fichier a ete DEPLACE a l'identique : aucune regle n'a change. */

/* ============================================================
   LOT U1 · SOUS-NAVBAR — ELLE RAISONNE SUR SA PROPRE LARGEUR
   ============================================================
   LE DEFAUT CONSTATE A L'OEIL. La recherche se reduisait a une loupe,
   puis « Creer un tournoi » a un « + », alors qu'il restait une zone
   vide nette a droite des controles et POURTANT DANS la barre.

   LA CAUSE, mesuree. La sous-navbar n'occupe pas la fenetre. Elle est
   bornee a gauche par le menu (20 + 220 + 16) et a droite par la
   colonne publicitaire (20 + 220 + 16). Mesure a neuf largeurs de
   fenetre, de 901 a 1920 px, l'ecart ne bouge pas d'un pixel :

        largeur interieure de la barre = fenetre - 561

   Or `@media (max-width: …)` interroge `window.innerWidth`. Une media
   query ne pouvait donc PAS savoir la place dont la barre dispose
   vraiment. Le seuil de 1380 px agissait sur un conteneur de 819 px,
   quand le contenu tient en 496 px une fois le titre efface et la
   recherche compacte : la recherche passait en loupe avec 324 px de
   vide sous les yeux. Meme erreur pour le bouton Creer, qui passait
   en « + » avec 100 px de libre.

   LE CORRECTIF. La barre devient son propre CONTENEUR DE REQUETE. Les
   etats sont declenches par SA largeur, jamais par celle de la fenetre.
   Et les seuils ci-dessous ne sont pas choisis a vue : chacun est la
   somme MESUREE des enfants dans l'etat vise. Largeurs naturelles
   relevees (Arial Black 11 px, gap 12 px entre colonnes, 8 px a
   l'interieur de la colonne de droite) :

     onglet        gauche  titre  recherche  creer   total
     tournois        293    213      192      143     873
     token           295    114      192      122     755
     bracket         295    203      192      146     868
     leaderboard     335    148      192       --     699

   Les seuils different donc d'un onglet a l'autre — c'est voulu : un
   seuil unique calé sur l'onglet le plus large recompacterait les
   autres trop tot, ce qui est exactement le defaut corrige ici.
   ============================================================ */

/* ============================================================
   0. L'EMPLACEMENT PUBLICITAIRE CEDE SA PLACE AVANT LES CONTROLES
   ============================================================
   REGLE ARRETEE PAR LE PROPRIETAIRE. Sur grand ecran : menu Fortnite a
   gauche, contenu au centre, emplacement publicitaire a droite. Des que
   la largeur commence a forcer la Recherche ou « Creer un tournoi » a se
   compacter ALORS QU'ILS TIENDRAIENT SANS LA PUBLICITE, c'est la
   publicite qui s'efface — entierement — et le contenu central recupere
   tout l'espace libere.

   La colonne n'est donc PAS supprimee du design : elle est presente
   partout ou elle tient, et elle garde ses 220 px. Elle s'efface en un
   seul morceau, jamais retrecie, et la barre ne passe jamais dessous.

   OU EXACTEMENT ? A la largeur ou l'onglet le plus exigeant — Bracket,
   295 + 12 + 192 + 8 + 146 = 653 px — ne tiendrait plus en entier.
   Avec la publicite, la barre vaut « fenetre - 561 » ; 653 + 561 = 1214.
   On bascule donc a 1213 px de fenetre. En dessous, la barre vaut
   « fenetre - 325 » : elle gagne d'un coup 236 px (220 de colonne et
   16 de gouttiere), et Recherche comme bouton restent complets bien plus
   bas — jusqu'a 973 px de fenetre, la ou la bascule mobile (900 px)
   prend le relais. Sur ordinateur, ils ne se compactent donc plus.

   Le menu Fortnite de gauche n'est pas touche : il garde ses 220 px et
   ses libelles jusqu'a la bascule mobile. */
@media (max-width: 1213px) {
    .side-nav-right { display: none !important; }
    .fn-subnav  { right: 20px !important; }
    .fn-content { margin-right: 20px !important; }
}

/* 1. LA BARRE EST LE CONTENEUR DE REFERENCE.
      `container-type: inline-size` n'impose que la containment en
      ligne : la barre est en `position: fixed` avec `left` et `right`
      fixes, sa largeur ne vient donc pas de son contenu et rien ne
      bouge. Elle etait deja un contexte d'empilement (`position:
      fixed` + `z-index: 990`), les menus deroulants ne changent pas
      de plan. La colonne publicitaire n'est pas touchee : `right:
      calc(20px + 220px + 16px)` reste tel quel, et c'est justement ce
      qui fait que la largeur interrogee EXCLUT deja la publicite. */
.fn-subnav { container-type: inline-size; container-name: subnav; }

/* 2. QUI CEDE, ET DANS QUEL ORDRE.
      Un seul element est elastique : la recherche. Les filtres et le
      bouton Creer sont des ACTIONS, ils gardent leur taille ; le titre
      est entier ou absent, jamais rogne.

      PIEGE EVITE ICI : donner `flex: 1` a une colonne dont les enfants
      sont en `flex-shrink: 0` ne retracte rien. La colonne retrecit,
      ses enfants gardent leur largeur et DEBORDENT par-dessus la
      colonne voisine. C'est ce qui faisait passer le champ Recherche
      par-dessus le bouton Type. */
.subnav-content { min-width: 0; }
.subnav-left   { flex: 0 0 auto; min-width: 0; }
.subnav-right  { flex: 1 1 auto; min-width: 0; }
.z7-dd-wrap, .subnav-lb-tab, .subnav-btn-create { flex-shrink: 0; }

/* 2 bis. LE TITRE EST CENTRE DANS LA BARRE, PAS ENTRE SES VOISINS.
      En flux, il se posait juste apres les filtres. Avec 293 px a gauche
      et 343 px a droite, son milieu tombait 25 px a cote du milieu de la
      barre — assez pour que l'oeil le voie de travers, et c'est ce qui a
      ete signale.

      On le sort donc du flux et on l'ancre au centre de la barre. La
      barre est en `position: fixed` : c'est elle le bloc de reference, et
      `left: 50%` vise bien le milieu de sa zone interieure.

      CONSEQUENCE ASSUMEE : ne prenant plus de place, le titre n'en cede
      plus non plus. Ce sont donc les seuils de la section 4 qui decident
      du moment ou il ne peut plus etre centre sans toucher ses voisins ;
      ils sont recalcules pour cela. Il reste entier ou absent, jamais
      rogne, et jamais par-dessus la recherche.

      `pointer-events: none` : c'est une decoration, elle ne doit pas
      intercepter les clics de ce qui passe dessous. */
.subnav-center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    max-width: 100%;
}

/* 3. LA RECHERCHE, SEUL ELEMENT ELASTIQUE.
      De 192 px (texte indicatif entier) a 90 px (« Tourn... »), en
      continu et SANS aucun seuil : c'est flex qui travaille. Le
      `min-width: 160px` d'origine l'empechait de ceder — en CSS,
      `min-width` l'emporte toujours sur `max-width`. */
.subnav-search { flex: 0 1 192px; min-width: 90px; width: auto; }
/* Quand le champ maigrit, le texte indicatif doit finir par des points
   de suspension, pas etre tranche au milieu d'une lettre. */
.subnav-search input { min-width: 0; width: 100%; text-overflow: ellipsis; }

/* NOTE sur les trois etats reduits qui suivent, ecrits onglet par
   onglet dans la section 4 :

   - RECHERCHE COMPACTE (la loupe seule). On n'y passe qu'une fois les
     90 px atteints, donc quand la place manque vraiment. Le champ
     reste un vrai champ : on clique dessus et l'on tape. Au focus, il
     reprend EXACTEMENT la place libre de la colonne de droite — la
     largeur fixe de 150 px utilisee jusqu'ici debordait quand il ne
     restait que 50 px.

     AUCUNE ANIMATION ici, et c'est le fruit d'une mesure : la largeur
     du champ etait animee sur 180 ms, or pendant ce repli il est
     encore large alors que la barre, elle, a deja retreci. Comme la
     colonne de droite est justifiee `flex-end`, son contenu debordait
     vers la GAUCHE, par-dessus le bouton Type — un chevauchement bien
     reel, visible au redimensionnement, que la recette a attrape a
     1100 px. Le repli est donc instantane.

   - LIBELLE RACCOURCI. « Creer un tournoi » devient « Creer » : seul
     le complement, dans `.subnav-btn-mot`, s'efface. Le libelle
     entier est regroupe dans un `.subnav-btn-libelle` pour ne former
     qu'UN element flex ; sans ce regroupement, le `gap: 6px` du
     bouton s'intercalait entre le verbe et son complement et l'on
     voyait un double espace.

   - BOUTON EN ICONE, en tout dernier recours. Le nom accessible ne
     change pas : le texte demeure dans le DOM, seule sa taille
     devient nulle — un lecteur d'ecran lit toujours « Creer un
     tournoi », et l'attribut `title` donne l'infobulle a la souris. */


/* ---- L'OUVERTURE DE LA RECHERCHE COMPACTE --------------------------
   En etat compact, la boite est un <label> : taper dessus donne le
   focus au champ qu'elle contient, nativement, sans JavaScript. Le
   champ fait alors zero pixel de large — il fallait bien pouvoir le
   viser autrement.

   A l'ouverture, `:focus-within` fait trois choses : la boite passe
   en `flex: 1 1 auto` et prend toute la largeur libre de sa colonne,
   le texte reapparait, et « Creer un tournoi » se replie pour lui
   ceder sa place. Les filtres, eux, ne bougent pas : ils sont en
   `flex-shrink: 0`.

   A la fermeture — clic ailleurs, ou Echap — le focus part, la regle
   cesse de s'appliquer, et tout revient exactement a l'etat d'avant.
   Rien n'est retire du DOM, donc rien n'est a reconstruire.

   CE QUI EST ANIME, ET CE QUI NE L'EST PAS. On anime l'opacite, les
   marges et le `max-width` du bouton. On n'anime AUCUNE largeur de
   la recherche : une transition sur `width` avait deja produit un
   chevauchement mesure a 1100 px — pendant l'animation le champ
   restait large alors que la barre avait deja retreci. La stabilite
   du responsive passe avant la douceur du geste. */
.subnav-search { transition: padding 0.18s ease; }
.subnav-search input { transition: opacity 0.14s ease; }
.subnav-btn-create {
    max-width: 260px;
    transition: max-width 0.2s ease, opacity 0.14s ease, padding 0.18s ease;
}

/* Une recherche repliee mais ACTIVE ne doit pas se taire : si le champ
   contient quelque chose, la loupe passe au bleu. Sans ce signe, un
   filtre restait applique derriere une simple loupe grise, sans que
   rien ne l'indique. */
.subnav-search:has(input:not(:placeholder-shown)) svg { stroke: #33C6FF; }
/* ============================================================
   4. LES SEUILS, PAR ONGLET, EN LARGEUR DE BARRE
   ============================================================
   REGLE APPLIQUEE : on bascule a « besoin - 1 px », jamais plus tot.

   LE TITRE FAIT EXCEPTION depuis qu'il est centre en absolu : il ne
   prend plus de place dans la rangee, donc son seuil n'est plus une
   somme mais un DEGAGEMENT. Il faut que son bord le plus proche reste
   a 12 px au moins de son voisin le plus large :

        T/2 - titre/2 - max(gauche, droite) >= 12
        soit  T >= 24 + titre + 2 x max(gauche, droite)

   C'est plus exigeant qu'en flux — le titre s'efface donc un peu plus
   tot qu'avant — mais tant qu'il est la, il est VRAIMENT centre.
   Chaque commentaire donne l'addition. Exemple, onglet Tournois :
   293 (filtres) + 12 (gap) + 213 (titre) + 12 + 192 (recherche) + 8
   + 143 (bouton) = 873 ; le titre tient donc jusqu'a 873 inclus et
   s'efface a 872. C'est l'arrondi genereux « pour avoir de la marge »
   qui produisait la compaction prematuree.

   ORDRE DES CONCESSIONS : a chaque palier on lache le MOINS possible.
   D'abord le titre (decoratif), puis la recherche qui maigrit toute
   seule, puis sa loupe, puis elle disparait ; le bouton Creer ne perd
   son libelle qu'en dernier — d'abord son complement (« un tournoi »),
   son verbe seulement au tout dernier palier. C'est ce qui fait tenir
   « Creer » 66 px de barre de plus qu'un passage direct a « + ».

   ETATS MESURES DU BOUTON : plein 143 / 122 / 146 px selon l'onglet,
   « Creer » seul 77 px, icone seule 36 px.
   ============================================================ */

/* ---- LES LIBELLES LONGS DES FILTRES (09/10/2026) -------------------
   Au-dessus de 900 px, Z7-GAME-FILTERS dit « Mode de jeu | Type de
   jeu | Region » : 374 px, et non plus les 293 px de « Mode | Type |
   Region » sur lesquels les seuils ci-dessous avaient ete ecrits.
   Deux consequences, mesurees par un balayage continu 1920 -> 850 :

   - LE TITRE. Les filtres deviennent le voisin le plus large : son
     degagement se calcule avec 374, et il s'efface plus tot. Avant
     cela, il passait SOUS « Region » (Tournois de 1521 a 1484 px de
     fenetre, 1V1 de 1422 a 1343, Bracket de 1511 a 1480).

   - UN PALIER DE PLUS : LES LIBELLES COURTS. Quand la recherche
     atteint son plancher de 90 px, seul le complement « de jeu »
     s'efface (`.z7-dd-complement`) : les filtres retombent a 293 px,
     et TOUS les paliers suivants retrouvent exactement la geometrie
     pour laquelle ils ont ete mesures. Sans ce palier, la loupe
     passait sous « Region » entre 901 et 942 px de fenetre.

   ORDRE DES CONCESSIONS, inchange : le titre d'abord, puis la
   recherche maigrit, puis le complement des libelles, puis la
   recherche se replie en loupe, et le bouton Creer en dernier. */
/* ---- TOURNOIS : 374 puis 293 | 213 | 192 | 143 --------------------- */
/* ---- CES SEUILS SONT CEUX DE LA GEOMETRIE DE BUREAU -----------------
   Ils valent au-dessus de 900 px de fenetre. En dessous,
   `Common/CSS/mobile.css` resserre les controles — les filtres passent
   de 293 a 229 px, le bouton de 143 a 130 — et la meme barre contient
   donc bien plus. Appliquer ces nombres la-bas retirait la recherche
   82 px trop tot, avec plus de cent pixels de vide a l'ecran. Le jeu
   mobile, mesure dans SA geometrie, suit juste apres. */
@media (min-width: 901px) {
    @container subnav (max-width: 984px) {   /* degagement : 24 + 213 + 2 x 374 = 985 */
        #subnav-tournois .subnav-center { display: none; }
    }
    @container subnav (max-width: 626px) {   /* 374+12+ 90+8+143 = 627 : libelles courts, 293 */
        #subnav-tournois .z7-dd-complement { display: none; }
    }
    @container subnav (max-width: 545px) {   /* 293+12+ 90+8+143 = 546 */
        #subnav-tournois .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-tournois .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-tournois .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-tournois .subnav-search:focus-within input { width: 100%; opacity: 1; }
        /* Dans cette bande il ne reste que 23 px de libre : le champ rouvert
           n'y faisait que 18 px, on ne pouvait rien y lire. PENDANT LA SAISIE
           SEULEMENT, le bouton voisin passe en icone et lui prete ses 107 px.
           La barre revient a son etat normal des que le champ perd le focus. */
        #subnav-tournois .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-tournois .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 495px) {   /* 293+12+ 40+8+143 = 496 */
        #subnav-tournois .subnav-search { display: none; }
    }
    @container subnav (max-width: 447px) {   /* 293+12+143 = 448 */
        #subnav-tournois .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 381px) {   /* 293+12+ 77 = 382 */
        #subnav-tournois .subnav-btn-create { font-size: 0; gap: 0; padding: 0 10px; }
        #subnav-tournois .subnav-btn-create svg { width: 14px; height: 14px; }
    }

    /* ---- TOKEN : 374 puis 293 | 114 | 192 | 122 ------------------------ */
    @container subnav (max-width: 885px) {   /* degagement : 24 + 114 + 2 x 374 = 886 */
        #subnav-token .subnav-center { display: none; }
    }
    @container subnav (max-width: 605px) {   /* 374+12+ 90+8+122 = 606 : libelles courts, 293 */
        #subnav-token .z7-dd-complement { display: none; }
    }
    @container subnav (max-width: 526px) {   /* 295+12+ 90+8+122 = 527 */
        #subnav-token .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-token .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-token .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-token .subnav-search:focus-within input { width: 100%; opacity: 1; }
        #subnav-token .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-token .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 476px) {   /* 295+12+ 40+8+122 = 477 */
        #subnav-token .subnav-search { display: none; }
    }
    @container subnav (max-width: 428px) {   /* 295+12+122 = 429 */
        #subnav-token .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 383px) {   /* 295+12+ 77 = 384 */
        #subnav-token .subnav-btn-create { font-size: 0; gap: 0; padding: 0 10px; }
        #subnav-token .subnav-btn-create svg { width: 14px; height: 14px; }
    }

    /* ---- BRACKET : 374 puis 293 | 203 | 192 | 146 ---------------------- */
    @container subnav (max-width: 974px) {   /* degagement : 24 + 203 + 2 x 374 = 975 */
        #subnav-bracket .subnav-center { display: none; }
    }
    @container subnav (max-width: 629px) {   /* 374+12+ 90+8+146 = 630 : libelles courts, 293 */
        #subnav-bracket .z7-dd-complement { display: none; }
    }
    @container subnav (max-width: 550px) {   /* 295+12+ 90+8+146 = 551 */
        #subnav-bracket .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-bracket .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-bracket .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-bracket .subnav-search:focus-within input { width: 100%; opacity: 1; }
        #subnav-bracket .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-bracket .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 500px) {   /* 295+12+ 40+8+146 = 501 */
        #subnav-bracket .subnav-search { display: none; }
    }
    @container subnav (max-width: 452px) {   /* 295+12+146 = 453 */
        #subnav-bracket .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 383px) {   /* 295+12+ 77 = 384 */
        #subnav-bracket .subnav-btn-create { font-size: 0; gap: 0; padding: 0 10px; }
        #subnav-bracket .subnav-btn-create svg { width: 14px; height: 14px; }
    }

    /* ---- LEADERBOARD : 335 | 148 | 192 | pas de bouton ----------------- */
    @container subnav (max-width: 841px) {   /* degagement : 24 + 148 + 2 x 335 = 842 */
        #subnav-leaderboard .subnav-center { display: none; }
    }
    @container subnav (max-width: 436px) {   /* 335+12+ 90 = 437 */
        #subnav-leaderboard .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-leaderboard .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-leaderboard .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-leaderboard .subnav-search:focus-within input { width: 100%; opacity: 1; }
        /* Cet onglet n'a pas de bouton Creer a qui emprunter. Ce sont donc
           les quatre pastilles qui se resserrent le temps de la saisie :
           4 x 16 px = 64 px rendus au champ, et aucun libelle n'est coupe. */
        #subnav-leaderboard:has(.subnav-search:focus-within) .subnav-lb-tab { padding: 0 6px; }
    }
    @container subnav (max-width: 386px) {   /* 335+12+ 40 = 387 */
        #subnav-leaderboard .subnav-search { display: none; }
    }

    /* ---- Le tout dernier pixel -----------------------------------------
       La barre la plus etroite que ce fichier puisse voir mesure 340 px
       (fenetre 901). Or les trois onglets a filtres reclament alors
       293 + 12 + 36 = 341 px : un pixel de trop. On resserre les espaces
       plutot que de retirer un controle. L'onglet Leaderboard n'en a pas
       besoin, ses quatre pastilles tiennent en 335 px. */
    @container subnav (max-width: 341px) {
        .subnav-content { gap: 8px; }
        .subnav-left { gap: 6px; }
    }
}

/* ============================================================
   4 bis. EN MOBILE, LES CINQ ACCES TIENNENT ENSEMBLE
   ============================================================
   REGLE ARRETEE PAR LE PROPRIETAIRE. Sur telephone, on garde en meme
   temps, et le plus longtemps possible :

       Region | Mode | Type | loupe | Creer

   La recherche n'est donc PLUS la premiere sacrifiee. C'est le bouton
   qui maigrit d'abord — « Creer un tournoi », puis « Creer », puis
   l'icone seule — puis ce sont les ESPACES qui se resserrent. La
   loupe ne part qu'en tout dernier, vers 320 px, quand cinq controles
   ne tiennent physiquement plus.

   LA LOUPE EST UN CARRE DE 32 px. Elle en mesurait 40 : deux
   bordures, 9 px de marge de chaque cote, 13 px d'icone, et 7 px
   d'ecart entre cette icone et un champ de largeur nulle — 7 px de
   vide pur. Le carre est plus franc a viser et rend 8 px a la barre.
   Ces 8 px sont exactement ce qui permet de garder les cinq acces a
   360 px au lieu de quatre.

   Largeurs relevees dans la geometrie mobile (barre = fenetre - 61) :

     onglet        filtres  loupe  bouton plein/court/icone
     tournois        229      32        130 / 70 / 30
     token           230      32        111 / 70 / 30
     bracket         230      32        132 / 70 / 30
     leaderboard     233      32           — (pas de bouton)

   Ecarts : 8 px entre les colonnes, 6 px dans celle de droite.
   Regle : on bascule a « besoin - 1 px ».
   ============================================================ */
@media (max-width: 900px) {

    /* ---- TOURNOIS ------------------------------------------------ */
    @container subnav (max-width: 462px) {   /* 229+8+ 90+6+130 = 463, la recherche atteint son plancher */
        #subnav-tournois .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-tournois .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-tournois .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-tournois .subnav-search:focus-within input { width: 100%; opacity: 1; }
        #subnav-tournois .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-tournois .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 404px) {   /* 229+8+32+6+130 = 405 */
        #subnav-tournois .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 344px) {   /* 229+8+32+6+ 70 = 345 */
        #subnav-tournois .subnav-btn-create { font-size: 0; gap: 0; padding: 0 8px; }
    }
    @container subnav (max-width: 296px) {   /* 225+6+32+4+30 = 297, espaces resserres */
        #subnav-tournois .subnav-search { display: none; }
    }

    /* ---- TOKEN --------------------------------------------------- */
    @container subnav (max-width: 444px) {   /* 230+8+ 90+6+111 = 445 */
        #subnav-token .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-token .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-token .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-token .subnav-search:focus-within input { width: 100%; opacity: 1; }
        #subnav-token .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-token .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 386px) {   /* 230+8+32+6+111 = 387 */
        #subnav-token .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 345px) {   /* 230+8+32+6+ 70 = 346 */
        #subnav-token .subnav-btn-create { font-size: 0; gap: 0; padding: 0 8px; }
    }
    @container subnav (max-width: 297px) {   /* 226+6+32+4+30 = 298 */
        #subnav-token .subnav-search { display: none; }
    }

    /* ---- BRACKET ------------------------------------------------- */
    @container subnav (max-width: 465px) {   /* 230+8+ 90+6+132 = 466 */
        #subnav-bracket .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-bracket .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-bracket .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-bracket .subnav-search:focus-within input { width: 100%; opacity: 1; }
        #subnav-bracket .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        #subnav-bracket .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @container subnav (max-width: 407px) {   /* 230+8+32+6+132 = 408 */
        #subnav-bracket .subnav-btn-mot { display: none; }
    }
    @container subnav (max-width: 345px) {   /* 230+8+32+6+ 70 = 346 */
        #subnav-bracket .subnav-btn-create { font-size: 0; gap: 0; padding: 0 8px; }
    }
    @container subnav (max-width: 297px) {   /* 226+6+32+4+30 = 298 */
        #subnav-bracket .subnav-search { display: none; }
    }

    /* ---- LEADERBOARD : pas de bouton, rien a lui prendre ---------- */
    @container subnav (max-width: 330px) {   /* 233+8+ 90 = 331 */
        #subnav-leaderboard .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        #subnav-leaderboard .subnav-search input { width: 0; padding: 0; opacity: 0; }
        #subnav-leaderboard .subnav-search:focus-within { flex: 1 1 auto; max-width: none; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        #subnav-leaderboard .subnav-search:focus-within input { width: 100%; opacity: 1; }
    }
    @container subnav (max-width: 272px) {   /* 233+8+32 = 273 */
        #subnav-leaderboard .subnav-search { display: none; }
    }

    /* ---- Deux resserrements, AVANT de retirer un acces ------------
       Quand l'icone seule ne suffit plus, on reprend la place sur les
       espaces et les marges internes des filtres, jamais sur un
       controle. Region, Mode et Type gardent leurs libelles. */
    @container subnav (max-width: 305px) {   /* 229+8+32+6+30 = 306, l'icone ne suffit plus */
        .subnav-content.active { gap: 6px; }
        .subnav-right { gap: 4px; }
        .z7-dd-btn { padding: 0 4px; }
        .subnav-lb-tab { padding: 0 6px; }
    }
    @container subnav (max-width: 262px) {   /* dernier cran avant de perdre la loupe */
        .z7-dd-btn { padding: 0 2px; }
    }
}

/* ---- OU S'ARRETE CE FICHIER ----------------------------------------
   Des 900 px de fenetre, `Common/CSS/mobile.css` pose le cadre, et avec
   des `!important` : la colonne publicitaire est retiree, le titre est
   masque, la barre devient collante, et `.subnav-content.active` recoit
   `overflow-x: auto`. C'est la le filet de securite : si les controles
   ne tiennent vraiment plus, la rangee defile au doigt plutot que de
   deborder la page. Les paliers ci-dessus ne font qu'eviter d'y arriver.

   Le dernier palier utile s'arrete a 262 px de barre. La plus petite
   fenetre qu'on soutient est 320 px, soit 259 px de barre : ecrire un
   palier sous 262 serait du code jamais atteint. */

/* ============================================================
   5. SECOURS POUR LES NAVIGATEURS SANS REQUETES DE CONTENEUR
   ============================================================
   Les requetes de conteneur sont disponibles partout depuis 2023. Un
   navigateur plus ancien retomberait sinon sur une barre qui deborde :
   on lui redonne donc les seuils de fenetre equivalents, obtenus en
   ajoutant les 561 px mesures, et cales sur l'onglet le plus large.
   C'est moins juste — c'est precisement le defaut corrige plus haut —
   mais rien ne se chevauche. */
@supports not (container-type: inline-size) {
    /* 985 px de barre + 561 = 1546 : en dessous, le titre ne peut
       plus etre centre sans toucher les filtres aux libelles longs. */
    @media (max-width: 1545px) { .subnav-center { display: none; } }
    /* 630 px de barre + 561 = 1191 : les libelles courts. */
    @media (max-width: 1190px) { .z7-dd-complement { display: none; } }
    @media (max-width: 1106px) {
        /* Meme loupe carree de 32 px qu'au-dessus, pour que le repli soit
           le meme geste partout, y compris chez ces navigateurs. */
        .subnav-search { flex: 0 0 auto; min-width: 0; width: 32px; padding: 0; gap: 0; justify-content: center; cursor: pointer; }
        .subnav-search input { width: 0; padding: 0; opacity: 0; }
        .subnav-search:focus-within { flex: 1 1 auto; max-width: 220px; width: auto; padding: 0 12px; gap: 7px; cursor: text; }
        .subnav-search:focus-within input { width: 100%; opacity: 1; }
        .subnav-search:focus-within ~ .subnav-btn-create { max-width: 0; padding: 0; border-width: 0; opacity: 0; overflow: hidden; pointer-events: none; }
        .subnav-right:has(.subnav-search:focus-within) { gap: 0; }
    }
    @media (max-width: 1056px) { .subnav-search { display: none; } }
    @media (max-width: 1008px) { .subnav-btn-mot { display: none; } }
    @media (max-width:  942px) {
        .subnav-btn-create { font-size: 0; gap: 0; padding: 0 10px; }
        .subnav-btn-create svg { width: 14px; height: 14px; }
    }
    /* Rien sous 900 px : mobile.css s'en charge, pour tout le monde. */
}


/* ============================================================
   REPLIS — le contenu passe avant la colonne des partenaires
   ============================================================
   L'ordre de sacrifice est celui du proprietaire : sur un ecran plus
   etroit, c'est la colonne de droite qui part la premiere, puis la
   barre laterale ; les tournois et leurs actions restent. */
/*  LA REGLE « UNE SEULE CARTE SOUS 1500 px » A ETE RETIREE. Elle lisait
    la largeur de l'ECRAN quand ce qui compte est la largeur du
    CONTENEUR : a 1440 px de fenetre, le carrousel dispose encore de
    719 px, de quoi porter deux cartes. Le compte est maintenant decide
    par les requetes de conteneur, pres de la definition de `.fnt-une`. */

@media (max-width: 1280px) {
    .side-nav-right { display: none; }
    .fn-content { margin-right: 20px !important; }
    .fn-subnav  { right: 20px !important; }
}

@media (max-width: 1024px) {
    .fnt-fin { flex-wrap: wrap; }
    .fnt-fin-gagnant { flex: 1 1 100%; order: 3; }
    .fnt-fin-action  { flex: 0 0 auto; order: 2; min-width: 140px; }
}

@media (max-width: 760px) {
    .fnt-grille { grid-template-columns: repeat(auto-fill, minmax(min(100%, 180px), 1fr)); gap: 12px; }
    /*  LES FLECHES SONT CACHEES ICI, la gouttiere ne protege plus rien.
        ATTENTION : `Common/CSS/mobile.css` est chargee APRES cette
        feuille et pose la meme propriete en `!important` ; c'est donc
        LA-BAS que la valeur est tranchee pour les petits ecrans. Cette
        ligne ne sert que si la feuille historique disparait un jour. */
    .featured-carousel-wrapper { padding-left: 4px; padding-right: 4px; }
    .carousel-nav-btn { display: none; }

    /*  LA CARTE MISE EN AVANT SE REDRESSE. Cote a cote, l'affiche et les
        informations se partageaient 340 px : le nom tombait a un mot par
        ligne, le decompte se chevauchait et les deux boutons se
        marchaient dessus. En colonne, l'affiche prend la largeur — cadree
        en carre comme les autres cartes, donc sans deformation — et les
        informations retrouvent la leur. */
    /*  UNE CARTE ENTIERE, PAS UNE CARTE ET DEMIE. A 340 px dans un
        conteneur de 591, la seconde carte etait coupee au bord sans
        qu'on puisse la lire ; a 390 px de fenetre la valeur ne changeait
        deja rien (100 % vaut 221 px). */
    /*  La carte en pile est l'affaire du composant : voir
        `Common/CSS/carte-une.css`. */
    /*  LA TETE GARDE SA FORME. Ces trois lignes venaient du temps ou la
        carte etait large de 160 px : le nom passait au-dessus, la
        pastille en dessous, et `min-height: 0` liberait la hauteur
        reservee au nom. Mesure au telephone : les titres d'une ligne et
        de deux lignes decalaient alors tout ce qui suit de 13 px. En
        colonne, la carte fait 269 px — le nom et la pastille tiennent
        cote a cote, et les deux lignes restent reservees. */

    /*  Les cibles tactiles gardent leur taille : on ne rapetisse pas
        l'interface pour faire entrer une maquette de bureau. */
    .fnt-btn { min-height: 42px; font-size: 11px; }
    .fnt-fin-action { min-height: 42px; }
    .fnt-actions { flex-wrap: wrap; }
}
