﻿/* Polices de la marque Sedes : manuscrite pour le nom, serif élégante pour le
   reste. Elles sont déclarées dans le <head> de App.razor, et non par @import
   ici : un @import ne part en téléchargement qu'une fois cette feuille reçue et
   analysée, ce qui retarde d'autant l'affichage du texte. */

/* ==================================================================
   Sedes — thèmes
   Les pages utilisent uniquement ces variables : chaque thème les redéfinit.
   ================================================================== */
/* Thème par défaut « CasaMya » : or sur bleu nuit (couleurs du logo) */
/* « color-scheme » indique au navigateur sur quel fond il dessine ses propres
   widgets : sélecteur de date, cases à cocher natives, ascenseurs. Sans lui,
   le calendrier d'un <input type="date"> et son icône restent dessinés en
   clair, donc illisibles sur fond sombre — un cas qu'aucune règle de fond ou
   de bordure ne peut rattraper, ces parties n'étant pas stylables.

   La valeur est posée sur CHAQUE thème, jamais par défaut : « casa », le thème
   initial, est sombre, alors qu'« ocean », « emeraude » et « sunset » sont
   clairs. Se fier à :root ferait donc l'inverse de ce qu'il faut pour la
   majorité des visiteurs. Ces sélecteurs ciblent tous <html> et ont la même
   spécificité : c'est l'ordre d'écriture qui tranche, d'où la déclaration
   répétée. */
