: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;
    /* Ecart entre cartes du back-office (.pal-bo-grid-2, .pal-bo-stack) */
    --pal-bo-section-gap: 1.1rem;
    /* 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);
    /* Bandeau d'information (Parametres du site › Affichage) — fonds satures sous le header
       sombre, texte --pal-on-accent. Assombris en theme sombre (variante B validee par Robin le
       13/10) : toujours visibles, moins eblouissants sur un fond noir. */
    --pal-bandeau-information: #1d4f91;
    --pal-bandeau-important: #8a560d;
    --pal-bandeau-urgent: #b3202f;
    /* Membre banni (fiche adhérent › Bannissement) — aubergine, seule famille de teinte absente des
       autres badges. Fond du badge PAL constant (texte blanc) ; --pal-banni-text = texte du chip,
       éclairci en thème sombre (blocs plus bas). */
    --pal-banni: #5b2a86;
    --pal-banni-text: #5b2a86;
    --pal-banni-bg: color-mix(in srgb, var(--pal-banni-text) 13%, 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);

    /* Hauteur maximale d'un tableau du back-office a en-tete fixe (regle T10 de l'harmonisation des
       tableaux, 2026-10-11) : le tableau defile dans sa carte, ses titres de colonnes restent visibles.
       Constant, ne change pas avec le theme. */
    --pal-bo-liste-max-height: calc(100vh - 14rem);

    /* 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);
    --pal-muted-bg: color-mix(in srgb, var(--text-muted) 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;
    /* Marge intérieure d'une page de contenu (pages CMS, Équipe CA). */
    --pal-cms-page-pad: .85rem;
    /* 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);
    /* Espace sous un bloc de page du back-office (en-tete, rangee d'indicateurs, carte) —
       constant, ne change pas avec le theme. */
    --pal-bo-bloc-gap: 1.375rem;

    /* 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: var(--pal-fs-2xs);
    --pal-hint-gap: .75rem;

    /* Echelle des tailles de texte (conventions de code § 7, audit Q-CSS-05) — constante, ne change
       pas avec le theme. Toute nouvelle taille renvoie a un palier : une variable de composant
       (--pal-xxx-font-size) vaut var(--pal-fs-...), jamais un nombre. Paliers poses sur les valeurs
       les plus employees du site ; pour harmoniser, on change un palier ici, pas les composants. */
    --pal-fs-2xs: .72rem;
    --pal-fs-xs: .78rem;
    --pal-fs-sm: .85rem;
    --pal-fs-md: .9rem;
    --pal-fs-base: 1rem;
    --pal-fs-lg: 1.15rem;
    --pal-fs-xl: 1.3rem;
    --pal-fs-2xl: 1.6rem;
    --pal-fs-3xl: 2rem;
    /* Titre h1 d'une page hors JumboTop (decision #titres-echelle-h1 : une seule echelle fluide). */
    --pal-fs-titre-page: clamp(1.6rem, 4vw, 2.2rem);

    /* Page de message courte et centrée (.pal-page-message, composant PalPageMessage) — tailles
       constantes ; seule la teinte de la pastille d'icône change en sombre (blocs plus bas). */
    --pal-page-message-max-width: 34rem;
    --pal-page-message-padding: 3.5rem 1rem 4rem;
    --pal-page-message-icon-size: 4rem;
    --pal-page-message-icon-font-size: var(--pal-fs-2xl);
    --pal-page-message-icon-gap: 1.25rem;
    --pal-page-message-icon-bg: color-mix(in srgb, var(--pal-red) 12%, transparent);
    --pal-page-message-title-size: var(--pal-fs-titre-page);
    --pal-page-message-title-gap: .5rem;
    --pal-page-message-text-size: var(--pal-fs-base);
    --pal-page-message-text-gap: 1.5rem;
    /* Variante « introuvable » (Shared/PalIntrouvable.razor, audit 17) : seconde phrase, adresse demandee,
       liens vers les pages les plus visitees. */
    --pal-introuvable-detail-size: var(--pal-fs-md);
    --pal-introuvable-detail-weight: 400;
    --pal-introuvable-detail-pull: 1rem;
    --pal-introuvable-adresse-pad: .3rem .7rem;
    --pal-introuvable-adresse-size: var(--pal-fs-sm);
    --pal-introuvable-trait: 1px;
    --pal-introuvable-liens-gap: .6rem 1.4rem;
    --pal-introuvable-liens-top: 2rem;
    --pal-introuvable-liens-size: var(--pal-fs-md);
    --pal-introuvable-liens-weight: 700;

    /* Captcha des formulaires publics (.pal-captcha : contact, inscription, mot de passe oublié,
       renvoi de la confirmation) — tailles constantes, ne changent pas avec le thème. */
    --pal-captcha-margin-bottom: 1.25rem;
    --pal-captcha-gap: .75rem;
    --pal-captcha-input-max-width: 12rem;

    /* 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;
    /* Pastille sur une ligne (mode Live/Online, statut d'un don) : arrondi complet. Constant. */
    --pal-pill-radius: 999px;
    /* Pastille d'icone d'un titre de section (.pal-bloc-titre-icone). Constant. */
    --pal-icon-tile-radius: 12px;
    /* Ligne de total d'une liste courte, sans pages a tourner (PALPaginator compact, 16/10) :
       ecart au tableau et taille du texte. Constant, ne change pas avec le theme. */
    --pal-list-foot-compact-gap: .6rem;
    --pal-list-foot-compact-pad: .5rem;
    --pal-list-foot-compact-font-size: var(--pal-fs-xs);
    /* Pastilles sur une ligne (.pal-mode-chip, .pal-status-chip) : taille du texte et marges
       interieures. Constant, ne change pas avec le theme. */
    --pal-pill-font-size: var(--pal-fs-2xs);
    --pal-pill-pad: .15rem .6rem;
    /* Blocs a titre et icone du site public (.pal-bloc*, espace membre 16/10) : marges
       interieures du bloc, taille du titre, de sa precision a droite, cote et taille de la
       pastille d'icone ; ecart unique entre les blocs d'une page (tableau de bord, Saison,
       Profil, inscription). Constant, ne change pas avec le theme. */
    --pal-bloc-pad: 1.25rem 1.4rem;
    --pal-bloc-gap: 1.25rem;
    --pal-bloc-title-font-size: var(--pal-fs-lg);
    --pal-bloc-sub-font-size: var(--pal-fs-sm);
    --pal-bloc-icon-tile-size: 2.6rem;
    --pal-bloc-icon-font-size: var(--pal-fs-lg);
    /* Lien en pied de bloc (.pal-bloc-lien) : ecart au contenu, taille du texte. */
    --pal-bloc-lien-gap: .75rem;
    --pal-bloc-lien-font-size: var(--pal-fs-sm);
    /* Cartes « Mes classements » (ClassementsMembre.razor) : marges interieures, nom du
       championnat, place (grand chiffre), lignes de detail. Constant. */
    --pal-cl-card-pad: .9rem 1rem;
    --pal-cl-title-font-size: var(--pal-fs-md);
    --pal-cl-place-font-size: var(--pal-fs-2xl);
    --pal-cl-meta-font-size: var(--pal-fs-sm);
    /* Dotations du membre (lot C) : ligne « Dotation de ta place » des cartes, precision sous un statut. */
    --pal-cl-dotation-gap: .35rem;
    --pal-dotations-membre-detail-gap: .2rem;
    --pal-dotations-membre-min: 34rem;
    /* Tableau des dons du tableau de bord (Dashboard.razor) : ligne de groupe d'une adhesion
       precedente, lien replie « Mes adhesions precedentes » et sa fleche. Constant. */
    --pal-dons-group-font-size: var(--pal-fs-sm);
    --pal-dons-prev-font-size: var(--pal-fs-sm);
    --pal-dons-prev-chevron-size: var(--pal-fs-2xs);
    --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;
    /* Fond d'une ligne d'en-tete de tableau (.pal-grid th) et des lignes de groupe qui en reprennent
       l'aspect (.pal-dons-groupe, tableau de bord). Construit sur --surface-card et --text, deja
       redefinies par chaque theme sur :root : pas d'override sombre a ecrire. */
    --pal-grid-th-bg: color-mix(in srgb, var(--surface-card) 92%, var(--text) 8%);
    /* Regle de forme "Champ" (harmonisation des champs du BO, decision Robin 2026-10-10) — constant,
       ne change pas avec le theme. Tout champ de saisie (texte, liste deroulante, recherche) prend
       ce rayon ; les pastilles (onglets de filtre, chips, badges) gardent leur arrondi complet.
       Les champs encore a 6/8/12 px ou arrondis complets (recherche du header, doublon) passent a
       cette variable avec le lot 2 de l'harmonisation. */
    --pal-field-radius: 7px;
    /* Fond de tout champ de saisie = fond de page : le champ se detache de la carte ou de la pop-up
       qui le contient, dans les deux themes (suit --surface-bg, redefini en sombre). Meme decision,
       meme calendrier que --pal-field-radius : pop-ups tout de suite, le reste avec le lot 2. */
    --pal-field-bg: var(--surface-bg);
    /* Anneau de focus des champs (Bootstrap compris), un seul pour tout le site (lot F-0, 16/10). */
    --pal-focus-ring: 0 0 0 .25rem color-mix(in srgb, var(--pal-red) 35%, transparent);
    /* Arrondi des encarts (messages .alert, zone de depot d'image) — constant, ne change pas avec
       le theme ; entre celui des champs (7 px) et celui des cartes (14 px). */
    --pal-encart-radius: 10px;
    /* Part du ton (vert, rouge, orange, bleu) dans la bordure d'un encart de couleur (.alert-*),
       melangee a --surface-border — constant, ne change pas avec le theme. */
    --pal-encart-bordure-dose: 30%;
    /* Texte d'un message d'erreur sous un champ (lot F-1, regle FO-10) : rouge fonce en clair,
       rouge vif en sombre (--pal-red-mid n'a pas de version sombre, illisible sur fond noir). */
    --pal-error-text: var(--pal-red-mid);
    /* Survol d'un lien discret (« Mot de passe oublie ? », « Retour a la connexion »...) : meme rouge
       lisible que le texte d'erreur, fonce en clair, vif en sombre (suit --pal-error-text). */
    --pal-link-hover: var(--pal-error-text);
    /* Ombre du rond de l'interrupteur (switch.css). Constant, ne change pas avec le theme. */
    --pal-switch-knob-shadow: rgba(0, 0, 0, .25);
    /* Fond de l'interrupteur eteint (switch.css) : au moins 3:1 face au rond blanc ET face au fond
       de page/carte, dans les deux themes (revue 19/10 : --text-muted sombre ne faisait que 2,5:1).
       Clair = l'ancien gris (3,8:1) ; sombre = gris chaud plus fonce (4,7:1 rond, 4,2:1 fond). */
    --pal-switch-off-bg: #838383;
    /* Fond de l'interrupteur allume (switch.css) : le vert « succes » du theme en clair (5,4:1 face
       au rond blanc) ; en sombre, un vert propre plus fonce que --pal-success (#4caf82 ne faisait que
       2,7:1) : 3,5:1 face au rond blanc, 4,8:1 face au fond des cartes (decision Robin 02/11). */
    --pal-switch-on-bg: var(--pal-success);
    /* Champs du site public (regle FO-2) : 16 px, en dessous iOS zoome sur le champ, et 44 px de
       haut, cible tactile minimale. Constant, ne change pas avec le theme. */
    --pal-fo-field-font-size: var(--pal-fs-base);
    --pal-fo-field-min-height: 44px;
    /* Fleche des listes deroulantes Bootstrap (.form-select), dessin de Bootstrap a la couleur
       --text-muted du theme (redefinie en sombre, plus bas). */
    --pal-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236e6c66' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    /* Plan de la barre « Enregistrer » collante en bas des fiches (.pal-sticky-button) : un panneau
       de suggestions (.pal-bo-pick-results) passe au-dessus. Constant, ne change pas avec le theme. */
    --pal-sticky-button-z: 400;

    /* 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;
    /* Ligne ou groupe coupé (mail automatique désactivé, Paramètres › Mails) : estompé. */
    --pal-opacite-coupe: .55;

    /* 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);

    /* Page Statistiques du back-office (onglets Membres, Dons, Affiliations) : geometrie des barres
       empilees, des colonnes et des barres horizontales. Constant, ne change pas avec le theme ; les
       couleurs reprennent la rampe --pal-tier-* (tranches de jeu, du gris au rouge) et la palette
       --agenda-* (live, online, les deux), deja declinees en theme sombre. */
    --pal-bo-stats-gap: .75rem;
    --pal-bo-stats-gap-sm: .5rem;
    --pal-bo-stats-gap-xs: .3rem;
    --pal-bo-stats-text-size: var(--pal-fs-sm);
    --pal-bo-stats-lead-size: var(--pal-fs-xl);
    --pal-bo-stats-bar-radius: 4px;
    --pal-bo-stats-seg-gap: 2px;
    --pal-bo-stats-empile-height: 22px;
    --pal-bo-stats-swatch: 11px;
    --pal-bo-stats-colonnes-height: 150px;
    --pal-bo-stats-colonne-width: min(60%, 2.875rem);
    --pal-bo-stats-bar-min: 2px;
    --pal-bo-stats-hbar-height: 14px;
    --pal-bo-stats-hbar-label: 12rem;
    --pal-bo-stats-hbar-label-mobile: 7.5rem;
    --pal-bo-stats-pied-pad: .6rem 1.25rem .75rem;
    /* Blocs (état des lieux / évolution / questions croisées), courbes et tableau des cohortes (21/10). */
    --pal-bo-stats-bloc-gap: 1rem;
    --pal-bo-stats-bloc-marge: 1.5rem;
    --pal-bo-stats-bloc-titre: var(--pal-fs-lg);
    --pal-bo-stats-axe-size: var(--pal-fs-2xs);
    --pal-bo-stats-trait: 2px;
    --pal-bo-stats-pointille: 5 4;
    --pal-bo-stats-partiel: 3 4;
    --pal-bo-stats-trait-legende: 3px;
    --pal-bo-stats-swatch-ligne: 16px;
    --pal-bo-stats-estompe: .45;
    --pal-bo-stats-cellule-min: 4.2em;
    --pal-bo-stats-cellule-pad: 2px 6px;
    --pal-bo-stats-grille: 1px;
    --pal-bo-stats-info-marge: .35rem;
    /* Carte à deux valeurs côte à côte (PalKpiDouble) et répartition par palier (PalPaliersRepartition). */
    --pal-bo-kpi-split-gap: 1rem;
    --pal-bo-kpi-split-value-size: var(--pal-fs-xl);
    --pal-tier-bar-height: 20px;
    --pal-tier-bar-radius: 999px;
    --pal-tier-bar-marge: 1.1rem;
    --pal-tier-legende-gap: 1.75rem;
    --pal-tier-item-gap: .6rem;
    --pal-tier-item-marge: .65rem;
    --pal-tier-swatch: 12px;
    --pal-tier-swatch-radius: 3px;
    --pal-tier-libelle-size: var(--pal-fs-sm);
    --pal-tier-montant-size: var(--pal-fs-2xs);
    --pal-tier-nombre-size: var(--pal-fs-md);
    --pal-tier-pourcent-size: var(--pal-fs-xs);
    --pal-tier-pourcent-marge: .3rem;
}

