/* ============================================================
   BioSans — Mondria custom typeface
   ============================================================ */
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-ExtraLight.otf') format('opentype'); font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-ExtraLightItalic.otf') format('opentype'); font-weight: 200; font-style: italic; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-Light.otf') format('opentype'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-LightItalic.otf') format('opentype'); font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-Regular.otf') format('opentype'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-Italic.otf') format('opentype'); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-SemiBold.otf') format('opentype'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-SemiBoldItalic.otf') format('opentype'); font-weight: 600; font-style: italic; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-Bold.otf') format('opentype'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-BoldItalic.otf') format('opentype'); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-ExtraBold.otf') format('opentype'); font-weight: 800; font-style: normal; font-display: swap; }
@font-face { font-family: 'BioSans'; src: url('fonts/BioSans-ExtraBoldItalic.otf') format('opentype'); font-weight: 800; font-style: italic; font-display: swap; }

/* ============================================================
   RendezVous — jetons de design (système « Mondria Atlas »)
   ------------------------------------------------------------
   Le clair vit sur :root ; le sombre surcharge via html.rv-dark /
   body.rv-dark, la classe que js/theme.js pose avant le premier
   rendu et que MudProviders tient à jour.

   Valeurs reprises de MIA (DockerAutomation,
   src/Mia.Core/wwwroot/css/app.css) pour que les deux consoles de
   la maison se lisent comme un seul produit :
     - sombre : nuit NEUTRE (#0A1017), cartes un cran au-dessus
       (#10171E) et découpées par un FILET, pas par une teinte ;
     - clair  : canevas #F5F7FA, surfaces blanches, filets #E0E3EB.

   UN accent d'action — le bleu signal (#3899F9 la nuit, #1065E5 au
   clair, où le premier tombe sous AA). L'orange Mondria (#FF4200)
   n'est pas une couleur d'interface : c'est une MARQUE (barrette du
   lien actif, carré du logo). Jamais du texte, jamais un bouton.

   Components/Layout/MondriaTheme.cs décrit les mêmes couleurs pour
   MudBlazor : les deux fichiers bougent ensemble, et avec MIA.
   ============================================================ */
:root {
    /* Marque — identité seulement. Jamais du texte, jamais un aplat d'action. */
    --rv-brand:            #FF4200;
    --rv-brand-rgb:        255, 66, 0;

    /* Action — le bleu signal d'Atlas. Au clair il s'assombrit (#1065E5) :
       le #3899F9 de la nuit tombe sous AA sur du blanc. */
    --rv-accent-rgb:       16, 101, 229;
    --rv-primary:          #1065E5;
    --rv-primary-hover:    #0A55C9;
    --rv-primary-active:   #0447BF;
    --rv-on-primary:       #FFFFFF;   /* 5,1:1 sur #1065E5 */
    --rv-primary-soft:     rgba(16, 101, 229, 0.08);
    --rv-primary-ink:      #0E5BD0;   /* le bleu en texte — AA sur surface et canevas */

    /* Surfaces */
    --rv-canvas:           #F5F7FA;
    --rv-surface:          #FFFFFF;
    --rv-surface-2:        #EEF1F6;   /* en-têtes de tableau, barres d'outils, puits */
    --rv-surface-3:        #E6EAF1;   /* ligne pressée / sélectionnée */
    --rv-input-bg:         #FFFFFF;
    --rv-hover:            rgba(17, 24, 39, 0.04);
    --rv-selected:         rgba(16, 101, 229, 0.07);

    /* Rampe d'encre — gris neutres d'Atlas */
    --rv-ink:              #1F2937;
    --rv-ink-2:            #374151;
    --rv-ink-3:            #4B5563;   /* texte secondaire / aide — 7,2:1 sur le canevas */
    --rv-ink-4:            #6B7280;   /* horodatages, méta — 4,6:1 sur le canevas */
    --rv-ink-disabled:     #9CA3AF;

    /* Bordures */
    --rv-border:           #E0E3EB;
    --rv-border-mid:       #D3D8E2;
    --rv-border-strong:    #C8CCD8;

    /* Chrome (barre haute, tiroir). Il SUIT le thème, comme dans Atlas : blanc au
       clair, un cran au-dessus de la nuit en sombre. Le navy permanent de l'ancien
       tiroir est retiré. */
    --rv-chrome-bg:        #FFFFFF;
    --rv-chrome-ink:       #1F2937;
    --rv-chrome-ink-2:     #4B5563;   /* liens du tiroir, texte d'appui */
    --rv-chrome-ink-3:     #6B7280;   /* icônes, intitulés de section, méta */
    --rv-chrome-line:      #E0E3EB;
    --rv-chrome-hover:     rgba(17, 24, 39, 0.05);
    --rv-chrome-well:      rgba(17, 24, 39, 0.03);

    /* Sémantique — lisible en texte sur surface, avec aplats doux assortis */
    --rv-success:          #0E7C55;
    --rv-success-soft:     #E8F7F0;
    --rv-success-border:   #B6E3CE;
    --rv-warning:          #9A5B00;
    --rv-warning-soft:     #FDF3E3;
    --rv-warning-border:   #EFD5A8;
    --rv-error:            #C42B30;
    --rv-error-soft:       #FDEEEE;
    --rv-error-border:     #F0C4C4;
    /* #1F6FD0 ne tenait que 4.47:1 sur son propre aplat doux : assombri
       juste assez pour passer le 4.5:1 sur --rv-info-soft ET sur la surface. */
    --rv-info:             #1A5FAE;
    --rv-info-soft:        #EDF4FD;
    --rv-info-border:      #C3DBF5;
    --rv-neutral-soft:     #F0F2F5;

    /* Info-bulle — une surface INVERSE, pour qu'elle se lise comme un objet qui
       flotte au-dessus de la page et non comme une feuille de plus. */
    --rv-tooltip-bg:       #1F2937;
    --rv-tooltip-ink:      #F3F4F6;
    --rv-tooltip-border:   #1F2937;

    /* Rayons — une seule échelle, registre produit */
    --rv-radius-xs:   4px;
    --rv-radius-sm:   6px;
    --rv-radius-md:   8px;
    --rv-radius-lg:  12px;
    --rv-radius-xl:  16px;
    --rv-radius-full: 9999px;

    /* Élévation — en clair la structure vient des bordures ; l'ombre est réservée à ce qui flotte */
    --rv-shadow-xs: 0 1px 2px rgba(17, 24, 39, 0.04);
    --rv-shadow-sm: 0 1px 3px rgba(17, 24, 39, 0.06), 0 1px 2px rgba(17, 24, 39, 0.04);
    --rv-shadow-md: 0 4px 12px rgba(17, 24, 39, 0.08), 0 1px 3px rgba(17, 24, 39, 0.05);
    --rv-shadow-lg: 0 12px 32px rgba(17, 24, 39, 0.12), 0 2px 6px rgba(17, 24, 39, 0.05);

    /* Focus — l'accent d'action, pas la marque */
    --rv-focus-ring:      0 0 0 2px var(--rv-surface), 0 0 0 4px rgba(var(--rv-accent-rgb), 0.55);
    --rv-focus-ring-flat: 0 0 0 2px rgba(var(--rv-accent-rgb), 0.55);

    /* Mouvement — registre produit : rapide, porteur d'état, aucune chorégraphie */
    --rv-ease:        cubic-bezier(0.22, 0.61, 0.36, 1);
    --rv-dur-fast:    120ms;
    --rv-dur:         160ms;
    --rv-dur-slow:    220ms;

    /* Échelle de z-index. Ordonnée par ce qui doit flotter au-dessus de quoi :
       un menu déroulant naît du chrome, donc il le dépasse. Le placer sous le
       tiroir et la barre haute, c'est ainsi qu'un menu finit caché derrière ce
       qui l'a ouvert. */
    --rv-z-sticky:   200;
    --rv-z-drawer:   300;
    --rv-z-dropdown: 400;
    --rv-z-backdrop: 500;
    --rv-z-modal:    600;
    --rv-z-toast:    700;
    --rv-z-tooltip:  800;

    /* Largeur du tiroir — la même que MudDrawer (MainLayout) et que MIA. */
    --rv-drawer-w: 252px;

    /* Police monospace — une seule pile pour tout le produit */
    --rv-mono: 'Cascadia Code', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* ── Alias de compatibilité ───────────────────────────────
       Des vues référencent encore --gcb-* en style inline.
       On les fait pointer sur la nouvelle échelle pour que rien ne dérive. */
    --gcb-primary:        var(--rv-primary);
    --gcb-primary-dark:   var(--rv-primary-hover);
    --gcb-primary-soft:   var(--rv-primary-soft);
    --gcb-accent:         var(--rv-ink-2);
    --gcb-accent-dark:    var(--rv-ink);
    --gcb-bg:             var(--rv-canvas);
    --gcb-bg-secondary:   var(--rv-surface-2);
    --gcb-surface:        var(--rv-surface);
    --gcb-elevated:       var(--rv-surface);
    --gcb-input-bg:       var(--rv-input-bg);
    --gcb-bg-sidebar:     var(--rv-chrome-bg);
    --gcb-bg-hover:       var(--rv-hover);
    --gcb-bg-active:      var(--rv-selected);
    --gcb-text-primary:   var(--rv-ink);
    --gcb-text-secondary: var(--rv-ink-2);
    --gcb-text-muted:     var(--rv-ink-3);
    --gcb-text-subtle:    var(--rv-ink-4);
    --gcb-border:         var(--rv-border);
    --gcb-border-mid:     var(--rv-border-mid);
    --gcb-border-strong:  var(--rv-border-strong);
    --gcb-success:        var(--rv-success);
    --gcb-warning:        var(--rv-warning);
    --gcb-error:          var(--rv-error);
    --gcb-info:           var(--rv-info);
    --gcb-radius-sm:      var(--rv-radius-sm);
    --gcb-radius-md:      var(--rv-radius-md);
    --gcb-radius-lg:      var(--rv-radius-lg);
    --gcb-radius-xl:      var(--rv-radius-xl);
    --gcb-radius-full:    var(--rv-radius-full);
    --gcb-shadow-sm:      var(--rv-shadow-sm);
    --gcb-shadow-md:      var(--rv-shadow-md);
    --gcb-shadow-lg:      var(--rv-shadow-lg);
    --gcb-transition:     var(--rv-dur-fast) var(--rv-ease);
    --gcb-transition-md:  var(--rv-dur) var(--rv-ease);
}

/* ── Thème sombre ────────────────────────────────────────── */
html.rv-dark,
body.rv-dark {
    /* Nuit neutre d'Atlas : noir à peine bleuté. C'est le filet qui découpe
       une carte, pas sa teinte — un fond navy teintait tout l'écran. */
    --rv-canvas:           #0A1017;
    --rv-surface:          #10171E;
    --rv-surface-2:        #161E28;
    --rv-surface-3:        #1C2531;
    --rv-input-bg:         #0B1219;   /* un champ est un creux : plus sombre que la surface */
    --rv-hover:            rgba(230, 237, 243, 0.05);
    --rv-selected:         rgba(56, 153, 249, 0.12);

    --rv-ink:              #E6EDF3;   /* 15:1 sur une carte */
    --rv-ink-2:            #BAC6D2;
    --rv-ink-3:            #8FA0B2;   /* 6,6:1 sur une carte */
    --rv-ink-4:            #8495A7;
    --rv-ink-disabled:     #5F6F80;

    --rv-border:           #222A33;
    --rv-border-mid:       #2A343F;
    --rv-border-strong:    #323D4B;

    --rv-accent-rgb:       56, 153, 249;
    --rv-primary:          #3899F9;
    --rv-primary-hover:    #5AABFA;
    --rv-primary-active:   #1F7FD8;
    --rv-on-primary:       #08111C;   /* blanc sur ce bleu = 3,0:1 ; l'encre de nuit passe AA */
    --rv-primary-ink:      #66B2FB;
    --rv-primary-soft:     rgba(56, 153, 249, 0.14);

    --rv-success:          #4FD99B;
    --rv-success-soft:     rgba(79, 217, 155, 0.12);
    --rv-success-border:   rgba(79, 217, 155, 0.28);
    --rv-warning:          #E6B25C;
    --rv-warning-soft:     rgba(230, 178, 92, 0.12);
    --rv-warning-border:   rgba(230, 178, 92, 0.28);
    --rv-error:            #F2647D;
    --rv-error-soft:       rgba(242, 100, 125, 0.12);
    --rv-error-border:     rgba(242, 100, 125, 0.30);
    --rv-info:             #66B2FB;
    --rv-info-soft:        rgba(56, 153, 249, 0.12);
    --rv-info-border:      rgba(56, 153, 249, 0.30);
    --rv-neutral-soft:     rgba(230, 237, 243, 0.07);

    --rv-chrome-bg:        #0B1118;
    --rv-chrome-ink:       #E6EDF3;
    --rv-chrome-ink-2:     #AEBBC8;
    --rv-chrome-ink-3:     #8FA0B2;
    --rv-chrome-line:      #1C242E;
    --rv-chrome-hover:     rgba(230, 237, 243, 0.06);
    --rv-chrome-well:      rgba(230, 237, 243, 0.04);

    /* Inverse veut toujours dire inverse : une bulle de nuit sur la nuit
       disparaîtrait, elle monte donc d'un cran et se découpe par un filet. */
    --rv-tooltip-bg:       #1C2531;
    --rv-tooltip-ink:      #E6EDF3;
    --rv-tooltip-border:   #323D4B;

    --rv-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.30);
    --rv-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.40);
    --rv-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.50);
    --rv-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.60);

    --rv-focus-ring:      0 0 0 2px var(--rv-canvas), 0 0 0 4px rgba(56, 153, 249, 0.7);
    --rv-focus-ring-flat: 0 0 0 2px rgba(56, 153, 249, 0.7);
}