:root, [data-theme="casa"] {
    color-scheme: dark;
    --accent: #c9a24b;
    --accent-2: #e6c583;
    /* Alias historiques utilisés dans les styles en ligne des pages. « --bleu »
       n'y sert QUE de couleur de texte (liens) : il suit donc --accent-texte,
       pas --accent, sans quoi ces liens échapperaient à la correction de
       contraste appliquée aux thèmes clairs. */
    --bleu: #c9a24b;
    --bleu-fonce: #e6c583;
    --bleu-clair: #232a3d;
    --fond: #12161f;
    --carte: #1c2230;
    --texte: #ede9df;
    --gris: #9aa1b2;
    --gris-clair: #232a3d;
    --bord: #2f3648;
    --vert: #6bbf7a;
    --vert-fond: #17281c;
    --orange: #e0a94b;
    --orange-fond: #2e2410;
    --rouge: #e5736b;
    /* Encre posée sur un aplat de rouge, comme --sur-accent l'est sur
       l'accent. Le rouge varie d'un thème à l'autre : du blanc sur ce
       rouge clair tomberait à 3,2:1, sous le seuil WCAG AA. */
    --sur-rouge: #2a0d0b;
    --rouge-fond: #2f1717;
    --topbar: #10131b;
    --topbar-texte: #cbb98d;
    --degrade: linear-gradient(135deg, #c9a24b, #e6c583);
    --ombre: 0 1px 3px rgba(0, 0, 0, 0.4);
    --ombre-forte: 0 14px 34px rgba(201, 162, 75, 0.22);
    /* Variante de l'accent réservée au TEXTE posé sur un fond de carte. Sur les
       thèmes sombres l'accent est déjà assez contrasté : la valeur est identique.
       Sur les thèmes clairs elle est assombrie — même teinte, luminosité réduite —
       pour atteindre les 4,5:1 exigés d'un texte courant. */
    --accent-texte: #c9a24b;
    /* Couleur du texte posé SUR un aplat d'accent (bouton principal, badge de
       rôle, onglet actif, pastille « i »). Le blanc sur l'or ne donnait que
       1,66:1 : c'est le bleu nuit de la marque qui sert d'encre. */
    --sur-accent: #10131b;
    /* Bordure des zones de saisie. « --bord » (1,3:1) ne suffit pas à délimiter
       un champ : la WCAG demande 3:1 pour les contours qui identifient un
       contrôle. Même famille neutre que --gris, éclaircie jusqu'au seuil. */
    --bord-champ: #636c81;
}

[data-theme="ocean"] {
    color-scheme: light;
    --accent: #2563eb;
    --accent-2: #7c3aed;
    --bleu: #1a5bea;             /* alias historiques utilisés dans les pages */
    --bleu-fonce: #1e3a8a;
    --bleu-clair: #eff6ff;
    --fond: #f1f5f9;
    --carte: #ffffff;
    --texte: #0f172a;
    /* Gris et couleurs d'état assombris (teinte inchangée) : les valeurs
       précédentes tombaient sous 4,5:1 sur les fonds très clairs de ce thème
       — #64748b/#f1f5f9 = 4,34, #16a34a/#f0fdf4 = 3,15, #ea580c/#fff7ed = 3,35. */
    --gris: #617187;
    --gris-clair: #f1f5f9;
    --bord: #e2e8f0;
    --vert: #11803a;
    --vert-fond: #f0fdf4;
    --orange: #c0480a;
    --orange-fond: #fff7ed;
    --rouge: #d82323;
    --sur-rouge: #ffffff;
    --rouge-fond: #fef2f2;
    --topbar: #0f172a;
    --topbar-texte: #cbd5e1;
    --degrade: linear-gradient(135deg, #2563eb, #7c3aed);
    --ombre: 0 1px 3px rgba(15, 23, 42, 0.07);
    --ombre-forte: 0 14px 34px rgba(37, 99, 235, 0.18);
    --accent-texte: #1a5bea;
    --sur-accent: #ffffff;
    --bord-champ: #8795a9;
}

[data-theme="emeraude"] {
    color-scheme: light;
    --accent: #059669;
    /* Assombri (même teinte) : seul usage réel, le titre des champs de
       formulaire, qui plafonnait à 3,74:1 sur une carte blanche. */
    --accent-2: #0c8479;
    --bleu: #047653;
    --bleu-fonce: #065f46;
    --bleu-clair: #ecfdf5;
    --fond: #f0fdf4;
    --carte: #ffffff;
    --texte: #052e16;
    --gris: #6b7280;
    --gris-clair: #f0fdf4;
    --bord: #d1fae5;
    /* Ce thème CLAIR ne redéfinissait aucune couleur d'état : il héritait donc
       de « casa », un thème SOMBRE. Le résultat était illisible — une alerte
       d'erreur affichait du texte #052e16 sur un fond #2f1717, soit 1,12:1, et
       l'encart viager 1,02:1. Mêmes teintes que les valeurs héritées, portées
       en version claire. */
    --vert: #11803a;
    --vert-fond: #f0fdf4;
    --orange: #c0480a;
    --orange-fond: #fff7ed;
    --rouge: #d82323;
    --sur-rouge: #ffffff;
    --rouge-fond: #fef2f2;
    --topbar: #064e3b;
    --topbar-texte: #a7f3d0;
    --degrade: linear-gradient(135deg, #059669, #0d9488);
    /* Même oubli pour l'ombre : celle de « casa » est un noir à 40 %, très
       lourd sur des cartes blanches. */
    --ombre: 0 1px 3px rgba(5, 46, 22, 0.08);
    --ombre-forte: 0 14px 34px rgba(5, 150, 105, 0.18);
    --accent-texte: #047653;
    --sur-accent: #031a0c;
    --bord-champ: #8e94a0;
}

[data-theme="sunset"] {
    color-scheme: light;
    --accent: #ea580c;
    --accent-2: #db2777;
    --bleu: #b24309;
    --bleu-fonce: #9a3412;
    --bleu-clair: #fff7ed;
    --fond: #fffbf5;
    --carte: #ffffff;
    --texte: #431407;
    /* Assombri d'un cheveu : #78716c ne donnait que 4,43:1 sur le gris clair. */
    --gris: #766f6b;
    --gris-clair: #faf5f0;
    --bord: #fed7aa;
    --orange: #b45309;
    --orange-fond: #fef3c7;
    /* Comme « emeraude », ce thème clair héritait du vert et du rouge SOMBRES
       de « casa » : une alerte d'erreur tombait à 1,07:1. Teintes conservées,
       versions claires. */
    --vert: #11803a;
    --vert-fond: #f0fdf4;
    --rouge: #d82323;
    --sur-rouge: #ffffff;
    --rouge-fond: #fef2f2;
    --topbar: #431407;
    --topbar-texte: #fed7aa;
    --degrade: linear-gradient(135deg, #ea580c, #db2777);
    --ombre: 0 1px 3px rgba(67, 20, 7, 0.08);
    --ombre-forte: 0 14px 34px rgba(234, 88, 12, 0.2);
    --accent-texte: #b24309;
    --sur-accent: #030100;
    --bord-champ: #9a938f;
}

[data-theme="nuit"] {
    color-scheme: dark;
    --accent: #60a5fa;
    --accent-2: #a78bfa;
    --bleu: #60a5fa;
    --bleu-fonce: #bfdbfe;
    --bleu-clair: #1e293b;
    --fond: #0b1120;
    --carte: #16203a;
    --texte: #e2e8f0;
    --gris: #94a3b8;
    --gris-clair: #1e293b;
    --bord: #2c3a55;
    --vert: #4ade80;
    --vert-fond: #14291c;
    --orange: #fdba74;
    --orange-fond: #33210f;
    --rouge: #f87171;
    --sur-rouge: #2a0d0b;
    --rouge-fond: #331414;
    --topbar: #060b16;
    --topbar-texte: #94a3b8;
    --degrade: linear-gradient(135deg, #3b82f6, #8b5cf6);
    --ombre: 0 1px 3px rgba(0, 0, 0, 0.4);
    --ombre-forte: 0 14px 34px rgba(0, 0, 0, 0.5);
    --accent-texte: #60a5fa;
    --sur-accent: #070b16;
    --bord-champ: #5a6d87;
}

/* ==================================================================
   Base
   ================================================================== */
* { box-sizing: border-box; }

/* Base agrandie : toutes les tailles en rem grandissent proportionnellement */
html { font-size: 18px; }

html, body {
    margin: 0;
    /* « Noto Color Emoji » (sous-ensemble drapeaux, chargé dans App.razor) en
       fin de pile : Windows n'affiche pas les drapeaux 🇫🇷 nativement. */
    font-family: "Segoe UI", system-ui, -apple-system, Arial, sans-serif, "Noto Color Emoji";
    background: var(--fond);
    color: var(--texte);
}

body { font-size: 1rem; }

h1:focus { outline: none; }
a { color: var(--accent-texte); }

/* ==================================================================
   Nom de la marque
   Partout où « Sedes » est écrit, le mot reprend la police du logo.
   Seule la police change : la couleur reste celle du texte environnant.
   ================================================================== */
.nom-marque {
    font-family: 'Dancing Script', 'Segoe Script', 'Brush Script MT', cursive;
    font-weight: 700;
    /* Les polices manuscrites paraissent plus petites : léger rattrapage. */
    font-size: 1.12em;
    letter-spacing: 0.3px;
    color: inherit;
}

/* ==================================================================
   Barre du haut
   ================================================================== */
.topbar {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    /* Gap vertical (entre les deux lignes) réduit ; gap horizontal conservé. */
    gap: 0.35rem 1.5rem;
    padding: 0.5rem 1.75rem;
    background: var(--topbar);
    flex-wrap: wrap;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
}

.brand {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    /* 1,35rem plus bas dans le fichier n'a jamais servi : une seconde règle
       « .brand { font-size: 1.6rem } », de même spécificité mais écrite après,
       l'écrasait silencieusement. Les deux sont fusionnées ici. */
    font-size: 1.6rem;
    font-weight: 800;
    color: white;
    text-decoration: none;
    letter-spacing: -0.5px;
    /* La marque peut se compresser (devise tronquée) plutôt que de pousser
       le menu ☰ à la ligne sur les petits écrans. */
    min-width: 0;
}

.brand .logo {
    width: 76px;
    height: 76px;
    flex: 0 0 auto;
    object-fit: contain;
    /* Logo à fond transparent : ombre portée qui épouse la forme
       (drop-shadow) plutôt qu'un carré (box-shadow). */
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
}

/* Bloc marque : nom centré au-dessus de la devise */
.brand-bloc {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    line-height: 1.15;
    min-width: 0;
}

.brand-texte {
    white-space: nowrap;
    font-family: 'Dancing Script', 'Segoe Script', 'Brush Script MT', cursive;
    font-weight: 700;
    font-size: 2.35rem;
    letter-spacing: 0.5px;
    line-height: 1.05;
}

.brand-accent {
    background: var(--degrade);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.brand-devise {
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.6px;
    color: var(--topbar-texte);
    white-space: nowrap;
    /* Tronquée avec « … » quand la place manque, au lieu de déborder. */
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

.brand span {
    background: var(--degrade);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.topbar nav {
    display: flex;
    gap: 0.2rem;
    flex-wrap: wrap;
    align-items: center;
    /* Deuxième ligne de l'entête : les onglets passent sous le logo et la
       zone utilisateur (ordre supérieur + pleine largeur pour forcer le retour). */
    order: 1;
    flex-basis: 100%;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.topbar nav a {
    color: var(--topbar-texte);
    text-decoration: none;
    padding: 0.42rem 0.85rem;
    border-radius: 999px;
    font-size: 0.92rem;
    transition: background 0.15s, color 0.15s;
}

.topbar nav a:hover { background: rgba(255, 255, 255, 0.1); color: white; }
.topbar nav a.active { background: var(--degrade); color: var(--sur-accent); font-weight: 600; }

/* Onglet « Mon suivi » sous forme de menu déroulant. */
.nav-dropdown { position: relative; display: inline-flex; }

.nav-lien-bouton {
    color: var(--topbar-texte);
    background: transparent;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.92rem;
    padding: 0.42rem 0.85rem;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s;
}
.nav-lien-bouton:hover { background: rgba(255, 255, 255, 0.1); color: white; }

.nav-voile { position: fixed; inset: 0; z-index: 90; }

.nav-sousmenu {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 100;
    min-width: 220px;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 12px;
    box-shadow: var(--ombre-forte);
    padding: 6px;
    display: flex; flex-direction: column;
}

/* Sélecteur préfixé par « .topbar nav » : sans cela la règle générale
   « .topbar nav a » (plus spécifique) imposerait la couleur claire de la barre
   de navigation à un sous-menu qui, lui, est posé sur un fond de carte. */
.topbar nav .nav-sousmenu a {
    padding: 9px 12px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--texte);
    background: transparent;
    font-weight: 600;
    font-size: 0.92rem;
    /* Chaque entrée tient sur une seule ligne : le menu s'élargit si besoin. */
    white-space: nowrap;
}

.topbar nav .nav-sousmenu a:hover { background: var(--gris-clair); color: var(--texte); }

/* Sépare les écrans de réglage des sections de « Mes paramètres ». */
.nav-sousmenu-separateur { height: 1px; background: var(--bord); margin: 6px 4px; }

/* Zone utilisateur + menu ☰, d'un seul tenant, poussés à droite. Trop étroit ?
   Le bloc entier passe à la ligne — son margin-left:auto le maintient à
   droite : le menu ☰ tombe sous le bouton de déconnexion, et son menu
   déroulant (ancré à droite) reste dans l'écran. */
.zone-droite {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-left: auto;
    min-width: 0;
}

.zone-user {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    justify-content: flex-end;
    /* Compressible (le pseudo se tronque) : le menu ☰ reste sur la ligne. */
    min-width: 0;
}

.pseudo {
    color: white;
    font-size: 0.88rem;
    font-weight: 600;
    /* Un nom long se tronque au lieu de pousser le menu ☰ hors de la ligne. */
    max-width: clamp(5rem, 24vw, 14rem);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.badge-role {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: var(--degrade);
    color: var(--sur-accent);
    font-weight: 700;
}

/* État du compte agent (icône ✔ / ⛔) : cliquable, mène à l'onglet abonnement. */
.badge-etat-compte {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    font-size: 0.8rem;
    text-decoration: none;
}
.badge-etat-compte.etat-actif { background: var(--vert-fond); color: var(--vert); }
.badge-etat-compte.etat-inactif { background: var(--rouge-fond); color: var(--rouge); }
.badge-etat-compte:hover { filter: brightness(1.2); text-decoration: none; }

/* Bouton de déconnexion, réduit à son icône. */
.btn-deconnexion {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem 0.5rem;
}
.btn-deconnexion svg { display: block; }

/* Bouton de visite guidée, poussé tout à droite de la ligne d'onglets. */
.nav-visite {
    margin-inline-start: auto;
    background: none;
    border: 1px solid color-mix(in srgb, var(--topbar-texte) 35%, transparent);
    color: var(--topbar-texte);
    padding: 0.35rem 0.8rem;
    border-radius: 999px;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.nav-visite:hover { background: rgba(255, 255, 255, 0.1); color: white; }

/* ------------------------------------------------------------------
   Visite guidée : voile, trou de lumière et bulle d'explication.
   Le voile attrape les clics ; l'assombrissement vient du box-shadow
   géant du trou, qui laisse la cible en pleine lumière.
   ------------------------------------------------------------------ */
.visite-voile { position: fixed; inset: 0; z-index: 4000; }

.visite-trou {
    position: absolute;
    z-index: 4001;
    border-radius: 10px;
    pointer-events: none;
    border: 2px solid var(--accent);
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.55);
}

.visite-bulle {
    position: absolute;
    z-index: 4002;
    width: min(340px, calc(100vw - 24px));
    background: var(--carte);
    color: var(--texte);
    border: 1px solid var(--bord);
    border-radius: 14px;
    padding: 1rem 1.1rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
}

.visite-titre { font-weight: 700; margin-bottom: 0.4rem; }
.visite-texte { font-size: 0.9rem; line-height: 1.5; }

.visite-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    justify-content: flex-end;
    margin-top: 0.8rem;
}

.visite-compteur {
    margin-inline-end: auto;
    font-size: 0.78rem;
    color: var(--gris);
}

/* Choix de notification : la case, l'intitulé et son explication sur une
   ligne cliquable entière — viser une case de 13 px au doigt est pénible. */
.choix-notif {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--bord);
    cursor: pointer;
}
.choix-notif:last-of-type { border-bottom: none; }
.choix-notif input { margin-top: 0.2rem; flex: 0 0 auto; }
.choix-notif span { display: flex; flex-direction: column; gap: 0.15rem; }
.choix-notif small { color: var(--gris); font-size: 0.85rem; line-height: 1.35; }

/* Compteur d'anomalies accolé à un titre de section : il doit accrocher
   l'œil sans hurler, l'information étant déjà rouge dans le tableau. */
.badge-alerte {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: var(--rouge-fond);
    color: var(--rouge);
    font-size: 0.75rem;
    font-weight: 600;
    vertical-align: middle;
}

.pastille {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.55);
    cursor: pointer;
    padding: 0;
    transition: transform 0.15s, border-color 0.15s;
}

.pastille:hover { transform: scale(1.25); border-color: white; }

/* ==================================================================
   Structure
   ================================================================== */
.page {
    /* Pleine largeur avec une petite marge de respiration de chaque côté. */
    max-width: none;
    margin: 0 auto;
    padding: 0 1.2rem 4rem;
}

/* Le pied de page est posé sur « --topbar », pas sur le fond de la page :
   c'est donc « --topbar-texte » qui lui convient, pas « --gris ». Ce dernier
   est calibré pour un fond de carte et tombait à 2,01:1 sur le vert foncé du
   thème « emeraude », 3,26:1 sur « sunset » et 3,75:1 sur « ocean ». */
.footer {
    background: var(--topbar);
    border-top: 1px solid var(--bord);
    margin-top: 3rem;
    color: var(--topbar-texte);
    font-size: 0.88rem;
}

.footer-contenu {
    max-width: none;
    margin: 0 auto;
    padding: 2.2rem 1.2rem 1.6rem;
    display: grid;
    /* Marque, puis Informations (plus large : coordonnées), Ressources,
       Clients et Professionnels. */
    grid-template-columns: 1.5fr 1.4fr 1.1fr 1fr 1fr;
    gap: 2rem;
}

@media (max-width: 1100px) {
    .footer-contenu { grid-template-columns: 1fr 1fr 1fr; }
}

@media (max-width: 820px) {
    .footer-contenu { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 520px) {
    .footer-contenu { grid-template-columns: 1fr; }
}

.footer-marque { display: flex; flex-direction: column; gap: 0.15rem; }

.footer-logo {
    font-family: 'Dancing Script', 'Segoe Script', 'Brush Script MT', cursive;
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    line-height: 1.15;
    background: var(--degrade);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.footer-devise {
    font-size: 0.75rem;
    letter-spacing: 0.6px;
    color: var(--topbar-texte);
}

.footer-marque p { margin: 0.7rem 0 0; line-height: 1.55; }

.footer-colonne { display: flex; flex-direction: column; gap: 0.45rem; }

/* L'accent pur ne tenait pas sur le fond sombre de la barre (2,58:1 sur
   « emeraude ») : on l'éclaircit vers le blanc — la teinte, elle, ne bouge pas. */
.footer-colonne h4 {
    margin: 0 0 0.35rem;
    font-size: 0.92rem;
    letter-spacing: 0.4px;
    color: color-mix(in srgb, var(--accent) 55%, white);
}

.footer-colonne a {
    color: var(--topbar-texte);
    text-decoration: none;
    transition: color 0.12s;
}

/* Le survol doit ÉCLAIRCIR : « --texte » est presque noir sur les thèmes
   clairs, donc invisible sur la barre sombre du pied de page. */
.footer-colonne a:hover { color: #ffffff; }

/* Pictogramme devant chaque lien du pied de page : largeur fixe pour que les
   libellés restent alignés en colonne quel que soit l'émoji. */
.footer-picto {
    display: inline-block; width: 1.5em; margin-right: 0.15rem;
    text-align: center; font-size: 0.95em;
}

/* ------------------------------------------------------------------
   Pictogrammes au trait (composant Icone)
   ------------------------------------------------------------------
   Trois tailles, une par emplacement. Toutes héritent de « currentColor » :
   sur un onglet actif, le dessin passe donc avec le texte en couleur
   d'accentuation, sans règle supplémentaire.

   « vertical-align: -0.18em » plutôt que « middle » : un SVG carré aligné au
   milieu de la ligne flotte au-dessus de la base des lettres. Ce léger
   décalage le pose sur la même ligne d'écriture que le texte.
   ------------------------------------------------------------------ */
.ico-nav, .ico-menu, .ico-titre {
    flex: 0 0 auto;
    vertical-align: -0.18em;
    margin-right: 0.42rem;
}

/* Onglets de la barre du haut : à la taille du texte, dans le doré adouci des
   icônes de coordonnées du pied de page — c'est la teinte qui fait la couleur
   du site sur fond sombre. */
.ico-nav { width: 1.05rem; height: 1.05rem; }

.topbar nav a .ico-nav,
.topbar nav .nav-lien-bouton .ico-nav,
.topbar nav .nav-visite .ico-nav {
    color: color-mix(in srgb, var(--accent) 55%, white);
}

/* Onglet actif : le fond est doré, une icône dorée y disparaîtrait. Elle
   reprend donc la couleur du libellé. Même chose au survol, où le fond
   s'éclaircit. */
.topbar nav a.active .ico-nav { color: inherit; }
.topbar nav a:hover .ico-nav,
.topbar nav .nav-lien-bouton:hover .ico-nav,
.topbar nav .nav-visite:hover .ico-nav { color: #ffffff; }

/* Entrées de menu (☰ et sous-menus) : la même taille, mais colorée en
   accentuation — le menu est posé sur un fond de carte, pas sur la barre
   sombre, et un trait gris s'y perdrait. */
.ico-menu {
    width: 1.1rem; height: 1.1rem;
    color: var(--accent);
}

/* Titres de colonne du pied de page : suit la couleur du titre (h4). */
.ico-titre { width: 1.05rem; height: 1.05rem; }

/* Les onglets et les entrées de menu portent un pictogramme suivi d'un
   libellé : les deux doivent rester sur une ligne, alignés verticalement. */
.topbar nav a, .topbar nav .nav-lien-bouton, .topbar nav .nav-visite,
.topbar nav .nav-sousmenu a, .burger-item, .footer-colonne h4 {
    display: inline-flex;
    align-items: center;
}

/* Le pied de page empile ses entrées : son titre reste un bloc de la colonne,
   pas un élément en ligne. (Les entrées du menu ☰ sont traitées avec leur
   propre règle, plus bas — déclarée après celle-ci, elle gagnerait.) */
.footer-colonne h4 { display: flex; }

/* ------------------------------------------------------------------
   Pied de page — colonne « Informations »
   Coordonnées (email, téléphone) et logos officiels des réseaux sociaux.
   ------------------------------------------------------------------ */
.footer-info {
    display: flex;
    align-items: center;
    /* Pas de « gap » : l'espace vient de la gouttière fixe du pictogramme
       (« footer-picto »), la même que dans les trois autres colonnes — sans
       quoi les libellés de cette colonne seraient décalés de 0,5 rem. */
    color: var(--topbar-texte);
    text-decoration: none;
    /* Une adresse email longue ne doit pas déborder de la colonne. */
    overflow-wrap: anywhere;
}

a.footer-info:hover { color: #ffffff; }

/* Ancienne classe des pictogrammes de cette colonne, quand ils étaient des
   SVG au trait. Conservée pour un contenu administrable qui l'emploierait
   encore ; les coordonnées, elles, portent désormais « footer-picto ». */
.footer-ico {
    width: 1.05rem;
    height: 1.05rem;
    flex: 0 0 auto;
    color: color-mix(in srgb, var(--accent) 55%, white);
}

.footer-reseaux-titre { margin-top: 0.35rem; line-height: 1.35; }

.footer-reseaux {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.15rem;
    /* Aligné sous le texte de la ligne « Rejoignez-nous… ». */
    padding-left: 1.55rem;
}

.footer-reseau {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    border: 1px solid var(--bord);
    color: var(--topbar-texte);
    text-decoration: none;
    transition: color 0.12s, border-color 0.12s, transform 0.12s;
}

.footer-reseau svg { width: 1.05rem; height: 1.05rem; }

/* Au survol, le logo reprend la couleur officielle de la marque. */
.footer-reseau:hover {
    color: var(--couleur-reseau, var(--accent));
    border-color: var(--couleur-reseau, var(--accent));
    transform: translateY(-2px);
}

.footer-bas {
    border-top: 1px solid var(--bord);
    text-align: center;
    padding: 1rem 1.5rem;
    font-size: 0.78rem;
    color: var(--topbar-texte);
}

/* ==================================================================
   Simulateur de crédit immobilier
   ================================================================== */
.simulateur { display: flex; flex-direction: column; gap: 1.2rem; }

/* Phrase d'introduction d'une section de formulaire. */
.aide-section {
    margin: -0.4rem 0 1rem;
    color: var(--gris);
    font-size: 0.88rem;
    line-height: 1.55;
}

/* Un champ à choix peut faire apparaître une saisie libre en dessous :
   les deux contrôles doivent rester lisiblement groupés. */
.champ select + input { margin-top: 0.4rem; }

/* ------------------------------------------------------------------
   Formulaire du simulateur : un critère par ligne.
   Le champ à gauche, son explication à droite — on lit le libellé, on
   saisit, et l'explication est là sans qu'il faille la chercher.
   ------------------------------------------------------------------ */
.simu-criteres { display: flex; flex-direction: column; }

/* Chaque critère occupe une ligne : libellé puis saisie en colonne de gauche,
   explication en colonne de droite. */
.simu-criteres > .champ {
    display: grid;
    grid-template-columns: minmax(15rem, 22rem) 1fr;
    /* Trois rangées explicites : libellé, liste de choix, saisie libre
       éventuelle. Sans elles, une explication placée « jusqu'à la dernière
       rangée » ne couvrirait en fait qu'une seule rangée. */
    grid-template-rows: repeat(3, auto);
    column-gap: 1.5rem;
    row-gap: 0.3rem;
    align-items: start;
    padding: 1rem 0;
    border-top: 1px solid var(--bord);
}

.simu-criteres > .champ:first-child { border-top: none; padding-top: 0.2rem; }

/* L'écart entre la liste de choix et la saisie libre qu'elle révèle est déjà
   assuré par row-gap : la marge générique ferait double emploi. */
.simu-criteres > .champ select + input { margin-top: 0; }

/* Libellé et champs de saisie restent à gauche… */
.simu-criteres > .champ > * { grid-column: 1; }

/* …et l'explication commence à la deuxième rangée, c'est-à-dire à la hauteur
   du champ de saisie et non à celle du libellé : l'œil relie ainsi directement
   le contrôle à son explication. */
.simu-criteres > .champ > .simu-explication {
    grid-column: 2;
    grid-row: 2 / -1;
    align-self: start;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--gris);
}

.simu-explication b { color: var(--texte); }

@media (max-width: 760px) {
    .simu-criteres > .champ { grid-template-columns: 1fr; }
    .simu-criteres > .champ > .simu-explication { grid-column: 1; grid-row: auto; }
}

/* ------------------------------------------------------------------
   Rangée de champs précédée d'une icône thématique (Mes paramètres).
   ------------------------------------------------------------------ */
.rangee {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1.2rem;
}

.rangee-icone {
    flex: 0 0 auto;
    font-size: 1.5rem;
    line-height: 1;
    /* Aligné sur les champs, sous la ligne des libellés. */
    padding-top: 1.6rem;
}

/* Les champs se répartissent toute la largeur restante et se replient
   d'eux-mêmes sur les écrans étroits. */
.rangee-champs {
    flex: 1 1 auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 1rem;
    min-width: 0;
}

/* Un champ qui mérite plus de place que ses voisins (adresse postale). */
.rangee-champs .champ-large { grid-column: span 2; }

/* Rangée d'adresse : pays, adresse, code postal, ville — quatre champs qui
   doivent tenir sur UNE ligne. À 13 rem de piste minimale, la grille n'en
   offrait pas assez de colonnes pour les six parts demandées (l'adresse et la
   ville en valent deux chacune) : la ville passait seule à la ligne suivante.
   9 rem suffisent amplement — un code postal fait cinq chiffres, un nom de pays
   tient dans une liste déroulante — et « auto-fit » réduit les pistes vides à
   zéro, si bien que les champs s'étalent ensuite sur toute la largeur au lieu
   de rester à 9 rem. Le repli sur écran étroit reste celui de la règle
   générale : sous 620 px, « champ-large » perd son span et tout s'empile. */
.rangee-champs.rangee-adresse { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }

@media (max-width: 620px) {
    .rangee-icone { display: none; }
    .rangee-champs .champ-large { grid-column: auto; }
}

/* ------------------------------------------------------------------
   Formulaire sur une ligne : champs à gauche, boutons au bout.
   ------------------------------------------------------------------ */
.ligne-formulaire {
    display: flex;
    gap: 1.2rem;
    flex-wrap: wrap;
}

.ligne-champs {
    flex: 1 1 30rem;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 1rem;
    min-width: 0;
}

/* Les champs se calent sur le bas de leur cellule (« .champ » aligne son
   contenu en fin de colonne) : les boutons font de même, et se retrouvent donc
   exactement sur la même ligne que les zones de saisie, quelle que soit la
   hauteur des libellés. */
.ligne-actions {
    flex: 0 0 auto;
    align-self: flex-end;
    display: flex;
    gap: 0.6rem;
}

@media (max-width: 620px) {
    .ligne-actions { width: 100%; }
    .ligne-actions .btn { flex: 1 1 auto; }
}

/* Boutons d'une fenêtre modale. */
.modal-actions {
    display: flex;
    gap: 0.6rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1rem;
}

/* Bandeau des quatre chiffres clés. */
.simu-resume {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
}

.simu-chiffre {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1.1rem 1.2rem;
    border: 1px solid var(--bord);
    border-radius: 14px;
    background: var(--carte);
}

/* La mensualité est le chiffre que l'on vient chercher : elle domine. */
.simu-chiffre-principal {
    border-color: var(--accent);
    box-shadow: var(--ombre-forte);
}

.simu-chiffre-alerte { border-color: var(--rouge); background: var(--rouge-fond); }

.simu-libelle {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--gris);
}

.simu-valeur {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: 1.7rem;
    font-weight: 800;
    line-height: 1.15;
    color: var(--accent);
}

.simu-chiffre-principal .simu-valeur { font-size: 2.1rem; }
.simu-chiffre-alerte .simu-valeur { color: var(--rouge); }
.simu-detail { font-size: 0.8rem; color: var(--gris); line-height: 1.4; }

.simu-colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 1.2rem;
    align-items: start;
}

/* Tableaux chiffrés : montants alignés à droite pour comparer les ordres de grandeur. */
.tableau-simu { width: 100%; }
.tableau-simu .montant { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tableau-simu .montant-negatif { color: var(--vert); }

.tableau-simu .ligne-detail td {
    padding-left: 1.6rem;
    font-size: 0.85rem;
    color: var(--gris);
}

.tableau-simu .ligne-total td {
    border-top: 2px solid var(--bord);
    font-weight: 700;
    color: var(--texte);
}

.tableau-simu .cellule-detail { background: var(--fond); padding: 0.5rem; }

/* Jauge du taux d'endettement, avec le repère des 35 %. */
.jauge-endettement { margin: 0.6rem 0 1rem; }

.jauge-piste {
    position: relative;
    height: 1.1rem;
    border-radius: 999px;
    background: var(--gris-clair);
    border: 1px solid var(--bord);
    overflow: hidden;
}

.jauge-remplissage { height: 100%; border-radius: 999px; transition: width 0.2s; }
.jauge-verte { background: var(--vert); }
.jauge-rouge { background: var(--rouge); }

/* Trait vertical marquant le plafond recommandé. */
.jauge-seuil {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--texte);
    opacity: 0.75;
}

.jauge-legende {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-top: 0.4rem;
    font-size: 0.82rem;
    color: var(--gris);
}

.jauge-legende b { font-size: 1.1rem; }
.texte-alerte { color: var(--rouge); }
.texte-ok { color: var(--vert); }

.simu-mentions {
    font-size: 0.76rem;
    line-height: 1.55;
    color: var(--gris);
    border-top: 1px solid var(--bord);
    padding-top: 0.9rem;
    margin: 0;
}

/* ==================================================================
   Grille tarifaire des abonnements
   ================================================================== */
.grille-tarifs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1.2rem;
    margin-bottom: 1.5rem;
}

.carte-tarif {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1.5rem 1.3rem 1.3rem;
    border: 1px solid var(--bord);
    border-radius: 14px;
    background: var(--carte);
}

/* La formule recommandée se distingue par sa bordure, pas par sa couleur de
   fond : les prix restent tous aussi lisibles les uns que les autres. */
.carte-tarif-avant {
    border: 2px solid var(--accent);
    box-shadow: var(--ombre-forte);
}

.etiquette-tarif {
    position: absolute;
    top: -0.7rem;
    left: 1.3rem;
    padding: 0.15rem 0.7rem;
    border-radius: 999px;
    background: var(--accent);
    color: var(--sur-accent);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.3px;
}

.carte-tarif h3 { margin: 0; font-size: 1.15rem; }
.tarif-duree { margin: 0; font-size: 0.82rem; color: var(--gris); }

.tarif-prix {
    margin: 0.5rem 0 0;
    font-family: 'Playfair Display', Georgia, serif;
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--accent);
}

.tarif-prix small { font-size: 0.85rem; font-weight: 400; color: var(--gris); }
.tarif-detail { margin: 0; font-size: 0.82rem; color: var(--gris); }

.tarif-description {
    margin: 0.5rem 0 0;
    font-size: 0.88rem;
    line-height: 1.5;
    flex: 1 1 auto;
}

/* Le bouton reste collé en bas de la carte, avec ou sans description :
   margin-top:auto absorbe tout l'espace restant de la colonne flex. */
.carte-tarif .btn { margin-top: auto; }
/* Garde un espace minimum entre le dernier texte et le bouton. */
.carte-tarif > :nth-last-child(2) { margin-bottom: 0.65rem; }

/* ------------------------------------------------------------------
   Impression de la fiche de virement : seule la fiche part sur papier.
   ------------------------------------------------------------------ */
@media print {
    .topbar, .footer, .no-print, .boutons-defilement { display: none !important; }

    .page { padding: 0 !important; }

    .card, .card-sensible {
        border: 1px solid #999 !important;
        box-shadow: none !important;
        break-inside: avoid;
    }
}

/* ==================================================================
   Accès global (section administrateur de « Mes paramètres »)
   ================================================================== */
.card-sensible { border: 1px solid var(--accent); }

.encart-mode-emploi {
    margin: 0.9rem 0;
    padding: 0.9rem 1.1rem;
    border-left: 3px solid var(--accent);
    border-radius: 0 10px 10px 0;
    background: var(--fond);
    line-height: 1.6;
}

.encart-mode-emploi ol { margin: 0.5rem 0; padding-left: 1.3rem; }
.encart-mode-emploi li { margin: 0.25rem 0; }

/* Champ de mot de passe accompagné de son bouton « Afficher ». */
.champ-secret { display: flex; gap: 0.5rem; align-items: stretch; }
.champ-secret input { flex: 1 1 auto; font-family: "Cascadia Code", Consolas, monospace; }
.champ-secret .btn { flex: 0 0 auto; white-space: nowrap; }

/* ------------------------------------------------------------------
   Mot de passe : l'œil qui le dévoile (Partage/ChampMotDePasse.razor)
   ------------------------------------------------------------------
   Le bouton est POSÉ SUR le champ, à droite, plutôt qu'à côté : la zone de
   saisie garde toute la largeur de la colonne, et rien ne passe à la ligne sur
   un écran étroit. La marge intérieure droite du champ lui réserve sa place —
   sans elle, un mot de passe long finirait sous le dessin. */
.champ-mdp { position: relative; display: block; }

/* « input[type] » et non « input » : la règle générale « .champ input » plus bas
   dans ce fichier pose « padding: 0.55rem 0.7rem » à specificité ÉGALE, et
   l'emporterait par sa position. Le sélecteur d'attribut fait pencher la
   balance sans avoir à déplacer quoi que ce soit. */
.champ-mdp input[type] { padding-right: 2.9rem; }

.oeil-mdp {
    position: absolute;
    top: 50%;
    right: 0.45rem;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    /* 2,25 rem ≈ 36 px : la cible tactile minimale recommandée (WCAG 2.5.8),
       alors que le dessin, lui, ne fait que 1,2 rem. */
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--gris);
    cursor: pointer;
    transition: color 0.15s, background-color 0.15s;
}

.oeil-mdp:hover { color: var(--texte); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.oeil-mdp:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ico-oeil { width: 1.2rem; height: 1.2rem; display: block; }

/* ==================================================================
   Éditeur de texte des pages de contenu (/admin/contenus)
   ================================================================== */
.editeur-visuel {
    min-height: 22rem;
    max-height: 40rem;
    overflow-y: auto;
    padding: 1rem 1.2rem;
    border: 1px solid var(--bord);
    border-radius: 10px;
    background: var(--carte);
    color: var(--texte);
    line-height: 1.7;
}

.editeur-visuel:focus { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Le rendu de la saisie reprend celui de la page publique, pour que
   l'administrateur voie exactement ce qu'il produit. */
.editeur-visuel h2 {
    font-size: 1.25rem;
    margin: 1.4rem 0 0.5rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--bord);
}

.editeur-visuel h3 { font-size: 1.08rem; margin: 1.1rem 0 0.35rem; }
.editeur-visuel p { margin: 0.6rem 0; }
.editeur-visuel ul, .editeur-visuel ol { margin: 0.6rem 0; padding-left: 1.4rem; }
.editeur-visuel li { margin: 0.3rem 0; }
.editeur-visuel a { color: var(--accent-texte); }
.editeur-visuel:empty::before { content: attr(data-vide); color: var(--gris); }

/* ==================================================================
   Back-office « Contenus du pied de page » (/admin/contenus)
   ================================================================== */
.aide {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    color: var(--gris);
    line-height: 1.45;
}

/* Aide d'une rangée : alignée sous les champs, pas sous l'icône.
   Déclarée après « .aide » pour en surcharger la marge haute. */
.rangee-aide { margin: -0.6rem 0 1.2rem 2.5rem; }

@media (max-width: 620px) {
    .rangee-aide { margin-left: 0; }
}

.actions-formulaire { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.9rem; }

.liste-pages { display: flex; flex-wrap: wrap; gap: 0.5rem; }

/* Une URL longue ne doit pas élargir le tableau. */
.cellule-url {
    max-width: 22rem;
    overflow-wrap: anywhere;
    color: var(--gris);
    font-size: 0.85rem;
}

.editeur-barre {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-bottom: 0.5rem;
}

/* Aperçu du logo reconnu automatiquement pour un réseau social. */
.apercu-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border: 1px solid var(--bord);
    border-radius: 50%;
    background: var(--topbar);
}

.apercu-logo svg { width: 1.3rem; height: 1.3rem; }
.apercu-logo-petit { width: 1.9rem; height: 1.9rem; }
.apercu-logo-petit svg { width: 1rem; height: 1rem; }

.apercu-pied {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 1rem 1.2rem;
    border-radius: 10px;
    background: var(--topbar);
    color: var(--gris);
    font-size: 0.88rem;
}

/* ==================================================================
   Pages institutionnelles (mentions légales, confidentialité, RGPD…)
   Contenu rédigé par l'administrateur : la mise en forme est définie ici,
   pas dans le texte saisi.
   ================================================================== */
.page-ressource {
    /* Pleine largeur, comme le reste du site (voir « .page ») : la colonne
       bridée — 52 rem à l'origine, puis 72 — laissait de larges bandes vides
       de chaque côté sur un écran d'ordinateur, alors que toutes les autres
       pages occupent l'espace disponible. Seul le rythme vertical reste ici ;
       les marges latérales sont celles de « .page », qui enveloppe cette
       page comme les autres. */
    margin: 0 auto;
    padding: 1.5rem 0 2rem;
}

.contenu-redactionnel {
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 14px;
    padding: 2rem 2.2rem;
    line-height: 1.7;
    /* Le corps de ces pages est saisi par l'administrateur : une URL entière,
       un IBAN, un SIRET ou une adresse tapée sans espace y passeront tôt ou
       tard. Sans coupure autorisée, un tel mot élargit la carte au-delà de
       l'écran et fait défiler TOUTE la page horizontalement — débordement
       silencieux, invisible sur ordinateur où la colonne fait 800 px, criant
       sur les 280 px d'un téléphone. « anywhere » plutôt que « break-word » :
       lui seul réduit aussi la largeur minimale de la boîte, ce qui compte dès
       que la carte est posée dans une grille.
       (Les tableaux, eux, ne peuvent pas déborder : NettoyageHtml n'autorise
       ni « table » ni « td » — un tableau collé par l'administrateur est
       réduit à son texte avant même d'atteindre la page.) */
    overflow-wrap: anywhere;
}

.contenu-redactionnel h1 {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: 2rem;
    margin: 0 0 1.4rem;
    color: var(--accent);
}

.contenu-redactionnel h2 {
    font-size: 1.25rem;
    margin: 2rem 0 0.6rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--bord);
    color: var(--texte);
}

.contenu-redactionnel h3 { font-size: 1.08rem; margin: 1.4rem 0 0.4rem; color: var(--texte); }
.contenu-redactionnel h4 { font-size: 1rem; margin: 1.1rem 0 0.3rem; color: var(--texte); }
.contenu-redactionnel p { margin: 0.7rem 0; }
.contenu-redactionnel ul, .contenu-redactionnel ol { margin: 0.7rem 0; padding-left: 1.4rem; }
.contenu-redactionnel li { margin: 0.35rem 0; }

.contenu-redactionnel blockquote {
    margin: 1rem 0;
    padding: 0.6rem 1rem;
    border-left: 3px solid var(--accent);
    background: var(--fond);
    border-radius: 0 8px 8px 0;
}

.contenu-redactionnel hr { border: none; border-top: 1px solid var(--bord); margin: 1.5rem 0; }

/* Pied de l'article : la date de mise à jour, puis le téléchargement PDF
   sous elle. Colonne alignée à gauche — le bouton suit le texte au lieu de
   le précéder en haut à droite. */
.contenu-pied {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.7rem;
    margin-top: 2rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--bord);
}

.contenu-maj {
    margin: 0;
    font-size: 0.82rem;
    color: var(--gris);
}

/* ------------------------------------------------------------------
   Téléphone : sur ces pages, qui ne sont QUE du texte, la largeur est tout.

   Le corps se lisait dans 228 px sur un écran de 360 : 37 % de la largeur
   partait en marges, et pas une marge large — TROIS gouttières de 1,2 rem
   empilées, celle de « .page », celle de « .page-ressource » et celle de la
   carte. Prises une à une elles semblent modestes ; mises bout à bout elles
   font 130 px. On garde celle de « .page » (qui détache la carte du bord de
   l'écran) et celle de la carte (qui détache le texte de son filet), on retire
   celle du milieu, qui ne sépare rien de rien. La colonne passe à 279 px, soit
   d'environ 25 caractères par ligne à un peu plus de 30 — encore loin des 45
   d'un texte suivi confortable, mais c'est tout ce qu'un téléphone peut donner.
   La taille du texte, elle, ne bouge pas : la racine est déjà à 18 px, et
   rétrécir des CGV pour gagner deux caractères par ligne serait un mauvais
   échange.

   Ce bloc est placé APRÈS toutes les règles de la section, et non près de
   « .page-ressource » : « .contenu-redactionnel h1 » est déclaré plus haut avec
   la même spécificité (0,1,1) — écrite avant lui, la réduction du titre serait
   restée lettre morte.
   ------------------------------------------------------------------ */
@media (max-width: 620px) {
    /* La gouttière du milieu disparaît ; le rythme vertical reste. */
    .page-ressource { padding: 1rem 0 1.5rem; }

    .contenu-redactionnel { padding: 1.35rem 1rem; }

    /* 2 rem = 36 px : « confidentialité » y mesure à lui seul près de 270 px,
       soit plus que la colonne n'en offrait. Le mot débordait — et avec le
       « overflow-wrap: anywhere » posé plus haut il se couperait désormais en
       plein milieu, ce qui est pire encore sur un titre. À 1,5 rem il tient. */
    .contenu-redactionnel h1 { font-size: 1.5rem; margin-bottom: 1rem; }

    /* Sur téléphone, le bouton garde ses proportions : l'étirer sur toute la
       largeur déformerait la carte du pictogramme. Sa hauteur dépasse déjà
       largement les 44 px que réclame une cible tactile. */
}

/* ==================================================================
   Héro
   ================================================================== */
.hero { text-align: center; padding: 2.25rem 1rem 0.75rem; }

.hero h1 {
    font-size: clamp(1.9rem, 4.5vw, 2.9rem);
    margin-top: 0;
    margin-bottom: 0.6rem;
    letter-spacing: -1px;
    line-height: 1.15;
}

.hero .accroche {
    background: var(--degrade);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.hero p { color: var(--gris); font-size: 1.08rem; max-width: 660px; margin: 0 auto; line-height: 1.6; }

/* Bloc éditorial du jour (SEO) : image + descriptif */
/* Bannière immersive : l'image occupe tout le bloc, le texte flotte par-dessus
   un dégradé — hauteurs toujours égales, avec animations (zoom lent « Ken Burns »,
   entrée du texte en cascade, badge doré scintillant). */
.hero-jour {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    /* Moitié de la hauteur d'écran : titre + image + descriptif + boutons visibles. */
    min-height: 50vh;
    border: 1px solid var(--bord);
    border-radius: 18px;
    margin: 0.5rem auto 0;
    max-width: none;
    box-shadow: var(--ombre);
    isolation: isolate;
}

.hero-jour-fond {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -2;
    animation: hero-zoom 22s ease-in-out infinite alternate;
}

@keyframes hero-zoom {
    from { transform: scale(1) translateX(0); }
    to   { transform: scale(1.1) translateX(-1.5%); }
}

/* Dégradé sombre à gauche pour la lisibilité du texte, quel que soit le thème. */
.hero-jour-voile {
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(90deg,
        rgba(10, 14, 25, 0.92) 0%,
        rgba(10, 14, 25, 0.85) 50%,
        rgba(10, 14, 25, 0.55) 78%,
        rgba(10, 14, 25, 0.05) 100%);
}

.hero-jour-contenu {
    position: relative;
    max-width: 1150px;
    padding: 2.4rem 2.6rem;
    color: #fff;
}

.hero-jour-contenu > * {
    opacity: 0;
    transform: translateY(16px);
    animation: hero-entree 0.7s ease forwards;
}

.hero-jour-contenu > *:nth-child(2) { animation-delay: 0.18s; }

@keyframes hero-entree {
    to { opacity: 1; transform: translateY(0); }
}

/* Badge doré avec reflet animé. */
.hero-jour-etiquette {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.38rem 1rem;
    border-radius: 999px;
    background: linear-gradient(110deg, #c9a24b 25%, #ffe9b0 50%, #c9a24b 75%);
    background-size: 220% 100%;
    color: #1a1f2e;
    font-weight: 800;
    font-size: 0.86rem;
    letter-spacing: 0.02em;
    margin-bottom: 1rem;
    box-shadow: 0 4px 18px rgba(201, 162, 75, 0.45);
    animation: hero-entree 0.7s ease forwards, hero-brillance 3.6s linear 1s infinite;
}

@keyframes hero-brillance {
    to { background-position: -220% 0; }
}

.hero-jour-contenu p {
    margin: 0;
    font-size: 1.18rem;
    line-height: 1.75;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}

/* Confort : pas d'animations pour ceux qui les désactivent. */
@media (prefers-reduced-motion: reduce) {
    .hero-jour-fond,
    .hero-jour-etiquette,
    .hero-jour-contenu > * {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* Boutons centrés sous l'image et la description */
.hero-jour-boutons {
    display: flex;
    gap: 0.8rem;
    flex-wrap: wrap;
    justify-content: center;
    max-width: none;
    margin: 0.8rem auto 0.3rem;
}

@media (max-width: 760px) {
    .hero-jour { min-height: 280px; }
    .hero-jour-contenu { padding: 1.6rem 1.4rem; }
    .hero-jour-contenu p { font-size: 1.02rem; }
    .hero-jour-voile {
        background: linear-gradient(180deg,
            rgba(10, 14, 25, 0.85) 0%,
            rgba(10, 14, 25, 0.55) 60%,
            rgba(10, 14, 25, 0.25) 100%);
    }
}

/* Boutons avec icône moderne (SVG au trait).
   Sélecteur doublé (.btn.btn-icone) pour l'emporter sur le display de .btn défini plus bas. */
.btn.btn-icone, .btn-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.6rem;
    padding: 0.7rem 1.2rem;
    font-size: 1.02rem;
}

.btn-ico {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
}

/* Dans le bandeau d'accueil : tous les boutons à la même largeur, contenu centré */
.hero-jour-boutons .btn-icone {
    width: 320px;
    max-width: 100%;
}

/* Actions des cartes de suivi : sous le titre, alignées à gauche, largeur uniforme */
.actions-suivi {
    display: flex;
    gap: 0.5rem;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: center;
    width: auto;
    margin: 0.35rem 0 0.75rem;
}

.actions-suivi .btn {
    flex: 0 0 auto;
    width: 9.5rem;
    max-width: 9.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.38rem 0.6rem;
    font-size: 0.88rem;
    line-height: 1.35;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Icône (emoji) des boutons d'action : plus grande que le libellé */
.actions-suivi .btn .ico {
    font-size: 1.25rem;
    line-height: 1;
    flex-shrink: 0;
}

@media (max-width: 760px) {
    .actions-suivi { flex-wrap: wrap; }
    .actions-suivi .btn { width: auto; max-width: none; flex: 1 1 45%; }
}

/* Puces de résumé agrandies (Mes recherches / Mes biens déposés) */
.puces-grandes .badge {
    font-size: 0.98rem;
    padding: 0.3rem 0.85rem;
}

/* ---------- Sélecteur de classe énergie (DPE / GES) ---------- */
.selecteur-energie {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
    align-items: center;
}

.selecteur-energie-case {
    width: 36px;
    height: 36px;
    border: 2px solid transparent;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 800;
    font-family: inherit;
    cursor: pointer;
    opacity: 0.45;
    transition: opacity 0.12s, transform 0.12s, border-color 0.12s, box-shadow 0.12s;
}

.selecteur-energie-case:hover { opacity: 0.9; transform: scale(1.08); }

.selecteur-energie-case.actif {
    opacity: 1;
    transform: scale(1.12);
    border-color: var(--texte);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

/* Bouton « Aucune » : même design que les cases de classe, en neutre,
   légèrement séparé du groupe A→G et en texte normal. */
.selecteur-energie-aucune {
    width: auto;
    padding: 0 0.8rem;
    margin-left: 0.7rem;
    background: var(--gris-clair);
    color: var(--gris);
    font-weight: 400;
    font-size: 0.85rem;
    letter-spacing: 0.2px;
}

.selecteur-energie-aucune.actif {
    color: var(--texte);
    border-color: var(--accent);
    box-shadow: none;
    transform: scale(1.04);
}

/* Brève explication de la classe sélectionnée, à droite des cases */
.selecteur-energie-info {
    margin-left: 0.4rem;
    font-size: 0.83rem;
    font-style: italic;
    color: var(--gris);
}

.selecteur-energie-info b { color: var(--texte); font-style: normal; }

/* ---------- Zone d'ajout de fichiers (remplace le bouton natif « Choisir des fichiers ») ---------- */
.zone-fichiers {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    padding: 1.25rem 1rem;
    border: 2px dashed var(--bord-champ);
    border-radius: 12px;
    background: var(--carte);
    cursor: pointer;
    text-align: center;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}

.zone-fichiers:hover {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* L'input natif, invisible, recouvre toute la zone : le clic ouvre le
   sélecteur et un glisser-déposer de fichiers y est capté nativement. */
.zone-fichiers input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

/* Le champ est invisible (opacity 0) : son anneau de focus l'était aussi. La
   zone entière le porte à sa place, sinon un clavier ne sait pas qu'il y est. */
.zone-fichiers:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Surbrillance pendant qu'un fichier est glissé au-dessus de la zone */
.zone-fichiers.survol {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--carte) 80%, var(--accent));
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 30%, transparent);
}

.zone-fichiers-icone { font-size: 1.7rem; line-height: 1; }

.zone-fichiers-titre { font-weight: 700; color: var(--accent-texte); }

.zone-fichiers-note { font-size: 0.8rem; color: var(--gris); }

/* ---------- Justificatifs déposés au formulaire d'inscription ---------- */
/* Trois zones côte à côte sur grand écran, empilées sur mobile. */
.documents-inscription {
    display: grid; gap: 0.6rem;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

/* Variante resserrée de .zone-fichiers : trois par ligne, sans occuper
   la moitié du formulaire d'inscription. */
.zone-fichiers-compacte { padding: 0.7rem 0.6rem; gap: 0.25rem; }
.zone-fichiers-compacte .zone-fichiers-icone { font-size: 1.3rem; }
.zone-fichiers-compacte .zone-fichiers-titre { font-size: 0.85rem; }
.zone-fichiers-compacte .zone-fichiers-note {
    font-size: 0.75rem; overflow-wrap: anywhere;
}

/* ---------- Pages éditoriales : titre ---------- */
.contenu-entete {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
}

.contenu-entete h1 { margin: 0; }

/* Le téléchargement PDF vit au pied de l'article (voir « .contenu-pied »).
   Le lien n'est QUE l'image : ni cadre, ni fond, ni remplissage — le dessin
   porte déjà sa propre forme. Un léger éclaircissement et une remontée d'un
   pixel au survol suffisent à montrer qu'il est cliquable. */
.lien-pdf {
    flex: 0 0 auto; text-decoration: none;
    display: inline-flex;
    transition: opacity 0.15s, transform 0.15s;
}

.lien-pdf:hover { opacity: 0.82; transform: translateY(-1px); }

/* Le focus clavier, lui, doit rester visible : sans cadre permanent, c'est le
   seul repère de la personne qui navigue à la tabulation. */
.lien-pdf:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
    border-radius: 6px;
}

/* Pictogramme officiel du fichier PDF (wwwroot/icone-pdf.svg). Hauteur et
   largeur suivent le rapport du dessin (75,3 × 92,6), pour ne pas l'étirer :
   une fois et demie la taille précédente. */
.ico-pdf { width: 3.45rem; height: 4.24rem; display: block; }

@media print {
    .lien-pdf { display: none; }
}

/* ---------- Acceptation des conditions générales ---------- */
/* La case et son libellé forment une seule cible cliquable. La case garde sa
   taille propre (flex-shrink) même quand le texte passe sur deux lignes. */
.case-cgv {
    display: flex; align-items: flex-start; gap: 0.6rem;
    cursor: pointer; font-size: 0.9rem; line-height: 1.45;
    font-weight: 400; color: var(--texte);
}

.case-cgv input[type=checkbox] {
    flex: 0 0 auto; width: 1.05rem; height: 1.05rem;
    margin-top: 0.12rem; cursor: pointer; accent-color: var(--accent);
}

.case-cgv a { color: var(--accent-texte); text-decoration: underline; }

/* ---------- Autocomplétion des villes (base officielle) ---------- */
/* Sommaire des longs formulaires : pastilles de navigation vers les sections. */
.sommaire-form { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 1.1rem; }
.sommaire-form button {
    padding: 0.3rem 0.85rem; border-radius: 999px; cursor: pointer;
    background: var(--carte); border: 1px solid var(--bord); color: var(--texte);
    font-size: 0.85rem; transition: border-color .15s, background .15s;
}
.sommaire-form button:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--carte)); }

.autocomplete { position: relative; }

.autocomplete input {
    width: 100%;
    box-sizing: border-box;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--bord-champ);
    border-radius: 10px;
    font-size: 0.95rem;
    font-family: inherit;
    background: var(--carte);
    color: var(--texte);
}

.autocomplete input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

.autocomplete-liste {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    /* Au moins aussi large que le champ, et plus si les noms le demandent :
       une liste étroite tronquait « Madrigal de las Altas Torres ». */
    min-width: 100%;
    width: max-content;
    max-width: min(480px, calc(100vw - 2rem));
    /* Au-dessus des calques Leaflet (z-index ≤ 800) pour ne pas passer derrière une carte. */
    z-index: 1200;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 10px;
    box-shadow: var(--ombre-forte);
    max-height: 280px;
    overflow-y: auto;
}

.autocomplete-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    width: 100%;
    padding: 0.55rem 0.85rem;
    background: none;
    border: none;
    border-bottom: 1px solid var(--bord);
    color: var(--texte);
    font: inherit;
    font-size: 0.92rem;
    text-align: left;
    cursor: pointer;
}

/* Chaque suggestion tient sur UNE ligne : le nom se tronque avec « … »,
   le complément (département) reste entier, aligné à droite. */
.autocomplete-item > span:first-child {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.autocomplete-item:last-child { border-bottom: none; }
.autocomplete-item:hover,
.autocomplete-item.actif { background: color-mix(in srgb, var(--accent) 14%, var(--carte)); }

.autocomplete-cp {
    color: var(--accent-texte);
    font-weight: 700;
    flex: 0 0 auto;
    white-space: nowrap;
    font-size: 0.85em;
}

/* Téléphone : la liste de suggestions se règle sur le champ, pas sur l'écran.

   Seuil de 560 px, celui que « .champ-double » emploie déjà plus bas : c'est là
   que les grilles de formulaire sont retombées à une colonne et que le champ
   occupe toute la largeur.

   Ce bloc doit rester APRÈS « .autocomplete-liste » et « .autocomplete-item »
   ci-dessus : mêmes sélecteurs, même spécificité, seul l'ordre les départage.

   1. LARGEUR. « max-width: min(480px, 100vw - 2rem) » compte depuis le bord de
      l'écran, alors que la liste, elle, part du bord GAUCHE du champ : un champ
      commençant à 140 px pouvait donc s'autoriser 328 px de liste et en pousser
      100 hors de l'écran — suggestions inatteignables et défilement horizontal
      sur toute la page. Sur téléphone, la liste ne dépasse plus le champ ; les
      noms trop longs continuent de se tronquer proprement (règle ci-dessus).
   2. HAUTEUR. 280 px de liste passent mal quand le clavier virtuel occupe la
      moitié basse de l'écran. La valeur en « dvh » suit ce rétrécissement là où
      il est signalé au CSS (Chrome Android) ; la déclaration en pixels qui la
      précède reste le repli pour les moteurs qui ignorent l'unité — elle doit
      rester AVANT, sans quoi c'est elle qui gagnerait.
   3. DÉFILEMENT. « contain » empêche le geste de se propager à la page une fois
      la liste arrivée en bout : on faisait défiler le formulaire derrière, et
      le champ que l'on est en train de remplir disparaissait sous le clavier.
   4. CIBLES. 0,55 rem de marge intérieure de part et d'autre + une ligne de
      0,92 rem (racine à 18 px) donnaient une suggestion de 41 à 43 px de haut
      selon les métriques de la police. Sous 44, le doigt attrape la ligne d'à
      côté — et dans une liste de communes voisines, l'erreur ne se voit pas.
      0,7 rem la porte à 46-48 px. On agit sur la marge intérieure plutôt que
      par « min-height » : celle-ci aurait ajouté le supplément SOUS le texte,
      qui est aligné sur sa ligne de base (« align-items: baseline »), au lieu
      de le répartir. */
@media (max-width: 560px) {
    .autocomplete-liste {
        max-width: 100%;
        max-height: 240px;
        max-height: min(240px, 40dvh);
        overscroll-behavior: contain;
    }

    .autocomplete-item { padding-block: 0.7rem; }
}

/* Combo « Pays » : un champ d'autocomplétion doté d'une flèche qui déroule
   la liste entière, dans les couleurs du site (la liste native des
   <datalist> est grise et impossible à styler). */
.combo-pays input { padding-right: 2.1rem; }

.combo-fleche {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    width: 1.7rem;
    height: 1.7rem;
    background: none;
    border: none;
    border-radius: 8px;
    color: var(--gris);
    font-size: 0.8rem;
    cursor: pointer;
}

.combo-fleche:hover { color: var(--texte); background: var(--gris-clair); }

/* Drapeau du pays reconnu, posé en tête du champ. */
.combo-pays.avec-drapeau input { padding-left: 2.3rem; }

.combo-drapeau {
    position: absolute;
    left: 0.65rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    font-size: 1rem;
}

/* Cellule de formulaire double : deux colonnes de la grille au lieu d'une —
   le champ ville du mode « ville + rayon » y affiche des noms longs. Sur les
   écrans étroits (grille à une colonne), retour à la cellule simple. */
.champ-double { grid-column: span 2; }

@media (max-width: 560px) {
    .champ-double { grid-column: auto; }
}

/* Boutons de défilement haut / bas, fixes en bas à droite */
.boutons-defilement {
    position: fixed;
    right: 1.1rem;
    bottom: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    z-index: 950;
}

.boutons-defilement button {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid var(--bord-champ);
    background: var(--carte);
    color: var(--accent-texte);
    font-size: 1.05rem;
    cursor: pointer;
    box-shadow: var(--ombre-forte);
    transition: transform 0.15s ease, background 0.15s ease;
}

.boutons-defilement button:hover {
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--accent) 18%, var(--carte));
}

