﻿/* ============================================================
   BREAKPOINTS MEDEF54 — convention 3 paliers (avril 2026)
   ============================================================
   - Mobile  : viewport < 768px  (téléphone, tablette portrait)
   - Laptop  : 768px → 1599px    (PC portable 1366×768 → 1920×1080)
   - Desktop : ≥ 1600px          (écran fixe / grand écran pro)

   Le module Prospection a été conçu pour Desktop ≥ 2560px ; cette
   convention vise à le rendre 100 % utilisable en Laptop sans
   dégrader le rendu Desktop.

   Convention d'écriture (mobile-first) :
       .element { ... }                         // base = mobile
       @media (min-width: 768px)  { ... }       // laptop+
       @media (min-width: 1600px) { ... }       // desktop only

   Règle sacrée : aucune règle en dehors d'un @media ne doit modifier
   le rendu au-delà de 1600px sans validation de capture before/after.
   ============================================================ */
:root {
    --bp-mobile-max:   767.98px;
    --bp-laptop-min:   768px;
    --bp-laptop-max:   1599.98px;
    --bp-desktop-min:  1600px;

    /* Exception : le menu général se replie en hamburger sous 1200px, pas 768 (il libère la
       largeur du contenu en laptop). Les variables --bp-* sont documentaires : un @media ne
       peut pas les lire. */
    --bp-nav-collapse: 1199.98px;

    /* Hauteur de l'écran pour la coquille (layout, listes, dialogs). Sur smartphone, Safari iOS
       compte dans 100vh la zone cachée sous sa barre d'outils : le paginateur et le bas des
       dialogs passaient dessous. 100dvh suit la zone réellement visible (voir le bloc mobile). */
    --hauteur-ecran: 100vh;
}

/* ============================================================
   JETONS DE DESIGN — docs/ui-patterns.md §5, §6, §7, §13
   ============================================================
   Le CSS du projet lit ces jetons, jamais une couleur en dur. Les composants FluentUI
   gardent leurs propres jetons (--neutral-*, --accent-*), calculés par la bibliothèque :
   l'accent reçoit la même couleur de marque par <FluentDesignTheme CustomColor>.

   --marque vient de l'organisation (Organisation.CouleurPrincipale), posée dans une balise
   <style> par App.razor puis MainLayout. L'échelle en découle par color-mix(in srgb), que
   CouleurMarque.Echelle reproduit en C# pour le contrôle de contraste : garder les mêmes
   pourcentages des deux côtés.

   Une variable dérivée se résout là où elle est déclarée : redéfinir --marque sur un
   descendant ne recalcule pas --marque-100. D'où .portee-marque, à poser sur l'élément qui
   redéfinit --marque (aperçu de l'administration).
   ============================================================ */