/* ============================================================
   Base
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html {
    background-color: var(--rv-canvas);
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

html, body {
    margin: 0;
    padding: 0;
    font-family: 'BioSans', -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    background-color: var(--rv-canvas);
    color: var(--rv-ink);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Les heures et les dates d'un tableau de suivi s'alignent colonne par colonne. */
    font-variant-numeric: tabular-nums;
}

/* Fond de nuit d'Atlas : presque plat. Les bords tiennent #090F16, le
   centre-bas monte à peine ; deux radiales à peine perceptibles suffisent —
   plus elles chauffent, plus elles ramènent le navy qu'Atlas a retiré.
   Le clair reste un canevas uni. */
body.rv-dark {
    background-image:
        radial-gradient(1200px 760px at 50% 104%, rgba(46, 66, 92, 0.16), transparent 64%),
        radial-gradient(1500px 560px at 52% -10%, rgba(40, 58, 82, 0.10), transparent 62%),
        linear-gradient(170deg, #090F16 0%, #0A1118 55%, #090F16 100%);
    background-attachment: fixed;
}

::selection {
    background: rgba(var(--rv-accent-rgb), 0.22);
    color: var(--rv-ink);
}

/* ============================================================
   Focus — visible, cohérent, clavier uniquement.

   Porté sur ce qu'on manipule réellement. Blazor pose le focus sur
   le <h1 tabindex="-1"> après chaque navigation pour les lecteurs
   d'écran : un anneau là n'est pas une affordance, c'est du bruit,
   donc les cibles programmatiques sont exclues.
   ============================================================ */
a:focus-visible,
button:focus-visible,
select:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
[role="menuitem"]:focus-visible,
input:focus-visible,
textarea:focus-visible,
.mud-button-root:focus-visible,
.mud-icon-button:focus-visible,
.mud-nav-link:focus-visible,
.mud-chip:focus-visible,
.mud-table-row-clickable:focus-visible {
    outline: none;
    box-shadow: var(--rv-focus-ring-flat) !important;
    border-radius: var(--rv-radius-xs);
}

/* Cibles de focus programmatique et conteneurs défilants : jamais d'anneau. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible,
h1:focus, h2:focus, h3:focus,
h1:focus-visible, h2:focus-visible, h3:focus-visible,
div:focus-visible, section:focus-visible, main:focus-visible {
    outline: none !important;
    box-shadow: none !important;
}

/* Le champ texte gère son propre focus (bordure + halo doux) : l'input
   interne ne doit pas dessiner un second anneau par-dessus. */
.mud-input input:focus-visible,
.mud-input textarea:focus-visible,
.mud-input-slot:focus-visible {
    box-shadow: none !important;
}

/* ============================================================
   Rôles de couleur du texte

   `Color.Secondary` sert partout au texte d'appui. La Secondary de
   la palette est un gris d'encre : on la force sur la rampe d'encre
   pour qu'une légende ne ressemble jamais à un lien.
   ============================================================ */
.mud-secondary-text,
.mud-typography.mud-secondary-text { color: var(--rv-ink-3) !important; }
.mud-secondary-text .mud-icon-root { color: var(--rv-ink-4) !important; }

/* `Color.Tertiary` : la Tertiary de la palette est une SURFACE. Employée
   comme couleur de texte, elle donnait du clair sur clair. */
.mud-tertiary-text,
.mud-typography.mud-tertiary-text { color: var(--rv-ink-4) !important; }

/* Le tiroir a sa propre rampe (--rv-chrome-*), qui suit le thème. */
.mud-drawer .mud-secondary-text,
.mud-drawer .mud-typography.mud-secondary-text,
.mud-drawer .mud-typography-caption { color: var(--rv-chrome-ink-2) !important; }
.mud-drawer .mud-secondary-text .mud-icon-root { color: var(--rv-chrome-ink-3) !important; }

/* ============================================================
   Liens
   ============================================================ */
a {
    color: var(--rv-primary-ink);
    text-decoration: none;
    transition: color var(--rv-dur) var(--rv-ease);
}
/* MudLink applique `.mud-primary-text`, qui porte la Primary de la palette :
   le bleu d'ACTION, calibré pour un aplat. Le lien reprend le bleu d'ENCRE,
   calibré pour être lu. */
.mud-link.mud-primary-text,
.mud-typography.mud-primary-text { color: var(--rv-primary-ink) !important; }
a:hover {
    color: var(--rv-primary-active);
    text-decoration: underline;
    text-underline-offset: 2px;
}
body.rv-dark a:hover { color: #8CC5FC; }

/* ============================================================
   Barre d'application — chrome discret. Le contenu est le sujet.
   ============================================================ */
/* Translucide sur le fond, séparée par un filet et non par une couleur (Atlas). */
.mud-appbar {
    background: color-mix(in srgb, var(--rv-chrome-bg) 88%, transparent) !important;
    backdrop-filter: blur(16px) saturate(1.1);
    -webkit-backdrop-filter: blur(16px) saturate(1.1);
    border-bottom: 1px solid var(--rv-chrome-line) !important;
    box-shadow: none !important;
    z-index: var(--rv-z-sticky) !important;
}
body.rv-dark .mud-appbar {
    background: color-mix(in srgb, var(--rv-chrome-bg) 72%, transparent) !important;
}
.mud-appbar .mud-toolbar { min-height: 64px; }
.mud-appbar .mud-icon-button { color: var(--rv-chrome-ink-2) !important; }

/* ── Verrou de marque : Mondria │ RendezVous ──────────────
   Mondria est la maison, RendezVous le produit. Le logotype porte la
   maison, le texte porte le produit, et un filet les tient distincts au
   lieu de les fondre en un seul mot. Même construction que MIA. */
.rv-brand-lockup {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    margin-left: 6px;
    flex-shrink: 0;
    text-decoration: none !important;
    border-radius: var(--rv-radius-sm);
}
.rv-brand-logo {
    height: 22px;
    width: auto;
    display: block;
    flex-shrink: 0;
}
.rv-brand-sep {
    width: 1px;
    height: 18px;
    background: var(--rv-border-strong);
    flex-shrink: 0;
}
/* Sur la nuit de la barre haute, un filet trop pâle disparaissait : les deux mots
   se lisaient « Mondria RendezVous » au lieu de « Mondria │ RendezVous ». */
body.rv-dark .rv-brand-sep { background: #3A4655; }
.rv-brand-product {
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1;
    color: var(--rv-ink);
    white-space: nowrap;
}
.rv-brand-lockup:hover .rv-brand-product { color: var(--rv-ink); }

/* Etudia reste visible sur mobile ; le nom du module s'efface au besoin. */
body.rv-dark .rv-brand-logo { background: transparent; }
.rv-brand-lockup:focus-visible { outline: 2px solid var(--rv-primary); outline-offset: 4px; }
@media (max-width: 599.95px) {
    .rv-brand-logo { height: 20px; }
    .rv-brand-lockup { gap: 9px; margin-left: 2px; }
    .rv-brand-product { font-size: 0.875rem; }
}
@media (max-width: 420px) {
    .rv-brand-sep, .rv-brand-product { display: none; }
}

/* ============================================================
   Tiroir / barre latérale — suit le thème (Atlas) : blanc au clair,
   un cran AU-DESSUS de la nuit en sombre. Il flotte, il ne se creuse pas.
   ============================================================ */
.mud-drawer {
    background: var(--rv-chrome-bg) !important;
    border-right: 1px solid var(--rv-chrome-line) !important;
    box-shadow: none !important;
    z-index: var(--rv-z-drawer) !important;
}
.mud-drawer-content {
    padding-left: 12px !important;
    padding-right: 12px !important;
    overflow-x: hidden !important;
}

/* ── Navigation ─────────────────────────────────────────── */
/* Conteneur défilant du menu. Il déborde de la gouttière du tiroir (12 px) pour
   la reprendre en padding : le rail orange du lien actif est dessiné à
   `left: -12px`, et un `overflow: hidden` posé sur un conteneur qui commence
   APRÈS la gouttière le coupait net — la règle existait, rien ne se peignait. */
.rv-nav-scroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    margin: 0 -12px;
    padding: 0 12px;
}
/* 12 px, pas 11 : sous 12 px, un texte de repère se lit mal sur le fond du tiroir (revue UX du 2026-10-26). */
.nav-section-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--rv-chrome-ink-3);
    padding: 15px 12px 4px;
    user-select: none;
    pointer-events: none;
}
/* L'accueil, en tête sans intitulé : il reprend l'air que l'intitulé lui donnait. */
.rv-nav-home { margin-top: 12px; }
.mud-nav-link {
    position: relative !important;
    border-radius: var(--rv-radius-md) !important;
    margin: 1px 0 !important;
    padding: 9px 12px !important;
    border-left: none !important;
    font-size: 0.875rem !important;
    font-weight: 500 !important;
    color: var(--rv-chrome-ink-2) !important;
    white-space: normal !important;
    transition: background var(--rv-dur-fast) var(--rv-ease), color var(--rv-dur-fast) var(--rv-ease) !important;
}
.mud-nav-link:hover:not(.active) {
    background: var(--rv-chrome-hover) !important;
    color: var(--rv-chrome-ink) !important;
}
/* Le `:not()` reprend celui de MudBlazor, qui pose
   `.mud-nav-link.active:not(.mud-nav-link-disabled) { font-weight: 500
   !important }` en spécificité (0,3,0). Sans lui, notre règle en (0,2,0) perdait
   malgré son `!important`, et l'élément actif gardait le poids des inactifs. */
/* `.rv-nav-parent` (posée par NavMenu sur le `.mud-nav-item`) : le lien de la section où vit une page
   fille — une organisation, un membre. Même lecture que l'actif : on est « dans » ce lien. */
.mud-nav-link.active,
.mud-nav-link.active:not(.mud-nav-link-disabled),
.rv-nav-parent > .mud-nav-link,
.rv-nav-parent > .mud-nav-link:not(.mud-nav-link-disabled) {
    /* Fond bleu levé (Atlas) ; l'orange reste à la barrette et à l'icône, où il désigne. */
    background: rgba(var(--rv-accent-rgb), 0.12) !important;
    color: var(--rv-chrome-ink) !important;
    font-weight: 600 !important;
}
/* Rail de sélection sur le bord du tiroir — un indicateur d'état,
   pas un liseré décoratif sur une carte. Porté par le conteneur
   `.mud-nav-item`, pas par le lien : MudBlazor pose `overflow: hidden` sur
   le lien pour contenir son ripple, et un `::before` dessiné à `left: -12px`
   sur le lien lui-même était coupé — la règle existait, rien ne se peignait. */
.mud-nav-item { position: relative; }
.mud-nav-item:has(> .mud-nav-link.active)::before,
.mud-nav-item.rv-nav-parent::before {
    content: "";
    position: absolute;
    left: -12px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 22px;
    background: var(--rv-brand);
    border-radius: 0 2px 2px 0;
    pointer-events: none;
}
.mud-nav-link .mud-icon-root {
    font-size: 18px !important;
    color: var(--rv-chrome-ink-3) !important;
    transition: color var(--rv-dur-fast) var(--rv-ease) !important;
}
.mud-nav-link:hover:not(.active) .mud-icon-root { color: var(--rv-chrome-ink-2) !important; }
.mud-nav-link.active .mud-icon-root,
.rv-nav-parent > .mud-nav-link .mud-icon-root,
.rv-nav-parent > .mud-nav-link:hover .mud-icon-root { color: var(--rv-brand) !important; }