/* Slider (rayon d'action) assorti au thème */
input[type="range"] {
    width: 100%;
    accent-color: var(--accent);
    cursor: pointer;
}

/* Les calques internes de Leaflet portent des z-index élevés (jusqu'à 1000 pour
   ses contrôles) : sans confinement, la carte passerait AU-DESSUS de l'entête et
   de ses menus déroulants (menu ☰, « Mon suivi »…). Le z-index:0 crée un
   contexte d'empilement local : tout ce qui vit dans la carte y reste enfermé,
   et l'entête (z-index 100) reprend le dessus. */
.leaflet-container {
    position: relative;
    z-index: 0;
}

/* Carte des zones d'activité (page Paramétrages agent) : fond neutre, France seule */
#carte-zones.leaflet-container,
#carte-zones .leaflet-container {
    background: var(--carte);
}

/* Conseils de prix selon l'état du bien (page Proposer mon bien) */
.conseils-prix {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0.2rem 0 0.6rem;
}

.ligne-conseil {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    flex-wrap: wrap;
    padding: 0.5rem 0.8rem;
    border: 1px solid var(--bord);
    border-radius: 10px;
    background: var(--carte);
}

.ligne-conseil .fourchette {
    color: var(--gris);
    font-size: 0.85rem;
}

.ligne-conseil.retenue {
    border-color: var(--vert);
    background: color-mix(in srgb, var(--vert) 10%, var(--carte));
}

