
/* ============================================================
   TOKENS DE DESIGN — palette centralisée
   Source unique de vérité pour les couleurs de l'application.
   Les règles du bloc <style> ci-dessous référencent ces variables.
   ============================================================ */
:root {
    --tt-dark:        #2c3e50;  /* bleu nuit — barres, en-têtes, texte fort */
    --tt-dark-2:      #34495e;  /* variante boutons (Outils) */
    --tt-primary:     #3498db;  /* bleu d'action principal */
    --tt-primary-2:   #2980b9;  /* bleu d'action (hover/foncé) */
    --tt-success:     #27ae60;  /* vert — validé / gagnant */
    --tt-success-2:   #2ecc71;  /* vert clair */
    --tt-danger:      #e74c3c;  /* rouge — suppression / alerte */
    --tt-danger-2:    #c0392b;  /* rouge foncé */
    --tt-muted:       #95a5a6;  /* gris — boutons secondaires (Annuler) */
    --tt-muted-2:     #7f8c8d;  /* gris texte secondaire */
    --tt-warn:        #f39c12;  /* orange — avertissement / accent */
    --tt-warn-2:      #e67e22;  /* orange foncé */
    --tt-purple:      #8e44ad;  /* violet — plein écran / régie */
    --tt-border:      #bdc3c7;  /* gris bordure neutre */

    /* Tokens NEUTRES sémantiques (surfaces, texte, bordures) */
    --tt-bg:          #f0f2f5;  /* fond de page / panneau */
    --tt-surface:     #ffffff;  /* surface de carte (poules, boîtes, inputs) */
    --tt-surface-2:   #ecf0f1;  /* surface secondaire (panel, onglets) */
    --tt-surface-3:   #f5f6fa;  /* survol léger / zones subtiles */
    --tt-ink:         #2c3e50;  /* texte principal */
    --tt-ink-2:       #555555;  /* texte secondaire */
    --tt-border-soft: #dddddd;  /* bordures fines */
    --tt-th:          #d2d2d2;  /* en-têtes de tableau */
    --tt-tabbar:      #1a252f;  /* barre d'onglets (déjà sombre) */
}


/* Items du menu Outils : style centralisé (remplace ~200 car. de style inline
   répétés sur chaque bouton, et le survol qui était géré en JS). */
.tools-menu-item {
    display: flex; align-items: center; gap: 8px;
    width: 100%; padding: 10px 14px;
    background: var(--tt-surface); border: none; border-bottom: 1px solid var(--tt-border-soft);
    cursor: pointer; font-size: 13px; text-align: left;
    color: var(--tt-dark);
}
.tools-menu-item:last-child { border-bottom: none; }
.tools-menu-item:hover { background: var(--tt-surface-3); }
.tools-menu-item.danger { color: var(--tt-danger-2); }
.tools-menu-item.muted  { color: var(--tt-muted-2); }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    background: black; /* évite tout liseré clair au chargement */
}


