:root {
    /* Chrome de marque (header, footer) — constant, ne change pas avec le theme */
    --chrome-bg: #131315;
    --chrome-text: #f5f4f0;
    --chrome-text-muted: rgba(245, 244, 240, 0.6);
    --chrome-border: #2a2a2c;

    /* Sidebar admin/membre — deja constante avant la refonte, conservee telle quelle */
    --pal-bo-bg: #444;
    --pal-locked: #444;
    /* Compte marque comme doublon d'un autre (module Gestion des doublons) — rouge sombre, distinct
       du bg-danger (adhesion expiree) et du bg-locked (gris). Constante, lisible en texte blanc. */
    --pal-doublon: #7a1220;
    --pal-doublon-bg: color-mix(in srgb, var(--pal-doublon) 14%, transparent);

    /* Accent rouge de marque — constant */
    --pal-red: #d6293a;
    --pal-red-deep: #630f16;
    --pal-red-mid: #931b24;
    /* Version teintee du rouge, meme construction que --pal-success-bg/--pal-warning-bg (fond
       clair pour badge/bandeau, ex. "adhesion expiree" — cf. AdhesionActive.razor.css) */
    --pal-red-bg: color-mix(in srgb, var(--pal-red) 13%, transparent);

    /* Texte/icone sur fond accent sature (--pal-red et --pal-warning) — constant, blanc lisible
       sur les deux. Audit du 2026-08-07 (session d'harmonisation) : "color: #fff" etait tape en
       dur ~24 fois sur des boutons/badges a fond accent au lieu de passer par une variable. */
    --pal-on-accent: #fff;

    /* Chrome sombre du back-office (sidebar) — construits sur --chrome-bg/--pal-red, theme-aware
       par construction (color-mix suit --chrome-bg/--pal-red qui ne changent pas eux-memes, mais
       la formule reste coherente si un jour ils bougent). Cf. decisions.md [[backoffice-redesign-kickoff]]. */
    --bo-chrome-hover: color-mix(in srgb, white 7%, var(--chrome-bg));
    --bo-chrome-active: color-mix(in srgb, var(--pal-red) 24%, var(--chrome-bg));
    --bo-chrome-active-icon: #ff8f97;

    /* Survol de ligne/carte back-office (surfaces claires, theme-aware via --surface-card) et
       fond "danger" teinte rouge (badges/icones d'alerte back-office). */
    --bo-row-hover: color-mix(in srgb, var(--pal-red) 5%, var(--surface-card));
    --bo-danger-bg: color-mix(in srgb, var(--pal-red) 12%, transparent);

    /* Couleurs semantiques (succes/attention) — distinctes de l'accent rouge de marque,
       bascule clair/sombre (voir blocs dark plus bas) */
    --pal-success: #1f7a4d;
    --pal-success-bg: color-mix(in srgb, var(--pal-success) 13%, transparent);
    --pal-warning: #a2650f;
    --pal-warning-bg: color-mix(in srgb, var(--pal-warning) 13%, transparent);
    --pal-info: #2f6f9e;
    --pal-info-bg: color-mix(in srgb, var(--pal-info) 13%, transparent);

    /* Toggle clair/sombre — constant, ne change pas avec le theme */
    --icon-sun-color: #f2a93b;
    --theme-toggle-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);

    /* Ombre portee sur l'avatar de fiche membre (Trombinoscope) — constant, meme famille que
       --theme-toggle-shadow ci-dessus. Audit du 2026-08-07 : etait en dur dans
       TrombinoscopeDetail.razor.css. */
    --pal-avatar-shadow: 0 2px 10px rgba(0, 0, 0, .12);

    /* Medailles podium (Archives) — constant, ne change pas avec le theme */
    --podium-gold: #e8d721;
    --podium-silver: #b9c0c2;
    --podium-bronze: #c68b22;

    /* Contenu des popups LinkBlazor Dialog (.pal-msgpop*, EditeCMSPop/EditeLieuPop) — simples alias
       vers les tokens de surface du site (voir plus bas, meme bloc que --text/--surface-card).
       Nommes a part pour que le contenu des popups reste lisible que qu'il ne soit garde comme
       alias theme-aware que via ces 4 variables (plutot que de coder en dur --text/--surface-card
       dans chaque regle .pal-msgpop-*) : le panneau .lb-dialog lui-meme consomme desormais les
       memes tokens, voir plus bas [[dialog-chrome-themed]]. */
    --dialog-text: var(--text);
    --dialog-text-muted: var(--text-muted);
    --dialog-surface: var(--surface-card);
    --dialog-border: var(--surface-border);

    /* Palette categorielle agenda (types d'evenements) — bascule clair/sombre (sauf Live et Autre,
       constants : le rouge de marque reste reserve a Live, Autre reste sur le gris neutre du texte) */
    --agenda-live: var(--pal-red);
    --agenda-online: #c07a12;
    --agenda-club: #1f7a68;
    --agenda-ext: #7a4fa3;
    --agenda-other-t: #3d5a80;
    --agenda-other: var(--text-muted);

    /* Degrade footer — bascule clair/sombre (plat en clair, fondu vers le noir en sombre, voir maquette) */
    --footer-grad-start: #9c0008;
    --footer-grad-end: #870005;

    /* Fond du hero/carrousel accueil (zone visible hors image : fallback sans image, bords du wrapper) —
       bascule clair/sombre ; le degrade de l'overlay texte reste lui volontairement fixe sur --chrome-bg
       (lisibilite du texte sur les photos, independante du theme) */
    --hero-bg: #f6f5f2;

    /* Surface de contenu — bascule clair/sombre, voir blocs dark plus bas */
    --surface-bg: #ffffff;
    --surface-card: #f6f5f2;
    --surface-border: #e7e4dc;
    --text: #17181a;
    --text-muted: #6e6c66;

    /* Points de rupture standards du site : smartphone (defaut, <600px) / tablette / PC petit ecran / PC grand ecran.
       Non utilisables tels quels dans une condition @media (une custom property n'est pas lisible a cet endroit du CSS) :
       servent de reference/documentation et sont utilisables en JS (getComputedStyle) ou en valeur de propriete normale.
       Chaque @media du site doit reprendre une de ces 3 valeurs en dur (voir commentaire "seuil: --bp-*" a cote). */
    --bp-tablet: 600px;
    --bp-desktop-sm: 1024px;
    --bp-desktop-lg: 1440px;

    /* CKEditor definit sa propre police par defaut (Helvetica/Arial...), differente de celle du
       site (voir font-family sur body plus bas) : sans cette ligne, tout contenu riche affiche via
       .ck-content (news, forum, messagerie, detail tournoi/championnat) tranche visuellement avec
       le reste du site. */
    --ck-content-font-family: 'AtkinsonHyperlegible','Umunu',"Raleway", Roboto, "Helvetica Neue", Arial, sans-serif;

    /* Police a chasse fixe pour les blocs "formule" de la doc back-office (DocThemeClassement) —
       constant, ne change pas avec le theme. */
    --pal-mono-font: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* Taille des icones SVG inline dans le contenu riche pal-cms-* (.pal-cms-mini-item-icon,
       .pal-cms-value-icon) — constant, ne change pas avec le theme. Ces icones sont forcement en
       <svg> brut (pas <i class="bi bi-...">) : CKEditor supprime les elements inline vides sans
       contenu texte a la sauvegarde (cf. commentaire sur .pal-cms-ticket dans pal-cms.css), et un
       <svg> sans largeur/hauteur explicite retombe sur sa taille par defaut (300x150) au lieu de
       suivre le style de son conteneur. */
    --pal-cms-icon-size: 1.4rem;
    /* News : podium d'un classement (.pal-cms-podium) et joueur d'une etape de chronologie
       (.pal-cms-timeline-player) — tailles constantes, couleurs reprises des tokens existants
       (--podium-*, --agenda-online), deja declines en theme sombre. */
    --pal-cms-podium-avatar-size: 3.5rem;
    --pal-cms-podium-avatar-size-first: 4.5rem;
    --pal-cms-podium-medal-size: 1.6rem;
    --pal-cms-podium-slot-width: 9rem;
    --pal-cms-podium-step: 1.5rem;
    --pal-cms-timeline-avatar-size: 2.75rem;
    --pal-cms-timeline-player-width: 7rem;
    --pal-cms-timeline-dot-ext: var(--agenda-online);
    /* Colonne d'evolution d'un classement (.pal-cms-ranking-evo), couleurs = --pal-success / --pal-red. */
    --pal-cms-ranking-evo-width: 3.2rem;
    --pal-cms-ranking-evo-width-mobile: 2.4rem;

    /* Diametre de la photo du vainqueur dans .pal-cms-winner-card (pal-cms.css, news mensuelle,
       section Flashback) — constant, ne change pas avec le theme. */
    --pal-cms-winner-photo-size: 4.5rem;

    /* Regle d'elevation "Carte" (audit graphique 2026-08-06/07, harmonisation cartes/sections —
       voir decisions.md [[cartes-sections-elevation]]) — constant, ne change pas avec le theme.
       Un seul rayon pour toute carte (isolee ou repetee) ; l'ombre ne marque que les cartes
       isolees (seul element principal d'une page : Account, CMS). Jamais les deux a la fois avec
       des valeurs differentes — toute nouvelle carte doit consommer ces variables, pas un nombre
       en dur. */
    --pal-card-radius: 14px;
    --pal-card-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 4px 12px -4px rgba(0, 0, 0, .15);

    /* Texte "hint" (petite explication sous un champ ou un tableau) — constant, ne change pas
       avec le theme. Aligne sur .pal-bo-form-hint (pal-backoffice.css). */
    --pal-hint-font-size: .72rem;
    --pal-hint-gap: .75rem;

    /* Regle de forme "Bouton" (audit graphique, harmonisation boutons — voir decisions.md
       [[boutons-forme-role]]) — constant, ne change pas avec le theme. Rond (50%/999px) reserve
       aux icones seules sans texte (pagination, avatars, icones de navigation) ; carre-arrondi
       pour tout le reste (tout bouton avec du texte, CTA, action de formulaire) — y compris 2
       exceptions volontaires a la regle "icone seule = rond" : le bouton "j'aime" et le bouton de
       recherche du header. Toute nouvelle icone-seule doit rester ronde sauf accord explicite. */
    --pal-btn-radius: 8px;

    /* Puce de texte pouvant passer sur 2 lignes (ex. nom de championnat, /GestionUtilisateur/Tournois)
       — constant, ne change pas avec le theme. Rayon ~ moitie de la hauteur d'une ligne : pilule sur
       1 ligne, rectangle arrondi sur 2 (999px en faisait un gros rond). */
    --pal-chip-wrap-radius: .8rem;
    --pal-chip-wrap-max-width: 12rem;

    /* Largeur minimale d'une colonne "nom" dans un tableau qui defile sur mobile (ex. colonne
       Tournoi de /GestionUtilisateur/Tournois) : les noms tiennent sur 2 lignes au lieu de 4-5. */
    --pal-grid-name-col-min-width: 12rem;

    /* Casse des en-tetes de tableau (QuickGrid ET tableaux HTML bruts <table>/<th>), site entier —
       audit du 2026-08-13 : la moitie des grilles avaient un entete en majuscules fixes
       (text-transform: uppercase code en dur par grille), l'autre moitie non, et certaines grilles
       melangeaient les deux au sein d'une meme ligne (colonnes triables, enveloppees par QuickGrid
       dans un <button> qui reinitialise text-transform:none via le Reboot Bootstrap — voir la regle
       "th button" de chaque grille, qui doit toujours contenir text-transform:inherit pour rester
       coherente avec ce token quelle que soit sa valeur). Valeur actuelle : casse normale. Repasser
       a "uppercase" ici rebascule toutes les grilles du site d'un coup, sans toucher a aucune
       d'entre elles. Perimetre volontairement limite aux vrais tableaux : ne couvre PAS les autres
       majuscules du site (badges/chips/eyebrows/en-tetes de l'agenda calendrier) qui restent des
       choix de design a part, deja tranches lors de l'audit graphique du 2026-08-07. */
    --pal-th-text-transform: none;

    /* Espace entre la valeur d'un champ number aligne a droite et ses boutons +/- natifs — voir
       la regle input[type="number"] plus bas. Variable partagee pour eviter de dupliquer la meme
       valeur a chaque endroit ou elle doit etre renforcee (specificite CSS plus forte qu'une
       regle en raccourci existante — cf. pal-backoffice.css/BOTournoiDetail.razor.css). */
    --pal-number-input-gutter: 0.4rem;

    /* Pseudo Winamax masque (********) dans les tableaux du processus d'affiliation quand un membre
       l'a passe prive : espacement des points, et espace entre le champ d'edition masque et son
       bouton oeil. Geometrie constante, ne change pas avec le theme. */
    --pal-winamax-prive-dots-spacing: 0.12em;
    --pal-winamax-input-gap: 0.4rem;
    /* Suivi des affiliations, reponse incoherente : espace entre la reponse, la ligne demandee et
       le statut du membre. Geometrie constante, ne change pas avec le theme. */
    --pal-affil-incoherente-gap: 0.4rem;

    /* Rampe de teintes pour la repartition des adherents par palier (Dashboard back-office) :
       gris neutre (aucun palier) vers rouge de marque de plus en plus sature (palier croissant)
       — encode visuellement l'ordre des paliers plutot que des couleurs arbitraires. Les 3
       teintes les plus foncees reutilisent les rouges de marque existants. */
    --pal-tier-none: #c9c6bd;
    --pal-tier-1: #f0b3ba;
    --pal-tier-2: #e37f89;
    --pal-tier-3: var(--pal-red);
    --pal-tier-4: var(--pal-red-mid);
    --pal-tier-5: var(--pal-red-deep);
}

