/* Thème « IDeal Evolution 01 » (premier thème produit, fidèle à une référence de style réelle ; valeurs
   exactes dans design-refs/ideal-evolution-01/_mapping.md) : typographie system-ui (échelle remontée
   prompt 95 : corps 15 px, menu 14 px), accent bleu #1f6bff, fond app #ebeef4 (clair) / #212837 (sombre),
   surfaces #FFFFFF / #2a374f, rayons 6 px, barre 54 px, tiroir 239/65 px. Le détail des couleurs/typo vit
   dans le thème MudBlazor centralisé
   (IdealeThemes.cs) ; cette feuille porte les variables globales (dégradés, ombres, rayons) et les réglages
   de shell non couverts par le thème. Architecture multi-thèmes : pour ajouter un thème, on peut scoper des
   variables sous [data-theme-ui="<cle>"] (le défaut « IDeal Evolution 01 » est porté par :root). */

/* Police web embarquée (issue de la référence) : FontAwesome (icônes). La référence n'embarque AUCUNE
   police de texte propriétaire — le corps reste en system-ui (cf. famille principale ci-dessous). Cette
   déclaration rend la police d'icônes disponible localement (aucune dépendance distante, aucune marque
   tierce dans l'UI). */
@font-face {
    font-family: 'Ideale Icons';
    font-style: normal;
    font-weight: 900;
    font-display: block;
    src: url('fonts/fa-solid-900.woff2') format('woff2');
}

/* === Variables CSS globales « IDeal Evolution 01 » (consommées partout — rien en dur dans les composants) =
   Dégradés KPI, ombres, rayons, surfaces secondaires, et ombre de la barre supérieure (clair/sombre). */
