html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* FocusOnNavigate (Routes.razor) place le focus sur le h1 à chaque navigation : sans
   cette règle, un contour apparaîtrait sur le titre à chaque changement de page. */
h1:focus {
    outline: none;
}

/* ── Adaptation mobile ─────────────────────────────────────────────────────────
   Les en-têtes de page (titre à gauche, actions à droite) et leurs groupes de
   boutons sont des conteneurs flex sans retour à la ligne. Sur un écran étroit,
   leur contenu élargit le document ; la barre supérieure, en largeur 100 %, suit
   cet élargissement, et ses commandes (thème, déconnexion) sortent de l'écran —
   la fiche d'un bien débordait ainsi de 320 px.

   Volontairement sans requête de média : le retour à la ligne ne se déclenche que
   lorsque le contenu ne tient pas. Un seuil fixe laisserait forcément une plage de
   largeurs non couverte — la fiche d'un bien débordait encore de 83 px à 620 px avec
   un seuil à 600 px.

   space-between n'a pas besoin d'être neutralisé : une ligne ne portant qu'un seul
   élément l'aligne déjà au début.

   La cible reste restreinte aux en-têtes et à leurs groupes d'actions directs. Une
   règle portant sur toutes les rangées flex ferait aussi passer à la ligne le contenu
   des tuiles du tableau de bord, dont la disposition est correcte. Les actions de
   carte sont exclues : leur répartition est voulue. */
.mud-main-content .d-flex.justify-space-between:not(.mud-card-actions),
.mud-main-content .d-flex.justify-space-between:not(.mud-card-actions) > .d-flex {
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Case à cocher native des formulaires rendus en SSR statique (connexion).
   MudCheckBox y est inutilisable : son icône est dessinée côté serveur d'après Value, donc
   elle ne réagit pas au clic faute de circuit. Le navigateur, lui, sait très bien dessiner
   une case cochée — il suffit de lui donner la couleur du thème. */
.epn-case-a-cocher {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    cursor: pointer;
    user-select: none;
}

.epn-case-a-cocher input[type="checkbox"] {
    width: 1.15rem;
    height: 1.15rem;
    margin: 0;
    accent-color: var(--mud-palette-primary);
    cursor: pointer;
}

/* Cellule principale d'une ligne de tableau, en mode empilé (sous 600 px).

   MudBlazor y transforme chaque cellule en rangée flex « libellé ..... valeur ». Pour la
   cellule qui porte l'identité de la ligne, cela comprime le contenu sur la moitié droite
   et empile côte à côte les éléments censés se succéder. On lui rend donc le flux normal,
   et on supprime son libellé : « Nom » n'apprend rien devant un nom. */
@media (max-width: 599.98px) {
    .mud-table-cell.epn-td-principal {
        display: block !important;
    }

    .mud-table-cell.epn-td-principal:before {
        content: none !important;
    }

    /* HideSmall pose « visibility: collapse » et remet à zéro hauteur et marges, mais la
       règle de densité de MudBlazor, déclarée après, réimpose son padding : chaque colonne
       masquée laissait 12 px de vide, soit 60 px sous chaque bien. On les retire du flux. */
    .mud-table-cell.mud-table-cell-hide {
        display: none !important;
    }

    /* Filtres repliés. La classe n'a d'effet qu'ici : sur écran large les filtres restent
       toujours visibles, le bouton qui les commande étant lui-même masqué (d-sm-none). */
    .epn-filtres-replies {
        display: none !important;
    }

    /* Cellule d'actions : sans libellé, le « space-between » du mode empilé écarte les
       boutons aux deux extrémités de la ligne. On les regroupe à droite. */
    .mud-table-cell.epn-td-actions {
        justify-content: flex-end;
        gap: 0.25rem;
    }

    .mud-table-cell.epn-td-actions:before {
        content: none !important;
    }

    /* Cibles tactiles. Les tableaux sont en mode dense et leurs boutons en Size.Small :
       environ 30 px de côté, sous le minimum recommandé pour le doigt. On élargit la zone
       cliquable sans grossir l'icône, et uniquement sur petit écran — au pointeur, la
       densité du bureau reste préférable. */
    .mud-table-cell .mud-icon-button {
        padding: 11px;
    }
}

/* ── Rythme des blocs ──────────────────────────────────────────────────────────
   Un seul écart entre deux blocs d'une page, vertical comme horizontal.

   Les cartes de section portent déjà leur marge basse (mb-3, 12 px), et la gouttière
   de MudGrid s'y ajoutait au lieu de la remplacer : les éléments d'une grille sont des
   enfants flex, où les marges ne fusionnent pas. Une même page montrait donc trois
   écarts — 12 px entre deux cartes empilées dans une colonne, 24 px entre deux
   colonnes, et 12 + 24 = 36 px dès qu'on passait à la ligne suivante.

   On confie donc tout le vertical à la marge des cartes, et à la grille le seul
   horizontal. Le décalage négatif du conteneur suit la même valeur, faute de quoi la
   première ligne remonterait d'autant.

   À réserver aux grilles de blocs : les grilles de champs, à l'intérieur d'une carte,
   gardent la gouttière de MudBlazor, leur rythme n'étant pas celui des blocs. */
.epn-sections {
    --epn-ecart-blocs: 12px;
    margin-top: 0;
    margin-left: calc(-1 * var(--epn-ecart-blocs));
    width: calc(100% + var(--epn-ecart-blocs));
}

.epn-sections > .mud-grid-item {
    padding-top: 0;
    padding-left: var(--epn-ecart-blocs);
}

/* ── Alignement du texte ───────────────────────────────────────────────────────
   MudBlazor n'expose aucun utilitaire d'alignement au niveau d'un conteneur : seul
   MudText sait s'aligner, par son paramètre Align. « text-center » et « text-right »
   étaient pourtant employés un peu partout — tuiles de statistiques, colonnes de
   montants, colonnes d'actions — comme s'ils venaient du cadriciel. Ils ne
   correspondaient à aucune règle : ces contenus n'ont jamais été alignés.

   On fournit donc les deux règles manquantes plutôt que de reprendre chaque appel :
   le balisage exprimait déjà l'intention, il lui manquait la déclaration.

   Attention : une rangée flex ne suit pas text-align, ses éléments l'ignorent. Il lui
   faut justify-center (cf. les tuiles du journal d'audit). */
.text-center {
    text-align: center;
}

.text-right {
    text-align: right;
}

/* Carrousel de photos d'un bien.

   « contain » et non « cover » : une photo de facture ou d'étiquette recadrée perdrait
   justement ce qu'on cherche à y lire. Le fond neutre comble le format restant. */
.epn-carrousel-photos {
    border-radius: var(--mud-default-borderradius);
    overflow: hidden;
}

.epn-carrousel-image {
    width: 100%;
    height: 100%;
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    background-color: var(--mud-palette-background-gray);
}

@media (max-width: 599.98px) {
    /* Un carrousel de 320 px prendrait 40 % de l'écran d'un téléphone. */
    .epn-carrousel-photos {
        height: 220px !important;
    }
}

/* Aperçu d'un document. Beaucoup de navigateurs mobiles refusent d'afficher un PDF
   dans une iframe : le cadre reste vide. On le réduit donc sur petit écran, pour que
   les informations et le bouton de téléchargement restent atteignables sans défiler. */
.epn-apercu-document {
    width: 100%;
    height: 600px;
    border: 0;
}

@media (max-width: 599.98px) {
    .epn-apercu-document {
        height: 45vh;
    }
}

/* Enrôlement 2FA. Le QR est un SVG noir sur blanc : il lui faut son fond blanc même en
   thème sombre, faute de quoi les lecteurs perdent le contraste dont ils vivent.

   La taille n'est imposée que parce que le SVG porte un « viewBox » (cf. ConstruireQr) :
   il se réduit alors au lieu d'être rogné. Le fond et la marge appartiennent au cadre, non
   au SVG — un remplissage sur l'élément lui-même décalerait le dessin dans son viewport.

   « max-width » plutôt qu'une largeur ferme : sur un téléphone étroit, mieux vaut un code
   plus petit qu'un code qui déborde. */
.epn-qr {
    display: inline-block;
    background: #fff;
    padding: 12px;
    border-radius: var(--mud-default-borderradius);
    line-height: 0;
}

.epn-qr svg {
    display: block;
    width: 240px;
    max-width: min(240px, 60vw);
    height: auto;
}

/* Codes de secours : à recopier sans erreur, donc en chasse fixe et bien séparés. */
.epn-codes-secours {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.5rem;
}

.epn-codes-secours code {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 1rem;
    letter-spacing: 0.05em;
    padding: 0.4rem 0.6rem;
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-background-gray);
    text-align: center;
}