@media (prefers-color-scheme: dark) {
    :root {
        --footer-grad-start: #3a0002;
        --footer-grad-end: #0a0302;
        --surface-bg: #0a0705;
        --surface-card: #17120f;
        --surface-border: #2e231e;
        --text: #f2f1ec;
        --text-muted: #a6a49c;
        --hero-bg: #131315;
        --agenda-online: #e2a542;
        --agenda-club: #4fae9c;
        --agenda-ext: #b78ce0;
        --agenda-other-t: #7fa3d1;
        --pal-success: #4caf82;
        --pal-success-bg: color-mix(in srgb, var(--pal-success) 17%, transparent);
        --pal-warning: #e0a94a;
        --pal-warning-bg: color-mix(in srgb, var(--pal-warning) 17%, transparent);
        --pal-info: #6fb3e0;
        --pal-info-bg: color-mix(in srgb, var(--pal-info) 17%, transparent);
        /* Bootstrap ne redefinit --bs-secondary-color que sous [data-bs-theme=dark], un
           attribut que ce site n'utilise jamais (on pilote le theme via [data-theme]) : sans
           cette ligne, les placeholders et autres textes "secondaires" Bootstrap restent
           bloques sur leur valeur claire (texte sombre), quasi invisibles sur fond sombre. */
        --bs-secondary-color: var(--text-muted);
        /* Idem pour CKEditor : --ck-content-font-color est fige a #000 par ckeditor5.css
           (jamais redefini pour un theme sombre), ce qui rend illisible tout contenu riche
           (news, forum, messagerie, detail tournoi/championnat) affiche via .ck-content. */
        --ck-content-font-color: var(--text);
        --ck-content-color-image-caption-text: var(--text-muted);
        --ck-content-color-image-caption-background: var(--surface-card);
        --ck-content-color-table-caption-text: var(--text-muted);
        --ck-content-color-table-caption-background: var(--surface-card);
        /* --ck-color-base-* sont les 4 tokens racine dont derive quasi toute la chrome CKEditor
           (toolbar/dropdown/panel-background -> base-background, boutons/bordures -> base-border,
           texte -> base-text) — jamais redefinis par ckeditor5.css pour un theme sombre (fige
           #fff/#333/#ccced1/#fafafa). Les surcharger ici, plutot qu'une regle CSS ciblant un
           selecteur precis de l'editeur, evite toute course a la specificite avec le CSS de
           CKEditor (ex. .ck.ck-editor__main>.ck-editor__editable, deja plus specifique qu'un
           .ck-editor__editable simple) et couvre en un coup toute la chrome, pas juste la zone
           de saisie. */
        --ck-color-base-background: var(--surface-card);
        --ck-color-base-foreground: var(--surface-bg);
        --ck-color-base-border: var(--surface-border);
        --ck-color-base-text: var(--text);
        /* Filtre qui recolore une icone en image de fond a couleur sombre fixe (invisible sur un
           entete/fond sombre) : ex. .sort-indicator de QuickGrid (cf. plus bas), ou le chevron
           replie de .accordion-button (SearchView.razor.css). Expose en variable (plutot qu'en
           dur sur chaque icone) pour qu'une page qui personnalise son fond en clair (ex.
           classement-general) puisse l'annuler sans dupliquer le theme sombre/clair dans son
           propre CSS scope (::deep + media ne se combinent pas). */
        --pal-icon-invert-filter: invert(100%) sepia(100%) saturate(14%) hue-rotate(212deg);
        /* Ombre separant les colonnes figees (position:sticky, ex. detail Championnat) du reste
           du tableau qui defile horizontalement en dessous. */
        --pal-sticky-shadow: 2px 0 6px rgba(0, 0, 0, .5);
        /* Degrade statique sur le bord droit d'un tableau a scroll horizontal (ex. detail
           Championnat), indice visuel qu'il reste des colonnes a decouvrir. Volontairement
           statique (toujours visible tant que le tableau deborde), pas reactif a la position de
           scroll : une version qui disparait une fois arrive au bout demanderait du JS (les
           lignes zebrees empechent la technique CSS pure background-attachment:local/scroll,
           qui suppose un fond uni a chaque bord). */
        --pal-edge-fade-color: rgba(0, 0, 0, .55);
        --pal-tier-none: #514c43;
    }
}

