﻿/* ═══ Confort de lecture ═══════════════════════════════════════════════════════════════════════
   Le texte courant vit entre 11 et 12 px — 49 % des 1080 tailles déclarées sont sous 12 px. C'est
   trop petit, et la police de base n'a aucune prise dessus : TOUT est en px absolus (92 déclarations
   seulement en rem).

   🔑 D'où un ZOOM plutôt qu'une passe sur les tailles : il agrandit le texte ET les boîtes dans le
   même rapport. Remonter les seules polices dans des conteneurs dont la hauteur est figée en px
   produirait du texte coupé — ce projet l'a déjà payé assez souvent pour ne pas recommencer à
   534 endroits.

   Déclaré avec les autres tokens, dans l'unique bloc :root. */
:root {
    --ui-zoom: 1.08;

    color-scheme: dark;

    /* Surfaces (du plus profond au plus élevé) — palette « broadcast » de la maquette Claude Design,
       désaturée par le thème 28 : la teinte ne vit plus que dans l'accent. */
    --bg-page:          #0b080c;
    /* Le fond de page du lot 29d est un DÉGRADÉ RADIAL, pas un aplat. --bg-page reste la couleur
       plate : une trentaine de règles s'en servent comme surface, et `color-mix(… var(--bg-page) …)`
       n'accepte pas un dégradé. Le radial vit dans son propre token, posé sur le body. */
    --bg-page-grad:     radial-gradient(120% 90% at 50% -10%, #2a1d2c 0%, #150e16 45%, #0b080c 100%);
    --bg-surface:       #140e14;
    --bg-input:         #1c151f;
    --bg-inset:         #070509;
    --bg-panel:         #140e14;
    --bg-elevated:      #1c151f;
    --surface-2:        #1c151f;
    --bg-hover:         #271e2b;
    --bg-chip:          #3a2d40;

    /* Lignes & bordures */
    --line-soft:        #1d151f;
    --line-strong:      #33283a;
    --border:           #2b2130;
    --border-input:     #443548;
    --border-hover:     #443548;

    /* Canal des voiles (hover, séparateurs) : clair sur fond sombre, sombre sur fond clair */
    --overlay-rgb:      255,255,255;
    --bg-surface-hover: rgba(var(--overlay-rgb),0.06);
    --bg-muted:         rgba(var(--overlay-rgb),0.08);
    --shadow-strong:    rgba(0,0,0,0.5);
    --scrim:            rgba(0,0,0,0.5);

    /* Landing hero (Home) : artwork dédié par thème (déclinaisons sombre/claire du même
       visuel) + dégradés par zone (nav/centre/CTA). */
    /* Aucun artwork pour l'instant — et la raison n'est PAS celle qu'une version de ce commentaire
       a donnée. ⚠️ La maquette « rouge dominant » porte bel et bien un emplacement d'image dans son
       hero : `<image-slot id="bh-hero-a" placeholder="Visuel Warzone">`, surmonté d'un voile
       latéral. Il est simplement VIDE dans l'export, ce qui se lit à tort comme « pas de photo ».
       Ce qu'on a retiré, c'est `home-hero.jpg` : un visuel de MARQUE, bleu, posé sur le `body` —
       donc sur tous les écrans — qui reteintait l'application entière en bleu quelle que soit la
       valeur des jetons de surface. La maquette, elle, demande un visuel de JEU, que le produit
       n'a pas encore.
       Le fichier reste dans wwwroot. Le jour où un visuel Warzone existe, remettre son url ici le
       rétablit partout — et il faudra alors RENDRE le voile latéral au hero (cf. .bh-hero-overlay,
       et le cas de BrandRedCssTests qui ne l'interdit que tant que ce jeton vaut `none`). */
    --hero-img:         none;
    --hero-img-filter:  none;
    --hero-ink:         #ffffff;
    --hero-ink-soft:    #d8ccd2;
    /* Fond de marque GLOBAL (login + zone de contenu des pages connectées, via body::before) :
       même artwork que le hero, mais voilé pour rester une ambiance derrière le contenu.
       Ellipse centrale = fond le logo géant de l'artwork (leçon de la PR #516 revertée). */
    --app-backdrop-overlay: radial-gradient(26% 30% at 50% 45%, rgba(11,8,12,0.8) 30%, rgba(11,8,12,0.45) 62%, rgba(11,8,12,0) 100%), linear-gradient(rgba(11,8,12,0.1), rgba(11,8,12,0.1));

    /* Texte */
    --text-primary:     #faf3f6;
    --text-secondary:   #d4cdd1;
    /* Encres discrètes — thème 29d (bleu profond).
       Pire surface PORTANT DU TEXTE : #203255, le haut du dégradé radial de page. La valeur de la
       maquette (#6a90d2) n'y mesure que 4,15:1, sous le seuil AA. #789cda est le MINIMUM de la
       rampe qui tient 4,5:1 (4,59) — un token « discret » doit rester le plus discret que
       l'accessibilité autorise, pas plus. Écart au corps de texte : 1,83:1.
       ⚠️ #334d85 (chips) et #395898 (bordures) ne sont PAS des surfaces de texte : les inclure
       dans la mesure ferait remonter toute la rampe pour rien.
       --text-ghost reste volontairement sous le seuil : états inactifs et décor, hors WCAG 1.4.3. */
    --text-muted:       #8f888c;
    --text-hint:        #8f888c;
    --text-bright:      #faf3f6;
    --text-body:        #d4cdd1;
    --text-soft:        #b0a8ad;
    --text-dim:         #8f888c;
    --text-faint:       #8f888c;
    --text-ghost:       #574a5c;

    /* ── Encre de NAVIGATION ─────────────────────────────────────────────────────────────
       Liens de barre, entrées de nav, onglets et boutons de segment au repos. Ils portaient
       la teinte discrète du texte secondaire : sur un fond bleu profond, une nav bleu pâle se
       lisait comme du commentaire alors qu'elle est la charpente de l'écran.
       ⚠️ C'est le BLANC pur, et non le blanc cassé du texte principal : ces deux encres se
       croisent (plusieurs survols visaient le texte principal), il faut donc pouvoir les
       distinguer. La liste des familles concernées est en tête du bloc de la top-nav. */
    --nav-ink:          #ffffff;

    /* ── Rouge de MARQUE ─────────────────────────────────────────────────────────────────
       La maquette « rouge dominant » (écran 1a) porte son identité par le ROUGE : halo du hero,
       pastilles « en direct », numéros de section, lisérés de carte. C'est un canal DECORATIF,
       d'ambiance, à ne pas confondre avec le rouge de DANGER (le jeton de danger, plus bas), qui
       porte une information et reste plus vif et plus rose.
       ⚠ L'accent d'ACTION reste le BLEU du logo : boutons, rails d'onglet, focus. C'est l'écart
       assumé avec la maquette, tranché le 2026-09-17 — « 1a mais avec des boutons bleus ».
       Les trois arrêts rouges sont ceux de la maquette. */
    --brand-red:        #d62c48;
    --brand-red-light:  #f4576f;
    --brand-red-deep:   #ad1936;
    --brand-red-rgb:    214,44,72;

    /* ── Accent : le bleu du LOGO, rien d'autre ──────────────────────────────────────────
       Les trois arrêts sont ceux des accolades du wordmark. Le dégradé n'apparaît que là où le
       logo l'emploie — sur une forme PLEINE. Jamais sur du texte, jamais sur une bordure. */
    --accent-top:       #00b3ff;
    --accent:           #0a7cff;   /* aplats : rail d'onglet actif, liseré de sélection, focus */
    --accent-bottom:    #0a52ff;
    --accent-light:     #75b8ff;   /* TOUT texte accentué : liens, valeurs mises en avant */
    --accent-hover:     #0a52ff;
    --accent-rgb:       10,124,255;
    /* Canaux des halos du hero (lot 29d) : le voile doit s'éteindre vers le FOND DE PAGE, pas vers
       `transparent` — qui vaut rgba(0,0,0,0) et fait franger de gris à l'interpolation. */
    --accent-top-rgb:   0,179,255;
    --accent-bottom-rgb: 10,82,255;
    --accent-warm-rgb:  249,160,63;
    --bg-page-rgb:      11,8,12;

    /* Halos du hero — lot 29d : cyan à gauche, AMBRE à droite, voile bleu qui retombe sur la page.
       C'est le seul endroit où la contre-couleur chaude est décorative ; ailleurs elle porte une
       information (onglet actif, rang 1, progression, Match Point). */
    --hero-halo:
        radial-gradient(40% 48% at 28% 58%, rgba(var(--brand-red-rgb),.42), rgba(var(--brand-red-rgb),0) 70%),
        radial-gradient(34% 42% at 74% 34%, rgba(var(--accent-rgb),.38), rgba(var(--accent-rgb),0) 72%),
        linear-gradient(180deg, rgba(var(--accent-bottom-rgb),.12), rgba(var(--bg-page-rgb),0) 70%);

    /* ── Lavis de marque du FOND DE PAGE ────────────────────────────────────────
       La lumière du hero, continuée sur TOUTE l'application : le rouge à gauche, le bleu à droite,
       aux mêmes places que les deux voiles de `.bh-hero-bg`. Sans eux l'identité s'arrêtait net sous
       le hero, et tout le reste de la page retombait sur un violet neutre.

       🔴 Ce sont des teintes de NUIT, et ce n'est pas une timidité de goût. Le lavis se compose
       en `normal` PAR-DESSUS le fond de page : là où il est plein, c'est LUI qui fixe la luminance.
       Chacune des deux est donc bornée à celle de l'arrêt le plus CLAIR de --bg-page-grad (#2a1d2c,
       0,0155) — le point le plus lumineux que la page atteint déjà. Le lavis ne peut ainsi JAMAIS
       éclaircir la page : il échange de la lumière neutre contre de la lumière de marque, à luminance
       constante. Mesuré : la mention discrète y tient 3,57:1 (rouge) et 3,53:1 (bleu) sous la fumée,
       contre 3,42:1 sur le violet qu'ils remplacent — le fond devient donc un peu PLUS lisible.
       ⚠️ Monter l'une des deux vers le rouge ou le bleu VIFS de la marque (#d62c48, #0a7cff)
       multiplierait sa luminance par six et ferait tomber ce même texte à 2,5:1. Le hero se le permet
       parce que son encre est un blanc pur à ombre portée ; une page de contenu, non.
       PageBrandWashTests borne les deux côtés : assez sombre pour ne rien éclaircir, assez coloré
       pour se voir. */
    --brand-red-night:     #420e16;
    --brand-red-night-rgb: 66,14,22;
    --accent-night:        #032042;
    --accent-night-rgb:    3,32,66;
    /* Chaque lavis s'éteint vers SA PROPRE couleur en alpha 0 : vers `transparent`
       (= rgba(0,0,0,0)) l'interpolation frangerait de gris, comme pour les voiles du hero. */
    --bg-page-brand:
        radial-gradient(78% 68% at 14% 66%, rgba(var(--brand-red-night-rgb),.95), rgba(var(--brand-red-night-rgb),0) 72%),
        radial-gradient(68% 60% at 88% 20%, rgba(var(--accent-night-rgb),.92), rgba(var(--accent-night-rgb),0) 74%);

    /* Filet de séparation des sections : ROUGE à gauche, BLEU à droite, bordure neutre au milieu.
       Les deux couleurs de marque se lisent ainsi à chaque rupture de section, et plus seulement
       dans le hero — pour un coût de contraste NUL, un filet d'un pixel ne portant aucun texte. */
    --brand-rule:   linear-gradient(90deg, var(--brand-red), var(--border) 38%, var(--border) 62%, var(--accent));
    --brand-rule-v: linear-gradient(180deg, var(--brand-red), var(--border) 38%, var(--border) 62%, var(--accent));
    /* ── Nappe de FUMÉE ──────────────────────────────────────────────────────────────────
       Un bruit fractal SVG, blanc sur transparent. La matrice de couleur ne garde du bruit que
       sa LUMINANCE, poussée en opacité (1,7×) puis seuillée (−0,66) : sans ce seuil on obtient
       un grain de pellicule uniforme, pas des volutes — c'est le seuil qui creuse les vides
       entre les traînées.
       La fréquence est BASSE (0,014) et les octaves nombreuses : une fréquence haute donne du
       bruit de télévision. Le motif est rendu UNE fois en image par le navigateur, puis
       simplement déplacé — voir le hero plus bas.
       Déclaré ici pour pouvoir servir ailleurs : le poser sur le fond de page donnerait la même
       ambiance à toute l'application. */
    --smoke-img:        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='f' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014' numOctaves='4' seed='11'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1.7 0 0 0 -0.66'/%3E%3C/filter%3E%3Crect width='600' height='600' filter='url(%23f)'/%3E%3C/svg%3E");

    --accent-subtle:    rgba(var(--accent-rgb),0.14);

    /* Dégradé d'IDENTITÉ, celui du logo : formes pleines SANS texte (rails, jauges). */
    --accent-grad:      linear-gradient(180deg, var(--accent-top), var(--accent-bottom));

    /* 🔴 Dégradé des surfaces qui PORTENT UN LIBELLÉ, resserré à dessein.
       Mesuré : sur le dégradé d'identité, le blanc ne tient que 3,08:1 à 4,44:1 dans la zone du
       texte (30-70 % de la hauteur) — il n'atteint jamais 4,5. Le « 6,3:1 » annoncé par la
       maquette 29 ne vaut que pour le bord INFÉRIEUR, où aucun texte ne se pose. Aucune couleur
       de texte ne franchit une plage de luminance aussi large : ni le blanc, ni le noir (3,45:1
       sur le bas). D'où ce dégradé resserré — 4,68:1 pour le blanc au pire point de la zone. */
    --accent-deep:      #0a45e0;
    --accent-gradient:  linear-gradient(180deg, var(--accent), var(--accent-deep));

    /* Une seule chose chaude par écran : progression vers un seuil, survol de ligne, leader. */
    --accent-warm:      #f9a03f;
    --on-accent:        #ffffff;  /* le dégradé resserré impose le blanc */
    --on-bright:        #0d0e12;  /* texte posé sur un aplat vif (or, vert) : sombre dans les 2 thèmes */

    --avatar-bg:        linear-gradient(135deg, var(--accent), var(--accent-top));
    --avatar-color:     #fff;
    --avatar-flat:      #0a7cff;

    /* Textes de statut — teintes maquette. */
    --gold-fg:          #f3c256;
    /* Bronze de la 3e place (maquette 7a).
       (Ne pas écrire « --token » suivi de deux-points dans un commentaire de ce bloc : ThemeCssTests
       lit les déclarations à la regex et y verrait un token déclaré deux fois.) */
    --bronze-fg:        #c98d5a;
    --lime-fg:          #37d99a;
    --lime2-fg:         #37d99a;
    --green-fg:         #37d99a;
    --red-fg:           #ff425c;
    --red2-fg:          #ff425c;
    --red-soft-fg:      #ff8a95;
    --indigo-fg:        #a5b4fc;
    --sky-fg:           #3fb6ff;
    --beige-fg:         #bcd3fa;
    --color-danger:     #ff425c;

    /* Aplats de statut (badges, encarts) */
    --tint-lime-bg:     #15210f;
    --tint-blue-bg:     #151d2e;
    --tint-red-bg:      #2a1219;
    --tint-red-bg-2:    #1d0a0f;
    --tint-gold-bg:     #1b1408;
    --tint-gold-bg-2:   #33280a;
    /* Doré LISIBLE sur l'aplat doré foncé — le doré habituel, 6,67:1.
       (Ne pas écrire un nom de token suivi de deux-points dans un commentaire de ce bloc :
       ThemeCssTests lit les déclarations à la regex et y verrait un token déclaré deux fois.) */
    --gold-on-tint:     #f3c256;
    --tint-orange-bg:   #261a10;
    /* Orange de marquage, distinct du doré : les deux repères d'équipe du tirage se lisaient pareil
       tant qu'ils partageaient la teinte dorée (cf .bhtl-team--strong / --strongest). */
    --orange-fg:        #f9a03f;
    --tint-orange-border: #8a4f12;
    --tint-green-bg:    #0d1f13;
    --tint-green-border:#166534;
    --tint-red-border:  #7f1d1d;
    --tint-gold-border: #7c5310;
    /* Teintes de rôle de la console des comptes (Bogue #997). Le doré reste au SuperAdmin ;
       les autres rôles prennent leur propre teinte.
       ⚠️ Deux valeurs ne pouvaient PAS être reprises telles quelles en clair : --orange-fg n'y
       mesure que 4,41:1 sur son aplat et --sky-fg 3,47:1, tous deux sous le seuil AA de 4,5 —
       même piège que --gold-on-tint. D'où --orange-on-tint, assombri en clair, et l'indigo
       (5,33:1) plutôt que le ciel pour l'organisateur. Verrouillé par ThemeCssTests. */
    --orange-on-tint:   #f9a03f;
    --tint-blue-border: #2d4570;

    /* Bleu Discord lisible : la teinte de marque #5865F2 ne donne que 3,8:1 sur nos fonds (mesuré),
       sous le seuil AA de 4,5:1. On l'éclaircit sur sombre et on l'assombrit sur clair pour le TEXTE.
       L'icône et le liseré gardent la teinte de marque exacte : décoratifs, 3:1 leur suffit. */
    --discord-link:     #8cc6ff;

    /* Largeur utile maximale d'un écran de lecture. Au-delà, une grande résolution n'ajoute pas
       d'information : elle étire les cartes, écarte les colonnes d'un tableau jusqu'à ce que l'œil
       ne fasse plus le lien entre une ligne et son statut, et éloigne le contenu du regard.
       Les écrans de la refonte la portaient déjà, chacun avec son propre 1180px en dur — la valeur
       vit désormais ICI seulement, comme --shell-pad.
       Invariante par thème : déclarée dans ce bloc uniquement, donc hors du champ de ThemeCssTests
       (qui ne compare que les deux blocs clairs entre eux), comme les polices ci-dessous. */
    --page-max:         1180px;

    /* Colonne propre à la CONSOLE D'ADMINISTRATION, plus étroite que celle des écrans publics.
       Ses écrans ne sont pas de la lecture mais du pilotage : listes filtrées, tableaux de six à
       sept colonnes, tiroirs. Étalés sur 1180px, l'identité d'une ligne et son statut finissent
       trop loin l'un de l'autre pour que l'œil fasse le lien — c'est le même défaut qui avait fait
       borner la console (elle n'a plus de sidebar pour la cadrer), en moins visible.
       1040px = le point de bascule mobile de la console, plus bas dans ce fichier : au-delà de cette
       largeur la console est « au bureau », en deçà sa sous-nav se replie en menu. Une seule largeur
       de référence pour les deux, plutôt qu'un nombre de plus.
       ⚠️ Toute règle de la console qui pose un PLANCHER (min-width d'un tableau) doit rester sous
       la piste que cette colonne lui laisse, sinon le tableau défile dès le bureau — cf.
       .bhadm-org-table. Invariante par thème, déclarée ICI seulement (comme --page-max). */
    --console-max:      1040px;

    /* Bande pleine largeur à CONTENU borné : le fond et la bordure traversent la fenêtre, le
       contenu ne dépasse pas --page-max. Sert aux écrans plein cadre, où poser un max-width sur la
       bande elle-même laisserait le fond de page apparaître de chaque côté.
       Le 100% se résout sur l'élément qui applique la variable (substitution textuelle), et le
       max() garantit le padding normal tant que la fenêtre est plus étroite que la colonne.
       Invariante par thème, déclarée ICI seulement (comme --page-max, cf. ThemeCssTests). */
    --band-pad-inline:  max(16px, calc((100% - var(--page-max)) / 2));

    /* Hauteur des TROIS barres de navigation : le shell en session (.appnav), l'accueil public
       (.bh-topbar) et la console d'administration (.bhcon-head). C'est la même marque au même
       endroit de l'écran, elle ne doit pas sauter d'un contexte à l'autre. Six règles en dépendent :
       les trois barres, les deux menus mobiles qui se posent juste dessous, et la hauteur du cockpit
       de tirage. Elle était recopiée en dur partout, et trois valeurs avaient DÉJÀ divergé :
       .pp-screen retranchait 56px d'une barre qui en mesurait 60, l'accueil public en faisait 64 et
       la console aussi. Comme --shell-pad et --page-max, elle ne vit qu'ICI.
       80px = logo de 64px + 8px de respiration de part et d'autre.
       Invariante par thème, déclarée ICI seulement (cf. ThemeCssTests). */
    --appnav-h:         80px;

    /* ── Rayon des angles ────────────────────────────────────────────────────────────────
       3px : la valeur de la maquette « rouge dominant », qui arrondit ses cartes, ses boutons,
       ses champs et ses pastilles au même rayon. L'application en portait DIX valeurs, de 2 à
       20px, recopiées dans près de 600 déclarations — un rayon d'angle n'est pas une décision
       par règle. Comme la largeur de page et la hauteur de barre, il ne vit plus qu'ICI.
       ⚠️ Ne couvre PAS les FORMES : un disque (50%) et une barre de progression (999px) sont
       des géométries, pas des angles adoucis. Deux règles gardent donc 999px à dessein — la
       pastille ronde de « Comment ça marche » et la jauge d'économie d'un forfait.
       Invariante par thème, déclarée ICI seulement (cf. ThemeCssTests). */
    --radius:           3px;

    /* Rayon d'un enfant qui touche l'intérieur d'un parent BORDÉ : le parent porte 1px de bordure,
       l'enfant s'inscrit donc dans une courbe réduite d'autant. Sans ça, un fond carré dépasse la
       courbe et laisse un liseré visible sur fond sombre.
       🔴 C'est la SEULE raison d'être de ce second jeton : il ne sert qu'aux en-têtes et aux
       dernières lignes des panneaux qui ne rognent pas leurs enfants (ceux-là ne peuvent pas poser
       `overflow: hidden`, qui découperait la fiche joueur au survol — cf. TeamRosterHoverCardClipTests).
       Les deux valeurs restent liées : changer le rayon suffit, l'intérieur suit. */
    --radius-inner:     calc(var(--radius) - 1px);

    /* Polices de la refonte « broadcast e-sport » de l'accueil public (Home.razor). */
    --font-display:     'Barlow Condensed', 'Space Grotesk', system-ui, sans-serif;
    --font-alt:         'Archivo', 'Inter', system-ui, sans-serif;
    --font-mono:        'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

    /* Plaque des emblèmes clairs (argent, platine) : les PNG de rang sont dessinés pour un
       fond sombre et s'y délaveraient sans elle. */
    --emblem-plaque:    #0f0a10;
}

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

[tabindex="-1"] { outline: none; }

html, body {
    height: 100%;
    overflow: hidden;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 16px;
    line-height: 1.5;
    color: var(--text-primary);
}

/* ─── Police des contrôles de formulaire ────────────────────
   Un <button>, <input>, <select> ou <textarea> n'hérite NI de la police NI de la taille de
   son parent : le navigateur leur impose sa propre police système (Arial 13,3 px sous Windows).
   Sans cette règle, TOUT le chrome de l'app s'affichait en Arial à côté d'un texte en Inter —
   onglets, boutons de la barre de navigation, champs de recherche, boutons d'action. Mesuré au
   style calculé le 2026-08-08 : .cal-nav-btn, .cal-view-btn, .tour-tab, .btn-save, .btn-ghost,
   .input-sm… tous en Arial. Six règles isolées déclaraient déjà `font-family: inherit` une par
   une (dont .bhmp-camp, corrigé sur la seule page de match par la PR #929) : la dette se payait
   au coup par coup, écran par écran, à chaque nouveau composant oublié.

   `font: inherit` plutôt que le seul `font-family` : la TAILLE est logée à la même enseigne
   (13,3 px imposés au lieu des 16 px du body), et un demi-héritage laisserait exactement le
   même piège pour la moitié restante.

   Placée ici, dans la couche de base : les règles de composant qui suivent portent une classe
   (spécificité 0,1,0) et gagnent donc toujours sur ce sélecteur de type (0,0,1) — leurs
   font-size / font-weight / line-height propres restent intacts. Idem pour la règle `textarea`
   plus bas, de même spécificité mais postérieure.

   `line-height` est explicitement ramené à `normal` : la valeur du body (1,5) grandirait la
   boîte de tous les boutons à hauteur automatique de ~4 px, sans rapport avec le défaut corrigé.
   C'est le choix de normalize.css, pour la même raison. */
button, input, select, textarea, optgroup {
    font: inherit;
    line-height: normal;
}

/* ─── Fond de marque global ─────────────────────────────────
   L'artwork du hero (par thème, --hero-img) sous le voile --app-backdrop-overlay
   (ellipse centrale en sombre pour fondre le logo géant ; voile uniforme en clair),
   peint comme fond du BODY lui-même. PAS de body::before en z-index:-1 : l'ordre de
   peinture CSS dessine un pseudo négatif SOUS le fond propre de body — il serait
   recouvert et invisible (piège rencontré). Visible UNIQUEMENT sur les pages d'auth
   (.auth-wrapper transparent) : les pages connectées (.app-shell) et les pages
   publiques hors accueil (.public-page-content) sont opaques par choix produit,
   et la landing (Home) pose son propre hero opaque au-dessus. */
/* 🔴 Le fond de l'application vit sur `html`, et `body` est TRANSPARENT — ce n'est pas un détail
   de style mais la CONDITION pour que les nappes de fumée ci-dessous se voient.
   L'ordre de peinture CSS dessine un pseudo en `z-index: -1` AVANT le fond des blocs en flux :
   tant que `body` peignait son propre fond, il recouvrait ses propres pseudos. Piège déjà
   rencontré et consigné plus haut, reproduit ici pour en avoir le cœur net — un aplat rouge à
   60 % posé dessous reste totalement invisible. Le fond remonté d'un cran, le pseudo passe
   au-dessus de lui et sous le contenu.
   ⚠️ Cela ne suffit pas : il faut AUSSI que les conteneurs d'écran restent transparents, sinon
   ce sont eux qui recouvrent la fumée — voir la liste plus bas. */
/* 🔑 Le lavis de marque se glisse JUSTE AU-DESSUS du dégradé de page, et sous l'artwork et son
   voile : il reçoit donc exactement le même assombrissement qu'eux. Posé par-dessus
   --app-backdrop-overlay il échapperait au voile plat de 10 % et la page finirait plus claire
   qu'avant, ce que la borne de luminance ci-dessus a précisément pour objet d'interdire. */
html {
    background:
        var(--app-backdrop-overlay),
        var(--hero-img) center / cover no-repeat fixed,
        var(--bg-page-brand) fixed,
        var(--bg-page-grad) fixed,
        var(--bg-page);
}
body { background: transparent; }

/* ── La fumée, sur TOUTE l'application ───────────────────────────────────────────────────
   Même nappe que celle du hero, mêmes règles : deux calques, durées premières entre elles,
   mouvement par `transform` seulement, `screen` pour ne jamais assombrir.
   Elles sont `fixed` : le défilement vit dans les conteneurs d'écran, jamais dans la page, donc
   la fumée reste POSÉE pendant qu'on fait défiler — c'est une atmosphère, pas un décor qui suit
   le texte.
   Opacité bien plus basse que dans le hero, et durées plus lentes : ici la nappe passe derrière
   des tableaux et des colonnes de chiffres, où un mouvement perceptible fatiguerait la lecture. */
body::before, body::after {
    content: "";
    position: fixed;
    inset: -30%;
    z-index: -1;
    background: var(--smoke-img) center / cover no-repeat;
    mix-blend-mode: screen;
    pointer-events: none;
}
/* 🔴 La SOMME de ces deux opacités est bornée, et ce n'est pas une question de goût.
   La nappe est blanche et se compose en `screen` : elle ÉCLAIRCIT le fond de page, donc elle
   rapproche le texte posé dessus de son fond. Au pic du bruit, la somme 0,17 d'un premier jet
   faisait tomber la mention discrète à 3,71:1 — sous le seuil AA de 4,5 que cette feuille tient
   partout ailleurs. Mesuré : la somme ne peut pas dépasser 0,110.
   ⚠️ Aucun test de contraste existant ne pouvait le voir : ils comparent un jeton à un autre
   jeton, jamais à un calque posé par-dessus. SmokeOpacityTests mesure désormais ce cas. */
body::before { opacity: .06; animation: bh-smoke-a 71s ease-in-out infinite; }
body::after  { opacity: .04; animation: bh-smoke-b 97s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
    body::before, body::after { animation: none; }
}

a { text-decoration: none; }

/* ─── Shell layout ─────────────────────────────────────── */
.app-shell {
    /* Refonte Claude Design : navigation commune EN HAUT (top-nav esport), plus de sidebar verticale.
       Le shell est une colonne — barre de nav puis contenu plein cadre. */
    display: flex;
    flex-direction: column;
    zoom: var(--ui-zoom);
    /* ⚠️ Compensée : `zoom` multiplie AUSSI les unités de viewport. Sans la division, le shell
       ferait 108 % de l'écran — barre de défilement et bas de page hors champ.
       🔴 `dvh` et non `vh`, comme .public-page-content, .home-page et .bhcon : sur un navigateur
       mobile, `100vh` vaut la hauteur BARRE D'ADRESSE MASQUÉE. Le shell était donc plus haut que la
       zone visible, et comme il porte `overflow: hidden` et que le document ne défile jamais (html
       et body sont eux aussi en overflow:hidden), la bande basse de CHAQUE écran connecté restait
       en permanence sous l'interface du navigateur — injoignable, sans barre de défilement pour le
       dire. C'est le défaut déjà corrigé sur .bhcon, un cran plus haut. */
    height: calc(100dvh / var(--ui-zoom));
    overflow: hidden;
    /* opaque : les pages connectées ne montrent PAS le fond de marque (choix produit) —
       le hero est réservé à la landing et aux pages d'auth (.auth-wrapper transparent) */
    background: transparent;   /* laisse passer le fond animé de la page */
}

/* ─── Topbar ────────────────────────────────────────────── */
.topbar {
    grid-column: 2 / -1;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 20px;
    background: var(--bg-surface);
    border-bottom: 0.5px solid var(--border);
    border-left: 0.5px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 100;
}

.search-wrapper {
    position: relative;
    width: 220px;
}

.topbar-search {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-input);
    border: 0.5px solid var(--border-input);
    border-radius: var(--radius);
    padding: 6px 12px;
    font-size: 13px;
    color: var(--text-muted);
    width: 100%;
    cursor: text;
}

.topbar-search input[type="search"] {
    background: transparent;
    border: none;
    outline: none;
    font-size: 13px;
    color: var(--text-primary);
    width: 100%;
    padding: 0;
}

.topbar-search input[type="search"]::placeholder { color: var(--text-muted); }
.topbar-search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

.search-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px var(--shadow-strong);
    z-index: 300;
    overflow: hidden;
    min-width: 260px;
}

.search-section-label {
    padding: 8px 12px 4px;
    font-size: 11px;
    color: var(--text-hint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.search-result {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    cursor: pointer;
    transition: background 0.1s;
}

.search-result:hover { background: rgba(var(--overlay-rgb),0.05); }

.search-result-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    flex-shrink: 0;
    overflow: hidden;
}

.search-result-avatar .avatar-img { width: 100%; height: 100%; object-fit: cover; }

.search-result-avatar .avatar-initials {
    width: 100%;
    height: 100%;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 600;
}

.search-result-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.search-result-name {
    font-size: 13px;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.search-result-sub {
    font-size: 11px;
    color: var(--text-muted);
}

.search-result-country {
    font-size: 11px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.search-no-results {
    padding: 12px;
    font-size: 13px;
    color: var(--text-muted);
    text-align: center;
}

.topbar-icon {
    font-size: 18px;
    color: var(--text-muted);
    cursor: pointer;
}

.lang-switcher {
    display: flex;
    align-items: center;
    gap: 2px;
}

.lang-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 500;
    cursor: pointer;
    padding: 2px 4px;
    letter-spacing: 0.05em;
}

.lang-btn:hover { color: var(--text-primary); }
.lang-active { color: var(--accent) !important; }
.lang-sep { color: var(--border); font-size: 11px; }

/* ─── Sidebar ───────────────────────────────────────────── */
.sidebar {
    grid-row: 1 / -1;
    background: var(--bg-surface);
    border-right: 0.5px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 0 0 12px;
    overflow-y: auto;
}

.sidebar-backdrop {
    display: none;
}

/* ─── Responsive shell (mobile/tablette) ────────────────── */
/* Ce bloc décrivait le repli de l'ANCIENNE mise en page : un shell en grille, une barre .topbar et
   une sidebar verticale qui glissait par-dessus le contenu. La refonte esport a remplacé tout ça par
   une barre haute (.appnav) et un shell en `display: flex` — ces règles ne s'appliquaient donc plus
   à rien : `grid-template-columns` est sans effet sur un conteneur flex, et aucun balisage ne porte
   plus .topbar, .sidebar ni .sidebar-backdrop. Le menu mobile de la barre haute, lui, vit avec elle
   (voir le bloc @media (max-width: 860px) de .appnav-links).
   ⚠️ .search-wrapper, EN REVANCHE, est bien vivante — SearchBox et la barre d'outils d'organisation
   la posent toutes les deux. C'est la seule règle du bloc à survivre. */
@media (max-width: 900px) {
    .search-wrapper {
        width: auto;
        flex: 1;
        min-width: 0;
    }
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 1px 12px;
    padding: 9px 12px;
    border-radius: var(--radius);
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.1s;
}

.nav-item:hover {
    background: rgba(var(--overlay-rgb),0.04);
    color: var(--text-secondary);
}

.nav-item.active {
    background: var(--accent-subtle);
    color: var(--accent-light);
    font-weight: 600;
}

.nav-item i {
    font-size: 16px;
    opacity: 0.7;
    flex-shrink: 0;
}

.nav-item.active i { opacity: 1; }

/* ─── User card (Discord-style) ─────────────────────────── */
.user-card-wrapper {
    position: relative;
    padding: 8px 8px 0;
    border-top: 0.5px solid var(--border);
}

.user-card {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background 0.15s;
    user-select: none;
}

.user-card:hover { background: rgba(var(--overlay-rgb),0.06); }
.user-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.user-card-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex-shrink: 0;
    object-fit: cover;
}

.user-card-initials {
    background: var(--avatar-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
    color: var(--avatar-color);
}

.user-card-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.user-card-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.user-card-more {
    font-size: 16px;
    color: var(--text-muted);
    opacity: 0;
    transition: opacity 0.15s;
    flex-shrink: 0;
}

.user-card:hover .user-card-more { opacity: 1; }

.user-popover {
    display: none;
    position: absolute;
    bottom: calc(100% - 4px);
    left: 8px;
    right: 8px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 4px;
    box-shadow: 0 8px 24px var(--shadow-strong);
    z-index: 200;
}

.user-popover.open { display: block; }

.user-popover-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius);
    font-size: 13px;
    color: var(--text-primary);
    text-decoration: none;
    transition: background 0.1s;
}

.user-popover-item:hover { background: rgba(var(--overlay-rgb),0.06); color: var(--text-primary); }

.user-popover-item--danger { color: #f04747; }
.user-popover-item--danger:hover { background: rgba(240,71,71,0.15); }

.user-popover-sep {
    height: 0.5px;
    background: var(--border);
    margin: 4px 2px;
}

.credits {
    font-size: 10px;
    color: var(--text-hint);
    text-align: center;
    padding: 10px 16px 4px;
}

/* ─── Accessibilité ─────────────────────────────────────────
   Texte réservé aux lecteurs d'écran : présent dans l'arbre d'accessibilité, invisible à l'œil.
   ⚠️ Ne PAS remplacer par `display:none` ni `visibility:hidden` — les deux retirent l'élément de
   l'arbre d'accessibilité, c'est-à-dire exactement ce qu'on cherche à préserver.
   Le nom vient de Bootstrap, mais Bootstrap n'est pas chargé ici (seuls tabler-icons, app.css et
   les styles scopés le sont) : sans cette règle la classe ne fait RIEN et le texte s'affiche en
   clair. C'est ce qui est arrivé aux libellés des interrupteurs de « Liens affichés ». */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ─── Main content ──────────────────────────────────────── */
.main-content {
    /* padding resserre (24->16) pour densifier toutes les pages et gagner de la hauteur.
       Exposé en variable parce qu'une page plein écran doit l'annuler par une marge négative :
       la valeur ne doit exister QU'ICI. Quand elle est passée de 24 à 16, la marge de .pp-screen
       est restée à -24 et l'écran de tirage a débordé de 8 px de chaque côté pendant des semaines. */
    --shell-pad: 16px;
    padding: var(--shell-pad);
    overflow-y: auto;
    flex: 1;
    min-height: 0;
}

/* Pages consultables sans connexion : pas de shell (.main-content), donc
   on applique le meme espacement directement sur le conteneur de la page. */
.public-page-content {
    padding: 16px;
    /* opaque : les pages publiques hors accueil/auth (calendrier, organisations, wiki)
       ne montrent pas le fond de marque du body */
    background: transparent;   /* laisse passer le fond animé de la page */
    box-sizing: border-box;
}

/* Coquille des visiteurs ANONYMES — le pendant de `.app-shell`, posée par MainLayout.
   🔴 C'est ELLE qui défile, et plus chaque page. `html` et `body` sont en `overflow: hidden` :
   sans zone défilante interne, un contenu plus haut que la fenêtre est coupé net, sans barre de
   défilement. Cette zone vivait sur `.public-page-content`, donc RÉPÉTÉE sur dix-neuf pages — dix-
   neuf occasions de l'oublier, et cinq l'avaient effectivement été en production. Remontée ici,
   elle ne peut plus manquer, et c'est ce qui permet au pied de page d'exister une fois pour
   toutes, sous le contenu de n'importe quelle page. */
.public-shell {
    zoom: var(--ui-zoom);
    height: calc(100dvh / var(--ui-zoom));
    overflow-y: auto;
    box-sizing: border-box;
}

/* ─── Colonne de lecture ────────────────────────────────────
   Plafond de largeur commun à toutes les pages du shell. Sans lui, chaque page s'étire sur toute
   la fenêtre : sur un écran très large les cartes se déforment et les colonnes d'un tableau
   s'éloignent au point qu'on ne relie plus une ligne à son statut.
   La barre de défilement reste au bord de la fenêtre — c'est .main-content qui défile, pas ses
   enfants — donc seule la mise en page est bornée, pas le cadre.
   ⚠️ Spécificité NULLE, par construction : `:where()` et `*` ne pèsent rien, donc n'importe quelle
   règle de page l'emporte sans surenchère. C'est ce qui rend la règle sûre à poser sur tout le
   monde : une page qui veut le plein cadre le dit chez elle (voir .home-page--shell et .pp-screen,
   qui annulent le plafond ET le padding du shell). La console d'administration a son propre shell
   (.bhcon), elle n'est pas concernée.

   🔴 `min(…, 100%)` et non `var(--page-max)` seul : un plafond de 1180px ABSOLUS ne borne rien dans
   une fenêtre de 390. Or un enfant dont la largeur intrinsèque dépasse le conteneur ne se contente
   pas de déborder — .main-content et .public-page-content sont des conteneurs FLEX en colonne, donc
   la ligne s'étire à l'élément le plus large et TOUS les blocs de la page prennent sa largeur.
   Vécu sur /leaderboard : .bhrk-rules calculait 748px (trois pistes de 240px que `auto-fit` ne
   replie pas, sa contribution intrinsèque décidant seule), et l'écran entier partait de 419px vers
   la droite à 390 — 83px encore à 768, donc jusque sur tablette. Un seul bloc fautif suffit, et
   rien ne le signale : ni erreur, ni log, une page qui glisse.
   Les blocs qui sortent VOLONTAIREMENT de la colonne posent déjà `max-width: none` (.bhlb-page,
   .bhlb-wide, .home-page--shell, .pp-screen) : ils l'emportent, comme avant. */
:where(.main-content, .public-page-content) > * {
    max-width: min(var(--page-max), 100%);
    margin-inline: auto;
}

/* ─── Page header ───────────────────────────────────────── */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

.page-title {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 20px;
    font-weight: 700;
    color: var(--text-primary);
}

.page-subtitle {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ─── Buttons ───────────────────────────────────────────── */
.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    background: var(--accent-gradient);
    color: var(--on-accent);
    border: none;
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    text-decoration: none;
    transition: filter 0.15s;
}

.btn-primary:hover { filter: brightness(1.08); color: var(--on-accent); }

/* ─── Stats grid ────────────────────────────────────────── */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 14px;
}

@media (max-width: 900px) {
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
    .stats-grid { grid-template-columns: 1fr; }
}

.stat-card {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 11px 14px;
}

.stat-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 6px;
}

.stat-label i { font-size: 14px; }

.stat-value {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 23px;
    font-weight: 700;
    color: var(--text-primary);
}

.stat-sub {
    font-size: 11px;
    color: var(--text-hint);
    margin-top: 2px;
}

/* ─── Section title ─────────────────────────────────────── */
.section-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 8px;
}

/* Sous-titre d'un bloc à l'intérieur d'une section (ex. « Annonces automatiques »).
   Référencé de longue date par OrganizationDetail mais jamais défini : les sous-titres
   étaient rendus sans style, indistinguables du texte courant. */
.section-subtitle {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    margin-bottom: 6px;
}

/* ─── Badges ────────────────────────────────────────────── */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
}

.panel {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
}

/* .panel-header redefined below with flex layout */

.panel-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
}

.rank { width: 20px; font-size: 12px; color: var(--text-hint); text-align: center; }
.rank.gold   { color: #BA7517; font-weight: 500; }

.rank.bronze { color: #854F0B; font-weight: 500; }

/* ─── Empty states ──────────────────────────────────────── */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-hint);
    gap: 8px;
}

.empty-state i { font-size: 32px; }
.empty-state p { font-size: 14px; }
/* Un état vide qui REFUSE porte un titre : « vue réservée » n'est pas la même chose que
   « rien à afficher », et la nuance se perd si les deux se rendent en gris de note de bas de page. */
.empty-state h2 { margin: 0; font-size: 16px; color: var(--text-primary); }

.empty-state-inline {
    font-size: 13px;
    color: var(--text-hint);
    padding: 16px 0;
    text-align: center;
}

/* ─── Forms (champs partagés) ───────────────────────────── */
.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 6px;
}

/* `.bhprof-link-value input` et `.bhprof-link-static` sont dans la liste, et pas recopiés plus bas
   dans la section bhprof- : une adresse de lien se présente exactement comme un champ d'identité, et
   des déclarations jumelles finiraient par diverger au premier ajustement. Sans cette ligne, l'input
   sort tel que le navigateur le dessine — plaque blanche sur fond sombre. Le pseudo Discord n'est pas
   une saisie mais garde le cadre : sans lui, il flottait nu entre trois lignes encadrées. Sa police
   et sa couleur, elles, restent les siennes (cf. `.bhprof-link-static` plus bas) — c'est là que se
   lit « reflet, pas saisie ». */
.field input, .field select, .field textarea, .bhprof-link-value input, .bhprof-link-static {
    padding: 10px 14px;
    font-size: 14px;
    border: 1.5px solid var(--border-input);
    border-radius: var(--radius);
    background: var(--bg-input);
    color: var(--text-primary);
    transition: border-color 0.15s;
    width: 100%;
}

.field input:focus, .field select:focus, .field textarea:focus, .bhprof-link-value input:focus {
    outline: none;
    border-color: var(--accent);
}

.field select {
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

.field select:disabled {
    opacity: 0.5;
    cursor: default;
}

.field-hint {
    font-size: 11px;
    color: var(--text-hint);
}

/* Astérisque d'un champ obligatoire, accolé au libellé. */
.field-required {
    color: var(--red-fg);
    font-weight: 600;
}

/* ─── Auth pages ────────────────────────────────────────── */
.auth-wrapper {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    /* transparent : la carte d'auth est posée sur le fond de marque global (body::before) */
    background: transparent;
    padding: 2rem;
}

.auth-card {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 2.5rem 2rem;
    width: 100%;
    max-width: 400px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.auth-lang {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 4px;
}

.auth-logo {
    display: flex;
    justify-content: center;
    margin-bottom: 8px;
}

.auth-logo-img {
    height: 140px;
    width: auto;
    object-fit: contain;
}

.accent { color: var(--accent); }

.auth-title {
    font-size: 20px;
    font-weight: 500;
    color: var(--text-primary);
    margin: 0;
    outline: none;
}

.auth-email-recap {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-muted);
    background: var(--bg-input);
    border-radius: var(--radius);
    padding: 8px 12px;
}

.auth-email-recap i { font-size: 14px; }

.btn-link {
    background: none;
    border: none;
    color: var(--accent);
    font-size: 13px;
    cursor: pointer;
    padding: 0;
    margin-left: auto;
}

.auth-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.btn-block {
    width: 100%;
    padding: 11px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: var(--radius);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-decoration: none;
}

.btn-block:hover { background: var(--accent-hover); color: #fff; }
.btn-block:disabled { background: rgba(var(--overlay-rgb),0.08); color: var(--text-hint); cursor: not-allowed; }

.btn-google {
    background: var(--bg-surface);
    color: var(--text-primary);
    border: 1.5px solid var(--border-input);
}

.btn-google:hover { background: rgba(var(--overlay-rgb),0.04); color: var(--text-primary); }

.divider {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--text-hint);
    font-size: 13px;
}

.divider::before, .divider::after {
    content: '';
    flex: 1;
    height: 0.5px;
    background: var(--border);
}

.auth-switch {
    text-align: center;
    font-size: 13px;
    color: var(--text-muted);
}

.auth-switch a { color: var(--accent); text-decoration: none; font-weight: 500; }

/* reCAPTCHA v3 invisible : mention légale sous le bouton */
.recaptcha-tos {
    margin: 10px 0 0;
    font-size: 11px;
    line-height: 1.4;
    text-align: center;
    color: var(--text-muted, var(--text-soft));
}
.recaptcha-tos a { color: var(--text-muted, var(--text-soft)); text-decoration: underline; }

/* Widget anti-robot (preuve de travail, auto-hébergé) */
.altcha-box {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 14px;
    padding: 9px 12px;
    border: 1px solid var(--border, var(--line-strong));
    border-radius: var(--radius);
    background: var(--surface-2, var(--bg-elevated));
    font-size: 13px;
    color: var(--text-muted, var(--text-soft));
}
.altcha-spinner {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    border: 2px solid var(--border, var(--line-strong));
    border-top-color: var(--accent, #EF9F27);
    border-radius: 50%;
    animation: altcha-spin .7s linear infinite;
}
.altcha-check { flex-shrink: 0; display: none; color: var(--green-fg); font-size: 16px; line-height: 1; }
.altcha-box[data-state="verified"] { border-color: var(--tint-green-border); background: var(--tint-green-bg); color: var(--green-fg); }
.altcha-box[data-state="verified"] .altcha-spinner { display: none; }
.altcha-box[data-state="verified"] .altcha-check { display: inline-flex; }
.altcha-box[data-state="error"] { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); color: #d9a441; }
.altcha-box[data-state="error"] .altcha-spinner { display: none; }
@keyframes altcha-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .altcha-spinner { animation: none; } }

.auth-footer {
    font-size: 11px;
    color: var(--text-hint);
    text-align: center;
    line-height: 1.5;
    margin-top: 4px;
}

/* ─── Accueil public — refonte « broadcast e-sport » ──────
   Direction validée le 2026-08-04 (maquette Claude Design « BracketHub Refonte »,
   écran 1a). Une page défilante (.home-page) avec topbar collante, hero sur l'artwork
   de marque, puis les sections En direct · Classement · Rangs · À venir · Badges ·
   Saison · conclusion · pied de page.

   AUCUNE couleur en dur : tout passe par les tokens de :root (convention PR #438), donc
   la page se décline en clair ET en sombre. La maquette n'était dessinée qu'en sombre ;
   les sections plus profondes que le fond utilisent --bg-page, les cartes --bg-surface.
   Titres display en var(--font-display), chiffres/étiquettes en var(--font-mono). */

/* Pas de zone défilante propre : l'accueil vit dans une coquille comme toutes les autres pages —
   `.public-shell` hors session, `.main-content` en session. Il en posait une, ce qui l'aurait
   imbriquée dans celle de la coquille : deux ascenseurs pour une seule page. */
.home-page {
    background: transparent;   /* laisse passer le fond animé de la page */
    color: var(--text-body);
    font-family: var(--font-alt);
}

/* Accueil rendu DANS le shell (session ouverte) : .main-content défile déjà et occupe la place
   laissée par la top-nav. Garder 100dvh y ajouterait un second ascenseur d'une hauteur d'écran
   sous une barre de 64px ; le padding du shell, lui, empêcherait le plein cadre voulu par la
   maquette. La marge passe par --shell-pad, jamais par un nombre (cf. ShellLayoutCssTests). */
.home-page--shell {
    height: auto;
    overflow: visible;
    margin: calc(-1 * var(--shell-pad, 16px));
    /* La vitrine est plein cadre : elle échappe au plafond de largeur du shell (hero pleine
       largeur, sections qui posent elles-mêmes leur propre colonne). */
    max-width: none;
}

/* Même dimension que le logo de la top-nav en session (.appnav-logo img) : c'est la même marque au
   même endroit de l'écran, et l'utilisateur passe de l'une à l'autre en se connectant. Les deux
   barres lisent d'ailleurs la même hauteur, --appnav-h. */
.landing-logo-img { height: 64px; width: auto; object-fit: contain; }

/* ── Topbar collante ── */
.bh-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 0 32px;
    /* Même hauteur que la top-nav en session : un logo de 64px ne tiendrait pas dans les 64px
       d'origine, et la marque sauterait au moment de la connexion. */
    height: var(--appnav-h);
    /* Barre TRANSPARENTE : le hero et son fond animé passent dessous, au lieu d'être coupés par une
       bande sombre posée en travers. Elle portait auparavant un aplat à 88 %.
       🔴 Cette transparence REPOSE ENTIÈREMENT SUR LE FLOU, ce n'est pas une décoration. Mesuré
       aux trois niveaux avant de trancher : à 45 % comme à 0 %, le flou tient la lisibilité ; SANS
       flou, le contenu qui défile traverse les libellés — l'eyebrow rouge « 01 — EN DIRECT » passe
       au travers de « Calendrier », et la barre devient illisible. D'où le repli ci-dessous : là où
       le navigateur ne sait pas flouter son arrière-plan, l'aplat d'origine revient. Retirer ce
       repli ne casserait rien sur un navigateur récent — et tout sur les autres. */
    background-color: transparent;
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
}

/* Le repli, et la seule raison d'être de ce bloc : sans flou, une barre transparente laisse le
   contenu défiler à travers ses libellés. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .bh-topbar { background-color: color-mix(in srgb, var(--bg-page) 88%, transparent); }
}

.bh-brand { display: inline-flex; align-items: center; gap: 10px; }

.bh-topnav { display: flex; gap: 24px; margin-left: 10px; }
.bh-topnav a {
    font: 500 13px/1 var(--font-alt);
    color: var(--nav-ink);
    transition: color .15s;
}
.bh-topnav a:hover { color: var(--accent-light); }

.bh-topbar-spacer { flex: 1; }

.bh-search {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 32px;
    padding: 0 12px;
    min-width: 168px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-dim);
    font: 400 12px/1 var(--font-alt);
    background: transparent;
    cursor: text;
}
.bh-search i { font-size: 14px; }

.bh-topbar-actions { display: inline-flex; align-items: center; gap: 12px; }
.bh-signin { font: 500 13px/1 var(--font-alt); color: var(--text-soft); }
.bh-signin:hover { color: var(--text-primary); }
.bh-btn-primary {
    display: inline-grid;
    place-items: center;
    height: 32px;
    padding: 0 16px;
    border-radius: var(--radius);
    background: var(--accent-gradient);
    color: var(--on-accent);
    font: 600 12.5px/1 var(--font-alt);
    transition: filter .15s;
}
.bh-btn-primary:hover { filter: brightness(1.08); color: var(--on-accent); }

/* ── Layout des sections ── */
.bh-sec {
    max-width: min(var(--page-max), 100%);
    margin: 0 auto;
    padding: 56px 72px;
    /* `border-image` plutôt qu'un pseudo : la section n'a pas de boîte à elle, et un pseudo aurait
       exigé un `position: relative` sur un conteneur qui n'en a aucun besoin.
       ⚠️ `border-image` s'applique aux QUATRE bords — les trois autres restent à 0 de large, donc
       invisibles. La tranche vaut 1 parce que le dégradé est horizontal : toutes ses lignes étant
       identiques, la tranche basse porte le dégradé entier.
       `border-color` reste déclarée : c'est elle qui s'affiche si `border-image` est ignorée. */
    border-width: 0 0 1px;
    border-style: solid;
    border-color: var(--border);
    border-image: var(--brand-rule) 1;
}
.bh-sec-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 24px;
}
.bh-kicker {
    display: block;
    font: 500 11px/1 var(--font-mono);
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--brand-red-light);
    margin-bottom: 8px;
}
.bh-kicker--live { color: var(--brand-red-light); }
.bh-h2 {
    margin: 0;
    font: 700 38px/1 var(--font-display);
    text-transform: uppercase;
    color: var(--text-primary);
}
.bh-morelink { font: 500 12.5px/1 var(--font-alt); color: var(--accent-light); white-space: nowrap; }
.bh-morelink:hover { color: var(--accent); }

/* ── Hero ── */
/* Hauteur mesurée sur la maquette : 520px sur son cadre de 1280 (donc 40,6 % de la largeur) et
   300px sur son cadre mobile. La borne basse et la borne haute REPRODUISENT ces deux valeurs, et
   l'interpolation relie les deux cadres — 72vh auparavant, ce qui liait la hauteur du hero à celle
   de la FENÊTRE : sur un écran bas le titre touchait les boutons, sur un écran haut le hero
   poussait toute la page sous la ligne de flottaison. La maquette raisonne en largeur. */
.bh-hero {
    position: relative;
    min-height: clamp(300px, 40.6vw, 520px);
    overflow: hidden;
    /* Le bas du hero est une rupture de section comme les autres : son filet porte donc la même
       marque. Resté neutre, il redevenait la seule ligne grise d'une page qui n'en a plus. */
    border-width: 0 0 1px;
    border-style: solid;
    border-color: var(--border);
    border-image: var(--brand-rule) 1;
    display: flex;
}
/* Artwork figé (background-attachment:fixed) : l'image reste fixe dans le viewport et le contenu
   du hero défile par-dessus (effet parallax), les sections opaques la recouvrent ensuite. */
/* Hero de l'accueil, maquette 1a : un aplat de surface, puis deux VOILES DE LUMIÈRE qui
   dérivent — le rouge de marque à gauche, le bleu du logo à droite. `mix-blend-mode: screen`
   les fait s'additionner sans jamais assombrir l'aplat, et chacun s'éteint vers sa PROPRE
   couleur en alpha 0 : vers `transparent` (= rgba(0,0,0,0)) l'interpolation frangerait de gris.
   Les deux voiles débordent de 25 % pour que leur dérive ne découvre jamais un bord. */
/* 🔴 Le hero n'a PLUS d'aplat à lui, et c'est ce qui supprime la marche au bas de sa bande.
   Il posait `--bg-surface`, donc une surface OPAQUE et neutre, pendant que la page, elle, porte
   désormais le lavis de marque : au raccord, le neutre du hero rencontrait le rouge de la page et
   la couture se voyait sur toute la largeur. Transparent, le hero laisse passer le fond de `html`
   — exactement le même calque, donc aligné par construction.
   ⚠️ Et c'est la SEULE façon de l'aligner : repeindre `--bg-page-brand` ici ne marcherait pas,
   un fond `fixed` déclaré sous un `zoom: 1.08` (la coquille) étant mis à l'échelle par ce zoom et
   décalé par rapport à celui de `html`, qui lui n'est pas zoomé.

   Le masque remplace le raccord que peignait `.bh-hero-overlay`, aux MÊMES arrêts (0 % / 45 % à
   26 % / 100 % à 58 %), mais il RETIRE la lumière du hero au lieu d'étaler un aplat par-dessus :
   au bas de la bande il ne reste donc que le fond de page, identique à ce qui suit.
   🔑 Le masque isole aussi les deux voiles : `screen` compose désormais leur groupe avec la
   page plutôt qu'avec un aplat sombre. L'écart est de quelques pour cent sur un fond aussi noir,
   et il a été regardé à l'écran avant d'être accepté. */
.bh-hero-bg {
    position: absolute; inset: 0; overflow: hidden;
    background: var(--hero-img) center 30% / cover no-repeat fixed;
    filter: var(--hero-img-filter);
    -webkit-mask-image: linear-gradient(0deg, transparent 0%, rgba(0,0,0,.45) 26%, #000 58%);
            mask-image: linear-gradient(0deg, transparent 0%, rgba(0,0,0,.45) 26%, #000 58%);
}
.bh-hero-bg::before, .bh-hero-bg::after {
    content: ""; position: absolute; inset: -25%; mix-blend-mode: screen; pointer-events: none;
}
.bh-hero-bg::before {
    background: radial-gradient(58% 58% at 22% 62%, rgba(var(--brand-red-rgb),.58), rgba(var(--brand-red-rgb),0) 72%);
    animation: bh-sweep-red 17s ease-in-out infinite;
}
.bh-hero-bg::after {
    background: radial-gradient(42% 50% at 82% 30%, rgba(var(--accent-rgb),.42), rgba(var(--accent-rgb),0) 72%);
    animation: bh-sweep-blue 23s ease-in-out infinite;
}
@keyframes bh-sweep-red {
    0%, 100% { transform: translate3d(-5%, -3%, 0) scale(1.04); opacity: .85; }
    50%      { transform: translate3d(9%, 5%, 0) scale(1.18); opacity: 1; }
}
@keyframes bh-sweep-blue {
    0%, 100% { transform: translate3d(6%, 4%, 0) scale(1.12); opacity: .7; }
    50%      { transform: translate3d(-7%, -5%, 0) scale(1.02); opacity: .95; }
}
/* Les voiles restent POSÉS : c'est l'ambiance du hero, pas une information. */
@media (prefers-reduced-motion: reduce) {
    .bh-hero-bg::before, .bh-hero-bg::after { animation: none; }
}
/* Voile « broadcast » propre au hero : voile latéral (assombrit la gauche du texte, laisse
   l'artwork à droite) + fondu vers le bas, construits sur --bg-page / --accent-subtle → valable
   en thème clair ET sombre. */
/* Les halos d'identité vivent dans .bh-hero-bg, où ils dérivent. Ce voile-ci ne fait plus que
   RACCORDER le bas du hero au fond de page, comme la maquette.
   🔴 Il assombrissait auparavant toute la moitié GAUCHE à 84 % — nécessaire tant qu'un
   photomontage passait sous le texte, ruineux depuis : le voile de lumière rouge se pose
   précisément à gauche (28 % / 58 %), et cette moitié noircie l'effaçait. Le hero ressortait
   entièrement bleu, la seule couleur qui survivait, à l'opposé de la maquette. Ne pas remettre
   de veil latéral sans remettre d'abord une photo dessous. */
/* 🔴 Il ne porte plus AUCUN aplat : le raccord est passé en masque sur `.bh-hero-bg`.
   Il étalait `--bg-page` — le fond de page PLAT — sur le bas de la bande, ce qui était juste tant
   que la page était de cette couleur, et faux dès qu'elle a porté le lavis de marque : on voyait
   une bande neutre finir net sur du rouge. Ne pas y remettre de fond ; ce bloc n'existe plus que
   pour la fumée ci-dessous. */
.bh-hero-overlay {
    position: absolute;
    inset: 0;
}

/* ── La fumée du hero ─────────────────────────────────────────────────────────────────────
   Deux nappes de la même image, qui dérivent, tournent et respirent sur des durées PREMIÈRES
   entre elles (43s et 67s). Synchronisées, elles se reliraient comme une seule image qui
   bouge, et l'illusion tombe ; décalées, leurs croisements ne se répètent qu'au bout de
   ~48 minutes.
   🔴 Le mouvement passe par `transform`, jamais par `background-position` ni par un dégradé
   animé : une image déplacée est composée par le GPU, alors que les deux autres repeignent
   toute la surface du hero à chaque image.
   `screen` fait MONTER les volutes sans jamais assombrir les voiles de couleur du dessous.
   Le masque les éteint en haut et en bas, pour que la fumée ne franchisse ni la barre de
   navigation ni le raccord au fond de page — sans lui, un bord net de nappe se voit.
   Elles débordent de 30 % : à `scale(1.12)` près, une nappe tournée découvrirait son coin. */
.bh-hero-overlay::before,
.bh-hero-overlay::after {
    content: "";
    position: absolute;
    inset: -30%;
    background: var(--smoke-img) center / cover no-repeat;
    mix-blend-mode: screen;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 60%, transparent 92%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 60%, transparent 92%);
}
.bh-hero-overlay::before { opacity: .17; animation: bh-smoke-a 43s ease-in-out infinite; }
.bh-hero-overlay::after  { opacity: .11; animation: bh-smoke-b 67s ease-in-out infinite; }

@keyframes bh-smoke-a {
    0%, 100% { transform: translate3d(-6%, 3%, 0) scale(1.14) rotate(0deg); }
    50%      { transform: translate3d(5%, -5%, 0) scale(1.34) rotate(7deg); }
}
@keyframes bh-smoke-b {
    0%, 100% { transform: translate3d(5%, -4%, 0) scale(1.30) rotate(0deg); }
    50%      { transform: translate3d(-7%, 6%, 0) scale(1.12) rotate(-9deg); }
}

/* La fumée reste POSÉE : c'est une ambiance, elle ne porte aucune information. */
@media (prefers-reduced-motion: reduce) {
    .bh-hero-overlay::before, .bh-hero-overlay::after { animation: none; }
}
.bh-hero-inner {
    position: relative;
    z-index: 2;
    max-width: min(var(--page-max), 100%);
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 24px;
    padding: 64px 72px;
}
/* Pastille « en direct » de la maquette : cadre rouge, aplat rouge profond très dilué, point
   rouge vif — et libellé en ENCRE CLAIRE. En rouge, la pastille se lirait comme une alerte. */
.bh-live-pill {
    display: inline-flex; align-items: center; gap: 10px;
    width: max-content; padding: 6px 12px; border-radius: var(--radius);
    border: 1px solid color-mix(in srgb, var(--brand-red) 50%, transparent);
    background: color-mix(in srgb, var(--brand-red-deep) 22%, transparent);
}
.bh-live-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--brand-red);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-red) 22%, transparent);
    animation: bh-pulse 2s ease-in-out infinite;
}

/* La pastille « en direct » de l'accueil bat, alors que son alter ego d'une fiche de tournoi
   (.bht-live-dot) s'immobilise depuis toujours : la même pulsation obéissait à la préférence sur un
   écran et l'ignorait sur l'autre. Constaté le 17/09 en vérifiant la fumée — le volet de test tourne
   avec « animations réduites », et ce point clignotait, seul, au milieu d'un hero figé. */
@media (prefers-reduced-motion: reduce) {
    .bh-live-dot { animation: none; }
}
@keyframes bh-pulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }
.bh-live-txt { font: 500 11px/1 var(--font-mono); letter-spacing: .2em; text-transform: uppercase; color: var(--text-bright); }
.bh-hero-title {
    margin: 0;
    max-width: 830px;
    font: 700 clamp(48px, 6.4vw, 92px)/.92 var(--font-display);
    letter-spacing: -.01em;
    text-transform: uppercase;
    color: var(--hero-ink);
    text-shadow: 0 2px 24px var(--shadow-strong);
}
/* 🔴 Le dégradé ne va JAMAIS sur du texte (règle du lot 29) : ici il était détouré au texte
   par background-clip. Tout texte accentué prend --accent-light. */
/* La seconde ligne du titre est ROUGE dans la maquette : c'est elle qui porte l'identité.
   Le bleu reste à l'ACTION (boutons) et aux DONNÉES (chiffres, liens, horaires). */
.bh-hero-title .accent {
    color: var(--brand-red);
    text-shadow: none;
}
.bh-hero-sub { margin: 0; max-width: 560px; font: 400 16px/1.6 var(--font-alt); color: var(--hero-ink-soft); text-shadow: 0 1px 10px var(--shadow-strong); }
.bh-hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.bh-cta {
    display: inline-grid; place-items: center;
    height: 46px; padding: 0 26px;
    border-radius: var(--radius);
    font: 600 14px/1 var(--font-alt);

    /* 🔴 Remise a zero pour l'emploi sur un <button>. Cette classe n'a longtemps servi que sur
       des <a> : posee telle quelle sur un bouton, elle laissait la BORDURE par defaut du navigateur
       (2px outset gris) et la fleche au lieu de la main. Les deux modificateurs reposent leur
       propre bordure et leur propre fond -- ils viennent APRES, donc ils gagnent. */
    appearance: none;
    border: 0;
    background: none;
    cursor: pointer;
}
.bh-cta--primary { background: var(--accent-gradient); color: var(--on-accent); box-shadow: 0 8px 30px color-mix(in srgb, var(--accent) 40%, transparent); transition: filter .15s; }
.bh-cta--primary:hover { filter: brightness(1.08); color: var(--on-accent); }
.bh-cta--ghost { border: 1px solid var(--border-hover); color: var(--hero-ink); background: color-mix(in srgb, var(--bg-page) 55%, transparent); transition: background .15s, border-color .15s; }
.bh-cta--ghost:hover { border-color: var(--accent); }
.bh-hero-stats {
    display: flex; flex-wrap: wrap; gap: 40px 52px;
    margin-top: 8px; padding-top: 24px;
    border-top: 1px solid var(--border);
    max-width: 820px;
}
.bh-stat { display: flex; flex-direction: column; gap: 5px; }
.bh-stat-num { font: 700 30px/1 var(--font-mono); color: var(--hero-ink); }
.bh-stat-lbl { font: 500 10.5px/1 var(--font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text-soft); }

/* ── Cartes tournoi (En direct + À venir) ── */
.bh-live-grid { display: grid; grid-template-columns: 1.45fr 1fr; gap: 20px; }
.bh-live-side { display: flex; flex-direction: column; gap: 14px; }

.bh-card {
    display: flex; flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-surface);
    color: inherit;
    overflow: hidden;
    transition: border-color .15s, transform .15s;
}
.bh-card:hover { border-color: var(--accent); transform: translateY(-2px); }

/* Le dégradé est l'ÉTAT VIDE : un `background-image` en ligne (la bannière de l'organisation) ne
   remplace que la couche image et le laisse en dessous. Rien à déclarer pour l'absence de bannière,
   donc aucune classe à tenir en phase avec le balisage. */
.bh-card-feat-banner {
    position: relative; height: 186px;
    background: linear-gradient(135deg, var(--bg-elevated), var(--bg-inset));
    background-size: cover; background-position: center;
}
.bh-card-feat-banner::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent, var(--bg-surface)); }
.bh-badges-row { position: absolute; z-index: 1; top: 14px; left: 14px; display: flex; gap: 8px; flex-wrap: wrap; }
.bh-flag {
    display: inline-flex; align-items: center; gap: 6px;
    height: 24px; padding: 0 10px; border-radius: var(--radius);
    font: 600 10.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase;
}
.bh-flag--live { background: var(--brand-red-deep); color: var(--text-bright); }
.bh-flag--live .d { width: 5px; height: 5px; border-radius: 50%; background: var(--on-bright); }
.bh-flag--neutral { background: color-mix(in srgb, var(--bg-page) 70%, transparent); border: 1px solid var(--border-hover); color: var(--text-bright); }

.bh-card-org { position: absolute; z-index: 1; bottom: 16px; left: 18px; display: flex; align-items: center; gap: 11px; }
/* 🔴 Le conteneur ne porte que la GÉOMÉTRIE. L'aplat coloré est descendu sur le repli en
   initiales : posé ici, il cerclerait d'un disque bleu tout logo au fond transparent — le même
   défaut que celui corrigé sur les avatars de joueur. */
.bh-card-org-logo {
    width: 38px; height: 38px; border-radius: 50%; overflow: hidden;
    display: grid; place-items: center; font: 700 13px/1 var(--font-display);
}
.bh-card-org-logo-img { width: 100%; height: 100%; object-fit: cover; }
.bh-card-org-logo-initials {
    width: 100%; height: 100%; display: grid; place-items: center;
    background: var(--accent-subtle); color: var(--accent-light);
}
.bh-card-org-name { display: flex; align-items: center; gap: 6px; font: 600 13px/1 var(--font-alt); color: var(--text-bright); }

.bh-card-org-sub { font: 500 10px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); margin-top: 3px; }

.bh-card-body { padding: 20px 22px 22px; display: flex; flex-direction: column; gap: 14px; }
.bh-card-title { margin: 0; font: 700 30px/1.02 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bh-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.bh-tag {
    height: 22px; padding: 0 9px; display: inline-grid; place-items: center;
    border-radius: var(--radius); background: var(--bg-chip);
    font: 500 10.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-body);
}

.bh-card-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding-top: 16px; border-top: 1px solid var(--border); }
.bh-metric { display: flex; flex-direction: column; gap: 5px; }
.bh-metric-lbl { font: 500 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bh-metric-val { font: 700 21px/1 var(--font-mono); color: var(--text-bright); }
.bh-metric-val--accent { color: var(--accent-light); }

/* Petite carte live latérale */
.bh-card--mini { padding: 18px; gap: 12px; }
.bh-card-line { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bh-live-inline { display: inline-flex; align-items: center; gap: 6px; font: 600 10.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--brand-red-light); }
.bh-live-inline--gold { color: var(--gold-fg); }
.bh-live-inline .d { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.bh-mini-title { margin: 0; font: 700 22px/1.05 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bh-mini-sub { font: 500 11px/1 var(--font-mono); text-transform: uppercase; color: var(--text-dim); }
.bh-progress { height: 5px; border-radius: var(--radius); background: var(--bg-chip); overflow: hidden; }
.bh-progress > span { display: block; height: 100%; background: var(--accent-warm); }
.bh-embed-slot { flex: 1; display: grid; place-items: center; border: 1px dashed var(--line-strong); border-radius: var(--radius); padding: 18px; text-align: center; font: 400 11px/1.5 var(--font-mono); color: var(--text-faint); }

/* ── Démonstration de l'overlay OBS, dans la colonne latérale de « En ce moment » ──
   Le vrai widget (.bhov), rendu avec des valeurs d'exemple : la démonstration ne redessine RIEN,
   sinon les deux finiraient par diverger et l'accueil montrerait un overlay qui n'existe plus.
   Le widget est THÈME-INDÉPENDANT par conception (toujours sombre) — c'est voulu ici aussi, on
   montre ce qu'OBS affichera, pas ce que le thème du visiteur préfère. */
.bh-ovdemo { display: flex; flex-direction: column; gap: 10px; border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; }
.bh-ovdemo-head { display: flex; align-items: center; gap: 8px; }
.bh-ovdemo-chip { height: 16px; padding: 0 7px; display: grid; place-items: center; border-radius: var(--radius); border: 1px solid var(--border); font: 600 8.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bh-ovdemo-note { margin: 0; font: 400 10.5px/1.4 var(--font-mono); color: var(--text-faint); }
/* Le widget garde ses 470×92 EXACTS : c'est la dimension qu'on annonce au streamer. Sous la
   largeur d'une colonne étroite, on le réduit à l'échelle plutôt que de le déformer — et la scène
   reprend la hauteur correspondante, une transformation ne changeant pas la boîte de mise en page. */
.bh-ovdemo-stage { overflow: hidden; }
/* Trois paliers, pas un : la colonne qui accueille le widget vaut (fenêtre − 40px de marge de
   section − 30px de carte). À 375px de fenêtre elle ne fait plus que 305px, et l'échelle .8 des
   débuts (376px) rognait le widget par la droite — la colonne « place moyenne » disparaissait
   sans barre de défilement pour le dire. Chaque palier est posé là où 470 × échelle cesse de
   tenir dans la colonne la plus étroite qu'il couvre ; HomeMobileWidthTests refait le calcul. */
@media (max-width: 560px) {
    .bh-ovdemo-stage { height: 74px; }
    .bh-ovdemo-stage .bhov { transform: scale(.8); transform-origin: 0 0; }
}
@media (max-width: 460px) {
    .bh-ovdemo-stage { height: 57px; }
    .bh-ovdemo-stage .bhov { transform: scale(.62); }
}
@media (max-width: 370px) {
    .bh-ovdemo-stage { height: 46px; }
    .bh-ovdemo-stage .bhov { transform: scale(.5); }
}

/* ── Bloc Classement + Rangs (2 colonnes) ── */
.bh-split { max-width: min(var(--page-max), 100%); margin: 0 auto; display: grid; grid-template-columns: 1.25fr 1fr; border-width: 0 0 1px; border-style: solid; border-color: var(--border); border-image: var(--brand-rule) 1; }
.bh-split > div { padding: 56px 72px; }
/* Le seul filet VERTICAL de l'accueil : même dégradé, tourné d'un quart de tour (rouge en haut,
   bleu en bas), pour que la colonne qui sépare le classement des rangs porte elle aussi la marque. */
.bh-split > div:first-child { border-width: 0 1px 0 0; border-style: solid; border-color: var(--border); border-image: var(--brand-rule-v) 1; }

.bh-ladder { display: flex; flex-direction: column; }
.bh-ladder-head, .bh-ladder-row { display: grid; grid-template-columns: 44px 1fr 78px 62px 78px; gap: 12px; align-items: center; }
.bh-ladder-head { padding: 0 12px 10px; border-bottom: 1px solid var(--border); }
.bh-ladder-head span { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bh-ladder-head .r { text-align: right; }
.bh-ladder-row { padding: 13px 12px; border-bottom: 1px solid var(--line-soft); color: inherit; }
.bh-ladder-row--first { background: linear-gradient(90deg, var(--tint-gold-bg), transparent); }
.bh-rank-no { font: 700 15px/1 var(--font-mono); color: var(--text-soft); }
.bh-rank-no--first { color: var(--gold-fg); }
.bh-player { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bh-player-emblem { width: 32px; height: 32px; flex: none; object-fit: contain; }
/* Même plaque sombre que la galerie des rangs, pour les pastilles argent/platine qui se
   délaveraient sur les lignes claires du classement (identique dans les deux thèmes). */
.bh-player-emblem--plaque { background: var(--emblem-plaque); border-radius: var(--radius); padding: 2px; }
.bh-player-name { font: 600 14px/1 var(--font-alt); color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bh-player-rank { font: 500 9.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); margin-top: 3px; }
.bh-player-rank--gold { color: var(--gold-fg); }
.bh-ladder-row .num { font: 700 15px/1 var(--font-mono); color: var(--text-primary); text-align: right; }
.bh-ladder-row .sub { font: 400 13px/1 var(--font-mono); color: var(--text-body); text-align: right; }

.bh-ranks { display: flex; flex-direction: column; gap: 7px; }
.bh-rank {
    display: flex; align-items: center; gap: 14px;
    padding: 9px 12px; border-radius: var(--radius);
    background: var(--bg-surface); border: 1px solid var(--border);
}
.bh-rank--iri { background: linear-gradient(90deg, var(--accent-subtle), var(--bg-surface)); border-color: var(--accent); }
.bh-rank-emblem { width: 38px; height: 38px; flex: none; object-fit: contain; }
/* Emblèmes clairs (argent, platine) : posés sur une plaque sombre arrondie, identique dans
   les deux thèmes, pour ne pas se délaver sur le blanc du thème clair. */
.bh-rank-emblem--plaque { background: var(--emblem-plaque); border-radius: var(--radius); padding: 3px; }
.bh-rank-name { flex: 1; font: 600 13px/1 var(--font-alt); color: var(--text-bright); }
.bh-rank-name .div { color: var(--text-dim); font-weight: 400; }
.bh-rank-range { font: 500 11px/1 var(--font-mono); color: var(--text-soft); }

/* Distinctions de place : bordure tiretée pour se distinguer des paliers, qui sont pleins. Ce
   n'est pas un palier de plus mais une place, et elle se perd sans avoir joué. */
.bh-dists { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.bh-dist-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.bh-dist {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 7px 12px 7px 8px; border-radius: var(--radius);
    background: var(--bg-surface); border: 1px dashed var(--tint-gold-border);
}
.bh-dist-emblem { width: 30px; height: 30px; flex: none; object-fit: contain; }
.bh-dist-name { font: 600 12px/1 var(--font-alt); color: var(--gold-fg); white-space: nowrap; }
.bh-dist-note { margin: 10px 0 0; font: 400 11px/1.5 var(--font-alt); color: var(--text-soft); }

/* ── Tournois à venir ── */
.bh-up-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.bh-up-card { display: flex; gap: 16px; padding: 18px; }
.bh-datebox {
    flex: none; width: 56px; display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 8px 0; border-radius: var(--radius); background: var(--bg-elevated); border: 1px solid var(--border);
}
.bh-datebox .m { font: 500 9.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); }
.bh-datebox .d { font: 700 24px/1 var(--font-display); color: var(--text-primary); }
.bh-datebox .t { font: 500 9.5px/1 var(--font-mono); color: var(--accent-light); }
.bh-up-body { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.bh-up-title { margin: 0; font: 700 19px/1.05 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bh-up-org { font: 500 10.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-dim); }
.bh-cap { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.bh-cap .bh-progress { flex: 1; }
.bh-cap-num { font: 500 10.5px/1 var(--font-mono); color: var(--text-soft); }

/* ── Badges ── */
.bh-badge-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; }
.bh-badge {
    display: flex; flex-direction: column; align-items: center; gap: 9px;
    padding: 16px 8px; border-radius: var(--radius);
    background: var(--bg-surface); border: 1px solid var(--border);
}
.bh-badge--evt { background: linear-gradient(180deg, var(--tint-gold-bg), var(--bg-surface)); border-color: var(--tint-gold-border); }

.bh-badge-name { font: 600 11px/1.2 var(--font-alt); color: var(--text-bright); text-align: center; }
.bh-badge--evt .bh-badge-name { color: var(--gold-fg); }
.bh-badge-req { font: 400 9.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-dim); }
.bh-badge--evt .bh-badge-req { color: var(--gold-fg); }

/* ── Saison ── */
.bh-season { max-width: min(var(--page-max), 100%); margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid var(--border); }
.bh-season > div { padding: 56px 72px; }
.bh-season > div:first-child { border-right: 1px solid var(--border); }
.bh-season-champ { position: relative; background: radial-gradient(90% 120% at 100% 0%, var(--tint-gold-bg), transparent 60%); }
.bh-season-bar { display: flex; align-items: center; gap: 12px; margin: 8px 0 14px; }
.bh-season-bar .e { font: 500 11px/1 var(--font-mono); text-transform: uppercase; color: var(--text-soft); }
.bh-season-desc { margin: 0 0 22px; font: 400 13px/1.6 var(--font-alt); color: var(--text-body); }
.bh-season-desc .g { color: var(--gold-fg); }
.bh-season-stats { display: flex; flex-wrap: wrap; gap: 32px; }
.bh-season-champ-kicker { font: 500 11px/1 var(--font-mono); letter-spacing: .2em; text-transform: uppercase; color: var(--gold-fg); }
.bh-champ-row { display: flex; align-items: center; gap: 18px; margin-top: 20px; }
.bh-champ-emblem { width: 72px; height: 72px; flex: none; object-fit: contain; }
.bh-champ-name { font: 700 34px/1 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bh-champ-meta { font: 500 11px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--gold-fg); margin-top: 7px; }

/* ── Conclusion ── */
.bh-cta-band { position: relative; overflow: hidden; padding: 72px; text-align: center; border-bottom: 1px solid var(--border); }
.bh-cta-band::before { content: ""; position: absolute; inset: 0; background: radial-gradient(70% 140% at 50% 120%, var(--accent-subtle), transparent 70%); }
.bh-cta-inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: 20px; }
.bh-cta-title { margin: 0; max-width: 640px; font: 700 clamp(34px, 4.5vw, 52px)/.98 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bh-cta-text { margin: 0; max-width: 520px; font: 400 14.5px/1.6 var(--font-alt); color: var(--text-body); }

/* ── Pied de page ── */
/* La GRILLE, rendue par l'accueil seul. Ni liseré ni marge en tête : c'est `.bh-foot-bar`, juste
   dessous, qui porte le trait — et elle le porte sur toutes les pages.
   ⚠️ La version « pied de page partout » avait ajouté ici un `margin-top: 40px` que le `margin:
   0 auto` de la même règle écrasait aussitôt, étant déclaré après lui. L'espace voulu n'a donc
   jamais existé, et rien ne pouvait le dire : une déclaration morte ne casse rien, elle ne fait
   rien. Elle est partie avec le retour du pied de page à l'accueil. */
.bh-foot { max-width: min(var(--page-max), 100%); margin: 0 auto; padding: 44px 72px 36px; display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 32px; }
.bh-foot-brand { display: flex; flex-direction: column; gap: 14px; }
/* Le logo est carré (1254×1254) : dans une colonne flex, align-items:stretch l'étirait à la
   largeur de la colonne (hauteur figée) → écrasé. align-self:flex-start conserve son ratio. */
.bh-foot-word { height: 60px; width: auto; align-self: flex-start; }
.bh-foot-tag { font: 400 11.5px/1.6 var(--font-alt); color: var(--text-dim); }
.bh-foot-col { display: flex; flex-direction: column; gap: 9px; }
.bh-foot-col-h { font: 500 10px/1 var(--font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--text-dim); }
.bh-foot-col a { font: 400 12.5px/1 var(--font-alt); color: var(--text-body); }
.bh-foot-col a:hover { color: var(--text-primary); }
/* La BARRE (`SiteCopyright`), posée par les deux coquilles : elle est sur CHAQUE page, là où la
   grille ci-dessus ne vit que sur l'accueil. C'est elle qui porte le liseré de séparation.
   ⚠️ Elle se pose sur le fond ANIMÉ de la page et non sur une surface opaque. `--text-faint` est
   mesuré à 4,5:1 par ThemeCssTests ; le prendre plus sourd le ferait passer sous le seuil.
   ⚠️ Plus de `justify-content: space-between` : il n'existait que pour pousser à droite le
   « FR · EN », retiré le 2026-09-18 parce qu'il était inerte. Avec un seul enfant il ne réglait
   plus rien — une déclaration qui a perdu son objet ne se voit pas, elle ne fait rien. */
.bh-foot-bar { max-width: min(var(--page-max), 100%); margin: 0 auto; padding: 18px 72px 30px; display: flex; align-items: center; border-top: 1px solid var(--line-soft); }
.bh-foot-bar span { font: 400 11px/1 var(--font-mono); color: var(--text-faint); }

/* ── 01 · Comment ça marche ──
   Section explicative posée entre le hero et « En ce moment ». La page n'en avait
   aucune : elle passait de l'accroche aux tournois en cours sans jamais dire ce que
   fait le produit. Le lecteur vidéo tient la gauche, les trois temps du parcours la
   droite. Tokens uniquement, aucune largeur en dur — la section hérite de --page-max
   par .bh-sec. */
.bh-how {
    display: grid;
    /* `minmax(0, …)` sur les DEUX pistes : le plancher d'une piste `1fr` est le
       min-content de son contenu, et une vidéo pousse à sa largeur intrinsèque.
       Même défaut que .bh-live-grid avant correction — la page entière défilait. */
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: 44px;
    align-items: start;
}

.bh-how-media { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.bh-how-frame {
    position: relative;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg-inset);
    box-shadow: 0 18px 50px var(--shadow-strong);
}
.bh-how-frame video { width: 100%; height: 100%; display: block; object-fit: cover; }

/* Le bouton couvre toute l'image tant qu'on n'a pas cliqué : la vidéo n'a alors ni
   contrôles natifs ni lecture automatique, et le fichier n'est pas téléchargé (seules
   ses métadonnées le sont, pour afficher la durée). Une lecture automatique coûterait
   plusieurs mégaoctets à chaque visiteur anonyme de la page la plus vue du site. */
.bh-how-play {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    border: 0; padding: 0; cursor: pointer;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--bg-page) 10%, transparent) 0%,
        color-mix(in srgb, var(--bg-page) 55%, transparent) 100%);
    transition: background .18s;
}
.bh-how-play:hover { background: color-mix(in srgb, var(--bg-page) 30%, transparent); }
.bh-how-play:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.bh-how-mark {
    width: 74px; height: 74px;
    border-radius: 999px;
    display: grid; place-items: center;
    background: var(--accent-gradient);
    color: var(--on-accent);
    box-shadow: 0 10px 34px color-mix(in srgb, var(--accent) 45%, transparent);
    transition: transform .18s;
}
.bh-how-play:hover .bh-how-mark { transform: scale(1.06); }
@media (prefers-reduced-motion: reduce) {
    .bh-how-play, .bh-how-mark { transition: none; }
    .bh-how-play:hover .bh-how-mark { transform: none; }
}
.bh-how-dur {
    position: absolute; right: 12px; bottom: 12px;
    padding: 4px 8px; border-radius: var(--radius);
    font: 500 11px/1 var(--font-mono);
    letter-spacing: .06em;
    color: var(--hero-ink);
    background: color-mix(in srgb, var(--bg-page) 72%, transparent);
    border: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}
/* Tant que les métadonnées ne sont pas arrivées, la pastille n'a rien à dire : une
   durée fausse vaut moins que pas de durée. */
.bh-how-dur:empty { display: none; }
.bh-how-cap { font: 400 12px/1.4 var(--font-mono); color: var(--text-dim); }

.bh-how-col { display: flex; flex-direction: column; }
.bh-how-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.bh-how-step {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 16px;
    padding: 18px 0;
    border-bottom: 1px solid var(--border);
}
.bh-how-step:first-child { padding-top: 0; }
.bh-how-num {
    font: 600 12px/1.3 var(--font-mono);
    letter-spacing: .12em;
    color: var(--accent);
    padding-top: 2px;
}
.bh-how-t { margin: 0; font: 600 15.5px/1.25 var(--font-alt); color: var(--text-primary); }
.bh-how-d { margin: 7px 0 0; font: 400 13.5px/1.6 var(--font-alt); color: var(--text-soft); }
.bh-how-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

/* ── Responsive ── */

/* 🔴 La barre publique complète réclame ~1120px : marque 64 + cinq liens 376 + recherche 168 +
   langues 55 + actions 147, gaps de 24 compris. Rien ne la comprimait avant 720px,
   donc de 721 à 1119px elle poussait la PAGE ENTIÈRE en défilement horizontal — sur une tablette
   en portrait, l'accueil dépassait de plus de 300px. Le retrait se fait par ordre d'importance
   croissante, la navigation en dernier : recherche (doublon du bandeau applicatif),
   puis les liens — qui restent atteignables dans le pied de page. */
@media (max-width: 1160px) {
    .bh-topbar { gap: 16px; padding: 0 20px; }
    .bh-topnav { gap: 16px; }
    .bh-search { display: none; }
}
@media (max-width: 760px) { .bh-topnav { display: none; } }

@media (max-width: 1080px) {
    /* 🔴 `minmax(0, 1fr)`, jamais `1fr` : le plancher d'une piste `1fr` est le min-content de son
       contenu, et la démonstration d'overlay y pose un widget de 470px de large. La piste restait
       donc à 500px dans une fenêtre de 375 — toute la page défilait de 145px vers la droite, la
       barre du haut comprise. Cf. le système de largeurs de page : min-width: auto sur les items
       d'une grille remonte à travers toutes les grilles parentes. */
    .bh-live-grid { grid-template-columns: minmax(0, 1fr); }
    .bh-split, .bh-season { grid-template-columns: 1fr; }
    /* Sous 1080px la colonne du lecteur tomberait sous 450px, où le texte incrusté
       dans la vidéo devient illisible : les trois temps passent sous elle. */
    .bh-how { grid-template-columns: minmax(0, 1fr); gap: 30px; }
    .bh-split > div:first-child, .bh-season > div:first-child { border-right: none; border-bottom: 1px solid var(--border); }
    .bh-up-grid { grid-template-columns: repeat(2, 1fr); }
    .bh-badge-grid { grid-template-columns: repeat(5, 1fr); }
}
@media (max-width: 720px) {
    .bh-topbar { padding: 0 14px; gap: 10px; }
    /* .bh-topnav et .bh-search sont déjà retirés plus haut, à la largeur où ils cessent de tenir. */
    .bh-signin { display: none; }
    .bh-topbar-actions { gap: 8px; }
    .bh-btn-primary { white-space: nowrap; padding: 0 12px; }
    .bh-sec, .bh-split > div, .bh-season > div, .bh-hero-inner, .bh-foot, .bh-foot-bar, .bh-cta-band { padding-left: 20px; padding-right: 20px; }
    .bh-sec { padding-top: 40px; padding-bottom: 40px; }
    .bh-up-grid { grid-template-columns: 1fr; }
    .bh-badge-grid { grid-template-columns: repeat(3, 1fr); }
    .bh-foot { grid-template-columns: 1fr 1fr; }
    .bh-hero-stats { gap: 24px 32px; }
    .bh-stat-num { font-size: 24px; }
}
@media (max-width: 560px) {
    /* La marque à 64px mangeait la moitié de la barre sur un téléphone. */
    .landing-logo-img { height: 44px; }
    .bh-topbar { padding: 0 12px; gap: 8px; }

    /* Trois colonnes dans 291px : « PP Custom par équipe » se cassait sur quatre lignes et
       « 16 / 32 » sur deux. Deux colonnes, le troisième relevé passant à la ligne. */
    .bh-card-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .bh-metric-val { font-size: 18px; }

    /* Le classement de l'accueil garde le rang, le joueur et le score. K/D et parties jouées
       demandaient 140px de plus que la colonne n'en a : la grille débordait de la section et
       poussait la page. Le tableau complet reste sur /rankings. */
    .bh-ladder-head, .bh-ladder-row { grid-template-columns: 30px minmax(0, 1fr) 68px; gap: 10px; }
    .bh-ladder-head > :nth-child(n+4), .bh-ladder-row > :nth-child(n+4) { display: none; }
}

/* ─── Classement public (refonte « broadcast e-sport », écran 1c) ────────────
   Hero + bandeau vainqueur + podium en tête de la page publique de classement.
   Le tableau complet reste rendu par <LeaderboardView> (composant partagé inchangé).
   Tokens uniquement — décliné clair/sombre. Titres en var(--font-display), chiffres
   en var(--font-mono). Les teintes argent/bronze du podium restent neutres (pas de
   token dédié) : seul le 1er porte l'or. */
.bhlb { font-family: var(--font-alt); }

/* 🔴 L'arbre d'un Wager traverse la colonne de lecture. À 6 camps il la remplit déjà ; à 16 il lui
   faudrait ~1720px pour 1180 disponibles — et tout le monde défilait dans .bhbr-scroll pendant qu'un
   tiers de l'écran restait vide de chaque côté.
   Le plafond vient de `:where(.main-content, .public-page-content) > *`, de spécificité NULLE : une
   simple classe l'emporte. Encore faut-il que le bloc SOIT un enfant direct du conteneur — d'où le
   découpage du classement en plusieurs .bhlb successifs, dont celui-ci.
   ⚠️ Deux fausses pistes déjà écartées, ne pas les refaire :
   • borner .bhlb par `padding-inline: var(--band-pad-inline)` et annuler ce padding sur l'enfant :
     le `100%` de l'enfant se résout sur la boîte de CONTENU du parent, déjà réduite à --page-max.
     Mesuré : 1212px au lieu de 2528 ;
   • `width: 100vw` + marge négative : le vw inclut la barre de défilement de .public-page-content
     et fait déborder la page entière — ce que .bhbr-scroll existe précisément pour éviter. */
/* L'enveloppe du classement ne plafonne plus : ce sont ses blocs qui se bornent, un par un. Sans
   ça, la vue CONNECTÉE plafonnait l'enveloppe elle-même (enfant direct de .main-content) et l'arbre
   ne pouvait plus s'en échapper — le plein cadre ne marchait qu'en anonyme. */
.bhlb-page { max-width: none; }

/* Reprise à l'identique du plafond de `:where(.main-content, .public-page-content) > *`, un niveau
   plus bas, avec la seule exception qui nous intéresse. Le bandeau, la barre de cagnotte et les
   tableaux gardent donc exactement la largeur qu'ils avaient.
   ⚠️ « À l'identique » vaut aussi pour le `min(…, 100%)` : sans lui, cette reprise rouvrirait chez
   elle le débordement que le plafond commun vient de fermer. */
.bhlb-page > *:not(.bhlb-wide) { max-width: min(var(--page-max), 100%); margin-inline: auto; }

.bhlb-wide { max-width: none; padding-inline: 56px; }

/* Le titre de l'arbre s'aligne sur le BORD GAUCHE de l'arbre, et sa note le suit au lieu d'être
   renvoyée à l'autre bout de l'écran : le `space-between` du bandeau de tableau, écrit pour une
   colonne de 1180px, séparait les deux de plus de deux mètres de pixels sur un écran large. */
.bhlb-wide .bhlb-tablehead { margin-inline: 0; justify-content: flex-start; gap: 18px; flex-wrap: wrap; }

.bhlb-prize { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.bhlb-prize-lbl { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bhlb-prize-val { font: 700 40px/1 var(--font-mono); color: var(--accent-light); }

/* Bandeau commun (TournamentBandeau) réutilisé sur les vues classement/statistiques : espace le
   bandeau du contenu comme le faisait le hero propre à chaque page. */
.bht-hero--bandeau { margin-bottom: 24px; }
/* Barre de cagnotte du classement (le hero propre est remplacé par le bandeau commun). */
.bhlb-prizebar { display: flex; align-items: baseline; gap: 14px; padding: 0 56px 20px; }
.bhlb-prizebar .bhlb-prize-val { font-size: 30px; }
/* Conteneur de la vue Statistiques publique (le composant apporte ses propres .tour-section). */
.tour-stats-page { max-width: min(var(--page-max), 100%); margin-inline: auto; padding: 4px 40px 44px; }
@media (max-width: 720px) {
    .bhlb-prizebar { padding: 0 20px 16px; }
    .tour-stats-page { padding: 4px 16px 32px; }
    /* Sur mobile, 56px de chaque côté prendraient un sixième de l'écran ; l'arbre a besoin de
       chaque pixel avant que .bhbr-scroll ne prenne le relais. */
    .bhlb-wide { padding-inline: 20px; }
}

/* Bandeau vainqueur */
.bhlb-winner {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin: 0 56px 26px; padding: 16px 22px; border-radius: var(--radius);
    border: 1px solid var(--tint-gold-border);
    background: linear-gradient(100deg, var(--tint-gold-bg-2), transparent);
}
.bhlb-winner-mark { width: 16px; height: 16px; background: var(--gold-fg); transform: rotate(45deg); flex: none; }
.bhlb-winner-name { font: 700 22px/1 var(--font-display); text-transform: uppercase; color: var(--gold-on-tint); }

.bhlb-winner-tag { margin-left: auto; font: 500 10.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--gold-on-tint); opacity: .7; }

/* Podium */
.bhlb-podium { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 0 56px 24px; }
.bhlb-pod {
    display: flex; flex-direction: column; gap: 10px;
    padding: 16px; border-radius: var(--radius);
    border: 1px solid var(--border); background: var(--bg-surface);
}
.bhlb-pod--1 { border-color: var(--tint-gold-border); background: linear-gradient(180deg, var(--tint-gold-bg), var(--bg-surface)); }
.bhlb-pod-head { display: flex; align-items: center; justify-content: space-between; }
/* La couronne vit DANS le rang : alignée sur sa ligne de base, elle suit toute variation de
   taille de la carte sans réglage séparé. */
.bhlb-pod-rank { display: inline-flex; align-items: center; gap: 8px; font: 700 26px/1 var(--font-display); color: var(--text-bright); }
/* Rang 2 laissé au gris du texte : c'est déjà la convention argent de l'écran des classements
   (.bhrk-row--pod2), et inventer un jeton « argent » ici les ferait diverger. */
.bhlb-pod-cup { font-size: 20px; line-height: 1; color: var(--text-secondary); }
.bhlb-pod--1 .bhlb-pod-cup { color: var(--gold-fg); }
.bhlb-pod--3 .bhlb-pod-cup { color: var(--bronze-fg); }
.bhlb-pod-rank sup { font-size: 13px; }
.bhlb-pod--1 .bhlb-pod-rank { color: var(--gold-fg); }
.bhlb-pod-prize { font: 700 15px/1 var(--font-mono); color: var(--text-bright); }
.bhlb-pod--1 .bhlb-pod-prize { color: var(--gold-fg); }
.bhlb-pod-num { width: 38px; height: 38px; border-radius: var(--radius); background: var(--bg-inset); border: 1px solid var(--line-strong); display: grid; place-items: center; font: 700 14px/1 var(--font-display); color: var(--text-bright); overflow: hidden; }
.bhlb-pod-num img { width: 100%; height: 100%; object-fit: cover; }
/* Le cadre (bordure + aplat) appartient au repli en initiales/numéro ; un logo se montre nu. */
.bhlb-pod-num--logo { border: none; background: none; }
.bhlb-pod--1 .bhlb-pod-num { border-color: var(--tint-gold-border); color: var(--gold-fg); }
.bhlb-pod--1 .bhlb-pod-num--logo { border: none; }
.bhlb-pod-body { display: flex; flex-direction: column; gap: 5px; }
.bhlb-pod-name { font: 700 19px/1 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bhlb-pod-line { font: 400 11.5px/1.5 var(--font-alt); color: var(--text-soft); }
.bhlb-pod--1 .bhlb-pod-line { color: var(--gold-on-tint); }
.bhlb-pod-sub { font: 500 10px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); }
.bhlb-pod--1 .bhlb-pod-sub { color: var(--gold-on-tint); }
/* Le badge Match Point du podium réutilise celui du tableau. .bhlb-pod-body est une colonne flex :
   sans align-self, une pastille en inline-grid s'étirerait sur toute la largeur de la carte. */
.bhlb-pod-mp { align-self: flex-start; }

/* Bande des parties + détail dépliable d'une carte de podium.
   La carte est devenue un <details> : ses variantes .bhlb-pod--1 continuent de porter, le contenu
   passant simplement dans le <summary>, qui reprend la colonne flex de la carte.
   ⚠️ min-width: 0 partout sur la chaîne (item de grille → summary → bande) : sans lui, un ruban de
   douze parties pousse la piste de la grille et fait défiler l'ÉCRAN au lieu de la bande. */
.bhlb-pod { min-width: 0; }
.bhlb-pod-sum { display: flex; flex-direction: column; gap: 10px; min-width: 0; cursor: pointer; list-style: none; }
.bhlb-pod-sum::-webkit-details-marker { display: none; }
.bhlb-pod-sum--flat { cursor: default; }
.bhlb-pod-gamesrow { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bhlb-pod-games { display: flex; gap: 4px; min-width: 0; overflow-x: auto; padding-bottom: 2px; }
.bhlb-pod-games::-webkit-scrollbar { height: 5px; }
.bhlb-pod-games::-webkit-scrollbar-thumb { background: var(--accent-subtle); border-radius: var(--radius); }
.bhlb-pod-g {
    flex: none; min-width: 26px; padding: 4px 5px; border-radius: var(--radius); text-align: center;
    background: var(--bg-inset); border: 1px solid var(--line-soft);
    font: 600 10.5px/1 var(--font-mono); color: var(--text-dim);
}
/* Seule la partie GAGNÉE se distingue : deux états valent mieux qu'une échelle de placement, que
   rien sur la carte ne permettrait de lire. */
.bhlb-pod-g--win { background: var(--tint-gold-bg); border-color: var(--tint-gold-border); color: var(--gold-fg); }
.bhlb-pod-chev { flex: none; font-size: 8px; font-style: normal; color: var(--text-faint); transition: transform .15s ease; }
.bhlb-pod[open] .bhlb-pod-chev { transform: rotate(90deg); }
/* Le ruban de cartes de game passe AU-DESSUS de la carte « Moyenne », et non à côté : dans les
   ~260px utiles d'une carte de podium, les mettre sur une ligne ne laissait qu'une partie visible. */
.bhlb-pod-exp { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.bhlb-pod-exp .lb2-strip { min-width: 0; }
.bhlb-pod-exp .lb2-mc--avg { flex: none; }

/* Titre de section au-dessus du tableau complet */
.bhlb-tablehead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 0 56px 14px; }
.bhlb-tablehead h2 { margin: 0; font: 700 24px/1 var(--font-display); text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bhlb-tablehead span { font: 400 11px/1 var(--font-alt); color: var(--text-dim); }
.bhlb-tablewrap { padding: 0 56px 40px; }

@media (max-width: 900px) {
    .bhlb-winner, .bhlb-podium, .bhlb-tablehead, .bhlb-tablewrap { margin-left: 0; margin-right: 0; padding-left: 20px; padding-right: 20px; }
    .bhlb-podium { grid-template-columns: 1fr; }
    .bhlb-prize { align-items: flex-start; }
}

/* ─── Overlay OBS d'une équipe (écran 1e) ────────────────────────────────────
   Widget 470×92, posé tel quel dans OBS. THÈME-INDÉPENDANT PAR CONCEPTION : toujours sombre et
   opaque — un overlay transparent devient illisible sur neige, sable ou ciel (note de la maquette).
   C'est l'une des exceptions volontaires à la règle « tout en tokens » (au même titre que les zones
   toujours posées sur une photo). Seules les polices restent tokenisées. Trois états par classe :
   base (bleu) · .bhov--mp (Match Point, or) · .bhov--done (terminé, rang en or). */
.bhov {
    width: 470px; height: 92px; margin: 0;
    border-radius: var(--radius); overflow: hidden;
    background: #0b0e14; border: 1px solid #1f2b3a;
    display: flex; flex-direction: column;
    font-family: var(--font-alt); color: #f2f7ff;
}
/* Page transparente derrière l'overlay (le fond de marque du body bavait à travers, et les coins
   arrondis doivent laisser voir le flux dans OBS). :has est supporté par le Chromium récent d'OBS.
   🔴 La règle s'accroche à `.bhov-page` — le marqueur posé par OverlayLayout — et NON au widget
   `.bhov` : sinon, un exemplaire du widget posé ailleurs (démonstration de l'accueil) effacerait le
   fond de toute la page, sans erreur ni trace. Verrouillé par OverlayTransparencyScopeTests. */
.bhov-page { display: contents; }
/* ⚠️ Le fond ayant remonté sur `html`, c'est LUI qu'il faut rendre transparent : ne neutraliser
   que `body` laisserait l'overlay sur un aplat opaque et le flux OBS perdrait sa transparence,
   sans qu'aucun test de page ne s'en aperçoive. */
html:has(.bhov-page), html:has(.bhov-page) body { background: transparent; }
html:has(.bhov-page) body::before, html:has(.bhov-page) body::after { display: none; }
.bhov--mp { border-color: rgba(243, 194, 86, .6); }

.bhov-head { display: flex; align-items: center; gap: 8px; padding: 7px 12px 6px; border-bottom: 1px solid rgba(255, 255, 255, .07); }
.bhov--mp .bhov-head { border-bottom-color: rgba(243, 194, 86, .2); }
.bhov-mark { height: 14px; width: auto; display: block; }
.bhov-tour { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: #8b98ad; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bhov-spacer { flex: 1; }
.bhov-org { width: 14px; height: 14px; border-radius: 50%; background: #16324f; display: grid; place-items: center; font: 700 7px/1 var(--font-alt); color: #8cc6ff; flex: none; }
.bhov-state { font: 500 9px/1 var(--font-mono); color: #5a6879; white-space: nowrap; }
.bhov-state--done { color: #37d99a; font-weight: 600; }

.bhov-body { flex: 1; display: flex; align-items: center; gap: 11px; padding: 0 12px; }
.bhov-rank { font: 700 26px/1 var(--font-display); color: #3fb6ff; width: 34px; flex: none; }
.bhov--mp .bhov-rank, .bhov--done .bhov-rank { color: #f3c256; }
.bhov-team { width: 30px; height: 30px; border-radius: var(--radius); background: #111b2b; border: 1px solid #2b3849; display: grid; place-items: center; font: 700 13px/1 var(--font-display); color: #8cc6ff; flex: none; }
.bhov--mp .bhov-team { border-color: rgba(243, 194, 86, .5); color: #f3c256; }
.bhov-id { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.bhov-name { font: 700 17px/1 var(--font-display); text-transform: uppercase; color: #f4f7fc; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bhov-sub { display: inline-flex; align-items: center; gap: 5px; font: 500 8.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: #5a6879; }
.bhov-mpchip { height: 12px; padding: 0 5px; display: grid; place-items: center; border-radius: var(--radius); background: rgba(243, 194, 86, .2); font: 600 7.5px/1 var(--font-mono); color: #f3c256; }
.bhov-stats { display: flex; gap: 14px; flex: none; }
.bhov-stat { display: flex; flex-direction: column; gap: 3px; align-items: flex-end; }
.bhov-stat-lbl { font: 500 8px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: #5a6879; }
.bhov--mp .bhov-stat-lbl { color: #8a7440; }
.bhov-stat-val { font: 700 16px/1 var(--font-mono); color: #f4f7fc; }
.bhov--mp .bhov-stat-val { color: #f3c256; }

/* ─── Fiche tournoi publique (refonte broadcast, écran 1b) ───────────────────
   Page anonyme /tournaments/{id}. Hero + 5 axes + cagnotte + règlement à gauche, encart
   participants/conditions/multiplicateurs/Discord à droite. Tokens uniquement, clair+sombre.
   Titres var(--font-display), chiffres var(--font-mono). */
.bht { font-family: var(--font-alt); color: var(--text-body); }

.bht-hero { position: relative; overflow: hidden; padding: 30px 56px 0; border-bottom: 1px solid var(--border); }
.bht-hero::before { content: ""; position: absolute; inset: 0; background: var(--hero-halo); pointer-events: none; }

/* ─── Bandeau posé sur la bannière de l'organisation (US #754) ────────────────
   La fiche publique porte déjà le nom et le logo de l'organisation qui reçoit ; sa bannière passe
   derrière, comme sur la vue de gestion. Calque séparé : c'est LUI qui porte l'assombrissement, que
   le texte posé dessus ne doit pas subir. */
.bht-hero-bg { position: absolute; inset: 0; background-size: cover; background-position: center; filter: brightness(.32) saturate(.75); }
/* Le halo d'accent n'a plus rien à éclairer devant une photo : il la salirait sans se voir. */
.bht-hero--photo::before { display: none; }
/* Texte posé sur une PHOTO : il n'a plus de thème, il est clair dans les deux (même exception
   assumée que .tour-hero-* et le hero d'organisation). Les jetons sont reposés ici plutôt que
   chaque classe réécrite — fil d'Ariane, badges, titre, onglets et boutons suivent d'un coup. */
/* 🔴 Filet de sécurité : la zone reste sombre même si l'IMAGE manque (fichier supprimé, 404). La
   palette ci-dessous pose du texte clair — sans ce fond, une bannière introuvable le laisserait sur
   le fond de page, illisible en thème clair. Aplat sombre assumé, comme le repli du hero de gestion. */
.bht-hero--photo {
    background: #141e33;
    --text-primary: #fff;
    --text-bright: rgba(255,255,255,.94);
    --text-soft: rgba(255,255,255,.80);
    --text-dim: rgba(255,255,255,.66);
    --text-muted: rgba(255,255,255,.62);
    --bg-chip: rgba(255,255,255,.14);
    --bg-surface: rgba(0,0,0,.34);
    --border: rgba(255,255,255,.22);
    --border-hover: rgba(255,255,255,.38);
    --line-strong: rgba(255,255,255,.30);
}
.bht-crumb { position: relative; display: flex; align-items: center; gap: 8px; font: 400 11.5px/1 var(--font-alt); color: var(--text-dim); }
.bht-crumb a { color: var(--text-dim); }
.bht-crumb a:hover { color: var(--text-soft); }
.bht-hero-row { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; flex-wrap: wrap; margin-top: 20px; }
/* 🔴 `flex: 1 1 0`, pas la base `auto` par défaut : avec `auto`, la colonne réclamait la largeur de
   son titre ÉCRIT SUR UNE LIGNE. Un titre long (« PP CUSTOM RÉSURGENCE SWITCH TRIO MP 150 ») ne
   laissait plus de place aux actions, et `flex-wrap` les renvoyait À LA LIGNE — collées à GAUCHE,
   sous le titre. Base nulle : la colonne prend ce que les actions laissent, et le titre s'y replie. */
.bht-hero-l { display: flex; flex-direction: column; gap: 16px; min-width: 0; flex: 1 1 0; }
.bht-badges { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bht-badge { display: inline-grid; place-items: center; height: 26px; padding: 0 11px; border-radius: var(--radius); font: 600 11px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; background: var(--bg-chip); color: var(--text-soft); }
.bht-badge--gold { background: var(--tint-gold-bg-2); border: 1px solid var(--tint-gold-border); color: var(--gold-on-tint); }
.bht-title { margin: 0; font: 700 clamp(38px, 5vw, 62px)/.94 var(--font-display); letter-spacing: -.005em; text-transform: uppercase; color: var(--text-primary); }
.bht-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bht-org { display: inline-flex; align-items: center; gap: 8px; }
.bht-org-logo { width: 32px; height: 32px; border-radius: 50%; background: var(--accent-subtle); color: var(--accent-light); display: grid; place-items: center; font: 700 12px/1 var(--font-display); overflow: hidden; }
.bht-org-logo img { width: 100%; height: 100%; object-fit: cover; }
.bht-org-name { font: 600 13.5px/1 var(--font-alt); color: var(--text-bright); }
.bht-sep { width: 1px; height: 16px; background: var(--line-strong); }
.bht-metatxt { font: 500 11.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-soft); }
.bht-hero-r { display: flex; flex-direction: column; gap: 10px; align-items: flex-end; flex: none; }
.bht-cta { display: inline-grid; place-items: center; height: 42px; padding: 0 22px; border-radius: var(--radius); font: 600 13.5px/1 var(--font-alt); }

.bht-cta--ghost { border: 1px solid var(--border-hover); color: var(--text-bright); background: var(--bg-surface); }
.bht-cta--ghost:hover { border-color: var(--accent); }

/* Gestes d'organisateur dans le hero de la fiche, à la place de l'ancien « Gérer ce tournoi ».
   Ils s'empilent comme le reste de .bht-hero-r, mais passent en ligne dès qu'il y en a deux. */
.bht-hero-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 9px; }
.bht-cta--go { border: 0; background: var(--accent-gradient); color: #fff; cursor: pointer; text-decoration: none; white-space: nowrap; }
.bht-cta--go:hover:not(:disabled) { color: #fff; filter: brightness(1.08); }
.bht-cta--go:disabled { background: var(--bg-hover); color: var(--text-muted); cursor: default; }
.bht-cta-err { font: 500 11px/1.4 var(--font-alt); color: var(--red-soft-fg); max-width: 260px; text-align: right; }

/* Filet entre les trois onglets publics et les trois onglets d'organisateur : ils ne s'adressent
   pas au même lecteur, et rien d'autre ne le dit. */
/* Onglet indisponible : ÉTEINT, jamais effacé — sa condition doit se lire. */
.bht-tab--soon { color: var(--text-muted); cursor: default; display: inline-flex; align-items: baseline; gap: 7px; }
/* 🔴 LA MENTION D'INDISPONIBILITÉ N'EST PLUS RENDUE — l'onglet est DÉSACTIVÉ à la place. Mesuré :
   les trois mentions (« au verrouillage des équipes », « après le lancement », « verrouillés —
   inscriptions closes ») pesaient **377 px**, un tiers du rail, et le faisaient passer à deux lignes
   dès l'ajout de l'onglet Diffusion. Le rail retombe de 1114 px à 736 px.
   🔑 L'indisponibilité se lit désormais dans la FORME : couleur sourde, curseur inerte,
   `aria-disabled` pour les lecteurs d'écran, et la raison au survol par le `title`. */
.bht-tabs-sep { align-self: center; width: 1px; height: 16px; margin: 0 10px 13px; background: var(--border); flex: none; }
.bht-cap { font: 400 11px/1 var(--font-alt); color: var(--text-dim); }
/* 🔴 Le rail se REPLIE quand il ne tient plus — il n'est ni rogné, ni comprimé. Posé dans un
   .bht-hero en `overflow: hidden`, un flex d'une seule ligne se fait couper sans rien dire :
   mesuré à 375 px, les quatre onglets publics réclament 386 px pour 327 disponibles (« Joueurs »
   coupé de 35 px), et les six onglets d'organisateur en réclament 573 — « Déroulé » et
   « Réglages » tombent alors ENTIÈREMENT hors du cadre, sans aucun moyen de les atteindre. Or
   « Joueurs » porte la seule porte d'inscription de l'application.
   💡 Replier et non faire défiler, contrairement à .bhpp-tabs et .appnav-scroll : ces deux rails-là
   portent trois entrées courtes, celui-ci en porte jusqu'à SIX plus un filet. Un rail qui défile
   laisse en plus l'onglet actif hors champ à l'arrivée — sur /participants, « Joueurs » est le
   quatrième — et il faudrait du script pour l'y ramener. Replié, tout est visible et cliquable
   sans geste préalable. Sur grand écran rien ne déborde — vrai de nouveau depuis qu'un onglet
   indisponible est DÉSACTIVÉ au lieu de porter sa condition en clair (voir `.bht-tab--soon`). */
.bht-tabs { position: relative; display: flex; flex-wrap: wrap; gap: 12px 0; margin-top: 30px; border-bottom: 1px solid var(--border); }
/* `flex: none` d'abord : sans lui le plus large des onglets se fait comprimer et « Vue d'ensemble »
   se casse sur deux lignes pendant que ses voisins tiennent sur une. */
.bht-tab { padding: 0 16px 13px; font: 500 13px/1 var(--font-alt); color: var(--nav-ink); flex: none; white-space: nowrap; }
.bht-tab--active { color: var(--text-primary); font-weight: 600; box-shadow: inset 0 -2px 0 var(--accent-warm); }
.bht-tab:hover { color: var(--accent-light); }

.bht-grid { display: grid; grid-template-columns: 1fr 344px; }
.bht-main { padding: 36px 40px 48px 56px; display: flex; flex-direction: column; gap: 36px; }
.bht-side { border-left: 1px solid var(--border); padding: 36px 56px 48px 28px; display: flex; flex-direction: column; gap: 26px; }
.bht-h2 { margin: 0 0 16px; font: 700 24px/1 var(--font-display); text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bht-h3 { margin: 0 0 14px; font: 700 20px/1 var(--font-display); text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }

/* 5 axes */
.bht-axes { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.bht-axis { display: flex; flex-direction: column; gap: 9px; padding: 16px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); }
.bht-axis--accent { border-color: var(--accent); background: linear-gradient(180deg, var(--accent-subtle), var(--bg-surface)); }
.bht-axis--gold { border-color: var(--tint-gold-border); background: linear-gradient(180deg, var(--tint-gold-bg), var(--bg-surface)); }
.bht-axis-k { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bht-axis--accent .bht-axis-k { color: var(--accent-light); }
.bht-axis--gold .bht-axis-k { color: var(--gold-on-tint); }
.bht-axis-v { font: 700 24px/1 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bht-axis-s { font: 400 10.5px/1 var(--font-alt); color: var(--text-faint); }

/* Cagnotte */
.bht-prize { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.bht-prize-net { padding: 22px; border: 1px solid var(--border); border-radius: var(--radius); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.bht-prize-big { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
/* 🔴 `clamp` et non 42px figés : c'est la DONNÉE qui décide de la largeur ici, pas la maquette.
   « 1 000 000 € » en mono à 42px mesure ~275px ; avec les 2×22px de .bht-prize-net et les 2×24px de
   .bht-main, le bloc réclamait 344px pour une piste de 301 à 360px de fenêtre, et poussait la fiche
   entière. Mesuré sur la finale Esport World Cup. Une cagnotte à six ou sept chiffres suffit — le
   défaut ne dépend donc pas de l'écran seul et n'apparaît jamais sur les tournois de démonstration.
   La borne haute reste la valeur de la maquette : rien ne bouge au-dessus de ~1000px. */
.bht-prize-big span:first-child { font: 700 clamp(26px, 7.2vw, 42px)/1 var(--font-mono); color: var(--accent-light); }
.bht-prize-big span:last-child { font: 500 10.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bht-prize-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border); }
.bht-prow { display: flex; justify-content: space-between; gap: 12px; }
.bht-prow span:first-child { font: 400 12px/1.2 var(--font-alt); color: var(--text-body); }
.bht-prow span:last-child { font: 500 12px/1 var(--font-mono); color: var(--text-bright); }
.bht-prow--total { padding-top: 8px; border-top: 1px dashed var(--line-strong); }
.bht-prow--total span { font-weight: 700; }
.bht-prow--minus span:last-child { color: var(--red2-fg); }
.bht-rewards { display: flex; flex-direction: column; gap: 10px; }
.bht-reward { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); }
.bht-reward--1 { border-color: var(--tint-gold-border); background: linear-gradient(100deg, var(--tint-gold-bg), var(--bg-surface)); }
.bht-reward-pos { font: 700 20px/1 var(--font-display); color: var(--text-soft); width: 26px; }
.bht-reward--1 .bht-reward-pos { color: var(--gold-fg); }
.bht-reward-l { flex: 1; display: flex; flex-direction: column; gap: 4px; }
.bht-reward-l b { font: 600 13px/1 var(--font-alt); color: var(--text-primary); }
.bht-reward-l span { font: 400 10.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-dim); }
.bht-reward-amt { font: 700 22px/1 var(--font-mono); color: var(--text-bright); }
.bht-reward--1 .bht-reward-amt { color: var(--gold-fg); }

/* Règlement */
.bht-rules { padding: 22px 24px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); }
.bht-rules p { margin: 0; font: 400 12.5px/1.7 var(--font-alt); color: var(--text-body); white-space: pre-wrap; }
/* Présentation : texte libre de l'organisateur, sauts de ligne conservés comme dans la zone de saisie. */
.bht-desc { margin: 0; font: 400 14px/1.7 var(--font-alt); color: var(--text-body); white-space: pre-wrap; overflow-wrap: anywhere; }

/* Sidebar */
.bht-part { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.bht-part-av { width: 26px; height: 26px; border-radius: 50%; background: var(--accent-subtle); color: var(--accent-light); display: grid; place-items: center; font: 600 10px/1 var(--font-alt); overflow: hidden; flex: none; }
.bht-part-av img { width: 100%; height: 100%; object-fit: cover; }
.bht-part-n { flex: 1; font: 500 12.5px/1 var(--font-alt); color: var(--text-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bht-part-w { height: 20px; padding: 0 8px; display: grid; place-items: center; border-radius: var(--radius); background: var(--tint-gold-bg); font: 600 9.5px/1 var(--font-mono); color: var(--gold-on-tint); }
/* Colonne défilable : un gros lobby (48 joueurs) ne doit pas étirer la colonne à l'infini. */
.bht-partlist, .bht-teamlist { display: flex; flex-direction: column; max-height: 360px; overflow-y: auto; margin-top: 2px; }
/* Lignes « équipe » (formations constituées) — même gabarit que les joueurs, logo à la place de l'avatar. */
.bht-team { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.bht-team-logo { width: 26px; height: 26px; border-radius: var(--radius); background: var(--bg-chip); color: var(--accent-light); display: grid; place-items: center; font: 700 10px/1 var(--font-display); overflow: hidden; flex: none; }
.bht-team-logo img { width: 100%; height: 100%; object-fit: cover; }
.bht-team-n { flex: 1; font: 600 12.5px/1.2 var(--font-alt); color: var(--text-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bht-team-tag { font: 500 10px/1 var(--font-mono); text-transform: uppercase; color: var(--text-muted); flex: none; }
.bht-team-c { font: 500 11px/1 var(--font-mono); color: var(--text-muted); flex: none; }
.bht-cond { display: flex; flex-direction: column; gap: 11px; }
.bht-cond-row { display: flex; justify-content: space-between; gap: 12px; }
.bht-cond-row span:first-child { font: 400 12px/1.3 var(--font-alt); color: var(--text-soft); }
.bht-cond-row span:last-child { font: 500 12px/1 var(--font-mono); color: var(--text-bright); text-align: right; }
.bht-mult { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 10px; }
.bht-mult-c { display: flex; flex-direction: column; gap: 4px; padding: 9px 6px; border-radius: var(--radius); background: var(--bg-surface); text-align: center; }
.bht-mult-c span:first-child { font: 500 10px/1 var(--font-mono); color: var(--text-dim); }
.bht-mult-c span:last-child { font: 700 13px/1 var(--font-mono); color: var(--text-bright); }
.bht-discord { display: flex; gap: 12px; padding: 16px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg-elevated); }
.bht-discord-ic { width: 30px; height: 30px; border-radius: var(--radius); background: var(--indigo-fg); display: grid; place-items: center; color: var(--on-accent); flex: none; }
.bht-discord-b { display: flex; flex-direction: column; gap: 7px; }
.bht-discord-b b { font: 600 12.5px/1.3 var(--font-alt); color: var(--text-bright); }
.bht-discord-b span { font: 400 11px/1.5 var(--font-alt); color: var(--text-soft); }
.bht-muted { font: 400 12px/1.5 var(--font-alt); color: var(--text-dim); }

@media (max-width: 1000px) {
    .bht-grid { grid-template-columns: 1fr; }
    .bht-side { border-left: none; border-top: 1px solid var(--border); }
    .bht-main, .bht-side { padding-left: 24px; padding-right: 24px; }
    .bht-hero { padding-left: 24px; padding-right: 24px; }
    .bht-axes { grid-template-columns: repeat(2, 1fr); }
    .bht-prize { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
    .bht-axes { grid-template-columns: 1fr; }
    /* Seul endroit où les actions passent SOUS le titre : la colonne de gauche reprend toute la
       largeur, ce que sa base nulle ne ferait plus d'elle-même. */
    .bht-hero-l { flex-basis: 100%; }
    .bht-hero-r { align-items: flex-start; }
    /* Sous cette largeur, le rail de l'organisateur ne tient plus d'une pièce (573 px de contenu
       pour 572 disponibles au plus). Le filet cesse alors d'être un trait vertical et devient un
       SAUT DE LIGNE : il sépare toujours les onglets publics de ceux de l'organisateur — ils ne
       s'adressent pas au même lecteur — mais en les posant sur deux rangs. Le repli naturel les
       aurait coupés n'importe où au milieu. */
    .bht-tabs-sep { flex-basis: 100%; width: auto; height: 0; margin: 0; background: none; }
}

/* ─── Tableau matriciel du classement public (écran 1c) ──────────────────────
   Une ligne par formation, une colonne par partie (P1..Pn) + total + Match Point. Reprend à la
   4ᵉ place (le podium montre le top 3). Rendu en propre sur la page publique (pas via LeaderboardView,
   partagé). Tokens only, clair+sombre. Le nombre de colonnes P est dynamique → grid-template-columns
   posé en inline sur les lignes. */
.bhmx { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--bg-surface); }
.bhmx-scroll { overflow-x: auto; }
.bhmx-head, .bhmx-row { display: grid; align-items: center; gap: 0; padding: 11px 16px; }
.bhmx-head { background: var(--bg-inset); border-bottom: 1px solid var(--border); }
.bhmx-head span { font: 500 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.bhmx-head .c { text-align: center; }
.bhmx-head .t { text-align: right; color: var(--accent-light); }
.bhmx-head .r { text-align: right; }
.bhmx-row { padding-top: 13px; padding-bottom: 13px; border-bottom: 1px solid var(--line-soft); }
.bhmx-row:last-child { border-bottom: none; }
.bhmx-place { font: 700 16px/1 var(--font-mono); color: var(--text-soft); }
.bhmx-team { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bhmx-tnum { width: 28px; height: 28px; flex: none; border-radius: var(--radius); background: var(--bg-inset); border: 1px solid var(--line-strong); display: grid; place-items: center; font: 700 11.5px/1 var(--font-display); color: var(--text-soft); overflow: hidden; }
.bhmx-tnum img { width: 100%; height: 100%; object-fit: cover; }
.bhmx-tnum--logo { border: none; background: none; }
.bhmx-lineup { font: 400 13.5px/1.3 var(--font-alt); color: var(--text-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bhmx-g { font: 400 13.5px/1 var(--font-mono); color: var(--text-body); text-align: center; }
.bhmx-g--empty { color: var(--text-faint); }
.bhmx-total { font: 700 15px/1 var(--font-mono); color: var(--text-primary); text-align: right; }
.bhmx-mp { justify-self: end; }
.bhmx-mp-badge { display: inline-grid; place-items: center; height: 22px; padding: 0 10px; border-radius: var(--radius); background: var(--tint-gold-bg); border: 1px solid var(--tint-gold-border); font: 600 10px/1 var(--font-mono); text-transform: uppercase; color: var(--gold-on-tint); }
.bhmx-mp-none { font: 400 13px/1 var(--font-mono); color: var(--text-faint); }

/* Ligne dépliable de la matrice (Bogue #876). La bordure passe sur le CONTENEUR : laissée sur la
   ligne, elle se glisserait entre l'en-tête de formation et ses propres cartes, qui se liraient
   alors comme la ligne suivante. Le Top Kills, lui, garde `.bhmx-row` nu — d'où le scope. */
.bhmx-rowx { border-bottom: 1px solid var(--line-soft); }
.bhmx-rowx:last-child { border-bottom: none; }
.bhmx-rowx > .bhmx-row { border-bottom: none; cursor: pointer; list-style: none; }
.bhmx-rowx > .bhmx-row::-webkit-details-marker { display: none; }
.bhmx-rowx > .bhmx-row:hover { background: var(--bg-inset); }
.bhmx-chev { flex: none; font-size: 8px; font-style: normal; color: var(--text-faint); transition: transform .15s ease; }
.bhmx-rowx[open] > .bhmx-row .bhmx-chev { transform: rotate(90deg); }
.bhmx-rowx[open] > .bhmx-row { background: var(--bg-inset); }
.bhmx-exp { display: flex; align-items: stretch; gap: 10px; padding: 0 16px 15px; }

/* Top Kills — MÊME tableau que la matrice, à quatre colonnes. Il était rendu en liste compacte
   à deux colonnes, sans en-tête ni équipe : deux tableaux de la même page se lisaient de deux
   façons différentes. Il réutilise donc .bhmx / .bhmx-head / .bhmx-row tels quels, et n'ajoute
   que la teinte de la colonne d'équipe.
   🔴 Son titre n'est PLUS un bandeau intégré au cadre (.bhmx-caption, supprimée) : il vit AU-DESSUS,
   dans le .bhlb-tablehead partagé avec la matrice, et son cadre dans un .bhlb-tablewrap à lui. Deux
   tableaux de la même page se lisaient encore de deux façons — l'un titré dehors, l'autre dedans.
   Partager les conteneurs garantit l'identité : il n'y a plus deux jeux de règles à tenir d'accord.
   ⚠️ Ne pas remettre d'espacement propre ici : la gouttière au-dessus du titre est le padding bas du
   wrap précédent, celle sous le titre la marge du tablehead. Une marge de plus décalerait ce seul
   tableau. La classe .bhmx--kills reste posée dans le balisage sans règle propre : elle n'y est
   plus que comme sélecteur des tests. */
.bhmx-kteam { color: var(--text-soft); }

/* ─── Emblèmes de badges dessinés (écran 2a) ─────────────────────────────────
   Écu identique pour les 14, glyphe géométrique centré, ornements cumulatifs. Dessin CSS pur
   (clip-path + formes), pas d'image. L'écu est un médaillon SOMBRE par nature (comme les PNG de
   rang) → couleurs d'art fixes, valables sur les deux thèmes ; seule la tuile est tokenisée. Deux
   familles : dérivés (bleu acier) et événementiels (or). Lisible jusqu'à ~28 px (contrainte overlay). */
.bhbg-shield { position: relative; width: 52px; height: 57px; flex: none; }
.bhbg-shield-o { position: absolute; inset: 0; clip-path: polygon(50% 0%, 100% 24%, 100% 74%, 50% 100%, 0 74%, 0 24%); background: linear-gradient(160deg, #3f5a7d, #131c29); }
.bhbg-shield-i { position: absolute; inset: 2px; clip-path: polygon(50% 0%, 100% 24%, 100% 74%, 50% 100%, 0 74%, 0 24%); background: linear-gradient(160deg, #16202f, #0a1019); }
.bhbg--evt .bhbg-shield-o { background: linear-gradient(160deg, #f3c256, #7d5f1d); }
.bhbg--evt .bhbg-shield-i { background: linear-gradient(160deg, #241c0c, #0e0a04); }
.bhbg-glyph { position: absolute; inset: 0; display: grid; place-items: center; }
/* Gemmes et traits géométriques (couleurs d'art). */
.bhbg-d { display: block; transform: rotate(45deg); background: #b6d3f2; }
.bhbg--evt .bhbg-d, .bhbg--evt .bhbg-c, .bhbg--evt .bhbg-b { background: #f3c256; }
.bhbg-b { display: block; background: #8fb8e6; }
.bhbg-c { display: block; border-top: 2.5px solid #b6d3f2; border-right: 2.5px solid #b6d3f2; transform: rotate(-45deg); }
.bhbg--evt .bhbg-c { border-color: #f3c256; }
.bhbg-ring { display: grid; place-items: center; border: 2.5px solid #8fb8e6; border-radius: 50%; }
.bhbg--evt .bhbg-ring { border-color: #f3c256; }
.bhbg-row { display: flex; align-items: center; justify-content: center; gap: 4px; }
.bhbg-col { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; }

/* ─── Alertes ───────────────────────────────────────────── */
.alert-error {
    padding: 10px 14px;
    background: var(--tint-red-bg);
    color: var(--red-soft-fg);
    border-radius: var(--radius);
    font-size: 13px;
}

/* ─── Adresse email non confirmée (US #504) ─────────────── */
/* Aplat doré : un rappel, pas une erreur. Le rouge est réservé à ce qui a échoué — ici le compte
   fonctionne, seule l'inscription à un tournoi est fermée tant que l'adresse n'est pas prouvée. */
.verify-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: var(--shell-pad);
    padding: 10px 14px;
    background: var(--tint-gold-bg-2);
    border: 1px solid var(--tint-gold-border);
    border-radius: var(--radius);
    font-size: 13px;
    color: var(--text-body);
}

.verify-banner-icon {
    flex: none;
    font-size: 20px;
    color: var(--gold-on-tint);
}

.verify-banner-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.verify-banner-text strong { color: var(--gold-on-tint); }

.verify-banner-btn {
    flex: none;
    margin-left: auto;
    padding: 6px 14px;
    background: transparent;
    border: 1px solid var(--tint-gold-border);
    border-radius: var(--radius);
    color: var(--gold-on-tint);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.verify-banner-btn:hover:not(:disabled) { background: var(--bg-surface-hover); }
.verify-banner-btn:disabled { opacity: .6; cursor: default; }

.verify-banner-sent {
    flex: none;
    margin-left: auto;
    color: var(--green-fg);
    font-weight: 600;
}

@media (max-width: 640px) {
    /* Sous 640 px le bouton chassait le texte sur trois lignes : on empile. */
    .verify-banner { flex-wrap: wrap; }
    .verify-banner-btn,
    .verify-banner-sent { margin-left: 0; }
}

/* Page /email-verified : bloc centré, autonome du gabarit d'auth (voir le commentaire de la page) */
.verify-page {
    max-width: 460px;
    margin: 48px auto;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.verify-page-title {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    color: var(--text-primary);
}

.verify-page-text {
    margin: 0;
    font-size: 14px;
    color: var(--text-secondary);
}

.verify-page .btn-primary { margin-top: 8px; }

/* Pastille de résultat de la page /email-verified */
.verify-result {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin: 0 auto 4px;
    border-radius: 50%;
    font-size: 30px;
}

.verify-result--ok {
    background: var(--tint-green-bg);
    border: 1px solid var(--tint-green-border);
    color: var(--green-fg);
}

.verify-result--ko {
    background: var(--tint-gold-bg-2);
    border: 1px solid var(--tint-gold-border);
    color: var(--gold-on-tint);
}

/* ─── Bandeau d'erreur Blazor (circuit perdu) ───────────── */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
    padding: 10px 20px;
    background: var(--tint-red-bg);
    color: var(--red-soft-fg);
    font-size: 13px;
    box-shadow: 0 -1px 4px var(--shadow-strong);
}

#blazor-error-ui .reload {
    color: var(--accent-light, var(--accent-light));
    margin-left: 12px;
    text-decoration: underline;
    cursor: pointer;
}

.alert-success {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--tint-lime-bg);
    color: var(--lime-fg);
    border-radius: var(--radius);
    font-size: 14px;
}

.alert-welcome {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--tint-lime-bg);
    color: var(--lime-fg);
    border-radius: var(--radius);
    font-size: 14px;
    margin-bottom: 8px;
}

/* ─── Profile ───────────────────────────────────────────── */
.profile-layout {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding-bottom: 24px;
}

.profile-form-wrapper {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.profile-info {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 4px 0;
}

.avatar-img {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
}

.avatar-initials {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    font-weight: 500;
}

.avatar-upload-form {
    display: contents;
}

/* Encadré des avatars et logos : il n'appartient qu'au repli.

   La convention du fichier est que le cadre (fond, bordure, liseré) est porté par l'élément
   d'initiales — .avatar-initials, .org-card-logo-initials, .team-crest-initials… — et jamais par le
   conteneur partagé. Cinq conteneurs de logo s'en écartaient et peignaient leur pastille sous
   l'image elle-même. Comme les logos sont très souvent des PNG ronds à fond transparent, le cadre
   se voyait dans les quatre coins : un rond posé sur un carré sombre.

   Ces règles les réalignent. Le repli garde sa pastille (aucun sélecteur ne l'atteint), l'image
   n'a plus rien derrière elle. */
.bhadm-org-logo:has(img), .org-detail-logo:has(img), .bhog-staff-av:has(img),
.bhtm-avatar:has(img), .team-member-avatar:has(img) {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
}

/* L'avatar remplit sa pastille. `.avatar-img` mesure 56px — la taille du profil — alors que ces
   deux conteneurs-ci font 30 et 34px : sans cette règle, la photo déborderait de son rond. Même
   forme que `.search-result-avatar .avatar-img`, plus haut. */
.bhtm-avatar img, .team-member-avatar img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.profile-avatar--editable {
    position: relative;
    display: inline-flex;
    cursor: pointer;
    border-radius: 50%;
}

.profile-avatar--editable:hover .avatar-img,
.profile-avatar--editable:hover .avatar-initials {
    filter: brightness(0.75);
}

.avatar-add-btn {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 14px;
    line-height: 18px;
    text-align: center;
    pointer-events: none;
    box-shadow: 0 0 0 2px var(--bg-panel);
}

.profile-name {
    font-size: 16px;
    font-weight: 500;
    color: var(--text-primary);
}

.profile-email {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 2px;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

@media (max-width: 720px) {
    .form-grid { grid-template-columns: 1fr; }
}

.form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 24px;
}

.btn-save {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 24px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: var(--radius);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s;
}

.btn-save:hover:not(:disabled) { background: var(--accent-hover); }
/* Sans cette règle, un bouton désactivé est indiscernable d'un bouton actif : on clique et
   rien ne se passe, sans savoir ce qui manque. Même convention que .btn-danger:disabled. */
.btn-save:disabled { opacity: 0.5; cursor: default; }

/* ─── Invitation à lier son compte Discord (US #227) ─────
   Le bleu Discord est une couleur de MARQUE : exception assumée à la règle « tout par tokens »,
   au même titre que les pastilles sociales ci-dessus. Le reste (texte, surface) suit les tokens,
   donc le bandeau reste lisible dans les deux thèmes. */
.discord-link-notice {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
    padding: 10px 14px;
    border: 0.5px solid rgba(88, 101, 242, 0.35);
    border-left: 3px solid #5865F2;
    border-radius: var(--radius);
    background: rgba(88, 101, 242, 0.08);
    font-size: 13px;
    color: var(--text-secondary);
}

.discord-link-notice i { color: #5865F2; font-size: 18px; flex-shrink: 0; }
.discord-link-notice span { flex: 1; }

.discord-link-notice a {
    color: var(--discord-link);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.discord-link-notice a:hover { text-decoration: underline; }

/* ─── Bannières (profil & joueur) ───────────────────────── */
/* Joueur sans bannière : le hero garde un fond de bannière plutôt qu'une surface nue.
   (Le hero lui-même est défini plus haut, avec son voile.) */
.profile-banner--empty {
    background-image: linear-gradient(120deg, var(--avatar-flat) 0%, #243660 60%, var(--bg-surface) 100%);
}
/* Pas de liseré sur le CONTENEUR : il était carré (rayon 16px) autour d'un avatar rond, donc
   visible aux quatre coins — un carré sombre derrière la pastille. Le liseré appartient à l'avatar
   lui-même (`.player-card-avatar .avatar-img/.avatar-initials`, plus haut), qui est rond et le
   porte déjà en 0 0 0 3px surface + 4px bordure. Même convention que les conteneurs de logo
   neutralisés plus haut : le cadre n'appartient jamais au conteneur partagé. */

/* Bannière éditable (profil) */
.profile-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 120px;
    border-radius: var(--radius);
    background-size: cover;
    background-position: center;
    margin-bottom: 16px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    border: 0.5px solid var(--border);
}
.profile-banner-edit {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: var(--radius);
    background: rgba(0,0,0,0.55);
    color: #fff;
    font-size: 12px;
    font-weight: 500;
    opacity: 0;
    transition: opacity 0.15s;
}
.profile-banner:hover .profile-banner-edit { opacity: 1; }

/* Logo éditable (organisation) */
.org-logo-upload { position: relative; display: inline-flex; cursor: pointer; border-radius: var(--radius); }
.org-logo-upload:hover .org-card-logo-img,
.org-logo-upload:hover .org-card-logo-initials { filter: brightness(0.7); }
.org-logo-edit {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    box-shadow: 0 0 0 2px var(--bg-surface);
}

/* ─── Boutons & utilitaires complémentaires ─────────────── */
/* .btn-ghost / .btn-danger canonical definitions live in "btn-ghost / btn-danger / btn-success" below — kept as one source of truth so hover states stay a soft tint, never a solid fill. */

.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    background: transparent;
    color: var(--text-muted);
    border: 0.5px solid var(--border-input);
    border-radius: var(--radius);
    cursor: pointer;
    /* La boîte est figée (30×30) mais l'icône, elle, suit la taille de police : sans cette
       ligne, l'héritage (bloc de base) la porterait à 16px dans des lignes denses — effectif
       d'équipe, barèmes, paliers — où elle voisine des boutons de 13px. */
    font-size: 13px;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.btn-icon:hover { background: rgba(var(--overlay-rgb),0.05); color: var(--text-primary); }
.btn-icon--danger:hover { background: rgba(226,75,74,0.15); color: var(--red-fg); border-color: rgba(226,75,74,0.4); }

.page-loading { display: flex; justify-content: center; padding: 48px; color: var(--text-muted); font-size: 28px; }
.spin { animation: bh-spin 0.9s linear infinite; }

/* Retour de Checkout : une carte centrée, un seul message à la fois. Volontairement sobre — la
   page ne propose aucune action sur le paiement, elle CONSTATE. Un écran chargé de boutons y
   inviterait à « relancer », c'est-à-dire à réclamer un droit depuis le navigateur du client. */
.bhret { display: grid; place-items: center; min-height: 60vh; padding: 32px 16px; }
.bhret-card { max-width: 520px; padding: 32px; border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--bg-inset); text-align: center; }
.bhret-card--ok { box-shadow: inset 0 3px 0 var(--green-fg); }
.bhret-card--wait { box-shadow: inset 0 3px 0 var(--accent); }
.bhret-icon { display: block; margin: 0 auto 12px; font-size: 34px; color: var(--text-muted); }
.bhret-card--ok .bhret-icon { color: var(--green-fg); }
.bhret-h1 { margin: 0 0 10px; font: 600 20px/1.3 'Archivo', sans-serif; color: var(--text-bright); }
.bhret-text { margin: 0 0 20px; font: 400 13.5px/1.65 'Archivo', sans-serif; color: var(--text-body); }
.bhret-card > :last-child { margin-bottom: 0; }
/* Deux sorties au lieu d'une : revenir a l'abonnement, ou nous ecrire si rien n'a bouge. Deux
   .btn-link cote a cote se touchent (padding: 0) -- flex + gap, et flex-wrap parce que la carte
   fait 520px au plus et que les deux libelles sont longs en anglais. Aucune couleur ici : les
   liens portent deja .btn-link, qui suit le theme. */
.bhret-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 20px; }

@keyframes bh-spin { to { transform: rotate(360deg); } }

textarea {
    width: 100%;
    background: var(--bg-input);
    border: 0.5px solid var(--border-input);
    border-radius: var(--radius);
    padding: 8px 12px;
    font-size: 13px;
    font-family: inherit;
    color: var(--text-primary);
    resize: vertical;
}
textarea:focus { outline: none; border-color: var(--accent); }

/* ─── Organisations : grille de cartes ──────────────────── */
/* La grille d'équipes est identique à celle des organisations : on regroupe plutôt
   que de dupliquer, pour qu'un ajustement de gabarit reste unique. */
.org-grid, .team-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 12px;
}

.org-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.15s, transform 0.1s, background 0.15s;
}
.org-card:hover {
    border-color: var(--border-hover);
    transform: translateY(-1px);
    background: radial-gradient(120% 160% at 0% 0%, var(--accent-subtle) 0%, transparent 60%), var(--bg-surface);
}

.org-card-logo, .org-card-logo-img, .org-card-logo-initials {
    width: 48px;
    height: 48px;
    border-radius: var(--radius);
    flex-shrink: 0;
}
.org-card-logo-img { object-fit: cover; }
.org-card-logo-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font-size: 16px;
    font-weight: 600;
}

.org-card-body { flex: 1; min-width: 0; }
.org-card-name {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.badge-inactive {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
    background: rgba(var(--overlay-rgb),0.07);
    color: var(--text-muted);
    border: 1px solid rgba(var(--overlay-rgb),0.1);
    vertical-align: middle;
}

.org-card--inactive {
    border-color: rgba(var(--overlay-rgb),0.05);
    background: repeating-linear-gradient(
        -45deg,
        transparent,
        transparent 18px,
        rgba(var(--overlay-rgb),0.015) 18px,
        rgba(var(--overlay-rgb),0.015) 19px
    );
    opacity: 0.85;
}

.org-card--inactive .org-card-logo-initials {
    background: rgba(var(--overlay-rgb),0.06);
    color: var(--text-muted);
}
.org-card-desc {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.org-card-meta { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.org-card-meta-item { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); }
.org-card-chevron { color: var(--text-hint); font-size: 18px; flex-shrink: 0; }

.org-role-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
}
.org-role-badge--admin { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.org-role-badge--member { color: var(--accent); background: var(--accent-subtle); }

/* Label « Confiance » : badge « vérifié » bleu, distinct du flag de sanction (doré/rouge). */
.org-trust-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    color: var(--sky-fg);
    background: var(--tint-blue-bg);
    vertical-align: middle;
    white-space: nowrap;
}
.org-trust-badge i { font-size: 13px; }
.org-trust-badge--compact { padding: 3px; gap: 0; }
.org-trust-badge--compact i { font-size: 15px; }

/* Pastille « Organisation fondatrice » : doré, la teinte de la distinction (1ʳᵉ place, champion),
   pas celle de l'alerte. --gold-on-tint et --tint-gold-bg-2 sont la paire dont le contraste est
   garanti en clair comme en sombre ; --gold-fg n'y mesure que 4,41:1, sous le seuil AA. */
.org-founder-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    color: var(--gold-on-tint);
    background: var(--tint-gold-bg-2);
    vertical-align: middle;
    white-space: nowrap;
}
.org-founder-badge i { font-size: 13px; }
.org-founder-badge--compact { padding: 3px; gap: 0; }
.org-founder-badge--compact i { font-size: 15px; }

.org-create-panel { margin-bottom: 16px; }

/* ─── Organisation : page détail ────────────────────────── */
/* ⚠️ PAS d'overflow:hidden ici. La carte contient la recherche de membre, dont la liste
   déroulante est en position:absolute : un overflow:hidden sur un ancêtre la DÉCOUPE, quel que
   soit son z-index. Elle n'apparaissait plus que sur une ligne et demie, tronquée par le bas de
   la carte. Le découpage aux coins arrondis est donc porté par les seuls éléments qui en ont
   besoin — le hero en haut, la barre d'enregistrement en bas — et non par le conteneur. */
.org-detail-card {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    width: 100%;
}

/* Hero = bannière + contenu fusionnés.
   Porte lui-même l'arrondi haut : c'est sa propre image de fond qu'il faut découper, et la carte
   ne peut plus s'en charger (voir .org-detail-card). */
.org-detail-hero {
    position: relative;
    min-height: 190px;
    background-size: cover;
    background-position: center;
    border-radius: var(--radius) var(--radius) 0 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
.org-detail-hero--empty {
    background-image: linear-gradient(120deg, var(--avatar-flat) 0%, #243660 60%, var(--bg-surface) 100%);
}
.org-detail-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(0,0,0,0.08) 0%, rgba(0,0,0,0.55) 100%);
    /* Même arrondi que le hero : le voile est un calque distinct, il déborderait sinon des coins. */
    border-radius: inherit;
    pointer-events: none;
}

/* Bouton modifier la bannière — positionné en haut à droite */
.org-banner-edit-btn {
    position: absolute;
    top: 12px;
    right: 12px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: var(--radius);
    background: rgba(0,0,0,0.50);
    backdrop-filter: blur(6px);
    color: rgba(255,255,255,0.85);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    border: 0.5px solid rgba(255,255,255,0.15);
    transition: background 0.15s, color 0.15s;
    /* 🔴 STRICTEMENT SUPÉRIEUR à celui de .org-detail-hero-content, et pas seulement « posé ».
       À valeur égale, c'est le DERNIER du DOM qui passe devant : le contenu du hero étant écrit
       APRÈS ce formulaire dans OrganizationDetail.razor, il recouvrait le coin haut-droit dès que
       la description de l'organisation montait assez haut. Le bouton restait PARFAITEMENT VISIBLE
       — son fond est transparent — mais n'attrapait plus le clic : ni sélecteur de fichiers, ni
       survol, ni erreur, ni requête. Bogue #1196 : VALAHLLA TOURNAMENT n'a jamais pu poser sa
       bannière en production, et le log nginx ne portait aucun POST. Le jumeau
       .team-banner-edit-btn était déjà à 2 et n'a jamais eu le défaut ; OrgHeroEditButtonCssTests
       compare désormais les deux valeurs. */
    z-index: 2;
}
.org-banner-edit-btn:hover {
    background: rgba(0,0,0,0.70);
    color: #fff;
}

/* Contenu du hero (logo + identité + actions) */
.org-detail-hero-content {
    position: relative;
    display: flex;
    align-items: flex-end;
    gap: 16px;
    padding: 16px 24px;
    z-index: 1;
}
.org-detail-logo, .org-detail-logo .org-card-logo-img, .org-detail-logo .org-card-logo-initials {
    width: 80px;
    height: 80px;
    border-radius: var(--radius);
    font-size: 26px;
    flex-shrink: 0;
    box-shadow: 0 0 0 3px rgba(255,255,255,0.12), 0 4px 12px rgba(0,0,0,0.4);
}
.org-detail-identity { flex: 1; min-width: 0; }
.org-detail-name-row { display: flex; align-items: center; gap: 10px; }
.org-detail-name { font-size: 22px; font-weight: 600; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,0.5); }
.org-detail-desc { font-size: 13px; color: rgba(255,255,255,0.75); margin-top: 4px; }
.org-detail-meta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; }
.org-detail-meta .org-card-meta-item { color: rgba(255,255,255,0.65); }
.org-detail-actions { flex-shrink: 0; align-self: flex-end; }

@media (max-width: 640px) {
    .org-detail-hero-content { flex-direction: column; align-items: flex-start; }
    .org-detail-actions { align-self: stretch; }
}

.org-status-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
}
.org-status-badge--inactive { color: var(--text-muted); background: rgba(var(--overlay-rgb),0.06); }

.org-detail-section { padding: 20px 24px; border-top: 0.5px solid var(--border); }
.org-detail-section.org-tournament-history { padding: 24px; }
.org-detail-section.org-danger-zone { padding: 10px 24px; }

/* ─── Onglet « Abonnement » d'une organisation (US #803) ────────────────────────────────────────
   Écran CLIENT, pas console : une carte lisible plutôt qu'un tableau. L'organisation n'a qu'un
   abonnement à la fois, il n'y a donc jamais de liste à aligner. */
.bhsub { display: flex; flex-direction: column; gap: 14px; }
.bhsub-card { padding: 18px 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-inset); }
.bhsub-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.bhsub-h3 { margin: 0; font: 600 15px/1.3 'Archivo', sans-serif; color: var(--text-bright); }
.bhsub-h4 { margin: 16px 0 8px; font: 600 12px/1.3 'Archivo', sans-serif; color: var(--text-bright); }

/* Carte « Organisation fondatrice » : un filet doré à gauche, la marque de distinction déjà employée
   par la ligne du vainqueur. Aucun fond propre — c'est une reconnaissance, pas une alerte, et un
   aplat la ferait lire comme un avertissement au milieu des cartes de facturation. */
.bhsub-card--founder { box-shadow: inset 3px 0 0 var(--gold-fg); }
/* Le titre porte la pastille : sans flex, l'icône se pose sur la ligne de base et décale le texte. */
.bhsub-card--founder .bhsub-h3 { display: flex; align-items: center; gap: 8px; }
.bhsub-text { margin: 0; font: 400 13px/1.6 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-empty { margin: 0; font: 400 12px/1.5 'Archivo', sans-serif; color: var(--text-muted); }

/* La pastille dit si les droits sont OUVERTS, pas quel est le statut : un abonnement résilié sert
   jusqu'à son terme, et l'afficher en éteint ferait croire au client qu'il a déjà tout perdu. */
.bhsub-pill { padding: 3px 10px; border-radius: var(--radius); font: 600 9.5px/1.4 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; }
.bhsub-pill--on { color: var(--on-bright); background: var(--accent); }
.bhsub-pill--off { color: var(--text-muted); background: rgba(var(--overlay-rgb),0.08); }

.bhsub-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin: 0; }
.bhsub-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhsub-cell dt { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhsub-cell dd { margin: 0; font: 400 13px/1.4 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-ver { font: 400 10.5px/1.3 'JetBrains Mono', monospace; color: var(--text-muted); }

.bhsub-note { margin: 14px 0 0; padding: 10px 12px; border-radius: var(--radius); background: rgba(var(--overlay-rgb),0.05); font: 400 12.5px/1.6 'Archivo', sans-serif; color: var(--text-body); }

/* Carte du Pass Tournoi, dans les reglages d'un tournoi. Meme grammaire que .bhsub-* : aucune
   couleur en dur, tout par tokens, pour que le theme la reprenne sans retouche. */
.bhpass { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.bhpass-h3 { margin: 0; font: 600 15px/1.3 'Archivo', sans-serif; color: var(--text-bright); }
.bhpass-text { margin: 0; font: 400 13px/1.6 'Archivo', sans-serif; color: var(--text-body); }
.bhpass-ok { margin: 0; padding: 10px 12px; border-radius: var(--radius); background: rgba(var(--overlay-rgb),0.05);
    font: 400 13px/1.6 'Archivo', sans-serif; color: var(--text-body); }
/* Carte « qui est prêt à être diffusé » (Tache #1168). Meme grammaire que .bhpass-* : tout par
   tokens, aucune couleur en dur. Le compte est la seule chose qui grossit -- c'est ce qu'on vient
   chercher, et il doit se lire sans rien parcourir. */
.bhready { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.bhready-h3 { margin: 0; font: 600 15px/1.3 'Archivo', sans-serif; color: var(--text-bright); }
.bhready-text { margin: 0; font: 400 13px/1.6 'Archivo', sans-serif; color: var(--text-body); }
.bhready-count { margin: 0; font: 400 15px/1.4 'Archivo', sans-serif; color: var(--text-body); }
.bhready-count b { font: 700 26px/1 'Archivo', sans-serif; color: var(--text-bright);
    font-variant-numeric: tabular-nums; }
/* Zero pret n'est pas une valeur comme une autre : c'est l'etat ou la regie n'a rien a proposer. */
.bhready-count--none b:first-child { color: var(--gold-fg); }
.bhready-ok { margin: 0; padding: 10px 12px; border-radius: var(--radius); background: rgba(var(--overlay-rgb),0.05);
    font: 400 13px/1.6 'Archivo', sans-serif; color: var(--text-body); }
.bhready-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px;
    width: 100%; }
.bhready-item { display: flex; align-items: center; gap: 10px; min-width: 0;
    font: 400 13px/1.5 'Archivo', sans-serif; color: var(--text-body); }
.bhready-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--gold-fg); }
.bhready-dot--on { background: var(--green-fg); }
.bhready-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhready-chan { margin-left: auto; flex: none; font: 400 12px/1.5 'JetBrains Mono', ui-monospace, monospace;
    color: var(--text-muted); }
.bhready-note { margin: 4px 0 0; font: 400 11.5px/1.5 'Archivo', sans-serif; color: var(--text-muted); }

.bhsub-caps { margin: 0; padding-left: 18px; }
.bhsub-cap { font: 400 12.5px/1.7 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-foot { margin: 14px 0 0; font: 400 11.5px/1.5 'Archivo', sans-serif; color: var(--text-muted); }
.bhsub-link { color: var(--accent); text-decoration: underline; }
/* Rangee de boutons d'achat (F3c). flex-wrap : sur mobile les deux boutons passent l'un sous
   l'autre plutot que de se comprimer -- un bouton d'achat ecrase est un bouton qu'on n'ose pas
   cliquer. Aucune couleur en dur : les deux boutons portent .btn-primary et .btn-ghost, qui
   existent deja et suivent le theme. */
.bhsub-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }

/* ── Écran 20a : le compteur de tournois offerts (US #812) ─────────────────────────────────────
   Le socle Découverte est l'état de presque toutes les organisations : c'est ce bloc, et non la
   carte d'abonnement, qui porte l'écran. */
.bhsub-kicker { font: 400 10.5px/1.4 'Archivo', sans-serif; color: var(--text-muted); }

.bhsub-gauge { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 16px; }
/* Une pastille par tournoi offert. Une barre continue dirait une PROPORTION ; ce qu'un organisateur
   veut lire ici est un RESTE, qui se compte. */
.bhsub-pips { display: flex; gap: 6px; flex: 1 1 140px; min-width: 0; }
.bhsub-pip { flex: 1 1 0; min-width: 16px; height: 8px; border-radius: var(--radius); background: rgba(var(--overlay-rgb),0.12); }
.bhsub-pip--used { background: var(--accent); }
.bhsub-count { flex: none; font: 700 18px/1 'JetBrains Mono', monospace; color: var(--text-bright); }
.bhsub-count-of { color: var(--text-muted); font-weight: 400; }
.bhsub-remain { flex: none; font: 400 11.5px/1.4 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-unlimited { margin: 4px 0 14px; font: 600 13px/1.5 'Archivo', sans-serif; color: var(--green-fg); }

.bhsub-ledger { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.bhsub-ledger-col { min-width: 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: rgba(var(--overlay-rgb),0.03); }
.bhsub-ledger-col .bhsub-h4 { margin-top: 0; }
.bhsub-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.bhsub-line { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; font: 400 12px/1.45 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-line-name { min-width: 0; overflow-wrap: anywhere; }
.bhsub-line-why { font-size: 11px; color: var(--text-muted); }
.bhsub-line--ok::before { content: "\2713"; color: var(--green-fg); font-weight: 700; }

/* Deux pistes seulement : le libellé, puis sa valeur ou sa provenance. Une troisième piste se
   ferait écraser sous sa largeur minimale dès que l'onglet rétrécit. */
.bhsub-quotas { display: flex; flex-direction: column; margin: 8px 0 0; }
.bhsub-quota { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: baseline; gap: 4px 14px; padding: 10px 0; border-top: 1px solid var(--border); }
.bhsub-quota:first-child { border-top: 0; }
.bhsub-quota-label { min-width: 0; font: 500 12.5px/1.4 'Archivo', sans-serif; color: var(--text-body); }
.bhsub-quota-label--off { color: var(--text-muted); }
.bhsub-quota-value { margin: 0; font: 700 13px/1 'JetBrains Mono', monospace; color: var(--text-bright); white-space: nowrap; }
.bhsub-quota-note { margin: 0; text-align: right; font: 400 10.5px/1.4 'Archivo', sans-serif; color: var(--text-muted); }
.bhsub-mark { display: inline-block; width: 14px; color: var(--green-fg); font-weight: 700; }
.bhsub-quota-label--off .bhsub-mark { color: var(--text-muted); }

/* Barre d'enregistrement collante des onglets de réglages d'une organisation.
   Enfant direct de .org-detail-card, qui n'a aucun padding : sans les 24px latéraux
   d'ici, le bouton se retrouvait collé au bord alors que toutes les sections
   au-dessus sont en retrait (.org-detail-section). */
.org-settings-actions {
    /* PAS de position: sticky. Collée en bas du conteneur de défilement, la barre flottait AU-DESSUS
       du formulaire et masquait les champs qui passaient dessous (les libellés « Seuil bas / haut »
       du barème disparaissaient derrière elle) : rien ne réserve la place en bas du formulaire pour
       la compenser. Un pied de carte ordinaire ne cache rien. */
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 24px;
    /* La barre est DANS la carte : elle doit en porter le fond. Avec --bg-page elle affichait le fond
       de la PAGE au milieu d'une carte en --bg-surface, et se lisait comme une barre flottante
       étrangère à l'écran plutôt que comme le pied de la carte. */
    background: var(--bg-surface);
    border-top: 0.5px solid var(--border);
    /* Dernier enfant de la carte et opaque : sans cet arrondi, ses angles droits dépasseraient des
       coins de la carte, qui ne découpe plus (voir .org-detail-card). */
    border-radius: 0 0 var(--radius) var(--radius);
}

/* Erreur affichée DANS la barre d'action, au contact du bouton : le bandeau du haut de page est
   hors écran quand on enregistre depuis la barre collante. mr-auto pour la coller à gauche, le
   bouton restant à droite. */
.org-settings-error {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: auto;
    font-size: 12px;
    color: var(--red-soft-fg);
}

/* Reste employée par la console de modération (Bans.razor) ; les autres règles de la liste de
   membres en cartes sont parties avec l'écran 8c, qui rend l'effectif en tableau. */
.org-member-avatar { width: 32px; height: 32px; font-size: 12px; flex-shrink: 0; }
.org-member-search {
    width: 100%;
    background: var(--bg-input);
    border: 0.5px solid var(--border-input);
    border-radius: var(--radius);
    padding: 8px 12px;
    font-size: 13px;
    color: var(--text-primary);
}
.org-member-search:focus { outline: none; border-color: var(--accent); }

.org-danger-zone {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.org-danger-title { font-size: 13px; font-weight: 500; color: var(--red-fg); display: flex; align-items: center; gap: 8px; }
.org-admin-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
    color: var(--gold-fg);
    background: rgba(239,159,39,0.14);
}
.org-danger-desc { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* ─── Organisations : pastilles (profils) ───────────────── */
.org-panel-header { display: flex; align-items: center; justify-content: space-between; }
.org-panel-link { font-size: 12px; color: var(--accent); display: inline-flex; align-items: center; gap: 5px; }

.org-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.org-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 12px 5px 6px;
    border-radius: var(--radius);
    border: 0.5px solid var(--border-input);
    background: rgba(var(--overlay-rgb),0.03);
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
    transition: border-color 0.15s, background 0.15s, transform 0.1s;
}
.org-pill:hover { border-color: var(--accent); background: var(--accent-subtle); transform: translateY(-1px); }
.org-pill-logo, .org-pill-logo img, .org-pill-initials {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    flex-shrink: 0;
}
.org-pill-logo img { object-fit: cover; }
.org-pill-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font-size: 10px;
    font-weight: 600;
}
.org-pill-admin { color: var(--gold-fg); font-size: 14px; }

/* ─── Gestion d'organisation : widgets ──────────────────── */
.org-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
}
.org-stat-card {
    background: var(--bg-input);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
}
.org-stat-label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); }
.org-stat-value { font-size: 26px; font-weight: 600; color: var(--text-primary); margin-top: 6px; }

.org-tourney-group { margin-bottom: 16px; }
.org-tourney-group:last-child { margin-bottom: 0; }
.org-tourney-cat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 6px;
}

.org-tourney-name { font-size: 14px; color: var(--text-primary); }

.org-tourney-date { font-size: 12px; color: var(--text-muted); }

/* Historique des tournois — cartes détaillées cliquables (onglet Historique) */
.org-tourney-cat-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius);
    background: rgba(var(--overlay-rgb),0.08);
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 600;
}
.org-tourney-card {
    padding: 10px 12px;
    border: 1px solid var(--border, var(--line-strong));
    border-radius: var(--radius);
    margin-bottom: 8px;
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
}
.org-tourney-card:last-child { margin-bottom: 0; }
.org-tourney-card:hover { background: rgba(var(--overlay-rgb),0.03); border-color: var(--accent, #EF9F27); }
.org-tourney-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.org-tourney-card-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-muted);
}
.org-tourney-card-meta span { display: inline-flex; align-items: center; gap: 5px; }

.tournament-status {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
}
.tournament-status--draft       { color: var(--text-muted); background: rgba(var(--overlay-rgb),0.06); }
.tournament-status--open        { color: var(--lime-fg); background: rgba(151,196,89,0.14); }
.tournament-status--drawphase   { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.tournament-status--inprogress  { color: #0a7cff; background: var(--accent-subtle); }
.tournament-status--completed   { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.07); }
.tournament-status--cancelled   { color: var(--red-fg); background: rgba(226,75,74,0.12); }

/* ─── Bannissements ─────────────────────────────────────── */
.ban-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(226,75,74,0.12);
    border: 0.5px solid rgba(226,75,74,0.4);
    color: var(--red-fg);
    margin-bottom: 12px;
}
.ban-banner i { font-size: 22px; }
.ban-banner-title { font-size: 14px; font-weight: 500; }
.ban-banner-reason { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

.ban-form { display: flex; gap: 8px; align-items: center; }
.ban-form .org-member-search { flex: 1; }
.ban-select {
    background: var(--bg-input);
    border: 0.5px solid var(--border-input);
    border-radius: var(--radius);
    padding: 8px 10px;
    font-size: 13px;
    color: var(--text-primary);
    cursor: pointer;
}
.ban-select:focus { outline: none; border-color: var(--accent); }
.ban-cat-tag {
    display: inline-block;
    padding: 1px 7px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 500;
    color: var(--gold-fg);
    background: rgba(239,159,39,0.14);
    margin-left: 6px;
}

.ban-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 0.5px solid rgba(var(--overlay-rgb),0.05);
}
.ban-row:last-child { border-bottom: none; }
.ban-row-scope { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--red-fg); font-weight: 500; }
.ban-row-reason { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.ban-requested { font-size: 12px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 5px; }

.ban-card-name { font-size: 14px; font-weight: 600; color: var(--text-primary); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.ban-card-name:hover { text-decoration: underline; }

.ban-card-date { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.ban-card-date .ti { font-size: 13px; }

/* ─── Error boundary ────────────────────────────────────── */
.blazor-error-boundary {
    padding: 1rem;
    background: #b32121;
    color: white;
    border-radius: var(--radius);
}

.blazor-error-boundary::after { content: "Une erreur est survenue."; }

/* ── Notification Bell ─────────────────────────────────────── */
.notif-bell-wrapper {
    position: relative;
    display: flex;
    align-items: center;
}

.notif-overlay {
    position: fixed;
    inset: 0;
    z-index: 999;
}

.notif-bell-btn {
    position: relative;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: inherit;
    font-size: 1.2rem;
}

.notif-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: var(--color-danger, #e53e3e);
    color: #fff;
    font-size: 0.6rem;
    font-weight: 700;
    border-radius: var(--radius);
    min-width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
    line-height: 1;
}

.notif-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 340px;
    z-index: 1000;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 8px 32px var(--shadow-strong);
    overflow: hidden;
    color: var(--text-primary);
}

@media (max-width: 480px) {
    .notif-dropdown { width: min(340px, calc(100vw - 24px)); }
}

.notif-dropdown-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    font-weight: 600;
    font-size: .85rem;
    border-bottom: 1px solid var(--border);
}

.notif-mark-all {
    background: none;
    border: none;
    cursor: pointer;
    font-size: .75rem;
    color: var(--accent);
    padding: 0;
}

.notif-mark-all:hover { text-decoration: underline; }

.notif-loading,
.notif-empty {
    padding: 24px 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: .85rem;
}

.notif-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 360px;
    overflow-y: auto;
}

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    transition: background .15s;
    color: var(--text-secondary);
}

.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: rgba(var(--overlay-rgb),.04); }

.notif-dot {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-top: 5px;
    background: transparent;
}

.notif-item--unread { color: var(--text-primary); }
.notif-item--unread .notif-dot {
    background: var(--accent);
}

.notif-item-body,
.notif-page-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.notif-msg {
    font-size: .85rem;
    line-height: 1.4;
    word-break: break-word;
}

/* Le token dédié qui vivait ici (un voile à 45 %, seul usage de toute la feuille) mesurait 4,36:1
   sur les surfaces élevées en sombre et 2,90:1 en clair — un doublon de la mention discrète, en
   moins lisible. L'heure d'une notification est du texte comme un autre : elle prend le token. */
.notif-time {
    font-size: .72rem;
    color: var(--text-muted);
}

.notif-footer {
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    text-align: center;
}

.notif-footer a {
    font-size: .8rem;
    color: var(--accent);
    text-decoration: none;
}

.notif-footer a:hover { text-decoration: underline; }

/* ── Notifications page ─────────────────────────────────────── */
.notif-page-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 16px;
}

.notif-page-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 18px;
    background: var(--bg-surface);
    border-radius: var(--radius);
    cursor: pointer;
    transition: background .15s;
    border: 1px solid var(--border);
    color: var(--text-secondary);
}

.notif-page-item:hover { background: rgba(var(--overlay-rgb),.04); }

.notif-page-item--unread { color: var(--text-primary); }
.notif-page-item--unread .notif-dot { background: var(--accent); }

.notif-action-link {
    margin-left: auto;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 1rem;
}

.notif-action-link:hover { color: var(--accent); }

.load-more {
    margin-top: 16px;
    text-align: center;
}

/* ─── panel-header (titre + lien à droite) ──────────────────── */
.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

/* ─── Stat cards cliquables ─────────────────────────────── */
.stat-card--clickable {
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
    text-align: left;
    width: 100%;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
    color: inherit;
}

.stat-card--clickable:hover {
    border-color: var(--accent, #0a7cff);
    background: var(--bg-surface-hover, rgba(var(--overlay-rgb),0.04));
}

.stat-card--alert { border-color: rgba(186,117,23,0.45) !important; }
.stat-card--alert:hover { border-color: #e59920 !important; }
.stat-value--warn { color: #BA7517; }

.badge-alert {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    color: #BA7517;
}

/* ─── Section header (titre + badge) ────────────────────── */
.section-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.badge-count--inline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius);
    background: #BA7517;
    color: #fff;
    font-size: 11px;
    font-weight: 600;
}

/* ─── Request list ───────────────────────────────────────── */
.request-list { display: flex; flex-direction: column; gap: 10px; }

.request-card {
    display: flex;
    align-items: center;
    gap: 16px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
}

.request-badge {
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    padding: 3px 8px;
    border-radius: var(--radius);
    text-transform: uppercase;
}

.request-badge--rehab            { background: rgba(186,117,23,0.18); color: #e59920; }
.request-badge--orgvalidation    { background: rgba(var(--accent-rgb),0.18); color: #0a7cff; }
.request-badge--orgreactivation  { background: rgba(99,153,34,0.18);  color: #7abb3a; }

.request-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.request-subject {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
}

.request-message {
    font-size: 12px;
    color: var(--text-hint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.request-date {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--text-hint);
    white-space: nowrap;
}

/* ─── Activity feed ─────────────────────────────────────── */
.activity-feed {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.activity-feed-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 0;
    border-bottom: 0.5px solid rgba(var(--overlay-rgb),0.05);
    font-size: 13px;
}

.activity-feed-item:last-child { border-bottom: none; }

.activity-feed-icon {
    font-size: 16px;
    flex-shrink: 0;
    width: 20px;
    text-align: center;
}

.activity-feed-icon--userjoined     { color: #639922; }
.activity-feed-icon--orgcreated     { color: #0a7cff; }
.activity-feed-icon--banissued      { color: #C03A1E; }
.activity-feed-icon--banlifted      { color: #639922; }
.activity-feed-icon--rehabrequested { color: #BA7517; }

.activity-feed-text { flex: 1; color: var(--text-secondary); }

.activity-feed-date {
    flex-shrink: 0;
    font-size: 11px;
    color: var(--text-hint);
    white-space: nowrap;
}

/* ─── btn-sm ─────────────────────────────────────────────── */
.btn-sm { padding: 5px 12px; font-size: 12px; }

/* ─── btn-ghost / btn-danger / btn-success ───────────────── */
/* 🔴 `.btn-ghost` EST le bouton secondaire du dépôt, et `.btn-primary` le principal. `.btn`,
   `.btn-secondary` et `.form-control` sont des noms BOOTSTRAP : la bibliothèque n'est pas chargée
   ici, aucune règle ne leur répond, et un contrôle qui les porte retombe sur l'habillage natif du
   navigateur — bordure `outset`, fond gris, 16 px, coins carrés. Rien ne le signale : le balisage
   est valide, la page part en 200, le build est vert. Vu le 2026-09-12 sur l'onglet Diffusion, où
   six boutons et un champ sortaient nus. `BootstrapClassNamesTests` interdit ces noms désormais. */
.btn-ghost {
    background: transparent;
    border: 0.5px solid var(--border);
    padding: 8px 16px;
    border-radius: var(--radius);
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.12s, border-color 0.12s;
}
.btn-ghost:hover { background: rgba(var(--overlay-rgb),0.06); border-color: var(--text-secondary); }

.btn-danger {
    background: rgba(226,75,74,0.08);
    border: 0.5px solid rgba(226,75,74,0.3);
    padding: 8px 16px;
    border-radius: var(--radius);
    color: var(--red-soft-fg);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.12s;
}
.btn-danger:hover:not(:disabled) { background: rgba(226,75,74,0.16); }
.btn-danger:disabled { opacity: 0.5; cursor: default; }

.btn-success {
    background: rgba(99,153,34,0.12);
    border: 0.5px solid rgba(99,153,34,0.4);
    padding: 8px 16px;
    border-radius: var(--radius);
    color: var(--lime2-fg);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.12s;
}
.btn-success:hover:not(:disabled) { background: rgba(99,153,34,0.22); }
.btn-success:disabled { opacity: 0.5; cursor: default; }

/* ─── Admin org table ────────────────────────────────────── */
.bhadm-org-filters {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.input-sm {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-size: 12px;
    padding: 5px 10px;
    outline: none;
    width: 180px;
}
.input-sm:focus { border-color: var(--accent, #0a7cff); }

.select-sm {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-secondary);
    font-size: 12px;
    padding: 5px 8px;
    outline: none;
    cursor: pointer;
}
.select-sm:focus { border-color: var(--accent, #0a7cff); }

.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th, .data-table td {
    padding: 12px 18px;
    text-align: left;
}

@media (max-width: 720px) {
    .data-table { min-width: 560px; }
}

.bhadm-org-table th:nth-child(1), .bhadm-org-table td:nth-child(1) { width: 34%; }
.bhadm-org-table th:nth-child(2), .bhadm-org-table td:nth-child(2) { width: 13%; }
.bhadm-org-table th:nth-child(3), .bhadm-org-table td:nth-child(3) { width: 13%; }
.bhadm-org-table th:nth-child(4), .bhadm-org-table td:nth-child(4) { width: 13%; }
.bhadm-org-table th:nth-child(5), .bhadm-org-table td:nth-child(5) { width: 14%; }
.bhadm-org-table th:nth-child(6), .bhadm-org-table td:nth-child(6) { width: 13%; }

.bhadm-org-table thead th {
    font-size: 11px;
    font-weight: 700;
    color: rgba(var(--overlay-rgb),0.35);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(var(--overlay-rgb),0.02);
    padding-top: 11px;
    padding-bottom: 11px;
}

.bhadm-org-table tbody tr {
    transition: background 0.1s;
}
.bhadm-org-table tbody tr:hover {
    background: rgba(var(--overlay-rgb),0.02);
}

.bhadm-org-row--inactive { opacity: 0.65; }

.bhadm-org-table tbody td { border-top: 0.5px solid rgba(var(--overlay-rgb),0.05); }

.bhadm-org-identity {
    display: flex;
    align-items: center;
    gap: 10px;
}

.bhadm-org-logo {
    width: 30px;
    height: 30px;
    border-radius: var(--radius);
    background: var(--bg-muted, rgba(var(--overlay-rgb),0.08));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    overflow: hidden;
}
.bhadm-org-logo img { width: 100%; height: 100%; object-fit: cover; }

.bhadm-org-name { font-size: 13px; font-weight: 500; color: var(--text-primary); }

.bhadm-org-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
}

.badge-count-sm {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius);
    background: var(--accent-subtle);
    color: var(--accent-light);
    font-size: 11px;
    font-weight: 600;
}

.badge-status--active   { background: rgba(99,153,34,0.15);  color: var(--lime2-fg); }
.badge-status--inactive { background: rgba(var(--overlay-rgb),0.07); color: var(--text-hint); }

/* ── Pager ────────────────────────────────────────────────── */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    padding: 0 2px;
}

.pager-info {
    font-size: 12px;
    color: var(--text-hint);
    white-space: nowrap;
}

.pager-controls {
    display: flex;
    align-items: center;
    gap: 2px;
}

.pager-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 6px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.pager-btn:hover:not(:disabled) {
    background: rgba(var(--overlay-rgb),0.06);
    border-color: var(--border-hover);
}

.pager-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.pager-btn--active {
    background: var(--accent-subtle);
    border-color: rgba(var(--accent-rgb),0.3);
    color: var(--accent);
    font-weight: 600;
}

.pager-ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    color: var(--text-hint);
    font-size: 13px;
}

/* ── Role badges (Dashboard org-chips) ─────────────────────── */
.badge-role {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    flex-shrink: 0;
}

/* ── Tournament status badges ───────────────────────────────── */
.badge-status {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

/* ─── tournament-status spinphase (alias DrawPhase renommé) ─── */
.tournament-status--spinphase           { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.tournament-status--registrationlocked { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.tournament-status--drawgenerated      { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.tournament-status--drawlocked         { color: #0a7cff; background: var(--accent-subtle); }
.tournament-status--resultspending     { color: #D4537E; background: rgba(212,83,126,0.12); }
.tournament-status--resultsvalidated   { color: var(--lime-fg); background: rgba(151,196,89,0.14); }
.tournament-status--full               { color: var(--beige-fg); background: rgba(218,208,196,0.14); }

/* ─── game result status (résultats de partie) ─── */
.tournament-status--pending    { color: var(--gold-fg); background: rgba(239,159,39,0.14); }
.tournament-status--validated  { color: var(--lime-fg); background: rgba(151,196,89,0.14); }
.tournament-status--disputed   { color: var(--red-fg); background: rgba(226,75,74,0.14); }

/* ─── leaderboard ─── */
.lb-block { margin-bottom: 24px; }

.mp-badge {
    display: inline-block; font-size: 11px; font-weight: 700;
    padding: 3px 10px; border-radius: var(--radius); white-space: nowrap;
    color: var(--gold-fg); border: .5px solid var(--tint-gold-border);
}
.mp-badge--on { background: rgba(239, 159, 39, .12); }
.mp-badge--win { background: rgba(239, 159, 39, .26); font-weight: 800; }

/* ─── Classement 2 colonnes : équipe repliable (cartes par partie) + top fragger ───
   Les couleurs de rang (or/argent/bronze) restent posées en style inline via les helpers
   Rank* du composant ; ici, uniquement la mise en page, tokenisée pour les deux thèmes. */
.lb2 { display: grid; grid-template-columns: minmax(0,1.55fr) minmax(0,1fr); gap: 16px; align-items: stretch; margin-top: 14px; margin-bottom: 20px; }
@media (max-width: 900px) { .lb2 { grid-template-columns: 1fr; } }
.lb2-col { border: .5px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.lb2-col--frag { position: relative; }
.lb2-frag-inner { display: flex; flex-direction: column; }
/* En 2 colonnes, la colonne individuelle est sortie du calcul de hauteur (position absolue) : la grille
   prend la hauteur de la colonne « par équipe », et la liste des fraggers défile dans ce cadre. Empilé
   (<=900px), tout redevient statique et la liste s'affiche en entier (c'est la page qui défile). */
@media (min-width: 901px) {
    .lb2-frag-inner { position: absolute; inset: 0; }
    .lb2-frag-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
}
.lb2-ttl { font-size: 13px; font-weight: 700; padding: 12px 14px 9px; display: flex; align-items: center; gap: 8px; }
.lb2-count { font-size: 11px; color: var(--text-muted); background: rgba(var(--overlay-rgb),.07); padding: 1px 8px; border-radius: var(--radius); }
.lb2-head { display: grid; padding: 4px 14px 6px; font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); font-weight: 700; border-bottom: .5px solid var(--border); }
.lb2-head--team { grid-template-columns: 58px 1fr 92px; }
.lb2-head--frag { grid-template-columns: 52px 1fr 48px; }
.lb2-head .r { text-align: right; }
.lb2-row { border-top: .5px solid rgba(var(--overlay-rgb),.05); }
.lb2-row:first-of-type { border-top: none; }

/* ── Match Point : bandeau des equipes + mise en evidence des lignes ──────── */
.lb2-mpbar {
  display: flex; align-items: center; gap: 10px; overflow: hidden;
  margin-top: 14px; padding: 8px 14px;
  border: 1px solid var(--gold-fg); border-radius: var(--radius); background: var(--tint-gold-bg);
}
.lb2-mpbar-lbl {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; white-space: nowrap;
  font-size: .78rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold-on-tint);
}
.lb2-mpbar-track { flex: 1 1 auto; min-width: 0; }
/* `flex-wrap` et PAS `width: max-content` : la piste ne defile plus, elle passe a la ligne.
   Voir le commentaire du bandeau dans LeaderboardView.razor — le defilement dupliquait la liste
   dans le DOM et l'affichait deux fois des que le contenu ne debordait pas. */
.lb2-mpbar-run { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.lb2-mpchip {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: 3px 10px; border-radius: var(--radius);
  background: var(--tint-gold-bg-2); color: var(--gold-on-tint);
  font-size: .78rem; font-weight: 700;
}

/* Vainqueur : ligne en or plein (il porte le 1er rang, donc la 1re recompense). */
.lb2-row--winner { background: var(--tint-gold-bg); box-shadow: inset 3px 0 0 var(--gold-fg); }
.lb2-row--winner .lb2-tn { color: var(--gold-on-tint); }
/* Encore en Match Point : pulsation DOUCE (pas un clignotement — risque WCAG sur le flash rapide). */
.lb2-row--mp { animation: lb2-mp-pulse 2.4s ease-in-out infinite; }
@keyframes lb2-mp-pulse { 0%, 100% { background: transparent; } 50% { background: var(--tint-gold-bg); } }

/* Accessibilite : aucune animation si l'utilisateur la refuse. L'or reste, seul le mouvement part. */
@media (prefers-reduced-motion: reduce) {
  .lb2-row--mp { animation: none; background: var(--tint-gold-bg); }
}
.lb2-rmain { display: grid; grid-template-columns: 58px 1fr 92px; align-items: center; padding: 9px 14px; cursor: pointer; list-style: none; }
.lb2-rmain::-webkit-details-marker { display: none; }
.lb2-rmain:hover { background: rgba(var(--overlay-rgb),.025); }
.lb2-rk { display: inline-flex; align-items: center; padding-left: 8px; }
.lb2-team { display: flex; align-items: center; gap: 10px; min-width: 0; }
.lb2-badge { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 12px; color: var(--on-bright); flex: none; }
/* Le blason porte l'image seule : aucun fond ici, la pastille de couleur n'est posée qu'en repli
   (style en ligne sur le span d'initiales), conformément à la convention de l'encadré des logos. */
.lb2-badge--img { object-fit: cover; }
.lb2-tmeta { min-width: 0; display: flex; flex-direction: column; }
.lb2-tn { font-size: 13px; font-weight: 700; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* overflow VISIBLE, et donc plus de points de suspension : un conteneur qui rogne aurait rogné
   la fiche de statistiques qui s'ouvre sous chaque pseudo. Un effectif tient en deux à quatre
   pseudos courts, la ligne ne débordait déjà quasiment jamais. */
.lb2-pl { font-size: 11px; color: var(--text-muted); overflow: visible; white-space: nowrap; }
.lb2-plsep { opacity: .55; }
.lb2-sc { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.lb2-scv { font-size: 16px; font-weight: 800; }
.lb2-chev { color: var(--text-muted); font-size: 11px; font-style: normal; transition: transform .18s; }
details[open] > .lb2-rmain .lb2-chev { transform: rotate(90deg); }
.lb2-chev--empty { opacity: .35; }
.lb2-exp { padding: 0 14px 12px 56px; display: flex; gap: 8px; align-items: stretch; }
.lb2-noplay { font-size: 12px; color: var(--text-muted); padding: 4px 0 8px; }
.lb2-strip { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 10px; flex: 1 1 auto; min-width: 0; }
.lb2-strip::-webkit-scrollbar { height: 7px; }
.lb2-strip::-webkit-scrollbar-thumb { background: var(--accent-subtle); border-radius: var(--radius); }
.lb2-mc { flex: 0 0 106px; background: var(--surface-2); border: .5px solid var(--border); border-radius: var(--radius); padding: 9px 10px; }
.lb2-mc--avg { background: var(--accent-subtle); flex: 0 0 116px; }
.lb2-mch { font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); font-weight: 700; margin-bottom: 5px; }
.lb2-mpl { font-size: 15px; font-weight: 800; margin-bottom: 6px; }
.lb2-pr { display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: var(--text-secondary); padding: 1px 0; }
.lb2-pr span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb2-pr b { color: var(--text-primary); font-weight: 700; }
.lb2-msc { margin-top: 6px; padding-top: 5px; border-top: .5px solid rgba(var(--overlay-rgb),.06); font-size: 14px; font-weight: 800; }
.lb2-avgk { font-size: 10.5px; color: var(--text-muted); }
.lb2-avgv { font-size: 15px; font-weight: 800; color: var(--text-primary); }
.lb2-fr { display: grid; grid-template-columns: 52px 1fr 48px; align-items: center; padding: 7px 14px; border-top: .5px solid rgba(var(--overlay-rgb),.05); }
.lb2-fr:first-of-type { border-top: none; }
.lb2-fr:hover { background: rgba(var(--overlay-rgb),.025); }
.lb2-frk { display: inline-flex; align-items: center; }
.lb2-fp { display: flex; align-items: center; gap: 9px; min-width: 0; }
.lb2-fav { width: 27px; height: 27px; border-radius: 50%; object-fit: cover; flex: none; }
.lb2-fav--ini { background: var(--avatar-bg); color: var(--avatar-color); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; }
.lb2-fpm { min-width: 0; display: flex; flex-direction: column; }
.lb2-fpn { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb2-fpo { font-size: 10.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb2-fk { text-align: right; font-size: 15px; font-weight: 800; color: var(--accent-light); }

/* ─── Tour filter tabs ─────────────────────────────────────── */
/* Conservée : la fiche d'ORGANISATION s'en sert encore pour sa propre barre d'onglets. Elle est
   partie une fois avec le chrome de /manage — et rien ne l'avait signalé, la page d'org n'ayant
   aucun test de mise en page. */
.tour-tab-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 24px;
    border-bottom: 0.5px solid var(--border);
}

/* 🔴 UNE SEULE LIGNE, et c'est une contrainte de fond, pas une préférence.
   La fiche d'organisation porte HUIT onglets. Mesurés avec la vraie police (Inter) ils occupent
   1174px ; la colonne de page vaut --page-max (1180px) moins les 48px de gouttière de la barre,
   soit 1130px de piste. Le huitième — « Bannissements » — passait donc à la ligne, et la barre
   faisait deux étages sous la bannière.
   Trois déclarations, chacune pour une raison :
     · nowrap      — ce qui interdit le retour à la ligne ;
     · min-width:0 — SANS LUI la piste refuse de se réduire sous sa largeur de contenu et élargit
                     ses ancêtres : c'est l'écran ENTIER qui se met à défiler, pas la barre ;
     · overflow-x  — le débordement reste alors DANS la barre, le jour où un onglet s'ajoute ou
                     qu'une traduction s'allonge. Rien ne s'affiche tant qu'on tient dans la piste.
   Les métriques resserrées plus bas (gap 6px, padding 12px) rendent 78px : on tient à 1096px,
   avec 34px de marge. ⚠️ Cette marge est mince — un neuvième onglet la mangera. */
.tour-tabs {
    display: flex;
    gap: 6px;
    margin-bottom: 20px;
    flex-wrap: nowrap;
    min-width: 0;
    overflow-x: auto;
}
.tour-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* 12px et non 16 : voir le commentaire de .tour-tabs — c'est ce resserrement qui fait tenir
       les huit onglets de la fiche d'organisation sur une ligne. */
    padding: 7px 12px;
    flex: 0 0 auto;
    border-radius: var(--radius);
    font-size: 13px;
    cursor: pointer;
    color: var(--text-muted);
    background: transparent;
    border: 0.5px solid transparent;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}
/* Le motif a ete concu pour des <button>. Le profil, en rendu statique, ne peut pas porter de
   gestionnaire Blazor : ses onglets sont des <a> vers ?tab=…, qui arriveraient soulignes. */
a.tour-tab, a.tour-tab:hover { text-decoration: none; }
.tour-tab:hover { color: var(--text-secondary); background: rgba(var(--overlay-rgb),0.04); }
.tour-tab--active {
    color: var(--accent);
    background: var(--accent-subtle);
    border-color: rgba(var(--accent-rgb),0.25);
    font-weight: 500;
}
.tour-tab-count {
    font-size: 11px;
    padding: 1px 6px;
    border-radius: var(--radius);
    background: rgba(var(--overlay-rgb),0.07);
    color: var(--text-muted);
    min-width: 18px;
    text-align: center;
}
.tour-tab--active .tour-tab-count {
    background: rgba(var(--accent-rgb),0.2);
    color: var(--accent);
}

.tour-card {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    cursor: pointer;
    min-height: 154px;
    transition: border-color 0.15s, transform 0.1s;
}
.tour-card:hover { border-color: var(--border-hover); transform: translateY(-1px); }

@media (max-width: 720px) {
    
    .tour-card { min-height: 150px; }
}

/* ─── Tour hero (detail page) ─────────────────────────────── */
/* Colonne de contenu centrée et bornée pour les pages tournoi (détail + résultats) : sur grand écran
   le contenu ne s'étale plus pleine largeur, il est centré dans .main-content. */
.tour-page { max-width: min(var(--page-max), 100%); margin-inline: auto; }
.tour-hero-state-dot { width: 6px; height: 6px; border-radius: 50%; background: #8db0e8; }
.tour-hero-state-dot--draft            { background: #EF9F27; }
.tour-hero-state-dot--open             { background: #97C459; }
.tour-hero-state-dot--spinphase,
.tour-hero-state-dot--drawphase,
.tour-hero-state-dot--drawgenerated,
.tour-hero-state-dot--registrationlocked { background: #EF9F27; }
.tour-hero-state-dot--drawlocked,
.tour-hero-state-dot--inprogress       { background: #0a7cff; }
.tour-hero-state-dot--resultspending   { background: #D4537E; }
.tour-hero-state-dot--resultsvalidated { background: #97C459; }
.tour-hero-state-dot--cancelled        { background: #E24B4A; }
.tour-action-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 6px 12px;
    border-radius: var(--radius);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    border: 0.5px solid;
    transition: opacity 0.15s;
    background: transparent;
}
.tour-action-btn:hover { opacity: 0.85; }
.tour-action-btn--open   { color: var(--lime-fg); border-color: rgba(151,196,89,0.3); }

/* ─── Tour section (detail page content areas) ────────────── */
.tour-section { padding: 16px 24px; }
/* En-tête de bloc de la Vue d'ensemble : le titre, et le renvoi vers Réglages quand il y a lieu (18a). */
.tour-ov-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.tour-ov-edit {
    display: inline-flex; align-items: center; gap: 5px;
    background: none; border: 0; padding: 2px 4px; cursor: pointer;
    font-size: 12px; color: var(--text-muted); border-radius: var(--radius);
}
.tour-ov-edit:hover { color: var(--accent); background: var(--bg-surface-hover); }

/* ─── Tour player list ────────────────────────────────────── */
.tour-player-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 8px;
}
.tour-player-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 10px;
    background: rgba(var(--overlay-rgb),0.03);
    border-radius: var(--radius);
    border: 0.5px solid var(--border);
    min-height: 68px;
}
.tour-player-row--paid {
    background: rgba(151,196,89,0.08);
    border-color: rgba(151,196,89,0.28);
}
.tour-player-identity { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.tour-player-identity > div:last-child { min-width: 0; }
.tour-player-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex-shrink: 0;
}
.tour-player-name {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tour-player-pseudo { font-size: 12px; line-height: 1.25; color: var(--text-muted); }
.tour-player-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    flex-wrap: wrap;
    row-gap: 5px;
    max-width: 58%;
}
.tour-skill-badge {
    font-size: 11px;
    line-height: 1.2;
    padding: 2px 8px;
    border-radius: var(--radius);
    background: rgba(var(--accent-rgb),0.12);
    color: var(--accent);
    white-space: nowrap;
    flex-shrink: 0;
}

/* Symbole d'attention « sanctions ailleurs » (visible organisation hôte + admins) */
.tour-flag {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: 6px;
    color: var(--gold-fg);
    font-size: 19px;
    cursor: help;
    flex-shrink: 0;
}
.tour-flag--global { color: var(--red-fg); }
/* Identité Discord manquante : information de conduite, PAS une sanction. Le bleu de marque
   (token --discord-link, dont le contraste est déjà ajusté par thème) le distingue de l'or et du
   rouge des signalements, et la taille légèrement réduite le range derrière eux dans le regard. */
.tour-flag--discord { color: var(--discord-link); font-size: 17px; }

/* ─── Aperçu de l'overlay OBS (profil, onglet Overlay) ───────────────────
   Le damier matérialise la TRANSPARENCE : sur un aplat uni, impossible de
   distinguer un fond transparent d'un fond de la couleur du panneau — et c'est
   précisément ce que le joueur vient vérifier avant de poser sa source. */
.overlay-preview-head {
    margin: 18px 0 8px;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}
.overlay-preview {
    display: inline-block;
    padding: 16px;
    border-radius: var(--radius);
    border: 0.5px solid var(--border);
    background-color: #789cda;
    background-image:
        linear-gradient(45deg, rgba(0,0,0,0.16) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.16) 75%),
        linear-gradient(45deg, rgba(0,0,0,0.16) 25%, transparent 25%, transparent 75%, rgba(0,0,0,0.16) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 10px 10px;
    max-width: 100%;
    overflow-x: auto;
}
.overlay-preview iframe {
    display: block;
    border: 0;
    background: transparent;
}

/* ─── Couleur d'identité de l'overlay (profil, onglet Overlay — maquette 23a) ───
   ⚠️ Aucune des neuf teintes n'est écrite ICI, et c'est délibéré : ce sont des
   DONNÉES (la palette du Domain), pas des couleurs de thème — elles ne changent pas
   d'un thème à l'autre, puisqu'elles sont toujours composées sur le fond de l'overlay.
   Elles arrivent par `--sw`, posé en ligne sur chaque pastille depuis le tableau C#.
   Les recopier ici les figerait à deux endroits, et enfreindrait la règle du dépôt :
   aucune couleur en dur dans cette feuille. */
.bhovc { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
/* ─── Le mode de fond (écran 24) ───────────────────────────────────────────────
   Chaque vignette montre la barre EN RÉDUCTION, peinte des couleurs du mode. Elle
   n'est pas décorative : sans elle, « Teinté » et « Plein » ne veulent rien dire
   avant d'avoir été essayés — et les essayer enregistre. */
.bhovc-modes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 9px;
    max-width: 520px;
}
.bhovc-mode {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 10px 11px 11px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-input);
    cursor: pointer;
    text-align: left;
}
.bhovc-mode:hover:not(:disabled) { border-color: var(--border-hover); }
.bhovc-mode:disabled { cursor: default; opacity: 0.6; }
.bhovc-mode--on { border: 2px solid var(--border-input); padding: 9px 10px 10px; }
.bhovc-mode-t { font-size: 12.5px; font-weight: 700; color: var(--text-primary); }
.bhovc-mode-d { font-size: 10.5px; line-height: 1.4; color: var(--text-muted); }
/* La vignette : mêmes proportions que la vraie barre (470 × 92 ⇒ ~5:1). */
.bhovc-mini {
    width: 100%;
    height: 30px;
    display: flex;
    align-items: center;
    gap: 5px;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--mini-bg);
    border: 1px solid rgba(var(--overlay-rgb), 0.12);
}
.bhovc-mini-rail { width: 3px; align-self: stretch; flex: none; }
/* Un gris moyen, volontairement neutre : il se voit aussi bien sur un fond sombre que
   sur un fond clair, et surtout il ne prétend RIEN sur l'encre — que seule l'Api déduit. */
.bhovc-mini-bar {
    height: 5px;
    border-radius: var(--radius);
    background: rgba(128, 128, 128, 0.55);
    flex: 1;
    margin-left: 4px;
}
.bhovc-mini-bar--s { flex: 0 0 22%; margin-right: 7px; }

/* ─── L'opacité ──────────────────────────────────────────────────────────────── */
.bhovc-oprow { display: flex; align-items: baseline; justify-content: space-between; max-width: 420px; }
.bhovc-opval { font-size: 11.5px; font-weight: 600; color: var(--text-primary); }
.bhovc-range { max-width: 420px; width: 100%; accent-color: var(--border-input); }
/* On PRÉVIENT, on ne bloque pas : un overlay très transparent est un choix légitime
   sur une scène sombre. */
.bhovc-warn {
    margin: 0;
    max-width: 420px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--text-body);
    display: flex;
    gap: 7px;
    align-items: baseline;
}

/* ─── Le cas où aucune encre ne passe ────────────────────────────────────────── */
.bhovc-choice {
    max-width: 520px;
    padding: 13px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--bg-inset);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.bhovc-choice-t { margin: 0; font-size: 12.5px; font-weight: 700; color: var(--text-primary); }
.bhovc-choice-d { margin: 0; font-size: 11px; line-height: 1.5; color: var(--text-muted); }
.bhovc-choice-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.bhovc-choice-o {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 11px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--sw-bg);
    color: var(--text-primary);
    font-size: 12px;
    cursor: pointer;
}
.bhovc-choice-o:hover:not(:disabled) { border-color: var(--border-hover); }
.bhovc-choice-o:disabled { cursor: default; opacity: 0.6; }
.bhovc-kicker {
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bhovc-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 8px;
    max-width: 420px;
}
/* 🔴 Le fond de la pastille est celui de l'OVERLAY, pas celui du formulaire, et il ne
   suit donc PAS le thème. Une pastille sur --bg-input devient blanche en thème clair,
   et la teinte pâle de la palette (#D2DDED) y disparaît purement et simplement — alors
   qu'elle est parfaitement lisible là où elle sert. La pastille est un échantillon de
   l'overlay, pas un contrôle de saisie : elle doit montrer la couleur DANS SON DÉCOR.
   La valeur arrive en ligne (--sw-bg), pour la même raison que les teintes. */
.bhovc-swatch {
    position: relative;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: var(--sw-bg);
    cursor: pointer;
    padding: 0;
}
.bhovc-swatch:hover:not(:disabled) { border-color: rgba(255, 255, 255, 0.28); }
.bhovc-swatch:disabled { cursor: default; opacity: 0.6; }
/* L'état retenu s'annonce par la TEINTE elle-même, cerclée et voilée : deux pastilles
   voisines ne se distinguent pas par une bordure neutre. */
.bhovc-swatch--on { border: 2px solid var(--sw, var(--border-hover)); }
.bhovc-dot { width: 18px; height: 18px; border-radius: 50%; background: var(--sw); }
.bhovc-check {
    position: absolute;
    right: 6px;
    top: 4px;
    font-size: 9px;
    font-weight: 700;
    color: var(--sw);
}
.bhovc-swatch--free {
    display: flex;
    gap: 7px;
    border-style: dashed;
    border-color: rgba(255, 255, 255, 0.22);
}
/* La tuile HEX est une PORTE, pas un choix : lui donner l'anneau de sélection ferait lire
   deux couleurs retenues en même temps. Ouverte, elle se contente de fermer son pointillé. */
.bhovc-open { border-style: solid; border-color: rgba(255, 255, 255, 0.40); }
/* Le dégradé dit « n'importe laquelle ». Ses deux bornes sont deux teintes de la palette,
   posées en ligne comme les pastilles — pour la même raison. */
.bhovc-prism {
    width: 14px;
    height: 14px;
    border-radius: var(--radius);
    background: linear-gradient(135deg, var(--sw-a), var(--sw-b));
}
.bhovc-hex { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; color: #8b98ad; }
.bhovc-free { display: flex; gap: 8px; align-items: center; max-width: 420px; }
.bhovc-input { flex: 1; min-width: 0; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }
.bhovc-note { margin: 0; }
.bhovc-corrected,
.bhovc-error { margin: 0; font-size: 12.5px; display: flex; gap: 7px; align-items: baseline; }
.bhovc-corrected { color: var(--text-body); }
.bhovc-error { color: var(--color-danger); }
.tour-flag-tip {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 40;
    width: max-content;
    max-width: 300px;
    padding: 10px 12px;
    background: var(--bg-surface);
    border: 0.5px solid rgba(var(--overlay-rgb),0.12);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px var(--shadow-strong);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-3px);
    transition: opacity .12s ease, transform .12s ease;
    pointer-events: none;
}
.tour-flag:hover .tour-flag-tip,
.tour-flag:focus-visible .tour-flag-tip,
.tour-flag:focus-within .tour-flag-tip {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.tour-flag-tip-head {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--text-muted);
    margin-bottom: 8px;
}
.tour-flag-tip-head .ti { color: var(--red-fg); font-size: 14px; }
.tour-flag-item { display: block; }
.tour-flag-item + .tour-flag-item { margin-top: 8px; padding-top: 8px; border-top: 0.5px solid rgba(var(--overlay-rgb),0.08); }
.tour-flag-item-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tour-flag-org, .tour-flag-date {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
}
.tour-flag-org .ti { font-size: 13px; color: var(--text-muted); }
.tour-flag-date { color: var(--text-muted); }
.tour-flag-date .ti { font-size: 13px; }
.tour-flag-reason { display: block; margin-top: 6px; font-size: 12.5px; line-height: 1.5; color: var(--text-secondary); }

@media (max-width: 720px) {
    .tour-flag-tip { left: auto; right: 0; }
}

/* Sections Inscrits / Liste d'attente + permutation */
.tour-roster-section { margin-bottom: 20px; }
.tour-roster-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 10px;
}
.tour-roster-head .ti { font-size: 16px; color: var(--accent); }
.tour-roster-section--waitlist .tour-roster-head { color: var(--gold-fg); }
.tour-roster-section--waitlist .tour-roster-head .ti { color: var(--gold-fg); }

/* Conseil affiché sous la cagnotte : informatif, pas une erreur — l'aplat doré le distingue d'un
   défaut sans crier au problème (le tournoi est valide, c'est le barème choisi qui ne convient pas). */
.tour-ov-advice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 10px;
    padding: 8px 12px;
    font-size: 12px;
    line-height: 1.5;
    border-radius: var(--radius);
    background: var(--tint-gold-bg-2);
    color: var(--gold-on-tint);
}
.tour-ov-advice .ti { flex-shrink: 0; font-size: 16px; margin-top: 1px; }

/* ─── Invitations (tournoi sur invitation) ────────────────────────── */
/* Liste VERTICALE : une invitation par ligne. Ne pas réutiliser .tour-player-list, qui est une
   grille en colonnes auto-remplies (cartes de joueur) et écraserait le nom sur 280 px. */
.tour-invite-list { display: flex; flex-direction: column; margin-top: 10px; }
.tour-invite-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    background: rgba(var(--overlay-rgb),0.02);
    margin-bottom: 6px;
}
.tour-invite-name { flex: 1; font-size: 13px; font-weight: 500; }
.tour-invite-status {
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius);
    white-space: nowrap;
}
/* Une invitation sans réponse APPELLE une action : elle se distingue des états déjà tranchés. */
.tour-invite-status--pending  { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.tour-invite-status--accepted { background: var(--tint-green-bg); color: var(--green-fg); }
.tour-invite-status--declined { background: var(--tint-red-bg); color: var(--red-soft-fg); }
.tour-invite-status--revoked  { background: rgba(var(--overlay-rgb),0.06); color: var(--text-muted); }
/* Message affiché au joueur non invité / ayant refusé : informatif, jamais une action. */
.tour-invite-note {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-muted);
}
.tour-swap-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    margin-bottom: 10px;
    border-radius: var(--radius);
    background: rgba(var(--accent-rgb),0.10);
    border: 0.5px solid rgba(var(--accent-rgb),0.30);
    color: var(--text-secondary);
    font-size: 13px;
}
.tour-swap-banner .ti { color: var(--accent); font-size: 16px; flex-shrink: 0; }
.tour-swap-banner span { flex: 1; }
.tour-swap-banner .btn-sm { flex-shrink: 0; padding: 3px 10px; font-size: 12px; }
.tour-payment-btn.tour-swap-target { background: rgba(var(--accent-rgb),0.14); color: var(--accent); border-color: rgba(var(--accent-rgb),0.4); }

@media (max-width: 720px) {
    .tour-player-row {
        align-items: flex-start;
        flex-direction: column;
    }
    .tour-player-actions {
        justify-content: flex-start;
        max-width: none;
        width: 100%;
    }
}

/* ─── Tour team list ──────────────────────────────────────── */
.tour-team-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    background: rgba(var(--overlay-rgb),0.03);
    border-radius: var(--radius);
    border: 0.5px solid var(--border);
    margin-bottom: 6px;
}
.tour-team-name { font-size: 13px; font-weight: 500; display: flex; align-items: center; gap: 6px; min-width: 120px; }
.tour-team-members { display: flex; gap: 6px; flex-wrap: wrap; }
.tour-team-member {
    font-size: 12px;
    padding: 2px 8px;
    background: rgba(var(--overlay-rgb),0.05);
    border-radius: var(--radius);
    color: var(--text-secondary);
}

/* ─── Type toggle (public/private) ────────────────────────── */
.tour-type-toggle { display: flex; border: 0.5px solid var(--border-input); border-radius: var(--radius); overflow: hidden; }
.tour-type-opt {
    flex: 1;
    padding: 7px 12px;
    text-align: center;
    font-size: 13px;
    cursor: pointer;
    color: var(--text-muted);
    background: transparent;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    transition: color 0.15s, background 0.15s;
}
.tour-type-opt:hover { color: var(--text-secondary); }
.tour-type-opt--active { color: var(--accent); background: var(--accent-subtle); font-weight: 500; }

/* ─── Switcheroo tiers ─────────────────────────────────────── */
.tour-tier-row {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    margin-bottom: 12px;
    padding: 12px;
    background: rgba(var(--accent-rgb),0.04);
    border: 0.5px solid rgba(var(--accent-rgb),0.15);
    border-radius: var(--radius);
}
.tour-tier-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    width: 80px;
    flex-shrink: 0;
    white-space: nowrap;
    padding-bottom: 8px;
}
.tour-tier-fields { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; flex: 1; }

@media (max-width: 900px) {
    .tour-tier-fields { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
    .tour-tier-fields { grid-template-columns: 1fr; }
}
.tour-mult-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}
.tour-mult-row input {
    padding: 10px 14px;
    font-size: 14px;
    border: 1.5px solid var(--border-input);
    border-radius: var(--radius);
    background: var(--bg-input);
    color: var(--text-primary);
    transition: border-color 0.15s;
}
.tour-mult-row input:focus {
    outline: none;
    border-color: var(--accent);
}
.tour-ov-details { display: grid; grid-template-columns: 1fr 1fr; column-gap: 20px; }
@media (max-width: 820px) { .tour-ov-details { grid-template-columns: 1fr; } }

.tour-ov-card { background: var(--bg-input); border: 0.5px solid var(--border); border-radius: var(--radius); padding: 12px 14px; }

/* ── Checklist du brouillon (18a) ────────────────────────────────────────────
   Elle dit ce qui reste à régler. Elle ne bloque rien : aucun style d'erreur, un ton d'invitation. */
.tour-ov-ready { background: var(--bg-input); border: 0.5px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.tour-ov-ready-head { display: flex; align-items: center; gap: 14px; padding: 14px 16px 12px; }
.tour-ov-ready-head > div:first-child { flex: 1; min-width: 0; }
.tour-ov-ready-title { font-size: 14px; font-weight: 600; }
.tour-ov-ready-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 6px; }
.tour-ov-ready-count { font-size: 19px; font-weight: 800; color: var(--accent); white-space: nowrap; }
.tour-ov-ready-count span { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.tour-ov-ready-gauge { height: 3px; background: rgba(var(--overlay-rgb),0.07); display: flex; }
.tour-ov-ready-gauge span { background: var(--accent); transition: width 0.25s; }
.tour-ov-ready-row {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 16px;
    border-top: 0.5px solid var(--border);
    font-size: 12.5px;
}
.tour-ov-ready-mark {
    width: 18px;
    height: 18px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: rgba(151,196,89,0.14);
    color: var(--lime-fg);
    font-size: 11px;
}
.tour-ov-ready-row--todo .tour-ov-ready-mark { background: rgba(239,159,39,0.14); color: var(--gold-fg); }
.tour-ov-ready-label { flex: 1; min-width: 0; color: var(--text-secondary); }
.tour-ov-ready-row--todo .tour-ov-ready-label { color: var(--text-primary); font-weight: 500; }
.tour-ov-ready-value { font-size: 11.5px; color: var(--text-muted); text-align: right; }
.tour-ov-ready-go {
    flex: none;
    padding: 4px 11px;
    border-radius: var(--radius);
    border: 0.5px solid rgba(239,159,39,0.3);
    background: transparent;
    color: var(--gold-fg);
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
}
.tour-ov-ready-go:hover { background: rgba(239,159,39,0.1); }
@media (max-width: 560px) {
    .tour-ov-ready-row { flex-wrap: wrap; }
    .tour-ov-ready-value { width: 100%; text-align: left; padding-left: 29px; }
}

/* ── Réglages en sections (18c) ──────────────────────────────────────────────
   L'édition se fait sur place : un rail de sections à gauche, le formulaire à droite, et une barre
   qui NOMME ce qui a changé avant d'enregistrer. */
.bhset { border: 0.5px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--bg-input); }
.bhset-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    border-bottom: 0.5px solid var(--border);
}
.bhset-head > div:first-child { flex: 1; min-width: 0; }
.bhset-title { font-size: 14px; font-weight: 600; }
.bhset-sub { margin-top: 6px; font-size: 11.5px; color: var(--text-muted); }

.bhset-body { display: grid; grid-template-columns: 210px 1fr; }
@media (max-width: 720px) { .bhset-body { grid-template-columns: 1fr; } }

.bhset-rail { padding: 16px 12px; border-right: 0.5px solid var(--border); min-width: 0; }
@media (max-width: 720px) { .bhset-rail { border-right: none; border-bottom: 0.5px solid var(--border); } }
.bhset-rail-label { font-size: 9.5px; font-weight: 700; letter-spacing: 0.14em; color: var(--text-muted); text-transform: uppercase; }
.bhset-rail-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    height: 32px;
    margin-top: 2px;
    padding: 0 10px;
    border: none;
    border-radius: var(--radius);
    background: transparent;
    color: var(--text-secondary);
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}
.bhset-rail-item:hover { background: rgba(var(--overlay-rgb),0.05); }
.bhset-rail-item--active { background: var(--accent-subtle); color: var(--accent); font-weight: 600; }
.bhset-rail-name { flex: 1; min-width: 0; }
.bhset-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--gold-fg); }

.bhset-panel { padding: 18px 20px 22px; min-width: 0; }
.bhset-panel-title {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-bottom: 14px;
}

/* La conséquence d'un réglage, montrée là où on le change. */
.bhset-effect {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: var(--radius);
    border: 0.5px solid var(--border-hover);
    background: var(--accent-subtle);
    font-size: 11.5px;
    color: var(--text-secondary);
}
.bhset-effect .ti { flex: none; font-size: 15px; color: var(--accent); }

.bhset-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 18px;
    border-top: 0.5px solid var(--border);
    background: rgba(var(--overlay-rgb),0.03);
}
.bhset-bar-count { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; color: var(--gold-fg); }
.bhset-bar-list { font-size: 11px; color: var(--text-muted); min-width: 0; }
.bhset-bar-spacer { flex: 1; }

/* ── Déroulé de la série (18b) ───────────────────────────────────────────────
   Une carte par partie : où en est la manche, et où en est sa saisie. */
.tour-games { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.tour-game {
    padding: 13px 14px;
    border-radius: var(--radius);
    border: 0.5px solid var(--border);
    background: var(--bg-input);
    min-width: 0;
}
.tour-game-no { font-size: 10px; font-weight: 700; letter-spacing: 0.1em; color: var(--text-muted); text-transform: uppercase; }
.tour-game-state { margin-top: 9px; font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.tour-game-scores { margin-top: 6px; font-size: 11px; color: var(--text-muted); }
.tour-game--current { border-color: var(--accent); background: var(--accent-subtle); }
.tour-game--current .tour-game-state { color: var(--accent); }
.tour-game--disputed { border-color: rgba(226,75,74,0.35); }
.tour-game--disputed .tour-game-state { color: var(--red-fg); }
.tour-game--soon { opacity: 0.55; }

/* Le litige passe avant la série : il gèle une part de cagnotte. */
.tour-dispute {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 15px;
    margin-bottom: 16px;
    border-radius: var(--radius);
    border: 0.5px solid rgba(226,75,74,0.35);
    background: rgba(226,75,74,0.06);
}
.tour-dispute-mark { color: var(--red-fg); font-size: 17px; display: flex; }
.tour-dispute-body { flex: 1; min-width: 0; }
.tour-dispute-title { font-size: 12.5px; font-weight: 600; }
.tour-dispute-hint { margin-top: 6px; font-size: 11px; color: var(--text-muted); }
.tour-dispute-go {
    flex: none;
    padding: 6px 13px;
    border-radius: var(--radius);
    border: 0.5px solid rgba(226,75,74,0.35);
    background: transparent;
    color: var(--red-fg);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.tour-dispute-go:hover { background: rgba(226,75,74,0.1); }
@media (max-width: 560px) { .tour-dispute { flex-wrap: wrap; } }

/* ── Projection de cagnotte à trois paliers (18a) ────────────────────────────
   Un montant unique « à pleine capacité » présentait une hypothèse comme un acquis. */
.tour-ov-pool-badge { font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; color: var(--text-muted); }

.tour-ov-pool { display: flex; align-items: center; justify-content: space-between; background: var(--bg-input); border: 0.5px solid var(--border); border-radius: var(--radius); padding: 14px 16px; }
.tour-ov-pool-label { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-secondary); }
.tour-ov-pool-label i { color: var(--green-fg); font-size: 18px; }
.tour-ov-pool-amount { font-size: 22px; font-weight: 800; color: var(--green-fg); }
.tour-ov-pool-hint { font-size: 11.5px; color: var(--text-muted); margin: 6px 2px 12px; }
.tour-ov-fee {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text-secondary);
    margin: 0 2px 12px;
    padding: 8px 10px;
    background: rgba(var(--overlay-rgb),0.03);
    border: 0.5px solid rgba(var(--overlay-rgb),0.07);
    border-radius: var(--radius);
}
.tour-ov-fee .ti { font-size: 15px; color: var(--text-muted); }
.tour-ov-fee-amount { margin-left: auto; font-weight: 600; color: var(--gold-fg); }
.tour-ov-podium { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.tour-ov-podium-card { background: var(--bg-input); border: 0.5px solid var(--border); border-radius: var(--radius); padding: 14px 8px; text-align: center; }
.tour-prize-editor { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.tour-prize-row { display: flex; align-items: center; gap: 8px; }
.tour-prize-pos { font-size: 12px; color: var(--text-secondary); min-width: 44px; }
.tour-prize-cur { font-size: 13px; color: var(--text-muted); }
.tour-prize-summary { font-size: 13px; color: var(--text-secondary); display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 4px; }
.tour-prize-summary--over { color: var(--red-fg, #e24b4a); }
.tour-prize-warn { display: inline-flex; align-items: center; gap: 4px; color: var(--red-fg, #e24b4a); font-size: 12.5px; }
.tour-ov-podium-pos { font-size: 11px; color: var(--text-muted); margin: 6px 0 4px; }
.tour-ov-podium-amount { font-size: 16px; font-weight: 800; }

.tour-ov-schedule { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (max-width: 560px) { .tour-ov-schedule { grid-template-columns: 1fr; } }
.tour-ov-sched-label { display: flex; align-items: center; gap: 7px; font-size: 11px; color: var(--text-muted); margin-bottom: 8px; }
.tour-ov-sched-val { font-size: 14px; font-weight: 600; }
.tour-ov-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }
.tour-ov-dot--open { background: #97C459; }
.tour-ov-dot--start { background: var(--accent); }
.tour-ov-table-wrap { background: var(--bg-input); border: 0.5px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.tour-ov-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.tour-ov-table th { text-align: left; padding: 11px 16px; font-size: 11px; font-weight: 600; color: var(--text-muted); }
.tour-ov-table td { padding: 11px 16px; border-top: 0.5px solid var(--border); }
.tour-ov-mult { color: #D85A30; font-weight: 600; }

.tour-confirm-grid { margin-bottom: 4px; }
.tour-confirm-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 0.5px solid var(--border);
}
.tour-confirm-row:last-child { border-bottom: none; }
.tour-confirm-label { font-size: 13px; color: var(--text-muted); min-width: 140px; flex-shrink: 0; }
.tour-confirm-value { font-size: 13px; font-weight: 500; display: flex; align-items: center; gap: 6px; }

/* ═══════════════════════════════════════════════════════════════════
   Private Party Draw — Dark Event Screen
   Palette: bg var(--bg-inset) / var(--bg-panel) / var(--bg-elevated)  accent #EF9F27
   ═══════════════════════════════════════════════════════════════════ */

.pp-screen {
    display: flex;
    flex-direction: column;
    /* `dvh` pour la même raison que .app-shell : le cockpit est l'écran le plus susceptible d'être
       tenu en main pendant un événement, et en `vh` sa dernière rangée se cachait sous la barre
       d'adresse. */
    /* 🔴 DIVISÉE par le zoom, comme .app-shell juste au-dessus — et pour la même raison :
       `zoom` multiplie AUSSI les unités de viewport. Sans la division, le cockpit faisait 1000 px
       dans les 920 px que .main-content lui offre à 1080 : 80 px de trop, donc un PREMIER ascenseur
       par-dessus celui du plateau. Mesuré sur page-sonde à deux hauteurs — 80 px à 1080, 67 px à
       900 — : le débordement est PROPORTIONNEL au viewport, pas fixe. ⚠️ À 1080 il valait très
       exactement la hauteur de la barre de navigation, coïncidence qui ferait accuser celle-ci ;
       la mesure à 900 tranche.
       🔴 ET PLUS AUCUNE SOUSTRACTION : le cockpit MASQUE la barre de navigation (règle juste sous
       ce bloc), il a donc l'écran ENTIER — 80 px rendus au plateau. Les deux moitiés vont
       ENSEMBLE : remettre la barre sans remettre la soustraction redonne un ascenseur, retirer
       la soustraction sans masquer la barre aussi. ShellLayoutCssTests garde le COUPLE, pas
       chacune des deux moitiés — c'est leur désaccord qui fait le défaut, pas leur valeur. */
    height: calc(100dvh / var(--ui-zoom));
    /* Repère des positions absolues du cockpit : le logo d'accueil, qui remplace la barre masquée.
       Sans lui, il se rattacherait à .main-content — donc au mauvais coin dès qu'elle défile. */
    position: relative;
    /* Plein écran : on annule le padding du shell, dont la valeur vient de .main-content par
       héritage. Le repli à 16px ne sert que si l'écran était rendu hors du shell — il ne l'est
       jamais, la page exigeant une session. Ne PAS réécrire un nombre en dur ici. */
    margin: calc(-1 * var(--shell-pad, 16px));
    /* Cockpit de tirage : plein cadre assumé, il échappe au plafond de largeur du shell. */
    max-width: none;
    background: var(--bg-inset);
    color: var(--text-bright);
    font-family: inherit;
    overflow: hidden;
}

/* 🔴 PAS DE BARRE DE COPYRIGHT SOUS UN ÉCRAN PLEIN CADRE.
   La coquille pose `SiteCopyright` sous `@Body`, dans le même `.main-content`. Le cockpit, lui,
   occupe déjà TOUTE la hauteur disponible : la mention ajoute 60 px par-dessus, donc un SECOND
   ascenseur en plus de celui du plateau. Mesuré sur page-sonde : `.main-content` client 920,
   scroll 980.
   ⚠️ C'est exactement ce qu'une première sonde n'avait PAS vu, faute d'avoir reproduit la barre :
   elle mesurait un débordement nul là où l'écran réel en montrait deux. Une sonde ne vaut que par
   ce qu'elle reproduit — si elle contredit l'écran, c'est elle qui a tort.
   Et sur le fond : une mention de copyright n'a rien à faire sous un écran de conduite tenu
   pendant un direct. */
.main-content:has(.pp-screen) .bh-foot-bar { display: none; }

/* 🔴 NI BARRE DE NAVIGATION. Le cockpit est un poste de conduite tenu pendant un direct : la
   recherche, la cloche, le sélecteur de langue et le menu du compte n'y servent à rien, et la
   barre coûtait 80 px de hauteur à l'écran qui en manque le plus. Ce qu'elle portait d'utile —
   le chemin du retour — est repris par .pp-home juste dessous.
   ⚠️ Le sélecteur porte sur .app-shell et non sur .main-content : la barre est la SŒUR de
   .main-content, pas sa descendante. Écrit comme la règle du copyright juste au-dessus, il ne
   désignerait rien — sans erreur, sans trace, et la barre resterait. */
.app-shell:has(.pp-screen) .appnav { display: none; }

/* Le seul chemin de retour qui reste, la barre étant masquée : le logo, en haut à gauche, qui
   ramène à l'accueil.
   EN ABSOLU, et c'est le point : il ne prend aucune rangée au cockpit, qui n'a pas un pixel de
   hauteur à donner, et il ne touche pas à la géométrie du bandeau, réglée au cinquième près pour
   son artwork. Il se pose dans le vide à sa gauche — le bandeau est CENTRÉ et dimensionné sur son
   contenu (ses marges `auto` désactivent l'étirement du flex), ce qui laisse 536 px à gauche à
   1920. Mesuré sur page-sonde, pas déduit.
   ⚠️ L'organisation garde SA marque DANS le bandeau (US #755) : cet écran se projette en salle,
   et c'est celle de qui reçoit qui doit s'y lire. Ce logo-ci n'est pas une signature, c'est le
   bouton d'accueil de la barre disparue — d'où sa place HORS du bandeau, et non dedans. */
.pp-home { position: absolute; top: 13px; left: 14px; z-index: 5; display: inline-flex; align-items: center; opacity: .78; transition: opacity .15s ease; }
.pp-home:hover, .pp-home:focus-visible { opacity: 1; }
/* 64px : la même marque à la même taille que dans les trois barres de navigation, et pour la
   même raison — le mot-symbole vit À L'INTÉRIEUR de l'image et redevient un pâté en dessous.
   ShellLayoutCssTests compare les quatre déclarations entre elles. */
.pp-home img { height: 64px; width: auto; max-width: none; display: block; }

/* Sous cette largeur, le bandeau n'est plus assez étroit pour laisser 92 px à sa gauche — un nom
   de tournoi long l'élargit d'autant — et le logo mordrait dessus. On lui RÉSERVE la place au
   lieu de masquer le logo : c'est le seul chemin de retour de cet écran, le faire disparaître
   avec la fenêtre y enfermerait l'organisateur.
   La marge droite reste `auto`, ce qui garde le bandeau dimensionné sur son contenu : le passer
   à une marge fixe des deux côtés le ferait étirer par le flex, et son calque en `cover`
   recommencerait à rogner l'artwork. */
@media (max-width: 1100px) {
    .pp-screen .bh3bar { margin-left: 92px; }
}

.tour-payment-badge,
.tour-payment-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.tour-payment-badge {
    padding: 2px 8px;
    color: var(--lime-fg);
    background: rgba(151,196,89,0.14);
}
.tour-payment-btn {
    padding: 3px 8px;
    color: var(--lime-fg);
    background: transparent;
    border: 0.5px solid rgba(151,196,89,0.35);
    cursor: pointer;
}
.tour-payment-btn:hover { background: rgba(151,196,89,0.10); }
.tour-payment-btn--danger {
    color: var(--red-fg);
    border-color: rgba(226,75,74,0.35);
}
.tour-payment-btn--danger:hover { background: rgba(226,75,74,0.10); }

/* Inscription pas encore validée par l'organisateur — volontairement neutre (pas d'alerte) :
   c'est l'état normal d'une inscription qui vient d'arriver sur un tournoi payant. */
.tour-reg-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--text-secondary);
    background: rgba(var(--overlay-rgb), 0.06);
    border: .5px solid var(--border);
}

.tour-draw-access {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    background: rgba(var(--overlay-rgb),0.03);
}
.tour-draw-title { font-size: 14px; font-weight: 700; color: var(--text-primary); }
.tour-draw-subtitle { margin-top: 2px; font-size: 12px; color: var(--text-muted); }

@media (max-width: 640px) {
    .tour-player-list { grid-template-columns: 1fr; }
    .tour-draw-access { align-items: flex-start; flex-direction: column; }
}

/* ── Calendrier des tournois ─────────────────────────────────────────── */
.cal-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.cal-nav { display: flex; align-items: center; gap: 8px; }
.cal-nav-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: var(--radius);
    border: 0.5px solid var(--border); background: var(--bg-surface);
    color: var(--text-secondary); cursor: pointer;
}
.cal-nav-btn:hover { border-color: var(--border-hover); color: var(--text-primary); }
.cal-month-label { font-size: 15px; font-weight: 600; min-width: 150px; text-align: center; }
.cal-today-btn {
    margin-left: 4px; padding: 5px 12px; border-radius: var(--radius); font-size: 13px; cursor: pointer;
    border: 0.5px solid var(--border); background: transparent; color: var(--text-secondary);
}
.cal-today-btn:hover { border-color: var(--border-hover); color: var(--text-primary); }
.cal-view-toggle { display: inline-flex; gap: 6px; }
.cal-view-btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px; border-radius: var(--radius); font-size: 13px; cursor: pointer;
    border: 0.5px solid transparent; background: transparent; color: var(--text-muted);
}
.cal-view-btn:hover { background: rgba(var(--overlay-rgb),0.04); color: var(--text-secondary); }
.cal-view-btn--active { color: var(--accent); background: var(--accent-subtle); border-color: rgba(var(--accent-rgb),0.25); }

.cal-weekdays {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin-bottom: 6px;
}
.cal-weekdays span {
    font-size: 12px; color: var(--text-muted); text-align: center; text-transform: capitalize;
}
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-cell {
    min-height: 108px; border: 0.5px solid var(--border); border-radius: var(--radius);
    padding: 5px 6px; background: var(--bg-surface); overflow: hidden;
}
.cal-cell--out { opacity: 0.4; }
.cal-cell--today { border-color: var(--accent); background: var(--accent-subtle); }
.cal-cell--sel { border-color: var(--border-input); box-shadow: inset 0 0 0 1px var(--border-input); }
/* Le numéro du jour EST le bouton de sélection : la case contient déjà des boutons (les tournois),
   et imbriquer des éléments interactifs donne un balisage invalide. */
.cal-cell-num {
    display: block; margin-bottom: 4px; padding: 0 4px; border: 0; border-radius: var(--radius);
    background: transparent; cursor: pointer; font: inherit;
    font-size: 12px; color: var(--text-muted);
}
.cal-cell-num:hover { background: var(--bg-hover); color: var(--text-primary); }
.cal-cell--today .cal-cell-num { color: var(--accent); font-weight: 600; }
.cal-cell--sel .cal-cell-num { color: var(--accent-light); font-weight: 700; }
.cal-tz {
    display: block; margin: -2px 0 6px; text-align: right;
    font-size: 10px; color: var(--text-faint);
}
/* 🔴 La pastille colorait avec --pill, que l'ancien balisage posait en style INLINE. La refonte 16a
   l'a remplacé par une classe bhcal-mode--* qui définit --bhcal-mode : plus personne ne posait
   --pill, donc couleur, fond et liseré tombaient tous les trois en silence (texte blanc nu).
   Une variable non définie ne casse rien et ne se voit pas dans un build — seul l'écran le dit.

   Le nom tient désormais sur DEUX lignes au lieu d'être coupé au milieu d'un mot : « Esport World
   Cup Group Stage » se lisait « Esport World Cu… », ce qui n'apprend rien. Au-delà, l'ellipse tombe
   en fin de 2ᵉ ligne et le titre natif porte le nom entier. */
/* La case dit désormais l'heure, le nom et l'état — les trois données qui permettent de décider sans
   ouvrir la fiche, et toutes disponibles sur le DTO de liste depuis l'US #678. */
.cal-pill {
    display: flex; flex-direction: column; gap: 1px;
    width: 100%; text-align: left;
    padding: 3px 6px; border-radius: var(--radius); margin-bottom: 3px;
    overflow: hidden; cursor: pointer;
    background: color-mix(in srgb, var(--bhcal-mode) 15%, transparent);
    border: 0; border-left: 2px solid var(--bhcal-mode);
}
.cal-pill:hover { background: color-mix(in srgb, var(--bhcal-mode) 28%, transparent); }
.cal-pill-time { font-size: 9.5px; font-weight: 600; letter-spacing: .02em; color: var(--bhcal-mode); }
.cal-pill-name {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2;
    overflow: hidden; overflow-wrap: anywhere;
    font-size: 11px; line-height: 1.28; color: var(--bhcal-mode);
}
.cal-pill-state {
    font-size: 9.5px; color: var(--text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-more {
    border: 0; background: transparent; cursor: pointer; padding: 0 2px;
    font: inherit; font-size: 11px; color: var(--text-muted); text-align: left;
}
.cal-more:hover { color: var(--accent); text-decoration: underline; }

.cal-agenda { display: flex; flex-direction: column; gap: 8px; }

.cal-agenda-row {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 12px; border: 0.5px solid var(--border); border-radius: var(--radius);
    background: var(--bg-surface); cursor: pointer; transition: border-color .12s, background .12s;
}
.cal-agenda-row:hover { border-color: var(--accent); background: rgba(var(--overlay-rgb),0.02); }
.cal-agenda-date { text-align: center; min-width: 40px; }
.cal-agenda-day-num { display: block; font-size: 18px; font-weight: 600; line-height: 1; }
.cal-agenda-mon { display: block; font-size: 10px; color: var(--text-muted); }
.cal-agenda-bar { width: 3px; height: 36px; border-radius: var(--radius); flex-shrink: 0; }
.cal-agenda-body { flex: 1; min-width: 0; }
.cal-agenda-name { font-size: 14px; color: var(--text-primary); }
.cal-agenda-sub {
    font-size: 12px; color: var(--text-secondary);
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 2px;
}
.cal-agenda-sub .cal-sep { color: var(--text-muted); }
.cal-agenda-sub i { margin-right: 3px; }

/* .cal-legend / .cal-legend-dot et .cal-upcoming-below RETIRÉS avec la refonte 16a : la légende vit
   dans le rail (.bhcal-legend) et la liste empilée sous la grille a disparu. Les règles restées ici
   étaient les DERNIÈRES à lire --pill, une variable que plus aucun balisage ne pose. */

.cal-embed-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.cal-embed-link { font-size: 13px; color: var(--accent); text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.cal-embed-link:hover { text-decoration: underline; }

/* ─────────────────────────────────────────────────────────────────────────────
   Calendrier — chronologie (écran 16a)

   Grammaire `bhcal-`. Aucune couleur en dur : la couleur de format passe par
   --bhcal-mode, posé par une classe `bhcal-mode--*` et lu par la barre de bord,
   la puce et le liseré. C'est ce qui permet aux trois de rester d'accord sans
   répéter la valeur, et au thème clair de suivre sans une seule règle en plus.
   ───────────────────────────────────────────────────────────────────────────── */

.bhcal-mode--switcheroo { --bhcal-mode: var(--gold-fg); }
.bhcal-mode--normal    { --bhcal-mode: var(--accent); }
.bhcal-mode--killrace  { --bhcal-mode: var(--green-fg); }
/* L'indigo est le seul jeton de la palette qui ne soit ni déjà pris par un format, ni porteur d'un
   sens d'état (le rouge dit l'erreur, le doré la distinction). Il est défini dans les trois blocs de
   thème, donc le clair suit sans une règle de plus. */
.bhcal-mode--wager     { --bhcal-mode: var(--indigo-fg); }
.bhcal-mode-edge--switcheroo { --bhcal-mode: var(--gold-fg); }
.bhcal-mode-edge--normal    { --bhcal-mode: var(--accent); }
.bhcal-mode-edge--killrace  { --bhcal-mode: var(--green-fg); }
.bhcal-mode-edge--wager     { --bhcal-mode: var(--indigo-fg); }

.bhcal-summary {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    margin-bottom: 14px;
}
.bhcal-summary-main { font-size: 12.5px; color: var(--text-muted); }
.bhcal-views {
    margin-left: auto; display: flex; gap: 2px; padding: 3px;
    border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--bg-surface);
}
.bhcal-view {
    height: 30px; padding: 0 14px; border: 0; border-radius: var(--radius); cursor: pointer;
    background: transparent; color: var(--nav-ink); font-size: 11.5px; font-weight: 500;
}
.bhcal-view--on { background: var(--bg-chip); color: var(--accent-light); font-weight: 600; }

.bhcal-filters {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 12px 0; margin-bottom: 6px; border-top: 0.5px solid var(--border); border-bottom: 0.5px solid var(--border);
}
.bhcal-search {
    display: flex; align-items: center; gap: 9px; height: 32px; padding: 0 12px;
    border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--bg-input);
    color: var(--text-muted); min-width: 0; flex: 0 1 230px;
}
.bhcal-search input {
    border: 0; background: transparent; color: var(--text-primary); font-size: 12px;
    outline: none; min-width: 0; width: 100%;
}
.bhcal-select {
    height: 32px; padding: 0 10px; border: 0.5px solid var(--border); border-radius: var(--radius);
    background: var(--bg-input); color: var(--text-secondary); font-size: 11.5px;
}
.bhcal-chip {
    height: 32px; padding: 0 13px; display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--bg-input);
    color: var(--text-secondary); font-size: 11.5px; font-weight: 500;
}
.bhcal-chip--on { border-color: var(--border-input); background: var(--accent-subtle); color: var(--accent-light); }
.bhcal-sortnote { margin-left: auto; font-size: 11px; color: var(--text-faint); }

.bhcal-body { display: grid; grid-template-columns: 244px minmax(0, 1fr); gap: 0; }
.bhcal-rail {
    border-right: 0.5px solid var(--border); padding: 18px 20px 24px 0;
    display: flex; flex-direction: column; gap: 18px;
}
.bhcal-rail-head { display: flex; align-items: center; justify-content: space-between; }
.bhcal-rail-month { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--text-primary); }
.bhcal-rail-nav { display: flex; gap: 5px; }
.bhcal-rail-btn {
    width: 22px; height: 22px; display: grid; place-items: center; cursor: pointer;
    border: 0.5px solid var(--border); border-radius: var(--radius); background: transparent; color: var(--text-soft);
}
.bhcal-rail-btn:hover { border-color: var(--border-hover); color: var(--text-primary); }
.bhcal-rail-dow, .bhcal-rail-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.bhcal-rail-dow { font-size: 8.5px; color: var(--text-faint); text-align: center; margin-bottom: 2px; }
.bhcal-rail-day {
    height: 26px; display: grid; place-items: center; position: relative; cursor: pointer;
    padding: 0; border: 0; background: transparent;
    font-size: 10.5px; font-family: inherit; color: var(--text-faint); border-radius: var(--radius);
}
.bhcal-rail-day:hover { background: var(--bg-hover); color: var(--text-primary); }
.bhcal-rail-day--out { color: var(--text-ghost); }
.bhcal-rail-day--today { background: var(--accent-hover); color: var(--on-accent); font-weight: 700; }
/* La sélection l'emporte sur « aujourd'hui » : sinon cliquer le jour courant ne se voit pas. */
.bhcal-rail-day--sel {
    background: var(--bg-chip); color: var(--accent-light); font-weight: 700;
    box-shadow: inset 0 0 0 1px var(--border-input);
}
.bhcal-rail-dot {
    position: absolute; bottom: 3px; width: 3px; height: 3px; border-radius: 50%;
    background: var(--accent);
}
.bhcal-rail-dot--many { width: 9px; border-radius: var(--radius); }
.bhcal-rail-day--today .bhcal-rail-dot { background: var(--on-accent); }
.bhcal-rail-block { padding-top: 14px; border-top: 0.5px solid var(--border); }
.bhcal-rail-label { font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); }
.bhcal-jumps { display: flex; flex-direction: column; gap: 1px; margin-top: 10px; }
.bhcal-jump {
    display: flex; align-items: center; justify-content: space-between; cursor: pointer;
    height: 28px; padding: 0 9px; border: 0; border-radius: var(--radius); background: transparent;
    color: var(--text-soft); font-size: 11px;
}
.bhcal-jump:hover { background: var(--bg-hover); color: var(--text-primary); }
.bhcal-jump--empty { color: var(--text-ghost); }
.bhcal-jump-n { font-size: 10px; font-weight: 600; color: var(--text-muted); }
.bhcal-legend { display: flex; flex-direction: column; gap: 9px; margin-top: 10px; }
.bhcal-legend-item { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--text-soft); }
.bhcal-legend-bar { width: 3px; height: 12px; border-radius: var(--radius); background: var(--bhcal-mode); }

.bhcal-stream { padding: 18px 0 24px 28px; min-width: 0; }

.bhcal-group { display: flex; align-items: baseline; gap: 11px; padding: 20px 0 10px; }
.bhcal-group:first-child { padding-top: 0; }
.bhcal-group-title { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-secondary); }
.bhcal-group:first-child .bhcal-group-title { color: var(--text-primary); }
.bhcal-group-note { font-size: 11px; color: var(--text-faint); }
.bhcal-group-rule { flex: 1; height: 1px; background: var(--border); }

.bhcal-rows { display: flex; flex-direction: column; gap: 8px; }
.bhcal-rows--done { margin-top: 12px; opacity: .78; }

/* La ligne est MISE EN RELIEF par la couleur de son format : liseré épais à gauche, voile teinté qui
   s'éteint vers la droite, et bordure elle-même teintée. Tout dérive du seul --bhcal-mode, donc les
   trois restent d'accord et le thème clair suit sans une règle de plus. Le voile est volontairement
   faible (6 %) : il doit signer la ligne, pas concurrencer le texte. */
.bhcal-row {
    position: relative; display: flex; align-items: center; gap: 18px; cursor: pointer;
    padding: 14px 18px 14px 22px; border-radius: var(--radius); overflow: visible;
    border: 0.5px solid color-mix(in srgb, var(--bhcal-mode) 26%, var(--border));
    background:
        linear-gradient(90deg, color-mix(in srgb, var(--bhcal-mode) 6%, transparent), transparent 42%),
        var(--bg-surface);
    transition: background-color .12s ease, border-color .12s ease;
}
.bhcal-row::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
    border-radius: var(--radius) 0 0 var(--radius); background: var(--bhcal-mode);
}
.bhcal-row:hover, .bhcal-row:focus-visible {
    border-color: color-mix(in srgb, var(--bhcal-mode) 55%, var(--border));
    background:
        linear-gradient(90deg, color-mix(in srgb, var(--bhcal-mode) 12%, transparent), transparent 52%),
        var(--bg-hover);
}
.bhcal-row--now {
    padding: 16px 18px 16px 22px;
    border-color: color-mix(in srgb, var(--bhcal-mode) 45%, var(--border-input));
    background:
        linear-gradient(90deg, color-mix(in srgb, var(--bhcal-mode) 14%, transparent), transparent 55%),
        linear-gradient(100deg, var(--accent-subtle), var(--bg-surface) 60%);
}

.bhcal-when { width: 56px; flex: none; text-align: center; }
.bhcal-when-time { display: block; font-size: 15px; font-weight: 700; color: var(--text-primary); }
.bhcal-when-time--sm { font-size: 11px; font-weight: 600; margin-top: 5px; color: var(--text-primary); }
.bhcal-when-zone { display: block; margin-top: 5px; font-size: 9.5px; font-weight: 500; color: var(--accent-light); }
.bhcal-when-day { display: block; font-size: 13px; font-weight: 700; text-transform: uppercase; color: var(--text-soft); }
.bhcal-when-month { display: block; margin-top: 5px; font-size: 10px; font-weight: 500; letter-spacing: .06em; color: var(--text-muted); }

.bhcal-main { flex: 1; min-width: 0; }
.bhcal-titleline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.bhcal-name {
    font-size: 14.5px; font-weight: 600; color: var(--text-primary);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcal-row--now .bhcal-name { font-size: 16px; }
.bhcal-badge {
    height: 18px; padding: 0 7px; display: grid; place-items: center; flex: none;
    border-radius: var(--radius); font-size: 9.5px; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--bhcal-mode);
    background: color-mix(in srgb, var(--bhcal-mode) 14%, transparent);
}
.bhcal-axis { font-size: 10.5px; font-weight: 500; text-transform: uppercase; color: var(--text-faint); flex: none; }
.bhcal-live {
    display: inline-flex; align-items: center; gap: 6px; height: 18px; padding: 0 8px; flex: none;
    border-radius: var(--radius); background: color-mix(in srgb, var(--green-fg) 14%, transparent);
    font-size: 9.5px; font-weight: 600; text-transform: uppercase; color: var(--green-fg);
}
.bhcal-live-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green-fg); }
.bhcal-subline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; font-size: 11.5px; color: var(--text-soft); }
.bhcal-dot { color: var(--text-ghost); }

.bhcal-gauge { width: 190px; flex: none; }
.bhcal-gauge-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.bhcal-gauge-count { font-size: 12px; font-weight: 600; color: var(--text-soft); }
.bhcal-gauge-count--full { color: var(--text-primary); }
.bhcal-waitlist { font-size: 10.5px; font-weight: 500; color: var(--gold-fg); }
.bhcal-nobody { font-size: 10.5px; font-weight: 500; color: var(--red-fg); }
.bhcal-closed { font-size: 10.5px; font-weight: 500; color: var(--text-muted); }
.bhcal-bar { height: 4px; border-radius: var(--radius); background: var(--bg-elevated); margin-top: 7px; overflow: hidden; }
.bhcal-bar-fill { display: block; height: 100%; background: var(--green-fg); }
.bhcal-bar-fill--full { background: var(--gold-fg); }
.bhcal-gauge-note { display: block; margin-top: 8px; font-size: 10.5px; color: var(--text-muted); }

.bhcal-action {
    flex: none; width: 150px; height: 34px; display: grid; place-items: center;
    border: 0.5px solid var(--border); border-radius: var(--radius);
    font-size: 12px; font-weight: 600; color: var(--text-secondary);
}
.bhcal-action--primary { border-color: transparent; background: var(--accent-gradient); color: var(--on-accent); }
.bhcal-row--now .bhcal-action { border-color: var(--border-input); background: var(--bg-chip); color: var(--accent-light); }

/* Carte de survol 16c — commune aux deux directions du canvas. Pas de JS : hover + focus-within,
   pour qu'elle s'ouvre aussi au clavier. `pointer-events:none` évite qu'elle vole le survol de la
   ligne et se mette à clignoter quand le curseur passe dessus. */
.bhcal-card {
    position: absolute; left: 74px; bottom: calc(100% + 8px); z-index: 30;
    width: min(320px, calc(100vw - 48px));
    display: flex; flex-direction: column; gap: 8px; padding: 14px 16px;
    border: 0.5px solid var(--border-hover); border-radius: var(--radius); background: var(--bg-elevated);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .32);
    opacity: 0; visibility: hidden; transform: translateY(4px);
    transition: opacity .12s ease, transform .12s ease, visibility .12s;
    pointer-events: none;
}
.bhcal-row:hover .bhcal-card, .bhcal-row:focus-visible .bhcal-card, .bhcal-row:focus-within .bhcal-card {
    opacity: 1; visibility: visible; transform: translateY(0);
}
.bhcal-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.bhcal-card-status { font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); }
.bhcal-card-name { font-size: 15px; font-weight: 600; color: var(--text-primary); }
.bhcal-card-sub { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 11.5px; color: var(--text-soft); }
.bhcal-card-metrics { display: flex; gap: 22px; padding-top: 8px; border-top: 0.5px solid var(--border); }
.bhcal-card-metric { display: flex; flex-direction: column; gap: 4px; }
.bhcal-card-metric-lbl { font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint); }
.bhcal-card-metric-val { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.bhcal-card-note { font-size: 11px; line-height: 1.5; color: var(--text-muted); }

.bhcal-hidden {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-top: 10px; padding: 11px 18px;
    border: 1px dashed var(--border); border-radius: var(--radius);
    font-size: 11.5px; color: var(--text-faint);
}
.bhcal-foot {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin-top: 20px; padding-top: 14px; border-top: 0.5px solid var(--border);
    font-size: 11.5px; color: var(--text-faint);
}
.bhcal-foot-note { flex: 1; min-width: 0; }
.bhcal-linkbtn {
    border: 0; background: transparent; cursor: pointer; padding: 0;
    font-size: 11.5px; font-weight: 500; color: var(--accent);
}
.bhcal-linkbtn:hover { text-decoration: underline; }

@media (max-width: 900px) {
    .bhcal-body { grid-template-columns: minmax(0, 1fr); }
    .bhcal-rail { border-right: 0; border-bottom: 0.5px solid var(--border); padding: 0 0 18px; }
    .bhcal-stream { padding-left: 0; }
    .bhcal-row { flex-wrap: wrap; gap: 12px; }
    .bhcal-gauge { width: 100%; order: 3; }
    .bhcal-action { width: 100%; order: 4; }
    .bhcal-card { left: 0; width: 100%; }
}

@media (max-width: 640px) {
    .cal-cell { min-height: 62px; }
    .cal-pill { font-size: 10px; }
}

/* Loading spinner */
.page-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    /* dvh comme partout : le spinner se centre sur la zone RÉELLEMENT visible, pas sur celle qu'on
       aurait barre d'adresse masquée. */
    height: 60dvh;
    font-size: 32px;
    color: var(--text-faint);
}
.spin { animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Écran de chargement plein écran (logo + spinner) — transition d'app / clic tournoi */
.loading-splash {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 20px;
    background: var(--bg-page);
}
.loading-splash-logo {
    height: 52px;
    width: auto;
    opacity: 0.95;
    animation: loading-splash-pulse 1.6s ease-in-out infinite;
}
.loading-splash-spinner { font-size: 26px; color: var(--accent, var(--gold-fg)); }
.loading-splash-label { font-size: 13px; color: var(--text-muted, var(--text-soft)); }
@keyframes loading-splash-pulse {
    0%, 100% { opacity: 0.55; transform: scale(0.98); }
    50%      { opacity: 1;    transform: scale(1.02); }
}
@media (prefers-reduced-motion: reduce) {
    .loading-splash-logo { animation: none; }
}

/* ── Saisie des résultats par les joueurs ──────────────────────────────────── */
.res-team { flex-direction: column; align-items: stretch; gap: 10px; margin-bottom: 10px; }
.res-team-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.res-owner { font-size: .78rem; color: var(--text-muted); display: flex; align-items: center; gap: 4px; }
/* Ligne à plusieurs champs : surtout PAS .field (flex-direction: column). */
.res-row { display: flex; align-items: center; gap: 10px; }
.res-label { min-width: 170px; font-size: .85rem; color: var(--text-muted); }
.res-input {
  /* 13px explicite : la saisie voisine le nom du joueur (.res-grid-player, 13px) sur la même
     ligne de la grille. Sans cette taille, l'héritage de la police (bloc de base) porterait la
     saisie aux 16px du body — visiblement plus gros que la cellule d'à côté, dans un tableau
     de saisie dense. */
  max-width: 110px; padding: 6px 10px; font-size: 13px;
  background: var(--bg-input); color: var(--text-primary); border: 1px solid var(--border-input); border-radius: var(--radius);
}
.res-shots { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 4px; }
.res-shot { display: flex; flex-direction: column; gap: 4px; font-size: .82rem; }
.res-shot label { color: var(--text-muted); }
.res-shot-ok { color: var(--accent-light); font-size: .78rem; display: flex; align-items: center; gap: 4px; }
.res-hint { font-size: .76rem; color: var(--text-muted); }

/* Verdict de la vérification par les captures (US #355).
   Deux états seulement s'affichent : confirmé et divergent. « Illisible » ne produit RIEN — c'est le
   fonctionnement d'avant, pas une anomalie, et un outil qui alerte une fois sur trois se fait ignorer.
   Couleurs par tokens. ⚠️ Contrastes MESURÉS au navigateur, à reprendre avant tout ajustement de
   token — le thème clair passe de justesse :
     sombre : ok 7,57 · warn 8,54 · detail 8,32
     clair  : ok 4,52 · warn 4,62 · detail 5,09   (seuil AA = 4,5)
   Ne PAS basculer sur --tint-gold-bg-2 : le doré n'y mesure que 4,41 en thème clair. */
.res-check {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 1px 8px; border-radius: var(--radius);
  font-size: .74rem; border: 1px solid transparent; white-space: nowrap;
}
.res-check--ok   { color: var(--green-fg); background: var(--tint-green-bg); border-color: var(--tint-green-border); }
.res-check--warn { color: var(--gold-fg);  background: var(--tint-gold-bg);  border-color: var(--tint-gold-border); }
.res-check--wait { color: var(--text-muted); background: transparent; border-color: var(--border); }
.res-check-detail { font-size: .76rem; color: var(--gold-fg); flex-basis: 100%; }

@media (max-width: 640px) {
  .res-row { flex-direction: column; align-items: stretch; gap: 4px; }
  .res-label { min-width: 0; }
  .res-input { max-width: none; }
}

/* ─── Wiki d'aide (US #239) ───────────────────────────────
   Uniquement des tokens : aucune couleur en dur (parité clair/sombre, ThemeCssTests). */
.wiki-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 28px;
    align-items: start;
    max-width: min(var(--page-max), 100%);
    margin: 0 auto;
}
.wiki-sidebar {
    position: sticky;
    top: 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-right: 8px;
    border-right: 1px solid var(--line-soft);
}
/* Sommaire repliable — le bouton n'existe QUE sur mobile (voir la media query plus bas).
   Sur desktop le panneau porte la mise en page que .wiki-sidebar tenait auparavant. */
.wiki-nav-panel {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.wiki-nav-toggle { display: none; }
.wiki-sidebar-home {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--radius);
    color: var(--text-secondary);
    font-weight: 600;
}
.wiki-sidebar-home:hover { background: var(--bg-surface-hover); color: var(--text-primary); }
.wiki-sidebar-home.active { background: var(--accent-subtle); color: var(--accent-light); }

.wiki-nav-section { margin-top: 14px; }
.wiki-nav-title {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-dim);
}
.wiki-nav-link {
    display: block;
    padding: 6px 10px 6px 24px;
    border-radius: var(--radius);
    font-size: 0.9rem;
    color: var(--nav-ink);
    border-left: 2px solid transparent;
}
.wiki-nav-link:hover { background: var(--bg-surface-hover); }
.wiki-nav-link.active {
    color: var(--accent-light);
    background: var(--accent-subtle);
    border-left-color: var(--accent);
    font-weight: 600;
}

.wiki-content { min-width: 0; }
.wiki-breadcrumb { font-size: 0.8rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }

/* Accueil du wiki : cartes des sections */
.wiki-home-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}
.wiki-home-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-panel);
    transition: border-color .15s, transform .15s;
}
.wiki-home-card:hover { border-color: var(--border-hover); transform: translateY(-2px); }
.wiki-home-card > i { font-size: 1.4rem; color: var(--accent-light); }
.wiki-home-card-title { font-weight: 600; color: var(--text-primary); }
.wiki-home-card-count { font-size: 0.8rem; color: var(--text-dim); }

/* Panneau « section réservée » */
.wiki-locked {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center;
    padding: 48px 24px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-panel);
}
.wiki-locked > i { font-size: 2rem; color: var(--text-dim); }
.wiki-locked h2 { margin: 0; color: var(--text-primary); }
.wiki-locked p { margin: 0; color: var(--text-soft); max-width: 40ch; }

/* Rendu du markdown.
   L'article est posé sur sa PROPRE surface opaque (--bg-panel), pas sur le fond de page : un long
   texte suivi se lit mieux sur une plaque nette que sur l'aplat de la page, et surtout la colonne
   de lecture reste lisible quel que soit ce qu'il y a derrière. Pas de voile translucide ni de
   flou : un fond semi-transparent laisse remonter ce qu'il recouvre — c'est justement ce qui
   rendait le wiki illisible en thème clair. */
.wiki-prose {
    color: var(--text-body);
    line-height: 1.65;
    max-width: 78ch;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 22px;
}
/* Les marges d'en-tête ne doivent pas creuser un blanc en haut de la plaque : le padding empêche
   la fusion des marges, il faut donc les annuler explicitement aux extrémités. */
.wiki-prose > :first-child { margin-top: 0; }
.wiki-prose > :last-child { margin-bottom: 0; }
.wiki-prose h2 {
    margin: 1.6em 0 0.5em;
    padding-bottom: 0.2em;
    border-bottom: 1px solid var(--line-soft);
    color: var(--text-primary);
    font-size: 1.25rem;
}
.wiki-prose h3 { margin: 1.3em 0 0.4em; color: var(--text-bright); font-size: 1.05rem; }
.wiki-prose p { margin: 0.7em 0; }
.wiki-prose a { color: var(--accent-light); text-decoration: underline; text-underline-offset: 2px; }
.wiki-prose ul, .wiki-prose ol { margin: 0.6em 0; padding-left: 1.4em; }
.wiki-prose li { margin: 0.3em 0; }
.wiki-prose strong { color: var(--text-primary); }
.wiki-prose blockquote {
    margin: 1em 0;
    padding: 8px 16px;
    border-left: 3px solid var(--accent);
    background: var(--accent-subtle);
    border-radius: 0 var(--radius) var(--radius) 0;
    color: var(--text-secondary);
}
.wiki-prose code {
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.88em;
    background: var(--bg-chip);
    padding: 1px 6px;
    border-radius: var(--radius);
    color: var(--text-bright);
}
.wiki-prose pre {
    margin: 1em 0;
    padding: 14px 16px;
    background: var(--bg-inset);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    overflow-x: auto;
}
.wiki-prose pre code { background: none; padding: 0; color: var(--text-body); }
/* 🔴 `table-layout: fixed`, et pas seulement `width: 100%` : un tableau en disposition automatique
   se dimensionne sur le CONTENU de ses cellules, et `width: 100%` ne borne alors plus rien. Le
   tableau des cookies de /confidentialite mesurait 421px dans une colonne de 300 : toute la page
   légale partait de 121px vers la droite à 360, paragraphes compris — et la page d'aide « Cagnotte »
   de 47px. Les tableaux à DEUX colonnes tenaient (268px) : c'est à trois que ça lâche, donc le
   défaut ne se voyait que sur deux pages du corpus.
   Les blocs <pre> voisins avaient déjà leur `overflow-x: auto` ; les tableaux avaient été oubliés.
   `overflow-wrap: anywhere` sur les cellules complète le tout : sans lui, une URL ou un identifiant
   sans espace impose un minimum que la disposition fixe ne peut pas réduire non plus. */
.wiki-prose table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    margin: 1em 0;
    font-size: 0.92rem;
}
.wiki-prose th, .wiki-prose td {
    text-align: left;
    padding: 8px 12px;
    border-bottom: 1px solid var(--line-soft);
    overflow-wrap: anywhere;
}
.wiki-prose th { color: var(--text-primary); background: var(--bg-chip); }
.wiki-prose td { color: var(--text-body); }

/* ─── Pages légales (CGU, confidentialité) ──────────────── */
/* Consultables sans connexion : rendues dans .main-content OU directement (NotAuthorized). */
.legal-prose { max-width: none; }
/* Le texte légal a beaucoup de titres numérotés : on resserre l'échelle du wiki-prose. */
.legal-prose h2 { font-size: 1.15rem; margin-top: 1.6em; }
.legal-prose h3 { font-size: 1rem; }

/* --text-body et non --text-muted : c'est la seule pastille de l'app qui pose une mention discrète
   sur --bg-chip, et l'aplat bleu y coûte assez de contraste pour que le discret tombe à 3,67:1 en
   sombre — le seul endroit où le token conforme ne suffit plus. Le corps de texte y sort à 6,18:1.
   Au passage c'est la bonne couleur sur le fond : « ce document est un brouillon » avertit le
   lecteur que ce qu'il lit n'engage rien, ce n'est pas une note de bas de page. */
.legal-draft {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-body);
    background: var(--bg-chip);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 4px 12px;
}

/* ══ Lecteur des documents légaux ════════════════════════════════════════════════════════
   Reprise de la maquette Claude Design « Conditions generales » : bandeau de titrage, titre de
   tête, bascule entre documents, sommaire collant. La maquette tire un design system « papier »
   clair et serif ; l'application n'ayant qu'un seul thème, ce lecteur prend SES jetons — seule la
   structure est reprise. Voir l'en-tête de LegalDocumentView.razor. */
.bhlg {
    max-width: min(var(--page-max), 100%);
    margin: 0 auto;
    padding: 40px 30px 80px;
}

/* Les trois filets du bandeau : épais, fin, puis le séparateur discret sous la tête. */
.bhlg-rule { height: 1px; background: var(--text-primary); }
.bhlg-rule--heavy { height: 4px; }
.bhlg-rule--soft { background: var(--border); }

.bhlg-masthead {
    display: flex; flex-wrap: wrap; gap: 15px;
    justify-content: space-between; align-items: baseline;
    padding: 8px 0 7px;
    font: 400 12px/1.4 var(--font-alt);
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--text-muted);
}
.bhlg-brand { color: var(--text-bright); font-weight: 600; }
/* La mention de brouillon garde SA casse et SON interlettrage : en capitales espacées comme le
   reste du bandeau, la phrase entière doublait de longueur et passait à la ligne. Elle conserve
   par ailleurs sa pastille, dont le contraste est mesuré (cf. ThemeCssTests). */
.bhlg-masthead .legal-draft { text-transform: none; letter-spacing: normal; }

/* Pas de largeur propre : la maquette bornait cette tête à 900px, ce que ShellLayoutCssTests
   interdit à raison — une largeur de cet ordre borne une PAGE, pas un composant, et chaque écran
   qui s'en donne une fait rediverger la colonne de lecture. Le titre prend donc la largeur du
   lecteur, et c'est le chapeau qui se borne, en `ch` : c'est lui que la mesure visait. */
.bhlg-head {
    display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px;
    padding: 40px 0 30px;
}
/* La maquette pose un serif de 76px. La police d'affichage d'ici est condensée et capitale : à
   taille égale elle hurlerait. Le palier est donc resserré — c'est la même intention de titre de
   une, dans la voix de l'application. */
.bhlg-title {
    margin: 0;
    font: 700 clamp(32px, 5vw, 56px)/1.02 var(--font-display);
    letter-spacing: .01em; text-transform: uppercase;
    color: var(--text-bright);
}
.bhlg-lede {
    margin: 0; max-width: 62ch;
    font: 400 18px/1.55 var(--font-alt);
    color: var(--text-body); text-wrap: pretty;
}
.bhlg-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 15px; padding-top: 5px; }

/* Bascule entre documents : des LIENS, pas des boutons radio — chaque document a sa route. */
.bhlg-seg {
    display: inline-flex; flex-wrap: wrap; overflow: hidden;
    border: 1px solid var(--border); border-radius: var(--radius);
}
.bhlg-seg-opt {
    display: inline-flex; align-items: center;
    padding: 7px 12px;
    font: 500 13px/1.2 var(--font-alt);
    color: var(--nav-ink); text-decoration: none;
}
.bhlg-seg-opt + .bhlg-seg-opt { border-left: 1px solid var(--border); }
.bhlg-seg-opt:hover { background: var(--bg-surface-hover); color: var(--nav-ink); }
.bhlg-seg-opt--on { background: var(--accent); color: var(--on-accent); }
.bhlg-seg-opt--on:hover { background: var(--accent); color: var(--on-accent); }
.bhlg-print { display: inline-flex; align-items: center; gap: 6px; }

.bhlg-grid {
    display: grid; grid-template-columns: 260px minmax(0, 1fr);
    gap: 50px; padding-top: 40px; align-items: start;
}

/* Le sommaire colle DANS la zone défilante : le `body` est en overflow hidden, c'est le conteneur
   de contenu qui défile, et `position: sticky` s'y accroche sans rien de plus. */
.bhlg-toc {
    position: sticky; top: 30px;
    display: flex; flex-direction: column; gap: 10px;
    padding-bottom: 20px; min-width: 0;
}
.bhlg-toc-h {
    font: 400 11px/1.2 var(--font-alt);
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--text-muted);
}
.bhlg-toc-link {
    display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 8px;
    padding: 3px 4px; border-radius: var(--radius);
    font: 400 15px/1.35 var(--font-alt);
    color: var(--nav-ink); text-decoration: none;
}
.bhlg-toc-link:hover { background: var(--bg-surface-hover); color: var(--nav-ink); }
.bhlg-toc-num { font-variant-numeric: tabular-nums; color: var(--text-muted); }
/* Le titre en cours de lecture, marqué par le suivi de lecture (legal-toc.js). L'attribut plutôt
   qu'une classe : il dit la même chose à l'œil et au lecteur d'écran. */
.bhlg-toc-link[aria-current] { color: var(--brand-red-light); }
.bhlg-toc-link[aria-current] .bhlg-toc-num { color: var(--brand-red-light); }
.bhlg-toc-aside {
    margin: 15px 0 0; max-width: 26ch;
    font: 400 13px/1.5 var(--font-alt);
    color: var(--text-muted);
}

.bhlg-article { max-width: 70ch; min-width: 0; }
/* Le sommaire amène sur un titre : sans cette réserve il se collerait au bord haut de la zone. */
.bhlg-article h2 { scroll-margin-top: 30px; }

/* Une seule colonne quand la place manque : c'est le seuil de la maquette. Le sommaire repasse en
   tête de document, déroulé, et cesse de coller. */
@media (max-width: 820px) {
    .bhlg { padding: 24px 16px 60px; }
    .bhlg-grid { grid-template-columns: minmax(0, 1fr); gap: 28px; padding-top: 28px; }
    .bhlg-toc { position: static; }
}

/* Le bouton « Télécharger en PDF » n'appelle que l'impression du navigateur : c'est cette feuille
   qui rend le résultat lisible. On ne garde que le document — le reste est de la navigation, qui
   n'a aucun sens sur du papier. */
@media print {
    .bhlg-actions, .bhlg-toc, .bh-topbar, .appnav, .bh-foot, .bh-foot-bar { display: none; }
    .bhlg-grid { grid-template-columns: minmax(0, 1fr); gap: 0; padding-top: 20px; }
    .bhlg { max-width: none; padding: 0; }
    .bhlg-article { max-width: none; }
}
.legal-fallback {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--accent-light);
    background: var(--accent-subtle);
    border: 1px solid var(--accent-subtle);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 16px;
}

@media (max-width: 820px) {
    .wiki-layout { grid-template-columns: 1fr; gap: 12px; }
    .wiki-sidebar {
        position: static;
        border-right: none;
        padding-right: 0;
    }
    /* Le sommaire déplié fait ~23 liens, soit plus d'une hauteur d'écran : en bloc statique il
       repoussait l'article entièrement hors de vue. Replié par défaut, il tient sur une ligne. */
    .wiki-nav-toggle {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        padding: 10px 12px;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--bg-panel);
        color: var(--text-primary);
        font: inherit;
        font-weight: 600;
        text-align: left;
        cursor: pointer;
    }
    .wiki-nav-caret { margin-left: auto; transition: transform .15s; }
    .wiki-nav-panel { display: none; }
    .wiki-nav-panel.is-open {
        display: flex;
        margin-top: 8px;
        padding-bottom: 12px;
        border-bottom: 1px solid var(--line-soft);
        /* Plafonné et défilant chez lui : même déplié, le sommaire laisse voir le début de
           l'article sous la fenêtre. */
        max-height: 55vh;
        overflow-y: auto;
    }
    .wiki-sidebar:has(.wiki-nav-panel.is-open) .wiki-nav-caret { transform: rotate(180deg); }
    .wiki-prose { padding: 14px 16px; }
}

/* Page Documentation API */
.wiki-api-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 4px 0 20px; }
.wiki-api-loading { color: var(--text-dim); }
.wiki-api-tag { margin-bottom: 22px; }
.wiki-api-tag h2 {
    margin: 0 0 8px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--line-soft);
    color: var(--text-primary);
    font-size: 1.1rem;
}
.wiki-api-op {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius);
    flex-wrap: wrap;
}
.wiki-api-op:hover { background: var(--bg-surface-hover); }
.wiki-api-path { font-size: 0.9rem; color: var(--text-bright); background: none; padding: 0; }
.wiki-api-summary { font-size: 0.85rem; color: var(--text-dim); }
.api-method {
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    padding: 2px 8px;
    border-radius: var(--radius);
    min-width: 52px;
    text-align: center;
}
.api-method--get    { color: var(--sky-fg);  background: var(--tint-blue-bg); }
.api-method--post   { color: var(--green-fg); background: var(--tint-green-bg); }
.api-method--put,
.api-method--patch  { color: var(--gold-fg); background: var(--tint-gold-bg); }
.api-method--delete { color: var(--red-fg);  background: var(--tint-red-bg); }

/* ═══ Équipes (team-*) ══════════════════════════════════════════════════════
   La grille est mutualisée avec .org-grid (voir plus haut). L'indicateur de
   sanction réutilise .tour-flag tel quel, aucun style dupliqué ici.
   ══════════════════════════════════════════════════════════════════════════ */

.team-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    width: 100%;
    text-align: left;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    font-family: inherit;
    color: var(--text-primary);
    transition: border-color 0.15s, transform 0.1s, background 0.15s;
}
.team-card:hover {
    border-color: var(--border-hover);
    transform: translateY(-1px);
    background: radial-gradient(120% 160% at 0% 0%, var(--accent-subtle) 0%, transparent 60%), var(--bg-surface);
}

.team-crest, .team-crest-img, .team-crest-initials {
    width: 48px;
    height: 48px;
    border-radius: var(--radius);
    flex-shrink: 0;
}
.team-crest-img { object-fit: cover; }
.team-crest-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font-size: 16px;
    font-weight: 600;
}
.team-crest-lg, .team-crest-lg.team-crest-img, .team-crest-lg.team-crest-initials {
    width: 66px;
    height: 66px;
    border-radius: var(--radius);
    font-size: 20px;
}

.team-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.team-card-name {
    font-size: 15px;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.team-card-sub {
    font-size: 12.5px;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 6px;
}

.team-tag {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--accent-light);
    background: var(--tint-blue-bg);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 2px 6px;
    flex-shrink: 0;
}

.team-role-pill {
    font-size: 10px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 700;
    border-radius: var(--radius);
    padding: 3px 7px;
    flex-shrink: 0;
    white-space: nowrap;
    background: var(--bg-chip);
    color: var(--text-soft);
}
.team-role-pill--captain { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.team-role-pill--pending { background: var(--bg-chip); color: var(--text-secondary); }

.team-filters { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.team-filters .input-sm { min-width: 240px; flex: 1; max-width: 420px; }

/* Ligne à deux champs : surtout PAS .field, qui empile en colonne. */
.team-create-row { display: flex; gap: 12px; flex-wrap: wrap; }
.team-create-row .field { flex: 1; min-width: 220px; }
.team-create-row .team-tag-field { flex: 0 0 130px; min-width: 110px; }

/* ── Bandeau de la fiche d'équipe ─────────────────────────────────────────── */

.team-hero {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 20px;
    border: 0.5px solid var(--border);
    background-size: cover;
    background-position: center;
}
.team-hero--empty { background: linear-gradient(135deg, var(--bg-elevated), var(--bg-surface)); }
.team-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10,10,12,0.30) 0%, rgba(10,10,12,0.86) 100%);
}
.team-hero--empty::before { background: none; }

.team-hero-in {
    position: relative;
    display: flex;
    align-items: flex-end;
    gap: 16px;
    padding: 40px 22px 20px;
    flex-wrap: wrap;
}
.team-hero-body { flex: 1; min-width: 200px; }
.team-hero-name { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.team-hero-name h1 { font-size: 24px; font-weight: 700; margin: 0; }
.team-hero-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    font-size: 13px;
    margin: 6px 0 0;
}
.team-hero-facts span { display: inline-flex; align-items: center; gap: 6px; }
.team-hero-desc { margin: 8px 0 0; font-size: 13.5px; max-width: 70ch; }
.team-hero-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* Sur bannière, le texte est toujours posé sur photo : blanc assumé (même exception
   que le hero de tournoi et la bannière d'organisation). */
.team-hero:not(.team-hero--empty) .team-hero-name h1 { color: #fff; }
.team-hero:not(.team-hero--empty) .team-hero-facts,
.team-hero:not(.team-hero--empty) .team-hero-desc { color: #d2d4d9; }

.team-banner-edit-btn {
    position: absolute;
    top: 12px;
    right: 14px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(10,10,12,0.62);
    border: 1px solid rgba(255,255,255,0.16);
    color: #f2f7ff;
    border-radius: var(--radius);
    padding: 6px 11px;
    font-size: 12px;
    cursor: pointer;
}
.team-logo-upload { position: relative; display: inline-block; cursor: pointer; }
.team-logo-edit {
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--on-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--bg-page);
    font-size: 12px;
}

/* ── Effectif ─────────────────────────────────────────────────────────────── */

.team-member-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 0.5px solid var(--line-soft);
}
.team-member-row:last-child { border-bottom: 0; }
.team-member-row:hover { background: var(--bg-hover); }
.team-member-row--pending { background: var(--bg-inset); }
.team-member-row--flagged .team-member-name > a { color: var(--text-secondary); }

.team-member-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
}
.team-member-ident { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.team-member-name { display: flex; align-items: center; font-size: 14px; font-weight: 500; }
.team-member-name > a { color: var(--text-primary); text-decoration: none; }
.team-member-name > a:hover { color: var(--accent-light); }
.team-member-meta { font-size: 12px; color: var(--text-muted); }
.team-member-spacer { flex: 1; }

.team-invite-results {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 10px;
    max-height: 280px;
    overflow-y: auto;
}
.team-invite-result {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    background: var(--surface-2);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    font-family: inherit;
    color: var(--text-primary);
    text-align: left;
}
.team-invite-result:hover { border-color: var(--border-hover); background: var(--bg-hover); }
.team-invite-result > span:nth-child(2) { flex: 1; display: flex; flex-direction: column; gap: 1px; }
.team-invite-result i { color: var(--accent); }

.panel-count { color: var(--text-muted); font-weight: 400; }

@media (max-width: 720px) {
    .team-hero-in { padding: 32px 16px 16px; }
    .team-hero-actions { width: 100%; }
    .team-create-row .team-tag-field { flex: 1 1 100%; }
}

/* Nom propre aux tuiles de statistiques. NE PAS renommer en « stats-grid » : cette classe-là
   existe déjà plus haut (ligne ~807) pour les cartes du tableau de bord et de l'administration,
   en repeat(4, 1fr). Les deux règles ayant la même spécificité, la seconde écrasait la première
   PARTOUT et rétrécissait ces cartes à 150 px — corrigé après coup, Bogue #327. */
.stat-tiles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
}

.stat-tile {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 11px 14px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.stat-tile-label {
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
}
.stat-tile-value {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 24px;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
/* Une valeur non mesurée n'est pas un zéro : elle s'affiche en tiret, en retrait. */
.stat-tile-value--none { color: var(--text-muted); font-weight: 400; }

.stat-tile-hint {
    font-size: 11px;
    color: var(--text-muted);
}

/* ── Chiffres clés : mêmes tuiles, mises en avant (chiffre plus gros, base de calcul dessous) ──
   Une seule grille pour les quatre, avec ou sans anneau. Elle a d'abord été scindée en deux (un
   bandeau de chiffres bruts au-dessus des anneaux) parce qu'une grille étire ses cases à la hauteur
   de la plus grande : les cases sans anneau y gagnaient 176 px de vide. Le centrage de .stat-hero,
   ajouté depuis, a réglé ce vide — et la scission, elle, coûtait une ligne entière (111 px + la
   gouttière) sur un écran large où les quatre cases tiennent côte à côte.
   Colonnes comptées, et non un auto-fit : à quatre cases, une grille fluide finit par tomber sur
   trois colonnes et laisse la quatrième seule sur une deuxième ligne. Quatre, puis deux, puis une. */
.stat-heroes {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}
@media (max-width: 1200px) { .stat-heroes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .stat-heroes { grid-template-columns: 1fr; } }
/* Contenu centré, horizontalement et verticalement : la grille étire toutes les cases à la hauteur
   de la plus grande (celles à jauge), et un chiffre calé en haut laissait sinon 120 px de vide en
   dessous. Centrer aligne aussi les quatre cases entre elles, avec ou sans anneau. */
.stat-hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 3px;
    padding: 13px 18px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.stat-hero-label {
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
}
.stat-hero-value {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 32px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}
.stat-hero-basis {
    font-size: 12px;
    color: var(--text-soft);
    font-variant-numeric: tabular-nums;
}

/* ── Code couleur des valeurs ───────────────────────────────────────────────
   Deux teintes, et pas de rouge : une fiche publique n'a pas à pointer du doigt un joueur sous la
   moyenne — le gris par défaut dit « ordinaire » sans rien reprocher. Or = remarquable,
   vert = solide. Les deux variables existent dans les deux thèmes : rien à ajouter en clair. */
.stat-tone--gold  { color: var(--gold-fg); }
.stat-tone--green { color: var(--green-fg); }

/* ── Jauges (anneaux) ──────────────────────────────────────────────────────
   Réservées aux données à échelle bornée ou à référence explicite : taux de victoire (0–100 %) et
   K/D (plein à 2,00, repère au 1,00). Ailleurs, un anneau inventerait un maximum. */
.stat-hero--gauge { gap: 6px; }

.stat-gauge {
    position: relative;
    width: 88px;
    height: 88px;
    margin: 2px 0;
}
.stat-gauge-svg { display: block; width: 100%; height: 100%; }
.stat-gauge-track {
    fill: none;
    stroke: var(--line-strong);
    stroke-width: 8;
}
/* L'arc reprend la teinte du chiffre qu'il illustre. Surcharges écrites en toutes lettres, et non
   via un currentColor hérité de .stat-tone--* : les deux sélecteurs ont la même spécificité, celui
   déclaré en dernier gagnait — l'arc restait bleu sous un chiffre passé en or. */
.stat-gauge-arc {
    fill: none;
    stroke: var(--accent);
    stroke-width: 8;
    stroke-linecap: round;
}
.stat-gauge-arc.stat-tone--gold  { stroke: var(--gold-fg); }
.stat-gauge-arc.stat-tone--green { stroke: var(--green-fg); }
.stat-gauge-ref { stroke: var(--text-muted); stroke-width: 2; }
.stat-gauge-value {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
}
/* L'échelle, écrite. C'est elle qui sépare une jauge d'une décoration : sans elle, personne ne
   peut dire ce que « l'anneau aux trois quarts » signifie. */
.stat-gauge-scale { font-size: 11px; color: var(--text-muted); }

/* Les deux termes du quotient, sous l'anneau : le K/D au-dessus de ses éliminations et de ses
   morts, le taux de victoire au-dessus de ses parties gagnées et de son total. */
.stat-gauge-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 14px;
    margin-top: 6px;
    padding-top: 8px;
    border-top: 0.5px solid var(--line-soft);
    width: 100%;
}
.stat-gauge-term { display: flex; flex-direction: column; align-items: center; gap: 2px; }
/* Le trait reprend la couleur de l'arc pour le premier terme, celle de l'anneau creux pour le
   second : la couleur dit lequel des deux remplit la jauge. Surcharges explicites — même piège de
   spécificité que .stat-gauge-arc. */
.stat-gauge-tick {
    width: 18px;
    height: 3px;
    border-radius: var(--radius);
    background: var(--accent);
}
.stat-gauge-tick.stat-tone--gold  { background: var(--gold-fg); }
.stat-gauge-tick.stat-tone--green { background: var(--green-fg); }
.stat-gauge-tick--rest { background: var(--line-strong); }
.stat-gauge-term-label {
    font-size: 10.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
}
.stat-gauge-term-value {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

/* ── Barres de paliers (Top 3 / 5 / 10) ────────────────────────────────────
   Des proportions d'un même total, pas des compteurs indépendants : le dénominateur est écrit à
   côté, sinon « 3 » ne dit pas si c'est sur 4 tournois ou sur 40. */
.stat-bars-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 10px;
    padding: 13px 18px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.stat-bar-row {
    display: grid;
    grid-template-columns: 64px 1fr auto;
    align-items: center;
    gap: 12px;
}
.stat-bar-label { font-size: 12.5px; color: var(--text-secondary); }
.stat-bar-track {
    height: 6px;
    border-radius: var(--radius);
    background: var(--line-strong);
    overflow: hidden;
}
.stat-bar-fill { height: 100%; border-radius: var(--radius); }
/* Trois paliers emboîtés, du plus exigeant au plus large : la teinte suit cet ordre. */
.stat-bar-fill--top3  { background: var(--gold-fg); }
.stat-bar-fill--top5  { background: var(--green-fg); }
.stat-bar-fill--top10 { background: var(--accent); }
.stat-bar-count {
    font-size: 12.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.stat-bar-count b { color: var(--text-primary); font-weight: 600; }

/* ── Courbe de progression ─────────────────────────────────────────────── */
.stat-chart-card {
    padding: 16px 18px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.stat-chart-sub {
    font-size: 12.5px;
    color: var(--text-muted);
}
/* viewBox + largeur fluide : la courbe s'adapte à sa colonne au lieu de la déborder. */
.stat-chart-plot { margin-top: 12px; }
.stat-chart-svg { display: block; width: 100%; height: auto; }
.stat-chart-grid { stroke: var(--border); stroke-width: 1; }
.stat-chart-tick {
    font-size: 11px;
    fill: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.stat-chart-area { fill: var(--accent-subtle); }
.stat-chart-line {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}
.stat-chart-dot { fill: var(--accent); stroke: var(--bg-surface); stroke-width: 2; }
.stat-chart-dot--win { fill: var(--gold-fg); }

/* Note d'état vide (gains non perçus) : un cadre discret, pas un tableau. */
.stat-empty-note {
    padding: 14px 16px;
    background: var(--bg-surface);
    border: 0.5px dashed var(--line-strong);
    border-radius: var(--radius);
    color: var(--text-soft);
    font-size: 13px;
}
.stats-earnings-cell { font-variant-numeric: tabular-nums; color: var(--text-body); }

/* Rang final : les trois premières places se lisent d'un coup d'œil. */
.stats-rank {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 26px;
    padding: 2px 7px;
    border-radius: var(--radius);
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    background: var(--bg-chip);
    color: var(--text-secondary);
}
.stats-rank--1 { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.stats-rank--2 { background: var(--bg-chip); color: var(--text-primary); }
.stats-rank--3 { background: var(--tint-orange-bg); color: var(--gold-fg); }

/* ── Saisie des résultats : grille joueur × statistique ────────────────────── */

.res-grid { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }

.res-grid-head, .res-grid-row {
    display: grid;
    grid-template-columns: minmax(90px, 1.6fr) repeat(4, minmax(58px, 1fr));
    gap: 8px;
    align-items: center;
}
.res-grid-head span {
    font-size: 10.5px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
}
.res-grid-head span:not(:first-child) { text-align: center; }

.res-grid-player {
    font-size: 13px;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.res-grid-row .res-input { width: 100%; text-align: center; }

.res-optional-hint { margin-top: 8px; }

@media (max-width: 720px) {
    .res-grid-head, .res-grid-row {
        grid-template-columns: minmax(70px, 1.2fr) repeat(4, minmax(46px, 1fr));
        gap: 5px;
    }
    .stats-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

/* ═══ Inscription par équipe (tour-team-*) ═════════════════════════════════ */

.tour-team-entry { display: flex; flex-direction: column; gap: 12px; }

/* Sélection de l'alignement : une puce cliquable par membre, l'état se lit d'un coup d'œil. */
.tour-lineup-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 8px;
}
.tour-lineup-pick {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    font-family: inherit;
    color: var(--text-primary);
    text-align: left;
    width: 100%;
}
.tour-lineup-pick:hover { border-color: var(--border-hover); background: var(--bg-hover); }
.tour-lineup-pick--on { border-color: var(--accent); background: var(--accent-subtle); }
.tour-lineup-pick--off { opacity: .5; cursor: not-allowed; }

.tour-lineup-check {
    width: 18px; height: 18px; flex: none;
    border-radius: var(--radius);
    border: 1.5px solid var(--border-input);
    display: grid; place-items: center;
    font-size: 11px;
}
.tour-lineup-pick--on .tour-lineup-check {
    background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
.tour-lineup-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tour-lineup-count { font-size: 12.5px; color: var(--text-muted); }
.tour-lineup-count--ok { color: var(--green-fg); font-weight: 600; }

/* Équipe en sous-effectif : le refus doit se LIRE. Sans ce bandeau, le compteur restait sur
   « 2 / 3 » et le bouton grisé, sans jamais nommer ce qui manque ni où le régler. Même grammaire
   que .discord-link-notice (icône · phrase · sortie), mais en tokens de statut : ce n'est pas une
   invitation, c'est ce qui bloque l'inscription. */
.tour-lineup-short {
    display: flex;
    align-items: center;
    /* La sortie passe SOUS la phrase quand la ligne ne les tient plus tous les deux. Sans ce repli,
       le lien — insécable — s'adjuge sa largeur et laisse la phrase se dérouler dans une colonne de
       quelques mots : à 375 px elle tombait sur cinq lignes. C'est le défaut même que ce bandeau
       vient annoncer, il n'a pas à le reproduire. */
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 14px;
    border: 0.5px solid var(--tint-orange-border);
    border-left: 3px solid var(--orange-fg);
    border-radius: var(--radius);
    background: var(--tint-orange-bg);
    font-size: 13px;
    color: var(--text-secondary);
}
.tour-lineup-short i { color: var(--orange-fg); font-size: 18px; flex: none; }
/* Plancher de lisibilité : sous 200 px la phrase se hache, mieux vaut renvoyer le lien à la ligne. */
.tour-lineup-short span { flex: 1 1 200px; }
.tour-lineup-short a { color: var(--accent); font-weight: 500; text-decoration: none; white-space: nowrap; }
.tour-lineup-short a:hover { text-decoration: underline; }

/* Équipes inscrites : un bloc par équipe, ses joueurs dessous. */
.tour-team-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 10px;
}
.tour-team-card {
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 13px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.tour-team-card--waitlisted { background: var(--bg-inset); }
/* Équipe validée : teinte verte de la carte (le vert de statut déjà utilisé par .tour-payment-badge),
   plus lisible d'un coup d'œil qu'un badge, et libère la ligne du nom. */
.tour-team-card--validated {
    border-color: rgba(151, 196, 89, 0.45);
    background: rgba(151, 196, 89, 0.08);
}
.tour-team-card-head { display: flex; align-items: center; gap: 10px; }
/* Pictogramme de statut sans texte (aligné à droite) : ne rogne pas le nom d'équipe. */
.tour-team-card-status {
    margin-left: auto;
    align-self: flex-start;
    display: inline-flex;
    font-size: 18px;
    line-height: 1;
}
.tour-team-card-status.is-validated { color: var(--lime-fg); }
.tour-team-card-status.is-pending { color: var(--text-secondary); }
.tour-team-crest, .tour-team-crest.team-crest-initials {
    width: 40px;
    height: 40px;
    border-radius: var(--radius);
    font-size: 14px;
}
.tour-team-card-id { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tour-team-card-name {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tour-team-card-id .team-tag { align-self: flex-start; }
.tour-team-wait-badge {
    margin-left: auto;
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10.5px;
    color: var(--gold-fg);
    background: var(--bg-chip);
    border-radius: var(--radius);
    padding: 2px 7px;
    white-space: nowrap;
}
.tour-team-card-players {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    border-top: 0.5px solid var(--border);
    padding-top: 10px;
}
.tour-team-card-player {
    font-size: 12px;
    padding: 3px 9px;
    border-radius: var(--radius);
    background: var(--bg-chip);
    color: var(--text-secondary);
}
.tour-team-card-spacer { flex: 1; }
/* Validation à l'échelle de l'équipe : boutons alignés à droite sous le roster. */
.tour-team-card-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
}

@media (max-width: 720px) {
    .tour-lineup-grid { grid-template-columns: 1fr; }
}

/* ─── Sélecteur de catégorie de statistiques ─────────────── */
.stats-category-picker,
.stats-season-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 18px;
}
/* Le sélecteur de saison coiffe toute la fiche : un cran de séparation sous lui. */
.stats-season-picker { margin-bottom: 4px; padding-bottom: 14px; border-bottom: 0.5px solid var(--line-soft); }
.stats-category-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 13px;
    border-radius: var(--radius);
    border: 0.5px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.stats-category-chip:hover { color: var(--text-primary); border-color: var(--line-strong); }
.stats-category-chip--active {
    background: var(--accent-subtle);
    border-color: var(--accent);
    color: var(--accent);
}
.stats-category-count {
    font-size: 11px;
    opacity: 0.75;
    font-variant-numeric: tabular-nums;
}
.stats-category-tag {
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
}

/* ─── Fiche joueur au survol (PlayerHoverCard) ─────────────────────────────

   Design « carte de collection » : silhouette découpée (coins hauts biseautés, léger pic au
   sommet, pointe en bas), liseré néon, trame diagonale, chiffre de tête à gauche, avatar cerclé
   à droite, nom au centre, six statistiques sur deux colonnes, ligne de pied.

   Mécanique reprise de .tour-flag-tip : la fiche vit dans le flux, cachée par visibility, et
   s'ouvre au survol OU au focus clavier (:focus-within) — le survol seul exclurait la navigation
   au clavier. pointer-events reste à none tant qu'elle est fermée, sinon une fiche invisible
   intercepterait les clics de la ligne en dessous.

   Le liseré suit la découpe par imbrication (cadre en dégradé, carte opaque par-dessus) :
   border-image ne se compose pas avec clip-path, et un simple border dessinerait un rectangle. */
/* ─── Carte de survol d'un joueur — dessin 26 ────────────────────────────────
   Palier, points de saison, PLACE et une seule distinction — la plus haute.

   🔴 Les couleurs de rang sont des couleurs d'IDENTITÉ, au même titre que celles des
   marques : un Platine turquoise et un Or doré désignent le palier lui-même, ils ne
   décrivent pas une surface. Elles vivent donc dans leur propre table, séparée des tokens
   de surface. */
:root {
    --rank-01-rang:       #7c8ca1;
    --rank-02-bronze:     #b78c5a;
    --rank-03-argent:     #a9b6c6;
    --rank-04-or:         #f3c256;
    --rank-05-platine:    #7ad3d1;
    --rank-06-diamant:    #8cc6ff;
    --rank-07-ecarlate:   #ff7285;
    --rank-08-iridescent: #dfa9ff;
}

.phc { position: relative; display: inline-flex; max-width: 100%; }

.phc-trigger { display: inline-flex; align-items: center; min-width: 0; cursor: help; border-radius: var(--radius); }
.phc-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 🔴 Plus de `clip-path` : le dessin 26 abandonne la silhouette à pointes pour une carte
   arrondie ordinaire. Le polygone découpait le contenu dès que la carte grandissait — et
   elle grandit désormais, la ligne de distinction n'apparaissant que pour certains. */
.phc-pop {
    position: absolute;
    top: calc(100% + 7px);
    left: 0;
    z-index: 60;
    display: block;
    width: 352px;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity .14s ease, transform .14s ease;
    pointer-events: none;
    filter: drop-shadow(0 18px 40px var(--shadow-strong));
}
.phc:hover .phc-pop,
.phc:focus-within .phc-pop { opacity: 1; visibility: visible; transform: translateY(0); }

/* 🔴 `display: none` au doigt, et pas seulement `visibility: hidden` : il n'y a PAS de survol sur un
   écran tactile, donc la carte n'y sert à rien — mais `visibility: hidden` la laisse OCCUPER LA MISE
   EN PAGE, et ses 352px de large gonflaient le défilement de la page qui l'héberge. Mesuré sur
   /organizations/{id} : 124px de dérive latérale à 360px de fenêtre, pour une carte que personne ne
   verra jamais là. Tant que le panneau parent rognait, le débordement était masqué ; en le retirant
   pour que la carte s'affiche ENTIÈRE au survol (cf. .bhog-panel--flush et .bhtm-panel), il est
   remonté à la surface. Les deux correctifs ne tiennent qu'ensemble.
   ⚠️ Ne pas remplacer par `content-visibility` ni par une marge négative : c'est la contribution au
   débordement qu'il faut supprimer, pas seulement le rendu. */
@media (pointer: coarse) {
    .phc-pop { display: none; }
}

.phc-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-surface);
    overflow: hidden;
}

/* Le rail prend la couleur du rang et s'éteint vers la droite : il désigne sans peser. */
.phc-rail { height: 3px; background: linear-gradient(90deg, var(--phc-tier), transparent); }

.phc-head { display: flex; align-items: flex-start; gap: 13px; padding: 16px 18px 15px; }
.phc-av-wrap { position: relative; flex: none; }

.phc-av {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    overflow: hidden;
    font: 700 19px/1 var(--font-display);
    letter-spacing: .03em;
    color: var(--phc-tier);
    background: var(--bg-inset);
}
.phc-av img { width: 100%; height: 100%; object-fit: cover; }

/* 🔴 EX-ID-25 : le liseré appartient au REPLI EN INITIALES, jamais à la photo. Posé sur un
   avatar, il l'enferme dans un anneau que rien ne justifie. */
.phc-av--initials { border: 1px solid var(--phc-tier); }

.phc-av-badge {
    position: absolute;
    right: -4px;
    bottom: -4px;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 1px solid var(--border);
}
.phc-av-badge img { width: 17px; height: 17px; display: block; }

.phc-id { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; padding-top: 2px; }

.phc-name {
    font: 700 21px/1.05 var(--font-display);
    text-transform: uppercase;
    letter-spacing: .015em;
    color: var(--text-bright);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.phc-sub { display: flex; align-items: center; gap: 9px; min-width: 0; font: 400 10.5px/1 var(--font-mono); color: var(--text-muted); }
.phc-tier { color: var(--phc-tier); white-space: nowrap; }
.phc-dot { color: var(--line-strong); }
.phc-handle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.phc-score {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 18px;
    border-top: 1px solid var(--line-soft);
    background: var(--bg-inset);
}
.phc-pts { font: 700 27px/1 var(--font-mono); color: var(--text-bright); }
.phc-pts-k { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; color: var(--text-muted); }
.phc-spacer { flex: 1; }
.phc-pos { display: flex; align-items: baseline; gap: 3px; }
.phc-pos b { font: 700 18px/1 var(--font-mono); color: var(--text-soft); }
.phc-pos span { font: 400 10px/1 var(--font-mono); color: var(--text-muted); }

.phc-dist {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 12px 18px;
    border-top: 1px solid var(--line-soft);
    background: var(--tint-gold-bg);
}
.phc-dist img { width: 26px; height: 26px; flex: none; display: block; }
.phc-dist > span { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.phc-dist b { font: 600 11.5px/1 var(--font-alt); color: var(--gold-fg); }
.phc-dist > span > span { font: 400 10px/1.35 var(--font-alt); color: var(--gold-on-tint); }

.phc-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; border-top: 1px solid var(--line-soft); }
.phc-stat { display: flex; flex-direction: column; gap: 6px; padding: 13px 0 14px 16px; }
.phc-stat + .phc-stat { border-left: 1px solid var(--line-soft); }
.phc-stat b { font: 700 15px/1 var(--font-mono); color: var(--text-primary); order: 2; }
.phc-stat span { font: 500 8.5px/1 var(--font-mono); letter-spacing: .13em; text-transform: uppercase; color: var(--text-muted); order: 1; }

.phc-note {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 18px 12px;
    border-top: 1px solid var(--line-soft);
    background: var(--bg-inset);
}
.phc-note-dot { width: 5px; height: 5px; flex: none; border-radius: 50%; background: var(--accent); }
.phc-note-txt { font: 400 10px/1.45 var(--font-alt); color: var(--text-soft); }
.phc-note-go { flex: none; font: 600 10.5px/1 var(--font-alt); color: var(--accent); }

.phc-msg {
    display: grid;
    place-items: center;
    padding: 26px 18px;
    font: 400 11px/1.4 var(--font-alt);
    color: var(--text-muted);
    border-top: 1px solid var(--line-soft);
}

@media (prefers-reduced-motion: reduce) {
    .phc-pop { transition: none; transform: none; }
    .phc:hover .phc-pop, .phc:focus-within .phc-pop { transform: none; }
}

/* ─── Profil joueur « broadcast » (écran 3e) ─────────────────────────────────
   Surface sombre inhérente (bannière + art e-sport), au même titre que le hero de tournoi :
   couleurs d'art fixes assumées (exception de la règle de tokenisation, cf. CLAUDE.md), valables
   sur les deux thèmes. Namespace .bhpp-. Réutilise .bhbg-* (écus de badges) et badges/0X-*.png. */
.bhpp { max-width: min(var(--page-max), 100%); margin: 0 auto; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: transparent;   /* laisse passer le fond animé de la page */ color: var(--text-secondary); font-family: 'Archivo', system-ui, sans-serif; }

/* Le HERO reste sombre dans les deux thèmes : c'est une zone de couverture (bannière/photo) et
   le voile sombre garantit la lisibilité du texte blanc par-dessus, comme les autres heros. */
.bhpp-hero { position: relative; overflow: hidden; border-bottom: 1px solid #243660; }
.bhpp-hero-bg { position: absolute; inset: 0; background-size: cover; background-position: center; }
.bhpp-hero-bg--empty { background: repeating-linear-gradient(115deg, #203255 0 14px, #141e33 14px 28px); }
.bhpp-hero-veil { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(var(--bg-page-rgb),.5), rgba(var(--bg-page-rgb),.94) 70%, var(--bg-page)); }
.bhpp-hero-in { position: relative; padding: 30px 40px 24px; display: flex; align-items: flex-end; gap: 26px; flex-wrap: wrap; }

.bhpp-avatar { width: 104px; height: 104px; border-radius: var(--radius); background: #1a2436; display: grid; place-items: center; font: 700 38px/1 'Barlow Condensed', sans-serif; color: #5fc3ff; flex: none; overflow: hidden; }
.bhpp-avatar img { width: 100%; height: 100%; object-fit: cover; }

.bhpp-id { display: flex; flex-direction: column; gap: 11px; flex: 1 1 320px; min-width: 260px; }
.bhpp-chips { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bhpp-chip-emblem { width: 18px; height: 18px; object-fit: contain; display: block; margin-left: -3px; }
.bhpp-chip { display: inline-flex; align-items: center; gap: 6px; height: 22px;padding: 0 9px; border-radius: var(--radius); font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: .08em; text-transform: uppercase; }
.bhpp-chip--rank { background: rgba(243,194,86,.14); border: 1px solid rgba(243,194,86,.45); color: #f3c256; }
.bhpp-chip--discord { background: #252a52; color: #c3cbf7; }
.bhpp-chip--muted { font-weight: 500; letter-spacing: .12em; color: #789cda; }
.bhpp-name { margin: 0; font: 700 54px/.94 'Barlow Condensed', sans-serif; text-transform: uppercase; color: #f2f7ff; word-break: break-word; }
.bhpp-orgline { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bhpp-orgline .org-pills { margin: 0; }
.bhpp-sep { width: 1px; height: 14px; background: #243660; }
.bhpp-orgmeta { font: 500 11px/1 'JetBrains Mono', monospace; color: #8db0e8; letter-spacing: .06em; }

/* ── Liens du joueur (US #1024) ────────────────────────────────────────────────────────────────
   Les bascules « affiche ce lien » du profil n'aboutissaient nulle part : elles reglaient une
   publication qui n'existait pas. Le filtrage vit dans l'Api (ToPublicDto rend null pour un lien
   masque) -- ici on ne fait qu'afficher.

   ⚠️ Couleurs en dur, comme tout le hero de cette fiche : il est pose sur la BANNIERE du joueur,
   l'une des trois zones ou les tokens de theme ne s'appliquent pas (cf. .bhpp-name, .bhpp-chip--*).
   Les teintes de marque en font partie. Ne pas "tokeniser" ce bloc sans deplacer le hero. */
.bhpp-links { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bhpp-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    max-width: 100%;
    min-height: 28px;
    padding: 0 11px;
    border-radius: var(--radius);
    border: 1px solid rgba(255,255,255,.12);
    background: rgba(10,10,12,.55);
    font: 500 11.5px/1 'JetBrains Mono', monospace;
    color: #bcd3fa;
    text-decoration: none;
}
.bhpp-link i { font-size: 15px; flex: none; }
/* Le pseudo peut etre long : il se tronque, il ne pousse pas la rangee hors du bandeau. */
.bhpp-link span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.bhpp-link:hover, a.bhpp-link:focus-visible { border-color: rgba(255,255,255,.3); color: #f2f7ff; }
/* Seule l'ICONE porte la teinte de marque : en 3:1 elle suffit pour un decor, la ou le texte
   demanderait 4,5:1 -- et quatre pastilles de marque pleines transformeraient le bandeau en
   rangee de logos. Discord n'est pas un <a> : pas d'etat de survol, rien a ouvrir. */
.bhpp-link--twitch i { color: #a970ff; }
.bhpp-link--youtube i { color: #ff4e45; }
.bhpp-link--x i { color: #e7ecf3; }
.bhpp-link--discord i { color: #7d8ceb; }

.bhpp-rankcard { display: flex; align-items: center; gap: 18px; padding: 16px 22px; border-radius: var(--radius); border: 1px solid #395898; background: rgba(19,20,24,.8); flex: none; }
.bhpp-rankcard img { width: 74px; height: 74px; display: block; flex: none; }
.bhpp-rankcard-txt { display: flex; flex-direction: column; gap: 7px; }
.bhpp-rankcard-name { font: 700 24px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; color: #f3c256; }
.bhpp-rankcard-meta { font: 500 10px/1 'JetBrains Mono', monospace; letter-spacing: .1em; color: #8a7440; }
.bhpp-rankcard-note { font: 400 10.5px/1.4 'Archivo', sans-serif; color: #8db0e8; max-width: 210px; }

.bhpp-body { display: grid; grid-template-columns: 1fr 320px; }
/* Même correctif que .bhadm-grid, pour la même raison : un item de grille a `min-width: auto`, donc
   sa piste ne descend jamais sous le min-content de son contenu. Repliée en une colonne sous 900px,
   la piste restait à 380px (le rail latéral et son adresse d'overlay) dans une page de 300 — et le
   `overflow: hidden` de .bhpp rognait la différence sans un mot. */
.bhpp-body > * { min-width: 0; }
.bhpp-main { padding: 28px 28px 36px 40px; display: flex; flex-direction: column; gap: 30px; min-width: 0; }
.bhpp-side { border-left: 1px solid var(--border); padding: 28px 40px 36px 26px; display: flex; flex-direction: column; gap: 24px; }

.bhpp-sec-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.bhpp-h2 { margin: 0; font: 700 23px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bhpp-h2 small { font: 500 10.5px/1 'JetBrains Mono', monospace; letter-spacing: .14em; color: var(--text-muted); }
.bhpp-h2-link { font: 500 11.5px/1 'Archivo', sans-serif; color: var(--accent); text-decoration: none; }

.bhpp-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.bhpp-stat { padding: 15px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; gap: 8px; }
.bhpp-stat-l { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .12em; color: var(--text-muted); }
.bhpp-stat-v { font: 700 25px/1 'JetBrains Mono', monospace; color: var(--text-primary); }
.bhpp-stat-v--blue { color: var(--accent); }
.bhpp-stat-v--gold { color: var(--gold-fg); }

.bhpp-badges { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; }
.bhpp-badge { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 15px 8px; border-radius: var(--radius); background: var(--bg-surface); border: 1px solid var(--border); }
.bhpp-badge--evt { background: linear-gradient(180deg, rgba(243,194,86,.12), var(--bg-surface)); border-color: rgba(243,194,86,.4); }
.bhpp-badge--locked { background: var(--bg-inset); border-style: dashed; border-color: var(--border); }
.bhpp-badge--locked .bhbg-shield { filter: grayscale(1); opacity: .3; }
.bhpp-badge-name { font: 600 10.5px/1.2 'Archivo', sans-serif; color: var(--text-secondary); text-align: center; }
.bhpp-badge--evt .bhpp-badge-name { color: var(--gold-fg); }
.bhpp-badge--locked .bhpp-badge-name { font-family: 'JetBrains Mono', monospace; font-weight: 500; font-size: 9.5px; color: var(--text-faint); }

.bhpp-side-l { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .14em; color: var(--text-muted); }
.bhpp-prog { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.bhpp-prog img { width: 30px; height: 30px; display: block; flex: none; }
.bhpp-prog-track { flex: 1; height: 7px; border-radius: var(--radius); background: var(--bg-inset); overflow: hidden; }
.bhpp-prog-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-hover), var(--accent)); }
.bhpp-prog-note { display: block; margin-top: 10px; font: 400 10.5px/1.5 'Archivo', sans-serif; color: var(--text-muted); }

.bhpp-ov { padding: 18px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.bhpp-ov-l { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .14em; color: var(--accent-light); }
.bhpp-ov-field { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 9px 11px; border-radius: var(--radius); background: var(--bg-inset); border: 1px solid var(--border); }
/* 🔴 `min-width: 0` : sans lui l'ellipsis ne se déclenchait JAMAIS. Un élément flex a
   `min-width: auto`, donc il ne descend pas sous sa taille min-content — et `white-space: nowrap`
   fait de cette taille min-content l'URL ENTIÈRE. `flex: 1` ne pouvait donc pas le comprimer :
   l'adresse d'overlay poussait le rail de la fiche joueur de 52px hors du cadre à 360px, pendant
   que les trois propriétés de troncature écrites juste à côté restaient décoratives. */
.bhpp-ov-url { flex: 1; min-width: 0; font: 400 10px/1 'JetBrains Mono', monospace; color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhpp-ov-copy { font: 600 10px/1 'JetBrains Mono', monospace; color: var(--accent-light); background: none; border: 0; cursor: pointer; padding: 0; }
.bhpp-ov-note { display: block; margin-top: 10px; font: 400 10.5px/1.5 'Archivo', sans-serif; color: var(--text-soft); }

.bhpp-orgs { padding-top: 20px; border-top: 1px solid var(--border); }
.bhpp-orgrow { display: flex; align-items: center; gap: 11px; margin-top: 12px; text-decoration: none; }
.bhpp-orglogo { width: 30px; height: 30px; border-radius: var(--radius); background: var(--bg-chip); display: grid; place-items: center; font: 700 11px/1 'Barlow Condensed', sans-serif; color: var(--text-soft); flex: none; overflow: hidden; }
.bhpp-orglogo img { width: 100%; height: 100%; object-fit: cover; }
.bhpp-orgname { font: 600 12.5px/1 'Archivo', sans-serif; color: var(--text-secondary); }

/* ── Onglets de la fiche joueur ───────────────────────────────────────────────────────────────
   Même grammaire que le bandeau de tournoi (.bht-tabs), mais posés DANS la carte, sous le hero :
   leur retrait horizontal suit donc celui du corps (40px, cf. .bhpp-main).
   🔴 Ce sont des <button> et non des <a> : sans remise à zéro, le navigateur les peint en plaques
   grises avec bordure. Aucun test ne verrait ça — c'est le rendu natif, pas une règle manquante. */
.bhpp-tabs { display: flex; gap: 0; padding: 0 40px; border-bottom: 1px solid var(--border); }
.bhpp-tab { appearance: none; -webkit-appearance: none; background: none; border: 0; border-radius: 0; margin: 0; cursor: pointer; padding: 15px 16px 13px; font: 500 13px/1 var(--font-alt); color: var(--nav-ink); }
.bhpp-tab:hover { color: var(--accent-light); }
.bhpp-tab--active { color: var(--text-primary); font-weight: 600; box-shadow: inset 0 -2px 0 var(--accent-warm); }

/* L'analyse vit désormais DANS la carte, en contenu d'onglet : elle hérite du cadre et de la
   largeur (--page-max) de .bhpp, au lieu de porter les siens en style inline. Son retrait reprend
   celui de .bhpp-main pour que les deux onglets aient la même assise. */
.bhpp-detail { padding: 28px 40px 36px; }

@media (max-width: 900px) {
    .bhpp-body { grid-template-columns: 1fr; }
    .bhpp-side { border-left: 0; border-top: 1px solid var(--border); padding: 26px 28px 32px; }
    .bhpp-main { padding: 26px 28px 30px; }
    /* Les onglets et le contenu d'analyse suivent le même retrait que le corps, sinon la barre
       d'onglets déborderait du cadre sur mobile. Les onglets défilent plutôt que de se replier. */
    .bhpp-tabs { padding: 0 28px; overflow-x: auto; }
    .bhpp-tab { white-space: nowrap; }
    .bhpp-detail { padding: 26px 28px 30px; }
    .bhpp-stats { grid-template-columns: repeat(2, 1fr); }
    .bhpp-badges { grid-template-columns: repeat(4, 1fr); }
    .bhpp-name { font-size: 40px; }

}

/* 🔴 Le hero de la fiche joueur ROGNAIT EN SILENCE sous 900px, et rien ne le disait.
   .bhpp-hero porte `overflow: hidden` ; .bhpp-rankcard est en `flex: none`, donc elle ne rétrécit
   jamais : mesurée à 376px de large, bord droit à x=437 dans une page qui s'arrête à x=342. Le rang
   du joueur — « DIAMANT I · 5 020 pts », la seule chose que le hero ait à dire — était simplement
   coupé. Pas de barre de défilement, pas d'erreur, rien en console : le mode d'échec le plus cher.
   Trois causes cumulées, donc trois retraits : le padding de 40px mangeait un quart de l'écran, le
   `min-width: 260px` de .bhpp-id empêchait la colonne de céder, et la carte de rang refusait de se
   comprimer. Elle passe pleine largeur : sur un téléphone la rangée n'a de toute façon plus rien à
   mettre à côté. */
@media (max-width: 560px) {
    .bhpp-hero-in { padding: 22px 18px 20px; gap: 16px; }
    .bhpp-id { flex-basis: 100%; min-width: 0; }
    /* `flex: 1 1 100%` et non `flex: none` : la carte prend la ligne et accepte de se réduire. */
    .bhpp-rankcard { flex: 1 1 100%; gap: 14px; padding: 14px 16px; min-width: 0; }
    .bhpp-rankcard-txt { min-width: 0; }
    /* Le plafond de lecture de la note n'a plus de sens quand la carte fait toute la largeur. */
    .bhpp-rankcard-note { max-width: none; }
    .bhpp-main, .bhpp-side, .bhpp-detail { padding-left: 18px; padding-right: 18px; }
    .bhpp-tabs { padding: 0 18px; }
    .bhpp-badges { grid-template-columns: repeat(3, 1fr); }
    .bhpp-name { font-size: 32px; }
}

/* ─── Dashboard organisateur « broadcast » (écran 3c) ────────────────────────
   Cockpit sombre inhérent (comme le hero de tournoi / la fiche joueur 3e) : art fixe assumé,
   valable sur les deux thèmes. Namespace .bhod-. Les widgets thémés (« Mes tournois », calendrier)
   restent SOUS la carte, dans le flux de page normal. */
.bhod { max-width: min(var(--page-max), 100%); margin: 0 auto; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: transparent;   /* laisse passer le fond animé de la page */ color: var(--text-secondary); font-family: 'Archivo', system-ui, sans-serif; }
/* Topbar (maquette 3c) : mark + sélecteur d'organisation + CTA, séparée du greeting. */
.bhod-topbar { display: flex; align-items: center; gap: 18px; padding: 16px 36px; border-bottom: 1px solid var(--border); background: var(--bg-surface); flex-wrap: wrap; }
.bhod-brand { display: inline-flex; align-items: center; flex: none; }
/* Le fichier est un CARRÉ dont le dessin n'occupe que 46% de la hauteur et 77% de la largeur : le
   reste est transparent. Rendre l'image à la hauteur de la barre donnerait donc un logo deux fois
   trop petit, et le mot-symbole qu'il porte à l'intérieur redeviendrait un pâté illisible — c'est
   la raison des 64px de la top-nav. On garde donc ces 64px, et on REPREND la marge morte en marges
   négatives : la barre reste à la hauteur du sélecteur d'organisation (38px) au lieu d'enfler. */
.bhod-brand img { height: 64px; width: auto; max-width: none; display: block; margin: -13px -7px; }
.bhod-orgswitch { display: inline-flex; align-items: center; gap: 10px; padding: 6px 12px; border-radius: var(--radius); border: 1px solid var(--border); text-decoration: none; }
.bhod-orgswitch-logo { width: 24px; height: 24px; border-radius: 50%; background: var(--bg-chip); display: grid; place-items: center; font: 700 9px/1 'Barlow Condensed', sans-serif; color: var(--accent-light); flex: none; overflow: hidden; }
.bhod-orgswitch-logo img { width: 100%; height: 100%; object-fit: cover; }
.bhod-orgswitch-name { font: 600 12.5px/1 'Archivo', sans-serif; color: var(--text-secondary); }
.bhod-orgswitch i { color: var(--text-muted); font-size: 15px; }

.bhod-head { padding: 26px 36px 0; display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.bhod-hello-wrap { display: flex; flex-direction: column; gap: 8px; }
.bhod-kicker { font: 500 10px/1 'JetBrains Mono', monospace; letter-spacing: .18em; color: var(--accent); text-transform: uppercase; }
.bhod-hello { margin: 0; font: 700 40px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; color: var(--text-primary); }

.bhod-sum { font: 400 11.5px/1.6 'Archivo', sans-serif; color: var(--text-muted); text-align: right; max-width: 300px; }
.bhod-cta { display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 36px; padding: 0 18px; border-radius: var(--radius); background: linear-gradient(135deg, var(--accent-hover), var(--accent)); font: 600 12.5px/1 'Archivo', sans-serif; color: #fff; text-decoration: none; white-space: nowrap; }

.bhod-body { padding: 26px 36px 34px; display: flex; flex-direction: column; gap: 26px; }
.bhod-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.bhod-kpi { padding: 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; gap: 10px; }
.bhod-kpi--accent { border-color: var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.bhod-kpi--gold { border-color: rgba(243,194,86,.35); background: linear-gradient(160deg, rgba(243,194,86,.09), var(--bg-surface)); }
.bhod-kpi-l { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .14em; color: var(--text-muted); }
.bhod-kpi--accent .bhod-kpi-l { color: var(--accent-light); }
.bhod-kpi--gold .bhod-kpi-l { color: var(--gold-fg); }
.bhod-kpi-v { font: 700 33px/1 'JetBrains Mono', monospace; color: var(--text-primary); }
.bhod-kpi--gold .bhod-kpi-v { color: var(--gold-fg); }
.bhod-kpi-v--blue { color: var(--accent); }
.bhod-kpi-s { font: 400 10.5px/1 'Archivo', sans-serif; color: var(--text-muted); }

.bhod-cols { display: grid; grid-template-columns: 1.3fr 1fr; gap: 20px; }
.bhod-panel { padding: 22px 24px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.bhod-panel-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.bhod-h2 { margin: 0; font: 700 23px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bhod-count { font: 500 10px/1 'JetBrains Mono', monospace; letter-spacing: .08em; color: var(--text-muted); text-transform: uppercase; }

.bhod-todo { display: flex; flex-direction: column; }
.bhod-todo-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line-soft); }
.bhod-todo-row:last-child { border-bottom: 0; }
.bhod-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.bhod-dot--gold { background: var(--gold-fg); }
.bhod-dot--red { background: var(--red-fg); }
.bhod-dot--blue { background: var(--accent); }
.bhod-dot--grey { background: var(--text-soft); }
.bhod-todo-txt { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhod-todo-t { font: 600 12.5px/1.3 'Archivo', sans-serif; color: var(--text-secondary); }
.bhod-todo-s { font: 400 10.5px/1 'Archivo', sans-serif; color: var(--text-muted); }
.bhod-todo-a { font: 600 11.5px/1 'Archivo', sans-serif; color: var(--accent); text-decoration: none; white-space: nowrap; flex: none; }
.bhod-empty { font: 400 12px/1.5 'Archivo', sans-serif; color: var(--text-muted); padding: 8px 0 2px; }

.bhod-side { display: flex; flex-direction: column; gap: 16px; }
.bhod-agenda-row { display: flex; align-items: center; gap: 12px; }
.bhod-agenda-row + .bhod-agenda-row { margin-top: 12px; }
.bhod-agenda-time { font: 600 11px/1 'JetBrains Mono', monospace; color: var(--accent); width: 52px; flex: none; }
.bhod-agenda-time--soon { color: var(--text-soft); }
.bhod-agenda-name { flex: 1; font: 500 12px/1.3 'Archivo', sans-serif; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; }
.bhod-agenda-fill { font: 500 10px/1 'JetBrains Mono', monospace; color: var(--text-muted); flex: none; }

.bhod-bot { padding: 20px 22px; border-radius: var(--radius); border: 1px solid var(--line-strong); background: var(--bg-inset); display: flex; gap: 14px; }
.bhod-bot-ico { width: 32px; height: 32px; border-radius: var(--radius); background: #3b4a8f; display: grid; place-items: center; flex: none; }
.bhod-bot-ico span { width: 13px; height: 13px; border-radius: 50%; background: #c3cbf7; display: block; }
.bhod-bot-txt { display: flex; flex-direction: column; gap: 8px; }
.bhod-bot-t { display: flex; align-items: center; gap: 8px; font: 600 13px/1 'Archivo', sans-serif; color: var(--text-secondary); }
/* Écart d'inscriptions en hausse : la seule variation qui merite d'etre coloree. */
.bhod-kpi-s--up { color: var(--green-fg); }
.bhod-bot-s { font: 400 11px/1.5 'Archivo', sans-serif; color: var(--text-soft); }
.bhod-bot-a { font: 600 11.5px/1 'Archivo', sans-serif; color: var(--accent-light); text-decoration: none; }

/* ─── Bandeau broadcast des écrans opérationnels t3 (3a/3b/3d/3f) ─────────────
   Barre sombre en tête de page (mark + titre + méta + contexte), posée AU-DESSUS du corps thémé
   qui, lui, garde le thème clair/sombre. Art fixe assumé (surface broadcast), namespace .bh3bar-. */
/* Carte bordée : elle suit la colonne de lecture. Sans plafond, elle traversait toute la fenêtre
   dans le cockpit de tirage (.pp-screen n'a pas le plafond du shell). */
.bh3bar { display: flex; align-items: center; gap: 18px; padding: 15px 24px; max-width: min(var(--page-max), 100%); margin-inline: auto; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); color: var(--text-secondary); margin-bottom: 18px; flex-wrap: wrap; font-family: 'Archivo', system-ui, sans-serif; }
/* 📌 Le bandeau du cockpit de tirage RESTE à la colonne de lecture, et se dimensionne sur son
   contenu. C'est un choix tenu, pas un oubli : il a été élargi au plein cadre (US #761) puis
   ramené ici.
   Ce qu'on a mesuré en l'élargissant : à 1920, sa boîte passe à 1840 × 104, soit 18:1, quand une
   bannière en fait 4:1 — le calque en `cover` jette alors 78 % de l'artwork, équerres et bords
   compris. Réduit à son contenu il ne fait que 562 px pour un plateau de 1920, donc il flotte,
   et sous 1300 px il passe sur deux lignes ; c'est la contrepartie assumée, l'image d'abord.
   ⚠️ Ne pas lui redonner `max-width: none` sans traiter le FORMAT de l'image : l'élargir sans lui
   donner une fenêtre à son propre rapport, c'est reperdre l'artwork exactement de la même façon.

   Il est agrandi d'environ un cinquième — HAUTEUR ET LARGEUR ENSEMBLE, pour garder le rapport ~4,8:1
   de sa boîte. Ne toucher qu'à l'une des deux rapprocherait le format de la boîte de celui d'une
   barre, et le calque en `cover` recommencerait à rogner l'artwork. Un plancher, pas une taille
   fixe : sur une fenêtre plus étroite que le plancher, `min()` rend la main au contenu. */
.bh3bar--pp.bh3bar--photo { min-width: min(675px, 100%); min-height: 142px; }

.bh3bar-mark { display: inline-flex; align-items: center; gap: 7px; font: 800 15px/1 'Barlow Condensed', sans-serif; letter-spacing: .02em; color: var(--text-primary); text-transform: uppercase; flex: none; }
.bh3bar-mark i { color: var(--accent); font-size: 19px; }
/* Le logo de marque dans le bandeau de conduite (écran 3b). Le fichier est un CARRÉ dont le dessin
   n'occupe que 46 % de la hauteur et 77 % de la largeur : le rendre à la hauteur de la barre
   donnerait un logo deux fois trop petit, et le mot-symbole qu'il porte à l'intérieur redeviendrait
   un pâté illisible — d'où les 64 px, ceux de la top-nav et du tableau de bord. La marge morte est
   REPRISE en marges négatives, sinon le bandeau enflerait de près de 50 px.
   ⚠️ Sélecteur porté par le MODIFICATEUR : `.bh3bar-mark` sert aussi au cockpit de tirage, où il
   encadre le logo de l'organisation (`img.bh3bar-ava`, 34 px). */
.bh3bar-mark--logo img { height: 64px; width: auto; max-width: none; display: block; margin: -13px -7px; }

.bh3bar-div { width: 1px; height: 30px; background: var(--border); flex: none; }
.bh3bar-titles { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bh3bar-title { font: 700 21px/1.05 'Barlow Condensed', sans-serif; text-transform: uppercase; color: var(--text-primary); }
.bh3bar-meta { font: 500 10px/1.3 'JetBrains Mono', monospace; letter-spacing: .13em; color: var(--text-muted); text-transform: uppercase; }
.bh3bar-sp { flex: 1 1 20px; }
.bh3bar-right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.bh3bar-rl { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .14em; color: var(--text-muted); }
.bh3bar-rv { font: 700 22px/1 'JetBrains Mono', monospace; color: var(--text-primary); }
.bh3bar-chip { display: inline-flex; align-items: center; gap: 7px; height: 28px; padding: 0 12px; border-radius: var(--radius); border: 1px solid var(--accent-subtle); background: var(--accent-subtle); font: 600 11px/1 'JetBrains Mono', monospace; letter-spacing: .06em; color: var(--accent); text-transform: uppercase; flex: none; }

.bh3bar-chip--live { border-color: rgba(55,217,154,.4); background: rgba(55,217,154,.12); color: var(--green-fg); }

/* ─── Entête aux couleurs de l'organisation (cockpit de tirage, US #755) ──────
   L'avatar de l'organisation prend la place du logo et du mot BracketHub : cet écran se projette
   en salle et se diffuse, c'est la marque de qui reçoit qui doit s'y lire. */
.bh3bar-ava { width: 34px; height: 34px; border-radius: var(--radius); object-fit: cover; flex: none; display: block; }
.bh3bar-ava--txt { display: grid; place-items: center; background: var(--accent-subtle); color: var(--accent); font: 700 13px/1 'Barlow Condensed', sans-serif; letter-spacing: .04em; }

/* 🔴 L'entête descend, l'écran ne bouge PAS : ce qui est pris en haut est rendu en bas
   (12 + 6 = les 18px de margin-bottom d'origine). Le cockpit est un .pp-screen à hauteur fixe en
   overflow hidden — une marge ajoutée sans compensation pousserait tout vers le bas et ferait
   rogner le pied de l'écran. Verrouillé par PrivatePartyDrawHeaderTests. */
.bh3bar--pp { margin-top: 12px; margin-bottom: 6px; }

/* Bannière de l'organisation en fond. Le calque porte l'assombrissement — appliquer le filtre à la
   barre l'appliquerait aussi au texte. Même traitement que le hero de tournoi (.tour-hero-bg). */
.bh3bar--photo { position: relative; overflow: hidden; }
.bh3bar-bg { position: absolute; inset: 0; background-size: cover; background-position: center; filter: brightness(.32) saturate(.7); }
/* Un absolu se peint AU-DESSUS des enfants non positionnés, quel que soit l'ordre du DOM : sans
   cette ligne la bannière recouvrirait le titre. */
.bh3bar--photo > :not(.bh3bar-bg) { position: relative; }

/* Texte posé sur une PHOTO : il n'a plus de thème, il est clair dans les deux (même exception
   assumée que .tour-hero-* et le hero d'organisation). Les jetons sont reposés ici plutôt que
   chaque classe réécrite — tout ce qui vit dans la barre suit. */
/* Même filet de sécurité que .bht-hero--photo : sans lui, une bannière introuvable laisserait le
   texte clair sur var(--bg-surface), qui est CLAIR en thème clair. */
.bh3bar--photo {
    background: #141e33;
    --text-primary: #fff;
    --text-secondary: rgba(255,255,255,.86);
    --text-muted: rgba(255,255,255,.72);
    --border: rgba(255,255,255,.18);
}
.bh3bar--photo .bh3bar-ava--txt { background: rgba(255,255,255,.18); color: #fff; }

@media (max-width: 720px) {
    .bh3bar-mark, .bh3bar-div { display: none; }
    .bh3bar-title { font-size: 18px; }
}

@media (max-width: 900px) {
    .bhod-kpis { grid-template-columns: repeat(2, 1fr); }
    .bhod-cols { grid-template-columns: 1fr; }
    .bhod-head { padding: 24px 22px 0; }
    .bhod-body { padding: 22px 22px 28px; }
    .bhod-hello { font-size: 32px; }
    .bhod-sum { display: none; }
}

/* ─── Marqueur .bhconsole (refonte t3/t4) ────────────────────────────────────
   Historiquement, ce conteneur FORÇAIT une palette broadcast sombre en dur (pour repeindre les
   pages opérationnelles sans réécrire le markup). Depuis que le **thème sombre lui-même** porte la
   palette maquette (bloc :root plus haut), ce forçage n'a plus lieu d'être — il cassait le thème
   clair. `.bhconsole` est donc redevenu THEME-AWARE : simple surface tokenisée qui suit le thème
   (navy en sombre, clair en clair). Conservé pour ne pas toucher au markup des pages déjà taguées. */
.bhconsole {
    background: transparent;   /* laisse passer le fond animé de la page */
    color: var(--text-primary);
}

/* ─── Barre de navigation commune EN HAUT (top-nav esport, refonte Claude Design) ─────────────
   Remplace la sidebar verticale. Entièrement tokenisée → suit le thème (navy en sombre = maquette,
   clair en thème clair). */
.appnav { display: flex; align-items: center; gap: 18px; height: var(--appnav-h); padding: 0 24px; background: var(--bg-surface); border-bottom: 1px solid var(--border); flex: none; position: relative; z-index: 150; }
.appnav-logo { display: inline-flex; align-items: center; flex: none; }
/* Le logo porte son mot-symbole À L'INTÉRIEUR de l'image : trop réduit, « BracketHub » n'est plus
   qu'un pâté illisible. 64px, avec 8px de respiration de part et d'autre : c'est ce couple qui fixe
   --appnav-h à 80px, et non l'inverse. Un logo plus grand que sa barre la déborderait.
   ⚠️ La valeur doit rester à UN SEUL endroit : elle était déclarée deux fois (30px ici, 34px dans
   le bloc de la console d'administration, qui l'emportait), donc la corriger ici ne changeait rien
   à l'écran. Le max-width est explicite : sans lui, l'image hérite du plafond de la colonne. */
.appnav-logo img { height: 64px; width: auto; max-width: none; display: block; }

/* min-width:0 + défilement : sans cela, la rangée de liens ne descend jamais sous sa largeur
   min-content (liens en white-space:nowrap) et pousse la recherche, la cloche et la carte
   utilisateur HORS de l'écran entre 861px et ~1450px — mesuré sur un compte administrateur, dont
   le menu Administration allonge la rangée. La recherche, elle, cède sa place en premier
   (flex-basis 220px, plancher 110px) : c'est le seul élément dont la largeur est du confort.
   ⚠️ Le défilement vit sur .appnav-scroll, PAS sur .appnav-links : un conteneur qui défile rogne
   ses descendants positionnés, et le panneau du menu Administration — absolu, posé SOUS la barre —
   s'y évaporait entièrement. Le bouton s'ouvrait, on ne voyait rien et rien n'était consigné.
   Tout ce qui ouvre un panneau doit donc rester EN DEHORS de .appnav-scroll. */
.appnav-links { display: flex; align-items: center; gap: 3px; min-width: 0; }
.appnav-scroll { display: flex; align-items: center; gap: 3px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.appnav-scroll::-webkit-scrollbar { height: 0; }
.appnav .search-wrapper { flex: 0 1 220px; min-width: 110px; }

/* ⚠️ C'est CETTE règle qui gouverne, pas le `width: 220px` de .search-wrapper : dans la barre, le
   wrapper est un élément flex, et `flex-basis` l'emporte sur `width`. Le même bloc est d'ailleurs
   déclaré DEUX fois plus haut dans la feuille — corriger la première déclaration n'aurait rien
   changé à l'écran, le piège déjà payé sur la taille du logo.

   Compacte au repos, déployée dès qu'on entre dedans : la barre porte sept entrées, une carte
   utilisateur et une cloche ; 220 px immobilisés pour un champ utilisé par intermittence, c'était
   la plus grosse dépense de largeur. `:focus-within` et non `:focus` — le panneau de résultats vit
   dans le wrapper, et se replier au premier clic sur un résultat le ferait disparaître avant
   l'ouverture du lien. */
.appnav .search-wrapper { flex: 0 0 40px; min-width: 40px; transition: flex-basis .16s ease; }
.appnav .search-wrapper:focus-within,
.appnav .search-wrapper:hover { flex-basis: 220px; }
.appnav .search-wrapper:not(:focus-within):not(:hover) .topbar-search input[type="search"] { width: 0; padding: 0; opacity: 0; }
.appnav .search-wrapper .topbar-search input[type="search"] { transition: width .16s ease, opacity .12s ease; }
/* Sélecteur de langue et cloche : rien à rogner, ils sont déjà à leur taille minimale (« FR | EN »
   amputé de son FR ne veut plus rien dire). Seuls les liens et la recherche cèdent. */
.appnav .lang-switcher, .appnav .notif-bell-wrapper { flex: none; }
/* ── Encre des liens de navigation ───────────────────────────────────────────────────────
   Repos = --nav-ink (blanc pur). Neuf familles la partagent, et doivent rester d'accord :
   .bh-topnav a (barre anonyme) · .appnav-link (barre en session) · .wiki-nav-link ·
   .bhcon-link (console) · .bht-tab · .bhpp-tab · .bhcal-view · .bhrk-scope-btn · .bhmod-filter.
   🔴 Conséquence à connaître avant d'y toucher : le repos occupe désormais la place que le
   SURVOL tenait (il visait le texte principal). Là où le survol ne changeait QUE la couleur, il
   serait devenu inerte — il vise donc l'accent clair. Là où il pose aussi un fond (ici et sur
   la nav du wiki), la couleur a été retirée : elle n'assombrissait plus que d'un cheveu.
   ⚠️ Les états ACTIFS des onglets (.bht-tab--active, .bhpp-tab--active, .bhcon-link.active) se
   distinguaient surtout par cette même couleur. Il leur reste la graisse 600 et leur liseré
   ambre / barre incrustée — ne pas retirer ces deux-là, ils portent seuls la sélection. */
.appnav-link { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 13px; border-radius: var(--radius); font: 600 12.5px/1 'Archivo', sans-serif; color: var(--nav-ink); text-decoration: none; background: none; border: 0; cursor: pointer; white-space: nowrap; }
.appnav-link:hover { background: var(--bg-hover); }
.appnav-link.active { color: var(--accent); background: var(--accent-subtle); }


.appnav-spacer { flex: 1; }
.appnav-burger { display: none; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: var(--radius); border: 1px solid var(--border); background: none; color: var(--text-body); cursor: pointer; font-size: 20px; flex: none; }

/* User-card dans la top-nav : override du style « pied de sidebar » (bordure haute, popover
   vers le haut) → carte compacte, popover qui descend et s'aligne à droite. */
.appnav-user { padding: 0; border-top: 0; flex: none; }
.appnav-user .user-card { padding: 5px 8px 5px 5px; border: 1px solid var(--border); border-radius: var(--radius); gap: 8px; }
.appnav-user .user-card:hover { background: var(--bg-hover); }
.appnav-user .user-card-avatar { width: 30px; height: 30px; }
.appnav-user .user-card-info { min-width: 0; max-width: 130px; }
.appnav-user .user-card-name { color: var(--text-primary); }
.appnav-user .user-card-more { opacity: 1; color: var(--text-muted); font-size: 15px; }
.appnav-user .user-popover { top: calc(100% + 8px); bottom: auto; left: auto; right: 0; min-width: 210px; background: var(--bg-elevated); border: 1px solid var(--border); box-shadow: 0 14px 34px var(--shadow-strong); }

@media (max-width: 980px) {
    .appnav-user .user-card-info { display: none; }
}
@media (max-width: 860px) {
    .appnav { gap: 12px; padding: 0 14px; }
    .appnav-burger { display: inline-flex; }
    .appnav-links { position: absolute; top: var(--appnav-h); left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 2px; padding: 10px 12px; background: var(--bg-surface); border-bottom: 1px solid var(--border); display: none; box-shadow: 0 18px 40px var(--shadow-strong); }
    .appnav-links.appnav-links--open { display: flex; }
    /* En panneau mobile les liens s'empilent : plus rien à faire défiler horizontalement. */
    .appnav-scroll { flex-direction: column; align-items: stretch; gap: 2px; overflow: visible; }
    .appnav-link { height: 40px; }
}

/* ─── Console admin 4a : journal d'audit + santé + file d'attente (refonte, theme-aware) ───── */
.bhadm-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 18px; margin-top: 20px; }
/* Un item de grille a min-width:auto, donc sa piste ne descend jamais sous la taille min-content de
   son contenu : le plancher du tableau large (voir .bhadm-audit) remontait jusqu'ici et faisait
   défiler TOUTE la console au lieu du seul tableau. Le min-width:0 rend la piste compressible et
   renvoie le débordement là où il doit être, dans .table-scroll. */
.bhadm-grid > * { min-width: 0; }
.bhadm-side { display: flex; flex-direction: column; gap: 18px; }
.bhadm-tag { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .12em; color: var(--text-muted); text-transform: uppercase; }
.bhadm-feed-time { font: 500 11px/1 'JetBrains Mono', monospace; color: var(--accent); white-space: nowrap; }
.bhadm-feed-ev { font: 600 12px/1 'JetBrains Mono', monospace; color: var(--text-primary); }
.bhadm-feed-actor { font: 400 12px/1.3 'Archivo', sans-serif; color: var(--text-soft); }
.bhadm-q { display: flex; flex-direction: column; gap: 8px; }
.bhadm-q-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius); border: 1px solid var(--border); background: none; text-decoration: none; width: 100%; cursor: pointer; }
.bhadm-q-row:hover { background: var(--bg-hover); }
.bhadm-q-count { min-width: 26px; height: 26px; padding: 0 8px; border-radius: var(--radius); background: var(--accent-subtle); color: var(--accent); display: grid; place-items: center; font: 700 13px/1 'JetBrains Mono', monospace; flex: none; }
.bhadm-q-label { font: 500 12.5px/1.3 'Archivo', sans-serif; color: var(--text-secondary); }
.bhadm-q-empty { font: 400 12px/1.4 'Archivo', sans-serif; color: var(--text-muted); padding: 6px 0; }
@media (max-width: 900px) { .bhadm-grid { grid-template-columns: 1fr; } }
/* ─── Panneau « Santé » de la console (US #852) ────────────────────────────────────────────────
   Rétabli après le Bogue #837, où les cinq lignes étaient des littéraux. Chaque pastille lit
   désormais un niveau mesuré par GET /admin/dashboard/health, et l'état « indéterminé » a sa
   couleur propre : il ne doit ressembler ni au vert ni au rouge. */
.bhadm-health { display: flex; flex-direction: column; gap: 2px; }
.bhadm-health-row { display: grid; grid-template-columns: minmax(64px, auto) 1fr 10px; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.bhadm-health-row:last-child { border-bottom: none; }
.bhadm-health-label { font: 500 12.5px/1.3 'Archivo', sans-serif; color: var(--text-secondary); }
/* La donnée passe avant la décoration : c'est elle qui se réduit en dernier, et elle peut être
   longue (« 3 en attente, la plus ancienne il y a 12 min »). */
.bhadm-health-detail { font: 400 12px/1.35 'JetBrains Mono', monospace; color: var(--text-muted); min-width: 0; overflow-wrap: anywhere; }
.bhadm-health-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--text-muted); }
.bhadm-health-dot--ok { background: var(--green-fg); }
.bhadm-health-dot--warn { background: var(--gold-fg); }
.bhadm-health-dot--down { background: var(--red-fg); }
.bhadm-health-dot--unknown { background: none; border: 1px solid var(--text-muted); }
.bhadm-health-refresh { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 2px 4px; border-radius: var(--radius); line-height: 1; }
.bhadm-health-refresh:hover:not(:disabled) { background: var(--bg-hover); color: var(--text-secondary); }
.bhadm-health-refresh:disabled { cursor: default; opacity: .6; }


/* ─── Modération 4b : filtres de portée + table de bannissements (theme-aware) ─────────────── */
.bhmod-filters { display: flex; align-items: center; gap: 6px; margin: 2px 0 16px; flex-wrap: wrap; }
.bhmod-filter { height: 30px; padding: 0 12px; border-radius: var(--radius); border: 1px solid var(--border); background: none; color: var(--nav-ink); font: 600 11px/1 'JetBrains Mono', monospace; letter-spacing: .08em; text-transform: uppercase; cursor: pointer; }
.bhmod-filter--active { background: var(--accent-subtle); border-color: var(--border-input); color: var(--accent); }
.bhmod-joueur { display: flex; align-items: center; gap: 10px; }
.bhmod-joueur .org-member-avatar { width: 28px; height: 28px; font-size: 11px; }
.bhmod-scope { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: .08em; text-transform: uppercase; }
.bhmod-scope--global { background: rgba(255,66,92,.12); color: var(--red-fg); }
.bhmod-scope--org { background: var(--accent-subtle); color: var(--accent); }
.bhmod-appeal { color: var(--gold-fg); font-size: 15px; vertical-align: middle; margin-left: 6px; }

/* Console admin : contenu borné + journal compact. */
/* Le contenu était exempté de tout plafond, au motif que « la sidebar fournit déjà le cadrage » —
   or la console n'a plus de sidebar depuis la refonte en deux rangées, et sur un écran large les
   tableaux s'étiraient sur toute la fenêtre : la date, le remplissage et le statut finissaient à
   des centaines de pixels de leur libellé. Il a d'abord suivi --page-max, puis sa propre colonne,
   plus étroite : du pilotage dense, pas de la lecture (cf. --console-max).
   Les BARRES (.bhcon-head, .bhcon-subnav) restent pleine largeur, comme la top-nav de l'app.
   ⚠️ TOUT écran de la console doit porter cette classe en plus de .bhconsole — c'est elle seule qui
   borne. Trois écrans l'ont manquée et s'étiraient encore ; ConsoleScreenWidthTests le verrouille. */
.bhadm-page { max-width: var(--console-max); margin-inline: auto; }
/* Les deux tableaux larges de la console vivent dans un .table-scroll, mais .data-table fait
   width:100% SANS plancher : le conteneur n'avait donc jamais rien à faire défiler et le tableau
   s'écrasait sur mobile (six colonnes réduites à quelques caractères). Le min-width est ce qui
   rend le défilement horizontal effectif.
   ⚠️ Un plancher ne doit jamais dépasser la place que son tableau reçoit réellement, sinon le
   tableau défile dès le bureau. Et les deux tableaux n'en reçoivent PAS autant :
   — .bhadm-org-table (annuaire des équipes) est un frère direct de .bhadm-page : il dispose de
     toute la colonne, soit --console-max ;
   — .bhadm-audit vit dans la piste GAUCHE de .bhadm-grid, qui n'en vaut que 1,4/2,4 moins la
     gouttière — ≈596px pour une colonne de 1040px, contre ≈678px quand la console suivait encore
     --page-max. C'est ce qui a fait descendre son plancher de 620 à 560 en même temps que la
     colonne. Un commentaire antérieur attribuait cette contrainte au tableau des équipes, qui n'a
     jamais été dans la grille. ShellLayoutCssTests refait les deux calculs. */
.bhadm-org-table { min-width: 640px; }
.bhadm-audit { min-width: 560px; }
.bhadm-audit th { padding-top: 9px; padding-bottom: 9px; }
.bhadm-audit td { padding-top: 8px; padding-bottom: 8px; }
.bhadm-maint-hint { font: 400 11.5px/1.5 'Archivo', sans-serif; color: var(--text-muted); margin: 0 0 14px; }

/* Titre de section des écrans d'administration (sous le top-nav global). */
.bhadm-head { margin-bottom: 18px; }
.bhadm-h1 { margin: 0; font: 700 30px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; letter-spacing: .02em; color: var(--text-primary); }
.bhadm-sub { margin: 5px 0 0; font: 400 12px/1.4 'Archivo', sans-serif; color: var(--text-muted); }

/* En-tête de section avec action à droite (maquette 4b « Modération »). */
.bhadm-head-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }

/* ─── SuperAdmin 4c : réglages plateforme, clients d'API, accès Discord ────────────────────────
   Traduction de la maquette 4c : en-tête à kicker doré + note de portée à droite, grille de cartes,
   champs à valeur monospace + unité, chips de scope, cartes « client » et carte « danger » pour les
   opérations irréversibles. Entièrement tokenisé → suit les deux thèmes (rien en dur, cf. PR #438). */
.bhset-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; }
.bhset-kicker { display: block; font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .18em; text-transform: uppercase; color: var(--gold-fg); margin-bottom: 7px; }
.bhset-note { font: 400 11px/1.6 'Archivo', sans-serif; color: var(--text-muted); text-align: right; max-width: 340px; }
.bhset-count { font: 500 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }

.bhset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.bhset-grid--wide { grid-template-columns: 1.25fr 1fr; }
.bhset-card { padding: 22px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-panel); }

.bhset-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
.bhset-h2 { margin: 0; font: 700 21px/1.1 'Barlow Condensed', sans-serif; text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bhset-foot { display: block; margin-top: 14px; font: 400 10.5px/1.5 'Archivo', sans-serif; color: var(--text-faint); }
.bhset-foot--warn { color: var(--red-soft-fg); }

/* Ligne de réglage : libellé à gauche, valeur monospace + unité à droite (gabarit maquette). */
.bhset-rows { display: flex; flex-direction: column; gap: 12px; }
.bhset-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.bhset-label { font: 400 12px/1.35 'Archivo', sans-serif; color: var(--text-body); }
.bhset-field { display: flex; align-items: center; gap: 6px; width: 132px; height: 36px; padding: 0 12px; border-radius: var(--radius); border: 1px solid var(--line-strong); background: var(--bg-input); flex: none; }
.bhset-field:focus-within { border-color: var(--border-input); }
/* 🔴 Plancher sur le NOMBRE, pas sur l'unité : les deux se partagent une boîte de largeur fixe, et
   sans plancher c'est l'unité qui gagne. Mesuré sur « max. simultanés » (91px sur 132) : le champ
   tombait à 9px, soit UN chiffre — régler le butoir à 10 devenait illisible. La donnée passe avant
   la décoration, donc c'est l'unité qui s'abrège. */
.bhset-field input { flex: 1 1 0; min-width: 44px; border: 0; background: none; outline: none; padding: 0; font: 700 13px/1 'JetBrains Mono', monospace; color: var(--text-primary); -moz-appearance: textfield; }
.bhset-field input::-webkit-outer-spin-button,
.bhset-field input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.bhset-unit { font: 500 10px/1 'JetBrains Mono', monospace; letter-spacing: .06em; color: var(--text-muted); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhset-flabel { display: flex; flex-direction: column; gap: 6px; font: 500 11.5px/1.3 'Archivo', sans-serif; color: var(--text-body); }
.bhset-flabel .input-sm { width: 100%; }

/* Action textuelle d'en-tête de carte (« Enregistrer », « Révoquer »). */
.bhset-act { background: none; border: 0; padding: 0; cursor: pointer; font: 600 11px/1 'Archivo', sans-serif; color: var(--accent); }
.bhset-act:hover { color: var(--accent-light); }
.bhset-act:disabled { color: var(--text-dim); cursor: default; }
.bhset-act--danger { color: var(--red-fg); font: 600 10.5px/1 'JetBrains Mono', monospace; letter-spacing: .06em; text-transform: uppercase; }
.bhset-act--danger:hover { color: var(--red-soft-fg); }

/* Clients d'API : carte mise en avant quand le client est actif, atténuée quand il est révoqué. */
.bhset-client { padding: 16px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-inset)); }
.bhset-client + .bhset-client { margin-top: 12px; }
.bhset-client--off { border-color: var(--border); background: var(--bg-inset); opacity: .7; }
.bhset-client-head { display: flex; align-items: center; gap: 10px; }
.bhset-client-ico { width: 28px; height: 28px; border-radius: var(--radius); background: var(--bg-chip); display: grid; place-items: center; flex: none; color: var(--accent-light); font-size: 15px; }
.bhset-client--off .bhset-client-ico { background: var(--surface-2); color: var(--text-dim); }
.bhset-client-id { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.bhset-client-name { font: 600 12.5px/1 'Archivo', sans-serif; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhset-client--off .bhset-client-name { color: var(--text-body); }
.bhset-client-sub { font: 400 9.5px/1.3 'JetBrains Mono', monospace; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhset-pill { display: inline-grid; place-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); font: 600 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .06em; flex: none; white-space: nowrap; }
.bhset-pill--on { background: rgba(55,217,154,.12); color: var(--green-fg); }
.bhset-pill--off { border: 1px solid var(--border); color: var(--text-muted); }
.bhset-scopes { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 14px; }
.bhset-scope { height: 20px; padding: 0 8px; display: grid; place-items: center; border-radius: var(--radius); background: var(--bg-hover); font: 500 9.5px/1 'JetBrains Mono', monospace; color: var(--text-body); }
.bhset-client-foot { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.bhset-client-meta { flex: 1; font: 400 10px/1.4 'JetBrains Mono', monospace; color: var(--text-faint); }
.bhset-secret { display: block; margin-top: 8px; padding: 10px 12px; border-radius: var(--radius); background: var(--bg-inset); font: 500 12px/1.5 'JetBrains Mono', monospace; color: var(--text-primary); user-select: all; word-break: break-all; }

/* Accès Discord : tableau en grille (identité, serveur, échéance, action). */
.bhdisc-head, .bhdisc-row { display: grid; grid-template-columns: 1fr 140px 120px 214px; gap: 12px; align-items: center; }
.bhdisc-head { padding: 0 4px 10px; border-bottom: 1px solid var(--border); }
.bhdisc-th { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhdisc-th--end { text-align: right; }
.bhdisc-row { padding: 12px 4px; border-bottom: 1px solid var(--line-soft); }
.bhdisc-row:last-of-type { border-bottom: 0; }
.bhdisc-org { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bhdisc-av { width: 24px; height: 24px; border-radius: 50%; background: var(--bg-chip); display: grid; place-items: center; font: 700 9px/1 'Barlow Condensed', sans-serif; color: var(--accent-light); flex: none; }
.bhdisc-row--off .bhdisc-av { background: var(--surface-2); color: var(--text-soft); }
.bhdisc-name { font: 500 12px/1.3 'Archivo', sans-serif; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhdisc-row--off .bhdisc-name { color: var(--text-body); }
.bhdisc-val { font: 400 11px/1.3 'JetBrains Mono', monospace; color: var(--text-body); }
.bhdisc-val--soon { color: var(--gold-fg); }
.bhdisc-val--none { color: var(--text-faint); }
.bhdisc-act { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.bhdisc-act .input-sm { width: 118px; }

@media (max-width: 1000px) {
    .bhset-grid, .bhset-grid--wide { grid-template-columns: 1fr; }
    .bhset-note { text-align: left; max-width: none; }
    .bhdisc-head { display: none; }
    .bhdisc-row { grid-template-columns: 1fr; gap: 8px; }
    .bhdisc-act { justify-content: flex-start; }
}

/* ─── Matrice organisation × capacité (console SuperAdmin) ───────────────────────────────────────
   Remplace les deux tableaux jumeaux Discord / résultats automatiques. Le nombre de colonnes vient
   de l'Api : la piste est donc posée en style inline par le composant, pas écrite en dur ici — une
   capacité ajoutée côté serveur n'impose aucune retouche de CSS. Le repli à deux colonnes sert au
   rendu avant que le style inline s'applique.
   ⚠️ minmax(0, …) et min-width:0 sur les cellules : sans ça le contenu d'une piste impose son
   plancher, remonte à travers la grille et fait défiler l'écran entier.

   🔴 La colonne d'IDENTITÉ, elle, a un plancher EN DUR — elle ne participe pas à ce partage. Tant
   qu'elle valait « 1fr », elle était la seule piste souple : chaque capacité ajoutée prenait sa
   place, et la 4ᵉ (Diffusion) l'a réduite à ZÉRO. Mesuré à 1440 px avant correction, la piste valait
   « 0px 234.5px 234.5px 234.5px 234.5px » — sept lignes sans un nom d'organisation, plus moyen de
   savoir à qui on accordait un droit. Le défaut n'était pas la largeur d'une piste mais le fait que
   ce soit l'identité qui cède quand la place manque : c'est désormais la MATRICE qui défile
   (.bhcap-scroll), la colonne du nom restant collée à gauche. */
.bhcap-scroll { overflow-x: auto; padding-bottom: 2px; }
.bhcap-scroll::-webkit-scrollbar { height: 7px; }
.bhcap-scroll::-webkit-scrollbar-thumb { background: var(--accent-subtle); border-radius: var(--radius); }
.bhcap-head, .bhcap-row { display: grid; grid-template-columns: var(--bhcap-tracks, minmax(180px, 220px) minmax(200px, 1fr) minmax(200px, 1fr)); gap: 12px; align-items: center; }
.bhcap-head { padding: 0 4px 10px; border-bottom: 1px solid var(--border); }
.bhcap-row { padding: 12px 4px; border-bottom: 1px solid var(--line-soft); }
.bhcap-row:last-of-type { border-bottom: 0; }
.bhcap-cell { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
/* Collée à gauche : quand la matrice défile, savoir QUELLE organisation on regarde est ce dont on ne
   peut pas se passer. Le fond opaque est celui de la carte, sinon les cellules passeraient au travers. */
.bhcap-org { position: sticky; left: 0; z-index: 1; background: var(--bg-panel); }
.bhcap-head .bhcap-org { padding-bottom: 10px; }
.bhcap-exp { font: 400 10px/1.3 'JetBrains Mono', monospace; color: var(--text-body); }
.bhcap-exp--soon { color: var(--gold-fg); }
.bhcap-exp--none { color: var(--text-faint); }
.bhcap-cell .input-sm { width: 108px; }

/* 🔴 Le composant pose --bhcap-tracks, JAMAIS grid-template-columns directement : un style inline
   sur la propriété écraserait cette media query, la colonne du nom s'écraserait à 0 px sur mobile
   et l'organisation deviendrait invisible. En passant par la variable, la règle ci-dessous garde la
   main. Vécu : mesuré à 375 px avant correction, la piste valait « 0px 152.5px 152.5px ». */
@media (max-width: 1000px) {
    .bhcap-head { display: none; }
    .bhcap-row { grid-template-columns: 1fr; gap: 8px; }
    /* Une seule colonne : plus rien à faire défiler, et une colonne collée à gauche sur toute la
       largeur poserait un fond opaque par-dessus le reste de la ligne. */
    .bhcap-scroll { overflow-x: visible; }
    .bhcap-org { position: static; background: none; }
}

/* ─── Console de facturation (/admin/billing) ──────────────────────────────────────────────────
   Cartes EMPILÉES, pas la grille à deux colonnes de .bhset-grid : chacune porte un tableau, et une
   colonne de demi-largeur y replierait montants et droits inclus sur trois lignes. */
.bhbil-stack { display: flex; flex-direction: column; gap: 18px; }
.bhbil-empty { margin: 0; font: 400 12px/1.5 'Archivo', sans-serif; color: var(--text-muted); }
.bhbil-mono { font: 400 11px/1.3 'JetBrains Mono', monospace; color: var(--text-body); min-width: 0; }
.bhbil-dim { font: 400 10.5px/1.3 'JetBrains Mono', monospace; color: var(--text-muted); }

/* La fenêtre de lecture (jours) et le sélecteur d'organisation prennent, à droite du titre, la
   place qu'occupe le bouton d'enregistrement sur les écrans de réglage. */
.bhbil-head-field { display: flex; align-items: center; gap: 8px; }
.bhbil-head-field label { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhbil-head-field .input-sm { width: 84px; }
.bhbil-head-field select.input-sm { width: 220px; }

/* Tableaux : grammaire de la console (.bhcons-table / .bhcons-thead / .bhcons-row), avec une piste
   propre à chaque table. ⚠️ minmax(0, …) partout — sinon un nom de quota ou un montant long impose
   son plancher, la piste déborde et c'est l'écran entier qui défile. */
.bhbil-exp-head, .bhbil-exp-row,
.bhbil-cens-head, .bhbil-cens-row,
.bhbil-pass-head, .bhbil-pass-row,
.bhbil-quota-head, .bhbil-quota-row,
.bhbil-plan-head, .bhbil-plan-row { display: grid; align-items: center; gap: 12px; padding: 11px 14px; }
.bhbil-exp-head, .bhbil-exp-row { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .6fr); }
.bhbil-cens-head, .bhbil-cens-row { grid-template-columns: minmax(0, 1.6fr) minmax(0, .8fr) minmax(0, .8fr) minmax(0, 1.1fr) minmax(0, .8fr) minmax(0, 1.8fr); }
.bhbil-cens-row .bhcons-tag { margin-right: 4px; }

/* Le nom d'organisation du recensement OUVRE cette organisation dans le bloc du dessous : c'est une
   action, donc un <button>, pas un lien — il n'y a pas d'URL derrière. Rendu comme du texte pour ne
   pas transformer la colonne en rangée de boutons. */
.bhbil-link { padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
.bhbil-link:hover { color: var(--accent); }
.bhbil-pass-head, .bhbil-pass-row { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); }
.bhbil-quota-head, .bhbil-quota-row { grid-template-columns: minmax(0, 2fr) minmax(0, 2fr) minmax(0, .6fr) minmax(0, 1fr); }
.bhbil-found-head, .bhbil-found-row { display: grid; align-items: center; gap: 12px; padding: 11px 14px; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, .9fr); }
/* La ligne d'octroi porte une pastille et un bouton : elle s'aligne sur la ligne de base plutôt que
   de laisser la pastille flotter au-dessus du texte qu'elle qualifie. */
.bhbil-acts--founder { align-items: center; gap: 12px; }
.bhbil-plan-head, .bhbil-plan-row { grid-template-columns: minmax(0, 1.2fr) minmax(0, .5fr) minmax(0, .8fr) minmax(0, 1fr) minmax(0, 1.7fr) minmax(0, .8fr) minmax(0, 1.5fr); }
.bhbil-plan-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.bhbil-plan-row .bhcons-tag { margin-right: 4px; }

/* Abonnement en cours : un pavé libellé/valeur plutôt qu'un tableau — il n'y a jamais qu'une ligne,
   et chaque intitulé doit rester lisible (« terme » et « depuis » se confondent sans étiquette). */
.bhbil-sum { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; padding: 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-inset); }
.bhbil-sum-cell { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhbil-sum-cell--wide { grid-column: 1 / -1; }
.bhbil-sum-l { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhbil-sum-v { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font: 400 12.5px/1.4 'Archivo', sans-serif; color: var(--text-body); }
.bhbil-acts { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 14px; }

/* Saisies : une ligne de champs étiquetés qui se replie, séparée du tableau par un filet — poser un
   abonnement et lire ceux qui existent sont deux gestes différents. */
.bhbil-form { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.bhbil-f { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhbil-f label { font: 500 9px/1 'JetBrains Mono', monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhbil-f .input-sm { width: 168px; }
.bhbil-f--caps { flex: 1 1 260px; }
.bhbil-caps { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; min-height: 30px; }
.bhbil-cap { display: flex; align-items: center; gap: 6px; font: 400 11.5px/1 'Archivo', sans-serif; color: var(--text-body); cursor: pointer; }

@media (max-width: 1000px) {
    .bhbil-exp-head, .bhbil-cens-head, .bhbil-pass-head, .bhbil-quota-head, .bhbil-plan-head, .bhbil-found-head { display: none; }
    .bhbil-exp-row, .bhbil-cens-row, .bhbil-pass-row, .bhbil-quota-row, .bhbil-plan-row, .bhbil-found-row { grid-template-columns: 1fr; gap: 6px; }
}

/* ─── Console d'administration : navbar dédiée en deux rangées (AdminConsoleLayout, écrans 4a/4b/4c) ─
   Bandeau haut (logo, CONSOLE, recherche, environnement, version, langue, utilisateur) + sous-nav
   (rubriques à gauche, groupe SuperAdmin à droite). Entièrement tokenisé → suit le thème. */
/* Hauteur FIXE, comme .app-shell — surtout pas min-height. html/body sont en overflow:hidden
   (cf. le bloc html, body) : une colonne en min-height grandit avec son contenu, le body la rogne,
   et le .bhcon-body qui devait defiler n'a jamais de hauteur definie a remplir. Resultat : le bas de
   la console etait inatteignable, sans barre de defilement, sur tous les ecrans /admin* et /bans. */
.bhcon { position: relative; display: flex; flex-direction: column; height: 100dvh; overflow: hidden; background: transparent;   /* laisse passer le fond animé de la page */ color: var(--text-primary); font-family: 'Archivo', system-ui, sans-serif; }

/* Troisième barre de navigation de l'application : même hauteur et même logo que les deux autres.
   ⚠️ Le menu mobile de la sous-nav se pose juste sous cet en-tête et lit la MÊME variable (voir le
   media query plus bas) : avec un nombre en dur, il flotterait ou recouvrirait l'en-tête dès que la
   hauteur change. C'est exactement ce qui était arrivé au cockpit de tirage. */
.bhcon-head { display: flex; align-items: center; gap: 14px; height: var(--appnav-h); padding: 0 32px; background: var(--bg-surface); border-bottom: 1px solid var(--border); flex: none; }
.bhcon-logo { display: inline-flex; align-items: center; flex: none; text-decoration: none; }
.bhcon-logo img { height: 64px; width: auto; display: block; }
.bhcon-tag { display: grid; place-items: center; height: 22px; padding: 0 8px; border: 1px solid var(--border); border-radius: var(--radius); font: 600 9.5px/1 'JetBrains Mono', monospace; letter-spacing: .18em; text-transform: uppercase; color: var(--text-muted); flex: none; }
.bhcon-burger { display: none; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--radius); border: 1px solid var(--border); background: none; color: var(--text-body); cursor: pointer; font-size: 19px; flex: none; }
.bhcon-sp { flex: 1; }
.bhcon-search { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px; width: 250px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-input); font: 400 12px/1 'Archivo', sans-serif; color: var(--text-muted); flex: none; }
.bhcon-search i { font-size: 14px; }
.bhcon-env { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: var(--radius); border: 1px solid rgba(55,217,154,.4); background: rgba(55,217,154,.1); font: 600 10px/1 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--green-fg); flex: none; }
.bhcon-env-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green-fg); }
/* Sortie de la console : discrète comme les repères voisins (env, version), mais cliquable et
   nommée. En étroit le libellé s'efface, l'icône et le title restent. */
.bhcon-exit { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px; border-radius: var(--radius); border: 1px solid var(--border); color: var(--text-secondary); text-decoration: none; font: 500 11.5px/1 'Archivo', sans-serif; }
.bhcon-exit:hover { background: var(--bg-hover); color: var(--text-primary); }
/* En étroit, l'icône seule : on lui garde une surface carrée cliquable plutôt qu'une bande de
   20 px. ⚠️ 26 px reste sous les 44 px d'une vraie cible tactile — c'est le gabarit de tous les
   repères de cet en-tête, à revoir en bloc lors de la passe mobile, pas ici tout seul. */
@media (max-width: 900px) { .bhcon-exit span { display: none; } .bhcon-exit { min-width: 26px; padding: 0 6px; justify-content: center; } }
.bhcon-ver { font: 500 10px/1 'JetBrains Mono', monospace; color: var(--text-faint); flex: none; }
.bhcon-lang { flex: none; }
.bhcon-user { display: flex; align-items: center; gap: 9px; flex: none; }
.bhcon-user-av { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: none; }
.bhcon-user-initials { display: grid; place-items: center; background: var(--tint-gold-bg); border: 1px solid rgba(243,194,86,.4); font: 600 10.5px/1 'Archivo', sans-serif; color: var(--gold-fg); }
.bhcon-user-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bhcon-user-name { font: 600 11.5px/1 'Archivo', sans-serif; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 140px; }
.bhcon-user-role { font: 600 8.5px/1 'JetBrains Mono', monospace; letter-spacing: .1em; color: var(--gold-fg); }

.bhcon-subnav { display: flex; align-items: center; height: 44px; padding: 0 32px; background: var(--bg-inset); border-bottom: 1px solid var(--border); flex: none; overflow-x: auto; }
.bhcon-nav { display: flex; align-items: center; height: 100%; }
.bhcon-link { display: flex; align-items: center; gap: 6px; height: 100%; padding: 0 10px; font: 500 12px/1 'Archivo', sans-serif; color: var(--nav-ink); text-decoration: none; white-space: nowrap; }
.bhcon-link:hover { color: var(--accent-light); }
.bhcon-link.active { font-weight: 600; color: var(--text-primary); box-shadow: inset 0 -2px 0 var(--accent-warm); }
.bhcon-sec { margin-right: 10px; font: 600 9px/1 'JetBrains Mono', monospace; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-fg); white-space: nowrap; }

.bhcon-body { flex: 1; overflow-y: auto; padding: 24px 32px 34px; min-height: 0; }

@media (max-width: 1040px) {
    .bhcon-head { padding: 0 16px; gap: 10px; }
    .bhcon-search, .bhcon-ver, .bhcon-user-txt { display: none; }
    .bhcon-burger { display: inline-flex; }
    /* La sous-nav se replie en menu déroulant (burger). Les badges, portés par les liens, y restent visibles. */
    .bhcon-subnav { position: absolute; top: var(--appnav-h); left: 0; right: 0; z-index: 200; height: auto; flex-direction: column; align-items: stretch; gap: 0; padding: 8px 12px; background: var(--bg-surface); border-bottom: 1px solid var(--border); box-shadow: 0 18px 40px var(--shadow-strong); overflow: visible; display: none; }
    .bhcon-subnav.bhcon-subnav--open { display: flex; }
    .bhcon-nav { flex-direction: column; align-items: stretch; height: auto; }
    .bhcon-sp { display: none; }
    .bhcon-link { height: 42px; justify-content: space-between; box-shadow: none !important; }
    .bhcon-link.active { color: var(--text-primary); box-shadow: inset 3px 0 0 var(--accent) !important; }
    .bhcon-sec { margin: 0; padding: 12px 10px 6px; }
    .bhcon-body { padding: 20px 16px 28px; }
}

/* Badges de compteurs de la sous-nav console : Demandes = pastille pleine (accent) ; Équipes =
   compteur rouge discret (équipes signalées). Tokenisés → suivent le thème. */
.bhcon-badge { display: grid; place-items: center; min-width: 17px; height: 17px; margin-left: 7px; padding: 0 5px; border-radius: var(--radius); background: var(--accent); font: 700 9px/1 'JetBrains Mono', monospace; color: var(--on-accent); flex: none; }
.bhcon-badge--warn { min-width: 0; height: auto; margin-left: 6px; padding: 0; border-radius: 0; background: none; color: var(--red-fg); font: 700 9.5px/1 'JetBrains Mono', monospace; }

/* ─── Stepper HORIZONTAL de création de tournoi (refonte Claude Design, écran 3d) ──────────────
   En-tête « Nouveau tournoi » + barre d'étapes horizontale (pastille + libellé, traits reliants),
   puis corps du formulaire centré. Remplace l'ancien rail vertical. Tokenisé → suit le thème. */
.tour-head { display: flex; align-items: center; gap: 16px; padding: 16px 40px; background: var(--bg-surface); border-bottom: 1px solid var(--border); }
/* 40px et non 26 : le logo était plus petit que le titre qu'il accompagne (22px de capitale
   condensée), et se lisait comme une puce plutôt que comme une marque. L'image source est carrée
   (1254×1254), donc la hauteur suffit à la dimensionner. */
.tour-head img { height: 40px; width: auto; display: block; }
.tour-head-title { font: 700 22px/1 'Barlow Condensed', sans-serif; text-transform: uppercase; letter-spacing: .02em; color: var(--text-primary); }
.tour-head-sp { flex: 1; }
.tour-head-counter { display: inline-flex; align-items: center; gap: 6px; font: 500 10px/1 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.tour-head-cancel { background: none; border: 0; padding: 0; cursor: pointer; font: 500 12.5px/1 'Archivo', sans-serif; color: var(--text-muted); }
.tour-head-cancel:hover { color: var(--text-primary); }

/* overflow-x conservé : à neuf étapes, aucune largeur ne les fera tenir sur un téléphone, et il vaut
   mieux que le rail défile SEUL que la page entière. Mais il ne doit pas se déclencher sur un écran
   de bureau ordinaire — mesuré, le seuil était à 1226 px, soit une fenêtre courante. */
.tour-hsteps { display: flex; align-items: center; gap: 0; padding: 16px 24px; background: var(--bg-inset); border-bottom: 1px solid var(--border); overflow-x: auto; }
.tour-hstep { display: flex; align-items: center; gap: 8px; flex: none; }
.tour-hstep--clickable { cursor: pointer; }
.tour-hstep-dot { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font: 600 10px/1 'JetBrains Mono', monospace; flex: none; }
.tour-hstep-label { font: 500 11px/1 'JetBrains Mono', monospace; letter-spacing: .04em; white-space: nowrap; }
/* 🔴 Les huit traits imposaient 8 × (24 + 2×10) = 352 px de plancher, soit plus du quart du rail pour
   de la pure décoration — c'est ce plancher, et non les libellés, qui déclenchait la barre de
   défilement. Ils restent extensibles (flex: 1) et occupent donc tout l'espace disponible sur un
   grand écran ; seul leur MINIMUM baisse. */
.tour-hstep-line { flex: 1; min-width: 10px; height: 1px; margin: 0 6px; }

.tour-hstep--done .tour-hstep-dot { background: var(--bg-chip); color: var(--accent-light); }
.tour-hstep--done .tour-hstep-label { color: var(--text-soft); }
.tour-hstep--active .tour-hstep-dot { background: var(--accent); color: var(--on-accent); font-weight: 700; }
.tour-hstep--active .tour-hstep-label { color: var(--text-primary); font-weight: 600; }
.tour-hstep--todo .tour-hstep-dot { border: 1px solid var(--line-strong); color: var(--text-dim); }
.tour-hstep--todo .tour-hstep-label { color: var(--text-faint); }
.tour-hstep--clickable:hover .tour-hstep-label { color: var(--text-primary); }

.tour-hstep-line--done { background: var(--border-input); }
.tour-hstep-line--active { background: linear-gradient(90deg, var(--border-input), var(--accent)); }
.tour-hstep-line--todo { background: var(--border); }

.tour-body { max-width: min(var(--page-max), 100%); margin-inline: auto; padding: 0 24px 44px; }

@media (max-width: 720px) {
    .tour-head { padding: 14px 16px; gap: 12px; }
    .tour-head-counter { display: none; }
    .tour-hsteps { padding: 14px 16px; }
    .tour-hstep-line { min-width: 10px; margin: 0 6px; }
    .tour-body { padding: 20px 16px 32px; }
}

/* ─── Création de tournoi — refonte « stepper 5a–5g » (Claude Design) ───────────────────────────
   Mise en page à deux colonnes : le formulaire de l'axe à gauche, un panneau « combinaison en cours »
   à droite qui suit la construction et porte la navigation. Entièrement tokenisé → suit les deux
   thèmes (sombre = maquette broadcast, clair conservé) ; aucune couleur en dur (cf. PR #438). */
.tour-stage { display: grid; grid-template-columns: minmax(0, 1fr) 356px; align-items: stretch; margin-top: 30px; border: 1px solid var(--border); border-radius: var(--radius); background: transparent;   /* laisse passer le fond animé de la page */ overflow: hidden; }
.tour-main { padding: 30px 34px 38px 36px; display: flex; flex-direction: column; gap: 26px; min-width: 0; }
.tour-side { border-left: 1px solid var(--border); padding: 30px 32px 34px 28px; display: flex; flex-direction: column; gap: 22px; background: var(--bg-inset); }
.tour-side-top { display: flex; flex-direction: column; gap: 16px; }

/* En-tête d'axe : kicker mono, grand titre condensé, chapô. */
.tour-axis-kicker { display: block; font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.tour-h2 { margin: 8px 0 6px; font: 700 32px/1 var(--font-display); text-transform: uppercase; letter-spacing: .01em; color: var(--text-primary); }
.tour-lead { margin: 0; font: 400 12.5px/1.6 var(--font-alt); color: var(--text-secondary); max-width: 640px; }

/* Cartes de sélection (un axe = une grille de cartes). */
.tour-cards { display: grid; gap: 12px; }
.tour-cards--4 { grid-template-columns: repeat(4, 1fr); }
.tour-cards--2 { grid-template-columns: 1fr 1fr; }
.tour-card { position: relative; text-align: left; padding: 20px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; gap: 10px; cursor: pointer; transition: border-color .12s, background .12s; font-family: var(--font-alt); }
.tour-card:hover { border-color: var(--line-strong); }
.tour-card--active { border-color: var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.tour-card--gold.tour-card--active { border-color: var(--tint-gold-border); background: linear-gradient(160deg, var(--tint-gold-bg), var(--bg-surface)); }
.tour-card-check { position: absolute; top: 14px; right: 14px; width: 18px; height: 18px; border-radius: 50%; background: var(--accent); display: grid; place-items: center; font-size: 9px; color: var(--on-accent); }
.tour-card-check--gold { background: var(--gold-fg); }
.tour-card-kicker { font: 500 10px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--accent-light); }
.tour-card:not(.tour-card--active) .tour-card-kicker { color: var(--text-muted); }
.tour-card-num { font: 700 34px/1 var(--font-display); color: var(--text-primary); }
.tour-card:not(.tour-card--active) .tour-card-num { color: var(--text-secondary); }
.tour-card-title { font: 700 24px/1 var(--font-display); text-transform: uppercase; letter-spacing: .01em; color: var(--text-primary); }
.tour-card:not(.tour-card--active) .tour-card-title { color: var(--text-secondary); }
.tour-card-title--gold { color: var(--gold-fg); }
.tour-card-desc { margin: 0; font: 400 11.5px/1.55 var(--font-alt); color: var(--text-secondary); }
.tour-card:not(.tour-card--active) .tour-card-desc { color: var(--text-muted); }
.tour-card-rows { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; margin-top: 2px; border-top: 1px solid var(--border); }
.tour-card-row { display: flex; justify-content: space-between; gap: 12px; font: 400 11px/1.3 var(--font-alt); color: var(--text-muted); }
.tour-card-row-v { font: 500 11px/1 var(--font-mono); color: var(--text-bright); }
.tour-card-row-v--accent { color: var(--accent); }
/* Carte « mode » : texte à gauche, grand nombre de capacité à droite. */
.tour-card--mode { flex-direction: row; align-items: flex-start; gap: 18px; }
.tour-card-mode-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.tour-card-metric { text-align: right; flex: none; }
.tour-card-metric-n { font: 700 30px/1 var(--font-mono); color: var(--text-primary); }
.tour-card:not(.tour-card--active) .tour-card-metric-n { color: var(--text-secondary); }
.tour-card-metric-u { display: block; margin-top: 5px; font: 500 9.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
/* Carte « format » : entrée numérique intégrée. */
.tour-card-input { display: flex; align-items: center; gap: 10px; }
.tour-card-input label { font: 500 10px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }
.tour-card-input input { width: 82px; height: 36px; border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-input); padding: 0 10px; font: 700 14px/1 var(--font-mono); color: var(--text-primary); }
.tour-tag { align-self: flex-start; height: 22px; padding: 0 9px; display: inline-grid; place-items: center; border-radius: var(--radius); border: 1px solid var(--border); font: 600 9.5px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.tour-tag--accent { border-color: transparent; background: var(--bg-chip); color: var(--accent-light); }

/* Encadrés pédagogiques (invariant, avertissement, danger, info). */
.tour-note { padding: 18px 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-inset); }
.tour-note--info { border-color: var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.tour-note-kicker { display: block; font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.tour-note-kicker--accent { color: var(--accent-light); }
.tour-note-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.tour-note-aside { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-muted); }

/* Résumé de combinaison (étape Format). */
.tour-combo { padding: 20px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.tour-combo-kicker { display: block; font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--accent-light); }
.tour-combo-terms { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.tour-combo-term { font: 700 26px/1.15 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.tour-combo-term--gold { color: var(--gold-fg); }
.tour-combo-plus { font: 400 20px/1 var(--font-mono); color: var(--text-faint); }

/* Panneau latéral : kicker, puces de combinaison, lignes clé/valeur, note. */
.tour-side-kicker { display: block; font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.tour-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tour-chip { height: 24px; padding: 0 10px; display: grid; place-items: center; border-radius: var(--radius); font: 500 10.5px/1 var(--font-mono); text-transform: uppercase; letter-spacing: .02em; }
.tour-chip--done { background: var(--bg-hover); color: var(--text-secondary); }
.tour-chip--active { background: var(--bg-chip); color: var(--accent-light); }
.tour-chip--todo { border: 1px dashed var(--line-strong); color: var(--text-faint); }
.tour-side-rows { display: flex; flex-direction: column; gap: 9px; padding-top: 14px; border-top: 1px solid var(--border); }
.tour-side-row { display: flex; justify-content: space-between; gap: 12px; }
.tour-side-row-k { font: 400 11.5px/1.3 var(--font-alt); color: var(--text-secondary); }
.tour-side-row-v { font: 500 11.5px/1.2 var(--font-mono); color: var(--text-bright); text-align: right; }
.tour-side-row-v--gold { color: var(--gold-fg); }
.tour-side-note { display: block; font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }

/* Navigation du panneau latéral (poussée en bas). */
.tour-nav { display: flex; gap: 10px; margin-top: auto; }
.tour-back { flex: none; }
.tour-back--off { flex: none; display: grid; place-items: center; height: 40px; padding: 0 16px; border-radius: var(--radius); border: 1px solid var(--border); font: 600 12.5px/1 var(--font-alt); color: var(--text-faint); }
.tour-go { flex: 1; justify-content: center; background: var(--accent-gradient); }
.tour-go:hover:not(:disabled) { background: var(--accent-gradient); filter: brightness(1.06); }

/* Étape Paramètres : grilles de champs, commission en ligne, contrôles, boîtes d'inscription. */
.tour-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.tour-field-hint { padding: 0; margin-top: 6px; }
.tour-inline-fields { display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 8px; }
.tour-inline-fields input { max-width: 100px; }
.tour-inline-sep { opacity: .4; }
.tour-optboxes { display: flex; gap: 10px; }
.tour-optbox { flex: 1; text-align: left; padding: 14px 16px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); cursor: pointer; transition: border-color .12s; }
.tour-optbox--active { border-color: var(--accent); }
.tour-optbox-title { font: 600 13px/1 var(--font-alt); color: var(--text-secondary); }
.tour-optbox--active .tour-optbox-title { color: var(--text-primary); }
.tour-optbox-desc { margin: 7px 0 0; font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }
.tour-checks { display: flex; flex-direction: column; gap: 8px; padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.tour-check { display: flex; align-items: center; gap: 8px; font: 400 11px/1.4 var(--font-alt); color: var(--text-secondary); }
.tour-check-dot { width: 14px; height: 14px; border-radius: 50%; display: grid; place-items: center; font-size: 8px; flex: none; }
.tour-check--ok .tour-check-dot { background: var(--tint-green-bg); color: var(--green-fg); }
.tour-check--bad .tour-check-dot { background: var(--tint-red-bg); color: var(--red-fg); }
.tour-check--bad { color: var(--red-soft-fg); }

/* ── Wager : étapes « Type de tournoi » et « Arbre » ─────────────────────────
   Tout est tokenisé — aucune couleur en dur, aucun préfixe `ad`, aucune largeur
   de page. Le tableau des classes défile dans son propre conteneur : sans ça,
   sa piste minimale ferait défiler l'écran entier à travers la grille. */
/* Ce qu'EST un Wager. Le bloc annonçait auparavant ce que le choix retirait du parcours, d'où
   la bordure tiretée et le titre barré : deux signaux de « supprimé » qui n'ont plus lieu d'être
   sur un descriptif. Bordure pleine, titre non barré. */
.tour-facts { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 13px; }
.tour-fact { flex: 1 1 200px; min-width: 0; padding: 13px 15px; border-radius: var(--radius); border: 1px solid var(--line-soft); background: var(--bg-surface); }
.tour-fact-title { display: block; font: 600 11.5px/1 var(--font-alt); color: var(--accent); }
.tour-drop-desc { margin: 7px 0 0; font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }

.tour-switches { display: flex; flex-wrap: wrap; gap: 12px; }
.tour-switch { flex: 1 1 260px; min-width: 0; display: flex; align-items: center; gap: 14px; text-align: left; padding: 14px 16px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); cursor: pointer; }
.tour-switch:disabled { opacity: .5; cursor: not-allowed; }
.tour-switch--on { border-color: var(--accent); }
.tour-switch-knob { position: relative; flex: none; width: 42px; height: 24px; border-radius: var(--radius); background: var(--line-strong); transition: background .15s; }
.tour-switch-knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--bg-page); transition: left .15s; }
.tour-switch--on .tour-switch-knob { background: var(--accent); }
.tour-switch--on .tour-switch-knob::after { left: 21px; }
.tour-switch-text { flex: 1; min-width: 0; }
.tour-switch-title { display: block; font: 600 12.5px/1.3 var(--font-alt); color: var(--text-secondary); }
.tour-switch--on .tour-switch-title { color: var(--text-primary); }
.tour-switch-desc { display: block; margin-top: 4px; font: 400 10px/1.45 var(--font-alt); color: var(--text-muted); }

.tour-bo-table { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow-x: auto; }
.tour-bo-head, .tour-bo-row, .tour-bo-total { display: grid; grid-template-columns: minmax(150px, 1.5fr) minmax(140px, 1.35fr) 76px 132px 64px; align-items: center; gap: 8px; padding: 12px 16px; min-width: 0; }
.tour-bo-head { background: var(--bg-hover); border-bottom: 1px solid var(--line-soft); font: 600 9px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-secondary); text-transform: uppercase; }
.tour-bo-row { border-bottom: 1px solid var(--line-soft); }
.tour-bo-row--loser { background: var(--tint-gold-bg); }
.tour-bo-class { font: 600 12px/1.3 var(--font-alt); color: var(--text-primary); min-width: 0; }
.tour-bo-fed { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-muted); min-width: 0; }
.tour-bo-num { font: 500 11.5px/1 var(--font-mono); color: var(--text-secondary); text-align: right; }
.tour-bo-num--strong { font-weight: 700; color: var(--text-primary); }
.tour-bo-num--accent { font-weight: 700; color: var(--accent-light); }
.tour-bo-slots { font-size: 9.5px; color: var(--text-faint); }
.tour-bo-fmt { justify-self: center; }
.tour-bo-total { background: var(--bg-hover); font: 600 11px/1 var(--font-mono); letter-spacing: .08em; color: var(--text-secondary); }
.tour-bo-atmost { font: 400 10px/1.3 var(--font-alt); color: var(--text-faint); justify-self: center; }

.tour-bo-pick { display: flex; border: 1px solid var(--border-input); border-radius: var(--radius); overflow: hidden; }
.tour-bo-opt { padding: 5px 9px; border: 0; background: transparent; font: 500 9.5px/1 var(--font-mono); color: var(--text-faint); cursor: pointer; }
.tour-bo-opt--on { background: var(--accent); color: var(--on-accent); font-weight: 700; }

.tour-sim { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-start; }
.tour-sim-why { flex: 1 1 260px; min-width: 0; }
.tour-sim-rows { flex: 0 1 238px; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.tour-side-row-v--ok { color: var(--green-fg); }
.tour-side-row-v--bad { color: var(--red-fg); }

/* Un axe que le parcours ne traverse pas : imposé, pas « à venir ». */
.tour-chip--locked { border: 1px solid var(--line-strong); background: var(--bg-hover); color: var(--text-muted); }

/* Étape Économie : bouton d'ajout de multiplicateur. */
.tour-mult { margin-top: 4px; }
.tour-mult .section-title { margin-bottom: 12px; }
.tour-mult-add { margin-top: 12px; }

/* Étape Récap : cartes de relecture, grille économie, carte cagnotte. */
.tour-recap-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.tour-recap-card { padding: 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.tour-recap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.tour-recap-head + .tour-side-rows { border-top: 0; padding-top: 0; }
.tour-recap-modify { background: none; border: 0; padding: 0; cursor: pointer; font: 500 10.5px/1 var(--font-alt); color: var(--accent); }
.tour-recap-modify:hover { color: var(--accent-light); }
.tour-recap-eco { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.tour-metric { display: flex; flex-direction: column; gap: 7px; }
.tour-metric-label { font: 400 10.5px/1.3 var(--font-alt); color: var(--text-secondary); }
.tour-metric-value { font: 700 16px/1 var(--font-mono); color: var(--text-bright); }
.tour-pot { padding: 20px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.tour-pot-kicker { display: block; font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--accent-light); }
.tour-pot-amount { font: 700 30px/1.1 var(--font-mono); color: var(--accent); margin-top: 10px; }
.tour-pot-rows { margin-top: 16px; }
.tour-draft { display: flex; flex-direction: column; gap: 12px; }
.tour-draft-row { display: flex; align-items: center; gap: 10px; }

@media (max-width: 900px) {
    .tour-stage { grid-template-columns: 1fr; }
    .tour-side { border-left: 0; border-top: 1px solid var(--border); }
    .tour-cards--4 { grid-template-columns: repeat(2, 1fr); }
    .tour-cards--2, .tour-grid-3, .tour-recap-cards, .tour-recap-eco { grid-template-columns: 1fr; }
    .tour-card--mode { flex-direction: column; }
    .tour-h2 { font-size: 26px; }
}

/* ─── Onglet Statistiques d'un tournoi — maquette 6a (composant TournamentStatsPanel) ───────────
   Bascule de métrique + « formations affichées » + graphe cumulé (seuil Match Point) + synthèse +
   alternative textuelle. Tokenisé → suit les deux thèmes ; la palette des courbes reste une palette
   de data-viz (comme partout ailleurs pour les séries). */
.bhst-toolbar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 4px; }
.bhst-seg { display: flex; gap: 4px; padding: 4px; border-radius: var(--radius); background: var(--bg-surface); border: 1px solid var(--border); }
.bhst-seg-opt { height: 32px; padding: 0 16px; border: 0; background: none; border-radius: var(--radius); display: grid; place-items: center; font: 500 12px/1 var(--font-alt); color: var(--text-secondary); cursor: pointer; }
.bhst-seg-opt:hover { color: var(--text-primary); }
.bhst-seg-opt--active { background: var(--bg-chip); color: var(--accent-light); font-weight: 600; }
.bhst-hint { font: 400 11px/1.5 var(--font-alt); color: var(--text-muted); max-width: 46ch; }
.bhst-spacer { flex: 1; }
.bhst-kicker { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
/* Paliers de multiplicateurs, à côté du bandeau : il annonçait « multiplicateurs appliqués » sans
   jamais dire lesquels, alors que la donnée voyage dans le même DTO (Bogue #1006). */
.bhst-mult { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-left: auto; }
.bhst-tiers { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.bhst-tier { font: 400 10.5px/1 var(--font-mono); color: var(--text-muted); white-space: nowrap; }
.bhst-tier b { font-weight: 600; color: var(--text-secondary); }

.bhst-panel { padding: 20px 24px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); margin-top: 14px; }
.bhst-panel-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.bhst-count { font: 500 10px/1 var(--font-mono); color: var(--text-muted); }
.bhst-note { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-faint); }

/* Légende : chaque formation visible est un bouton cliquable (retirer la courbe). */
.bhst-legend { display: flex; flex-wrap: wrap; gap: 10px 22px; align-items: center; }
.bhst-leg { display: inline-flex; align-items: center; gap: 9px; background: none; border: 0; padding: 0; cursor: pointer; font: 500 12px/1 var(--font-alt); }
.bhst-leg-dot { width: 10px; height: 10px; border-radius: var(--radius); flex: none; }
.bhst-leg-name { color: var(--text-secondary); }
.bhst-leg:hover .bhst-leg-name { color: var(--text-primary); }
.bhst-leg-val { font: 700 12px/1 var(--font-mono); color: var(--text-bright); }
.bhst-leg--lead .bhst-leg-name { color: var(--text-primary); font-weight: 600; }
.bhst-leg--lead .bhst-leg-val { color: var(--gold-fg); }
.bhst-legsep { width: 1px; height: 18px; background: var(--border); }
.bhst-hidden { display: flex; flex-wrap: wrap; gap: 5px; }
.bhst-chip { height: 22px; padding: 0 8px; border-radius: var(--radius); border: 1px solid var(--border); background: none; display: grid; place-items: center; font: 500 10px/1 var(--font-mono); text-transform: uppercase; color: var(--text-muted); cursor: pointer; }
.bhst-chip:hover { border-color: var(--line-strong); color: var(--text-secondary); }

/* Graphe + repère de franchissement. */
.bhst-caption { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); font: 400 10.5px/1.4 var(--font-alt); color: var(--text-secondary); }
.bhst-caption-mark { width: 14px; height: 0; border-top: 1px dashed var(--gold-fg); flex: none; }

/* Synthèse sur l'ensemble du tournoi. */
.bhst-summary { display: flex; align-items: center; gap: 32px; padding: 18px 24px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); margin-top: 14px; flex-wrap: wrap; }
.bhst-sumsep { width: 1px; height: 34px; background: var(--border); flex: none; }
.bhst-stat { display: flex; flex-direction: column; gap: 5px; }
.bhst-stat-n { font: 700 22px/1 var(--font-mono); color: var(--text-primary); }
.bhst-stat-l { font: 400 10.5px/1.3 var(--font-alt); color: var(--text-muted); }

/* Alternative textuelle du graphe (accessibilité). */
.bhst-alt { overflow-x: auto; }
/* 🔴 Le plancher se CALCULE à partir de --games, il ne peut pas être une constante : le nombre de
   colonnes est celui des parties, et le composant le pose déjà en style en ligne (`--games`) pour
   la piste. Écrit en dur à 620px, il mentait dès qu'un tournoi dépassait ~7 parties : sur la finale
   EWC (11 parties) la grille réclamait 878px, si bien que .bhst-alt défilait correctement mais que
   la LIGNE, elle, s'arrêtait à 620 — fond zébré, bordure et survol interrompus 258px avant les
   chiffres. Défaut visible sur tablette autant que sur téléphone : il suffit que le conteneur soit
   plus étroit que la grille.
   `max(620px, …)` conserve exactement le rendu d'avant pour les tournois courts, où le plancher
   servait de confort de lecture et non de mesure. Les 8px de queue sont le `padding: 11px 4px` de
   la ligne : `box-sizing: border-box` est global ici, donc un plancher qui les oublie laisse
   repasser 4px de contenu hors de la boîte — mesuré. */
.bhst-alt-head, .bhst-alt-row { display: grid; grid-template-columns: 150px repeat(var(--games, 5), minmax(44px, 1fr)) 96px; gap: 12px; align-items: center; min-width: max(620px, calc(150px + var(--games, 5) * 44px + 96px + (var(--games, 5) + 1) * 12px + 8px)); }
.bhst-alt-head { padding: 0 4px 10px; border-bottom: 1px solid var(--border); }
.bhst-alt-head span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
/* Les colonnes de partie portent le libellé complet (« Partie 11 »). Sur un tournoi à onze parties
   la piste retombe à son plancher de 44px : le libellé passe à la ligne au lieu d'imposer un
   défilement horizontal, et l'alignement bas garde les autres en-têtes sur la même ligne de base. */
.bhst-alt-head { align-items: end; }
.bhst-alt-head .bhst-alt-g { line-height: 1.3; }
.bhst-alt-end { text-align: right; }
.bhst-alt-row { padding: 11px 4px; border-bottom: 1px solid var(--line-soft); }
.bhst-alt-row:last-child { border-bottom: 0; }
.bhst-alt-row--lead { background: linear-gradient(90deg, var(--tint-gold-bg), transparent); }
.bhst-alt-team { display: flex; align-items: center; gap: 9px; font: 500 12px/1 var(--font-alt); color: var(--text-secondary); }
.bhst-alt-row--lead .bhst-alt-team { color: var(--text-primary); font-weight: 600; }
.bhst-alt-v { font: 400 11.5px/1 var(--font-mono); color: var(--text-secondary); }
.bhst-alt-total { font: 700 13px/1 var(--font-mono); color: var(--text-bright); text-align: right; }
.bhst-alt-row--lead .bhst-alt-total { color: var(--gold-fg); }

@media (max-width: 720px) {
    .bhst-summary { gap: 18px; }
    .bhst-sumsep { display: none; }
    /* Les trois métriques (« Points cumulés », « Placement », « Éliminations ») réclament 286px pour
       269 disponibles à 360 : le segment débordait de son propre cadre de 17px. Il se replie sur
       deux rangs plutôt que de rogner un libellé — c'est le nom de la métrique qui dit ce que le
       graphique montre. */
    .bhst-seg { flex-wrap: wrap; }
    .bhst-seg-opt { padding: 0 10px; }
}

/* ═══ Classements globaux (/leaderboard, maquette 7a) ═══════════════════════════════════════
   Écran public : rendu dans le shell quand une session est ouverte, plein cadre sinon.
   Entièrement tokenisé — les hex de la maquette SONT les valeurs sombres des tokens, donc le
   sombre reproduit la maquette et le thème clair suit sans réécriture. */
.bhrk { display: flex; flex-direction: column; gap: 20px; padding: 26px clamp(16px, 3vw, 56px) 44px; }
/* ⚠️ Hors session, cet élément porte AUSSI .public-page-content, donc height:100dvh : une colonne
   flex à hauteur définie écrase ses enfants au lieu de déborder. Sans ce flex:none, le tableau
   était tronqué en plein milieu d'une ligne — constaté à l'écran, invisible aux tests. */
.bhrk > * { flex: none; }

.bhrk-kicker { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; color: var(--text-muted); text-transform: uppercase; }
.bhrk-note { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-faint); }
.bhrk-fspacer { flex: 1; }
.bhrk-num { font: 400 12px/1 var(--font-mono); color: var(--text-secondary); }
.bhrk-right { text-align: right; }

/* ── En-tête ── */
.bhrk-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 28px; flex-wrap: wrap; }
.bhrk-headline { display: flex; flex-direction: column; gap: 11px; min-width: 0; }
.bhrk-h1 { margin: 0; font: 700 clamp(34px, 5vw, 52px)/.96 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bhrk-lead { margin: 0; font: 400 12.5px/1.6 var(--font-alt); color: var(--text-soft); max-width: 76ch; }
.bhrk-scope-wrap { display: flex; flex-direction: column; gap: 10px; align-items: flex-end; flex: none; }
.bhrk-scope { display: flex; gap: 4px; padding: 4px; border-radius: var(--radius); background: var(--bg-surface); border: 1px solid var(--border); }
/* Ce sont de vrais <button> : sans remise à plat, le navigateur leur pose son fond gris et sa
   bordure, et l'onglet inactif ressort plus que l'actif. */
.bhrk-scope-btn { display: grid; place-items: center; height: 32px; padding: 0 16px; border: 0; border-radius: var(--radius); background: none; cursor: pointer; font: 500 12px/1 var(--font-alt); color: var(--nav-ink); }
.bhrk-scope-btn:hover { color: var(--accent-light); }
.bhrk-scope-btn--on, .bhrk-scope-btn--on:hover { background: var(--bg-chip); color: var(--accent-light); font-weight: 600; }

/* ── Filtres ── */
.bhrk-filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-bottom: 20px; border-bottom: 1px solid var(--border); }
.bhrk-flabel { font: 500 9px/1 var(--font-mono); letter-spacing: .14em; color: var(--text-muted); flex: none; }
.bhrk-fsep { width: 1px; height: 20px; background: var(--border); flex: none; }
.bhrk-chip { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 14px; border-radius: var(--radius); border: 1px solid var(--border); font: 500 11.5px/1 var(--font-alt); color: var(--text-soft); }
.bhrk-chip--on { border-color: var(--border-input); background: var(--accent-subtle); color: var(--accent-light); font-weight: 600; }
.bhrk-chip--off { cursor: not-allowed; opacity: .75; }
.bhrk-live-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--lime-fg); }
.bhrk-live-txt { font: 500 9.5px/1 var(--font-mono); color: var(--lime-fg); }
.bhrk-count { font: 400 11px/1 var(--font-mono); color: var(--text-muted); text-transform: uppercase; }

/* ── Échelle de la saison ── */
.bhrk-scale { padding: 20px 24px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.bhrk-scale-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
/* 8 cases : « non classé » + les 7 paliers. Les distinctions de place ont leur propre rangée
   (.bhrk-dists) — les mêler ici laisserait croire à un 8ᵉ, 9ᵉ… palier, alors qu'elles ne se gagnent
   pas sur un score et se perdent sans avoir joué. */
.bhrk-scale-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 6px; }
.bhrk-tier { position: relative; padding: 13px 8px; border-radius: var(--radius); border: 1px solid var(--line-soft); background: var(--bg-inset); display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.bhrk-tier--muted .bhrk-tier-emblem { opacity: .65; }
.bhrk-tier--position { border-style: dashed; border-color: var(--line-strong); }
.bhrk-tier--mine { border-color: var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-inset)); }
.bhrk-tier--mine .bhrk-tier-name { color: var(--text-primary); }
.bhrk-tier--mine .bhrk-tier-range { color: var(--accent-light); }
.bhrk-tier-flag { position: absolute; top: -1px; left: 50%; transform: translateX(-50%); height: 3px; width: 34px; border-radius: 0 0 var(--radius) var(--radius); background: var(--accent); }
/* Plaque sombre dans les deux thèmes : les emblèmes clairs (argent, platine) se délaveraient sur
   le blanc du thème clair. Même parti que .bh-rank-emblem--plaque, appliqué à tous les emblèmes
   de l'écran pour éviter une règle par rang. */
.bhrk-tier-emblem { width: 28px; height: 28px; object-fit: contain; background: var(--emblem-plaque); border-radius: var(--radius); padding: 2px; }
.bhrk-tier-name { font: 600 10.5px/1.2 var(--font-alt); color: var(--text-secondary); }
.bhrk-tier-range { font: 500 9px/1.2 var(--font-mono); color: var(--text-faint); }
.bhrk-tier-range--gold { color: var(--gold-fg); }
/* Coût d'entrée du palier : ce qu'une partie retire avant de rapporter. Volontairement discret —
   c'est une précision de règle, pas la donnée principale de la case. */
.bhrk-tier-cost { font: 500 8.5px/1.2 var(--font-mono); color: var(--text-soft); opacity: .75; }

/* ── Variations de cote (RatingHistory) ──
   Le même bloc sur la fiche joueur et la fiche d'équipe. Les variations NÉGATIVES sont affichées :
   c'est tout le propos du système, une cote qui bouge sans qu'on sache pourquoi n'apprend rien. */
.bhrh {
    margin-top: 22px; padding: 18px; border-radius: var(--radius);
    background: var(--bg-surface); border: 1px solid var(--border);
}
.bhrh-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 14px; }
.bhrh-fspacer { flex: 1; }
.bhrh-l { font: 600 11px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-soft); }
.bhrh-total { font: 700 20px/1 var(--font-mono); color: var(--text-bright); }
.bhrh-unit { font: 400 10px/1 var(--font-alt); color: var(--text-faint); }
.bhrh-empty { margin: 0; font: 400 12px/1.5 var(--font-alt); color: var(--text-soft); }
.bhrh-rows { display: flex; flex-direction: column; }
.bhrh-row {
    display: grid; grid-template-columns: 1fr 72px 62px 76px 72px; gap: 8px;
    align-items: center; padding: 8px 4px; border-bottom: 1px solid var(--line-soft);
}
.bhrh-row:last-child { border-bottom: none; }
.bhrh-row--head {
    font: 600 9px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-faint); border-bottom-color: var(--border);
}
.bhrh-r { text-align: right; }
.bhrh-when { display: flex; align-items: center; gap: 8px; font: 500 11px/1 var(--font-alt); color: var(--text-secondary); }
.bhrh-emblem { width: 20px; height: 20px; flex: none; object-fit: contain; background: var(--emblem-plaque); border-radius: var(--radius); padding: 1px; }
.bhrh-gross { font: 500 11px/1 var(--font-mono); color: var(--text-body); }
.bhrh-cost { font: 500 11px/1 var(--font-mono); color: var(--text-faint); }
.bhrh-delta { font: 700 12px/1 var(--font-mono); }
.bhrh-delta--up { color: var(--green-fg); }
.bhrh-delta--down { color: var(--red-fg); }
.bhrh-after { font: 600 11px/1 var(--font-mono); color: var(--text-primary); }
.bhrh-more {
    margin-top: 12px; width: 100%; height: 30px; border-radius: var(--radius); cursor: pointer;
    background: transparent; border: 1px dashed var(--line-strong);
    font: 500 10px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft);
}
.bhrh-more:hover { border-color: var(--border-input); color: var(--text-secondary); }
@media (max-width: 720px) {
    .bhrh-row { grid-template-columns: 1fr 64px 72px; }
    .bhrh-row > :nth-child(2), .bhrh-row > :nth-child(3) { display: none; }
}
/* Rangée des distinctions de place : de la plus large à la plus rare, en dehors de l'échelle. */
.bhrk-dists { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.bhrk-dist-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.bhrk-dist { display: inline-flex; align-items: center; gap: 9px; padding: 7px 12px 7px 8px; border-radius: var(--radius); border: 1px dashed var(--line-strong); background: var(--bg-inset); }
.bhrk-dist--mine { border-style: solid; border-color: var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-inset)); }
.bhrk-dist-emblem { width: 26px; height: 26px; object-fit: contain; background: var(--emblem-plaque); border-radius: var(--radius); padding: 2px; flex: none; }
.bhrk-dist-name { font: 600 11px/1 var(--font-alt); color: var(--text-secondary); white-space: nowrap; }
.bhrk-dist--mine .bhrk-dist-name { color: var(--text-primary); }

.bhrk-scale-foot { display: flex; align-items: center; gap: 10px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.bhrk-badge-dashed { height: 20px; padding: 0 8px; display: grid; place-items: center; border-radius: var(--radius); border: 1px dashed var(--line-strong); font: 500 9px/1 var(--font-mono); letter-spacing: .08em; color: var(--text-soft); flex: none; text-transform: uppercase; }
.bhrk-foot-text { font: 400 11px/1.5 var(--font-alt); color: var(--text-soft); }

/* ── Le classement ── */
.bhrk-board { border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); overflow: hidden; }
.bhrk-board-head { display: flex; align-items: center; gap: 12px; padding: 14px 24px; border-bottom: 1px solid var(--border); background: linear-gradient(90deg, var(--tint-gold-bg), transparent); flex-wrap: wrap; }
.bhrk-board-kicker { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; color: var(--gold-fg); text-transform: uppercase; }
.bhrk-empty { padding: 34px 24px; text-align: center; font: 400 12px/1 var(--font-alt); color: var(--text-muted); }

/* Le pseudo prend la place qu'il lui faut mais pas toute : au-delà, c'est le rang qui absorbe le
   surplus de largeur, sinon un écran large creuse un vide de 400px entre le nom et son emblème. */
.bhrk-row { display: grid; grid-template-columns: 64px minmax(160px, 340px) minmax(186px, 1fr) 92px 76px 116px; gap: 14px; align-items: center; padding: 13px 24px; border-bottom: 1px solid var(--line-soft); }
/* Portée « équipes » : une colonne de plus que les joueurs — le classement moyen, que la ligne
   d'équipe porte (la somme des placements est additive) alors que la ligne joueur ne l'a pas. */
.bhrk-board--teams .bhrk-row { grid-template-columns: 64px minmax(160px, 340px) minmax(150px, 1fr) 92px 104px 104px 116px; }
.bhrk-row--head { padding: 11px 24px; background: var(--bg-inset); border-bottom: 1px solid var(--border); }
.bhrk-row--head span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-muted); text-transform: uppercase; }
.bhrk-row--pod1 { background: linear-gradient(90deg, var(--tint-gold-bg), transparent); }

.bhrk-place { display: flex; align-items: center; gap: 7px; }
.bhrk-place-no { font: 600 13px/1 var(--font-mono); color: var(--text-muted); }
.bhrk-place-bar { width: 4px; height: 16px; border-radius: var(--radius); background: currentColor; }
.bhrk-row--pod1 .bhrk-place, .bhrk-row--pod2 .bhrk-place, .bhrk-row--pod3 .bhrk-place { font: 700 20px/1 var(--font-display); }
.bhrk-row--pod1 .bhrk-place-no, .bhrk-row--pod2 .bhrk-place-no, .bhrk-row--pod3 .bhrk-place-no { font: inherit; }
.bhrk-row--pod1 .bhrk-place { color: var(--gold-fg); }
.bhrk-row--pod1 .bhrk-place-no { color: var(--gold-fg); }
.bhrk-row--pod2 .bhrk-place, .bhrk-row--pod2 .bhrk-place-no { color: var(--text-secondary); }
.bhrk-row--pod3 .bhrk-place, .bhrk-row--pod3 .bhrk-place-no { color: var(--bronze-fg); }

.bhrk-player { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bhrk-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--bg-hover); display: grid; place-items: center; font: 700 11px/1 var(--font-display); color: var(--text-soft); flex: none; }
.bhrk-row--pod1 .bhrk-avatar { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.bhrk-name { font: 500 13px/1 var(--font-alt); color: var(--text-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhrk-name:hover { color: var(--accent-light); }
.bhrk-row--pod1 .bhrk-name, .bhrk-row--pod2 .bhrk-name, .bhrk-row--pod3 .bhrk-name { font-weight: 600; font-size: 13.5px; }
.bhrk-avatar--logo { object-fit: cover; background: var(--bg-inset); }
.bhrk-tag { height: 20px; padding: 0 8px; display: grid; place-items: center; border-radius: var(--radius); background: var(--bg-chip); font: 600 9px/1 var(--font-mono); letter-spacing: .08em; color: var(--accent-light); flex: none; text-transform: uppercase; }
/* Le tag d'équipe est une identité, pas une distinction : ton neutre, réservé à l'accent la pastille « mon équipe ». */
.bhrk-tag--team { background: var(--bg-hover); color: var(--text-soft); }
.bhrk-rank { display: flex; align-items: center; gap: 9px; min-width: 0; }
.bhrk-rank-emblem { width: 24px; height: 24px; object-fit: contain; background: var(--emblem-plaque); border-radius: var(--radius); padding: 2px; flex: none; }
.bhrk-rank-label { font: 500 12px/1 var(--font-alt); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhrk-score { font: 600 14px/1 var(--font-mono); color: var(--text-primary); }
.bhrk-row--pod1 .bhrk-score { font-weight: 700; font-size: 15px; color: var(--gold-fg); }
.bhrk-row--me { border-top: 1px solid var(--border-input); background: linear-gradient(90deg, var(--accent-subtle), transparent); }
.bhrk-row--me .bhrk-place-no, .bhrk-row--me .bhrk-score { color: var(--accent-light); }

.bhrk-more { display: flex; align-items: center; gap: 12px; padding: 12px 24px; border-top: 1px solid var(--border); background: var(--bg-inset); }
.bhrk-more-label { font: 500 10px/1 var(--font-mono); letter-spacing: .1em; color: var(--text-faint); text-transform: uppercase; }
.bhrk-more-line { flex: 1; height: 1px; background: var(--line-soft); }
.bhrk-more-btn { border: 0; background: none; padding: 0; cursor: pointer; font: 500 11.5px/1 var(--font-alt); color: var(--accent); }
.bhrk-more-btn:hover { color: var(--accent-light); }
.bhrk-mine { display: flex; align-items: center; gap: 10px; padding: 11px 24px 14px; background: linear-gradient(90deg, var(--accent-subtle), transparent); flex-wrap: wrap; }
.bhrk-mine-text { font: 400 11px/1.5 var(--font-alt); color: var(--text-soft); }
.bhrk-mine-link { font: 500 11.5px/1 var(--font-alt); color: var(--accent); flex: none; text-decoration: none; }

/* ── Les trois règles ── */
.bhrk-rules { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.bhrk-rule { padding: 16px 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-inset); }
.bhrk-rule p { margin: 9px 0 0; font: 400 11px/1.55 var(--font-alt); color: var(--text-soft); }

/* Sous 1100px, six colonnes ne tiennent plus : le rang passe sous le pseudo et les parties
   disparaissent (le score et le K/D suffisent à situer une ligne). Les positions sont écrites
   explicitement — en placement automatique, le score retombait sous la colonne « place ». */
@media (max-width: 1100px) {
    .bhrk-scale-grid { grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); }

    .bhrk-row, .bhrk-row--head,
    .bhrk-board--teams .bhrk-row { grid-template-columns: 52px minmax(0, 1fr) 64px 84px; row-gap: 6px; }
    .bhrk-row > .bhrk-place  { grid-column: 1; grid-row: 1; }
    .bhrk-row > .bhrk-player { grid-column: 2; grid-row: 1; }
    .bhrk-row > .bhrk-rank   { grid-column: 2; grid-row: 2; }
    .bhrk-row > span:nth-child(4) { display: none; }                     /* parties */
    .bhrk-row > span:nth-child(5) { grid-column: 3; grid-row: 1; }       /* K/D · élim/partie */
    .bhrk-row > span:nth-child(6) { grid-column: 4; grid-row: 1; }       /* score (joueurs) */
    .bhrk-row--head span:nth-child(3), .bhrk-row--head span:nth-child(4) { display: none; }

    /* Équipes : une colonne de plus, donc le classement moyen tombe aussi et le score se décale. */
    .bhrk-board--teams .bhrk-row > span:nth-child(6) { display: none; }              /* clas. moyen */
    .bhrk-board--teams .bhrk-row > span:nth-child(7) { grid-column: 4; grid-row: 1; }
    .bhrk-board--teams .bhrk-row--head span:nth-child(6) { display: none; }
}

/* ─── Fiche d'équipe publique « broadcast » (écran 8a) ───────────────────────
   Namespace .bhtm-. Même partage que la fiche joueur 3e : le HERO reste sombre dans les deux
   thèmes (zone de couverture posée sur une bannière, le voile garantit la lisibilité du texte
   blanc), le CORPS est tokenisé et suit donc le thème. */
.bhtm { max-width: min(var(--page-max), 100%); margin: 0 auto; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: transparent;   /* laisse passer le fond animé de la page */ color: var(--text-secondary); font-family: var(--font-alt); }

.bhtm-hero { position: relative; overflow: hidden; border-bottom: 1px solid #243660; }
.bhtm-hero-bg { position: absolute; inset: 0; background-size: cover; background-position: center; }
.bhtm-hero-bg--empty { background: repeating-linear-gradient(115deg, #203255 0 14px, #141e33 14px 28px); }
.bhtm-hero-veil { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(var(--bg-page-rgb),.5), rgba(var(--bg-page-rgb),.94) 74%, var(--bg-page)); }
.bhtm-hero-in { position: relative; padding: 30px 40px 0; display: flex; align-items: flex-start; gap: 22px; flex-wrap: wrap; }

.bhtm-crest { position: relative; width: 76px; height: 76px; border-radius: var(--radius); background: #1a2436; display: grid; place-items: center; font: 700 26px/1 var(--font-display); color: #5fc3ff; flex: none; overflow: hidden; }
.bhtm-crest img { width: 100%; height: 100%; object-fit: cover; }

.bhtm-id { display: flex; flex-direction: column; gap: 10px; flex: 1 1 320px; min-width: 260px; }
.bhtm-name-row { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.bhtm-name { margin: 0; font: 700 42px/1 var(--font-display); text-transform: uppercase; color: #f2f7ff; word-break: break-word; }
.bhtm-tag { display: grid; place-items: center; height: 24px; padding: 0 10px; border-radius: var(--radius); background: #203255; font: 600 11px/1 var(--font-mono); letter-spacing: .1em; color: #8db0e8; }
.bhtm-meta { font: 500 10.5px/1.5 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: #789cda; }
.bhtm-desc { margin: 0; max-width: 68ch; font: 400 12.5px/1.6 var(--font-alt); color: #bcd3fa; }
.bhtm-hero-actions { display: flex; gap: 8px; flex: none; }

.bhtm-tabs { position: relative; display: flex; gap: 0; margin: 24px 40px 0; flex-wrap: wrap; }
.bhtm-tab { display: inline-flex; align-items: center; gap: 7px; padding: 0 14px 13px; border: 0; background: none; cursor: pointer; font: 500 12.5px/1 var(--font-alt); color: #8db0e8; }
.bhtm-tab:hover { color: #f2f7ff; }
.bhtm-tab--active { font-weight: 600; color: #f2f7ff; box-shadow: inset 0 -2px 0 var(--accent-warm); }
.bhtm-tab-n { font: 500 10.5px/1 var(--font-mono); color: #789cda; }

.bhtm-body { padding: 22px 40px 40px; display: flex; flex-direction: column; gap: 16px; }

/* Bandeau de sanctions : rouge teinte, reserve a qui a le droit de voir les sanctions. */
.bhtm-alert { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-radius: var(--radius); border: 1px solid var(--tint-red-border); background: linear-gradient(90deg, var(--tint-red-bg), var(--bg-surface)); flex-wrap: wrap; }
.bhtm-alert-tag { display: grid; place-items: center; height: 20px; padding: 0 8px; border-radius: var(--radius); background: var(--tint-red-bg-2); font: 600 9px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--red-soft-fg); flex: none; }
.bhtm-alert-txt { font: 400 11.5px/1.5 var(--font-alt); color: var(--red-soft-fg); }

/* 🔴 PAS d'`overflow: hidden` ici. Il servait à faire suivre les coins arrondis par les enfants,
   mais il découpait AUSSI la fiche joueur au survol (.phc-pop, 348px de haut, posée en absolu sous
   la ligne) : la carte s'ouvrait à moitié masquée, coupée net au bas du panneau. Un conteneur qui
   rogne ne distingue pas ce qu'il protège de ce qu'il ampute.
   Les coins sont désormais portés par les deux seuls enfants qui les touchent — l'en-tête en haut,
   la dernière ligne en bas — et le panneau ne rogne plus rien. */
.bhtm-panel { border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.bhtm-panel--pad { padding: 20px 22px; }
.bhtm-panel--inset { background: var(--bg-inset); }
/* 11px et non 12 : le panneau porte 1px de bordure, l'enfant s'inscrit donc dans un rayon réduit
   d'autant. À 12px, l'angle du fond dépasserait la courbe d'un cheveu, visible sur fond sombre. */
.bhtm-panel-head { display: flex; align-items: center; gap: 12px; padding: 14px 22px; border-bottom: 1px solid var(--border); background: var(--bg-inset); flex-wrap: wrap; border-radius: var(--radius-inner) var(--radius-inner) 0 0; }
.bhtm-kicker { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhtm-pill-out { display: grid; place-items: center; height: 20px; padding: 0 8px; border-radius: var(--radius); border: 1px solid var(--border); font: 500 9px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.bhtm-spacer { flex: 1; }
.bhtm-note { margin: 10px 0 0; font: 400 10.5px/1.6 var(--font-alt); color: var(--text-muted); }
.bhtm-panel-head .bhtm-note { margin: 0; }
.bhtm-cta { height: 32px; padding: 0 14px; border: 0; border-radius: var(--radius); background: var(--bg-chip); font: 600 11.5px/1 var(--font-alt); color: var(--accent-light); cursor: pointer; flex: none; }
.bhtm-cta:hover { background: var(--accent-subtle); }

/* Effectif : une grille commune a l'en-tete et aux lignes, pour que les colonnes s'alignent. */
.bhtm-rowhead, .bhtm-row { display: grid; grid-template-columns: minmax(160px, 1fr) 116px 148px 84px 84px minmax(190px, auto); gap: 14px; align-items: center; padding: 11px 22px; }
.bhtm-rowhead { border-bottom: 1px solid var(--border); }
.bhtm-rowhead span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhtm-row { padding: 12px 22px; border-bottom: 1px solid var(--line-soft); }
/* Le rayon du bas suit la même raison que celui de l'en-tête : la dernière ligne peut porter un fond
   (celle du capitaine en a un), qui carrerait les coins du panneau maintenant qu'il ne rogne plus. */
.bhtm-row:last-child { border-bottom: 0; border-radius: 0 0 var(--radius-inner) var(--radius-inner); }
.bhtm-row--captain { background: linear-gradient(90deg, var(--tint-gold-bg), transparent); }
.bhtm-row--pending { opacity: .74; }
.bhtm-end { justify-self: end; text-align: right; }

.bhtm-member { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bhtm-avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--bg-hover); display: grid; place-items: center; font: 700 12px/1 var(--font-display); color: var(--text-soft); flex: none; text-decoration: none; }
.bhtm-row--captain .bhtm-avatar { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.bhtm-member-name { font: 500 13px/1.2 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhtm-member-name:hover { color: var(--accent-light); }

.bhtm-role { justify-self: start; font: 400 11.5px/1 var(--font-alt); color: var(--text-soft); }
.bhtm-role--captain { display: inline-grid; place-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); background: var(--tint-gold-bg-2); font: 600 9.5px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--gold-on-tint); }
.bhtm-role--invited { display: inline-grid; place-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); border: 1px dashed var(--line-strong); font: 600 9.5px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }

.bhtm-rank { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bhtm-rank img { width: 22px; height: 22px; display: block; flex: none; }
.bhtm-rank-l { font: 500 12px/1.2 var(--font-alt); color: var(--text-secondary); }
.bhtm-rank-l--none { color: var(--text-muted); }
.bhtm-num { font: 400 12px/1 var(--font-mono); color: var(--text-secondary); }

.bhtm-actions { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.bhtm-avail { display: grid; place-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); font: 600 9.5px/1 var(--font-mono); letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }
.bhtm-avail--ok { background: var(--tint-green-bg); color: var(--lime-fg); }
.bhtm-avail--ko { background: var(--tint-red-bg); color: var(--red-soft-fg); }

.bhtm-sep { display: flex; align-items: center; gap: 12px; padding: 11px 22px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); }
.bhtm-sep-line { flex: 1; height: 1px; background: var(--line-soft); }

/* Digest sous l'effectif : palmares a gauche, compteurs et perimetre a droite. */
.bhtm-split { display: grid; grid-template-columns: 1fr 392px; gap: 14px; align-items: start; }
.bhtm-side { display: flex; flex-direction: column; gap: 14px; }
.bhtm-sec-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.bhtm-link { border: 0; background: none; padding: 0; cursor: pointer; font: 500 10.5px/1 var(--font-alt); color: var(--accent); }
.bhtm-link:hover { color: var(--accent-light); }

.bhtm-hon-head, .bhtm-hon-row { display: grid; grid-template-columns: 1fr 92px 64px; gap: 12px; align-items: center; }
.bhtm-hon-head { padding: 0 2px 9px; border-bottom: 1px solid var(--border); }
.bhtm-hon-head span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhtm-hon-row { padding: 11px 2px; border-bottom: 1px solid var(--line-soft); }
.bhtm-hon-row:last-child { border-bottom: 0; }
.bhtm-hon-name { font: 500 12px/1.3 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhtm-hon-name:hover { color: var(--accent-light); }
.bhtm-place { display: inline-grid; place-items: center; min-width: 26px; height: 22px; padding: 0 7px; border-radius: var(--radius); font: 700 12px/1 var(--font-mono); color: var(--text-secondary); }
.bhtm-place--1 { background: var(--tint-gold-bg-2); color: var(--gold-on-tint); }
.bhtm-place--2 { background: var(--bg-hover); color: var(--text-primary); }
.bhtm-place--3 { background: var(--tint-orange-bg); color: var(--gold-fg); }

.bhtm-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 14px; }
.bhtm-kpi { display: flex; flex-direction: column; gap: 5px; }
.bhtm-kpi-v { font: 700 24px/1 var(--font-mono); color: var(--text-primary); }
.bhtm-kpi-v--gold { color: var(--gold-fg); }
.bhtm-kpi-l { font: 400 10.5px/1.3 var(--font-alt); color: var(--text-muted); }
.bhtm-foot { display: block; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }
.bhtm-public { margin: 0; font: 400 11px/1.6 var(--font-alt); color: var(--text-muted); max-width: 80ch; }

@media (max-width: 1000px) {
    .bhtm-split { grid-template-columns: 1fr; }
    .bhtm-rowhead { display: none; }
    .bhtm-row { grid-template-columns: 1fr 1fr; row-gap: 8px; }
    .bhtm-row .bhtm-member { grid-column: 1 / -1; }
    .bhtm-end { justify-self: start; text-align: left; }
    .bhtm-actions { justify-content: flex-start; }
}

@media (max-width: 720px) {
    .bhtm-hero-in, .bhtm-body { padding-left: 22px; padding-right: 22px; }
    .bhtm-tabs { margin-left: 22px; margin-right: 22px; }
    .bhtm-name { font-size: 32px; }
}

/* ─── Organisation, vue d'ensemble (écran 8b) ────────────────────────────────
   Namespace .bhog-. Écran opérationnel : entièrement tokenisé, donc thémé. Les valeurs sombres
   des tokens étant celles de la maquette, le rendu sombre est la maquette. */
.bhog { display: flex; flex-direction: column; gap: 16px; }

.bhog-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.bhog-kpi { padding: 18px 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; gap: 8px; }
.bhog-kicker { font: 500 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhog-kicker--accent { color: var(--accent-light); }
.bhog-kpi-v { font: 700 30px/1 var(--font-mono); color: var(--text-primary); }
.bhog-kpi-v--green { color: var(--lime-fg); }
.bhog-kpi-sub { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-muted); }

.bhog-split { display: grid; grid-template-columns: 1fr 392px; gap: 16px; align-items: start; }
.bhog-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.bhog-panel { padding: 20px 22px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
.bhog-sec-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.bhog-link { border: 0; background: none; padding: 0; cursor: pointer; font: 500 10.5px/1 var(--font-alt); color: var(--accent); text-decoration: none; }
.bhog-link:hover { color: var(--accent-light); }
.bhog-note { margin: 0; font: 400 10.5px/1.6 var(--font-alt); color: var(--text-muted); }

/* Prochain tournoi : la seule carte accentuée de l'écran, pour qu'elle se voie sans lire. */
.bhog-next { padding: 20px 22px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(160deg, var(--accent-subtle), var(--bg-surface)); }
.bhog-next-in { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.bhog-next-id { flex: 1 1 240px; min-width: 0; }
.bhog-next-name { margin: 0 0 8px; font: 700 26px/1 var(--font-display); text-transform: uppercase; color: var(--text-primary); }
.bhog-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.bhog-tag { display: grid; place-items: center; height: 22px; padding: 0 9px; border-radius: var(--radius); background: var(--bg-hover); font: 500 10px/1 var(--font-mono); text-transform: uppercase; color: var(--text-secondary); }
.bhog-next-sep { width: 1px; height: 56px; background: var(--border); flex: none; }
.bhog-gauge { display: flex; flex-direction: column; gap: 6px; flex: none; width: 148px; }
.bhog-gauge-v { font: 700 22px/1 var(--font-mono); color: var(--text-primary); }
.bhog-gauge-track { height: 5px; border-radius: var(--radius); background: var(--bg-hover); overflow: hidden; display: block; }
.bhog-gauge-fill { display: block; height: 100%; background: var(--accent-grad); }
.bhog-gauge-l { font: 400 10px/1.3 var(--font-alt); color: var(--text-soft); }

/* Ce qui demande une décision : trois niveaux d'urgence, même gabarit. */
.bhog-todo { display: flex; align-items: center; gap: 14px; padding: 13px 16px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-inset); flex-wrap: wrap; }
.bhog-todo + .bhog-todo { margin-top: 10px; }
.bhog-todo-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted); flex: none; }
.bhog-todo-txt { flex: 1; font: 400 11.5px/1.5 var(--font-alt); color: var(--text-secondary); min-width: 200px; }
.bhog-todo-act { border: 0; background: none; padding: 0; cursor: pointer; font: 600 11px/1 var(--font-alt); color: var(--accent); flex: none; }
.bhog-todo--hot { border-color: var(--tint-red-border); background: var(--tint-red-bg); }
.bhog-todo--hot .bhog-todo-dot { background: var(--red-fg); }
.bhog-todo--hot .bhog-todo-act { color: var(--red-soft-fg); }
.bhog-todo--warn { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); }
.bhog-todo--warn .bhog-todo-dot { background: var(--gold-fg); }
.bhog-todo--warn .bhog-todo-act { color: var(--gold-fg); }

.bhog-thead, .bhog-trow { display: grid; grid-template-columns: minmax(140px, 1fr) 104px 96px 116px; gap: 12px; align-items: center; }
.bhog-thead { padding: 0 2px 9px; border-bottom: 1px solid var(--border); }
.bhog-thead span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhog-trow { padding: 11px 2px; border-bottom: 1px solid var(--line-soft); }
.bhog-trow:last-child { border-bottom: 0; }
.bhog-tname { font: 500 12px/1.3 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhog-tname:hover { color: var(--accent-light); }
.bhog-num { font: 400 11px/1 var(--font-mono); color: var(--text-soft); }
.bhog-end { justify-self: end; text-align: right; }

.bhog-disc-h { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.bhog-disc-mark { width: 28px; height: 28px; border-radius: var(--radius); background: #3b4a8f; display: grid; place-items: center; color: #c3cbf7; font-size: 16px; flex: none; }
.bhog-disc-t { flex: 1; font: 600 13px/1 var(--font-alt); color: var(--text-primary); }
.bhog-badge { display: grid; place-items: center; height: 20px; padding: 0 8px; border-radius: var(--radius); border: 1px solid var(--border); font: 600 9.5px/1 var(--font-mono); text-transform: uppercase; color: var(--text-muted); flex: none; }
.bhog-badge--ok { border-color: transparent; background: var(--tint-green-bg); color: var(--lime-fg); }
.bhog-badge--admin { border-color: transparent; background: var(--bg-chip); color: var(--accent-light); }

.bhog-rows { display: flex; flex-direction: column; gap: 9px; }
.bhog-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.bhog-row-l { font: 400 11.5px/1.4 var(--font-alt); color: var(--text-soft); }
.bhog-row-v { font: 500 11.5px/1.4 var(--font-mono); color: var(--text-primary); text-align: right; overflow-wrap: anywhere; }
.bhog-row-v--gold { color: var(--gold-fg); }
.bhog-foot { display: block; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }

.bhog-staff { display: flex; flex-direction: column; gap: 11px; }
.bhog-staff-row { display: flex; align-items: center; gap: 11px; }
.bhog-staff-av { width: 28px; height: 28px; border-radius: 50%; background: var(--bg-chip); display: grid; place-items: center; font: 600 11px/1 var(--font-alt); color: var(--accent-light); flex: none; text-decoration: none; }
/* L'avatar remplit la pastille : sans dimension propre, l'image garde sa taille naturelle et
   déborde de la grille du conteneur, qui ne la contraint pas. */
.bhog-staff-img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.bhog-staff-n { flex: 1; font: 500 12.5px/1 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhog-staff-n:hover { color: var(--accent-light); }
.bhog-staff-row--more .bhog-staff-av { background: var(--bg-hover); color: var(--text-soft); }
.bhog-staff-row--more .bhog-staff-n { font-weight: 400; color: var(--text-muted); }

/* ─── Membres & bannissements d'une organisation (écran 8c) ──────────────────
   Même namespace .bhog- que la vue d'ensemble : c'est le même écran, vu par ses onglets. */
/* 🔴 Pas d'`overflow: hidden` ici — même défaut que celui corrigé sur .bhtm-panel, et même remède.
   Le panneau hébergeait la fiche joueur au survol (.phc-pop, posée en absolu, large de 352px et
   haute de plusieurs centaines de pixels) : il la tranchait net. Mesuré sur la fiche d'organisation,
   165px de contenu amputés à 360px de fenêtre. Un conteneur qui rogne ne distingue pas ce qu'il
   protège de ce qu'il ampute.
   Les coins arrondis passent donc aux enfants de bord, comme pour .bhtm-panel-head : 11px et non 12,
   le panneau portant 1px de bordure — à 12 l'angle du fond dépasserait la courbe d'un cheveu. */
.bhog-panel--flush { padding: 0; }
.bhog-panel--flush > :first-child { border-radius: var(--radius-inner) var(--radius-inner) 0 0; }
.bhog-panel--flush > :last-child { border-radius: 0 0 var(--radius-inner) var(--radius-inner); }
.bhog-panel--danger { border-color: var(--tint-red-border); background: linear-gradient(160deg, var(--tint-red-bg), var(--bg-surface)); }

.bhog-tbar { display: flex; align-items: center; gap: 12px; padding: 14px 22px; border-bottom: 1px solid var(--border); background: var(--bg-inset); flex-wrap: wrap; }
.bhog-tbar-search { min-width: 220px; flex: 0 1 280px; position: relative; }
.bhog-tbar-search .org-member-search { width: 100%; }
.bhog-tfoot { display: flex; align-items: center; gap: 12px; padding: 12px 22px; border-top: 1px solid var(--border); background: var(--bg-inset); flex-wrap: wrap; }
/* Formulaire de sanction : trois champs sur une ligne. `.org-member-search` fait 100 % de large
   pour ses autres emplois — sans cette reprise, chacun prend toute la ligne et le pied de tableau
   se déplie sur trois rangs. */
.bhog-banform { gap: 10px; }
.bhog-banform .org-member-search { width: auto; flex: 1 1 190px; min-width: 0; }
.bhog-banform .ban-select { flex: none; }

/* La colonne « membre » est bornée : à 1fr elle absorbait toute la largeur du panneau et
   repoussait le rôle au milieu de nulle part. */
.bhog-mhead, .bhog-mrow { display: grid; grid-template-columns: minmax(220px, 480px) 180px 1fr; gap: 14px; align-items: center; padding: 11px 22px; }
.bhog-mhead { border-bottom: 1px solid var(--border); }
.bhog-mhead span, .bhog-bhead span { font: 500 9px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhog-mrow { padding: 12px 22px; border-bottom: 1px solid var(--line-soft); }
.bhog-mrow:last-child { border-bottom: 0; }

.bhog-member { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bhog-mav { width: 30px; height: 30px; border-radius: 50%; background: var(--bg-chip); display: grid; place-items: center; font: 700 12px/1 var(--font-display); color: var(--accent-light); flex: none; object-fit: cover; }
.bhog-mident { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bhog-mname { font: 600 13px/1.2 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhog-mname:hover { color: var(--accent-light); }
.bhog-msub { font: 400 10px/1.2 var(--font-mono); color: var(--text-muted); }
.bhog-mrole { justify-self: start; }
.bhog-mact { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.bhog-act { border: 0; background: none; padding: 0; cursor: pointer; font: 500 11px/1 var(--font-alt); color: var(--text-soft); }
.bhog-act:hover { color: var(--text-primary); }
.bhog-act--go { color: var(--accent); }
.bhog-act--go:hover { color: var(--accent-light); }
.bhog-act--ko { color: var(--red-soft-fg); }

.bhog-ban-h { display: flex; align-items: center; gap: 14px; padding: 16px 22px; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.bhog-ban-t { font: 700 19px/1 var(--font-display); text-transform: uppercase; letter-spacing: .04em; color: var(--text-primary); }
.bhog-ban-note { font: 400 11px/1.5 var(--font-alt); color: var(--red-soft-fg); max-width: 46ch; }
.bhog-badge--ko { border-color: transparent; background: var(--tint-red-bg-2); color: var(--red-soft-fg); }

.bhog-bhead, .bhog-brow { display: grid; grid-template-columns: minmax(160px, 1fr) 130px minmax(200px, 1.2fr) 112px 108px; gap: 14px; align-items: center; padding: 11px 22px; }
.bhog-bhead { border-bottom: 1px solid var(--border); }
.bhog-brow { padding: 12px 22px; border-bottom: 1px solid var(--line-soft); }
.bhog-brow:last-of-type { border-bottom: 0; }
.bhog-breason { font: 400 11.5px/1.45 var(--font-alt); color: var(--text-secondary); min-width: 0; }
.bhog-appeal { display: block; margin-top: 5px; font: 500 10.5px/1.4 var(--font-alt); color: var(--gold-fg); }

.bhog-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.bhog-card { padding: 16px 20px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-inset); }
.bhog-card--warn { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); }
.bhog-kicker--gold { color: var(--gold-on-tint); }

/* ── Paramètres généraux d'organisation (écran 3f) ────────────────────────────
   Variantes ÉDITABLES de la grammaire .bhog-. Les panneaux de 8b/8c affichent
   des valeurs, celui-ci en saisit : il lui faut des champs, pas des lignes.
   Tout est tokenisé, donc le thème clair suit sans rien de plus. */
.bhog-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.bhog-fields--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Le barème compte QUATRE valeurs qui se lisent ensemble (deux seuils, deux montants) : sur une
   grille de trois, la dernière tombait seule à la ligne et se lisait comme un réglage à part. */
.bhog-fields--quad { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.bhog-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.bhog-flabel { font: 400 11.5px/1.4 var(--font-alt); color: var(--text-soft); }
.bhog-fbox { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bhog-finput {
    flex: 1;
    min-width: 0;
    height: 38px;
    padding: 0 11px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    color: var(--text-primary);
    font: 700 18px/1 var(--font-mono);
}
.bhog-finput:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Les bornes d'un palier sont courtes : leur laisser toute la largeur ferait
   trois champs géants pour trois nombres à deux chiffres. */
.bhog-finput--rank { flex: none; width: 74px; font-size: 15px; }
.bhog-funit { font: 400 10.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }

.bhog-ftext {
    width: 100%;
    min-height: 132px;
    padding: 12px 14px;
    resize: vertical;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    color: var(--text-primary);
    font: 400 12.5px/1.7 var(--font-alt);
}
.bhog-ftext:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bhog-count { font: 500 10.5px/1 var(--font-mono); color: var(--text-muted); }
/* Le compteur ne se remarque qu'au moment où il compte : la limite approche. */
.bhog-count--near { color: var(--gold-on-tint); }

.bhog-mults { display: flex; flex-direction: column; gap: 8px; }
.bhog-mult { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bhog-mult-sep, .bhog-mult-x { font: 400 12px/1 var(--font-mono); color: var(--text-muted); }
.bhog-mult-del {
    margin-left: auto;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}
.bhog-mult-del:hover { border-color: var(--tint-red-border); color: var(--color-danger); }

.bhog-save { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }

@media (max-width: 1000px) {
    .bhog-split { grid-template-columns: 1fr; }
    .bhog-fields, .bhog-fields--pair, .bhog-fields--quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .bhog-kpis { grid-template-columns: repeat(2, 1fr); }
    .bhog-next-sep { display: none; }
    .bhog-thead, .bhog-mhead, .bhog-bhead { display: none; }
    .bhog-trow { grid-template-columns: 1fr 1fr; row-gap: 6px; }
    .bhog-trow .bhog-tname { grid-column: 1 / -1; }
    .bhog-mrow, .bhog-brow { grid-template-columns: 1fr 1fr; row-gap: 8px; }
    .bhog-mrow .bhog-member, .bhog-brow .bhog-member, .bhog-breason { grid-column: 1 / -1; }
    .bhog-cards { grid-template-columns: 1fr; }
    .bhog-end { justify-self: start; text-align: left; }
    .bhog-mact { justify-content: flex-start; }
}

/* ─── Console d'administration : grammaire commune aux écrans 9a/9b/10a/10b/10c ──────────────
   La maquette le dit explicitement : « les trois écrans réutilisent la grammaire de 9a ». Titre de
   section, recherche chiffrée, pastilles de facette, tableau dense, pagination — c'est le même
   vocabulaire partout, écrit une fois ici. Chaque écran n'ajoute ensuite que ses colonnes.
   Namespace `bhcons-` : jamais de préfixe « ad », cf. AdBlockerSafeClassNamesTests.
   Entièrement tokenisé : les hex de la maquette SONT les valeurs du thème sombre, donc le sombre
   rend la maquette et le clair reste juste. */
.bhcons-head { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; margin-bottom: 16px; }
.bhcons-head-txt { flex: 1 1 320px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhcons-h1 { margin: 0; font: 700 34px/1 var(--font-display); text-transform: uppercase; letter-spacing: .03em; color: var(--text-primary); }
.bhcons-sub { font: 400 12.5px/1.4 var(--font-alt); color: var(--text-soft); }
.bhcons-head-act { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }

.bhcons-btn { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px; border: 1px solid var(--border); border-radius: var(--radius); background: none; font: 500 12px/1 var(--font-alt); color: var(--text-secondary); cursor: pointer; text-decoration: none; }
.bhcons-btn:hover:not(:disabled) { border-color: var(--border-hover); color: var(--text-primary); }
.bhcons-btn:disabled { opacity: .45; cursor: default; }
.bhcons-btn--primary { border-color: transparent; background: var(--accent-hover); color: #fff; font-weight: 600; padding: 0 15px; }
.bhcons-btn--primary:hover:not(:disabled) { background: var(--accent); color: var(--on-accent); }
.bhcons-btn--ko { border-color: var(--tint-red-border); color: var(--red-soft-fg); }
.bhcons-btn--ko:hover:not(:disabled) { border-color: var(--red-fg); color: var(--red-fg); }
/* Rappel chiffré vers un autre écran (« 2 demandes en attente ») : un lien, pas un bouton. */
.bhcons-btn--note { border-color: var(--border-input); color: var(--accent-light); }

/* Recherche : le compte de résultats vit DANS le champ, comme sur la maquette — c'est ce qui en
   fait un filtre chiffré et non un bouton isolé. */
.bhcons-searchbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.bhcons-search { flex: 1 1 320px; display: flex; align-items: center; gap: 10px; height: 38px; padding: 0 14px; border: 1px solid var(--border-input); border-radius: var(--radius); background: var(--bg-input); min-width: 0; }
.bhcons-search i { color: var(--text-muted); font-size: 14px; flex: none; }
.bhcons-search input { flex: 1; min-width: 0; border: 0; background: none; outline: none; font: 400 13px/1 var(--font-alt); color: var(--text-primary); }
.bhcons-search input::placeholder { color: var(--text-muted); }
.bhcons-search-n { flex: none; font: 500 10px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.bhcons-sort { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 13px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-input); font: 500 11.5px/1 var(--font-alt); color: var(--text-secondary); }
.bhcons-sort select { border: 0; background: none; outline: none; font: inherit; color: inherit; cursor: pointer; }

/* Pastilles de facette. Le chiffre est TOUJOURS là : une facette sans son compte ne dit pas s'il
   vaut la peine de cliquer. */
.bhcons-chips { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 14px; }
.bhcons-chip { display: inline-flex; align-items: baseline; gap: 7px; height: 30px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius); background: none; font: 500 11.5px/28px var(--font-alt); color: var(--text-secondary); cursor: pointer; }
.bhcons-chip:hover { border-color: var(--border-hover); color: var(--text-primary); }
.bhcons-chip-n { font: 500 10px/1 var(--font-mono); color: var(--text-muted); }
.bhcons-chip--active { border-color: var(--border-input); background: var(--accent-subtle); color: var(--text-primary); font-weight: 600; }
.bhcons-chip--active .bhcons-chip-n { color: var(--accent-light); }
.bhcons-chip--alert { border-color: var(--tint-red-border); background: var(--tint-red-bg-2); color: var(--red-soft-fg); }
.bhcons-chip--alert .bhcons-chip-n { color: var(--red-soft-fg); font-weight: 600; }
.bhcons-chip-sep { width: 1px; height: 18px; background: var(--border); margin: 0 4px; }

/* Barre de sélection multiple : n'apparaît qu'avec une sélection, et porte les actions de masse. */
.bhcons-bulk { display: flex; align-items: center; gap: 14px; min-height: 44px; padding: 6px 14px; border-radius: var(--radius); border: 1px solid var(--border-input); background: linear-gradient(90deg, var(--accent-subtle), transparent); margin-bottom: 14px; flex-wrap: wrap; }
.bhcons-bulk-n { font: 600 12px/1 var(--font-alt); color: var(--text-primary); }
.bhcons-bulk-sep { width: 1px; height: 18px; background: var(--border-input); }
.bhcons-bulk-act { border: 0; background: none; padding: 0; cursor: pointer; font: 500 11.5px/1 var(--font-alt); color: var(--accent-light); }
.bhcons-bulk-act:hover:not(:disabled) { color: var(--text-primary); }
.bhcons-bulk-act:disabled { opacity: .5; cursor: default; }
.bhcons-bulk-act--ko { color: var(--red-soft-fg); }
.bhcons-bulk-sp { flex: 1; }

/* Tableau. Une ligne = un état complet, d'où la densité : 12px de padding vertical, pas 20. */
.bhcons-table { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow: hidden; }
.bhcons-thead { border-bottom: 1px solid var(--border); background: var(--bg-inset); }
.bhcons-thead span { font: 500 9px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhcons-thead .bhcons-sorted { color: var(--accent-light); }
.bhcons-row { border-bottom: 1px solid var(--line-soft); }
.bhcons-row:last-child { border-bottom: 0; }
.bhcons-row:hover { background: var(--bg-hover); }
/* Liseré de gauche : l'état de la ligne se lit avant même de la parcourir. */
.bhcons-row--picked { background: var(--accent-subtle); box-shadow: inset 2px 0 0 var(--accent-hover); }
.bhcons-row--alert { background: var(--tint-red-bg-2); box-shadow: inset 2px 0 0 var(--red-fg); }
.bhcons-row--muted { opacity: .68; }

.bhcons-check { width: 15px; height: 15px; border: 1.5px solid var(--line-strong); border-radius: var(--radius); background: none; display: grid; place-items: center; cursor: pointer; padding: 0; color: transparent; }
.bhcons-check:hover { border-color: var(--border-hover); }
.bhcons-check--on { border-color: transparent; background: var(--accent-hover); color: #fff; font: 700 10px/1 var(--font-alt); }

/* Identité : avatar + nom + ligne technique. Le min-width:0 est indispensable — sans lui l'adresse
   pousse la grille et la colonne d'action sort de l'écran. */
.bhcons-ident { display: flex; align-items: center; gap: 11px; min-width: 0; }
.bhcons-av { width: 32px; height: 32px; flex: none; border-radius: 50%; background: var(--tint-blue-bg); border: 1px solid var(--border); display: grid; place-items: center; font: 600 12px/1 var(--font-alt); color: var(--accent-light); object-fit: cover; }
.bhcons-av--gold { background: var(--tint-gold-bg); border-color: var(--tint-gold-border); color: var(--gold-on-tint); }
.bhcons-av--ko { background: var(--tint-red-bg); border-color: var(--tint-red-border); color: var(--red-soft-fg); }
.bhcons-av--sq { border-radius: var(--radius); font-family: var(--font-display); font-weight: 700; letter-spacing: .04em; }
.bhcons-idtxt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* Le nom est tantôt un lien (organisations, sanctions), tantôt un bouton qui ouvre le tiroir
   (comptes). Sans la remise à zéro du bouton, le nom s'affiche dans une plaque grise : le style par
   défaut du navigateur l'emporte, et rien dans le code ne le laisse deviner. */
.bhcons-name { display: flex; align-items: center; gap: 8px; border: 0; background: none; padding: 0; text-align: left; cursor: pointer; font: 600 13px/1.2 var(--font-alt); color: var(--text-primary); text-decoration: none; min-width: 0; }
.bhcons-name:hover { color: var(--accent-light); }
.bhcons-mail { font: 400 11px/1.2 var(--font-mono); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhcons-tag { flex: none; font: 500 9px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; padding: 3px 5px; border-radius: var(--radius); background: var(--bg-hover); color: var(--text-soft); }
.bhcons-tag--me { background: var(--tint-gold-bg); color: var(--gold-on-tint); }
.bhcons-tag--info { background: var(--bg-chip); color: var(--accent-light); }

/* Statut : pastille de couleur + libellé, avec une note facultative en dessous. */
.bhcons-state { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhcons-state-l { display: flex; align-items: center; gap: 7px; font: 400 11.5px/1.3 var(--font-alt); color: var(--text-secondary); }
.bhcons-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--text-muted); }
.bhcons-dot--ok { background: var(--green-fg); }
.bhcons-dot--warn { background: var(--gold-fg); }
.bhcons-dot--ko { background: var(--red-fg); }
.bhcons-state--warn .bhcons-state-l { color: var(--text-primary); }
.bhcons-state--ko .bhcons-state-l { color: var(--red-soft-fg); font-weight: 500; }
.bhcons-note { font: 400 10px/1.3 var(--font-alt); color: var(--text-muted); padding-left: 13px; }
a.bhcons-note:hover { color: var(--text-secondary); }

/* Étiquette compacte (portée d'une sanction, accès bot) */
.bhcons-pill { display: inline-flex; align-items: center; gap: 6px; justify-self: start; height: 24px; padding: 0 9px; border-radius: var(--radius); border: 1px solid var(--border); font: 600 10px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--text-soft); }
.bhcons-pill--on { border-color: var(--border-input); background: var(--accent-subtle); color: var(--accent-light); }
.bhcons-pill--ko { border-color: var(--tint-red-border); background: var(--tint-red-bg-2); color: var(--red-soft-fg); }
.bhcons-pill--warn { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); color: var(--gold-on-tint); }
.bhcons-pill--off { color: var(--text-muted); }

/* Sélecteur de rôle posé sur la ligne : le « Changer le rôle » répété de l'ancienne liste. */
.bhcons-inline-select { justify-self: start; height: 26px; padding: 0 8px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-hover); font: 500 11.5px/1 var(--font-alt); color: var(--text-secondary); cursor: pointer; max-width: 100%; }
.bhcons-inline-select:hover:not(:disabled) { border-color: var(--border-hover); color: var(--text-primary); }
.bhcons-inline-select:disabled { cursor: default; }
/* Le SuperAdmin ne se change pas depuis la ligne : c'est le tiroir, avec son motif, qui en décide. */
.bhcons-role-locked { display: inline-flex; align-items: center; justify-self: start; height: 26px; padding: 0 10px; border-radius: var(--radius); border: 1px solid var(--tint-gold-border); background: var(--tint-gold-bg); font: 600 11.5px/1 var(--font-alt); color: var(--gold-on-tint); }

/* Teintes de rôle (Bogue #997). La couleur décrit le RÔLE, pas le droit de le changer : elle vaut
   donc pour la pastille en lecture comme pour le sélecteur, sinon le SuperAdmin — celui qui a le
   plus besoin de repérer un compte élevé — serait le seul à ne pas l'avoir.
   ⚠️ Elle ne porte AUCUNE information à elle seule : la pastille dit le rôle en toutes lettres
   (WCAG 1.4.1). C'est un renfort, pas un code.
   Le SuperAdmin n'a pas de modificateur : il garde le doré de .bhcons-role-locked. Les trois autres
   évitent le rouge et le vert, déjà pris par la colonne « Statut du compte » juste à côté.
   Le participant reste NEUTRE à dessein : il pèse 186 lignes sur 212 : le teinter noierait
   précisément le signal qu'on cherche à donner. */
.bhcons-role--admin { border-color: var(--tint-orange-border); background: var(--tint-orange-bg); color: var(--orange-on-tint); font-weight: 600; }
.bhcons-role--organizer { border-color: var(--tint-blue-border); background: var(--tint-blue-bg); color: var(--indigo-fg); font-weight: 600; }
.bhcons-role--participant { border-color: var(--border); background: var(--bg-hover); color: var(--text-secondary); font-weight: 600; }

.bhcons-rank { display: flex; align-items: center; gap: 7px; min-width: 0; }
.bhcons-rank img { width: 19px; height: 19px; flex: none; display: block; }
.bhcons-rank span { font: 500 11px/1.2 var(--font-alt); color: var(--text-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Sur un compte banni le rang s'efface, mais seul l'EMBLÈME est atténué : la même opacité
   appliquée au libellé le faisait tomber sous 2,5 pour 1 en thème clair. */
.bhcons-rank--off img { opacity: .45; }
.bhcons-rank--off span { color: var(--text-muted); }

.bhcons-when { font: 400 11.5px/1.3 var(--font-alt); color: var(--text-soft); }
.bhcons-when--live { color: var(--green-fg); }
.bhcons-when--fresh { color: var(--text-primary); }
.bhcons-when--never { color: var(--text-muted); }

.bhcons-more { justify-self: center; border: 0; background: none; padding: 0; cursor: pointer; font: 600 15px/1 var(--font-alt); color: var(--text-muted); }
.bhcons-more:hover { color: var(--text-primary); }

.bhcons-foot { display: flex; align-items: center; gap: 14px; margin-top: 14px; flex-wrap: wrap; }
.bhcons-foot-info { font: 400 11.5px/1 var(--font-alt); color: var(--text-muted); }
.bhcons-foot-sp { flex: 1; }
.bhcons-empty { padding: 40px 20px; text-align: center; font: 400 13px/1.5 var(--font-alt); color: var(--text-muted); }

/* ─── Console des comptes — écrans 9a (liste) et 9b (tiroir) ──────────────────────────────── */
.bhusr-thead, .bhusr-row { display: grid; grid-template-columns: 32px minmax(220px, 1fr) 168px 176px 116px 118px 30px; gap: 12px; align-items: center; padding: 12px 16px; }
.bhusr-thead { padding: 11px 16px; }

/* Le tiroir. Position FIXE et non absolue : la console défile dans .bhcon-body, un tiroir absolu y
   serait rogné par le conteneur qui défile — même piège que les popovers de la top-nav. */
.bhusr-scrim { position: fixed; inset: 0; z-index: 60; background: var(--scrim); border: 0; padding: 0; cursor: pointer; }
.bhusr-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(498px, 100vw); z-index: 61; display: flex; flex-direction: column; overflow-y: auto; border-left: 1px solid var(--border); background: var(--bg-page); box-shadow: -18px 0 40px var(--shadow-strong); }
.bhusr-dhead { display: flex; align-items: flex-start; gap: 14px; padding: 20px 24px 18px; border-bottom: 1px solid var(--line-soft); }
.bhusr-dav { width: 52px; height: 52px; flex: none; border-radius: 50%; background: var(--tint-blue-bg); border: 1px solid var(--border); display: grid; place-items: center; font: 600 18px/1 var(--font-alt); color: var(--accent-light); object-fit: cover; }
.bhusr-dident { flex: 1; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhusr-dname { display: flex; align-items: center; gap: 9px; font: 700 22px/1.1 var(--font-display); text-transform: uppercase; letter-spacing: .03em; color: var(--text-primary); }
.bhusr-dname img { width: 18px; height: 18px; display: block; }
.bhusr-dmail { font: 400 11.5px/1.3 var(--font-mono); color: var(--text-soft); overflow-wrap: anywhere; }
.bhusr-dchips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bhusr-dchip { height: 21px; padding: 0 8px; border-radius: var(--radius); background: var(--bg-hover); font: 500 9.5px/21px var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-soft); }
.bhusr-dchip--ok { background: var(--tint-green-bg); color: var(--green-fg); }
.bhusr-dchip--ko { background: var(--tint-red-bg); color: var(--red-soft-fg); }
.bhusr-dclose { border: 0; background: none; padding: 0; cursor: pointer; font: 400 17px/1 var(--font-alt); color: var(--text-muted); }
.bhusr-dclose:hover { color: var(--text-primary); }

.bhusr-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 16px 24px; border-bottom: 1px solid var(--line-soft); }
.bhusr-fact { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhusr-fact-k { font: 500 8.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhusr-fact-v { font: 500 12px/1.3 var(--font-alt); color: var(--text-secondary); overflow-wrap: anywhere; }
a.bhusr-fact-v { color: var(--accent); text-decoration: none; }
a.bhusr-fact-v:hover { color: var(--accent-light); }

.bhusr-sec { display: flex; flex-direction: column; gap: 11px; padding: 18px 24px; border-bottom: 1px solid var(--line-soft); }
.bhusr-sec:last-child { border-bottom: 0; padding-bottom: 22px; }
.bhusr-sec-k { font: 600 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhusr-sec-k em { font-style: normal; color: var(--red-soft-fg); }

/* Choix de rôle : des cartes, pas une liste déroulante — chacune porte ce que le rôle autorise. */
.bhusr-roles { display: flex; flex-direction: column; gap: 8px; }
.bhusr-role { display: flex; align-items: flex-start; gap: 11px; padding: 11px 13px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); text-align: left; cursor: pointer; }
.bhusr-role:hover:not(:disabled) { border-color: var(--border-hover); }
.bhusr-role:disabled { cursor: default; opacity: .75; }
.bhusr-role--on { border-color: var(--border-input); background: linear-gradient(120deg, var(--accent-subtle), transparent); }
.bhusr-radio { width: 15px; height: 15px; flex: none; margin-top: 1px; border: 1.5px solid var(--line-strong); border-radius: 50%; }
.bhusr-role--on .bhusr-radio { border: 4.5px solid var(--accent-hover); background: var(--bg-page); }
.bhusr-role-txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhusr-role-n { font: 600 12.5px/1.2 var(--font-alt); color: var(--text-secondary); }
.bhusr-role--on .bhusr-role-n { color: var(--text-primary); }
.bhusr-role-d { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-muted); }
.bhusr-role--on .bhusr-role-d { color: var(--accent-light); }
.bhusr-role-flag { font: 500 9px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--accent-light); }
.bhusr-role-flag--gold { color: var(--gold-fg); }
.bhusr-reason { min-height: 58px; padding: 10px 12px; border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-input); font: 400 11.5px/1.5 var(--font-alt); color: var(--text-primary); resize: vertical; outline: none; }
.bhusr-reason::placeholder { color: var(--text-muted); }
.bhusr-apply { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bhusr-apply-note { flex: 1; min-width: 120px; text-align: right; font: 400 10.5px/1.4 var(--font-alt); color: var(--text-faint); }

.bhusr-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.bhusr-act { display: flex; align-items: center; gap: 7px; height: 32px; padding: 0 12px; border: 1px solid var(--border); border-radius: var(--radius); background: none; font: 500 11.5px/1 var(--font-alt); color: var(--text-secondary); cursor: pointer; text-align: left; }
.bhusr-act:hover:not(:disabled) { border-color: var(--border-hover); color: var(--text-primary); }
.bhusr-act:disabled { opacity: .45; cursor: default; }
.bhusr-act--ko { border-color: var(--tint-red-border); color: var(--red-soft-fg); }
.bhusr-act--on { background: var(--tint-red-bg-2); }

/* Prononcer une sanction plateforme depuis le tiroir : catégorie et durée côte à côte, motif sur
   toute la largeur. La durée est grisée quand « Définitif » est coché — le champ reste visible pour
   qu'on voie CE qu'on annule, au lieu de le faire disparaître. */
.bhusr-ban { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 13px; border: 1px solid var(--tint-red-border); border-radius: var(--radius); background: var(--tint-red-bg); }
.bhusr-ban-f { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhusr-ban-f select, .bhusr-ban-f input { height: 30px; padding: 0 9px; border: 1px solid var(--border-input); border-radius: var(--radius); background: var(--bg-input); font: 400 11.5px/1 var(--font-alt); color: var(--text-primary); outline: none; min-width: 0; }
.bhusr-ban-f input:disabled { opacity: .45; }
.bhusr-ban-perm { grid-column: 1 / -1; display: flex; align-items: center; gap: 7px; font: 500 11.5px/1 var(--font-alt); color: var(--text-secondary); cursor: pointer; }
.bhusr-ban-r { grid-column: 1 / -1; height: 32px; padding: 0 11px; border: 1px solid var(--border-input); border-radius: var(--radius); background: var(--bg-input); font: 400 11.5px/1 var(--font-alt); color: var(--text-primary); outline: none; }
.bhusr-ban-r::placeholder { color: var(--text-muted); }
.bhusr-ban .bhusr-apply { grid-column: 1 / -1; }

.bhusr-log { display: flex; flex-direction: column; gap: 10px; }
.bhusr-log-row { display: grid; grid-template-columns: 78px 1fr; gap: 11px; align-items: baseline; }
.bhusr-log-t { font: 400 10.5px/1.4 var(--font-mono); color: var(--text-faint); }
.bhusr-log-x { font: 400 11.5px/1.45 var(--font-alt); color: var(--text-secondary); overflow-wrap: anywhere; }
.bhusr-log-x b { font-weight: 600; color: var(--accent-light); }

/* ─── Annuaire des organisations — écran 10a ───────────────────────────────────────────────── */
.bhorgs-thead, .bhorgs-row { display: grid; grid-template-columns: minmax(240px, 1fr) 168px 88px 104px 150px 126px 30px; gap: 12px; align-items: center; padding: 13px 16px; }
.bhorgs-thead { padding: 11px 16px; }
.bhorgs-num { font: 500 12px/1 var(--font-mono); color: var(--text-secondary); }
.bhorgs-num--zero { color: var(--text-faint); }
.bhorgs-owner { font: 500 12px/1.3 var(--font-alt); color: var(--accent); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhorgs-owner:hover { color: var(--accent-light); }
.bhorgs-owner--none { color: var(--text-muted); }

/* ─── File des demandes — écran 10b ────────────────────────────────────────────────────────── */
/* Deux volets : la file à gauche, le dossier à droite. Le minmax(0,…) sur les deux colonnes est ce
   qui empêche le contenu du dossier de pousser la grille au-delà de la fenêtre. */
.bhreq-split { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr); gap: 18px; align-items: start; }
.bhreq-queue { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.bhreq-tabs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.bhreq-tab { display: inline-flex; align-items: baseline; gap: 6px; height: 27px; padding: 0 10px; border: 1px solid var(--border); border-radius: var(--radius); background: none; font: 500 11px/25px var(--font-alt); color: var(--text-secondary); cursor: pointer; }
.bhreq-tab:hover { border-color: var(--border-hover); color: var(--text-primary); }
.bhreq-tab--on { border-color: transparent; background: var(--bg-chip); color: var(--text-primary); font-weight: 600; }
.bhreq-tab-n { font: 500 9.5px/1 var(--font-mono); color: var(--text-muted); }
.bhreq-tab--on .bhreq-tab-n { color: var(--accent-light); }

.bhreq-list { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow: hidden; display: flex; flex-direction: column; }
.bhreq-item { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 14px 15px; border: 0; border-bottom: 1px solid var(--line-soft); background: none; text-align: left; cursor: pointer; }
.bhreq-item:last-child { border-bottom: 0; }
.bhreq-item:hover { background: var(--bg-hover); }
.bhreq-item--on { background: var(--accent-subtle); box-shadow: inset 2px 0 0 var(--accent-hover); }
/* L'âge de la demande en premier : la file se traite dans l'ordre d'arrivée, c'est l'information
   qui désigne la suivante. */
.bhreq-age { display: flex; flex-direction: column; align-items: center; gap: 5px; width: 38px; flex: none; }
.bhreq-age-n { font: 700 15px/1 var(--font-mono); color: var(--text-secondary); }
.bhreq-age-u { font: 500 8.5px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }
.bhreq-item--on .bhreq-age-n { color: var(--text-primary); }
.bhreq-age--hot .bhreq-age-u { color: var(--red-soft-fg); }
.bhreq-age--warm .bhreq-age-u { color: var(--gold-fg); }
.bhreq-body { flex: 1; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhreq-kind { font: 600 10px/1.2 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--accent-light); }
.bhreq-kind--rehab { color: var(--red-soft-fg); }
.bhreq-kind--react { color: var(--gold-fg); }
.bhreq-subject { font: 600 13px/1.2 var(--font-alt); color: var(--text-primary); overflow-wrap: anywhere; }
.bhreq-meta { font: 400 11px/1.35 var(--font-alt); color: var(--text-soft); overflow-wrap: anywhere; }
.bhreq-hint { font: 400 10.5px/1.5 var(--font-alt); color: var(--text-faint); }

.bhreq-panel { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow: hidden; display: flex; flex-direction: column; min-width: 0; }
.bhreq-phead { display: flex; align-items: flex-start; gap: 14px; padding: 20px 22px 16px; border-bottom: 1px solid var(--line-soft); }
.bhreq-plogo { width: 46px; height: 46px; flex: none; border-radius: var(--radius); background: var(--tint-blue-bg); border: 1px solid var(--border); display: grid; place-items: center; font: 700 13px/1 var(--font-display); letter-spacing: .04em; color: var(--accent-light); object-fit: cover; }
.bhreq-ptxt { flex: 1; display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.bhreq-pkind { font: 600 10px/1.3 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--accent-light); }
.bhreq-pname { font: 700 26px/1.1 var(--font-display); text-transform: uppercase; letter-spacing: .03em; color: var(--text-primary); overflow-wrap: anywhere; }
.bhreq-pslug { font: 400 11.5px/1.3 var(--font-mono); color: var(--text-muted); }

.bhreq-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 16px 22px; border-bottom: 1px solid var(--line-soft); }
.bhreq-fact { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhreq-fact-k { font: 500 8.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhreq-fact-v { font: 500 12.5px/1.3 var(--font-alt); color: var(--text-secondary); overflow-wrap: anywhere; }
a.bhreq-fact-v { color: var(--accent); text-decoration: none; }
a.bhreq-fact-v:hover { color: var(--accent-light); }
.bhreq-fact-s { font: 400 10.5px/1.3 var(--font-mono); color: var(--text-muted); overflow-wrap: anywhere; }
.bhreq-fact-s--ok { color: var(--green-fg); font-family: var(--font-alt); }
.bhreq-fact-s--ko { color: var(--red-soft-fg); font-family: var(--font-alt); }

.bhreq-sec { display: flex; flex-direction: column; gap: 10px; padding: 18px 22px; border-bottom: 1px solid var(--line-soft); }
.bhreq-sec:last-child { border-bottom: 0; }
.bhreq-sec-k { font: 600 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bhreq-sec-k em { font-style: normal; color: var(--red-soft-fg); }
.bhreq-quote { margin: 0; font: 400 12.5px/1.6 var(--font-alt); color: var(--text-secondary); text-wrap: pretty; overflow-wrap: anywhere; }

.bhreq-checks { display: flex; flex-direction: column; gap: 9px; }
.bhreq-check { display: flex; align-items: center; gap: 10px; }
.bhreq-check-l { flex: 1; font: 400 12px/1.4 var(--font-alt); color: var(--text-secondary); }
.bhreq-check--warn .bhreq-check-l, .bhreq-check--ko .bhreq-check-l { color: var(--text-primary); }
.bhreq-check-v { font: 500 10.5px/1.3 var(--font-mono); color: var(--text-muted); overflow-wrap: anywhere; text-align: right; }

.bhreq-decide { display: flex; align-items: center; gap: 9px; margin-top: 3px; flex-wrap: wrap; }
.bhreq-decide-sp { flex: 1; }
.bhreq-next { border: 0; background: none; padding: 0; cursor: pointer; font: 500 11px/1 var(--font-alt); color: var(--text-soft); }
.bhreq-next:hover:not(:disabled) { color: var(--text-primary); }
.bhreq-next:disabled { opacity: .45; cursor: default; }

/* ─── Bannissements — écran 10c (prolonge le namespace .bhmod- de 4b) ──────────────────────── */
.bhmod-thead, .bhmod-row { display: grid; grid-template-columns: minmax(220px, 1fr) 200px 148px 186px 146px 84px; gap: 12px; align-items: center; padding: 13px 16px; }
.bhmod-thead { padding: 11px 16px; }
.bhmod-reason { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhmod-reason-l { font: 500 11.5px/1.35 var(--font-alt); color: var(--text-secondary); }
.bhmod-reason-s { font: 400 10.5px/1.35 var(--font-alt); color: var(--text-muted); overflow-wrap: anywhere; }

/* Temps restant : un libellé, une jauge, et la durée totale en dessous. La jauge se lit d'un coup
   d'œil là où « FIN 08/08 21:00 » demande un calcul mental. */
.bhmod-left { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhmod-left-l { font: 600 11.5px/1.2 var(--font-alt); color: var(--text-secondary); }
.bhmod-left--soon .bhmod-left-l { color: var(--gold-fg); }
.bhmod-left--perm .bhmod-left-l { color: var(--red-soft-fg); }
.bhmod-left--done .bhmod-left-l { color: var(--green-fg); }
.bhmod-gauge { height: 3px; border-radius: var(--radius); background: var(--border); overflow: hidden; }
.bhmod-gauge i { display: block; height: 100%; background: var(--accent); }
.bhmod-left--soon .bhmod-gauge i { background: var(--gold-fg); }
.bhmod-gauge--perm { background: var(--tint-red-border); }
.bhmod-gauge--done { background: var(--tint-green-border); }
.bhmod-left-s { font: 400 9.5px/1.3 var(--font-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--text-faint); }
.bhmod-by { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhmod-by-n { font: 500 11.5px/1.3 var(--font-alt); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhmod-by-d { font: 400 10px/1.3 var(--font-mono); color: var(--text-muted); }
.bhmod-end { justify-self: end; display: flex; align-items: center; gap: 10px; }
.bhmod-link { border: 0; background: none; padding: 0; cursor: pointer; font: 500 11.5px/1 var(--font-alt); color: var(--accent); text-decoration: none; }
.bhmod-link:hover:not(:disabled) { color: var(--accent-light); }
.bhmod-link:disabled { opacity: .45; cursor: default; }
.bhmod-link--off { color: var(--text-muted); cursor: default; }

/* Formulaire « prononcer » / « prolonger » : replié par défaut, il n'occupe la place que quand on
   s'en sert. */
.bhmod-form { display: flex; align-items: flex-end; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); background: var(--bg-inset); flex-wrap: wrap; }
.bhmod-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhmod-field-k { font: 500 8.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhmod-field input, .bhmod-field select { height: 32px; padding: 0 10px; border: 1px solid var(--border-input); border-radius: var(--radius); background: var(--bg-input); font: 400 12px/1 var(--font-alt); color: var(--text-primary); outline: none; }
.bhmod-field--grow { flex: 1 1 200px; }
.bhmod-field--grow input { width: 100%; }

@media (max-width: 1100px) {
    .bhreq-split { grid-template-columns: 1fr; }
}

@media (max-width: 1000px) {
    .bhcons-h1 { font-size: 27px; }
    .bhcons-thead, .bhusr-thead, .bhorgs-thead, .bhmod-thead { display: none; }
    .bhusr-row, .bhorgs-row, .bhmod-row { grid-template-columns: 1fr 1fr; row-gap: 8px; }
    .bhusr-row .bhcons-ident, .bhorgs-row .bhcons-ident, .bhmod-row .bhcons-ident,
    .bhmod-row .bhmod-reason { grid-column: 1 / -1; }
    .bhcons-more, .bhmod-end { justify-self: start; }
    .bhusr-facts, .bhreq-facts { grid-template-columns: 1fr; }
    .bhusr-acts { grid-template-columns: 1fr; }
    .bhusr-apply-note { text-align: left; }
}

/* ── Palmarès d'équipe (écrans 11a / 11b) ────────────────────────────────────────────────────
   Le tableau à trois colonnes devient un relevé : la place se lit sur le champ de départ, et
   chaque ligne porte le contexte du tournoi, les points et les gains.
   Namespace `bhpal-` : jamais de préfixe « ad », cf. AdBlockerSafeClassNamesTests. */
.bhpal { display: flex; flex-direction: column; gap: 18px; }

.bhpal-sum { display: grid; grid-template-columns: 1.35fr repeat(3, 1fr); gap: 12px; }
.bhpal-tile { display: flex; flex-direction: column; gap: 8px; padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-panel); min-width: 0; }
.bhpal-tile--best { flex-direction: row; align-items: center; gap: 14px; border-color: var(--tint-gold-border); background: var(--tint-gold-bg); }
.bhpal-tile-txt { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
/* Sur l'aplat doré, le gris de --text-muted tombe à 4,3 pour 1 en thème clair — sous le
   seuil. `--gold-on-tint` existe pour ce cas précis : du texte posé sur une teinte dorée. */
.bhpal-tile--best .bhpal-k { color: var(--gold-on-tint); }
.bhpal-best-name { font: 700 18px/1.15 var(--font-display); text-transform: uppercase; letter-spacing: .03em; color: var(--text-primary); overflow-wrap: anywhere; }

.bhpal-k { font: 500 9px/1 var(--font-mono); letter-spacing: .14em; color: var(--text-muted); }
.bhpal-v { font: 700 26px/1 var(--font-mono); color: var(--text-primary); }
.bhpal-v--cash { color: var(--green-fg); }
.bhpal-sub { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-soft); }

.bhpal-list { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel); overflow: hidden; }
.bhpal-list-head { display: flex; align-items: center; gap: 12px; padding: 13px 22px; border-bottom: 1px solid var(--border); background: var(--bg-inset); }

.bhpal-row { display: grid; grid-template-columns: 86px minmax(0, 1fr) 132px 118px 104px; align-items: center; gap: 16px; padding: 16px 22px; border-bottom: 1px solid var(--bg-hover); }
.bhpal-row:last-child { border-bottom: 0; }

.bhpal-place { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.bhpal-medal { display: grid; place-items: center; width: 46px; height: 46px; flex: none; border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-inset); font: 700 20px/1 var(--font-display); color: var(--text-secondary); }
.bhpal-medal sup { font-size: 11px; }
.bhpal-medal--gold { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); color: var(--gold-fg); }
.bhpal-medal--silver { color: var(--text-bright); }
.bhpal-medal--bronze { color: var(--bronze-fg); }
.bhpal-field { font: 500 9px/1 var(--font-mono); letter-spacing: .1em; color: var(--text-muted); }

.bhpal-what { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.bhpal-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bhpal-title a { font: 600 15px/1.2 var(--font-alt); color: var(--text-primary); }
.bhpal-title a:hover { color: var(--accent-light); }
.bhpal-tag { display: grid; place-items: center; height: 19px; padding: 0 7px; border-radius: var(--radius); font: 600 9px/1 var(--font-mono); letter-spacing: .08em; background: var(--bg-hover); color: var(--text-secondary); }
.bhpal-tag--gold { background: var(--tint-gold-bg); color: var(--gold-fg); }
.bhpal-tag--bronze { color: var(--bronze-fg); }
.bhpal-ctx { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.bhpal-org { font: 500 11.5px/1 var(--font-alt); color: var(--accent-light); }
.bhpal-format { font: 400 11px/1 var(--font-mono); color: var(--text-muted); }

.bhpal-cell { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhpal-n { font: 700 15px/1 var(--font-mono); color: var(--text-body); }
.bhpal-n--cash { color: var(--green-fg); }

.bhpal-end { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.bhpal-date { font: 500 11.5px/1 var(--font-mono); color: var(--text-secondary); }
.bhpal-end a { font: 500 11px/1 var(--font-alt); }

/* Sous 900px la grille à cinq colonnes ne tient plus : la ligne se replie en deux rangées, le
   médaillon et le titre en tête, les chiffres dessous. */
@media (max-width: 900px) {
    .bhpal-sum { grid-template-columns: 1fr 1fr; }
    .bhpal-row { grid-template-columns: 86px minmax(0, 1fr); row-gap: 12px; }
    .bhpal-cell, .bhpal-end { grid-column: 2; align-items: flex-start; }
}

@media (max-width: 560px) {
    .bhpal-sum { grid-template-columns: 1fr; }
}

/* ── Inventaire des connexions (écrans 12a / 12b) ────────────────────────────────────────────
   Prolonge la grammaire `bhcons-` de la console : seules les colonnes propres à ces deux écrans
   vivent ici. Namespace `bhlog-` / `bhses-` : jamais de préfixe « ad ». */
.bhlog-relay { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 13px; border-radius: var(--radius); border: 1px solid var(--border); font: 600 10px/1 var(--font-mono); letter-spacing: .1em; }
.bhlog-relay--on { border-color: var(--tint-green-border); color: var(--green-fg); }
/* Relais inactif = la colonne des adresses ne vaut pas ce qu'elle paraît. Ce n'est pas décoratif. */
.bhlog-relay--off { border-color: var(--tint-red-border); color: var(--red-soft-fg); }

.bhlog-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 220px)); gap: 12px; margin-bottom: 14px; }
.bhlog-tile { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; padding: 14px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-panel); cursor: pointer; text-align: left; font: inherit; }
.bhlog-tile:hover { border-color: var(--border-hover); }
.bhlog-tile--on { border-color: var(--accent); background: var(--accent-subtle); }
.bhlog-tile-v { font: 700 26px/1 var(--font-mono); color: var(--text-primary); }
.bhlog-tile-sub { font: 400 10.5px/1.3 var(--font-alt); color: var(--text-soft); }

.bhlog-alert { display: flex; align-items: center; gap: 14px; padding: 14px 18px; margin-bottom: 12px; border-radius: var(--radius); border: 1px solid var(--tint-red-border); background: var(--tint-red-bg); }
/* Pastille d'alerte : teinte + texte rouge, et non un aplat rouge plein. Le blanc sur le rouge
   du theme CLAIR ne mesure que 3,4 pour 1 a 15px gras, sous le seuil AA du texte normal. */
.bhlog-alert-mark { display: grid; place-items: center; width: 26px; height: 26px; flex: none; border-radius: 50%; border: 1px solid var(--red-fg); background: var(--tint-red-bg-2); color: var(--red-fg); font: 700 15px/1 var(--font-display); }
.bhlog-alert-txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.bhlog-alert-title { font: 600 13px/1.35 var(--font-alt); color: var(--text-primary); }
.bhlog-alert-sub { font: 400 11.5px/1.45 var(--font-alt); color: var(--text-soft); }

.bhlog-thead, .bhlog-row { display: grid; grid-template-columns: 92px minmax(0, 1fr) 116px 190px 150px 140px; align-items: center; gap: 14px; }
/* ⚠️ La colonne des cases est déclarée ICI, en tête des deux gabarits : l'en-tête et les lignes
   partagent la même grille, et n'en changer qu'un décale toutes les colonnes de l'autre. */
.bhses-thead, .bhses-row { display: grid; grid-template-columns: 34px minmax(0, 1fr) 118px 118px 148px 150px 96px; align-items: center; gap: 14px; }
.bhses-pick { display: flex; align-items: center; justify-content: center; }

/* Barre de sélection : n'apparaît qu'une fois quelque chose de coché. */
.bhses-bulk { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; padding: 9px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-inset); }
.bhses-bulk-n { flex: 1 1 auto; font: 500 12px/1.4 var(--font-alt); color: var(--text-primary); }
.bhses-report { margin-bottom: 12px; padding: 10px 14px; border: 1px solid var(--tint-green-border); border-radius: var(--radius); background: var(--tint-green-bg); font: 400 12px/1.5 var(--font-alt); color: var(--green-fg); }

.bhlog-when-cell { display: flex; flex-direction: column; gap: 3px; }
.bhlog-time { font: 500 12.5px/1 var(--font-mono); color: var(--text-body); }
.bhlog-day { font: 500 8.5px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-muted); }
.bhlog-when { font: 500 11.5px/1.3 var(--font-mono); color: var(--text-secondary); }

.bhlog-name { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font: 500 13px/1.2 var(--font-alt); color: var(--text-primary); }
.bhlog-av--unknown { color: var(--text-muted); }

.bhlog-method { font: 500 10px/1 var(--font-mono); letter-spacing: .1em; color: var(--text-soft); }

.bhlog-outcome { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhlog-verdict { font: 500 12.5px/1.2 var(--font-alt); }
.bhlog-verdict--ok { color: var(--green-fg); }
.bhlog-verdict--ko { color: var(--red-soft-fg); }
/* Le contexte qui transforme une ligne isolée en signal : « 31e tentative de cette IP ». */
.bhlog-hint { font: 400 10.5px/1.35 var(--font-alt); color: var(--text-soft); }

.bhlog-ip { font: 500 12px/1.3 var(--font-mono); color: var(--text-secondary); overflow-wrap: anywhere; }
.bhlog-device { font: 400 11px/1.35 var(--font-alt); color: var(--text-soft); overflow-wrap: anywhere; }
.bhlog-act { display: flex; justify-content: flex-end; }
.bhlog-none { font: 400 12px/1 var(--font-mono); color: var(--text-muted); }

.bhlog-retention { margin: 14px 0 0; font: 400 11px/1.55 var(--font-alt); color: var(--text-muted); }

/* ── Couper une session : l'effet réel est annoncé AVANT le geste ─────────────────────── */
.bhlog-modal-back { position: fixed; inset: 0; background: rgba(var(--overlay-rgb), .55); z-index: 60; }
.bhlog-modal { position: fixed; z-index: 61; top: 50%; left: 50%; transform: translate(-50%, -50%); width: min(92vw, 520px); display: flex; flex-direction: column; gap: 10px; padding: 24px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-elevated); box-shadow: 0 24px 60px var(--shadow-strong); }
.bhlog-modal-who { font: 600 16px/1.3 var(--font-alt); color: var(--text-primary); }
.bhlog-modal-sub { font: 400 11.5px/1.4 var(--font-mono); color: var(--text-soft); }

.bhlog-effect { display: flex; flex-direction: column; gap: 3px; padding: 11px 13px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-panel); }
.bhlog-effect-k { font: 600 10px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-soft); }
.bhlog-effect-k--now { color: var(--red-soft-fg); }
.bhlog-effect-v { font: 400 11.5px/1.5 var(--font-alt); color: var(--text-body); }

.bhlog-reason-lbl { display: flex; align-items: baseline; gap: 9px; margin-top: 4px; font: 600 10px/1 var(--font-mono); letter-spacing: .12em; color: var(--text-soft); }
.bhlog-reason-opt { font: 500 9px/1 var(--font-mono); letter-spacing: .1em; color: var(--text-muted); }
.bhlog-modal-act { display: flex; gap: 9px; margin-top: 6px; }

/* Section « Connexions récentes » greffée au tiroir de compte (12c). */
.bhusr-sec-head { display: flex; align-items: baseline; gap: 12px; }
.bhusr-sec-all { margin-left: auto; font: 500 10.5px/1 var(--font-alt); }

@media (max-width: 900px) {
    .bhlog-thead, .bhses-thead { display: none; }
    .bhlog-row { grid-template-columns: 92px minmax(0, 1fr); row-gap: 10px; }
    /* En étroit, tout s'empile dans une colonne — sauf la case, qui garde sa gouttière à gauche et
       reste en face de l'identité. Empilée comme le reste, elle flotterait au-dessus de la ligne
       sans qu'on voie ce qu'elle coche. */
    .bhses-row { grid-template-columns: 34px minmax(0, 1fr); row-gap: 10px; }
    .bhses-row > * { grid-column: 2; }
    .bhses-row .bhses-pick { grid-column: 1; grid-row: 1; }
    .bhlog-row .bhlog-method, .bhlog-row .bhlog-outcome, .bhlog-row .bhlog-ip, .bhlog-row .bhlog-device { grid-column: 2; }
    .bhlog-act { justify-content: flex-start; }
    .bhlog-tiles { grid-template-columns: 1fr 1fr; }
}
/* ── Audience d'un tournoi (écran 1c) ────────────────────────────────────────────────────────
   Le badge « en direct » et les vues cumulées, dans le bandeau de la fiche publique. */
.bht-live { display: inline-flex; align-items: center; gap: 8px; height: 24px; padding: 0 11px 0 10px; border-radius: var(--radius); border: 1px solid var(--accent); background: var(--tint-blue-bg); }
.bht-live-dot { position: relative; width: 7px; height: 7px; flex: none; display: block; }
.bht-live-dot::before, .bht-live-dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; }
.bht-live-dot::before { background: var(--accent-light); animation: bh-live-dot 1.8s ease-in-out infinite; }
.bht-live-dot::after { border: 1px solid var(--accent-light); animation: bh-live-ring 1.8s ease-out infinite; }
.bht-live-n { font: 700 12px/1 var(--font-mono); font-variant-numeric: tabular-nums; min-width: 20px; color: var(--text-bright); }
.bht-live-k { font: 600 9.5px/1 var(--font-mono); letter-spacing: .13em; color: var(--accent-light); }

@keyframes bh-live-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.72); } }
@keyframes bh-live-ring { 0% { opacity: .55; transform: scale(1); } 70%, 100% { opacity: 0; transform: scale(2.6); } }

/* Une pulsation qui ne s'arrête jamais est exactement ce que ce réglage vise. Le badge reste
   lisible : c'est le mouvement qui disparaît, pas l'information. */
@media (prefers-reduced-motion: reduce) {
    .bht-live-dot::before, .bht-live-dot::after { animation: none; }
    .bht-live-dot::after { opacity: 0; }
}

.bht-views { font: 500 10px/1 var(--font-mono); letter-spacing: .1em; color: var(--text-muted); }

/* ── Revue des résultats (écran 3b) ───────────────────────────────────
   Un TABLEAU, pas une pile de cartes : l'organisateur compare des lignes entre
   elles, ce qu'un empilement ne permet pas. Tout est tokenisé. */
.bh3b-split { display: grid; grid-template-columns: 1fr 320px; gap: 16px; align-items: start; }
.bh3b-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.bh3b-sec-h { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.bh3b-formula { font: 400 10.5px/1.4 var(--font-alt); color: var(--text-muted); text-align: right; }
.bh3b-panel { padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-surface); }
/* ⚠️ Sélecteur COMPOSÉ obligatoire : .bh3b-panel est déclaré APRÈS .bhog-card--warn dans ce
   fichier, et l'emporte donc à spécificité égale. Sans cette règle, la carte Match Point perd son
   fond doré et devient une carte ordinaire — défaut invisible aux tests, vu à la capture. */
.bh3b-panel.bhog-card--warn { border-color: var(--tint-gold-border); background: var(--tint-gold-bg); }
.bh3b-ratio { font: 700 15px/1 var(--font-mono); color: var(--text-primary); }

/* ── La série, partie par partie (maquette 3b) ───────────────────────────────────────────
   Une carte par manche, et c'est aussi le sélecteur de l'écran. auto-fit plutôt qu'un nombre
   fixe de colonnes : une série va de trois à huit parties, et cinq pistes en dur laisseraient
   une carte seule sur une deuxième ligne dès la sixième. */
.bh3b-games { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.bh3b-gcard {
    display: flex; flex-direction: column; gap: 6px; text-align: left;
    padding: 11px 13px; border-radius: var(--radius);
    border: 1px solid var(--border); background: var(--bg-surface);
    color: inherit; cursor: pointer;
}
.bh3b-gcard:hover:not(:disabled) { border-color: var(--border-hover); }
/* La partie AFFICHÉE : celle que le tableau, la colonne latérale et les deux gestes suivent. */
.bh3b-gcard--on { border-color: var(--accent); background: var(--accent-subtle); }
/* Une manche annoncée mais pas jouée : rien à y saisir, et le pointillé le dit avant le clic. */
.bh3b-gcard--soon { border-style: dashed; background: none; }
/* ⚠️ « disabled » ne suffit pas à l'œil : sans opacité, une carte non cliquable se lit comme
   les autres et l'utilisateur croit que le clic n'a pas marché. */
.bh3b-gcard:disabled { opacity: .55; cursor: default; }
.bh3b-ghead { display: flex; align-items: center; gap: 7px; }
.bh3b-gdot { width: 6px; height: 6px; border-radius: 50%; background: var(--border); flex: none; }
.bh3b-gdot--ok { background: var(--green-fg); }
.bh3b-gdot--now { background: var(--gold-fg); }
.bh3b-gdot--warn { background: var(--color-danger); }
.bh3b-gdot--todo { background: var(--border-input); }
.bh3b-gname { font: 700 12px/1 var(--font-mono); color: var(--text-soft); }
.bh3b-gcard--on .bh3b-gname { color: var(--text-primary); }
.bh3b-gstate {
    margin-left: auto;
    font: 500 9px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase;
    color: var(--text-muted);
}
.bh3b-gcard--on .bh3b-gstate { color: var(--gold-fg); }
.bh3b-gsub { font: 400 10.5px/1.3 var(--font-alt); color: var(--text-muted); }

/* Rappel de la partie visée, au-dessus du formulaire de saisie. */
.bh3b-target { margin: 0 0 10px; }

/* ── La série en colonnes (maquette 3b) ──────────────────────────────────────────────────
   Une ligne par formation, une colonne par partie. Le gabarit de pistes est calculé en C# et
   passé par --bh3b-grid : le nombre de colonnes dépend du nombre de manches jouées, et trois
   listes de pistes à tenir d'accord (en-tête, sous-ligne, lignes) se seraient décalées au
   premier ajout. La colonne de vérification n'existe que pour l'organisateur — le gabarit ne
   la pose pas plutôt que de laisser une piste vide. */
.bh3b-mwrap { overflow-x: auto; min-width: 0; }
/* ⚠️ PAS de « min-width: max-content » : il fait dimensionner les pistes élastiques sur leur
   contenu le plus long — la puce « Confirmé par les captures » à elle seule sortait le tableau
   de son cadre et posait un ascenseur horizontal sur un cas de TROIS formations. Les minimums
   des pistes (44px, les colonnes de partie, le cumul) suffisent à empêcher l'écrasement : le
   cadre ne défile alors que si la série est réellement trop large. */
.bh3b-matrix { display: flex; flex-direction: column; }
.bh3b-thead, .bh3b-msub, .bh3b-trow {
    display: grid;
    grid-template-columns: var(--bh3b-grid, 44px minmax(0, 1fr) 84px);
    align-items: center;
    gap: 10px;
}
.bh3b-mcol { text-align: center; }
.bh3b-mcol--on { color: var(--gold-fg); }
.bh3b-mcol--soon { opacity: .45; }
.bh3b-mcum { text-align: right; color: var(--accent-light); }

/* Sous-ligne d'unités : elle explique « 1·17 » une fois pour toutes les lignes. */
.bh3b-msub { padding: 6px 6px 0; font: 400 8.5px/1 var(--font-mono); color: var(--text-faint); }
.bh3b-msub > span { text-align: center; }
.bh3b-msub--on { color: var(--gold-fg); }

/* Une cellule de partie. Celle de la partie AFFICHÉE est encadrée : c'est la seule que
   l'organisateur est en train d'arbitrer, et sans cadre la colonne se perdait parmi les autres. */
.bh3b-cell { display: grid; place-items: center; height: 30px; font: 500 12px/1 var(--font-mono); color: var(--text-soft); }
.bh3b-cell--on {
    border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-input);
    font-weight: 700; color: var(--text-primary);
}
.bh3b-cell--soon { border: 1px dashed var(--border); border-radius: var(--radius); color: var(--text-faint); }
.bh3b-cum { text-align: right; }

/* Une cellule cliquable reste une CELLULE : ni fond ni bordure de bouton, le seul indice est le
   curseur et, au survol, la bordure d'accent. Un vrai bouton dessiné casserait l'alignement
   monospace du tableau, qui est ce qui rend les colonnes comparables à l'œil. */
.bh3b-cell--edit, .bh3b-cell--link {
    border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer;
}
.bh3b-cell--edit { border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-input); }
.bh3b-cell--link:hover { color: var(--accent-light); }
.bh3b-cell--edit:hover { border-color: var(--accent); }
.bh3b-cell--open { border-color: var(--accent); background: var(--accent-subtle); }

/* ── La saisie dépliée sous sa ligne ─────────────────────────────────────────────────────
   Posée HORS de la grille des lignes, en frère : glissée dedans, elle occuperait une piste de
   62 px. Le décalage à gauche l'amarre visuellement à la ligne qu'elle prolonge, et la bordure
   sans sommet la lui rattache. */
.bh3b-editor {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 14px 24px;
    align-items: start;
    margin: 0 6px 10px 54px;
    padding: 14px 16px;
    border: 1px solid var(--accent); border-top: 0;
    border-radius: 0 0 var(--radius) var(--radius);
    background: var(--bg-surface);
}
.bh3b-ed-col { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.bh3b-ed-col--sum { align-items: flex-end; }
.bh3b-ed-kicker {
    font: 500 9px/1 var(--font-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--text-muted);
}
.bh3b-ed-kicker--on { color: var(--gold-fg); }
.bh3b-ed-note { font: 400 9.5px/1.4 var(--font-alt); color: var(--text-faint); max-width: 22ch; }

.bh3b-ed-place {
    width: 56px; height: 32px; text-align: center;
    border-radius: var(--radius); border: 1px solid var(--accent); background: var(--bg-input);
    font: 700 15px/1 var(--font-mono); color: var(--text-primary);
}

/* auto-fit : une formation va de deux à quatre joueurs, et trois pistes en dur laisseraient un
   trou en duo comme un retour à la ligne en quatuor. */
.bh3b-ed-players { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; }
.bh3b-ed-player {
    display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 4px 0 10px;
    border-radius: var(--radius); border: 1px solid var(--border-input); background: var(--bg-input);
}
.bh3b-ed-player:focus-within { border-color: var(--accent); }
.bh3b-ed-pname {
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font: 400 11.5px/1 var(--font-alt); color: var(--text-soft);
}
.bh3b-ed-kills {
    width: 46px; height: 26px; text-align: right;
    border: 0; background: none; font: 700 14px/1 var(--font-mono); color: var(--text-primary);
}
.bh3b-ed-kills:focus { outline: none; }

.bh3b-ed-total { display: flex; align-items: baseline; gap: 8px; height: 32px; }
.bh3b-ed-addends { font: 400 11px/1 var(--font-mono); color: var(--text-faint); }
.bh3b-ed-sum { font: 700 20px/1 var(--font-mono); color: var(--gold-fg); }

/* Les mesures facultatives et les captures : repliées, pas retirées. */
.bh3b-ed-more { grid-column: 1 / -1; }
.bh3b-ed-more > summary {
    cursor: pointer; font: 500 10.5px/1 var(--font-mono); letter-spacing: .06em;
    color: var(--accent-light); padding: 6px 0;
}
.bh3b-ed-acts {
    grid-column: 1 / -1;
    display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap;
}
.bh3b-ed-acts .res-owner { margin-right: auto; }
.bh3b-legend { margin: 10px 0 0; font: 400 10.5px/1.5 var(--font-alt); color: var(--text-muted); }
.bh3b-thead {
    padding: 0 6px 8px;
    border-bottom: 1px solid var(--border);
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bh3b-trow { padding: 9px 6px; border-bottom: 1px solid var(--border); }
.bh3b-trow:last-child { border-bottom: 0; }
.bh3b-num { font: 700 14px/1 var(--font-mono); color: var(--text-muted); }
/* Les noms sont la colonne élastique : ils débordent avant tout le reste. */
.bh3b-players { font: 400 12px/1.4 var(--font-alt); color: var(--text-primary); overflow-wrap: anywhere; }
.bh3b-pts { font: 700 14px/1 var(--font-mono); color: var(--text-primary); }
.bh3b-check { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.bh3b-noshot { font: 400 10.5px/1 var(--font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.bh3b-shot { color: var(--text-muted); text-decoration: none; }
.bh3b-shot:hover { color: var(--accent); }

.bh3b-ocr-note { margin: 10px 0 0; font: 400 10.5px/1.6 var(--font-alt); color: var(--text-muted); }
.bh3b-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.bh3b-act--ko { color: var(--color-danger); border-color: var(--tint-red-border); }

/* ── Écran 3b : état des lignes, captures et déroulé de la manche ────────────────────────
   États de ligne. Le fond est un APLAT DE TEINTE, jamais une couleur en dur : le thème clair
   redéfinit ces tokens et la ligne suit. La priorité est écart > sans capture > Match Point,
   posée côté C# (RowState) — une seule source, sinon deux classes pourraient cohabiter. */
.bh3b-trow--gold  { background: var(--tint-gold-bg); }
.bh3b-trow--warn  { background: var(--tint-red-bg); }
.bh3b-trow--warn .bh3b-cell--on { color: var(--color-danger); border-color: var(--tint-red-border); }
.bh3b-trow--muted { opacity: .6; }

/* Le multiplicateur accompagne les points sans les concurrencer : plus petit, plus discret. */
.bh3b-mult { margin-left: 5px; font: 500 10px/1 var(--font-mono); color: var(--text-muted); }
.bh3b-trow--gold .bh3b-mult { color: var(--gold-fg); }

/* Bande de pied : la note OCR et les deux gestes qu'elle explique, dans un seul cadre. */
.bh3b-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
    margin-top: 14px; padding: 12px 14px; border-radius: var(--radius);
    border: 1px solid var(--border); background: var(--bg-surface);
}
.bh3b-foot .bh3b-ocr-note { margin: 0; max-width: 56ch; }
.bh3b-foot .bh3b-acts { margin-top: 0; }

/* Grille de vignettes des captures reçues. */
.bh3b-shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 4px; }
.bh3b-shotthumb {
    display: block; height: 56px; border-radius: var(--radius); overflow: hidden;
    border: 1px solid var(--border); background: var(--bg-elevated, var(--bg-surface));
}
.bh3b-shotthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bh3b-shotthumb:hover { border-color: var(--accent); }
.bh3b-shotthumb--warn { border-color: var(--tint-red-border); }
.bh3b-shotmore {
    display: grid; place-items: center; height: 56px; border-radius: var(--radius);
    border: 1px dashed var(--border); font: 400 11px/1 var(--font-mono); color: var(--text-muted);
}

/* Déroulé de la manche : quatre jalons, la pastille dit où l'on en est. */
.bh3b-steps { display: flex; flex-direction: column; gap: 11px; margin-top: 12px; }
.bh3b-step { display: flex; align-items: center; gap: 10px; }
.bh3b-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border); flex: none; }
.bh3b-step-l { flex: 1; font: 400 12px/1.3 var(--font-alt); color: var(--text-soft); }
.bh3b-step-v { font: 500 11px/1 var(--font-mono); color: var(--text-muted); }
.bh3b-step--done .bh3b-dot { background: var(--green-fg); }
.bh3b-step--now  .bh3b-dot { background: var(--gold-fg); }
.bh3b-step--now  .bh3b-step-l,
.bh3b-step--now  .bh3b-step-v { color: var(--gold-fg); }
.bh3b-step--todo { opacity: .5; }

/* Changer le code du lobby depuis le bandeau de conduite. */
.bh3bar-rdiv { width: 1px; height: 16px; background: var(--border); }
.bh3bar-ract {
    border: 0; background: none; cursor: pointer; padding: 0 2px;
    font: 600 10.5px/1 var(--font-mono); letter-spacing: .04em; color: var(--accent);
}
.bh3bar-ract:disabled { opacity: .5; cursor: default; }
.bh3bar-rinput {
    width: 9ch; padding: 4px 6px; border-radius: var(--radius);
    border: 1px solid var(--border); background: var(--bg-surface);
    font: 700 15px/1 var(--font-mono); color: var(--text-primary); text-transform: uppercase;
}

@media (max-width: 1000px) {
    .bh3b-split { grid-template-columns: 1fr; }
    .bh3b-foot { flex-direction: column; align-items: stretch; }
    .bh3b-foot .bh3b-acts { justify-content: stretch; }
    /* Le tableau ne se replie plus : ses colonnes SONT l'information, et les empiler
       reviendrait à la pile de cartes que la maquette remplace. Il défile dans .bh3b-mwrap.
       ⚠️ Le parent porte « min-width: 0 » (.bh3b-col) — sans lui, la largeur du tableau
       remonterait à travers la grille et ferait défiler la page entière. */
    .bh3b-games { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
    /* L'éditeur perd son décalage d'amarrage et ses trois colonnes : sur un téléphone, la piste
       des joueurs y tomberait sous la centaine de pixels. */
    .bh3b-editor { grid-template-columns: 1fr; margin-left: 6px; }
    .bh3b-ed-col--sum { align-items: flex-start; }
}

/* ─── Mon profil, onglet « Profil public » (maquette 14a) ─────────────────────────────────────
   Namespace `bhprof-`. ⚠️ Jamais de classe préfixée `ad*` : les bloqueurs de publicité les masquent
   sans rien dire (cf. AdBlockerSafeClassNamesTests). Tout est tokenisé, donc suit le thème. */
.bhprof-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; align-items: start; }
.bhprof-grid > * { min-width: 0; }
.bhprof-main, .bhprof-rail { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.bhprof-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); padding: 18px 20px; }
.bhprof-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.bhprof-card-title { margin: 0; font: 600 11px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.bhprof-card-note { font: 400 11px/1.4 var(--font-alt); color: var(--text-faint); }

.bhprof-identity { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.bhprof-identity-fields { flex: 1 1 320px; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.bhprof-avatar-btn { position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 0; text-align: center; font: 600 9px/1.4 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; background: rgba(var(--overlay-rgb), .55); color: var(--text-primary); }

/* La grille des champs secondaires suit le bloc avatar + pseudo + présentation : sans respiration,
   « Pseudo gaming » se colle sous la présentation et se lit comme la suite du même bloc. */
.bhprof-fields { margin-top: 18px; }

.bhprof-pseudo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bhprof-pseudo input { flex: 1 1 200px; min-width: 0; }
.bhprof-discriminator { font: 500 13px/1 var(--font-mono); color: var(--text-muted); }
.bhprof-counter { float: right; font: 400 10.5px/1 var(--font-mono); color: var(--text-faint); }

.bhprof-avail { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 9px; border-radius: var(--radius); font: 600 10px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }
.bhprof-avail--ok { background: var(--tint-green-bg); color: var(--green-fg); }
.bhprof-avail--ko { background: var(--tint-red-bg); color: var(--red-fg); }
.bhprof-refus { margin: 6px 0 0; font: 400 11.5px/1.5 var(--font-alt); color: var(--red-fg); }
.bhprof-inline-btn { margin-top: 8px; }
.bhprof-readonly-tag { margin-left: 8px; font: 600 9px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--accent-light); }

/* Une ligne de lien : libellé, adresse, bascule d'affichage. */
.bhprof-link { display: flex; align-items: center; gap: 14px; padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.bhprof-link:last-of-type { border-bottom: 0; }
.bhprof-link-label { flex: 0 0 84px; font: 500 12.5px/1 var(--font-alt); color: var(--text-secondary); }
.bhprof-link-value { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
/* Cadre, fond et rayon viennent de la règle `.field input` (section formulaires) — ici, juste ce
   qu'il faut pour que le champ se rétrécisse dans sa colonne flex. */
.bhprof-link-value input { min-width: 0; }
/* Interligne 1.28 et pas 1 : 12.5 × 1.28 = 16px, la hauteur de ligne d'un input à 14px, donc un
   cadre exactement aussi haut que les trois autres (mesuré : 38px partout). */
.bhprof-link-static { flex: 1; display: flex; align-items: center; gap: 8px; font: 500 12.5px/1.28 var(--font-mono); color: var(--text-muted); }
.bhprof-link-static-txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhprof-link-badge { flex: none; font: 600 9px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; padding: 3px 7px; border-radius: var(--radius); background: var(--accent-subtle); color: var(--accent); }

/* Interrupteur : une VRAIE case à cocher sous le CSS, pour que le lecteur d'écran l'annonce comme
   un état et que le clavier l'atteigne. */
.bhprof-switch { position: relative; flex: none; display: inline-flex; align-items: center; cursor: pointer; }
.bhprof-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.bhprof-switch-track { width: 38px; height: 21px; border-radius: var(--radius); background: var(--bg-inset); border: 1px solid var(--border-input); transition: background .15s, border-color .15s; position: relative; }
.bhprof-switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--text-muted); transition: transform .15s, background .15s; }
.bhprof-switch input:checked + .bhprof-switch-track { background: var(--accent); border-color: transparent; }
.bhprof-switch input:checked + .bhprof-switch-track::after { transform: translateX(17px); background: var(--on-accent); }
.bhprof-switch input:disabled + .bhprof-switch-track { opacity: .4; cursor: default; }
.bhprof-switch input:focus-visible + .bhprof-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

.bhprof-preview-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.bhprof-preview-av { width: 46px; height: 46px; border-radius: 50%; }
.bhprof-preview-name { font: 700 20px/1.1 var(--font-display); text-transform: uppercase; color: var(--text-primary); display: flex; align-items: baseline; gap: 7px; }
.bhprof-preview-bio { margin: 0 0 10px; font: 400 12.5px/1.6 var(--font-alt); color: var(--text-secondary); }

.bhprof-private { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.bhprof-private li { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font: 400 12px/1.4 var(--font-alt); color: var(--text-secondary); }
.bhprof-private em { font-style: normal; font: 600 9.5px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); }
.bhprof-private--tunable { color: var(--accent-light) !important; }

/* Barre d'enregistrement : collée au bas de la COLONNE, pas de la fenêtre — la page ne défile pas
   elle-même (cf. architecture de défilement), une barre en position:fixed flotterait au mauvais
   endroit dès que le shell change de gabarit. */
.bhprof-savebar { position: sticky; bottom: 0; z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-top: 16px; padding: 12px 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); box-shadow: 0 -8px 24px var(--shadow-strong); }
.bhprof-savebar-txt { font: 500 12.5px/1 var(--font-alt); color: var(--gold-fg); }
.bhprof-savebar-fields { font: 400 11.5px/1.4 var(--font-alt); color: var(--text-muted); }
.bhprof-savebar-actions { display: flex; gap: 10px; }

@media (max-width: 900px) {
    .bhprof-grid { grid-template-columns: 1fr; }
    .bhprof-link { flex-wrap: wrap; }
    .bhprof-link-label { flex-basis: 100%; }
}

/* ─── Onglet « Compte & sécurité » (14b) ────────────────────────────────────
   Grammaire bhacc-. Même ossature que bhprof- (grille + rail), mais des LIGNES plutôt que des
   champs : chaque moyen de connexion est un état qu'on lit, avec une seule action à droite.
   ⚠️ Aucune couleur en dur — tout passe par les tokens de :root, thème clair compris. */
.bhacc-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; align-items: start; }
.bhacc-grid > * { min-width: 0; }
.bhacc-main, .bhacc-rail { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.bhacc-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow: hidden; }
.bhacc-card--pad { padding: 16px; display: flex; flex-direction: column; gap: 11px; }
.bhacc-card--danger { border-color: var(--tint-red-border); padding: 18px 20px; display: flex; flex-direction: column; gap: 14px; }
.bhacc-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 14px 18px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); }
.bhacc-card-title { font: 600 11px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.bhacc-card-note { font: 400 11px/1.4 var(--font-alt); color: var(--text-faint); }
.bhacc-count { color: var(--text-faint); }
.bhacc-headaction { border: 0; background: none; cursor: pointer; font: 500 11.5px/1 var(--font-alt); color: var(--red-fg); padding: 0; }

/* Une ligne = un moyen de connexion. La 3ᵉ colonne est fixe pour que les actions s'alignent. */
.bhacc-row { display: grid; grid-template-columns: 150px 1fr auto; align-items: center; gap: 14px; padding: 14px 18px; border-bottom: 1px solid var(--line-soft); }
.bhacc-row:last-of-type { border-bottom: 0; }
.bhacc-row--alert { background: var(--tint-red-bg); box-shadow: inset 2px 0 0 var(--red-fg); }
.bhacc-row-label { font: 500 12px/1.3 var(--font-alt); color: var(--text-secondary); }
.bhacc-row-body { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhacc-row-value { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.bhacc-row-state { font: 600 12px/1 var(--font-alt); }
.bhacc-row-state--ok { color: var(--green-fg); }
.bhacc-row-state--ko { color: var(--red-fg); }
.bhacc-mono { font: 400 12px/1.3 var(--font-mono); color: var(--text-primary); overflow-wrap: anywhere; }
.bhacc-hint { font: 400 10.5px/1.5 var(--font-alt); color: var(--text-faint); }
.bhacc-grow { flex: 1 1 200px; }
.bhacc-empty { margin: 0; padding: 16px 18px; font: 400 11.5px/1.4 var(--font-alt); color: var(--text-faint); }

.bhacc-tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 6px; border-radius: var(--radius); font: 600 9px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; background: var(--bg-inset); color: var(--text-muted); }
.bhacc-tag--ok { background: var(--tint-green-bg); color: var(--green-fg); }
.bhacc-tag--warn { background: var(--tint-gold-bg); color: var(--gold-fg); }
.bhacc-tag--discord { background: var(--accent-subtle); color: var(--accent); }
.bhacc-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--text-faint); }
.bhacc-dot--live { background: var(--green-fg); }
.bhacc-dot--ko { background: var(--red-fg); }

.bhacc-action { display: inline-flex; align-items: center; height: 30px; padding: 0 13px; border-radius: var(--radius); border: 1px solid var(--line-strong); background: none; cursor: pointer; font: 500 11.5px/1 var(--font-alt); color: var(--text-primary); text-decoration: none; }
.bhacc-action:hover:not(:disabled) { background: rgba(var(--overlay-rgb), .06); }
.bhacc-action--primary { border-color: transparent; background: var(--accent); color: var(--on-accent); font-weight: 600; }
.bhacc-action:disabled { opacity: .5; cursor: default; }
.bhacc-noaction { font: 500 9.5px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); }
.bhacc-linkbtn { border: 0; background: none; cursor: pointer; padding: 0; font: 500 11.5px/1 var(--font-alt); color: var(--accent-light); }
.bhacc-linkbtn:disabled { opacity: .5; cursor: default; }
.bhacc-block { width: 100%; justify-content: center; text-align: center; }

/* Tiroir : le formulaire POST d'origine, replié tant qu'on ne l'a pas demandé. */
.bhacc-drawer { padding: 16px 18px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); display: flex; flex-direction: column; gap: 10px; }
.bhacc-inline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bhacc-code { width: 190px; max-width: 100%; }
.bhacc-appeal { flex: 1 1 220px; min-width: 0; }
.bhacc-secret { padding: 12px 14px; border-radius: var(--radius); border: 1px dashed var(--line-strong); background: var(--bg-input); font: 600 15px/1.4 var(--font-mono); letter-spacing: .14em; color: var(--text-primary); overflow-wrap: anywhere; }

.bhacc-device { display: grid; grid-template-columns: 1fr 170px 130px auto; align-items: center; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--line-soft); }
.bhacc-device:last-of-type { border-bottom: 0; }
.bhacc-device-id { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bhacc-device-name { display: block; font: 500 12px/1.3 var(--font-alt); color: var(--text-primary); }
.bhacc-device-me { display: block; margin-top: 3px; font: 500 9px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--green-fg); }
.bhacc-device-ip { font-size: 11px; color: var(--text-soft); }
.bhacc-device-seen { font: 400 11px/1.3 var(--font-alt); color: var(--text-muted); }
.bhacc-device-cut { justify-self: end; color: var(--text-faint); }

.bhacc-ban { padding: 14px 18px; border-bottom: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 8px; }
.bhacc-ban:last-of-type { border-bottom: 0; }
.bhacc-ban--active { background: var(--tint-red-bg); box-shadow: inset 2px 0 0 var(--red-fg); }
.bhacc-ban-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.bhacc-ban-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font: 600 12.5px/1.3 var(--font-alt); color: var(--text-primary); }
.bhacc-ban-lifted { font: 500 10px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--green-fg); }
.bhacc-ban-appeal { font: 500 11px/1.3 var(--font-alt); color: var(--gold-fg); }

.bhacc-danger-title { margin: 0; font: 700 21px/1 var(--font-display); letter-spacing: .04em; text-transform: uppercase; color: var(--text-primary); }
.bhacc-danger-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.bhacc-danger-box { padding: 13px 15px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-inset); display: flex; flex-direction: column; gap: 8px; }
.bhacc-danger-label { font: 600 9.5px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-soft); }
.bhacc-danger-label--ko { color: var(--red-fg); }

/* Compte rendu d'un geste, rendu DANS la carte qui l'a déclenché (Bogue #868). La bannière de la
   page vit tout en haut ; la carte « supprimer mon compte », elle, est en bas d'un onglet long — un
   refus s'y affichait donc hors de l'écran, exactement là où personne ne regarde. */
.bhacc-outcome { margin: 10px 0 0; padding: 8px 11px; border-radius: var(--radius); font: 500 11.5px/1.45 var(--font-alt); }
.bhacc-outcome--ok { background: var(--tint-green-bg); color: var(--green-fg); }
.bhacc-outcome--ko { background: var(--tint-red-bg); color: var(--red-fg); }

.bhacc-form { display: flex; flex-direction: column; gap: 12px; }
.bhacc-form .form-grid { margin: 0; }

.bhacc-logins { padding: 14px 18px; display: flex; flex-direction: column; gap: 12px; }
.bhacc-login { display: grid; grid-template-columns: 6px 1fr; gap: 10px; align-items: start; }
.bhacc-login .bhacc-dot { margin-top: 5px; }
.bhacc-login-what { display: block; font: 400 11.5px/1.3 var(--font-alt); color: var(--text-primary); }
.bhacc-login-what--ko { font-weight: 600; color: var(--red-fg); }
.bhacc-login-method { color: var(--text-muted); }
.bhacc-login-when { display: block; margin-top: 3px; font-size: 10px; color: var(--text-faint); }
.bhacc-login-warn { padding: 11px 18px; border-top: 1px solid var(--line-soft); background: var(--tint-red-bg); font: 400 10.5px/1.5 var(--font-alt); color: var(--red-fg); }
.bhacc-export-state { font: 500 11px/1 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); }

@media (max-width: 900px) {
    .bhacc-grid { grid-template-columns: 1fr; }
    .bhacc-row { grid-template-columns: 1fr; }
    .bhacc-device { grid-template-columns: 1fr auto; }
    .bhacc-device-ip, .bhacc-device-seen { grid-column: 1 / -1; }
    .bhacc-danger-grid { grid-template-columns: 1fr; }
}

/* ─── Onglet « Notifications » (14c) ────────────────────────────────────────
   Grammaire bhnot-. Une MATRICE : une ligne par type de notification, trois colonnes de canaux de
   largeur fixe pour que les bascules s'alignent d'un bout à l'autre du tableau, familles comprises.
   ⚠️ Aucune couleur en dur — tout passe par les tokens de :root, thème clair compris.
   ⚠️ La largeur des colonnes de canaux est déclarée DEUX fois, dans .bhnot-head et .bhnot-row : un
   écart entre les deux décale les en-têtes des bascules qu'ils désignent. */
.bhnot-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; align-items: start; }
.bhnot-grid > * { min-width: 0; }
.bhnot-main, .bhnot-rail { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.bhnot-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); overflow: hidden; }
.bhnot-card--pad { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.bhnot-card-head { padding: 13px 16px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); }
.bhnot-card-title { font: 600 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-soft); }
.bhnot-hint { font: 400 10.5px/1.5 var(--font-alt); color: var(--text-faint); }
.bhnot-warn { font: 500 10.5px/1.5 var(--font-alt); color: var(--gold-fg); }
.bhnot-failed { margin: 0; padding: 18px 20px; border: 1px solid var(--tint-red-border); border-radius: var(--radius); background: var(--tint-red-bg); font: 400 12.5px/1.5 var(--font-alt); color: var(--red-fg); }

.bhnot-head { display: grid; grid-template-columns: 1fr 84px 84px 84px; align-items: end; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); }
.bhnot-head-ev { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font: 600 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); }
.bhnot-head-ch { justify-self: center; font: 600 10px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }
.bhnot-head-ch--site { color: var(--accent-light); }
.bhnot-head-ch--discord { color: var(--accent); }
.bhnot-reset { display: inline-flex; align-items: center; gap: 5px; border: 0; background: none; cursor: pointer; padding: 0; font: 500 10.5px/1 var(--font-alt); letter-spacing: 0; text-transform: none; color: var(--accent-light); }
.bhnot-reset:disabled { opacity: .5; cursor: default; }

/* Compte Discord non lié : la colonne reste réglable, un bandeau dit qu'elle n'enverra rien tant
   que la liaison n'est pas faite (Bogue #658). Posé SOUS l'en-tête et non dans le rail : c'est de
   la colonne juste au-dessus qu'il parle, et un avertissement rangé ailleurs se lit comme un
   message général qu'on saute. */
.bhnot-nolink { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin: 0; padding: 10px 18px; border-bottom: 1px solid var(--line-soft); background: var(--accent-subtle); font: 400 11px/1.55 var(--font-alt); color: var(--text-soft); }
.bhnot-nolink-link { color: var(--accent-light); }

.bhnot-family { padding: 9px 18px 7px; border-bottom: 1px solid var(--line-soft); background: var(--bg-inset); font: 600 9.5px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-soft); }

.bhnot-row { display: grid; grid-template-columns: 1fr 84px 84px 84px; align-items: center; gap: 12px; padding: 11px 18px; border-bottom: 1px solid var(--line-soft); }
.bhnot-row:last-of-type { border-bottom: 0; }
.bhnot-row--hl { background: var(--accent-subtle); }
.bhnot-row--dormant { opacity: .6; }
.bhnot-ev { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.bhnot-ev-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font: 500 12px/1.3 var(--font-alt); color: var(--text-primary); }
.bhnot-ev-code { font: 400 9.5px/1.3 var(--font-mono); color: var(--text-faint); overflow-wrap: anywhere; }
.bhnot-ev-note { font: 400 10px/1.45 var(--font-alt); color: var(--text-faint); }
.bhnot-badge { padding: 3px 5px; border-radius: var(--radius); font: 600 8.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; background: var(--accent-subtle); color: var(--accent-light); }
.bhnot-cell { justify-self: center; }
.bhnot-na { font: 400 11px/1 var(--font-alt); color: var(--text-faint); }
.bhnot-legend { margin: 0; font: 400 11px/1.55 var(--font-alt); color: var(--text-faint); }

/* Bascule. Le verrou ne se distingue pas par sa couleur mais par son opacité et son curseur : un
   allumé imposé DOIT rester lisible comme allumé, sinon il se lit comme éteint. */
.bhnot-sw { display: inline-flex; align-items: center; justify-content: flex-start; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: var(--radius); background: var(--bg-input); box-shadow: inset 0 0 0 1px var(--line-strong); cursor: pointer; }
.bhnot-sw--on { justify-content: flex-end; background: var(--accent); box-shadow: none; }
.bhnot-sw--locked { background: var(--accent-subtle); box-shadow: inset 0 0 0 1px var(--accent-light); cursor: default; }
.bhnot-sw:disabled:not(.bhnot-sw--locked) { opacity: .5; cursor: default; }
.bhnot-knob { display: block; width: 16px; height: 16px; border-radius: 50%; background: var(--text-faint); }
.bhnot-sw--on .bhnot-knob { background: var(--on-accent); }
.bhnot-sw--locked .bhnot-knob { background: var(--accent-light); }

.bhnot-quiet { display: flex; align-items: center; gap: 10px; }
.bhnot-time { flex: 1; min-width: 0; font-family: var(--font-mono); }
.bhnot-quiet-arrow { font: 400 11px/1 var(--font-alt); color: var(--text-faint); }
.bhnot-zone { display: flex; flex-direction: column; gap: 6px; padding-top: 11px; border-top: 1px solid var(--line-soft); }
.bhnot-zone label { font: 400 11.5px/1.3 var(--font-alt); color: var(--text-secondary); }

.bhnot-privacy { padding: 16px; display: flex; flex-direction: column; gap: 16px; }
.bhnot-choice { display: flex; flex-direction: column; gap: 9px; }
.bhnot-choice-label { font: 500 11.5px/1.35 var(--font-alt); color: var(--text-primary); }
.bhnot-seg { display: flex; gap: 5px; }
.bhnot-seg-opt { flex: 1; min-width: 0; height: 30px; padding: 0 6px; border: 1px solid var(--border); border-radius: var(--radius); background: none; cursor: pointer; font: 500 11px/1 var(--font-alt); color: var(--text-muted); }
.bhnot-seg-opt--on { border-color: transparent; background: var(--accent-subtle); font-weight: 600; color: var(--accent-light); }
.bhnot-seg-opt:disabled { opacity: .5; cursor: default; }
.bhnot-flag { display: flex; align-items: center; gap: 12px; }
.bhnot-flag-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bhnot-flag .bhnot-sw { flex: none; }

@media (max-width: 900px) {
    .bhnot-grid { grid-template-columns: 1fr; }
    /* Les trois canaux passent sous le libellé plutôt que de rétrécir : à 84px chacun, la colonne
       ÉVÉNEMENT deviendrait illisible bien avant les bascules. Chaque case reprend alors le nom de
       son canal — sans l'en-tête au-dessus, trois bascules alignées ne disent plus de quoi elles
       décident. */
    .bhnot-head { grid-template-columns: 1fr; }
    .bhnot-head-ch { display: none; }
    .bhnot-row { grid-template-columns: repeat(3, 1fr); }
    .bhnot-ev { grid-column: 1 / -1; }
    .bhnot-cell { justify-self: start; display: flex; flex-direction: column; gap: 5px; }
    .bhnot-cell::before { content: attr(data-ch); font: 600 9px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); }
}

/* ── Arbre du Wager (US #630) ─────────────────────────────────────────────
   Partagé par l'écran public et par l'écran du tirage des matchs.
   ⚠️ Le défilement latéral appartient à .bhbr-scroll, jamais à la page : un arbre
   à huit camps est plus large que l'écran, et sans ce conteneur c'est la page
   entière qui part sur le côté, navigation comprise. Corollaire : min-width:0 sur
   les items de grille, sinon la largeur intrinsèque remonte et déborde quand même. */
.bhbr { min-width: 0; }
.bhbr-empty { color: var(--text-muted); margin: 0; }
/* ═══ L'arbre déborde, et il doit le DIRE ═══════════════════════════════════════════════════════
   Un arbre à 16 camps réclame ~1720 px de large : sur un téléphone, et même sur la colonne de
   1180 px d'un écran de bureau, il défile horizontalement. C'est voulu — le compresser rendrait les
   noms illisibles. Ce qui ne l'était pas, c'est que RIEN ne l'annonce : la première colonne remplit
   l'écran, et rien ne laisse deviner qu'il y en a d'autres à droite.

   🔑 Ombres de défilement en CSS pure, sans JavaScript ni écouteur : deux aplats de couleur de fond
   attachés au CONTENU (`local`) masquent les ombres tant qu'on est à l'extrémité, et deux ombres
   attachées au CADRE (`scroll`) restent visibles du côté où il reste quelque chose à voir. Le
   dégradé apparaît donc exactement quand il y a du contenu au-delà du bord, et disparaît sinon.

   ⚠️ Couleurs par tokens uniquement — `--bg-page` pour le cache, `--shadow-strong` pour l'ombre.
   Un `rgba(0,0,0,…)` en dur donnerait un halo noir sur le fond blanc du thème clair. */

.bhbr-scroll {
  background:
    linear-gradient(to right, var(--bg-page) 30%, transparent) left center / 28px 100% no-repeat,
    linear-gradient(to left,  var(--bg-page) 30%, transparent) right center / 28px 100% no-repeat,
    radial-gradient(farthest-side at 0% 50%, var(--shadow-strong), transparent) left center / 14px 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, var(--shadow-strong), transparent) right center / 14px 100% no-repeat,
    /* 🔴 L'arbre pose son PROPRE aplat depuis que les conteneurs d'écran sont transparents.
       Les deux premières bandes sont des caches OPAQUES en `background-attachment: local` : elles
       suivent le défilement et effacent l'ombre quand on arrive au bout. La technique exige que
       leur couleur soit EXACTEMENT celle de la surface qu'elles recouvrent — impossible au-dessus
       d'un fond animé, où elles se verraient comme deux bandes plates aux extrémités. L'arbre se
       pose donc sur son propre aplat et la fumée passe autour : c'est un diagramme dense, il
       gagne à se lire au calme. */
    var(--bg-page);
  background-attachment: local, local, scroll, scroll, scroll;

    overflow-x: auto;
    min-width: 0;
    padding-bottom: 8px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    /* Sans ça, l'étirement par défaut du flex donnerait à la scène toute la largeur disponible et
       annulerait son max-content : elle ne pourrait plus se centrer. */
    align-items: flex-start;
}

/* La scène : les deux tableaux réunis, dimensionnés sur le plus large des deux et centrés tant que
   la place le permet.
   🔑 `width: max-content` + `margin-inline: auto` donne les DEUX comportements demandés d'un coup —
   l'arbre s'étire à mesure qu'il grandit, et reste centré tant qu'il ne remplit pas la largeur.
   Quand il la dépasse, l'espace libre devient négatif : les marges auto retombent à 0, le bord
   gauche reste atteignable et .bhbr-scroll défile comme avant. C'est ce qui rend l'écriture sûre là
   où un `justify-content: center` rendrait le début de l'arbre inaccessible. */
.bhbr-stage {
    width: max-content;
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.bhbr-band { min-width: 0; }
.bhbr-band-title {
    display: block;
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-hint);
    margin-bottom: 8px;
}
.bhbr-band--loser .bhbr-band-title { color: var(--text-faint); }

.bhbr-cols { display: flex; gap: 14px; align-items: flex-start; }

/* ── Canevas de l'arbre (17a) ──────────────────────────────────────────────
   🔴 Positionnement ABSOLU, et c'est structurel : un match doit être centré entre ses deux
   alimentateurs et relié à eux. Une pile de colonnes n'alignait rien, et l'arbre ne disait plus
   qui nourrit qui — c'est-à-dire l'information qu'un arbre existe pour porter. Les coordonnées
   viennent de BracketGeometry, jamais du CSS. */
/* 22px et non 10 : les pastilles d'état se posent à top:-17px au-dessus de leur carte, et celles de
   la PREMIÈRE ligne remontaient dans la bande d'en-têtes, où le conteneur de défilement les coupait. */
.bhbr-heads { display: flex; gap: 56px; margin-bottom: 22px; }
/* `flow-root` : sans lui, la marge haute de l'encart de cagnotte FUSIONNE avec celle du canevas et
   sort du bloc au lieu de l'écarter — l'encart se retrouve alors posé en haut, sur le premier tour. */
.bhbr-canvas { position: relative; display: flow-root; }
/* ⚠️ L'encart de cagnotte n'a plus de `position: absolute` — il reste DANS le flux (cf.
   AsideFragment), et c'est lui qui donne au canevas sa hauteur réelle quand il descend plus bas que
   la dernière carte. En absolu, il débordait sous la bande du looser et recouvrait une carte. */
.bhbr-aside .bhbr-pot { margin-top: 0; max-width: none; }
.bhbr-canvas .bhbr-slot { position: absolute; padding-left: 0; }

/* Connecteurs : des traits bordés plutôt qu'un SVG, pour qu'ils héritent des tokens de thème
   sans redéclarer la couleur deux fois. */
.bhbr-link {
    position: absolute; height: 1px; background: var(--border-hover); pointer-events: none;
}
.bhbr-link--v { width: 1px; height: auto; }

/* Le numéro de match se pose SUR le connecteur, à gauche de la carte : dans la carte il entrait en
   concurrence avec le format et l'état. */
.bhbr-canvas .bhbr-no {
    left: -13px; top: 50%; transform: translateY(-50%);
    z-index: 2;
}

/* Une exemption tient sur une seule ligne. */
.bhbr-match--slim { display: flex; align-items: center; gap: 8px; padding: 4px 8px; }
.bhbr-match--slim .bhbr-camp { flex: 1; min-width: 0; height: auto; }
.bhbr-bye-tag {
    flex: none; font-size: .5rem; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: var(--text-faint);
}

.bhbr-col-head--final { border-color: var(--border-input); background: var(--bg-chip); }
.bhbr-col-head--final .bhbr-col-title { color: var(--accent-light); }

.bhbr-col {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 190px;
}
/* En-tête de colonne (17a) : le titre du tour ET ce qu'il contient — « 5 matchs · 3 exemptions ».
   Sans le compte, une colonne trouée par des exemptions se lit comme une colonne incomplète. */
.bhbr-col-head {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    height: 30px; padding: 0 11px; border-radius: var(--radius);
    border: 0.5px solid var(--border); background: var(--bg-surface);
}
.bhbr-col-title {
    font-size: .74rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--text-secondary); white-space: nowrap;
}
.bhbr-col-count { font-size: .62rem; color: var(--text-faint); white-space: nowrap; }

/* ── Bandeau de légende + suivi de camp (17a) ─────────────────────────────── */
.bhbr-legend {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 9px 0 12px; margin-bottom: 4px;
    border-bottom: 0.5px solid var(--border);
}
.bhbr-legend-label {
    font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint);
}
.bhbr-legend-item {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: .68rem; color: var(--text-soft);
}
.bhbr-legend-win { width: 11px; height: 11px; border-radius: var(--radius); background: var(--accent-hover); }
.bhbr-legend-path { width: 14px; height: 2px; border-radius: var(--radius); background: var(--accent); }
.bhbr-legend-bye { width: 11px; height: 11px; border-radius: var(--radius); border: 1px dashed var(--border-hover); }
.bhbr-legend-num {
    min-width: 14px; height: 11px; display: grid; place-items: center; padding: 0 2px;
    border-radius: var(--radius); border: 0.5px solid var(--border); background: var(--bg-surface);
    font-size: .5rem; font-weight: 600; color: var(--text-faint);
}
.bhbr-legend-note { margin-left: auto; font-size: .66rem; color: var(--text-faint); }

.bhbr-tracking {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin: 10px 0 2px; padding: 8px 12px; border-radius: var(--radius);
    border: 0.5px solid var(--border-input); background: var(--accent-subtle);
    font-size: .72rem; color: var(--accent-light);
}
.bhbr-linkbtn {
    border: 0; background: transparent; cursor: pointer; padding: 0;
    font: inherit; color: var(--accent); text-decoration: underline;
}

/* Le numéro de match vit à GAUCHE de la carte, pas dedans : dans la carte il entrait en concurrence
   avec le format et le statut, qui portent l'information utile au joueur. */
.bhbr-slot { position: relative; padding-left: 20px; }
.bhbr-canvas .bhbr-match {
    width: 100%; height: 100%; box-sizing: border-box; position: relative;
    display: flex; flex-direction: column; justify-content: center; gap: 0;
    padding: 0; overflow: hidden;
}
/* Pastilles flottantes : la carte de 17a n'a que DEUX lignes, elles ne peuvent pas en prendre une. */
.bhbr-tag--float, .bhbr-livetag { position: absolute; right: 0; top: -17px; z-index: 3; }
.bhbr-livetag {
    display: inline-flex; align-items: center; gap: 5px; padding: 2px 7px;
    border-radius: var(--radius); border: 0.5px solid var(--border-input); background: var(--bg-chip);
    font-size: .5rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--accent-light);
}
.bhbr-livetag--pending {
    border-color: var(--gold-fg); color: var(--gold-fg);
    background: color-mix(in srgb, var(--gold-fg) 14%, transparent);
}
.bhbr-livetag--disputed {
    border-color: var(--red-fg); color: var(--red-fg);
    background: color-mix(in srgb, var(--red-fg) 14%, transparent);
}
/* 🔴 La hauteur vient de la GEOMETRIE, pas du contenu : si le DOM se dimensionnait tout seul, les
   cartes se toucheraient dès que le rendu dépasse la hauteur supposée — vu à l'écran. */
.bhbr-no {
    position: absolute; left: 0; top: 10px;
    min-width: 16px; height: 16px; display: grid; place-items: center; padding: 0 3px;
    border-radius: var(--radius); border: 0.5px solid var(--border); background: var(--bg-surface);
    font-size: .55rem; font-weight: 600; color: var(--text-faint);
}
.bhbr-slot--path .bhbr-no { border-color: var(--border-input); color: var(--accent-light); }
.bhbr-slot--path .bhbr-match { border-color: var(--accent); }

/* États de 17b. « pending » et « disputed » se dérivent des déclarations ; le délai de 15 min de la
   maquette n'existe pas dans le modèle et n'est donc pas annoncé. */
.bhbr-state {
    height: 15px; padding: 0 6px; display: inline-grid; place-items: center; flex: none;
    border-radius: var(--radius); font-size: .52rem; font-weight: 600; letter-spacing: .05em;
    text-transform: uppercase; white-space: nowrap;
}
.bhbr-state--todo { background: var(--bg-elevated); color: var(--text-muted); }
.bhbr-state--live { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.bhbr-state--pending { background: color-mix(in srgb, var(--gold-fg) 16%, transparent); color: var(--gold-fg); }
.bhbr-state--disputed { background: color-mix(in srgb, var(--red-fg) 16%, transparent); color: var(--red-fg); }
.bhbr-state--done { background: color-mix(in srgb, var(--green-fg) 14%, transparent); color: var(--green-fg); }
.bhbr-state--bye, .bhbr-state--skipped { background: transparent; color: var(--text-faint); border: 0.5px dashed var(--border); }

/* ── En-tête de l'écran d'arbre (17a) ─────────────────────────────────────── */
.bhbr-head {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding-bottom: 14px; margin-bottom: 12px; border-bottom: 0.5px solid var(--border);
}
.bhbr-head-title {
    margin: 0; font-size: 1.5rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .01em; color: var(--text-primary);
}
.bhbr-head-axes { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 8px; }
.bhbr-head-note { font-size: .62rem; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.bhbr-badge {
    height: 17px; padding: 0 7px; display: grid; place-items: center; flex: none;
    border-radius: var(--radius); font-size: .55rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.bhbr-badge--mode { background: color-mix(in srgb, var(--gold-fg) 14%, transparent); color: var(--gold-fg); }
.bhbr-badge--fee { background: color-mix(in srgb, var(--green-fg) 14%, transparent); color: var(--green-fg); }
.bhbr-head-pot { margin-left: auto; text-align: right; }
.bhbr-head-pot-lbl {
    display: block; font-size: .53rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint);
}
.bhbr-head-pot-val {
    display: block; margin-top: 6px; font-size: 1.05rem; font-weight: 700;
    font-variant-numeric: tabular-nums; color: var(--green-fg);
}
.bhbr-live {
    display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 12px; flex: none;
    border-radius: var(--radius); border: 0.5px solid var(--border-input); background: var(--bg-chip);
    font-size: .62rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--accent-light);
}
.bhbr-live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green-fg); }

/* ── Répartition de la cagnotte, sous l'arbre (17a) ───────────────────────── */
.bhbr-pot {
    margin-top: 20px; padding: 16px 18px; max-width: 420px;
    border: 0.5px solid var(--border); border-radius: var(--radius); background: var(--bg-surface);
}
.bhbr-pot-title {
    font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint);
}
.bhbr-pot-rows { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 12px; }
.bhbr-pot-row {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding-bottom: 8px; border-bottom: 0.5px solid var(--border);
}
.bhbr-pot-row:last-child { border-bottom: 0; padding-bottom: 0; }
.bhbr-pot-rank { font-size: .78rem; color: var(--text-secondary); }
.bhbr-pot-amount { font-size: .9rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.bhbr-pot-row:first-child .bhbr-pot-amount { color: var(--gold-fg); }
.bhbr-pot-note { font-size: .66rem; line-height: 1.5; color: var(--text-muted); }

.bhbr-match {
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    background: var(--surface-2);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.bhbr-match--current { border-color: var(--gold-fg); box-shadow: 0 8px 24px var(--shadow-strong); }
.bhbr-match--done { border-color: var(--line-strong); }
.bhbr-match--bye { opacity: .75; border-style: dashed; }
/* Le reset qui n'a pas eu lieu reste LISIBLE, seulement estompé : le masquer ferait
   croire à une finale sèche et fausserait la lecture du tableau. */
.bhbr-match--skipped { opacity: .45; border-style: dashed; }

.bhbr-match-head { display: flex; align-items: center; gap: 6px; }
.bhbr-fmt { font-size: .68rem; color: var(--text-hint); letter-spacing: .06em; }
.bhbr-tag {
    font-size: .62rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: var(--radius);
    background: var(--accent-subtle);
    color: var(--accent);
}
.bhbr-tag--off { background: transparent; color: var(--text-faint); border: 1px solid var(--line-soft); }

/* La ligne de camp telle que 17a la dessine : deux lignes à RAS BORD séparées d'un filet, et le
   score en BLOC pleine hauteur collé au bord droit. Des lignes avec du padding et un score en texte
   libre ne donnaient pas la lecture en colonnes qui fait qu'on trouve le score sans le chercher. */
.bhbr-camp {
    display: flex;
    align-items: center;
    gap: 0;
    height: 27px;
    min-width: 0;
    cursor: pointer;
}
.bhbr-camp + .bhbr-camp { border-top: 1px solid var(--bg-elevated); }
.bhbr-camp:hover { background: var(--bg-hover); }
.bhbr-camp--win { background: var(--accent-subtle); }
.bhbr-camp--none { color: var(--text-faint); font-style: italic; cursor: default; }
/* Le camp suivi est éclairé sur TOUTES ses cartes : c'est ce qui remplace les lignes de « chemin
   qualifié » de la maquette, que notre mise en page en grille ne peut pas tracer. */
.bhbr-camp--tracked { box-shadow: inset 0 0 0 1px var(--accent); }
/* Colonne du numéro de camp : largeur fixe, pour que les noms s'alignent d'une ligne à l'autre. */
.bhbr-camp-no {
    width: 23px; flex: none; text-align: center;
    font-size: .56rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-ghost);
}
.bhbr-camp--win .bhbr-camp-no { color: var(--accent-light); }
/* Niveau de barème : en gris devant le pseudo, sans manger sa place (maquette 17a). */
.bhbr-lvl {
    font-size: .53rem; font-weight: 600; font-variant-numeric: tabular-nums;
    color: var(--text-faint); margin-right: 5px;
}
.bhbr-camp-name span + .bhbr-lvl { margin-left: 4px; }
.bhbr-camp-x { color: var(--text-ghost); margin: 0 2px; }
.bhbr-camp-name {
    flex: 1;
    padding-right: 8px;
    font-size: .72rem;
    font-weight: 500;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.bhbr-camp--win .bhbr-camp-name { color: var(--text-bright); font-weight: 600; }

/* Le score est un BLOC, pas un texte : c'est lui qui donne la colonne de droite de 17a.
   ⚠️ Fond `--accent` et non le bleu profond de la maquette : c'est la seule paire documentée avec
   `--on-accent`, donc la seule qui garde un contraste correct dans les DEUX thèmes. */
.bhbr-camp-score {
    width: 28px; flex: none; align-self: stretch;
    display: grid; place-items: center;
    font-size: .68rem; font-weight: 700; font-variant-numeric: tabular-nums;
    background: var(--bg-elevated); color: var(--text-faint);
}
.bhbr-camp--win .bhbr-camp-score { background: var(--accent); color: var(--on-accent); }

/* ── Écran du tirage des matchs (US #646) ─────────────────────────────────
   Barre d'état + actions au-dessus de l'arbre. La barre s'enroule plutôt que de
   forcer une largeur : elle vit au-dessus d'un conteneur qui défile déjà, et un
   deuxième défilement horizontal rendrait la page illisible. */
.bhmd-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
    min-width: 0;
}
.bhmd-state { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.bhmd-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.bhmd-seed {
    font-size: .72rem;
    color: var(--text-hint);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
    min-width: 0;
}

.bhmd-note {
    color: var(--text-muted);
    font-size: .82rem;
    margin: 0 0 12px;
}

/* ── Jauge de relance du tirage des matchs (US #644/#646) ─────────────────
   La jauge se lit d'un coup d'œil pendant que le compte à rebours descend :
   les montants et le minuteur restent sur une seule ligne, qui s'enroule
   plutôt que de forcer une largeur. */
.bhmd-eco {
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 14px;
    min-width: 0;
}
.bhmd-eco-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; min-width: 0; }
.bhmd-eco-label { font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-hint); }
.bhmd-eco-amounts { font-variant-numeric: tabular-nums; color: var(--text-bright); font-weight: 600; }

.bhmd-timer {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-size: 1.05rem;
    color: var(--text-body);
}
.bhmd-timer--urgent { color: var(--gold-fg); }

.bhmd-eco-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--line-soft);
    overflow: hidden;
    margin: 10px 0 6px;
}
.bhmd-eco-bar > span { display: block; height: 100%; background: var(--accent); }
.bhmd-eco-rest { font-size: .76rem; color: var(--text-muted); }

.bhmd-bet { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; min-width: 0; }

/* Carte de match cliquable : seulement quand l'hôte a branché un lien. Sans href, l'ancre reste
   une carte inerte — pas de curseur main sur un écran public où il n'y a rien à ouvrir. */
.bhbr-match { color: inherit; text-decoration: none; }
.bhbr-match--link { cursor: pointer; }
.bhbr-match--link:hover { border-color: var(--accent); }

/* ── Page de match (US #639) ──────────────────────────────────────────────── */
/* Vu à l'écran : sans plafond, les deux camps s'étiraient sur 1214 px pour un match à deux
   équipes — deux boutons pleine fenêtre qu'on vise mal et qui ne se comparent plus d'un coup
   d'œil. C'est un formulaire court, pas une colonne de lecture : pas de --page-max ici. */
.bhmp-card {
    max-width: 520px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
.bhmp-camp {
    /* Un <button> n'hérite NI de la police NI de la taille : sans cette ligne le nom des joueurs
       s'affichait en Arial 13 px sur la page de match, et en Inter dans l'arbre juste à côté —
       les mêmes pseudos dans deux polices. Le reste du chrome de l'app est logé à la même
       enseigne, mais c'est un sujet global, pas celui de cet écran. */
    font: inherit;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    text-align: left;
    padding: 12px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line-soft);
    background: var(--surface-2);
    color: var(--text-body);
    cursor: pointer;
    min-width: 0;
}
.bhmp-camp:disabled { opacity: .5; cursor: not-allowed; }
.bhmp-camp--picked { border-color: var(--accent); }
.bhmp-camp--win { background: var(--accent-subtle); }
.bhmp-camp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.bhmp-camp-badge {
    font-size: .62rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--on-accent);
}

.bhmp-score { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
/* .input-sm fait 180 px : la largeur d'un champ texte, pour saisir un nombre de manches qui ne
   dépasse jamais 3. Deux champs de 180 px cadraient la saisie comme le geste principal, alors
   que le score est facultatif. */
.bhmp-score .input-sm { width: 64px; }
.bhmp-score-label { font-size: .76rem; color: var(--text-muted); }
.bhmp-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.bhmp-back { align-self: flex-start; margin-top: 14px; }

/* ── Manches, en gestion automatique (US #680) ────────────────────────────────
   Le compteur en tête, la liste des manches dessous, la saisie en bas. Le score y est GROS et les
   manches en petit : c'est le score que tout le monde vient lire, la liste ne sert qu'à savoir d'où
   il vient et à le corriger. */
.bhmp-tally {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: 10px;
}
.bhmp-tally-camp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.bhmp-tally-camp--right { text-align: right; }
.bhmp-tally-score { font-size: 1.5rem; font-weight: 600; white-space: nowrap; }
.bhmp-tally-note { font-size: .76rem; color: var(--text-muted); }
.bhmp-tally-empty { font-size: .82rem; color: var(--text-muted); }

.bhmp-round-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
/* Grille et non flex, pour la même raison que la liste des déclarations : sans colonnes fixes, un
   pseudo long décale l'état et les boutons d'une ligne à l'autre.

   ⚠️ Le nom du déclarant est sur une SECONDE ligne, pas à côté de l'état. Mesuré sur la carte de
   520 px : à cinq colonnes, une manche en attente (« Corriger » + « Valider », 156 px de boutons)
   ne laissait que 84 px au « saisie par … », qui partait en points de suspension — et il partait
   précisément sur les manches non validées, celles où savoir qui a déclaré est le plus utile.
   Le rang et les boutons enjambent les deux lignes pour rester alignés d'une manche à l'autre. */
.bhmp-round {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas:
        "no win state do"
        "no who who   do";
    align-items: center;
    column-gap: 8px;
    row-gap: 2px;
    font-size: .82rem;
    padding: 6px 8px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    min-width: 0;
}
/* Un liseré, pas un aplat. Mesuré en thème clair : sur --accent-subtle, le texte en --text-muted
   tombait à 3,81:1 là où il sort à 4,36:1 sur la surface de la carte — la ligne validée devenait la
   moins lisible de la liste, alors que c'est la seule qui compte pour le score. Le liseré est posé
   en ombre interne pour ne décaler aucun texte d'une ligne à l'autre. */
.bhmp-round--ok { box-shadow: inset 3px 0 0 var(--accent); }
/* Une manche nulle est jouée mais n'a rien tranché : elle mérite d'être repérable dans la liste sans
   se confondre avec une manche gagnée. Liseré neutre, même mécanique que --ok pour ne rien décaler ;
   la règle vient APRÈS --ok pour qu'une nulle validée porte bien la marque de la nulle. */
.bhmp-round--draw { box-shadow: inset 3px 0 0 var(--text-muted); }
.bhmp-round-no { grid-area: no; align-self: center; font-weight: 500; white-space: nowrap; }
/* Les deux cumuls, sous le rang : c'est d'eux que sort l'issue. En chiffres tabulaires pour que les
   colonnes ne dansent pas d'une manche à l'autre.

   ⚠️ Couleur du corps de texte, PAS --text-muted — même raison que .bhmp-round-state. Mesuré sur la
   sonde : le muté sort à 3,5:1 en thème sombre, sous le seuil AA pour un texte de cette taille. Le
   passer en muté ferait du chiffre qui DÉCIDE la manche le moins lisible de la ligne. */
.bhmp-round-tally {
    display: block;
    font-size: .74rem;
    font-variant-numeric: tabular-nums;
}
.bhmp-round-win { grid-area: win; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Couleur du corps de texte, pas --text-muted : « validée » / « en attente » est l'information de
   la ligne, pas une mention secondaire. */
.bhmp-round-state { grid-area: state; white-space: nowrap; }
.bhmp-round-who {
    grid-area: who;
    color: var(--text-muted);
    font-size: .74rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.bhmp-round-do { grid-area: do; align-self: center; display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
/* Mesuré à 375 px : « Corriger » + « Valider » font 156 px, et sur une carte de 327 px il ne restait
   que 37 px au nom du déclarant — de nouveau coupé, de nouveau sur la manche en attente. En dessous
   de cette largeur les boutons passent sous la ligne au lieu de la comprimer. */
@media (max-width: 560px) {
    .bhmp-round {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "no  win  state"
            "no  who  who"
            "do  do   do";
    }
    .bhmp-round-do { justify-content: flex-start; margin-top: 4px; }
}

.bhmp-declare {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--line-soft);
    min-width: 0;
}
/* Les deux camps CÔTE À CÔTE, là où le mode manuel les empile. Vu à l'écran : empilés, deux pavés
   pleine largeur de 486 px prenaient plus de place que le déroulé des manches qu'ils complètent,
   alors qu'ici le choix se répète à chaque manche. `auto-fit` les remet l'un sous l'autre quand la
   carte descend sous les deux fois 180 px, plutôt que de les écraser. */
.bhmp-declare-camps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 8px;
    min-width: 0;
}
.bhmp-declare-camps .bhmp-camp { padding: 10px 12px; }

/* ── Saisie des frags (US #701) ───────────────────────────────────────────────
   Un joueur par ligne, son champ à droite. Grille et non flex : les champs doivent s'aligner d'un
   joueur à l'autre, sinon un pseudo long décale le sien et la colonne part en escalier. */
.bhmp-frag-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.bhmp-frag {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px;
    align-items: center;
    column-gap: 8px;
    min-width: 0;
}
.bhmp-frag-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; font-size: .86rem; }
/* La largeur est portée par la piste de la grille, pas par le champ : un `width` ici rendrait la
   colonne dépendante du style d'input hérité, qui varie d'un navigateur à l'autre. */
.bhmp-frag-input { width: 100%; text-align: right; font-variant-numeric: tabular-nums; }
.bhmp-report-label {
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bhmp-report-total { font-size: .82rem; font-weight: 600; font-variant-numeric: tabular-nums; }
/* La règle du jeu, écrite là où le geste se fait : sans elle, un joueur laisse un coéquipier vide en
   croyant que « rien » vaut « zéro », et l'Api refuse un rapport qu'il croyait complet. */
.bhmp-report-hint { font-size: .74rem; color: var(--text-muted); }

/* ── Déclarations remontées de Discord (US #640) ──────────────────────────────
   Volontairement SOBRE, et sous la carte de saisie : ce ne sont pas des résultats. Leur donner
   l'apparence d'un score les ferait lire comme un verdict, alors que l'organisateur reste seul à
   trancher. */
.bhmp-decl {
    max-width: 520px;
    margin-top: 16px;
    padding: 12px 14px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}
.bhmp-decl-head { display: flex; flex-direction: column; gap: 3px; }
.bhmp-decl-kicker {
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* --text-body et non --text-faint : mesuré, ce dernier sort à 2,35:1 en thème clair. Or c'est LA
   phrase qui empêche l'organisateur de prendre une liste de « a gagné » pour un résultat acté — la
   rendre discrète serait exactement le contraire de ce que l'US demande. */
.bhmp-decl-note { font-size: .76rem; color: var(--text-body); }
/* Paire --tint-gold-bg-2 / --gold-on-tint : la seule du thème dont le contraste est vérifié AA dans
   les DEUX thèmes (cf. le commentaire de :root). Un doré posé sur autre chose repasserait sous le
   seuil en thème clair. */
.bhmp-decl-clash {
    font-size: .78rem;
    padding: 7px 10px;
    border-radius: var(--radius);
    border: 1px solid var(--tint-gold-border);
    background: var(--tint-gold-bg-2);
    color: var(--gold-on-tint);
}
.bhmp-decl-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
/* Grille plutôt que flex : les quatre colonnes s'alignent d'une ligne à l'autre, sinon les pseudos
   de longueurs différentes décalent tout le reste et la liste devient illisible. */
.bhmp-decl-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto auto;
    align-items: baseline;
    gap: 8px;
    font-size: .82rem;
}
.bhmp-decl-who { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhmp-decl-camp { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhmp-decl-said--won { color: var(--accent); }
.bhmp-decl-said--lost { color: var(--text-muted); }
.bhmp-decl-when { color: var(--text-faint); font-size: .74rem; }

/* ── Forme de l'arbre sur l'écran du tirage (US #634) ─────────────────────────
   Réutilise .tour-switches / .tour-switch et .tour-bo-pick de l'étape « Arbre » de la création :
   ce sont les mêmes réglages à deux moments du parcours, et deux apparences pour un même geste se
   liraient comme deux fonctions différentes. */
.bhmd-set {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 14px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    min-width: 0;
}
.bhmd-set-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.bhmd-set-kicker {
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bhmd-set-frozen { font-size: .76rem; color: var(--text-faint); }

/* auto-fit plutôt qu'un nombre de colonnes fixe : six faits tiennent sur une ligne au large et se
   replient sans media query. */
.bhmd-set-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
    gap: 8px;
}
.bhmd-set-fact {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px;
    border-radius: var(--radius);
    background: var(--surface-2);
    min-width: 0;
}
.bhmd-set-fact span { font-size: .72rem; color: var(--text-muted); }
.bhmd-set-fact strong { font-size: 1.05rem; }

/* 272px et non 210 : mesuré à l'écran, « Finale des finales — reset » réclame 143 px de libellé et
   n'en recevait que 121 — dix libellés sur douze étaient coupés en 1280 comme en 768, alors qu'ils
   passaient en 375. Le libellé dit QUEL format on règle : tronqué, le sélecteur ne veut plus rien
   dire. */
.bhmd-set-formats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
    gap: 8px;
}
.bhmd-set-format { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
/* Le libellé revient à la ligne plutôt que de se faire couper : une traduction plus longue que le
   français doit s'afficher en entier, quitte à prendre deux lignes. Une ellipse la perdrait, et sur
   tactile il n'y a pas de survol pour la retrouver. */
.bhmd-set-format-label {
    font-size: .8rem;
    color: var(--text-body);
    min-width: 0;
}
.bhmd-set-apply { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bhmd-set-dirty { font-size: .76rem; color: var(--text-muted); }

/* ─── Tirage live `.bhtl-` (maquette TirageLive.dc.html) ───────────────────────────────────────
   Corps de l'écran 3a, resté non dessiné jusqu'à cette maquette (son `dc-import name="TirageLive"`
   n'était pas résolu). Deux colonnes : la SALLE à gauche (formations + saisie des mises), la
   CONDUITE à droite (cagnotte, relance, actions organisateur).
   Entièrement tokenisé : les hex de la maquette SONT les tokens du thème sombre, le thème clair
   suit sans reprise (même règle que `.tour-` et `.bhog-`). */
/* 🔴 PLEIN CADRE, comme l'arbre d'un Wager (.bhlb-wide) et pour la même raison : seize formations
   de trois joueurs en quatre colonnes plus un rail de 348 px ne tiennent pas dans les 1180 px de la
   colonne de lecture. Bornées à --band-pad-inline, les cartes s'étranglaient pendant qu'un tiers de
   l'écran restait vide de chaque côté — sur un écran que la salle regarde projeté.
   Le padding est FIXE : --band-pad-inline recentre sur --page-max, donc reborne exactement ce
   qu'on veut libérer. Même fausse piste que celle déjà écartée pour l'arbre. */
.bhtl {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 348px;
    padding-inline: 40px;
    background: transparent;   /* laisse passer le fond animé de la page */
    align-items: start;
    /* `.pp-screen` est une colonne flex de hauteur fixe en `overflow:hidden` : sans ces trois
       lignes, une grille de seize formations déborde SANS ascenseur — le bas de l'écran devient
       inatteignable au lieu de défiler. */
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}
.bhtl-main {
    padding: 26px 32px 30px 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;
}
.bhtl-rail {
    border-left: 1px solid var(--border);
    padding: 26px 0 30px 24px;
    display: flex;
    flex-direction: column;
    gap: 22px;
    min-height: 100%;
}

/* Intitulé de section : mono, capitales, très espacé. Le seul style de titre de cet écran. */
.bhtl-kicker {
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-muted);
    flex: none;
}
.bhtl-kicker--on   { color: var(--accent-light); }
.bhtl-kicker--warn { color: var(--gold-fg); }
.bhtl-note {
    font: 400 10.5px/1.4 var(--font-alt);
    color: var(--text-muted);
}
.bhtl-sp { flex: 1; }
/* 🔴 Sauf dans le rail du cockpit, où ce séparateur valait à lui seul 350 à 448 px de VIDE
   (mesuré sur page-sonde à 16 et 48 formations) : il poussait les actions d'organisateur tout en
   bas, aussi loin que le plateau était haut. Il garde une respiration FIXE — assez pour que
   « Verrouiller le tirage » ne se clique pas à la place d'un bouton de chrono, sans creuser un
   trou qui grandit avec le nombre d'équipes. Mesuré après : 71 px entre le chrono et les actions,
   contre près de 500 avant.
   ⚠️ Ce vide n'était PAS la cause du débordement : le rail est étiré PAR la colonne principale,
   jamais l'inverse. Le supprimer ne fait pas tenir un plateau de plus — ça se mesure. */
.bhtl-rail .bhtl-sp { flex: 0 0 auto; height: 22px; }
.bhtl-count {
    font: 600 9.5px/1 var(--font-mono);
    color: var(--gold-fg);
}

.bhtl-seedline { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.bhtl-seed     { font: 400 11px/1 var(--font-alt); color: var(--text-muted); }
.bhtl-seed-val { font-family: var(--font-mono); color: var(--text-soft); }

.bhtl-error {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--tint-red-border);
    background: var(--tint-red-bg);
    color: var(--red-soft-fg);
    font: 500 12px/1.4 var(--font-alt);
}

/* ── Grille des formations ── */
/* 🔴 `auto-fill` sur un PLANCHER de largeur, jamais un nombre de colonnes figé : un Switcheroo
   fait 16 formations, un Battle Royale de 150 joueurs en fait 50. Le plancher vient du composant
   (--bhtl-min) et se resserre avec le plateau ; la grille s'adapte en plus à la fenêtre, ce qu'un
   compte de colonnes ne fait jamais. */
.bhtl-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--bhtl-min, 230px), 1fr));
    gap: var(--bhtl-gap, 11px);
    /* 🔴 Le PLAFOND de colonnes, sans lequel `auto-fill` étale 16 formations sur sept colonnes de
       trois rangées sur un écran de 1920 — la maquette en pose quatre. Le plafond commande sur
       écran large, le plancher (--bhtl-min) reprend la main dès que la fenêtre se resserre : c'est
       lui qui fait le reflux. Le facteur 1,2 laisse les cartes respirer un peu au-delà de leur
       plancher au lieu de les figer à la largeur minimale. */
}

/* Au-delà de 24 formations : mêmes informations, moins de place perdue. Resserrer les colonnes ne
   suffit pas — c'est la HAUTEUR cumulée qui fait déborder un plateau de 50. */
.bhtl-grid--dense { --bhtl-gap: 8px; }
/* 🔴 Au-delà de 1500 px, on POSE le nombre de colonnes au lieu de le laisser déduire. Les deux
   réglages ne se disputent plus la même largeur : le plancher sert la fenêtre étroite (à 1280,
   seize formations retrouvent quatre colonnes), le plafond sert l'écran large (sans lui, ces mêmes
   seize s'étalaient sur sept colonnes de trois rangées, là où la maquette en pose quatre).
   Tenté d'abord par un `max-width` calculé : `auto-fill` glisse une colonne de plus dès qu'il
   reste la place d'un plancher, le plafond ne mordait pas. */
@media (min-width: 1500px) {
    .bhtl-grid { grid-template-columns: repeat(var(--bhtl-maxcols, 4), minmax(0, 1fr)); }
}

.bhtl-grid--dense .bhtl-team { padding: 9px 10px; gap: 6px; }
.bhtl-grid--dense .bhtl-team-name { font-size: 14px; }
.bhtl-grid--dense .bhtl-team-tag { display: none; }
.bhtl-grid--dense .bhtl-slot { height: 18px; gap: 7px; }
.bhtl-grid--dense .bhtl-slot-name { font-size: 11px; }
.bhtl-team {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 13px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    min-width: 0;
    /* Apparition en cascade : le tirage est le moment de spectacle de la soirée, les formations
       tombent une par une au lieu d'apparaître d'un bloc. Les cartes portent `@key="team.Id"`,
       donc un nouveau tirage les RECRÉE et l'animation rejoue d'elle-même.
       Livrée en US #182 sur `.pp-team-card`, perdue à la refonte des écrans de conduite. */
    /* 🔑 DEUX animations, dont la seconde est un trou : les formations marquées y versent leur
       pulsation (--bhtl-team-pulse, posé par les modificateurs juste dessous). Écrite ainsi, et
       non sur les modificateurs, pour deux raisons qui comptent autant l'une que l'autre :
       • `animation` est une propriété, pas une liste cumulative — une déclaration sur
         `.bhtl-team--strong` REMPLACERAIT celle-ci, et la carte marquée perdrait son entrée en
         cascade au respin suivant, qui la recrée ;
       • le refus d'animation (`prefers-reduced-motion`, plus bas) vise `.bhtl-team` : tout ce qui
         passe par ici s'y éteint SANS RIEN AJOUTER. Une animation déclarée sur un modificateur
         échapperait au garde-fou, en silence.
       Le repli `none` n'est pas décoratif : sans lui, une carte non marquée rendrait la
       déclaration entière invalide au calcul, et perdrait AUSSI son entrée. */
    animation: bhtl-team-in .55s cubic-bezier(.22, .61, .36, 1) both, var(--bhtl-team-pulse, none);
    /* Le rang plafonne à 24 : à 50 ms par carte, un plateau de 50 formations aurait fait attendre
       2,5 s la dernière. Au-delà du plafond les cartes tombent ensemble, la cascade reste lue. */
    animation-delay: calc(min(var(--bhtl-team-i, 0), 24) * 50ms);
}
@keyframes bhtl-team-in {
    from { opacity: 0; transform: translateY(12px) scale(.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Une cascade de cinquante cartes est exactement ce que ce réglage système sert à éviter.
   🔑 Et cette seule ligne éteint AUSSI la pulsation des formations marquées, puisqu'elle passe
   par la même propriété : le marquage garde ses couleurs, seul le mouvement part. C'est ce qui
   interdit de déclarer `animation` sur un modificateur — il sortirait de ce filet. */
@media (prefers-reduced-motion: reduce) {
    .bhtl-team { animation: none; }
}
.bhtl-team--selected { border-color: var(--accent); }
/* 🔴 Marquer une équipe doit se voir sur la CARTE. Les variantes `.pp-team-card--*` portaient bien
   un fond, mais elles sont déclarées 4 800 lignes plus haut : à spécificité égale, `.bhtl-team`,
   plus tardive, reprenait la main sur `background` et `border-color`. Seul le nom changeait de
   teinte — un marquage qui ne marquait rien. Les variantes vivent donc ICI, dans le même
   namespace et juste après la règle de base. */
/* ⚠️ Et les DEUX marquages doivent se distinguer L'UN DE L'AUTRE. Ils partageaient la même bordure
   dorée et deux fonds voisins : à l'écran, « forte » et « la plus forte » se confondaient. Ils sont
   maintenant séparés par la TEINTE (orange contre doré) autant que par l'intensité, et chacun porte
   un liseré vertical — un repère de structure, que la couleur seule ne donne pas (et qui reste lisible
   pour un œil qui distingue mal l'orange du doré). */
/* 🔴 UNE PULSATION, PAS UN CLIGNOTEMENT. Le plateau est projeté en salle : un flash rapide y est
   à la fois une gêne et un risque (WCAG 2.3.1 borne à trois flashs par seconde ; on est ici à
   moins d'un demi-hertz). Même parti que `.lb2-row--mp`, la ligne encore en Match Point du
   classement — c'est la pulsation maison, autant s'en tenir à une seule.
   ⚠️ Les images-clés ne touchent QUE `box-shadow` et `border-color`, jamais une propriété de
   mise en page. Animer la bordure ou le padding ferait respirer la grille entière au rythme du
   marquage — c'est déjà pour ça que `--strongest` compense ses 2px de bordure par son padding. */
.bhtl-team--strong {
    border-color: var(--tint-orange-border);
    background: linear-gradient(135deg, var(--tint-orange-bg) 0%, var(--bg-panel) 72%);
    box-shadow: inset 3px 0 0 var(--orange-fg);
    --bhtl-team-pulse: bhtl-strong-pulse 2.4s ease-in-out infinite;
}
@keyframes bhtl-strong-pulse {
    0%, 100% { border-color: var(--tint-orange-border); box-shadow: inset 3px 0 0 var(--orange-fg); }
    50%      { border-color: var(--orange-fg); box-shadow: inset 3px 0 0 var(--orange-fg), 0 0 0 4px var(--tint-orange-bg); }
}
.bhtl-team--strongest {
    border-color: var(--gold-fg);
    /* Bordure épaissie et padding réduit d'autant : la carte ne change pas de taille en étant marquée,
       sinon la grille se réorganise sous le clic. */
    border-width: 2px;
    padding: 12px;
    background: linear-gradient(135deg, var(--tint-gold-bg-2) 0%, var(--tint-gold-bg) 55%, var(--bg-panel) 100%);
    box-shadow: inset 5px 0 0 var(--gold-fg), 0 0 0 3px var(--tint-gold-bg);
    /* Plus court que la forte : il n'y en a QU'UNE, et elle doit se distinguer des autres
       marquées autant que des non marquées. On reste loin du flash — 0,56 Hz contre 0,42. */
    --bhtl-team-pulse: bhtl-strongest-pulse 1.8s ease-in-out infinite;
}
@keyframes bhtl-strongest-pulse {
    0%, 100% { box-shadow: inset 5px 0 0 var(--gold-fg), 0 0 0 3px var(--tint-gold-bg); }
    50%      { box-shadow: inset 5px 0 0 var(--gold-fg), 0 0 0 8px var(--tint-gold-bg-2); }
}
.bhtl-team--strongest .bhtl-team-name { color: var(--gold-on-tint); }
.bhtl-grid--dense .bhtl-team--strongest { padding: 8px 9px; }
/* La maquette n'a que le nom et l'état sur cette ligne ; nous y gardons en plus les deux repères
   d'équilibrage. À 200 px de carte les quatre ne tiennent pas, et sans `wrap` c'est le NOM qui
   s'écrase — le seul élément qu'on ne peut pas se permettre de perdre. Il garde donc la première
   ligne pour lui, l'état et les repères passent dessous quand la place manque. */
.bhtl-team-head { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
/* Le nom peut être enveloppé par la fiche au survol (`.phc`) : la contrainte de largeur doit
   traverser l'enveloppe, sinon un nom long pousse l'état hors de la carte. */
.bhtl-team-head > .phc { flex: 1 1 auto; min-width: 0; overflow: hidden; }
.bhtl-team-head > .phc > .phc-trigger { display: block; min-width: 0; overflow: hidden; }
.bhtl-team-name {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    font: 700 17px/1 var(--font-display);
    text-transform: uppercase;
    color: var(--bhtl-accent, var(--accent-light));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bhtl-team-tag {
    margin-left: auto;
    flex: none;
    font: 500 8.5px/1 var(--font-mono);
    letter-spacing: .1em;
    color: var(--text-faint);
}
.bhtl-team-marks { display: flex; gap: 1px; flex: none; }
.bhtl-ts {
    background: none;
    border: 0;
    padding: 2px 3px;
    border-radius: var(--radius);
    line-height: 1;
    font-size: 12px;
    color: var(--text-ghost);
    cursor: pointer;
    transition: color .12s;
}
.bhtl-ts:hover        { color: var(--text-body); }
.bhtl-ts--strong      { color: var(--gold-fg); }
.bhtl-ts--best        { color: var(--accent); }

.bhtl-slot {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 22px;
    min-width: 0;
    border-radius: var(--radius);
    cursor: pointer;
}
.bhtl-slot-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--bhtl-accent, var(--accent));
    display: block;
    flex: none;
}
.bhtl-slot > .phc { flex: 1; min-width: 0; overflow: hidden; }
.bhtl-slot > .phc > .phc-trigger { display: block; min-width: 0; overflow: hidden; }
.bhtl-slot-name {
    display: block;
    font: 600 12px/1 var(--font-alt);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bhtl-slot-swap { flex: none; color: var(--text-faint); font-size: 12px; opacity: 0; transition: opacity .12s; }
.bhtl-slot:hover .bhtl-slot-swap { opacity: 1; }

/* ── Joueurs restants non répartis (Bogue #1250) ──
   🔴 Cette règle a été MASQUÉE pendant un temps par une seconde déclaration de `.bhtl-wait`,
   posée 460 lignes plus bas par la liste d'attente repliable : même sélecteur, `flex-direction:
   column`, et c'est elle qui gagnait. Le bloc s'empilait donc en colonne alors que cette
   déclaration-ci le dessine en rangée. La repliable est partie avec le Bogue #1247 ; sa feuille
   est partie avec le #1250, et la rangée revient.
   ⚠️ Deux déclarations du même sélecteur, c'est le piège déjà payé sur la taille du logo et sur
   la largeur de la recherche : corriger la première ne change rien à l'écran. */
.bhtl-wait { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.bhtl-wait-label {
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--gold-fg);
}
.bhtl-wchip {
    height: 21px;
    padding: 0 9px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: var(--bg-hover);
    font: 500 10.5px/1 var(--font-alt);
    color: var(--text-body);
}

/* ── Bloc des mises : saisie à gauche, encaissement à droite ── */
.bhtl-stakes {
    display: grid;
    grid-template-columns: 296px minmax(0, 1fr);
    gap: 22px;
    padding: 18px 20px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-panel);
}
.bhtl-stake-form { display: flex; flex-direction: column; gap: 11px; min-width: 0; }
.bhtl-stake-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    border-left: 1px solid var(--border);
    padding-left: 22px;
    min-width: 0;
}
.bhtl-stake-list-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }

.bhtl-input {
    height: 38px;
    width: 100%;
    box-sizing: border-box;
    padding: 0 12px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--bg-input);
    color: var(--text-primary);
    font: 500 12.5px/1 var(--font-alt);
    outline: none;
}
.bhtl-input:focus { border-color: var(--accent); }
.bhtl-stake-row { display: flex; gap: 9px; }
.bhtl-amount {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    height: 38px;
    min-width: 0;
    padding: 0 12px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--bg-input);
}
.bhtl-amount:focus-within { border-color: var(--accent); }
.bhtl-amount input {
    flex: 1;
    min-width: 0;
    width: 100%;
    border: 0;
    background: none;
    outline: none;
    padding: 0;
    color: var(--text-primary);
    font: 700 13px/1 var(--font-mono);
    -moz-appearance: textfield;
}
.bhtl-amount input::-webkit-outer-spin-button,
.bhtl-amount input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.bhtl-amount-unit { font: 500 10px/1 var(--font-mono); color: var(--text-muted); flex: none; }
.bhtl-add {
    flex: none;
    height: 38px;
    padding: 0 16px;
    border: 0;
    border-radius: var(--radius);
    background: var(--bg-chip);
    color: var(--accent-light);
    font: 600 12px/1 var(--font-alt);
    cursor: pointer;
}
.bhtl-add:hover:not(:disabled) { background: var(--border-input); }
.bhtl-add:disabled { color: var(--text-ghost); cursor: default; }
.bhtl-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.bhtl-preset {
    height: 24px;
    padding: 0 9px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: none;
    color: var(--text-body);
    font: 500 10.5px/1 var(--font-mono);
    cursor: pointer;
}
.bhtl-preset:hover:not(:disabled) { border-color: var(--border-input); color: var(--text-primary); }
.bhtl-preset:disabled { color: var(--text-ghost); cursor: default; }
.bhtl-hint { font: 400 10.5px/1.5 var(--font-alt); color: var(--text-soft); }

.bhtl-rows {
    display: grid;
    /* La carte est taillée sur le pseudo le PLUS LONG de la liste : l'écran pose dans
       `--bhtl-stake-name` la longueur du plus long en `ch`, qui s'ajoute aux ~280 px de
       commandes fixes de la ligne (avatar, montant, saisie, « − », « PAYÉ », « ↩ », toutes
       en `flex: none`). À 260 px en dur il ne restait rien pour le nom, coupé quelle que
       soit la largeur de l'écran.
       Deux bornes : 320 px pour qu'une liste de pseudos courts garde une carte lisible,
       640 px pour qu'un pseudo à rallonge ne réduise pas la liste à une seule colonne —
       au-delà c'est le repli à la ligne qui prend le relais, le nom reste entier.
       `min(100%, …)` empêche la piste de déborder sous 900 px, où la liste prend toute la
       largeur du panneau. */
    grid-template-columns:
        repeat(auto-fill, minmax(min(100%, clamp(320px, calc(280px + var(--bhtl-stake-name, 12ch)), 640px)), 1fr));
    /* `ch` se résout dans la police de CET élément : sans cette déclaration il vaudrait la
       taille héritée du panneau (16 px) et la piste sortirait ~40 % trop large. Aucun enfant
       n'en hérite — toutes les pièces de la ligne posent leur propre police. */
    font: 500 11.5px/1.3 var(--font-alt);
    gap: 8px;
    align-content: start;
    max-height: 168px;
    overflow-y: auto;
}
.bhtl-row {
    display: flex;
    align-items: center;
    /* Les commandes de la ligne occupent ~280 px incompressibles (elles sont toutes en
       `flex: none`). Quand la piste est plus étroite que ça — écran de téléphone —, elles
       passent à la ligne suivante au lieu d'écraser le pseudo à zéro pixel. Sans repli, la
       largeur manquante était prise sur le seul élément souple : le nom. */
    flex-wrap: wrap;
    gap: 8px;
    padding: 9px 10px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-input);
    min-width: 0;
}
.bhtl-row--slim { padding: 7px 0; border: 0; background: none; border-bottom: 1px solid var(--line-soft); border-radius: 0; }
.bhtl-row--settled { background: var(--bg-inset); }
.bhtl-av {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg-chip);
    display: grid;
    place-items: center;
    font: 600 9px/1 var(--font-alt);
    color: var(--accent-light);
    flex: none;
}
.bhtl-av--off { background: var(--surface-2); color: var(--text-muted); }
/* Le pseudo est la seule donnée qui dise À QUI encaisser : il ne se tronque jamais. Un nom
   trop long passe à la ligne au lieu de finir en « … », et `anywhere` casse aussi ceux qui
   n'ont aucune espace. Interligne 1 → 1.3 pour que deux lignes ne se touchent pas. */
.bhtl-row-name {
    /* Base 120 px, pas 0 : c'est elle qui décide du repli. À base nulle, le nom se laisse
       comprimer sans jamais provoquer de retour à la ligne, et la ligne « tient » en
       n'affichant plus rien. Sur une ligne assez large le rendu est inchangé — le nom reste
       le seul élément qui grandit, il récupère donc tout l'espace libre de la même façon. */
    flex: 1 1 120px;
    min-width: 0;
    font: 500 11.5px/1.3 var(--font-alt);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}
.bhtl-row-amount { font: 600 11px/1 var(--font-mono); color: var(--gold-fg); flex: none; }
.bhtl-row-amount--paid { color: var(--green-fg); }
.bhtl-row-input {
    width: 52px;
    flex: none;
    height: 26px;
    padding: 0 6px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-page);
    color: var(--text-primary);
    font: 500 10.5px/1 var(--font-mono);
    outline: none;
    -moz-appearance: textfield;
}
.bhtl-row-input::-webkit-outer-spin-button,
.bhtl-row-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.bhtl-row-part {
    flex: none;
    width: 24px;
    height: 26px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: none;
    color: var(--text-body);
    font: 600 12px/1 var(--font-mono);
    cursor: pointer;
}
.bhtl-row-part:disabled { color: var(--text-ghost); cursor: default; }
.bhtl-pay {
    flex: none;
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--tint-green-border);
    border-radius: var(--radius);
    background: var(--tint-green-bg);
    color: var(--green-fg);
    font: 600 9.5px/1 var(--font-mono);
    cursor: pointer;
}
.bhtl-pay:hover { border-color: var(--green-fg); }
.bhtl-undo {
    flex: none;
    width: 28px;
    height: 26px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: none;
    color: var(--text-soft);
    font: 500 13px/1 var(--font-alt);
    cursor: pointer;
}
.bhtl-undo:hover { color: var(--text-primary); border-color: var(--border-input); }
.bhtl-empty {
    display: block;
    padding: 16px 12px;
    border-radius: var(--radius);
    border: 1px dashed var(--border);
    font: 400 10.5px/1.5 var(--font-alt);
    color: var(--text-muted);
    text-align: center;
}
.bhtl-settled > summary {
    cursor: pointer;
    font: 500 10.5px/1 var(--font-alt);
    color: var(--text-muted);
    padding: 6px 0;
}
.bhtl-settled > .bhtl-row { margin-top: 6px; }

/* ── Barre de partie (après verrouillage) ── */
.bhtl-game {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding: 14px 18px;
    border-radius: var(--radius);
    border: 1px solid var(--border-input);
    background: var(--bg-panel);
}
.bhtl-game-code { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bhtl-game-code label { font: 500 10.5px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.bhtl-game-code input {
    height: 32px;
    width: 128px;
    padding: 0 10px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--bg-input);
    color: var(--text-primary);
    font: 700 12.5px/1 var(--font-mono);
    outline: none;
}
.bhtl-game-actions { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-left: auto; }
.bhtl-game-num { font: 600 11.5px/1 var(--font-alt); color: var(--text-body); display: flex; align-items: center; gap: 6px; }
.bhtl-pill {
    height: 24px;
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    font: 600 10px/1 var(--font-mono);
    color: var(--text-muted);
}
.bhtl-pill--on { border-color: var(--tint-green-border); background: var(--tint-green-bg); color: var(--green-fg); }

.bhtl-btn {
    height: 32px;
    padding: 0 13px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    color: var(--text-body);
    font: 600 11.5px/1 var(--font-alt);
    cursor: pointer;
    text-decoration: none;
}
.bhtl-btn:hover:not(:disabled) { color: var(--text-primary); border-color: var(--border-input); }
.bhtl-btn:disabled { color: var(--text-ghost); cursor: default; }
.bhtl-btn--go     { border-color: var(--tint-green-border); color: var(--green-fg); }
.bhtl-btn--accent { border-color: var(--border-input); color: var(--accent-light); }

/* ── Historique des tirages ── */
.bhtl-history > summary {
    cursor: pointer;
    font: 500 11px/1 var(--font-alt);
    color: var(--text-muted);
    padding: 8px 0;
}
.bhtl-history-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.bhtl-dh {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px 10px;
    border-radius: var(--radius);
    background: var(--bg-inset);
    font: 400 10.5px/1 var(--font-mono);
    color: var(--text-muted);
}
.bhtl-dh-label  { color: var(--text-body); }
.bhtl-dh-teams  { margin-left: auto; }
.bhtl-dh-status--locked    { color: var(--accent); }
.bhtl-dh-status--published { color: var(--green-fg); }

/* ── Rail : état, cagnotte, relance, actions ── */
.bhtl-status { display: flex; align-items: center; gap: 9px; }
.bhtl-status-dot { width: 6px; height: 6px; border-radius: 50%; display: block; flex: none; }
.bhtl-status-dot--open      { background: var(--green-fg); }
.bhtl-status-dot--locked    { background: var(--accent); }
.bhtl-status-dot--published { background: var(--gold-fg); }
.bhtl-status-label { font: 600 10px/1.4 var(--font-mono); letter-spacing: .1em; }
.bhtl-status-label--open      { color: var(--green-fg); }
.bhtl-status-label--locked    { color: var(--accent); }
.bhtl-status-label--published { color: var(--gold-fg); }

.bhtl-pot {
    padding: 18px;
    border-radius: var(--radius);
    border: 1px solid var(--border-input);
    background: linear-gradient(160deg, var(--accent-subtle), var(--bg-panel));
}
.bhtl-pot-val { font: 700 34px/1 var(--font-mono); color: var(--accent); margin-top: 10px; }
.bhtl-pot-row {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: 8px;
    font: 400 10.5px/1.3 var(--font-mono);
    color: var(--text-soft);
    text-transform: uppercase;
}
.bhtl-pot-row--sep { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.bhtl-pot-warn   { font-weight: 600; color: var(--gold-fg); }
.bhtl-pot-strong { font-weight: 600; color: var(--text-primary); }
/* Ce qui est RETENU sur la cagnotte, par opposition à ce qui reste à encaisser (doré, au-dessus) :
   même rouge que la ligne de commission de l'aperçu public (.bht-prow--minus), pour que la même
   retenue se lise pareil des deux côtés. */
.bhtl-pot-minus  { font-weight: 600; color: var(--red2-fg); }

.bhtl-spin {
    min-height: 52px;
    padding: 8px 14px;
    border: 0;
    border-radius: var(--radius);
    background: var(--accent-gradient);
    color: #fff;
    font: 600 14px/1.2 var(--font-alt);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
}
.bhtl-spin-sub { font: 500 10px/1 var(--font-mono); opacity: .82; }

.bhtl-unpaid {
    padding: 14px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--tint-gold-border);
    background: var(--tint-gold-bg);
}
.bhtl-unpaid .bhtl-row:last-child { border-bottom: 0; }

/* Le compte à rebours est la valeur que la SALLE regarde, et celle que l'organisateur doit pouvoir
   rallonger d'un geste sûr pendant que le tirage tourne. À 22 px il se lisait comme une ligne de
   détail parmi d'autres, et ses commandes de 26 px se visaient mal. */
.bhtl-timer { padding-top: 18px; border-top: 1px solid var(--border); }
.bhtl-timer-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.bhtl-timer-val { font: 700 40px/1 var(--font-mono); color: var(--text-primary); letter-spacing: -.01em; }
.bhtl-timer-btns { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.bhtl-tb {
    height: 34px;
    padding: 0 13px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: none;
    color: var(--text-body);
    font: 600 13px/1 var(--font-mono);
    cursor: pointer;
}
.bhtl-tb:hover:not(:disabled) { border-color: var(--border-input); color: var(--text-primary); }
.bhtl-tb:disabled { color: var(--text-ghost); cursor: default; }
.bhtl-tb--go { border-color: var(--tint-green-border); color: var(--green-fg); }

.bhtl-actions {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}
.bhtl-act {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 40px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: none;
    color: var(--text-soft);
    font: 600 12.5px/1 var(--font-alt);
    cursor: pointer;
    text-decoration: none;
}
.bhtl-act:hover { color: var(--text-primary); border-color: var(--border-input); }
.bhtl-act--primary { border-color: var(--line-strong); color: var(--text-primary); }
.bhtl-published {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 40px;
    border-radius: var(--radius);
    border: 1px solid var(--tint-green-border);
    background: var(--tint-green-bg);
    color: var(--green-fg);
    font: 600 12.5px/1 var(--font-alt);
}

/* ── Panneau de remplacement ── */
.bhtl-replace {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--border-input);
    background: var(--bg-panel);
}
.bhtl-replace-label { font: 500 11.5px/1 var(--font-alt); color: var(--text-body); }
.bhtl-replace-err   { font: 500 11px/1 var(--font-alt); color: var(--red-soft-fg); }
/* « Personne en liste d'attente » : ce n'est ni une erreur ni une alerte, seulement l'état des
   lieux — d'où l'encre discrète, celle des libellés secondaires, et non le rouge de -err. */
.bhtl-replace-hint  { font: 500 11px/1 var(--font-alt); color: var(--text-muted); }

.bhtl-arrow { color: var(--text-muted); }
.bhtl-select {
    height: 32px;
    padding: 0 9px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--bg-input);
    color: var(--text-primary);
    font: 500 11.5px/1 var(--font-alt);
}

/* Le rail passe sous la salle avant de devenir illisible : à 348 px fixes il écrase la grille
   des formations bien avant le seuil tablette. */
@media (max-width: 1180px) {
    .bhtl { grid-template-columns: minmax(0, 1fr); }
    .bhtl-main { padding: 22px 24px 24px; }
    .bhtl-rail { border-left: 0; border-top: 1px solid var(--border); padding: 22px 24px 28px; min-height: 0; }
    .bhtl-sp { display: none; }
}
@media (max-width: 900px) {
    .bhtl-stakes { grid-template-columns: minmax(0, 1fr); }
    .bhtl-stake-list { border-left: 0; padding-left: 0; border-top: 1px solid var(--border); padding-top: 16px; }
    .bhtl-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
    .bhtl-game-actions { margin-left: 0; }
}

/* ── Écran de validation des entrées (même grammaire que le tirage) ──────────────────────────── */
.bhtl-search { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px; border-radius: var(--radius); border: 1px solid var(--line-strong); background: var(--bg-input); color: var(--text-muted); }
.bhtl-search input { border: 0; background: none; outline: none; padding: 0; min-width: 180px; color: var(--text-primary); font: 500 12px/1 var(--font-alt); }

.bhtl-sect { display: flex; align-items: center; gap: 10px; }
.bhtl-sect-label { display: flex; align-items: center; gap: 7px; font: 700 13px/1 var(--font-display); text-transform: uppercase; letter-spacing: .06em; color: var(--text-primary); flex: none; }
.bhtl-sect-label--wait { color: var(--gold-fg); }
.bhtl-sect-line { flex: 1; height: 1px; background: var(--line-soft); }

.bhtl-roster { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 10px; }
.bhtl-p { display: flex; flex-direction: column; gap: 8px; padding: 11px 12px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-panel); min-width: 0; }
.bhtl-p--ok   { border-color: var(--tint-green-border); background: var(--tint-green-bg); }
.bhtl-p--off  { border-color: var(--border); }
.bhtl-p--wait { border-style: dashed; }
.bhtl-p-top { display: flex; align-items: center; gap: 9px; min-width: 0; cursor: pointer; }
.bhtl-p-cb { width: 18px; height: 18px; flex: none; display: grid; place-items: center; border-radius: var(--radius); border: 1px solid var(--line-strong); background: var(--bg-input); color: var(--green-fg); font-size: 11px; }
.bhtl-p--ok .bhtl-p-cb { border-color: var(--green-fg); background: var(--tint-green-bg); }
.bhtl-p-name { flex: 1; min-width: 0; font: 600 12.5px/1 var(--font-alt); color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhtl-p-fee { flex: none; font: 600 10.5px/1 var(--font-mono); color: var(--gold-fg); }
.bhtl-p-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.bhtl-p-tags:empty { display: none; }
.bhtl-tag { height: 18px; padding: 0 7px; display: inline-grid; place-items: center; border-radius: var(--radius); background: var(--bg-hover); font: 600 9px/1 var(--font-mono); letter-spacing: .04em; color: var(--text-muted); }
.bhtl-tag--warn   { background: var(--tint-gold-bg); color: var(--gold-fg); }
.bhtl-tag--info   { background: var(--accent-subtle); color: var(--accent-light); }
.bhtl-tag--wait   { background: var(--tint-orange-bg); color: var(--gold-fg); }
.bhtl-tag--danger { background: var(--tint-red-bg); color: var(--red-soft-fg); }
.bhtl-p-acts { display: flex; gap: 4px; }
.bhtl-pa { width: 26px; height: 24px; display: grid; place-items: center; border-radius: var(--radius); border: 1px solid var(--border); background: none; color: var(--text-muted); font-size: 12px; cursor: pointer; }
.bhtl-pa:hover { color: var(--text-primary); border-color: var(--border-input); }
.bhtl-pa--go { color: var(--green-fg); border-color: var(--tint-green-border); }
/* Permutation en cours : ce joueur en attente est CHOISI, il ne reste qu'à désigner qui s'efface.
   Teinte d'accent — l'état n'est ni une réussite (vert) ni un danger (rouge), c'est une attente. */
.bhtl-pa--on { color: var(--accent); border-color: var(--accent); }
.bhtl-act--danger { color: var(--red-soft-fg); border-color: var(--tint-red-border); }
.bhtl-act--danger:hover:not(:disabled) { color: var(--red-fg); border-color: var(--red-fg); }
.bhtl-act:disabled { color: var(--text-ghost); border-color: var(--border); cursor: default; }
.bhtl-spin:disabled { background: var(--bg-hover); color: var(--text-muted); cursor: default; }

/* Zone sensible de la fiche : encadré POINTILLÉ, hors du flux des cartes pleines — ce n'est pas une
   section de plus, c'est la limite de la page. Rendue au seul organisateur. */
.bht-danger { margin-top: 26px; padding: 15px 18px; border-radius: var(--radius); border: 1px dashed var(--border); }
.bht-danger-k { display: block; font: 600 9px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.bht-danger-p { margin: 11px 0 0; font: 400 11.5px/1.55 var(--font-alt); color: var(--text-soft); max-width: 62ch; }
.bht-danger-err { margin: 10px 0 0; font: 500 11.5px/1.5 var(--font-alt); color: var(--red-soft-fg); }
.bht-danger-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-top: 12px; }
.bht-danger-btn {
    display: inline-flex;
    align-items: center;
    height: 34px;
    margin-top: 12px;
    padding: 0 14px;
    border-radius: var(--radius);
    border: 1px solid var(--tint-red-border);
    background: none;
    font: 600 12px/1 var(--font-alt);
    color: var(--red-soft-fg);
    cursor: pointer;
}
.bht-danger-btn:hover { color: var(--red-fg); border-color: var(--red-fg); }
.bht-danger-acts .bht-danger-btn { margin-top: 0; }
.bht-danger-acts .bht-cta { height: 34px; padding: 0 14px; font-size: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Page publique de tarifs (F7 / US #773)
   Aucune couleur en dur : tout passe par les tokens de :root, donc les deux
   thèmes suivent sans second jeu de règles.
   ═══════════════════════════════════════════════════════════════════════════ */
.bhtar-page { max-width: min(var(--page-max), 100%); margin: 0 auto; padding: 48px 20px 72px; }
.bhtar-head { text-align: center; margin-bottom: 44px; }
.bhtar-kicker { display: block; font: 600 11px/1 'Archivo', sans-serif; letter-spacing: .18em; text-transform: uppercase; color: var(--accent); margin-bottom: 12px; }
.bhtar-h1 { font: 700 34px/1.15 'Archivo', sans-serif; color: var(--text-primary); margin: 0 0 14px; }
.bhtar-lead { font: 400 15px/1.6 'Archivo', sans-serif; color: var(--text-muted); margin: 0 auto; max-width: 56ch; }

/* Plancher de piste supérieur à la somme des éléments fixes d'une carte : sous 260px
   le prix et son unité se disputeraient la ligne. min(100%, …) pour ne pas faire
   défiler la page à l'horizontale sur mobile. */
.bhtar-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 20px; align-items: start; }

.bhtar-card { display: flex; flex-direction: column; gap: 14px; padding: 28px 24px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg-panel); }
/* Deux CTA d'achat dans une carte de tarif : EMPILES, jamais cote a cote. Une carte fait ~300 px
   et .bh-cta porte deja 26 px de rembourrage horizontal de chaque cote : sur une rangee,
   « Souscrire — 300 €/an » deborderait de la carte. */
.bhtar-ctas { display: grid; gap: 10px; }
.bhtar-card--feature { border-color: var(--accent); box-shadow: var(--shadow-strong); }
.bhtar-name { font: 600 12px/1 'Archivo', sans-serif; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }
.bhtar-price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.bhtar-amount { font: 700 38px/1 'Archivo', sans-serif; color: var(--text-primary); }
.bhtar-per { font: 500 13px/1 'Archivo', sans-serif; color: var(--text-muted); }
.bhtar-alt { font: 400 12.5px/1.4 'Archivo', sans-serif; color: var(--text-faint); margin: -8px 0 0; }
.bhtar-claim { font: 400 13.5px/1.55 'Archivo', sans-serif; color: var(--text-body); margin: 0; }

.bhtar-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.bhtar-list li { position: relative; padding-left: 20px; font: 400 13px/1.5 'Archivo', sans-serif; color: var(--text-body); }
.bhtar-list li::before { content: "✓"; position: absolute; left: 0; color: var(--accent); font-size: 12px; }

.bhtar-founder { margin-top: 40px; padding: 28px 24px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg-elevated); }
.bhtar-h2 { font: 700 19px/1.25 'Archivo', sans-serif; color: var(--text-primary); margin: 0 0 12px; }
.bhtar-founder-text { font: 400 13.5px/1.6 'Archivo', sans-serif; color: var(--text-body); margin: 0 0 10px; }
.bhtar-founder-note { font: 400 12.5px/1.6 'Archivo', sans-serif; color: var(--text-muted); margin: 0; }

.bhtar-legal { margin-top: 32px; text-align: center; }
.bhtar-legal p { font: 400 11.5px/1.6 'Archivo', sans-serif; color: var(--text-faint); margin: 0 0 6px; }
.bhtar-legal a { color: var(--accent); }

/* ═══ Cibles tactiles (US #862) ═══════════════════════════════════════════════════════════════
   Seuil visé : 44 px, la recommandation iOS (48 dp côté Android). Les commandes de l'application
   sont dessinées compactes — 18 à 34 px — ce qui va très bien à la souris et beaucoup moins au
   doigt. Une application Android/iOS est envisagée : le critère devient « atteignable », pas
   seulement « lisible ».

   🔑 La condition est `pointer: coarse` AVANT la largeur. Un doigt sur une tablette de 1024 px a le
   même besoin qu'un doigt sur un téléphone, et une fenêtre étroite pilotée à la souris n'a aucune
   raison de gonfler. La borne de largeur reste en second, pour les navigateurs qui ne rapportent
   pas le type de pointeur — et parce qu'elle rend la règle MESURABLE en sonde.

   ⚠️ Aucune hauteur d'origine n'est modifiée : `min-height` l'emporte sur `height` quand elle est
   plus grande, donc le rendu à la souris est strictement inchangé. */
@media (pointer: coarse), (max-width: 900px) {

  /* ── Famille 1 : commandes en ligne, dans un flux qui peut grandir ── */
  .appnav-link, .bhcons-btn, .bht-danger-btn, .bhtl-btn, .bhrk-scope-btn,
  .bhcon-exit, .bhcon-search, .bhcon-link,
  /* 🔴 Relevées par la MESURE en navigateur, pas par la relecture de la feuille : le contrôle de
     source ci-contre reconnaît une commande à son SUFFIXE de nom (`-btn`, `-link`), et la moitié
     des commandes du dépôt ne s'appelle pas ainsi. `.bhcal-view` (30px), `.bhcal-select` et
     `.bhcal-chip` (32px), `.bhcal-jump` (28px) et `.bhcal-rail-day` (26px) déclarent pourtant bien
     leur hauteur : elles étaient invisibles au garde-fou pour la seule raison de leur nom.
     `.bhrk-more-btn` et `.bhcal-linkbtn`, elles, portent le bon suffixe mais ne déclarent AUCUNE
     hauteur — mesurées à 12 et 15px, tenues par leur seul texte. Deux angles morts distincts. */
  .bhcal-view, .bhcal-select, .bhcal-chip, .bhcal-jump, .bhst-seg-opt,
  .bhrk-more-btn, .bhcal-linkbtn,
  /* Les deux menus burger : ils n'existent QUE sur mobile, et il s'en fallait de 6 et 8px. */
  .appnav-burger, .bhcon-burger {
    min-height: 44px;
  }

  /* `.lang-btn` est étroite dans les deux dimensions (23 × 18 mesurés) : elle a aussi besoin d'une
     largeur. Le fond est transparent, l'agrandir ne dessine donc rien de plus. */
  .lang-btn { min-height: 44px; min-width: 44px; }

  /* Le chemin d'authentification, mesuré entre 39 et 42px — il s'en fallait de deux à cinq pixels
     sur les commandes les plus importantes du produit. Les champs comptent autant que les boutons :
     un champ qu'on rate au doigt fait recommencer la saisie. */
  .btn-block, .field input, .field select, .field textarea { min-height: 44px; }

  /* La zone de recherche est un conteneur de 32px qui HABILLE l'input ; c'est elle qu'on vise du
     doigt, l'input à l'intérieur ne faisant que 16px de haut. */
  .bhcal-search, .bhtl-search { min-height: 44px; }

  /* Le jour du calendrier faisait 49 × 28 : la largeur passait déjà, la hauteur non. La case grandit
     dans sa grille — pas de pseudo-élément ici, contrairement aux flèches voisines : à sept colonnes
     serrées, une surface de 44px débordant sur les jours d'à côté ferait se recouvrir des cibles
     voisines, ce qui est pire qu'une cible petite. */
  .bhcal-rail-day { min-height: 44px; }

  /* L'onglet de tournoi est la navigation de l'écran le plus consulté du produit, et il ne déclare
     aucune hauteur : 28px tenus par `padding: 0 16px 13px` et une ligne de 13px. `box-sizing` et le
     centrage gardent le texte à sa place ; le liseré de l'onglet actif est un `inset box-shadow`
     posé au bas de la boîte, il reste donc collé au filet de la barre. */
  .bht-tab { min-height: 44px; box-sizing: border-box; display: inline-flex; align-items: center; }

  /* .bhcon-link mérite sa mention : ce n'est pas la barre de bureau qui pose problème (ses liens
     font toute la hauteur de la sous-nav) mais le menu REPLIÉ sous 1040 px, où chaque ligne tombe
     à 42 px. Deux pixels manquants, dans le seul mode où le doigt s'en sert. */

  /* ── Famille 2 : boutons carrés de navigation ── */
  .pager-btn, .cal-nav-btn { min-width: 44px; min-height: 44px; }

  /* ── Famille 3 : micro-commandes POSÉES SUR autre chose ──
     Les agrandir mangerait ce qu'elles décorent : le bouton d'ajout couvrirait l'avatar, et les
     flèches du rail écarteraient le calendrier. Leur surface tactile est donc étendue par un
     pseudo-élément transparent, centré : l'aspect ne bouge pas d'un pixel, la zone atteignable
     passe à 44 px. */
  .avatar-add-btn, .bhcal-rail-btn { position: relative; }
  .avatar-add-btn::after, .bhcal-rail-btn::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }

  /* ── L'en-tête de la console déborde à 390 px (448 px de contenu mesurés) ──
     Il aligne sept repères sur une seule ligne. Plutôt que d'en masquer, on l'autorise à passer à
     la ligne : rien ne disparaît, et la hauteur n'augmente que là où c'est nécessaire. */
  .bhcon-head { flex-wrap: wrap; height: auto; row-gap: 8px; padding-top: 8px; padding-bottom: 8px; }
  /* ⚠️ La recherche, la version et le libellé du compte sont déjà masqués sous 1040 px
     (règle plus haut) : inutile de les redimensionner ici. Le min-height posé sur
     .bhcon-search plus haut vise la tablette au-dessus de ce seuil, où elle est visible. */
}

/* ── Barrière d'erreur (Bogue #868) ─────────────────────────────────────────────
   L'écran qui prend la place d'un contenu qui a levé. Il n'apparaît que quand quelque
   chose est déjà allé de travers : il doit être lisible, pas décoratif.
   Aucune couleur en dur — tout passe par les tokens, donc il suit les deux thèmes. */
.bherr {
    max-width: 560px;
    margin: 48px auto;
    padding: 28px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    text-align: center;
}

.bherr-title {
    margin: 0 0 12px;
    font-size: 1.25rem;
    color: var(--text-primary);
}

.bherr-text {
    margin: 0 0 24px;
    color: var(--text-body);
    line-height: 1.6;
}

.bherr-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

/* Le seuil tactile s'applique ici comme partout : la condition porte sur pointer: coarse
   AVANT la largeur, un doigt sur une tablette ayant le même besoin qu'un doigt sur un
   téléphone. */
@media (pointer: coarse) {
    .bherr-actions > * { min-height: 44px; }
}
/* ── Formulaire de contact (Fonctionnalité #886) ────────────────────────────────
   Aucune couleur en dur : tout par tokens, donc les deux thèmes suivent.
   Aucune largeur de page en dur non plus — la colonne vit dans --page-max. */
/* ── Écran 22 (/contact) — maquettes 22a a 22f ────────────────────────────────────────────────
   Colonne de lecture a deux colonnes : formulaire en carte, appoint a droite.
   🔴 PAS de bandeau sur l'artwork, contrairement a 22a : ecart voulu (2026-09-03). Un ecran ou
   l'on vient poser une question n'est pas une vitrine, et 320px d'artwork repoussaient le premier
   champ hors de la fenetre. L'en-tete est a plat, dans le flux. */
.bhct-head { margin-bottom: 22px; }
.bhct-kicker {
    display: block;
    font: 600 0.7rem/1 'JetBrains Mono', ui-monospace, monospace;
    letter-spacing: .18em;
    color: var(--accent);
}
/* Un cran sous l'echelle du hero : hors artwork, 40px ecraseraient le formulaire qui suit. */
.bhct-h1 {
    margin: 10px 0 0;
    font: 700 clamp(1.6rem, 3vw, 2.1rem)/1.1 'Barlow Condensed', sans-serif;
    text-transform: uppercase;
    letter-spacing: .015em;
    color: var(--text-primary);
}
.bhct-lede { margin: 9px 0 0; max-width: 520px; line-height: 1.6; color: var(--text-body); text-wrap: pretty; }

/* container-type plutot qu'une media query : la colonne d'appoint doit se replier selon la
   largeur DE CETTE COLONNE, pas celle de la fenetre -- une media query ne voit pas une colonne
   etroite dans une fenetre large. min-width: 0 sur les items, sinon un champ large fait defiler
   l'ecran entier a travers la grille. */
.bhct-page { max-width: min(var(--page-max), 100%); margin: 0 auto; padding: 26px 16px 64px; container: bhct / inline-size; }
.bhct-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
.bhct-grid > * { min-width: 0; }
@container bhct (min-width: 860px) {
    .bhct-grid { grid-template-columns: minmax(0, 1fr) 258px; }
}

.bhct-card {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 22px 24px 24px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    /* C'est l'ombre qui detache la carte du bandeau : sans elle, le haut du formulaire se confond
       avec le degrade de l'artwork (annotation 3 de 22a). */
    box-shadow: 0 18px 46px var(--shadow-strong);
}

.bhct-field { margin: 0; }
.bhct-sep { height: 1px; background: var(--border); }

/* Legende du selecteur de motif : intitule, nombre de choix, et ce que le choix declenche. */
.bhct-legend { display: flex; align-items: baseline; gap: 9px; margin-bottom: 10px; flex-wrap: wrap; }
.bhct-legend-txt {
    font: 600 0.7rem/1 'JetBrains Mono', ui-monospace, monospace;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-body);
}
.bhct-legend-num {
    width: 15px; height: 15px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: var(--accent);
    font: 700 0.56rem/1 'JetBrains Mono', ui-monospace, monospace;
    color: var(--on-accent);
}
.bhct-legend-hint { font-size: 0.78rem; color: var(--text-muted); }

/* Grille 2x2, repliee en une colonne quand la carte est etroite OU au doigt : deux cartes de
   motif cote a cote sous 640px deviennent illisibles avant d'etre cliquables. */
.bhct-reasons { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@container bhct (max-width: 640px) {
    .bhct-reasons { grid-template-columns: 1fr; }
}
@media (pointer: coarse) {
    .bhct-reasons { grid-template-columns: 1fr; }
}

.bhct-reason {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-height: 44px;
    padding: 11px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-input);
    cursor: pointer;
}
.bhct-reason--on { border-color: var(--accent); background: var(--accent-subtle); }
/* Le bouton radio reste dans l'arbre d'accessibilite et reste focusable : il est masque a l'oeil,
   jamais retire. display:none le sortirait de la navigation au clavier. */
.bhct-reason-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.bhct-reason-dot {
    width: 15px; height: 15px;
    flex: none;
    margin-top: 2px;
    border-radius: 50%;
    border: 1.5px solid var(--text-muted);
}
.bhct-reason--on .bhct-reason-dot { border: 4.5px solid var(--accent); background: var(--bg-page); }
.bhct-reason-input:focus-visible + .bhct-reason-dot { outline: 2px solid var(--accent); outline-offset: 2px; }
.bhct-reason-txt { min-width: 0; }
.bhct-reason-title { display: block; font-weight: 600; line-height: 1.25; color: var(--text-primary); }
.bhct-reason-hint { display: block; margin-top: 5px; font-size: 0.78rem; line-height: 1.35; color: var(--text-body); text-wrap: pretty; }

/* Paliers de volume : meme mecanique que les motifs, en plus compact. */
.bhct-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.bhct-chip {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-input);
    font-size: 0.85rem;
    color: var(--text-body);
    cursor: pointer;
}
.bhct-chip--on { border-color: var(--accent); background: var(--accent-subtle); color: var(--text-primary); font-weight: 600; }
.bhct-chip .bhct-reason-input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 3px; }

.bhct-count { margin-top: 6px; text-align: right; font: 400 0.7rem/1 'JetBrains Mono', ui-monospace, monospace; color: var(--text-muted); }

.bhct-consent { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.bhct-consent-box { width: 17px; height: 17px; flex: none; margin-top: 2px; accent-color: var(--accent); }
.bhct-consent-txt { font-size: 0.8rem; line-height: 1.5; color: var(--text-body); text-wrap: pretty; }

/* Colonne d'appoint. Elle ne porte QUE le centre d'aide : la carte Discord et la carte des delais
   de la maquette sont absentes faute de serveur communautaire et de delai lisible cote Web. */
.bhct-aside { display: flex; flex-direction: column; gap: 14px; }
.bhct-side-card { padding: 16px 16px 15px; background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--radius); }
.bhct-side-title { display: block; font-weight: 700; color: var(--text-primary); }
.bhct-side-body { margin: 9px 0 0; font-size: 0.78rem; line-height: 1.55; color: var(--text-body); }
.bhct-side-links { display: flex; flex-direction: column; margin-top: 10px; }
.bhct-side-links a { min-height: 36px; display: flex; align-items: center; font-size: 0.82rem; line-height: 1.35; color: var(--accent); }

.bhct-label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    color: var(--text-primary);
}

/* Hauteur 44px, 48 au doigt (annotation 5 de 22a) : la cible tactile minimale. min-height plutot
   que height, sinon le textarea ne pourrait plus grandir. */
.bhct-input {
    width: 100%;
    min-height: 44px;
    padding: 10px 13px;
    background: var(--bg-input);
    color: var(--text-primary);
    border: 1px solid var(--border-input);
    border-radius: var(--radius);
}
@media (pointer: coarse) {
    .bhct-input { min-height: 48px; }
}

/* Anneau de focus, et pas seulement un changement de bordure : une bordure qui vire de 1px se
   voit mal, et c'est le seul reperage de qui navigue au clavier. */
.bhct-input:focus-visible {
    border-color: var(--accent);
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-subtle);
}

.bhct-textarea { resize: vertical; min-height: 160px; font: inherit; }

.bhct-hint { margin: 6px 0 0; font-size: 0.85rem; color: var(--text-muted); }

.bhct-error { margin: 6px 0 0; font-size: 0.85rem; color: var(--color-danger); font-weight: 600; }

.bhct-outcome {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin: 0 0 18px;
    padding: 16px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-surface-hover);
}

.bhct-outcome-title { margin: 0 0 4px; font-weight: 600; color: var(--text-primary); }
.bhct-outcome-text { margin: 0; color: var(--text-body); line-height: 1.5; }
.bhct-outcome--ok { border-color: var(--tint-green-border); }
.bhct-outcome--ko { border-color: var(--color-danger); }

/* Bouton a sa largeur naturelle, pleine largeur seulement quand la carte devient etroite
   (annotation 6 de 22a). Un bouton pleine largeur sur 900px se lit comme une banniere. */
.bhct-submit { align-self: flex-start; min-height: 44px; }
@container bhct (max-width: 480px) {
    .bhct-submit { align-self: stretch; width: 100%; }
}
.bhct-alt { margin: 0; color: var(--text-muted); font-size: 0.8rem; line-height: 1.5; }

/* Seuil tactile : la condition porte sur pointer: coarse AVANT la largeur, un doigt sur une
   tablette ayant le même besoin qu'un doigt sur un téléphone. */
@media (pointer: coarse) {
    .bhct-input, .bhct-submit, .bhct-card button { min-height: 44px; }
}

/* ── Barème de distribution du cash prize (écrans 25b organisation / 25d console) ──────────────
   Namespace .bhbar-. Le tableau des trois paliers est l'objet de l'écran ; les quatre valeurs
   réglables sont posées DANS le tableau, en lignes de borne entre les paliers qu'elles séparent.

   ⚠️ Aucun palier n'est teinté. Une teinte d'accent sur une ligne de palier se lirait « c'est
   celui-ci qui s'applique », ce qu'aucun des deux écrans ne peut savoir : la cagnotte d'un tournoi
   futur leur est inconnue. Le rythme vient des lignes de BORNE, qui portent réellement autre chose.

   Entièrement tokenisé, donc thémé : les valeurs sombres des tokens sont celles de la maquette. */
.bhbar {
    border-radius: var(--radius);
    border: 1px solid var(--border);
    /* Fond de SURFACE, et les champs en creux dessus — l'idiome des autres écrans de réglage
       (.bhog-finput). Le tableau et ses champs partageaient --bg-inset : en sombre la bordure bleue
       de --border-input les distinguait, mais en THÈME CLAIR cette bordure n'est qu'un filet noir à
       16 % (≈1,4:1) et les quatre champs devenaient des rectangles blancs sur fond blanc. Un défaut
       qu'aucun test de rendu n'aurait signalé : le balisage est complet, seule la couleur ment. */
    background: var(--bg-surface);
    /* 🔴 Le repli suit la largeur du CONTENEUR, pas celle de la fenêtre. Le tableau vit dans la
       colonne gauche de .bhog-split, qui garde deux colonnes tant que la fenêtre dépasse 1000px :
       à 1001px de fenêtre la colonne ne fait plus que 561px, le tableau en réclamait 16 de plus, et
       overflow:hidden les rognait EN SILENCE — une colonne du tableau simplement absente, sans
       barre de défilement pour le signaler. Aucune media query ne pouvait exprimer ce cas : la
       fenêtre est large, c'est la colonne qui est étroite. */
    container-type: inline-size;
    container-name: bhbar;
    /* Dernier recours là où @container ne s'applique pas : on défile, on ne rogne pas. Rien ne doit
       disparaître sans que le lecteur le sache. */
    overflow-x: auto;
}

/* Une seule grille pour l'en-tête et les paliers : les quatre colonnes doivent s'aligner d'une
   ligne à l'autre, sinon la lecture « ce que touche le 2ᵉ selon la cagnotte » se perd.
   min-width: 0 sur les items, sans quoi un contenu long pousserait la grille au-delà du panneau
   et ferait défiler l'écran entier (cf. le système de largeurs de page). */
.bhbar-head,
.bhbar-tier {
    display: grid;
    grid-template-columns: minmax(120px, 1.5fr) minmax(0, 1.5fr) minmax(0, 1.1fr) minmax(0, 1.1fr);
    gap: 14px;
    align-items: center;
}
.bhbar-head > *,
.bhbar-tier > * { min-width: 0; }

.bhbar-head {
    padding: 12px 20px;
    border-bottom: 1px solid var(--border);
}
.bhbar-hcell {
    font: 500 9.5px/1.3 var(--font-mono);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.bhbar-tier { padding: 16px 20px; }
.bhbar-tname { font: 600 12.5px/1.4 var(--font-alt); color: var(--text-primary); }

/* Chaque cellule porte SON libellé de position, masqué tant que l'en-tête est visible. Sans lui, le
   repli étroit — qui supprime l'en-tête — laisserait trois valeurs empilées sans dire laquelle est
   celle du 2ᵉ : « 150 € » et « Son entrée remboursée » se liraient dans le désordre. */
.bhbar-c { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bhbar-clab {
    display: none;
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bhbar-cell { font: 400 12.5px/1.4 var(--font-alt); color: var(--text-secondary); }
/* « Rien » est un résultat, pas une absence de donnée : il reste lisible, en retrait. */
.bhbar-cell--none { color: var(--text-muted); }

/* Le remboursement n'est jamais un montant : lui donner la forme d'une pastille, et non celle d'un
   champ ni d'un chiffre, est ce qui empêche de le lire comme une somme fixe. Il vaut l'entrée payée
   par l'équipe, connue au tournoi seulement. */
.bhbar-chip {
    justify-self: start;
    display: inline-flex;
    align-items: center;
    height: 26px;
    padding: 0 10px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    font: 500 11px/1.35 var(--font-alt);
    color: var(--text-secondary);
    /* Pas de nowrap : « Son entrée remboursée » posait à lui seul un plancher de largeur qui
       remontait dans la grille et faisait déborder tout le tableau. */
    min-height: 26px;
    height: auto;
    padding: 4px 10px;
}

/* Ligne de borne : elle sépare deux paliers ET porte le champ qui déplace la frontière. */
.bhbar-bound {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 11px 20px;
    border-top: 1px solid var(--line-soft);
    border-bottom: 1px solid var(--line-soft);
}
.bhbar-bname {
    flex: none;
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--accent-light);
}
.bhbar-bnote {
    flex: 1 1 220px;
    min-width: 0;
    font: 400 11px/1.5 var(--font-alt);
    color: var(--text-muted);
}

.bhbar-fbox {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
/* Largeur fixe : les quatre valeurs se comparent du regard d'une ligne à l'autre, ce qu'une
   largeur élastique romprait. Elle ne bouge pas d'une langue à l'autre — un nombre ne se traduit
   pas, seuls les libellés autour s'allongent. */
.bhbar-input {
    flex: none;
    width: 96px;
    height: 40px;
    padding: 0 12px;
    border-radius: var(--radius);
    border: 1px solid var(--border-input);
    background: var(--bg-inset);
    color: var(--text-primary);
    font: 600 14px/1 var(--font-mono);
}
.bhbar-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bhbar-unit {
    font: 400 11.5px/1 var(--font-mono);
    color: var(--text-muted);
    white-space: nowrap;
}

.bhbar-foot {
    display: flex;
    align-items: center;
    gap: 11px;
    flex-wrap: wrap;
    padding: 13px 20px;
    border-top: 1px solid var(--border);
}
.bhbar-badge {
    flex: none;
    display: grid;
    place-items: center;
    height: 22px;
    padding: 0 9px;
    border-radius: var(--radius);
    background: var(--tint-blue-bg);
    border: 1px solid var(--border-input);
    font: 600 9.5px/1 var(--font-mono);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--accent-light);
}
.bhbar-fnote {
    flex: 1 1 240px;
    min-width: 0;
    font: 400 11.5px/1.5 var(--font-alt);
    color: var(--text-secondary);
}

/* Deux notes de contexte sous le tableau, côté organisation : ce que vaut un remboursement, et
   pourquoi le palier se lit sur le brut quand la répartition se fait sur le net. */
.bhbar-notes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.bhbar-note {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 18px;
    border-radius: var(--radius);
    border: 1px solid var(--line-soft);
    background: var(--bg-surface);
}
.bhbar-note-k {
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.bhbar-note-t { font: 400 11.5px/1.55 var(--font-alt); color: var(--text-soft); }

/* En dessous de cette largeur, quatre colonnes donnent des cellules de deux mots par ligne :
   l'en-tête disparaît et chaque palier se lit comme un bloc, la position en préfixe. */
/* Sous cette largeur DE CONTENEUR, quatre colonnes donneraient des cellules de deux mots par
   ligne : l'en-tête disparaît et chaque palier se lit comme un bloc, chaque valeur précédée de sa
   position. */
@container bhbar (max-width: 620px) {
    .bhbar-head { display: none; }
    .bhbar-tier { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .bhbar-clab { display: block; }
}

@media (max-width: 860px) {
    .bhbar-notes { grid-template-columns: minmax(0, 1fr); }
}

/* ════════════════════════════════════════════════════════════════════════════
   DIFFUSION — écrans C (« Cast - Bleu Profond »)

   Namespace `bhcast-`. 🔴 Jamais de nom préfixé `ad*` : un bloqueur de publicité
   poserait display:none dessus et ferait disparaître l'écran entier, sans log,
   sans erreur, tout en 200. Ici ce serait la régie d'un direct.

   L'onglet Diffusion vit dans le chrome de l'application et suit donc les
   TOKENS. La régie, elle, porte sa propre palette sombre — exception assumée,
   au même titre que les écrans posés sur photo : c'est un poste de pilotage
   regardé à côté d'OBS, pas une page du site. La palette est scopée à
   `.bhcast-room`, elle ne fuit nulle part ailleurs.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Onglet Diffusion d'une organisation (C3) ──────────────────────────────── */
.bhcast-tab { display: flex; flex-direction: column; gap: 18px; }

.bhcast-card {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}

.bhcast-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bhcast-h3 { margin: 0; font-size: 15px; font-weight: 600; color: var(--text-primary); }
.bhcast-note { margin: 0; font-size: 13px; color: var(--text-muted); }
.bhcast-hint { font-size: 12px; color: var(--text-muted); }
.bhcast-empty { margin: 0; font-size: 13px; color: var(--text-muted); }

.bhcast-pill {
    font-size: 11px; letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
    padding: 4px 10px; border-radius: var(--radius); border: 1px solid var(--border);
    color: var(--text-secondary); white-space: nowrap;
}
/* La promesse la plus importante de l'écran : elle se voit avant tout le reste. */
.bhcast-pill--promise { color: var(--accent); border-color: var(--accent); }
.bhcast-pill--write { color: var(--text-bright); border-color: var(--border-hover); }

.bhcast-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* ⚠️ `.bhcast-field` est une COLONNE flex, donc `align-items: stretch` par défaut : un bouton posé
   dedans s'étire sur toute la largeur de la carte et prend l'allure d'une barre. Un geste unique se
   dimensionne à son libellé — les champs, eux, gardent bien la pleine largeur. */
.bhcast-field > .btn-ghost { align-self: flex-start; }
.bhcast-label { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.bhcast-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }

/* L'URL doit rester lisible ET copiable : elle défile dans son cadre plutôt que
   d'étirer la ligne — un enfant trop large étirerait toute la ligne flex. */
.bhcast-url {
    flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap;
    font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px;
    background: var(--bg-inset); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 8px 12px; color: var(--text-body);
}

.bhcast-tags { display: flex; gap: 8px; flex-wrap: wrap; }
.bhcast-tag {
    font-size: 11px; letter-spacing: .06em; padding: 3px 9px; border-radius: var(--radius);
    background: var(--bg-chip); color: var(--text-secondary);
}
/* « À VÉRIFIER » : la maquette l'annonce, et ce n'est pas un ornement — l'autoplay
   avec le son dans OBS n'est pas établi. La nuance doit rester visible. */
.bhcast-tag--unsure { color: var(--text-muted); border: 1px dashed var(--border); }

.bhcast-locked {
    display: flex; gap: 14px; align-items: flex-start;
    background: var(--bg-inset); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 16px 18px; color: var(--text-secondary);
}
.bhcast-locked p { margin: 6px 0 0; font-size: 13px; color: var(--text-muted); }
.bhcast-locked i { font-size: 20px; color: var(--text-muted); }

.bhcast-switch { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-body); }
.bhcast-switch--tight { font-size: 12px; color: var(--text-secondary); }

.bhcast-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }

.bhcast-item {
    display: flex; align-items: center; gap: 12px; min-width: 0;
    background: var(--bg-inset); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 10px 14px;
}
.bhcast-item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bhcast-item-name { font-size: 14px; font-weight: 600; color: var(--text-primary); }
/* Une adresse à rallonge tronque, elle ne pousse jamais la ligne hors du cadre. */
.bhcast-item-sub {
    font-size: 12px; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Un secret rendu UNE fois : il doit sauter aux yeux, sinon il est perdu. */
.bhcast-secret {
    display: flex; flex-direction: column; gap: 6px; min-width: 0;
    background: var(--bg-inset); border: 1px solid var(--accent);
    border-radius: var(--radius); padding: 12px 14px;
}
.bhcast-secret code {
    font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px;
    word-break: break-all; color: var(--text-bright);
}

.bhcast-form { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.bhcast-input {
    background: var(--bg-input); border: 1px solid var(--border-input);
    border-radius: var(--radius); padding: 8px 12px; color: var(--text-body);
    font-size: 14px; font-family: inherit; min-width: 0; flex: 1 1 180px;
}
.bhcast-input--area { width: 100%; min-height: 64px; resize: vertical; }

.bhcast-link {
    background: none; border: 0; padding: 0; cursor: pointer;
    font-size: 13px; color: var(--accent); font-family: inherit;
}
.bhcast-link--danger { color: var(--text-muted); }
.bhcast-link:disabled { color: var(--text-faint); cursor: default; }

/* ── Préparer un cast (C5) ─────────────────────────────────────────────────── */
/* 🔑 Même palette que la régie, et pour la même raison : c'est l'écran d'AVANT
   la régie, ouvert par la même personne au même moment. Deux habillages entre
   deux clics feraient croire à deux outils. Les jetons sont partagés plus bas,
   avec `.bhcast-room`. */
.bhcast-prep .bhcast-empty,
.bhcast-prep .bhcast-hint,
.bhcast-prep .bhcast-note { color: var(--room-ink-3); font-size: 10.5px; }
.bhcast-prep .bhcast-locked { margin: 18px; }
.bhcast-prep .alert-error { margin: 0 18px 18px; }

.bhcast-prep-head {
    display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    padding: 14px 18px;
    border-bottom: 1px solid var(--room-line-1);
    background: linear-gradient(180deg, var(--room-navy-3), var(--room-navy-1));
}
.bhcast-prep-head-main { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 5px; }
.bhcast-prep-title {
    margin: 0; font: 700 20px/1 var(--room-display);
    text-transform: uppercase; color: var(--room-ink);
}
.bhcast-prep-step {
    font: 500 9.5px/1.4 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-ink-3);
}
/* Le droit du casteur, dit une fois, en haut : c'est ce qui explique la liste
   qui suit — et pourquoi elle s'arrête là où elle s'arrête. */
.bhcast-prep-kind {
    flex: none; height: 28px; padding: 0 11px; display: flex; align-items: center; gap: 7px;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-2);
    font: 700 9px/1 var(--room-mono); letter-spacing: .1em; color: var(--room-ink-2);
}
.bhcast-prep-kind--platform {
    border-color: rgba(249, 160, 63, .45); background: rgba(249, 160, 63, .12); color: var(--room-gold);
}
.bhcast-prep-kind em { font: 400 9px/1 var(--room-mono); font-style: normal; color: var(--room-gold-2); }

.bhcast-prep-body { padding: 20px 18px 26px; display: flex; flex-direction: column; gap: 12px; }
.bhcast-prep-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bhcast-prep-scope {
    font: 600 8.5px/1 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-ink-3);
}
.bhcast-prep-search {
    flex: 1 1 160px; min-width: 140px; height: 26px; padding: 0 9px;
    border-radius: var(--radius); border: 1px solid var(--room-line-2); background: var(--room-navy-2);
    font: 400 9.5px/1 var(--room-mono); color: var(--room-ink);
}
.bhcast-prep-search::placeholder { color: var(--room-ink-4); }
.bhcast-prep-search:focus { border-color: var(--room-acc-2); outline: none; }
.bhcast-filters { flex: none; display: flex; border-radius: var(--radius); border: 1px solid var(--room-line-3); overflow: hidden; }
.bhcast-filter {
    height: 26px; padding: 0 9px; display: grid; place-items: center; white-space: nowrap;
    border: 0; background: var(--room-navy-2);
    font: 500 9.5px/1 'Archivo', sans-serif; color: var(--room-ink-2); cursor: pointer;
}
.bhcast-filter--on { background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3)); color: #fff; }

.bhcast-prep-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.bhcast-prep-card {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; min-width: 0;
    padding: 12px 14px; border-radius: var(--radius);
    border: 1px solid var(--room-line-2); background: var(--room-navy-1);
}
/* Celui qu'on peut préparer tout de suite se distingue : bordure et fond d'accent. */
.bhcast-prep-card--ready {
    border-color: var(--room-acc-2);
    background: linear-gradient(160deg, rgba(0, 179, 255, .16), var(--room-navy-1));
}
/* Un tournoi fermé reste VISIBLE, en retrait : il porte sa raison. */
.bhcast-prep-card--off { opacity: .6; border-style: dashed; border-color: var(--room-line-1); }

.bhcast-prep-org {
    width: 44px; height: 44px; border-radius: var(--radius); flex: none; overflow: hidden;
    display: grid; place-items: center;
    font: 700 14px/1 var(--room-display); color: var(--room-acc);
    background: var(--room-navy-3); border: 1px solid var(--room-line-3);
}
.bhcast-prep-org img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bhcast-prep-main { flex: 1 1 180px; min-width: 0; }
.bhcast-prep-name {
    display: block; font: 700 15px/1 var(--room-display); text-transform: uppercase; color: var(--room-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-prep-sub {
    display: flex; align-items: center; gap: 8px; margin-top: 6px; min-width: 0;
    font: 400 9.5px/1 'Archivo', sans-serif; color: var(--room-ink-3);
}
.bhcast-prep-sub > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bhcast-prep-live { flex: none; display: flex; align-items: center; gap: 6px; color: var(--room-live-2); }
.bhcast-prep-live i {
    width: 5px; height: 5px; border-radius: 50%; background: var(--room-live); display: block;
    animation: bhcast-live 1.6s ease-in-out infinite;
}
.bhcast-prep-stats {
    flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; align-items: flex-end;
}
/* La pastille d'accès porte la couleur de ce qu'elle autorise : vert ouvert,
   ambre sur demande, éteint fermé. C'est la première chose qu'on cherche. */
.bhcast-prep-access {
    height: 18px; padding: 0 7px; display: grid; place-items: center; border-radius: var(--radius);
    font: 600 8px/1 var(--room-mono); letter-spacing: .06em; white-space: nowrap;
}
.bhcast-prep-access--open { background: rgba(55, 217, 154, .12); color: #37d99a; }
.bhcast-prep-access--request { border: 1px solid rgba(249, 160, 63, .45); color: var(--room-gold); }
.bhcast-prep-access--closed { background: var(--room-navy-3); color: var(--room-ink-3); }
.bhcast-prep-casts { font: 400 9px/1 var(--room-mono); color: var(--room-ink-3); text-align: right; }
.bhcast-prep-go {
    flex: none; height: 30px; padding: 0 14px; display: grid; place-items: center; white-space: nowrap;
    border-radius: var(--radius); border: 0; color: #fff; cursor: pointer;
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
    font: 600 11px/1 'Archivo', sans-serif;
}
.bhcast-prep-go:disabled { opacity: .55; cursor: default; }
.bhcast-prep-reason { flex: none; max-width: 220px; text-align: right; font: 400 9.5px/1.35 'Archivo', sans-serif; color: var(--room-ink-4); }

/* Le pas suivant, dit à la fin de la liste : préparer n'est pas diffuser. */
.bhcast-prep-next {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 11px 14px; border-radius: var(--radius);
    border: 1px solid var(--room-line-1); background: var(--room-navy-1);
    font: 400 10px/1.45 'Archivo', sans-serif; color: var(--room-ink-2);
}
.bhcast-prep-next strong { color: var(--room-acc); font: 500 10px/1 'Archivo', sans-serif; white-space: nowrap; margin-left: auto; }

/* ── La régie (C1) ─────────────────────────────────────────────────────────── */
/* 🔑 Palette locale « BLEU PROFOND », scopée à `.bhcast-room` : la régie se
   regarde à côté d'OBS, pas dans le site. Exception assumée, au même titre que
   les écrans posés sur photo — et elle ne fuit nulle part, tout vit sous le
   sélecteur racine. Les trois polices sont celles de la maquette, déjà chargées
   par `App.razor` : la régie et la source doivent se ressembler, sinon le
   casteur compare deux habillages au lieu d'un seul.

   🔑 L'écran de PRÉPARATION partage la palette et le cadre : c'est l'écran
   d'avant, ouvert par la même personne au même moment. Deux habillages entre
   deux clics feraient croire à deux outils. */
.bhcast-room,
.bhcast-prep {
    --room-bg: #040d24;
    --room-navy-1: #071433;
    --room-navy-2: #091a3e;
    --room-navy-3: #0c2250;
    --room-navy-4: #0f2c66;
    --room-line-1: #143070;
    --room-line-2: #1f4699;
    --room-line-3: #2451ad;
    --room-ink: #f2f7ff;
    --room-ink-2: #bcd3fa;
    --room-ink-3: #8db0e8;
    --room-ink-4: #6a90d2;
    --room-acc: #5fc3ff;
    --room-acc-2: #00b3ff;
    --room-acc-3: #0a52ff;
    --room-gold: #f9a03f;
    --room-gold-2: #e8c58a;
    /* Le vert de la pastille « connecté » : il ne sert QUE là, et surtout pas à dire
       « en ligne » au sens antenne — l'antenne, dans cet écran, c'est le rouge. */
    --room-ok: #37d99a;
    --room-live: #ff425c;
    --room-live-2: #ff7285;
    --room-display: 'Barlow Condensed', 'Archivo', system-ui, sans-serif;
    --room-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;

    background: radial-gradient(120% 90% at 50% -10%, var(--room-navy-4) 0%, var(--room-navy-1) 45%, var(--room-bg) 100%);
    color: var(--room-ink);
    font-family: 'Archivo', system-ui, sans-serif;
    border: 1px solid var(--room-line-2);
    border-radius: var(--radius);
    overflow: hidden;
    min-width: 0;
}
.bhcast-room .bhcast-note,
.bhcast-room .bhcast-hint,
.bhcast-room .bhcast-empty { color: var(--room-ink-3); font-size: 10.5px; }
.bhcast-room .bhcast-input {
    background: var(--room-navy-2); border: 1px solid var(--room-line-2); color: var(--room-ink);
    border-radius: var(--radius); font: 400 10.5px/1.4 'Archivo', sans-serif;
}
.bhcast-room .bhcast-input:focus { border-color: var(--room-acc-2); outline: none; }
/* 🔴 `.bhcast-input` porte `flex: 1 1 180px`, pensé pour la RANGÉE de l'onglet Diffusion.
   Posé dans une COLONNE, `flex-basis` devient une HAUTEUR : les champs du pilotage d'OBS
   mesuraient 180 px à l'écran. Mesuré au style calculé le 2026-09-09 — illisible dans le CSS,
   où aucune règle ne dit « 180 px de haut ». Le `<textarea>` du bandeau, lui, GRANDIT : c'est
   sa raison d'être, il garde donc son flex. */
.bhcast-room .bhcast-input:not(.bhcast-input--area) { flex: none; }
.bhcast-room .alert-error { margin: 0 18px 18px; }

@keyframes bhcast-live { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ── Le bandeau supérieur ──────────────────────────────────────────────────── */
.bhcast-topbar {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 14px 18px;
    border-bottom: 1px solid var(--room-line-1);
    background: linear-gradient(180deg, var(--room-navy-3), var(--room-navy-1));
}
.bhcast-topbar-mark { height: 24px; width: auto; display: block; flex: none; }
.bhcast-topbar-main { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 5px; }
.bhcast-room-title {
    font: 700 20px/1 var(--room-display); text-transform: uppercase; color: var(--room-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-room-sub {
    font: 500 9.5px/1.4 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-ink-3);
}

/* 🔴 Le mode est un TÉMOIN, pas un réglage : il se déduit du contenu à l'antenne.
   Un interrupteur ferait chercher pourquoi le basculer ne change rien — sans
   contenu principal la source est transparente, avec un contenu elle est pleine. */
.bhcast-modes {
    display: flex; flex: none; border-radius: var(--radius);
    border: 1px solid var(--room-line-3); overflow: hidden;
}
.bhcast-mode {
    height: 28px; padding: 0 12px; display: flex; align-items: center; gap: 7px;
    white-space: nowrap; background: var(--room-navy-2);
    font: 600 10.5px/1 'Archivo', sans-serif; color: var(--room-ink-2);
}
.bhcast-mode--on { background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3)); color: #fff; }
.bhcast-mode i { width: 12px; height: 9px; border-radius: var(--radius); flex: none; display: block; }
.bhcast-mode--full i { background: var(--room-navy-4); border: 1px solid rgba(255, 255, 255, .5); }
.bhcast-mode--alpha i {
    background: repeating-conic-gradient(var(--room-ink-2) 0 25%, rgba(188, 211, 250, .35) 0 50%) 0 0 / 6px 6px;
}

.bhcast-quick {
    flex: none; height: 28px; padding: 0 11px; display: flex; align-items: center; gap: 7px;
    white-space: nowrap; border-radius: var(--radius); border: 1px solid var(--room-line-3);
    background: var(--room-navy-2); font: 600 10.5px/1 'Archivo', sans-serif;
    color: var(--room-ink); cursor: pointer;
}
.bhcast-quick:hover { border-color: var(--room-acc-2); color: #fff; }
.bhcast-quick--danger { color: var(--room-live-2); }
.bhcast-quick--danger:hover { border-color: var(--room-live); color: var(--room-live-2); }

/* ── Le pilotage d'OBS, en pastille d'en-tête ──────────────────────────────── */
/* 🔴 IL A QUITTÉ LA COLONNE DE DROITE. Replié, il pèse la hauteur d'une pastille dans
   une barre déjà là, au lieu d'environ 260 px de colonne — il ne peut donc plus prendre
   la place d'un organe vital. C'est un CONFORT : sans lui la régie marche, le casteur
   bascule sa source à la main. */
.bhcast-obs { position: relative; flex: none; }
.bhcast-obs-pill {
    height: 34px; padding: 0 11px; display: flex; align-items: center; gap: 8px;
    list-style: none; cursor: pointer; white-space: nowrap;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-2);
}
.bhcast-obs-pill::-webkit-details-marker { display: none; }
.bhcast-obs-caret { font: 400 11px/1 'Archivo', sans-serif; color: var(--room-ink-4); }
.bhcast-obs[open] .bhcast-obs-pill { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
/* Le panneau se pose PAR-DESSUS l'écran, aligné à droite : ouvert, il ne doit pas pousser
   la barre ni déplacer les deux boutons qui la terminent. */
.bhcast-obs-pop {
    position: absolute; right: 0; top: 100%; z-index: 5; width: 336px; box-sizing: border-box;
    border-radius: var(--radius) 0 var(--radius) var(--radius); border: 1px solid var(--room-line-3);
    background: linear-gradient(180deg, rgba(15, 44, 102, .95), rgba(7, 20, 51, .99));
    box-shadow: 0 16px 44px rgba(2, 7, 20, .7);
}
.bhcast-obs-poptitle {
    margin: 0; padding: 11px 15px 0;
    font: 600 9.5px/1 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-ink-3);
}
.bhcast-obs--on .bhcast-obs-pill { border-color: rgba(55, 217, 154, .4); background: rgba(55, 217, 154, .08); }
.bhcast-obs--on .bhcast-obs-caret { color: var(--room-ok); }
.bhcast-obs--fail .bhcast-obs-pill { border-color: rgba(249, 160, 63, .5); background: rgba(249, 160, 63, .12); }
.bhcast-obs--fail .bhcast-obs-caret { color: var(--room-gold); }
.bhcast-obs--fail .bhcast-obs-pop { border-color: rgba(249, 160, 63, .45); }
.bhcast-obs--on .bhcast-obs-pop { border-color: rgba(55, 217, 154, .4); }

/* Piloté à distance (Tâche #1161) : le CYAN d'accent, et pas le vert du « connecté » local.
   Les deux états sont bons, mais ils ne disent pas la même chose — et c'est justement la
   confusion entre « ma régie pilote » et « quelqu'un d'autre pilote » que ce lot supprime.
   La préséance est la même dans le CSS que dans le code : ces règles suivent celles du vert
   et de l'ambre, donc elles l'emportent à spécificité égale. */
.bhcast-obs--remote .bhcast-obs-pill { border-color: rgba(95, 195, 255, .45); background: rgba(95, 195, 255, .1); }
.bhcast-obs--remote .bhcast-obs-caret { color: var(--room-acc); }
.bhcast-obs--remote .bhcast-obs-state { color: var(--room-acc); }
.bhcast-obs--remote .bhcast-obs-pop { border-color: rgba(95, 195, 255, .45); }

/* La ligne « pilotage à distance », toujours en tête du panneau — y compris quand rien ne
   pilote : un vide se lirait comme « pas encore chargé », alors que c'est une information. */
.bhcast-obs-remote {
    box-sizing: border-box; display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px; padding: 7px 10px; border-radius: var(--radius);
    border: 1px solid var(--room-line-2); background: var(--room-navy-3);
}
.bhcast-obs-remote-dot {
    flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--room-ink-4);
}
.bhcast-obs-remote-state {
    font: 500 9px/1.35 var(--room-mono); letter-spacing: .08em;
    text-transform: uppercase; color: var(--room-ink-3);
}
.bhcast-obs-remote--on { border-color: rgba(95, 195, 255, .4); background: rgba(95, 195, 255, .08); }
.bhcast-obs-remote--on .bhcast-obs-remote-dot { background: var(--room-acc); }
.bhcast-obs-remote--on .bhcast-obs-remote-state { color: var(--room-acc); }
.bhcast-obs-remote--wait { border-color: rgba(249, 160, 63, .45); background: rgba(249, 160, 63, .1); }
.bhcast-obs-remote--wait .bhcast-obs-remote-dot { background: var(--room-gold); }
.bhcast-obs-remote--wait .bhcast-obs-remote-state { color: var(--room-gold); }

/* ── Le bandeau d'antenne ──────────────────────────────────────────────────── */
/* 🔴 LA SEULE ZONE CONÇUE POUR ÊTRE LUE DE LOIN, en parlant, sans tourner la tête. Tout le
   reste de l'écran est de la consultation, entre 11 et 15 px. C'est le contraste d'échelle
   qui rend ce bandeau lisible — le grossir sans rapetisser le reste ne donnerait rien. */
.bhcast-air {
    box-sizing: border-box; min-height: 88px;
    display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    padding: 12px 18px;
    border-bottom: 1px solid var(--room-line-1);
    background: linear-gradient(90deg, rgba(31, 70, 153, .22), rgba(9, 26, 62, .4) 55%, transparent);
}
/* 🔑 Au repos, l'ABSENCE de rouge est l'information. Le bandeau ne disparaît pas : il
   déplacerait tout l'écran au premier envoi. */
.bhcast-air-dot {
    width: 12px; height: 12px; flex: none; border-radius: 50%;
    background: var(--room-line-2); box-shadow: 0 0 0 5px rgba(31, 70, 153, .22);
}
.bhcast-air-tag {
    flex: none; font: 700 13px/1 var(--room-mono); letter-spacing: .18em;
    text-transform: uppercase; color: var(--room-ink-3);
}
.bhcast-air-sep { width: 1px; height: 36px; flex: none; background: var(--room-line-2); }
.bhcast-air-title {
    min-width: 0; font: 700 40px/1 var(--room-display);
    text-transform: uppercase; color: var(--room-ink-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-air-badge {
    flex: none; height: 22px; padding: 0 8px; display: grid; place-items: center;
    border-radius: var(--radius); background: var(--room-navy-3);
    font: 700 10px/1 var(--room-mono); letter-spacing: .08em; color: var(--room-ink-2);
}
.bhcast-air-spacer { flex: 1; min-width: 0; }
.bhcast-air-clock { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 7px; }
/* ⚠️ Chiffres TABULAIRES : sans eux le chrono danse d'un demi-caractère à chaque seconde,
   et l'œil y revient au lieu de le lire au passage. */
.bhcast-air-time {
    font: 700 38px/1 var(--room-mono); color: var(--room-ink-4); font-variant-numeric: tabular-nums;
}
.bhcast-air-who {
    font: 500 11px/1 var(--room-mono); letter-spacing: .12em;
    text-transform: uppercase; color: var(--room-ink-4); white-space: nowrap;
}
.bhcast-air-cut {
    flex: none; height: 40px; padding: 0 16px; display: grid; place-items: center; cursor: pointer;
    border-radius: var(--radius); border: 1px solid rgba(255, 66, 92, .5); background: rgba(255, 66, 92, .12);
    font: 600 13px/1 'Archivo', sans-serif; color: var(--room-live-2);
}
.bhcast-air-cut:hover { border-color: var(--room-live); background: rgba(255, 66, 92, .2); }

/* Quelque chose SORT : tout le bandeau bascule au rouge, et lui seul. */
.bhcast-air--live { border-bottom-color: rgba(255, 66, 92, .4);
    background: linear-gradient(90deg, rgba(255, 66, 92, .2), rgba(255, 66, 92, .06) 58%, transparent); }
.bhcast-air--live .bhcast-air-dot {
    background: var(--room-live); box-shadow: 0 0 0 5px rgba(255, 66, 92, .2);
    animation: bhcast-live 1.6s ease-in-out infinite;
}
.bhcast-air--live .bhcast-air-tag { color: var(--room-live-2); }
.bhcast-air--live .bhcast-air-sep { background: rgba(255, 66, 92, .35); }
.bhcast-air--live .bhcast-air-title { color: #fff; }
.bhcast-air--live .bhcast-air-badge { background: rgba(255, 66, 92, .18); color: var(--room-live-2); }
.bhcast-air--live .bhcast-air-time { color: #fff; }
.bhcast-air--live .bhcast-air-who { color: #ff9aa9; }

/* ── Les intertitres de la liste unique ────────────────────────────────────── */
/* 🔑 Un INTERTITRE, pas un panneau : les trois groupes vivent dans la même liste, avec le
   même bouton. Trois cadres laissaient croire à trois mécaniques — et les sources vivaient
   même dans une autre colonne. */
.bhcast-group {
    box-sizing: border-box; min-height: 28px; display: flex; align-items: center; gap: 9px;
    padding: 0 15px; background: rgba(15, 44, 102, .5);
}
.bhcast-group-title {
    font: 600 9px/1 var(--room-mono); letter-spacing: .16em;
    text-transform: uppercase; color: var(--room-ink-4);
}
.bhcast-group-note {
    margin-left: auto; font: 400 10px/1.4 'Archivo', sans-serif; color: var(--room-ink-4);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-room .bhcast-onelist { padding: 0 2px; text-wrap: pretty; }

/* ── Ce qui partirait au clic suivant ──────────────────────────────────────── */
/* 🔴 L'armement au survol était INVISIBLE : le casteur ne savait pas qu'il avait fait
   quelque chose. Cyan, jamais rouge — le rouge est réservé à ce qui sort déjà. */
.bhcast-armed {
    box-sizing: border-box; min-height: 64px; display: flex; align-items: center; gap: 14px;
    padding: 11px 15px; border-radius: var(--radius);
    border: 1px solid rgba(0, 179, 255, .45); background: rgba(0, 179, 255, .08);
}
.bhcast-armed-tag {
    flex: none; font: 600 10px/1 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-acc);
}
.bhcast-armed-thumb {
    width: 72px; height: 40px; flex: none; border-radius: var(--radius); border: 1px solid var(--room-line-3);
    background: repeating-linear-gradient(135deg, var(--room-navy-3), var(--room-navy-3) 8px,
                var(--room-navy-2) 8px, var(--room-navy-2) 16px);
}
.bhcast-armed-main { flex: 1; min-width: 0; }
.bhcast-armed-name {
    display: block; font: 700 22px/1 var(--room-display);
    text-transform: uppercase; color: var(--room-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-armed-note {
    display: block; margin-top: 5px; font: 400 12px/1.4 'Archivo', sans-serif;
    color: var(--room-ink-2); text-wrap: pretty;
}
.bhcast-armed-go {
    flex: none; height: 34px; padding: 0 15px; display: grid; place-items: center; cursor: pointer;
    border: 0; border-radius: var(--radius);
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
    font: 600 13px/1 'Archivo', sans-serif; color: #fff;
}

/* ── Déclarer une source : la rangée d'action au repos ─────────────────────── */
/* 🔑 Quand le groupe est vide, cette rangée EST le groupe : pas de phrase « rien à envoyer »
   au-dessus d'un formulaire — une ligne d'action suffit et tient en une hauteur d'entrée. */
.bhcast-addsrc-open {
    box-sizing: border-box; width: 100%; height: 42px; display: flex; align-items: center; gap: 10px;
    padding: 0 15px; border: 0; border-top: 1px dashed var(--room-line-2); background: none;
    cursor: pointer; font: 600 13px/1 'Archivo', sans-serif; color: var(--room-acc); text-align: left;
}
.bhcast-addsrc-open:hover { background: rgba(0, 179, 255, .06); }
.bhcast-addsrc-plus {
    width: 18px; height: 18px; flex: none; display: grid; place-items: center;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-3);
    font: 600 12px/1 'Archivo', sans-serif; color: var(--room-acc);
}

/* ── La régie refuse de se réduire ─────────────────────────────────────────── */
/* 🔴 Sous 820 px, trois colonnes empilées mettent l'antenne, la liste et les calques à trois
   écrans de défilement les uns des autres : le casteur enverrait à l'aveugle. Mieux vaut un
   message qu'un outil qui ment sur ce qu'il sait faire. */
.bhcast-narrow { display: none; padding: 22px 18px; }
.bhcast-narrow strong { display: block; font: 700 20px/1.2 var(--room-display); text-transform: uppercase; }
.bhcast-narrow p { margin: 10px 0 0; font: 400 13px/1.6 'Archivo', sans-serif; color: var(--room-ink-2); }


/* ── Trois colonnes : bibliothèque · antenne · calques ─────────────────────── */
/* Elles retombent en une seule sous 1100px — la régie ne se pilote pas sur un
   téléphone, mais un portable 13" reste un poste de casteur légitime. */
.bhcast-room-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.9fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    padding: 18px;
}
.bhcast-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* ── Les panneaux ──────────────────────────────────────────────────────────── */
.bhcast-panel {
    border-radius: var(--radius); border: 1px solid var(--room-line-2); overflow: hidden; min-width: 0;
    background: linear-gradient(180deg, rgba(15, 44, 102, .7), rgba(7, 20, 51, .95));
}
.bhcast-panel-head {
    display: flex; align-items: center; gap: 8px; padding: 10px 13px;
    border-bottom: 1px solid var(--room-line-1);
}
.bhcast-panel-title {
    margin: 0; font: 600 8.5px/1 var(--room-mono); letter-spacing: .14em;
    text-transform: uppercase; color: var(--room-ink-3); font-weight: 600;
}
.bhcast-panel-count { margin-left: auto; font: 400 9.5px/1 'Archivo', sans-serif; color: var(--room-ink-4); }
.bhcast-panel-body { padding: 3px 0; }
.bhcast-panel-foot { padding: 9px 13px; border-top: 1px solid var(--room-line-1); }

/* ── Une entrée de la bibliothèque ─────────────────────────────────────────── */
.bhcast-entry { display: flex; align-items: center; gap: 11px; min-width: 0; padding: 10px 15px; }
/* Ce qui passe à l'antenne : liseré rouge et aplat. Le casteur le repère sans lire. */
.bhcast-entry--onair { background: rgba(255, 66, 92, .1); box-shadow: inset 3px 0 0 var(--room-live); }
/* 🔴 PAS D'OPACITÉ D'ENSEMBLE sur une entrée indisponible. Elle faisait tomber le libellé sous le
   seuil de contraste — illisible au moment précis où le casteur cherche POURQUOI il ne peut pas
   l'envoyer. On désature la pastille et la raison ; le nom, lui, reste lisible. */
.bhcast-entry--off .bhcast-entry-name { color: var(--room-ink-3); }
.bhcast-entry--off .bhcast-entry-sub { color: var(--room-ink-4); }
.bhcast-entry-main { flex: 1; min-width: 0; }
.bhcast-entry-name {
    display: block; font: 600 15px/1.15 'Archivo', sans-serif; color: var(--room-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhcast-entry-sub {
    display: flex; align-items: center; gap: 7px; row-gap: 4px; flex-wrap: wrap;
    margin-top: 4px; min-width: 0;
    font: 400 11.5px/1 'Archivo', sans-serif; color: var(--room-ink-3);
}
/* 🔴 LA CIBLE EST NOMMÉE, PAS COMPTÉE. Ce sélecteur visait `span:last-child` — c'était le
   sous-libellé jusqu'au jour où un repère est venu se poser après lui : l'ellipse est alors
   tombée sur le REPÈRE, tronqué à « confirm… ». Un sélecteur positionnel se casse en silence
   au premier élément ajouté. */
.bhcast-entry-sublabel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 🔑 UNE ÉTIQUETTE, plus une vignette de 38x22. La vignette tenait la place d'un aperçu qui
   n'est jamais venu : elle imposait 22 px à la sous-ligne, donc des rangées de 63 px au lieu
   des 46 annotés sur la maquette — un tiers de liste en moins à l'écran, chez un casteur qui
   peut avoir quatorze POV. Sa largeur suit désormais le mot. */
.bhcast-badge {
    height: 16px; padding: 0 5px; flex: none; display: grid; place-items: center;
    border-radius: var(--radius); background: var(--room-navy-3);
    font: 700 8px/1 var(--room-mono); letter-spacing: .06em; color: var(--room-ink-3);
}
.bhcast-send {
    flex: none; height: 26px; padding: 0 11px; display: grid; place-items: center;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-2);
    font: 600 12px/1 'Archivo', sans-serif; color: var(--room-ink-2); cursor: pointer;
}
.bhcast-send:hover,
/* Armé par le survol : le bouton s'allume AVANT le clic, comme la rangée. */
.bhcast-send--armed {
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
    border-color: var(--room-acc-2); color: #fff;
}
.bhcast-entry-onair {
    flex: none; height: 26px; padding: 0 10px; display: grid; place-items: center;
    border-radius: var(--radius); background: rgba(255, 66, 92, .22);
    font: 700 10.5px/1 var(--room-mono); letter-spacing: .06em; color: var(--room-live-2);
}
/* La raison d'un bouton absent : elle a autant de place que le bouton qu'elle remplace. */
.bhcast-entry-reason {
    flex: none; max-width: 170px; text-align: right;
    font: 400 9.5px/1.35 'Archivo', sans-serif; color: var(--room-ink-4);
}
.bhcast-dot-s { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--room-live); }
.bhcast-dot-s--idle { background: var(--room-line-2); }
.bhcast-dot-s--pulse { animation: bhcast-live 1.6s ease-in-out infinite; }

/* ── L'antenne ─────────────────────────────────────────────────────────────── */
.bhcast-onair { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.bhcast-onair-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.bhcast-onair-tag {
    height: 20px; padding: 0 8px; display: flex; align-items: center; gap: 6px; flex: none;
    border-radius: var(--radius); background: rgba(255, 66, 92, .16);
    font: 700 9px/1 var(--room-mono); letter-spacing: .12em; color: var(--room-live-2);
}
.bhcast-onair-tag i {
    width: 5px; height: 5px; border-radius: 50%; background: var(--room-live); display: block;
    animation: bhcast-live 1.6s ease-in-out infinite;
}
.bhcast-onair-what { font: 600 12px/1 'Archivo', sans-serif; color: var(--room-ink); }
.bhcast-onair-since { font: 400 10px/1 'Archivo', sans-serif; color: var(--room-ink-3); margin-left: auto; }
.bhcast-onair-frame {
    position: relative; aspect-ratio: 16 / 9; min-height: 200px;
    border: 2px solid var(--room-live); border-radius: var(--radius); overflow: hidden;
    display: flex; flex-direction: column; gap: 8px;
    align-items: center; justify-content: center; text-align: center;
    background: radial-gradient(90% 80% at 50% 0%, #12347a 0%, var(--room-navy-1) 55%, var(--room-bg) 100%);
}
/* 🔴 LE MONTAGE À DEUX COUCHES, celui du casteur reproduit dans la régie.

   Au FOND, le lecteur de la plateforme. Il est **cliquable**, et ce n'est pas un oubli : sur une
   chaîne étiquetée « contenu mature » — toutes les chaînes Warzone le sont — Twitch exige un geste
   humain, et c'est ici qu'on le fait. Une fois par navigateur : le stockage cloisonné retient
   l'acceptation pour cette origine.

   PAR-DESSUS, l'habillage, en `pointer-events: none` — sinon il avalerait ce clic sans que rien ne
   le dise, et le casteur conclurait à une panne. Son fond ne devient transparent QUE lorsqu'une
   vidéo est posée dessous : sans vidéo, il doit garder son aplat, faute de quoi le damier du mode
   transparent transparaîtrait sous un contenu plein écran. */
.bhcast-onair-video {
    position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000;
}
.bhcast-onair-live {
    position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
    pointer-events: none; background: var(--room-bg);
}
.bhcast-onair-frame--video .bhcast-onair-live { background: transparent; }

.bhcast-room .bhcast-onair-why { max-width: 380px; }
/* Sans adresse de page, la note ne doit pas couvrir l'image : elle monte en haut du cadre. */
.bhcast-onair-frame--video .bhcast-onair-why {
    position: absolute; left: 12px; right: 12px; top: 12px; z-index: 2; max-width: none;
    padding: 7px 10px; border-radius: var(--radius); background: rgba(4, 13, 36, .82);
}
/* Le geste à faire une fois, dit SUR le cadre. Ambre : c'est un mode d'emploi, pas une panne. */
/* 🔴 SOUS LE CADRE, plus DEDANS. En `position: absolute` au bas du lecteur, ce mode d'emploi
   masquait la moitié basse de l'image — c'est-à-dire la barre de Twitch et l'endroit exact où il
   faut cliquer pour accepter la barrière. Un repère qui explique un geste ne doit pas recouvrir sa
   cible. Il est donc devenu un bloc ordinaire, posé après le cadre. */
.bhcast-onair-gate {
    display: block; margin: 9px 0 0;
    padding: 8px 11px; border-radius: var(--radius);
    border: 1px solid rgba(249, 160, 63, .45); background: rgba(4, 13, 36, .88);
    font: 500 11px/1.45 'Archivo', sans-serif; color: var(--room-gold-2); text-wrap: pretty;
}
/* Le damier n'existe QUE dans l'aperçu de la régie : il n'est jamais rendu à
   l'antenne. Il dit « ici, c'est transparent ». */
.bhcast-onair-frame--alpha {
    border-color: var(--room-line-3);
    background-color: var(--room-bg);
    background-image:
        linear-gradient(45deg, var(--room-navy-3) 25%, transparent 25%),
        linear-gradient(-45deg, var(--room-navy-3) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--room-navy-3) 75%),
        linear-gradient(-45deg, transparent 75%, var(--room-navy-3) 75%);
    background-size: 22px 22px;
    background-position: 0 0, 0 11px, 11px -11px, -11px 0;
}
.bhcast-onair-rail { position: absolute; left: 0; right: 0; top: 0; height: 4px; background: var(--room-acc-2); }
.bhcast-onair-frame--alpha .bhcast-onair-rail { display: none; }
.bhcast-onair-what-big { font: 700 34px/1 var(--room-display); text-transform: uppercase; color: var(--room-ink); }
.bhcast-onair-mode {
    position: absolute; right: 12px; top: 12px; height: 18px; padding: 0 7px;
    display: grid; place-items: center; border-radius: var(--radius); background: rgba(4, 13, 36, .85);
    font: 600 7.5px/1 var(--room-mono); letter-spacing: .08em; color: var(--room-ink-3);
}
.bhcast-journal {
    margin: 0; display: flex; align-items: center; gap: 10px;
    padding: 10px 13px; border-radius: var(--radius);
    border: 1px solid var(--room-line-1); background: var(--room-navy-1);
    font: 400 10px/1.45 'Archivo', sans-serif; color: var(--room-ink-2);
}
.bhcast-journal-who { margin-left: auto; font: 400 9px/1 var(--room-mono); color: var(--room-ink-4); white-space: nowrap; }

/* Le repli du chien de garde : ambre, comme tout ce qui alerte sans être une panne. */
/* 🔴 SOUS UN BANDEAU D'ANTENNE RESTÉ ROUGE : quelque chose EST diffusé, l'écran d'attente.
   La bande dit ce qui a lâché, en ambre, et propose la seule action utile. Rien ne clignote
   en rouge « erreur » — dans cet écran le rouge ne veut dire qu'une chose. */
.bhcast-fallback {
    box-sizing: border-box; min-height: 64px;
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 12px 18px;
    border-top: 1px solid rgba(249, 160, 63, .3);
    border-bottom: 1px solid rgba(249, 160, 63, .3);
    background: rgba(249, 160, 63, .1);
    font: 400 13px/1.45 'Archivo', sans-serif; color: var(--room-gold-2);
}
.bhcast-fallback-tag {
    flex: none; height: 18px; padding: 0 7px; display: grid; place-items: center;
    border-radius: var(--radius); background: rgba(249, 160, 63, .16);
    font: 700 8px/1 var(--room-mono); letter-spacing: .08em; color: var(--room-gold);
}
.bhcast-fallback-why { flex: 1; min-width: 120px; font: 600 13px/1.35 'Archivo', sans-serif; color: var(--room-gold-2); }
.bhcast-fallback-when { font: 400 9px/1 var(--room-mono); color: var(--room-ink-3); white-space: nowrap; }
/* Une seule action VRAIMENT utile est mise en avant : renvoyer ce qui est tombé. Rester sur
   l'attente n'est qu'un accusé de lecture — il n'envoie rien, il écarte la bande. */
.bhcast-fallback-go {
    flex: none; height: 36px; padding: 0 15px; display: grid; place-items: center; cursor: pointer;
    border: 0; border-radius: var(--radius);
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
    font: 600 13px/1 'Archivo', sans-serif; color: #fff;
}
.bhcast-fallback-stay {
    flex: none; height: 36px; padding: 0 15px; display: grid; place-items: center; cursor: pointer;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-2);
    font: 600 13px/1 'Archivo', sans-serif; color: var(--room-ink-2);
}

/* ── Les calques ───────────────────────────────────────────────────────────── */
.bhcast-layer {
    display: flex; align-items: center; gap: 9px; min-width: 0;
    padding: 11px 14px; border-bottom: 1px solid var(--room-navy-3);
}
.bhcast-layer:last-child { border-bottom: 0; }
.bhcast-layer--main { background: rgba(0, 179, 255, .06); box-shadow: inset 2px 0 0 var(--room-acc-2); }
.bhcast-layer-main { flex: 1; min-width: 0; }
.bhcast-layer-name { display: block; font: 600 11.5px/1 'Archivo', sans-serif; color: var(--room-ink); }
.bhcast-layer-sub {
    display: block; margin-top: 4px; font: 400 9px/1 'Archivo', sans-serif; color: var(--room-ink-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 🔴 Les deux réglages restent des CASES À COCHER — seule leur peinture change.
   Un bouton stylé perdrait l'état coché, le pilotage au clavier et le rôle lu
   par les lecteurs d'écran, pour un pixel identique. Le libellé est masqué à
   l'œil mais reste DANS le document : c'est lui qui nomme la commande. */
.bhcast-room .bhcast-switch--vis,
.bhcast-room .bhcast-switch--pin { position: relative; flex: none; cursor: pointer; display: block; }
.bhcast-room .bhcast-switch--vis span,
.bhcast-room .bhcast-switch--pin span {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
}
.bhcast-room .bhcast-switch--vis input,
.bhcast-room .bhcast-switch--pin input {
    appearance: none; margin: 0; cursor: pointer; display: block;
}
.bhcast-room .bhcast-switch--vis input {
    position: relative; width: 38px; height: 22px; border-radius: var(--radius);
    background: var(--room-navy-3); border: 1px solid var(--room-line-3);
}
.bhcast-room .bhcast-switch--vis input::after {
    content: ''; position: absolute; left: 3px; top: 3px; width: 14px; height: 14px;
    border-radius: 50%; background: var(--room-ink-4); transition: left .15s ease;
}
.bhcast-room .bhcast-switch--vis input:checked {
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
}
.bhcast-room .bhcast-switch--vis input:checked::after { left: 19px; background: #fff; }
.bhcast-room .bhcast-switch--pin input {
    width: 24px; height: 24px; border-radius: var(--radius);
    border: 1px solid var(--room-line-1); background: transparent;
    color: var(--room-ink-4); font: 600 11px/22px var(--room-mono); text-align: center;
}
.bhcast-room .bhcast-switch--pin input::after { content: '⊙'; display: block; }
.bhcast-room .bhcast-switch--pin input:checked {
    border-color: var(--room-acc-2); color: #fff;
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
}
.bhcast-room .bhcast-switch--vis input:focus-visible,
.bhcast-room .bhcast-switch--pin input:focus-visible { outline: 2px solid var(--room-acc); outline-offset: 2px; }

/* ── Le bandeau d'information ──────────────────────────────────────────────── */
.bhcast-banner-body { padding: 11px 13px; display: flex; flex-direction: column; gap: 8px; }
.bhcast-room .bhcast-input--area { min-height: 46px; padding: 8px 10px; resize: vertical; }
/* Des textes tout prêts : en direct, on clique, on ne rédige pas. */
.bhcast-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.bhcast-chip {
    height: 20px; padding: 0 8px; display: grid; place-items: center;
    border-radius: var(--radius); border: 1px solid var(--room-line-2); background: var(--room-navy-3);
    font: 500 9px/1 'Archivo', sans-serif; color: var(--room-ink-2); cursor: pointer;
}
.bhcast-chip:hover { border-color: var(--room-acc-2); color: var(--room-ink); }
.bhcast-banner-actions { display: flex; gap: 8px; }
.bhcast-banner-actions .btn-primary,
.bhcast-banner-actions .btn-ghost {
    height: 26px; padding: 0 12px; border-radius: var(--radius);
    font: 600 10px/1 'Archivo', sans-serif;
}
.bhcast-banner-actions .btn-primary {
    flex: 1; border: 0; color: #fff;
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
}
.bhcast-banner-actions .btn-ghost {
    border: 1px solid var(--room-line-3); background: var(--room-navy-2); color: var(--room-ink-2);
}

/* ── Pilotage d'OBS ──────────────────────────────────────────────────── */
/* 🔴 CE PANNEAU NE RÉUTILISE PLUS `.bhcast-banner-body` : ce conteneur a été dessiné autour
   d'un `<textarea>` qui porte sa propre hauteur, et trois champs d'une ligne n'y héritaient
   d'aucune géométrie. Tout ce qui suit est à lui. */
.bhcast-obs-body { padding: 14px 15px 15px; display: flex; flex-direction: column; gap: 11px; }
.bhcast-obs-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhcast-obs-label {
    font: 600 9.5px/1 var(--room-mono); letter-spacing: .12em;
    text-transform: uppercase; color: var(--room-ink-4);
}
/* La géométrie du champ, en propre : hauteur, `box-sizing` et interlignage explicites.
   ⚠️ 30 px d'interlignage pour 32 px de haut : `border-box` retranche les deux bordures.
   🔑 Les métriques sont celles ANNOTÉES sur la maquette (Rd) : h 32, padding 0 11, texte 12.5. */
.bhcast-room .bhcast-obs-input {
    box-sizing: border-box;
    width: 100%;
    height: 32px;
    flex: none;
    padding: 0 11px; border-radius: var(--radius);
    border: 1px solid var(--room-line-3); background: var(--room-navy-2);
    font: 400 12.5px/30px 'Archivo', sans-serif; color: var(--room-ink);
}
.bhcast-obs-go {
    box-sizing: border-box; width: 100%; height: 32px; display: grid; place-items: center;
    border: 0; border-radius: var(--radius); cursor: pointer;
    background: linear-gradient(180deg, var(--room-acc-2), var(--room-acc-3));
    font: 600 13px/1 'Archivo', sans-serif; color: #fff;
}
.bhcast-obs-notes { display: flex; flex-direction: column; gap: 5px; padding-top: 2px; }
.bhcast-room .bhcast-obs-note { font: 400 9.5px/1.45 'Archivo', sans-serif; color: var(--room-ink-2); }
.bhcast-room .bhcast-obs-note--dim { color: var(--room-ink-3); }
.bhcast-obs-note b { color: var(--room-acc); font-weight: 600; }
/* Le geste d'oubli vit DANS la note qui annonce ce qui est retenu : un réglage gardé en silence est
   une surprise, et l'adresse de page porte la clé de diffusion. Discret — c'est un geste rare —
   mais toujours à portée, sur un poste partagé notamment. */
.bhcast-obs-forget {
    margin-left: 6px; padding: 0; border: 0; background: none; cursor: pointer;
    font: 600 9.5px/1.45 'Archivo', sans-serif; color: var(--room-acc);
    text-decoration: underline;
}
.bhcast-obs-forget:hover { color: var(--room-ink); }

/* La pastille d'état, lue du coin de l'œil. Éteinte par défaut. */
.bhcast-obs-dot {
    width: 7px; height: 7px; flex: none; margin-left: auto; border-radius: 50%;
    background: var(--room-line-2); box-shadow: 0 0 0 3px rgba(31, 70, 153, .18);
}
.bhcast-obs-state {
    font: 500 9px/1 var(--room-mono); letter-spacing: .1em;
    text-transform: uppercase; color: var(--room-ink-4); white-space: nowrap;
}

/* État connecté : le formulaire s'efface, il ne reste qu'une ligne. */
.bhcast-obs-live {
    box-sizing: border-box; min-height: 44px; display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; border-radius: var(--radius);
    border: 1px solid rgba(55, 217, 154, .35); background: rgba(55, 217, 154, .08);
}
.bhcast-obs-live-dot { width: 5px; height: 5px; flex: none; border-radius: 50%; background: var(--room-ok); }
.bhcast-obs-live-main { flex: 1; min-width: 0; }
.bhcast-obs-live-name {
    display: block; font: 600 11.5px/1 'Archivo', sans-serif; color: var(--room-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bhcast-obs-live-addr {
    display: block; margin-top: 4px; font: 400 9px/1 var(--room-mono); color: var(--room-ink-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Se déconnecter est un geste rare : bordure, jamais un aplat qui appellerait le clic. */
.bhcast-obs-off {
    box-sizing: border-box; height: 22px; padding: 0 9px; display: grid; place-items: center;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-2);
    font: 600 10px/1 'Archivo', sans-serif; color: var(--room-ink-2); cursor: pointer;
}
.bhcast-obs--on .bhcast-obs-dot { background: var(--room-ok); box-shadow: 0 0 0 3px rgba(55, 217, 154, .18); }
.bhcast-obs--on .bhcast-obs-state { color: var(--room-ok); }

/* 🔴 ÉCHEC EN AMBRE, JAMAIS EN ROUGE : dans cet écran le rouge dit « à l'antenne ». Un cadre
   rouge autour d'un panneau de confort ferait croire à une diffusion tombée. */
.bhcast-obs--fail { border-color: rgba(249, 160, 63, .45); }
.bhcast-obs--fail .bhcast-panel-head {
    border-bottom-color: rgba(249, 160, 63, .3); background: rgba(249, 160, 63, .08);
}
.bhcast-obs--fail .bhcast-obs-dot { background: var(--room-gold); box-shadow: 0 0 0 3px rgba(249, 160, 63, .2); }
.bhcast-obs--fail .bhcast-obs-state { color: var(--room-gold); }
.bhcast-obs-alert {
    display: flex; gap: 9px; padding: 9px 10px; border-radius: var(--radius);
    border: 1px solid rgba(249, 160, 63, .4); background: rgba(249, 160, 63, .1);
}
.bhcast-obs-alert-dot {
    width: 5px; height: 5px; flex: none; margin-top: 4px; border-radius: 50%; background: var(--room-gold);
}
.bhcast-obs-alert-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bhcast-obs-alert-title { font: 600 10.5px/1.35 'Archivo', sans-serif; color: var(--room-gold-2); }
.bhcast-obs-alert-calm { font: 400 9.5px/1.45 'Archivo', sans-serif; color: var(--room-ink-2); }
.bhcast-obs-field--fail .bhcast-obs-label { color: var(--room-gold); }
.bhcast-room .bhcast-obs-field--fail .bhcast-obs-input { border-color: var(--room-gold); }


/* 🔴 DEUX COLONNES, JAMAIS UNE. Sous le point de rupture, la sortie passe pleine largeur en
   haut et la liste côtoie les calques — une régie en colonne unique n'est pas pilotable : les
   trois organes se retrouvent à trois écrans de défilement les uns des autres. */
@media (max-width: 1240px) {
    .bhcast-room-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
    .bhcast-room-grid .bhcast-onair { grid-column: 1 / -1; order: -1; }
    .bhcast-air-title { font-size: 30px; }
    .bhcast-air-time { font-size: 28px; }
}

/* 🔴 Et sous 820 px, un REFUS plutôt qu'une console inutilisable. C'est un choix assumé :
   mieux vaut un message qu'un outil qui ment sur ce qu'il sait faire. */
@media (max-width: 820px) {
    .bhcast-room > .bhcast-topbar,
    .bhcast-room > .bhcast-air,
    .bhcast-room > .bhcast-fallback,
    .bhcast-room > .bhcast-room-grid { display: none; }
    .bhcast-narrow { display: block; }
}
/* Une liste vide se dit DANS le panneau, pas à côté. */
/* ── Les repères d'une entrée : ce qui gênera l'envoi ──────────────────────── */
/* 🔴 DES REPÈRES, PAS DES VERROUS : le bouton « Envoyer » reste. L'état vient d'une
   interrogation, et un joueur peut lancer son flux entre la lecture et le clic.
   🔑 Hiérarchie voulue : « n'émet pas » signifie qu'il n'y a RIEN à jouer, donc l'ambre ;
   « confirmation dans OBS » n'est qu'un geste à faire une fois, donc un simple contour. */
.bhcast-warn {
    flex: none; height: 15px; padding: 0 6px; display: inline-grid; place-items: center;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-3);
    font: 500 8.5px/1 var(--room-mono); letter-spacing: .04em; text-transform: uppercase;
    color: var(--room-ink-4); white-space: nowrap;
}
.bhcast-warn--off {
    border-color: rgba(249, 160, 63, .45); background: rgba(249, 160, 63, .1);
    color: var(--room-gold);
}
.bhcast-panel-empty { margin: 0; padding: 12px 13px; }

/* Consentement de rediffusion sur la fiche de tournoi (SPEC-CAST §7.3). Discret mais toujours
   visible : c'est une autorisation qu'on doit pouvoir retirer aussi facilement qu'on l'a donnée. */
.bhcast-consent {
    margin-top: 14px;
    padding: 12px 16px;
    background: var(--bg-inset);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
/* L'option « caster BracketHub » dans le tiroir des comptes (US #1090). */
.bhusr-caster-state { display: flex; align-items: center; gap: 8px; margin: 2px 0 6px; }
.bhusr-caster-on {
    height: 22px; padding: 0 10px; display: inline-grid; place-items: center; border-radius: var(--radius);
    background: var(--tint-green-bg); color: var(--green-fg);
    font: 600 11px/1 'JetBrains Mono', monospace; letter-spacing: .06em;
}
.bhusr-caster-off {
    height: 22px; padding: 0 10px; display: inline-grid; place-items: center; border-radius: var(--radius);
    background: var(--bg-chip); color: var(--text-muted);
    font: 600 11px/1 'JetBrains Mono', monospace; letter-spacing: .06em;
}
.bhusr-caster-note { margin: 0 0 10px; font: 400 12px/1.55 'Archivo', sans-serif; color: var(--text-muted); }
.bhusr-caster-form { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.bhusr-caster-until { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bhusr-caster-until > span { font: 500 11px/1 'JetBrains Mono', monospace; letter-spacing: .1em;
    text-transform: uppercase; color: var(--text-muted); }
.bhusr-caster-until em { font-style: normal; color: var(--orange-fg); }
/* ── L'aperçu du survol dans la régie (US #1095) ───────────────────────────── */
/* Il vit DANS l'entrée survolée, jamais dans le cadre du centre : celui-ci
   montre ce qui est à l'antenne, et confondre les deux serait la faute d'une
   régie. L'entrée survolée s'éclaire d'un accent bleu — l'antenne, elle, reste
   la seule chose en rouge. */
.bhcast-entry-wrap { min-width: 0; }
.bhcast-entry--peek { background: rgba(0, 179, 255, .07); box-shadow: inset 2px 0 0 var(--room-acc-2); }
.bhcast-peek { display: flex; align-items: center; gap: 9px; padding: 0 13px 10px; min-width: 0; }
.bhcast-peek-frame {
    position: relative; width: 150px; aspect-ratio: 16 / 9; flex: none; overflow: hidden;
    border-radius: var(--radius); border: 1px solid var(--room-line-3); background: var(--room-navy-3);
    /* La vignette publique de la chaîne, posée en style en ligne par PeekBackdrop. */
    background-size: cover; background-position: center;
}
/* 🔴 Le lecteur est RÉVÉLÉ, pas affiché d'emblée, et ce délai n'est pas décoratif : un iframe qui
   n'a pas encore peint son document est rendu BLANC par Chrome, ce qui masquerait la vignette du
   fond juste au moment où elle sert — cf. feedback_iframe_transparent_needs_color_scheme. Le
   fondu laisse donc voir le fond pendant le chargement, puis rend la main au lecteur.
   ⚠️ 0,9 s est une approximation du temps de montage, pas un signal : la page ne peut RIEN savoir
   de ce qui se passe dans un iframe tiers (mesuré le 2026-09-12 — même lecteur, 60 img/s dans un
   navigateur et gelé dans l'autre, avec les mêmes événements). */
.bhcast-peek-frame iframe {
    position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
    opacity: 0; animation: bhcast-peek-reveal .18s .9s forwards;
}
@keyframes bhcast-peek-reveal { to { opacity: 1; } }
/* ── « Interaction Twitch requise » : le repère posé PAR-DESSUS le lecteur ────────────────────
   🔴 `pointer-events: none` EST LA RÈGLE, pas une finition : ce repère annonce un clic à faire
   DANS le lecteur qui est dessous. S'il avalait ce clic, il empêcherait le geste qu'il demande.
   ⚠️ Discret à dessein : il apparaît pendant un direct, et un bandeau criard ferait croire à une
   panne de BracketHub alors que c'est un écran de Twitch qui attend un humain. */
.bhcast-onair-interact {
    position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
    max-width: 90%; padding: 5px 11px; border-radius: var(--radius);
    border: 1px solid var(--room-line-2); background: rgba(var(--overlay-rgb), .72);
    font: 500 10px/1.4 'Archivo', sans-serif; letter-spacing: .04em;
    color: var(--room-ink); text-align: center;
    pointer-events: none;
}
/* 🔴 Le mot « MUET » est posé PAR-DESSUS le lecteur, et il n'est pas décoratif :
   c'est la seule chose qui distingue un aperçu d'un direct à l'antenne. */
.bhcast-peek-muted {
    position: absolute; left: 5px; bottom: 4px; height: 15px; padding: 0 5px;
    display: grid; place-items: center; border-radius: var(--radius); background: rgba(4, 13, 36, .85);
    font: 600 7.5px/1 var(--room-mono); letter-spacing: .08em; color: var(--room-ink-3);
}
.bhcast-peek-note { flex: 1; min-width: 0; font: 400 9.5px/1.4 'Archivo', sans-serif; color: var(--room-ink-2); }
/* ── Le lien de régie d'un casteur invité (US #1094) ───────────────────────── */
/* Il répond à la bonne question au bon moment : il s'affiche quand on n'est
   caster de rien, c'est-à-dire là où un casteur invité arrive. */
.bhcast-invite {
    margin: 18px; padding: 14px 16px; border-radius: var(--radius);
    border: 1px solid var(--room-line-3);
    background: linear-gradient(160deg, rgba(0, 179, 255, .1), var(--room-navy-1));
}
.bhcast-invite-title {
    display: block; font: 600 12.5px/1 'Archivo', sans-serif; color: var(--room-ink);
}
.bhcast-invite-note {
    margin: 8px 0 0; font: 400 10.5px/1.5 'Archivo', sans-serif; color: var(--room-ink-2);
}
.bhcast-invite-form { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 11px; }

/* ── Le geste Twitch, à faire une fois dans OBS (écran de préparation) ───────────────────────
   Même famille visuelle que l'encart du lien de régie : c'est une consigne d'installation, pas
   une alerte. Elle doit se lire une fois puis se laisser oublier — d'où le ton neutre et non
   l'aplat de statut, qui appellerait une action urgente à chaque ouverture de l'écran. */
.bhcast-prep-twitch {
    margin: 0 18px 18px; padding: 14px 16px; border-radius: var(--radius);
    border: 1px solid var(--room-line-3); background: var(--room-navy-1);
}
.bhcast-prep-twitch-title {
    margin: 0; font: 600 12.5px/1.2 'Archivo', sans-serif; color: var(--room-ink);
}
.bhcast-prep-twitch-why {
    margin: 8px 0 0; font: 400 10.5px/1.5 'Archivo', sans-serif; color: var(--room-ink-2);
}
.bhcast-prep-twitch-steps {
    margin: 10px 0 0; padding-left: 20px;
    font: 400 10.5px/1.7 'Archivo', sans-serif; color: var(--room-ink);
}
/* 🔑 La ligne qui dit ce que le produit NE fait PAS se distingue de la liste des gestes : sans
   ça elle se lit comme une cinquième étape, alors qu'elle en est la mise en garde. */
.bhcast-prep-twitch-session {
    margin: 10px 0 0; padding-top: 9px; border-top: 1px solid var(--room-line-3);
    font: 400 10px/1.5 'Archivo', sans-serif; color: var(--room-ink-3);
}
.bhcast-invite-input {
    flex: 1 1 240px; min-width: 180px; height: 30px; padding: 0 10px;
    border-radius: var(--radius); border: 1px solid var(--room-line-2); background: var(--room-navy-2);
    font: 400 11px/1 var(--room-mono); color: var(--room-ink);
}
.bhcast-invite-input:focus { border-color: var(--room-acc-2); outline: none; }
.bhcast-invite-on { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.bhcast-invite-tag {
    flex: none; height: 22px; padding: 0 10px; display: grid; place-items: center; border-radius: var(--radius);
    background: rgba(55, 217, 154, .12); color: #37d99a;
    font: 600 10px/1 var(--room-mono); letter-spacing: .08em;
}
.bhcast-invite-on .bhcast-invite-note { flex: 1; min-width: 0; margin: 0; }
.bhcast-invite-forget {
    flex: none; height: 26px; padding: 0 11px; border-radius: var(--radius); cursor: pointer;
    border: 1px solid rgba(255, 66, 92, .4); background: rgba(255, 66, 92, .1);
    font: 600 10.5px/1 'Archivo', sans-serif; color: var(--room-live-2);
}

/* ── Déclarer une source depuis la régie (US #1122) ─────────────────────────────────────────────
   🔴 Les champs reprennent `.bhcast-obs-input`, qui porte SA PROPRE géométrie. Sans elle ils
   héritaient du `flex: 1 1 180px` de `.bhcast-input` — pensé pour une RANGÉE — et mesuraient 180 px
   de haut dans une colonne. Le défaut ne se lit pas dans le CSS, il se mesure au style calculé. */
.bhcast-addsrc { display: flex; flex-direction: column; gap: 6px; padding-top: 8px; }
.bhcast-addsrc-row { display: flex; gap: 6px; align-items: center; }
/* Le type est court et fixe ; le nom prend ce qui reste. */
.bhcast-addsrc-kind { flex: none; width: 86px; }
.bhcast-addsrc-row .bhcast-obs-input { width: auto; flex: 1 1 auto; min-width: 0; }

/* Le secret rendu une fois, à l'échelle de la régie : le cadre général est trop grand ici. */
.bhcast-secret--room {
    gap: 4px; border-radius: var(--radius); padding: 8px 10px;
    border-color: var(--room-gold); background: rgba(249, 160, 63, .1);
}
.bhcast-secret--room strong { font: 600 9.5px/1.4 'Archivo', sans-serif; color: var(--room-ink); }
.bhcast-secret--room code { font-size: 10.5px; color: var(--room-ink); }

/* Le retrait, en deux temps. ⚠️ DISCRET AU REPOS, à côté d'un bouton d'envoi : en régie, deux
   boutons de même poids se confondent, et l'un des deux coupe l'antenne. */
.bhcast-drop {
    flex: none; width: 18px; height: 18px; display: grid; place-items: center;
    border: 1px solid transparent; border-radius: var(--radius); background: none; cursor: pointer;
    font: 400 13px/1 'Archivo', sans-serif; color: var(--room-ink-4);
}
.bhcast-drop:hover { border-color: var(--room-line-3); color: var(--room-ink-2); }
/* Armé : il change de forme ET de mot, jamais de couleur seule. */
.bhcast-drop--armed {
    width: auto; height: 18px; padding: 0 8px;
    border-color: var(--room-gold); background: rgba(249, 160, 63, .12);
    font: 600 8.5px/1 var(--room-mono); letter-spacing: .06em;
    text-transform: uppercase; color: var(--room-gold); white-space: nowrap;
}

/* ═══ Chaînes de l'organisation — onglet Diffusion, planche 30a ══════════════════════════════════
   🔑 Une ligne par chaîne : pastille de plateforme, identifiant, adresse et état, puis les gestes.
   La principale se distingue par un liseré à sa couleur de marque — c'est la SEULE couleur en dur
   admise ici, au titre de l'exception « couleurs de marque » du thème. */
.bhchan-list { display: flex; flex-direction: column; }

.bhchan {
    display: flex; align-items: center; gap: 14px;
    padding: 13px 16px; border-top: 1px solid var(--line-soft);
}
.bhchan:first-child { border-top: 0; }

/* La principale : liseré intérieur à gauche + fond très léger, pour se lire d'un coup d'œil dans
   une liste de trois ou quatre lignes par ailleurs identiques. */
.bhchan--primary {
    background: var(--bg-surface-hover);
    box-shadow: inset 3px 0 0 var(--bhchan-brand, var(--accent));
}

/* 🔑 Les couleurs de MARQUE sont l'une des trois exceptions assumées au thème tokenisé — elles ne
   s'adaptent pas, c'est ce qui en fait des marques. Elles vivent en tokens plutôt qu'en style inline
   sur la balise : une valeur écrite dans le Razor échapperait à toute relecture du CSS.
   ⚠️ Teintes ÉCLAIRCIES pour tenir sur fond sombre : le violet Twitch officiel (#9146ff) et le rouge
   YouTube (#ff0000) descendent sous le seuil de lisibilité sur nos surfaces. */
.bhchan--twitch  { --bhchan-brand: #a970ff; }
.bhchan--kick    { --bhchan-brand: #8ff56a; }
.bhchan--youtube { --bhchan-brand: #ff4e45; }

/* Pastille de plateforme. */
.bhchan-logo {
    width: 36px; height: 36px; flex: none; display: grid; place-items: center;
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--bhchan-brand, var(--text-ghost)) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--bhchan-brand, var(--text-ghost)) 40%, transparent);
    color: var(--bhchan-brand, var(--text-soft));
    font: 700 15px/1 'JetBrains Mono', monospace;
}

.bhchan-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bhchan-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.bhchan-name {
    font: 600 14px/1.15 'Archivo', sans-serif; color: var(--text-bright);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.bhchan-sub {
    font: 400 11.5px/1.3 'JetBrains Mono', monospace; color: var(--text-dim);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.bhchan-tag {
    height: 18px; padding: 0 6px; flex: none; display: inline-flex; align-items: center; gap: 5px;
    border-radius: var(--radius); border: 1px solid var(--border);
    font: 600 8.5px/1 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase;
    color: var(--text-soft); background: var(--bg-inset);
}
.bhchan-tag--primary {
    color: var(--gold-fg); border-color: color-mix(in srgb, var(--gold-fg) 35%, transparent);
    background: color-mix(in srgb, var(--gold-fg) 14%, transparent);
}
.bhchan-tag--live {
    color: var(--red-soft-fg); border-color: color-mix(in srgb, var(--red-fg) 40%, transparent);
    background: color-mix(in srgb, var(--red-fg) 14%, transparent);
}
.bhchan-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--red-fg); }

.bhchan-acts { display: flex; align-items: center; gap: 6px; flex: none; }

/* Le formulaire d'ajout, replié tant qu'on n'ajoute pas. */
.bhchan-add { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bhchan-add input { flex: 1 1 240px; min-width: 0; }
.bhchan-detected {
    flex: none; display: inline-flex; align-items: center; gap: 6px;
    font: 600 9px/1 'JetBrains Mono', monospace; letter-spacing: .12em; text-transform: uppercase;
    color: var(--accent-light);
}
.bhchan-detected--unknown { color: var(--text-dim); }
.bhchan-detected--refused { color: var(--red-soft-fg); }

/* ⚠️ Sous 640px les gestes passent SOUS la ligne au lieu de comprimer le nom : à trois boutons,
   l'identifiant tombait sous 60px et l'ellipse mangeait la moitié du pseudo. */
@media (max-width: 640px) {
    .bhchan { flex-wrap: wrap; }
    .bhchan-main { flex: 1 1 100%; order: 2; }
    .bhchan-acts { order: 3; flex: 1 1 100%; justify-content: flex-end; }
}

/* ═══ Onglet Diffusion d'une fiche tournoi — planche 30b ═════════════════════════════════════════
   🔑 Deux colonnes : ce qu'on regarde à gauche, les à-côtés à droite. Sous 900px la colonne de
   droite passe dessous — elle ne porte que des compléments, jamais le contenu principal. */
.bhdiff-page { display: flex; flex-direction: column; }
.bhdiff {
    display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 18px;
    /* ⚠️ `min(…, 100%)` et non le token seul : un plafond en pixels absolus ne borne rien dans une
       fenêtre de téléphone, et un enfant plus large y étire toute la ligne. `ShellLayoutCssTests`
       l'exige — et me l'a rappelé. */
    padding: 18px 24px 44px; max-width: min(var(--page-max), 100%); margin: 0 auto; width: 100%;
}
/* ⚠️ `min-width: 0` sur les deux pistes : sans lui, une grille de POV large fait défiler l'ÉCRAN
   entier au lieu de se contraindre — le `min-width: auto` par défaut des items de grille remonte. */
.bhdiff-main, .bhdiff-side { min-width: 0; display: flex; flex-direction: column; gap: 14px; }

@media (max-width: 900px) {
    .bhdiff { grid-template-columns: minmax(0, 1fr); padding: 14px 16px 32px; }
}

/* La vignette de la chaîne officielle. Le fond est posé en style inline par le composant quand la
   plateforme en sert une ; sinon l'aplat reste, et personne ne voit d'image cassée. */
.bhdiff-official { padding: 0; overflow: hidden; }
.bhdiff-thumb {
    position: relative; display: grid; place-items: center;
    aspect-ratio: 16 / 9; width: 100%;
    background: var(--bg-inset) center / cover no-repeat;
    border-bottom: 1px solid var(--line-soft);
    text-decoration: none; color: var(--text-bright);
}
.bhdiff-thumb::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(rgba(0,0,0,.15), rgba(0,0,0,.65));
}
.bhdiff-thumb-play, .bhdiff-thumb-cta, .bhdiff-thumb-live { position: relative; z-index: 1; }
.bhdiff-thumb-play {
    width: 54px; height: 54px; display: grid; place-items: center; border-radius: 50%;
    background: rgba(var(--overlay-rgb), .14); border: 1px solid rgba(var(--overlay-rgb), .35);
    font-size: 22px;
}
.bhdiff-thumb-cta { margin-top: 10px; font: 600 13px/1 'Archivo', sans-serif; }
.bhdiff-thumb-live { position: absolute; top: 12px; left: 12px; }
.bhdiff-thumb:hover .bhdiff-thumb-play { background: rgba(var(--overlay-rgb), .24); }

/* La grille des POV. ⚠️ `auto-fill` et non `auto-fit` : à une seule vignette, `auto-fit` l'étire sur
   toute la largeur et elle ne ressemble plus à une vignette. */
.bhdiff-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px;
}
.bhdiff-pov {
    display: flex; flex-direction: column; gap: 6px; min-width: 0;
    padding: 11px 12px; border-radius: var(--radius);
    border: 1px solid var(--border); background: var(--bg-inset);
    text-decoration: none;
}
.bhdiff-pov:hover { border-color: var(--bhchan-brand, var(--border-hover)); }
.bhdiff-pov--live { box-shadow: inset 3px 0 0 var(--red-fg); }
.bhdiff-pov-top { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.bhdiff-pov-name {
    font: 600 13.5px/1.2 'Archivo', sans-serif; color: var(--text-bright);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bhdiff-pov-sub {
    font: 400 11px/1.2 'JetBrains Mono', monospace; color: var(--text-dim);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Dans la colonne de droite, une chaîne est un LIEN entier : pas de bouton, tout le bloc part. */
a.bhchan { text-decoration: none; }
a.bhchan:hover { background: var(--bg-surface-hover); }

/* ═══ Lecteur et tchat embarqués — onglet Diffusion (US #1190) ═══════════════════════════════════
   🔑 Le lecteur et le tchat côte à côte, comme sur la plateforme : c'est la disposition que le
   spectateur connaît, et la seule où le tchat reste lisible pendant qu'on regarde. */
.bhdiff-live {
    display: grid; grid-template-columns: minmax(0, 1fr) 320px;
    border-bottom: 1px solid var(--line-soft);
}
/* ⚠️ `min-width: 0` sur les deux pistes : sans lui le `min-width: auto` par défaut des items de
   grille remonte, et un cadre plus large que sa piste fait défiler l'ÉCRAN entier. */
.bhdiff-player, .bhdiff-chat { min-width: 0; border: 0; display: block; background: var(--bg-inset); }
.bhdiff-player { width: 100%; aspect-ratio: 16 / 9; }
/* Le tchat suit la hauteur du lecteur : il n'a pas de hauteur propre, et sans cette contrainte il
   s'effondrerait à zéro — un iframe sans hauteur déclarée ne tire rien de son contenu. */
.bhdiff-chat { width: 100%; height: 100%; }

/* ⚠️ Sous 900px le tchat passe SOUS le lecteur et prend une hauteur fixe. Le laisser en colonne y
   réduirait le lecteur à une bande de 60px de large sur un téléphone. */
@media (max-width: 900px) {
    .bhdiff-live { grid-template-columns: minmax(0, 1fr); }
    .bhdiff-chat { height: 360px; border-top: 1px solid var(--line-soft); }
}

/* ═══ Inscription rapide par équipe (bhqte-*) et place tenue (bhhold-*) ════════
   Maquette 31. Réutilise volontairement .tour-lineup-* pour le choix de l'alignement : c'est le
   même geste que dans l'ancien panneau, et lui donner une seconde apparence aurait fait croire à
   deux mécanismes différents. */

.bhqte { display: flex; flex-direction: column; gap: 12px; }

.bhqte-head { display: flex; align-items: flex-start; gap: 12px; }
.bhqte-head > div:not(:last-child) { flex: 1 1 auto; min-width: 0; }
.bhqte-sub { margin: 2px 0 0; font-size: 12.5px; color: var(--text-muted); }

.bhqte-back, .bhqte-close {
    flex: none;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    background: transparent;
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 14px;
}
.bhqte-back:hover, .bhqte-close:hover { border-color: var(--border-hover); background: var(--bg-hover); color: var(--text-primary); }
.bhqte-close { margin-left: auto; }

.bhqte-section { display: flex; align-items: baseline; gap: 10px; margin-top: 4px; }
.bhqte-label {
    font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-muted);
}
.bhqte-count { font-size: 12px; color: var(--text-muted); margin-left: auto; }
.bhqte-count--ok { color: var(--green-fg); font-weight: 600; }

/* Une équipe proposée. Le motif d'inaptitude et le geste qui répare vivent DANS la carte : la
   maquette refuse l'équipe grisée sans explication. */
.bhqte-team {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.bhqte-team--on { border-color: var(--accent); background: var(--accent-subtle); }
.bhqte-team-main {
    flex: 1 1 auto; min-width: 0;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    background: transparent; border: 0; padding: 0;
    color: inherit; font-family: inherit; text-align: left; cursor: pointer;
}
.bhqte-team-name { font-size: 14px; font-weight: 600; }
.bhqte-team-members {
    font-size: 12px; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    flex: 1 1 100%;
}
.bhqte-team-count { font-size: 12.5px; color: var(--text-muted); margin-left: auto; flex: none; }
.bhqte-reason { font-size: 12px; color: var(--orange-fg); }

.bhqte-badge {
    font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    padding: 2px 7px; border-radius: var(--radius);
    background: var(--bg-chip); color: var(--text-muted);
}
.bhqte-badge--ok { background: var(--tint-green-bg); color: var(--green-fg); }

.bhqte-fix {
    flex: none;
    padding: 6px 11px;
    background: transparent;
    border: 0.5px solid var(--border-hover);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-family: inherit; font-size: 12.5px; cursor: pointer;
}
.bhqte-fix:hover { background: var(--bg-hover); }

.bhqte-lineup { padding: 4px 12px 12px; }

/* Séparateur « ou » : il dit que monter une équipe est une ALTERNATIVE au choix, pas une suite. */
.bhqte-or { display: flex; align-items: center; gap: 12px; color: var(--text-muted); font-size: 12px; }
.bhqte-or::before, .bhqte-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.bhqte-build {
    display: flex; align-items: center; gap: 12px;
    width: 100%;
    padding: 12px 14px;
    background: var(--bg-surface);
    border: 1px dashed var(--border-hover);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-family: inherit; text-align: left; cursor: pointer;
}
.bhqte-build:hover { background: var(--bg-hover); border-color: var(--accent); }
.bhqte-build strong { display: block; font-size: 13.5px; }
.bhqte-build small { display: block; margin-top: 2px; font-size: 12px; color: var(--text-muted); }
.bhqte-build-plus {
    flex: none; width: 28px; height: 28px;
    display: grid; place-items: center;
    border-radius: var(--radius);
    background: var(--accent-subtle); color: var(--accent);
    font-size: 17px; font-weight: 600;
}

.bhqte-note {
    display: flex; align-items: flex-start; gap: 8px;
    margin: 4px 0 0;
    font-size: 12px; line-height: 1.5; color: var(--text-muted);
}
.bhqte-hint { display: block; margin-top: 4px; font-size: 11.5px; color: var(--text-muted); }

.bhqte-error {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 12px;
    border-radius: var(--radius);
    background: var(--tint-red-bg);
    color: var(--red-fg);
    font-size: 12.5px;
}

/* Effectif en construction (31b) */
.bhqte-roster { display: flex; flex-direction: column; gap: 6px; }
.bhqte-seat {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.bhqte-seat-name { font-size: 13px; font-weight: 500; }
.bhqte-seat-mail { font-size: 12px; color: var(--text-muted); }
.bhqte-seat-remove {
    margin-left: auto;
    background: transparent; border: 0; padding: 0;
    color: var(--text-muted); font-family: inherit; font-size: 12px; cursor: pointer;
}
.bhqte-seat-remove:hover { color: var(--red-fg); }

.bhqte-hit {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    border-bottom: 0.5px solid var(--border);
}
.bhqte-hit--off { opacity: .55; }
.bhqte-hit-name { font-size: 13px; }
.bhqte-hit-state { font-size: 12px; color: var(--text-muted); margin-left: auto; }
.bhqte-hit-add {
    flex: none;
    min-width: 28px; height: 28px; padding: 0 9px;
    background: var(--accent-subtle); color: var(--accent);
    border: 0; border-radius: var(--radius);
    font-family: inherit; font-size: 13px; cursor: pointer;
}
.bhqte-hit-add:hover { background: var(--accent); color: var(--on-accent); }

/* ── Place tenue (31c) ─────────────────────────────────────────────────────── */

.bhhold { display: flex; flex-direction: column; gap: 12px; border-color: var(--orange-fg); }
.bhhold-head { display: flex; align-items: flex-start; gap: 12px; }
.bhhold-icon { font-size: 20px; color: var(--orange-fg); flex: none; margin-top: 2px; }
.bhhold-notice { margin: 4px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }

.bhhold-team { display: flex; align-items: baseline; gap: 10px; }
.bhhold-team-name { font-size: 14px; font-weight: 600; }
.bhhold-count {
    margin-left: auto;
    font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-muted);
}

.bhhold-seats { display: flex; flex-direction: column; gap: 6px; }
.bhhold-seat {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: var(--bg-surface);
    border: 0.5px solid var(--border);
    border-radius: var(--radius);
}
.bhhold-seat--ok { color: var(--green-fg); }
.bhhold-seat--wait { border-style: dashed; }
.bhhold-seat-name { font-size: 13px; font-weight: 500; }
.bhhold-seat-state { font-size: 12px; color: var(--text-muted); }
.bhhold-reminded { font-style: normal; color: var(--green-fg); }
.bhhold-act {
    padding: 5px 10px;
    background: transparent;
    border: 0.5px solid var(--border-hover);
    border-radius: var(--radius);
    color: var(--text-primary);
    font-family: inherit; font-size: 12px; cursor: pointer;
}
.bhhold-act:first-of-type { margin-left: auto; }
.bhhold-act:hover { background: var(--bg-hover); }
.bhhold-act:disabled { opacity: .5; cursor: not-allowed; }

.bhhold-replace {
    padding: 10px 12px;
    background: var(--bg-inset);
    border-radius: var(--radius);
}

.bhhold-accept { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.bhhold-warn {
    display: flex; align-items: center; gap: 8px;
    margin: 0; font-size: 12.5px; color: var(--orange-fg);
}

.bhhold-rules { font-size: 12px; color: var(--text-muted); }
.bhhold-rules ul { margin: 6px 0 0; padding-left: 18px; }
.bhhold-rules li { margin-bottom: 4px; line-height: 1.5; }

/* À l'étroit, les cartes d'équipe et les sièges passent en colonne : les gestes gardent une cible
   confortable au lieu de se tasser sur la droite. */
@media (max-width: 560px) {
    .bhqte-team, .bhhold-seat { flex-wrap: wrap; }
    .bhqte-team-count, .bhqte-hit-state { margin-left: 0; }
    .bhhold-act:first-of-type { margin-left: 0; }
    .bhqte-fix, .bhhold-act { flex: 1 1 auto; }
}

/* ═══ Écrans de menu Équipes et Organisations — maquette 32 (32a → 32d) ══════════════════════════
   Deux écrans, un seul vocabulaire. Ce qui est COMMUN aux deux — onglets, filtres, listes de lignes,
   bandeaux, appel à l'action — porte le préfixe `bhdir-`. Ce qui est propre à une carte porte
   `bhtc-` (équipe) ou `bhoc-` (organisation), parce que les deux cartes ne répondent pas à la même
   question et n'ont donc pas la même anatomie.

   ⚠️ Aucune largeur en dur : la colonne vit dans --page-max, posée par le shell. Les items de grille
   portent `min-width: 0`, sans quoi le `min-width: auto` par défaut fait déborder une carte dont le
   contenu est long et pousse l'écran ENTIER en défilement horizontal.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── Onglets ──────────────────────────────────────────────────────────────────────────────────
   Même idiome que la fiche d'équipe (.bhtm-tab) : un souligné ambre sous l'onglet actif. L'ambre
   est la contre-couleur de l'onglet actif depuis le thème 28f — le bleu du logo reste aux aplats. */
.bhdir-tabs {
    position: relative;
    display: flex;
    gap: 0;
    flex-wrap: wrap;
    margin: 4px 0 20px;
    border-bottom: 1px solid var(--line-soft);
}
.bhdir-tab {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    padding: 0 14px 12px;
    margin-bottom: -1px;
    border: 0;
    background: none;
    cursor: pointer;
    font: 500 13px/1 var(--font-alt);
    color: var(--text-soft);
    transition: color 0.15s;
}
.bhdir-tab:hover { color: var(--text-primary); }
.bhdir-tab--active {
    font-weight: 600;
    color: var(--text-primary);
    box-shadow: inset 0 -2px 0 var(--accent-warm);
}
.bhdir-tab-n { font: 400 11.5px/1 var(--font-mono); color: var(--text-muted); }

/* ── Titre de section : libellé, filet, décompte ─────────────────────────────────────────────── */
.bhdir-sectionhead {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 14px;
}
.bhdir-sectionhead--quiet { padding-top: 28px; }
.bhdir-kicker {
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    flex: none;
}
.bhdir-rule { flex: 1; height: 1px; background: var(--line-soft); }
.bhdir-tally { font: 400 11px/1 var(--font-alt); color: var(--text-muted); flex: none; }

/* ── Bandeaux du haut : ce qui demande une action passe avant les onglets ────────────────────── */
.bhdir-invite,
.bhdir-pending {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 14px 18px;
    margin-bottom: 18px;
    border-radius: var(--radius);
    flex-wrap: wrap;
}
.bhdir-invite {
    border: 1px solid rgba(var(--accent-rgb), 0.35);
    background: var(--accent-subtle);
}
.bhdir-invite-n {
    width: 30px;
    height: 30px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(var(--accent-rgb), 0.16);
    border: 1px solid rgba(var(--accent-rgb), 0.45);
    font: 700 12px/1 var(--font-mono);
    color: var(--accent-light);
}
.bhdir-invite-txt { flex: 1; min-width: 200px; font: 400 12.5px/1.45 var(--font-alt); color: var(--text-body); }
.bhdir-invite-act { flex: none; height: 32px; padding: 0 14px; font-size: 11.5px; }

.bhdir-pending {
    align-items: flex-start;
    border: 1px solid var(--border);
    background: var(--bg-surface);
}
.bhdir-pending-mark {
    width: 30px;
    height: 30px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--bg-chip);
    border: 1px solid var(--border-input);
    color: var(--text-secondary);
    font-size: 14px;
}
.bhdir-pending-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bhdir-pending-title { font: 600 13px/1.3 var(--font-alt); color: var(--text-primary); }
.bhdir-pending-sub { font: 400 11.5px/1.45 var(--font-alt); color: var(--text-muted); }

/* ── Filtres de l'annuaire ────────────────────────────────────────────────────────────────────
   `flex-wrap` plutôt qu'une grille : à l'étroit, la recherche garde toute la largeur et les deux
   réglages passent dessous, au lieu de se tasser en trois colonnes illisibles. */
.bhdir-filters {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 16px;
    flex-wrap: wrap;
}
.bhdir-search {
    box-sizing: border-box;
    flex: 1 1 260px;
    min-width: 0;
    height: 38px;
    padding: 0 13px;
    display: flex;
    align-items: center;
    gap: 9px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    color: var(--text-muted);
}
.bhdir-search input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: none;
    outline: none;
    font: 400 12.5px/1 var(--font-alt);
    color: var(--text-primary);
}
.bhdir-search input::placeholder { color: var(--text-ghost); }

.bhdir-select {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 38px;
    padding: 0 13px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    flex: none;
}
.bhdir-select-key { font: 400 12px/1 var(--font-alt); color: var(--text-muted); }
.bhdir-select select {
    border: 0;
    background: none;
    outline: none;
    font: 500 12px/1 var(--font-alt);
    color: var(--text-secondary);
    cursor: pointer;
}
.bhdir-check {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 38px;
    padding: 0 13px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-inset);
    font: 500 12px/1 var(--font-alt);
    color: var(--text-secondary);
    cursor: pointer;
    flex: none;
}

/* ── Liste de lignes (32c et 32d) ─────────────────────────────────────────────────────────────
   Une ligne est un LIEN entier : la cible est la ligne, pas un mot au bout. `bhdir-open` n'est donc
   qu'un repère visuel, jamais un second lien imbriqué — ce qui serait du HTML invalide. */
.bhdir-list {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-surface);
    overflow: hidden;
}
.bhdir-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--line-soft);
    text-decoration: none;
    color: inherit;
    transition: background 0.15s;
}
.bhdir-row:last-child { border-bottom: 0; }
.bhdir-row:hover { background: var(--bg-surface-hover); }
.bhdir-row--mine { background: rgba(var(--accent-rgb), 0.05); }
.bhdir-row--mine:hover { background: rgba(var(--accent-rgb), 0.1); }
.bhdir-row--off { opacity: 0.72; }

.bhdir-crest {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: var(--radius);
    object-fit: cover;
}
.bhdir-crest--initials {
    display: grid;
    place-items: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font: 700 13px/1 var(--font-display);
    letter-spacing: 0.06em;
}

.bhdir-ident { width: 300px; flex: none; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.bhdir-ident--org { width: 330px; }
.bhdir-ident-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.bhdir-name {
    font: 600 14px/1.2 var(--font-alt);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
.bhdir-tag {
    height: 17px;
    padding: 0 6px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: var(--bg-chip);
    border: 1px solid var(--border);
    font: 600 8.5px/1 var(--font-mono);
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    flex: none;
}
.bhdir-mine {
    height: 17px;
    padding: 0 6px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: rgba(var(--accent-rgb), 0.14);
    border: 1px solid rgba(var(--accent-rgb), 0.4);
    font: 600 8.5px/1 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent-light);
    flex: none;
}
.bhdir-sub {
    font: 400 11px/1.4 var(--font-alt);
    color: var(--text-muted);
    display: flex;
    align-items: baseline;
    gap: 5px;
    min-width: 0;
}
.bhdir-desc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bhdir-activity { flex: 1; min-width: 0; font: 400 11.5px/1.4 var(--font-alt); color: var(--text-secondary); }
.bhdir-count { width: 110px; flex: none; font: 400 11.5px/1 var(--font-alt); color: var(--text-muted); }

.bhdir-next { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.bhdir-next-key {
    font: 500 9px/1 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-ghost);
}
.bhdir-next-val {
    font: 500 12px/1.3 var(--font-alt);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bhdir-next-val--none { color: var(--text-muted); font-weight: 400; }
.bhdir-channel { width: 150px; flex: none; min-width: 0; }

.bhdir-open {
    display: grid;
    place-items: center;
    height: 32px;
    padding: 0 13px;
    flex: none;
    border-radius: var(--radius);
    border: 1px solid var(--border-input);
    background: var(--bg-elevated);
    font: 600 11.5px/1 var(--font-alt);
    color: var(--text-primary);
}
.bhdir-row:hover .bhdir-open { border-color: var(--accent); color: var(--accent-light); }

/* ── Appel à l'action en pied de « Mes équipes » ──────────────────────────────────────────────── */
.bhdir-cta {
    display: flex;
    align-items: center;
    gap: 13px;
    width: 100%;
    padding: 15px 18px;
    margin-top: 22px;
    border-radius: var(--radius);
    border: 1px dashed var(--border-input);
    background: var(--bg-inset);
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    transition: border-color 0.15s, background 0.15s;
}
.bhdir-cta:hover { border-color: var(--accent); background: var(--accent-subtle); }
.bhdir-cta-mark {
    width: 32px;
    height: 32px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: rgba(var(--accent-rgb), 0.12);
    border: 1px solid rgba(var(--accent-rgb), 0.35);
    font: 400 16px/1 var(--font-alt);
    color: var(--accent-light);
}
.bhdir-cta-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.bhdir-cta-title { font: 600 13px/1 var(--font-alt); color: var(--text-primary); }
.bhdir-cta-sub { font: 400 11.5px/1.4 var(--font-alt); color: var(--text-muted); }
.bhdir-cta-go { font: 400 15px/1 var(--font-alt); color: var(--accent-light); flex: none; }

/* ── Pile d'avatars de l'effectif ─────────────────────────────────────────────────────────────── */
.bhrf { display: flex; flex: none; }
.bhrf-face {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 2px solid var(--bg-surface);
    object-fit: cover;
    flex: none;
}
.bhrf-face + .bhrf-face { margin-left: -8px; }
.bhrf-face--initials,
.bhrf-face--more {
    display: grid;
    place-items: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font: 600 9px/1 var(--font-mono);
}
.bhrf-face--more { background: var(--bg-chip); color: var(--text-secondary); }
/* L'invitation sans réponse : un siège vide, pas un joueur. */
.bhrf-face--pending { background: var(--bg-inset); border: 2px dashed var(--border-input); }

/* ── Carte d'équipe (32a) et carte d'organisation (32b) ───────────────────────────────────────── */
.bhtc-grid,
.bhoc-grid {
    display: grid;
    gap: 16px;
}
.bhtc-grid { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
.bhoc-grid { grid-template-columns: repeat(auto-fill, minmax(460px, 1fr)); }
/* 🔴 Le plancher des items, sans quoi `min-width: auto` laisse une carte au contenu long élargir
   sa piste et pousser l'écran ENTIER en défilement horizontal. */
.bhtc-grid > *, .bhoc-grid > * { min-width: 0; }

.bhtc, .bhoc {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-surface);
    overflow: hidden;
}
.bhoc--inactive { opacity: 0.72; }

.bhtc-banner, .bhoc-banner {
    position: relative;
    background-size: cover;
    background-position: center;
}
.bhtc-banner { height: 96px; }
.bhoc-banner { height: 120px; }
/* 🔴 Le VOILE BAS de la maquette, posé en surcouche plutôt que dans le background : l'image, elle,
   arrive en style inline, et une bannière claire laisserait sinon le blason et le nom illisibles.
   Le voile s'éteint vers la surface de la CARTE, pas vers `transparent` — qui vaut rgba(0,0,0,0) et
   frange de gris à l'interpolation. */
.bhtc-banner::after, .bhoc-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(var(--bg-page-rgb), 0) 38%, var(--bg-surface) 100%);
}
/* Le repli de plateforme : jamais un trou, toujours une surface qui tient le blason. Volontairement
   SOURD — le dégradé d'identité y serait un aplat vif sur chaque carte sans bannière, c'est-à-dire
   la majorité, et l'écran perdrait sa seule hiérarchie. */
.bhtc-banner--fallback, .bhoc-banner--fallback {
    background-image: linear-gradient(120deg, var(--bg-hover) 0%, var(--line-strong) 60%, var(--bg-surface) 100%);
}

/* 🔴 `position: relative` + `z-index` : le blason CHEVAUCHE la bannière par une marge négative, et
   le voile bas de celle-ci est un ::after posé en absolu. Sans contexte d'empilement ici, le voile
   se peint PAR-DESSUS le blason et le mange à moitié — vu à l'écran, invisible au balisage. */
.bhtc-id, .bhoc-id {
    position: relative;
    z-index: 1;
    padding: 0 17px 15px;
    margin-top: -26px;
    display: flex;
    flex-direction: column;
    gap: 11px;
    min-width: 0;
}
.bhtc-crest, .bhoc-crest {
    width: 48px;
    height: 48px;
    flex: none;
    border-radius: var(--radius);
    box-shadow: 0 0 0 3px var(--bg-surface);
    object-fit: cover;
}
.bhtc-crest--initials, .bhoc-crest--initials {
    display: grid;
    place-items: center;
    background: var(--avatar-bg);
    color: var(--avatar-color);
    font: 700 15px/1 var(--font-display);
    letter-spacing: 0.06em;
}

.bhtc-name, .bhoc-name { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.bhtc-title, .bhoc-title {
    font: 600 16px/1.15 var(--font-alt);
    color: var(--text-primary);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bhtc-title:hover, .bhoc-title:hover { color: var(--accent-light); }
.bhoc-title { font-size: 17px; }
.bhtc-chips, .bhoc-title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }

.bhtc-tag {
    height: 18px;
    padding: 0 6px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: var(--bg-chip);
    border: 1px solid var(--border);
    font: 600 9px/1 var(--font-mono);
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    flex: none;
}
.bhtc-pill, .bhoc-pill {
    height: 18px;
    padding: 0 6px;
    display: grid;
    place-items: center;
    border-radius: var(--radius);
    background: var(--bg-inset);
    border: 1px solid var(--border);
    font: 600 9px/1 var(--font-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    flex: none;
}
.bhoc-pill { height: 19px; padding: 0 7px; }
/* Capitaine et propriétaire portent la contre-couleur chaude : une seule chose chaude par carte. */
.bhtc-pill--captain, .bhoc-pill--owner {
    background: var(--tint-gold-bg-2);
    border-color: var(--tint-gold-border);
    color: var(--gold-on-tint);
}

.bhoc-desc, .bhoc-staff { font: 400 12px/1.45 var(--font-alt); color: var(--text-muted); }
.bhoc-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bhtc-roster { padding: 0 17px 15px; display: flex; align-items: center; gap: 9px; min-width: 0; }
.bhtc-roster-txt {
    font: 400 11.5px/1.3 var(--font-alt);
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bhtc-state {
    padding: 13px 17px;
    border-top: 1px solid var(--line-soft);
    background: var(--bg-inset);
    display: flex;
    flex-direction: column;
    gap: 9px;
    min-width: 0;
}
.bhtc-ready { display: flex; align-items: center; gap: 8px; font: 500 11.5px/1.3 var(--font-alt); }
.bhtc-ready--ok { color: var(--lime-fg); }
.bhtc-ready--partial { color: var(--orange-fg); }
.bhtc-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.bhtc-activity { font: 400 11px/1.4 var(--font-alt); color: var(--text-muted); }

.bhtc-actions, .bhoc-actions {
    display: flex;
    gap: 8px;
    padding: 13px 17px;
    border-top: 1px solid var(--line-soft);
    flex-wrap: wrap;
    align-items: center;
}
.bhtc-act, .bhoc-act {
    display: grid;
    place-items: center;
    height: 34px;
    padding: 0 14px;
    border-radius: var(--radius);
    font: 600 11.5px/1 var(--font-alt);
    text-decoration: none;
    white-space: nowrap;
}
.bhtc-act { flex: 1 1 auto; }
/* Le geste qui RÉPARE porte la teinte de l'état qu'il répare — le lien se fait sans lire. */
.bhtc-act--repair {
    background: var(--tint-orange-bg);
    border: 1px solid var(--tint-orange-border);
    color: var(--orange-fg);
}
.bhoc-act--quiet { color: var(--text-muted); }
.bhoc-spacer { flex: 1; }

/* ── Les trois compteurs de la carte d'organisation (32b) ─────────────────────────────────────── */
.bhoc-stats {
    display: flex;
    border-top: 1px solid var(--line-soft);
    background: var(--bg-inset);
    flex-wrap: wrap;
}
.bhoc-stat {
    flex: 1 1 130px;
    min-width: 0;
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    border-right: 1px solid var(--line-soft);
}
.bhoc-stat--wide { flex: 1.2 1 160px; border-right: 0; }
.bhoc-stat-key {
    font: 500 9px/1 var(--font-mono);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-ghost);
}
.bhoc-stat-val {
    display: flex;
    align-items: center;
    gap: 7px;
    font: 600 13px/1.2 var(--font-alt);
    color: var(--text-primary);
    min-width: 0;
}
.bhoc-stat-val--none { font-weight: 400; color: var(--text-muted); }
.bhoc-stat-link { font: 500 12px/1 var(--font-alt); color: var(--accent-light); text-decoration: none; }
.bhoc-stat-link:hover { text-decoration: underline; }
/* Le point rouge « à l'antenne » : une pastille, pas un mot — elle se repère en balayant l'écran. */
.bhoc-live,
.bhchp-live {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--red-fg);
    box-shadow: 0 0 0 3px var(--tint-red-bg);
    flex: none;
}

/* ── Pastille de chaîne ───────────────────────────────────────────────────────────────────────── */
.bhchp { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.bhchp-icon { font-size: 14px; color: var(--text-secondary); flex: none; }
.bhchp-label {
    font: 500 11.5px/1 var(--font-alt);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bhchp--none { font: 400 11.5px/1 var(--font-alt); color: var(--text-muted); }

/* ── À l'étroit ───────────────────────────────────────────────────────────────────────────────
   Les lignes d'annuaire abandonnent leurs colonnes fixes avant de se tasser : l'identité garde la
   largeur, le reste passe dessous. Sans cela, `width: 300px` sur l'identité pousse la page en
   défilement horizontal bien avant le mobile. */
@media (max-width: 900px) {
    .bhdir-row { flex-wrap: wrap; }
    .bhdir-ident, .bhdir-ident--org { width: auto; flex: 1 1 200px; }
    .bhdir-count, .bhdir-channel { width: auto; flex: 0 0 auto; }
    .bhdir-activity, .bhdir-next { flex: 1 1 100%; }
    .bhoc-grid { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
    .bhtc-grid { grid-template-columns: 1fr; }
    .bhdir-open { margin-left: auto; }
    .bhdir-filters .bhdir-select, .bhdir-filters .bhdir-check { flex: 1 1 auto; }
    .bhoc-stat { border-right: 0; }
}

/* ═══ Modale partagée — BhModal ═══════════════════════════════════════════════════════════════
   Le voile et le panneau des modales du shell (créer une équipe, créer une organisation).

   🔴 1100 / 1101, ET PAS 60 / 61. Les deux idiomes plus anciens — `.bhlog-modal-back` (console des
   connexions) et `.bhusr-scrim` (tiroir des comptes) — vivent sous un shell d'administration dont
   la barre est `.bhcon-head`. Les écrans du shell public, eux, ont `.appnav` à 150 : une modale
   posée à 61 y passerait DERRIÈRE la navigation, et son voile ne l'assombrirait même pas. L'étage
   tel qu'il est aujourd'hui :

     .bhlog-modal / .bhusr-drawer   60 / 61
     .appnav (barre du shell)       150
     .user-popover                  200
     cloche de notifications        999 / 1000
     #blazor-error-ui               1000
     .loading-splash                2000

   On se range au-dessus de la cloche et sous l'écran de chargement : une modale doit couvrir la
   navigation, jamais le message qui annonce que le circuit est tombé.

   🔴 DES POURCENTAGES, JAMAIS DE `vw` / `vh` ICI. `.app-shell` porte `zoom: var(--ui-zoom)` (1.08),
   et `zoom` ne divise PAS les unités de viewport : `94vw` mesurerait 101 % de la fenêtre et ferait
   déborder l'écran en largeur. Un pourcentage, lui, se résout sur le bloc conteneur — la fenêtre,
   puisque l'élément est fixe — et traverse le zoom sans dommage. C'est le piège déjà compensé à la
   main sur la hauteur de `.app-shell`, un cran plus haut.

   ⚠️ Le voile est en `position: fixed` : son ancêtre de défilement est la fenêtre, pas
   `.main-content`. C'est ce qui immobilise le fond sans une ligne de JavaScript. */
/* 🔴 `max-width: none` OBLIGATOIRE, ET CE N'EST PAS DÉCORATIF.
   `:where(.main-content, .public-page-content) > *` pose sur TOUT enfant direct du conteneur de
   défilement la colonne de lecture : `max-width: min(var(--page-max), 100%)` et
   `margin-inline: auto`. Le voile en héritait — mesuré à 1500 px de large, il ne couvrait plus que
   1274 px, centré, laissant **113 px de page de chaque côté en pleine lumière et toujours
   cliquables**, barre de navigation comprise. Rien ne le signale sous 1180 px : la fenêtre du
   développeur suffit à cacher le défaut. C'est le même opt-out que .pp-screen, .home-page--shell
   et .bhlb-page. */
.bhmod-back, .bhmod { max-width: none; margin-inline: 0; }

.bhmod-back { position: fixed; inset: 0; z-index: 1100; background: var(--scrim); cursor: pointer; }

.bhmod {
    position: fixed; z-index: 1101; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: min(94%, 560px); max-height: 86%;
    display: flex; flex-direction: column;
    border-radius: var(--radius); border: 1px solid var(--border);
    background: var(--bg-elevated); box-shadow: 0 24px 60px var(--shadow-strong);
}
/* Le panneau prend le focus à l'ouverture pour qu'`Échap` réponde tout de suite : c'est un point
   d'ancrage, pas une cible de clic — donc pas de halo. */
.bhmod:focus { outline: none; }
.bhmod--wide { width: min(94%, 720px); }

.bhmod-head { display: flex; align-items: center; gap: 12px; padding: 17px 20px 14px; border-bottom: 1px solid var(--line-soft); }
.bhmod-title { flex: 1; min-width: 0; margin: 0; font: 700 17px/1.2 var(--font-display); text-transform: uppercase; letter-spacing: .03em; color: var(--text-primary); }
.bhmod-x { flex: none; width: 30px; height: 30px; display: grid; place-items: center; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel); font-size: 15px; color: var(--text-muted); cursor: pointer; }
.bhmod-x:hover { background: var(--bg-hover); color: var(--text-primary); }

/* C'est le CORPS qui défile, pas le panneau : l'en-tête et la croix restent atteignables quand le
   formulaire dépasse la hauteur de la fenêtre. */
.bhmod-body { padding: 18px 20px 20px; overflow-y: auto; }

/* Sentinelles du piège de focus. Focalisables mais invisibles ET hors de portée du pointeur :
   `display: none` ou `visibility: hidden` les retireraient de l'ordre de tabulation, ce qui
   annulerait le piège sans que rien ne le signale. */
.bhmod-guard { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

@media (max-width: 560px) {
    .bhmod, .bhmod--wide { width: min(96%, 560px); max-height: 92%; }
    .bhmod-body { padding: 16px; }
}