:root, .portee-marque {
    --marque-100: color-mix(in srgb, var(--marque, #1D4E89) 10%, #fff);
    --marque-200: color-mix(in srgb, var(--marque, #1D4E89) 25%, #fff);
    --marque-300: color-mix(in srgb, var(--marque, #1D4E89) 45%, #fff);
    --marque-400: color-mix(in srgb, var(--marque, #1D4E89) 70%, #fff);
    --marque-500: var(--marque, #1D4E89);
    --marque-600: color-mix(in srgb, var(--marque, #1D4E89) 85%, #000);
    --marque-700: color-mix(in srgb, var(--marque, #1D4E89) 70%, #000);
    --marque-800: color-mix(in srgb, var(--marque, #1D4E89) 55%, #000);
    --marque-900: color-mix(in srgb, var(--marque, #1D4E89) 40%, #000);

    /* Bandeau : la marque dans les deux thèmes, texte blanc (contrôlé à la saisie, ≥ 4,5:1) */
    --bandeau-fond: var(--marque-500);
    --bandeau-texte: #fff;
    --bandeau-texte-discret: rgba(255, 255, 255, 0.8);
    --bandeau-survol: rgba(255, 255, 255, 0.16);

    --texte-lien: var(--marque-500);
    --texte-sur-marque: #fff;
    --focus: var(--marque-500);
    --surface-selection: color-mix(in srgb, var(--marque, #1D4E89) 16%, var(--surface-carte));
    --surface-survol: color-mix(in srgb, var(--marque, #1D4E89) 6%, var(--surface-carte));

    --statut-marque-fond: var(--marque-100);
    --statut-marque-texte: var(--marque-700);
    --statut-marque-bordure: var(--marque-200);
    --statut-marque-plein: var(--marque-500);
}

:root {
    /* Surfaces et textes : neutres froids. Contrastes mesurés sur --surface-carte. */
    --surface-page: #F5F7FA;
    --surface-carte: #FFFFFF;
    --surface-creuse: #EEF2F6;
    --texte-principal: #1B2430;   /* 15,7:1 */
    --texte-secondaire: #55606E;  /* 6,4:1 */
    --texte-discret: #626D7B;     /* 5,3:1 ; 4,9:1 sur la page */
    --bordure: #D5DBE3;
    --bordure-forte: #B4BDC9;

    /* Statuts : fond pâle, texte foncé de la même famille (≥ 6:1), bordure, aplat (≥ 3:1) */
    --statut-succes-fond: #E6F4EA;
    --statut-succes-texte: #17603A;
    --statut-succes-bordure: #A8D5B8;
    --statut-succes-plein: #1F8A4C;
    --statut-attention-fond: #FDF1DC;
    --statut-attention-texte: #8A4B08;
    --statut-attention-bordure: #F0CB8A;
    --statut-attention-plein: #B86E00;
    --statut-erreur-fond: #FCE8E8;
    --statut-erreur-texte: #A12323;
    --statut-erreur-bordure: #F0B4B4;
    --statut-erreur-plein: #C93636;
    --statut-information-fond: #E5F0FB;
    --statut-information-texte: #1B5591;
    --statut-information-bordure: #A9CBEE;
    --statut-information-plein: #2B74C0;
    --statut-neutre-fond: #EEF1F5;
    --statut-neutre-texte: #465263;
    --statut-neutre-bordure: #CBD3DD;
    --statut-neutre-plein: #6B7685;
    /* Étape : pour les parcours à plus de cinq états, qui ne tiennent pas dans les tons ci-dessus */
    --statut-etape-fond: #EFEAFB;
    --statut-etape-texte: #5B3AA6;
    --statut-etape-bordure: #CDBEF0;
    --statut-etape-plein: #7654C8;

    /* Catégories : pour ce qui se distingue sans être un statut (cadences, canaux, référentiels) */
    --categorie-1-fond: #dbeafe; --categorie-1-texte: #1e40af;
    --categorie-2-fond: #fce7f3; --categorie-2-texte: #9d174d;
    --categorie-3-fond: #dcfce7; --categorie-3-texte: #166534;
    --categorie-4-fond: #fef3c7; --categorie-4-texte: #92400e;
    --categorie-5-fond: #ede9fe; --categorie-5-texte: #5b21b6;
    --categorie-6-fond: #cffafe; --categorie-6-texte: #155e75;
    --categorie-7-fond: #fee2e2; --categorie-7-texte: #991b1b;
    --categorie-8-fond: #e0e7ff; --categorie-8-texte: #3730a3;

    /* Typographie */
    --police-corps: 'Segoe UI Variable Text', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
    --police-mono: 'Cascadia Code', Consolas, 'Courier New', monospace;
    --taille-2xs: 11px;
    --taille-xs: 12px;
    --taille-s: 13px;
    --taille-base: 14px;
    --taille-l: 16px;
    --taille-xl: 18px;
    --taille-2xl: 22px;
    --taille-3xl: 28px;
    --graisse-normale: 400;
    --graisse-forte: 600;
    --graisse-titre: 700;
    --interligne-titre: 1.25;
    --interligne-corps: 1.5;

    /* Espacement : multiples de 4 */
    --espace-1: 4px;
    --espace-2: 8px;
    --espace-3: 12px;
    --espace-4: 16px;
    --espace-5: 20px;
    --espace-6: 24px;
    --espace-8: 32px;
    --espace-10: 40px;

    --rayon-s: 4px;
    --rayon-m: 6px;
    --rayon-l: 8px;
    --rayon-pilule: 999px;
    --ombre-1: 0 1px 3px rgba(16, 24, 40, 0.08);
    --ombre-2: 0 4px 12px rgba(16, 24, 40, 0.12);

    /* Mouvement : entrée en ease-out, sortie en ease-in, jamais plus de 300 ms */
    --duree-rapide: 100ms;
    --duree-normale: 200ms;
    --duree-lente: 300ms;
    --courbe-entree: cubic-bezier(0, 0, 0.2, 1);
    --courbe-sortie: cubic-bezier(0.4, 0, 1, 1);
}

/* Les pages publiques forcent un fond sombre sans poser data-bs-theme. */
html[data-bs-theme="dark"], .page-publique-layout {
    --bandeau-fond: var(--marque-600);
    --texte-lien: var(--marque-300);
    --focus: var(--marque-300);
    --surface-selection: color-mix(in srgb, var(--marque, #1D4E89) 30%, var(--surface-carte));
    --surface-survol: color-mix(in srgb, var(--marque, #1D4E89) 22%, var(--surface-carte));
    --statut-marque-fond: color-mix(in srgb, var(--marque, #1D4E89) 30%, var(--surface-carte));
    --statut-marque-texte: var(--marque-200);
    --statut-marque-bordure: var(--marque-600);
    --statut-marque-plein: var(--marque-300);

    --surface-page: #181B20;
    --surface-carte: #262A31;
    --surface-creuse: #2E333B;
    --texte-principal: #E8ECF1;   /* 12,1:1 */
    --texte-secondaire: #A9B3C0;  /* 6,8:1 */
    --texte-discret: #8D98A6;     /* 4,9:1 */
    --bordure: #3A404A;
    --bordure-forte: #4A515D;

    --statut-succes-plein: #34A867;
    --statut-succes-fond: color-mix(in srgb, var(--statut-succes-plein) 18%, var(--surface-carte));
    --statut-succes-texte: #86EFAC;
    --statut-succes-bordure: color-mix(in srgb, var(--statut-succes-plein) 45%, var(--surface-carte));
    --statut-attention-plein: #D98A1E;
    --statut-attention-fond: color-mix(in srgb, var(--statut-attention-plein) 18%, var(--surface-carte));
    --statut-attention-texte: #FCD34D;
    --statut-attention-bordure: color-mix(in srgb, var(--statut-attention-plein) 45%, var(--surface-carte));
    --statut-erreur-plein: #E05A5A;
    --statut-erreur-fond: color-mix(in srgb, var(--statut-erreur-plein) 18%, var(--surface-carte));
    --statut-erreur-texte: #FCA5A5;
    --statut-erreur-bordure: color-mix(in srgb, var(--statut-erreur-plein) 45%, var(--surface-carte));
    --statut-information-plein: #4C93DC;
    --statut-information-fond: color-mix(in srgb, var(--statut-information-plein) 18%, var(--surface-carte));
    --statut-information-texte: #93C5FD;
    --statut-information-bordure: color-mix(in srgb, var(--statut-information-plein) 45%, var(--surface-carte));
    --statut-neutre-plein: #8A95A5;
    --statut-neutre-fond: color-mix(in srgb, var(--statut-neutre-plein) 18%, var(--surface-carte));
    --statut-neutre-texte: #CBD5E1;
    --statut-neutre-bordure: color-mix(in srgb, var(--statut-neutre-plein) 45%, var(--surface-carte));
    --statut-etape-plein: #9475E0;
    --statut-etape-fond: color-mix(in srgb, var(--statut-etape-plein) 18%, var(--surface-carte));
    --statut-etape-texte: #C4B5FD;
    --statut-etape-bordure: color-mix(in srgb, var(--statut-etape-plein) 45%, var(--surface-carte));

    /* En sombre, la paire s'inverse : le pastel devient le texte, sur le ton foncé assourdi */
    --categorie-1-fond: color-mix(in srgb, #1e40af 45%, var(--surface-carte)); --categorie-1-texte: #dbeafe;
    --categorie-2-fond: color-mix(in srgb, #9d174d 45%, var(--surface-carte)); --categorie-2-texte: #fce7f3;
    --categorie-3-fond: color-mix(in srgb, #166534 45%, var(--surface-carte)); --categorie-3-texte: #dcfce7;
    --categorie-4-fond: color-mix(in srgb, #92400e 45%, var(--surface-carte)); --categorie-4-texte: #fef3c7;
    --categorie-5-fond: color-mix(in srgb, #5b21b6 45%, var(--surface-carte)); --categorie-5-texte: #ede9fe;
    --categorie-6-fond: color-mix(in srgb, #155e75 45%, var(--surface-carte)); --categorie-6-texte: #cffafe;
    --categorie-7-fond: color-mix(in srgb, #991b1b 45%, var(--surface-carte)); --categorie-7-texte: #fee2e2;
    --categorie-8-fond: color-mix(in srgb, #3730a3 45%, var(--surface-carte)); --categorie-8-texte: #e0e7ff;

    --ombre-1: 0 1px 3px rgba(0, 0, 0, 0.4);
    --ombre-2: 0 4px 12px rgba(0, 0, 0, 0.5);
}

/* FluentUI ne prend pas la couleur reçue telle quelle : il choisit dans sa palette une nuance
   plus claire (#486CAD pour #1D4E89), et les boutons juraient avec le bandeau. En clair, l'aplat
   d'accent est la marque elle-même, sous du texte blanc (contraste contrôlé à la saisie). En
   sombre, on garde le calcul de FluentUI : un aplat clair sous du texte foncé. Les pages
   publiques, sombres sans data-bs-theme, gardent leur accent. */
html:not([data-bs-theme="dark"]):not(:has(.page-publique-layout)) {
    --accent-fill-rest: var(--marque-500);
    --accent-fill-hover: var(--marque-600);
    --accent-fill-active: var(--marque-700);
    --accent-fill-focus: var(--marque-500);
    --foreground-on-accent-rest: #fff;
    --foreground-on-accent-hover: #fff;
    --foreground-on-accent-active: #fff;
    --foreground-on-accent-focus: #fff;
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --duree-rapide: 0ms;
        --duree-normale: 0ms;
        --duree-lente: 0ms;
    }
}

/* ========================================
   CARTE LEAFLET
   ======================================== */

.carte-marker-container {
    background: transparent !important;
    border: none !important;
}

.carte-pin {
    width: 20px;
    height: 20px;
    border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg);
    border: 2px solid white;
    box-shadow: 0 1px 4px rgba(0,0,0,.45);
}

.leaflet-popup-content a {
    color: #0078d4;
    text-decoration: none;
}
.leaflet-popup-content a:hover {
    text-decoration: underline;
}

.leaflet-container {
    isolation: isolate;
}

/* Le fond vient d'un jeton, connu dès le premier rendu : pas de flash clair en thème sombre
   pendant le chargement de FluentUI. */
html, body {
    font-family: var(--police-corps);
    background: var(--surface-page);
    margin: 0;
    padding: 0;
    overflow: hidden; /* Empêche le scroll global */
    height: var(--hauteur-ecran);
}

/* Une seule police : FluentUI lit --body-font, le HTML brut lit font-family. */
body {
    --body-font: var(--police-corps);
}

/* Bandeau d'erreur de circuit Blazor (MainLayout). Masqué au repos : blazor.web.js l'affiche
   quand le circuit tombe. Texte foncé imposé, le fond jaune clair ne suit pas le thème. */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    color: #1a1a1a;
    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;
}

/* FluentCard : en mode sombre, certaines instances (notamment TeamsFileExplorer,
   dont le contenu se charge en async) gardent un fond blanc APRÈS une bascule de
   thème au runtime. Cause : FluentUI applique les design tokens (--neutral-layer-*)
   par élément via JS au moment du rendu ; un composant qui ne re-render pas à la
   bascule conserve la valeur claire périmée (var --neutral-layer-card-container
   reste #f3f3f3 sur ces cartes). Deux conséquences pour le correctif :
   - cibler l'HÔTE fluent-card (FluentUI 4.13 n'expose PAS de ::part(control)),
   - utiliser des valeurs fixes (la var est périmée sur les cartes fautives). */
html[data-bs-theme="dark"] fluent-card {
    background-color: var(--surface-carte) !important;
    color: var(--texte-principal) !important;
}

/* Cartes : blanches sur le fond de page gris-bleu, un filet et une ombre légère. Sans
   !important : .page-publique-layout fluent-card doit rester transparent. */
fluent-card {
    background: var(--surface-carte);
    color: var(--texte-principal);
    border: 1px solid var(--bordure);
    box-shadow: var(--ombre-1);
}

/* Cartes côte à côte (ui-patterns §3). Grille CSS et non flex : fluent-card pose
   `height: var(--card-height, 100%)` dans son Shadow DOM, et un 100 % dans un conteneur flex de
   hauteur indéfinie vaut auto, donc la carte la plus courte ne s'étire pas ; dans une grille,
   l'aire de la ligne est définie et chaque carte la remplit. `--colonnes` règle la répartition
   (défaut : deux moitiés). Une colonne qui empile plusieurs cartes (`.colonne-cartes`) laisse
   sa dernière carte prendre le reste, pour que les deux colonnes finissent sur la même ligne. */
.rangee-cartes {
    display: grid;
    grid-template-columns: var(--colonnes, 1fr 1fr);
    gap: var(--espace-4);
    align-items: stretch;
    width: 100%;
}
.rangee-cartes > fluent-card,
.rangee-cartes > .colonne-cartes {
    min-width: 0;
}
.colonne-cartes {
    display: flex;
    flex-direction: column;
    gap: var(--espace-4);
}
.colonne-cartes > fluent-card {
    --card-height: auto;
}
.colonne-cartes > fluent-card:last-of-type {
    flex: 1 1 auto;
}
@media (max-width: 767.98px) {
    .rangee-cartes {
        grid-template-columns: 1fr;
    }
}

/* Régularisation d'un adhérent sans dossier : trois issues exclusives, chacune avec la phrase
   qui dit ce que l'application fera. */
.choix-regularisation {
    display: flex;
    flex-direction: column;
    gap: var(--espace-2);
    width: 100%;
}
.choix-regularisation-option {
    display: flex;
    align-items: flex-start;
    gap: var(--espace-3);
    padding: var(--espace-3);
    border: 1px solid var(--bordure);
    border-radius: 6px;
    cursor: pointer;
}
.choix-regularisation-option:has(input:checked) {
    border-color: var(--accent-fill-rest);
}
.choix-regularisation-option input[type="radio"] {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 2px 0 0;
    cursor: pointer;
    accent-color: var(--accent-fill-rest);
}
.choix-regularisation-aide {
    display: block;
    margin-top: var(--espace-1);
    font-size: var(--taille-xs);
    color: var(--texte-secondaire);
}
.choix-regularisation-champ {
    padding-left: calc(16px + var(--espace-3) + var(--espace-3));
}

/* Fiche club — Membres et Fichiers. Sur écran réduit, le tiers laissé à Membres coupait ses
   boutons : la carte prend 45 %. Les champs d'Identité suivent la même répartition, pour
   tomber à l'aplomb des deux cartes du bas. */
.club-colonnes {
    --colonnes: 1fr 2fr;
}
@media (max-width: 1599.98px) {
    .club-colonnes {
        --colonnes: 9fr 11fr;
    }
}
.club-identite {
    display: grid;
    grid-template-columns: var(--colonnes);
    gap: var(--espace-4);
    align-items: start;
    width: 100%;
}
/* La description tient sur une ligne, à la hauteur du nom, et grandit avec son texte : trois
   lignes fixes laissaient un vide sous le nom. */
.club-identite fluent-text-area::part(control) {
    field-sizing: content;
    min-height: 32px;
    /* 6 px de marge interne plus la bordure donnaient 33 px, un de plus que le champ voisin. */
    padding-block: 5px;
    resize: none;
}
/* Un sélecteur trop étroit replie son libellé et descend sous ses voisins : passé ce
   minimum, il change de rang. */
.club-roles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: var(--espace-4);
    width: 100%;
}
.club-identite > *,
.club-roles > * {
    min-width: 0;
}
@media (max-width: 767.98px) {
    .club-identite {
        grid-template-columns: 1fr;
    }
}

/* Fiche d'adhésion — carte « Adhésion » : elle ne règle que le calcul de la cotisation (effectif,
   mode, résultat). L'en-tête dit le statut et la date de première adhésion. */
.adhesion-titre-carte {
    display: flex;
    align-items: center;
    gap: var(--espace-2);
    flex-wrap: wrap;
    min-width: 0;
}
.adhesion-depuis {
    display: flex;
    align-items: center;
    gap: var(--espace-1);
    min-height: 32px;
    margin-top: calc(-1 * var(--espace-2));
    color: var(--texte-secondaire);
}
.adhesion-bloc-titre {
    font-size: var(--taille-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--texte-secondaire);
}
.adhesion-champs {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--espace-3) var(--espace-4);
    align-items: center;
}
.adhesion-libelle {
    font-weight: 600;
}
/* Libellés au-dessus des champs, un bloc par colonne. Le remplissage par colonne garde
   l'ordre libellé-champ du balisage, donc de la lecture et de l'empilement mobile. */
.adhesion-calcul {
    display: grid;
    grid-template-columns: max-content 1fr;
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    gap: var(--espace-1) var(--espace-8);
    align-items: start;
}
@media (max-width: 768px) {
    .adhesion-calcul {
        grid-template-columns: 1fr;
        grid-template-rows: none;
        grid-auto-flow: row;
    }
    .adhesion-calcul > .adhesion-libelle:not(:first-child) {
        margin-top: var(--espace-2);
    }
}
.adhesion-modes {
    display: flex;
    flex-direction: column;
    gap: var(--espace-2);
}
.adhesion-mode {
    display: flex;
    align-items: center;
    gap: var(--espace-2);
    min-height: 32px;
}
.adhesion-mode input[type="radio"] {
    width: 16px;
    height: 16px;
    margin: 0;
    cursor: pointer;
    accent-color: var(--accent-fill-rest);
}
.adhesion-mode label {
    min-width: 64px;
    font-weight: 600;
    cursor: pointer;
}
.adhesion-resultat {
    display: flex;
    align-items: center;
    gap: var(--espace-3);
    flex-wrap: wrap;
    width: 100%;
    padding-top: var(--espace-3);
    border-top: 1px solid var(--bordure);
}
/* Lien porté par un titre de page : il garde la typographie du titre. */
html .content a.titre-lien {
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
    text-decoration-color: var(--bordure-forte);
}
html .content a.titre-lien:hover,
html .content a.titre-lien:focus-visible {
    text-decoration-color: currentColor;
}

/* Même symptôme sur les boutons de la toolbar de l'explorateur Teams (fil d'Ariane,
   rafraîchir, « Ajouter un fichier ») : leur ::part(control) garde un fond blanc
   périmé après la bascule. Tous Lightweight/Stealth/Outline (aucun Accent dans la
   toolbar) → fond transparent pour révéler la carte sombre. Scopé à .teams-dropzone
   pour ne pas toucher les boutons Accent ailleurs. */
html[data-bs-theme="dark"] .teams-dropzone fluent-button::part(control) {
    background: transparent !important;
}

/* FluentDataGrid : même symptôme — header et cellules tirent un fond blanc par défaut.
   En FluentUI 4.x la grille rend un <table> : cibler th/td, pas des éléments -row/-cell
   qui n'existent pas. */
html[data-bs-theme="dark"] fluent-data-grid,
html[data-bs-theme="dark"] .fluent-data-grid td {
    background: transparent !important;
    color: var(--neutral-foreground-rest) !important;
}

/* En-tête de grille : légèrement en retrait, dans les deux thèmes. Opaque, parce qu'il est
   collant et que les lignes défilent dessous. Les boutons de tri (fluent-button stealth)
   peignent leur propre fond : transparents, sinon ils font des pavés dans l'en-tête. */
.fluent-data-grid th {
    background: var(--surface-creuse) !important;
    color: var(--texte-principal) !important;
}

.fluent-data-grid th fluent-button::part(control) {
    background: transparent;
}

.fluent-data-grid th fluent-button:hover::part(control) {
    background: var(--surface-survol);
}

/* Survol d'une ligne cliquable. Sur les cellules, pour la raison expliquée ci-dessous ; avant
   les règles de sélection, qui doivent l'emporter. Seules les lignes qui mènent quelque part
   réagissent : un survol sur une ligne inerte promettrait un clic qui n'existe pas. */
html .fluent-data-grid tbody tr.cursor-pointer:hover > td,
html .fluent-data-grid tbody tr.clickable-row:hover > td {
    background: var(--surface-survol) !important;
}

.cursor-pointer {
    cursor: pointer;
}

/* Ligne sélectionnée d'un FluentDataGrid (signalement 401).
   Deux raisons pour lesquelles un `background` posé sur `.selected-row` ne se voit pas :
   1. FluentUI met les <tr> de la grille en `display: contents` — ils ne génèrent aucune
      boîte, leur fond n'est donc JAMAIS peint, dans les deux thèmes. La mise en évidence
      doit porter sur les cellules.
   2. La règle ci-dessus force `background: transparent !important` sur toutes les cellules
      en mode sombre : il faut passer devant, d'où le `html` en tête qui porte la
      spécificité à (0,2,3).
   La sélection est une teinte de la marque, pas son aplat : le texte garde sa couleur et
   la ligne reste lisible dans les deux thèmes. */
html .fluent-data-grid tr.selected-row > td,
html .fluent-data-grid tr.selected-row:hover > td {
    background: var(--surface-selection) !important;
    color: var(--texte-principal) !important;
}

/* Les liens d'une ligne sélectionnée prennent la couleur du texte de la ligne (signalement
   393 : bleu sur bleu illisible) ; le soulignement les distingue encore. Sur la teinte de
   sélection, la couleur de lien d'une organisation à marque claire passerait sous 4,5:1.
   FluentAnchor peint son lien dans son Shadow DOM : seul ::part(control) l'atteint. */
html .fluent-data-grid tr.selected-row > td a,
html .fluent-data-grid tr.selected-row > td fluent-anchor::part(control) {
    color: var(--texte-principal) !important;
    text-decoration: underline;
}

/* ========================================
   LAYOUT PRINCIPAL FULL-VIEWPORT
   ======================================== */

/* FluentLayout : conteneur principal en flexbox vertical */
fluent-layout {
    display: flex !important;
    flex-direction: column !important;
    height: var(--hauteur-ecran) !important;
    overflow: hidden !important;
}

/* FluentHeader rend un <header class="header"> avec z-index: 10, qui en fait un contexte
   d'empilement : les fenêtres ouvertes depuis le header (signalement, information recueillie,
   menu utilisateur) ne pouvaient pas dépasser ce niveau, et une carte de page à z-index 30
   les recouvrait (signalement 415). Sans contexte propre, elles s'empilent comme les
   fenêtres des pages. */
header.header {
    flex-shrink: 0 !important;
    z-index: auto !important;
    /* FluentHeader prend l'accent, que FluentUI éclaircit en thème sombre : le bandeau virait
       au bleu clair. Il garde la couleur de marque dans les deux thèmes. */
    background: var(--bandeau-fond) !important;
    color: var(--bandeau-texte) !important;
}

/* Zone principale (nav + content) - prend l'espace restant */
.main {
    flex: 1 1 auto !important;
    min-height: 0 !important; /* Permet le shrink en flexbox */
    overflow: hidden !important;
    display: flex !important;
    width: 100%;
}

/* Menu latéral - hauteur auto dans le conteneur flex (visible en flux à partir de 1200px) */
@media (min-width: 1200px) {
    .nav-sidebar {
        height: 100%;
        overflow-y: auto;
        flex-shrink: 0;
        transition: width 0.2s ease;
    }
}

/* Contenu principal - scrolle en interne, se redéploie quand le menu collapse */
.main > fluent-body-content,
.main > .main-content {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    min-width: 0 !important;
    overflow-y: auto !important;
    width: 0 !important;
}

/* Footer - reste fixe en bas */
fluent-footer {
    flex-shrink: 0 !important;
}

a, .btn-link {
    color: var(--texte-lien);
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
    padding-left: 20px;
    padding-right: 20px;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

/* Header des pages de liste */
.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    max-width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
    overflow: hidden;
}

.page-header > .stack-horizontal,
.page-header > .stackhorizontal {
    justify-content: flex-end !important;
}

/* FluentStack se donne width:100% : placé à côté du titre, il lui prenait toute la largeur
   et « Tableau de bord » passait sur deux lignes. Le titre tient sur une ligne et se tronque
   s'il est trop long. .actions-entete-card garde sa propre règle (ci-dessous). */
.page-header > .stack-horizontal:not(.actions-entete-card) {
    width: auto !important;
}

.page-header > .fluent-typography[typo='page-title'] {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 767.98px) {
    .page-header > .fluent-typography[typo='page-title'] {
        white-space: normal;
    }
}

/* Titres : la hiérarchie tient à la graisse, pas à une couleur. « html .content » porte la
   spécificité au-dessus de la règle de FluentUI (classe + attribut + portée), chargée après. */
html .content .fluent-typography[typo='page-title'] {
    font-size: var(--taille-3xl);
    font-weight: var(--graisse-forte);
    line-height: var(--interligne-titre);
    color: var(--texte-principal);
}

.content fluent-card .fluent-typography[typo='subject'] {
    font-weight: var(--graisse-forte);
    color: var(--texte-principal);
}

/* Groupe de boutons a droite du titre d'une card. Trois pieges se cumulaient sur la fiche
   adhesion (ORANGE, trois boutons) :
   - width:100% sur un second enfant flex reclame toute la largeur du parent en partant
     d'apres le titre, donc deborde mecaniquement de la largeur du titre -> flex:1 + min-width:0 ;
   - un fluent-button compresse ne tronque pas son libelle (nowrap dans le shadow DOM) :
     le texte sort du bouton et s'ecrit par-dessus le voisin -> flex-shrink:0 ;
   - .page-header a overflow:hidden, donc ce qui depasse disparait sans le moindre indice.
   Avec Wrap="true" cote composant, les boutons passent a la ligne au lieu de se chevaucher. */
.actions-entete-card {
    flex: 1 1 auto;
    min-width: 0;
}

.actions-entete-card > fluent-button {
    flex: 0 0 auto;
}

/* Dans une FluentCard, le padding horizontal du .page-header desaligne le titre
   par rapport au contenu et aux titres des cards sans bouton (Identite, Contact).
   La card fournit deja son padding : on neutralise celui du header. */
fluent-card .page-header {
    padding-left: 0;
    padding-right: 0;
}

fluent-body-content {
    flex: 1 1 0 !important;
    width: 0 !important;
    max-width: 100% !important;
    padding-right: 20px;
}

fluent-body-content > * {
    width: 100% !important;
    max-width: 100% !important;
}

/* Force FluentStack dans main-content à prendre toute la largeur */
.main-content {
    flex: 1 1 0 !important;
    width: 0 !important;
    max-width: 100% !important;
    min-width: 0; /* Permet le shrink en flexbox */
}

.main-content fluent-stack,
.main-content > fluent-stack {
    width: 100% !important;
    max-width: 100% !important;
}

/* Page d'accueil */
.home-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: calc(var(--hauteur-ecran) - 200px);
    padding: 40px 20px;
    text-align: center;
    box-sizing: border-box;
}

.home-logo {
    height: 140px;
    width: auto;
    margin-bottom: 24px;
}

.home-title {
    font-size: 28px;
    font-weight: 600;
    color: var(--neutral-foreground-rest);
    margin: 0;
}

.home-subtitle {
    font-size: 18px;
    color: var(--neutral-foreground-hint);
    margin: 4px 0 0 0;
}

.home-description {
    max-width: 520px;
    margin: 24px 0;
    color: var(--neutral-foreground-rest);
    font-size: 15px;
    line-height: 1.6;
}

.home-features {
    display: flex;
    gap: 24px;
    margin-top: 12px;
    flex-wrap: wrap;
    justify-content: center;
}

.home-feature {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 20px 24px;
    border-radius: 8px;
    background: var(--neutral-layer-card-container);
    border: 1px solid var(--neutral-stroke-divider-rest);
    min-width: 200px;
    max-width: 240px;
}

.home-feature strong {
    font-size: 15px;
    color: var(--accent-fill-rest);
}

.home-feature span {
    font-size: 13px;
    color: var(--neutral-foreground-hint);
    line-height: 1.4;
}

/* Footer version */
.app-footer-version {
    font-size: 12px !important;
    font-family: 'Cascadia Code', 'Consolas', 'Courier New', monospace;
    opacity: 0.6;
    cursor: pointer;
}

a.app-footer-version:hover {
    opacity: 1;
    text-decoration: underline !important;
}

/* Bouton Nouveautés dans le header */
.changelog-badge-link {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    width: 42px;
    height: 42px;
    border-radius: 6px;
    text-decoration: none;
    color: inherit;
    opacity: 0.85;
    transition: opacity 0.15s, background 0.15s;
}

.changelog-badge-link:hover {
    opacity: 1;
    background: var(--bandeau-survol);
}

.changelog-badge-dot {
    position: absolute;
    top: 4px;
    right: 4px;
    background: #ef4444;
    color: white;
    font-size: 9px;
    font-weight: 700;
    padding: 1px 4px;
    border-radius: 8px;
    line-height: 1.5;
    letter-spacing: 0.03em;
    pointer-events: none;
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

/* Footer */
.footer {
    margin-top: auto;
}

.app-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    width: 100%;
    padding: 8px 0;
}

.app-footer span {
    color: var(--neutral-foreground-hint);
    font-size: 15px;
}

.app-footer-logo {
    height: 66px;
    width: auto;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Stepper workflow campagne */
.workflow-stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    padding: 16px 24px 32px;
    width: 100%;
}
.workflow-step {
    display: flex;
    align-items: center;
    gap: 0;
    flex: 1;
    position: relative;
}
.workflow-step:last-child {
    flex: 0;
}
.workflow-step-circle {
    width: 32px;
    height: 32px;
    min-width: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 600;
    z-index: 1;
    border: 2px solid var(--neutral-stroke-rest);
    background: var(--neutral-layer-1);
    color: var(--neutral-foreground-hint);
}
.workflow-step-circle.done {
    background: var(--accent-fill-rest);
    border-color: var(--accent-fill-rest);
    color: white;
}
.workflow-step-circle.active {
    border-color: var(--accent-fill-rest);
    color: var(--accent-fill-rest);
    background: var(--neutral-layer-1);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-fill-rest) 25%, transparent);
}
.workflow-step-circle.scheduled {
    border-color: #22c55e;
    color: #22c55e;
    background: var(--neutral-layer-1);
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.2);
}
.workflow-step-circle.rejected {
    border-color: #ef4444;
    color: #ef4444;
    background: var(--neutral-layer-1);
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2);
}
.workflow-step-label {
    position: absolute;
    top: 38px;
    left: 16px;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 0.7rem;
    color: var(--neutral-foreground-hint);
}
.workflow-step-label.active,
.workflow-step-label.done {
    color: var(--neutral-foreground-rest);
    font-weight: 600;
}
.workflow-step-label.scheduled {
    color: #22c55e;
    font-weight: 600;
}
.workflow-step-date {
    position: absolute;
    top: 52px;
    left: 16px;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 0.65rem;
    color: #22c55e;
    font-weight: 600;
}
.workflow-step-label.rejected {
    color: #ef4444;
    font-weight: 600;
}
.workflow-step-line {
    flex: 1;
    height: 2px;
    background: var(--neutral-stroke-rest);
    margin: 0 4px;
}
.workflow-step-line.done {
    background: var(--accent-fill-rest);
}

/* Bouton Soumettre sur le stepper */
.workflow-submit-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 14px;
    border: none;
    border-radius: 4px;
    background: var(--accent-fill-rest);
    color: white;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s;
}
.workflow-submit-btn:hover {
    background: var(--accent-fill-hover);
}
.workflow-submit-btn:active {
    background: var(--accent-fill-active);
}
.workflow-submit-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.workflow-reject-btn {
    background: #ef4444;
}
.workflow-reject-btn:hover {
    background: #dc2626;
}
.workflow-reject-btn:active {
    background: #b91c1c;
}
.workflow-neutral-btn {
    background: #6b7280;
}
.workflow-neutral-btn:hover {
    background: #4b5563;
}
.workflow-neutral-btn:active {
    background: #374151;
}
.workflow-archive-btn {
    background: #92400e;
}
.workflow-archive-btn:hover {
    background: #78350f;
}
.workflow-archive-btn:active {
    background: #451a03;
}

/* Lignes cliquables dans les grilles */
.clickable-row {
    cursor: pointer;
}
.clickable-row:hover {
    background-color: var(--neutral-layer-2);
}

/* Désinscriptions déjà consultées : visuellement atténuées */
.desinscription-traitee {
    color: var(--neutral-foreground-hint);
    background-color: var(--neutral-layer-1);
}
.desinscription-traitee td {
    opacity: 0.72;
}
.desinscription-traitee:hover {
    opacity: 1;
    background-color: var(--neutral-layer-2);
}

/* Menu contextuel pour images (clic droit sur vignette bibliothèque) */
.image-context-menu {
    min-width: 240px;
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
    padding: 4px 0;
    font-size: 13px;
}
.image-context-menu-header {
    padding: 6px 12px 8px;
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    border-bottom: 1px solid var(--neutral-stroke-rest);
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 320px;
}
.image-context-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 12px;
    border: none;
    background: transparent;
    text-align: left;
    cursor: pointer;
    color: var(--neutral-foreground-rest);
    font-size: 13px;
    font-family: inherit;
}
.image-context-menu-item:hover {
    background-color: var(--neutral-layer-3);
}
.image-context-menu-separator {
    height: 1px;
    background: var(--neutral-stroke-rest);
    margin: 4px 0;
}

/* Bibliotheque d'images : bascule d'affichage des templates utilisateurs */
.image-usages-toggle {
    cursor: pointer;
    color: var(--accent-fill-rest);
    font-weight: 600;
    white-space: nowrap;
}

/* ============================================================
   Bibliotheque d'images : rail des templates (categorie > template)
   Rail (240px) pose par l'emplacement Rail de ListePage, meme metrique
   que le rail des evenements. Cache en dessous de 1200px, ou le select
   de repli au-dessus de la grille prend le relais.
   ============================================================ */
.images-sidebar {
    flex: 0 0 240px;
    max-width: 240px;
    background: var(--neutral-layer-2);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    padding: 8px 6px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 13px;
}

.images-sidebar-loading {
    display: flex;
    justify-content: center;
    padding: 20px 0;
}

.images-sidebar-section {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.images-sidebar-separator {
    height: 1px;
    background: var(--neutral-stroke-rest);
    margin: 6px 4px;
}

.images-sidebar-node,
.images-sidebar-node-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    /* sans min-width:0 le bouton refuse de passer sous la largeur de son libelle
       et pousse le compteur hors de la ligne (categories a nom long) */
    min-width: 0;
    padding: 6px 8px;
    border: none;
    background: transparent;
    border-radius: 4px;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font-size: inherit;
    font-family: inherit;
}

.images-sidebar-node:hover,
.images-sidebar-node-inline:hover {
    background: var(--neutral-fill-hover);
}

.images-sidebar-node.active,
.images-sidebar-categorie-row.active {
    background: var(--accent-fill-rest);
    color: white;
}

.images-sidebar-node.active .images-sidebar-count,
.images-sidebar-categorie-row.active .images-sidebar-count {
    background: rgba(255, 255, 255, 0.25);
    color: white;
}

.images-sidebar-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Le compteur ne se laisse jamais comprimer par un libelle long */
.images-sidebar-count {
    flex: 0 0 auto;
    background: var(--neutral-fill-rest);
    color: var(--neutral-foreground-hint);
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 11px;
    min-width: 22px;
    text-align: center;
}

.images-sidebar-categorie {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.images-sidebar-categorie-row {
    display: flex;
    align-items: center;
    border-radius: 4px;
    overflow: hidden;
}

.images-sidebar-categorie-row:hover {
    background: var(--neutral-fill-hover);
}

.images-sidebar-categorie-row.active:hover {
    background: var(--accent-fill-hover);
}

.images-sidebar-chevron {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 4px 2px 4px 6px;
    display: flex;
    align-items: center;
    color: inherit;
}

.images-sidebar-templates {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding-left: 22px;
}

.images-sidebar-node-template {
    padding: 4px 8px;
    font-size: 12.5px;
}

/* Le rail porte le filtre : le select de repli ne sert que sur petit ecran */
.images-filtre-repli { display: none; }

@media (max-width: 1199.98px) {
    .images-sidebar { display: none; }
    .images-filtre-repli { display: block; }
    .images-filtre-actif { display: none; }
}

/* Bibliotheque d'images : popup listant les templates utilisant un fichier.
   Hors de la grille : la hauteur d'une ligne FluentDataGrid est fixe et rognerait la liste. */
.image-usages-popup {
    display: flex;
    flex-direction: column;
    min-width: 220px;
    max-width: 380px;
    overflow-y: auto;
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
    padding: 4px 0;
    font-size: 13px;
}
.image-usages-popup-header {
    padding: 6px 12px 8px;
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    border-bottom: 1px solid var(--neutral-stroke-rest);
    margin-bottom: 4px;
}
.image-usages-popup-item {
    padding: 4px 12px;
    line-height: 1.4;
}
.image-usages-popup-item:hover {
    background-color: var(--neutral-layer-3);
}

/* TeamsFileExplorer : menu actions fichier */
.file-action-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
    cursor: pointer;
    font-size: 14px;
    color: var(--neutral-foreground-rest);
    transition: background-color 0.1s ease;
}
.file-action-item:hover {
    background-color: var(--neutral-fill-stealth-hover);
}
.file-action-danger {
    color: var(--error);
}

/* Upload dialog : zone de drop */
.upload-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 32px 16px;
    border: 2px dashed var(--neutral-stroke-rest);
    border-radius: 8px;
    background: var(--neutral-layer-2);
    transition: border-color 0.2s ease, background-color 0.2s ease;
    cursor: default;
}
.upload-dropzone-active,
.upload-dropzone:hover {
    border-color: var(--accent-fill-rest);
    background: rgba(0, 120, 212, 0.04);
}
.upload-dropzone-browse {
    display: inline-block;
    padding: 4px 16px;
    border: 1px solid var(--accent-fill-rest);
    border-radius: 4px;
    color: var(--accent-fill-rest);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s ease;
}
.upload-dropzone-browse:hover {
    background: rgba(0, 120, 212, 0.08);
}

/* Drop zone drag & drop feedback (grille principale) */
.teams-dropzone {
    position: relative;
    transition: border-color 0.2s ease;
}
.teams-dropzone.drop-active::after {
    content: 'Déposer les fichiers ici';
    position: absolute;
    inset: 0;
    background: rgba(0, 120, 212, 0.08);
    border: 2px dashed var(--accent-fill-rest);
    border-radius: 8px;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 600;
    color: var(--accent-fill-rest);
    pointer-events: none;
}

/* Grid rôles : cellules auto-height pour badges multi-lignes */
.roles-grid-autoheight td {
    height: auto !important;
    min-height: 32px;
    overflow: visible !important;
}

/* Coloration rôles actifs/terminés */
.role-actif {
    background-color: #E8F5E9 !important;
}
.role-actif:hover {
    background-color: #C8E6C9 !important;
}
.role-termine {
    background-color: #FFEBEE !important;
}
.role-termine:hover {
    background-color: #FFCDD2 !important;
}

/* Panneaux "Organisations" (fiche PP) — fusion rôle + coordonnées + adresse */
.org-panel {
    border: 1px solid #e1dfdd;
    border-radius: 7px;
    overflow: hidden;
    background: #ffffff;
}
.org-panel + .org-panel { margin-top: 10px; }
.org-panel.principal {
    border-color: #d9b40b;
    box-shadow: 0 0 0 1px #d9b40b inset;
}
.org-panel-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px 12px;
    background: #E8F5E9;
    border-bottom: 1px solid #edebe9;
}
.org-panel.terminated .org-panel-head { background: #FFEBEE; }
.org-panel:hover .org-panel-head { filter: brightness(0.98); }
.org-panel-name {
    min-width: 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.org-panel-body {
    display: grid;
    grid-template-columns: 1fr 1fr;
}
.org-panel-body > div { padding: 9px 12px; min-width: 0; }
.org-panel-body > div:first-child { border-right: 1px solid #edebe9; }
.op-label {
    font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: #8a8886; margin-bottom: 3px;
}
.op-line { font-size: 13px; margin: 1px 0; word-break: break-word; }
.op-pill {
    display: inline-block; font-size: 11.5px; font-weight: 600;
    color: #605e5c; background: #edebe9; border-radius: 10px; padding: 1px 9px; white-space: nowrap;
}
.op-pill.pos { color: #005a9e; background: #deecf9; }
@media (max-width: 768px) {
    .org-panel-body { grid-template-columns: 1fr; }
    .org-panel-body > div:first-child { border-right: none; border-bottom: 1px solid #edebe9; }
}

/* Éviter la troncature des textes dans les sous-menus (toujours appliqué) */
fluent-nav-link::part(content),
fluent-nav-group::part(content) {
    overflow: visible;
    text-overflow: unset;
    white-space: normal;
}

/* Mode compact uniquement — font-size réduit */
.nav-menu-compact fluent-nav-link,
.nav-menu-compact fluent-nav-group {
    font-size: 0.875rem;
}
.nav-menu-compact fluent-nav-group::part(content) {
    font-size: 0.875rem;
}

/* Styles responsive pour les pages d'édition */

/* Header des pages d'édition - empile verticalement sur mobile */
.edit-page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    gap: 16px;
    flex-wrap: wrap;
}

@media (max-width: 768px) {
    .edit-page-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .edit-page-header > * {
        width: 100%;
    }

    .page-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
        padding: 0 12px;
    }
}

/* ResponsiveActions : barre de boutons (desktop) ou menu deroulant (<1024px) */
.responsive-actions {
    display: contents;
}

.responsive-actions-bar {
    display: flex;
    flex-direction: row;
    gap: 10px;
    flex-wrap: nowrap;
    align-items: center;
}

.responsive-actions-toggle {
    display: none !important;
}

@media (max-width: 1023.98px) {
    .responsive-actions-bar {
        display: none;
    }

    .responsive-actions-toggle {
        display: inline-flex !important;
        margin-left: auto;
    }
}

@media (max-width: 768px) {
    .responsive-actions-toggle {
        align-self: flex-end;
    }
}

/* Groupe de champs responsive */
.responsive-field-group {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    width: 100%;
    align-items: end;
}

.responsive-field-group > * {
    min-width: 0;
}

@media (max-width: 768px) {
    .responsive-field-group {
        grid-template-columns: 1fr;
    }
}

/* Champs en ligne (ui-patterns §2). Les champs Fluent sont des inline-block : en ligne, ils gardaient
   sous eux l'espace de descente du texte (4 px), que la liste déroulante n'a pas. Toute rangée
   alignée par le bas décalait ainsi le champ texte de 4 px au-dessus de ses voisins. */
fluent-text-field,
fluent-number-field,
fluent-search,
fluent-text-area {
    vertical-align: top;
}

/* Lignes répétées (critères, lignes de saisie) : grille CSS et non flex, pour que les colonnes
   tombent l'une sous l'autre d'une ligne à l'autre (flex: 1 répartit selon le contenu de chaque
   cellule). Le gabarit vient de --colonnes-lignes, le même sur l'en-tête et sur chaque ligne ;
   les intitulés forment une ligne à part, les contrôles n'ont pas de Label et se centrent
   (ui-patterns §2). Sous 768 px, une cellule par ligne et l'en-tête disparaît. */
.lignes-repetees {
    display: grid;
    grid-template-columns: var(--colonnes-lignes, repeat(4, minmax(0, 1fr)) 32px);
    gap: var(--espace-2);
    align-items: center;
    width: 100%;
}
.lignes-repetees > * {
    min-width: 0;
}
/* FluentSelect impose min-width: 250px à son hôte : dans une cellule plus étroite il débordait
   sur la colonne voisine. La largeur vient de la cellule. */
.lignes-repetees fluent-select {
    min-width: 0;
}
.lignes-repetees-entete {
    font-size: var(--taille-base);
    color: var(--texte-principal);
}
@media (max-width: 767.98px) {
    .lignes-repetees {
        grid-template-columns: 1fr;
    }
    .lignes-repetees-entete {
        display: none;
    }
}

/* Page édition mandat : 2 colonnes (formulaire + dossier Teams de l'organisme).
   Repli en 1 colonne sous le palier laptop étroit ; rien n'est dégradé au-delà. */
.mandat-edit-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 760px);
    gap: 16px;
    width: 100%;
    align-items: start;
}

.mandat-edit-main {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
}

.mandat-edit-side {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

@media (max-width: 1599.98px) {
    .mandat-edit-layout {
        grid-template-columns: 1fr;
    }
}

/* Variant 2-1-1 pour ligne avec un champ principal large + 2 secondaires
   (ex: Entreprise/Ville/SIRET, Contact/Téléphone/Email).
   Bascule en 1 colonne en mobile (cf règle ci-dessus). */
.responsive-field-group.entreprise-row,
.responsive-field-group.contact-row {
    grid-template-columns: 2fr 1fr 1fr;
}

@media (max-width: 768px) {
    .responsive-field-group.entreprise-row,
    .responsive-field-group.contact-row {
        grid-template-columns: 1fr;
    }
}

/* Groupe de checkboxes responsive */
.responsive-checkbox-group {
    display: flex;
    gap: 24px;
    width: 100%;
    align-items: flex-end;
    flex-wrap: wrap;
}

.responsive-checkbox-group > fluent-checkbox,
.responsive-checkbox-group > .checkbox-item {
    flex: 0 0 auto;
    margin-bottom: 8px;
}

.responsive-checkbox-group > fluent-date-picker,
.responsive-checkbox-group > .date-item {
    flex: 1 1 180px;
    min-width: 0;
}

@media (max-width: 768px) {
    .responsive-checkbox-group {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    .responsive-checkbox-group > fluent-date-picker,
    .responsive-checkbox-group > .date-item {
        width: 100%;
    }
}

/* Groupe de 4 champs - style de base */
.responsive-field-group-4col {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}

.responsive-field-group-4col > * {
    min-width: 0;
}

.responsive-field-group > * {
    min-width: 0;
}

/* Forcer display: block sur les composants FluentUI dans les grilles */
/* Par défaut FluentUI utilise display: contents qui casse le layout */
.responsive-field-group fluent-text-field,
.responsive-field-group fluent-number-field,
.responsive-field-group fluent-select,
.responsive-field-group fluent-combobox,
.responsive-field-group fluent-autocomplete,
.responsive-field-group-4col fluent-text-field,
.responsive-field-group-4col fluent-number-field,
.responsive-field-group-4col fluent-select,
.responsive-field-group-4col fluent-combobox,
.responsive-field-group-4col fluent-autocomplete {
    display: block !important;
}

@media (max-width: 1024px) {
    .responsive-field-group-4col {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .responsive-field-group-4col {
        grid-template-columns: 1fr;
    }
}

/* Champ forfaitaire : supprimer le liseré, aligner à droite */
/* Montant du forfait : un champ ordinaire, chiffres alignés à droite. */
fluent-text-field#forfait-montant::part(control) {
    text-align: right;
}

/* Réduire l'espacement entre labels et champs FluentUI */
fluent-text-field::part(label),
fluent-number-field::part(label),
fluent-select::part(label),
fluent-combobox::part(label) {
    margin-bottom: 4px;
}

/* ========================================
   RESPONSIVE MOBILE (< 768px)
   ======================================== */

/* Bouton hamburger - visible uniquement sur mobile */
.mobile-menu-toggle {
    display: none;
    background: none;
    border: none;
    color: var(--bandeau-texte);
    cursor: pointer;
    padding: 8px;
    margin-right: 8px;
}

/* Le menu général se replie en hamburger sous 1200px (libère la largeur du contenu) */
@media (max-width: 1199.98px) {
    .mobile-menu-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
    }
}

/* Navigation — le sidebar s'adapte à la largeur du FluentNavMenu */
.nav-sidebar {
    transition: transform 0.3s ease, width 0.3s ease;
    width: fit-content;
    background: var(--surface-carte);
    border-right: 1px solid var(--bordure);
}

/* Menu : un panneau uni au lieu d'une pile de pavés (FluentUI peint chaque entrée). L'entrée
   de la page courante porte la teinte de sélection, en plus du trait d'accent de FluentUI. */
.nav-sidebar .positioning-region {
    background: transparent;
    transition: background var(--duree-rapide) var(--courbe-entree);
}

.nav-sidebar .fluent-nav-link:hover .positioning-region,
.nav-sidebar .fluent-nav-group > .positioning-region:hover {
    background: var(--surface-survol);
}

.nav-sidebar a.fluent-nav-link.active .positioning-region {
    background: var(--surface-selection);
    color: var(--texte-lien);
    font-weight: var(--graisse-forte);
}

@media (max-width: 1199.98px) {
    /* Menu masqué par défaut : hamburger + overlay (mobile ET laptop < 1200px) */
    .nav-sidebar {
        position: fixed;
        left: 0;
        top: 50px;
        height: calc(var(--hauteur-ecran) - 50px);
        z-index: 1000;
        background: var(--surface-carte);
        box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
        transform: translateX(-100%);
    }

    .nav-sidebar.mobile-open {
        transform: translateX(0);
    }

    /* Overlay pour fermer le menu */
    .nav-overlay {
        display: none;
        position: fixed;
        top: 50px;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 999;
    }

    .nav-overlay.visible {
        display: block;
    }

    /* Contenu principal prend toute la largeur */
    .main-content {
        width: 100% !important;
        margin-left: 0 !important;
    }
}

/* À partir de 1200px, le menu reste déployé en permanence (pas d'overlay) */
@media (min-width: 1200px) {
    .nav-overlay {
        display: none !important;
    }
}

/* Titre d'en-tête : version courte sur petit écran (bascule inchangée à 768px) */
/* Le titre ne doit jamais passer à la ligne : la hauteur du bandeau est fixe, une 2e ligne
   sort du cadre. */
.header-title {
    white-space: nowrap;
}

/* La bascule se fait à 1024px et non 768 : entre les deux, le titre long cohabite avec la date
   et les badges: il ne rentre plus et débordait du bandeau. */
@media (max-width: 1024px) {
    .header-title {
        font-size: 14px !important;
    }

    .header-title-full {
        display: none;
    }

    .header-title-short {
        display: inline;
    }
}

@media (min-width: 1025px) {
    .header-title-full {
        display: inline;
    }

    .header-title-short {
        display: none;
    }
}

/* Table responsive - scroll horizontal */
.table-responsive {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

@media (max-width: 768px) {
    .table-responsive fluent-data-grid {
        min-width: 600px;
    }
}

/* Cards responsive */
@media (max-width: 768px) {
    fluent-card {
        padding: 12px !important;
    }

    /* Boutons d'action en bas - stack vertical */
    .action-buttons-row {
        flex-direction: column !important;
        gap: 8px !important;
    }

    .action-buttons-row > * {
        width: 100%;
    }

    /* FluentGrid items - force full width */
    fluent-grid-item {
        width: 100% !important;
    }
}

/* Header de page responsive */
@media (max-width: 768px) {
    .edit-page-header {
        padding: 0 8px;
    }

    .edit-page-header fluent-button {
        font-size: 12px;
        padding: 6px 10px;
    }
}

/* Dialog rôle: plus large pour Position|Fonction côte à côte */
fluent-dialog.dialog-role::part(control) {
    width: min(850px, 95vw) !important;
    max-width: 850px !important;
    max-height: 95vh !important;
    padding: 16px 24px !important;
}

fluent-dialog.dialog-role .fluent-dialog-header {
    padding-bottom: 12px !important;
}

fluent-dialog.dialog-role .fluent-dialog-footer {
    padding-top: 12px !important;
}

fluent-dialog.dialog-role .fluent-dialog-body {
    overflow-y: visible !important;
}

/* Dialogs standard: max-height et scroll interne */
fluent-dialog:not(.dialog-large)::part(control) {
    max-height: 95vh !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: visible !important;
}

fluent-dialog:not(.dialog-large) .fluent-dialog-body {
    overflow-y: auto !important;
    flex: 1 !important;
    min-height: 0 !important;
}

/* Dialog avec dropdown/select : overflow visible pour que le popup dépasse */
fluent-dialog.dialog-dropdown .fluent-dialog-body {
    overflow: visible !important;
}

/* Fiche d'une image de la bibliothèque : aperçu et cinq actions sur une ligne */
fluent-dialog.dialog-fiche-image::part(control) {
    width: min(760px, 95vw) !important;
    max-width: 95vw !important;
}
fluent-dialog.dialog-fiche-image .fluent-dialog-footer {
    flex-wrap: wrap;
    gap: var(--espace-2);
}
/* Dialog large: largeur adaptée et scroll interne */
fluent-dialog.dialog-large::part(control) {
    width: min(1100px, 95vw) !important;
    max-width: 95vw !important;
    max-height: 85vh !important;
    overflow: hidden !important;
    display: flex !important;
    flex-direction: column !important;
}

fluent-dialog.dialog-large .fluent-dialog-body {
    overflow-y: auto !important;
    flex: 1 !important;
    min-height: 0 !important;
}

/* Dialog Teams Documents: grande taille fixe pour l'explorateur de fichiers
   (dialog Documents Teams sur événement, Pièces jointes Teams sur campagne).
   Cible ::part(control) — le Style inline sur <FluentDialog> ne suffit pas car
   il s'applique au host fluent-dialog, pas au panel interne. */
fluent-dialog.dialog-teams-documents::part(control) {
    width: min(1280px, 95vw) !important;
    max-width: 95vw !important;
    height: min(800px, 92vh) !important;
    max-height: 92vh !important;
    overflow: hidden !important;
    display: flex !important;
    flex-direction: column !important;
}

fluent-dialog.dialog-teams-documents .fluent-dialog-body {
    overflow-y: auto !important;
    flex: 1 !important;
    min-height: 0 !important;
}

/* Dialog Question Formulaire : largeur intermédiaire pour faciliter la saisie
   de descriptions multi-lignes (cf. memory FluentDialog width).*/
fluent-dialog.dialog-question-formulaire::part(control) {
    width: min(880px, 95vw) !important;
    max-width: 95vw !important;
    max-height: calc(var(--hauteur-ecran) * 0.9) !important;
    overflow: hidden !important;
    display: flex !important;
    flex-direction: column !important;
}

fluent-dialog.dialog-question-formulaire .fluent-dialog-body {
    overflow-y: auto !important;
    flex: 1 !important;
    min-height: 0 !important;
}

/* Fix: DatePicker/TimePicker popups coupés dans les FluentTabs */
fluent-tab-panel {
    overflow: visible !important;
}

fluent-tabs {
    overflow: visible !important;
}

/* Dialogs responsive */
@media (max-width: 768px) {
    fluent-dialog {
        min-width: auto !important;
        width: 95vw !important;
        max-width: 95vw !important;
        margin: 0 auto;
    }

    /* La largeur posée sur l'hôte ne descend pas dans le panneau interne (voir dialog-teams-documents) :
       sans cette règle le panneau prenait 100vw, collé aux bords de l'écran. */
    fluent-dialog::part(control) {
        width: 95vw !important;
        max-width: 95vw !important;
        max-height: calc(var(--hauteur-ecran) * 0.9) !important;
        display: flex !important;
        flex-direction: column !important;
        overflow: hidden !important;
    }

    fluent-dialog .fluent-dialog-body {
        max-height: calc(var(--hauteur-ecran) * 0.9 - 120px) !important;
        overflow-y: auto !important;
        flex: 1 !important;
        min-height: 0 !important;
    }

    fluent-dialog .fluent-dialog-footer {
        flex-shrink: 0 !important;
    }

    /* Exception responsive pour dialogs avec dropdown */
    fluent-dialog.dialog-dropdown::part(control) {
        overflow: visible !important;
    }

    fluent-dialog.dialog-dropdown .fluent-dialog-body {
        overflow: visible !important;
        max-height: none !important;
    }
}

/* ========================================
   OPTIMISATION GRANDS ECRANS (4K)
   ======================================== */

/* Base styles for edit forms - mobile first */
.edit-form-4k {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    max-width: 100%;
    padding: 4px; /* Espace pour les ombres des cards */
}

.edit-form-column {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
}

.edit-form-4k-full {
    width: 100%;
}

/* Medium screens (≥1024px) */
@media (min-width: 1024px) {
    .edit-form-4k {
        display: grid;
        grid-template-columns: 3fr 2fr;
        gap: 12px;
        align-items: start;
        max-width: 100%;
    }

    .edit-form-4k-full {
        grid-column: span 2;
    }
}

/* Large screens (≥1400px) */
@media (min-width: 1400px) {
    /* Layout en colonnes pour les formulaires d'edition */
    .edit-form-4k {
        display: grid;
        grid-template-columns: 3fr 2fr;
        gap: 12px;
        align-items: start;
        max-width: 100%;
    }

    .edit-form-column {
        display: flex;
        flex-direction: column;
        gap: 12px;
    }

    .edit-form-4k-full {
        grid-column: span 2;
    }

    /* Champs en 3 colonnes sur grands ecrans */
    .responsive-field-group-3col {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 16px;
    }
}

/* ========================================
   EditReunion — Fiche en bandes pleine largeur
   Les deux colonnes précédentes laissaient un grand vide à gauche : la carte réunion,
   courte par nature, était étirée à la hauteur de la carte communication.
   ======================================== */
.reunion-meta-chips {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
    align-items: center;
    color: var(--neutral-foreground-hint);
}

.reunion-meta-chips a {
    color: var(--accent-fill-rest);
    text-decoration: none;
}

.reunion-meta-chips a:hover {
    text-decoration: underline;
}

/* Modèle de contenu à gauche, bloc de rappel à droite ; empilés proprement en étroit. */
/* flex-start et non flex-end : le bloc des absents porte une ligne de plus (« personne à qui
   écrire »), et un alignement par le bas faisait remonter tout son contenu — les deux
   sélecteurs de modèle ne tombaient plus sur la même ligne (signalement 402). */
.reunion-controls-row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 24px;
    align-items: flex-start;
    justify-content: space-between;
}

/* Base assez large pour que le bloc de rappel garde son modèle et son bouton lisibles ;
   en dessous les deux blocs s'empilent au lieu de se serrer. */
.reunion-controls-row > * {
    flex: 1 1 340px;
    min-width: 0;
}

/* Texte d'aide au-dessus d'un sélecteur de modèle. La hauteur est réservée pour deux lignes :
   sans elle, un bloc dont l'aide tient sur une seule ligne remonte son sélecteur, et les deux
   listes déroulantes de la paire ne tombent plus au même niveau (signalement 402). */
.reunion-bloc-aide {
    display: block;
    font-style: italic;
    color: var(--neutral-foreground-rest);
    /* Exactement deux lignes. `lh` suit la densité d'affichage, qui change la taille de police ;
       la valeur en `em` juste au-dessus sert de repli aux navigateurs qui ignorent `lh`. */
    min-height: 2.9em;
    min-height: 2lh;
    margin-bottom: 8px;
}

/* Compteurs RSVP : cliquables, ils filtrent la liste des participants sous eux. */
.rsvp-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 8px 4px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: none;
    font: inherit;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.rsvp-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    background: var(--neutral-layer-1);
}

.rsvp-tile:focus-visible {
    outline: 2px solid var(--accent-fill-rest);
    outline-offset: 2px;
}

.rsvp-tile--active {
    border-color: var(--accent-fill-rest);
    background: var(--neutral-layer-1);
}

/* Un dossier Teams fourni ne doit pas repousser la liste des participants hors de l'écran. */
.pj-selector-body {
    max-height: 300px;
    overflow-y: auto;
}


/* ========================================
   RESPONSIVE MOBILE — Colonnes secondaires DataGrid
   ========================================
   Sprint 1 mobile : masquer les colonnes secondaires des FluentDataGrid
   sur smartphones (<768px) pour conserver une lisibilité acceptable.

   Usage :
     1. Ajouter Class="col-hide-mobile" sur les PropertyColumn/TemplateColumn secondaires
     2. Ajouter Class="<page>-grid" sur le FluentDataGrid
     3. Définir l'override grid-template-columns mobile ci-dessous

   Note : le mode sélection (col-select) ajoute une colonne checkbox en début ; les gabarits
   ne la comptent pas. Sous 768px, ListePage masque l'action « Sélectionner » (PageAction
   Classe="masque-mobile") : la sélection multiple est un travail de bureau.

   Avant d'écrire un gabarit, grep la classe : une règle orpheline plus bas l'emporte en silence.
   Les pages passent la classe par GridClass="<page>-grid" sur <ListePage>.
*/
@media (max-width: 767.98px) {
    .col-hide-mobile {
        display: none !important;
    }

    /*
     * Les overrides grid-template-columns doivent lister TOUTES les pistes,
     * y compris celles des colonnes masquées (mise à 0px), car FluentDataGrid
     * écrit un style inline sur <table> qui inclut chaque colonne.
     * Sans override complet, les pistes vides occupent de l'espace et repoussent
     * les colonnes visibles hors du viewport.
     *
     * Colonnes masquées (col-hide-mobile) → 0px
     * Colonnes visibles → minmax(min, fr)
     *
     * Note : le mode sélection ajoute 1 colonne checkbox au début — l'override
     * ne couvre pas ce cas (acceptable en Sprint 1, la sélection multi est rare mobile).
     */

    /* ListeMembres : (22%) RaisonSociale | (13%) Enseigne× | (14%) SIRET× | (14%) Ville | (14%) Taille× | (12%) Type d'entité× | (14%) Statut | (8%) Contacts× */
    table.membres-grid {
        grid-template-columns:
            minmax(120px, 2fr) 0px 0px minmax(70px, 1fr) 0px 0px minmax(80px, 1fr) 0px
            !important;
    }

    /* ListeGroupesTravail : (30%) Nom | (50%) Description× | (10%) Membres | (10%) Teams× */
    table.groupes-travail-grid {
        grid-template-columns: minmax(140px, 3fr) 0px minmax(96px, 1fr) 0px !important;
    }

    /* ListeAdhesions : (32%) RaisonSociale | (12%) Date d'adhésion | (9%) Type× | (12%) Cotisation× | (13%) Statut cotisation.
       Avec « Anciens adhérents », deux colonnes de plus après la date : Date de résiliation× et Statut×. */
    table.adhesions-grid {
        grid-template-columns:
            minmax(100px, 2fr) 104px 0px 0px minmax(80px, 1fr)
            !important;
    }

    table.adhesions-grid--anciens {
        grid-template-columns:
            minmax(100px, 2fr) 104px 0px 0px 0px 0px minmax(80px, 1fr)
            !important;
    }

    /* ListePersonnesPhysiques : (5%) Civilité× | (15%) Nom | (20%) Organisation | (20%) Position× | (20%) Email | (12%) Téléphone× | (8%) Rôles× */
    table.pp-grid {
        grid-template-columns:
            0px minmax(90px, 1fr) minmax(100px, 1.3fr) 0px minmax(120px, 1.4fr) 0px 0px
            !important;
    }

    /* ListeEvenements : (20%) Titre | (10%) Type× | (16%) Statut× | (14%) Date | (10%) Lieu× | (10%) Catégorie× | (10%) Thématique× | (9%) Inscrits | (8%) Présents× */
    table.evenements-grid {
        grid-template-columns:
            minmax(110px, 2fr) 0px 0px minmax(75px, 0.9fr) 0px 0px 0px minmax(50px, 0.5fr) 0px
            !important;
    }

    /* ListeLieux : (22%) Nom | (16%) Type | (20%) Contact× | (20%) Adresse× | (8%) Événements */
    table.lieux-grid {
        grid-template-columns:
            minmax(120px, 2fr) minmax(80px, 1fr) 0px 0px minmax(50px, 0.6fr)
            !important;
    }

    /* ListePrestataires : (22%) Entreprise | (12%) Type | (14%) Contact× | (18%) Email× | (12%) Téléphone× | (10%) Événements */
    table.prestataires-grid {
        grid-template-columns:
            minmax(120px, 2fr) minmax(80px, 1fr) 0px 0px 0px minmax(50px, 0.6fr)
            !important;
    }

    /* Requetes : (22%) Nom | (16%) Usages | (10%) Cible | (10%) Canal× | (10%) Résultats | (10%) Campagnes× | (12%) Créée× */
    table.requetes-grid {
        grid-template-columns:
            minmax(110px, 2fr) minmax(80px, 1.4fr) minmax(60px, 0.8fr) 0px minmax(50px, 0.6fr) 0px 0px
            !important;
    }

    /* Listes : (22%) Nom | (12%) Usage | (12%) Cible× | (12%) Canal× | (12%) Destinataires | (10%) Campagnes× | (12%) Créée× */
    table.listes-grid {
        grid-template-columns:
            minmax(110px, 2fr) minmax(70px, 1fr) 0px 0px minmax(70px, 1fr) 0px 0px
            !important;
    }

    /* Campagnes : (18%) Nom | (8%) Canal | (12%) Statut | (16%) Liste× | (16%) Template× | (8%) Dest× | (12%) Envois | (10%) Créé× */
    table.campagnes-grid {
        grid-template-columns:
            minmax(100px, 2fr) minmax(50px, 0.7fr) minmax(70px, 1fr) 0px 0px 0px minmax(70px, 1fr) 0px
            !important;
    }

    /* Désinscriptions : Traitée(80) | Date×(160) | Personne | Entreprise | Campagne× | Canal×(90) | Destinataire× | RGPD(140) */
    table.desinscriptions-grid {
        grid-template-columns:
            60px 0px minmax(90px, 1.5fr) minmax(90px, 1.5fr) 0px 0px 0px minmax(80px, 1fr)
            !important;
    }

    /* Paiements : (25%) RaisonSociale | (10%) Date | (11%) Type | (7%) Année× | (16%) N°× | (11%) Modalité× | (13%) Montant */
    table.paiements-grid {
        grid-template-columns:
            minmax(110px, 2fr) minmax(80px, 1fr) minmax(70px, 0.9fr) 0px 0px 0px minmax(70px, 1fr)
            !important;
    }

    /* Mandats : (22%) Organisme× | (20%) Titre | (13%) Pôle | (10%) Échelon× | (10%) Titulaires | (10%) Suppléants | (10%) Fin prév× */
    table.mandats-grid {
        grid-template-columns:
            0px minmax(110px, 2fr) minmax(70px, 1fr) 0px minmax(50px, 0.6fr) minmax(50px, 0.6fr) 0px
            !important;
    }

    /* Mandataires : (18%) Nom | (18%) Prénom | (22%) Email× | (10%) Mandats actifs | (32%) Pôles */
    table.mandataires-grid {
        grid-template-columns:
            minmax(80px, 1fr) minmax(80px, 1fr) 0px minmax(50px, 0.5fr) minmax(100px, 1.6fr)
            !important;
    }

    /* Campagne de cotisations : (24%) RaisonSociale | (8%) Année× | (10%) Type× | (14%) Montant | (22%) Destinataire× | (22%) Situation */
    table.cotisations-grid {
        grid-template-columns:
            minmax(120px, 2fr) 0px 0px minmax(70px, 0.8fr) 0px minmax(90px, 1fr)
            !important;
    }

    /* Règlements : (24%) RaisonSociale | (6%) Année× | (9%) Échéance× | (8%) Retard | (9%) Net dû× | (9%) Solde | (15%) Situation | (12%) Relances× | (8%) Traiter× */
    table.reglements-grid {
        grid-template-columns:
            minmax(110px, 2fr) 0px 0px minmax(52px, 0.6fr) 0px minmax(72px, 0.9fr) minmax(80px, 1fr) 0px 0px
            !important;
    }

    /* Mes signalements (gabarit fixe 80/130/2fr/140/110/60 au-dessus) : # | Type× | Titre | Envoyé le× | Statut | Pièces× */
    table.mes-signalements-grid {
        grid-template-columns:
            52px 0px minmax(100px, 2fr) 0px minmax(80px, 1fr) 0px
            !important;
    }

    /* Signalements, côté administration : (80px) # | (12%) Type× | (38%) Titre | (16%) Auteur× | (14%) Date× | (12%) Statut | (56px) Pièces×.
       Le type se filtre déjà par ses tuiles. 64px et non 52 : « # » porte la flèche du tri par
       défaut, qui chassait le libellé de l'en-tête. */
    table.signalements-grid {
        grid-template-columns:
            64px 0px minmax(100px, 2fr) 0px 0px minmax(80px, 1fr) 0px
            !important;
    }
}


/* ========================================
   RESPONSIVE MOBILE — Sprint 2
   Sidebar + paddings + densité supercompact
   ========================================
   Ces règles s'appliquent à tous les viewports <768px quelle que soit
   la densité configurée par l'utilisateur en base de données.
   La densité BDD reste inchangée — seule l'apparence mobile est compactée.
*/
@media (max-width: 767.98px) {

    /* --- Sidebar : 320px → 260px (gain de 60px de contenu visible) ---
       FluentNavMenu pose sa largeur via CSS var. On contraint le conteneur
       et le web component directement. */
    .nav-sidebar {
        width: 260px !important;
        max-width: 80vw !important;
        overflow-x: hidden;
    }
    .nav-sidebar fluent-nav-menu {
        width: 260px !important;
        max-width: 260px !important;
    }

    /* --- Paddings réduits : 20px → 10px sur .content et .page-header --- */
    .content {
        padding-left: 10px !important;
        padding-right: 10px !important;
        padding-top: 0.6rem !important;
        font-size: 13px !important;
    }
    .page-header {
        padding-left: 10px !important;
        padding-right: 10px !important;
        margin-bottom: 6px !important;
    }

    /* --- Densité auto supercompact sur mobile --- */
    .list-page-container {
        gap: 8px !important;
    }
    .responsive-field-group {
        gap: 8px !important;
    }
    .list-page-card-content {
        gap: 6px !important;
    }
    .list-page-footer {
        padding-top: 6px !important;
        gap: 4px !important;
    }
    .list-page-grid-container .fluent-data-grid th,
    .list-page-grid-container .fluent-data-grid td {
        font-size: 13px;
        line-height: 1.25;
    }
    .list-page-grid-container .fluent-data-grid td {
        padding-top: 2px;
        padding-bottom: 2px;
    }
}


/* ========================================
   RESPONSIVE MOBILE — Sprint 3 : smartphone (iPhone, 393px)
   Coquille : en-tête allégé, hauteur visible, saisie sans zoom
   ========================================
   Rien ici ne touche le rendu à 768px et au-delà : les enveloppes .masque-mobile sont en
   display: contents hors du palier mobile, donc sans boîte ni espacement.
*/

/* Enveloppe d'un élément à retirer sur smartphone (pendant de .col-hide-mobile hors grille).
   Dans l'en-tête, elle ne crée pas de boîte : la pile garde ses espacements. Enfants directs
   seulement : le menu de l'utilisateur est rendu dans cette pile et une de ses entrées porte
   la classe, display: contents lui ôtait sa rangée au bureau. */
.header-actions > .masque-mobile {
    display: contents;
}

/* Pendant de .masque-mobile : un texte qui n'existe qu'au téléphone (consigne « Touchez… » à la
   place de « Ctrl+V »). */
.seulement-mobile {
    display: none;
}

@media (max-width: 767.98px) {
    .masque-mobile {
        display: none !important;
    }

    .seulement-mobile {
        display: inline;
    }

    /* Safari iOS compte dans 100vh la zone cachée sous sa barre d'outils ; 100dvh suit la zone
       réellement visible. Les anciens Safari sans dvh gardent 100vh. */
    @supports (height: 100dvh) {
        :root {
            --hauteur-ecran: 100dvh;
        }
    }

    /* Zone réservée au bas de l'écran (barre d'accueil iPhone) : utile en mode plein écran,
       nulle dans Safari classique. Demande viewport-fit=cover dans App.razor. */
    .main > .main-content {
        padding-bottom: env(safe-area-inset-bottom);
    }

    /* En-tête : restent le hamburger, le titre court, l'avatar, les notifications et les
       signalements. Le nom de l'utilisateur sort, l'avatar et le chevron suffisent. */
    .user-menu .fluent-persona .name {
        display: none;
    }

    /* Pied de page (logo 66px + raison sociale + version) : 82px perdus sur 852. FluentFooter
       rend un <footer class="footer">, pas une balise fluent-footer. */
    footer.footer {
        display: none !important;
    }

    /* Safari iOS zoome la page au focus d'un champ dont la police est sous 16px, et ne
       revient pas en arrière : la page restait agrandie avec un défilement horizontal. Les
       champs FluentUI étaient à 14px, le texte courant mobile à 13px. Seuls les champs natifs
       (input, textarea, select) déclenchent ce zoom ; le texte courant garde ses 13px. */
    fluent-text-field::part(root),
    fluent-text-field::part(control),
    fluent-search::part(root),
    fluent-search::part(control),
    fluent-number-field::part(root),
    fluent-number-field::part(control),
    fluent-text-area::part(root),
    fluent-text-area::part(control),
    fluent-combobox::part(root),
    fluent-combobox::part(control),
    fluent-select::part(control) {
        font-size: 16px !important;
    }

    .content input,
    .content textarea,
    .content select {
        font-size: 16px;
    }

    /* Tuiles de filtrage : chaque groupe est une bande qui défile au doigt, plutôt que sept
       tuiles écrasées ou empilées sur trois rangées. min-width: 0 sur le groupe, sinon l'élément
       flex s'élargit à son contenu (729px mesurés) au lieu de défiler.
       Un groupe par rangée : côte à côte, deux groupes se partageaient la largeur selon leur
       `flex` en ligne (126px pour trois tuiles à 390px), et Safari iOS, qui ne montre pas de
       barre de défilement, n'en laissait voir que des tuiles coupées (signalement 476). */
    .kpi-strip {
        row-gap: 6px;
    }

    .kpi-strip .kpi-group {
        min-width: 0;
        flex: 1 1 100% !important;
    }

    /* Entre deux rangées, le trait vertical n'a plus rien à séparer. */
    .kpi-strip .kpi-separator {
        display: none;
    }

    .kpi-strip .kpi-group > div {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 2px;
        scrollbar-width: thin;
    }

    /* Les tuiles se partagent la place libre de leur rangée sans jamais rétrécir : quand elles
       n'y tiennent pas, la rangée défile. */
    .kpi-strip .kpi-card {
        flex: 1 0 auto;
    }

    /* Les en-têtes de FluentDataGrid portent un min-width de 100px en ligne : sur une piste de
       87px l'en-tête débordait de sa colonne, et dans une fiche (sous-grilles des adresses, du
       groupe d'entreprises, des abonnements) il élargissait la carte au-delà de l'écran. */
    .fluent-data-grid th {
        min-width: 0 !important;
    }

    /* FluentDataGrid pose grid-column en ligne sur chaque cellule dès qu'il a des données, mais
       pas sur les en-têtes d'une grille vide (« Pas de données ») : en placement automatique, les
       en-têtes visibles glissaient dans les pistes à 0px des colonnes masquées (Titre sous #,
       Statut sous Titre). Le rang de chaque en-tête devient sa colonne ; le style en ligne, quand
       il existe, dit la même chose. */
    .fluent-data-grid thead th:nth-child(1) { grid-column: 1; }
    .fluent-data-grid thead th:nth-child(2) { grid-column: 2; }
    .fluent-data-grid thead th:nth-child(3) { grid-column: 3; }
    .fluent-data-grid thead th:nth-child(4) { grid-column: 4; }
    .fluent-data-grid thead th:nth-child(5) { grid-column: 5; }
    .fluent-data-grid thead th:nth-child(6) { grid-column: 6; }
    .fluent-data-grid thead th:nth-child(7) { grid-column: 7; }
    .fluent-data-grid thead th:nth-child(8) { grid-column: 8; }
    .fluent-data-grid thead th:nth-child(9) { grid-column: 9; }
    .fluent-data-grid thead th:nth-child(10) { grid-column: 10; }
    .fluent-data-grid thead th:nth-child(11) { grid-column: 11; }
    .fluent-data-grid thead th:nth-child(12) { grid-column: 12; }
    .fluent-data-grid thead th:nth-child(13) { grid-column: 13; }
    .fluent-data-grid thead th:nth-child(14) { grid-column: 14; }
    .fluent-data-grid thead th:nth-child(15) { grid-column: 15; }
    .fluent-data-grid thead th:nth-child(16) { grid-column: 16; }

    /* Sous-grille des adresses d'une fiche (personne morale : 500px, personne physique : 360px
       en ligne) : la largeur minimale du bureau élargissait toute la colonne de cartes. */
    .adresses-grid {
        min-width: 0 !important;
    }

    /* Suivi chronologique (événement, adhésion, cotisation) : pastilles de 24 px, seul le libellé
       de l'étape en cours (ou planifiée, ou rejetée) reste ; sept libellés se chevauchaient sur
       347 px. */
    .workflow-stepper {
        padding: 8px 4px 28px;
    }

    .workflow-step-circle {
        width: 24px;
        height: 24px;
        min-width: 24px;
        font-size: 0.65rem;
    }

    .workflow-step-label {
        left: 12px;
    }

    .workflow-step-label:not(.active):not(.scheduled):not(.rejected),
    .workflow-step-date {
        display: none;
    }

    /* Parcours achevé (cotisation payée) : aucune étape en cours, le libellé de la dernière reste. */
    .workflow-stepper:not(:has(.workflow-step-label.active, .workflow-step-label.scheduled, .workflow-step-label.rejected)) .workflow-step:last-child .workflow-step-label {
        display: inline;
    }

    /* Rangée de filtres d'une liste (événements) : la recherche sur toute la largeur, les
       listes déroulantes deux par rangée, au lieu des largeurs minimales du bureau. */
    .filtres-liste > fluent-search {
        flex: 1 1 100%;
        min-width: 0 !important;
        max-width: none !important;
    }

    .filtres-liste .filtre-categorie-repli {
        display: contents;
    }

    .filtres-liste fluent-select {
        flex: 1 1 calc(50% - var(--espace-2));
        min-width: 0 !important;
    }

    /* FluentSelect impose un min-width de 250px : dans une carte de filtres de 347px, le
       sélecteur d'année (règlements, campagne) débordait de la carte et de l'écran. */
    .list-page-filters fluent-select {
        min-width: 0 !important;
    }

    /* Tableau de bord : une colonne bornée à l'écran. « 1fr » vaut minmax(auto, 1fr) et la
       colonne s'élargissait au contenu le plus large (le pipeline, 467px) : tous les widgets
       débordaient. Les widgets gardent leurs hauteurs (lignes de 160px, listes défilantes). */
    .dashboard-grid {
        grid-template-columns: minmax(0, 1fr);
        padding: 0;
    }

    .dashboard-widget {
        min-width: 0;
        grid-column: span 1 !important;
    }

    .pipeline-container {
        justify-content: flex-start;
        overflow-x: auto;
    }

    .pipeline-stage {
        flex: 0 0 72px;
    }
}


/* ========================================
   RESPONSIVE MOBILE — Sprint 3, lot 5 : édition au doigt
   Cibles tactiles, menus flottants, pied de formulaire, appui long
   ========================================
   Rien ici ne touche le rendu à 768px et au-delà. Seule exception, .appui-long, qui ne dépend
   pas de la largeur mais de l'absence de survol (écran tactile).
*/

/* Élément dont l'appui long vaut clic droit (js/tactile.js) : ni sélection de texte ni bulle
   iOS pendant l'appui, ni délai de double-tap. */
@media (hover: none) {
    .appui-long {
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
        touch-action: manipulation;
    }
}

@media (max-width: 767.98px) {
    /* Cibles tactiles à 40px : boutons et champs mesurés à 32px, cases à 20px, entrées du menu
       à 33px, liens « Appeler » à 17px. Les boutons de tri des en-têtes de grille gardent leur
       taille : la rangée d'en-tête reste à 32px. */
    fluent-button,
    fluent-button::part(control) {
        min-height: 40px;
        min-width: 40px;
    }

    .fluent-data-grid thead fluent-button,
    .fluent-data-grid thead fluent-button::part(control) {
        min-height: 0;
        min-width: 0;
    }

    /* L'hôte garde sa hauteur de 32px dans son propre style (:host) : sans cette règle le
       contrôle agrandi déborde de l'hôte et chevauche la ligne suivante. */
    fluent-text-field,
    fluent-text-field::part(root),
    fluent-search,
    fluent-search::part(root),
    fluent-number-field,
    fluent-number-field::part(root),
    fluent-combobox,
    fluent-combobox::part(root),
    fluent-select::part(control),
    fluent-option,
    fluent-menu-item {
        min-height: 40px;
    }

    fluent-checkbox,
    fluent-switch,
    fluent-radio {
        min-height: 40px;
    }

    /* Le style isolé de FluentNavLink (MEDEF54.Web.styles.css, chargé après) fixe 33px. */
    .nav-sidebar .fluent-nav-link .positioning-region {
        min-height: 40px !important;
    }

    /* Calendrier d'un FluentDatePicker : jours de 30px dans une boîte figée à 224 × 272 px (style
       isolé de FluentCalendar). La boîte suit son contenu ; le calendrier passe à 318 px de large
       et tient dans l'écran. */
    .fluent-datepicker-popup .fluent-calendar {
        width: max-content !important;
        height: auto !important;
    }

    .fluent-datepicker-popup .fluent-calendar .day {
        width: 40px !important;
        height: 40px !important;
    }

    /* Liens téléphone et email dans une cellule : la zone d'appui s'étend à la hauteur de la
       ligne sans déplacer le texte. */
    a[href^="tel:"],
    a[href^="mailto:"] {
        display: inline-block;
        padding: 10px 4px;
        margin: -10px -4px;
    }

    /* Entrées des menus flottants (statut et présence d'une inscription). Le padding est en
       ligne dans la page, d'où le !important. */
    .menu-flottant-item {
        min-height: 40px;
        padding-top: 9px !important;
        padding-bottom: 9px !important;
    }

    /* Menus FluentUI ancrés (utilisateur, « Actions ») : jamais plus larges que l'écran, libellé
       tronqué au besoin. Le menu de l'utilisateur, ancré au chevron du bord droit, s'ouvrait vers
       la gauche et sortait de l'écran. */
    fluent-anchored-region > fluent-menu {
        max-width: calc(100vw - 16px);
    }

    fluent-anchored-region fluent-menu-item::part(content) {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Pied Annuler/Enregistrer d'une fiche : collé au bas de l'écran dès qu'il y a quelque chose
       à enregistrer (classe posée par la page), au-dessus de la barre d'accueil iPhone. Au repos
       il reste à sa place, en fin de fiche. */
    .pied-formulaire--actif {
        position: sticky;
        bottom: 0;
        z-index: 5;
        margin-bottom: calc(-1 * env(safe-area-inset-bottom));
        padding: 8px 0 calc(8px + env(safe-area-inset-bottom));
        background: var(--neutral-layer-1);
        border-top: 1px solid var(--neutral-stroke-rest);
    }
}


/* ========================================
   RESPONSIVE MOBILE — Sprint 3, lot 6 : raccourci sur l'écran d'accueil
   ========================================
   Ouverte depuis l'écran d'accueil d'un téléphone (display-mode: standalone), la page occupe
   tout l'écran, barre d'état comprise (apple-mobile-web-app-status-bar-style: black-translucent
   dans App.razor). Le bandeau s'allonge de la hauteur de la barre d'état, qu'il garde dans sa
   couleur, et le menu latéral se cale sous lui. Dans un navigateur l'inset vaut zéro : aucun
   effet, à tous les paliers.
*/
@media (display-mode: standalone) {
    header.header {
        box-sizing: border-box;
        height: calc(50px + env(safe-area-inset-top)) !important;
        padding-top: env(safe-area-inset-top);
    }

    @media (max-width: 1199.98px) {
        .nav-sidebar {
            top: calc(50px + env(safe-area-inset-top));
            height: calc(var(--hauteur-ecran) - 50px - env(safe-area-inset-top));
        }

        .nav-overlay {
            top: calc(50px + env(safe-area-inset-top));
        }
    }
}


/* ========================================
   CODE NAF - Troncature du texte long
   ======================================== */

/* Conteneur du Code NAF - forcer la largeur max */
.code-naf-truncate {
    min-width: 0;
    overflow: hidden;
}

/* Ligne d'aide en tête de la liste d'une autocomplétion ouverte par sa loupe (signalement 429) */
.autocomplete-aide {
    padding: 6px 10px 4px;
    color: var(--neutral-foreground-hint);
    font-size: var(--type-ramp-minus-1-font-size);
    line-height: var(--type-ramp-minus-1-line-height);
}

/* Limiter la largeur du composant autocomplete */
.code-naf-truncate fluent-autocomplete {
    width: 100%;
    max-width: 100%;
}

/* Cibler le conteneur des options sélectionnées */
.code-naf-truncate fluent-autocomplete::part(selected-options),
.code-naf-truncate fluent-autocomplete [part="selected-options"] {
    max-width: 100%;
    overflow: hidden;
}

/* Le tag/badge sélectionné dans le FluentAutocomplete */
.code-naf-truncate fluent-badge,
.code-naf-truncate [class*="badge"],
.code-naf-truncate [class*="tag"],
.code-naf-truncate [class*="chip"] {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
}

/* Texte à l'intérieur du tag */
.code-naf-truncate fluent-badge span,
.code-naf-truncate fluent-badge div {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
}

/* ========================================
   FLUENT SELECT - STABILISATION DROPDOWN
   ======================================== */

/* S'assurer que les dropdowns FluentSelect s'affichent correctement */
.responsive-field-group fluent-select,
.responsive-field-group fluent-combobox {
    position: relative;
}

/* Le listbox du FluentSelect doit utiliser position fixed pour éviter les problèmes de overflow */
fluent-select::part(listbox),
fluent-combobox::part(listbox) {
    z-index: 9999;
    /* Borner la hauteur quand la liste est très longue (templates, contacts, etc.)
       sinon le popup déborde du viewport et le premier item se retrouve sous la barre
       de titre du navigateur. Le scroll interne prend le relais. */
    max-height: min(360px, 60vh) !important;
    overflow-y: auto !important;
}

/* Carte des adhérents : filtres en <select> HTML natifs (issue #22 — FluentSelect popup
   ignorait position="below" dans .list-page-container et s'ouvrait masqué par le header) */
.carte-filtre {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.carte-filtre label {
    font-size: 12px;
    color: var(--neutral-foreground-rest);
    line-height: 1;
}

.carte-filtre-select {
    height: 32px;
    padding: 4px 8px;
    border: 1px solid var(--neutral-stroke-rest, #ccc);
    border-radius: 4px;
    background: var(--neutral-fill-input-rest, #fff);
    color: var(--neutral-foreground-rest);
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
}

.carte-filtre-select:focus {
    outline: 2px solid var(--accent-fill-rest, #0078d4);
    outline-offset: -2px;
}

/* Civilité (M./Mme/Dr/Me/Pr) — colonne étroite : forcer le composant FluentSelect à
   respecter la width du wrapper (sans cela, min-width interne ~180px → débord sur Prénom). */
fluent-select.civilite-select,
fluent-select.civilite-select::part(control) {
    min-width: 0 !important;
    width: 100% !important;
}

fluent-select.civilite-select::part(control) {
    height: 32px !important;
    min-height: 32px !important;
}

/* Convention collective - conteneur large pour les longs libellés */
.code-naf-large {
    min-width: 0;
    width: 100%;
}

.code-naf-large fluent-autocomplete {
    width: 100%;
}

/* Date fields side by side - fix for FluentDatePicker display:contents behavior */
.date-fields-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.date-fields-row fluent-date-picker {
    display: block !important;
}

/* Diff rows for bulk operations */
.diff-row {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    gap: 12px;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.diff-row-added {
    background-color: rgba(34, 197, 94, 0.1);
    border-left: 3px solid #22c55e;
}

.diff-row-removed {
    background-color: rgba(239, 68, 68, 0.1);
    border-left: 3px solid #ef4444;
    text-decoration: line-through;
    opacity: 0.8;
}

.diff-row-unchanged {
    opacity: 0.6;
}

.diff-icon {
    font-weight: bold;
    width: 20px;
    text-align: center;
}

.diff-row-added .diff-icon {
    color: #22c55e;
}

.diff-row-removed .diff-icon {
    color: #ef4444;
}

.diff-row-unchanged .diff-icon {
    color: var(--neutral-foreground-hint);
}

.diff-name {
    font-weight: 600;
    min-width: 200px;
}

.diff-detail {
    color: var(--neutral-foreground-hint);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================
   Monaco Editor - BlazorMonaco Styles
   ============================================ */

/* Container wrapper for Monaco */
.monaco-container {
    width: 100%;
    height: 398px; /* Fixed height in pixels */
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    overflow: hidden;
}

/* BlazorMonaco - dimensions du conteneur */
/* La navigation vers cette page utilise forceLoad:true pour éviter les problèmes d'enhanced navigation */
/* AutomaticLayout=true gère le redimensionnement, mais le conteneur a besoin de dimensions initiales */
/* et de position:relative car Monaco utilise position:absolute en interne */
#template-html-editor,
.template-monaco-editor {
    width: 100% !important;
    height: 50vh !important;
    position: relative !important;
}

#contrat-html-editor,
.contrat-monaco-editor {
    width: 100% !important;
    height: 50vh !important;
    position: relative !important;
}

#template-document-editor,
.template-document-monaco-editor {
    width: 100% !important;
    height: 50vh !important;
    position: relative !important;
}

#pageweb-html-editor,
.pageweb-monaco-editor,
.tpw-monaco-fill {
    width: 100% !important;
    height: 100% !important;
    position: relative !important;
}

/* Contraindre les images dans l'éditeur Radzen des templates pages web */
.tpw-editor-content .rz-html-editor-content img {
    max-width: 100%;
    height: auto;
}

/* FluentTextArea : forcer le textarea interne (shadow DOM) à remplir l'espace flex */
.stretch-textarea::part(control) {
    flex: 1;
}

/* FluentTextArea : forcer le host (inline par défaut) en block + textarea interne 100% */
.fulltextarea {
    display: block !important;
    width: 100% !important;
}

.fulltextarea::part(control) {
    width: 100%;
    box-sizing: border-box;
}

/* ============================================
   Suivi Communication Événement
   ============================================ */

/* Pastilles compactes de statut d'envoi */
.suivi-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 700;
    color: white;
    line-height: 1;
}

.suivi-dot-delivre { background-color: #22c55e; }
.suivi-dot-ouvert { background-color: #3b82f6; }
.suivi-dot-clique { background-color: #8b5cf6; }
.suivi-dot-bounce { background-color: #ef4444; }
.suivi-dot-erreur { background-color: #dc2626; }
.suivi-dot-envoye { background-color: #f59e0b; }
.suivi-dot-planifie { background-color: #9ca3af; }

/* Ligne de cartes stats */
.suivi-stats-row {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

.suivi-stat-card {
    flex: 1;
    /* Assez large pour que « À RECONFIRMER » tienne sur une ligne : sinon son libellé passe sur
       deux lignes et sa valeur descend, désalignée des autres tuiles. */
    min-width: 160px;
    max-width: 220px;
    background: var(--neutral-layer-card-container);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    padding: 12px 16px;
    text-align: center;
}

.suivi-stat-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 4px;
    /* line-height explicite : la réserve de 2.4em ne tient que si deux lignes font exactement
       2 × 1.2em. Sans elle, un libellé qui passe sur deux lignes déborde et pousse sa valeur
       plus bas que celle des tuiles voisines (cas des écrans étroits). */
    line-height: 1.2;
    min-height: 2.4em;
    display: flex;
    align-items: center;
    justify-content: center;
}

.suivi-stat-value {
    font-size: 24px;
    font-weight: 700;
    line-height: 1.2;
}

.suivi-stat-detail {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    margin-top: 2px;
}

.suivi-stat-date {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    margin-top: 2px;
}

.suivi-liste-card {
    margin-left: auto;
    background: var(--neutral-layer-card-container);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    min-width: 140px;
    max-width: 280px;
}

/* Légende */
.suivi-legende {
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--neutral-foreground-hint);
    padding: 8px 0;
}

.suivi-legende .suivi-dot {
    width: 18px;
    height: 18px;
    font-size: 9px;
    margin-right: 2px;
}

@media (max-width: 768px) {
    .suivi-stat-card {
        min-width: 90px;
        padding: 8px 10px;
    }

    .suivi-stat-value {
        font-size: 18px;
    }
}

/* ===========================================
   PagePubliqueLayout — pages web publiques
   =========================================== */

/* Fond sombre par défaut sur les pages publiques (inscription, adhésion) */
html:has(.page-publique-layout),
html:has(.page-publique-layout) body {
    background: #0b1026 !important;
    color: #ffffff !important;
}

.page-publique-layout {
    min-height: 100vh;
    max-width: 1000px;
    margin: 0 auto;
    overflow: hidden;
    color: #ffffff;
    --neutral-foreground-rest: #ffffff;
    --neutral-foreground-hint: rgba(255, 255, 255, 0.7);
    --accent-foreground-rest: #60cdff;
    --neutral-stroke-rest: rgba(255, 255, 255, 0.3);
}

.page-publique-layout img {
    max-width: 100%;
    height: auto;
}

.page-publique-iframe {
    width: 100%;
    border: none;
    overflow: hidden;
    min-height: 200px;
    border-radius: 8px;
}

/* FluentDesignTheme Dark gère les couleurs des composants FluentUI automatiquement.
   On ne conserve que les overrides structurels nécessaires. */

/* FluentCards transparentes pour laisser voir le fond sombre de la page */
.page-publique-layout fluent-card {
    background: transparent !important;
    /* La carte se fond dans la page du modèle : ni le filet ni l'ombre des cartes de l'application. */
    border: none;
    box-shadow: none;
    color: inherit;
}

.page-publique-layout fluent-card .stack-vertical {
    align-items: stretch !important;
    width: 100%;
}

/* Alertes pages publiques — remplace FluentMessageBar (Shadow DOM illisible sur fond sombre) */
.public-alert {
    padding: 12px 16px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1.5;
    max-width: 700px;
    margin: 0 auto 8px;
}

.public-alert-success {
    background: #d4edda;
    color: #155724;
    border: 1px solid #c3e6cb;
}

.public-alert-info {
    background: #d1ecf1;
    color: #0c5460;
    border: 1px solid #bee5eb;
}

.public-alert-warning {
    background: #fff3cd;
    color: #856404;
    border: 1px solid #ffeeba;
}

.public-alert-error {
    background: #f8d7da;
    color: #721c24;
    border: 1px solid #f5c6cb;
}

/* ========================== */
/* Dashboard personnalisable  */
/* ========================== */

/* Grille du dashboard */
.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 160px;
    gap: 16px;
    padding: 20px;
    width: 100%;
    box-sizing: border-box;
    min-width: 0;
}

@media (max-width: 600px) {
    .dashboard-grid {
        padding: 8px;
        gap: 10px;
    }
}

@media (max-width: 1200px) {
    .dashboard-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 900px) {
    .dashboard-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .dashboard-grid {
        grid-template-columns: 1fr;
    }
}

/* Largeurs de widgets */
.dashboard-widget.largeur-1 { grid-column: span 1; }
.dashboard-widget.largeur-2 { grid-column: span 2; }
.dashboard-widget.largeur-3 { grid-column: span 3; }
.dashboard-widget.largeur-4 { grid-column: span 4; }

/* Hauteurs de widgets (multiples de la hauteur KPI 160px) */
.dashboard-widget.hauteur-1 { grid-row: span 1; }
.dashboard-widget.hauteur-2 { grid-row: span 2; }
.dashboard-widget.hauteur-3 { grid-row: span 3; }
.dashboard-widget.hauteur-4 { grid-row: span 4; }

.dashboard-widget.hauteur-2 > .liste-widget,
.dashboard-widget.hauteur-3 > .liste-widget,
.dashboard-widget.hauteur-4 > .liste-widget {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.dashboard-widget.hauteur-2 > .liste-widget > .liste-widget-items,
.dashboard-widget.hauteur-3 > .liste-widget > .liste-widget-items,
.dashboard-widget.hauteur-4 > .liste-widget > .liste-widget-items {
    flex: 1;
    overflow-y: auto;
}

@media (max-width: 900px) {
    .dashboard-widget.largeur-2,
    .dashboard-widget.largeur-3,
    .dashboard-widget.largeur-4 {
        grid-column: span 2;
    }
}

@media (max-width: 600px) {
    .dashboard-widget.largeur-1,
    .dashboard-widget.largeur-2,
    .dashboard-widget.largeur-3,
    .dashboard-widget.largeur-4 {
        grid-column: span 1;
    }
}

/* KPI Card */
.kpi-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
    background: var(--surface-carte);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-l);
    box-shadow: var(--ombre-1);
    text-align: center;
    height: 160px;
    transition: box-shadow var(--duree-rapide) var(--courbe-entree), border-color var(--duree-rapide) var(--courbe-entree);
}

/* Les widgets reçoivent leur couleur du service, en var(--success|warning|error|info). Ces
   jetons FluentUI ne suivent pas le thème : « J-10 » en #616161 disparaissait sur fond sombre.
   Dans les tuiles et les listes, où ils ne servent que de couleur de texte et d'icône, ils
   sont ramenés sur les textes de statut. */
.kpi-card,
.liste-widget {
    --success: var(--statut-succes-texte);
    --warning: var(--statut-attention-texte);
    --error: var(--statut-erreur-texte);
    --info: var(--statut-information-texte);
}

.kpi-year-nav {
    position: absolute;
    top: 6px;
    right: 6px;
    display: flex;
    align-items: center;
    gap: 2px;
    z-index: 1;
}

.kpi-year-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
    min-width: 32px;
    text-align: center;
}

.kpi-card-clickable {
    cursor: pointer;
}

.kpi-card-clickable:hover {
    border-color: var(--marque-500);
    box-shadow: var(--ombre-2);
}

/* Tableau de bord : l'icône dans une pastille à la teinte de sa couleur, valeur et libellé à
   l'échelle. Portée .dashboard-widget : css/prospection.css redéfinit .kpi-icon, .kpi-value et
   .kpi-title pour « Ma journée » sans portée, et s'appliquait ici aussi (majuscules, 2.5rem,
   tuile qui se soulève au survol). */
.dashboard-widget .kpi-card-clickable:hover {
    transform: none;
}

.dashboard-widget .kpi-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: color-mix(in srgb, currentColor 12%, transparent);
    opacity: 1;
    margin-bottom: var(--espace-2);
}

.dashboard-widget .kpi-icon svg {
    width: 24px !important;
    height: 24px;
}

.dashboard-widget .kpi-value {
    font-size: var(--taille-3xl);
    font-weight: var(--graisse-titre);
    line-height: 1.2;
    margin-bottom: var(--espace-1);
}

.dashboard-widget .kpi-title {
    font-size: var(--taille-s);
    font-weight: 500;
    color: var(--texte-secondaire);
    text-transform: none;
    letter-spacing: 0;
}

.kpi-icon {
    font-size: 28px;
    margin-bottom: 8px;
}

.kpi-value {
    font-size: 32px;
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: 4px;
}

.kpi-title {
    font-size: 14px;
    color: var(--neutral-foreground-hint);
    font-weight: 500;
}

.kpi-subtitle {
    font-size: 12px;
    color: var(--neutral-foreground-hint);
    margin-top: 4px;
}

/* KPI Strip — bande de tuiles de filtrage (listes de prospection, cibles)
   Toutes les tuiles font la même hauteur, quelle que soit la longueur de leur
   sous-titre : les trois `stretch` ci-dessous propagent la hauteur de la rangée
   jusqu'aux cartes. Avec `flex-start`, chacune se calait sur son contenu et la
   rangée devenait un peigne dès qu'un sous-titre passait sur deux lignes. */
.kpi-strip {
    display: flex;
    gap: 12px;
    flex-shrink: 0;
    margin-bottom: 10px;
    flex-wrap: wrap;
    align-items: stretch;
    width: 100%;
    max-width: 1400px;
}
.kpi-strip .kpi-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}
.kpi-strip .kpi-group > div {
    display: flex;
    gap: 6px;
    align-items: stretch;
    flex: 1;
}
.kpi-strip .kpi-card {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: 5px 10px;
    border-radius: 6px;
    min-width: 90px;
    flex: 1;
    border: 1px solid transparent;
    text-align: left;
    align-items: flex-start;
    position: static;
    transition: none;
    box-shadow: none;
    height: auto;
}
.kpi-strip .kpi-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
    margin-bottom: 1px;
    white-space: nowrap;
}
.kpi-strip .kpi-value {
    font-size: 18px;
    font-weight: 700;
    line-height: 1.1;
}
.kpi-strip .kpi-sub {
    font-size: 11px;
    margin-top: 1px;
    opacity: 0.85;
}
.kpi-strip .kpi-card--green    { background: #f0fdf4; border-color: #86efac; color: #166534; }
.kpi-strip .kpi-card--neutral  { background: var(--surface-creuse); border-color: var(--bordure-forte); color: var(--texte-principal); }
.kpi-strip .kpi-card--blue     { background: #eff6ff; border-color: #bfdbfe; color: #1e40af; }
.kpi-strip .kpi-card--indigo   { background: #eef2ff; border-color: #c7d2fe; color: #3730a3; }
.kpi-strip .kpi-card--slate    { background: var(--statut-neutre-fond); border-color: var(--statut-neutre-bordure); color: var(--statut-neutre-texte); }
.kpi-strip .kpi-card--amber    { background: #fffbeb; border-color: #fcd34d; color: #92400e; }
.kpi-strip .kpi-card--avoir    { background: #fff7ed; border-color: #fdba74; color: #9a3412; }
.kpi-strip .kpi-card--emerald  { background: #ecfdf5; border-color: #6ee7b7; color: #065f46; }
.kpi-strip .kpi-card--violet   { background: #f6f2ff; border-color: #ddd6fe; color: #6d28d9; }
.kpi-strip .kpi-card--red      { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
/* Tuile d'une catégorie : mêmes jetons que le badge `badge-statut--cat-N` de la grille, pour que
   la tuile filtrante et la pastille de la ligne se reconnaissent. Les jetons portent déjà leur
   valeur sombre. */
.kpi-strip .kpi-card--cat-1 { background: var(--categorie-1-fond); border-color: color-mix(in srgb, var(--categorie-1-texte) 30%, transparent); color: var(--categorie-1-texte); }
.kpi-strip .kpi-card--cat-2 { background: var(--categorie-2-fond); border-color: color-mix(in srgb, var(--categorie-2-texte) 30%, transparent); color: var(--categorie-2-texte); }
.kpi-strip .kpi-card--cat-3 { background: var(--categorie-3-fond); border-color: color-mix(in srgb, var(--categorie-3-texte) 30%, transparent); color: var(--categorie-3-texte); }
.kpi-strip .kpi-card--cat-4 { background: var(--categorie-4-fond); border-color: color-mix(in srgb, var(--categorie-4-texte) 30%, transparent); color: var(--categorie-4-texte); }
.kpi-strip .kpi-card--cat-5 { background: var(--categorie-5-fond); border-color: color-mix(in srgb, var(--categorie-5-texte) 30%, transparent); color: var(--categorie-5-texte); }
.kpi-strip .kpi-card--cat-6 { background: var(--categorie-6-fond); border-color: color-mix(in srgb, var(--categorie-6-texte) 30%, transparent); color: var(--categorie-6-texte); }
.kpi-strip .kpi-card--cat-7 { background: var(--categorie-7-fond); border-color: color-mix(in srgb, var(--categorie-7-texte) 30%, transparent); color: var(--categorie-7-texte); }
.kpi-strip .kpi-card--cat-8 { background: var(--categorie-8-fond); border-color: color-mix(in srgb, var(--categorie-8-texte) 30%, transparent); color: var(--categorie-8-texte); }
.kpi-strip .kpi-separator {
    width: 1px;
    background: var(--neutral-stroke-rest);
    align-self: stretch;
    margin: 0 4px;
}
.kpi-strip .kpi-group-label {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
    padding-left: 2px;
}

/* Widget Liste */
.liste-widget {
    background: var(--surface-carte);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-l);
    box-shadow: var(--ombre-1);
    overflow: hidden;
}

.liste-widget-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px 10px;
}

.liste-widget-header-left {
    display: flex;
    align-items: center;
    gap: 8px;
}

.liste-widget-header-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--accent-fill-rest) 12%, transparent);
}

.liste-widget-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--neutral-foreground-rest);
}

.liste-widget-voir-tout {
    display: flex;
    align-items: center;
    gap: 3px;
    font-size: 12px;
    font-weight: 500;
    color: var(--accent-fill-rest);
    cursor: pointer;
    text-decoration: none;
    padding: 4px 8px;
    border-radius: 4px;
    transition: background-color 0.15s;
}

.liste-widget-voir-tout:hover {
    background: color-mix(in srgb, var(--accent-fill-rest) 8%, transparent);
}

.liste-widget-items {
    display: flex;
    flex-direction: column;
    padding: 0 8px 8px;
}

.liste-widget-item {
    display: flex;
    align-items: center;
    padding: 8px;
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.15s, box-shadow 0.15s;
    gap: 12px;
}

.liste-widget-item:hover {
    background-color: var(--neutral-layer-2);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}

.liste-widget-item + .liste-widget-item {
    border-top: 1px solid var(--neutral-stroke-divider-rest);
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.liste-widget-item:hover + .liste-widget-item,
.liste-widget-item + .liste-widget-item:hover {
    border-top-color: transparent;
}

/* Date block (calendrier) */
.liste-widget-date-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    width: 44px;
    height: 44px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--accent-fill-rest) 10%, transparent);
    flex-shrink: 0;
}

.liste-widget-date-day {
    font-size: 17px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--accent-fill-rest);
}

.liste-widget-date-month {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--accent-fill-rest);
    opacity: 0.75;
    letter-spacing: 0.3px;
}

.liste-widget-item-content {
    flex: 1;
    min-width: 0;
}

.liste-widget-item-titre {
    font-size: 13px;
    font-weight: 500;
    color: var(--neutral-foreground-rest);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
}

.liste-widget-item-soustitre {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 1px;
}

.liste-widget-item-badge {
    font-size: 11px;
    font-weight: 500;
    padding: 3px 8px;
    border-radius: 12px;
    background: var(--neutral-layer-2);
    white-space: nowrap;
}

/* État vide */
.liste-widget-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 24px 16px;
    color: var(--neutral-foreground-hint);
    font-size: 13px;
}

/* Widget Pipeline */
.pipeline-container {
    display: flex;
    align-items: flex-end;
    justify-content: space-around;
    gap: 8px;
    padding: 16px 8px;
    min-height: 180px;
}

.pipeline-stage {
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: pointer;
    flex: 1;
    max-width: 80px;
}

.pipeline-stage:hover .pipeline-bar-fill {
    opacity: 0.8;
}

.pipeline-count {
    margin-bottom: 8px;
}

.pipeline-count .badge {
    font-size: 14px;
    padding: 4px 8px;
}

.pipeline-label {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    text-align: center;
    margin-bottom: 8px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.pipeline-bar {
    width: 100%;
    height: 80px;
    background: var(--neutral-layer-2);
    border-radius: 4px;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
}

.pipeline-bar-fill {
    width: 100%;
    border-radius: 4px 4px 0 0;
    transition: height 0.3s ease;
    min-height: 4px;
}

.pipeline-arrow {
    display: flex;
    align-items: center;
    color: var(--neutral-foreground-hint);
    font-size: 12px;
    margin: 0 -4px;
}

/* Configurateur de dashboard */
.widget-catalog {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    max-height: 250px;
    overflow-y: auto;
    padding: 4px;
}

.widget-catalog-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;
}

.widget-catalog-item:hover {
    border-color: var(--accent-fill-rest);
}

.widget-catalog-item.selected {
    border-color: var(--accent-fill-rest);
    background-color: var(--accent-fill-subtle);
}

.widget-catalog-item-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.widget-catalog-item-libelle {
    font-weight: 500;
    font-size: 14px;
}

.widget-catalog-item-module {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    padding: 2px 6px;
    background: var(--neutral-layer-2);
    border-radius: 4px;
}

.widget-catalog-item-description {
    font-size: 12px;
    color: var(--neutral-foreground-hint);
    line-height: 1.4;
}

/* Liste des widgets configurés */
.configured-widgets-list {
    max-height: 320px;
    overflow-y: auto;
}

.configured-widget-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--neutral-stroke-divider-rest);
    border-radius: 6px;
    background: var(--neutral-layer-card-container);
}

.configured-widget-item-content {
    flex: 1;
    min-width: 0;
}

.configured-widget-item-actions {
    display: flex;
    gap: 4px;
}

.configured-widget-params {
    margin-top: 4px;
}

/* Dashboard vide */
.dashboard-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60px 20px;
    text-align: center;
    color: var(--neutral-foreground-hint);
}

.dashboard-empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
    opacity: 0.5;
}

/* ========================================
   LAYOUT FULL-VIEWPORT (Pages de liste)
   Permet aux pages de tenir sur l'écran
   sans scroll global (footer toujours visible)
   ======================================== */

/* Conteneur principal qui remplit toute la hauteur disponible */
.list-page-container {
    display: flex;
    flex-direction: column;
    gap: 12px; /* Espacement entre header, card recherche et card liste */
    height: calc(var(--hauteur-ecran) - 160px); /* viewport - header(50px) - footer(90px) - padding(20px) */
    min-height: 400px;
    width: 100%;
}

/* Card qui contient la grille - prend tout l'espace restant */
.list-page-card {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0; /* Crucial pour permettre le shrink en flexbox */
    overflow: hidden;
}

/* ListePage avec rail : rail à gauche, tuiles + filtres + liste en colonne à droite. Sans rail,
   les deux enveloppes s'effacent et rien ne change pour les autres listes. */
.liste-page-corps {
    display: flex;
    gap: var(--espace-3);
    flex: 1 1 auto;
    min-height: 0;
}

.liste-page-colonne {
    display: flex;
    flex-direction: column;
    gap: var(--espace-3);
    flex: 1;
    min-width: 0;
    min-height: 0;
}

.liste-page-corps--sans-rail,
.liste-page-corps--sans-rail > .liste-page-colonne {
    display: contents;
}

/* Wrapper du contenu de la card */
.list-page-card-content {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    gap: 10px;
    /* Ancre le voile de chargement. position: relative ne cree pas de bloc conteneur pour
       les popups en position: fixed (FluentSelect, DatePicker) : eux ne bougent pas. */
    position: relative;
}

/* Voile de chargement pendant une recherche. Il se superpose a la grille au lieu de la
   remplacer : la demonter invaliderait la reference @ref dont depend RefreshDataAsync. */
.list-page-loading-overlay {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.6);
}

/* Un voile sombre sur un fond deja sombre ne se voit pas : le temoin doit etre un bloc
   contraste, pas seulement un anneau. */
.list-page-loading-box {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 22px;
    border-radius: 8px;
    background: #ffffff;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
    font-size: 14px;
}

html[data-bs-theme="dark"] .list-page-loading-overlay {
    background: rgba(26, 26, 26, 0.6);
}

html[data-bs-theme="dark"] .list-page-loading-box {
    background: #2b2b2b;
    color: #f0f0f0;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}

/* Chargement en echec : doit se distinguer du « Pas de donnees disponibles » d'une liste vide. */
.list-page-echec {
    color: #a4262c;
    font-weight: 600;
}

html[data-bs-theme="dark"] .list-page-echec {
    color: #f1a3a6;
}

/* État vide : dit pourquoi c'est vide et propose la suite (effacer la recherche, créer).
   .etat-vide vaut partout ; .list-page-vide en est l'emploi dans une grille de liste. */
.etat-vide,
.list-page-vide {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--espace-3);
    padding: var(--espace-6) 0;
    color: var(--texte-secondaire);
    text-align: center;
}

.etat-vide > fluent-icon,
.etat-vide > svg {
    color: var(--texte-discret);
}

/* ============================================================
   BADGE DE STATUT — composant BadgeStatut (docs/ui-patterns.md §10)
   ============================================================
   Fond pâle, texte foncé de la même famille, filet : lisible dans les deux thèmes sans règle
   par thème, les jetons s'en chargent. Chaque ton ne fait que brancher trois variables. */
.badge-statut {
    --badge-fond: var(--statut-neutre-fond);
    --badge-texte: var(--statut-neutre-texte);
    --badge-bordure: var(--statut-neutre-bordure);
    display: inline-flex;
    align-items: center;
    gap: var(--espace-1);
    padding: 1px var(--espace-2);
    border: 1px solid var(--badge-bordure);
    border-radius: var(--rayon-pilule);
    background: var(--badge-fond);
    color: var(--badge-texte);
    font-family: inherit;
    font-size: var(--taille-xs);
    font-weight: var(--graisse-forte);
    line-height: 1.5;
    white-space: nowrap;
    vertical-align: middle;
}

.badge-statut--petit {
    padding: 0 6px;
    font-size: var(--taille-2xs);
}

.badge-statut--grand {
    padding: 2px 10px;
    font-size: var(--taille-base);
}

.badge-statut--marque      { --badge-fond: var(--statut-marque-fond);      --badge-texte: var(--statut-marque-texte);      --badge-bordure: var(--statut-marque-bordure); }
.badge-statut--information { --badge-fond: var(--statut-information-fond); --badge-texte: var(--statut-information-texte); --badge-bordure: var(--statut-information-bordure); }
.badge-statut--succes      { --badge-fond: var(--statut-succes-fond);      --badge-texte: var(--statut-succes-texte);      --badge-bordure: var(--statut-succes-bordure); }
.badge-statut--attention   { --badge-fond: var(--statut-attention-fond);   --badge-texte: var(--statut-attention-texte);   --badge-bordure: var(--statut-attention-bordure); }
.badge-statut--erreur      { --badge-fond: var(--statut-erreur-fond);      --badge-texte: var(--statut-erreur-texte);      --badge-bordure: var(--statut-erreur-bordure); }
.badge-statut--etape       { --badge-fond: var(--statut-etape-fond);       --badge-texte: var(--statut-etape-texte);       --badge-bordure: var(--statut-etape-bordure); }

.badge-statut--cat-1 { --badge-fond: var(--categorie-1-fond); --badge-texte: var(--categorie-1-texte); --badge-bordure: transparent; }
.badge-statut--cat-2 { --badge-fond: var(--categorie-2-fond); --badge-texte: var(--categorie-2-texte); --badge-bordure: transparent; }
.badge-statut--cat-3 { --badge-fond: var(--categorie-3-fond); --badge-texte: var(--categorie-3-texte); --badge-bordure: transparent; }
.badge-statut--cat-4 { --badge-fond: var(--categorie-4-fond); --badge-texte: var(--categorie-4-texte); --badge-bordure: transparent; }
.badge-statut--cat-5 { --badge-fond: var(--categorie-5-fond); --badge-texte: var(--categorie-5-texte); --badge-bordure: transparent; }
.badge-statut--cat-6 { --badge-fond: var(--categorie-6-fond); --badge-texte: var(--categorie-6-texte); --badge-bordure: transparent; }
.badge-statut--cat-7 { --badge-fond: var(--categorie-7-fond); --badge-texte: var(--categorie-7-texte); --badge-bordure: transparent; }
.badge-statut--cat-8 { --badge-fond: var(--categorie-8-fond); --badge-texte: var(--categorie-8-texte); --badge-bordure: transparent; }

/* La règle sombre des grilles et celle des lignes sélectionnées imposent une couleur de texte
   aux cellules en !important ; le badge garde la sienne. */
.fluent-data-grid td .badge-statut {
    color: var(--badge-texte);
}

button.badge-statut {
    cursor: pointer;
    transition: border-color var(--duree-rapide) var(--courbe-entree);
}

button.badge-statut:hover {
    border-color: var(--badge-texte);
}

button.badge-statut:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

/* Élément désactivé affiché à la demande dans une liste qui masque d'ordinaire les inactifs.
   Contour sans fond : en sombre, --neutral-layer-3 donnait une pastille noire, l'élément le plus
   appuyé de la ligne, pour une simple mention. */
.badge-desactive {
    display: inline-block;
    margin-left: 8px;
    background: transparent;
    color: var(--neutral-foreground-rest);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 10px;
    padding: 1px 8px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    vertical-align: middle;
}

/* Colonne de comptage : chiffres à chasse fixe, les unités restent alignées d'une ligne à l'autre */
.col-nombre {
    font-variant-numeric: tabular-nums;
}

/* Colonne d'appoint (description…) : en texte secondaire, la colonne d'identification ressort
   sans graisse ajoutée. Cellules seulement, l'en-tête garde le ton des autres. */
td.col-secondaire {
    color: var(--texte-secondaire);
}

/* La règle sombre des grilles impose --neutral-foreground-rest en !important à toute cellule. */
html[data-bs-theme="dark"] .fluent-data-grid td.col-secondaire {
    color: var(--texte-secondaire) !important;
}

/* Zone de filtres - hauteur fixe */
.list-page-filters {
    flex-shrink: 0;
}

/* Conteneur de la grille - prend l'espace restant et scrolle en interne.
   min-height: 0 et non 200px : un plancher pousse le paginateur hors de la card sur un
   petit écran, ce qui recrée l'ascenseur qu'on cherche à supprimer. */
.list-page-grid-container {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* La grille elle-même - largeur fixée, pas de scroll horizontal */
.list-page-grid-container fluent-data-grid,
.list-page-grid-container .fluent-data-grid {
    flex: 1;
    min-height: 0;
    width: 100% !important;
    max-width: 100% !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    /* Fix: FluentDataGrid met grid-template-rows: auto 1fr par défaut, ce qui fait
       que la première ligne de données prend tout l'espace restant. On force auto. */
    grid-template-rows: auto !important;
    /* Fix: garder les lignes en haut quand il y en a peu */
    align-content: start !important;
}

/* Footer de la liste (pagination + compteur) - hauteur fixe */
.list-page-footer {
    flex-shrink: 0;
    padding-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Version compacte pour écrans plus petits */
@media (max-height: 800px) {
    .list-page-container {
        height: calc(var(--hauteur-ecran) - 140px);
    }
}

/* Version plus haute pour grands écrans */
@media (min-height: 1080px) {
    .list-page-container {
        height: calc(var(--hauteur-ecran) - 180px);
    }
}

/* Mobile - scroll global assumé : la liste prend sa hauteur naturelle et c'est .main-content
   qui défile. La pagination adaptative ne mesure rien sous 768px (viewport-service.js), la
   taille de page est fixée à GridMetrics.MobileItemsPerPage : pas de plafond en hauteur ici,
   il recréait un ascenseur interne au-dessus du paginateur. */
@media (max-width: 768px) {
    .list-page-container {
        height: auto;
        min-height: auto;
    }

    .list-page-card {
        overflow: visible;
    }

    .list-page-grid-container {
        overflow: visible;
    }
}

/* Fix pour FluentDataGrid avec AutoItemsPerPage */
.list-page-grid-container[data-auto-height="true"] {
    overflow-y: hidden;
}

/* Ensure FluentCard padding doesn't affect layout calculations */
.list-page-card fluent-card {
    display: flex;
    flex-direction: column;
    height: 100%;
}


/* ============================================
   EDIT LISTE - Layout full-viewport
   Card Paramétrage fixe + Card Membres extensible
   ============================================ */
.edit-liste-container {
    display: flex;
    flex-direction: column;
    height: calc(var(--hauteur-ecran) - 160px);
    min-height: 400px;
    width: 100%;
    gap: 12px;
}

/* Wrapper div pour contrôler le flex (fluent-card a des styles internes) */
.edit-liste-membres-wrapper {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.edit-liste-membres-card {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 !important;
    min-height: 0 !important;
    overflow: hidden !important;
}

.edit-liste-membres-content {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    gap: 10px;
}

.edit-liste-grid-container {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}

/* Neutraliser position:sticky sur les TH (inline style du FluentDataGrid)
   qui gonfle artificiellement le scrollHeight du conteneur */
.edit-liste-grid-container th {
    position: static !important;
}

/* Card Membres réduite (toggle collapse, usage abonnement) */
.edit-liste-membres-wrapper.collapsed {
    flex: 0 0 auto;
}

/* Card Rôles non inscrits (usage abonnement) — hauteur naturelle */
.edit-liste-roles-wrapper {
    flex: 0 0 auto;
}

/* Mode abonnement : hauteur illimitée, le scroll se fait au niveau de la page */
.edit-liste-container.abonnement {
    height: auto;
    min-height: unset;
}

.edit-liste-container.abonnement .edit-liste-membres-wrapper {
    flex: 0 0 auto;
}

.edit-liste-container.abonnement .edit-liste-membres-card {
    flex: unset !important;
    min-height: unset !important;
    overflow: visible !important;
}

.edit-liste-container.abonnement .edit-liste-membres-content {
    flex: unset;
    min-height: unset;
}

.edit-liste-container.abonnement .edit-liste-grid-container {
    flex: unset;
    min-height: unset;
    overflow-y: visible;
}

/* Badge orange "N manquant(s)" dans le header de colonne */
.edit-liste-manquant-badge {
    cursor: pointer;
    background: transparent;
    color: #f59e0b;
    border: 1px solid #f59e0b;
    border-radius: 10px;
    padding: 0 6px;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    user-select: none;
}

.edit-liste-manquant-badge:hover {
    background: rgba(245, 158, 11, 0.15);
}

.edit-liste-manquant-badge.active {
    background: #f59e0b;
    color: white;
}

@media (max-height: 800px) {
    .edit-liste-container {
        height: calc(var(--hauteur-ecran) - 140px);
    }
}

@media (min-height: 1080px) {
    .edit-liste-container {
        height: calc(var(--hauteur-ecran) - 180px);
    }
}

@media (max-width: 768px) {
    .edit-liste-container {
        height: auto;
        min-height: auto;
    }

    .edit-liste-membres-card {
        overflow: visible;
    }

    .edit-liste-grid-container {
        overflow-y: visible;
    }
}

/* FluentAutocomplete multi-select : forcer le wrap des chips dans les dialogs */
.autocomplete-wrap fluent-autocomplete {
    width: 100%;
    max-width: 100%;
}

.autocomplete-wrap fluent-autocomplete::part(listbox) {
    max-height: 200px;
}

.autocomplete-wrap fluent-autocomplete::part(selected-options) {
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
}

/* FluentAutocomplete — affichage "champ texte" sans badge/croix */
.autocomplete-flat fluent-badge {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    font-size: inherit;
    color: var(--neutral-foreground-rest);
}

.autocomplete-flat fluent-badge::part(control) {
    background: transparent !important;
    padding: 0 !important;
    color: var(--neutral-foreground-rest) !important;
}

/* Masquer la croix "Remove" dans le badge (SVG inline) */
.autocomplete-flat fluent-badge svg[role="button"] {
    display: none !important;
}

/* Masquer le bouton "Clear" du champ (SVG avec slot=end) */
.autocomplete-flat svg[slot="end"],
.autocomplete-flat fluent-text-field svg[role="button"][slot="end"] {
    display: none !important;
}

/* FluentDataGrid — colonne de sélection (checkboxes) en mode sélection.
   Cacher le bouton "3 points" (col-options) et permettre l'affichage complet de la checkbox. */
.col-select .col-header-cell-text {
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
.col-select .col-options-button {
    display: none !important;
}
.col-select {
    overflow: visible !important;
}

/* Barre d'actions rendue juste au-dessus de la grille (ListePage ActionsAboveList) */
/* Colonne d'icône : les en-têtes de FluentDataGrid portent un min-width de 100px. Sur une
   colonne plus étroite, l'en-tête déborde à droite et son titre n'est plus aligné sur les
   cellules — d'où cette neutralisation, à poser via le Class de la colonne. */
.col-etroit {
    min-width: 0 !important;
}

.list-page-toolbar {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
}

/* Banner "sélectionner toutes les pages" (style Gmail) */
.select-all-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    border-radius: 4px;
    font-size: 13px;
    color: #1e40af;
    flex-shrink: 0;
    margin-bottom: 4px;
}
.select-all-banner-link {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: #1d4ed8;
    font-weight: 600;
    text-decoration: underline;
    font-size: 13px;
}
.select-all-banner-link:hover {
    color: #1e3a8a;
}
.select-all-banner-link:disabled {
    opacity: 0.6;
    cursor: wait;
}

/* Touche clavier dans la card de raccourcis (mode revue cotisation) */
.revue-kbd {
    display: inline-block;
    padding: 1px 6px;
    background: var(--neutral-layer-card-container);
    border: 1px solid var(--neutral-stroke-rest);
    border-bottom-width: 2px;
    border-radius: 4px;
    font-size: 12px;
    font-family: monospace;
    color: var(--neutral-foreground-rest);
    white-space: nowrap;
}

/* ========================================
   RADZEN SCHEDULER — intégration thème FluentUI
   Page : /evenements (vue Agenda)
   ======================================== */

.rz-scheduler {
    font-family: var(--body-font);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    background: var(--neutral-layer-1);
    color: var(--neutral-foreground-rest);
}

.rz-scheduler-toolbar {
    background: var(--neutral-layer-2);
    border-bottom: 1px solid var(--neutral-stroke-rest);
    padding: 6px 10px;
    gap: 6px;
}

.rz-scheduler-toolbar .rz-button {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    border: none;
    border-radius: 4px;
    padding: 4px 12px;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.1s;
}

.rz-scheduler-toolbar .rz-button:hover {
    background: var(--accent-fill-hover);
}

.rz-scheduler-toolbar .rz-button.rz-button-secondary,
.rz-scheduler-toolbar .rz-button[class*="outline"] {
    background: transparent;
    color: var(--neutral-foreground-rest);
    border: 1px solid var(--neutral-stroke-rest);
}

.rz-scheduler-toolbar .rz-button.rz-state-active {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
}

/* En-têtes de jours/heures */
.rz-scheduler .rz-slot-header,
.rz-scheduler .rz-day-slot-header {
    background: var(--neutral-layer-2);
    border-color: var(--neutral-stroke-rest);
    font-size: 12px;
    font-weight: 600;
    color: var(--neutral-foreground-rest);
}

/* Cellules de la grille */
.rz-scheduler .rz-slot {
    border-color: var(--neutral-stroke-rest);
}

/* Jour actuel mis en évidence */
.rz-scheduler .rz-today {
    background: color-mix(in srgb, var(--accent-fill-rest) 8%, transparent);
}

/* Événements dans la vue mois */
.rz-event-content {
    font-size: 11px !important;
    padding: 1px 4px !important;
    line-height: 1.3;
}

/* Template personnalisé des événements */
.evenement-appointment {
    display: flex;
    align-items: center;
    gap: 3px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 11px;
    font-weight: 500;
}

.appointment-inscrits {
    font-size: 10px;
    opacity: 0.85;
    flex-shrink: 0;
}

/* ============================================
   Calendrier unifié — Toggles types
   ============================================ */

.calendrier-type-toggles {
    display: flex;
    gap: 6px;
    align-items: center;
}

.calendrier-type-toggle {
    cursor: pointer;
    padding: 4px 12px;
    border-radius: 16px;
    font-size: 0.85em;
    border: 1px solid var(--neutral-stroke-rest);
    background: transparent;
    color: var(--neutral-foreground-rest);
    transition: all 0.15s;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.calendrier-type-toggle:hover {
    background: var(--neutral-layer-2);
}

.calendrier-type-toggle-evenements.calendrier-type-toggle-active {
    background: #6366f1;
    color: white;
    border-color: #6366f1;
    font-weight: 600;
}

.calendrier-type-toggle-reunions.calendrier-type-toggle-active {
    background: #0d9488;
    color: white;
    border-color: #0d9488;
    font-weight: 600;
}

/* Commutateur de vue (ui-patterns §3) : groupe segmenté posé à gauche, après le titre. Un
   réglage d'affichage, pas une action : la droite reste aux boutons d'action. */
.selecteur-vue {
    display: inline-flex;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon-s);
    overflow: hidden;
    flex-shrink: 0;
    margin-left: var(--espace-6);
}
/* Seul sur sa ligne, pour choisir un mode de saisie dans un dialog : aucun titre dont s'écarter. */
.selecteur-vue-seul .selecteur-vue {
    margin-left: 0;
}
/* Dans un en-tête en space-between, l'espace libre va à cette marge : le commutateur reste collé
   au titre et les actions au bord droit, au lieu de se retrouver centré entre les deux. */
.page-header > .selecteur-vue {
    margin-right: auto;
}
.selecteur-vue__option {
    cursor: pointer;
    padding: 5px 12px;
    font: inherit;
    font-size: var(--taille-s);
    line-height: 1.2;
    border: none;
    background: transparent;
    color: var(--texte-principal);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    transition: background var(--duree-rapide) var(--courbe-sortie);
}
.selecteur-vue__option + .selecteur-vue__option {
    border-left: 1px solid var(--bordure);
}
.selecteur-vue__option:hover {
    background: var(--surface-survol);
}
.selecteur-vue__option:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: -2px;
}
.selecteur-vue__option[aria-pressed="true"] {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    font-weight: 600;
}
.selecteur-vue__option[aria-pressed="true"]:hover {
    background: var(--accent-fill-hover);
}

/* Colonne barre de couleur dans la vue liste calendrier */
.col-color-bar {
    padding: 0 !important;
    width: 6px !important;
    min-width: 6px !important;
    overflow: visible !important;
}

.col-color-bar .col-options-button { display: none !important; }

/* ============================================
   Module Signalement (bugs & améliorations)
   ============================================ */

.signalement-badge-btn {
    position: relative;
    display: inline-flex;
}

.signalement-badge-inner-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 6px;
    border: none;
    background: transparent;
    cursor: pointer;
    color: inherit;
    opacity: 0.85;
    transition: opacity 0.15s, background 0.15s;
    padding: 0;
}

.signalement-badge-inner-btn:hover {
    opacity: 1;
    background: var(--bandeau-survol);
}

.signalement-badge-count {
    position: absolute;
    top: -4px;
    right: -6px;
    background: var(--error);
    color: white;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    line-height: 1;
    z-index: 1;
}

/* Signalements : captures jointes (ticket #144) */
/* Couleur explicite : le dialogue de saisie est rendu dans le badge de l'en-tête, dont le texte
   est blanc ; sans elle, les noms des images disparaissaient sur le fond clair. */
.signalement-piece-attachee {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
    padding: 6px 10px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    background: var(--neutral-layer-2);
    color: var(--neutral-foreground-rest);
}

.signalement-piece-attachee__nom {
    font-size: 13px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.signalement-piece-attachee__taille {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
}

.signalement-nb-pieces {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: 12px;
}

.signalement-galerie {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
}

.signalement-vignette {
    width: 140px;
    height: 96px;
    padding: 0;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    overflow: hidden;
    background: var(--neutral-layer-2);
    cursor: zoom-in;
}

.signalement-vignette:hover,
.signalement-vignette:focus-visible {
    border-color: var(--accent-fill-rest);
    outline: none;
}

.signalement-vignette img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Visionneuse d'images : quasi plein écran, l'image seule défile */
fluent-dialog.dialog-visionneuse::part(control) {
    width: 95vw !important;
    max-width: 95vw !important;
    height: 92vh !important;
    max-height: 92vh !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}

fluent-dialog.dialog-visionneuse .fluent-dialog-body {
    flex: 1 !important;
    min-height: 0 !important;
    overflow: hidden !important;
    padding: 0 !important;
}

.visionneuse-entete {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
}

.visionneuse-position {
    font-size: 13px;
    color: var(--neutral-foreground-hint);
    font-variant-numeric: tabular-nums;
}

.visionneuse-lien {
    font-size: 13px;
    color: var(--accent-foreground-rest);
}

/* display:flex + margin:auto sur l'image, et non justify-content:center : centrée par le
   flex, une image plus grande que le cadre déborderait à gauche, hors de portée du défilement. */
.visionneuse-cadre {
    display: flex;
    width: 100%;
    height: 100%;
    overflow: auto;
    background: var(--neutral-layer-3);
    outline: none;
}

.visionneuse-image {
    margin: auto;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    cursor: zoom-in;
}

.visionneuse-image--reelle {
    max-width: none;
    max-height: none;
    cursor: zoom-out;
}

/* Contexte technique d'un signalement (ticket #146) */
.signalement-contexte {
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    padding: 6px 10px;
    font-size: 12px;
}

.signalement-contexte summary {
    cursor: pointer;
    color: var(--neutral-foreground-hint);
}

.signalement-contexte dl {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 4px 12px;
    margin: 8px 0 2px;
}

.signalement-contexte dt {
    color: var(--neutral-foreground-hint);
}

.signalement-contexte dd {
    margin: 0;
    min-width: 0;
}

.signalement-contexte__navigateur {
    overflow-wrap: anywhere;
    font-family: Consolas, monospace;
    font-size: 11px;
}

/* Fil d'activité d'un signalement (ticket #145) */
.signalement-fil {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
}

.signalement-fil-vide {
    margin-top: 4px;
    font-size: 12px;
    color: var(--neutral-foreground-hint);
}

.signalement-fil-entree {
    padding: 6px 10px;
    border-left: 3px solid var(--accent-fill-rest);
    border-radius: 0 4px 4px 0;
    background: var(--neutral-layer-2);
    font-size: 13px;
}

.signalement-fil-entree--interne {
    border-left-color: #d97706;
}

.signalement-fil-entree__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 11px;
    color: var(--neutral-foreground-hint);
}

.signalement-fil-badge {
    padding: 0 6px;
    border-radius: 8px;
    border: 1px solid #d97706;
    color: #d97706;
    font-size: 10px;
    font-weight: 600;
}

.signalement-fil-entree__statut {
    margin-top: 2px;
    font-weight: 600;
}

.signalement-fil-entree__texte {
    margin-top: 2px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.signalement-fil-entree__version summary {
    margin-top: 2px;
    font-weight: 600;
    cursor: pointer;
}

/* Fiche d'un signalement (ticket #147) */
.signalement-zone-collage {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    padding: 10px;
    border: 2px dashed var(--neutral-stroke-rest);
    border-radius: 4px;
    font-size: 12px;
    color: var(--neutral-foreground-hint);
    cursor: text;
}

.signalement-zone-collage:focus {
    outline: none;
    border-color: var(--accent-fill-rest);
    color: var(--neutral-foreground-rest);
}

/* Menu flottant ouvert au clic sur une pastille (statut d'une nomination). La page pose left et
   top en ligne puis le ramène dans l'écran par __clampPopupInViewport ; le voile le referme. */
.menu-flottant-voile {
    position: fixed;
    inset: 0;
    z-index: 999;
}

.menu-flottant {
    position: fixed;
    z-index: 1000;
    min-width: 230px;
    padding: var(--espace-1);
    background: var(--neutral-layer-floating);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: var(--rayon-m);
    box-shadow: var(--ombre-2);
}

.menu-flottant__titre {
    margin: var(--espace-1) var(--espace-2) var(--espace-2);
    font-size: var(--taille-s);
    font-weight: var(--graisse-forte);
}

/* Zone de dépôt des captures (dialogue de création, fiche). FluentInputFile pose son contenu, le
   texte d'invite, au-dessus du champ fichier invisible : cliquer ou appuyer sur le texte
   n'atteignait pas le champ. Au téléphone le texte couvrait toute la zone et le sélecteur de
   photos ne s'ouvrait jamais, alors qu'iOS n'a pas de collage d'image (signalement 470). Le
   contenu laisse passer le pointeur jusqu'au champ. */
.zone-captures .inputfile-content {
    pointer-events: none;
}

.signalement-lien-mes {
    font-size: 13px;
    color: var(--accent-foreground-rest);
}

/* Dialog signalement — scroll interne pour petits écrans */
fluent-dialog.dialog-signalement::part(control) {
    max-height: calc(var(--hauteur-ecran) * 0.9) !important;
    display: flex !important;
    flex-direction: column !important;
}

fluent-dialog.dialog-signalement .fluent-dialog-body {
    overflow-y: auto !important;
    flex: 1 !important;
    min-height: 0 !important;
}

fluent-dialog.dialog-signalement .fluent-dialog-footer {
    flex-shrink: 0 !important;
}

/* Badges statut cliquables dans la grille signalements */
.statut-badge-clickable {
    cursor: pointer;
    transition: opacity 0.15s;
    display: inline-block;
}

.statut-badge-clickable:hover {
    opacity: 0.8;
}

.statut-popover-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px;
}

/* ============================================
   Toggle Dark/Light Mode - Bouton dans le header
   ============================================ */

.theme-toggle-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 6px;
    background: transparent;
    border: none;
    cursor: pointer;
    color: inherit;
    opacity: 0.85;
    transition: opacity 0.15s, background 0.15s;
    padding: 0;
}

.theme-toggle-badge:hover {
    opacity: 1;
    background: var(--bandeau-survol);
}

/* ============================================
   DARK MODE - Overrides CSS personnalisés
   ============================================ */

/* Liens */
[data-bs-theme="dark"] a,
[data-bs-theme="dark"] .btn-link {
    color: var(--texte-lien);
}

[data-bs-theme="dark"] a:hover,
[data-bs-theme="dark"] .btn-link:hover {
    color: var(--marque-200);
}

/* Radzen Scheduler */
[data-bs-theme="dark"] .rz-scheduler {
    background-color: var(--neutral-layer-1);
    color: var(--neutral-foreground-rest);
}

[data-bs-theme="dark"] .rz-scheduler .rz-scheduler-toolbar,
[data-bs-theme="dark"] .rz-scheduler .rz-scheduler-body {
    background-color: var(--neutral-layer-1);
    border-color: var(--neutral-stroke-rest);
    color: var(--neutral-foreground-rest);
}

[data-bs-theme="dark"] .rz-scheduler .rz-event-content {
    background-color: var(--accent-fill-rest);
}

[data-bs-theme="dark"] .rz-scheduler .rz-slot-header,
[data-bs-theme="dark"] .rz-scheduler .rz-resource-header {
    background-color: var(--neutral-layer-2);
    color: var(--neutral-foreground-rest);
    border-color: var(--neutral-stroke-rest);
}

[data-bs-theme="dark"] .rz-scheduler td,
[data-bs-theme="dark"] .rz-scheduler th {
    border-color: var(--neutral-stroke-rest);
}

/* ========================================
   TEMPLATE PREVIEW — Aperçu de l'email rendu
   Le contenu reste sur fond blanc (l'email est conçu pour fond blanc),
   mais l'encadrement et le contraste s'adaptent au thème.
   ======================================== */
.template-preview-frame,
.template-preview-html {
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    overflow-y: auto;
    background-color: #f4f4f4;
}

.template-preview-frame {
    padding: 0;
}

.template-preview-html {
    /* Pas de padding : l'iframe à l'intérieur est en width:100% avec son propre padding
       via le wrapper HTML5, ce qui donne un rendu fidèle sans marge externe double. */
    padding: 0;
    background-color: white;
    color: #1a1a1a;
}

[data-bs-theme="dark"] .template-preview-frame {
    background-color: var(--neutral-layer-2);
    border-color: rgba(255, 255, 255, 0.12);
}

[data-bs-theme="dark"] .template-preview-html {
    /* Conserver fond blanc — un email est conçu pour fond blanc.
       On ajoute un cadre net pour bien le détacher du reste de l'UI sombre. */
    border: 1px solid rgba(255, 255, 255, 0.18);
    box-shadow: 0 0 0 4px var(--neutral-layer-2);
}

/* Radzen HtmlEditor */
[data-bs-theme="dark"] .rz-html-editor {
    background-color: var(--neutral-layer-1);
    color: var(--neutral-foreground-rest);
    border-color: var(--neutral-stroke-rest);
}

[data-bs-theme="dark"] .rz-html-editor-toolbar {
    background-color: var(--neutral-layer-2);
    border-color: var(--neutral-stroke-rest);
}

[data-bs-theme="dark"] .rz-html-editor-content {
    background-color: var(--neutral-layer-1);
    color: var(--neutral-foreground-rest);
}

/* Logo footer et accueil — fond blanc pour lisibilité sur fond sombre */
[data-bs-theme="dark"] .app-footer-logo,
[data-bs-theme="dark"] .home-logo {
    background: white;
    border-radius: 6px;
    padding: 4px 8px;
}

/* KPI Strip Cards — fonds semi-transparents adaptés au dark */
[data-bs-theme="dark"] .kpi-strip .kpi-card--green   { background: rgba(34,197,94,0.12); border-color: rgba(34,197,94,0.35); color: #86efac; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--blue    { background: rgba(59,130,246,0.12); border-color: rgba(59,130,246,0.35); color: #93c5fd; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--indigo  { background: rgba(99,102,241,0.12); border-color: rgba(99,102,241,0.35); color: #a5b4fc; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--amber   { background: rgba(245,158,11,0.12); border-color: rgba(245,158,11,0.35); color: #fcd34d; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--avoir   { background: rgba(249,115,22,0.12); border-color: rgba(249,115,22,0.35); color: #fdba74; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--emerald { background: rgba(16,185,129,0.12); border-color: rgba(16,185,129,0.35); color: #6ee7b7; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--violet  { background: rgba(139,92,246,0.12); border-color: rgba(139,92,246,0.35); color: #c4b5fd; }
[data-bs-theme="dark"] .kpi-strip .kpi-card--red     { background: rgba(239,68,68,0.12); border-color: rgba(239,68,68,0.35); color: #fca5a5; }

/* Campagne — stat cards */
.campagne-stat-card {
    text-align: center;
    padding: 15px;
    border-radius: 8px;
    cursor: pointer;
    transition: outline 0.2s;
}
.campagne-stat--neutral { background-color: var(--neutral-layer-2); }
.campagne-stat--green   { background-color: #dcfce7; }
.campagne-stat--blue    { background-color: #dbeafe; }
.campagne-stat--purple  { background-color: #f3e8ff; }
.campagne-stat--red     { background-color: #fef2f2; padding: 10px; }
.campagne-stat--orange  { background-color: #fff7ed; padding: 10px; }
.campagne-stat--active-green  { outline: 2px solid #22c55e; }
.campagne-stat--active-blue   { outline: 2px solid #3b82f6; }
.campagne-stat--active-purple { outline: 2px solid #8b5cf6; }
.campagne-stat--active-red    { outline: 2px solid #ef4444; }
.campagne-stat--active-orange { outline: 2px solid #f59e0b; }
.campagne-stat-value--green  { color: #16a34a; }
.campagne-stat-value--blue   { color: #3b82f6; }
.campagne-stat-value--purple { color: #8b5cf6; }
.campagne-stat-value--red    { color: #ef4444; }
.campagne-stat-value--orange { color: #f59e0b; }

[data-bs-theme="dark"] .campagne-stat--green  { background: rgba(34,197,94,0.12); }
[data-bs-theme="dark"] .campagne-stat--blue   { background: rgba(59,130,246,0.12); }
[data-bs-theme="dark"] .campagne-stat--purple { background: rgba(139,92,246,0.12); }
[data-bs-theme="dark"] .campagne-stat--red    { background: rgba(239,68,68,0.12); }
[data-bs-theme="dark"] .campagne-stat--orange { background: rgba(245,158,11,0.12); }
[data-bs-theme="dark"] .campagne-stat-value--green  { color: #86efac; }
[data-bs-theme="dark"] .campagne-stat-value--blue   { color: #93c5fd; }
[data-bs-theme="dark"] .campagne-stat-value--purple { color: #c4b5fd; }
[data-bs-theme="dark"] .campagne-stat-value--red    { color: #fca5a5; }
[data-bs-theme="dark"] .campagne-stat-value--orange { color: #fcd34d; }

/* Sondage de campagne : tuile Réponses et dépouillement */
.campagne-stat--teal { background-color: #ccfbf1; }
.campagne-stat--active-teal { outline: 2px solid #14b8a6; }
.campagne-stat-value--teal { color: #0d9488; }
[data-bs-theme="dark"] .campagne-stat--teal { background: rgba(20,184,166,0.12); }
[data-bs-theme="dark"] .campagne-stat-value--teal { color: #5eead4; }

.sondage-badge {
    background: var(--neutral-layer-3);
    border-radius: 12px;
    padding: 2px 10px;
    font-size: 12px;
    color: var(--neutral-foreground-rest);
    white-space: nowrap;
}

.sondage-barre-ligne {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
    font-size: 13px;
}

.sondage-barre-libelle {
    flex: 0 0 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--neutral-foreground-rest);
}

.sondage-barre-fond {
    flex: 1;
    height: 14px;
    background: var(--neutral-layer-3);
    border-radius: 7px;
    overflow: hidden;
    min-width: 60px;
}

.sondage-barre-valeur {
    height: 100%;
    background: var(--accent-fill-rest);
    border-radius: 7px;
    transition: width 0.3s ease;
}

.sondage-barre-chiffre {
    flex: 0 0 90px;
    text-align: right;
    color: var(--neutral-foreground-hint);
    white-space: nowrap;
}

.sondage-textes {
    max-height: 200px;
    overflow-y: auto;
    margin-top: 4px;
}

.sondage-texte {
    padding: 4px 8px;
    margin-bottom: 4px;
    background: var(--neutral-layer-2);
    border-radius: 4px;
    font-size: 13px;
    white-space: pre-line;
}

.sondage-badge-repondu {
    background: rgba(20,184,166,0.15);
    color: #0d9488;
    border-radius: 10px;
    padding: 1px 8px;
    font-size: 11px;
    white-space: nowrap;
}

[data-bs-theme="dark"] .sondage-badge-repondu { color: #5eead4; }

/* Cotisation exonérée (signalement 433) : soldée sans facture, distincte du vert « À jour » */
.badge-exoneree {
    display: inline-block;
    background: rgba(135,100,184,0.15);
    color: #6b4fa0;
    border: 1px solid rgba(135,100,184,0.45);
    border-radius: 10px;
    padding: 1px 8px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    cursor: default;
}

[data-bs-theme="dark"] .badge-exoneree { color: #c4b0e8; }

.sondage-resume {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--neutral-foreground-hint);
    font-size: 12px;
}

/* Select-All Banner — fond semi-transparent bleu */
[data-bs-theme="dark"] .select-all-banner {
    background: rgba(59,130,246,0.12);
    border-color: rgba(59,130,246,0.35);
    color: #93c5fd;
}
[data-bs-theme="dark"] .select-all-banner-link { color: #60a5fa; }
[data-bs-theme="dark"] .select-all-banner-link:hover { color: #93c5fd; }

/* Role Row Coloring — teintes subtiles en dark */
[data-bs-theme="dark"] .role-actif { background-color: rgba(34,197,94,0.1) !important; }
[data-bs-theme="dark"] .role-actif:hover { background-color: rgba(34,197,94,0.18) !important; }
[data-bs-theme="dark"] .role-termine { background-color: rgba(239,68,68,0.1) !important; }
[data-bs-theme="dark"] .role-termine:hover { background-color: rgba(239,68,68,0.18) !important; }

/* Panneaux "Organisations" — dark */
[data-bs-theme="dark"] .org-panel { border-color: rgba(255,255,255,0.12); background: transparent; }
[data-bs-theme="dark"] .org-panel-head { background: rgba(34,197,94,0.12); border-bottom-color: rgba(255,255,255,0.08); }
[data-bs-theme="dark"] .org-panel.terminated .org-panel-head { background: rgba(239,68,68,0.12); }
[data-bs-theme="dark"] .org-panel-body > div:first-child { border-right-color: rgba(255,255,255,0.08); }
[data-bs-theme="dark"] .op-label { color: #a19f9d; }
[data-bs-theme="dark"] .op-pill { color: #d0d0d0; background: rgba(255,255,255,0.1); }
[data-bs-theme="dark"] .op-pill.pos { color: #9ecbff; background: rgba(0,120,212,0.22); }

/* Dialog Dark Mode — overlay plus opaque et bordure pour contraste */
[data-bs-theme="dark"] fluent-dialog::part(overlay) {
    background: rgba(0, 0, 0, 0.7);
}
[data-bs-theme="dark"] fluent-dialog::part(control) {
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

/* Dialog Dark Mode — texte lisible sur fond sombre */
[data-bs-theme="dark"] fluent-dialog .fluent-dialog-header,
[data-bs-theme="dark"] fluent-dialog .fluent-dialog-body,
[data-bs-theme="dark"] fluent-dialog .fluent-dialog-footer {
    color: rgba(255, 255, 255, 0.9);
}

/* ==========================================
   SearchCard — Mode selector + Sauvegardées
   ========================================== */

.search-mode-group {
    display: flex;
    gap: 4px;
    align-items: center;
}

.search-mode-radio {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 5px 14px;
    border-radius: 20px;
    cursor: pointer;
    font-size: 0.88em;
    transition: all 0.15s ease;
    border: 1px solid var(--neutral-stroke-rest);
    background: transparent;
    user-select: none;
}

.search-mode-radio input[type="radio"] {
    margin: 0;
    accent-color: var(--accent-fill-rest);
}

.search-mode-radio:hover {
    background-color: var(--neutral-layer-2);
}

.search-mode-radio-active {
    background-color: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    border-color: var(--accent-fill-rest);
    font-weight: 600;
}

.search-mode-radio-active input[type="radio"] {
    accent-color: white;
}

fluent-button.saved-search-btn::part(control) {
    background: color-mix(in srgb, var(--accent-fill-rest) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-fill-rest) 30%, transparent);
    border-radius: 8px;
    padding: 6px 14px;
    font-weight: 500;
    transition: all 0.15s ease;
}

fluent-button.saved-search-btn:hover::part(control) {
    background: color-mix(in srgb, var(--accent-fill-rest) 25%, transparent);
}

/* ==========================================
   SearchCard — Filtres par champ (badges)
   ========================================== */

.filter-badge {
    cursor: pointer;
    user-select: none;
    padding: 4px 12px;
    font-size: 0.85em;
    border-radius: 16px;
    transition: all 0.15s ease;
}

.filter-badge:hover {
    opacity: 0.85;
    transform: scale(1.03);
}

.filter-badge-active {
    font-weight: 600;
}

.field-filters-zone {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    background-color: var(--neutral-layer-2);
    border-radius: 6px;
    border: 1px solid var(--neutral-stroke-rest);
}

.field-filter-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.field-filter-row fluent-text-field,
.field-filter-row fluent-select {
    flex: 1;
    min-width: 0;
}

/* Dropdown suggestions communes (adresse) */
.commune-suggestions-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1000;
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    max-height: 220px;
    overflow-y: auto;
    margin-top: 2px;
}
.commune-suggestion-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    cursor: pointer;
    font-size: 13px;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}
.commune-suggestion-item:last-child {
    border-bottom: none;
}
.commune-suggestion-item:hover {
    background: var(--neutral-layer-2);
}
.commune-cp {
    font-weight: 600;
    color: var(--accent-fill-rest);
    min-width: 52px;
}
.commune-nom {
    flex: 1;
}
.commune-cc {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    font-style: italic;
}

/* ========================================
   MODES DE DENSITÉ (data-density attribute sur <html>)
   Valeurs : "supercompact" | "compact" (défaut) | "normal"
   ======================================== */

/* --- Mode Normal --- */
[data-density="normal"] .list-page-container {
    gap: 16px;
}

[data-density="normal"] .responsive-field-group {
    gap: 16px;
}

[data-density="normal"] fluent-card {
    --card-padding: 20px;
}

[data-density="normal"] .page-header {
    margin-bottom: 16px;
}

/* --- Mode Super Compact --- */
[data-density="supercompact"] .list-page-container {
    gap: 8px;
}

[data-density="supercompact"] .responsive-field-group {
    gap: 8px;
}

[data-density="supercompact"] .page-header {
    margin-bottom: 6px;
}

[data-density="supercompact"] .list-page-card-content {
    gap: 6px;
}

[data-density="supercompact"] .list-page-footer {
    padding-top: 6px;
    gap: 4px;
}

/* Grille super compacte : lignes plus serrées.
   On agit sur le padding et l'interligne, jamais sur la hauteur : une cellule qui tient sur
   deux lignes (raison sociale + SIREN) doit pouvoir rester sur deux lignes, c'est la mesure
   du rendu réel qui en tient compte. */
[data-density="supercompact"] .list-page-grid-container .fluent-data-grid th,
[data-density="supercompact"] .list-page-grid-container .fluent-data-grid td {
    font-size: 13px;
    line-height: 1.25;
}

[data-density="supercompact"] .list-page-grid-container .fluent-data-grid td {
    padding-top: 2px;
    padding-bottom: 2px;
}

/* Navigation super compacte */
.nav-menu-supercompact fluent-nav-link,
.nav-menu-supercompact fluent-nav-group {
    font-size: 0.75rem;
}

.nav-menu-supercompact fluent-nav-group::part(content) {
    font-size: 0.75rem;
}

/* Font body réduit en super compact */
[data-density="supercompact"] .content {
    font-size: 13px;
}

/* Card padding réduit en super compact */
[data-density="supercompact"] fluent-card::part(control) {
    padding: 12px;
}

/* Font body augmenté en normal */
[data-density="normal"] .content {
    font-size: 15px;
}

/* Macro-tâches — vue hiérarchique */
.macro-row {
    background: var(--neutral-layer-2) !important;
    font-weight: 500;
}
.micro-row {
    font-size: 13px;
}

/* ===== Dialog d'import Brevo ===== */
.brevo-import-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.brevo-import-body code {
    background: var(--neutral-layer-2);
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 0.9em;
}

.brevo-import-loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 32px 0;
    color: var(--neutral-foreground-hint);
}

.brevo-import-grid {
    border: 1px solid var(--neutral-stroke-divider-rest);
    border-radius: 4px;
    max-height: 320px;
    overflow-y: auto;
    overflow-x: hidden;
}

.brevo-import-grid fluent-data-grid {
    width: 100%;
}

.brevo-import-grid fluent-data-grid-row[row-type="header"] {
    background: var(--neutral-layer-2);
}

.brevo-import-grid fluent-data-grid-row {
    cursor: pointer;
    border-bottom: 1px solid var(--neutral-stroke-divider-rest);
}

.brevo-import-grid fluent-data-grid-row:hover:not([row-type="header"]) {
    background: var(--neutral-fill-stealth-hover);
}

.brevo-import-grid fluent-data-grid-row.brevo-row-selected {
    background: var(--accent-fill-rest) !important;
    color: var(--foreground-on-accent-rest);
}

.brevo-import-grid fluent-data-grid-row.brevo-row-selected fluent-data-grid-cell {
    color: var(--foreground-on-accent-rest);
    font-weight: 500;
}

.brevo-import-selected {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: var(--neutral-layer-2);
    border-radius: 4px;
    min-height: 36px;
    font-size: 13px;
}

.brevo-import-hint {
    color: var(--neutral-foreground-hint);
    font-style: italic;
}

.brevo-import-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
}

/* ============================================================
   Sidebar arborescente des évènements (ListeEvenements)
   Layout : sidebar (240px) + carte liste (flex:1)
   Cachée en dessous de 1200px pour préserver la largeur utile.
   ============================================================ */
.evenements-sidebar {
    flex: 0 0 240px;
    max-width: 240px;
    background: var(--neutral-layer-2);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    padding: 8px 6px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 13px;
}

.evenements-sidebar-loading {
    display: flex;
    justify-content: center;
    padding: 20px 0;
}

.evenements-sidebar-section {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.evenements-sidebar-separator {
    height: 1px;
    background: var(--neutral-stroke-rest);
    margin: 6px 4px;
}

.evenements-sidebar-node,
.evenements-sidebar-node-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    width: 100%;
    border: none;
    background: transparent;
    border-radius: 4px;
    cursor: pointer;
    text-align: left;
    color: var(--neutral-foreground-rest);
    font-size: inherit;
    font-family: inherit;
}

.evenements-sidebar-node:hover,
.evenements-sidebar-node-inline:hover {
    background: var(--neutral-fill-hover);
}

.evenements-sidebar-node.active,
.evenements-sidebar-annee-row.active {
    background: var(--accent-fill-rest);
    color: white;
}

.evenements-sidebar-node.active .evenements-sidebar-count,
.evenements-sidebar-annee-row.active .evenements-sidebar-count {
    background: rgba(255, 255, 255, 0.25);
    color: white;
}

.evenements-sidebar-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.evenements-sidebar-count {
    background: var(--neutral-fill-rest);
    color: var(--neutral-foreground-hint);
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    min-width: 22px;
    text-align: center;
}

.evenements-sidebar-annee {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.evenements-sidebar-annee-row {
    display: flex;
    align-items: center;
    border-radius: 4px;
    overflow: hidden;
}

.evenements-sidebar-annee-row:hover {
    background: var(--neutral-fill-hover);
}

.evenements-sidebar-annee-row.active:hover {
    background: var(--accent-fill-hover);
}

.evenements-sidebar-chevron {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 6px 4px 6px 6px;
    display: flex;
    align-items: center;
    color: inherit;
}

.evenements-sidebar-categories {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding-left: 22px;
}

.evenements-sidebar-node-cat {
    padding: 4px 8px;
    font-size: 12.5px;
}

/* Sous 1200px : on cache la sidebar (l'utilisateur peut utiliser les filtres au-dessus de la grille) */
@media (max-width: 1199.98px) {
    .evenements-sidebar { display: none; }
}

/* Filtre categorie du bandeau : doublon du rail tant que celui-ci est affiche, donc masque
   au-dessus de 1200px (signalement 422). Le calendrier n'a pas de rail : son bandeau garde le
   filtre a toutes les largeurs. */
@media (min-width: 1200px) {
    .liste-page-corps:has(> .evenements-sidebar) .filtre-categorie-repli { display: none; }
}

/* Carte « Capacité & Options » de l'événement (signalement 424) : un seul séparateur, visible dans
   les deux thèmes, et chaque sous-option en retrait sous l'option dont elle dépend. Le retrait de
   30px (case de 20px + marge du libellé de 10px) aligne la sous-option sur le texte de l'option
   parente, pas sur sa case. */
.carte-options-evenement fluent-checkbox {
    align-items: flex-start;
}

/* Sur un libellé de deux lignes, la case se comprimait à 17px et se centrait entre les lignes :
   les carrés ne tombaient plus à intervalle régulier. */
.carte-options-evenement fluent-checkbox::part(control) {
    flex-shrink: 0;
}

.options-separateur {
    border: none;
    border-top: 1px solid var(--neutral-stroke-rest);
    margin: 0;
    width: 100%;
}

.option-dependante {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-left: 30px;
}

.option-avec-aide {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.option-aide {
    margin-left: 30px;
    color: var(--neutral-foreground-hint);
    font-size: var(--type-ramp-minus-1-font-size);
    line-height: var(--type-ramp-minus-1-line-height);
}

/* === Page Campagne de cotisations : stepper d'avancement === */
.campagne-etape-titre {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
}

/* ============================================
   Informations recueillies (saisie à la volée)
   ============================================ */

.information-badge-btn {
    position: relative;
    display: inline-flex;
}

.information-badge-inner-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 6px;
    border: none;
    background: transparent;
    cursor: pointer;
    color: inherit;
    opacity: 0.85;
    transition: opacity 0.15s, background 0.15s;
    padding: 0;
}

.information-badge-inner-btn:hover {
    opacity: 1;
    background: var(--bandeau-survol);
}

/* Cible imposée par l'écran appelant : non modifiable, donc affichée et non éditable. */
.information-cible-figee {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 12px;
    border-radius: 6px;
    border: 1px solid var(--neutral-stroke-rest);
    background: var(--neutral-fill-secondary-rest);
    font-weight: 600;
}

.informations-liste {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
}

.information-ligne {
    border-left: 3px solid var(--accent-fill-rest);
    padding: 4px 0 4px 10px;
}

.information-ligne__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.76rem;
    color: var(--neutral-foreground-hint);
}

.information-ligne__sep {
    opacity: 0.6;
}

.information-ligne__via {
    color: var(--accent-foreground-rest);
    text-decoration: none;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 10px;
    padding: 0 8px;
}

.information-ligne__via:hover {
    text-decoration: underline;
}

/* Le contenu est du texte saisi tel quel : les retours à la ligne comptent. */
.information-ligne__contenu {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-top: 2px;
}

/* Grille des contacts d'une fiche adhésion — signalement 393.
   Un contact peut cumuler cinq usages (Principal, Facturation, Révision, Comm., Signataire).
   Les badges passent alors sur deux rangs, mais la cellule de FluentDataGrid est haute de
   32 px en RowSize Small avec overflow:hidden : le second rang disparaissait sans le moindre
   indice, et la fiche affirmait qu'un président n'était destinataire que de deux choses.
   La ligne s'ajuste donc à son contenu ici — la grille compte peu de lignes. */
/* !important : FluentDataGrid pose la hauteur de rang sur la cellule elle-même, avec une
   spécificité que ce sélecteur ne dépasse pas. */
.contacts-grid .fluent-data-grid td,
.contacts-grid fluent-data-grid td {
    height: auto !important;
    min-height: 32px;
    overflow: visible;
    align-items: flex-start;
    /* La grille centre ses cellules : sans étirement, une ligne sélectionnée dont les
       usages tiennent sur deux rangs peint une bande bleue en escalier (signalement 393). */
    align-self: stretch;
    padding-top: 6px;
    padding-bottom: 6px;
}

/* Bloc de texte d'un echange (compte rendu, contenu d'email), partage par la fiche prospect
   et la boite de notifications (signalement 419). */
.detail-echange-bloc {
    white-space: pre-wrap;
    padding: 8px 10px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    background: var(--neutral-layer-2);
    font-size: 13px;
    overflow-wrap: anywhere;
}

/* Widget dont le chargement a echoue (signalement 420) : meme boite que les autres cartes du
   tableau de bord, un message lisible et un bouton pour reessayer. */
.widget-erreur {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 16px;
    height: 100%;
    box-sizing: border-box;
    background: var(--neutral-layer-card-container);
    border: 1px solid var(--neutral-stroke-divider-rest);
    border-left: 3px solid var(--warning);
    border-radius: 8px;
}

.widget-erreur-entete {
    display: flex;
    align-items: center;
    gap: 8px;
}

.widget-erreur-titre {
    font-weight: 600;
}

.widget-erreur-message {
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
}

/* ===== Fiche ouverte sans droit de modification =====
   La sécurité est tenue par les services ; ces règles retirent seulement ce qui ne servirait à rien.
   Les champs passent en ::part car ils vivent dans le Shadow DOM. */
.lecture-seule :is(fluent-text-field, fluent-text-area, fluent-number-field, fluent-select,
                   fluent-combobox, fluent-checkbox, fluent-switch, fluent-radio, fluent-slider,
                   .fluent-autocomplete-multiselect, fluent-date-picker, fluent-time-picker) {
    pointer-events: none;
}

.lecture-seule .ecriture {
    display: none !important;
}

/* Un filtre d'affichage n'écrit rien : il reste utilisable */
.lecture-seule .consultation {
    pointer-events: auto;
}

.lecture-seule .cell-menu {
    cursor: default;
}

.lecture-seule .cell-menu-chevron {
    display: none;
}

/* ===== Mode « Voir comme » : rappel permanent dans l'en-tête ===== */
.voir-comme-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 14px;
    background: #fbbf24;
    color: #1f2937;
    font-size: 12px;
    white-space: nowrap;
}

.voir-comme-badge a {
    color: #1f2937;
    font-weight: 600;
    text-decoration: underline;
}