@media (prefers-color-scheme: dark) {
    :root {
        --pal-opacite-coupe: .5;
        --pal-bandeau-information: #163d70;
        --pal-bandeau-important: #6b430a;
        --pal-bandeau-urgent: #8c1925;
        --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);
        --pal-banni-text: #c3a0e6;
        --pal-banni-bg: color-mix(in srgb, var(--pal-banni-text) 17%, transparent);
        --pal-muted-bg: color-mix(in srgb, var(--text-muted) 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;
        --pal-switch-off-bg: #75736d;
        --pal-switch-on-bg: #3d9a6e;
        --pal-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23a6a49c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
        --pal-error-text: var(--pal-red);
        /* Rampe des tranches en sombre : les rouges de marque fonces (mid, deep) disparaissaient
           sur le fond des cartes. Tranches 3 a 5 eclaircies, toujours de plus en plus foncees,
           la plus foncee gardant un contraste d'au moins 3:1 avec --surface-card. */
        --pal-tier-3: #e45563;
        --pal-tier-4: var(--pal-red);
        --pal-tier-5: #c01f30;
        /* Pastille d'icône des pages de message : plus dense, sinon presque invisible sur fond sombre. */
        --pal-page-message-icon-bg: color-mix(in srgb, var(--pal-red) 22%, transparent);
    }
}