/* ── Pied de la barre latérale ──────────────────────────── */
.sidebar-footer {
    margin: 0 4px 6px;
    /* 8 px de côté : la signature s'aligne sur les icônes du menu (24 px du bord) et
       le rang de logos tient dans les 203 px utiles du tiroir de 252 px. */
    padding: 16px 8px 8px;
    border-top: 1px solid var(--rv-chrome-line);
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* Le rôle s'affiche sous le nom, dans le menu du compte (barre haute) — plus ici. */
/* [Etudia] une plateforme [Mondria] : deux logos-liens autour d'une phrase.
   Les logos sont un peu éteints au repos et reprennent leur plein éclat au survol. */
.sidebar-footer-publisher {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0;
    color: var(--rv-chrome-ink-3);
    font-size: 0.6875rem;
    line-height: 1;
    white-space: nowrap;
}
.sidebar-footer-publisher a {
    display: block;
    flex-shrink: 0;
    border-radius: 4px;
    text-decoration: none !important;
}
.sidebar-footer-publisher img {
    display: block;
    width: auto;
    opacity: .8;
    transition: opacity var(--rv-dur-fast) var(--rv-ease);
}
.sidebar-footer-etudia  { height: 12px; }
/* Le pavé Mondria est plus haut que son mot : 18 px le met à la taille optique d'« etudia ». */
.sidebar-footer-mondria { height: 18px; }
.sidebar-footer-publisher a:focus-visible { outline: 2px solid var(--rv-primary); outline-offset: 3px; }
.sidebar-footer-publisher a:focus-visible img { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
    .sidebar-footer-publisher a:hover img { opacity: 1; }
}

/* ============================================================
   Surfaces — la structure vient des bordures, pas des ombres
   ============================================================ */
.mud-paper {
    background-color: var(--rv-surface);
    background-image: none;
    color: var(--rv-ink);
}
.mud-paper-outlined,
.mud-paper.mud-elevation-1,
.mud-paper.mud-elevation-2 {
    background: var(--rv-surface) !important;
    border: 1px solid var(--rv-border) !important;
    border-radius: var(--rv-radius-lg) !important;
    box-shadow: none !important;
    transition: border-color var(--rv-dur) var(--rv-ease), box-shadow var(--rv-dur) var(--rv-ease) !important;
}
body:not(.rv-dark) .mud-paper-outlined,
body:not(.rv-dark) .mud-paper.mud-elevation-1,
body:not(.rv-dark) .mud-paper.mud-elevation-2 {
    box-shadow: var(--rv-shadow-xs) !important;
}
.mud-paper-outlined:hover { border-color: var(--rv-border-mid) !important; }

/* Seules les surfaces flottantes reçoivent une vraie élévation.
   :not(.mud-tooltip) est porteur. MudTooltip partage ce même nœud — la
   bulle porte à la fois .mud-popover et .mud-tooltip — et c'est le seul
   membre de la famille que MudBlazor peint en clair-sur-sombre. Lui
   donner la couleur de surface ici mettait du texte blanc sur une
   pastille blanche. */
.mud-popover:not(.mud-tooltip), .mud-menu-popover, .mud-list.mud-menu-list, .mud-picker-popover {
    border: 1px solid var(--rv-border) !important;
    border-radius: var(--rv-radius-md) !important;
    box-shadow: var(--rv-shadow-lg) !important;
    background: var(--rv-surface) !important;
    z-index: var(--rv-z-dropdown);
}
.mud-menu-popover {
    animation: rv-drop var(--rv-dur) var(--rv-ease) both;
}
@keyframes rv-drop {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

/* Les info-bulles sont des surfaces inverses, pas du papier. Elles passent
   au-dessus du tiroir et de la barre haute, donc elles prennent le sommet
   de l'échelle z. */
.mud-tooltip.mud-tooltip-default {
    background-color: var(--rv-tooltip-bg);
    color: var(--rv-tooltip-ink);
    border: 1px solid var(--rv-tooltip-border);
    border-radius: var(--rv-radius-sm);
    box-shadow: var(--rv-shadow-md);
    font-size: 0.75rem;
    max-width: 22rem;
    z-index: var(--rv-z-tooltip);
}
.mud-tooltip.mud-tooltip-default.mud-tooltip-arrow::after {
    border-color: var(--rv-tooltip-bg) transparent transparent transparent;
}
.mud-dialog {
    border: 1px solid var(--rv-border) !important;
    border-radius: var(--rv-radius-xl) !important;
    box-shadow: var(--rv-shadow-lg) !important;
    background: var(--rv-surface) !important;
}
.mud-dialog-title {
    font-size: 1.0625rem !important;
    font-weight: 600 !important;
    letter-spacing: -0.01em;
    color: var(--rv-ink);
    padding-bottom: 8px !important;
}
.mud-overlay-dark { background: rgba(3, 6, 10, 0.55) !important; }

/* ============================================================
   En-tête de page
   ============================================================ */
.mia-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}
.mia-page-title {
    margin: 0 0 3px;
    font-size: 1.3125rem;
    font-weight: 700;
    letter-spacing: -0.021em;
    color: var(--rv-ink);
    line-height: 1.22;
    text-wrap: balance;
}
.mia-page-subtitle {
    margin: 0;
    font-size: 0.8125rem;
    color: var(--rv-ink-3);
    max-width: 68ch;
    text-wrap: pretty;
}
.mia-page-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
/* Navigation de période (‹ Aujourd'hui ›) : un groupe insécable dans une rangée qui passe à la ligne. */
.rv-window-nav {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
}
/* Horodatage « dernière actualisation » — méta, jamais un titre. */
.mia-page-stamp {
    font-size: 0.75rem;
    color: var(--rv-ink-3);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
/* Rangée d'état sous le sous-titre d'une page : des badges, pas des pastilles
   d'un autre vocabulaire. */
.rv-page-status {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 12px;
}

/* Étiquette de section — employée avec parcimonie, au-dessus d'un
   groupe seulement. Ni majuscules, ni interlettrage étiré. */
.rv-section-label {
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-transform: none;
    color: var(--rv-ink);
    margin-bottom: 10px;
}
/* Un libellé qui suit un bloc sans marge basse (une carte d'intégration) : les 22 px entre blocs. */
.rv-section-label--after-block { margin-top: 22px; }

/* ============================================================
   Bande de mesures — une rangée bordée, divisée en filets.
   Remplace les quatre cartes flottantes identiques.
   ============================================================ */
.rv-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
    overflow: hidden;
    margin-bottom: 22px;
}
body:not(.rv-dark) .rv-metrics { box-shadow: var(--rv-shadow-xs); }

.rv-metric {
    padding: 15px 18px;
    border-right: 1px solid var(--rv-border);
    min-width: 0;
}
.rv-metric:last-child { border-right: none; }

.rv-metric-label {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--rv-ink-3);
    margin-bottom: 7px;
}
.rv-metric-label .mud-icon-root {
    font-size: 15px !important;
    color: var(--rv-ink-4) !important;
    flex-shrink: 0;
}
.rv-metric-value {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.028em;
    line-height: 1.1;
    color: var(--rv-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Variante pour une valeur textuelle : un mot ne se lit pas à 28 px,
   il se lit à 17 px. Le chiffre garde la grande taille. */
.rv-metric-value--sm {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.012em;
    line-height: 1.35;
    white-space: normal;
    word-break: break-word;
}
/* Valeur absente : un tiret gris à la taille d'un mot. Un « -- » à 28 px se lit
   comme un chargement qui n'aboutit pas, pas comme une absence. */
.rv-metric-value--nil {
    font-size: 1.0625rem;
    font-weight: 500;
    line-height: 1.35;
    color: var(--rv-ink-4);
}
.rv-metric-value .rv-unit {
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--rv-ink-3);
    letter-spacing: 0;
}
.rv-metric-foot {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--rv-ink-4);
    min-width: 0;
}
.rv-metric-foot .mud-icon-root { font-size: 13px !important; flex-shrink: 0; }
/* Un lien de pied (« Ma configuration ») ne se coupe pas en deux à 390 px : il passe entier à la ligne. */
.rv-metric-foot a { white-space: nowrap; }
.rv-metric-foot--success { color: var(--rv-success); }
.rv-metric-foot--warning { color: var(--rv-warning); }
.rv-metric-foot--error   { color: var(--rv-error); }

/* Téléphone : deux colonnes, pas une pile. Quatre cases empilées prenaient 360 px — tout le
   premier écran — avant la première donnée de la page. Les filets viennent de l'écart de 1 px
   sur un fond de filet, ce qui les tient justes quelle que soit la case qui finit une rangée ;
   un nombre impair de cases donne toute la largeur à la dernière, jamais une demi-rangée vide. */
@media (max-width: 599px) {
    .rv-metrics {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1px;
        background: var(--rv-border);
    }
    .rv-metric { border-right: none; background: var(--rv-surface); padding: 13px 14px; }
    .rv-metric:last-child:nth-child(odd) { grid-column: 1 / -1; }
    /* Dans une demi-largeur, le pied coule comme une phrase : en flex, « réglage d'organisation · »
       et son lien se serraient en deux colonnes et le point tombait seul sur sa ligne. */
    .rv-metric-foot { display: block; }
    .rv-metric-foot .mud-icon-root { vertical-align: -2px; margin-right: 4px; }
}

/* Tablette et fenêtre étroite : auto-fit à 190 px posait trois cases sur la première rangée et
   la quatrième seule sur la seconde, avec un filet vertical orphelin au bout de la troisième.
   Quatre cases et plus : deux colonnes (2 × 2), filets par l'écart de 1 px comme au téléphone ;
   trois cases ou moins : une seule rangée, colonnes égales. */
@media (min-width: 600px) and (max-width: 959px) {
    .rv-metrics {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1px;
        background: var(--rv-border);
    }
    .rv-metrics:not(:has(> .rv-metric:nth-child(4))) {
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
    }
    .rv-metric { border-right: none; background: var(--rv-surface); }
    .rv-metric:last-child:nth-child(odd) { grid-column: 1 / -1; }
    .rv-metrics:not(:has(> .rv-metric:nth-child(4))) .rv-metric:last-child { grid-column: auto; }
}


/* ============================================================
   Carte d'entité — en-tête / lignes de définition / actions.
   Pas de liseré d'accent, pas de tuile d'icône teintée : les
   paires libellé-valeur portent l'information et l'œil balaie
   une seule colonne.
   ============================================================ */
.rv-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
    overflow: hidden;
    transition: border-color var(--rv-dur) var(--rv-ease);
}
body:not(.rv-dark) .rv-card { box-shadow: var(--rv-shadow-xs); }
.rv-card:hover { border-color: var(--rv-border-mid); }
.rv-card--muted { background: var(--rv-canvas); }

.rv-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 18px;
}
.rv-card-ident { display: flex; align-items: center; gap: 11px; min-width: 0; }
.rv-mono-tile {
    width: 34px; height: 34px;
    border-radius: var(--rv-radius-md);
    background: var(--rv-surface-2);
    border: 1px solid var(--rv-border);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.9375rem; font-weight: 700;
    color: var(--rv-ink-3);
    flex-shrink: 0;
}
/* Tuile « active » : l'accent d'action, pas la marque — un monogramme teinté
   est une information d'état (organisation active, intégration connectée). */
.rv-mono-tile--brand {
    background: var(--rv-primary-soft);
    border-color: rgba(var(--rv-accent-rgb), 0.20);
    color: var(--rv-primary-ink);
}
.rv-mono-tile .mud-icon-root { font-size: 18px !important; color: inherit !important; }
.rv-card-name {
    font-weight: 600;
    font-size: 0.9375rem;
    color: var(--rv-ink);
    letter-spacing: -0.01em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rv-card-sub {
    font-size: 0.75rem;
    color: var(--rv-ink-3);
    margin-top: 1px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Lignes de définition */
.rv-defs {
    border-top: 1px solid var(--rv-border);
    padding: 4px 18px;
    flex: 1;
}
.rv-def {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    font-size: 0.8125rem;
    border-bottom: 1px solid var(--rv-border);
}
.rv-def:last-child { border-bottom: none; }
.rv-def-key { color: var(--rv-ink-3); flex-shrink: 0; }
.rv-def-val {
    color: var(--rv-ink);
    font-weight: 500;
    text-align: right;
    min-width: 0;
}
.rv-def-val small {
    display: block;
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--rv-ink-4);
    margin-top: 1px;
}
.rv-def-val--muted { color: var(--rv-ink-3); font-weight: 400; }
.rv-def-val--mono { font-family: var(--rv-mono); font-size: 0.75rem; }
/* Lignes de définition hors carte (un dialogue) : sans la gouttière de carte. */
.rv-defs--flush { padding: 0; border-top: none; }
/* Valeur avant / après d'une modification (journal) : monospace, aplat doux de la teinte. */
.rv-diff-label { font-size: 0.75rem; font-weight: 500; color: var(--rv-ink-3); margin-bottom: 4px; }
.rv-diff {
    margin: 0;
    white-space: pre-wrap;
    word-break: break-word;
    font-family: var(--rv-mono);
    font-size: 0.8125rem;
    max-height: 240px;
    overflow: auto;
    color: var(--rv-ink);
    padding: 8px 10px;
    border-radius: var(--rv-radius-md);
    border: 1px solid transparent;
}
.rv-diff--old { background: var(--rv-error-soft); border-color: var(--rv-error-border); }
.rv-diff--new { background: var(--rv-success-soft); border-color: var(--rv-success-border); }
.rv-diff-desc { margin: 0; font-size: 0.8125rem; color: var(--rv-ink-2); max-width: 68ch; }

.rv-card-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding: 11px 18px;
    border-top: 1px solid var(--rv-border);
    background: var(--rv-surface-2);
}
body.rv-dark .rv-card-foot { background: rgba(230, 237, 243, 0.03); }

/* Barre de section dans une carte de réglages — icône + titre, une ligne.
   Les icônes restent neutres : une teinte par section, c'est des
   confettis, pas de l'information. */
.rv-card-bar {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--rv-border);
    background: var(--rv-surface-2);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--rv-ink);
}
body.rv-dark .rv-card-bar { background: rgba(230, 237, 243, 0.03); }
.rv-card-bar .mud-icon-root {
    font-size: 17px !important;
    color: var(--rv-ink-4) !important;
    flex-shrink: 0;
}
.rv-card-bar > span {
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    color: inherit;
    text-transform: none;
}
.rv-card-bar-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* ============================================================
   Badges d'état — un seul vocabulaire, partout
   ============================================================ */