:root[data-theme="dark"] {
    --footer-grad-start: #3a0002;
    --footer-grad-end: #0a0302;
    --surface-bg: #0a0705;
    --surface-card: #17120f;
    --surface-border: #2e231e;
    --text: #f2f1ec;
    --text-muted: #a6a49c;
    --hero-bg: #131315;
    --agenda-online: #e2a542;
    --agenda-club: #4fae9c;
    --agenda-ext: #b78ce0;
    --agenda-other-t: #7fa3d1;
    --pal-success: #4caf82;
    --pal-success-bg: color-mix(in srgb, var(--pal-success) 17%, transparent);
    --pal-warning: #e0a94a;
    --pal-warning-bg: color-mix(in srgb, var(--pal-warning) 17%, transparent);
    --pal-info: #6fb3e0;
    --pal-info-bg: color-mix(in srgb, var(--pal-info) 17%, transparent);
    --bs-secondary-color: var(--text-muted);
    --ck-content-font-color: var(--text);
    --ck-content-color-image-caption-text: var(--text-muted);
    --ck-content-color-image-caption-background: var(--surface-card);
    --ck-content-color-table-caption-text: var(--text-muted);
    --ck-content-color-table-caption-background: var(--surface-card);
    --ck-color-base-background: var(--surface-card);
    --ck-color-base-foreground: var(--surface-bg);
    --ck-color-base-border: var(--surface-border);
    --ck-color-base-text: var(--text);
    --pal-icon-invert-filter: invert(100%) sepia(100%) saturate(14%) hue-rotate(212deg);
    --pal-sticky-shadow: 2px 0 6px rgba(0, 0, 0, .5);
    --pal-edge-fade-color: rgba(0, 0, 0, .55);
    --pal-tier-none: #514c43;
}

:root[data-theme="light"] {
    --footer-grad-start: #9c0008;
    --footer-grad-end: #870005;
    --surface-bg: #ffffff;
    --surface-card: #f6f5f2;
    --surface-border: #e7e4dc;
    --text: #17181a;
    --text-muted: #6e6c66;
    --hero-bg: #f6f5f2;
    --agenda-online: #c07a12;
    --agenda-club: #1f7a68;
    --agenda-ext: #7a4fa3;
    --agenda-other-t: #3d5a80;
    --pal-success: #1f7a4d;
    --pal-success-bg: color-mix(in srgb, var(--pal-success) 13%, transparent);
    --pal-warning: #a2650f;
    --pal-warning-bg: color-mix(in srgb, var(--pal-warning) 13%, transparent);
    --pal-info: #2f6f9e;
    --pal-info-bg: color-mix(in srgb, var(--pal-info) 13%, transparent);
    --bs-secondary-color: var(--text-muted);
    --ck-content-font-color: var(--text);
    --ck-content-color-image-caption-text: var(--text-muted);
    --ck-content-color-image-caption-background: var(--surface-card);
    --ck-content-color-table-caption-text: var(--text-muted);
    --ck-content-color-table-caption-background: var(--surface-card);
    --ck-color-base-background: var(--surface-card);
    --ck-color-base-foreground: var(--surface-bg);
    --ck-color-base-border: var(--surface-border);
    --ck-color-base-text: var(--text);
    --pal-icon-invert-filter: none;
    --pal-sticky-shadow: 2px 0 6px rgba(0, 0, 0, .12);
    --pal-edge-fade-color: rgba(0, 0, 0, .2);
}

@font-face {
    font-family: 'Umunu';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: url('/lib/font/umunu.otf') format('opentype');
}

@font-face {
    font-family: 'AtkinsonHyperlegible';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: url('/lib/font/AtkinsonHyperlegible-Regular.ttf') format('truetype');
}

@font-face {
    font-family: 'AtkinsonHyperlegible';
    font-style: italic;
    font-weight: normal;
    font-display: swap;
    src: url('/lib/font/AtkinsonHyperlegible-Italic.ttf') format('truetype');
}

@font-face {
    font-family: 'AtkinsonHyperlegible';
    font-style: normal;
    font-weight: bold;
    font-display: swap;
    src: url('/lib/font/AtkinsonHyperlegible-Bold.ttf') format('truetype');
}

@font-face {
    font-family: 'AtkinsonHyperlegible';
    font-style: italic;
    font-weight: bold;
    font-display: swap;
    src: url('/lib/font/AtkinsonHyperlegible-BoldItalic.ttf') format('truetype');
}

.bg-locked {
    background-color: var(--pal-locked);
    box-shadow: #000 0 0 1px;
    box-shadow: inset 0 0 0 1px #000;
}

.bg-doublon {
    background-color: var(--pal-doublon);
    color: #fff;
    box-shadow: inset 0 0 0 1px #000;
}

.btn-refresh {
    display: none;
}

.btn-primary {
    --bs-btn-bg: var(--pal-red);
    --bs-btn-border-color: var(--pal-red-deep);
    --bs-btn-hover-bg: color-mix(in srgb,var(--pal-red) 50%,black 50%);
    --bs-btn-hover-border-color: color-mix(in srgb,var(--pal-red-deep) 50%,black 50%);
    --bs-btn-active-bg: color-mix(in srgb,var(--pal-red) 50%,white 50%);
    --bs-btn-active-border-color: color-mix(in srgb,var(--pal-red-deep) 50%,white 50%);
    --bs-btn-disabled-bg: color-mix(in srgb,var(--pal-red) 20%,black 80%);
    --bs-btn-disabled-border-color: color-mix(in srgb,var(--pal-red-deep) 20%,black 80%);
}