/* Puce de ville supprimable */
.chip-ville {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.chip-retirer {
    width: 20px;
    height: 20px;
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    color: inherit;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

/* « --carte » comme encre : sombre sur les thèmes sombres (où --rouge est
   clair) et blanche sur les thèmes clairs (où --rouge est foncé). Le blanc fixe
   ne tenait pas sur le rouge clair de « casa » (3,00:1). */
.chip-retirer:hover { background: var(--rouge); color: var(--carte); }

/* ---------- Groupes de boutons uniformes ---------- */
.groupe-boutons {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}

.groupe-boutons .btn { min-width: 150px; text-align: center; }

/* Boutons d'action uniformes dans les tableaux */
.tableau .btn-petit { min-width: 130px; text-align: center; }

/* ------------------------------------------------------------------
   Boutons de réordonnancement (monter / descendre)
   ------------------------------------------------------------------
   Carrés et compacts : la largeur minimale de 130px des boutons de
   tableau étirait une flèche seule en pastille vide. La flèche est un
   SVG à trait épais — le caractère « ↑ » rend un glyphe fin, presque
   invisible sur fond sombre. */
.groupe-ordre { display: inline-flex; gap: 6px; }

.tableau .btn-ordre, .btn-ordre {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    min-width: 40px;
    padding: 0;
    border-radius: 11px;
    border: 1px solid var(--bord);
    background: var(--carte);
    color: var(--accent);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.btn-ordre svg { width: 20px; height: 20px; display: block; }

.btn-ordre:hover:not(:disabled) {
    background: color-mix(in srgb, var(--accent) 14%, var(--carte));
    border-color: var(--accent);
    transform: translateY(-1px);
    box-shadow: var(--ombre);
}

.btn-ordre:active:not(:disabled) { transform: translateY(0); box-shadow: none; }

.btn-ordre:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Bout de liste : le bouton reste en place pour ne pas décaler la colonne. */
.btn-ordre:disabled { opacity: 0.3; cursor: not-allowed; }

/* Bandeau de section (image + texte + bouton) dans Mon suivi */
.section-banniere {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 1.25rem;
    align-items: center;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-left: 4px solid var(--accent);
    border-radius: 14px;
    padding: 1.1rem 1.35rem;
    margin-bottom: 1rem;
    box-shadow: var(--ombre);
}

.section-banniere img {
    width: 110px;
    height: 90px;
    object-fit: cover;
    border-radius: 10px;
    display: block;
}

.section-banniere h3 { margin: 0 0 0.35rem; }
.section-banniere p { margin: 0; color: var(--gris); line-height: 1.5; font-size: 0.92rem; }
.section-banniere p + p { margin-top: 0.45rem; }

/* Colonne d'actions d'une bannière de section (ex. bascule recherches / biens) */
.actions-banniere {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: stretch;
}

.actions-banniere .btn {
    white-space: nowrap;
    text-align: center;
}

@media (max-width: 700px) {
    .section-banniere { grid-template-columns: 1fr; text-align: center; }
    .section-banniere img { width: 100%; height: 140px; }
}

/* ==================================================================
   Cartes et sections
   ================================================================== */
.card {
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 16px;
    padding: 1.5rem;
    margin-bottom: 1.25rem;
    box-shadow: var(--ombre);
}

.card h2, .card h3 { margin-top: 0; }

/* ==================================================================
   Formulaires
   ================================================================== */
.form-section {
    background: var(--carte);
    border: 1px solid var(--bord);
    border-left: 4px solid var(--accent);
    border-radius: 14px;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1rem;
    box-shadow: var(--ombre);
}

.form-section > h3 {
    margin: 0 0 1rem;
    color: var(--accent-texte);
    font-size: 1.05rem;
    border-bottom: 1px solid var(--bord);
    padding-bottom: 0.55rem;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.9rem 1.25rem;
}

.form-grid.wide { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }

/* Grille à deux colonnes fixes, pour des champs qui vont par paires (une borne
   basse et une borne haute) : chaque paire tient sur sa rangée, quelle que
   soit la largeur. Une seule colonne sur téléphone, comme les autres. */
.form-grid.paires { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 560px) {
    .form-grid.paires { grid-template-columns: 1fr; }
}

/* justify-content:flex-end : les zones de saisie d'une même ligne restent
   alignées entre elles même si un titre de champ passe sur deux lignes. */
.champ { display: flex; flex-direction: column; gap: 0.3rem; justify-content: flex-end; }
.champ.pleine-largeur, .pleine-largeur { grid-column: 1 / -1; }

/* Formulaire d'inscription : grille à six colonnes — les paires ordinaires
   (prénom / nom) occupent 3 + 3, et la rangée ville / code postal 4 + 2 :
   la ville, souvent longue, respire, le code postal (5 chiffres) se contente
   d'un tiers. Les règles 2tiers/1tiers/pleine-largeur suivent la règle
   générale « span 3 » : à spécificité égale, c'est l'ordre qui tranche. */
.grille-inscription { grid-template-columns: repeat(6, 1fr); }
.grille-inscription > .champ { grid-column: span 3; }
.grille-inscription > .champ-2tiers { grid-column: span 4; }
.grille-inscription > .champ-1tiers { grid-column: span 2; }
.grille-inscription > .champ.pleine-largeur { grid-column: 1 / -1; }

/* ------------------------------------------------------------------
   Type de transaction : liste déroulante + texte explicatif à droite
   ------------------------------------------------------------------
   Le texte est posé À CÔTÉ du choix, et non dessous : sous la liste, il
   allongeait la cellule de la grille et désalignait les champs voisins
   de la même rangée.
   La largeur est bornée pour que l'explication tienne sur deux lignes
   sans devenir une bande de texte illisible sur grand écran. */
.champ-transaction { grid-column: 1 / -1; }

.transaction-ligne {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

/* Sélecteur préfixé par « .champ » pour l'emporter sur la règle
   « .champ select { width: 100% } », plus spécifique, qui étirerait la liste
   sur toute la rangée et chasserait l'explication hors de l'écran. */
.champ .transaction-ligne > select { flex: 0 0 240px; width: 240px; max-width: 240px; }

.transaction-aide {
    margin: 0;
    flex: 1 1 auto;
    max-width: 78ch;
    color: var(--gris);
    font-size: 0.9rem;
    line-height: 1.5;
}

/* Petit écran : le texte passe sous la liste, qui reprend toute la largeur. */
@media (max-width: 720px) {
    .transaction-ligne { flex-direction: column; align-items: stretch; gap: 0.45rem; }
    .champ .transaction-ligne > select { flex: 1 1 auto; width: 100%; max-width: none; }
    .transaction-aide { max-width: none; }
}

/* Titre du champ : doré, en flex pour que le (i) reste à droite du texte
   sans passer à la ligne — et bien distinct du texte saisi dans le champ.
   « > » : ne s'applique qu'au titre direct du champ, pas aux cases à cocher. */
.champ > label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    color: var(--accent-2);
}

.champ > label .infobulle { flex-shrink: 0; }

/* Pleine opacité : « --gris » passe déjà le contraste sur chaque thème, et
   l'atténuation le ramenait à 2,5:1 sur les thèmes clairs. */
.champ input::placeholder, .champ textarea::placeholder { color: var(--gris); opacity: 1; }

/* Le contour d'une zone de saisie est la SEULE chose qui signale qu'on peut y
   écrire : la WCAG (1.4.11) lui impose 3:1. « --bord », taillé pour séparer
   deux cartes, n'atteignait que 1,1 à 1,4:1 selon le thème. */
.champ input, .champ select, .champ textarea,
input.saisie, select.saisie, textarea.saisie {
    width: 100%;
    box-sizing: border-box;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--bord-champ);
    border-radius: 10px;
    font-size: 0.95rem;
    font-family: inherit;
    background: var(--carte);
    color: var(--texte);
    transition: border-color 0.15s, box-shadow 0.15s;
}

.champ input:focus, .champ select:focus, .champ textarea:focus,
input.saisie:focus, select.saisie:focus, textarea.saisie:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

.cases {
    display: grid;
    /* 210 px et non 180 : à 180, la colonne n'offrait que ~134 px au texte une
       fois retirés la case (16), l'écart (8) et les marges intérieures (2×11).
       « Chambre parentale », « Environnement calme » ou « Ascenseur obligatoire »
       y passaient sur deux lignes, ce qui fait grandir toute la rangée de la
       grille — les cellules d'une même rangée partagent leur hauteur.
       210 px laissent ~164 px au texte, de quoi tenir les libellés les plus longs
       du site sur une seule ligne. Une chaîne encore plus longue se replierait
       de nouveau : c'est le seuil qu'il faudrait alors relever, pas le libellé
       qu'il faut raccourcir. */
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.5rem;
}

/* Liste « Exposition souhaitée », sur sa propre ligne au-dessus des cases de la
   section Localisation. Bridée en largeur : ses sept entrées sont courtes
   (« Sud-Ouest » au plus long), et étalée sur toute la colonne du formulaire
   elle écrasait visuellement les cases à cocher qui la suivent. La largeur est
   celle d'une colonne de « .cases », pour que les deux rangées s'alignent. */
.champ-expo {
    max-width: 210px;
    margin-top: 0.9rem;
}

/* Case à cocher accompagnée d'une infobulle. L'infobulle ne peut PAS être posée
   à l'intérieur du « <label> » : le label couvre tout ce qu'il contient, si bien
   qu'un clic sur le « i » cocherait la case au lieu d'ouvrir l'explication.
   Elle est donc sa voisine, les deux réunies dans une cellule de la grille. */
.case-avec-aide {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* La case prend toute la place restante : sans cela elle se réduirait à son
   texte et n'aurait plus la même largeur que les cases sans infobulle.
   L'infobulle lui prend une trentaine de pixels sur les 210 de la colonne :
   « Grilles de défense » passait alors sur deux lignes, et la case grandissait
   seule dans sa rangée. Les marges intérieures sont resserrées, l'écart avec
   le « i » réduit, et le libellé ne se replie plus — il garde ainsi la même
   hauteur que ses voisines. */
.case-avec-aide > .case-cocher {
    flex: 1;
    min-width: 0;
    padding-left: 0.55rem;
    padding-right: 0.45rem;
    white-space: nowrap;
}

.case-avec-aide > .infobulle { margin-left: 0; }

.case-cocher {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.48rem 0.7rem;
    border: 1px solid var(--bord);
    border-radius: 10px;
    cursor: pointer;
    font-size: 0.92rem;
    background: var(--carte);
    color: var(--texte);
    user-select: none;
    transition: border-color 0.15s, background 0.15s;
}

.case-cocher:hover { border-color: var(--accent); }

/* Case à cocher posée dans une rangée de champs de saisie : mêmes hauteur et
   arrondi qu'une zone de saisie, pour s'aligner sur ses voisines. */
.case-champ { padding: 0.55rem 0.7rem; font-size: 0.95rem; }
/* « flex-shrink: 0 » : sur un libellé long qui passe sur deux lignes, la case
   à cocher est le seul élément compressible de la ligne flex — sans cela elle
   s'écrase à 12 px pendant que le texte garde sa place. */
.case-cocher input { accent-color: var(--accent); width: 16px; height: 16px; flex-shrink: 0; }

/* État coché : la couleur seule, jamais la graisse ni l'épaisseur de bordure.
   Une graisse de 600 élargit le texte d'environ 4 % : « Local commercial »
   passait alors sur deux lignes et la case grandissait au clic, faisant sauter
   toute la grille autour. Même piège avec une bordure portée à 2 px, qui
   ajoute 2 px à la boîte. La bordure accentuée et le fond teinté suffisent
   largement à distinguer l'état, et ne coûtent aucun recalcul de mise en page. */
.case-cocher.cochee {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 16%, var(--carte));
}

/* ==================================================================
   Boutons
   ================================================================== */
.btn {
    display: inline-block;
    padding: 0.6rem 1.4rem;
    border-radius: 10px;
    border: none;
    font-size: 0.98rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    font-family: inherit;
    transition: transform 0.12s, box-shadow 0.12s, opacity 0.12s;
}

.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }

/* Le texte du bouton principal suit le thème : blanc sur les dégradés foncés
   (ocean), encre sombre sur l'or de « casa » — le blanc n'y donnait que 1,66:1
   sur la fin du dégradé, soit un libellé quasiment illisible. */
.btn-principal {
    background: var(--degrade);
    color: var(--sur-accent);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 35%, transparent);
}