:root[data-theme="dark"] {
    --pal-opacite-coupe: .5;
    --pal-bandeau-information: #163d70;
    --pal-bandeau-important: #6b430a;
    --pal-bandeau-urgent: #8c1925;
    --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);
    --pal-banni-text: #c3a0e6;
    --pal-banni-bg: color-mix(in srgb, var(--pal-banni-text) 17%, transparent);
    --pal-muted-bg: color-mix(in srgb, var(--text-muted) 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;
    --pal-switch-off-bg: #75736d;
    --pal-switch-on-bg: #3d9a6e;
    --pal-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23a6a49c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    --pal-error-text: var(--pal-red);
    --pal-tier-3: #e45563;
    --pal-tier-4: var(--pal-red);
    --pal-tier-5: #c01f30;
    --pal-page-message-icon-bg: color-mix(in srgb, var(--pal-red) 22%, transparent);
}

:root[data-theme="light"] {
    --pal-opacite-coupe: .55;
    --pal-page-message-icon-bg: color-mix(in srgb, var(--pal-red) 12%, transparent);
    --pal-bandeau-information: #1d4f91;
    --pal-bandeau-important: #8a560d;
    --pal-bandeau-urgent: #b3202f;
    --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);
    --pal-banni-text: #5b2a86;
    --pal-banni-bg: color-mix(in srgb, var(--pal-banni-text) 13%, transparent);
    --pal-muted-bg: color-mix(in srgb, var(--text-muted) 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);
    --pal-switch-off-bg: #838383;
    --pal-switch-on-bg: var(--pal-success);
    --pal-select-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236e6c66' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    --pal-error-text: var(--pal-red-mid);
    /* Rampe des tranches : valeurs claires remises quand le theme clair est force sur un systeme
       en sombre (sinon les valeurs sombres du bloc media restaient). */
    --pal-tier-none: #c9c6bd;
    --pal-tier-3: var(--pal-red);
    --pal-tier-4: var(--pal-red-mid);
    --pal-tier-5: var(--pal-red-deep);
}