.border-primary {
    border-color: var(--pal-red) !important;
}

.pal-color {
    color: var(--pal-red);
}

/* Carte isolee (regle d'elevation, cf. --pal-card-radius/--pal-card-shadow plus haut) : le seul
   element principal d'une page (formulaire de connexion, page CMS). Remplace 4 blocs identiques
   auparavant dupliques dans Login/Register/ForgotPassword/ResendEmailConfirmation.razor.css. */
.pal-card-isolated {
    background: var(--surface-card);
    border: 1px solid var(--surface-border);
    border-radius: var(--pal-card-radius);
    padding: 1.75rem;
    box-shadow: var(--pal-card-shadow);
}

/* Bouton "Retour a l'accueil" : remplace 3 blocs CSS identiques auparavant dupliques dans
   Error/AccessDenied/Lockout.razor.css (harmonisation boutons, decisions.md [[boutons-forme-role]]). */
.pal-btn-home {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    background-color: var(--pal-red);
    color: var(--pal-on-accent);
    text-decoration: none;
    font-weight: 700;
    font-size: .9rem;
    padding: .7rem 1.5rem;
    border-radius: var(--pal-btn-radius);
}

html {
    /* Reserve toujours la place de la scrollbar verticale : sans ca, calc(50% - 50vw) (JumboTop.razor.css,
       technique de debordement pleine largeur) desynchronise 50% (largeur reelle du parent, scrollbar deduite)
       et 50vw (largeur totale du viewport, scrollbar incluse) => leger scroll horizontal fantome sur tout le site. */
    scrollbar-gutter: stable;
}

body, html {
    background-color: var(--surface-bg);
    margin: 0;
    font-family: 'AtkinsonHyperlegible','Umunu',"Raleway", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--text);
    text-align: left;
}

.form-control:focus {
    box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--pal-red), transparent 65%);
}

/* Convention "champ number" du site (2026-08-13) : toujours aligne a droite. S'applique
   automatiquement a tout <input type="number">, present et futur, sans classe a poser
   manuellement.
   Piege corrige le meme jour : augmenter le padding-right ne separe PAS la valeur des boutons
   +/- (Chrome/Edge collent le bouton directement contre le texte, a l'interieur du padding) —
   ca ne fait qu'ajouter du vide apres le bouton, entre lui et la bordure. Le vrai espacement
   s'obtient en ciblant le bouton lui-meme via son pseudo-element (regle juste en dessous). */
input[type="number"] {
    text-align: right;
    padding-right: var(--pal-number-input-gutter);
}

/* Ecarte le bouton +/- natif du texte (WebKit/Blink — Chrome, Edge, Safari) via une marge posee
   directement sur son pseudo-element, seul endroit ou ca fonctionne reellement (cf. piege
   ci-dessus). Pas d'equivalent connu pour Firefox (son spinner ne s'y prete pas de la meme
   maniere) — au pire un ecart plus faible, jamais un chevauchement. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    margin-left: var(--pal-number-input-gutter);
}

/* Icone calendrier native de <input type="date"> : couleur fixe (sombre) cote navigateur, quel
   que soit le theme du site — invisible sur fond sombre sans cette regle. Meme mecanisme que les
   autres icones a couleur fixe du site (--pal-icon-invert-filter, defini plus haut). WebKit/Blink
   uniquement (Chrome, Edge, Safari) — Firefox n'expose pas ce pseudo-element mais son icone reste
   theme-aware nativement, pas de probleme constate. */
input[type="date"]::-webkit-calendar-picker-indicator {
    filter: var(--pal-icon-invert-filter);
}

.form-control:focus {
    border-color: var(--pal-red-deep);
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.hidden-select {
    border: none;
    color: black;
    background: none;
    padding: 0;
    -moz-appearance: none;
    -webkit-appearance: none;
}

.pal-container {
    background-color: var(--surface-bg);
    display: flex;
    justify-content: center;
    min-height: 70vh;
}

.pal-content {
    background-color: var(--surface-bg);
    transition: max-width 0.15s ease;
    width: 100%;
}

/* seuil: --bp-desktop-sm */
@media (min-width:1024px) {
    .pal-content {
        max-width: 1180px;
    }
}

/* seuil: --bp-desktop-lg */
@media (min-width:1440px) {
    .pal-content {
        max-width: 1320px;
    }
}

h1:focus {
    outline: none;
}

.droparea {
    border: 2px dashed var(--pal-red);
    padding: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    cursor: pointer;
    position: relative;
    min-height: 200px;
}

    .droparea.drop-mini {
        min-height: unset;
        padding: 2px;
        font-size: 1rem;
    }

    .droparea:hover {
        background-color: var(--pal-red-deep);
        color: white;
    }

    .droparea input[type=file] {
        position: absolute;
        width: 100%;
        height: 100%;
        opacity: 0;
        cursor: pointer;
    }

/* ============================================================
   Contenu de popup (Dialog.OpenAsync<T>) — .pal-msgpop*
   Le chrome du panneau (.lb-dialog, librairie tierce LinkBlazor) est desormais theme (2026-08-13,
   decisions.md [[dialog-chrome-themed]] — a remplace l'ancien [[dialog-chrome-invariant]], panneau
   auparavant blanc en dur). Ces classes theme le contenu via --dialog-text/--dialog-text-muted/
   --dialog-surface/--dialog-border (:root plus haut), qui sont maintenant de simples alias vers
   --text/--text-muted/--surface-card/--surface-border — theme-reactifs par construction, comme le
   reste du panneau. Promu ici en global (etait scope a EditeCMSPop.razor.css) des la 2e popup
   concernee (EditeLieuPop).
   ============================================================ */
.pal-msgpop {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.pal-msgpop-head h2 {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--dialog-text);
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--dialog-border);
}

    .pal-msgpop-head h2 i {
        color: var(--pal-red);
    }

.pal-msgpop-field label {
    display: block;
    color: var(--dialog-text-muted);
    font-weight: 600;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.pal-msgpop-field input,
.pal-msgpop-field .form-control {
    width: 100%;
    background-color: var(--dialog-surface);
    border: 1px solid var(--dialog-border);
    color: var(--dialog-text);
    border-radius: 7px;
    padding: 7px 10px;
    font: inherit;
    font-size: .88rem;
}

.pal-msgpop-field input:focus,
.pal-msgpop-field .form-control:focus {
    background-color: var(--dialog-surface);
    color: var(--dialog-text);
    border-color: var(--pal-red-mid);
    box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--pal-red) 20%, transparent);
    outline: none;
}

.pal-msgpop-grid-2 {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.1rem;
}

/* seuil: --bp-tablet */
@media (min-width: 600px) {
    .pal-msgpop-grid-2 {
        grid-template-columns: 1fr 1fr;
    }
}

.pal-msgpop-editor {
    border: 1px solid var(--dialog-border);
    border-radius: 10px;
    overflow: hidden;
}

.pal-msgpop-actions {
    display: flex;
    gap: .6rem;
    justify-content: flex-end;
}

/* Convention pop-up (2026-09-11) : boutons d'action centrés en bas — ImportOnline (référence),
   ConfirmPop, et toute pop-up reprise pour suivre la convention. Modificateur plutôt que de changer
   le flex-end par défaut, qui reste ce que rendent EditeCMSPop/EditeLieuPop tant qu'ils ne sont pas
   repris. */
.pal-msgpop-actions.centered {
    justify-content: center;
}

/* Texte de confirmation (ConfirmPop) : pre-line pour préserver les messages multi-lignes (ex.
   suppression tournoi/championnat avec liste des conséquences) sans figer les espaces d'indentation
   — même besoin que l'ancien Dialog.Confirm (cf. règle .lb-dialog :is(div,p) plus bas). */
.pal-msgpop-text {
    margin: 0;
    color: var(--dialog-text);
    font-size: .92rem;
    white-space: pre-line;
}

