/* ============================================================================
   Direction visuelle RCM — TELT (audit UX 07/2026)
   Palette institutionnelle, pile typographique système, code couleur des états.
   Un seul point de vérité : les composants et pages ne dupliquent aucune couleur.
   ============================================================================ */
:root {
    /* Pile de polices système alignée sur FluentUI (tue le retour à Times, P1-6). */
    --rcm-font: "Segoe UI Variable", "Segoe UI", system-ui, -apple-system,
                "Inter", "Roboto", "Helvetica Neue", Arial, sans-serif;

    /* Palette sémantique des verdicts / statuts (fonds pleins, texte blanc — WCAG AA).
       L'orange « À vérifier » est assombri de #E9835E (2,67:1) à #A85B32 (4,52:1) — P2-5. */
    --rcm-verdict-conforme: #0E700E;   /* vert   — Conforme / Validé          (6,28:1) */
    --rcm-verdict-infraction: #BC2F32; /* rouge  — Infraction potentielle     (5,85:1) */
    --rcm-verdict-averifier: #A85B32;  /* orange — À vérifier                 (4,52:1) */
    --rcm-verdict-manuel: #8A5A00;     /* ambre  — Contrôle manuel            (4,71:1) */
    --rcm-verdict-neutre: #5A5F66;     /* gris   — Exclu / Hors plage / inactif (5,3:1) */
    --rcm-statut-attente: #8A5A00;     /* ambre  — En attente                        */

    /* Fond de page très légèrement bleuté pour poser les cartes (§3 direction visuelle). */
    --rcm-fond-page: #F7F9FB;

    /* Échelle typographique affirmée (§3). */
    --rcm-titre-page: 1.5rem;   /* 24px */
    --rcm-titre-section: 1.125rem; /* 18px */
}

html {
    /* La pile système s'applique à tout le texte libre hors composants Fluent (P1-6). */
    font-family: var(--rcm-font);
}

body {
    font-family: var(--rcm-font);
    /* Sans ça, la marge UA (8px) laisse le document défiler de 16px et décale la coquille. */
    margin: 0;
}

/* Fond de page bleuté (posé sur la zone de contenu Fluent, pas les cartes/dialogues).
   NB : FluentBodyContent rend une div `.body-content` (pas `.fluent-body-content`). */
.body-content {
    background: var(--rcm-fond-page);
}

/* ============================================================================
   Coquille applicative fixe : l'en-tête et la navigation restent en place,
   SEULE la zone de contenu défile. Sans cela, le scroll se fait au niveau du
   document et emporte header + nav hors écran (pages longues type Administration).
   Rendu réel de FluentLayout : <div class="layout"> (flex colonne) contenant
   <header class="header"> puis notre FluentStack `.rcm-corps`. La hauteur
   100dvh est posée en style inline sur <FluentLayout> (la feuille FluentUI
   redéfinit .layout et gagnerait sur une règle externe).
   ============================================================================ */

/* Corps (nav + contenu) : occupe le reste sous le header ; min-height:0 est
   indispensable pour qu'un enfant flex puisse défiler au lieu d'étirer la page. */
.rcm-corps {
    flex: 1 1 0;
    min-height: 0;
}

.rcm-corps > .body-content {
    height: 100%;
    min-height: 0;
    overflow-y: auto;
}

@media (min-width: 769px) {
    /* En desktop la nav est dans le flux : pleine hauteur, défile en interne si
       besoin. (En mobile elle est en position:fixed top/bottom — ne pas forcer
       height ici, les deux contraintes se contrediraient.) */
    .rcm-nav {
        height: 100%;
        overflow-y: auto;
        flex-shrink: 0;
    }
}

/* Chiffres tabulaires pour aligner les colonnes de nombres (compteurs, scores). */
.rcm-chiffre {
    font-variant-numeric: tabular-nums;
}

/* Surcharge GLOBALE et volontaire de FluentMessageBar, valable sur tous les écrans.
   Le composant se dimensionne en `content-box` : sa feuille pose `width:100%` PUIS ajoute 2 × 12 px
   de padding par-dessus, si bien que le bandeau ressort 26 px plus large que la colonne qui le
   contient. Constaté sur « Points de contrôle » et « Purge RGPD », où il dépassait seul la ligne de
   tous les autres blocs, mais le défaut est celui du composant : il vaut partout où un bandeau est
   posé (accueil, barrière, conformité, cartographie, dialogues). On ne fixe aucune largeur en dur,
   on change seulement la façon de compter. */
.fluent-messagebar {
    box-sizing: border-box;
}

/* Texte destiné aux seuls lecteurs d'écran : retiré de l'affichage sans être retiré de l'arbre
   d'accessibilité (ce que feraient `display:none` ou `visibility:hidden`). Sert à nommer un
   contrôle dont l'intitulé visible est porté par une image ou par le contexte. */
.rcm-hors-ecran {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

h1:focus {
    outline: none;
}

/* ============================================================================
   Badge d'état (verdict / statut) — composant BadgeEtat.
   Remplace le bug FluentBadge Appearance=Accent qui neutralisait BackgroundColor
   (tous les badges rendaient un bleu identique — P1-1). Couleur + icône + texte
   (jamais couleur seule — WCAG 1.4.1).
   ============================================================================ */
.rcm-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 9px 2px 7px;
    border-radius: 11px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.35;
    white-space: nowrap;
    color: #fff;
    background: var(--rcm-verdict-neutre);
    letter-spacing: 0.01em;
}

.rcm-badge svg {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
}

.rcm-badge--conforme { background: var(--rcm-verdict-conforme); }
.rcm-badge--infraction { background: var(--rcm-verdict-infraction); }
.rcm-badge--averifier { background: var(--rcm-verdict-averifier); }
.rcm-badge--manuel { background: var(--rcm-verdict-manuel); }
.rcm-badge--neutre { background: var(--rcm-verdict-neutre); }
.rcm-badge--attente { background: var(--rcm-statut-attente); }

/* Marqueur compact des grilles d'administration (colonne étroite, à côté d'une autre valeur).
   Distinct de .rcm-badge : il n'impose PAS de couleur, l'appelant pose la sienne en ligne pour
   l'état d'une caméra. Il était appelé sans jamais avoir été défini : le marqueur « Barrière »
   sortait en texte nu à taille normale et débordait sa cellule, tronqué en « Ba… ». */
.rcm-badge-statut {
    display: inline-flex;
    align-items: center;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
    letter-spacing: 0.01em;
}

/* Le seul marqueur qui doit se voir comme une pastille : il désigne le poste de l'agent de terrain
   et la caméra dont le relais commande la barrière. */
.rcm-badge-statut--barriere {
    padding: 1px 7px;
    border-radius: 9px;
    color: #fff;
    background: var(--rcm-verdict-neutre);
}

/* ============================================================================
   Grilles exploitables — scroll interne, en-têtes figés, filtres persistants.
   (P1-2, P1-3, P3-3)
   ============================================================================ */
/* Wrapper à hauteur bornée : capte la molette et fige l'en-tête (GenerateHeader Sticky).
   Le scroll reste dans la grille au lieu d'emporter toute la page. */
.rcm-grille-scroll {
    max-height: calc(100vh - 340px);
    min-height: 180px;
    /* max-width : sans lui, agrandir une colonne (poignées FluentDataGrid) étire le wrapper
       au-delà de son parent → le tableau sort de la page, clippé sans aucun scroll possible.
       Clampé, c'est ce conteneur qui porte la barre de défilement horizontale. */
    max-width: 100%;
    /* align-self : filet de sécurité contre le piège du FluentStack vertical, dont `align-items`
       vaut « start » et dimensionne chaque enfant sur son contenu. Sans étirement, la largeur de la
       grille suivait le texte des lignes affichées : un tri qui remonte des libellés courts repliait
       le tableau — et son cadre — à quelques centaines de pixels (constaté sur /conformite en triant
       par État). Les écrans posent HorizontalAlignment.Stretch sur leur pile ; cette règle rattrape
       celui qu'on oublierait. Sans effet hors contexte flex. */
    align-self: stretch;
    overflow: auto;
    border: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    border-radius: 4px;
}

/* Variante courte pour les grilles secondaires (cartes, chronologies). MODIFICATEUR : elle se pose
   TOUJOURS en plus de `.rcm-grille-scroll`, dont elle n'ajuste que les hauteurs. Employée seule dans
   un dialogue, elle laissait le wrapper prendre la largeur naturelle des colonnes et déborder du
   dialogue (barre horizontale parasite). Le plancher de 180px est levé : deux passages ne doivent
   pas réserver la hauteur de six. */
.rcm-grille-scroll--court {
    max-height: 320px;
    min-height: 0;
}

/* Plaque cliquable d'une cellule de grille : ouvre le relevé du contrôle. Un <button> natif, jamais
   un lien — la cible est un dialogue, et surtout la plaque ne doit entrer dans aucune URL (§6
   CLAUDE.md). Le bouton se dépouille de son fond et de sa bordure pour se lire comme la valeur
   qu'il porte, mais reste un vrai contrôle : atteignable au Tab, avec son anneau de focus. */
.rcm-plaque-lien {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent-fill-rest, #0f6cbd);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.rcm-plaque-lien:hover:not(:disabled) {
    text-decoration: underline;
}