.btn-principal:hover:not([disabled]) { box-shadow: var(--ombre-forte); transform: translateY(-1px); }

.btn-secondaire {
    background: var(--carte);
    color: var(--accent-texte);
    border: 1px solid var(--accent);
}

.btn-secondaire:hover { background: color-mix(in srgb, var(--accent) 10%, var(--carte)); }

.btn-danger { background: var(--carte); color: var(--rouge); border: 1px solid var(--rouge); }
.btn-danger:hover { background: var(--rouge-fond); }

/* Refus RETENU, pendant de « btn-principal » pour l'accord.
   « btn-danger » est un contour — pensé pour « Supprimer », où il faut se
   distinguer sans attirer le clic. Employé pour marquer le choix courant, il ne
   se distinguait plus de « btn-secondaire » : deux boutons cerclés côte à côte,
   l'un doré l'autre rouge, sans que rien ne dise lequel est actif. Un aplat le
   dit, comme le dégradé le dit pour l'accord.
   La bordure reste de la même épaisseur que celle des autres états : la porter
   à 2 px décalerait le bouton de 2 px au moment du clic. */
.btn-danger-actif {
    background: var(--rouge);
    color: var(--sur-rouge);
    border: 1px solid var(--rouge);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--rouge) 35%, transparent);
}
.btn-danger-actif:hover:not([disabled]) { box-shadow: var(--ombre-forte); transform: translateY(-1px); }
.btn-petit { padding: 0.32rem 0.8rem; font-size: 0.85rem; }

/* ==================================================================
   Badges
   ================================================================== */
.badge {
    display: inline-block;
    padding: 0.16rem 0.62rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
}

.badge-bleu { background: color-mix(in srgb, var(--accent) 14%, var(--carte)); color: var(--accent-texte); }
.badge-vert { background: var(--vert-fond); color: var(--vert); }
.badge-orange { background: var(--orange-fond); color: var(--orange); }
.badge-gris { background: var(--gris-clair); color: var(--gris); }
.badge-rouge { background: var(--rouge-fond); color: var(--rouge); }

/* ==================================================================
   Tableaux
   ================================================================== */
.tableau { width: 100%; border-collapse: collapse; background: var(--carte); border-radius: 12px; overflow: hidden; }

.tableau th {
    text-align: left;
    padding: 0.65rem 0.85rem;
    background: var(--gris-clair);
    font-size: 0.88rem;
    /* En-têtes de colonnes : majuscules, couleur du texte principal (blanc en
       thème sombre) — règle commune à tous les tableaux du site. */
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--texte);
    border-bottom: 2px solid var(--bord);
}

/* Légère séparation entre les titres de colonnes */
.tableau th + th { border-left: 1px solid var(--bord); }

.tableau td { padding: 0.65rem 0.85rem; border-bottom: 1px solid var(--bord); font-size: 0.92rem; }
.tableau tr:hover td { background: color-mix(in srgb, var(--accent) 4%, var(--carte)); }

/* Tableau large : défilement horizontal plutôt que débordement de la page. */
.tableau-defilant { width: 100%; overflow-x: auto; margin-top: 1rem; }
.tableau-defilant .tableau { min-width: 760px; }

/* En-tête cliquable d'une section repliable (espace annonces de l'agent). */
.entete-section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    cursor: pointer;
    user-select: none;
}

.entete-section h2, h2.entete-section { font-size: 1.15rem; }

/* Le titre est un bouton (repli / dépli au clavier) : il prend toute la
   largeur du titre, sans l'habillage des boutons du navigateur. */
.entete-section-bouton {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: 0.6rem; width: 100%;
    background: transparent; border: none; padding: 0; margin: 0;
    color: inherit; font: inherit; text-align: start; cursor: pointer;
}

/* ==================================================================
   Annonces
   ================================================================== */
.grille-annonces {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.25rem;
}

/* Toutes les cartes de liste (annonces et recherches) partagent le même
   agencement : visuel, contenu variable, puis informations de publication et
   bouton d'action alignés en bas, quelle que soit la hauteur du contenu. */
.carte-annonce {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 16px;
    overflow: hidden;
    transition: box-shadow 0.18s, transform 0.18s, border-color 0.18s;
    box-shadow: var(--ombre);
    /* La carte se comporte comme un seul bouton : main partout, jamais le
       curseur de sélection de texte, et pas de sélection accidentelle au clic.
       « cursor » étant héritée, tous les textes de la carte suivent. */
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

.carte-annonce:hover {
    box-shadow: var(--ombre-forte);
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--accent) 45%, var(--bord));
}

.carte-annonce-visuel {
    position: relative;
    flex-shrink: 0;
    background: var(--degrade);
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
}

.carte-annonce-transaction {
    position: absolute;
    top: 0.6rem;
    left: 0.6rem;
    background: rgba(255, 255, 255, 0.92);
    color: #0f172a;
    z-index: 2;
}

/* Étiquettes purement informatives posées sur le visuel : elles ne doivent pas
   intercepter le clic, sinon la carte n'est plus cliquable à cet endroit. */
.carte-annonce-transaction,
.carte-annonce-visuel .badge-externe,
.carte-annonce-visuel .badge-match,
.compteur-carrousel { pointer-events: none; }

.carte-annonce-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.fleche-carrousel {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: none;
    background: rgba(15, 23, 42, 0.55);
    color: white;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 0 3px;
    transition: background 0.15s;
}

.fleche-carrousel:hover { background: rgba(15, 23, 42, 0.85); }
.fleche-carrousel.gauche { left: 0.5rem; }
.fleche-carrousel.droite { right: 0.5rem; }

.compteur-carrousel {
    position: absolute;
    bottom: 0.5rem;
    right: 0.6rem;
    z-index: 3;
    background: rgba(15, 23, 42, 0.65);
    color: white;
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
}

/* Ces deux badges servent à la fois en étiquette posée sur le visuel d'une carte
   et en badge normal dans un tableau : le positionnement absolu n'est donc appliqué
   que dans le visuel d'une carte, sinon ils flotteraient hors de leur cellule. */
.badge-match { background: rgba(15, 23, 42, 0.82); color: #fde68a; }
.badge-externe { background: rgba(15, 23, 42, 0.82); color: #a5f3fc; }

.carte-annonce-visuel .badge-match {
    position: absolute;
    bottom: 0.6rem;
    left: 0.6rem;
    z-index: 2;
}

.carte-annonce-visuel .badge-externe {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    z-index: 2;
}

/* ---------- Info-bulles (i) ---------- */
.infobulle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    margin-left: 0.35rem;
    cursor: help;
}

/* L'info-bulle est atteignable au clavier (c'est « :focus » qui la déplie) :
   elle doit donc montrer où se trouve le focus. Un « outline: none » la rendait
   invisible au parcours clavier — on ne savait plus sur quel (i) on était. */
.infobulle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 50%; }

.infobulle-icone {
    width: 17px;
    height: 17px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--sur-accent);
    font-size: 0.72rem;
    font-weight: 700;
    font-style: italic;
    font-family: Georgia, "Times New Roman", serif;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.infobulle-demo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--sur-accent);
    font-size: 0.68rem;
    font-weight: 700;
    font-style: italic;
    font-family: Georgia, serif;
}

.infobulle-texte {
    position: absolute;
    bottom: 135%;
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    width: max-content;
    max-width: 260px;
    background: #0f172a;
    color: #f1f5f9;
    text-align: left;
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.4;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s, transform 0.15s;
    z-index: 200;
    pointer-events: none;
    white-space: normal;
}

.infobulle-texte::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-top-color: #0f172a;
}

.infobulle:hover .infobulle-texte,
.infobulle:focus .infobulle-texte {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}

/* Rapproche la bulle du bord pour ne pas déborder à gauche/droite */
.champ label .infobulle-texte { left: 0; transform: translateX(0) translateY(4px); }
.champ label .infobulle:hover .infobulle-texte,
.champ label .infobulle:focus .infobulle-texte { transform: translateX(0) translateY(0); }
.champ label .infobulle-texte::after { left: 8px; }

/* ---------- Étiquettes énergie (DPE / GES) ---------- */
.etiquettes-duo {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-bottom: 0.5rem;
}

.doc-edition {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--bord);
}

.doc-edition input {
    flex: 1;
    min-width: 160px;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--bord-champ);
    border-radius: 8px;
    background: var(--carte);
    color: var(--texte);
    font-family: inherit;
    font-size: 0.9rem;
}

.etiquette-energie { min-width: 210px; }
.etiquette-titre { font-size: 0.85rem; margin-bottom: 0.35rem; color: var(--gris); }

.etiquette-echelle {
    display: flex;
    gap: 3px;
    align-items: stretch;
}

.etiquette-barreau {
    position: relative;
    flex: 1;
    text-align: center;
    padding: 0.35rem 0;
    font-weight: 700;
    font-size: 0.82rem;
    color: #1a1a1a;
    border-radius: 4px;
    opacity: 0.45;
    transition: opacity 0.15s;
}

.etiquette-barreau.actif {
    opacity: 1;
    outline: 2px solid var(--texte);
    transform: scaleY(1.35);
    z-index: 1;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.etiquette-fleche {
    position: absolute;
    right: -12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.6rem;
    color: var(--texte);
}

/* Colonne : le contenu variable pousse le pied et l'action vers le bas. */
.carte-annonce-corps {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 1rem 1.1rem 1.1rem;
}

.carte-annonce-prix { font-size: 1.22rem; font-weight: 800; color: var(--accent); }
/* Variante pour un texte long (fourchette de budget d'une recherche). */
.carte-annonce-prix.prix-long { font-size: 1.02rem; line-height: 1.35; }
.carte-annonce-titre { font-weight: 600; margin: 0.2rem 0; }
.carte-annonce-infos { color: var(--gris); font-size: 0.9rem; }
.carte-annonce-lieu { font-size: 0.9rem; margin: 0.3rem 0 0.5rem; }

/* margin-top:auto = toujours collé en bas, même sur une carte peu remplie. */
.carte-annonce-pied {
    margin-top: auto;
    padding-top: 0.6rem;
    border-top: 1px solid var(--bord);
    color: var(--gris);
    font-size: 0.8rem;
}

/* Bouton d'action, tout en bas de la carte. */
.carte-annonce-action { display: flex; margin-top: 0.7rem; }
.carte-annonce-action .btn { width: 100%; text-align: center; justify-content: center; }

/* La carte entière reste cliquable : le lien d'action est étiré en surimpression.
   Les commandes du visuel (cœur, flèches du carrousel) sont en z-index 3 et
   restent donc accessibles par-dessus. */
.carte-annonce-action .btn::after { content: ""; position: absolute; inset: 0; z-index: 1; }

/* Le cœur des favoris et l'étiquette « Particulier » occupent le même coin :
   on décale l'étiquette quand les deux sont affichés. */
.carte-annonce-visuel:has(.bouton-favori) .badge-externe { right: 3.1rem; }

/* ==================================================================
   Fiche bien
   ================================================================== */
.fiche-bien {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 1.25rem;
    align-items: start;
}

@media (max-width: 900px) {
    .fiche-bien { grid-template-columns: 1fr; }
}

.carte-bien {
    width: 100%;
    height: 420px;
    border: none;
    border-radius: 10px;
    margin-top: 0.5rem;
}

.galerie {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.galerie-item { margin: 0; }

.galerie img {
    width: 100%;
    height: 120px;
    object-fit: cover;
    border-radius: 10px;
    border: 1px solid var(--bord);
    transition: transform 0.15s, box-shadow 0.15s;
}

.galerie img:hover { transform: scale(1.03); box-shadow: var(--ombre-forte); }

.galerie-item figcaption {
    font-size: 0.8rem;
    color: var(--gris);
    margin-top: 0.25rem;
    line-height: 1.3;
}

.galerie-item figcaption b { color: var(--texte); }

/* Vidéos jointes à une annonce (fiche du bien). */
.galerie-videos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.galerie-video { margin: 0; }

.galerie-video video {
    width: 100%;
    max-height: 320px;
    border-radius: 10px;
    border: 1px solid var(--bord);
    background: #000;
}

.galerie-video figcaption {
    font-size: 0.8rem;
    color: var(--gris);
    margin-top: 0.25rem;
    line-height: 1.3;
}

.galerie-video figcaption b { color: var(--texte); }

/* Lecteur YouTube intégré à la fiche du bien. */
.video-youtube {
    margin: 0.9rem 0 0;
    max-width: 720px;
}

.video-youtube iframe {
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--bord);
    border-radius: 10px;
    background: #000;
}

.video-youtube figcaption {
    font-size: 0.8rem;
    color: var(--gris);
    margin-top: 0.25rem;
}

/* Boutons des autres liens externes (visite virtuelle, site...). */
.liens-bien {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.9rem;
}

/* Tableau de saisie des liens externes (formulaires de bien). */
.tableau-liens .col-type { width: 200px; }
.tableau-liens .col-titre { width: 220px; }
.tableau-liens .col-action { width: 1%; white-space: nowrap; }

.tableau-liens select,
.tableau-liens input {
    width: 100%;
    box-sizing: border-box;
}

.liens-note {
    color: var(--gris);
    font-size: 0.88rem;
    margin: 0 0 0.7rem;
}

@media (max-width: 720px) {
    .tableau-liens .col-type { width: 130px; }
    .tableau-liens .col-titre { display: none; }
}

.encart-viager {
    background: var(--orange-fond);
    border: 1px solid color-mix(in srgb, var(--orange) 35%, transparent);
    border-radius: 12px;
    padding: 0.9rem 1.1rem;
    margin-bottom: 1rem;
}

/* ==================================================================
   Divers
   ================================================================== */
.alerte-succes {
    background: var(--vert-fond);
    border: 1px solid color-mix(in srgb, var(--vert) 35%, transparent);
    color: var(--vert);
    padding: 1rem 1.25rem;
    border-radius: 12px;
    margin-bottom: 1rem;
}

/* Espace entre les boutons d'action d'un message de succès */
.alerte-succes .btn { margin: 0.35rem 0.7rem 0 0; }

/* ---------- Boîte de confirmation (remplace window.confirm) ---------- */
.voile-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
}

.boite-confirm {
    background: var(--carte);
    color: var(--texte);
    border: 1px solid var(--bord);
    border-radius: 14px;
    padding: 1.6rem 1.8rem;
    max-width: 420px;
    width: calc(100% - 2rem);
    text-align: center;
    box-shadow: var(--ombre-forte);
    animation: apparition-boite 0.15s ease-out;
}

@keyframes apparition-boite {
    from { transform: scale(0.94); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.boite-confirm-icone { font-size: 2.1rem; line-height: 1; }

.boite-confirm h3 { margin: 0.5rem 0 0.3rem; }

.boite-confirm p { color: var(--gris); margin: 0 0 1.2rem; line-height: 1.5; }

.boite-confirm-actions {
    display: flex;
    gap: 0.6rem;
    justify-content: center;
    flex-wrap: wrap;
}

/* Excuses pour une langue partiellement traduite : le texte y est plus long
   que dans une confirmation, et il faut lui laisser de la place. Le sens de
   lecture est porté par l'attribut dir, pour l'arabe notamment. */
.boite-traduction {
    max-width: 560px;
    text-align: start;
}

.boite-traduction .boite-confirm-icone,
.boite-traduction h3 { text-align: center; }

.boite-traduction p {
    color: var(--texte);
    line-height: 1.65;
    text-align: start;
}

.alerte-info {
    background: color-mix(in srgb, var(--accent) 10%, var(--carte));
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
    color: var(--texte);
    padding: 1rem 1.25rem;
    border-radius: 12px;
    margin-bottom: 1rem;
}

/* Popup modal (ex. accès agent bloqué). */
.modal-fond {
    position: fixed; inset: 0; z-index: 1000;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    padding: 1rem;
}

.modal-boite {
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 16px;
    box-shadow: var(--ombre-forte);
    padding: 1.6rem 1.8rem;
    max-width: 420px; width: 100%;
    text-align: center;
}
.modal-boite h3 { margin: 0.4rem 0 0.6rem; }
.modal-boite p { color: var(--gris); line-height: 1.5; margin-bottom: 1.2rem; }
.modal-icone { font-size: 2.6rem; line-height: 1; }

/* Menu ☰ (burger) : paramètres + langue, en haut à droite. */
.menu-burger { position: relative; }

.burger-bouton {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--topbar-texte) 35%, transparent);
    border-radius: 10px;
    color: var(--topbar-texte);
    cursor: pointer; transition: border-color .15s, background .15s;
}
.burger-bouton:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }

.burger-barres, .burger-barres::before, .burger-barres::after {
    display: block; width: 20px; height: 2px;
    background: currentColor; border-radius: 2px;
}
.burger-barres { position: relative; }
.burger-barres::before { content: ""; position: absolute; top: -6px; left: 0; }
.burger-barres::after { content: ""; position: absolute; top: 6px; left: 0; }

.burger-voile { position: fixed; inset: 0; z-index: 90; }

.burger-menu {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 100;
    min-width: 210px; max-height: 75vh; overflow-y: auto;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 14px;
    box-shadow: var(--ombre-forte);
    padding: 6px;
    display: flex; flex-direction: column;
}

.burger-item {
    /* Flex et non bloc : chaque entrée porte un pictogramme suivi d'un
       libellé (voir le composant Icone), qui doivent rester sur une ligne. */
    display: flex; align-items: center;
    padding: 10px 12px;
    border-radius: 9px; text-decoration: none;
    color: var(--texte); font-weight: 600;
    white-space: nowrap;
}
.burger-item:hover { background: var(--gris-clair); }

.burger-titre {
    display: flex; align-items: center;
    padding: 8px 12px 4px; font-size: 0.78rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .5px; color: var(--gris);
}

.burger-separateur { height: 1px; background: var(--bord); margin: 6px 4px; }

/* Les onglets de navigation ne s'affichent dans le menu ☰ que sur petit écran. */
.burger-nav { display: none; flex-direction: column; }