/* Encart vert facultatif de ConfirmPop (paramètre Info) : ce que l'action conserve ou fait en plus. */
.pal-msgpop-info {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    margin-top: .9rem;
    padding: .75rem .9rem;
    border-radius: 10px;
    background: var(--pal-success-bg);
    border: 1px solid color-mix(in srgb, var(--pal-success) 30%, var(--dialog-border));
    color: var(--dialog-text);
    font-size: .88rem;
    line-height: 1.5;
}

.pal-msgpop-info > i {
    color: var(--pal-success);
    margin-top: .1rem;
}

.pal-msgpop-submit {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background-color: var(--pal-red);
    color: var(--pal-on-accent);
    border: none;
    padding: 0.65rem 1.4rem;
    border-radius: var(--pal-btn-radius);
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
}

.pal-msgpop-submit:hover {
    background-color: color-mix(in srgb, var(--pal-red) 82%, black 18%);
}

/* Aligne sur .pal-cms-hero h1 (pal-cms.css) retenu comme rendu de reference — harmonisation
   titres, decisions.md [[titres-echelle-h1]]. Etait fixe/rouge/600, devient fluide/couleur
   texte/poids par defaut : un h1 rend desormais pareil qu'il soit dans le hero d'une page CMS
   ou ailleurs dans du contenu riche (.cms). */
.cms h1 {
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    line-height: 1.15;
    color: var(--text);
}

.cms h2 {
    font-size: 1.6rem;
    font-weight: 500;
}

.cms img {
    max-width: 100%;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

.pal-img-16-9 {
    aspect-ratio: 16 / 9; /* modern browsers: keeps consistent box ratio */
    overflow: hidden;
    position: relative;
}

.quickgrid[theme=default] .sort-indicator {
    opacity: 0.9;
}

.sort-indicator {
    filter: invert(100%) sepia(100%) saturate(14%) hue-rotate(212deg);
}

/* Par defaut, QuickGrid ne montre une icone de tri (fleche) que sur la colonne actuellement
   triee — les autres colonnes triables du meme tableau ne montrent rien, aucun signe qu'elles
   le sont aussi (ex. /classement, /Championnat, page tournoi onglet Classement). On affiche une
   icone neutre "double fleche" sur toute colonne triable, front-office ET back-office (regle
   volontairement generique, non scopee a une classe de page) ; specificite volontairement plus
   faible que la regle QuickGrid .col-sort-asc/.col-sort-desc (cf. Microsoft.AspNetCore.Components
   .QuickGrid.*.bundle.scp.css), qui reste prioritaire et affiche sa propre fleche de direction
   des qu'une colonne devient le tri actif. */
.col-title .sort-indicator {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="black"><path fill-rule="evenodd" d="M11.5 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5zm-7-14a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V1.5a.5.5 0 0 1 .5-.5z"/></svg>');
}

.img-mini {
    max-height: 35px;
}
/*NEWS*/
.pal-news h2 {
    font-size: 1.4rem;
    font-weight: 600;
    color: var(--pal-red);
}

.pal-news h3 {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-muted);
}

.pal-news .creator {
    font-weight: 600;
    font-size: 0.8rem;
    margin-bottom: 10px;
}

.pal-post-date {
    display: block;
    background: var(--chrome-bg);
    color: var(--chrome-text);
    position: absolute;
    top: 10px;
    right: 0;
    padding: 2px 7px;
    font-size: 0.6rem;
    z-index: 2;
}

a.silent {
    text-decoration: none !important;
}

.pal-fake-text {
    height: 1.5rem;
}
/*AGENDA*/



.pal-widget-list {
    display: flex;
    flex-direction: column;
}

    /* En ligne (ex. /search), .pal-widget-event n'a par defaut aucune largeur propre : chaque
       carte se dimensionne sur son propre contenu (titre plus ou moins long), d'ou des largeurs
       incoherentes d'une carte a l'autre. CSS grid (plutot que flex) : colonnes d'au moins 240px
       (largeur fixe uniforme, un peu moins large qu'une carte News, cf. .pal-search-news-grid),
       qui grandissent egalement (1fr) pour combler exactement la largeur de la ligne — necessaire
       pour qu'une ligne complete (typiquement la 1ere) colle bien son dernier element au bord
       droit, comme les News. Contrepartie assumee : une derniere ligne incomplete (moins d'items
       que de colonnes) garde un vide a droite plutot que de faire grandir ses items au-dela de
       240px — comportement standard d'une grille a colonnes uniformes (idem .pal-search-news-grid). */
    .pal-widget-list.pal-widget-row {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    }

        /* .pal-widget-event porte un margin-bottom pense pour l'empilement vertical par defaut
           (.pal-widget-list en colonne, ex. sidebar /news) : dans cette variante en grille, cette
           marge s'additionnerait au gap de la grille (row-gap plus grand que column-gap, cartes mal
           alignees verticalement). Neutralisee ici, l'espacement des 2 axes vient uniquement du gap. */
        .pal-widget-list.pal-widget-row .pal-widget-event {
            margin-bottom: 0;
        }

    .pal-widget-list a {
        color: var(--pal-red);
        text-decoration: none;
        background-color: transparent;
    }

.pal-widget-event {
    background-color: var(--surface-card) !important;
    padding: 5px;
    margin-bottom: 0.75rem;
    min-height: 6rem; /* aligne la hauteur des lignes sur .pal-home-news (Home.razor.css), colonne News voisine — 3 lignes de contenu des deux cotes */
    border: solid 1px var(--surface-border);
    border-radius: var(--pal-card-radius); /* etait 4px, ilot isole — harmonisation cartes/sections, cf. decisions.md */
    display: flex;
    align-items: center;
}