/* Bandeau d'erreur Blazor : MASQUÉ par défaut. Le runtime le passe en « display: block »
   lorsqu'une erreur non gérée survient. Sans cette règle, il s'affiche en permanence
   au bas de chaque page, sans mise en forme. */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    z-index: 2000;
    box-sizing: border-box;
    padding: 0.75rem 3rem 0.75rem 1.25rem;
    background: #b32121;
    color: #fff;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
}

#blazor-error-ui .reload {
    color: #fff;
    text-decoration: underline;
    margin-left: 0.5rem;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 1rem;
    top: 0.7rem;
}

/* ── Code à six chiffres (connexion, second facteur) ───────────────────────────
   Six cases plutôt qu'un champ : c'est la forme attendue partout ailleurs, et elle
   dit d'elle-même combien de chiffres sont demandés.

   Contrôles natifs, comme la case à cocher ci-dessus : la page est rendue en SSR
   statique — elle doit produire une réponse HTTP pour poser le cookie de session —
   donc aucun composant MudBlazor n'y réagirait au clavier. Les couleurs viennent du
   thème pour que l'ensemble reste cohérent en clair comme en sombre. */
.epn-otp {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
}

.epn-otp input {
    width: 3rem;
    height: 3.5rem;
    padding: 0;
    text-align: center;
    font-size: 1.5rem;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: var(--mud-default-borderradius);
    caret-color: var(--mud-palette-primary);
}

.epn-otp input:focus {
    outline: none;
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 1px var(--mud-palette-primary);
}

/* Les flèches des champs numériques n'ont pas de sens sur une case d'un seul chiffre. */
.epn-otp input::-webkit-outer-spin-button,
.epn-otp input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

@media (max-width: 400px) {
    .epn-otp input {
        width: 2.5rem;
        height: 3rem;
        font-size: 1.25rem;
    }
}