@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;
}

/* Badge PAL d'un membre banni (jamais sur les écrans vus par le membre, cf. GetBg) */
.bg-banni {
    background-color: var(--pal-banni);
    color: var(--pal-on-accent);
}

/* Bouton de rafraichissement de BlazorCaptcha (div.divCaptach > button.btn-refresh) : masque
   partout, il ne marche pas en rendu statique (inscription, mot de passe oublie). */
.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);
    /* Aussi posé sur un <button> (confirmation du désabonnement de la newsletter) : sans bordure
       native, même aspect qu'un lien. */
    border: 0;
    cursor: pointer;
}

/* Page de message courte et centrée (pastille d'icône, titre, phrase, bouton .pal-btn-home) :
   balisage dans le composant PalPageMessage, seule source (compte verrouillé, accès refusé, erreur,
   désabonnement de la newsletter, refus d'un message de contact, page « Trop de tentatives »).
   Remplace les blocs identiques auparavant dupliqués dans Lockout/AccessDenied/Error.razor.css. Titre
   en h2 quand la page a déjà son h1 (Contact, sous le bandeau JumboTop). */
.pal-page-message {
    max-width: var(--pal-page-message-max-width);
    margin: 0 auto;
    padding: var(--pal-page-message-padding);
    text-align: center;
}

.pal-page-message-icon {
    width: var(--pal-page-message-icon-size);
    height: var(--pal-page-message-icon-size);
    margin: 0 auto var(--pal-page-message-icon-gap);
    border-radius: 50%;
    display: grid;
    place-items: center;
    background-color: var(--pal-page-message-icon-bg);
    color: var(--pal-red);
    font-size: var(--pal-page-message-icon-font-size);
}

.pal-page-message :is(h1, h2) {
    margin: 0 0 var(--pal-page-message-title-gap);
    font-size: var(--pal-page-message-title-size);
    color: var(--text);
}

.pal-page-message p {
    margin: 0 0 var(--pal-page-message-text-gap);
    font-size: var(--pal-page-message-text-size);
    font-weight: 600;
    color: var(--text-muted);
}

/* Captcha des formulaires publics : formulaire de contact (Contact.razor) et formulaires de compte
   en rendu statique (CaptchaFormulaire.razor : inscription, mot de passe oublié, renvoi de la
   confirmation). Une seule présentation, auparavant recopiée dans Contact.razor.css et
   CaptchaFormulaire.razor.css. Posé avec .pal-field : libellé au style des champs. */
.pal-captcha {
    margin-bottom: var(--pal-captcha-margin-bottom);
}

/* Variante : captcha seul dans un bloc qui a déjà ses marges intérieures (bloc « Vérification »
   de l'inscription) — pas d'écart en plus dessous. CaptchaFormulaire DansBloc="true". */
.pal-captcha--dans-bloc {
    margin-bottom: 0;
}

.pal-captcha-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--pal-captcha-gap);
}

/* seuil: --bp-tablet */
@media (min-width: 600px) {
    .pal-captcha-row {
        flex-direction: row;
        align-items: center;
    }

    /* Deux classes : passe devant le width: 100% de .form-control (Bootstrap). */
    .pal-captcha-row .pal-captcha-input {
        width: auto;
        max-width: var(--pal-captcha-input-max-width);
    }
}

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;
}

/* ---- Socle des champs (harmonisation du site public, lot F-0, regles FO-1 / FO-2, 2026-10-16) ----
   Bootstrap peint ses champs avec --bs-body-bg (#fff) et --bs-border-color, jamais redefinis pour
   le theme sombre de ce site (pilote par [data-theme], pas par [data-bs-theme]) : champs blancs en
   sombre. Ici, une seule forme pour tout le site, back-office compris : fond de page, bordure et
   texte du theme, rayon des champs du BO, un seul anneau de focus. Les ecrans qui stylent encore
   leurs champs dans leur propre CSS (connexion, inscription, profil, recherches...) gardent leur
   rendu jusqu'a leur lot (F-1, F-2) : leur selecteur scope est plus specifique. Taille 16 px /
   44 px : site public seulement, plus bas. */
.form-control,
.form-select {
    background-color: var(--pal-field-bg);
    color: var(--text);
    border-color: var(--surface-border);
    border-radius: var(--pal-field-radius);
}

    .form-control::placeholder {
        color: var(--text-muted);
    }

    .form-control:focus,
    .form-select:focus {
        background-color: var(--pal-field-bg);
        color: var(--text);
        border-color: var(--pal-red-mid);
        box-shadow: var(--pal-focus-ring);
    }

    .form-control:disabled,
    .form-select:disabled,
    .form-control[readonly] {
        background-color: var(--surface-card);
        color: var(--text-muted);
    }

/* Fleche de la liste deroulante : image SVG a couleur fixe (#343a40) chez Bootstrap, quasi
   invisible en sombre. Meme dessin, couleur du theme (variable redefinie en sombre). */