.pal-widget-event > div:last-child {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.pal-widget-event .badge {
    /* .pal-widget-event > div:last-child est en colonne flex sans align-items explicite (donc
       stretch par defaut) : le badge etait etire a la largeur du plus large de ses freres
       (generalement le titre de l'evenement) au lieu de sa propre largeur de texte. */
    align-self: flex-start;
}

.pal-widget-event .event_title {
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.25;
}

.pal-widget-event small {
    font-size: 0.78rem;
}

.pal-widget-title:after {
    content: "";
    display: inline-block;
    height: 2px;
    width: 95px;
    background-color: var(--pal-red);
    vertical-align: middle;
    margin: 0px;
    position: absolute;
    left: 0;
    bottom: -1.95px;
}

.pal-widget-title {
    margin: 0 0 15px;
    padding-bottom: 5px;
    font-size: 1.1rem;
    font-weight: 700;
    position: relative;
    border-bottom: 2px solid var(--surface-border);
    color: var(--text);
}

.pal-widget-event:hover {
    background-color: color-mix(in srgb, var(--surface-card) 85%, var(--text) 15%) !important;
    cursor: pointer;
}


.pal-widget-event .text-muted {
    color: var(--text-muted) !important;
}

.pal-widget-event .day {
    text-transform: uppercase;
    height: 15px;
    font-size: 0.9rem;
    color: var(--pal-red);
}

.pal-widget-event .number {
    font-weight: 600;
    font-size: 1.5rem;
    height: 30px;
    color: var(--text);
}

.pal-widget-event .month {
    color: var(--pal-red);
}

.pal-widget-date {
    font-family: "Oswald", Roboto, "Helvetica Neue", Arial, sans-serif;
    text-align: center;
    font-weight: 400;
    margin: 0px 35px 0px 15px;
    color: var(--text-muted);
}

.live {
    --agenda-link-color: var(--agenda-live);
}

.online {
    --agenda-link-color: var(--agenda-online);
}

.club {
    --agenda-link-color: var(--agenda-club);
}

.external {
    --agenda-link-color: var(--agenda-ext);
}

.other_tournament {
    --agenda-link-color: var(--agenda-other-t);
}

.other {
    --agenda-link-color: var(--agenda-other);
}

.pal-img {
    border-radius: 50% !important;
    height: var(--img-size);
    width: var(--img-size);
}

.pal-img-25 {
    --img-size: 25px;
}

.pal-img-40 {
    --img-size: 40px;
}

.pal-img-52 {
    --img-size: 52px;
}

.pal-img-60 {
    --img-size: 60px;
}

.pal-img-80 {
    --img-size: 80px;
}

.pal-img-150 {
    --img-size: 150px;
}

.pal-img-25, .pal-img-40, .pal-img-60, .pal-img-80, .pal-img-150 {
    height: calc(0.6*var(--img-size));
    width: calc(0.6*var(--img-size));
}

/* seuil: --bp-desktop-sm */
@media (min-width:1024px) {
    .pal-img-25, .pal-img-40, .pal-img-60, .pal-img-80, .pal-img-150 {
        height: calc(0.8*var(--img-size));
        width: calc(0.8*var(--img-size));
    }
}

/* seuil: --bp-desktop-lg */
@media (min-width:1440px) {
    .pal-img-25, .pal-img-40, .pal-img-60, .pal-img-80, .pal-img-150 {
        height: var(--img-size);
        width: var(--img-size);
    }
}

/* Cellule avatar+pseudo d'une ligne de tableau (QuickGrid) : identique sur ClassementGeneral,
   QualifiesPast et ChampionnatDetail — centralisee ici plutot que dupliquee dans les 3 fichiers
   .razor.css scopes (chacun peut encore ajouter des regles complementaires specifiques, ex.
   l'ellipsis de ChampionnatDetail.razor.css pour sa colonne Pseudo a largeur figee). */
.pal-player-cell {
    display: flex;
    align-items: center;
    gap: .65rem;
    position: relative;
}

.pal-player-name {
    font-weight: 700;
    color: var(--text);
}

/* Phrase expliquant la methode de classement, sous les tableaux de ClassementGeneral et
   ChampionnatDetail (texte fourni par MethodeClassement.Phrase). Centralisee ici : rendu
   identique sur les deux pages. Meme traitement de "hint" que .pal-bo-form-hint cote back-office. */
.pal-classement-methode-hint {
    margin-top: var(--pal-hint-gap);
    padding-top: var(--pal-hint-gap);
    border-top: 1px solid var(--surface-border);
    font-size: var(--pal-hint-font-size);
    color: var(--text-muted);
}

.pal-agenda-date {
    text-align: center;
    border: 1px solid #444;
    display: flex;
    flex-direction: column;
    flex: 0 1 95px;
}

    .pal-agenda-date .month {
        padding: 0 0.4rem;
        background-color: var(--pal-red);
        color: white;
    }

    .pal-agenda-date .number {
        font-weight: bold;
        font-size: 1.5rem;
    }

    .pal-agenda-date .day {
        color: var(--pal-red);
    }

.pal-inscription-badge {
    position: relative;
    width: 33%;
    padding: 0.5rem;
}

/* seuil: --bp-tablet */
@media (min-width: 600px) {
    .pal-inscription-badge {
        width: 25%;
    }
}

/* seuil: --bp-desktop-sm */
@media (min-width: 1024px) {
    .pal-inscription-badge {
        width: 11.11%;
    }
}

.pal-inscription-badge .pal-interested:after {
    position: absolute;
    top: 5px;
    left: 5px;
    color: blue;
    content: "\F586";
    font-family: "bootstrap-icons";
}

.pal-inscription-badge .pal-registered:after {
    position: absolute;
    top: 5px;
    left: 5px;
    color: green;
    content: "\F26A";
    font-family: "bootstrap-icons";
}

.pal-inscription-badge .pal-waitinglist:after {
    position: absolute;
    top: 5px;
    left: 5px;
    color: #9c900d;
    content: "\F41F";
    font-family: "bootstrap-icons";
}

/*Table Styling*/
table.quickgrid {
    width: 100%;
}

.quickgrid > tbody > tr > td:empty {
    display: inherit;
}

.quickgrid th {
    color: #fff;
    background-color: #343a40;
    border-color: #454d55;
}

    .quickgrid th button {
        color: #fff;
    }

    .quickgrid th .sort-indicator {
        color: #fff;
        /*        background-color:#000*/
    }

.quickgrid tbody tr:nth-of-type(odd) {
    background-color: rgba(0, 0, 0, 0.05);
}

.quickgrid td.pal-point {
    color: var(--pal-red);
}

.quickgrid td.pal-rank {
    color: #1031f5;
    font-weight: bold;
}

/* QuickGrid (non virtualise) remplit la derniere page partielle avec des <tr> de bourrage dont
   toutes les <td> sont vides (aucun item reel derriere) — invisibles tant qu'aucun style de ligne
   (fond/bordure/hauteur) n'est perceptible, mais visibles des qu'on stylise une grille. Regle
   generale valable pour toute grille QuickGrid du site (voir aussi le fix specifique deja en place
   sur Trombinoscope, .card-grid, dont la structure de ligne de bourrage differe legerement). */
.quickgrid tbody tr:not(:has(> td:not(:empty))) {
    display: none;
}

.quickgrid input, .quickgrid select {
    border: none;
    background-color: inherit;
    width: 100%;
}

.bg-inherit {
    background-color: inherit !important;
}

.quickgrid .wc-255 {
    width: 255px;
}

.quickgrid .wc-135 {
    width: 135px;
}

.quickgrid .col-justify-end input {
    text-align: end;
}

.quickgrid.quick-nohead th {
    color: unset;
    background-color: unset;
    border-color: unset;
}

.quickgrid .col-options-button:after {
    background: none !important;
    color: white;
    content: "\F3E0";
    font-family: "bootstrap-icons";
}

.quickgrid .col-options label {
    color: black;
}

.quickgrid .pal-title-vertical .col-title-text {
    white-space: pre-wrap; /* css-3 */
    white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
    white-space: -pre-wrap; /* Opera 4-6 */
    white-space: -o-pre-wrap; /* Opera 7 */
    word-wrap: break-word; /* Internet Explorer 5.5+ */
}

.quickgrid td.pal-tournoi-mode, .quickgrid td.pal-tournoi-place {
    color: white;
    background-color: #18692b;
}

.quickgrid tbody tr:nth-of-type(odd) td.pal-tournoi-mode {
    background-color: #1d552a;
}

.quickgrid td.pal-tournoi-place {
    background-color: #004f93;
}

.quickgrid tbody tr:nth-of-type(odd) td.pal-tournoi-place {
    background-color: #053b68;
}

/* /news : le QuickGrid (rendu par une librairie tierce, hors scope CSS isolation Blazor)
   est transforme visuellement en grille CSS 2 colonnes. La news vedette n'est pas dans cette
   grille (rendue a part dans NewsList.razor), donc la grille garde toujours un nombre pair
   d'items et n'a jamais besoin d'une ligne qui s'etale sur les 2 colonnes. */
table.pal-news-grid {
    display: block;
    width: 100%;
    box-sizing: border-box;
}

.pal-news-grid thead {
    display: none;
}

.pal-news-grid tbody {
    display: grid;
    width: 100%;
    box-sizing: border-box;
    grid-template-columns: 1fr;
    gap: 1.75rem;
}

.pal-news-grid tr {
    display: contents;
}

/* Specificite renforcee (classe+attribut+3 balises) pour gagner sur la regle par defaut de la
   librairie QuickGrid elle-meme (Microsoft.AspNetCore.Components.QuickGrid.*.bundle.scp.css) :
   .quickgrid[theme=default] > tbody > tr > td { padding: 0.1rem calc(0.4rem + var(--col-gap)) 0.1rem 0.4rem; }
   Plus specifique que notre ancienne regle .pal-news-grid td, d'ou le padding asymetrique observe
   (colonnes plus decalees a droite qu'a gauche). */
.pal-news-grid.quickgrid[theme=default] > tbody > tr > td {
    display: block;
    padding: 0;
    border: none;
    min-width: 0; /* sans ca, une cellule de grille CSS ne retrecit jamais sous la taille naturelle
                     de son contenu (ex. un titre sans espace) : la grille 1fr/1fr devient inegale et
                     les cartes ne sont plus alignees sur les bords gauche/droit du bloc. */
}

/* seuil: --bp-desktop-sm */
@media (min-width: 1024px) {
    .pal-news-grid tbody {
        grid-template-columns: repeat(2, 1fr);
    }
}

.quickgrid > tbody > tr > td.pal-tournoi-mode, .quickgrid > tbody > tr > td.pal-tournoi-place {
    padding: 0;
}
/*.quickgrid td.pal-rank {
    background-color: #0c48c4;
    text-align:center;
    color:white;
}*/
/*Account*/
.pal-account {
    background-color: var(--surface-bg);
    padding: 2rem;
    min-height: 800px;
}

.ck-editor {
    width: 100%;
}

.ck-editor__editable {
    min-height: 280px;
}
/* Forum : voir pal-forum.css (fichier dedie, meme principe que pal-manage.css) */

.lb-dialog .ck.ck-balloon-panel {
    z-index: 2050;
}

/* Chrome du panneau .lb-dialog (librairie tierce LinkBlazor) — restait blanc en dur jusqu'ici
   (voir ancien commentaire [[dialog-theme-invariant]] dans decisions.md) : desormais theme via
   les memes tokens --dialog-* et --surface-card ci-dessus [[dialog-chrome-themed]]. Couvre les
   ~6 popups qui partagent ce composant (EditeCMSPop, EditeLieuPop, Pop/ImportLive*, BOEditAbo,
   SearchItemView) sans qu'aucune n'ait besoin d'etre modifiee individuellement : les popups deja
   sur .pal-msgpop-* heritent directement des alias --dialog-*, les autres (SearchItemView,
   BOEditAbo, Pop/ImportLive*) utilisent du Bootstrap brut (.form-control/.table/.card) qui lit
   ses propres variables --bs-* jamais theme-aware par defaut — redefinies ici, scopees a
   .lb-dialog, memes techniques que --bs-secondary-color (:root, plus haut) et
   pal-manage.css/SearchView.razor.css (redefinition locale des variables Bootstrap). */
:root {
    --lb-dialog-background-color: var(--dialog-surface);
    --lb-dialog-border-radius: var(--pal-card-radius);
    --lb-dialog-shadow: var(--pal-card-shadow);
    --lb-dialog-content-padding: 1rem;
}

.lb-dialog {
    border: 1px solid var(--dialog-border);
    color: var(--dialog-text);
    --bs-body-color: var(--dialog-text);
    --bs-body-bg: var(--dialog-surface);
    --bs-border-color: var(--dialog-border);
    --bs-emphasis-color: var(--dialog-text);
    --bs-tertiary-bg: var(--dialog-surface);
    --bs-table-striped-bg: color-mix(in srgb, var(--dialog-text) 5%, transparent);
    --bs-table-hover-bg: color-mix(in srgb, var(--dialog-text) 7.5%, transparent);
    --bs-table-active-bg: color-mix(in srgb, var(--dialog-text) 10%, transparent);
}

.lb-dialog-titlebar-close {
    --lb-close-border-color: var(--dialog-border);
    color: var(--dialog-text-muted);
}

/* CrossIcon (composant LinkBlazor partage par .lb-dialog-titlebar-close et .lb-toast-titlebar-close)
   rend un <svg><path> sans fill="currentColor" — le trait est donc noir en dur par defaut du
   navigateur, invisible en theme sombre tant que ce fill n'est pas explicitement rattache a la
   couleur du bouton parent. */
.lb-dialog-titlebar-close svg,
.lb-toast-titlebar-close svg {
    fill: currentColor;
}

/* Popup ouvert avec CssClass="pal-pop-noheader" (DialogOptions) : on retire la barre du haut
   (croix + zone de titre) uniquement. NE PAS toucher à .lb-dialog-titlebar : c'est le conteneur
   colonne qui enveloppe AUSSI .lb-dialog-content (le corps du popup). Le contenu du popup fournit
   son propre titre et un bouton « Annuler ». */
.pal-pop-noheader .lb-top-dialog {
    display: none;
}

/* Dialogue de confirmation (Dialog.Confirm) : le composant ConfirmDialog de LinkBlazor rend le
   message dans un simple <div> sans classe, juste avant .lb-confirm-btn-container, comme un noeud
   texte — les retours a la ligne d'un message multi-lignes (ex. suppression tournoi/championnat
   avec liste des consequences) seraient donc ecrases. pre-line les preserve sans figer les
   espaces d'indentation. */
.lb-dialog :is(div, p):has(+ .lb-confirm-btn-container) {
    white-space: pre-line;
}

/* Toasts (LinkBlazor.DialogAndToast) — contrairement a .lb-dialog ([[dialog-theme-invariant]],
   laisse blanc en dur pour ne pas risquer de casser du contenu back-office), un toast est une
   notification ephemere sans contenu structure : aucun risque a le themer globalement, front et
   back-office confondus. La librairie pose des couleurs pleines en dur par severite
   (#f23939/#39d0f2/#30c833/#f2e339, bordure noire, ombre fixe) — remplacees par le meme langage
   que les badges/chips semantiques du site (fond teinte clair + liseret/titre colores). */
.lb-toast-item {
    border: 1px solid var(--surface-border);
    border-radius: var(--pal-card-radius);
    background: var(--surface-card);
    box-shadow: var(--pal-card-shadow);
    overflow: hidden;
    /* la plupart des toasts du site n'ont qu'une ligne (titre seul, "mode solo" de la librairie,
       sans .lb-toast-detail en dessous) : sans hauteur mini ni centrage, le padding du titre
       seul (pense pour etre suivi d'un detail) laissait un pave bas et desequilibre. */
    min-height: 3.75rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

    .lb-toast-item:hover {
        box-shadow: var(--pal-card-shadow);
    }

.lb-toast-titlebar {
    background: transparent;
    border-bottom: none;
    color: var(--text);
    align-items: center;
    padding: .5rem 1.1rem;
}

.lb-toast-titlebar-close {
    --lb-close-border-color: var(--surface-border);
    color: var(--text-muted);
}

.lb-toast-detail {
    color: var(--text);
    padding: 0 1.1rem 1rem 1.1rem;
}

.lb-toast-title {
    font-weight: 700;
}

.lb-message-error .lb-toast-item { border-left: 4px solid var(--pal-red); }
.lb-message-error .lb-toast-title { color: var(--pal-red); }
.lb-message-info .lb-toast-item { border-left: 4px solid var(--pal-info); }
.lb-message-info .lb-toast-title { color: var(--pal-info); }
.lb-message-success .lb-toast-item { border-left: 4px solid var(--pal-success); }
.lb-message-success .lb-toast-title { color: var(--pal-success); }
.lb-message-warn .lb-toast-item { border-left: 4px solid var(--pal-warning); }
.lb-message-warn .lb-toast-title { color: var(--pal-warning); }

/* Dashboard Menus */

.pal-dash-sep > div + div {
    border-left: 1px solid;
    padding-left: 7px;
}

.pal-dash-menu {
    flex-direction: column;
    display: flex;
    background-color: var(--pal-bo-bg) !important;
    color: var(--chrome-text-muted);
    min-width: 300px;
}

/* seuil: --bp-desktop-sm */
@media (min-width:1024px) {
    .pal-dash-menu {
        min-height: 100vh;
    }
}

.pal-dash-menu.pal-lg {
    min-height: auto;
    height: 100%;
}

/* seuil: --bp-desktop-sm */
@media (min-width:1024px) {
    .pal-dash-menu.pal-lg {
        min-height: 100vh;
    }
}

.accordion-fakebutton {
    cursor: pointer;
    position: relative;
}

.pal-dash-menu .accordion-button::after {
    content: '\F282';
    background-image: unset;
    font-family: 'bootstrap-icons'
}

.pal-dash-menu ul {
    list-style-type: none;
    margin-block-start: 0;
    margin-block-end: 0;
    padding-inline-start: 0;
    background-color: color-mix(in srgb, var(--pal-bo-bg) 85%, white 15%);
}

.pal-dash-menu .accordion-body {
    padding: unset;
}

.pal-dash-menu li {
    padding: 0.6rem 0 0 3.5rem;
    position: relative;
    cursor: pointer;
}

.pal-dash-menu .accordion-button:focus {
    box-shadow: unset;
}

.pal-dash-menu .accordion-fakebutton a {
    padding: 1rem 1.25rem;
    display: inline-block;
}

.pal-dash-menu .accordion-fakebutton button {
    padding: 1rem 1.25rem;
    display: inline-block;
    border: unset;
    color: unset;
    background-color: unset
}

.pal-dash-menu .accordion {
    background-color: var(--pal-bo-bg);
}

.pal-dash-menu .accordion-button, .pal-dash-menu .accordion-fakebutton, .pal-dash-menu .accordion-button:not(.collapsed), .pal-dash-menu .accordion-item {
    background-color: var(--pal-bo-bg);
    border-bottom: 1px solid var(--chrome-border);
    color: var(--chrome-text-muted);
    box-shadow: none;
}

.pal-dash-menu .accordion-button {
    color: var(--chrome-text-muted);
}

.pal-dash-menu .accordion-item {
    border: unset;
}

.pal-dash-menu a {
    text-decoration: none;
    color: var(--chrome-text-muted);
    width: 100%;
}

.pal-dash-menu i {
    margin-right: 4px;
}

.accordion-header i {
    margin-right: 8px;
}

.pal-dash-menu .accordion-fakebutton:hover a, .pal-dash-menu .accordion-button:hover, .pal-dash-menu li:hover a {
    color: var(--chrome-text);
}

.pal-dash-menu .accordion-fakebutton:hover, .pal-dash-menu .accordion-button:hover, .pal-dash-menu li:hover {
    background-color: color-mix(in srgb, var(--pal-bo-bg) 80%, black 20%);
}

.pal-dash-menu .accordion-body li:last-child {
    padding-bottom: 8px;
}

/* Bootstrap*/
.pal-img.img-thumbnail {
    max-width: unset;
}

.dropdown-item i {
    margin-right: 10px;
}

.nav-link:hover {
    --bs-nav-link-hover-color: var(--pal-red-deep);
}

.nav-link {
    --bs-nav-link-color: var(--pal-red);
}

.nav-tabs .nav-link {
    background-color: var(--surface-card);
}

.nav-tabs {
    --bs-nav-tabs-link-active-color: #fff;
    --bs-nav-tabs-link-active-bg: var(--pal-red);
    --bs-nav-tabs-link-active-border-color: #000;
}

    .nav-tabs .nav-link.active:hover {
        --bs-nav-tabs-link-active-bg: var(--pal-red-deep);
    }

    .nav-tabs:hover {
        --bs-nav-tabs-link-active-color: #fff;
        --bs-nav-tabs-link-active-bg: var(--pal-red);
        --bs-nav-tabs-link-active-border-color: #000;
    }

.card-header {
    background-color: hsl(from var(--pal-red) h s l / 0.05);
}

.accordion-button:not(.collapsed) {
    color: white;
    background-color: var(--pal-red);
    box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--pal-red);
}

.accordion-button:focus {
    z-index: 3;
    outline: 0;
    box-shadow: 0 0 0 0.1rem hsl(from var(--pal-red) h s l / 0.2);
}

.accordion-button:not(.collapsed)::after {
    filter: invert(100%) sepia(100%) saturate(14%) hue-rotate(212deg);
}

.breadcrumb-item + .breadcrumb-item::before {
    content: var(--bs-breadcrumb-divider, ">");
}

/* Quick Grid */
td.pal-pill-info {
    color: var(--bs-info);
}

.qg-max-300 {
    max-height: 300px;
    overflow: auto;
}

.pal-bo label, .pal-profil label, .pal-login label {
    font-weight: bold;
}

.pal-bo input.form-control, .pal-profil input.form-control, .pal-login input.form-control,
.pal-bo select.form-control, .pal-profil select.form-control, .pal-login select.form-control,
.pal-bo div.input-group, .pal-profil div.input-group, .pal-login div.input-group {
    margin-bottom: 0.5rem;
}

.pal-bo .input-group input.form-control {
    margin-bottom: unset;
}

.pal-sticky-button {
    display: flex;
    justify-content: center;
    margin-top: 0.4rem;
    padding: 0.25rem 0;
    position: -webkit-sticky;
    position: sticky;
    bottom: 0;
    z-index: 400;
    /* Fond blanc translucide + bordure grise fixes (codes en dur avant cette session) : invisible/
       incoherent en theme sombre. Utilise sur 14 pages (front + back-office). */
    background-color: hsl(from var(--surface-card) h s l / .85);
    border: 1px solid var(--surface-border);
    border-radius: 5px;
}
/*User Defined*/
.pal-user-cms .pal-flex-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 30px;
    margin: 30px 0;
}