/* Sous 900px : la barre de navigation passe dans le menu ☰ (plus de retour à la ligne). */
@media (max-width: 900px) {
    .topbar nav { display: none; }
    .burger-nav { display: flex; }

    /* La barre de messages descend sur sa propre ligne : « order » la place
       après la marque et la zone utilisateur.
       Sa PLEINE LARGEUR ne peut pas être déclarée ici — elle a été déplacée
       juste après la règle de base « .barre-message », plus bas dans le
       fichier, avec l'explication du pourquoi. */
    .barre-message { order: 1; }
}

/* Le menu ☰ ne se compresse ni ne passe à la ligne : il reste en haut à droite. */
.menu-burger { flex-shrink: 0; }

/* Très petits écrans : on allège la zone de droite pour éviter les débordements. */
@media (max-width: 560px) {
    .badge-role { display: none; }
    .topbar { gap: 0.5rem 0.75rem; padding: 0.6rem 1rem; }
    .brand { gap: 0.35rem; }
    .brand .logo { width: 46px; height: 46px; }
    .brand-texte { font-size: 1.65rem; }
    .zone-droite { gap: 0.5rem; }
    .zone-user { gap: 0.4rem; }
    /* La cloche n'est PAS réglée ici : sa règle de base est écrite plus bas dans
       le fichier, et à spécificité égale c'est la dernière qui l'emporte — même
       depuis une requête de média, qui n'ajoute aucun poids. Son allègement pour
       petit écran suit donc immédiatement cette règle de base. */
    .pseudo { max-width: clamp(4rem, 20vw, 9rem); }
}

/* Écrans étroits : la devise disparaît, il ne reste que le logo et le nom. */
@media (max-width: 420px) {
    .brand-devise { display: none; }
}

/* Choix du thème (page paramètres). */
.choix-themes { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.choix-theme {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.55rem 0.9rem;
    background: var(--carte); border: 1px solid var(--bord);
    border-radius: 999px; color: var(--texte); font-weight: 600;
    cursor: pointer; transition: border-color .12s, background .12s;
}
.choix-theme:hover { border-color: var(--accent); background: var(--gris-clair); }
.theme-pastille { width: 20px; height: 20px; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,.3); }

/* Cloche de notifications dans la barre du haut. */
.cloche-notif {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 1.25rem; text-decoration: none;
    width: 38px; height: 38px; border-radius: 50%;
    transition: background .15s;
}
.cloche-notif:hover { background: color-mix(in srgb, var(--topbar-texte) 15%, transparent); }

/* Très petits écrans : la cloche s'aligne sur le reste de la zone de droite,
   allégée plus haut au même seuil. Ce bloc doit rester APRÈS la règle de base
   ci-dessus — écrit dans la requête de média du haut du fichier, il était
   intégralement neutralisé par elle, et la cloche gardait ses 38 px pendant que
   le logo, le nom et le pseudo rétrécissaient autour. */
@media (max-width: 560px) {
    .cloche-notif { width: 34px; height: 34px; font-size: 1.1rem; }
}

.cloche-badge {
    position: absolute; top: 2px; right: 0;
    min-width: 17px; height: 17px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 10px; font-weight: 700; line-height: 1;
    color: #fff; background: #e11d48;
    border-radius: 999px;
}

/* Liste des notifications (page /notifications). */
.liste-notifs { display: flex; flex-direction: column; gap: 0.5rem; }

.ligne-notif {
    display: flex; align-items: center; gap: 0.9rem;
    width: 100%; text-align: start;
    background: var(--carte); border: 1px solid var(--bord);
    border-radius: 12px; padding: 0.85rem 1rem;
    cursor: pointer; transition: background .12s, border-color .12s;
    /* La ligne était un <button> : le texte prenait la couleur des boutons du
       navigateur, illisible sur fond sombre. On force celle du thème. */
    color: var(--texte); font: inherit;
}
.ligne-notif:hover { border-color: var(--accent); background: var(--gris-clair); }

/* Bouton d'ouverture : occupe toute la ligne, sans l'habillage des boutons
   du navigateur — c'est la ligne elle-même qui se lit comme cliquable. */
.notif-ouvrir {
    display: flex; align-items: center; gap: 0.9rem; flex: 1; min-width: 0;
    background: transparent; border: none; padding: 0; margin: 0;
    text-align: start; color: inherit; font: inherit; cursor: pointer;
}
.ligne-notif.non-lue { border-inline-start: 3px solid var(--accent); }

.notif-icone { font-size: 1.4rem; }
.notif-corps { display: flex; flex-direction: column; gap: 0.15rem; flex: 1; }
.notif-message { font-weight: 600; color: var(--texte); }

/* Bouton de suppression : discret tant que la ligne n'est pas survolée. */
.notif-suppr { flex-shrink: 0; opacity: 0.55; }
.ligne-notif:hover .notif-suppr { opacity: 1; }

/* Champ « Jusqu'au » de la suppression par date, aligné avec les boutons. */
.notif-jusquau {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--gris);
    margin-inline: 0.5rem 0.3rem;
}
/* width:auto annule le 100 % de « .saisie » : dans un conteneur inline-flex,
   une base de 100 % ferait rétrécir le libellé « Jusqu'au » à côté. */
.notif-jusquau input { width: auto; max-width: 10rem; flex: 0 0 auto; }
.notif-date { font-size: 0.8rem; color: var(--gris); }

/* Pastille de légende (carte des zones) : la couleur en échantillon, le mot
   en texte normal — un mot coloré ne passait pas le contraste. */
.legende-pastille {
    display: inline-block; width: 0.8em; height: 0.8em; border-radius: 50%;
    vertical-align: middle; border: 1px solid var(--bord);
}
.notif-pastille { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }

/* Tableau de bord agent : cartes de statistiques. */
.grille-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.9rem;
    margin: 1.2rem 0 1.6rem;
}

.carte-stat {
    display: flex; flex-direction: column; gap: 0.15rem;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 14px;
    padding: 1rem 1.1rem;
    box-shadow: var(--ombre);
}

.carte-stat .stat-valeur { font-size: 1.9rem; font-weight: 800; color: var(--accent); line-height: 1.1; }
.carte-stat .stat-libelle { font-weight: 600; }
.carte-stat .stat-detail { font-size: 0.82rem; color: var(--gris); }