.form-select {
    --bs-form-select-bg-img: var(--pal-select-chevron);
}

/* Prefixe / suffixe d'un groupe de champs (« € » du don, icones de recherche) : ton de carte. */
.input-group-text {
    background-color: var(--surface-card);
    color: var(--text-muted);
    border-color: var(--surface-border);
    border-radius: var(--pal-field-radius);
}

/* Site public seulement (la mise en page publique est .pal-container, le BO .pal-bo-shell) :
   texte a 16 px, sous lequel iOS zoome sur le champ, et cible tactile de 44 px (regle FO-2). Le
   back-office garde ses champs compacts. */
.pal-container :is(.form-control, .form-select):not(textarea) {
    font-size: var(--pal-fo-field-font-size);
    min-height: var(--pal-fo-field-min-height);
}

.pal-container textarea.form-control {
    font-size: var(--pal-fo-field-font-size);
}

/* ---- Champ du site public : libelle au-dessus (lot F-1, regle FO-3, 2026-10-16) ----
   Un seul mode de libelle sur tout le site, comme le back-office : jamais de libelle flottant,
   jamais un texte d'exemple a la place du libelle. Reprend le libelle « au-dessus » qui existait
   deja sur l'inscription (date de naissance) et le profil, promu ici pour tous les formulaires.
       <div class="pal-field">
           <label for="X">Libelle <span class="pal-field-req">*</span></label>
           <input id="X" class="form-control" ... />
           <span class="pal-field-hint">Aide facultative</span>
           <ValidationMessage ... />
       </div> */
.pal-field {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    min-width: 0;
}

    .pal-field > label {
        color: var(--text-muted);
        font-weight: 600;
        font-size: var(--pal-fs-md);
        margin: 0;
    }

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

.pal-field-hint {
    color: var(--text-muted);
    font-size: var(--pal-fs-sm);
}

/* Message d'erreur (regle FO-10) : sous un champ (ValidationMessage, rendu en .validation-message)
   et resume en tete de formulaire (ValidationSummary, rendu en ul.validation-errors). Seule
   definition : ne pas passer class="text-danger" a ces composants (la classe remplace la leur, et
   le rouge Bootstrap est en !important). Couleur seule hors champ : .validation-message, plus bas. */
.pal-field .validation-message,
.validation-errors {
    color: var(--pal-error-text);
    font-size: var(--pal-fs-sm);
}

/* Interrupteur suivi de son libelle, sur une ligne (« Se souvenir de moi »). Jamais de <label>
   autour de TheSwitch, qui en est deja un : le libelle est relie par for / Id.
       <div class="pal-field-switch"><TheSwitch Id="X" ... /><label for="X">Texte</label></div> */
.pal-field-switch {
    display: flex;
    align-items: center;
    gap: .6rem;
}

    .pal-field-switch .switch {
        flex: none;
    }

    .pal-field-switch > label {
        color: var(--text);
        font-size: var(--pal-fs-md);
        cursor: pointer;
        margin: 0;
    }

/* Variante « ligne de preference » (inscription, Mon profil) : libelle a gauche sur toute la
   largeur, interrupteur a droite, filet entre deux lignes.
       <div class="pal-field-switch pal-field-switch--pref"><label for="X">Texte</label><TheSwitch Id="X" ... /></div> */
.pal-field-switch--pref {
    justify-content: space-between;
    gap: 1rem;
    padding: .6rem 0;
}

    .pal-field-switch--pref + .pal-field-switch--pref {
        border-top: 1px solid var(--surface-border);
    }

    .pal-field-switch--pref > label {
        flex: 1 1 auto;
        min-width: 0;
    }

/* Groupes de preferences (Confidentialite, Communication) : un groupe = un petit titre + ses
   lignes .pal-field-switch--pref ; une colonne, deux des --bp-tablet. Inscription et Mon profil
   (PreferencesUser). */
.pal-prefs {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
}

    .pal-prefs-groupe > h3 {
        margin: 0 0 .85rem;
        padding-bottom: .5rem;
        font-size: var(--pal-fs-xs);
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: .06em;
        color: var(--pal-red);
        border-bottom: 1px solid var(--surface-border);
    }

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

/* Champ mot de passe avec bouton « afficher » : PalChampMotDePasse (son CSS dans
   PalChampMotDePasse.razor.css). */

/* ---- Petite page du compte (connexion, mot de passe oublie, renvoi de confirmation,
   reinitialisation, double authentification) : en-tete centre + carte isolee + bouton pleine
   largeur + lien d'aide. Ex-copies identiques ForgotPassword.razor.css /
   ResendEmailConfirmation.razor.css, promues ici (lot F-1). L'inscription garde sa propre
   largeur (formulaire sur deux colonnes) et reprend seulement l'en-tete. */
.pal-compte {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.75rem 1rem 3rem;
}

/* Variante etroite : la connexion (deux champs). */
.pal-compte--etroit {
    max-width: 30rem;
}

/* En-tete de page (titre + phrase) : pages du compte (centre) et, avec --gauche, inscription, Mon
   profil, tableau de bord et page Saison. --pal-compte-hero-pad : ecart du filet sous l'en-tete ;
   --pal-compte-hero-titre-gap : ecart entre le titre et la phrase. */
.pal-compte-hero {
    --pal-compte-hero-pad: 1.5rem;
    --pal-compte-hero-titre-gap: .5rem;
    padding-bottom: var(--pal-compte-hero-pad);
    margin-bottom: var(--pal-compte-hero-pad);
    border-bottom: 1px solid var(--surface-border);
    text-align: center;
}

    .pal-compte-hero h1 {
        margin: 0 0 var(--pal-compte-hero-titre-gap);
        font-size: var(--pal-fs-titre-page);
        line-height: 1.15;
        color: var(--text);
    }

    .pal-compte-hero p {
        color: var(--text-muted);
        margin: 0;
    }