.rv-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: var(--rv-radius-full);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.55;
    white-space: nowrap;
    border: 1px solid transparent;
}
.rv-badge .mud-icon-root { font-size: 13px !important; }
.rv-badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.rv-badge--success { background: var(--rv-success-soft); color: var(--rv-success); border-color: var(--rv-success-border); }
.rv-badge--warning { background: var(--rv-warning-soft); color: var(--rv-warning); border-color: var(--rv-warning-border); }
.rv-badge--error   { background: var(--rv-error-soft);   color: var(--rv-error);   border-color: var(--rv-error-border); }
.rv-badge--info    { background: var(--rv-info-soft);    color: var(--rv-info);    border-color: var(--rv-info-border); }
.rv-badge--neutral { background: var(--rv-neutral-soft); color: var(--rv-ink-2);   border-color: var(--rv-border); }
.rv-badge--brand   { background: var(--rv-primary-soft); color: var(--rv-primary-ink); border-color: rgba(var(--rv-accent-rgb), 0.22); }

/* Jeton de modèle cliquable — syntaxe littérale, donc il a l'air littéral */
.mud-chip.rv-token-chip {
    font-family: var(--rv-mono) !important;
    background: var(--rv-surface-2) !important;
    color: var(--rv-ink-2) !important;
    border: 1px solid var(--rv-border-mid) !important;
    cursor: pointer;
}
/* Une cible de 22 px en 11,5 px était trop petite pour un jeton qu'on clique souvent. */
.mud-chip.mud-chip-size-small.rv-token-chip {
    min-height: 28px;
    font-size: 0.8125rem !important;
    padding: 0 12px;
}
.mud-chip.rv-token-chip:hover {
    background: var(--rv-primary-soft) !important;
    color: var(--rv-primary-ink) !important;
    border-color: rgba(var(--rv-accent-rgb), 0.28) !important;
}

/* Valeur monospace en ligne — codes, jetons, différences de modèles */
.rv-code {
    font-family: var(--rv-mono);
    font-size: 0.75rem;
    background: var(--rv-surface-2);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-xs);
    padding: 1px 6px;
    color: var(--rv-ink-2);
}

/* ============================================================
   Boutons — une forme, un vocabulaire
   ============================================================ */
.mud-button-root {
    border-radius: var(--rv-radius-md) !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
    font-weight: 500 !important;
    transition: background-color var(--rv-dur-fast) var(--rv-ease),
                border-color var(--rv-dur-fast) var(--rv-ease),
                color var(--rv-dur-fast) var(--rv-ease) !important;
}
/* Le label d'un bouton ne se coupe pas en deux lignes. */
.mud-button .mud-button-label { white-space: nowrap; }
.mud-button-filled { box-shadow: none !important; }
/* MudBlazor écrit la classe combinée `mud-button-filled-primary` (vérifié sur le DOM
   rendu) ; l'ancien sélecteur `.mud-button-color-primary` ne matchait rien. */
.mud-button-filled-primary,
.mud-button-filled.mud-button-color-primary {
    background-color: var(--rv-primary) !important;
    color: var(--rv-on-primary) !important;
}
/* Ni halo ni translation au survol : c'était décoratif. */
.mud-button-filled-primary:hover,
.mud-button-filled.mud-button-color-primary:hover {
    background-color: var(--rv-primary-hover) !important;
    box-shadow: none !important;
    transform: none !important;
}
.mud-button-filled-primary:active,
.mud-button-filled.mud-button-color-primary:active {
    background-color: var(--rv-primary-active) !important;
}
/* Garde-fou : un bouton PLEIN dans une couleur autre que Primary.
   MudBlazor pose le texte de contraste (blanc) sur la couleur de la palette. Or
   Secondary et Tertiary sont ici des couleurs d'ENCRE et de SURFACE, pas des
   aplats de bouton. MudBlazor écrit la classe combinée `mud-button-filled-secondary`,
   pas `mud-button-color-secondary` — vérifié sur le DOM rendu. */
.mud-button-filled-secondary,
.mud-button-filled-tertiary,
.mud-button-filled-default,
.mud-button-filled-inherit,
.mud-button-filled-surface {
    background-color: var(--rv-surface-2) !important;
    color: var(--rv-ink) !important;
    border: 1px solid var(--rv-border-mid) !important;
}
.mud-button-filled-secondary:hover,
.mud-button-filled-tertiary:hover,
.mud-button-filled-default:hover,
.mud-button-filled-inherit:hover,
.mud-button-filled-surface:hover {
    background-color: var(--rv-surface-3) !important;
    border-color: var(--rv-border-strong) !important;
}
/* Les teintes sémantiques sont calibrées pour du TEXTE : elles ne peuvent pas
   porter du blanc. En plein, elles deviennent donc des contours teintés. */
.mud-button-filled-success,
.mud-button-filled-warning,
.mud-button-filled-info {
    background-color: transparent !important;
    border: 1px solid currentColor !important;
}
.mud-button-filled-success { color: var(--rv-success) !important; }
.mud-button-filled-warning { color: var(--rv-warning) !important; }
.mud-button-filled-info    { color: var(--rv-info) !important; }
.mud-button-filled-success:hover { background-color: var(--rv-success-soft) !important; }
.mud-button-filled-warning:hover { background-color: var(--rv-warning-soft) !important; }
.mud-button-filled-info:hover    { background-color: var(--rv-info-soft) !important; }

.mud-button-outlined {
    border-color: var(--rv-border-mid) !important;
    color: var(--rv-ink) !important;
    background-color: var(--rv-surface) !important;
}
.mud-button-outlined:hover {
    background-color: var(--rv-hover) !important;
    border-color: var(--rv-border-strong) !important;
}
.mud-button-outlined.mud-button-color-error { color: var(--rv-error) !important; border-color: var(--rv-error-border) !important; }
.mud-button-outlined.mud-button-color-error:hover { background-color: var(--rv-error-soft) !important; }
.mud-button-text { color: var(--rv-ink-2) !important; }
.mud-button-text:hover { background-color: var(--rv-hover) !important; color: var(--rv-ink) !important; }
/* Un bouton libellé désactivé garde une surface pleine, manifestement
   inerte. Les boutons-icône sont exclus : leur donner un cadre rend les
   flèches désactivées plus visibles que les contrôles actifs. */
.mud-button.mud-button-root:disabled,
.mud-button.mud-button-root.mud-disabled {
    opacity: 1 !important;
    background-color: var(--rv-surface-2) !important;
    border-color: var(--rv-border) !important;
    color: var(--rv-ink-disabled) !important;
    box-shadow: none !important;
}
.mud-icon-button:disabled:not(.mud-button-outlined),
.mud-icon-button.mud-disabled:not(.mud-button-outlined) {
    background-color: transparent !important;
    border: none !important;
    color: var(--rv-ink-disabled) !important;
    box-shadow: none !important;
}

/* Avatar d'initiales — identité, pas emphase */
.mud-avatar { transition: opacity var(--rv-dur-fast) var(--rv-ease); }
.mud-avatar.rv-avatar {
    background-color: var(--rv-primary-soft) !important;
    color: var(--rv-primary-ink) !important;
    border: 1px solid rgba(var(--rv-accent-rgb), 0.20);
}
.mud-icon-button {
    border-radius: var(--rv-radius-md) !important;
    transition: background-color var(--rv-dur-fast) var(--rv-ease),
                border-color var(--rv-dur-fast) var(--rv-ease) !important;
}
.mud-icon-button:hover { background-color: var(--rv-hover) !important; }

/* Les actions en ligne d'une rangée dense restent petites à l'écran, sinon
   elles cassent le rythme — mais 24 px est le strict minimum de WCAG 2.5.8,
   pas une cible confortable au doigt. Le pseudo-élément réclame 40 px de zone
   de clic sans occuper de place : le bouton a l'air inchangé et se touche
   à coup sûr. */
/* Texte pour les lecteurs d'écran seulement (en-tête d'une colonne d'actions, par exemple). */
.rv-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.rv-inline-action { position: relative; }
.rv-inline-action::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    transform: translate(-50%, -50%);
}

/* Un bouton-icône en contour a besoin d'un bord, sinon il se lit comme du
   chrome nu et l'état désactivé paraît plus solide que l'état actif. */
.mud-icon-button.mud-button-outlined {
    border: 1px solid var(--rv-border-mid) !important;
    background-color: var(--rv-surface) !important;
    color: var(--rv-ink-2) !important;
}
.mud-icon-button.mud-button-outlined:hover {
    border-color: var(--rv-border-strong) !important;
    background-color: var(--rv-hover) !important;
}
.mud-icon-button.mud-button-outlined.mud-button-color-error {
    color: var(--rv-error) !important;
    border-color: var(--rv-error-border) !important;
}
.mud-icon-button.mud-button-outlined.mud-button-color-error:hover {
    background-color: var(--rv-error-soft) !important;
}
.mud-icon-button.mud-button-outlined:disabled,
.mud-icon-button.mud-button-outlined.mud-disabled {
    border-color: var(--rv-border) !important;
    background-color: var(--rv-surface) !important;
    color: var(--rv-ink-disabled) !important;
}

/* Groupe d'actions dans une ligne de tableau. */
.rv-row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
}
.rv-row-actions .mud-icon-button { padding: 5px !important; }
.rv-row-actions .mud-icon-root { font-size: 17px !important; }

/* ============================================================
   Contrôle segmenté — Mois / Semaine / Jour

   Un changement de vue n'est pas une action primaire : le segment
   actif est une surface neutre, pas l'accent.
   ============================================================ */
.mud-button-group-root {
    border: 1px solid var(--rv-border-mid);
    border-radius: var(--rv-radius-md);
    overflow: hidden;
    box-shadow: none !important;
    background: var(--rv-surface);
    padding: 2px;
    gap: 2px;
    display: inline-flex;
}
.mud-button-group-root > .mud-button-root {
    border: none !important;
    border-radius: var(--rv-radius-sm) !important;
    box-shadow: none !important;
    min-width: 0;
    padding: 5px 14px !important;
    background-color: transparent !important;
    color: var(--rv-ink-3) !important;
    font-weight: 500 !important;
}
.mud-button-group-root > .mud-button-root:hover {
    background-color: var(--rv-hover) !important;
    color: var(--rv-ink) !important;
}
/* La variante pleine marque le segment actif. */
.mud-button-group-root > .mud-button-filled {
    background-color: var(--rv-surface-3) !important;
    color: var(--rv-ink) !important;
    font-weight: 600 !important;
}

/* ============================================================
   Barre d'outils du calendrier — le chrome de navigation reste discret
   ============================================================ */
.mud-cal-toolbar .mud-button-filled,
.mud-cal-toolbar .mud-button-filled-primary,
.mud-cal-toolbar .mud-picker-input-button .mud-button-filled {
    background-color: var(--rv-surface) !important;
    color: var(--rv-ink) !important;
    border: 1px solid var(--rv-border-mid) !important;
    box-shadow: none !important;
    font-weight: 500 !important;
}
.mud-cal-toolbar .mud-button-filled:hover,
.mud-cal-toolbar .mud-picker-input-button .mud-button-filled:hover {
    background-color: var(--rv-hover) !important;
    border-color: var(--rv-border-strong) !important;
}
.mud-cal-toolbar .mud-icon-button.mud-button-filled { color: var(--rv-ink-2) !important; }
.mud-cal-toolbar-nav { gap: 6px; }
/* Rend au contrôle segmenté son traitement propre dans la barre d'outils. */
.mud-cal-toolbar .mud-button-group-root > .mud-button-filled {
    background-color: var(--rv-surface-3) !important;
    border: none !important;
    font-weight: 600 !important;
}

/* ============================================================
   Puces
   ============================================================ */
.mud-chip {
    border-radius: var(--rv-radius-full) !important;
    font-size: 0.75rem !important;
    font-weight: 500 !important;
    height: auto !important;
    min-height: 24px;
    box-shadow: none !important;
    transition: background-color var(--rv-dur-fast) var(--rv-ease), border-color var(--rv-dur-fast) var(--rv-ease);
}
.mud-chip.mud-chip-size-small { min-height: 22px; font-size: 0.71875rem !important; padding: 0 10px; }
.mud-chip .mud-chip-icon { color: inherit !important; }
.mud-chip.mud-chip-filled.mud-chip-color-primary,
.mud-chip.mud-chip-color-primary {
    background: var(--rv-primary-soft) !important;
    color: var(--rv-primary-ink) !important;
    border: 1px solid rgba(var(--rv-accent-rgb), 0.22) !important;
}
.mud-chip.mud-chip-color-success { background: var(--rv-success-soft) !important; color: var(--rv-success) !important; border: 1px solid var(--rv-success-border) !important; }
.mud-chip.mud-chip-color-warning { background: var(--rv-warning-soft) !important; color: var(--rv-warning) !important; border: 1px solid var(--rv-warning-border) !important; }
.mud-chip.mud-chip-color-error   { background: var(--rv-error-soft) !important;   color: var(--rv-error) !important;   border: 1px solid var(--rv-error-border) !important; }
.mud-chip.mud-chip-color-info    { background: var(--rv-info-soft) !important;    color: var(--rv-info) !important;    border: 1px solid var(--rv-info-border) !important; }
.mud-chip.mud-chip-color-default,
.mud-chip.mud-chip-color-secondary,
.mud-chip.mud-chip-color-tertiary { background: var(--rv-neutral-soft) !important; color: var(--rv-ink-2) !important; border: 1px solid var(--rv-border) !important; }
/* Pastille de filtre sélectionnée : la teinte reste celle de l'état ; la sélection se lit au filet
   doublé en currentColor, à la graisse et à la coche — jamais à la couleur seule. */