:root {
    /* Dégradés d'accent KPI (accent #1f6bff de la référence). */
    --g-blue: linear-gradient(135deg, #4f8bff, #1f6bff);
    --g-amber: linear-gradient(135deg, #F59E0B, #F97316);
    --g-green: linear-gradient(135deg, #22C55E, #16A34A);
    /* Ombres (clair). */
    --sh-sm: 0 1px 2px rgba(33, 40, 55, .06);
    --sh: 0 4px 14px rgba(33, 40, 55, .07);
    --sh-lg: 0 12px 34px rgba(33, 40, 55, .14);
    /* Ombre de la barre supérieure (référence : halo bleu très léger en clair). */
    --sh-topbar: 0 6px 6px rgba(31, 107, 255, .1);
    /* Rayons (référence : sm 3 / défaut 6 / lg 9). */
    --r-sm: 6px;
    --r: 6px;
    --r-lg: 9px;
    --r-pill: 999px;
    /* Surface secondaire (fond intermédiaire / champ de recherche clair = gris 100 de la référence). */
    --s-2: #ebeef4;
    /* Survol d'item de menu (référence : gris 300 à 50 %). */
    --ideale-nav-hover: rgba(201, 210, 227, .5);
    /* Largeurs de CONTENU des dialogues — convention #279 (M2) : 3 paliers cohérents, en remplacement des
       max-width en dur épars. sm = formulaire simple ; md = formulaire standard une colonne ; lg = formulaire
       riche à deux colonnes (avec aperçu). À réutiliser sur le conteneur du DialogContent (jamais une valeur en px). */
    --ideale-dialog-sm: 520px;
    --ideale-dialog-md: 640px;
    --ideale-dialog-lg: 860px;
}

/* Filet ErrorBoundary de haut niveau (#280) : carte de RÉCUPÉRATION centrée, affichée uniquement si une
   exception d'un provider MudBlazor (dialogue / snackbar / popover) est rattrapée — le circuit reste vivant.
   Superposition fixe au-dessus de tout (les dialogues Mud sont ~1400 ; on passe largement au-dessus). Thémée via
   les tokens de surface (clair ET sombre) : le MudThemeProvider reste monté au-dessus du filet. */
.ideale-filet-erreur {
    position: fixed;
    inset: 0;
    z-index: 5000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(15, 18, 24, .38);
}

.ideale-filet-erreur-carte {
    max-width: 460px;
    width: 100%;
    border-radius: var(--r-lg);
    box-shadow: var(--sh-lg);
}

/* Mode sombre : surfaces secondaires et ombres plus profondes. La règle s'accroche à l'attribut posé
   par MudBlazor (data-theme="dark") et à la classe utilitaire éventuelle. */
[data-theme="dark"], .mud-theme-dark {
    --sh-sm: 0 1px 2px rgba(0, 0, 0, .40);
    --sh: 0 4px 14px rgba(0, 0, 0, .45);
    --sh-lg: 0 12px 34px rgba(0, 0, 0, .55);
    /* Ombre de barre en sombre (référence). */
    --sh-topbar: 0 2px 16px rgba(0, 0, 0, .35);
    /* Champ de recherche / fond intermédiaire sombre (référence). */
    --s-2: #364767;
    /* Survol d'item de menu sombre (référence : gris 800 à 50 %). */
    --ideale-nav-hover: rgba(60, 78, 113, .5);
}

html, body {
    /* Famille principale « IDeal Evolution 01 » = system-ui (fidèle à la référence ; aucune police de texte
       propriétaire). 'Ideale Icons' (FontAwesome) reste disponible pour d'éventuelles icônes. */
    font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif;
    /* Corps « IDeal Evolution 01 » — échelle remontée (prompt 95) : 15 px / interligne 1.45. Base coordonnée
       avec la typographie du thème MudBlazor (IdealeThemes.BuildTypography → Default 15 px). */
    font-size: 15px;
    line-height: 1.45;
    /* BUG ascenseur horizontal permanent (prompt 78) : le tiroir de l'assistant IA (Persistent, ancré à
       droite) est en position fixed ; FERMÉ, il reste hors-champ à droite et créait un ascenseur horizontal
       permanent — même en plein écran — qui tronquait les bulles d'aide de bord. On clippe le débordement
       HORIZONTAL au niveau du conteneur de défilement (le défilement vertical reste intact, et aucun contenu
       utile n'est masqué : le tiroir reste pleinement visible quand il s'ouvre, en superposition/dock). */
    overflow-x: hidden;
}

/* Liens et boutons Bootstrap résiduels : alignés sur l'accent du thème courant (plus de bleu Fluent figé). */
a, .btn-link {
    color: var(--mud-palette-primary);
}

.btn-primary {
    color: #fff;
    background-color: var(--mud-palette-primary);
    border-color: var(--mud-palette-primary);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.2rem var(--mud-palette-primary);
}

/* Classes utilitaires KPI : tuiles/indicateurs à fond dégradé (consomment les variables ci-dessus). */
.ideale-kpi-blue { background: var(--g-blue); color: #fff; }
.ideale-kpi-amber { background: var(--g-amber); color: #fff; }
.ideale-kpi-green { background: var(--g-green); color: #fff; }

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "Une erreur est survenue."
    }

/* Conteneur de l'aide contextuelle : ancre la bulle MAISON (positionnée par rapport à l'icône). inline-flex
   pour ne pas casser les mises en page « champ + ? » alignées. */
.ideale-aide {
    position: relative;
    display: inline-flex;
    align-items: center;
}

/* Icône d'aide contextuelle (composant AideContextuelle) : discrète, légèrement estompée au repos,
   pleinement visible au survol/focus pour rester accessible. */
.ideale-aide-icone {
    opacity: 0.6;
    padding: 4px;
}

    .ideale-aide-icone:hover,
    .ideale-aide-icone:focus-visible {
        opacity: 1;
    }

/* === Bulle d'aide MAISON (prompt 60) ===============================================================
   Remplace le tooltip MudBlazor (popover dont la largeur restait incontrôlable). Bulle = simple <span>
   positionné SOUS l'icône, largeur PLAFONNÉE à 300px et retour à la ligne GARANTIS (white-space:normal +
   coupure de mots), hauteur auto → texte sur 2-3 lignes. Masquée au repos, révélée au survol/focus du « ? ».
   Couleurs reprises du tooltip MudBlazor (gris foncé + texte clair) → identique en clair ET sombre. */
.ideale-aide-bulle {
    position: absolute;
    top: calc(100% + 8px);
    left: 50%;
    /* Repositionnement « shift » (prompt 79) : la bulle est centrée par défaut, mais un décalage horizontal
       (--decalage, calculé en JS au survol) la ramène DANS le viewport quand elle déborderait d'un bord →
       texte complet, jamais tronqué (y compris l'aide « comment obtenir la clé API » au bord droit). */
    transform: translateX(calc(-50% + var(--decalage, 0px)));
    z-index: 1400;
    max-width: 300px;
    width: max-content;
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-word;
    text-align: center;
    padding: 8px 12px;
    border-radius: var(--r-sm);
    background-color: var(--mud-palette-gray-darker);
    color: var(--mud-palette-dark-text);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.45;
    box-shadow: var(--sh-lg);
    pointer-events: none;
    /* Masquée au repos SANS occuper d'espace (prompt 183). Une bulle en position:absolute laissée en
       visibility:hidden RESTE dans le flux de dimensionnement : large de 300px et ancrée à left:50%, elle
       débordait à droite du conteneur → ascenseur horizontal PARASITE dans les dialogues (et pages) qui
       utilisent AideContextuelle. display:none supprime toute empreinte de mise en page au repos ; la bulle
       est révélée en display:block au survol/focus (le JS de recentrage --decalage reste mesurable à ce
       moment-là, il s'exécute sur mouseover quand la bulle est déjà affichée). */
    display: none;
}

/* Flèche pointant vers le « ? » (au-dessus de la bulle). Quand la bulle est décalée (--decalage) pour rester
   dans le viewport, la flèche est décalée en SENS INVERSE afin de continuer à pointer vers l'icône « ? ». */
.ideale-aide-bulle::after {
    content: "";
    position: absolute;
    bottom: 100%;
    left: calc(50% - var(--decalage, 0px));
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-bottom-color: var(--mud-palette-gray-darker);
}

/* Bascule AU-DESSUS de l'icône (prompt 228, N11) : posée par le JS (ideale.aide.ajuster) quand la bulle,
   placée sous l'icône, dépasserait le bas de la boîte de confinement (ex. icône d'aide en bas d'un dialogue).
   La bulle passe au-dessus et la flèche pointe vers le BAS (vers l'icône). Empêche le débordement de la box
   et l'ascenseur associé, tout en gardant l'aide entièrement lisible. */
.ideale-aide-bulle.ideale-aide-bulle--dessus {
    top: auto;
    bottom: calc(100% + 8px);
}

    .ideale-aide-bulle.ideale-aide-bulle--dessus::after {
        top: 100%;
        bottom: auto;
        border-bottom-color: transparent;
        border-top-color: var(--mud-palette-gray-darker);
    }

/* Révélation au survol de l'icône (ou focus clavier dans le conteneur). */
.ideale-aide:hover .ideale-aide-bulle,
.ideale-aide:focus-within .ideale-aide-bulle {
    display: block;
}

/* Bulle d'aide contextuelle (MudTooltip) : compacte et lisible. Sans contrainte, une aide longue
   s'étire sur toute la largeur en une seule ligne ; on borne la largeur, on autorise le retour à la
   ligne, on arrondit les coins et on aère le contenu. */
.mud-tooltip {
    max-width: 300px;
    white-space: normal;
    overflow-wrap: anywhere;
    border-radius: var(--r-sm);
    padding: 8px 12px;
    line-height: 1.45;
    text-align: left;
}

/* Texte d'aide réservé aux lecteurs d'écran : visuellement masqué mais présent dans le DOM, pour
   être annoncé via aria-describedby quand le champ associé reçoit le focus (cf. AideContextuelle). */
.ideale-aide-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Champs de formulaire HTML natif (pages de connexion : POST réel vers /auth/login et
   /auth/plateforme/login — impossible d'utiliser MudTextField puisqu'il faut un vrai POST pour
   poser le cookie). On les style donc à la main pour suivre le thème MudBlazor (clair/sombre) via
   les variables de palette : couleurs de texte, surface et bordures issues du thème courant. */
.ideale-form-label {
    display: block;
    margin: 14px 0 5px;
    font-weight: 600;
    font-size: 0.75rem;
    color: var(--mud-palette-text-primary);
}

.ideale-form-field {
    display: block;
    width: 100%;
    /* Hauteur compacte ~32 px (densité Fluent). */
    padding: 6px 12px;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: var(--mud-default-borderradius);
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--mud-palette-text-primary);
    background-color: var(--mud-palette-surface);
    box-sizing: border-box;
    /* color-scheme aligne les éléments natifs (caret, remplissage auto) sur le thème. */
    color-scheme: light dark;
    transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}

    .ideale-form-field::placeholder {
        color: var(--mud-palette-text-disabled);
    }

    .ideale-form-field:hover {
        border-color: var(--mud-palette-text-secondary);
    }

    .ideale-form-field:focus {
        outline: none;
        border-color: var(--mud-palette-primary);
        box-shadow: 0 0 0 2px rgba(var(--mud-palette-primary-rgb), 0.25);
    }

.mud-width-full {
    width: 100%;
}

/* Combo de sélection de langue (③bis, défaut 1) : un seul contrôle « langue courante + chevron » qui déroule
   le choix — on n'affiche plus la langue NON choisie en permanence. Bouton transparent qui HÉRITE de la couleur
   du contexte (barre du haut, panneau de connexion clair/sombre) ; accessible (activateur <button>, focus visible).
   Composant PARTAGÉ → styles dans app.css (world-agnostic), tokens MudBlazor comme le reste de cette feuille. */
.ideale-langue-combo {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border: 0;
    border-radius: var(--mud-default-borderradius);
    background: transparent;
    color: inherit;
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease;
}

    .ideale-langue-combo:hover {
        background-color: var(--mud-palette-action-default-hover);
    }

    .ideale-langue-combo:focus-visible {
        outline: none;
        box-shadow: 0 0 0 2px rgba(var(--mud-palette-primary-rgb), 0.4);
    }

.ideale-langue-combo-chevron {
    opacity: 0.7;
}

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* === Pied de page « collé en bas » (sticky footer) ===========================
   Le pied de page est unique (dans les layouts) et toujours ancré tout en bas :
   la zone de contenu prend la hauteur disponible et pousse le pied en bas de la
   fenêtre quand la page est courte ; sur une page longue, il apparaît à la fin
   après défilement. Jamais collé juste sous le contenu.

   Layouts MudBlazor (MainLayout, PlatformLayout, BackOfficeLayout). */
.mud-layout {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.mud-main-content {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
}

/* Layout épuré (SetupLayout : connexion, launcher, assistant). Fond professionnel sobre façon
   Microsoft 365 : léger halo d'accent en haut au-dessus du fond thématisé (clair/sombre), sans
   dégradé criard ni image. */
.setup-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background:
        radial-gradient(900px 480px at 50% -5%, rgba(var(--mud-palette-primary-rgb), 0.10), transparent 70%),
        var(--mud-palette-background);
}

/* Zone enveloppant le pied : poussée tout en bas de l'espace disponible. */
.ideale-pied-zone {
    margin-top: auto;
}

/* === Page de connexion plateforme (esprit IONOS, prompt 101) =================
   Barre supérieure pleine largeur (logo IDeal + accroche en italique léger + sélecteur de langue) au-dessus
   d'un fond neutre, avec la box de connexion centrée, arrondie et descendue. */

/* Barre supérieure : surface du thème + ombre de la barre applicative (cohérence visuelle). */
.ideale-connexion-barre {
    display: flex;
    align-items: center;
    gap: 14px;
    height: 60px;
    padding: 0 24px;
    background-color: var(--mud-palette-surface);
    box-shadow: var(--sh-topbar);
    flex: 0 0 auto;
}

/* (.ideale-connexion-logo retirée : son unique porteur — l'image de logo de la barre de SystemeLayoutLocataire
   — a laissé place au lock-up, qui porte sa propre géométrie. Règle du dépôt : le lot qui orpheline ramasse.) */

/* Séparateur vertical discret entre le logo et l'accroche : fin filet du thème (divider), hauteur calée sur
   l'optique de la barre, centré verticalement par le flex parent (align-items:center). Décoratif. */
.ideale-connexion-separateur {
    flex: 0 0 auto;
    width: 1px;
    height: 30px;
    background-color: var(--mud-palette-divider);
    opacity: 0.8;
}

/* Accroche produit juste à côté du logo : texte fin, léger italique, couleur discrète. Un cran plus grande
   (~0.9375rem) pour plus de présence ; line-height:1 + alignement flex → même centre optique que le logo. */
.ideale-connexion-accroche {
    font-size: 0.9375rem;
    font-weight: 400;
    font-style: italic;
    color: var(--mud-palette-text-secondary);
    letter-spacing: 0.01em;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Sélecteur de langue : poussé vers la droite, sans être collé au bord (le padding de la barre l'en éloigne). */
.ideale-connexion-barre-fin {
    margin-left: auto;
    flex: 0 0 auto;
}

/* Corps : box centrée horizontalement et DESCENDUE (davantage d'air au-dessus). */
.ideale-connexion-corps {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: clamp(48px, 12vh, 140px) 1rem 2rem;
}

/* Box de connexion façon IONOS : coins BIEN arrondis (rayon dédié, plus marqué que le token --r-lg du thème
   actif pour l'élégance IONOS), ombre douce, largeur IMPOSANTE (650 px) tout en restant responsive
   (width:100% → 100% de la largeur disponible, avec marges, sur petit écran). */
.ideale-connexion-carte {
    width: 100%;
    max-width: 650px;
    border-radius: 18px;
    box-shadow: var(--sh-lg);
}

/* Champs E-mail / Mot de passe SCOPÉS à la box de connexion plateforme (n'affecte pas l'écran d'instance qui
   partage .ideale-form-field) : police plus lisible (~15px) et hauteur augmentée (champs plus confortables). */
.ideale-connexion-carte .ideale-form-field {
    font-size: 15px;
    padding: 11px 14px;
}

/* Libellés un cran plus lisibles, cohérents avec les champs agrandis (scopés à la box de connexion). */
.ideale-connexion-carte .ideale-form-label {
    font-size: 0.8125rem;
    margin: 18px 0 6px;
}

/* Bouton « Se connecter » plus GÉNÉREUX (plus haut via le padding vertical) et nettement DÉCOLLÉ du champ
   mot de passe (marge au-dessus). Pleine largeur de la box conservée (mud-width-full). Le bleu du Design
   System reste inchangé (mud-button-filled-primary non touché). */
.ideale-connexion-carte .ideale-connexion-bouton {
    margin-top: 24px;
    padding-top: 13px;
    padding-bottom: 13px;
    height: auto;
    font-size: 0.95rem;
}

/* Avatar rond du titre, cohérent avec « Connexion ». */
.ideale-connexion-avatar {
    height: 40px;
    width: 40px;
}

.ideale-connexion-titre {
    font-weight: 700;
    letter-spacing: 0.01em;
}

/* Responsive : sur petit écran, l'accroche ET son séparateur se masquent pour ne pas encombrer (logo +
   langue conservés). */
@media (max-width: 760px) {
    .ideale-connexion-accroche,
    .ideale-connexion-separateur {
        display: none;
    }

    .ideale-connexion-barre {
        padding: 0 14px;
    }
}

/* Pied de page centré (variante utilisée par SetupLayout : connexion / launcher / assistant). */
.ideale-pied-centre {
    text-align: center;
}

/* Lock-up de marque dans la barre supérieure (à côté du burger), sur les deux périmètres. Marque à 32 px dans
   une barre de 54 px : centré verticalement par la toolbar (align-items:center). Le blanc à droite matérialise
   la ZONE DE PROTECTION face au voisin (recherche / indicateur) — 16 px = le rayon du disque à cette taille.
   Verticalement, les 54 px de la barre ne laissent que 11 px de part et d'autre : la zone de protection est
   donc tenue là où du CONTENU peut entrer (les côtés), pas contre le bord de la barre elle-même — conséquence
   assumée de « la barre ne change pas », à revoir si le lot topbar la rehausse.
   Cette classe ne fait QUE la marge : le repli sur écran étroit appartient au lock-up horizontal lui-même
   (kit-ui.css) et vaut donc pour TOUTES les barres — y compris celles qui, ayant déjà leur propre `gap`, n'ont
   pas besoin de cette marge et ne portent pas cette classe.
   (#310 : commentaire refermé — une fermeture prématurée laissait ce paragraphe ORPHELIN dans le flux CSS et
   la règle ci-dessous était IGNORÉE par le parseur, sélecteur invalide oblige.) */
.ideale-appbar-lockup {
    margin-right: 16px;
}

/* #312 — ZONE DE MARQUE STABLE : la barre du haut ne réagit PLUS à l'état du menu (renversement ASSUMÉ de la
   décision #310-A, recette du 20/07/2026). Le #310 faisait suivre à cette zone la largeur du tiroir pour
   aligner la recherche sur le contenu dans les DEUX états — au prix du nom d'application, effacé en rail : à
   l'usage, le nom apparaissait/disparaissait au gré du menu alors que la barre, elle, ne bouge pas. Nouvelle
   doctrine : le lock-up est TOUJOURS ENTIER et la barre est IMMOBILE — la zone réserve une largeur FIXE calée
   sur le tiroir DÉPLOYÉ (--mud-drawer-width-left, posée en inline sur .mud-layout par MudBlazor — jamais les
   valeurs :root du thème, périmées), si bien que la recherche qui la suit en flux tombe sur le bord gauche de
   la ZONE DE CONTENU quand le menu est ÉPINGLÉ (280 + 40 de gouttière = 320) : l'acquis d'alignement du #310
   est PRÉSERVÉ dans cet état. En rail, le contenu remonte à 114 px mais la recherche ne peut PAS l'y suivre
   sans chevaucher le nom (fin d'encre à 232 px + 16 px de protection = 248 px > 114 px, mesuré) : compromis
   ASSUMÉ, la recherche reste à 320 px — priorité 1 = lock-up stable, priorité 2 = alignement. AUCUN sélecteur
   d'état ici (ni .mud-drawer-open/close-mini-md-left, ni .ideal-shell--etendu, ni .mud-drawer--open/--closed) :
   l'immobilité vaut PAR CONSTRUCTION, y compris pendant l'overlay d'expansion au survol (#305), et aucune
   transition n'est nécessaire — rien ne bouge. min-width (et non width + rognage) : si la marque s'allonge un
   jour, la zone grandit et POUSSE la recherche au lieu de rogner le nom en silence. */
.ideale-appbar-zone-marque {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

/* Le dimensionnement ne vaut qu'à partir du point de rupture du tiroir (Breakpoint.Md = 960 px) : en dessous,
   le tiroir est en overlay, la recherche est masquée (d-md-flex) et le lock-up garde son comportement natif
   (repli < 600 px porté par kit-ui.css — un seuil de LARGEUR D'ÉCRAN, sans aucun lien avec l'état du menu). */
@media (min-width: 960px) {
    /* Largeur réservée = tiroir déployé − 24 px déjà fournis par la gouttière gauche de la toolbar
       (.mud-toolbar-gutters) : 280 − 24 = 256 px, où le lock-up (208 px d'encre + 16 px de protection) tient
       ENTIER avec de l'air. */
    .ideale-appbar-zone-marque {
        min-width: calc(var(--mud-drawer-width-left) - 24px);
    }

    /* La recherche suit la zone de marque en flux, à 40 px — la gouttière de .ideale-contenu : son bord GAUCHE
       tombe sur le bord gauche du contenu MENU ÉPINGLÉ (280 + 40 = 320), et n'en bouge plus (voir le compromis
       assumé ci-dessus). Largeur 420 px inchangée. */
    .ideale-appbar .ideale-recherche-globale {
        margin-left: 40px;
    }
}

/* Initiales de repli dans une pastille d'habillage (AvatarHabille, prompt 160) : quand le client n'a pas de
   logo, on affiche ses initiales — texte gras et lisible sur le dégradé (blanc via la couleur de l'avatar). */
.ideale-avatar-initiales {
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

/* Brand (zone logo en haut à gauche de la barre, fidèle à .brand de la référence) : burger + logo texte,
   calé à gauche. Largeur souple (le header ne commence pas par un grand vide). */
.ideale-brand {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-right: 8px;
    min-width: 0;
}

/* Marque (texte « IDeal Evolution Studio ») : 16 px / 600, couleur encre du header. */
.ideale-brand-texte {
    font-size: 16px;
    font-weight: 600;
}

/* Le nom de l'appli est un LIEN vers le tableau de bord : curseur main, léger éclaircissement au survol
   (couleur primaire), AUCUN effet de glissement/translation. */
.ideale-brand-lien {
    cursor: pointer;
    transition: color 150ms ease;
}

    .ideale-brand-lien:hover {
        color: var(--mud-palette-primary);
    }

/* Zone de droite de la barre : toujours ancrée à l'EXTRÊME DROITE (margin-left:auto) — elle ne se décale pas
   vers le centre quand la fenêtre s'agrandit (la recherche, plafonnée, laisse l'espace à la marge auto). */
.ideale-appbar-droite {
    display: flex;
    align-items: center;
    /* Espacement HOMOGÈNE entre les utilitaires — ordre #307 : [pastille Conso IA (locataire seulement)] ·
       [bascule thème] · [cloche] · [avatar utilisateur, tout au bout]. Gap uniforme de 12 px (prompt 78 :
       barre aérée). */
    gap: 12px;
    margin-left: auto;
    flex-shrink: 0;
}

/* Alignement vertical (recette interface 24/06/2026) : lune (bascule clair/sombre), cloche et avatar sur le
   MÊME axe horizontal. Chaque utilitaire devient une boîte de hauteur commune (40 px) qui CENTRE son contenu →
   la lune (MudIconButton), la cloche (MudIcon + badge) et l'avatar partagent exactement le même centre vertical
   dans la barre de 54 px. `!important` sur display/align : sans ça, le conteneur d'info-bulle de la lune reste
   en `inline-block` (réglage MudBlazor) → le bouton, plus haut que 40 px, se cale en HAUT au lieu d'être centré
   (lune ~2 px trop bas). On force donc le centrage flex. */
.ideale-appbar-droite > * {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center;
    height: 40px;
}

/* Les FORMULAIRES MASQUÉS (déconnexion des menus avatar, #307) ne sont pas des utilitaires : sans cette
   exception, le `display:inline-flex !important` ci-dessus BATTRAIT leur `display:none` inline → un créneau
   fantôme de 40 px + un gap de 12 px apparaîtraient après l'avatar. */
.ideale-appbar-droite > form {
    display: none !important;
}

/* La cloche est un MudIcon (plus petit que sa boîte) enveloppé d'un badge : on centre explicitement l'icône
   DANS le badge (sinon elle se cale en haut → cloche ~2,4 px trop haute). L'activateur et le badge prennent la
   hauteur commune et centrent leur contenu → l'icône de cloche retombe sur le même axe que la lune et l'avatar. */
.ideale-cloche-activateur,
.ideale-cloche-activateur .mud-badge-root {
    display: inline-flex;
    align-items: center;
    height: 40px;
}

/* Espacement uniforme désormais porté par le `gap` du conteneur (.ideale-appbar-droite) : on ne fixe plus de
   marges asymétriques entre les éléments (prompt 78 : écart identique entre les 4 utilitaires). */

/* Bouton BURGER (≡) : au survol, PAS de rond/cercle derrière l'icône — on neutralise le fond de survol et la
   vague (ripple) de MudBlazor. Le seul retour visuel = l'icône qui grise légèrement (couleur secondaire). */
.ideale-brand .mud-icon-button {
    --mud-ripple-opacity: 0;
    --mud-ripple-opacity-secondary: 0;
}

.ideale-brand .mud-icon-button:hover,
.ideale-brand .mud-icon-button:focus-visible,
.ideale-brand .mud-icon-button:active {
    background-color: transparent !important;
}

.ideale-brand .mud-icon-button:hover .mud-icon-root {
    color: var(--mud-palette-text-secondary);
}

/* Activateur du menu avatar : avatar (carré arrondi — doctrine ①) + nom, cliquable d'un bloc. */
.ideale-avatar-activateur {
    cursor: pointer;
}

/* Avatar carré arrondi 30 × 30 px (DOCTRINE « le rond n'appartient qu'à IDeal », Interface ① : plus aucun
   avatar rond hors IDeal). La FORME est portée par la règle de monde
   `html.ideale-monde-* .mud-avatar { border-radius: var(--ds-rayon-avatar) }` (app-saas/app-locataire.css) ;
   ici on ne fixe que la TAILLE. !important pour battre les tailles MudBlazor (.mud-avatar-medium = 40 px). */
.ideale-avatar-activateur .mud-avatar {
    width: 30px !important;
    height: 30px !important;
    min-width: 30px !important;
    max-width: 30px !important;
    font-size: 12px;
}

.ideale-avatar-nom {
    font-weight: 500;
    max-width: 180px;
}

/* Activateur de la cloche : zone cliquable compacte autour de l'icône + pastille. */
.ideale-cloche-activateur {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}

/* Sidebar : fond identique au contenu (référence) → un filet droit la sépare du contenu. */
.ideale-drawer.mud-drawer {
    border-right: 1px solid var(--mud-palette-divider);
}

/* Recherche globale (centre de la barre), conforme ASPStudio. On cible la BOÎTE de saisie outlined de
   MudAutocomplete (`.mud-input.mud-input-outlined`, qui sinon fait ~61 px) et l'input qu'elle contient :
   hauteur 40 px FORCÉE, fond gris #EBEEF4 (--s-2), coins arrondis, AUCUNE bordure au repos, liseré bleu
   UNIQUEMENT au focus. `!important` pour battre les styles internes de MudBlazor (hauteur dense, fond, outline). */
.ideale-recherche-globale {
    flex: 1 1 auto;
    /* #307 (recette) : 760px mangeait la barre — plafonnée à 420px pour libérer la droite (pastille IA ·
       thème · cloche · avatar). Valeur locale commentée : aucun token --ds-* de dimension n'existe à ce jour. */
    max-width: 420px;
    margin: 0 16px;
}

    /* La boîte outlined = le RECTANGLE GRIS VISIBLE : hauteur TOTALE 40 px (box-sizing border-box pour que
       padding/bordure n'ajoutent rien), fond gris, contenu (loupe + input) centré verticalement. C'est CET
       élément qui dessine le fond #EBEEF4 ; sa hauteur mesurée = la hauteur visible du champ. */
    .ideale-recherche-globale .mud-input.mud-input-outlined {
        box-sizing: border-box !important;
        height: 40px !important;
        min-height: 40px !important;
        max-height: 40px !important;
        border-radius: var(--r-sm);
        /* EXP-9d (B) — le fond du champ a QUITTÉ cette feuille commune : --s-2 (#EBEEF4) était la seule teinte
           BLEUE du shell, étrangère à la famille sarcelle, et la réparer ici aurait aggravé la dette #203.
           Les deux jumelles vivent désormais dans app-saas.css et app-locataire.css, écrites séparément. */
        align-items: center;
    }

    /* Pile MudBlazor compactée : ni le conteneur de saisie ni le contrôle n'ajoutent de hauteur (label
       flottant non utilisé ici — placeholder seul). */
    .ideale-recherche-globale .mud-input-control-input-container,
    .ideale-recherche-globale .mud-input-control {
        margin: 0 !important;
        padding: 0 !important;
    }

    /* L'input lui-même (le slot EST l'input) : 40 px TOTAL grâce à box-sizing:border-box (sans ça, le
       padding vertical s'AJOUTAIT à la hauteur → input à 52 px). Padding-left FAIBLE (4 px) : la loupe est un
       adornement flex AVANT l'input, donc c'est lui qui fournit l'espace gauche — un grand padding-left
       s'AJOUTERAIT à la largeur de la loupe (double vide). Le texte démarre donc juste après la loupe. */
    .ideale-recherche-globale .mud-input-slot {
        box-sizing: border-box !important;
        height: 40px !important;
        min-height: 40px !important;
        background-color: transparent !important;
        padding: 6px 12px 6px 4px !important;
        /* Texte saisi + placeholder à 14 px, centrés verticalement dans les 40 px (line-height adapté) → le
           champ ne paraît plus « gros ». !important pour battre la typo MudBlazor (subtitle1 ≈ 16 px). */
        font-size: 14px !important;
        line-height: 1.4 !important;
    }

    /* Loupe COMPACTE et près du bord gauche : on neutralise la marge à droite de l'adornement et on resserre
       le bouton-icône, pour que le texte commence juste à droite de la loupe (sans grand vide). */
    .ideale-recherche-globale .mud-input-adornment-start {
        margin-right: 0 !important;
    }

    .ideale-recherche-globale .mud-input-adornment-start .mud-icon-button {
        padding: 6px !important;
    }

    /* Bordure de l'outline (le <fieldset>) : AUCUNE au repos (ni au survol). */
    .ideale-recherche-globale .mud-input-outlined-border {
        border-color: transparent !important;
    }

    /* AU FOCUS uniquement : liseré bleu (le focus est sur l'input dans la boîte → :focus-within). */
    .ideale-recherche-globale .mud-input.mud-input-outlined:focus-within .mud-input-outlined-border {
        border-color: var(--mud-palette-primary) !important;
        border-width: 2px !important;
    }

    /* Placeholder gris et loupe grise (au repos). */
    .ideale-recherche-globale .mud-input-slot::placeholder {
        color: var(--mud-palette-text-secondary);
        opacity: 1;
    }

    .ideale-recherche-globale .mud-input-adornment .mud-icon-root {
        color: var(--mud-palette-text-secondary);
    }

/* Zone de contenu (toutes les pages) : largeur PLEINE (MaxWidth.False) avec un espacement horizontal CONSTANT
   d'environ 40 px. Combiné à la marge gauche du contenu qui suit le tiroir (MudBlazor : 280 px déployé / 74 px
   replié — les largeurs réelles du shell, cohérentes avec la géométrie #312 gravée plus haut), le contenu se
   cale toujours à ~40 px du bord et s'élargit quand le menu se ferme — sans grand vide. */
.ideale-contenu {
    padding-left: 40px;
    padding-right: 40px;
}

/* Pied de page de copyright (cf. PiedDePageCopyright) : discret, séparé du contenu par un fin filet. La
   couleur secondaire et le filet (divider) MudBlazor s'adaptent au thème clair/sombre. Le logo et la ligne
   copyright forment UNE UNITÉ CENTRÉE horizontalement (logo juste à gauche du texte, même axe optique) —
   identique sur la plateforme ET la page de connexion (prompt 122). */
.ideale-pied-copyright {
    width: 100%;
    padding: 0.6rem 0.25rem 0.5rem;
    border-top: 1px solid var(--mud-palette-divider);
    opacity: 0.85;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

    /* Texte du copyright : marges annulées pour un centrage vertical net avec le logo (align-items:center). */
    .ideale-pied-copyright .mud-typography {
        letter-spacing: 0.01em;
        margin: 0;
    }

/* Petite marque discrète du pied, JUSTE À GAUCHE du texte (et non collée au bord), centrée verticalement sur
   la même ligne optique que le texte. La taille et le rapport carré viennent désormais du composant (SVG à
   24 px, déclinaison minimale) : plus de hauteur ni d'object-fit à forcer ici. */
.ideale-pied-logo {
    flex: 0 0 auto;
    align-self: center;
}

/* === Barre supérieure & densité du menu latéral ====================================================
   Hauteur de la barre applicative et compacité des éléments de navigation. */

/* Barre supérieure « IDeal Evolution 01 » (54 px) : on aligne le décalage du contenu principal sur cette
   hauteur via la variable MudBlazor (sinon un espace resterait sous la barre). Les éléments de la barre
   (brand, recherche, icônes, avatar) sont centrés verticalement dans ces 54 px (toolbar en align-items:center). */
.mud-layout {
    --mud-appbar-height: 54px !important;
}

/* Hauteur effective de la barre = 54 px, contenu centré verticalement, sans débordement. */
.ideale-appbar .mud-toolbar {
    height: 54px;
    min-height: 54px;
    align-items: center;
}

/* Barre supérieure : surface claire/sombre du thème, séparée du contenu par l'ombre de la référence
   (halo bleu très léger en clair, ombre plus marquée en sombre — variable --sh-topbar). */
.ideale-appbar.mud-appbar {
    box-shadow: var(--sh-topbar);
}

/* Icônes utilitaires de la barre (burger, notifications, IA, thème, etc.) : fines (20 px). */
.ideale-appbar .mud-icon-button .mud-icon-root {
    font-size: 20px;
}

/* Les éléments de la barre ne se compriment PAS (flex-shrink:0) — sauf la recherche qui occupe l'espace.
   Sans cela, sur une barre serrée, la cloche et l'avatar pouvaient être réduits à 0 (invisibles / non
   cliquables). La recherche, elle, peut rétrécir (min-width:0) au lieu de pousser les icônes hors champ. */
.ideale-appbar .mud-toolbar > * {
    flex-shrink: 0;
}

.ideale-appbar .ideale-recherche-globale {
    flex: 1 1 auto;
    min-width: 0;
}

/* Densité « IDeal Evolution 01 » : tous les éléments du menu latéral à la MÊME hauteur, coins arrondis 6 px.
   Liste plus DENSE : hauteur de ligne resserrée (30 px), padding vertical réduit (3 px) et marge verticale
   nulle → l'espace vertical entre groupes est resserré et homogène. */
.mud-nav-link,
.mud-nav-group .mud-nav-link {
    min-height: 30px;
    padding-top: 3px;
    padding-bottom: 3px;
    padding-left: 10px;
    padding-right: 10px;
    border-radius: var(--r-sm);
    margin: 0 8px;
    /* Police du menu = 14 px (prompt 95 : valeur d'origine de la référence ASPStudio), taille UNIQUE pour tout
       le menu (groupes ET sous-entrées partagent ce sélecteur) → homogène sur l'ensemble de la sidebar.
       Line-height 20 px : aéré et cohérent avec la remontée d'échelle. */
    font-size: 14px;
    font-weight: 400;
    line-height: 20px;
}

/* Sous-entrées d'un groupe (ex. Pilotage → Tableau de bord / Santé…) : MudBlazor impose `padding:8px 16px`
   (sélecteur plus spécifique que la densité ci-dessus) → lignes trop hautes. On REssERRE le padding vertical
   et la hauteur mini pour une liste compacte, en CONSERVANT l'indentation gauche (padding-left de MudBlazor). */
.ideale-drawer .mud-nav-item .mud-nav-link {
    padding-top: 2px !important;
    padding-bottom: 2px !important;
    min-height: 26px;
}

/* Icône d'item : 16 px (référence 1rem). Seuls les GROUPES portent encore une icône (les sous-entrées sont
   en texte seul) : espace icône ↔ libellé ENCORE resserré (compact, 2 px), identique pour tous les groupes. */
.mud-nav-link .mud-nav-link-icon {
    margin-right: 2px;
    min-width: 0;
}

.mud-nav-link .mud-nav-link-icon .mud-icon-root,
.mud-nav-link .mud-nav-link-icon.mud-icon-root {
    font-size: 16px;
}

/* Libellé d'item : ne pas déborder horizontalement (renfort anti-ascenseur horizontal). Un libellé trop long
   est tronqué proprement (…) plutôt que de pousser la largeur de la colonne. Le flyout réaffiche le texte entier. */
.mud-nav-link .mud-nav-link-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Chevrons de groupe (MudNavGroup) : petits et fins. */
.mud-nav-group > .mud-nav-link .mud-nav-link-expand-icon {
    font-size: 16px;
}

/* Survol (référence) : fond gris translucide (sauf item actif). */
.mud-nav-link:hover:not(.active) {
    background-color: var(--ideale-nav-hover);
}

/* État actif « IDeal Evolution 01 » (fidèle à la référence) : FOND TRANSPARENT, texte et icône en couleur
   primaire (#1f6bff), graisse 600. Pas de pavé plein ni de barre latérale. */
.mud-nav-link.active {
    background-color: transparent;
    color: var(--mud-palette-primary);
    font-weight: 600;
}

.mud-nav-link.active .mud-nav-link-icon .mud-icon-root,
.mud-nav-link.active .mud-nav-link-icon.mud-icon-root {
    color: var(--mud-palette-primary);
}

/* Boutons compacts (~34 px) sans capitales forcées (la casse normale vient du thème). */
.mud-button-root.mud-button {
    min-height: 34px;
}

/* Lignes de tableau compactes (~38–40 px) : on resserre le rembourrage vertical des cellules. */
.mud-table-cell {
    padding-top: 8px;
    padding-bottom: 8px;
}

/* === Tiroir de navigation mini-variant (v0.6) ======================================================
   Le contenu du tiroir est une colonne flex : la navigation occupe l'espace, le bouton utilitaire est
   ancré tout en bas. */
.ideale-drawer-flux {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.ideale-drawer-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    /* Aucun défilement horizontal : on masque tout débordement latéral (libellé long, padding) → plus de barre
       de défilement horizontale en bas de la sidebar. Le défilement vertical reste possible. En mode replié,
       l'override plus bas repasse en overflow:visible pour laisser sortir la bulle (flyout). */
    overflow-x: hidden;
}

/* En mode replié : le menu (icônes) est court → on laisse DÉBORDER (overflow visible) pour que la bulle
   de sous-menu (flyout) sorte à droite sans être rognée. overflow:visible ne masque jamais de contenu. */
.mud-drawer--closed.mud-drawer-mini.ideale-drawer,
.mud-drawer--closed.mud-drawer-mini .ideale-drawer-nav {
    overflow: visible;
}

/* Bouton utilitaire ancré en bas du tiroir (préférences / aide), séparé par un filet. */
.ideale-drawer-bas {
    margin-top: auto;
    border-top: 1px solid var(--mud-palette-divider);
    padding-bottom: 4px;
}

/* Libellés de section (Navigation / SOLUTION / ADMINISTRATION) — densité « IDeal Evolution 01 » : petits et
   HOMOGÈNES (même taille/graisse/couleur pour les trois), gris atténué, MAJUSCULES, marge régulière au-dessus
   de chaque bloc. Taille réduite (12 → 11 px) pour un rendu plus discret. */
.ideale-nav-section {
    padding: 10px 20px 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* Par défaut (mode déployé) : on montre le libellé long, on masque le micro-repère court. */
.ideale-nav-section-court {
    display: none;
}

/* En-tête de la 1re section (« Navigation ») : titre + boutons « tout dérouler / tout enrouler » alignés à
   droite (prompt 79). Porté par .ideale-nav-section-long → automatiquement MASQUÉ en mode replié (mini). */
.ideale-nav-section-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

.ideale-nav-actions {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.ideale-nav-action-btn {
    padding: 2px;
    opacity: 0.65;
}

    .ideale-nav-action-btn:hover,
    .ideale-nav-action-btn:focus-visible {
        opacity: 1;
    }

    .ideale-nav-action-btn .mud-icon-root {
        font-size: 1.15rem;
    }

/* === Mode replié (mini) PROPRE ====================================================================
   Notre MudNavMenu est enveloppé dans .ideale-drawer-flux ; le sélecteur natif de MudBlazor qui masque le
   texte en mini exige un MudNavMenu enfant DIRECT de .mud-drawer-content → il ne s'applique donc pas chez
   nous (d'où les libellés tronqués « P », « M »…). On masque donc explicitement le texte d'item et le chevron
   en mode replié ; le titre de section, lui, n'est PAS masqué : on y montre son micro-repère court (B2).
   Seules les icônes d'item restent (centrées). */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link-text,
.mud-drawer--closed.mud-drawer-mini .mud-nav-link-expand-icon {
    display: none;
}

/* Mode replié : titre de section réduit à son micro-repère court (« Nav » / « Sol » / « Adm »), centré et
   discret → on conserve la séparation Navigation / Solution / Administration sans casser l'alignement des
   icônes. Le libellé long est masqué, le court est affiché. */
.mud-drawer--closed.mud-drawer-mini .ideale-nav-section {
    padding: 8px 0 4px;
    text-align: center;
    font-size: 10px;
    letter-spacing: 0.03em;
}

.mud-drawer--closed.mud-drawer-mini .ideale-nav-section-long {
    display: none;
}

.mud-drawer--closed.mud-drawer-mini .ideale-nav-section-court {
    display: inline;
}

/* En mode replié : chaque item devient un petit CARRÉ compact (32×32) CENTRÉ horizontalement dans la colonne
   (margin auto) → icône parfaitement centrée et alignée avec les micro-libellés de section (NAV/SOL/ADM, eux
   aussi centrés). Padding nul : le survol (fond gris) reste à la taille du carré, sans déborder. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link {
    justify-content: center;
    width: 32px;
    height: 32px;
    min-height: 32px;
    padding: 0;
    margin: 2px auto;
    border-radius: var(--r-sm);
}

.mud-drawer--closed.mud-drawer-mini .mud-nav-link .mud-nav-link-icon {
    margin-right: 0;
}

/* Verrou anti-mouvement (recette interface 24/06/2026) : on RÉAFFIRME explicitement la même boîte au repos,
   au survol ET au focus clavier → AUCUNE variation de taille/marge/padding/bordure/line-height entre les états.
   Seule la couleur de l'icône change (cf. règles de survol plus bas). L'anneau de focus reste un `outline`
   (hors flux, ne décale rien). Résultat : icônes strictement immobiles quand on passe de l'une à l'autre. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link,
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:hover,
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:focus,
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:focus-visible {
    width: 32px;
    height: 32px;
    min-height: 32px;
    padding: 0;
    margin: 2px auto;
    border: 0;
    line-height: 18px;
}

/* Chevron « sous-menu » en mode replié : SEULS les en-têtes de GROUPE (`.mud-nav-group > .mud-nav-link`, qui
   ouvrent une bulle) reçoivent un petit triangle discret à droite de l'icône → repère visuel qu'un menu
   déroulant existe. Les items sans sous-menu (Préférences/Aide, hors groupe) n'en ont pas. Pseudo-élément
   (pointer-events:none) → n'interfère ni avec le survol ni avec la bulle. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-nav-link {
    position: relative;
    overflow: visible;
}

.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-nav-link::after {
    content: "";
    position: absolute;
    top: 50%;
    right: -7px;
    transform: translateY(-50%);
    width: 0;
    height: 0;
    border-top: 3px solid transparent;
    border-bottom: 3px solid transparent;
    border-left: 4px solid var(--mud-palette-text-secondary);
    opacity: 0.75;
    pointer-events: none;
}

/* Survol en mode replié : AUCUN fond gris/carré derrière l'icône. On neutralise le fond de survol (hérité de
   la règle générale) ; à la place, l'ICÔNE passe en BLEU (accent du thème), comme un lien survolé. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:hover:not(.active) {
    background-color: transparent;
}

/* Transition de couleur propre pour l'icône et le chevron au survol. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link .mud-nav-link-icon .mud-icon-root,
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-nav-link::after {
    transition: color 150ms ease, border-color 150ms ease;
}

/* Au survol : icône en bleu primaire (sans fond). */
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:hover .mud-nav-link-icon .mud-icon-root,
.mud-drawer--closed.mud-drawer-mini .mud-nav-link:hover .mud-nav-link-icon.mud-icon-root {
    color: var(--mud-palette-primary);
}

/* Le chevron des icônes à sous-menu passe aussi en bleu au survol, pour rester cohérent avec l'icône. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-nav-link:hover::after {
    border-left-color: var(--mud-palette-primary);
}

/* Atténuer l'effet de vague (ripple) du menu SANS masquer les éléments : la classe `.mud-ripple` est posée
   par MudBlazor sur le lien interactif LUI-MÊME (et non sur un calque enfant) — un `display:none` sur
   `.mud-ripple` masquerait donc tous les liens. On désactive proprement l'animation via la propriété dédiée. */
.ideale-drawer .mud-nav-link {
    --mud-ripple-opacity: 0;
    --mud-ripple-opacity-secondary: 0;
}

/* === Flyout (bulle de sous-menu) en mode replié ====================================================
   MudBlazor n'a pas de flyout au survol : on le construit en CSS, UNIQUEMENT au survol (on ne touche PAS
   l'état par défaut → impossible de vider la sidebar). Au survol d'une icône de groupe, son sous-menu
   sort en bulle flottante à droite, avec ses libellés, sans redéployer la sidebar. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-group {
    position: relative;
}

/* En mode replié et HORS survol : on REPLIE de force le conteneur de sous-entrées de CHAQUE groupe (même le
   groupe actif, déplié par défaut) → les sous-entrées ne « fuient » pas dans le rail, les icônes restent
   contiguës et parfaitement alignées. !important pour battre le style inline `grid-template-rows:1fr`
   posé par MudBlazor sur un groupe déplié. Le survol (règle ci-dessous, plus spécifique) rouvre en bulle.

   CORRECTION DU CLIGNOTEMENT (point clé) : on COUPE la transition `grid-template-rows` du collapse en mode
   replié. Sans ça, l'ouverture CSS au survol déclenche un `transitionend` que le JS de MudCollapse intercepte
   pour réconcilier ses classes selon l'état `Expanded` (faux pour un groupe non déplié) → il ré-applique
   `mud-collapse-hidden`, qui entre en conflit avec notre affichage de bulle → la bulle vibre/clignote. En
   supprimant la transition, aucun `transitionend` n'est émis : la bulle apparaît/disparaît instantanément et
   reste STABLE. L'accordéon animé ne joue donc plus du tout en mode replié (il reste normal en déployé). */
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-collapse-container,
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-collapse-container .mud-collapse-wrapper {
    grid-template-rows: 0 !important;
    /* AUCUNE animation d'apparition : on coupe la transition ET toute animation du collapse en mode replié
       (conteneur + wrapper interne). La bulle apparaît/disparaît NETTEMENT, sans scale/zoom/contraction. Cela
       évite aussi le `transitionend` qui faisait clignoter la bulle (cf. correction du prompt précédent). */
    transition: none !important;
    animation: none !important;
}

/* STABILITÉ DES ICÔNES AU SURVOL (recette interface 24/06/2026) : le conteneur de sous-entrées est sorti du
   FLUX en PERMANENCE (position absolue + masqué hors survol), et plus seulement au survol. Sans ça, l'ouverture
   d'un flyout faisait passer ce conteneur de « en flux » à « absolu » → les icônes voisines, encore en flux, se
   décalaient légèrement (petit saut vertical au passage d'une icône à l'autre). Désormais il ne réserve JAMAIS
   d'espace : zéro décalage. La règle de survol ci-dessous ne fait que le RÉVÉLER (visibility) — la position est
   déjà posée ici. visibility:hidden suffit à le rendre non cliquable et invisible hors survol. */
.mud-drawer--closed.mud-drawer-mini .mud-nav-group > .mud-collapse-container {
    position: absolute;
    inset-inline-start: 100%;
    top: 0;
    visibility: hidden;
}

.mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container {
    grid-template-rows: 1fr !important;
    /* Les groupes NON dépliés portent la classe MudBlazor `.mud-collapse-hidden` (visibility:hidden) → sans
       ça, leur bulle resterait invisible au survol. On rétablit la visibilité pour TOUS les groupes. */
    visibility: visible !important;
    position: absolute;
    inset-inline-start: 100%;
    top: 0;
    min-width: 220px;
    background-color: var(--mud-palette-surface);
    /* Bulle NEUTRE : pas de liseré/bordure ; seule une ombre douce la détache du fond (clair comme sombre). */
    border: none;
    border-radius: var(--r);
    box-shadow: var(--sh-lg);
    z-index: 1300;
}

    /* Dans le flyout : conteneur interne non rogné. */
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-collapse-wrapper {
        overflow: visible;
    }

    /* Dans le flyout : sous-items en PLEINE LARGEUR (on annule le carré 32×32 du rail), alignés à gauche,
       libellés réaffichés. Espacement vertical RÉDUIT (liste compacte) : padding vertical 3 px, marge nulle. */
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link {
        justify-content: flex-start;
        width: auto;
        height: auto;
        padding: 3px 16px 3px 14px;
        margin: 0;
        min-height: 0;
        transition: color 150ms ease;
    }

    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link-text {
        display: inline !important;
    }

    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link .mud-nav-link-icon {
        margin-right: 10px;
    }

    /* Dans la bulle : AUCUN fond/surbrillance gris — ni au repos, ni au survol, ni sur l'entrée active. On
       neutralise tout fond (la règle générale de survol et le fond d'actif de MudBlazor) avec !important. */
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link,
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link:hover,
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link.active {
        background-color: transparent !important;
    }

    /* Seul marqueur d'état dans la bulle = le TEXTE en BLEU (accent), au survol ET sur l'entrée active. */
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link:hover,
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link:hover .mud-nav-link-text,
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link.active,
    .mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .mud-nav-link.active .mud-nav-link-text {
        color: var(--mud-palette-primary) !important;
    }

/* Titre du groupe en tête de la bulle (flyout). Masqué partout par défaut (en mode déployé, l'en-tête du
   groupe porte déjà le libellé → pas de doublon), affiché UNIQUEMENT en tête de la bulle au survol en replié :
   gras, séparé des sous-entrées par un filet. */
.ideale-flyout-titre {
    display: none;
}

.mud-drawer--closed.mud-drawer-mini .mud-nav-group:hover > .mud-collapse-container .ideale-flyout-titre {
    display: block;
    /* Titre de bulle PLUS PETIT et discret, cohérent avec les titres de section (11 px / 600). */
    padding: 6px 16px 5px 14px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    border-bottom: 1px solid var(--mud-palette-divider);
    margin-bottom: 3px;
}

/* Anneau de focus visible et contrasté (accessibilité AA) pour les éléments interactifs au
   clavier : on s'appuie sur l'accent du thème courant (clair comme sombre). */
.mud-button-root:focus-visible,
.mud-icon-button:focus-visible,
.mud-nav-link:focus-visible,
a:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* === Compte à rebours de déconnexion (recette interface 24/06/2026) ================================
   Barre de progression « qui se vide » (de 100 % à 0 %) avec le compteur (10 → 0) centré À L'INTÉRIEUR.
   On donne assez de hauteur à la barre pour loger le chiffre, et un halo léger au texte pour qu'il reste
   lisible aussi bien sur la portion remplie (bleu) que sur la portion vide (piste claire/sombre). */
.ideale-deconnexion-rebours.mud-progress-linear {
    height: 24px;
    border-radius: var(--r-sm);
}

.ideale-deconnexion-compteur {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
    /* Halo = couleur de surface (blanc en clair, sombre en mode sombre) → contraste sur les deux fonds. */
    text-shadow: 0 0 2px var(--mud-palette-surface), 0 0 2px var(--mud-palette-surface);
}

/* === Bulles d'aide (tooltips) — réglage TRANSVERSE (prompts 58 & 59) ===============================
   La bulle MudBlazor est le POPOVER lui-même : div `.mud-popover.mud-tooltip` (avec `d-flex`), dans lequel le
   texte est injecté à l'ouverture. C'est CET élément qui doit plafonner sa largeur et autoriser le retour à la
   ligne. On cible donc `.mud-popover.mud-tooltip` (spécificité supérieure à `.mud-tooltip` seul et au `d-flex`
   utilitaire), on force `display:block` (évite toute ambiguïté de calcul de largeur du conteneur flex à un seul
   item), `white-space:normal !important` (annule tout `nowrap` hérité), et la coupure des mots. Mesuré : un
   texte d'aide long s'affiche sur plusieurs lignes dans une bulle ≤ 300 px. Transverse (toutes les bulles). */
.mud-popover.mud-tooltip {
    display: block !important;
    max-width: 300px;
    white-space: normal !important;
    overflow-wrap: anywhere;
    word-break: break-word;
    text-align: center;
    line-height: 1.4;
    height: auto !important;
}

/* Sécurité : si une bulle héberge un contenu enfant (ChildContent au lieu de Text), il wrappe aussi. */
.mud-popover.mud-tooltip > * {
    white-space: normal !important;
    max-width: 100%;
}

/* === Toasts (snackbars) — placement GLOBAL (prompt 58) ============================================
   Configurés « top-center » côté code (Program.cs). On les décale sous la barre du haut (54 px) pour
   qu'ils apparaissent CENTRÉS, juste sous la barre, dans la zone de contenu (clair comme sombre). */
.mud-snackbar-location-top-center {
    top: 66px;
}

/* === Zone basse FIXE : PIED DE PAGE copyright ancré tout en bas (prompt 97 ; dock IA retiré au prompt 234) ==
   Conteneur fixe en bas, pleine largeur. Le copyright, dernier (et unique) enfant, reste collé en bas de la
   fenêtre. z-index sous les dialogues/popovers MudBlazor mais au-dessus du contenu. */
.ideale-bas-fixe {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1300;
    display: flex;
    flex-direction: column;
}

/* Pied de page (copyright) DANS la zone basse fixe : DERNIÈRE LIGNE, fond opaque (couvre le contenu qui défile
   dessous). Padding vertical discret. Le FILET de séparation est porté par le composant lui-même
   (.ideale-pied-copyright border-top) — un seul trait, qui suit le pied partout (③bis, défaut 2 : plus de
   border-top ici, qui doublait celui du copyright). */
.ideale-bas-pied {
    background-color: var(--mud-palette-background);
    padding: 2px 0;
}

/* On réserve l'espace bas du contenu pour ne pas le masquer sous la zone fixe du pied de page (UNIQUEMENT le
   layout qui la porte, via :has → n'affecte pas les autres layouts). Hauteur = le token --ds-pied-hauteur
   (③bis, défaut 5) — MÊME source que le décalage bas de la bulle IDeal, pour qu'ils ne divergent jamais. */
.mud-layout:has(.ideale-bas-fixe) .mud-main-content {
    padding-bottom: var(--ds-pied-hauteur);
}

/* === Présence IA « Atlas » — dock sobre ancré en bas (locataire #249 + Admin SaaS #260) ==========
   Atlas s'empile DANS la zone basse fixe, AU-DESSUS du copyright (dernière ligne). Conteneur centré,
   discret au repos, déployé pendant l'échange, JAMAIS dans le passage. Couleurs 100 % thème (design
   tokens / variables MudBlazor) — aucune couleur en dur ; clair ET sombre soignés.
   PARTAGE ASSUMÉ (prompt 260) : ces classes .ideale-atlas-* habillent les DEUX présences (locataire ET
   Admin SaaS) pour garantir une EXPÉRIENCE IDENTIQUE et une cohérence de marque durable. Le CSS est
   PRÉSENTATIONNEL (ni code, ni état, ni service, ni table) → la frontière #203 reste stricte là où elle
   compte (composants/état/services séparés : PresenceAtlas ≠ PresenceAtlasSaaS, etc.).
   Point d'accroche pour une éventuelle NUANCE de style propre au SaaS, sans casser le partage :
   la racine SaaS porte en plus la classe .ideale-atlas--saas → cibler « .ideale-atlas--saas .xxx { … } ». */
.ideale-atlas {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 860px;
    margin: 0 auto;
    padding: 0 12px;
    pointer-events: none;                 /* laisse passer les clics dans les gouttières autour de la carte */
}

.ideale-atlas > * {
    pointer-events: auto;                 /* la carte (barre / panneau) reste interactive */
}

/* Quand Atlas est actif, sa barre repliée occupe ~40 px au-dessus du copyright : on réserve l'espace bas
   correspondant (scopé à la présence de la barre → s'applique aux DEUX shells locataire ET Admin SaaS quand
   Atlas est présent, et à rien quand l'IA est désactivée). */
.mud-layout:has(.ideale-atlas-barre) .mud-main-content {
    padding-bottom: 92px;
}

/* Barre repliée : discrète, cliquable, toujours visible quand Atlas est actif. */
.ideale-atlas-barre {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 8px 0 12px;
    background-color: var(--s-2, var(--mud-palette-surface));
    border: 1px solid var(--mud-palette-divider);
    border-bottom: none;
    border-radius: var(--r) var(--r) 0 0;
    box-shadow: var(--sh, 0 2px 8px rgba(0, 0, 0, .08));
    cursor: pointer;
    color: var(--mud-palette-text-primary);
    transition: background-color .15s ease;
}

.ideale-atlas-barre:hover {
    background-color: var(--mud-palette-action-default-hover);
}

.ideale-atlas-barre:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* Pastille = signature sobre (icône IA). Animation par OPACITÉ uniquement (jamais transform en boucle —
   gotcha connu : une animation transform en boucle bloque les clics et l'automatisation). */
.ideale-atlas-pastille {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--g-blue, var(--mud-palette-primary));
    color: #fff;
    flex: 0 0 auto;
}

.ideale-atlas-nom {
    font-weight: 700;
    flex: 0 0 auto;
}

.ideale-atlas-invite {
    color: var(--mud-palette-text-secondary);
    min-width: 0;                          /* autorise le text-truncate dans le flex */
}

.ideale-atlas-chevron {
    color: var(--mud-palette-text-secondary);
}

/* États comportementaux — exprimés par la PASTILLE (jamais par un avatar). */
.ideale-atlas--reflechit .ideale-atlas-pastille {
    animation: ideale-atlas-pulse 1.1s ease-in-out infinite;
}

.ideale-atlas--propose .ideale-atlas-barre {
    border-color: var(--mud-palette-primary);
}

.ideale-atlas--propose .ideale-atlas-pastille {
    box-shadow: 0 0 0 3px var(--mud-palette-primary-hover);
}

@keyframes ideale-atlas-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}

/* Panneau déployé : carte au-dessus de la barre, hauteur bornée, conversation défilable (scroll MAÎTRISÉ de
   la seule zone de contenu ; l'en-tête et la saisie restent ancrés — UX #246 §1). */
.ideale-atlas-panneau {
    display: flex;
    flex-direction: column;
    max-height: min(60vh, 460px);
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-bottom: none;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    box-shadow: var(--sh-lg, 0 8px 30px rgba(0, 0, 0, .18));
    overflow: hidden;
}

.ideale-atlas-entete {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 8px 8px 12px;
    border-bottom: 1px solid var(--mud-palette-divider);
    flex: 0 0 auto;
}

.ideale-atlas-titre {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
    min-width: 0;
}

.ideale-atlas-fil {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ideale-atlas-vide {
    padding: 4px;
}

.ideale-atlas-msg {
    max-width: 92%;
}

.ideale-atlas-msg--moi {
    align-self: flex-end;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    padding: 6px 10px;
    border-radius: 12px 12px 2px 12px;
}

.ideale-atlas-msg--ia {
    align-self: flex-start;
    width: 100%;
}

.ideale-atlas-attente {
    display: flex;
    align-items: center;
    gap: 8px;
}

.ideale-atlas-saisie {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-top: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-surface);
    flex: 0 0 auto;
}

.ideale-atlas-champ {
    flex: 1 1 auto;
}

/* Contrat d'intégration (Atlas-2) : proposition NON ancrée + actions contextuelles dans le panneau. */
.ideale-atlas-proposition {
    margin: 0 12px 8px;
    padding: 10px 12px;
    background-color: var(--s-2, var(--mud-palette-surface));
    border: 1px solid var(--mud-palette-primary);
    border-radius: var(--r-sm);
}

.ideale-atlas-note {
    margin: 0 12px 8px;
}

.ideale-atlas-actions {
    padding: 0 12px 8px;
}

/* Point d'ancrage in-vue (AncrageAtlas) : carte discrète signalant une proposition d'Atlas sur l'élément
   concerné. Filet primaire à gauche = signature Atlas. Couleurs 100 % thème (clair/sombre). */
.ideale-atlas-ancrage {
    padding: 10px 12px;
    border-left: 3px solid var(--mud-palette-primary);
}

/* Entrée vocale (Atlas-4) : indicateur d'enregistrement / transcription + bouton micro. L'utilisateur voit
   TOUJOURS quand le micro est ouvert (aucune écoute cachée). Animations par OPACITÉ uniquement. */
.ideale-atlas-vocal-etat {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px 6px;
}

.ideale-atlas-vocal-etat--ecoute {
    color: var(--mud-palette-error);
    font-weight: 600;
}

/* Pastille rouge « en écoute » : pulsation par opacité (jamais transform en boucle — gotcha clics/automatisation). */
.ideale-atlas-mic-point {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--mud-palette-error);
    flex: 0 0 auto;
    animation: ideale-atlas-mic-pulse 1s ease-in-out infinite;
}

.ideale-atlas-mic--enregistre {
    animation: ideale-atlas-mic-pulse 1s ease-in-out infinite;
}

@keyframes ideale-atlas-mic-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

/* Champ « masqué » (clé API, prompt 79) : on n'utilise PAS type=password (qui déclenche la proposition de
   login/mot de passe enregistré du navigateur). Le champ reste un type=text, mais sa saisie est masquée
   visuellement par -webkit-text-security (puces) — la valeur n'est donc jamais lisible à l'écran. */
.ideale-champ-masque input {
    -webkit-text-security: disc;
    text-security: disc;
}

/* ====================================================================================================
   AIDE CONTEXTUELLE DE PAGE (prompt 108) — icône d'aide en en-tête → popover (aide statique + « Demander à
   l'IA »). Largeur bornée + défilement interne ; 100 % thématisé (clair/sombre via variables MudBlazor).
   ==================================================================================================== */
.ideale-aidepage {
    display: inline-flex;
    align-items: center;
}

/* Carte du panneau d'aide : largeur lisible bornée, hauteur plafonnée avec ascenseur interne (réponses IA longues). */
.ideale-aidepage-carte {
    width: min(92vw, 380px);
    max-height: min(70vh, 560px);
    overflow-y: auto;
    overflow-x: hidden;
}

/* Les mots/URL longs de la réponse IA passent à la ligne (jamais de débordement horizontal). */
.ideale-aidepage-reponse {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Zone de l'indicateur IA à GAUCHE, juste à côté de la recherche (prompt 76) : un petit espace les sépare,
   et la zone ne se comprime pas. L'espace « auto » de la barre la sépare nettement du groupe avatar à droite. */
.ideale-ia-indicateur-zone {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    margin-left: 4px;
}

/* === Indicateur d'IA active dans la barre (prompt 72) ============================================
   Petite pastille cliquable : icône + modèle/fournisseur + repère de budget (jetons). Cohérente avec la
   barre (couleur héritée, survol BLEU sans fond gris, pas d'animation parasite), stable au redimensionnement. */
.ideale-ia-indicateur {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 10px;
    border-radius: var(--r-pill, 999px);
    cursor: pointer;
    color: inherit;
    white-space: nowrap;
    transition: color 0.15s ease;
}

/* Survol : l'icône et le texte passent en bleu primaire, SANS fond gris (cohérent burger/icônes de la barre). */
.ideale-ia-indicateur:hover {
    color: var(--mud-palette-primary);
}

.ideale-ia-indicateur-modele {
    font-size: 13px;
    font-weight: 600;
}

.ideale-ia-indicateur-budget {
    font-size: 12px;
    opacity: 0.75;
}

/* Badge d'origine de la config IA active (spécifique utilisateur vs globale héritée) : pastille discrète. */
.ideale-ia-indicateur-origine {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    padding: 1px 6px;
    border-radius: var(--r-pill, 999px);
    background: color-mix(in srgb, var(--mud-palette-primary) 16%, transparent);
    color: var(--mud-palette-primary);
}

/* Panneau de détail (popover) : largeur confortable et bornée. */
.ideale-ia-indicateur-detail {
    min-width: 280px;
    max-width: 340px;
}

/* Responsive : sur écran moyen on masque le budget compact ; sur petit écran, il ne reste que l'icône
   (le détail complet reste accessible au clic). */
@media (max-width: 960px) {
    .ideale-ia-indicateur-budget {
        display: none;
    }
}

@media (max-width: 740px) {
    .ideale-ia-indicateur-modele {
        display: none;
    }
}
/* ── Calendrier (espace personnel — menu avatar) ─────────────────────────────────────────────
   Grille mensuelle simple : 7 colonnes (lundi → dimanche). Le jour courant est mis en évidence,
   les jours des mois adjacents sont atténués. Thème clair/sombre via les variables MudBlazor. */
.ideale-calendrier-grille {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
}

.ideale-calendrier-entetes {
    margin-bottom: 4px;
}

.ideale-calendrier-entete {
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    padding: 4px 0;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.ideale-calendrier-grille + .ideale-calendrier-grille {
    margin-top: 4px;
}

.ideale-calendrier-jour {
    min-height: 84px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--r-sm);
    padding: 6px;
    background: var(--mud-palette-surface);
}

.ideale-calendrier-numero {
    font-size: 13px;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.ideale-calendrier-hors-mois {
    background: transparent;
    opacity: 0.45;
}

.ideale-calendrier-aujourdhui {
    border-color: var(--mud-palette-primary);
    box-shadow: inset 0 0 0 1px var(--mud-palette-primary);
}

.ideale-calendrier-aujourdhui .ideale-calendrier-numero {
    color: var(--mud-palette-primary);
}

/* === Menu : entrée « grisée + cadenas » (prompts 126 locataire & 136 Exploitant) ===================== */
/* Visibilité à deux/trois niveaux : une entrée que l'on peut voir mais pas piloter (locataire : droit
   manquant ; Exploitant : aucun locataire courant) est rendue par un MudNavLink désactivé. On renforce
   l'affordance « non cliquable » : curseur interdit, opacité réduite et cadenas (icône principale) en couleur
   secondaire — clair ET sombre via les variables du thème. La règle cible « .ideale-drawer-nav » → s'applique
   au menu plateforme ET au menu locataire (qui porte aussi « .ideale-locataire-nav »). La distinction
   grisé/invisible reste gouvernée par les sources uniques NavigationPlateforme / NavigationLocataire. */
.ideale-drawer-nav .ideale-nav-verrou.mud-nav-link.mud-nav-link-disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

.ideale-drawer-nav .ideale-nav-verrou.mud-nav-link.mud-nav-link-disabled .mud-icon-root {
    color: var(--mud-palette-text-secondary);
}

/* E-mail de l'utilisateur connecté dans la barre du shell locataire : discret, tronqué si trop long. */
.ideale-locataire-utilisateur {
    max-width: 220px;
    color: var(--mud-palette-text-secondary);
}

/* Le formulaire de déconnexion (POST natif) ne doit pas perturber l'alignement des icônes de la barre. */
.ideale-locataire-deconnexion-form {
    display: inline-flex;
    align-items: center;
    margin: 0;
}

/* === Landing humaine du locataire (prompt 127) : cartes par entité + responsables empilés ============ */
/* Carte d'entité : hauteur homogène dans la grille (les actions s'alignent en bas). */
.ideale-carte-entite {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.ideale-carte-entite .mud-card-actions {
    margin-top: auto;
}

/* Carte « grisée » (vue mais non pilotée) : estompée et non interactive, cohérent avec la visibilité 3 états. */
.ideale-carte-grisee {
    opacity: 0.6;
}

/* Description tronquée à quelques lignes pour garder des cartes régulières. */
.ideale-carte-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Avatars de responsables EMPILÉS (chevauchement léger) ; le premier sans décalage. */
.ideale-resp-avatars {
    display: flex;
    align-items: center;
}

.ideale-resp-avatar {
    display: inline-flex;
    margin-left: -8px;
    border: 2px solid var(--mud-palette-surface);
    /* Carré arrondi (DOCTRINE du rond, Interface ①) : l'avatar de responsable REPRÉSENTE une personne → jamais rond. */
    border-radius: var(--ds-rayon-avatar);
}

.ideale-resp-avatar:first-child {
    margin-left: 0;
}

/* Bloc nom/rôle du responsable principal : ne déborde pas la carte. */
.ideale-resp-principal {
    min-width: 0;
}

/* Mini-fiche (au survol d'un avatar) : alignée à gauche, lignes lisibles. */
.ideale-resp-fiche {
    text-align: left;
    line-height: 1.4;
}

/* === Sélecteur d'habillage (prompt 130) ============================================================= */
/* Nuancier : pastilles cliquables ; la pastille choisie est entourée. */
.ideale-habillage-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.ideale-swatch {
    width: 26px;
    height: 26px;
    /* Carré arrondi (DOCTRINE du rond, Interface ①) : ≥ 12 px → se lit comme une forme, donc jamais rond. La
       teinte choisie habille un avatar d'entité, lui aussi carré arrondi : le nuancier en préfigure la forme. */
    border-radius: var(--ds-rayon-avatar);
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
}

.ideale-swatch:disabled {
    cursor: default;
}

.ideale-swatch-sel {
    border-color: var(--mud-palette-text-primary);
    transform: scale(1.12);
}

/* Color picker natif : taille raisonnable, coins arrondis. */
.ideale-color-input {
    width: 42px;
    height: 28px;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: var(--r-sm);
    background: transparent;
    cursor: pointer;
    padding: 0;
}

.ideale-degrade-slider {
    min-width: 220px;
}

/* Grille d'icônes (recherche) : enveloppe, hauteur bornée avec défilement. */
.ideale-habillage-icones {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    max-height: 96px;
    overflow-y: auto;
    border: 1px solid var(--mud-palette-divider);
    border-radius: var(--r-sm);
    padding: 4px;
}

/* Aperçu : tuile avec bandeau dégradé + corps. Surfaces CLAIRE et SOMBRE fixées (indépendantes du thème). */
.ideale-habillage-apercu {
    width: 150px;
    border-radius: var(--r);
    overflow: hidden;
    box-shadow: var(--sh-sm);
}

.ideale-apercu-clair {
    background: #ffffff;
    color: #1f2430;
}

.ideale-apercu-sombre {
    background: #171b24;
    color: #e6e9ef;
}

.ideale-apercu-bandeau {
    height: 46px;
    display: flex;
    align-items: center;
    padding: 0 12px;
}

.ideale-apercu-corps {
    padding: 8px 12px;
    display: flex;
    flex-direction: column;
}

.ideale-apercu-titre {
    font-weight: 600;
    font-size: 0.85rem;
    line-height: 1.2;
}

.ideale-apercu-soustitre {
    font-size: 0.72rem;
    opacity: 0.7;
}

.ideale-habillage-logo-apercu {
    height: 28px;
    width: auto;
    border-radius: 4px;
}

/* === Rendu de l'habillage PARTOUT (prompt 131) : bandeau réutilisable ================================ */
/* Bandeau au dégradé effectif de l'entité : texte/icône blancs (contraste garanti, fond saturé hors thème). */
.ideale-habillage-bandeau {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    color: #fff;
    /* Le bandeau affleure le haut de sa carte : ses coins SUIVENT ceux du conteneur (idiome MudBlazor, cf.
       .mud-expand-panel:first-child). Un rayon fixe déborderait de l'arrondi dès que la carte change de thème,
       son dégradé étant opaque et la carte n'ayant pas d'overflow. */
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

/* Variante compacte : en-tête de carte (plus fin que l'en-tête de page de détail). */
.ideale-habillage-bandeau-compact {
    padding: 10px 14px;
    gap: 10px;
}

/* Teinte « sourde » : entité vue mais non pilotée (grisée) — désaturée, reconnaissable sans être vive. */
.ideale-habillage-sourd {
    filter: saturate(0.35);
}

/* Média (logo ou icône) : pastille translucide pour détacher l'icône du dégradé. */
.ideale-habillage-bandeau-media {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, 0.18);
}

.ideale-habillage-bandeau-logo {
    max-width: 36px;
    max-height: 36px;
    border-radius: 4px;
}

/* Bloc texte : titre + sous-titre, tronqués pour ne pas déborder. */
.ideale-habillage-bandeau-texte {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.ideale-habillage-bandeau-titre {
    font-weight: 700;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ideale-habillage-bandeau-soustitre {
    font-size: 0.78rem;
    opacity: 0.85;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Zone d'actions/badges ancrée à droite du bandeau. */
.ideale-habillage-bandeau-actions {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* === Tableau de bord coloré (prompt 132, H3) : cartes KPI à dégradés ================================= */
/* Carte KPI : fond dégradé (fourni en style inline, issu du design system), texte blanc, icône en filigrane.
   Le dégradé saturé garantit le contraste du texte en clair ET sombre (indépendant des surfaces du thème). */
.ideale-tuile-kpi {
    position: relative;
    overflow: hidden;
    height: 100%;
    min-height: 104px;
    padding: 16px 18px;
    border-radius: var(--r-lg);
    box-shadow: var(--sh);
    color: #fff;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Variante cliquable (lien « voir ») : curseur main + léger lift au survol. */
.ideale-tuile-kpi-lien {
    cursor: pointer;
    transition: box-shadow .15s ease, transform .15s ease;
}

.ideale-tuile-kpi-lien:hover {
    box-shadow: var(--sh-lg);
    transform: translateY(-2px);
}

/* Icône décorative en filigrane (grande, translucide, ancrée en haut à droite). */
.ideale-tuile-kpi .ideale-kpi-filigrane {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 72px;
    height: 72px;
    font-size: 72px;
    opacity: 0.22;
    pointer-events: none;
}

/* Ligne haute : titre (+ éventuel badge démo). */
.ideale-kpi-haut {
    display: flex;
    align-items: center;
    gap: 8px;
    z-index: 1;
}

.ideale-kpi-titre {
    font-size: 0.82rem;
    font-weight: 600;
    opacity: 0.95;
}

/* Grand chiffre mis en avant. */
.ideale-kpi-valeur {
    font-size: 2rem;
    font-weight: 800;
    line-height: 1.1;
    z-index: 1;
}

.ideale-kpi-tendance {
    font-size: 0.76rem;
    opacity: 0.9;
    z-index: 1;
}

/* Invite « voir » (lien), ancrée en bas. */
.ideale-kpi-voir {
    margin-top: auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.78rem;
    font-weight: 600;
    opacity: 0.95;
    z-index: 1;
}

/* Carte de SOLUTION habillée sur le tableau de bord : bandeau (BandeauHabille) + corps cliquable. */
.ideale-carte-solution {
    height: 100%;
    cursor: pointer;
    transition: box-shadow .15s ease, transform .15s ease;
}

.ideale-carte-solution:hover {
    box-shadow: var(--sh-lg);
    transform: translateY(-2px);
}

/* ------------------------------------------------------------------------------------------------
   Croix (X) des dialogues de SAISIE protégés (prompt 219). La croix native MudBlazor n'étant pas
   interceptable, on rend notre propre croix (BoutonFermerDialogueProtege), déposée à l'intérieur du
   contenu du dialogue mais positionnée en haut à droite du dialogue (au-dessus de la barre de titre),
   comme une croix native. Le dialogue devient le repère de positionnement le temps qu'une croix y soit.
   ------------------------------------------------------------------------------------------------ */
.mud-dialog:has(.ideale-dialog-fermer) {
    position: relative;
}

.ideale-dialog-fermer {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
}

/* N10 (prompt 228) — croix ALIGNÉE SUR LE TITRE. MudBlazor pose `position:relative` sur `.mud-dialog-content` :
   il devenait le référent de la croix (absolue), qui tombait donc SOUS la barre de titre (« trop basse »). On
   neutralise ce positionnement pour les SEULS dialogues protégés → la croix se réfère à `.mud-dialog`
   (`position:relative` via le `:has` ci-dessus) et se place en haut à droite, au niveau du titre, comme une
   croix native. Le contenu conserve son défilement (`overflow-y`), et l'ancrage des bulles d'aide
   (`.ideale-aide`, elle-même `position:relative`) n'est pas affecté. */
.mud-dialog:has(.ideale-dialog-fermer) .mud-dialog-content {
    position: static;
}

/* ============================================================================================================
   Aperçu HTML « fidèle » de la facture (#272b) — imite le rendu du PDF MigraDoc. Neutres = tokens du thème ;
   l'accent est appliqué en style inline (hex de la CHARTE, source unique). « Papier » clair même en mode sombre
   (une facture s'imprime sur fond blanc — l'aperçu reflète le document imprimé, pas l'UI). Défile si trop haut.
   ============================================================================================================ */
.ideale-apercu-facture {
    background: #ffffff;
    color: #1f2430;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--r);
    box-shadow: var(--sh-sm);
    padding: 20px 22px;
    font-size: 12px;
    line-height: 1.5;
    max-height: 74vh;
    overflow: auto;
}

.ideale-apercu-facture .apf-entete {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.ideale-apercu-facture .apf-emetteur { max-width: 58%; }
.ideale-apercu-facture .apf-titre-zone { text-align: right; }
.ideale-apercu-facture .apf-logo { display: block; height: auto; margin-bottom: 6px; }
.ideale-apercu-facture .apf-logo-droite { margin-left: auto; }
.ideale-apercu-facture .apf-raison { font-weight: 700; margin-bottom: 2px; }
.ideale-apercu-facture .apf-secondaire { color: #5b6472; }
.ideale-apercu-facture .apf-titre { font-size: 22px; font-weight: 800; letter-spacing: .5px; }
.ideale-apercu-facture .apf-numero { font-weight: 700; }

.ideale-apercu-facture .apf-client {
    margin: 14px 0 14px auto;
    width: 55%;
    border: 1px solid;
    border-radius: 6px;
    padding: 8px 10px;
}
.ideale-apercu-facture .apf-client-titre { font-weight: 700; }

.ideale-apercu-facture .apf-table {
    width: 100%;
    border-collapse: collapse;
    border: 1px solid;
    margin-top: 6px;
}
.ideale-apercu-facture .apf-table th,
.ideale-apercu-facture .apf-table td {
    border: 1px solid #e6e9ef;
    padding: 6px 8px;
    text-align: left;
}
.ideale-apercu-facture .apf-table th { font-weight: 700; }
.ideale-apercu-facture .apf-droite { text-align: right; }

.ideale-apercu-facture .apf-totaux {
    margin-top: 10px;
    margin-left: auto;
    width: 55%;
}
.ideale-apercu-facture .apf-total-ligne {
    display: flex;
    justify-content: space-between;
    padding: 2px 0;
}
.ideale-apercu-facture .apf-ttc { font-weight: 800; }

.ideale-apercu-facture .apf-mention { margin-top: 8px; }
.ideale-apercu-facture .apf-italique { font-style: italic; }
.ideale-apercu-facture .apf-retard { font-size: 10px; color: #6b7280; }
.ideale-apercu-facture .apf-pied {
    margin-top: 18px;
    text-align: center;
    font-size: 10px;
    color: #6b7280;
    border-top: 1px solid #e6e9ef;
    padding-top: 6px;
}
.ideale-apercu-facture .apf-pied-libre { border-top: none; font-size: 9px; padding-top: 2px; }
.ideale-apercu-facture .apf-ligne { word-break: break-word; }