/* Variante alignee a gauche : pages en blocs (inscription, Mon profil, tableau de bord, Saison),
   une seule mesure pour toutes (ex-copies .pal-dashboard-hero / .pal-tournois-hero). Posee dans
   un conteneur .pal-blocs : la marge du bas y est retiree, l'ecart vient du gap. */
.pal-compte-hero--gauche {
    --pal-compte-hero-pad: 1.25rem;
    --pal-compte-hero-titre-gap: .35rem;
    text-align: left;
}

.pal-compte .alert {
    margin-bottom: 1.25rem;
}

/* Champs poses directement dans le formulaire (pas ceux d'une rangee, comme « Se souvenir de
   moi » a cote de « Mot de passe oublie ? » sur la connexion). */
.pal-compte form > .pal-field,
.pal-compte form > .pal-field-switch {
    margin-bottom: 1.25rem;
}

.pal-compte-submit {
    width: 100%;
    padding: .85rem 1.3rem;
    font-size: var(--pal-fs-base);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    border-radius: var(--pal-btn-radius);
}

.pal-compte-help {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    margin-top: 1.25rem;
    color: var(--text-muted);
    font-size: var(--pal-fs-sm);
    text-decoration: none;
}

    .pal-compte-help:hover {
        color: var(--pal-link-hover);
    }

/* Variante sous un champ (« Envoyer l'e-mail de vérification ») : bouton sans habillage, aligne a
   gauche, colle au champ ; ne s'etire pas dans la colonne du .pal-field. */
.pal-compte-help--champ {
    align-self: flex-start;
    margin-top: 0;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* ---- Messages (regle FO-10) ----
   Alertes Bootstrap aux couleurs du theme sur tout le site (ex-.pal-manage-card .alert-* de
   pal-manage.css, promues ici) : vert pour une reussite, rouge pour une erreur. Les pages du
   compte choisissent la couleur par le parametre Erreur de StatusMessage. */
.alert {
    border-radius: var(--pal-encart-radius);
    border: 1px solid var(--surface-border);
    background-color: var(--surface-bg);
    color: var(--text);
}

/* Encart de couleur : chaque ton ne donne que sa couleur et son fond teinte (--pal-*-bg, comme les
   pastilles) ; la bordure est construite une seule fois. */
.alert-success,
.alert-danger,
.alert-warning,
.alert-info {
    background-color: var(--_encart-fond);
    border-color: color-mix(in srgb, var(--_encart-ton) var(--pal-encart-bordure-dose), var(--surface-border));
}

.alert-success {
    --_encart-ton: var(--pal-success);
    --_encart-fond: var(--pal-success-bg);
}

.alert-danger {
    --_encart-ton: var(--pal-red);
    --_encart-fond: var(--pal-red-bg);
}

.alert-warning {
    --_encart-ton: var(--pal-warning);
    --_encart-fond: var(--pal-warning-bg);
}

.alert-info {
    --_encart-ton: var(--pal-info);
    --_encart-fond: var(--pal-info-bg);
}

/* ---- Cases a cocher et boutons radio (regle FO-5) ----
   Toutes les cases du site sont natives (aucune .form-check-input) : couleur du site par
   accent-color, heritee partout. Les cases dessinees de /search (FO-21) viennent avec le lot F-2. */
:root {
    accent-color: var(--pal-red);
}

/* 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);
}

#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 select,
.pal-msgpop-field .form-control {
    width: 100%;
    background-color: var(--pal-field-bg);
    border: 1px solid var(--dialog-border);
    color: var(--dialog-text);
    border-radius: var(--pal-field-radius);
    padding: 7px 10px;
    font: inherit;
    font-size: .88rem;
}

/* Partagé avec la liste de filtre des listes du BO (.pal-bo-filtre-liste, pal-backoffice.css). */
.pal-msgpop-field input:focus,
.pal-msgpop-field select:focus,
.pal-msgpop-field .form-control:focus,
.pal-bo-filtre-liste:focus {
    background-color: var(--pal-field-bg);
    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 var(--pal-error-text);
}

.validation-message {
    color: var(--pal-error-text);
}

.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."
    }

.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%;
}

/* Information absente dans un tableau = tiret discret, posé ici pour toutes les grilles (Robin, 29/10) :
   pas de « — » à écrire à la main dans les colonnes. La cellule reste une vraie cellule : l'ancienne
   règle « td:empty { display: inherit } » la sortait de la ligne et décalait les colonnes suivantes.
   Colonne d'indicateur visuel (épingle, icône, image) qui n'affiche rien quand la condition est fausse :
   poser Class="pal-col-sans-tiret" sur la colonne, la cellule vide reste alors vide.
   Le tiret est décoratif : texte alternatif vide (après « / ») pour que les lecteurs d'écran ne le lisent pas,
   la première déclaration sert de repli aux navigateurs qui ignorent cette syntaxe. */
.quickgrid > tbody > tr > td:empty:not(.pal-col-sans-tiret)::after {
    content: "—";
    content: "—" / "";
    color: var(--text-muted);
}

.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, grille de cartes du Trombinoscope comprise. */
.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;
}

/* Anciens formulaires de l'espace membre et du BO : libelles en gras, marge sous chaque champ.
   Ne s'applique pas aux champs du modele commun .pal-field (lot F-1), qui ont leur propre
   espacement ; la connexion (ex-.pal-login) est entierement passee a ce modele. */
.pal-bo label, .pal-profil :not(.pal-field):not(.pal-field-switch) > label {
    font-weight: bold;
}

.pal-bo input.form-control, .pal-profil :not(.pal-field):not(.pal-field-mdp) > input.form-control,
.pal-bo select.form-control, .pal-profil :not(.pal-field) > select.form-control,
.pal-bo div.input-group, .pal-profil :not(.pal-field) > 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: var(--pal-sticky-button-z);
    /* 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;
    /* Pas de marge : l'ecart avec les blocs voisins vient de la page (flex + gap). */
    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;
}