.mud-chip.rv-filter-chip--active {
    box-shadow: inset 0 0 0 1px currentColor !important;
    font-weight: 600 !important;
}
/* Icône de puce à 13 px, comme celle des badges, au repos comme sélectionnée : la puce ne change pas
   de largeur au clic, et une icône à 20 px n'écrase pas un libellé de 12 px. */
.mud-chip.mud-chip-size-small .mud-chip-icon,
.mud-chip.rv-filter-chip--active .mud-chip-icon { font-size: 13px; margin-inline-end: 4px; }
/* Une puce désactivée reste lisible — elle porte de l'information. */
.mud-chip.mud-disabled, .mud-chip:disabled {
    opacity: 1 !important;
    background: var(--rv-surface-2) !important;
    color: var(--rv-ink-3) !important;
    border: 1px solid var(--rv-border) !important;
}

/* Les liens dans de la donnée dense restent neutres jusqu'au survol —
   une colonne d'adresses bleues, c'est du bruit, pas de la hiérarchie. */
.mud-table-root .mud-link,
.mud-table-root a {
    color: var(--rv-ink-2) !important;
    text-decoration: none;
}
.mud-table-root .mud-link:hover,
.mud-table-root a:hover {
    color: var(--rv-primary-ink) !important;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ============================================================
   Alertes — surface teintée, sans liseré latéral
   ============================================================ */
.mud-alert {
    border-radius: var(--rv-radius-md) !important;
    box-shadow: none !important;
    border: 1px solid transparent;
    font-size: 0.8125rem;
}
.mud-alert-outlined-info, .mud-alert-filled-info, .mud-alert-text-info {
    background: var(--rv-info-soft) !important;
    border-color: var(--rv-info-border) !important;
    color: var(--rv-ink-2) !important;
}
.mud-alert-outlined-success, .mud-alert-filled-success, .mud-alert-text-success {
    background: var(--rv-success-soft) !important;
    border-color: var(--rv-success-border) !important;
    color: var(--rv-ink-2) !important;
}
.mud-alert-outlined-warning, .mud-alert-filled-warning, .mud-alert-text-warning {
    background: var(--rv-warning-soft) !important;
    border-color: var(--rv-warning-border) !important;
    color: var(--rv-ink-2) !important;
}
.mud-alert-outlined-error, .mud-alert-filled-error, .mud-alert-text-error {
    background: var(--rv-error-soft) !important;
    border-color: var(--rv-error-border) !important;
    color: var(--rv-ink-2) !important;
}
.mud-alert .mud-alert-icon { align-items: flex-start; padding-top: 2px; }
.mud-alert-outlined-info .mud-alert-icon .mud-icon-root,
.mud-alert-text-info .mud-alert-icon .mud-icon-root,
.mud-alert-filled-info .mud-alert-icon .mud-icon-root { color: var(--rv-info) !important; }
.mud-alert-outlined-success .mud-alert-icon .mud-icon-root,
.mud-alert-text-success .mud-alert-icon .mud-icon-root,
.mud-alert-filled-success .mud-alert-icon .mud-icon-root { color: var(--rv-success) !important; }
.mud-alert-outlined-warning .mud-alert-icon .mud-icon-root,
.mud-alert-text-warning .mud-alert-icon .mud-icon-root,
.mud-alert-filled-warning .mud-alert-icon .mud-icon-root { color: var(--rv-warning) !important; }
.mud-alert-outlined-error .mud-alert-icon .mud-icon-root,
.mud-alert-text-error .mud-alert-icon .mud-icon-root,
.mud-alert-filled-error .mud-alert-icon .mud-icon-root { color: var(--rv-error) !important; }
/* Dans une alerte, le corps est de l'encre, pas de la couleur. */
.mud-alert code, .mud-alert .rv-code { background: rgba(15, 20, 25, 0.05); }
body.rv-dark .mud-alert code,
body.rv-dark .mud-alert .rv-code { background: rgba(230, 237, 243, 0.08); }

/* ============================================================
   Formulaires — un vocabulaire de contrôle : contour, 8px, filet
   ============================================================ */
.mud-input.mud-input-outlined .mud-input-outlined-border {
    border-radius: var(--rv-radius-md) !important;
    border-color: var(--rv-border-mid) !important;
    transition: border-color var(--rv-dur-fast) var(--rv-ease), box-shadow var(--rv-dur-fast) var(--rv-ease);
}
.mud-input.mud-input-outlined:hover:not(.mud-disabled) .mud-input-outlined-border {
    border-color: var(--rv-border-strong) !important;
}
.mud-input-control.mud-input-required .mud-input-outlined-border,
.mud-input.mud-input-outlined.mud-focused .mud-input-outlined-border {
    border-width: 1px !important;
}
.mud-input.mud-input-outlined.mud-focused .mud-input-outlined-border {
    border-color: var(--rv-primary) !important;
    box-shadow: 0 0 0 3px var(--rv-primary-soft) !important;
}
.mud-input-root, .mud-input-slot, .mud-input input, .mud-input textarea {
    color: var(--rv-ink) !important;
    font-size: 0.875rem !important;
}
/* Le texte d'invite doit atteindre le même 4.5:1 que le corps. */
.mud-input input::placeholder,
.mud-input textarea::placeholder {
    color: var(--rv-ink-3) !important;
    opacity: 1 !important;
}
.mud-input-label, .mud-input-label-inputcontrol {
    color: var(--rv-ink-3) !important;
    font-size: 0.8125rem !important;
}
.mud-input-control.mud-focused .mud-input-label { color: var(--rv-primary-ink) !important; }
.mud-input-helper-text {
    color: var(--rv-ink-3) !important;
    font-size: 0.75rem !important;
    margin-top: 5px !important;
}
/* L'aide s'aligne sur le bord du champ, pas sur son retrait intérieur. */
.mud-input-control-helper-container { padding-inline: 0 !important; margin-inline: 0 !important; }
.mud-input-helper-text.mud-input-error { color: var(--rv-error) !important; }
.mud-input-error .mud-input-outlined-border { border-color: var(--rv-error) !important; }

/* Les champs soulignés sont retirés du vocabulaire — on normalise
   ceux qui restent pour que le formulaire reste homogène. */
.mud-input.mud-input-underline::before,
.mud-input.mud-input-underline::after { display: none !important; }
.mud-input.mud-input-underline {
    background: var(--rv-input-bg);
    border: 1px solid var(--rv-border-mid);
    border-radius: var(--rv-radius-md);
    padding-left: 12px !important;
    padding-right: 12px !important;
    transition: border-color var(--rv-dur-fast) var(--rv-ease), box-shadow var(--rv-dur-fast) var(--rv-ease);
}
.mud-input.mud-input-underline:hover { border-color: var(--rv-border-strong); }
.mud-input.mud-input-underline.mud-focused {
    border-color: var(--rv-primary);
    box-shadow: 0 0 0 3px var(--rv-primary-soft);
}

/* Interrupteurs — MudBlazor tient la couleur active ; on rend juste
   la piste inactive lisible et on donne un vrai bord au curseur. */
.mud-switch .mud-switch-track { opacity: 1; }
.mud-switch .mud-switch-base:not(.mud-checked) + .mud-switch-track {
    background-color: var(--rv-border-strong);
    opacity: 1;
}
.mud-switch-thumb { box-shadow: var(--rv-shadow-sm); }

/* Cases et radios — aucune couleur d'accent sur un état inactif */
.mud-checkbox .mud-button-root:not(.mud-checked):not(.mud-indeterminate) .mud-icon-root,
.mud-radio .mud-button-root:not(.mud-checked) .mud-icon-root {
    color: var(--rv-border-strong) !important;
}

/* ============================================================
   Tableaux et grille de données
   ============================================================ */
.mud-table, .mud-table-container { background: transparent !important; }
.mud-table.mud-table-outlined {
    border: 1px solid var(--rv-border) !important;
    border-radius: var(--rv-radius-lg) !important;
    overflow: hidden;
}
.mud-table-root { border-collapse: separate; border-spacing: 0; }
.mud-table-root .mud-table-head th {
    font-size: 0.75rem !important;
    font-weight: 600 !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
    color: var(--rv-ink-3) !important;
    background: var(--rv-surface-2) !important;
    border-bottom: 1px solid var(--rv-border) !important;
    padding: 10px 14px !important;
    white-space: nowrap;
}
body.rv-dark .mud-table-root .mud-table-head th { background: rgba(230, 237, 243, 0.04) !important; }
.mud-table-row td {
    border-bottom: 1px solid var(--rv-border) !important;
    padding: 10px 14px !important;
    font-size: 0.8125rem !important;
    color: var(--rv-ink-2);
    transition: background-color var(--rv-dur-fast) var(--rv-ease);
}
.mud-table-body .mud-table-row:last-child td { border-bottom: none !important; }
.mud-table-row:hover td { background: var(--rv-hover) !important; }
.mud-table-row.mud-table-row-clickable { cursor: pointer; }
.mud-table-toolbar,
.mud-table.mud-data-grid .mud-toolbar,
.mud-table.mud-data-grid .mud-toolbar-gutters,
.mud-table.mud-data-grid .mud-table-toolbar {
    height: auto !important;
    min-height: 0 !important;
    padding: 12px 14px !important;
    border-bottom: 1px solid var(--rv-border);
}
.mud-table-pagination,
.mud-table.mud-data-grid .mud-table-pagination-toolbar {
    height: auto !important;
    padding: 9px 14px !important;
    border-top: 1px solid var(--rv-border);
    color: var(--rv-ink-3);
    font-size: 0.8125rem;
}
/* Un pager masqué laisse un .mud-table-pagination vide : son filet et son
   retrait dessinaient un trait fantôme de 28 px au coin de la table. Et quand
   il enveloppe une barre d'outils, c'est la barre qui porte le retrait. */
.mud-table-pagination:empty { display: none !important; }
.mud-table-pagination:has(> .mud-table-pagination-toolbar) { padding: 0 !important; }
.mud-table-pagination > .mud-table-pagination-toolbar { padding: 9px 14px !important; border: none !important; }
.mud-table-container { background-color: transparent !important; }
.mud-table-cell-header-sortable:hover { color: var(--rv-ink) !important; }
/* Cellule vide : un tiret cadratin, pas un blanc qui ressemble à un bug. */
.rv-nil { color: var(--rv-ink-3); }

/* ── Tableau empilé (sous sm) ─────────────────────────────
   MudBlazor transforme chaque ligne en paires libellé/valeur et
   imprime l'en-tête via ::before. Les cellules qui portent un
   contrôle plutôt qu'une valeur (case, menu de ligne) n'ont pas de
   data-label : on les rassemble sur une seule ligne d'actions en fin
   d'enregistrement. */
@media (max-width: 599.95px) {
    .mud-table-body .mud-table-row {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        border-bottom: 2px solid var(--rv-border);
        padding-bottom: 6px;
    }
    .mud-table-body td[data-label] {
        flex: 1 0 100%;
        justify-content: space-between;
        gap: 16px;
        align-items: center;
    }
    .mud-table-body td[data-label]::before {
        color: var(--rv-ink-3);
        font-weight: 500;
        flex-shrink: 0;
    }
    .mud-table-body td:not([data-label]) {
        order: 99;
        flex: 0 0 auto;
        display: inline-flex !important;
        align-items: center;
        width: auto !important;
        border-bottom: none !important;
        padding: 4px 2px !important;
    }
    .mud-table-body td:not([data-label]):first-of-type { margin-left: auto; }
    .mud-table-body td:not([data-label])::before { display: none !important; }
    .mud-table-body td[data-label]:empty::after {
        content: "—";
        color: var(--rv-ink-disabled);
    }
}

/* ── Tableau en cartes (.rv-table-cards, sous md) ───────────
   MudBlazor empile une table « Breakpoint.Sm » jusqu'à 960 px : entre 600 et 960, chaque
   enregistrement devenait une colonne de paires libellé/valeur de 350 px, case et menu
   isolés en haut et en bas. Ici l'enregistrement devient une carte d'entité : la cellule
   d'identité (.rv-cell-lead) en tête, sans libellé ; la case (.rv-cell-select) et les
   actions (.rv-cell-actions) dans ses coins ; le reste en lignes de définition serrées. */
@media (max-width: 960px) {
    .rv-table-cards.mud-sm-table .mud-table-body { border-top: none; }
    .rv-table-cards.mud-sm-table .mud-table-body .mud-table-row {
        position: relative;
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        /* La règle du tableau empilé (sous 600 px) centre la ligne ; en colonne, les cellules se
           rétrécissaient alors à leur contenu et se centraient : libellés et valeurs flottaient au
           milieu de la carte, l'identité décalée. Une carte s'étire bord à bord. */
        align-items: stretch;
        margin: 0 12px 10px;
        padding: 4px 0 6px;
        border: 1px solid var(--rv-border);
        border-radius: var(--rv-radius-lg);
        background: var(--rv-surface);
    }
    .rv-table-cards.mud-sm-table .mud-table-body .mud-table-row:first-child { margin-top: 12px; }
    .rv-table-cards.mud-sm-table .mud-table-body .mud-table-row td {
        flex: 0 0 auto;
        border-bottom: none !important;
        padding: 4px 18px !important;
        gap: 16px;
        background: transparent !important;
    }
    .rv-table-cards.mud-sm-table .mud-table-body td[data-label]::before {
        color: var(--rv-ink-3);
        font-weight: 400;
        flex-shrink: 0;
    }
    .rv-table-cards.mud-sm-table .mud-table-body .mud-table-row:hover { border-color: var(--rv-border-mid); }
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-lead {
        order: -1;
        justify-content: flex-start;
        padding: 10px 56px 10px 18px !important;
        margin-bottom: 4px;
        border-bottom: 1px solid var(--rv-border) !important;
    }
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-lead::before,
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-select::before,
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-actions::before { content: none; display: none; }
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-actions {
        position: absolute;
        top: 10px;
        right: 8px;
        width: auto !important;
        padding: 0 !important;
        margin: 0 !important;
    }
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-select {
        position: absolute;
        top: 12px;
        left: 8px;
        width: auto !important;
        padding: 0 !important;
        margin: 0 !important;
    }
    .rv-table-cards.mud-sm-table .mud-table-body .mud-table-row:has(> td.rv-cell-select) td.rv-cell-lead {
        padding-left: 52px !important;
    }
    /* Cellule qui se lit sans son libellé (un objet, une frise) : pleine largeur, sans « Libellé : ». */
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-plain { display: block !important; }
    .rv-table-cards.mud-sm-table .mud-table-body td.rv-cell-plain::before { content: none; display: none; }
}

/* ── Suivi des rappels ─────────────────────────────────────
   Rendez-vous : le jour en encre, l'heure en dessous. Frise des textos (.rv-steps) : un point plein
   par texto parti, un point creux pour l'étape attendue qui n'a pas eu lieu, la réponse à la teinte
   de l'état. En carte (sous 960 px), quatre zones : date | état, puis l'objet, puis la frise. */
.rv-appt-when {
    display: flex;
    flex-direction: column;
    line-height: 1.35;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.rv-appt-day { font-weight: 600; color: var(--rv-ink); }
.rv-appt-time { color: var(--rv-ink-3); }
.rv-state-note { font-size: 0.75rem; color: var(--rv-ink-3); margin-top: 4px; }
/* Le geste à faire sous un état « À traiter » : un cran plus foncé que la note, sans reprendre le rouge du
   badge juste au-dessus — le badge alerte, la note explique. */
.rv-state-note--action { color: var(--rv-ink-2); max-width: 32ch; }
/* Filet entre le raccourci « À traiter » et les pastilles d'état : deux natures de filtre, une rangée. */
.rv-filter-sep { width: 1px; height: 18px; background: var(--rv-border-mid); }
.rv-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.rv-step {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.75rem;
    color: var(--rv-ink-3);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.rv-step-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--rv-ink-4);
}
.rv-step--pending { color: var(--rv-ink-4); }
.rv-step--pending .rv-step-dot { background: transparent; box-shadow: inset 0 0 0 1px var(--rv-border-strong); }
.rv-step--success { color: var(--rv-success); font-weight: 500; }
.rv-step--success .rv-step-dot { background: var(--rv-success); }
.rv-step--warning { color: var(--rv-warning); font-weight: 500; }
.rv-step--warning .rv-step-dot { background: var(--rv-warning); }
.rv-step--error { color: var(--rv-error); font-weight: 500; }
.rv-step--error .rv-step-dot { background: var(--rv-error); }
@media (max-width: 960px) {
    /* En cartes, le cadre de la table s'efface : une carte dans une carte doublait chaque bordure. */
    .rv-card:has(> .rv-tracking-table.mud-sm-table) { border: none; background: transparent; box-shadow: none; }
    .rv-tracking-table.mud-sm-table .mud-table-body .mud-table-row { margin-left: 0; margin-right: 0; }
    .rv-tracking-table.mud-sm-table .mud-table-body .mud-table-row:first-child { margin-top: 0; }
    .rv-tracking-table.mud-sm-table .mud-table-body .mud-table-row:not(.rv-recipients-row) {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 12px;
        padding-bottom: 10px;
    }
    .rv-tracking-table.mud-sm-table .mud-table-body td.rv-cell-lead {
        grid-column: 1;
        grid-row: 1;
        border-bottom: none !important;
        margin-bottom: 0;
        padding: 12px 0 4px 18px !important;
    }
    .rv-tracking-table.mud-sm-table .mud-table-body td.rv-cell-state {
        grid-column: 2;
        grid-row: 1;
        flex-direction: column;
        align-items: flex-end;
        text-align: right;
        padding: 12px 18px 4px 0 !important;
    }
    .rv-tracking-table.mud-sm-table .mud-table-body td.rv-cell-state::before { content: none; display: none; }
    .rv-tracking-table.mud-sm-table .mud-table-body td.rv-cell-subject { grid-column: 1 / -1; }
    .rv-tracking-table.mud-sm-table .mud-table-body td.rv-cell-steps {
        grid-column: 1 / -1;
        margin: 8px 18px 0;
        padding: 10px 0 0 !important;
        border-top: 1px solid var(--rv-border) !important;
    }
    .rv-tracking-table.mud-sm-table .rv-appt-when { flex-direction: row; gap: 6px; }
    .rv-tracking-table.mud-sm-table .rv-appt-time::before { content: "·"; margin-right: 6px; color: var(--rv-ink-4); }
    .rv-tracking-table.mud-sm-table .mud-table-body .rv-recipients-row td {
        display: block !important;
        width: auto !important;
        flex: 1 1 100%;
        padding: 10px 18px !important;
        border-radius: var(--rv-radius-lg);
    }
}

/* ============================================================
   Onglets
   ============================================================ */
.mud-tabs { background-color: transparent; }
.mud-tabs-toolbar { border-bottom: 1px solid var(--rv-border) !important; }
.mud-tab {
    text-transform: none !important;
    letter-spacing: 0 !important;
    font-size: 0.875rem !important;
    font-weight: 500 !important;
    color: var(--rv-ink-3) !important;
    min-height: 42px !important;
}
.mud-tab.mud-tab-active { color: var(--rv-ink) !important; font-weight: 600 !important; }
.mud-tab-slider { background: var(--rv-primary) !important; height: 2px !important; }

/* ============================================================
   Fil d'Ariane
   ============================================================ */
.mud-breadcrumbs {
    padding: 0 !important;
    margin-bottom: 14px;
    font-size: 0.8125rem;
}
.mud-breadcrumb-item a { color: var(--rv-ink-3) !important; }
.mud-breadcrumb-item a:hover { color: var(--rv-ink) !important; text-decoration: none; }
.mud-breadcrumb-item.mud-disabled p,
.mud-breadcrumb-item:last-child { color: var(--rv-ink) !important; font-weight: 500; }
.mud-breadcrumb-separator { color: var(--rv-ink-disabled) !important; }

/* ============================================================
   Chronologie — le contenu prime, la pastille situe
   ============================================================ */
.mud-timeline-item-dot { width: 20px !important; height: 20px !important; }
.mud-timeline-item .mud-timeline-item-dot-inner {
    background: var(--rv-surface) !important;
    border: 2px solid var(--rv-border-strong) !important;
    box-shadow: none !important;
}
.mud-timeline-item .mud-timeline-item-divider { background: var(--rv-border) !important; }

/* ============================================================
   États vides — enseigner l'interface, pas seulement dire « rien »
   ============================================================ */
.rv-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 3rem 2rem;
    text-align: center;
}
/* Page d'état entière (introuvable, approbation, invitation) : plus d'air au-dessus qu'un vide de carte. */
.rv-empty--page { padding: 6rem 2rem; }
.rv-empty-icon {
    width: 44px; height: 44px;
    border-radius: var(--rv-radius-md);
    background: var(--rv-surface-2);
    border: 1px solid var(--rv-border);
    display: flex; align-items: center; justify-content: center;
}
.rv-empty-icon .mud-icon-root { font-size: 21px !important; color: var(--rv-ink-4) !important; }
/* margin/line-height : sur une page qui n'est qu'un état vide (404, consentement), le titre
   est le h1 de la page — il ne doit pas hériter des marges et de l'interlignage d'un h1. */