.rcm-plaque-lien:focus-visible {
    outline: 2px solid var(--accent-fill-rest, #0f6cbd);
    outline-offset: 2px;
    border-radius: 3px;
}

.rcm-plaque-lien:disabled {
    color: var(--neutral-foreground-hint, #5a5a5a);
    cursor: default;
}

.rcm-plaque-lien code {
    color: inherit;
}

/* Barre de filtres persistante en haut du scroll de page (P3-3).
   z-index : la feuille FluentUI pose l'en-tête figé de FluentDataGrid en `position:sticky;
   z-index:5`. Comme cette barre est elle-même collante AVEC un z-index, elle crée un contexte
   d'empilement : tout ce qu'elle contient — dont le panneau déroulant d'un FluentSelect, pourtant
   en z-index 9995 — est plafonné à SON niveau. En dessous de 5, l'en-tête opaque de la grille se
   dessinait par-dessus le panneau et masquait purement et simplement l'option qui tombait à sa
   hauteur (option « Validé » du filtre Statut sur /conformite). On reste donc au-dessus des
   couches de grille, tout en laissant la place aux surcouches applicatives (tiroir mobile : 1100+). */
.rcm-filtres-sticky {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--rcm-fond-page);
    padding-bottom: 0.5rem;
}

/* FluentCard se confine deux fois : `contain: content` (= `layout paint style`) ET
   `content-visibility: auto`, qui impose le même confinement pour son propre compte. Le volet
   `paint` ROGNE les descendants à la boîte de la carte et le volet `layout` en fait un contexte
   d'empilement : toute surcouche ouverte depuis un contrôle posé dans une carte (panneau de
   FluentSelect, calendrier de FluentDatePicker, liste d'autocomplétion…) était tronquée au bord
   de la carte — barres de filtres de /vehicules, cartes de paramètres de /admin. Aucun z-index ne
   corrige un rognage : il faut lever les DEUX déclarations. On ne garde que `style` (portée des
   compteurs et des quotes), seul volet sans effet sur la peinture ni sur l'empilement. */
fluent-card {
    contain: style;
    content-visibility: visible;
}

/* Cible tactile des boutons d'action de grille : ≥ 32px (WCAG 2.5.8, P3-6). */
.rcm-actions-grille .fluent-button,
.rcm-actions-grille fluent-button {
    min-width: 32px;
    min-height: 32px;
}

/* Sélecteur éditable en place dans une cellule de grille (colonne « Transporteur » de /vehicules).
   `<select>` NATIF, jamais FluentSelect : ce dernier rend sa liste d'options dans le document, où
   elle est rognée par la cellule de FluentDataGrid (`overflow:hidden`) ET par `.rcm-grille-scroll`
   (`overflow:auto`) — deux ancêtres dont les débordements sont des exigences de l'écran —, puis
   recouverte par la carte de filtres ; aucun z-index n'y peut rien (même constat que les cartes
   FluentUI plus haut). La liste d'un select natif est peinte par le navigateur hors du document.
   L'apparence reste celle des champs FluentUI : mêmes bordure, rayon, police et hauteur de cible
   tactile (≥ 32px, WCAG 2.5.8). Le chevron est celui du navigateur — un contrôle natif assumé. */
.rcm-select-ligne {
    width: 100%;
    max-width: 100%;
    min-height: 32px;
    padding: 4px 8px;
    font: inherit;
    color: inherit;
    background: var(--neutral-fill-input-rest, #fff);
    border: 1px solid var(--neutral-stroke-input-rest, #d1d1d1);
    border-radius: 4px;
}

.rcm-select-ligne:hover {
    border-color: var(--neutral-stroke-input-hover, #a0a0a0);
}

.rcm-select-ligne:focus-visible {
    outline: 2px solid var(--accent-fill-rest, #0f6cbd);
    outline-offset: 1px;
}

/* ============================================================================
   Titres de page affirmés (P2-4).
   ============================================================================ */
.rcm-titre-page {
    font-size: var(--rcm-titre-page);
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* ============================================================================
   Focus initial du dialogue : ne pas peindre un halo bleu sur le titre non
   interactif (donnait l'illusion d'un champ éditable — P2-2).
   ============================================================================ */
fluent-dialog [role="heading"]:focus,
fluent-dialog .fluent-dialog-header h1:focus,
fluent-dialog .fluent-dialog-header:focus {
    outline: none;
}

/* ============================================================================
   Pied de dialogue : un seul moyen de fermer.
   Les dialogues de consultation (relevé de contrôle, détail de passage, push
   ITSAPI) n'offrent plus de bouton « Fermer » en pied — la croix de l'en-tête
   suffit et deux commandes identiques pour la même action désorientent. Sans
   action déclarée, FluentUI rend malgré tout le pied (une pile vide) qui garde
   son padding : 24px de bande morte sous le contenu. On l'efface quand il n'a
   aucun enfant. `:not(:has(*))` et non `:empty` — le rendu Blazor y laisse des
   nœuds texte qui mettent `:empty` en échec.
   La classe est répétée à dessein : le pied est aussi un `.stack-horizontal`,
   dont la règle isolée de FluentUI (`.stack-horizontal[b-…] { display:flex }`)
   pèse deux classes. Sans ce doublon, `display:none` perdait la cascade.
   ============================================================================ */
fluent-dialog .fluent-dialog-footer.fluent-dialog-footer:not(:has(*)) {
    display: none;
    padding: 0;
}

/* ============================================================================
   Toasts : hauteur pensée en border-box par FluentUI (min-height 44px = titre
   + 2×12px de marge interne), mais l'élément reste en content-box faute de
   reset global. Les 24px de padding s'ajoutaient alors au minimum et
   laissaient une bande vide sous le titre. Mesuré : 68px au lieu de 44.
   ============================================================================ */
.fluent-toast {
    box-sizing: border-box;
}

/* --- Page de connexion --- */
.login-conteneur {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: 1rem;
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.login-label {
    font-size: 0.85rem;
    font-weight: 600;
    margin-top: 0.5rem;
}

.login-input {
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--neutral-stroke-rest, #ccc);
    border-radius: 4px;
    font-size: 0.95rem;
}

.login-bouton {
    margin-top: 1rem;
    padding: 0.6rem;
    background: var(--accent-fill-rest, #0f6cbd);
    color: #fff;
    border: none;
    border-radius: 4px;
    font-size: 0.95rem;
    cursor: pointer;
}

.login-bouton:hover {
    background: var(--accent-fill-hover, #115ea3);
}

/* Liens secondaires des écrans de connexion et de récupération de mot de passe. Le second sélecteur
   habille un <button> de formulaire posté (déconnexion) : un lien ne peut pas porter de jeton
   antiforgery, il faut donc un vrai bouton qui en ait l'apparence. */
.login-lien,
.login-lien-bouton {
    font-size: 0.85rem;
    color: var(--accent-foreground-rest, #0f6cbd);
    text-decoration: none;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
}

.login-lien:hover,
.login-lien-bouton:hover {
    text-decoration: underline;
}
/* --- Tableau de bord d'exploitation : grille de compteurs et cartes cliquables --- */
.grille-compteurs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
}

.carte-compteur {
    text-decoration: none;
    color: inherit;
    display: block;
}

.carte-compteur .carte-compteur-fond {
    border-left: 4px solid var(--accent, var(--accent-fill-rest));
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.carte-compteur:hover .carte-compteur-fond {
    box-shadow: var(--elevation-shadow-card-hover, 0 2px 8px rgba(0, 0, 0, 0.15));
    transform: translateY(-1px);
}

.carte-compteur:focus-visible {
    outline: 2px solid var(--accent-fill-rest);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Chiffre de compteur en tabulaire (alignement des colonnes de nombres, §3). */
.carte-compteur .carte-compteur-valeur {
    font-variant-numeric: tabular-nums;
}

/* ============================================================================
   Responsive — mobile / tablette (P1-5).
   Sous 768px la navigation devient un tiroir superposé, ouvert par la case à
   cocher `#rcm-nav-toggle` (aucun JS : MainLayout est rendu en SSR statique ;
   c'est js/navigation.js qui la referme après une navigation).
   Ici on empêche aussi le titre d'être rogné et on borne les grilles à l'écran.
   ============================================================================ */

/* En-tête applicatif : ne jamais rogner le titre (P3-5). */
.rcm-titre-app {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Case à cocher masquée qui pilote le tiroir (pas de JS — layout SSR statique). */
.rcm-nav-toggle {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

/* Hamburger et voile masqués en desktop ; version courte du titre masquée aussi. */
.rcm-hamburger,
.rcm-nav-voile-label {
    display: none;
}

.rcm-titre-app-court {
    display: none;
}

@media (max-width: 768px) {
    /* Header compact : bouton hamburger visible, titre court, nom d'utilisateur masqué. */
    .rcm-hamburger {
        display: inline-flex;
        align-items: center;
        cursor: pointer;
        padding: 4px;
    }

    .rcm-titre-app-long { display: none; }
    .rcm-titre-app-court { display: inline; }
    .rcm-user-nom { display: none; }

    /* Tiroir de navigation : hors écran par défaut, glisse à l'ouverture de la case.
       overflow-y indispensable : en paysage (ou petit écran), les 8 entrées du menu Admin
       dépassent la hauteur du tiroir et les dernières étaient inatteignables. */
    .rcm-nav {
        position: fixed;
        top: 52px;
        bottom: 0;
        left: 0;
        z-index: 1200;
        overflow-y: auto;
        overscroll-behavior: contain;
        transform: translateX(-105%);
        transition: transform 0.22s ease;
        background: var(--neutral-layer-1, #fff);
        box-shadow: 2px 0 14px rgba(0, 0, 0, 0.28);
    }

    /* Expander interne de FluentNavMenu (Collapsible) : inutile ici, le tiroir a déjà son
       bouton dans l'en-tête. Replié, il réduit le menu à un rail de 40px au milieu d'un
       tiroir superposé — et son bouton disparaît avec le tiroir, donc sans moyen de revenir
       en arrière. On le masque : le repli reste disponible en desktop (≥ 769px). */
    .rcm-nav .expander {
        display: none;
    }

    /* Repli hérité d'un passage par le desktop (rotation de l'écran, redimensionnement) :
       le tiroir mobile se réaffiche toujours en pleine largeur. Les styles à neutraliser
       sont posés en inline par le JS de FluentNavMenu, d'où le !important. */
    .rcm-nav .fluent-nav-menu.collapsed {
        width: 250px !important;
        min-width: 250px !important;
    }

    .rcm-nav .fluent-nav-menu.collapsed .fluent-nav-text {
        display: block !important;
    }

    /* Case cochée : le tiroir apparaît et le voile se pose derrière. */
    .rcm-nav-toggle:checked ~ * .rcm-nav {
        transform: translateX(0);
    }

    .rcm-nav-voile-label {
        display: none;
        position: fixed;
        inset: 52px 0 0 0;
        background: rgba(0, 0, 0, 0.35);
        z-index: 1100;
    }

    .rcm-nav-toggle:checked ~ * .rcm-nav-voile-label {
        display: block;
    }
}

@media (max-width: 768px) {
    /* Header compact et titre raccourci géré côté composant. */
    .body-content > div {
        padding: 0.75rem !important;
    }

    /* Grilles bornées à la largeur de l'écran : scroll horizontal interne plutôt
       que débordement de toute la page (Statut/Passages restaient invisibles). */
    .rcm-grille-scroll,
    .rcm-grille-scroll--court {
        max-height: 46vh;
    }
}

/* ============================================================================
   État vide (recherche plaque, etc.) — P3-1.
   ============================================================================ */
.rcm-etat-vide {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-etat-vide svg {
    width: 48px;
    height: 48px;
    opacity: 0.55;
}

/* ============================================================================
   Administration — mise en page des onglets (regroupement en sections/cartes).
   Objectif ergonomie : casser la longue colonne brute de « Paramètres » en
   sections thématiques lisibles, avec grilles responsives et unités visibles.
   Classes préfixées `rcm-adm-` pour rester locales à l'écran d'administration.
   ============================================================================ */

/* --------------------------------------------------------------------------
   Coquille de l'écran : rail de navigation à gauche, section à droite.

   Elle remplace la barre FluentTabs, dont l'overflow masquait les entrées qui
   ne rentraient pas derrière un compteur « +N » NON CLIQUABLE : à 390 px, cinq
   sections sur huit étaient inatteignables, et l'indicateur de sélection se
   dessinait sous le compteur. Aucune largeur ne peut plus masquer une section :
   sous 900 px le rail cède la place à un sélecteur qui les liste toutes.
   -------------------------------------------------------------------------- */
.rcm-adm-coquille {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    gap: 1.75rem;
    align-items: start;
    margin-top: 1rem;
}

/* Le rail suit le défilement : avec neuf cartes de réglages, revenir en haut de
   page pour changer de section était un aller-retour à chaque fois. */
.rcm-adm-rail {
    position: sticky;
    top: 0;
    padding-bottom: 1rem;
}

.rcm-adm-rail-groupe {
    margin: 0.9rem 0 0.35rem 0.65rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-adm-rail-groupe:first-child {
    margin-top: 0;
}

.rcm-adm-rail-liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.rcm-adm-rail-lien {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.65rem;
    border-radius: 6px;
    border-left: 3px solid transparent;
    color: var(--neutral-foreground-rest, #242424);
    text-decoration: none;
    font-size: 0.9rem;
    line-height: 1.3;
    transition: background-color 0.12s ease;
}

/* `fill: currentColor` et non `color:` — FluentIcon peint son SVG en accent, et il le fait en style
   INLINE (`style="fill: var(--accent-fill-rest)"`), que seule une déclaration `!important` peut
   reprendre : sans elle, les icônes du rail sortaient toutes bleues, la courante comme les autres.
   L'icône suit ainsi l'état du lien — neutre au repos, accent sur la section courante. */
.rcm-adm-rail-lien svg,
.rcm-adm-rail-lien svg path {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    fill: currentColor !important;
}

.rcm-adm-rail-lien:hover {
    background: var(--neutral-fill-secondary-hover, #f0f0f0);
}

/* Focus clavier visible : le rail est la navigation principale de l'écran
   (WCAG 2.4.7), le seul fond de survol ne s'affiche pas au Tab. */
.rcm-adm-rail-lien:focus-visible {
    outline: 2px solid var(--accent-fill-rest, #0f6cbd);
    outline-offset: 1px;
}

/* Section courante : marquée par la couleur ET par la barre de gauche, jamais
   par la seule couleur (WCAG 1.4.1). `aria-current="page"` la dit en plus au
   lecteur d'écran. */
.rcm-adm-rail-lien--actif {
    background: var(--neutral-fill-secondary-rest, #f5f5f5);
    border-left-color: var(--accent-fill-rest, #0f6cbd);
    color: var(--accent-fill-rest, #0f6cbd);
    font-weight: 600;
}

/* L'icône de la section courante suit la couleur du lien, posée juste au-dessus (règle héritée de
   `.rcm-adm-rail-lien svg` : rien à répéter ici). */

/* Sélecteur de section : caché tant que le rail tient à l'écran. */
.rcm-adm-selecteur {
    display: none;
}

/* Colonne de contenu. `min-width: 0` est indispensable : sans lui, une grille
   large impose sa largeur naturelle à la piste de grille et pousse la page en
   débordement horizontal au lieu de défiler dans son propre cadre.
   AUCUNE largeur maximale : le contenu d'une section prend toute la place que le
   rail lui laisse (exigence ferme de l'utilisateur, 13/08/2026, CLAUDE.md
   « Conventions UI durables » — un plafond de 1280px a été posé puis signalé
   comme un défaut sur écran large, au même titre que les gabarits en ch). */
.rcm-adm-contenu {
    min-width: 0;
}

@media (max-width: 900px) {
    .rcm-adm-coquille {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.5rem;
    }

    .rcm-adm-rail {
        display: none;
    }

    .rcm-adm-selecteur {
        display: block;
        margin-top: 0.75rem;
        /* Borné : étiré sur toute la largeur d'une tablette, un sélecteur de huit entrées se lit
           comme un titre plutôt que comme un contrôle. */
        max-width: 22rem;
    }
}

/* Bandeau d'introduction en tête de section : titre + courte description. */
.rcm-adm-intro {
    margin: 1rem 0 0.25rem;
}

.rcm-adm-intro h5 {
    margin: 0;
    font-size: var(--rcm-titre-section);
    font-weight: 600;
    letter-spacing: -0.005em;
}

/* AUCUNE bride de largeur sur les textes d'écran (exigence ferme de l'utilisateur,
   13/08/2026, CLAUDE.md « Conventions UI durables ») : le texte suit son conteneur.
   Deux gabarits successifs (60ch puis 96ch) ont été essayés et rejetés — sur un
   écran large, le paragraphe se repliait pendant que champs et grilles s'étalaient
   dessous. */
.rcm-adm-intro p {
    margin: 0.15rem 0 0;
    color: var(--neutral-foreground-hint, #5a5a5a);
    font-size: 0.85rem;
}

/* Colonne des cartes de réglages. La largeur est désormais celle de
   `.rcm-adm-contenu` : c'est lui qui borne la ligne de lecture, une seule fois
   pour toute la section. */
.rcm-adm-sections {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-top: 1rem;
}

/* Au-delà de 1650 px, les cartes se rangent en deux colonnes : les neuf cartes
   de « Paramètres » demandaient sinon quatre écrans de défilement, la moitié
   droite de l'écran restant vide.

   GRILLE et non `columns`. Les colonnes CSS étaient plus compactes (elles
   maçonnent, sans trou), mais une carte trop haute pour la fin d'une colonne y
   est FRAGMENTÉE : elle se coupait en bas de la colonne gauche et reprenait en
   haut de la droite, son ombre portée avec elle. `break-inside: avoid` ne l'a
   pas empêché — les navigateurs le traitent en indication, pas en règle, et
   `contain: content` de FluentCard n'aide pas. Une grille ne peut pas couper une
   carte : chacune occupe sa cellule.

   `align-items: start` garde à chaque carte sa hauteur naturelle : une carte
   courte ne s'étire pas jusqu'à la hauteur de sa voisine. Le prix est un espace
   vide sous la plus courte de chaque rangée — c'est ce qu'on échange contre
   l'assurance qu'aucune carte n'est coupée.

   Seuil mesuré, et non choisi : la colonne de contenu vaut la fenêtre moins le
   menu principal (250 px), le rail (236 px) et les gouttières. À 1500 px de
   fenêtre, les deux colonnes tombaient à 457 px et les champs, en
   `minmax(200px, 1fr)`, repassaient à un par ligne — la mise en page perdait au
   change. À 1650 px, chaque carte tient deux champs de front. */
@media (min-width: 1650px) {
    .rcm-adm-sections {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
        gap: 1.25rem;
    }
}

/* --------------------------------------------------------------------------
   Bulle d'aide d'une carte de réglages (composant BulleAide).
   Le déclencheur est un FluentButton discret : apparence, survol et contour de
   focus viennent de la bibliothèque. Il ne reste ici que la taille — un bouton
   de barre d'outils à côté d'un titre de carte serait deux fois trop grand — et
   la mise en forme du contenu de la bulle.
   -------------------------------------------------------------------------- */
/* Le pictogramme se pose en haut à droite de la boîte du champ, donc sur la ligne
   de son libellé. Il vit DEHORS du <label> : posé dedans, la bulle s'y trouvait
   aussi et le DOM ne correspondait plus à ce que Blazor attendait. */
.rcm-adm-champ {
    position: relative;
}

.rcm-adm-aide {
    position: absolute;
    top: -2px;
    right: 0;
    line-height: 0;
}

/* Déclencheur : bouton nu, la couleur suit l'état. Les tokens sont ceux de
   FluentUI — seule la forme est locale, le composant FluentButton ne convenant
   pas ici (son shadow DOM avale l'infobulle). */
.rcm-adm-bulle {
    display: inline-flex;
    padding: 2px;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--neutral-foreground-hint, #5a5a5a);
    cursor: help;
    line-height: 0;
}

.rcm-adm-bulle:hover {
    color: var(--accent-fill-rest, #0f6cbd);
}

/* Focus visible : le pictogramme est le seul contenu du bouton (WCAG 2.4.7). */
.rcm-adm-bulle:focus-visible {
    outline: 2px solid var(--accent-fill-rest, #0f6cbd);
    outline-offset: 1px;
    color: var(--accent-fill-rest, #0f6cbd);
}

.rcm-adm-bulle svg,
.rcm-adm-bulle svg path {
    width: 16px;
    height: 16px;
    fill: currentColor !important;
}

/* La bulle : masquée par défaut, ouverte au survol ET au focus clavier. Aucun
   JavaScript — donc aucun nœud déplacé sous Blazor, ce qui est exactement ce qui
   faisait tomber le circuit avec FluentTooltip.
   `right: 0` l'ancre sur le bord droit du champ : posée à gauche du pictogramme,
   elle ne peut pas sortir de l'écran, quel que soit l'endroit de la page. */
.rcm-adm-bulle-texte {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 20;
    width: max-content;
    max-width: min(360px, 80vw);
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    border-radius: 6px;
    background: var(--neutral-layer-1, #fff);
    box-shadow: 0 4px 14px rgb(0 0 0 / 14%);
    color: var(--neutral-foreground-rest, #242424);
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.4;
    white-space: normal;
    text-align: left;
    text-transform: none;
    letter-spacing: normal;
}

.rcm-adm-bulle:hover + .rcm-adm-bulle-texte,
.rcm-adm-bulle:focus-visible + .rcm-adm-bulle-texte,
.rcm-adm-aide:hover .rcm-adm-bulle-texte {
    display: block;
}

/* Variantes de placement (paramètre Classe de BulleAide). La bulle par défaut s'étend vers la
   gauche et vers le bas : posée dans un dialogue défilant (`overflow` qui rogne) ou dans une zone
   collée au bas de l'écran, elle sortait du cadre — mesuré sur le relevé du contrôle. */
/* Déclencheur EN LIGNE, dans le flux (titre de section, rangée de boutons) : le conteneur n'est
   pas une cellule .rcm-adm-champ pleine largeur. Le sélecteur est DOUBLÉ à dessein : AideRepliable
   partage la classe .rcm-adm-aide et lui donne une marge basse plus loin dans cette feuille — à
   spécificité égale, c'est l'ordre du fichier qui gagnait et le pictogramme partait 8px au-dessus
   du texte qu'il accompagne (mesuré en revue sur les entêtes de section du dialogue caméra). */
.rcm-adm-aide.rcm-adm-aide--enligne {
    position: relative;
    top: auto;
    right: auto;
    display: inline-flex;
    margin: 0;
    vertical-align: middle;
}

/* Dans un entête de section (.rcm-adm-carte-entete), la règle d'icône de titre (20px, accent)
   s'appliquait aussi au pictogramme de la bulle : il doit rester à la taille et à la couleur des
   autres bulles, celles du bouton qui le porte. */
.rcm-adm-carte-entete .rcm-adm-bulle svg,
.rcm-adm-carte-entete .rcm-adm-bulle svg path {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    color: inherit;
}

/* Bulle ancrée au bord GAUCHE du déclencheur : elle s'étend vers la droite (déclencheur proche du
   bord gauche d'un conteneur qui rogne). */
.rcm-adm-aide--droite .rcm-adm-bulle-texte {
    right: auto;
    left: 0;
}

/* Bulle ouverte vers le HAUT : déclencheur posé au bas d'un dialogue (zone de décision collante). */
.rcm-adm-aide--haut .rcm-adm-bulle-texte {
    top: auto;
    bottom: calc(100% + 6px);
}

/* Ligne « contenu + bulle d'aide » : un titre de section, un interrupteur ou un champ suivi de son
   pictogramme, collé et centré verticalement. Compagne des variantes --enligne ci-dessus. */
.rcm-ligne-aide {
    display: flex;
    align-items: center;
    gap: .3rem;
}

/* Sous 760px, la bulle devient une FEUILLE fixée au bas de l'écran : sur un écran étroit, aucun
   ancrage latéral ne convient à toutes les positions de déclencheur — mesuré sur le dialogue
   caméra, chaque variante sortait du viewport d'un côté ou de l'autre. Le déclencheur vient d'être
   touché ou focalisé : le lien de contexte est immédiat. Les sélecteurs des variantes sont repris
   pour battre leurs ancrages, plus spécifiques que la classe seule. Aucun ancêtre des dialogues ne
   pose de transform (vérifié) : `fixed` s'ancre bien au viewport. */
@media (max-width: 760px) {
    .rcm-adm-bulle-texte,
    .rcm-adm-aide--droite .rcm-adm-bulle-texte,
    .rcm-adm-aide--haut .rcm-adm-bulle-texte {
        position: fixed;
        top: auto;
        right: 3vw;
        bottom: 12px;
        left: 3vw;
        z-index: 10000;
        width: auto;
        max-width: none;
    }
}

/* --------------------------------------------------------------------------
   Dialogue « Configurer la caméra » : sections titrées comme les cartes de
   réglages (icône + titre), séparées par un filet, champs sur la grille
   .rcm-adm-grille. La fiche « configuration à reporter » est un panneau
   clé / valeur — les lignes de code nues se lisaient comme du bruit.
   -------------------------------------------------------------------------- */
.rcm-cam-section {
    width: 100%;
    border-top: 1px solid var(--neutral-stroke-divider-rest, #e0e0e0);
    padding-top: .9rem;
    display: flex;
    flex-direction: column;
    gap: .75rem;
}

.rcm-cam-fiche {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: .4rem .9rem;
    margin: 0;
    padding: .7rem .9rem;
    border: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    border-radius: 6px;
    background: var(--neutral-layer-2, #f7f7f7);
    font-size: .85rem;
}

.rcm-cam-fiche dt {
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-cam-fiche dd {
    margin: 0;
    overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   Libellé posé À GAUCHE d'un champ : centré sur la hauteur du champ.
   FluentUI rend le libellé (`label.fluent-input-label`, ~20px) comme un
   FRÈRE du champ (~32px). Deux dérives mesurées selon le conteneur : 6px
   trop haut dans une pile horizontale à alignement par défaut (haut — le
   dialogue « Configurer la caméra »), 2px dans les barres de filtres
   alignées en bas (leur marge basse de libellé). La règle couvre les DEUX
   conteneurs à libellés latéraux du projet — FluentStack horizontal et
   `.rcm-barre-filtres` (/vehicules, /plaques) — et ne touche pas les piles
   verticales, où le libellé est AU-DESSUS du champ. Elle écrase sciemment
   l'alignement vertical déclaré sur la pile (`VerticalAlignment.Bottom` des
   barres de filtres) pour le SEUL libellé : ses champs restent alignés
   entre eux, le libellé se centre sur la rangée.
   -------------------------------------------------------------------------- */
.stack-horizontal > label.fluent-input-label,
.rcm-barre-filtres > label.fluent-input-label,
.rcm-filtre-groupe > label.fluent-input-label {
    align-self: center;
    /* La marge basse de 4px sert quand le libellé est AU-DESSUS du champ ; à gauche, elle décalait
       encore le centre de 2px après l'alignement. */
    margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Couple « libellé + champ » d'une barre de filtres, rendu INSÉCABLE.
   FluentUI émet le libellé comme un FRÈRE du champ : dans une barre à
   `flex-wrap`, le retour à la ligne pouvait donc tomber ENTRE les deux et
   laisser un libellé orphelin en fin de rangée (mesuré à 1280 px sur la
   barre de /vehicules, dont la composition a changé depuis — la classe vaut
   pour toute barre de filtres). Le groupe est un item de flex unique ; à
   l'intérieur, la disposition reste celle de la barre.
   -------------------------------------------------------------------------- */
.rcm-filtre-groupe {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    min-width: 0;
}

/* --------------------------------------------------------------------------
   Aide détaillée repliable (composant AideRepliable).
   Les explications des cartes de réglages disent pourquoi une valeur est bornée
   et rappellent des incidents réels : elles ne sont pas supprimables. Repliées,
   elles laissent les champs au-dessus de la ligne de flottaison.
   -------------------------------------------------------------------------- */
.rcm-adm-aide {
    margin: 0 0 0.9rem;
}

/* `list-item` conservé (valeur par défaut d'un <summary>) : toute autre valeur d'affichage supprime
   le ::marker, donc le triangle qui dit si l'aide est ouverte ou fermée. Sans lui, il ne resterait
   qu'un texte bleu — or ce repli n'a d'intérêt que s'il reste découvrable. */
.rcm-adm-aide-resume {
    display: list-item;
    list-style-position: inside;
    width: fit-content;
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--accent-fill-rest, #0f6cbd);
    padding: 0.15rem 0.2rem 0.15rem 0;
    border-radius: 4px;
}

.rcm-adm-aide-resume:focus-visible {
    outline: 2px solid var(--accent-fill-rest, #0f6cbd);
    outline-offset: 2px;
}

.rcm-adm-aide-corps {
    margin-top: 0.35rem;
    padding-left: 0.85rem;
    border-left: 2px solid var(--neutral-stroke-rest, #e0e0e0);
}

/* Les paragraphes d'aide gardent le gabarit des descriptions de carte, mais le
   dernier ne pousse pas d'espace avant les champs. */
.rcm-adm-aide-corps .rcm-adm-carte-desc:last-child {
    margin-bottom: 0;
}

/* Carte de section : titre, description, grille de champs. */
.rcm-adm-carte {
    padding: 1.1rem 1.25rem 1.25rem;
}

.rcm-adm-carte-entete {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-bottom: 0.15rem;
}

.rcm-adm-carte-entete svg {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    color: var(--accent-fill-rest, #0f6cbd);
}

.rcm-adm-carte-titre {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
}

/* Pas de max-width : les textes d'écran suivent leur conteneur (exigence ferme de
   l'utilisateur, 13/08/2026, CLAUDE.md « Conventions UI durables »). L'ancien
   modificateur `.rcm-adm-carte-large`, qui ne servait qu'à élargir cette bride,
   est retiré avec elle. */
.rcm-adm-carte-desc {
    margin: 0.1rem 0 0.9rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
    font-size: 0.82rem;
}

/* Grille de champs responsive : 2–3 colonnes selon la place, champs bornés. */
.rcm-adm-grille {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.85rem 1rem;
    align-items: end;
}

/* Un champ occupe une cellule ; la largeur est pilotée par la grille. */
.rcm-adm-champ {
    min-width: 0;
}

.rcm-adm-champ .fluent-text-field,
.rcm-adm-champ fluent-text-field,
.rcm-adm-champ .fluent-number-field,
.rcm-adm-champ fluent-number-field,
.rcm-adm-champ .fluent-time-picker,
.rcm-adm-champ fluent-time-picker {
    width: 100%;
}

/* Un champ qui doit s'étaler sur toute la largeur (ex. fuseau horaire). */
.rcm-adm-champ--large {
    grid-column: 1 / -1;
}

/* Barre d'action en fin de colonne. */
.rcm-adm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding-top: 0.25rem;
}

/* Variante réellement collante, pour une section dont les réglages dépassent la
   hauteur de l'écran : les 29 paramètres s'enregistrent d'un seul geste, mais le
   bouton vivait sous neuf cartes — on modifiait la plage horaire en haut et il
   fallait traverser tout l'écran pour valider, sans jamais voir si l'on avait
   oublié un champ en route. Le fond opaque est nécessaire : le contenu défile
   dessous. */
.rcm-adm-actions--collante {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin-top: 0.25rem;
    padding: 0.7rem 0;
    background: var(--rcm-fond-page);
    border-top: 1px solid var(--neutral-stroke-rest, #e0e0e0);
}

/* Barre d'outils d'onglet (filtres, boutons de création) : carte discrète. */
.rcm-adm-barre {
    padding: 0.9rem 1rem;
}

/* Grille de compteurs libellé / valeur. Deux usages aujourd'hui : le résumé de purge RGPD et
   l'aperçu d'un itinéraire chauffeur déposé. Le nom historique `-purge-` est conservé pour ne pas
   retoucher un balisage existant ; l'alias `-compteurs-` dit ce que la grille est réellement, hors
   de tout contexte de purge — une même règle, jamais deux copies destinées à diverger. */
.rcm-adm-purge-grille,
.rcm-adm-compteurs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 0.75rem 1rem;
    margin-top: 0.75rem;
}

.rcm-adm-purge-item,
.rcm-adm-compteur {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    border-radius: 6px;
    background: var(--neutral-layer-1, #fff);
}

.rcm-adm-purge-item .rcm-adm-purge-valeur,
.rcm-adm-compteur .rcm-adm-compteur-valeur {
    font-size: 1.4rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.rcm-adm-purge-item .rcm-adm-purge-libelle,
.rcm-adm-compteur .rcm-adm-compteur-libelle {
    font-size: 0.78rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* « Cliquez pour parcourir » — la zone de dépôt ne réagissait qu'au glisser-déposer.
   FluentInputFile empile un <input type="file"> transparent (opacity 0) SOUS un calque de contenu
   posé en `z-index: 991`. C'est ce calque qui recevait le clic : `elementFromPoint` au centre de la
   zone rendait le <span> du libellé, jamais l'input, et le sélecteur de fichier ne s'ouvrait donc
   jamais. Sur un poste sans souris à glisser (ou pour qui le glisser-déposer n'est pas naturel), la
   seule voie d'import de l'itinéraire était fermée.
   Le contenu est purement illustratif — une icône et deux lignes de texte : le rendre transparent
   aux clics laisse passer le geste jusqu'à l'input, sans rien changer au glisser-déposer, qui est
   traité par le conteneur. Si ce contenu devait un jour porter un élément réellement cliquable, il
   faudrait lui rendre `pointer-events: auto` explicitement. */
.fluent-inputfile-container .inputfile-content {
    pointer-events: none;
}

/* Zone de dépôt du relevé GPX : contenu centré de la boîte glisser-déposer de FluentInputFile.
   La bordure en tirets, le fond et le curseur viennent de la feuille scopée du composant. */
.rcm-adm-depot {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: var(--neutral-foreground-rest, #242424);
}

.rcm-adm-depot svg {
    width: 24px;
    height: 24px;
    color: var(--accent-fill-rest, #0f6cbd);
}

/* Précision secondaire de la zone de dépôt : elle garde la couleur du texte courant sur le fond
   teinté de la boîte, où le gris atténué passait sous le seuil de contraste. */
.rcm-adm-depot-note {
    font-size: 0.8rem;
    color: var(--neutral-foreground-rest, #242424);
}

/* --------------------------------------------------------------------------
   Saisie des traductions de consignes, dans l'aperçu d'import GPX.
   Une consigne par bloc : son texte d'origine en tête, puis un champ par langue
   servie. Le texte source reste visible pendant la saisie — on traduit ce qu'on
   lit, et c'est aussi lui qui rattache la traduction à la bonne consigne.
   -------------------------------------------------------------------------- */
.rcm-adm-traductions {
    margin-top: 0.9rem;
}

.rcm-adm-traductions-titre {
    margin: 0 0 0.15rem;
    font-size: 0.95rem;
    font-weight: 600;
}

.rcm-adm-traduction {
    padding: 0.7rem 0.85rem 0.85rem;
    margin-top: 0.7rem;
    border: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    border-radius: 6px;
    background: var(--neutral-layer-1, #fff);
}

.rcm-adm-traduction-source {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin-bottom: 0.6rem;
}

/* Marque « (restauree) » du repere d'une consigne remise a la main : elle explique
   pourquoi une consigne que l'apercu montre comme ecartee demande une traduction.
   Accent plutot que gris : c'est une information, pas un detail attenue. */
.rcm-adm-traduction-restauree {
    margin-left: 0.35rem;
    color: var(--accent-fill-rest, #0f6cbd);
    text-transform: none;
    letter-spacing: 0;
}

.rcm-adm-traduction-repere {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--neutral-foreground-hint, #5a5a5a);
    font-variant-numeric: tabular-nums;
}

/* Le texte à traduire : lisible sans effort, c'est la référence de la saisie. */
.rcm-adm-traduction-texte {
    font-size: 0.9rem;
    line-height: 1.35;
    color: var(--neutral-foreground-rest, #242424);
}

/* Marqueur de provenance d'une consigne dans l'aperçu d'import : icône + mot, sans couleur d'état
   (une consigne déduite n'est ni meilleure ni pire qu'une consigne écrite dans le fichier). */
.rcm-adm-provenance {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.78rem;
    white-space: nowrap;
}

.rcm-adm-provenance svg {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
}

/* Aperçu d'import : ligne d'une consigne ÉCARTÉE par le dédoublonnage automatique.
   Elle reste lisible — c'est une consigne que quelqu'un a écrite, et on demande à
   l'administrateur de juger s'il la rétablit — mais elle ne doit pas se confondre
   avec ce qui part réellement au chauffeur. D'où le fond ambré discret plutôt qu'un
   simple gris : le gris se lit « désactivé », l'ambre se lit « à regarder ». */
.rcm-adm-consigne-ecartee {
    background: var(--rcm-ecartee-fond, rgba(255, 185, 0, 0.09));
}

/* Résumé de la chaîne de caméras sur la ligne d'un tracé : un fait court, le détail
   dans le `title` de la cellule. La troncature est celle d'une CELLULE de grille, pas
   une bride de largeur sur du texte d'écran — la colonne, elle, suit la grille. */
.rcm-adm-chaine {
    color: var(--neutral-foreground-hint, #5a5a5a);
    font-size: 0.85em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Pastille de couleur d'un tracé. Elle reprend la teinte de sa polyligne (même calcul
   côté serveur) : c'est le seul repère commun entre la liste des tracés, la carte des
   caméras et la page du chauffeur. */
.rcm-adm-pastille-trace {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    margin-right: 0.5rem;
    vertical-align: middle;
    flex: none;
}

/* Fil de retour d'une fiche vers sa liste : posé au-dessus du contenu, discret. */
.rcm-adm-fil {
    margin-bottom: 0.8rem;
}

/* Diagnostic de topologie sous une grille : les bandeaux se suivent sans se toucher,
   et respirent par rapport à la grille qui les précède. Sans cette règle ils
   collaient au bord inférieur de la carte, empilés sans interligne. */
.rcm-adm-diagnostic {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 0.9rem;
}

/* Aperçu d'import : ligne en cours de glissement, et ligne visée par le dépôt.
   La zone de dépôt est la cellule « Ordre » — FluentDataGrid n'offre pas de point
   d'accroche sur sa ligne —, si bien que ces deux teintes sont le SEUL repère de
   ce que l'on tient et de l'endroit où cela va tomber. Sans elles, le geste se
   ferait à l'aveugle : on lâche, et on découvre le résultat.
   `:hover` ne peut pas les remplacer : les navigateurs ne le mettent pas à jour
   pendant un glisser-déposer HTML5. */
.rcm-adm-ligne-glissee {
    opacity: 0.55;
}

.rcm-adm-ligne-cible {
    box-shadow: inset 0 2px 0 0 var(--accent-fill-rest);
    background: var(--neutral-fill-secondary-hover);
}

/* Cellule « Ordre » : poignée + deux flèches de rang. Elle occupe toute la
   cellule, la surface de dépôt étant ce que l'on vise à la souris. */
.rcm-adm-ordre {
    display: flex;
    align-items: center;
    gap: 0.1rem;
    width: 100%;
    min-height: 26px;
}

/* Poignée de glissement. Le curseur dit ce qui est saisissable — c'est la seule
   indication avant que le geste ne commence. */
.rcm-adm-poignee {
    display: inline-flex;
    align-items: center;
    cursor: grab;
    padding: 0 0.15rem;
    color: var(--neutral-foreground-hint);
}

.rcm-adm-poignee:active {
    cursor: grabbing;
}

.rcm-adm-poignee svg {
    width: 18px;
    height: 18px;
}

/* Départ et arrivée : le rang est FIXE, et on le dit plutôt que de laisser une
   cellule vide, qui se lirait « ligne oubliée ». */
.rcm-adm-ordre-fixe {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.78rem;
    color: var(--neutral-foreground-hint);
    white-space: nowrap;
}

.rcm-adm-ordre-fixe svg {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
}

/* Abscisse réattribuée à la main : elle ne vient plus du fichier, et la colonne
   est le seul endroit où cela se chiffre. */
.rcm-adm-abscisse-deplacee {
    color: var(--accent-foreground-rest);
    font-weight: 600;
}

/* ----------------------------------------------------------------------------
   Aperçu d'import : carte du tracé déposé (module js/apercu-itineraire.js).
   La hauteur est FIXE, la largeur suit le conteneur : une carte a besoin d'une
   hauteur pour exister (un conteneur Leaflet sans hauteur se rend à 0 px), et
   ce n'est pas une bride de largeur sur du contenu au sens des conventions UI.
   ---------------------------------------------------------------------------- */
.rcm-adm-apercu-carte {
    height: 420px;
    width: 100%;
    margin: 0.3rem 0 0.9rem;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    overflow: hidden;
}

/* Conteneur du DivIcon : Leaflet lui applique déjà sa position absolue, on ne
   fait que neutraliser le fond blanc et la bordure de son style par défaut. */
.rcm-apercu-marqueur {
    background: transparent;
    border: 0;
}

/* Pastille numérotée : le numéro est celui de la colonne « N° » de la grille —
   c'est le seul lien entre un virage sur la carte et sa ligne dans la liste. */
.rcm-apercu-pastille {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--rcm-apercu-servie, #0f6cbd);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Départ et arrivée : elles ancrent le guidage et ne se décochent pas, elles se
   distinguent donc des consignes intermédiaires. Les deux teintes ci-dessous sont
   celles de la légende de `/carte` (vert « autorisé », gris « hors état »), mais
   écrites ici : les variables `--carte-point-*` vivent dans css/carte.css, qui
   n'est chargé que par l'écran de cartographie — les référencer donnerait
   l'illusion d'un partage qui n'existe pas sur cette page. */
.rcm-apercu-pastille--extremite {
    background: #2e7d32;
}

/* Consigne écartée ou décochée : elle ne partira PAS au chauffeur. Gris atténué
   et bordure discontinue — la même lecture que la case décochée de la grille. */
.rcm-apercu-pastille--ecartee {
    background: #9e9e9e;
    border-style: dashed;
    opacity: 0.85;
}

/* Bulle d'une consigne (contenu rendu et échappé côté serveur). */
.rcm-apercu-popup {
    font-size: 0.85rem;
    line-height: 1.45;
}

.rcm-apercu-popup-titre {
    font-weight: 600;
}

.rcm-apercu-popup-note {
    color: #6b5200;
}

/* Case « Garder » d'une extrémité : conteneur de la case désactivée, porteur du
   `title` qui explique pourquoi elle ne se décoche pas. Une `BulleAide` a été
   essayée ici et retirée — son déclencheur est positionné en absolu, il sortait
   de la cellule de 90 px et `overflow:hidden` le coupait : mesuré invisible au
   navigateur. Le `title` d'un élément NATIF, lui, s'affiche (le cas qui échoue
   est celui du FluentButton, dont le shadow DOM avale l'attribut). */
.rcm-adm-garder {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

/* ============================================================================
   Référentiel (Véhicules, recherche de plaque) — barres de filtres regroupées
   et compteurs, dans l'esprit des cartes `rcm-adm-*`.
   Classes génériques `rcm-*` réutilisables sur toute page à onglets.
   ============================================================================ */

/* Carte discrète regroupant les filtres en tête d'écran. */
.rcm-barre-outils {
    padding: 0.9rem 1rem 1rem;
}

/* Bloc de filtres : champs alignés en bas, largeurs bornées, retour à la ligne. */
.rcm-barre-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 0.85rem;
}

.rcm-barre-filtres .fluent-search,
.rcm-barre-filtres fluent-search,
.rcm-barre-filtres .fluent-select,
.rcm-barre-filtres fluent-select,
.rcm-barre-filtres .fluent-date-picker,
.rcm-barre-filtres fluent-date-picker {
    min-width: 160px;
}

/* Ligne compteur au-dessus d'une grille : « N véhicules » lisible. */
.rcm-grille-entete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.rcm-compteur {
    font-size: 0.85rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* Barre sous une grille : réglage « Par page » à gauche, paginateur à droite. Alignement en bas —
   le sélecteur porte son libellé AU-DESSUS du champ, un alignement centré décalerait le paginateur. */
/* Barre commune sous chaque grille paginée : réglage de densité à gauche, navigation à droite.
   width:100% est indispensable — dans un FluentStack vertical sans « Stretch », la barre restait en
   fit-content et tout se tassait à gauche (disposition divergente entre conformité et véhicules). */
.rcm-pagination-barre {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    width: 100%;
}

/* Libellé « Par page » soudé à son menu (voir SelecteurTaillePage.razor). */
.rcm-taille-page {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
}

.rcm-taille-page-libelle {
    font-size: 0.85rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* Groupe de navigation maison (Précédent / x–y sur N / Suivant) des paginations sans FluentPaginator. */
.rcm-pagination-nav {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.rcm-compteur strong {
    font-variant-numeric: tabular-nums;
    color: var(--neutral-foreground-rest, #242424);
    font-weight: 600;
}

/* Cellule sans valeur (référentiel) : tiret grisé, jamais un vide ambigu. */
.rcm-coord-vide {
    color: var(--neutral-foreground-hint, #9a9a9a);
}

/* ============================================================================
   Vignettes de preuve normalisées (P3-4) — emprise fixe, fond neutre.
   `contain` et non `cover` : une preuve ne se recadre pas. `cover` remplissait
   le cadre 3:2 en rognant le haut et le bas d'un cliché 16:9 — sur une photo de
   contrôle, c'est exactement la plaque ou le gabarit qu'on perd. Le cadre reste
   fixe (colonnes alignées), l'image est simplement centrée dans le fond neutre.
   ============================================================================ */
.rcm-vignette-preuve {
    width: 84px;
    height: 48px;
    object-fit: contain;
    border-radius: 4px;
    background: var(--neutral-fill-rest, #f0f0f0);
    display: block;
}

/* ============================================================================
   Écran barrière (/barriere) — l'opérateur est debout devant la barrière et lit
   l'écran à plusieurs mètres. Fond plein pleine surface, texte blanc, libellé
   TOUJOURS doublé d'une icône et d'un texte : la couleur ne porte jamais seule
   l'information (WCAG 1.4.1). Les trois feux sont dérivés de la palette des
   verdicts, sans y ajouter de nouvelle teinte.
   ============================================================================ */
:root {
    --rcm-feu-passe: var(--rcm-verdict-conforme);     /* vert   — passage autorisé      (6,28:1) */
    --rcm-feu-controle: var(--rcm-verdict-averifier); /* orange — contrôle avant ouverture (4,52:1) */
    --rcm-feu-arret: var(--rcm-verdict-infraction);   /* rouge  — infraction, arrêt     (5,85:1) */
    --rcm-feu-attente: var(--rcm-verdict-neutre);     /* gris   — évaluation en cours   (5,30:1) */
    --rcm-feu-alerte: var(--rcm-verdict-averifier);   /* orange — écran non configuré   (4,52:1) */
    --rcm-feu-texte: #ffffff;
    --rcm-barriere-bandeau-fond: #1F2933;
}

/* Coquille plein écran : seule la file des passages précédents défile. */
.rcm-barriere-coquille {
    height: 100dvh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: #ffffff;
}

.rcm-barriere-bandeau {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0 0.75rem;
    height: 2.25rem;
    background: var(--rcm-barriere-bandeau-fond);
    color: #ffffff;
    font-size: 0.8rem;
}

.rcm-barriere-bandeau-titre {
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.rcm-barriere-bandeau-point {
    opacity: 0.85;
}

.rcm-barriere-bandeau-espace {
    flex: 1 1 auto;
}

.rcm-barriere-bandeau-user {
    opacity: 0.85;
}

/* Lien et bouton de déconnexion : même apparence discrète, cible tactile suffisante. */
.rcm-barriere-bandeau-lien {
    display: inline-flex;
    align-items: center;
    min-height: 1.75rem;
    padding: 0 0.4rem;
    border: none;
    border-radius: 3px;
    background: transparent;
    color: #ffffff;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.rcm-barriere-bandeau-lien:hover {
    background: rgba(255, 255, 255, 0.14);
}

.rcm-barriere-contenu {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* --- Panneau principal : ~40 % de la hauteur utile ---
   Volontairement plus compact qu'auparavant (flex 3 → 2, paddings et typographies resserrés) : le
   panneau ne porte que quatre informations et laissait la file à quatre ou cinq lignes, alors que
   l'agent y cherche un camion passé il y a vingt minutes. La lisibilité à distance est préservée par
   les clamp() ci-dessous, qui restent largement au-dessus des tailles d'un écran de bureau. */
.rcm-barriere-principal {
    flex: 2 1 0;
    min-height: 0;
    display: flex;
}

.rcm-barriere-panneau {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    width: 100%;
    padding: 0.5rem 1rem;
    border: none;
    color: var(--rcm-feu-texte);
    font: inherit;
    text-align: center;
    background: var(--rcm-feu-attente);
    /* Filet : rien ne doit déborder sur la file, même avec une plaque étrangère très longue. Les
       media queries ci-dessous font en sorte que le contenu tienne réellement dans le plafond. */
    overflow: hidden;
}

button.rcm-barriere-panneau {
    cursor: pointer;
}

button.rcm-barriere-panneau:focus-visible {
    outline: 4px solid #ffffff;
    outline-offset: -8px;
}

.rcm-barriere-panneau--passe { background: var(--rcm-feu-passe); }
.rcm-barriere-panneau--controle { background: var(--rcm-feu-controle); }
.rcm-barriere-panneau--arret { background: var(--rcm-feu-arret); }
.rcm-barriere-panneau--attente { background: var(--rcm-feu-attente); }
.rcm-barriere-panneau--neutre { background: var(--rcm-feu-attente); }

/* FluentIcon pose la largeur en STYLE INLINE (width: 24px) : seul !important peut la remettre à
   l'échelle de l'écran barrière, qui se lit à plusieurs mètres. */
.rcm-barriere-icone svg {
    width: clamp(1.75rem, 4vw, 3.25rem) !important;
    height: auto;
}

.rcm-barriere-plaque {
    font-family: ui-monospace, "Cascadia Mono", "Consolas", "Menlo", monospace;
    font-size: clamp(2.25rem, 9vw, 6rem);
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 1;
}

.rcm-barriere-heure {
    font-size: clamp(1.1rem, 2.6vw, 2rem);
    font-weight: 600;
    line-height: 1.1;
}

.rcm-barriere-libelle {
    font-size: clamp(1.4rem, 3.8vw, 3rem);
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.05;
}

/* Sous-libellé : cause COURTE du verdict (cf. FormatsBarriere.CauseCourte). Deux lignes au plus,
   au-delà on tronque plutôt que de repousser l'invitation « Voir le détail » hors du panneau. */
.rcm-barriere-sous-libelle {
    font-size: clamp(0.95rem, 1.8vw, 1.4rem);
    max-width: 48ch;
    /* `display: -webkit-box` désactive le `min-height: auto` des éléments flex : sans ce
       `flex-shrink: 0`, le panneau comprimé (depuis l'ajout du bandeau portail) réduisait ce bloc à
       une bande de quelques pixels où le texte bavait derrière l'invitation « Voir le détail ». */
    flex: 0 0 auto;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rcm-barriere-action {
    margin-top: 0.2rem;
    padding: 0.2rem 0.8rem;
    border: 2px solid currentColor;
    border-radius: 999px;
    font-size: clamp(0.8rem, 1.4vw, 1.05rem);
    font-weight: 600;
}

/* --- Bandeau portail ---
   Ce que l'agent fait du camion présent. Sur feu vert, une simple pastille (« Ouverture automatique »)
   suffit : il n'y a rien à décider. Sur orange ou rouge, deux cibles tactiles larges — l'agent est
   debout, ganté, devant une tablette de guérite — dont le geste est archivé au dossier. Aucun
   matériel n'est piloté : ces boutons n'ouvrent rien, ils se souviennent.
   Trois partis pris de forme, tous dictés par l'usage terrain :
   1. un seul aplat de couleur (le geste d'ouverture) — deux boutons pleins côte à côte se
      ressemblaient trop et invitaient au mauvais clic ;
   2. un écart franc entre les deux gestes, qui sont opposés et irrévocablement consignés ;
   3. le dernier geste relégué en pastille de fin de rangée : il se relit, il ne se clique pas. */
.rcm-barriere-portail {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.65rem 1rem;
    border-top: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    background: var(--rcm-fond-page, #f7f7f7);
}

/* Intitulé de la rangée : une étiquette en petites capitales, dans l'esprit du bandeau supérieur.
   Volontairement discrète — ce sont les boutons qui portent le sens. */
.rcm-barriere-portail-question {
    flex: 0 0 auto;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* Groupe des deux gestes : largeur commune et bornée — assez large pour un doigt ganté, jamais étiré
   d'un bord à l'autre d'un écran mural. C'est ce conteneur qui porte l'écart de sécurité. */
.rcm-barriere-portail-actions {
    flex: 1 1 24rem;
    max-width: 42rem;
    display: flex;
    gap: 1.5rem;
}

.rcm-barriere-portail-bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    /* Cible tactile généreuse : 3,5 rem = 56 px, bien au-delà des 44 px recommandés. */
    min-height: 3.5rem;
    padding: 0 1.2rem;
    border: 2px solid transparent;
    border-radius: 8px;
    font: inherit;
    font-size: clamp(1rem, 1.5vw, 1.2rem);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    /* Transitions très courtes : un écran de terrain doit répondre, pas s'animer. */
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease,
                box-shadow 120ms ease, transform 60ms ease;
}

/* FluentIcon peint son SVG en accent (bleu) par défaut : sans cette reprise, le pictogramme et le
   libellé seraient lus comme deux informations distinctes. */
.rcm-barriere-portail-bouton svg,
.rcm-barriere-portail-bouton svg path {
    fill: currentColor;
}

/* Geste principal : le seul aplat plein de la rangée, il se repère sans lire. */
.rcm-barriere-portail-bouton--ouvrir {
    flex: 3 1 0;
    background: var(--rcm-feu-passe);
    border-color: var(--rcm-feu-passe);
    color: var(--rcm-feu-texte);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.20);
}

.rcm-barriere-portail-bouton--ouvrir:hover:not(:disabled) {
    background: #0B5A0B;
    border-color: #0B5A0B;
}

/* Geste secondaire : contour sombre neutre plutôt qu'un second feu — la couleur du feu est déjà
   au-dessus, sur le panneau, et la répéter ici brouillerait la hiérarchie des deux gestes. */
.rcm-barriere-portail-bouton--fermer {
    flex: 2 1 0;
    background: #ffffff;
    border-color: var(--rcm-barriere-bandeau-fond);
    color: var(--rcm-barriere-bandeau-fond);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.12);
}

.rcm-barriere-portail-bouton--fermer:hover:not(:disabled) {
    background: var(--rcm-barriere-bandeau-fond);
    border-color: var(--rcm-barriere-bandeau-fond);
    color: #ffffff;
}

/* Enfoncement : le bouton descend sur son ombre. Retour tactile net sur un écran sans clavier. */
.rcm-barriere-portail-bouton:active:not(:disabled) {
    transform: translateY(2px);
    box-shadow: none;
}

.rcm-barriere-portail-bouton--ouvrir:active:not(:disabled) {
    background: #094A09;
    border-color: #094A09;
}

.rcm-barriere-portail-bouton--fermer:active:not(:disabled) {
    background: #0E1620;
    border-color: #0E1620;
    color: #ffffff;
}

/* Focus clavier : anneau sombre doublé d'un halo, lisible aussi bien sur le vert plein que sur le
   fond clair de la rangée (WCAG 2.4.7). */
.rcm-barriere-portail-bouton:focus-visible {
    outline: 3px solid var(--rcm-barriere-bandeau-fond);
    outline-offset: 3px;
    box-shadow: 0 0 0 6px rgba(31, 41, 51, 0.18);
}

.rcm-barriere-portail-bouton:disabled {
    opacity: 0.45;
    cursor: default;
    transform: none;
    box-shadow: none;
}

/* Geste rapide « Ignorer » : décision de dossier, pas geste de portail. Délibérément DISCRET —
   contour fin, pas de capitales, pas d'aplat — pour qu'il ne se confonde jamais avec les deux gestes
   ci-contre, qui commandent la barrière devant un camion à l'arrêt. Il garde toutefois une cible
   tactile confortable : l'écran de la barrière se touche au doigt, parfois ganté. */
.rcm-barriere-ignorer {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    flex: 0 0 auto;
    min-height: 2.6rem;
    padding: 0 0.9rem;
    border: 1px solid var(--neutral-stroke-rest, #c8c8c8);
    border-radius: 8px;
    background: #ffffff;
    color: var(--neutral-foreground-hint, #5a5a5a);
    font: inherit;
    font-size: 0.92rem;
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

/* Même reprise que sur les boutons de portail : FluentIcon peint son SVG en accent par défaut. */
.rcm-barriere-ignorer svg,
.rcm-barriere-ignorer svg path {
    fill: currentColor;
}

.rcm-barriere-ignorer:hover:not(:disabled) {
    border-color: var(--rcm-barriere-bandeau-fond);
    color: var(--rcm-barriere-bandeau-fond);
}

.rcm-barriere-ignorer:focus-visible {
    outline: 3px solid var(--rcm-barriere-bandeau-fond);
    outline-offset: 3px;
}

.rcm-barriere-ignorer:disabled {
    opacity: 0.45;
    cursor: default;
}

/* Bouton + légende empilés : la légende dit le motif que le clic enregistre, visible au toucher
   là où le title du bouton ne s'affiche qu'à la souris. */
.rcm-barriere-ignorer-bloc {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    flex: 0 0 auto;
}

.rcm-barriere-ignorer-aide {
    font-size: 0.78rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* --- Pastilles de la rangée portail : information, jamais action ---
   Même gabarit pour la mention du feu vert et pour le dernier geste consigné, afin que la rangée
   garde la même silhouette quel que soit le feu affiché au-dessus. */
.rcm-barriere-pastille {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 2.1rem;
    padding: 0.25rem 0.9rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 0.92rem;
    line-height: 1.25;
}

.rcm-barriere-pastille svg,
.rcm-barriere-pastille svg path {
    fill: currentColor;
}

/* Feu vert : la pastille occupe la place des boutons absents, donc à gauche comme eux. */
.rcm-barriere-pastille--auto {
    font-weight: 700;
    color: var(--rcm-feu-passe);
    background: rgba(14, 112, 14, 0.10);
    border-color: rgba(14, 112, 14, 0.35);
}

/* Verdict indisponible : l'évaluation a échoué et aucun verdict ne viendra. La pastille prend la
   place des boutons — le geste n'a pas de dossier où s'archiver — et emprunte la couleur de l'orange
   du feu, pour que la rangée dise la même chose que le panneau juste au-dessus. */
.rcm-barriere-pastille--alerte {
    font-weight: 700;
    color: var(--rcm-feu-controle);
    background: rgba(191, 122, 0, 0.10);
    border-color: rgba(191, 122, 0, 0.35);
}

/* Panneau gris (évaluation en vol) : la pastille tient la place des boutons absents et reprend le gris
   du panneau. Neutre à dessein — elle ne doit ni promettre l'ouverture (vert) ni alarmer (orange). */
.rcm-barriere-pastille--attente {
    font-weight: 700;
    color: var(--neutral-foreground-hint, #5a5a5a);
    background: rgba(90, 90, 90, 0.08);
    border-color: rgba(90, 90, 90, 0.30);
}

/* Dernier geste : poussé en fin de rangée, sans jamais voler la vedette aux boutons. */
.rcm-barriere-pastille--geste {
    margin-left: auto;
    color: var(--neutral-foreground-hint, #5a5a5a);
    background: #ffffff;
    border-color: var(--neutral-stroke-rest, #e0e0e0);
}

.rcm-barriere-pastille-titre {
    font-weight: 700;
    color: var(--rcm-barriere-bandeau-fond);
}

/* --- File des passages de la fenêtre récente (~60 %) ---
   Seule zone défilante de l'écran (la coquille reste en 100dvh sans scroll de document) ; le défilement
   tactile doit rester fluide sur la tablette du poste. */
.rcm-barriere-file {
    flex: 3 1 0;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    border-top: 3px solid var(--rcm-barriere-bandeau-fond);
}

.rcm-barriere-ligne {
    display: flex;
    align-items: center;
    gap: 1rem;
    width: 100%;
    min-height: 3.25rem;
    padding: 0.35rem 1rem;
    border: none;
    border-bottom: 1px solid var(--neutral-stroke-rest, #e0e0e0);
    background: #ffffff;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.rcm-barriere-ligne:hover {
    background: var(--rcm-fond-page);
}

.rcm-barriere-ligne:focus-visible {
    outline: 3px solid var(--rcm-barriere-bandeau-fond);
    outline-offset: -3px;
}

.rcm-barriere-ligne-heure {
    flex: 0 0 auto;
    width: 9ch;
    font-size: 1.35rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.rcm-barriere-ligne-plaque {
    flex: 1 1 auto;
    min-width: 0;
    font-family: ui-monospace, "Cascadia Mono", "Consolas", "Menlo", monospace;
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rcm-barriere-ligne-etat {
    flex: 0 0 auto;
}

.rcm-barriere-file-vide {
    margin: 0;
    padding: 1rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-barriere-fraicheur {
    flex: 0 0 auto;
    margin: 0;
    padding: 0.15rem 0.75rem;
    text-align: right;
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

/* Paramétrage inexploitable : l'écran ne montre plus rien d'autre que l'appel à l'administrateur. */
.rcm-barriere-nonconfigure {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 2rem;
    text-align: center;
    background: var(--rcm-feu-alerte);
    color: var(--rcm-feu-texte);
    font-size: clamp(1.25rem, 3.5vw, 2.5rem);
    font-weight: 700;
}

.rcm-barriere-nonconfigure svg {
    width: clamp(2.5rem, 6vw, 5rem) !important;
    height: auto;
}

/* --- Responsivité de l'écran barrière ---
   Le poste est indifféremment un grand écran mural, une tablette posée sur la guérite ou un portable
   de secours. Trois adaptations, toutes dans le même sens : ne JAMAIS laisser le panneau écraser la
   file, qui est ce que l'agent parcourt. La coquille reste en 100dvh sans scroll de document — seule
   `.rcm-barriere-file` défile. */

/* Écran peu haut (portable de bureau 900 px, tablette en paysage, portable 768 px) : le panneau est
   plafonné en hauteur plutôt qu'en proportion, sinon la file se réduit à deux lignes. Les tailles sont
   réduites ET l'icône retirée pour que le contenu TIENNE dans ce plafond : le panneau est en
   `overflow: hidden`, un contenu trop grand y serait rogné en plein milieu d'une ligne de texte. Le
   libellé reste, c'est lui qui double la couleur en texte (WCAG 1.4.1).
   Seuil remonté de 800 à 950 px avec l'arrivée du bandeau portail : celui-ci prend une rangée sur le
   budget vertical du panneau, et un 1440×900 ne tenait plus (sous-libellé écrasé). */
@media (max-height: 950px) {
    .rcm-barriere-principal {
        flex: 0 0 auto;
        max-height: 42dvh;
    }

    .rcm-barriere-plaque {
        font-size: clamp(1.9rem, 7vw, 3.5rem);
    }

    .rcm-barriere-libelle {
        font-size: clamp(1.15rem, 3vw, 2rem);
    }

    .rcm-barriere-sous-libelle {
        -webkit-line-clamp: 1;
        line-clamp: 1;
    }

    .rcm-barriere-icone {
        display: none;
    }
}

/* Écran étroit (tablette en portrait, téléphone) : l'heure et la pastille passent au-dessus de la
   plaque plutôt que de comprimer les trois colonnes jusqu'à l'illisible. */
@media (max-width: 640px) {
    .rcm-barriere-bandeau {
        gap: 0.4rem;
        padding: 0 0.4rem;
        font-size: 0.72rem;
    }

    .rcm-barriere-panneau {
        padding: 0.4rem 0.6rem;
    }

    /* Portail : les deux gestes s'empilent en pleine largeur plutôt que de se partager 480 px, où ils
       redeviendraient deux petites cibles voisines — exactement ce que l'écart cherche à éviter. */
    .rcm-barriere-portail {
        padding: 0.55rem 0.7rem;
    }

    .rcm-barriere-portail-actions {
        flex: 1 1 100%;
        flex-direction: column;
        gap: 0.85rem;
    }

    /* Plus de place pour la reléguer à droite : la pastille repasse sous les boutons, à gauche. */
    .rcm-barriere-pastille--geste {
        margin-left: 0;
    }

    .rcm-barriere-heure {
        font-size: clamp(0.95rem, 4vw, 1.4rem);
    }

    .rcm-barriere-ligne {
        flex-wrap: wrap;
        gap: 0.2rem 0.75rem;
        padding: 0.45rem 0.7rem;
    }

    .rcm-barriere-ligne-heure {
        font-size: 1.05rem;
    }

    .rcm-barriere-ligne-plaque {
        font-size: 1.2rem;
        /* Passe en pleine largeur sous l'heure : la plaque ne doit jamais être tronquée. */
        flex: 1 0 100%;
        order: 3;
    }

    .rcm-barriere-ligne-etat {
        margin-left: auto;
    }
}

/* Très petite hauteur (tablette clavier déplié, fenêtre réduite) : le panneau rend tout ce qu'il peut
   à la file et se réduit à plaque + heure + état. Le sous-libellé disparaît — sa cause courte est
   reprise dans le détail —, jamais le libellé principal ni l'invitation « Voir le détail ». */
@media (max-height: 560px) {
    .rcm-barriere-principal {
        max-height: 38dvh;
    }

    .rcm-barriere-sous-libelle {
        display: none;
    }

    /* La rangée portail rend ses marges, jamais la hauteur de ses boutons : la cible tactile de 56 px
       est justement ce dont l'agent a besoin quand l'écran est déjà à l'étroit. */
    .rcm-barriere-portail {
        padding: 0.4rem 1rem;
        gap: 0.35rem 0.9rem;
    }
}

/* ==========================================================================
   Refonte écran véhicules (feature/refonte-vehicules) — bloc ajouté en fin de
   fichier pour ne pas entrer en conflit avec les règles existantes.
   ========================================================================== */

/* Grille dont chaque ligne ouvre une fiche : le curseur doit l'annoncer, sauf
   sur la colonne d'actions dont les boutons ne naviguent pas (stopPropagation). */
.rcm-grille-cliquable tbody tr {
    cursor: pointer;
}

.rcm-grille-cliquable tbody tr .rcm-actions-grille {
    cursor: default;
}

/* ==========================================================================
   Fiche véhicule & pleine largeur (feature/fiche-vehicule) — bloc ajouté en
   fin de fichier pour ne pas entrer en conflit avec les règles existantes.
   ========================================================================== */

/* `.rcm-intro-large p` n'a plus de règle : sa seule raison d'être était une bride
   de largeur (96ch), retirée le 13/08/2026 — les textes d'écran suivent leur
   conteneur (exigence ferme de l'utilisateur, CLAUDE.md « Conventions UI
   durables »). La classe reste dans le balisage. */

/* Chaîne de navigation en tête de page : flèche de retour + titre alignés. */
.rcm-fil-retour {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}

/* Bandeau d'identité de la fiche : la plaque prime, les compteurs l'accompagnent. */
.rcm-fiche-entete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 2rem;
}

.rcm-fiche-plaque {
    font-size: 1.6rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
}

/* Compteurs d'activité : libellé discret au-dessus de la valeur. */
.rcm-fiche-mesures {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 2rem;
}

.rcm-fiche-mesure {
    display: flex;
    flex-direction: column;
}

.rcm-fiche-mesure span:first-child {
    font-size: 0.8rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-fiche-mesure span:last-child {
    font-size: 1.05rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Période non déplaçable de la file des contrôles en vue limitée : mêmes
   gabarits qu'une étiquette de champ FluentUI, pour que la barre de filtres
   garde son alignement une fois les deux sélecteurs de dates retirés. */
.rcm-periode-figee {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding-bottom: 0.35rem;
}

.rcm-periode-figee-libelle {
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint, #5a5a5a);
}

.rcm-periode-figee-valeur {
    font-size: 0.9rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