body {
    font-family: sans-serif;
    background: var(--tt-dark);
    margin: 0;
    font-size: 11px;

    display: flex;
    flex-direction: column;

    height: 100dvh;   /* hauteur réelle écran */
}




        /* Images de fond retirées (1.jpg → 5.jpg non utilisées) */

        .tabs { display: flex; background: var(--tt-tabbar); padding: 3px 3px 2px 3px; gap: 4px; align-items: center; flex-shrink: 1; white-space: nowrap; scrollbar-width: thin; scrollbar-color: #7a6555 #2c3442; overflow-x: auto; overflow-y: hidden; }
        .tabs.firefox-tabs { padding-bottom: 8px; }
        .tabs::-webkit-scrollbar { height: 6px; background: #2c3442; }
        .tabs::-webkit-scrollbar-thumb { background: #7a6555; border-radius: 4px; }
        .tab { padding: 8px 16px; background: var(--tt-muted-2); color: white; cursor: grab; border: none; font-weight: bold; display: flex; align-items: center; gap: 8px; font-size: 14px; user-select: none; flex-shrink: 0; border-radius: 3px; }
        .tab.active { background: var(--tt-primary); transform: scale(1.13); transform-origin: center bottom; box-shadow: 0 4px 12px rgba(0,0,0,0.35); z-index: 2; position: relative; border-radius: 6px; }
        .tab.dragging { opacity: 0.5; cursor: grabbing; border: 1px dashed #fff; }
        .tab span { background: rgba(0,0,0,0.3); padding: 0 4px; border-radius: 2px; font-size: 11px; cursor: pointer; }
        .sub-nav { display: flex; background: var(--tt-border); padding: 5px; gap: 6px; flex-shrink: 0; flex-wrap: wrap; }
        .sub-btn { padding: 6px 10px; cursor: pointer; border: none; font-weight: bold; background: var(--tt-surface-2); border-radius: 3px; white-space: nowrap; flex-shrink: 0; }

        /* ===== Onglets de départage ===== */
        .dept-view { display:flex; flex-direction:column; align-items:center; overflow-y:auto; }
        .dept-view .tree-grid { margin: 0 auto; }
        #classement-view table { width: auto !important; min-width: 500px; max-width: 100%; }
        .sub-btn.dept-tab { background: #5d6d7e; }
        .sub-btn.dept-tab:hover, .sub-btn.dept-tab.active { background: var(--tt-warn-2); color:#fff; }
        .sub-btn.classement-tab { background: var(--tt-dark); font-weight:bold; }
        .sub-btn.classement-tab:hover, .sub-btn.classement-tab.active { background: #c9a227; color:#fff; }

        .sub-btn.active { background: var(--tt-warn-2); color: white; }
        .add-btn { padding: 6px 12px; cursor: pointer; background: var(--tt-success); color: white; border: none; font-weight: bold; flex-shrink: 0; border-radius: 3px; }
        .print-btn { padding: 6px 12px; cursor: pointer; background: var(--tt-warn); color: white; border: none; font-weight: bold; margin-left: 4px; border-radius: 3px; }
        .reset-all-btn { padding: 6px 12px; cursor: pointer; background: var(--tt-danger-2); color: white; border: none; font-weight: bold; border-radius: 3px; }
.panel {
    background: var(--tt-surface-2);
    padding: 5px;
    display: flex;
    flex-direction: column;
    flex: 1;          /* ← LA CLÉ */
    min-height: 0;    /* évite les débordements */
}

#app {
    flex: 1;
    min-height: 0;
}


        .registration-list {
            counter-reset: p-count;
            margin: 0;
            width: 100%;
            display: flex;
            flex-direction: column;
            flex-wrap: wrap;
            align-content: flex-start;
            column-gap: 10px;
            max-height: calc(100vh - 180px);
        }
        .registration-row {
            width: 320px;
            box-sizing: border-box;
    display: flex;
    gap: 15px;
    border-bottom: 1px solid var(--tt-border-soft);
    padding: 4px 10px;
    align-items: center;
    font-size: 15px;
    font-weight: bold;

    background: rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);

    border: 1px solid #000;
    margin-bottom: 2px;
    border-radius: 3px;
}


        .registration-row::before { counter-increment: p-count; content: counter(p-count) ". "; color: var(--tt-ink); flex-shrink: 0; }
        .validation-screen .registration-row::before { display: none; }
        .validation-screen .registration-row { width: auto; min-width: 200px; }
        .registration-row span { flex: 1; }
        .registration-row button { flex-shrink: 0; }
        .poule-grid { display: flex; flex-wrap: wrap; gap: 8px; height: 100%; width: 100%; align-content: flex-start; overflow-y: auto; padding-bottom: 5px; }
.poule { border: 1px solid #000; background: var(--tt-surface); display: flex; flex-direction: column; flex: 0 1 49.5%; min-height: 350px; max-height: 795px; overflow: hidden; border-radius: 3px; }
        .poule-layout { display: flex; flex-direction: column; padding: 4px; flex: 1; overflow: hidden; }
        .match-list { overflow-y: auto; flex: 1; border-top: 1px solid var(--tt-border-soft); }
        .match-num { display:inline-flex;align-items:center;justify-content:center;min-width:20px;font-size:11px;color:#888;font-weight:normal;flex-shrink:0;margin-right:4px;user-select:none;pointer-events:none; }

        .match-box-row.bracket-dragging { opacity:0.4; }
        .match-box-row[data-bkey] { cursor:pointer; }
        .match-box-row.bracket-selected { background:#d5e8f7 !important; outline:2px solid var(--tt-primary-2); outline-offset:-2px; }
        .match-box-row.bracket-drag-over { background:#eaf4fb; outline:2px dashed var(--tt-primary); outline-offset:-2px; }
        .match-list .row[draggable] { cursor: grab; user-select: none; }
        .match-list .row[draggable]:active { cursor: grabbing; }
        .match-list .row.dragging { opacity: 0.4; }
        body.drag-forbidden, body.drag-forbidden * { cursor: no-drop !important; }
        .row { display: flex; justify-content: flex-start; border-bottom: 1px solid var(--tt-border-soft); padding: 2px 6px; align-items: center; min-height: 28px; }
        .player-name { flex: 1; min-width: fit-content; font-weight: bold; font-size: 14px; white-space: nowrap; }
        .player-name.right { text-align: right; }
        /* Affichage poule : les deux noms regroupés à gauche, scores poussés à droite */
        .row .player-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
        .row .player-name.right { text-align: left; }
        .row .vs-sep { flex: 0 0 auto; color: var(--tt-muted-2); font-weight: normal; margin: 0 5px; user-select: none; }
        /* Quand un drapeau précède directement le « vs » (match non joué), on resserre
           à gauche pour que le drapeau colle au vs. Match fini (sans drapeau) : marge normale. */
        .row .ff-flag + .vs-sep { margin-left: 1px; }
        .row .sets { margin-left: auto; }
        .sets { display: flex; gap: 0; flex-shrink: 0; padding: 0 5px; position: relative; }
        /* Zone des cases de score (hors badge table / cadenas) : sert d'ancrage
           au filigrane « FORFAIT » pour qu'il ne déborde pas sur le badge ni le
           cadenas. */
        .sets-cells { position: relative; display: inline-flex; }
        /* Badge « Forfait » propre : remplace les cases vides d'un forfait sec,
           ou s'affiche après le score (barré gris) d'un abandon. */
        .forfait-tag {
            display: inline-flex; align-items: center; justify-content: center;
            align-self: stretch; flex: 0 0 auto; width: auto; min-width: 0;
            padding: 0 5px; box-sizing: border-box;
            font-size: 14px; font-weight: 800; letter-spacing: 0;
            text-transform: uppercase; line-height: 1; white-space: nowrap;
            color: #c0392b; background: #fdecea;
            border: 1px solid #e8a89f; border-radius: 4px;
            cursor: pointer; user-select: none; transition: background 0.12s, box-shadow 0.12s;
        }
        .forfait-tag:hover { background: #fad7d2; box-shadow: 0 0 0 2px rgba(192,57,43,0.15); }
        .forfait-tag-after { margin-left: 5px; }
        /* Abandon : les scores joués sont grisés et barrés par UN SEUL trait
           continu GRIS en travers de toutes les cases (et non case par case). */
        .set-box.set-forfait .score-num { color: #95a5a6; text-decoration: none; }
        .sets-cells.forfait-struck::after {
            content: ''; position: absolute; left: 2px; right: 2px; top: 50%;
            border-top: 2px solid #7f8c8d; transform: translateY(-1px);
            pointer-events: none; z-index: 2;
        }
        /* Drapeau de forfait (abandon) — cliquable, masqué à l'impression */
        .ff-flag { cursor: pointer; font-size: 13px; line-height: 1; opacity: 0.62; flex: 0 0 auto; user-select: none; transition: opacity 0.12s, transform 0.12s; margin: 0 0 0 1px; }
        .ff-flag:hover { opacity: 1; transform: scale(1.25); }
        .ff-flag.active { opacity: 1; filter: drop-shadow(0 0 1px #c0392b); }
        .match-box-row .ff-flag { font-size: 11px; margin-left: 4px; }
        .player-name.ff-loser { color: #999 !important; text-decoration: line-through; font-weight: normal !important; }
        /* Pastille unique forfait + cartons (une par joueur, après le nom). */
        .ff-chip { cursor: pointer; display: inline-flex; align-items: center; gap: 1px; flex: 0 0 auto; margin: 0 0 0 4px; line-height: 1; user-select: none; position: relative; vertical-align: middle; font-size: 13px; }
        .ff-chip .ff-sq { width: 11px; height: 15px; border-radius: 2px; display: inline-block; }
        .ff-chip .ff-sq-j { background: #f1c40f; }
        .ff-chip .ff-sq-r { background: #e74c3c; }
        .ff-chip .ff-sq-dash { width: 11px; height: 15px; border: 1.5px dashed #aab2b8; border-radius: 2px; display: inline-block; opacity: 0.6; transition: opacity 0.12s, border-color 0.12s; }
        .ff-chip:hover .ff-sq-dash { opacity: 1; border-color: #7f8c8d; }
        .ff-chip .ff-corner { position: absolute; right: -5px; top: -6px; font-size: 9px; }
        .ff-chip .ff-chip-flag { filter: drop-shadow(0 0 1px #c0392b); }
        body.live-spectator .ff-chip.ff-empty { display: none !important; }
        body.live-spectator .ff-chip { pointer-events: none !important; }
        /* Match cadenassé : on masque les pastilles vides (en pointillé), seuls
           les cartons et forfaits déjà posés restent visibles. */
        [data-match-key][data-locked="1"] .ff-chip.ff-empty { display: none !important; }
        .set-box { display: inline-flex; margin-right: 2px; }
        .score-num { 
            width: 18px; 
            height: 22px;
            text-align: center; 
            font-weight: bold; 
            border: 1px solid #999; 
            font-size: 12px; 
            padding: 2px 0; 
            background: var(--tt-surface); 
            margin: 0;
        }
        .score-num:first-child { border-radius: 2px 0 0 2px; border-right: none; }
        .score-num:nth-child(2) { border-radius: 0 2px 2px 0; border-left: 1px solid #999; }
        .set-box.set-empty .score-num { color: var(--tt-border); }
        .score-num:focus { color: var(--tt-ink) !important; }
        .score-num[readonly]:focus { outline: none !important; box-shadow: none !important; background: inherit !important; color: inherit !important; }
        .score-num:disabled { opacity: 1 !important; color: inherit !important; background: inherit !important; cursor: default; }
        .set-box.set-invalid .score-num { border-color: var(--tt-danger); background: #fadbd8; }
        .set-box.set-win-bg .score-num { background: #d5f4e6; border-color: var(--tt-success); }
        .sets input:disabled { background: var(--tt-surface-3); border-color: var(--tt-border-soft); cursor: not-allowed; opacity: 0.5; }
        .set-unplayed input { background: transparent !important; border-color: var(--tt-border-soft) !important; opacity: 0.4; }
        .print-val { display: none; }
.set-win-bg {
    background-color: #d4edda !important; /* Le vert clair */
    color: var(--tt-ink) !important;             /* Texte bien lisible */
    border: 1px solid #000000 !important; /* Bordure noire demandée */
} 
        .winner-style { color: #1e8449 !important; font-weight: 900; text-decoration: underline; -webkit-print-color-adjust: exact; print-color-adjust: exact; } 
.set-invalid { 
    color: var(--tt-danger) !important; 
    border: 1px solid var(--tt-danger) !important; 
    background-color: var(--tt-surface) !important;
}
.set-empty { 
    color: var(--tt-border) !important; 
    border: 1px solid #000000 !important; 
    background-color: var(--tt-surface) !important;
}
        table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-bottom: 6px; flex-shrink: 0; }
        th, td { border: 1px solid #000; padding: 4px 4px; text-align: center; font-weight: bold; }
th { background-color: var(--tt-th); }
        /* Colonnes Rang (1) et V (3) ajustées au texte */
        table th:nth-child(1), table td:nth-child(1),
        table th:nth-child(3), table td:nth-child(3) {
            width: 1%;
            white-space: nowrap;
        }
        /* Poules : colonnes Joués (3) et Pts (4) de largeur identique et compacte.
           "Joués" étant plus long que "Pts", on réduit un peu l'en-tête pour qu'il
           tienne dans la même largeur sans élargir la colonne. */
        table[id^="ranking-"] th:nth-child(3), table[id^="ranking-"] td:nth-child(3),
        table[id^="ranking-"] th:nth-child(4), table[id^="ranking-"] td:nth-child(4) {
            width: 3em;
            min-width: 3em;
            max-width: 3em;
            white-space: nowrap;
            padding-left: 2px;
            padding-right: 2px;
            box-sizing: border-box;
        }
        table[id^="ranking-"] th:nth-child(3) { font-size: 0.78em; }
        .col-set-perdus { width: 1%; white-space: nowrap; padding: 4px 2px !important; }
        .col-set-perdus { width: 1%; white-space: nowrap; padding: 4px 2px !important; }
.final-tree {
    background: transparent;
    padding: 5px;
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow-y: auto;  /* Scroll vertical si contenu dépasse */
    overflow-x: auto;  /* ✅ Scroll horizontal si tableau trop large */
    min-height: 0;
}

.final-tree.top-align { justify-content: flex-start; }

.tree-grid {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    gap: 10px;
    width: max-content;
    min-width: min(100%, 900px);
    min-height: max(100%, 720px);
    /* flex-shrink:0 : même correctif que le bloc mobile — .final-tree (flex colonne,
       min-height:0) ne doit jamais comprimer la grille sous la hauteur de son contenu,
       sinon les colonnes (space-around) écrasent les .match-box à leur min-height (80px)
       et la 2e ligne joueur passe sous la boîte suivante (coupée). La vue défile
       verticalement à la place (.final-tree a déjà overflow-y:auto). */
    flex-shrink: 0;
    padding: 10px 0;
    box-sizing: border-box;
    margin: 0 auto;
}
/* Pendant le (re)calcul des offsets d'alignement (alignBracketRows), l'arbre est
   masqué pour éviter le flash de bracket désaligné, puis révélé une fois aligné.
   Remplace l'ancien clone-overlay en position fixe (qui doublait le DOM et se
   désalignait au scroll). La classe est retirée dans le rAF de addTourPrintButtons,
   avec un filet de sécurité (setTimeout) dans render() qui garantit la révélation. */
.tree-grid.rendering { opacity: 0; }

.column {
    display: flex;
    flex-direction: column;
    justify-content: space-around;  /* ✅ space-around : aligne les tours (chaque match du tour N+1 est centré entre 2 matchs du tour N) */
    flex: 1;
    min-width: 180px;
}

.tree-grid.only-semis {
    justify-content: center;
}

.tree-grid.only-semis .column {
    flex: 1;
    max-width: 360px;
}

.tree-grid.consolante-3-joueurs {
    justify-content: center;
}

.tree-grid.consolante-3-joueurs .column {
    flex: 1;
    max-width: 360px;
}

.tree-grid.only-quarts {
    justify-content: center;
}

.tree-grid.only-quarts .column {
    flex: 1;
    max-width: 360px;
}

.tree-grid.only-huitiemes {
    justify-content: center;
}

.tree-grid.only-huitiemes .column {
    flex: 1;
    max-width: 360px;
}

.tree-grid.only-seiziemes {
    justify-content: center;
}

.tree-grid.only-seiziemes .column {
    flex: 1;
    max-width: 360px;
}

.column.final-col { 
    justify-content: center;
    gap: 6px;
    align-items: flex-end;
}
.match-box[data-match-key$="_PFIN"] {
    width: max-content;
    min-width: 100%;
    margin-top: -5px;
}
        .match-box { 
            border: 2px solid #333; 
            padding: 4px; 
            background: rgba(249, 249, 249, 0.85); 
            box-shadow: 2px 2px 0px rgba(44, 62, 80, 0.5); 
            margin: 2px 0; 
            width: 100%; 
            box-sizing: border-box; 
            position: relative; 
            border-radius: 3px;
            min-height: 80px;  /* ✅ Hauteur minimale pour bloquer le rapprochement */
        }
        .match-box.tour-P {
            border-color: #000 !important;
        }
        .match-box-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--tt-border-soft); margin-bottom: 3px; }
        .match-box b { font-size: 9px; color: #c0560a; font-weight: bold; text-transform: uppercase; white-space: nowrap; }
        .match-box-row { display: flex; justify-content: space-between; align-items: center; padding: 2px 0; border-bottom: 1px solid var(--tt-border-soft); }
        .match-box-row:last-child { border-bottom: none; }
        .match-box .player-name { font-size: 14px; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .match-box .player-name.right { direction: rtl; text-align: left; unicode-bidi: plaintext; }
        /* Nom dans case tableau : affiche prénom complet par défaut, bascule sur initiale si ça déborde */
        .match-box .player-name .bn-full { display: inline; }
        .match-box .player-name .bn-short { display: none; }
        /* Quand le span full déborde (détecté par JS post-render), on affiche la version courte */
        .match-box .player-name.use-short .bn-full { display: none; }
        .match-box .player-name.use-short .bn-short { display: inline; }
        /* Cacher bn-short partout par défaut (classement + lignes de match poules) */
        .bn-short { display: none; }
        .use-short .bn-short { display: inline; }
        .use-short .bn-full { display: none; }
        .match-box .sets { padding: 0; }
        .table-badge {
            display: inline-block;
            padding: 1px 4px;
            border-radius: 10px;
            font-size: 9px;
            font-weight: bold;
            cursor: pointer;
            white-space: nowrap;
            flex-shrink: 0;
            margin: 0 2px;
            border: none;
            transition: opacity 0.15s;
        }
        .table-badge:hover { opacity: 0.8; }
        .table-badge-free { background: #ecf0f1; color: var(--tt-muted-2); border: 1px dashed var(--tt-border); }
        .table-badge-assigned { background: var(--tt-success); color: #fff; }
        /* Badge dans les poules (dans .row) */
        /* Tooltips */
        /* Tooltips smart repositionnés par JS — voir initSmartTooltips() */
        #smart-tooltip { position: fixed; background: #333; color: #fff; padding: 4px 8px; border-radius: 4px; font-size: 11px; white-space: nowrap; z-index: 99999; pointer-events: none; opacity: 0; transition: opacity 0.12s; }
        #smart-tooltip.visible { opacity: 1; }
        #smart-tooltip::after { content: ''; position: absolute; left: var(--arrow-left, 50%); transform: translateX(-50%); border: 4px solid transparent; }
        #smart-tooltip.tip-top::after { top: 100%; border-top-color: #333; }
        #smart-tooltip.tip-bottom::after { bottom: 100%; border-bottom-color: #333; }
        .row .table-badge { margin: 0 6px 0 0; flex: 0 0 auto; align-self: center; }
        .print-header { display: none; width: 100%; text-align: center; font-size: 24px; font-weight: bold; margin-bottom: 10px; border-bottom: 2px solid #000; padding-bottom: 5px; text-transform: uppercase; }
        .print-only-poules { display: none !important; }
        .full-name { display: inline; }
        .short-name { display: none; }
        .use-initiale .full-name { display: none; }
        .use-initiale .short-name { display: inline; }
        /* Noms du classement : inline-block calé à gauche, largeur égalisée en JS
           (= largeur du plus long) pour que tous démarrent au même endroit tout en
           étant centrés en bloc dans la cellule (td en text-align:center). */
        .rank-name { display: inline-block; text-align: left; max-width: 100%; }

        .seo-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
        .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }

        /* OPTIMISATION SMARTPHONE */
        @media (max-width: 600px) {
            body { overflow-y: auto; height: auto; min-height: 100vh; padding: 0; }
            .panel { overflow-y: visible; flex: none; border: none; padding: 5px 0; height: auto; }
            .poule-grid { gap: 10px; padding: 0; }
            .poule { flex: 0 1 100%; max-height: none; border-left: none; border-right: none; }
            .final-tree { overflow-x: auto; overflow-y: visible; }
            /* flex-shrink:0 : la tree-grid ne doit JAMAIS être comprimée par
               .final-tree (flex colonne) en dessous de la hauteur de son contenu,
               sinon les colonnes (space-around) compriment les match-box et la
               2e ligne joueur est coupée. La page défile verticalement à la place. */
            .tree-grid { min-width: 600px; min-height: 400px; flex-shrink: 0; }

            /* Cibles tactiles agrandies pour la saisie des scores en poule :
               on augmente la HAUTEUR (de la place disponible verticalement) sans
               toucher à la largeur, pour ne pas casser l'affichage de tous les sets. */
            .poule .row { min-height: 40px; }
            .poule .score-num { height: 34px; font-size: 14px; padding: 4px 0; }
            .poule .set-box { margin-right: 3px; }

            /* ============================================================
               NOUVELLE PRÉSENTATION MOBILE DES MATCHS DE POULE
               Les deux joueurs sont empilés (l'un sous l'autre) à gauche,
               et les scores de chaque joueur sont affichés en face, à
               droite, sur la ligne qui lui correspond.

               Cible « .match-list .row » : couvre TOUTES les poules
               (qualification, consolante, poule finale, départage), car
               tous ces matchs sont rendus dans un .match-list. Les tableaux
               à élimination (qui utilisent .match-box) ne sont pas touchés.

               Mise en page CSS uniquement (le HTML/JS est inchangé) : la
               saisie des scores, le glisser-déposer, l'impression et le
               classement continuent de fonctionner exactement comme avant,
               et l'affichage sur ordinateur n'est pas touché.
               ============================================================ */
            .match-list .row {
                display: grid;
                /* num | nom (ajusté au contenu) | drapeau | ressort | scores
                   La colonne « ressort » (1fr) pousse les scores tout à droite,
                   pendant que le drapeau de forfait reste collé au nom. */
                grid-template-columns: auto minmax(0, max-content) auto 1fr auto;
                grid-template-rows: auto auto;
                align-items: center;
                column-gap: 4px;
                row-gap: 4px;
                padding: 7px 8px;
                min-height: 0;
            }
            /* Numéro du match : colonne de gauche, centré sur les 2 lignes */
            .match-list .row .match-num {
                grid-column: 1;
                grid-row: 1 / span 2;
                align-self: center;
                margin-right: 0;
            }
            /* Joueur 1 en haut, joueur 2 juste en dessous */
            .match-list .row .player-name {
                grid-column: 2;
                grid-row: 1;
                text-align: left;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                min-width: 0;
                font-size: 15px;
            }
            .match-list .row .player-name.right {
                grid-row: 2;
                text-align: left;
            }
            /* Drapeaux de forfait : juste après le nom du joueur concerné */
            .match-list .row .player-name + .ff-flag,
            .match-list .row .player-name + .ff-chip {
                grid-column: 3;
                grid-row: 1;
                align-self: center;
                margin: 0;
            }
            .match-list .row .player-name.right + .ff-flag,
            .match-list .row .player-name.right + .ff-chip {
                grid-row: 2;
            }
            /* Le séparateur « vs / bat / perd » n'a plus de sens en vertical */
            .match-list .row .vs-sep { display: none; }

            /* Zone des scores : à droite, alignée en face des joueurs.
               Grille de 2 lignes (joueur 1 / joueur 2) × N colonnes
               (une colonne par set). */
            .match-list .row .sets {
                grid-column: 5;
                grid-row: 1 / span 2;
                display: grid;
                grid-auto-flow: column;
                grid-template-rows: auto auto;
                column-gap: 2px;
                row-gap: 3px;
                align-items: center;
                justify-items: center;
                margin-left: auto;
                padding: 0;
            }
            /* On « aplatit » chaque set pour répartir ses 2 cases sur les
               2 lignes : score du joueur 1 en haut, du joueur 2 en bas. */
            .match-list .row .sets-cells { display: contents; }
            /* Badge Forfait : centré sur les 2 lignes en présentation empilée. */
            .match-list .row .sets-cells.forfait-only { display: flex; grid-row: 1 / span 2; align-items: center; }
            .match-list .row .forfait-tag-after { grid-row: 1 / span 2; align-self: center; }
            .match-list .row .set-box { display: contents; }
            .match-list .row .set-box .score-num:first-child { grid-row: 1; }
            .match-list .row .set-box .score-num:nth-child(2) { grid-row: 2; }
            /* Cases de score : carrées, lisibles et faciles à toucher.
               (Les fonds vert/rose des sets gagnés/invalides restent gérés
               par les classes set-win-bg / set-invalid / set-empty.) */
            .match-list .row .score-num {
                width: 23px;
                height: 28px;
                font-size: 13px;
                padding: 0;
                margin: 0;
                border: 1px solid #999;
                border-radius: 3px;
            }
            /* Badge « table » et cadenas de validation : sur toute la hauteur */
            .match-list .row .sets .table-badge,
            .match-list .row .sets [id^="chk-val-"] {
                grid-row: 1 / span 2;
                align-self: center;
                margin: 0;
            }
            /* Pile de badges (arbitre + table) : on l'« aplatit » dans la grille
               (display:contents) pour que ses deux badges deviennent des items
               de la grille des scores et se répartissent sur les 2 lignes —
               arbitre sur la ligne du joueur 1, table sur celle du joueur 2.
               (Surcharge la règle table-badge ci-dessus, plus spécifique.) */
            .match-list .row .sets .match-action-stack { display: contents; }
            .match-list .row .sets .match-action-stack .arb-badge {
                grid-row: 1;
                align-self: center;
                margin: 0;
            }
            .match-list .row .sets .match-action-stack .table-badge {
                grid-row: 2;
                align-self: center;
                margin: 0;
            }

            /* Barre d'onglets : sur mobile on ne garde que l'onglet actif à
               côté du bouton imprimer ; on masque le nom du tournoi (et son
               séparateur) qui prenait la place et tronquait l'onglet. */
            .snav-tname,
            .snav-sep { display: none !important; }

            /* Classement : grand tableau (≈600px de large) → sur mobile on
               l'aligne à gauche et on autorise le défilement horizontal, pour
               voir d'abord les colonnes Place / Joueur au lieu de les rogner. */
            #classement-view { align-items: stretch; }
            .classement-cols-wrap {
                align-items: flex-start !important;
                width: 100%;
                overflow-x: auto;
                -webkit-overflow-scrolling: touch;
            }

            /* === FIXES CONSOLANTE MOBILE UNIQUEMENT === */
            
            /* Poule finale (12/13 joueurs) - espacée du tableau */
            #consolante-view .poule-finale-container {
                margin-top: 120px !important;
                min-width: 100% !important;
                width: 100% !important;
                order: 2 !important;
            }
            
            #consolante-view .tree-grid {
                order: 1 !important;
            }
            
            /* Inputs de score réduits pour voir tous les sets.
               Restreint aux TABLEAUX (.match-box) : les poules de consolante
               utilisent désormais la présentation empilée (.match-list .row)
               et n'ont plus besoin d'être rétrécies. */
            #consolante-view .match-box .sets input {
                width: 25px !important;
                font-size: 10px !important;
                padding: 0 !important;
            }
            
            #consolante-view .match-box .sets {
                gap: 1px !important;
                padding: 0 3px !important;
            }
            
            /* 2 poules + finale (6 joueurs) */
            #consolante-view .consolante-container {
                display: flex !important;
                flex-direction: column !important;
                min-height: auto !important;
            }
            
            /* Poules en colonne sur mobile */
            #consolante-view .poules-wrapper {
                flex-direction: column !important;
                align-items: center !important;
                gap: 10px !important;
            }
            
            #consolante-view .consolante-container > div:last-child {
                position: relative !important;
                left: auto !important;
                top: auto !important;
                transform: none !important;
                margin: 20px auto 0 auto !important;
                width: 100% !important;
                max-width: 300px !important;
            }

            /* ============================================================
               MATCHS DE TABLEAU (.match-box) — même présentation que les
               poules en mobile : nom + scores du joueur 1 sur la 1re ligne,
               nom + scores du joueur 2 sur la 2nde, label + badges en tête.
               Placement par ZONES NOMMÉES (aucune auto-placement) + sélecteurs
               de frères adjacents (robustes — contrairement à nth-of-type qui
               avait fait chevaucher les noms). Les .match-box-row restent de
               vraies boîtes : sélection / glisser-déposer du bracket préservés.
               ============================================================ */
            .match-box {
                display: grid;
                grid-template-columns: minmax(0, 1fr) auto;
                grid-template-rows: auto minmax(30px, auto) minmax(30px, auto); /* label / joueur 1 / joueur 2 : 30px mini pour les cases de score (28px), mais extensibles si le contenu est plus haut (badges, chips…) */
                grid-template-areas:
                    "label  badges"
                    "j1     scores"
                    "j2     scores";
                align-items: center;
                column-gap: 8px;
                row-gap: 2px;
                min-height: 0; /* annule min-height:80px → hauteur juste suffisante */
                flex-shrink: 0; /* item flex de .column : ne JAMAIS comprimer la box sous la hauteur de son contenu (sinon 2e ligne joueur coupée). space-around ne distribue que l'espace positif → alignement des tours inchangé. */
            }
            /* On expose label, badges et zone scores au niveau de la grille. */
            .match-box .match-box-header { display: contents; }
            .match-box .match-box-header > b { grid-area: label; align-self: center; }
            .match-box .match-box-header > .match-action-stack { grid-area: badges; justify-self: end; }
            .match-box .match-box-header > .sets {
                grid-area: scores;
                align-self: stretch;
                display: grid;
                grid-auto-flow: column;
                grid-template-rows: 1fr 1fr;
                column-gap: 2px;
                row-gap: 2px;
                align-items: center;
                justify-items: center;
                padding: 0;
                margin: 0;
            }
            /* Noms : joueur 1 (1re ligne) puis joueur 2 (2nde), colonne gauche.
               min-width:0 + overflow:hidden bornent le nom à la colonne de grille,
               sinon le .player-name s'étend à sa largeur naturelle (la box ne le
               contraint pas) → l'ellipsis ne se déclenche jamais et la bascule
               use-short (mesurée via scrollWidth>clientWidth) reste inactive. */
            .match-box .match-box-header + .match-box-row {
                grid-area: j1; border-bottom: none; padding: 0; min-width: 0; overflow: hidden;
            }
            .match-box .match-box-header + .match-box-row + .match-box-row {
                grid-area: j2; border-bottom: none; padding: 0; min-width: 0; overflow: hidden;
            }
            /* Le nom lui-même : largeur FIXE = celle de la row, tronqué avec « … ».
               min-width:0 ANNULE le min-width:fit-content de la règle de base
               (.player-name) qui, en contexte flex, força le span à la largeur de
               son texte (310px) malgré width:100% → débordement non tronqué. */
            .match-box .match-box-row .player-name {
                display: block; width: 100%; min-width: 0; box-sizing: border-box;
                white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
            }
            /* Scores empilés j1/j2 comme en poule. */
            .match-box .sets-cells { display: contents; }
            .match-box .set-box { display: contents; }
            .match-box .set-box .score-num:first-child { grid-row: 1; }
            .match-box .set-box .score-num:nth-child(2) { grid-row: 2; }
            .match-box .sets .score-num {
                width: 23px; height: 28px; font-size: 13px;
                padding: 0; margin: 0; border: 1px solid #999; border-radius: 3px;
            }
            /* Cadenas de validation et badge forfait : centrés sur les 2 lignes. */
            .match-box .sets [id^="chk-val-"] { grid-row: 1 / 3; align-self: center; }
            .match-box .sets-cells.forfait-only { display: flex; grid-row: 1 / 3; align-items: center; }
            .match-box .forfait-tag-after { grid-row: 1 / 3; align-self: center; }
        }

@media print {
    @page { 
        size: A4 landscape; 
        margin: 10mm; 
    }

    #classement-view th { background: var(--tt-surface) !important; color: var(--tt-ink) !important; border: 1px solid #888 !important; }
    #classement-view tr td { background: var(--tt-surface) !important; }
    body.print-a3 .poule-box tr td:nth-child(2) { font-size: 18px !important; }
    body.print-a3 #classement-view { zoom: 1.41; }

    /* Classement : portrait, pleine largeur */
    body.print-classement-active @page, #classement-view ~ * { }
    #classement-view {
        overflow: visible !important;
        width: 100% !important;
    }
    #classement-view > div {
        overflow: visible !important;
        width: 100% !important;
    }
    #classement-view table {
        width: auto !important;
        min-width: 500px;
        margin: 0 auto;
    }

    body.print-a3 .poule { zoom: 1.41; }
    body.print-a3 .validation-screen > div[style*='flex'] > div { zoom: 1.41; }
    .poule-top-spacer { display: none; }
    #poule-view .poule-top-spacer { display: block !important; height: 5mm; width: 100%; }
    body.print-a3 .poule-top-spacer { display: block !important; height: 4mm; width: 100%; background: white; }
    .poule-bottom-spacer { display: none; }
    #poule-view .poule-bottom-spacer { display: block !important; height: 2mm; width: 100%; }
    body.print-a3 .poule-grid { display: flex !important; flex-wrap: wrap !important; padding: 5mm 5mm 0 5mm !important; box-sizing: border-box !important; width: 100% !important; }
    body.print-a3 .match-box { zoom: 1.41; }
    .tree-grid { transform: scaleX(0.85); transform-origin: left top; }

    /* Saut de page avant la poule finale de consolante */
    .poule-finale-page {
        page-break-before: always !important;
        break-before: page !important;
        -webkit-break-before: page !important;
        display: block !important;
        width: 100% !important;
        margin-top: 0 !important;
        padding-top: 10mm !important;
    }
    
    /* Élargir la poule finale à l'impression */
    .poule-finale-page .poule {
        max-width: 95% !important;
        width: 95% !important;
        flex: 0 0 95% !important;
        margin: 0 auto !important;
    }
    
    .poule-finale-page table {
        width: 100% !important;
        table-layout: fixed !important;
    }
    
    /* Forcer la colonne Joueur à être très large */
    .poule-finale-page table th:nth-child(2),
    .poule-finale-page table td:nth-child(2) {
        width: 60% !important;
        min-width: 60% !important;
        max-width: none !important;
        white-space: normal !important;
        word-wrap: break-word !important;
    }
    
    .poule-finale-page table th:nth-child(1),
    .poule-finale-page table td:nth-child(1) {
        width: 8% !important;
    }
    
    .poule-finale-page table th:nth-child(3),
    .poule-finale-page table td:nth-child(3) {
        width: 8% !important;
    }

    .poule-finale-page table th:nth-child(4),
    .poule-finale-page table td:nth-child(4),
    .poule-finale-page table th:nth-child(5),
    .poule-finale-page table td:nth-child(5),
    .poule-finale-page table th:nth-child(6),
    .poule-finale-page table td:nth-child(6) {
        width: 10% !important;
    }




    
    html { transform: rotate(0deg); }
 
    
    body { 
        background: var(--tt-surface); 
        overflow: visible !important; 
        height: auto !important; 
        display: block !important; 
        box-sizing: border-box !important;
        -webkit-print-color-adjust: exact !important; 
        print-color-adjust: exact !important; 
    }


    /* Cache les éléments d'interface */
    .tabs, .sub-nav, .add-btn, .print-btn, .reset-all-btn, button, .tab span, input, .seo-hidden, .table-badge, .no-print { 
        display: none !important; 
    }

    .validation-screen { display: block !important; }
    .validation-screen h2,
    .validation-screen > div:first-of-type,
    .validation-screen button { display: none !important; }
    .validation-screen > div[style*='flex'] { display: flex !important; flex-wrap: wrap !important; gap: 8px !important; padding: 0 5mm !important; box-sizing: border-box !important; }

    .print-header { 
        display: block !important; 
        visibility: visible !important; 
        height: auto !important; 
        margin: 5mm 0 5px 0 !important; 
        font-size: 16px !important;   
    }

    .panel { border: none; display: block; padding: 0; background: var(--tt-surface) !important; overflow: visible !important; }
    .registration-list { overflow: visible !important; max-width: 100% !important; }
    
    .panel.registration-page, .panel.poules-page, .panel.final-page, .panel.consolante-page {
        background-image: none !important;
        background: var(--tt-surface) !important;
    }
    
    /* À l'impression, on NE force PLUS les initiales : on garde le prénom complet,
       et les initiales ne s'appliquent que si la ligne porte .use-initiale (nom trop
       long), exactement comme à l'écran. Les règles .use-initiale (hors @media) gèrent
       la bascule full-name → short-name. */

    #poule-view { 
        display: grid !important;
        grid-template-columns: 1fr 1fr !important;
        gap: 5px !important;
        overflow: visible !important;
        align-items: start !important;
        padding: 0 5mm 0 5mm !important;
        box-sizing: border-box !important;
        width: 100% !important;
    }
    #poule-view .print-header {
        grid-column: 1 / -1;
    }

    #final-view, #consolante-view, .final-tree, .dept-view { 
        display: flex !important; 
        flex-direction: column !important; 
        height: auto !important;
        flex: none !important;
        overflow: visible !important; 
        justify-content: flex-start !important; 
        border: none !important;
        padding: 0 5mm !important;
        box-sizing: border-box !important;
    }

    /* Cacher la consolante en impression si mode sans consolante */
    body.no-consolante #consolante-view {
        display: none !important;
    }

    body.print-a3 #final-view,
    body.print-a3 #consolante-view { padding-top: 5.2mm !important; }

    .tree-grid { display: flex !important; flex-direction: row !important; align-items: stretch !important; gap: 10px; width: 100%; min-height: 720px !important; }
    .match-box { transition: none !important; }
    .tree-grid.rendering { opacity: 0 !important; }
    .column { display: flex !important; flex-direction: column !important; justify-content: space-around !important; height: auto !important; flex: 1 !important; }
    .column.final-col { justify-content: center !important; gap: 5px !important; }

    .poule { 
        display: block !important;
        border: 1px solid #000; 
        break-inside: avoid;
        page-break-inside: avoid;
        -webkit-column-break-inside: avoid;
        height: auto !important;
        width: 100% !important;
        flex: none !important;
    }



    .row { 
        font-size: 10px !important; 
        min-height: 14px !important; 
        padding: 0px 5px !important; 
    }

    table { 
        font-size: 11px !important; 
        margin-bottom: 2px !important; 
        width: 100%;
        border-collapse: collapse;
    }

    th, td { padding: 0px 2px !important; border: 1px solid #000 !important; line-height: 1.2 !important; }
    #poule-view th, #poule-view td { font-size: 13px !important; padding: 0px 2px !important; line-height: 1.2 !important; }
    /* En-tête "Matchs" (plus long que "Pts") : réduit en impression pour tenir
       dans sa colonne sans déborder sur la colonne Pts. */
    #poule-view table[id^="ranking-"] th:nth-child(3) { font-size: 9px !important; }
    .match-box .sets input, .match-box .print-val { width: 18px !important; font-size: 11px !important; }

    /* Noms dans les matchs des poules : 12px */
    #poule-view .match-box .player-name { font-size: 12px !important; }
    
    /* Noms dans les matchs des tableaux : 15px */
    #final-view .match-box .player-name,
    #consolante-view .match-box .player-name { font-size: 15px !important; }
    #consolante-view .tree-grid { width: 100% !important; min-width: unset !important; max-width: 100% !important; }
    #consolante-view .column { min-width: unset !important; max-width: unset !important; flex: 1 !important; }
    #consolante-view .tree-grid.consolante-finale-2 { width: 100% !important; max-width: 100% !important; min-width: unset !important; display: flex !important; justify-content: center !important; }
    #consolante-view .tree-grid.consolante-finale-2 .match-box { width: 320px !important; min-width: 320px !important; max-width: 320px !important; box-sizing: border-box !important; }
    
    .match-box b { font-size: 9px !important; white-space: nowrap !important; color: #b94700 !important; font-weight: bold !important; }
    th { background-color: var(--tt-th) !important; -webkit-print-color-adjust: exact; }
    
    /* Gagnants à l'impression : vert foncé + souligné + gras - tableaux ET poules */
    #final-view .winner-style,
    #consolante-view .winner-style,
    #poule-view .winner-style {
        color: #1a6b3a !important;
        font-weight: 900 !important;
        text-decoration: underline !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    /* --- STYLE DES SCORES COMPACT SANS BORDURES --- */
    .match-box .sets {
        padding: 0 !important;
        gap: 0 !important;
    }
    
    .print-val { 
        display: inline !important; 
        width: auto !important; 
        text-align: left !important; 
        border: none !important; 
        margin: 0 4px 0 0 !important; 
        padding: 0 !important;
        height: auto !important; 
        vertical-align: middle; 
        font-size: 11px !important; 
        color: var(--tt-ink) !important;
        white-space: nowrap !important;
    }
    
    .set-box { 
        margin: 0 !important;
        padding: 0 !important;
        display: inline !important;
    }
    .score-num {
        display: none !important;
    }

    .set-win-bg { 
        background-color: #d4edda !important; 
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
        border: none !important;
    }

    .set-empty, .set-invalid {
        color: transparent !important; 
        background-color: transparent !important;
        border: none !important;
    }

    /* --- CONFIGURATION IMPRESSION VIERGE (isViergePrint) --- */
    
    /* Poules, classements, tableaux : noms et winner-style gérés par le JS (render avec isVierge) */

    /* Scores : on vide les SCORES partout (Poules + Finales) et on vire le fond vert */
    body.isViergePrint .set-win-bg,
    body.isViergePrint .print-val,
    body.isViergePrint .set-empty {
        background-color: transparent !important;
        background: transparent !important;
        color: transparent !important; /* Cache les chiffres des scores */
        border: none !important;
    }

    /* Impression vierge poules : cases de scores collées comme dans l'affichage principal */
    body.isViergePrint #poule-view .set-box {
        display: inline-flex !important;
        margin: 0 2px 0 0 !important;
        padding: 0 !important;
        vertical-align: middle !important;
    }
    body.isViergePrint #poule-view .score-num {
        display: inline-block !important;
        width: 20px !important;
        height: 20px !important;
        border: 1px solid #999 !important;
        background: var(--tt-surface) !important;
        margin: 0 !important;
        padding: 0 !important;
        font-size: 0 !important;
        color: transparent !important;
        vertical-align: middle !important;
        box-sizing: border-box !important;
        border-radius: 0 !important;
        opacity: 1 !important;
        cursor: default !important;
    }
    body.isViergePrint #poule-view .score-num:first-child {
        border-radius: 3px 0 0 3px !important;
        border-right: none !important;
    }
    body.isViergePrint #poule-view .score-num:nth-child(2) {
        border-radius: 0 3px 3px 0 !important;
        border-left: 1px solid #999 !important;
    }
    body.isViergePrint #poule-view .print-val {
        display: none !important;
    }
    body.isViergePrint #poule-view .set-win-bg .score-num,
    body.isViergePrint #poule-view .set-empty .score-num,
    body.isViergePrint #poule-view .set-invalid .score-num,
    body.isViergePrint #poule-view .score-num:disabled,
    body.isViergePrint #poule-view .score-num[disabled] {
        background: var(--tt-surface) !important;
        border-color: #999 !important;
        opacity: 1 !important;
    }

    body.isViergePrint #poule-view table th {
        color: var(--tt-ink) !important;
        visibility: visible !important;
    }
    body.isViergePrint #poule-view table .col-dyn,
    body.isViergePrint #poule-view table .th-sets,
    body.isViergePrint #poule-view table .th-points {
        /* colonnes conservées en mode vierge pour remplissage manuel */
        width: 55px !important;
        min-width: 55px !important;
        max-width: 55px !important;
        white-space: nowrap !important;
    }
    body.isViergePrint #poule-view table td:nth-child(2),
    body.isViergePrint #poule-view table th:nth-child(2) {
        width: auto !important;
        max-width: none !important;
    }
    body.isViergePrint #poule-view table tr td:nth-child(3),
    body.isViergePrint #poule-view table tr td:nth-child(4),
    body.isViergePrint #poule-view table tr td:nth-child(5),
    body.isViergePrint #poule-view table tr td.col-dyn {
        color: transparent !important;
        border: 1px solid #000 !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    .match-box { 
        margin: 3px 0 !important; 
        background: var(--tt-surface) !important; 
        border: 1px solid #000 !important; 
    }
}

@media (max-width: 700px){
    .home-screen{
        padding-top:20px;
    }
    .main-title{
        font-size:28px;
        margin-bottom:15px;
    }
    .home-msg{
        font-size:14px;
    }
}

.home-msg{
    font-size: 20px;
    color: #e6e6e6;
    text-align: center;
    background: transparent;
    padding: 0;
    border-radius: 0;
    margin-top:20px;

    filter:
        drop-shadow(0 8px 15px rgba(0,0,0,1))
        drop-shadow(0 25px 55px rgba(0,0,0,1))
        drop-shadow(0 50px 110px rgba(0,0,0,0.95));
}


.panel.home-mode{
    border: none;
    padding: 0;
}

@supports (height: 100dvh) {
    body {
        height: 100dvh;
    }
}

@media (max-width: 700px){

    .home-screen{
        justify-content: center !important;
        padding-top: 0 !important;
    }

    .main-title{
        margin-top: -120px !important;
    }
}






/* Cas spécifique : finale consolante avec seulement 2 joueurs */
.consolante-finale-2 {
    width: auto !important;
    max-width: 520px !important;
    min-width: 480px !important;
    min-height: auto !important;
    margin: 0 auto !important;
    justify-content: center !important;
}

.consolante-finale-2 .match-box {
    min-height: 40px !important;
    width: 100% !important;
    box-sizing: border-box !important;
}

.match-box:has([id*="_Q"]) {
    border: 2.5px solid #0b4f0b;
}
.match-box:has([id*="_H"]) {
    border: 2.5px solid #6b3e1e; /* marron */
}

/* Préliminaires (_R suivi d'un chiffre) */
.match-box:has([id*="_R"][id*="-"]) {
    border: 2.5px solid #3f3f3f;
}

/* 8èmes */
.match-box:has([id*="_H"][id*="-"]) {
    border: 2.5px solid #6b3e0b;
}

/* 12èmes */
.match-box:has([id*="_T"][id*="-"]) {
    border: 2.5px solid #4b2c6f;
}

/* Quarts */
.match-box:has([id*="_Q"][id*="-"]) {
    border: 2.5px solid #0b4f0b;
}

/* Demis */
.match-box:has([id*="_D"][id*="-"]) {
    border: 2.5px solid #0b3d6b;
}

/* Petite finale */
.match-box:has([id*="_P"][id*="-"]) {
    border: 2.5px solid #a35400;
}



/* Finale */
.match-box:has([id*="_F"][id*="-"]) {
    border: 2.5px solid #7a0b0b;
}



/* ===== Barre de progression du tournoi (cf. updateTournamentProgress) ===== */
.tt-progress {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 8px;
    background: var(--tt-dark-2);
    color: #ecf0f1;
    font-size: 11px;
    font-weight: bold;
    flex-shrink: 0;
    border-bottom: 1px solid var(--tt-dark);
}
.tt-progress-bar {
    flex: 1;
    height: 6px;
    background: rgba(0,0,0,0.35);
    border-radius: 3px;
    overflow: hidden;
    position: relative;
}
.tt-progress-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--tt-success), var(--tt-success-2));
    transition: width 0.3s ease;
    border-radius: 3px;
}
.tt-progress.complete .tt-progress-fill {
    background: linear-gradient(90deg, #f1c40f, var(--tt-warn));
}
.tt-progress-label {
    flex-shrink: 0;
    white-space: nowrap;
    min-width: 90px;
    text-align: right;
}
@media print {
    .tt-progress { display: none !important; }
}

/* ===== Diffusion en direct (live spectateurs) ===== */
.live-dot { display:inline-block; width:9px; height:9px; border-radius:50%; background:#e74c3c; margin-right:6px; vertical-align:middle; }
.live-dot.on { background:#27ae60; animation:livePulse 1.6s ease-in-out infinite; }
@keyframes livePulse { 0%,100%{ box-shadow:0 0 0 0 rgba(39,174,96,0.5);} 50%{ box-shadow:0 0 0 5px rgba(39,174,96,0);} }
/* Bandeau spectateur (mode lecture seule) : placé DANS le flux, en tout
   premier, pour qu'il ne recouvre ni la barre de progression ni les onglets. */
#live-spectator-banner {
    flex-shrink:0; order:-1;
    background:linear-gradient(90deg,#1a252f,#27632f); color:#fff;
    font-size:13px; font-weight:600; text-align:center; padding:7px 12px;
}
#live-spectator-banner .live-dot { background:#2ecc71; animation:livePulse 1.6s ease-in-out infinite; }
/* Compteur de spectateurs (👁 N) dans le bandeau spectateur */
.live-viewers {
    display:inline-block; padding:1px 8px; margin-left:4px;
    background:rgba(255,255,255,0.18); border-radius:11px;
    font-size:12px; font-weight:700; white-space:nowrap; vertical-align:middle;
}
/* Bandeau du mode arbitre */
#arb-banner {
    flex-shrink:0;
    background:linear-gradient(90deg,#1a252f,#2c3e50); color:#fff;
    font-size:14px; font-weight:600; text-align:center; padding:9px 12px;
}
#arb-banner .live-dot { background:#27ae60; animation:none; }
#arb-banner .live-dot.off { background:#f39c12; animation:livePulse 1.6s ease-in-out infinite; }
/* En mode arbitre, la page peut dépasser l'écran : on laisse le body grandir
   et on impose un fond clair jusqu'en bas (sinon le fond noir du html apparaît
   quand on scrolle au-delà de la hauteur d'écran). */
body.arbitre-mode { height:auto; min-height:100dvh; background:#f4f6f7; overflow-y:auto; }
html:has(body.arbitre-mode) { background:#f4f6f7; }
body.arbitre-mode #app { flex:1 0 auto; background:#f4f6f7; }
/* En mode spectateur : neutraliser toute interaction de saisie */
body.live-spectator input,
body.live-spectator .table-badge-free,
body.live-spectator .resize-handle,
body.live-spectator .registration-row[draggable="true"],
body.live-spectator .match-list .row[draggable="true"] { pointer-events:none !important; }
/* Renforcement : bloquer aussi les set-box cliquables (déverrouillage),
   les cases de score (saisie clavier après focus via Tab), et la
   sélection de joueurs pour swap. */
body.live-spectator .score-num,
body.live-spectator .set-box[onclick],
body.live-spectator [onclick*="selectPlayerForSwap"],
body.live-spectator [onclick*="toggleForfait"],
body.live-spectator [onclick*="askUnlockMatch"],
body.live-spectator [onclick*="validateMatch"] {
    pointer-events: none !important;
    cursor: default !important;
    user-select: none !important;
}
/* Bloquer aussi les events touch sur mobile (pointer-events ne suffit
   pas toujours selon les navigateurs). */
body.live-spectator .score-num {
    touch-action: none !important;
    -webkit-user-select: none !important;
}
body.live-spectator .row[draggable], body.live-spectator .match-box { cursor:default !important; }
/* Les onglets restent CLIQUABLES (navigation entre tableaux) ; on neutralise
   seulement leur glisser-déposer en bloquant le démarrage du drag. */
body.live-spectator .tab { cursor:pointer !important; }
/* Masquer toutes les commandes d'action (création, suppression, impression,
   export, attribution de table…). La barre de navigation .sub-btn reste
   cliquable pour que le spectateur change de vue ; seules les petites icônes
   d'impression qu'elle contient sont retirées.
   Le menu Outils reste accessible mais on n'y garde que « Plan des tables » et
   « Statistiques » (intéressants pour les spectateurs) — les autres rubriques
   sont masquées. */
body.live-spectator .add-btn,
body.live-spectator .registration-row button,
body.live-spectator .tab span,
body.live-spectator .print-btn,
body.live-spectator .tour-print-bar,
body.live-spectator .table-badge-free,
body.live-spectator .sub-btn .tooltip-right,
body.live-spectator [onclick*="showPrintModal"],
body.live-spectator [onclick*="exportPlayersToExcel"],
body.live-spectator [onclick*="printAllPouleMatchSheets"],
body.live-spectator [onclick*="printTourMatchSheets"],
body.live-spectator [onclick*="printPouleMatchSheets"],
body.live-spectator [onclick*="showLiveModal"],
body.live-spectator [onclick*="showArbitresModal"],
body.live-spectator [onclick*="showPaiementModal"],
body.live-spectator [onclick*="exportChoix"],
body.live-spectator [onclick*="importTournoi"],
body.live-spectator [onclick*="resetEverything"],
body.live-spectator [onclick*="showAboutModal"],
body.live-spectator .plan-edit-controls,
body.live-spectator [id^="chk-val-"],
body.live-spectator .ff-flag:not(.active) { display:none !important; }
/* Le drapeau ACTIF (vrai forfait) reste visible — info utile — mais non cliquable. */
body.live-spectator .ff-flag.active { pointer-events:none !important; }
/* Les badges de table ASSIGNÉE restent visibles en mode spectateur (info utile),
   mais non cliquables. */
body.live-spectator .table-badge-assigned { display:inline-flex !important; pointer-events:none !important; cursor:default !important; }

/* ============================================================
   MODE ARBITRE — MATCH EN PLEIN ÉCRAN (#arb-fullscreen-overlay)
   Tout est agrandi pour une saisie confortable : noms en gros,
   grosses cases de score tactiles. La carte de la LISTE n'est
   pas touchée (ces règles ne ciblent que l'overlay).
   ============================================================ */
#arb-fullscreen-overlay .arb-match { cursor: default !important; }
#arb-fullscreen-overlay .arb-match .player-name {
    font-size: 24px !important;
    font-weight: bold;
    line-height: 1.25;
}
#arb-fullscreen-overlay .arb-match .score-num,
#arb-fullscreen-overlay .arb-match .sets input.score-num {
    width: 48px !important;
    height: 58px !important;
    font-size: 28px !important;
    border-radius: 6px !important;
}
#arb-fullscreen-overlay .arb-match .sets {
    column-gap: 6px !important;
    row-gap: 6px !important;
}
/* Cadenas, badge WO et chips sanction : agrandis aussi */
#arb-fullscreen-overlay .arb-match [id^="chk-val-"] { font-size: 30px !important; }
#arb-fullscreen-overlay .arb-match .forfait-tag { font-size: 18px !important; padding: 6px 12px !important; }
#arb-fullscreen-overlay .arb-match .ff-chip { transform: scale(1.5); transform-origin: left center; margin: 0 8px; }
/* Libellé du match (tableau · stade) */
#arb-fullscreen-overlay .arb-match > div:first-child span:first-child { font-size: 14px !important; }

@media (max-width: 600px) {
    /* En mobile, la zone de scores quitte la colonne de droite (trop étroite
       pour des cases de 48px) et passe en PLEINE LARGEUR sous les deux noms,
       centrée. Les deux lignes de cases restent ligne 1 = joueur du haut,
       ligne 2 = joueur du bas. La grille de la carte liste (.match-list .row)
       n'est pas modifiée : on ne surcharge que dans l'overlay. */
    #arb-fullscreen-overlay .match-list .row {
        grid-template-columns: auto minmax(0, 1fr) auto 0 auto;
        grid-template-rows: auto auto auto;
        row-gap: 10px;
    }
    #arb-fullscreen-overlay .match-list .row .sets {
        grid-column: 1 / -1 !important;
        grid-row: 3 !important;
        justify-content: center;
        justify-items: center;
        margin: 8px auto 0 !important;
    }
    #arb-fullscreen-overlay .match-list .row .player-name { white-space: normal !important; }
}