.rv-empty-title { margin: 0; font-weight: 600; font-size: 0.9375rem; line-height: 1.5; color: var(--rv-ink); }
.rv-empty-body { font-size: 0.8125rem; color: var(--rv-ink-3); max-width: 46ch; margin-top: 3px; }
/* Ce qu'on peut faire d'un écran vide : une ou deux actions, sous le texte, centrées avec lui. */
.rv-empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }

/* ============================================================
   Chargement — des squelettes, pas des toupies dans le contenu
   ============================================================ */
.mia-skeleton {
    min-height: 96px;
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
    position: relative;
    overflow: hidden;
}
.mia-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent 0%, var(--rv-hover) 45%, transparent 90%);
    background-size: 200% 100%;
    animation: rv-shimmer 1.4s var(--rv-ease) infinite;
}
@keyframes rv-shimmer {
    from { background-position: 150% 0; }
    to   { background-position: -150% 0; }
}
/* Une date qui attend le fuseau du navigateur (LocalTime) : un squelette en ligne de la largeur de la date
   attendue. « … » en gris se lisait comme une valeur, pas comme un chargement. */
.rv-time-pending {
    display: inline-block;
    max-width: 100%;
    height: 0.85em;
    vertical-align: -0.08em;
    border-radius: var(--rv-radius-xs);
    background: var(--rv-surface-3);
    position: relative;
    overflow: hidden;
}
.rv-time-pending::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent 0%, var(--rv-hover) 45%, transparent 90%);
    background-size: 200% 100%;
    animation: rv-shimmer 1.4s var(--rv-ease) infinite;
}
.mud-progress-linear { border-radius: var(--rv-radius-full); overflow: hidden; }

/* ============================================================
   Entrée de page — un seul fondu court. De l'état, pas une chorégraphie.
   ============================================================ */
.page-enter { animation: rv-page-enter var(--rv-dur-slow) var(--rv-ease) both; }
@keyframes rv-page-enter {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
}

/* ============================================================
   Calendrier
   ============================================================ */
.rv-cal-layout { display: flex; gap: 16px; align-items: flex-start; }
.rv-cal-main { flex: 1; min-width: 0; }

.mud-cal-toolbar, .mud-calendar-toolbar { border-bottom: 1px solid var(--rv-border); }
.mud-cal-cell, .mud-cal-week-layout .mud-cal-cell { border-color: var(--rv-border) !important; }
.mud-cal-header-cell, .mud-cal-month-cell-title {
    font-size: 0.8125rem !important;
    font-weight: 600 !important;
    color: var(--rv-ink-2) !important;
}

/* Cellules d'événement. Surface teintée de l'accent, découpée par un filet
   d'un pixel sur l'axe du temps — un filet, pas un liseré. L'accent d'action
   pour un rendez-vous, le bleu d'information pour une réunion en ligne :
   l'orange de marque n'est pas une couleur de donnée. */
.rv-cal-event {
    cursor: pointer;
    height: 100%;
    overflow: hidden;
    transition: background-color var(--rv-dur-fast) var(--rv-ease);
}
.rv-cal-event--week,
.rv-cal-event--day {
    background: rgba(var(--rv-accent-rgb), 0.10);
    border-left: 1px solid var(--rv-primary);
    border-radius: 0 var(--rv-radius-xs) var(--rv-radius-xs) 0;
    padding: 3px 7px;
}
.rv-cal-event--week:hover,
.rv-cal-event--day:hover { background: rgba(var(--rv-accent-rgb), 0.17); }
.rv-cal-event--online.rv-cal-event--week,
.rv-cal-event--online.rv-cal-event--day {
    background: var(--rv-info-soft);
    border-left-color: var(--rv-info);
}
.rv-cal-event--online.rv-cal-event--week:hover,
.rv-cal-event--online.rv-cal-event--day:hover { background: rgba(var(--rv-accent-rgb), 0.17); }
.rv-cal-event--month {
    background: rgba(var(--rv-accent-rgb), 0.10);
    border-left: 1px solid var(--rv-primary);
    border-radius: 0 var(--rv-radius-xs) var(--rv-radius-xs) 0;
    padding: 1px 5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
}
.rv-cal-event--online.rv-cal-event--month {
    background: var(--rv-info-soft);
    border-left-color: var(--rv-info);
}
.rv-cal-event-title {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--rv-ink);
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rv-cal-event-loc {
    font-size: 0.6875rem;
    color: var(--rv-ink-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-top: 1px;
}

/* Panneau de détail d'un événement */
.rv-event-panel {
    width: 280px;
    min-width: 280px;
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
    padding: 18px;
    position: sticky;
    top: 84px;
    box-shadow: var(--rv-shadow-sm);
    overflow: hidden;
    animation: rv-panel-in var(--rv-dur) var(--rv-ease) both;
}
@keyframes rv-panel-in {
    from { opacity: 0; transform: translateX(8px); }
    to   { opacity: 1; transform: none; }
}
.rv-panel-subject {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--rv-ink);
    line-height: 1.35;
    margin-bottom: 12px;
    letter-spacing: -0.01em;
}
.rv-panel-row {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 0.8125rem;
    color: var(--rv-ink-3);
    margin-bottom: 8px;
    line-height: 1.45;
}
.rv-panel-row .mud-icon-root { color: var(--rv-ink-4) !important; }
.rv-panel-body {
    font-size: 0.8125rem;
    color: var(--rv-ink-3);
    line-height: 1.55;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--rv-border);
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (max-width: 959px) {
    .rv-cal-layout { flex-direction: column; }
    .rv-event-panel { width: 100%; min-width: 0; position: static; }
}