/* ==== Pastilles du site public (refonte de l'espace membre, 2026-10-16) ========================
   Ex-copies identiques de MesTournois / Dashboard / TrombinoscopeDetail .razor.css, promues ici.
   Mode d'un tournoi ou d'un championnat : <span class="pal-mode-chip is-live">Live</span>.
   Statut d'un don ou d'un lot : <span class="pal-status-chip is-valide|is-attente|is-info|is-muted">. */
.pal-mode-chip,
.pal-status-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: var(--pal-pill-pad);
    border-radius: var(--pal-pill-radius);
    font-size: var(--pal-pill-font-size);
    font-weight: 700;
    white-space: nowrap;
}

.pal-mode-chip.is-live {
    background-color: color-mix(in srgb, var(--agenda-live) 14%, transparent);
    color: var(--agenda-live);
}

.pal-mode-chip.is-online {
    background-color: color-mix(in srgb, var(--agenda-online) 16%, transparent);
    color: var(--agenda-online);
}

.pal-status-chip.is-valide {
    background-color: var(--pal-success-bg);
    color: var(--pal-success);
}

.pal-status-chip.is-attente {
    background-color: var(--pal-warning-bg);
    color: var(--pal-warning);
}

/* Lot a recuperer ou a crediter (espace membre, dotations) : en cours cote equipe ou Winamax. */
.pal-status-chip.is-info {
    background-color: var(--pal-info-bg);
    color: var(--pal-info);
}

/* Lot non attribue : plus rien a attendre. */
.pal-status-chip.is-muted {
    background-color: var(--pal-muted-bg);
    color: var(--text-muted);
}

/* ==== Blocs et titres a icone du site public (espace membre, 16/10/2026) =====================
   Titre de section a icone : ex-copies identiques de Profil.razor.css et Register.razor.css,
   promues ici pour le tableau de bord et la page Saison. Bloc = une carte par section ; l'ecart
   entre blocs est donne par le conteneur .pal-blocs, jamais par une marge du bloc.
   <div class="pal-blocs"><section class="pal-bloc"><div class="pal-bloc-titre"><span class="pal-bloc-titre-icone">
   <i class="bi bi-..."></i></span><h2>Titre</h2><span class="pal-bloc-titre-sub">...</span></div> */

/* Conteneur d'une suite de blocs (page ou formulaire de l'espace membre, inscription) : une
   colonne, un seul ecart --pal-bloc-gap entre ses enfants. Les marges propres des enfants
   (en-tete, message .alert, liste d'erreurs) sont retirees : sinon elles s'ajouteraient a l'ecart.
   Place apres .pal-compte-hero pour l'emporter sur sa marge du bas. */
.pal-blocs {
    display: flex;
    flex-direction: column;
    gap: var(--pal-bloc-gap);
}

    .pal-blocs > * {
        margin-top: 0;
        margin-bottom: 0;
    }

.pal-bloc {
    background: var(--surface-card);
    border: 1px solid var(--surface-border);
    border-radius: var(--pal-card-radius);
    padding: var(--pal-bloc-pad);
    min-width: 0;
}

.pal-bloc-titre {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem .75rem;
    margin-bottom: 1.1rem;
}

    .pal-bloc-titre h2 {
        margin: 0;
        font-size: var(--pal-bloc-title-font-size);
        color: var(--text);
    }

.pal-bloc-titre-icone {
    width: var(--pal-bloc-icon-tile-size);
    height: var(--pal-bloc-icon-tile-size);
    flex: none;
    display: grid;
    place-items: center;
    border-radius: var(--pal-icon-tile-radius);
    background: color-mix(in srgb, var(--pal-red) 14%, transparent);
    color: var(--pal-red);
    font-size: var(--pal-bloc-icon-font-size);
}

/* Precision a droite du titre (periode, saison, total). */
.pal-bloc-titre-sub {
    margin-left: auto;
    color: var(--text-muted);
    font-size: var(--pal-bloc-sub-font-size);
}

    .pal-bloc-titre-sub strong {
        color: var(--text);
    }

/* Lien en pied de bloc, sous sa liste (« Tous mes classements par saison », « Toutes mes dotations
   par saison ») : ex-.pal-cl-link de ClassementsMembre.razor.css, promu pour le bloc des dotations
   du tableau de bord. */
.pal-bloc-lien {
    margin-top: var(--pal-bloc-lien-gap);
}

    .pal-bloc-lien a {
        color: var(--pal-red);
        font-size: var(--pal-bloc-lien-font-size);
        font-weight: 600;
    }

/* Telephone : la precision passe sous le titre, alignee a gauche (et non calee a droite). */
/* seuil: --bp-tablet */
@media (max-width: 599.98px) {
    .pal-bloc-titre-sub {
        flex-basis: 100%;
        margin-left: 0;
    }
}

/* ==== Tableaux communs au site et au back-office (lot F-0, regle FO-12, 2026-10-16) ============
   Un seul style de tableau pour tout le site : ex-.pal-bo-grid / .pal-bo-tablewrap / .pal-bo-num /
   .pal-bo-date du back-office, renommes et deplaces ici depuis pal-backoffice.css. Places APRES
   les regles QuickGrid generiques d'app.css, qu'ils doivent battre a specificite egale. Attention :
   pal-cms, pal-tournoi-content, pal-manage et pal-forum.css sont charges apres app.css ; une
   regle th/td de meme specificite qui y serait ajoutee l'emporterait sur ce tableau (aujourd'hui,
   seule .pal-manage-card table td y touche, plus specifique de toute facon). Les retouches propres
   au BO (en-tete fixe, tableau des inscrits) restent dans pal-backoffice.css.
   Un ecran l'adopte en posant Class="pal-grid" sur son QuickGrid (ou son <table>), dans un
   conteneur .pal-tablewrap qui defile sur telephone, avec PALPaginator et PalListeVide en pied.

   Origine : pattern duplique par page (::deep .pal-bo-xxx-grid) sur Championnats/Utilisateurs/
   Tournois, promu en classe partagee des la 4e page concernee (Saisons/News/Pages/Partenaires/
   Rooms/Lieux) plutot que de reconduire la duplication.
   .pal-grid--pleine : meme pleine largeur pour un <table class="pal-grid"> ecrit a la main
   (page Statistiques), au lieu d'un style="width:100%" en ligne. */