/* Barre de messages fusionnée, placée dans l'entête (email + annonces admin). */
.barre-message {
    flex: 1; min-width: 0;
    display: flex; align-items: center; justify-content: flex-start;
    gap: 0.5rem;
    padding: 0.3rem 0.7rem;
    border-radius: 10px;
    font-size: 0.9rem;
    color: var(--topbar-texte);
}
.barre-email { background: color-mix(in srgb, #d97706 26%, transparent); }
.barre-admin { background: color-mix(in srgb, var(--accent) 26%, transparent); }

/* Zones d'actions ancrées aux extrémités de la barre de messages */
.barre-cote {
    display: flex; align-items: center; gap: 0.4rem;
    flex-shrink: 0;
}
.barre-cote-droite { margin-left: auto; }

/* Message cadré à gauche, les actions restant collées à droite */
.barre-contenu {
    display: flex; align-items: center; gap: 0.6rem;
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-start;
    text-align: left;
}
.barre-contenu > span {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.barre-nav {
    background: transparent; border: none; cursor: pointer;
    color: var(--topbar-texte); font-size: 1.3rem; line-height: 1;
    padding: 0 0.25rem; flex-shrink: 0;
}
.barre-nav:hover { color: white; }
.barre-compteur { font-size: 0.78rem; opacity: 0.85; flex-shrink: 0; }

/* Boutons-icônes de la barre de messages (Afficher / Lu). */
.barre-icone {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; flex-shrink: 0;
    background: rgba(255, 255, 255, 0.16);
    border: none; border-radius: 10px;
    color: var(--topbar-texte);
    cursor: pointer;
    transition: background .12s, transform .12s, color .12s;
}
.barre-icone:hover { background: rgba(255, 255, 255, 0.32); color: #fff; transform: scale(1.08); }
.barre-icone svg { width: 24px; height: 24px; }

/* Sous 900 px : la barre de messages occupe une ligne entière, sous la marque
   et la zone utilisateur (l'« order » qui l'y envoie est, lui, déclaré au seuil
   de 900 px plus haut).

   Ce bloc DOIT rester APRÈS la règle de base ci-dessus, et c'est justement le
   défaut qu'il corrige : écrit dans la requête de média du haut du fichier, son
   « flex-basis: 100% » était annulé par le « flex: 1 » de « .barre-message » —
   le raccourci « flex » repose AUSSI flex-basis, à 0 %. À spécificité égale,
   c'est la dernière déclaration écrite qui l'emporte, une requête de média
   n'ajoutant aucun poids. La barre restait donc collée sur la même ligne que la
   zone utilisateur, réduite à la place qui traînait à droite du bouton de
   déconnexion : une centaine de pixels sur un téléphone, moins que la largeur
   minimale de son propre bouton, qui débordait alors du fond arrondi. Même
   bévue que pour la cloche de notifications, plus haut. */
@media (max-width: 900px) {
    .barre-message { flex-basis: 100%; }
}

/* Téléphone : le rappel « confirmez votre email » s'empile.

   Même à pleine largeur, la barre n'offre qu'environ 280 px à son contenu sur
   un écran de 360. Le bouton « Renvoyer l'email » ne se comprime pas en deçà de
   son mot le plus long (~90 px) : la phrase tombait sous l'ellipse de
   « .barre-contenu > span » au bout d'une vingtaine de caractères — « 📧 Pensez
   à confir… » — pendant que le bouton, serré à sa largeur minimale, cassait son
   libellé sur deux lignes. Ni le message ni l'action n'étaient lisibles.

   Même parti que « .bandeau-annonce » à son propre seuil : le texte prend toute
   la largeur, l'action passe dessous. Mais on s'arrête là. Ce rappel n'est pas
   une annonce d'accueil : il vit dans l'entête, à gauche, et garde son ton
   discret — pas de centrage, pas de bouton pleine largeur.

   Réservé à « .barre-email » : un message d'administrateur, lui, DOIT rester
   sur une ligne. Sa troncature est voulue — le bouton 👁 sert justement à
   l'ouvrir en entier. */
@media (max-width: 700px) {
    .barre-email .barre-contenu { flex-wrap: wrap; row-gap: 0.45rem; }

    /* Base de 100 % : la phrase occupe la première ligne à elle seule et
       repousse le bouton (ou l'accusé « ✔ ») sur la suivante. Le retour à
       « normal » lève la troncature : sur deux lignes, la phrase tient. */
    .barre-email .barre-contenu > span {
        flex: 1 1 100%;
        white-space: normal;
        overflow: visible;
    }

    /* 44 px de cible tactile, comme la croix du bandeau d'annonce. « inline-flex »
       recentre le libellé dans cette hauteur imposée : « .btn » est un
       inline-block, dont le texte resterait plaqué en haut. Le « nowrap » n'est
       plus une précaution mais une garantie — la ligne entière est à lui. */
    .barre-email .barre-contenu .btn {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        white-space: nowrap;
    }
}

/* Encadré d'attention (ex. agents en attente de validation) : ton ambré. */
.alerte-attention {
    background: color-mix(in srgb, #d97706 10%, var(--carte));
    border: 1px solid color-mix(in srgb, #d97706 35%, transparent);
    color: var(--texte);
    padding: 1rem 1.25rem;
    border-radius: 12px;
    margin-bottom: 1rem;
}

.alerte-erreur {
    background: var(--rouge-fond);
    border: 1px solid color-mix(in srgb, var(--rouge) 35%, transparent);
    /* Couleur de texte du thème : blanc cassé sur les thèmes sombres, foncé
       sur les thèmes clairs — du blanc pur serait illisible sur fond clair. */
    color: var(--texte);
    padding: 0.8rem 1.1rem;
    border-radius: 12px;
    margin-bottom: 1rem;
    /* Les messages écrits sur plusieurs lignes (\n) gardent leurs sauts. */
    white-space: pre-line;
}

.criteres-puces { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }

/* ------------------------------------------------------------------
   Mes recherches (suivi client) : popup « Consulter » avec le cadre
   récapitulatif de tous les critères.
   ------------------------------------------------------------------ */
.modal-criteres {
    text-align: start;
    max-width: 620px;
    width: 94%;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
}

/* Seul le cadre défile : le titre et le bouton Fermer restent visibles. */
.modal-criteres-contenu { overflow-y: auto; flex: 1; }

/* Variante large : le tableau des correspondances a besoin de place. */
.modal-correspondances { max-width: 1100px; }

/* Cadre récapitulatif de tous les critères d'une recherche. */
.cadre-criteres {
    border: 1px solid var(--accent);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    background: color-mix(in srgb, var(--accent) 6%, var(--carte));
}

/* Entête du cadre : titre à gauche, bouton Dupliquer à droite. */
.cadre-criteres-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.7rem;
}
.cadre-criteres-entete h4 { margin: 0; }

/* Les critères eux-mêmes reprennent la couleur de texte du thème (blanc sur
   les thèmes sombres), les intitulés de section se détachent en doré. */
.cadre-criteres .badge { color: var(--texte); }

.cadre-criteres-groupe { margin-bottom: 0.75rem; }
.cadre-criteres-groupe:last-child { margin-bottom: 0; }

.cadre-criteres-titre {
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 700;
    color: var(--accent-texte);
    margin-bottom: 0.25rem;
}

.cadre-criteres .criteres-puces { margin-top: 0; }

.cadre-criteres-texte {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.5;
    white-space: pre-line;
}

.vide { text-align: center; color: var(--gris); padding: 2.5rem; }

.validation-message { color: var(--rouge); font-size: 0.82rem; }
.invalid { outline: 1px solid var(--rouge); }

.entete-page {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.entete-page h1 { margin: 0; font-size: 1.6rem; letter-spacing: -0.5px; }

/* Coordonnées du client sous le titre de la page (détail d'une recherche). */
.entete-coordonnees {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1.1rem;
    margin-top: 0.45rem;
    font-size: 0.93rem;
}

.entete-coordonnees a { color: var(--accent-texte); text-decoration: none; font-weight: 600; }
.entete-coordonnees a:hover { text-decoration: underline; }

/* ==================================================================
   Grille des critères d'une recherche
   ================================================================== */
.grille-criteres {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 0.9rem 1.6rem;
    margin-top: 1.1rem;
}

.critere { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }

.critere-libelle {
    color: var(--gris);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.critere-valeur { font-weight: 600; overflow-wrap: anywhere; }

/* Valeurs longues (listes d'options, de villes…) : toute la largeur. */
.critere.pleine { grid-column: 1 / -1; }

/* ==================================================================
   Propositions reçues (Mon suivi) : une ligne = l'annonce en carte à
   gauche, le rappel des critères de la recherche à droite.
   ================================================================== */
.ligne-proposition {
    display: grid;
    grid-template-columns: minmax(260px, 320px) 1fr;
    gap: 1.4rem;
    /* start : la carte de l'annonce garde sa hauteur naturelle (pas de bande vide
       au milieu quand les critères sont nombreux). */
    align-items: start;
}

@media (max-width: 860px) {
    .ligne-proposition { grid-template-columns: 1fr; }
}

.proposition-detail {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    min-width: 0;
}

/* Colonne de gauche : métadonnées (statut, date, expéditeur) puis carte de
   l'annonce, qui s'aligne ainsi avec le bloc d'analyse à droite. */
.proposition-annonce {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    min-width: 0;
}

/* Métadonnées en tête de carte, sur une seule ligne pleine largeur : le badge
   de statut, la date et l'expéditeur. Les points de suspension prennent le
   relais si l'écran est trop étroit. */
.ligne-proposition { row-gap: 0.8rem; }

.ligne-proposition .proposition-meta {
    grid-column: 1 / -1;
    flex-wrap: nowrap;
    white-space: nowrap;
    overflow: hidden;
}

.ligne-proposition .proposition-meta > span {
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 1;
}

.ligne-proposition .proposition-meta .badge { flex-shrink: 0; }

/* Boutons d'avis à droite de la ligne d'en-tête, sur la même ligne que le
   statut et l'expéditeur. */
.ligne-proposition .proposition-meta .actions-avis {
    margin-left: auto;
    flex-shrink: 0;
}

@media (max-width: 860px) {
    .ligne-proposition .proposition-meta {
        flex-wrap: wrap;
        white-space: normal;
    }

    .ligne-proposition .proposition-meta .actions-avis { margin-left: 0; }
}

/* Boutons d'avis : exactement les mêmes métriques que le « .btn-petit » de la
   carte (padding, taille, interligne) pour que les deux rangées s'alignent. */
.actions-avis .btn {
    width: auto;
    max-width: none;
    flex: 0 1 auto;
    padding: 0.32rem 0.9rem;
    font-size: 0.85rem;
    line-height: normal;
}

.proposition-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
    color: var(--gris);
    font-size: 0.88rem;
}

.proposition-meta a { color: var(--accent-texte); text-decoration: none; }

.proposition-message {
    margin: 0;
    padding: 0.6rem 0.9rem;
    border-left: 3px solid var(--accent);
    background: var(--gris-clair);
    border-radius: 0 8px 8px 0;
    font-style: italic;
}

.correspondance {
    border: 1px solid var(--bord);
    border-radius: 12px;
    padding: 0.9rem 1rem;
    background: var(--gris-clair);
}

.correspondance-entete {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.correspondance-titre { font-weight: 700; }
.correspondance-lien { color: var(--accent-texte); text-decoration: none; font-size: 0.85rem; margin-left: 0.6rem; }
.correspondance-lien:hover { text-decoration: underline; }

/* ---------- Bilan du rapprochement : points forts ---------- */
.correspondance-bilan {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.6rem;
    margin-bottom: 0.6rem;
    font-size: 0.86rem;
    line-height: 1.45;
}

.bilan-titre { font-weight: 700; white-space: nowrap; }
.bilan-fort { color: var(--vert); }

/* Tableau unique des critères : ce que le client demande / ce que le bien
   propose / verdict en icône. Reprend le style .tableau du site (fond carte,
   arrondis, en-têtes), en plus compact. */
.tableau-criteres { border: 1px solid var(--bord); }

.tableau-criteres th,
.tableau-criteres td { padding: 0.42rem 0.7rem; font-size: 0.86rem; }

.tableau-criteres td + td { border-left: 1px solid var(--bord); }

.tableau-criteres .col-verdict { width: 1%; white-space: nowrap; text-align: center; }

/* Ligne de famille (Surfaces, Équipements...) : sépare les groupes de critères.
   Majuscules et couleur du texte principal, comme les en-têtes de colonnes. */
.tableau-criteres .ligne-categorie td,
.tableau-fiche .ligne-categorie td {
    font-size: 0.71rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--texte);
    background: var(--gris-clair);
    border-left: none;
    width: auto;
    padding: 0.3rem 0.7rem;
}

.tableau-criteres .ligne-categorie:hover td,
.tableau-fiche .ligne-categorie:hover td { background: var(--gris-clair); }

/* Fiche du bien : tableau complet des caractéristiques, par famille. */
.tableau-fiche { border: 1px solid var(--bord); }

.tableau-fiche td { padding: 0.42rem 0.7rem; font-size: 0.9rem; }

.tableau-fiche tr:not(.ligne-categorie) td:first-child { width: 240px; color: var(--gris); }

.tableau-fiche td + td { border-left: 1px solid var(--bord); }

/* Verdict d'un critère : pastille ronde ✓ / ≈ / ✕. */
.verdict {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.45rem;
    height: 1.45rem;
    padding: 0;
    box-sizing: border-box;
    border-radius: 50%;
    font-size: 0.85rem;
    font-weight: 700;
    /* Centre le glyphe : sans hauteur de ligne fixe, ✓ ≈ ✕ flottent au-dessus
       du milieu (leur boîte suit la ligne de base du texte). */
    line-height: 1;
    cursor: help;
}

.verdict-ok { background: var(--vert-fond); color: var(--vert); border: 1.5px solid var(--vert); }
.verdict-partiel { background: var(--orange-fond); color: var(--orange); border: 1.5px solid var(--orange); }
.verdict-ko { background: var(--rouge-fond); color: var(--rouge); border: 1.5px solid var(--rouge); }

/* ---------- Pastille de score de compatibilité ---------- */
.score-match {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.25rem 0.7rem 0.25rem 0.3rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Pilule claire « 100 % » : chiffre foncé lisible sur tous les fonds de badge. */
.score-match-valeur {
    display: inline-flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.05rem;
    padding: 0.16rem 0.6rem;
    border-radius: 999px;
    background: #ffffff;
    color: #12161f;
    font-size: 0.92rem;
    font-weight: 800;
    line-height: 1.15;
}

/* « % » légèrement plus petit et discret que le chiffre. */
.score-match-pct { font-size: 0.72em; font-weight: 700; opacity: 0.75; }

.score-match-libelle { font-weight: 700; }

/* ---------- Réglage des poids du moteur (admin) ---------- */
.grille-poids {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.1rem 1.6rem;
    margin-top: 0.8rem;
}

.poids-critere { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.poids-critere > label { font-weight: 600; font-size: 0.92rem; }
.poids-critere.neutralise { opacity: 0.6; }

.poids-reglage { display: flex; align-items: center; gap: 0.7rem; }
.poids-reglage input[type="range"] { flex: 1; accent-color: var(--accent); min-width: 0; }

.poids-valeur {
    width: 4.2rem;
    flex-shrink: 0;
    padding: 0.3rem 0.4rem;
    text-align: center;
    border: 1px solid var(--bord-champ);
    border-radius: 8px;
    background: var(--carte);
    color: var(--texte);
    font-family: inherit;
    font-weight: 700;
}

/* Message joint à une proposition : plus grand et plus confortable à écrire. */
.champ textarea.message-proposition {
    font-size: 1.02rem;
    line-height: 1.55;
    min-height: 130px;
    padding: 0.75rem 0.9rem;
    resize: vertical;
}

/* Page de connexion */
.carte-connexion { max-width: 460px; margin: 2.5rem auto; }

/* Le titre de ces pages courtes (connexion, mot de passe, confirmation) est le
   <h1> de la page — il en faut un et un seul — mais garde la taille d'un
   sous-titre : la carte est étroite, un h1 à sa taille par défaut y écraserait
   tout le reste. */
.carte-connexion > h1 { font-size: 1.5rem; margin-top: 0; }

.onglets-connexion { display: flex; gap: 0.5rem; margin-bottom: 1.25rem; }

/* Champ en lecture seule (ex. raison sociale renseignée automatiquement). */
input[readonly] { opacity: 0.75; cursor: default; }

.onglets-connexion button {
    flex: 1;
    padding: 0.55rem;
    border-radius: 10px;
    border: 1px solid var(--bord);
    background: var(--carte);
    color: var(--texte);
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}

.onglets-connexion button.actif {
    background: var(--degrade);
    color: var(--sur-accent);
    border-color: transparent;
}

/* Onglets de contenu d'une page (ex. Recherches clients) : même style que les
   onglets de connexion, mais largeur libre et retour à la ligne sur mobile. */
.onglets-page { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.25rem; }

/* Barre d'onglets portant une action à droite (ex. « + Nouvelle formule » sur
   la page Tarifs). L'action reste sur la même ligne que les onglets tant que la
   largeur le permet, et passe dessous sur mobile. */
.barre-onglets {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin: 0 0 1.25rem;
}

/* La marge basse est portée par le conteneur, pas par la liste d'onglets. */
.barre-onglets .onglets-page { margin-bottom: 0; }

.onglets-page button {
    padding: 0.55rem 1.1rem;
    border-radius: 10px;
    border: 1px solid var(--bord);
    background: var(--carte);
    color: var(--texte);
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}

.onglets-page button:hover { border-color: var(--accent); }

.onglets-page button.actif {
    background: var(--degrade);
    color: var(--sur-accent);
    border-color: transparent;
}

/* Explication de l'onglet actif, juste sous la barre d'onglets. */
.onglet-aide { color: var(--gris); margin: -0.75rem 0 1.1rem; font-size: 0.92rem; }

/* ==================================================================
   Bascule d'affichage tableau / cartes
   ================================================================== */
.bascule-vue {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0;
    border: none;
    background: none;
    font-family: inherit;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

.bascule-libelle {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--gris);
    transition: color 0.15s;
    white-space: nowrap;
}

.bascule-libelle.actif { color: var(--accent-texte); }

.bascule-piste {
    position: relative;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
    border: 1px solid var(--bord);
    border-radius: 999px;
    background: var(--gris-clair);
    transition: background 0.15s, border-color 0.15s;
}

.bascule-piste.droite { background: var(--degrade); border-color: transparent; }

.bascule-pastille {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--carte);
    box-shadow: var(--ombre);
    transition: transform 0.18s;
}

.bascule-piste.droite .bascule-pastille { transform: translateX(20px); }

.bascule-vue:focus-visible .bascule-piste { outline: 2px solid var(--accent); outline-offset: 2px; }


#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    color: #0f172a;
}

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

/* ==================================================================
   Images de fond par thème (les thèmes clairs ; « nuit » reste uni)
   ================================================================== */
[data-theme="ocean"] body,
[data-theme="emeraude"] body,
[data-theme="sunset"] body {
    background-size: cover;
    background-position: center;
    background-attachment: fixed;
    background-repeat: no-repeat;
}

[data-theme="ocean"] body { background-image: url("bg-ocean.svg"); }
[data-theme="emeraude"] body { background-image: url("bg-emeraude.svg"); }
[data-theme="sunset"] body { background-image: url("bg-sunset.svg"); }

/* ==================================================================
   Choix de la langue — rendu dans le menu ☰ (voir MainLayout).
   L'ancien menu déroulant autonome de la barre du haut a été retiré : ses
   règles (.selecteur-langue, .langue-bouton, .langue-code, .langue-voile,
   .langue-menu) ne servaient plus.
   ================================================================== */
.langue-choix {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px;
    background: transparent; border: none; border-radius: 9px;
    color: var(--texte); font-size: 14px; text-align: start;
    cursor: pointer; transition: background .12s;
}

.langue-choix:hover { background: var(--gris-clair); }

.langue-choix.actif { background: color-mix(in srgb, var(--accent) 16%, transparent); font-weight: 700; }

/* Police d'emojis couleur pour afficher les drapeaux même sur Windows,
   qui n'a pas de police de drapeaux native. Repli sur les emojis système ailleurs. */
.langue-drapeau {
    font-size: 17px;
    font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
}

/* Bouton favori (cœur) posé en haut à droite d'une carte d'annonce. */
.bouton-favori {
    position: absolute; top: 8px; right: 8px; z-index: 3;
    width: 34px; height: 34px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0; font-size: 17px; line-height: 1;
    background: rgba(255, 255, 255, .9);
    border: none; border-radius: 50%;
    cursor: pointer; box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
    transition: transform .12s, background .12s;
}

.bouton-favori:hover { transform: scale(1.12); background: #fff; }
.bouton-favori.actif { background: #fff; }

/* Variante « en favori » du bouton de la page détail. */
.btn.favori-actif {
    border-color: var(--rouge, #e11d48);
    color: var(--rouge, #e11d48);
}

/* ==================================================================
   Page /documentation (admin) : onglets et cadre d'affichage des
   documents HTML servis depuis le dossier docs/ du dépôt (hors wwwroot), via
   un lien signé — voir Program.cs, point d'entrée /docs/{nom}.
   ================================================================== */
.doc-onglets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 1.2rem 0 0.6rem;
}

.doc-legende {
    color: var(--gris);
    font-size: 0.9rem;
    margin-bottom: 0.9rem;
}

.doc-cadre {
    border: 1px solid var(--bord);
    border-radius: 14px;
    overflow: hidden;
    background: var(--carte);
    height: calc(100vh - 320px);
    min-height: 520px;
}

.doc-cadre iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

/* ==================================================================
   « Déposer ma recherche » — deux colonnes et panneau de synthèse collant
   ==================================================================
   Le formulaire tient la colonne de gauche ; le récapitulatif de ce qui a été
   coché reste sous les yeux, à droite, pendant qu'on descend dans le formulaire.

   POURQUOI « COLLANT » ET NON « PARALLAXE ».
   La demande parlait de parallaxe, c'est-à-dire d'un panneau défilant à une
   vitesse différente du reste. Un vrai parallaxe se pilote en JavaScript, au
   rythme des événements de défilement : il saccade sur pavé tactile et sur les
   défilements à inertie (l'événement arrive après le rendu, le panneau court
   derrière la page), il se désynchronise au saut d'ancre et au zoom, et il doit
   être entièrement débranché sous « prefers-reduced-motion » — donc écrit deux
   fois. « position: sticky » donne exactement l'effet recherché — le panneau
   paraît flotter au-dessus du formulaire qui défile — nativement, sans une
   ligne de script, avec le même comportement sur tous les périphériques de
   défilement. L'entrée en fondu ci-dessous suffit à le faire « arriver ».
   ------------------------------------------------------------------ */

/* Hauteur réelle de « .topbar » au-delà de 900 px, RELEVÉE sur les règles de ce
   fichier et non devinée (html { font-size: 18px }, donc 1 rem = 18 px) :
     padding vertical ..... 2 × 0.5rem ......................... 18 px
     1re ligne ............ .brand .logo, 76 px ................ 76 px
     interligne ........... gap vertical 0.35rem ................ 6 px
     2e ligne (nav) ....... padding-top 0.5rem (9) + border-top (1)
                            + onglet 2 × 0.42rem + texte 0.92rem ≈ 47 px
                                                                 -------
                                                                 ≈ 147 px
   Arrondi à 148 px. La barre de messages n'y ajoute rien : au-delà de 900 px
   elle partage la première ligne (flex: 1) et reste plus basse que le logo. */
:root { --hauteur-topbar: 148px; }

/* Mise en page à deux colonnes des formulaires de dépôt : la recherche du
   client (NouvelleRecherche), mais aussi les deux formulaires de bien
   (ProposerBien, AgentBiens), qui partagent depuis le même panneau collant
   (RecapBien). Les noms de classe gardent le préfixe « recherche- » : c'est
   là qu'ils sont nés, et les renommer ne changerait rien à l'écran. */
.recherche-mise-en-page {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.6rem;
    /* Sans « start », l'étirement par défaut de la grille donnerait au panneau
       la hauteur entière de la rangée : son bloc couvrirait déjà toute la
       course de défilement et « sticky » n'aurait plus rien à parcourir. */
    align-items: start;
}

/* Empêche une valeur longue (nom de ville, puce de critère) d'élargir la
   colonne au-delà de sa part de grille : « auto » est le minimum implicite
   d'une piste 1fr, « minmax(0, 1fr) » côté grille et « min-width: 0 » ici. */
.recherche-formulaire { min-width: 0; }

.recherche-recap {
    /* Masqué en dessous du seuil, et non replié sous le formulaire : sur
       téléphone la place manque, et un récapitulatif qu'il faut dépasser avant
       d'atteindre le bouton d'envoi dessert le formulaire au lieu de l'aider. */
    display: none;
    flex-direction: column;
    position: sticky;
    /* Se cale juste sous la barre du haut, elle-même collante : sans ce
       décalage le panneau viendrait glisser dessous et serait tronqué. */
    top: calc(var(--hauteur-topbar) + 0.9rem);
    /* Borné à la hauteur de la fenêtre : un récapitulatif long dépasserait
       sinon par le bas sans qu'aucun défilement puisse en montrer la fin — le
       panneau étant collé, il ne remonte jamais. Le reliquat de 5,5rem laisse
       passer les boutons de défilement fixes, en bas à droite de l'écran. */
    max-height: calc(100vh - var(--hauteur-topbar) - 5.5rem);
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 16px;
    padding: 1.25rem 1.35rem;
    box-shadow: var(--ombre);
    animation: recap-entree 0.35s ease-out;
}

/* Seule requête « min-width » du fichier, et c'est délibéré : la consigne est
   que le panneau n'apparaisse qu'À PARTIR de 1200 px. Transcrite en max-width,
   il faudrait borner à 1199.98px pour ne pas laisser un trou entre 1199 et
   1200 px — moins lisible que d'écrire le seuil tel qu'il a été demandé.

   PLACÉE APRÈS « .recherche-recap », et c'est tout l'enjeu : une requête de
   média n'ajoute AUCUNE spécificité. « @media … { .recherche-recap { display:
   flex } } » et « .recherche-recap { display: none } » pèsent donc exactement
   le même poids (0,1,0), et c'est la dernière écrite qui l'emporte. Écrite
   au-dessus, la requête était intégralement neutralisée par le « display: none »
   qui la suivait : le panneau restait invisible à toute largeur, tandis que la
   piste de 23 rem, elle, était bien réservée — d'où une colonne vide à droite
   du formulaire. Ne pas remonter ce bloc. */
@media (min-width: 1200px) {
    .recherche-mise-en-page { grid-template-columns: minmax(0, 1fr) 23rem; }
    .recherche-recap { display: flex; }
}

/* Fondu d'entrée écrit en « from → to » plutôt qu'avec un « opacity: 0 » posé
   sur l'élément : si l'animation ne joue pas (durée ramenée à 0,01 ms par la
   garde « prefers-reduced-motion » en fin de fichier, ou moteur qui la
   refuse), le panneau reste visible au lieu de disparaître. */
@keyframes recap-entree {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Titre du panneau : même traitement que celui d'une « .form-section », pour
   que les deux colonnes se lisent comme un seul écran. « flex: 0 0 auto » le
   maintient hors de la zone qui défile : c'est le seul repère fixe du panneau. */
.recherche-recap > h2,
.recherche-recap > h3,
.recherche-recap > h4 {
    flex: 0 0 auto;
    margin: 0 0 0.8rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--bord);
    color: var(--accent-texte);
    font-size: 1.05rem;
}

.recherche-recap-corps {
    /* Ne grandit pas (grow 0) : un récapitulatif court garde un panneau court,
       sans bordure flottant loin sous le dernier critère. Il rétrécit en
       revanche, et « min-height: 0 » est ce qui l'y autorise — le minimum
       « auto » d'un élément flex l'empêcherait de passer sous la hauteur de son
       contenu, et c'est alors le panneau entier qui déborderait. */
    flex: 0 1 auto;
    min-height: 0;
    max-height: calc(100vh - var(--hauteur-topbar) - 10rem);
    overflow-y: auto;
    /* Gouttière réservée en permanence : sans elle, l'apparition de l'ascenseur
       au premier critère coché décalerait d'un coup tout le contenu du panneau. */
    scrollbar-gutter: stable;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--texte);
}

/* État « rien de coché » : encadré en pointillés pour dire que la place est
   réservée et qu'elle se remplira, là où un simple texte gris laisserait
   croire à un panneau cassé. Le pointillé prend « --bord-champ » (3:1 sur les
   cinq thèmes) et non « --bord » (1,1 à 1,4:1), invisible ici. */
.recherche-recap-vide {
    margin: 0;
    padding: 1.1rem 0.9rem;
    border: 1px dashed var(--bord-champ);
    border-radius: 10px;
    color: var(--gris);
    font-size: 0.9rem;
    line-height: 1.5;
    text-align: center;
}

/* Prix moyen au m² : posé sur « --gris-clair » et non sur une teinte d'accent.
   Un fond « color-mix(accent 8 %, carte) » faisait tomber le texte gris à
   4,40:1 sur « emeraude » ; sur --gris-clair il reste à 4,54:1 au pire. */
.recherche-recap-estimation {
    flex: 0 0 auto;
    margin-top: 0.9rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--bord);
    border-radius: 10px;
    background: var(--gris-clair);
    color: var(--gris);
    font-size: 0.9rem;
    line-height: 1.45;
}

.recherche-recap-estimation b,
.recherche-recap-estimation strong {
    display: block;
    color: var(--accent-texte);
    font-size: 1.15rem;
    line-height: 1.3;
    /* Chiffres à chasse fixe : la valeur se recalcule à chaque frappe, et des
       chiffres de largeurs différentes la feraient tressauter. */
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------
   Curseur de rayon
   ------------------------------------------------------------------ */
.champ-rayon {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.champ-rayon input[type="range"] { flex: 1 1 auto; min-width: 0; }

/* Largeur minimale figée et chiffres à chasse fixe : sans cela la valeur
   change de largeur en passant de « 9 km » à « 100 km » et pousse le curseur
   d'un côté à l'autre pendant qu'on le déplace. */
.rayon-valeur {
    flex: 0 0 auto;
    min-width: 4.6rem;
    text-align: right;
    font-weight: 700;
    color: var(--accent-texte);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ==================================================================
   Curseurs (input[type="range"]) — habillage commun aux deux moteurs
   ==================================================================
   Aucun style de piste ni de pouce n'existait : seuls « width » et
   « accent-color » étaient posés, ce qui laissait aux navigateurs un rendu
   natif dont ni le contraste ni la taille de cible ne sont maîtrisés. Les
   règles ci-dessous valent pour TOUS les curseurs du site (rayon d'action,
   poids du matching, durée du simulateur) : un habillage unique vaut mieux
   qu'une exception réservée à un écran.

   Le sélecteur est dédoublé avec « .champ » : « .champ input » impose une
   bordure, un fond et un rembourrage de zone de saisie, qui n'ont aucun sens
   sur un curseur — il faut donc l'emporter en spécificité, pas seulement en
   ordre d'écriture. */
input[type="range"],
.champ input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    /* Hauteur du pouce et non de la piste : elle donne au cadre de focus une
       forme lisible et une cible confortable à la souris. */
    height: 1.4rem;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    accent-color: var(--accent);
    cursor: pointer;
}

/* Les pseudo-éléments préfixés ne peuvent PAS être regroupés dans une même
   liste de sélecteurs : un seul nom inconnu invalide la règle entière et les
   deux moteurs la jettent. D'où quatre blocs quasi identiques, volontairement. */

/* --- Blink / WebKit --- */
input[type="range"]::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: 999px;
    /* « --bord-champ » et non « --bord » : la piste est un élément d'interface,
       la WCAG 1.4.11 lui demande 3:1. --bord-champ est calibré pour cela
       (3,02 à 3,05:1 sur fond de carte), --bord plafonne à 1,4:1. */
    background: var(--bord-champ);
}

input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--accent);
    /* Double cerne : l'anneau clair détache le pouce de la piste (l'accent seul
       ne donnait que 1,18:1 contre elle sur « sunset »), le liseré extérieur
       le détache du fond de la carte. Chaque frontière tient ainsi les 3:1. */
    border: 2px solid var(--carte);
    box-shadow: 0 0 0 1px var(--bord-champ);
    /* WebKit aligne le HAUT du pouce sur le haut de la piste : (6 − 20) / 2
       le recentre. Firefox centre le sien tout seul, d'où l'absence de marge
       dans le bloc ::-moz-range-thumb. */
    margin-top: -7px;
}

/* --- Gecko --- */
input[type="range"]::-moz-range-track {
    height: 6px;
    border: none;
    border-radius: 999px;
    background: var(--bord-champ);
}

/* Portion parcourue, colorée : Firefox sait la peindre nativement. Blink n'a
   pas d'équivalent — il faudrait recalculer un dégradé à chaque saisie, donc
   du JavaScript. Le curseur reste parfaitement lisible sans, la position du
   pouce et la valeur chiffrée à côté portant déjà l'information. */
input[type="range"]::-moz-range-progress {
    height: 6px;
    border-radius: 999px;
    background: var(--accent);
}

input[type="range"]::-moz-range-thumb {
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--carte);
    box-shadow: 0 0 0 1px var(--bord-champ);
}

/* La règle « .champ input:focus » (fin de la section Formulaires) coupe le
   contour et pose un anneau de 3 px calibré pour une zone de saisie
   rectangulaire : sur un curseur il encadre une ligne de 6 px de haut et
   n'indique rien. On la neutralise, puis on rend un vrai contour au clavier.
   Dans chacune des deux règles, c'est le sélecteur préfixé par « .champ » qui
   tranche : (0,3,1) contre les (0,2,1) de « .champ input:focus ». Ce n'est donc
   pas l'ordre d'écriture qui décide, et déplacer ce bloc ne casserait rien. */
input[type="range"]:focus,
.champ input[type="range"]:focus {
    outline: none;
    box-shadow: none;
}

/* La règle « :focus-visible » commune, en fin de fichier, s'applique bien à un
   curseur (focalisable au clavier, donc jamais filtré par le
   « [tabindex="-1"] ») — mais elle perdait contre « .champ input:focus ».
   Elle est reprise ici à l'identique, avec un décalage un peu plus large pour
   ne pas venir mordre sur le cerne du pouce. */
input[type="range"]:focus-visible,
.champ input[type="range"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* ==================================================================
   Accessibilité transverse
   ================================================================== */

/* Texte réservé aux lecteurs d'écran : hors de l'écran mais bien lu, à la
   différence de « display: none » qui le supprimerait de l'arbre d'accessibilité.
   Sert aux boutons réduits à une icône et aux libellés de tableaux. */
.lecteur-ecran-seul {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Lien d'évitement : caché tant qu'il n'a pas le focus, il apparaît en haut à
   gauche à la première tabulation et mène droit au contenu principal. */
.lien-evitement {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 5000;
    padding: 0.7rem 1.2rem;
    background: var(--carte);
    color: var(--accent-texte);
    border: 2px solid var(--accent);
    border-radius: 0 0 10px 0;
    font-weight: 700;
    text-decoration: none;
}

.lien-evitement:focus { left: 0; }

/* Dialogue de reconnexion du circuit Blazor (voir App.razor).

   MASQUÉ PAR DÉFAUT : l'élément est présent dans la page dès le premier rendu,
   c'est le runtime qui pose « components-reconnect-show » quand la connexion
   tombe. Sans ce display:none, il s'afficherait en permanence. */
.dialogue-reconnexion { display: none; }

/* Le runtime ajoute l'une de ces classes ; « hide » est reposé au retour. */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
    position: fixed;
    inset: 0;
    /* Au-dessus de tout, listes de saisie prédictive comprises (z-index 1200). */
    z-index: 4000;
    align-items: center;
    justify-content: center;
    /* Voile plutôt qu'aplat opaque : le visiteur voit que sa page est toujours
       là, seulement suspendue. Un rectangle blanc plein donnait l'impression
       d'avoir quitté le site. */
    background: rgba(18, 22, 31, 0.55);
    padding: 1rem;
}

#components-reconnect-modal.components-reconnect-hide { display: none; }

.dialogue-reconnexion-boite {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    max-width: 26rem;
    padding: 1rem 1.3rem;
    background: var(--carte);
    color: var(--texte);
    border: 1px solid var(--bord);
    border-left: 4px solid var(--accent);
    border-radius: 12px;
    box-shadow: 0 10px 34px rgba(0, 0, 0, .32);
    font-size: 0.95rem;
    line-height: 1.4;
}

/* Un seul des deux messages s'affiche, selon l'état posé par le runtime :
   tant qu'il retente, puis quand il abandonne (le script recharge alors). */
.reconnexion-en-cours,
.reconnexion-echec { display: none; }

#components-reconnect-modal.components-reconnect-show .reconnexion-en-cours,
#components-reconnect-modal.components-reconnect-failed .reconnexion-echec,
#components-reconnect-modal.components-reconnect-rejected .reconnexion-echec {
    display: inline;
}

.dialogue-reconnexion-rond {
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    border: 2px solid var(--bord);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: reconnexion-tourne 0.9s linear infinite;
}

@keyframes reconnexion-tourne { to { transform: rotate(360deg); } }

/* Respect du réglage système : une animation en boucle sur un écran de panne
   est exactement ce que ce réglage vise. Le rond reste, il ne tourne plus. */
@media (prefers-reduced-motion: reduce) {
    .dialogue-reconnexion-rond { animation: none; }
}

/* Bandeau d'annonce (réglé dans /admin/contenus).

   Sur l'aplat d'accent, avec --sur-accent comme encre : c'est la seule paire du
   thème garantie lisible dans les deux modes. Écrire du blanc sur cet or clair
   tomberait sous le contraste minimal en thème clair — le site a déjà cette
   variable pour cette raison exacte, elle sert ici aussi.

   Pas de position: sticky : le ruban défile avec la page. Collé en haut, il
   volerait une bande de l'écran sur chaque page et pour toujours, ce qui coûte
   cher sur téléphone. */
.bandeau-annonce {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.6rem 1rem;
    padding: 0.7rem 3rem 0.7rem 1.2rem;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
    color: var(--sur-accent);
    /* Le bouton de fermeture est positionné par rapport à ce conteneur. */
    position: relative;
    text-align: center;
}

.bandeau-texte {
    font-weight: 600;
    line-height: 1.4;
}

/* Le bouton d'action hérite de .btn-principal, dont le fond est justement
   l'accent : sur ce même aplat il disparaîtrait. On l'inverse — encre du
   bandeau en fond, accent en texte. */
.bandeau-annonce .btn-principal {
    background: var(--sur-accent);
    color: var(--accent-2);
    border-color: var(--sur-accent);
    white-space: nowrap;
}

.bandeau-fermer {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: 0;
    color: inherit;
    font-size: 1.1rem;
    line-height: 1;
    /* 44 px de cible tactile : sous cette taille, la croix se rate au doigt. */
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
    opacity: 0.75;
}

.bandeau-fermer:hover { opacity: 1; }

@media (max-width: 700px) {
    /* Le texte prend toute la largeur et le bouton passe dessous : côte à côte,
       ils se réduisaient l'un l'autre jusqu'à deux mots par ligne. */
    .bandeau-annonce {
        flex-direction: column;
        gap: 0.5rem;
        padding-right: 2.6rem;
        font-size: 0.92rem;
    }
}

/* Indicateur de focus commun. Le contour par défaut des navigateurs se perd sur
   les fonds sombres du site ; celui-ci reprend l'accent du thème, avec un
   décalage pour rester lisible sur les éléments à fond plein. Il ne vise que
   « :focus-visible » : un clic à la souris ne le déclenche pas.

   « tabindex » est filtré sur la valeur -1, et c'est indispensable. Un élément
   à tabindex="-1" n'est PAS atteignable au clavier : il ne reçoit le focus que
   par du code, pour amener l'utilisateur quelque part. L'entourer d'un cadre
   n'apprend donc rien à personne, et se voit au pire moment — Routes.razor
   déclare <FocusOnNavigate Selector="h1" />, qui pose un tabindex="-1" sur le
   titre de chaque page et lui donne le focus à l'arrivée (c'est ainsi que les
   lecteurs d'écran annoncent le changement de page). Sans ce filtre, tout
   visiteur voit un cadre doré autour du titre en arrivant sur le site, jusqu'à
   son premier clic. La règle « h1:focus { outline: none } », plus haut, ne
   suffit pas à l'en empêcher : « [tabindex]:focus-visible » lui est supérieur
   en spécificité et repasse devant.

   Même raison pour <main tabindex="-1"> (cible du lien d'évitement) et pour la
   boîte de confirmation, qui reçoivent eux aussi un focus purement programmatique. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Respect du réglage système « réduire les animations ». Les blocs de la
   bannière d'accueil ont leur propre garde plus haut ; celle-ci couvre tout le
   reste — apparition des boîtes de dialogue, survols qui déplacent ou
   agrandissent, transitions de bascule. Les états d'arrivée sont conservés :
   seule la durée tombe à zéro. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    /* Les survols qui déplacent ou agrandissent sont neutralisés : sans durée,
       ils « sautent » d'un coup, ce qui est justement ce qu'on veut éviter. */
    .carte-annonce:hover,
    .btn-principal:hover:not([disabled]),
    .btn-ordre:hover:not(:disabled),
    .boutons-defilement button:hover,
    .footer-reseau:hover,
    .barre-icone:hover,
    .bouton-favori:hover,
    .galerie img:hover,
    .pastille:hover,
    .selecteur-energie-case:hover { transform: none; }
}

/* ==================================================================
   Messagerie instantanée (Components/Partage/WidgetChat.razor)

   Fenêtre flottante en bas à droite, déplaçable par sa barre de titre,
   redimensionnable par son coin haut-gauche, agrandissable d'un clic.
   Couche 960 : au-dessus des boutons de défilement (950), sous les boîtes
   de dialogue (1000) — une confirmation doit pouvoir la recouvrir.
   Sur petit écran, elle devient un volet fixé en bas, non déplaçable.
   ================================================================== */
.chat-lanceur {
    position: fixed;
    /* Dans la colonne des boutons de défilement, juste au-dessus de la flèche
       « remonter » : même bord droit (1,1 rem), même diamètre (42 px), et un
       bas calé au-dessus des deux boutons (2 × 42 px) et de leurs écarts
       (2 × 0,45 rem) — voir .boutons-defilement. */
    right: 1.1rem;
    bottom: calc(1.2rem + 84px + 0.9rem);
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: none;
    background: var(--degrade);
    color: var(--sur-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: var(--ombre-forte);
    z-index: 960;
    transition: transform 0.15s ease;
}

.chat-lanceur:hover { transform: translateY(-2px); }

.ico-chat { width: 1.45rem; height: 1.45rem; }

/* Même dessin que la pastille de la cloche, mais posée sur un bouton rond. */
.chat-pastille {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: #e11d48;
    border-radius: 999px;
    box-shadow: 0 0 0 2px var(--fond);
}

.chat-panneau {
    position: fixed;
    /* À gauche de la colonne des boutons (lanceur compris), pour ne recouvrir
       aucun d'eux tant qu'on ne l'a pas déplacée ; le bas est celui de la
       colonne. */
    right: 4.4rem;
    bottom: 1.2rem;
    width: 370px;
    /* Les bornes ne laissent qu'une marge : la fenêtre peut être tirée ou
       agrandie jusqu'à presque tout l'écran (voir sedesChat.dimensionner). */
    max-width: calc(100vw - 1rem);
    height: 540px;
    max-height: calc(100vh - 1rem);
    display: flex;
    flex-direction: column;
    background: var(--carte);
    border: 1px solid var(--bord);
    border-radius: 16px;
    box-shadow: var(--ombre-forte);
    z-index: 960;
    overflow: hidden;
}

.chat-en-deplacement { opacity: 0.92; }

/* Fenêtre agrandie (bouton de la barre de titre) : une taille de lecture
   confortable, jamais au-delà de l'écran. Une taille tirée à la main est
   posée en style en ligne par le JS et l'emporterait : sedesChat.ajuster
   l'efface au moment de basculer. */
.chat-panneau-grand {
    width: min(760px, calc(100vw - 1rem));
    height: min(85vh, calc(100vh - 1rem));
}

/* Coin de redimensionnement, en haut à gauche — le seul coin qui a de la place
   devant lui quand la fenêtre est à sa place d'origine. Un petit crochet ┌,
   et le curseur qui dit le reste. « touch-action: none » pour que le doigt
   redimensionne au lieu de faire défiler la page. */
.chat-redim {
    position: absolute;
    top: 0;
    left: 0;
    width: 22px;
    height: 22px;
    z-index: 2;
    cursor: nwse-resize;
    touch-action: none;
    color: var(--topbar-texte);
    opacity: 0.55;
}

.chat-redim::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 5px;
    width: 9px;
    height: 9px;
    border-top: 2px solid currentColor;
    border-left: 2px solid currentColor;
    border-top-left-radius: 3px;
}

.chat-redim:hover { opacity: 1; }

/* Barre de titre : c'est la poignée. « touch-action: none » pour que le doigt
   déplace la fenêtre au lieu de faire défiler la page. */
.chat-entete {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.6rem 0.55rem 0.9rem;
    background: var(--topbar);
    color: var(--topbar-texte);
    border-bottom: 1px solid var(--bord);
    cursor: move;
    user-select: none;
    touch-action: none;
}

.chat-entete-titre {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.chat-entete-titre strong,
.chat-entete-titre small {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-entete-titre small { font-size: 0.74rem; opacity: 0.8; }

.chat-entete-btn {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    font-size: 1.1rem;
    cursor: pointer;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Pictogrammes des boutons de la barre (agrandir, réduire, détacher). */
.ico-chat-entete { width: 1.05rem; height: 1.05rem; }

/* Enveloppe du bouton « fenêtre séparée » (voir WidgetChat) : invisible dans
   la rangée, elle ne porte que le gestionnaire de clic natif. */
.chat-detacher { display: inline-flex; flex: 0 0 auto; }

.chat-entete-btn:hover { background: color-mix(in srgb, var(--topbar-texte) 15%, transparent); }

/* Liste des fils. */
.chat-corps {
    flex: 1;
    overflow-y: auto;
    padding: 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.chat-fil {
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.1rem 0.5rem;
    padding: 0.55rem 0.7rem;
    text-align: left;
    background: var(--fond);
    border: 1px solid var(--bord);
    border-radius: 12px;
    color: var(--texte);
    font-family: inherit;
    font-size: 0.92rem;
    cursor: pointer;
}

.chat-fil:hover { border-color: var(--accent); }

.chat-fil-nom {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chat-fil-nonlu .chat-fil-nom { font-weight: 700; color: var(--accent-texte); }

.chat-fil-date { color: var(--gris); font-size: 0.72rem; white-space: nowrap; }

.chat-fil-apercu {
    grid-column: 1 / -1;
    color: var(--gris);
    font-size: 0.82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding-right: 1.6rem;
}

.chat-pastille-fil { top: auto; right: 0.6rem; bottom: 0.55rem; }

.chat-section {
    margin: 0.7rem 0 0.15rem;
    color: var(--gris);
    font-size: 0.74rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.chat-vide {
    margin: auto;
    padding: 1.2rem 0.8rem;
    color: var(--gris);
    text-align: center;
    line-height: 1.5;
}

/* Fil ouvert : bulles. */
.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 0.7rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    background: var(--fond);
}

.chat-jour {
    align-self: center;
    margin: 0.4rem 0 0.2rem;
    color: var(--gris);
    font-size: 0.72rem;
}

.chat-bulle {
    max-width: 82%;
    padding: 0.45rem 0.65rem;
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    font-size: 0.92rem;
}

.chat-bulle-texte { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.4; }

.chat-bulle-heure { align-self: flex-end; font-size: 0.68rem; opacity: 0.75; }

/* Mes messages sur l'accentuation : texte en « sur-accent », jamais en blanc
   (voir la note du bouton principal). */
.chat-bulle-moi {
    align-self: flex-end;
    background: var(--accent);
    color: var(--sur-accent);
    border-bottom-right-radius: 4px;
}

.chat-bulle-autre {
    align-self: flex-start;
    background: var(--carte);
    color: var(--texte);
    border: 1px solid var(--bord);
    border-bottom-left-radius: 4px;
}

/* Zone de saisie. */
.chat-pied {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.4rem;
    padding: 0.55rem;
    border-top: 1px solid var(--bord);
}

.chat-saisie {
    flex: 1;
    min-width: 0;
    box-sizing: border-box;
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--bord-champ);
    border-radius: 10px;
    font-size: 0.92rem;
    font-family: inherit;
    background: var(--fond);
    color: var(--texte);
    resize: none;
}

.chat-saisie:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

.chat-envoyer { padding: 0.5rem 0.7rem; display: inline-flex; align-items: center; }

.chat-blocage { margin: 0; color: var(--gris); font-size: 0.85rem; line-height: 1.45; }

.chat-erreur { flex-basis: 100%; margin: 0.2rem 0 0; color: var(--rouge); font-size: 0.82rem; }

@media (max-width: 560px) {
    /* Volet fixé en bas : la position et la taille mémorisées sont ignorées
       (voir sedesChat.restaurer), et le coin de redimensionnement disparaît. */
    .chat-panneau,
    .chat-panneau-grand {
        left: 0 !important;
        right: 0 !important;
        top: auto !important;
        bottom: 0 !important;
        width: 100% !important;
        max-width: 100%;
        height: 78vh !important;
        max-height: 78vh;
        border-radius: 16px 16px 0 0;
    }

    .chat-entete { cursor: default; touch-action: auto; }

    /* Ni coin de redimensionnement ni bouton « agrandir » : le volet occupe
       déjà toute la largeur et sa hauteur est imposée. */
    .chat-redim, .chat-btn-taille { display: none; }
}

/* Fenêtre séparée du navigateur (page /messagerie, mise en page
   LayoutMessagerie) : le panneau EST la fenêtre — il en occupe tout
   l'intérieur, sans bordure ni ombre, et ne se déplace pas : c'est le
   navigateur qui s'en charge. Écrit après la requête de média ci-dessus et
   avec « !important » pour l'emporter sur le volet de petit écran, dont les
   règles portent le même poids. */
.chat-panneau-detache,
.chat-panneau-detache.chat-panneau-grand {
    position: fixed;
    inset: 0 !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    max-height: none !important;
    border: none;
    border-radius: 0;
    box-shadow: none;
    z-index: 1;
}

.chat-panneau-detache .chat-entete { cursor: default; touch-action: auto; }

/* Fond de la fenêtre séparée : celui du site, sans quoi le corps du document
   (transparent) laisserait paraître le blanc du navigateur en thème sombre. */
.messagerie-detachee { min-height: 100vh; background: var(--fond); }

@media print {
    .chat-lanceur, .chat-panneau { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
    .chat-lanceur:hover { transform: none; }
}