.pal-user-cms .pal-flex-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 360px;
}

.pal-user-cms .pal-team-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 30px;
    padding: 40px;
}

.pal-user-cms .pal-team-member {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    width: 200px;
}

    .pal-user-cms .pal-team-member img {
        width: 120px;
        height: 120px;
        border-radius: 50%;
        object-fit: cover;
        margin-bottom: 5px;
    }

.pal-user-cms .pal-member-role {
    font-size: 18px;
    color: #A00500;
}

.pal-user-cms .pal-member-name {
    font-size: 14px;
    font-weight: bold;
    color: #222;
}

.ck-editor__editable {
    min-height: 0px;
}

/* ============================================================================
   Affiliation Winamax — encart de l'espace membre (/GestionUtilisateur/Dashboard)
   Uniquement textuel, fond de couleur selon le statut. Ne revele jamais le
   caractere exceptionnel/restreint (libelles neutres cote front-office).
   ============================================================================ */
.pal-affil-fo {
    --_c: var(--text-muted);
    --_bg: color-mix(in srgb, var(--pal-tier-none) 30%, transparent);
    /* Colonne : le bloc d'actions passe TOUJOURS sous le texte (avant : cote a cote avec
       justify-content:space-between, l'action ne descendait qu'a l'etroit — incoherent d'un
       statut a l'autre selon la longueur du message). */
    display: flex;
    flex-direction: column;
    gap: .7rem;
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    border-radius: var(--pal-card-radius);
    border: 1px solid color-mix(in srgb, var(--_c) 32%, transparent);
    background-color: var(--_bg);
}
.pal-affil-fo--ok { --_c: var(--pal-success); --_bg: var(--pal-success-bg); }
.pal-affil-fo--pending { --_c: var(--pal-info); --_bg: var(--pal-info-bg); }
/* Cas « a traiter » (pseudo non reconnu, autre club) : orange, comme .pal-affil-bo--warn cote
   back-office — distingue « tu dois faire quelque chose » de « tu n'es simplement pas affilie ». */
.pal-affil-fo--warn { --_c: var(--pal-warning); --_bg: var(--pal-warning-bg); }

.pal-affil-fo-main { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.pal-affil-fo-title { font-weight: 800; color: var(--_c); }
.pal-affil-fo-msg { font-size: .9rem; color: var(--text); }

.pal-affil-fo-actions { display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: center; }
.pal-affil-fo-actions a,
.pal-affil-fo-actions button {
    font-size: .86rem;
    font-weight: 700;
    color: var(--_c);
    background: none;
    border: 1px solid color-mix(in srgb, var(--_c) 45%, transparent);
    border-radius: 999px;
    padding: .35rem .9rem;
    text-decoration: none;
    cursor: pointer;
}