.pal-tablewrap {
    overflow: auto;
}

.pal-grid.quickgrid,
.pal-grid.pal-grid--pleine {
    width: 100%;
}

.pal-grid th {
    background-color: var(--pal-grid-th-bg);
    color: var(--text);
    border-color: var(--surface-border);
    font-size: var(--pal-fs-xs);
    text-transform: var(--pal-th-text-transform);
    letter-spacing: .04em;
    font-weight: 700;
    padding: 0.7rem 0.875rem;
}

    .pal-grid th .sort-indicator {
        filter: var(--pal-icon-invert-filter);
    }

    /* Les colonnes triables de QuickGrid enveloppent leur libelle dans un <button> — un <button>
       n'herite pas de color/background de son parent comme le ferait un <div> (regle UA du
       navigateur, independante du theme du site), d'ou un entete de colonne triable qui restait au
       rendu systeme (parfois blanc en clair, texte noir en sombre). */
    .pal-grid th button {
        color: inherit;
        background: transparent;
        border: none;
        text-transform: inherit;
        letter-spacing: inherit;
    }

.pal-grid > tbody > tr {
    border-bottom: 1px solid var(--surface-border);
}

.pal-grid tbody tr:nth-of-type(odd) {
    background-color: color-mix(in srgb, var(--text) 4%, transparent);
}

.pal-grid tbody tr:hover {
    background-color: var(--bo-row-hover);
}

.pal-grid td {
    color: var(--text);
    vertical-align: middle;
    padding: 0.6rem 0.875rem;
}

/* Harmonisation des tableaux (decisions Robin 2026-10-11, decisions.md#harmonisation-bo), regle
   T8 : nombres et montants a droite, chiffres de meme largeur ; dates a gauche, sur une ligne.
   Sur une colonne QuickGrid : Class="pal-num" (td ET th) + Align="Align.End" (aligne le titre). */
.pal-grid .pal-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pal-grid .pal-date {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Cellules editables (ex. tableau des paliers de la fiche Saison) : un <input>/<select> brut,
   sans classe, ne suit pas le theme du site (couleur/fond fixes du navigateur) meme si le <td>
   parent est correctement theme. Forme commune des champs (arrondi et fond), taille compacte. */
.pal-grid td input,
.pal-grid td select {
    width: 100%;
    padding: 5px 7px;
    border-radius: var(--pal-field-radius);
    border: 1px solid var(--surface-border);
    background-color: var(--pal-field-bg);
    color: var(--text);
    font: inherit;
    font-size: var(--pal-fs-sm);
}

    /* input seul (pas select, dont la fleche native a besoin de sa marge par defaut) : padding-right
       resserre pour les boutons +/- d'un eventuel type="number" (meme technique que
       .pal-bo-form-row input). */
    .pal-grid td input {
        padding-right: var(--pal-number-input-gutter);
    }
/* ---- Bandeau d'information (BandeauInfo.razor) et rappel de maintenance (MainLayout) ----
   Pleine largeur sous le header, contenu aligne sur .pal-content (memes largeurs que le bandeau
   des comptes en double). Global (pas scope) : partage par deux composants (le ton « urgent » sert aussi
   au rappel de maintenance). Le bouton de fermeture, propre a BandeauInfo, est dans BandeauInfo.razor.css. */
.pal-bandeau-info {
    --pal-bandeau-info-pad-y: .7rem;
    --pal-bandeau-info-pad-x: 1rem;
    --pal-bandeau-info-gap: .6rem;
    --pal-bandeau-info-size: var(--pal-fs-sm);
    --pal-bandeau-info-lh: 1.5;
    --pal-bandeau-info-max-lg: 1180px;
    --pal-bandeau-info-max-xl: 1320px;
    --pal-bandeau-info-ico-size: 1rem;
    --pal-bandeau-info-ico-mt: .1rem;
    --pal-bandeau-info-espace: .25rem;
    --pal-bandeau-info-x-size: var(--pal-fs-md);
    background: var(--pal-bandeau-information);
    color: var(--pal-on-accent);
}

.pal-bandeau-info-important {
    background: var(--pal-bandeau-important);
}

.pal-bandeau-info-urgent {
    background: var(--pal-bandeau-urgent);
}

.pal-bandeau-info-inner {
    width: 100%;
    margin: 0 auto;
    padding: var(--pal-bandeau-info-pad-y) var(--pal-bandeau-info-pad-x);
    display: flex;
    align-items: flex-start;
    gap: var(--pal-bandeau-info-gap);
    font-size: var(--pal-bandeau-info-size);
    line-height: var(--pal-bandeau-info-lh);
}

@media (min-width: 1024px) {
    .pal-bandeau-info-inner {
        max-width: var(--pal-bandeau-info-max-lg);
    }
}

@media (min-width: 1440px) {
    .pal-bandeau-info-inner {
        max-width: var(--pal-bandeau-info-max-xl);
    }
}

    .pal-bandeau-info-inner > i {
        font-size: var(--pal-bandeau-info-ico-size);
        margin-top: var(--pal-bandeau-info-ico-mt);
        flex: none;
    }

    .pal-bandeau-info-inner p {
        margin: 0;
        flex: 1;
        min-width: 0;
    }

    /* Lien du message ; dans l'aperçu du back-office, un <a> sans adresse (BandeauInfo). */
    .pal-bandeau-info-inner a {
        color: var(--pal-on-accent);
        text-decoration: underline;
        font-weight: 700;
        margin-left: var(--pal-bandeau-info-espace);
    }

/* Page de contenu (MainPages, Équipe CA) : marge intérieure commune. */
.pal-cms-page {
    padding: var(--pal-cms-page-pad);
}