/* ============================================================
   Notifications
   ============================================================ */
.mud-snackbar {
    border-radius: var(--rv-radius-md) !important;
    box-shadow: var(--rv-shadow-lg) !important;
    font-size: 0.875rem;
    z-index: var(--rv-z-toast);
}

/* ============================================================
   Disposition
   ============================================================ */
.mud-main-content {
    min-height: 100vh;
    background: transparent;
}
/* Le contenu n'anime pas son propre reflux. Animer le padding ici redisposait
   et repeignait toute la colonne principale pendant la durée ; le tiroir
   glisse déjà sous son propre transform, le geste reste lisible et le
   contenu se pose simplement. */
.mud-drawer + .mud-main-content { transition: none; }
/* L'air au-dessus du titre de page : 16 px le collaient à la barre haute ; 36 px le
   détachent sans pousser la bande de mesures sous la ligne de flottaison. */
.rv-main-container { padding-top: 36px; padding-bottom: 32px; }
@media (max-width: 599.95px) {
    .rv-main-container { padding-top: 22px; padding-bottom: 22px; }
}

/* Connexion : scène indépendante et colonne bornée, comme dans Atlas. */
.rv-login {
    position: relative;
    isolation: isolate;
    min-height: 100svh;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    overflow: hidden;
    color: #f0f4fa;
    background: radial-gradient(ellipse at 80% 0%, #192b40, transparent 65%), #07111d;
}
.rv-login-etudia {
    position: absolute;
    top: 28px;
    left: 4%;
    z-index: 2;
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 14px;
    border-radius: 6px;
    background: transparent;
}
.rv-login-etudia img { display: block; width: 132px; height: auto; }
.rv-login-publisher {
    position: absolute;
    bottom: 28px;
    left: 50%;
    width: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 0 24px;
    color: #a1b3c9;
    font-size: 12px;
    z-index: 1;
}
.rv-login-publisher a { display: inline-flex; align-items: center; min-height: 44px; border-radius: 4px; }
.rv-login-publisher img { display: block; width: 90px; height: auto; }
.rv-login-hero {
    position: absolute;
    inset: 0 auto 0 0;
    width: 55%;
    display: flex;
    align-items: center;
    pointer-events: none;
    mask-image: linear-gradient(to right, #000 75%, transparent);
}
.rv-login-scene {
    width: 100%;
    max-width: 1050px;
    aspect-ratio: 840 / 900;
    overflow: hidden;
    mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 85%, transparent),
        linear-gradient(to right, #000 76%, transparent 100%);
    mask-composite: intersect;
}
.rv-login-scene img { display: block; width: 177.5%; max-width: none; height: auto; }
.rv-login-panel {
    grid-column: 2;
    z-index: 1;
    width: min(100%, 536px);
    padding: 72px 32px 112px;
    justify-self: center;
}
.rv-login-brand { display: flex; align-items: center; gap: 18px; margin-bottom: 42px; font-size: 40px; font-weight: 650; letter-spacing: -1.4px; }
.rv-login-brand svg { width: 58px; height: 58px; flex-shrink: 0; }
.rv-login-accent { color: #ff5005; }
.rv-login-panel h1 { margin: 0; font-size: 38px; font-weight: 600; line-height: 1.15; letter-spacing: -.7px; }
.rv-login-lead { margin: 12px 0 0; font-size: 28px; line-height: 1.25; color: #adc2da; }
.rv-login-description { margin: 28px 0 32px; font-size: 16px; line-height: 1.6; color: #a1b3c9; }
.rv-login-button { display: flex; align-items: center; gap: 16px; width: 100%; min-height: 60px; padding: 14px 20px; border-radius: 8px; color: #fff; background: #1685e5; font-size: 16px; font-weight: 600; text-decoration: none; transition: background-color 150ms ease; }
.rv-login-button span { flex: 1; text-align: center; }
.rv-login-button svg { width: 24px; height: 24px; flex-shrink: 0; }
.rv-login-button:active { background: #0968ba; }
.rv-login-or { display: flex; align-items: center; gap: 18px; margin: 24px 0 12px; color: #9bafc7; font-size: 14px; }
.rv-login-or::before, .rv-login-or::after { content: ""; height: 1px; background: #2b3b50; flex: 1; }
.rv-login-other { display: flex; justify-content: center; align-items: center; min-height: 44px; color: #adc2da; font-size: 14px; text-decoration: none; border-radius: 4px; }
.rv-login a:focus-visible { outline: 3px solid #fff; outline-offset: 5px; }
.rv-login-features { position: absolute; bottom: 40px; left: 4%; display: flex; gap: 32px; list-style: none; padding: 0; margin: 0; color: #a1b3c9; font-size: 13px; line-height: 1.5; }
.rv-login-features li { display: flex; align-items: center; gap: 12px; }
.rv-login-features .mud-icon-root { width: 28px; height: 28px; }
.rv-login-watermark { position: absolute; right: -24px; bottom: -58px; width: 240px; height: 240px; color: #1c2d40; transform: rotate(-10deg); z-index: -1; }
@media (hover: hover) and (pointer: fine) {
    .rv-login-button:hover { background: #0874ce; }
    .rv-login-other:hover { color: #fff; text-decoration: underline; }
}
@media (max-width: 1099px) {
    .rv-login { grid-template-columns: 1fr; padding: 24px; }
    .rv-login-etudia { position: relative; top: auto; left: auto; justify-self: start; }
    .rv-login-publisher { position: static; width: 100%; padding: 16px 0 0; flex-wrap: wrap; }
    .rv-login-hero { display: none; }
    .rv-login-panel { grid-column: 1; padding: 40px 0; max-width: 472px; }
    .rv-login-features { position: static; flex-wrap: wrap; justify-content: center; gap: 24px; padding: 24px 0; }
    .rv-login-watermark { opacity: .45; }
}
@media (max-width: 480px) {
    .rv-login-brand { font-size: 32px; gap: 12px; margin-bottom: 32px; }
    .rv-login-brand svg { width: 46px; height: 46px; }
    .rv-login-panel h1 { font-size: 32px; }
    .rv-login-lead { font-size: 24px; }
    .rv-login-button { gap: 12px; padding-inline: 14px; font-size: 14px; }
    .rv-login-features { justify-content: flex-start; font-size: 12px; }
}

/* ============================================================
   Barres de défilement — taille standard et neutres
   ============================================================ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--rv-border-strong);
    border-radius: var(--rv-radius-full);
    border: 2px solid transparent;
    background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--rv-ink-disabled); background-clip: content-box; }
* { scrollbar-color: var(--rv-border-strong) transparent; scrollbar-width: thin; }

/* ============================================================
   Infrastructure Blazor
   ============================================================ */
#blazor-error-ui {
    background: var(--rv-warning-soft);
    color: var(--rv-ink);
    border-top: 1px solid var(--rv-warning-border);
    bottom: 0;
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    font-size: 0.875rem;
    z-index: var(--rv-z-toast);
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.6rem; }
.blazor-error-boundary::after { content: "Une erreur s'est produite."; }


/* ============================================================
   Aperçu de texto — volontairement indépendant du thème
   ------------------------------------------------------------
   Cette boîte tient lieu de bulle de message d'un téléphone : elle
   garde sa propre apparence claire dans les deux thèmes au lieu de
   suivre le canevas. Les valeurs sont fixes à dessein ; c'est pour
   cela qu'elles sont nommées ici et non reliées aux jetons.
   ============================================================ */
.rv-sms-preview {
    background-color: #F5F5F5 !important;
    border: 1px solid #DDDDDD !important;
    border-radius: var(--rv-radius-md) !important;
    box-shadow: none !important;
}
.rv-sms-preview .rv-sms-preview-body {
    white-space: pre-wrap;
    color: #1A1A1A;
}

/* ============================================================
   Mouvement réduit — le déplacement s'en va, le retour d'état reste
   ------------------------------------------------------------
   Réduire, pas retirer. Un `transition-duration: 0.01ms` global
   emporte le retour de survol, de focus, de désactivation et de
   sélection avec le mouvement, ce qui coûte plus aux personnes qui
   règlent cette préférence que le mouvement ne leur coûtait.

   Donc : on restreint CE QUI peut s'animer plutôt que sa durée. Les
   propriétés porteuses d'état continuent de s'adoucir ; transform,
   width et padding sont simplement absents de la liste, donc ils se
   posent instantanément sans être forcés à `none` — ce qui compte,
   parce que MudBlazor positionne les info-bulles et leurs flèches
   par transform et casserait si on l'annulait.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        transition-property: color, background-color, border-color,
                             box-shadow, opacity, fill, stroke !important;
        transition-duration: var(--rv-dur-fast) !important;
    }

    /* Les entrées écrites et le miroitement sont le mouvement réel de
       cette application, et ils s'en vont. Ce qui n'est PAS tué ici : les
       toupies indéterminées. Leur mouvement est le seul signal qu'un
       travail est en cours, et une toupie figée se lit comme une
       application plantée. */
    .page-enter, .rv-event-panel, .mud-menu-popover { animation: none; opacity: 1; transform: none; }
    .mia-skeleton::after, .rv-time-pending::after { animation: none; }
}

/* ============================================================
   Primitives de polissage (2026-10-09)
   ============================================================ */

/* Aide de section : du texte d'appui, pas une alerte. Une MudAlert info
   par page au plus ; le reste de l'aide vit ici, sous le titre. */
.rv-section-help {
    margin: 2px 0 12px;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--rv-ink-3);
    max-width: 68ch;
    text-wrap: pretty;
}
.rv-section-help strong { color: var(--rv-ink-2); font-weight: 600; }
/* Une aide qui ferme un bloc de page (et non une aide sous le titre d'une carte) : les 22 px entre blocs. */
.rv-section-help--block { margin-bottom: 22px; }

/* Onglets de section d'une page de réglages : une vue à la fois, la barre
   tenue par un filet, curseur 2 px bleu signal sous l'onglet actif. Sous son
   nom, chaque onglet dit l'état de sa section (une ligne, ton sémantique). */
.rv-tabs {
    display: flex;
    gap: 2px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--rv-border);
    overflow-x: auto;
    scrollbar-width: none;
}
.rv-tabs::-webkit-scrollbar { display: none; }
.rv-tab {
    position: relative;
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-width: 168px;
    padding: 10px 16px 12px;
    background: none;
    border: 0;
    border-radius: var(--rv-radius-md) var(--rv-radius-md) 0 0;
    font: inherit;
    text-align: left;
    color: var(--rv-ink-3);
    cursor: pointer;
    transition: background-color var(--rv-dur-fast) var(--rv-ease), color var(--rv-dur-fast) var(--rv-ease);
}
.rv-tab:hover { background: var(--rv-hover); color: var(--rv-ink); }
.rv-tab::after {
    content: "";
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: -1px;
    height: 2px;
    border-radius: 2px 2px 0 0;
    background: transparent;
    transition: background-color var(--rv-dur-fast) var(--rv-ease);
}
.rv-tab[aria-selected="true"] { color: var(--rv-ink); }
.rv-tab[aria-selected="true"]::after { background: var(--rv-primary); }
.rv-tab-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.875rem;
    font-weight: 500;
    white-space: nowrap;
}
.rv-tab[aria-selected="true"] .rv-tab-label { font-weight: 600; }
.rv-tab-label .mud-icon-root { font-size: 17px !important; color: var(--rv-ink-4) !important; }
.rv-tab-status {
    display: flex;
    align-items: center;
    gap: 6px;
    padding-left: 25px;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--rv-ink-4);
    white-space: nowrap;
}
.rv-tab-status--success { color: var(--rv-success); }
.rv-tab-status--warning { color: var(--rv-warning); }
.rv-tab-status--error   { color: var(--rv-error); }
.rv-tab-status-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rv-tab-label-short { display: none; }
.rv-tabpanel { display: flex; flex-direction: column; gap: 14px; }
.rv-tabpanel-next { display: flex; justify-content: flex-end; }
/* Tablette et fenêtre étroite : la barre défilait sans indice (barre de défilement masquée)
   et le quatrième onglet sortait de l'écran sous 800 px. Les onglets se partagent la
   largeur ; un libellé long passe sur deux lignes plutôt que d'être coupé. */
@media (min-width: 600px) and (max-width: 959.95px) {
    .rv-tabs { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); overflow: visible; }
    .rv-tab { min-width: 0; padding: 10px 12px 12px; }
    .rv-tab::after { left: 12px; right: 12px; }
    .rv-tab-label { white-space: normal; text-wrap: balance; line-height: 1.3; min-width: 0; }
    .rv-tab-status { max-width: 100%; }
}
/* Téléphone : les onglets se partagent la largeur au lieu de défiler — un
   onglet actif coupé au bord de l'écran ne se lit pas comme sélectionné. */
@media (max-width: 599.95px) {
    .rv-tabs { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0; }
    .rv-tab { min-width: 0; align-items: center; padding: 9px 6px 11px; text-align: center; }
    .rv-tab::after { left: 8px; right: 8px; }
    .rv-tab-label .mud-icon-root,
    .rv-tab-label-full { display: none; }
    .rv-tab-label-short { display: inline; }
    .rv-tab-label { max-width: 100%; min-width: 0; }
    /* Le libellé court se lit en entier : 13 px et 4 px de marge suffisent à « Organisation » dans un
       quart de 390 px ; il était coupé en « Organisat… ». */
    .rv-tab { padding: 9px 4px 11px; }
    .rv-tab-label { font-size: 0.8125rem; }
    .rv-tab-label-short { display: inline-block; max-width: 100%; white-space: nowrap; vertical-align: bottom; }
    .rv-tab-status { max-width: 100%; padding-left: 0; justify-content: center; min-height: 6px; }
    /* Cinq onglets (la page d'une organisation du SuperAdmin) : le cran label (12 px) et 2 px de marge,
       pour que « Désabonnés » ne sorte pas de l'écran. */
    .rv-tabs:has(> .rv-tab:nth-child(5)) .rv-tab { padding-left: 2px; padding-right: 2px; }
    .rv-tabs:has(> .rv-tab:nth-child(5)) .rv-tab-label { font-size: 0.75rem; }
    /* L'état ne tient pas en clair dans un quart d'écran (« Envoi à 09:… ») : il reste lu par le lecteur
       d'écran (aria-describedby) et, s'il demande l'attention, se voit à son point. */
    .rv-tab-status-text {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
        overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
    }
}

/* Légende des modèles de texto : la règle sur une ligne, puis une rangée de
   jetons à copier — l'exemple de chacun est dans son info-bulle. */
.rv-vars-rule { margin-bottom: 8px; }
.rv-vars-rule .rv-code { font-size: 0.75rem; }
.rv-vars {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 16px;
}
.rv-vars-label {
    margin-right: 4px;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--rv-ink-2);
}

/* « Comment ça marche » : le détail d'une règle, replié sous sa phrase
   d'aide. La phrase suffit pour régler ; le détail reste à un clic. */
.rv-more { margin: -4px 0 12px; max-width: 68ch; }
.rv-more > summary {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--rv-primary-ink);
    cursor: pointer;
    list-style: none;
    border-radius: var(--rv-radius-xs, 4px);
}
.rv-more > summary::-webkit-details-marker { display: none; }
.rv-more > summary::before {
    content: "";
    width: 6px;
    height: 6px;
    margin: 0 4px 0 2px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform var(--rv-dur-fast) var(--rv-ease);
}
.rv-more[open] > summary::before { transform: rotate(45deg); }
.rv-more > summary:hover { text-decoration: underline; text-underline-offset: 2px; }
.rv-more > summary:focus-visible { outline: none; box-shadow: var(--rv-focus-ring-flat); }
.rv-more > p {
    margin: 8px 0 0;
    font-size: 0.8125rem;
    line-height: 1.55;
    color: var(--rv-ink-3);
    text-wrap: pretty;
}

/* Panneau latéral : une fiche ouverte par-dessus une liste, sans la quitter.
   Il flotte réellement, donc il porte l'ombre lg et passe sur un voile
   (échelle z : voile 500, panneau 600). Il glisse depuis la droite en
   220 ms ; sous prefers-reduced-motion il se pose, le voile garde son fondu. */
.rv-sheet-scrim {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: rgba(3, 6, 10, 0.55);
    animation: rv-fade var(--rv-dur-slow, 220ms) var(--rv-ease) both;
}
.rv-sheet {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 600;
    width: min(720px, 100vw);
    display: flex;
    flex-direction: column;
    background: var(--rv-canvas);
    border-left: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-xl) 0 0 var(--rv-radius-xl);
    box-shadow: var(--rv-shadow-lg);
    animation: rv-sheet-in var(--rv-dur-slow, 220ms) var(--rv-ease) both;
}
.rv-sheet-trap { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.rv-sheet-head {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 16px 14px 16px 22px;
    border-bottom: 1px solid var(--rv-border);
    background: var(--rv-surface);
    border-radius: var(--rv-radius-xl) 0 0 0;
}
.rv-sheet-ident { flex: 1; min-width: 0; }
.rv-sheet-title {
    margin: 0;
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.3;
    color: var(--rv-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rv-sheet-sub {
    margin: 1px 0 0;
    font-size: 0.8125rem;
    color: var(--rv-ink-3);
    overflow-wrap: anywhere;
}
.rv-sheet-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 18px 22px 0;
}
/* La barre d'actions de la fiche reste collée au bas du panneau, pas de la fenêtre. */
.rv-sheet-body .rv-actionbar { margin-bottom: 18px; }
@keyframes rv-sheet-in { from { transform: translateX(100%); } to { transform: none; } }
@keyframes rv-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .rv-sheet { animation: none; }
}
@media (max-width: 599.95px) {
    .rv-sheet { border-radius: 0; border-left: none; }
    .rv-sheet-head { border-radius: 0; padding-left: 16px; }
    .rv-sheet-body { padding: 16px 16px 0; }
}

/* Modèles de texto, un à la fois (TemplatePager) : la liste à gauche dans un puits (surface 2), le volet
   ouvert à droite. Le volet choisi se lève d'un cran (surface + filet), comme le segment actif d'un
   contrôle segmenté — un choix de vue, pas une action. Au téléphone, la liste passe en rangée. */
.rv-pager {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
    overflow: hidden;
}
body:not(.rv-dark) .rv-pager { box-shadow: var(--rv-shadow-xs); }
.rv-pager-nav {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 10px;
    background: var(--rv-surface-2);
    border-right: 1px solid var(--rv-border);
}
.rv-pager-list { display: flex; flex-direction: column; gap: 2px; }
.rv-pager-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-width: 0;
    padding: 9px 12px;
    background: none;
    border: 0;
    border-radius: var(--rv-radius-md);
    font: inherit;
    text-align: left;
    color: var(--rv-ink-2);
    cursor: pointer;
    transition: background-color var(--rv-dur-fast) var(--rv-ease), color var(--rv-dur-fast) var(--rv-ease);
}
.rv-pager-item:hover { background: var(--rv-hover); color: var(--rv-ink); }
.rv-pager-item[aria-selected="true"] {
    background: var(--rv-surface);
    color: var(--rv-ink);
    box-shadow: inset 0 0 0 1px var(--rv-border-mid);
}
.rv-pager-label { font-size: 0.875rem; font-weight: 500; line-height: 1.35; }
.rv-pager-item[aria-selected="true"] .rv-pager-label { font-weight: 600; }
.rv-pager-status {
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--rv-ink-4);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rv-pager-aside {
    margin-top: auto;
    padding: 12px 6px 4px;
    border-top: 1px solid var(--rv-border);
}
.rv-pager-body { min-width: 0; padding: 16px 20px 18px; }
.rv-pager-title {
    margin: 0 0 10px;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--rv-ink);
}
@media (max-width: 899.95px) {
    .rv-pager { grid-template-columns: minmax(0, 1fr); }
    .rv-pager-nav { border-right: none; border-bottom: 1px solid var(--rv-border); }
    .rv-pager-list { flex-direction: row; }
    .rv-pager-item { flex: 1 1 0; }
    .rv-pager-aside { margin-top: 0; padding: 10px 6px 2px; }
    .rv-pager-body { padding: 14px 16px 16px; }
}

/* Le panneau prend le focus à l'ouverture pour Échap et le clavier : cible programmatique, pas d'anneau. */
.rv-sheet:focus { outline: none; }

/* Poste de travail : le panneau se range sous la barre haute et pousse la page vers la gauche au lieu de
   la recouvrir — la liste reste lisible, une autre ligne s'ouvre sans fermer. Rangé, il ne flotte plus :
   ni voile ni ombre, un filet. Sous 1200 px, il reste par-dessus, sur son voile. */
:root { --rv-sheet-docked-w: 520px; }
.rv-sheet-host { transition: margin-right var(--rv-dur-slow, 220ms) var(--rv-ease); }
@media (min-width: 1200px) {
    .rv-sheet-host--open { margin-right: var(--rv-sheet-docked-w); }
    /* Poussée, la liste garde l'essentiel — le membre, ses trois modèles, la flèche ; le reste est dans le panneau. */
    .rv-sheet-host--open .rv-col-secondary { display: none; }
    .rv-sheet-host--open .rv-th-sub { display: none; }
    .rv-sheet-host--open .rv-col-member { min-width: 150px !important; }
    .rv-sheet-scrim { display: none; }
    .rv-sheet {
        top: 64px;
        width: var(--rv-sheet-docked-w);
        border-radius: 0;
        box-shadow: none;
    }
    .rv-sheet-head { border-radius: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .rv-sheet-host { transition: none; }
}

/* La ligne du membre ouvert dans le panneau. */
.mud-table-row.rv-row-selected td { background: var(--rv-primary-soft) !important; }

/* Nom d'un membre dans une table : un lien qui se lit comme un nom, souligné au survol. */
.rv-member-link {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--rv-ink);
    text-decoration: none;
}
.rv-member-link:hover { color: var(--rv-primary-ink); text-decoration: underline; text-underline-offset: 2px; }

/* Unité d'une mesure (« jour », « h ») : posée sur la ligne de base du chiffre. */
.rv-metric-unit {
    margin-left: 4px;
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: normal;
    color: var(--rv-ink-3);
}

/* Barre d'actions d'un formulaire : collée au bas de la fenêtre tant que le
   formulaire défile, pour qu'« Enregistrer » reste à portée des champs. */
.rv-actionbar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 8px;
    padding: 11px 18px;
    margin-top: 16px;
    background: var(--rv-surface);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius-lg);
}
body:not(.rv-dark) .rv-actionbar { box-shadow: 0 -1px 0 var(--rv-border), 0 -6px 16px rgba(17, 24, 39, 0.05); }
.rv-actionbar-note {
    margin-right: auto;
    font-size: 0.8125rem;
    color: var(--rv-ink-3);
}
.rv-actionbar-note--dirty { color: var(--rv-warning); font-weight: 500; }
/* Variante interne à une carte : remplace le pied, pleine largeur. */
.rv-actionbar--inset {
    margin: 0;
    border: none;
    border-top: 1px solid var(--rv-border);
    border-radius: 0 0 var(--rv-radius-lg) var(--rv-radius-lg);
    background: var(--rv-surface-2);
}
body.rv-dark .rv-actionbar--inset { background: var(--rv-surface-2); }

/* Bouton de copie d'une cellule : présent au clavier, discret à la souris. */
.rv-copy { opacity: 0; transition: opacity var(--rv-dur) var(--rv-ease); }
.mud-table-row:hover .rv-copy,
.rv-copy:focus-visible { opacity: 1; }
@media (hover: none) { .rv-copy { opacity: 1; } }

@media (max-width: 599.95px) {
    .rv-actionbar { padding: 10px 12px; }
    /* La note prend sa ligne : sans quoi elle partageait la sienne avec « Annuler » sur un onglet et avec
       « Aperçu » sur l'autre — la même barre changeait de disposition d'un onglet à l'autre. */
    .rv-actionbar > .rv-actionbar-note { flex-basis: 100%; margin-right: 0; }
    .rv-actionbar > .mud-button-root,
    .rv-actionbar > .mud-tooltip-root { flex: 1 1 auto; }
    .rv-actionbar > .mud-tooltip-root > .mud-button-root { width: 100%; }
}

/* Suivi des rappels, vue Grille : le calendrier tient dans une carte, sans sa propre barre d'outils
   (la période se règle dans l'en-tête de page). */
.rv-cal-card { height: auto; padding: 4px 0 0; overflow: hidden; }
.rv-cal-card .rv-cal-layout { padding: 0 12px 12px; }

/* ── Menu du compte (barre haute) ─────────────────────────
   Même disposition qu'Atlas : initiales, nom, rôle sous le nom, chevron. */
.rv-me {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: 6px;
    padding: 4px 6px 4px 4px;
    border-radius: var(--rv-radius-md);
    cursor: pointer;
    user-select: none;
    color: var(--rv-ink);
    transition: background-color var(--rv-dur-fast) var(--rv-ease);
}
.rv-me:hover { background: var(--rv-hover); }
.rv-me:focus-visible { outline: 2px solid var(--rv-primary); outline-offset: 2px; }
.rv-me-avatar {
    display: inline-grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--rv-primary-soft);
    color: var(--rv-primary-ink);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0;
}
.rv-me-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; min-width: 0; }
.rv-me-name { font-size: 0.8125rem; font-weight: 600; color: var(--rv-ink); white-space: nowrap; }
.rv-me-role { font-size: 0.6875rem; color: var(--rv-ink-3); white-space: nowrap; }
.rv-me-caret.mud-icon-root { font-size: 18px; color: var(--rv-ink-4); }
@media (max-width: 599.95px) {
    .rv-me-text { display: none; }
    .rv-me { gap: 4px; margin-left: 2px; }
}
