/* =====================================================================
   3M-Promotion — coque d'administration, direction « ardoise translucide ».

   Aucun style n'est écrit en ligne dans les gabarits : la politique de
   sécurité du site est à nonce, sans repli permissif, et un attribut
   style= y serait silencieusement bloqué. Tout vit ici.
   ===================================================================== */

:root {
    --slate:        #122634;
    --slate-soft:   rgba(18, 38, 52, 0.86);
    --slate-line:   rgba(255, 255, 255, 0.10);
    --slate-text:   #a8c0cf;
    --slate-hover:  rgba(255, 255, 255, 0.08);
    --slate-active: rgba(255, 255, 255, 0.15);

    --blue:       #0188CC;
    --blue-dark:  #015d8c;
    --blue-tint:  #e8f1f7;

    --page:   #f4f7f9;
    --card:   #ffffff;
    --line:   #e3eaef;
    --ink:    #122634;
    --ink-2:  #4a5c69;
    --ink-3:  #7d8d99;

    --ok:     #1f9d6b;
    --warn:   #d98324;
    --danger: #d24b4b;

    --radius: 10px;
    --side-w: 236px;
    --side-rail: 72px;
    --bar-h: 60px;

    --sans: 'Segoe UI', system-ui, -apple-system, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--page);
    color: var(--ink);
    font-family: var(--sans);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--blue-dark); }

/* ------------------------------ coque ------------------------------- */
.shell { min-height: 100vh; }

.side {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--side-w);
    background: var(--slate-soft);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-right: 1px solid var(--slate-line);
    display: flex;
    flex-direction: column;
    padding: 18px 12px;
    z-index: 20;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 8px 18px;
    color: #eaf3f8;
    font-weight: 600;
    letter-spacing: .2px;
}
.brand { text-decoration: none; transition: opacity .15s ease; }
.brand:hover { opacity: .85; }

/* Le mot-symbole, renversé en blanc : le logo est dessiné pour un fond clair,
   et le bandeau latéral est sombre. Un filtre plutôt qu'un second fichier —
   une variante blanche de plus à maintenir et à oublier de mettre à jour. */
.brand-mot { display: block; height: 26px; width: auto; filter: brightness(0) invert(1); }
.brand-carre { display: none; width: 28px; height: 28px; border-radius: 6px; flex: 0 0 auto; }

/* Conservé pour les gabarits qui n'ont pas encore de logo. */
.brand-mark {
    width: 28px; height: 28px;
    border-radius: 8px;
    background: var(--blue);
    flex: 0 0 auto;
}
.brand-text { font-size: 15px; white-space: nowrap; }

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 10px;
    border-radius: 8px;
    color: var(--slate-text);
    text-decoration: none;
    font-size: 14px;
    white-space: nowrap;
    transition: background .12s ease, color .12s ease;
}
.nav a:hover  { background: var(--slate-hover); color: #eaf3f8; }
.nav a.active { background: var(--slate-active); color: #ffffff; }
.nav svg { width: 19px; height: 19px; flex: 0 0 auto; }

.side-foot { margin-top: auto; padding: 12px 8px 0; border-top: 1px solid var(--slate-line); }
.side-user { color: #eaf3f8; font-size: 13px; }
.side-role { color: var(--slate-text); font-size: 12px; text-transform: lowercase; }

/* ----------------------------- contenu ------------------------------ */
.main { margin-left: var(--side-w); min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
    height: var(--bar-h);
    background: rgba(255, 255, 255, 0.84);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 24px;
    position: sticky;
    top: 0;
    z-index: 10;
}
.topbar h1 { font-size: 17px; font-weight: 600; margin: 0; flex: 1; }

.pill {
    font-size: 12px;
    background: var(--blue-tint);
    color: var(--blue-dark);
    padding: 4px 11px;
    border-radius: 999px;
    white-space: nowrap;
}

.content { padding: 24px; flex: 1; }
.content > :first-child { margin-top: 0; }

/* ------------------------------ blocs ------------------------------- */
.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 18px 20px;
    margin-bottom: 18px;
}
.card h2 { font-size: 16px; margin: 0 0 12px; font-weight: 600; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: 12px; margin-bottom: 18px; }
.stat { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
.stat-l { font-size: 12px; color: var(--ink-3); }
.stat-n { font-size: 24px; font-weight: 600; color: var(--blue-dark); }

table.grid { width: 100%; border-collapse: collapse; }
table.grid th {
    text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
    color: var(--ink-3); font-weight: 600; padding: 10px 14px; border-bottom: 1px solid var(--line);
}
table.grid td { padding: 12px 14px; border-bottom: 1px solid var(--line); font-size: 14px; }
table.grid tr:last-child td { border-bottom: 0; }
table.grid tbody tr:hover td { background: #fafcfd; }
/* `table.grid th` aligne à gauche avec une spécificité supérieure à `.num` :
   les en-têtes de colonnes chiffrées restaient donc à gauche pendant que
   leurs valeurs passaient à droite. On réaligne les deux ensemble — un
   nombre se lit par la droite, son titre doit le surplomber. */
.num,
table.grid th.num,
table.grid td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Colonne d'ouverture : largeur minimale, collée à droite. */
table.grid th.cell-action, table.grid td.cell-action { width: 1%; white-space: nowrap; text-align: right; }
.btn-ouvrir { font-size: 12.5px; padding: 5px 12px; font-weight: 700; color: var(--blue-dark); }
.btn-ouvrir:hover { border-color: var(--blue); background: var(--blue-tint); }
/* La ligne entière réagit : on comprend qu'elle mène quelque part avant
   d'avoir trouvé le bouton. */
table.grid tbody tr:hover .btn-ouvrir { border-color: var(--blue); background: var(--blue-tint); }
.cell-titre { font-weight: 600; }
.cell-titre a { color: inherit; text-decoration: none; }
.cell-titre a:hover { color: var(--blue-dark); }

.tag { font-size: 12px; background: var(--blue-tint); color: var(--blue-dark); padding: 3px 9px; border-radius: 6px; }
.muted { color: var(--ink-3); font-size: 13px; }

/* ----------------------------- contrôles ---------------------------- */
.btn {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid var(--line); background: var(--card); color: var(--ink);
    border-radius: 8px; padding: 9px 15px; font-size: 14px; font-family: var(--sans);
    cursor: pointer; text-decoration: none; transition: border-color .12s, background .12s;
}
.btn:hover { border-color: var(--blue); background: #f7fbfd; }
.btn-primary { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-dark); border-color: var(--blue-dark); }
.btn-block { width: 100%; justify-content: center; }

.field { display: block; margin-bottom: 14px; }
.field-label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; }
.field input, .field select, .field textarea {
    width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
    font-family: var(--sans); font-size: 14px; background: #fff; color: var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(1, 136, 204, .14);
}

.alert { padding: 12px 15px; border-radius: 9px; font-size: 14px; margin-bottom: 16px; }
.alert-error { background: #fbecec; color: #8c2f2f; }
.alert-ok    { background: #e7f6ef; color: #156a4c; }
.alert-info  { background: var(--blue-tint); color: var(--blue-dark); }

/* ------------------------- écrans d'identité ------------------------ */
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; background: var(--slate); }
.auth-card { width: 100%; max-width: 400px; background: var(--card); border-radius: 14px; padding: 30px 28px; }
.auth-card h1 { font-size: 19px; margin: 0 0 4px; }
.auth-sub { color: var(--ink-3); font-size: 14px; margin: 0 0 22px; }
.auth-brand {
    display: inline-flex; align-items: center; gap: 10px; margin-bottom: 20px;
    text-decoration: none; border-radius: 8px; padding: 2px;
    transition: opacity .15s ease;
}
.auth-brand img { display: block; height: 30px; width: auto; }
.auth-brand:hover { opacity: .75; }
.code-input { letter-spacing: 9px; font-size: 22px; text-align: center; font-variant-numeric: tabular-nums; }

/* ------------------------- suivi de projet -------------------------- */
.steps { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.step { border: 1px solid var(--line); border-radius: 12px; padding: 13px 15px; background: #fff; }
.step-now { border-color: var(--blue); box-shadow: 0 0 0 1px var(--blue) inset; }
.step-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.step-num {
    flex: 0 0 auto; width: 25px; height: 25px; border-radius: 50%;
    background: var(--blue-tint); color: var(--blue-dark);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700;
}
.step-now .step-num { background: var(--blue); color: #fff; }
.step-title { font-weight: 600; font-size: 14px; }
.step-desc { color: var(--ink-3); font-size: 13px; margin: 7px 0 0 34px; }
.step-tools { margin-left: auto; display: flex; gap: 4px; }
.step-tools form { display: inline; }

.todo { list-style: none; margin: 9px 0 0 34px; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.todo-item { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.todo-item form { display: inline-flex; }
.todo-label { flex: 1; }
.is-done .todo-label { color: var(--ink-3); text-decoration: line-through; }
.todo-side {
    font-size: 11px; color: var(--ink-3); background: #f2f5f7;
    padding: 2px 7px; border-radius: 5px; text-transform: lowercase;
}

/* La case à cocher est un bouton de formulaire : sans JavaScript en ligne,
   cocher est une vraie requête, donc une action tracée et protégée par jeton. */
.check {
    width: 20px; height: 20px; flex: 0 0 auto; cursor: pointer;
    border: 1.5px solid var(--line); border-radius: 5px; background: #fff;
    color: var(--blue-dark); font-size: 12px; line-height: 1;
    display: flex; align-items: center; justify-content: center; padding: 0;
}
.check:hover { border-color: var(--blue); }
.is-done .check { background: var(--blue); border-color: var(--blue); color: #fff; }
.check-ro { cursor: default; }

/* ------------------------ formulaires courts ------------------------ */
.inline-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 11px; }
.inline-form input[type="text"] { flex: 1 1 160px; min-width: 0; }
/* Un champ ne doit jamais être plus large que la carte qui le porte. */
.inline-form input, .inline-form select, .inline-form button { max-width: 100%; }
.inline-form input, .inline-form select {
    padding: 8px 11px; border: 1px solid var(--line); border-radius: 8px;
    font: inherit; font-size: 13px; background: #fff;
}
.inline-form input:focus, .inline-form select:focus { outline: none; border-color: var(--blue); }
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.row-actions form { display: inline; }

.btn-mini { padding: 4px 8px; font-size: 12px; line-height: 1.2; }
.btn-danger { color: #8c2f2f; }
.btn-danger:hover { border-color: #c45b5b; background: #fdf4f4; }

.field textarea { min-height: 80px; resize: vertical; font: inherit; }

/* --------------------------- messagerie ----------------------------- */
.thread li.from-promo  { background: var(--blue-tint); }
.thread li.from-client { background: #f2f5f7; }

/* ------------------------ gestion de chantier ----------------------- */
/* Un tableau dense ne rétrécit pas à l'infini : passé une certaine largeur il
   défile dans son propre cadre au lieu de pousser la page entière, ce qui
   faisait paraître tout l'écran cassé. `overscroll-behavior-x` empêche que le
   geste horizontal déclenche le retour arrière du navigateur une fois le bout
   du tableau atteint. */
.table-scroll { overflow-x: auto; overscroll-behavior-x: contain; margin: 0 -4px; padding: 0 4px; }

table.grid-dense th, table.grid-dense td { padding: 7px 9px; font-size: 12.5px; }
table.grid-dense .cell-wrap { max-width: 280px; white-space: normal; }
table.grid-dense td { white-space: nowrap; }

/* Provenance d'un montant. Ces fonds sont PERMANENTS : ils disent d'où vient
   le chiffre. La mise en évidence des lignes récentes ne doit jamais les
   effacer — d'où la spécificité plus forte que celle de .is-recent. */
table.grid td.val-calc   { background: #eaf4fb; }
table.grid td.val-manual { background: #d7ebf8; font-weight: 600; }

.etat { font-size: 11px; padding: 2px 7px; border-radius: 5px; background: #f2f5f7; color: var(--ink-3); }
.etat-ok   { background: #e7f6ef; color: #156a4c; }
.etat-warn { background: #fdf3e3; color: #8a5a12; }
.etat-err  { background: #fbecec; color: #8c2f2f; }

tr.is-duplicate > td { background: #fdf7ee; }

/* Ligne modifiée récemment : s'allume, puis s'éteint lentement. La transition
   porte la durée ; le script se contente de poser puis retirer la classe. */
/* L'extinction, une fois la classe retirée : plus rapide que l'allumage, pour
   que la ligne redevienne une ligne ordinaire sans qu'on l'attende. */
tr[data-recent] > td { transition: background-color 3s ease-out, box-shadow 3s ease-out; }
/* La ligne entière s'allume, cellules de montant comprises : c'est la LIGNE
   qui vient d'être ajoutée ou modifiée, et n'en éclairer qu'une partie oblige
   à chercher ce qui a bougé. Les fonds de provenance ne sont pas perdus — ils
   réapparaissent à mesure que la mise en évidence s'éteint.

   Vert tendre plutôt que bleu : le bleu sert déjà à dire d'où vient un
   montant, et deux bleus voisins pour deux sens différents se confondent.
   Le liseré doré marque le bord gauche — on repère la ligne du coin de l'œil
   même après avoir fait défiler. */
table.grid tr.is-recent > td { background: #e9f6e2; transition: background-color 30s linear; }
table.grid tr.is-recent > td:first-child {
    box-shadow: inset 3px 0 0 #d9b451;
    transition: background-color 30s linear, box-shadow 30s linear;
}

.actions-cell { white-space: nowrap; }
.actions-cell form { display: inline-flex; margin-right: 2px; }
/* Le champ de fichier est masqué derrière son libellé : un input brut dans un
   tableau dense le ferait exploser en largeur. */
.file-hidden { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
label.btn { cursor: pointer; }

/* --------------------------- espace client -------------------------- */
/* Valeur textuelle dans une tuile de chiffres : même emplacement, taille
   réduite, sinon un nom de commune déborde là où un nombre tenait. */
.stat-n.stat-sm { font-size: 16px; line-height: 1.35; font-weight: 600; }

.thread { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.thread li { background: var(--blue-tint); border-radius: 10px; padding: 11px 14px; font-size: 14px; }
.thread-who { display: block; font-weight: 600; color: var(--blue-dark); font-size: 12px; margin-bottom: 3px; }

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr)); gap: 14px; }
.shot { margin: 0; }
.shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; display: block; background: var(--blue-tint); }
.shot figcaption { font-size: 12px; color: var(--ink-3); margin-top: 6px; }

/* L'écran de reprise utilise la coque d'identité, mais affiche des tableaux :
   il lui faut de la largeur. */
.auth-card.auth-wide { max-width: 760px; }
.auth-wide h2 { font-size: 15px; margin: 22px 0 8px; }
.auth-wide table.grid { margin-bottom: 4px; }
.auth-wide code { background: #f2f5f7; padding: 1px 5px; border-radius: 4px; font-size: 12px; }

/* ----------------------------- adaptatif ---------------------------- */
@media (max-width: 1079px) {
    .side { width: var(--side-rail); padding: 18px 10px; }
    .main { margin-left: var(--side-rail); }
    .brand-text, .nav a span, .side-foot { display: none; }
    /* Bandeau replié en rail : le mot ne tient plus, la marque seule reste. */
    .brand-mot { display: none; }
    .brand-carre { display: block; }
    .nav a { justify-content: center; padding: 11px 0; }
}

@media (max-width: 759px) {
    .side {
        inset: auto 0 0 0;
        /* `max-width` en plus de `right: 0` : une barre fixe ne doit en aucun cas
           dépasser l'écran, quelle que soit la façon dont le navigateur
           résout sa largeur. */
        width: auto; max-width: 100vw;
        height: calc(62px + env(safe-area-inset-bottom, 0px));
        flex-direction: row; align-items: center;
        /* Le creux du bas réserve la zone du geste d'accueil des iPhone. */
        padding: 0 6px env(safe-area-inset-bottom, 0px);
        border-right: 0; border-top: 1px solid var(--slate-line);
    }
    .brand { display: none; }
    /* Onze entrées dans l'administration. À onze, « space-around » les écrase
       sous la largeur d'un mot et la barre déborde de l'écran : c'est ce qui
       faisait défiler latéralement TOUTES les pages d'administration sur
       téléphone. C'est donc la barre qui défile, chaque entrée gardant une
       largeur lisible. « safe center » centre tant qu'il y a la place et
       repasse à gauche dès que ça déborde — sans lui, les premières entrées
       deviennent inatteignables. */
    .nav {
        flex-direction: row; width: 100%; gap: 0;
        justify-content: center;
        justify-content: safe center;
        overflow-x: auto; overscroll-behavior-x: contain;
        scrollbar-width: none;
    }
    .nav::-webkit-scrollbar { display: none; }
    .nav a {
        flex: 0 0 auto; min-width: 66px; text-align: center;
        flex-direction: column; gap: 3px; padding: 7px 6px; font-size: 10px;
    }
    .nav a span { display: block; }
    /* La barre du bas déborde sur la zone réservée au geste d'accueil des
       iPhone récents : on la rehausse, et le contenu se réserve d'autant. */
    .main { margin-left: 0; padding-bottom: calc(62px + env(safe-area-inset-bottom, 0px)); }
    /* Hauteur libre : un titre long passe sur deux lignes au lieu d'être coupé
       ou de pousser le bouton de déconnexion hors de l'écran. */
    .topbar { height: auto; min-height: var(--bar-h); padding: 9px 14px; gap: 10px; flex-wrap: wrap; }
    /* Barre du haut à l'étroit : le nom du compte est déjà dans la barre
       inférieure, et le bouton ne doit pas passer sur deux lignes. */
    .topbar h1 { font-size: 15px; line-height: 1.3; min-width: 0; overflow-wrap: anywhere; }
    .topbar .pill { display: none; }
    .topbar .btn { padding: 7px 11px; font-size: 12px; white-space: nowrap; }
    .content { padding: 16px; }
    table.grid th, table.grid td { padding: 10px 8px; font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; }
}

/* ========================= site public ==============================
   Le site public ne partage avec le back-office que sa palette. Sa mise
   en page obéit à une autre contrainte : convaincre un visiteur qui ne
   connaît pas l'entreprise, en quelques secondes et souvent sur un
   téléphone. D'où les pleines largeurs, les images généreuses et les
   contrastes marqués, là où l'application privée cherche la densité.

   Aucune photo n'est déclarée en image de fond : la politique de sécurité
   interdit les styles en ligne, donc les visuels variables passent par des
   <img> positionnées en absolu. Même rendu, et le navigateur peut les
   précharger.
   ==================================================================== */
body.pub { background: #ffffff; }

.contenu { max-width: 1180px; margin: 0 auto; padding: 0 24px; }

/* ---------------------------- en-tête ------------------------------- */
.pub-top {
    display: flex; align-items: center; justify-content: space-between;
    gap: 18px; padding: 14px 32px;
    position: sticky; top: 0; z-index: 30;
    background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
    transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
/* Sur l'accueil, l'en-tête flotte au-dessus de la photo : c'est l'image qui
   accueille, pas une barre blanche. Il redevient opaque dès qu'on défile,
   sinon les liens finissent sur un fond clair et deviennent illisibles. */
.pub-top.est-transparent {
    position: fixed; left: 0; right: 0;
    background: linear-gradient(to bottom, rgba(6, 22, 33, 0.55), rgba(6, 22, 33, 0));
    border-bottom-color: transparent;
}
.pub-top.est-transparent .pub-nav a { color: rgba(255, 255, 255, 0.92); }
.pub-top.est-transparent .pub-nav a:hover,
.pub-top.est-transparent .pub-nav a.est-actif { color: #fff; }
/* Spécificité plutôt que `!important` : au-dessus de la photo, le bouton
   s'inverse — fond blanc, texte bleu — et il faut que cette règle gagne
   sans qu'on doive ensuite surenchérir partout ailleurs. */
.pub-top.est-transparent .pub-nav a.pub-connexion {
    background: #fff; color: var(--blue-dark); border-color: #fff;
}
.pub-top.est-transparent .pub-nav a.pub-connexion:hover { background: #eef7fd; }
.pub-top.est-transparent .pub-marque img { filter: brightness(0) invert(1); }

.pub-marque { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.pub-marque img { display: block; height: 32px; width: auto; transition: filter 0.3s ease; }
.pub-nav { display: flex; align-items: center; gap: 22px; }
.pub-nav a { color: var(--ink-2); text-decoration: none; font-size: 14px; font-weight: 600; }
.pub-nav a:hover { color: var(--blue-dark); }
.pub-nav a.est-actif { color: var(--blue); }
.pub-nav a.pub-connexion {
    border: 1px solid var(--blue); border-radius: 999px; padding: 8px 18px;
    background: var(--blue); color: #fff;
}
.pub-nav a.pub-connexion:hover { background: var(--blue-dark); border-color: var(--blue-dark); color: #fff; }

.pub-main { width: 100%; }

/* ---------------------------- bandeau ------------------------------- */
.hero {
    position: relative; min-height: 600px; height: 92vh; max-height: 880px;
    display: flex; align-items: center; overflow: hidden;
    background: linear-gradient(135deg, var(--blue-dark), #06324a);
}
.hero-nu { min-height: 420px; height: auto; padding: 150px 0 90px; }
.hero-plans { position: absolute; inset: 0; }
.hero-plan {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; opacity: 0; transform: scale(1.06);
    transition: opacity 1.4s ease;
}
/* Le lent zoom avant donne vie à une photo fixe. C'est tout l'effet : il n'y
   a rien à cliquer, rien à attendre, l'image respire pendant qu'on lit. */
.hero-plan.on { opacity: 1; animation: respire 8s ease forwards; }
@keyframes respire { from { transform: scale(1.09); } to { transform: scale(1); } }
.hero-voile {
    position: absolute; inset: 0;
    background: linear-gradient(100deg, rgba(6, 22, 33, 0.82) 0%, rgba(6, 22, 33, 0.5) 42%, rgba(6, 22, 33, 0.12) 100%);
}
.hero-dedans {
    position: relative; z-index: 2; color: #fff;
    max-width: 1180px; width: 100%; margin: 0 auto; padding: 0 24px;
}
.hero-dedans h1 {
    font-size: clamp(2.3rem, 5.6vw, 4.2rem); line-height: 1.04; margin: 0;
    max-width: 13ch; letter-spacing: -0.02em;
    text-shadow: 0 2px 30px rgba(0, 0, 0, 0.3);
}
.hero-sous {
    font-size: clamp(1.02rem, 1.9vw, 1.3rem); margin: 20px 0 26px; max-width: 32ch;
    color: rgba(255, 255, 255, 0.92);
}
.hero-dispo {
    display: inline-flex; align-items: center; gap: 9px; margin: 0 0 24px;
    background: rgba(255, 255, 255, 0.16); border-radius: 999px;
    padding: 8px 16px; font-size: 14px; font-weight: 700;
}
.hero-pastille { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: #fff; }
.hero-pastille.est-libre { background: var(--ok); box-shadow: 0 0 0 4px rgba(31, 157, 107, 0.35); }
.hero-pastille.est-complet { background: rgba(255, 255, 255, 0.6); box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.14); }
.hero-boutons { display: flex; gap: 12px; flex-wrap: wrap; margin: 0; }
.hero-points {
    position: absolute; z-index: 3; bottom: 26px; left: 50%; transform: translateX(-50%);
    display: flex; gap: 9px;
}
.hero-points button {
    width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%;
    background: rgba(255, 255, 255, 0.45); cursor: pointer;
    transition: width 0.3s ease, background 0.3s ease;
}
.hero-points button.on { background: #fff; width: 28px; border-radius: 999px; }

.btn-clair { background: #fff; color: var(--blue-dark); }
.btn-clair:hover { background: #eef7fd; }
.btn-fantome { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, 0.55); }
.btn-fantome:hover { background: rgba(255, 255, 255, 0.14); }
.btn-ligne { background: #fff; color: var(--blue-dark); border: 1px solid var(--line); }
.btn-ligne:hover { border-color: var(--blue); background: var(--blue-tint); }

/* --------------------- en-tête des pages internes ------------------- */
.entete-page {
    background: linear-gradient(120deg, var(--blue-dark) 0%, var(--blue) 100%);
    color: #fff; padding: 72px 0 64px;
}
.entete-page h1 { font-size: clamp(2rem, 4.6vw, 3.1rem); margin: 0; letter-spacing: -0.02em; }
.entete-page-sous { color: rgba(255, 255, 255, 0.88); margin: 14px 0 0; max-width: 56ch; font-size: 17px; }
.entete-fiche { padding: 62px 0 54px; }
.entete-retour { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; flex-wrap: wrap; }
.entete-retour a { color: rgba(255, 255, 255, 0.9); text-decoration: none; font-weight: 600; font-size: 14px; }
.entete-retour a:hover { color: #fff; text-decoration: underline; }
.entete-retour .fiche-statut { position: static; }

/* ---------------------------- sections ------------------------------ */
.bande { padding: 76px 0; }
.bande-teintee { background: #f3f9fd; }
.bande-appel { background: var(--blue-dark); color: #fff; text-align: center; }
.bande-appel h2 { color: #fff; font-size: clamp(1.6rem, 3.2vw, 2.3rem); margin: 0 0 10px; }
.bande-appel .chapo { color: rgba(255, 255, 255, 0.86); margin: 0 auto 22px; }
.bande-tete { max-width: 680px; margin: 0 auto 44px; text-align: center; }
.bande-tete h2 { font-size: clamp(1.6rem, 3.2vw, 2.3rem); margin: 0; }
.bande-tete .chapo { margin: 12px auto 0; }
.bande-suite { margin-top: 30px; text-align: center; }

.surtitre {
    display: inline-block; margin-bottom: 10px;
    text-transform: uppercase; letter-spacing: 0.16em;
    font-size: 12px; font-weight: 800; color: var(--blue);
}
.surtitre-clair { color: rgba(255, 255, 255, 0.82); }
.chapo { font-size: 17px; color: var(--ink-2); max-width: 62ch; }
.lien-fort { color: var(--blue-dark); font-weight: 700; text-decoration: none; }
.lien-fort:hover { text-decoration: underline; }

/* ------------------------- cartes de biens -------------------------- */
/* `min(300px, 100%)` et non `300px` : sur un écran de 320 px, une piste qui
   refuse de descendre sous 300 px déborde de son conteneur et emporte la page
   avec elle. Le `min()` laisse la piste rétrécir quand il le faut. */
.grille-biens { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 28px; }
.fiche {
    position: relative;
    display: block; text-decoration: none; color: inherit; background: #fff;
    border: 1px solid var(--line); border-radius: 18px; overflow: hidden;
    transition: transform 0.2s ease, box-shadow 0.25s ease;
}
/* La carte entière reste cliquable sans qu'un lien en contienne un autre :
   c'est le lien du titre qui s'étend, par un calque transparent. Le bouton de
   visite passe au-dessus et garde son propre clic. */
.fiche-titre a { color: inherit; text-decoration: none; }
.fiche-titre a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.fiche-titre a:hover { color: var(--blue-dark); }
.fiche-3d { position: relative; z-index: 2; margin-top: 14px; font-size: 13px; }
.fiche:hover { transform: translateY(-4px); box-shadow: 0 22px 48px rgba(18, 38, 52, 0.14); }
.fiche-image { position: relative; display: block; aspect-ratio: 16 / 11; overflow: hidden; background: var(--blue-tint); }
.fiche-image img { width: 100%; height: 100%; object-fit: cover; display: block; transition: filter 0.3s ease; }
/* Réservé ou vendu : l'image se désature. On garde la référence visible, mais
   l'œil doit trier en une fraction de seconde ce qui est encore à prendre. */
.fiche.est-pris .fiche-image img { filter: grayscale(1) brightness(0.97); }
.fiche-vide { display: block; width: 100%; height: 100%; background: linear-gradient(135deg, #0a96d8, var(--blue-dark)); }
.fiche-statut {
    position: absolute; top: 14px; left: 14px;
    font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 6px 13px; border-radius: 999px; background: #fff; color: var(--ink);
    box-shadow: 0 2px 6px rgba(18, 38, 52, 0.2);
}
.fiche-statut.statut-disponible { background: var(--ok); color: #fff; }
.fiche-statut.statut-a_vendre   { background: var(--blue); color: #fff; }
.fiche-statut.statut-reserve    { background: var(--warn); color: #fff; }
.fiche-statut.statut-vendu      { background: var(--ink); color: #fff; }
.fiche-statut.statut-projet     { background: var(--ink-3); color: #fff; }
.fiche-corps { display: block; padding: 20px 22px 22px; }
.fiche-titre { margin: 0; }
.fiche-lieu { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-3); margin-bottom: 7px; }
.fiche-epingle {
    width: 12px; height: 12px; flex: 0 0 auto; border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg); background: var(--blue); opacity: 0.75;
}
.fiche-epingle-clair { background: rgba(255, 255, 255, 0.85); }
.fiche-titre { display: block; font-size: 20px; font-weight: 700; line-height: 1.25; }
.fiche-meta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.fiche-meta span {
    font-size: 12px; color: var(--ink-2); background: var(--blue-tint);
    border-radius: 999px; padding: 5px 11px;
}
.fiche-pied {
    display: flex; align-items: center; gap: 10px; margin-top: 18px;
    padding-top: 15px; border-top: 1px solid var(--line);
}
.fiche-prix { font-weight: 800; color: var(--blue-dark); }
.fiche-prix.est-barre { color: var(--ink-3); text-decoration: line-through; }
.fiche-dispo { font-size: 12px; font-weight: 700; color: var(--ok); }
.fiche-fleche { margin-left: auto; color: var(--blue); font-weight: 700; font-size: 18px; }

/* ------------------------- fiche d'un bien -------------------------- */
.fiche-page {
    display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 40px;
    align-items: start; padding-top: 56px; padding-bottom: 72px;
}
.fiche-gauche h2 { font-size: 1.6rem; margin: 40px 0 14px; }
.fiche-gauche h2:first-child { margin-top: 0; }

.galerie { margin: 0; }
.galerie-grande {
    width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
    border-radius: 18px; display: block; background: var(--blue-tint);
}
.galerie-vignettes { display: flex; gap: 10px; margin-top: 12px; overflow-x: auto; padding-bottom: 4px; }
.galerie-vignettes button {
    flex: 0 0 auto; width: 84px; height: 62px; padding: 0; cursor: pointer;
    border: 2px solid transparent; border-radius: 10px; overflow: hidden; background: none;
}
.galerie-vignettes button.est-choisie { border-color: var(--blue); }
.galerie-vignettes img { width: 100%; height: 100%; object-fit: cover; display: block; }

.lot-carte {
    display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 0;
    border: 1px solid var(--line); border-radius: 18px; overflow: hidden;
    background: #fff; margin-bottom: 20px;
}
.lot-carte.est-pris .lot-image img { filter: grayscale(1) brightness(0.97); }
.lot-image { position: relative; min-height: 190px; background: var(--blue-tint); }
.lot-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lot-corps { padding: 22px 24px; }
.lot-corps h3 { margin: 0 0 10px; font-size: 19px; }
.lot-corps .pub-texte { margin-top: 12px; font-size: 14px; }
.lot-pied { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.lot-pied .fiche-prix { margin-right: auto; font-size: 17px; }

.encart-clair {
    background: #fff; border: 1px solid var(--line); border-radius: 18px;
    padding: 24px 24px 26px; margin-bottom: 22px;
    box-shadow: 0 10px 28px rgba(18, 38, 52, 0.06);
}
.encart-clair h3 { margin: 0 0 16px; font-size: 18px; }
.liste-infos { display: grid; grid-template-columns: auto 1fr; gap: 0; margin: 0; }
.liste-infos dt {
    color: var(--ink-3); font-size: 14px; padding: 10px 0;
    border-top: 1px solid var(--line-soft, var(--line));
}
.liste-infos dd {
    margin: 0; text-align: right; font-weight: 600; font-size: 14px; padding: 10px 0;
    border-top: 1px solid var(--line-soft, var(--line));
}
.liste-infos dt:first-of-type, .liste-infos dd:first-of-type { border-top: 0; }

/* ------------------------- métiers, atouts -------------------------- */
.grille-metiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 22px; }
.metier { background: #fff; border: 1px solid var(--line); border-radius: 18px; padding: 28px 26px; }
.metier h3 { margin: 0 0 8px; font-size: 18px; }
.metier p { margin: 0; color: var(--ink-2); }

.deux-colonnes { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 48px; align-items: start; }
.deux-colonnes h2 { margin: 0 0 14px; font-size: clamp(1.6rem, 3.2vw, 2.2rem); }
.encart { background: var(--blue-dark); color: #fff; border-radius: 20px; padding: 32px 30px; }
.encart h3 { margin: 0 0 16px; color: #fff; font-size: 19px; }
.liste-atouts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.liste-atouts li { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px; }
.liste-atouts strong { font-size: 15px; }
.liste-atouts span { font-size: 14px; color: rgba(255, 255, 255, 0.78); }

/* La carte garde son cadre même avant chargement : sans hauteur réservée,
   l'arrivée de l'iframe pousse tout le contenu qui la suit. */
.carte { position: relative; border-radius: 12px; overflow: hidden; background: var(--blue-tint); }
.carte iframe { display: block; width: 100%; height: 240px; border: 0; }

/* ------------------------- formulaires publics ---------------------- */
.pub-form { margin: 0; }
/* Les paragraphes sont désormais de vrais paragraphes, découpés côté serveur :
   plus besoin de `white-space: pre-line`, qui conservait aussi les retours à
   la ligne parasites de l'éditeur d'origine. */
.pub-texte { max-width: 72ch; color: var(--ink-2); line-height: 1.7; margin: 0 0 14px; }
.pub-texte:last-child { margin-bottom: 0; }
.pub-section { max-width: 1180px; margin: 0 auto; padding: 44px 24px; }
.pub-intro { font-size: 16px; color: var(--ink-2); max-width: 680px; }

/* Champ-piège : hors écran plutôt que display:none, que certains robots
   savent repérer. Masqué aussi aux lecteurs d'écran par aria-hidden. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ------------------------------ pied -------------------------------- */
.pub-pied {
    border-top: 1px solid var(--line); padding: 52px 0 28px;
    color: var(--ink-3); font-size: 14px; background: #f7f9fb;
}
.pub-pied-grille { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 30px; }
.pub-pied-bloc strong {
    display: block; color: var(--ink); margin-bottom: 10px;
    text-transform: uppercase; letter-spacing: 0.1em; font-size: 12px;
}
.pub-pied-bloc div { margin-bottom: 5px; }
.pub-pied a { color: var(--ink-2); text-decoration: none; }
.pub-pied a:hover { color: var(--blue-dark); }
.pub-pied-bas {
    margin: 36px auto 0; padding-top: 20px; border-top: 1px solid var(--line);
    font-size: 13px; color: var(--ink-3);
}

/* --------------------- fiche de dossier (back-office) --------------- */
/* Le déroulé du projet peut faire deux cents lignes ; les coordonnées, la
   messagerie et les dépôts doivent rester atteignables pendant qu'on le lit,
   donc à côté et non dessous. */
.dossier-page { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }
/* `minmax(0, 1fr)` et non la colonne implicite : une colonne de grille en
   `auto` prend la largeur de son contenu le plus large et déborde de son
   propre conteneur. C'est ce qui arrivait ici — le champ de dépôt de fichier
   imposait sa largeur intrinsèque, la colonne passait à 570 px dans un écran
   de 375, et toute la fiche de dossier débordait sur téléphone. */
.dossier-droite { position: sticky; top: 76px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; max-height: calc(100vh - 96px); overflow-y: auto; }
.dossier-droite .card { margin: 0; }
.stat-sous { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

/* Dans une colonne de 380 px, « étiquette à gauche / valeur alignée à droite »
   écrase les deux. On empile : l'étiquette en petit au-dessus, la valeur en
   pleine largeur — un numéro de téléphone ou une adresse doit se lire d'un
   trait, pas se couper en deux. */
.dossier-droite .liste-infos { grid-template-columns: 1fr; }
.dossier-droite .liste-infos dt {
    padding: 10px 0 0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
}
.dossier-droite .liste-infos dd { text-align: left; padding: 0 0 10px; border-top: 0; font-size: 14px; }
.dossier-droite .liste-infos dt:empty { padding: 0; }

.todo-tete {
    display: flex; align-items: center; gap: 10px;
    margin: 16px 0 6px; font-size: 12px; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.08em;
}
.todo-tete-promo  { color: var(--blue-dark); }
.todo-tete-client { color: var(--warn); }
.todo-compte {
    font-weight: 700; letter-spacing: 0; text-transform: none;
    background: var(--blue-tint); color: var(--ink-2); border-radius: 999px; padding: 2px 9px;
}
.todo-tete-client .todo-compte { background: #fdf2e3; }

@media (max-width: 1099px) {
    .dossier-page { grid-template-columns: minmax(0, 1fr); }
    .dossier-droite { position: static; max-height: none; overflow: visible; }
}

/* ------------------------- back-office, divers ---------------------- */
.lot-bloc { border-top: 1px solid var(--line); padding: 11px 0; }
.lot-bloc:first-of-type { border-top: 0; }
.demande { border-top: 1px solid var(--line); padding: 13px 0; }
.demande:first-of-type { border-top: 0; }
.demande.est-neuve { border-left: 3px solid var(--blue); padding-left: 12px; }
.demande-tete { display: flex; gap: 11px; flex-wrap: wrap; align-items: center; font-size: 13px; }
.demande-corps { white-space: pre-line; margin: 8px 0; color: var(--ink-2); }
tr.est-exclu > td { opacity: 0.5; }

@media (max-width: 759px) {
    .pub-top { padding: 12px 16px; }
    /* Sur un téléphone, l'en-tête doit tenir sur une ligne : le logo rapetisse
       et les liens se resserrent, plutôt que le menu passe sur deux lignes. */
    .pub-marque img { height: 22px; }
    /* Les libellés ne doivent pas se couper en deux lignes : « À vendre »
       devenait « À / vendre » et l'en-tête doublait de hauteur. */
    .pub-nav { gap: 11px; }
    .pub-nav a { font-size: 13px; white-space: nowrap; }
    .pub-nav a.pub-connexion { padding: 7px 12px; font-size: 12px; }
    .pub-hero { padding: 36px 0 24px; }
    .pub-hero h1 { font-size: 26px; }

    .contenu, .hero-dedans { padding: 0 18px; }
    .hero { min-height: 520px; height: auto; padding: 130px 0 70px; }
    .hero-nu { padding: 120px 0 64px; }
    .hero-dedans h1 { max-width: none; }
    .bande { padding: 48px 0; }
    .bande-tete { margin-bottom: 28px; }
    .deux-colonnes { grid-template-columns: minmax(0, 1fr); gap: 30px; }
    .pub-section { padding: 30px 18px; }
    .hero-boutons .btn { flex: 1 1 auto; }

    .entete-page { padding: 48px 0 42px; }
    .fiche-page { grid-template-columns: minmax(0, 1fr); gap: 28px; padding-top: 36px; padding-bottom: 48px; }
    /* Le formulaire passe sous le contenu : sur un téléphone, on lit d'abord,
       on écrit ensuite. */
    .fiche-droite { order: 2; }
    .lot-carte { grid-template-columns: minmax(0, 1fr); }
    .lot-image { min-height: 200px; aspect-ratio: 16 / 10; }
    .pub-pied-grille { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 24px; }
}

/* Très petits écrans : « Accueil » disparaît de la barre — le logo y mène
   déjà, et la place gagnée évite que le menu passe sur deux lignes. */
@media (max-width: 420px) {
    .pub-nav a[href="/"] { display: none; }
    .pub-top { padding: 10px 14px; }
    .pub-nav { gap: 9px; }
}

@media (max-width: 1023px) and (min-width: 760px) {
    .fiche-page { grid-template-columns: minmax(0, 1fr); }
    .fiche-droite { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
}

/* Le bandeau ne défile pas pour qui demande moins d'animation : la première
   image reste affichée, et les pastilles continuent de répondre au clic. */
@media (prefers-reduced-motion: reduce) {
    .hero-plan { transition: none; }
    .hero-plan.on { animation: none; transform: none; }
    .fiche:hover { transform: none; }
}


/* --------------------- jauge d'avancement --------------------------- */
/* La largeur passe par une classe et non par un style en ligne : la
   politique de sécurité interdit les seconds, et vingt-et-un paliers de
   5 % suffisent amplement à lire une progression. */
.jauge { display: inline-block; vertical-align: middle; width: 90px; height: 7px;
         background: var(--line); border-radius: 999px; overflow: hidden; }
.jauge-barre { display: block; height: 100%; background: var(--blue); border-radius: 999px; }
.jauge-val { font-size: 12px; color: var(--ink-2); margin-left: 8px; }
.jauge-0 { width: 0%; }
.jauge-5 { width: 5%; }
.jauge-10 { width: 10%; }
.jauge-15 { width: 15%; }
.jauge-20 { width: 20%; }
.jauge-25 { width: 25%; }
.jauge-30 { width: 30%; }
.jauge-35 { width: 35%; }
.jauge-40 { width: 40%; }
.jauge-45 { width: 45%; }
.jauge-50 { width: 50%; }
.jauge-55 { width: 55%; }
.jauge-60 { width: 60%; }
.jauge-65 { width: 65%; }
.jauge-70 { width: 70%; }
.jauge-75 { width: 75%; }
.jauge-80 { width: 80%; }
.jauge-85 { width: 85%; }
.jauge-90 { width: 90%; }
.jauge-95 { width: 95%; }
.jauge-100 { width: 100%; }
.jauge-100 { background: var(--ok); }
.tag-alerte { background: var(--warn); color: #fff; }

/* ------------- recherche et tri d'un tableau ------------------------ */
.carte-tete { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.carte-tete h2 { margin: 0; }
.recherche { display: flex; gap: 8px; align-items: center; }
/* Le champ s'étire dans la place disponible plutôt que d'en exiger 280 px :
   sur un téléphone, cette largeur plancher poussait le bouton hors de l'écran. */
.recherche { flex: 1 1 240px; justify-content: flex-end; }
.recherche input[type=search] { flex: 1 1 auto; min-width: 0; }
@media (min-width: 760px) { .recherche input[type=search] { min-width: 260px; } }
/* Un en-tete triable doit se voir cliquable avant qu'on l'essaie. */
th.tri { padding: 0; }
th.tri a { display: block; padding: 10px 12px; color: inherit; text-decoration: none; white-space: nowrap; }
th.tri a:hover { color: var(--blue-dark); background: var(--blue-tint); }
th.tri.est-trie a { color: var(--blue); font-weight: 800; }
th.tri.num a { text-align: right; }

/* ------------- edition repliee dans un panneau ---------------------- */
/* Repliee par defaut : l'ecran sert d'abord a consulter. */
.edition { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 14px; }
.edition > summary { cursor: pointer; font-weight: 700; font-size: 14px; color: var(--blue-dark); }
.edition-titre { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); margin: 18px 0 8px; }
.edition-valeur { flex: 1 1 auto; font-size: 14px; }

/* ------------------- zones de depot (chantier) ---------------------- */
.depots { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 18px; }
.depot { display: flex; flex-direction: column; gap: 12px; }
.depot-zone {
    display: flex; flex-direction: column; gap: 4px; cursor: pointer;
    border: 2px dashed var(--line); border-radius: 14px; padding: 22px 20px;
    background: #fbfdfe; transition: border-color .2s ease, background .2s ease;
}
.depot-zone:hover, .depot-zone.est-survolee { border-color: var(--blue); background: var(--blue-tint); }
.depot-titre { font-weight: 700; font-size: 15px; }
.depot-aide { font-size: 13px; color: var(--ink-3); }
.depot-nom { font-size: 13px; font-weight: 600; color: var(--blue-dark); margin-top: 6px; }
.depot-nom:empty { display: none; }
/* Le choix du mode et le bouton passent l'un sous l'autre plutôt que de
   dépasser : sur un écran de 320 px, les deux côte à côte ne tiennent pas. */
.depot-pied { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.depot-pied select { flex: 1 1 160px; min-width: 0; }
.section-titre { font-size: 13px; text-transform: uppercase; letter-spacing: .08em;
                 color: var(--blue-dark); margin: 26px 0 6px; padding-top: 14px;
                 border-top: 1px solid var(--line); }
.section-titre:first-of-type { margin-top: 4px; border-top: 0; padding-top: 0; }

.dialogue { background: #0f1b24; color: #cfe3ee; border-radius: 10px; padding: 14px 16px;
            font-size: 12px; line-height: 1.55; overflow-x: auto; white-space: pre-wrap;
            word-break: break-word; max-height: 420px; overflow-y: auto; }

/* ------------------- aperçus d'un lot d'import ---------------------- */
.grille-pieces { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); gap: 18px; }
.piece { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: #fff; display: flex; flex-direction: column; }
.piece-apercu { position: relative; height: clamp(170px, 42vw, 230px); background: var(--blue-tint); border-bottom: 1px solid var(--line); }
.piece-apercu iframe, .piece-apercu img { width: 100%; height: 100%; border: 0; display: block; object-fit: cover; object-position: top; }
/* Le cadre d'un PDF capte le clic : le lien d'ouverture est posé par-dessus. */
.piece-ouvrir { position: absolute; right: 8px; bottom: 8px; z-index: 2; background: rgba(255,255,255,.94);
                border: 1px solid var(--line); border-radius: 999px; padding: 4px 12px;
                font-size: 12px; font-weight: 700; color: var(--blue-dark); text-decoration: none; }
.piece-ouvrir:hover { background: #fff; border-color: var(--blue); }
.piece-corps { padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 4px; }
.piece-pages { margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3); }
.piece-titre { margin: 0; font-weight: 700; font-size: 15px; }
.piece-detail { margin: 0; font-size: 13px; color: var(--ink-2); }
.piece-montant { margin: 4px 0 0; font-weight: 800; color: var(--blue-dark); }
.piece-etats { margin: 6px 0 0; display: flex; gap: 6px; flex-wrap: wrap; }
.piece-etats:empty { display: none; }
.piece-actions { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.piece-actions form { display: inline-flex; }

/* La carte entiere est la cible du depot : viser le rectangle en pointilles
   au pixel pres n'est pas un geste qu'on reussit avec un fichier au bout du
   curseur. */
.depot { border-radius: 16px; transition: background .15s ease; }
.depot-zone { min-height: 140px; justify-content: center; }
.depot-zone.est-survolee { border-color: var(--blue); background: var(--blue-tint); }
.depot.a-un-fichier .depot-zone { border-style: solid; border-color: var(--ok); background: #f1faf6; }
.depot.a-un-fichier .depot-nom { color: #156a4c; }

/* ------------------- attente d'un envoi ----------------------------- */
/* Barre indeterminee : on ne connait pas l'avancement reel d'une analyse,
   et une barre qui stagne a 90 %% ment plus qu'elle n'informe. */
.progression { height: 4px; border-radius: 999px; background: var(--blue-tint); overflow: hidden; margin-top: 10px; }
.progression-barre { display: block; height: 100%; width: 40%; border-radius: 999px;
                     background: linear-gradient(90deg, var(--blue), var(--blue-dark));
                     animation: glisse 1.1s ease-in-out infinite; }
@keyframes glisse {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}
.depot.est-en-cours .depot-zone { opacity: .6; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
    .progression-barre { animation: none; width: 100%; opacity: .7; }
}

/* ------------------- legende des montants --------------------------- */
.legende { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
           font-size: 12.5px; color: var(--ink-2); margin: 0 0 12px; }
.legende-cle { width: 16px; height: 16px; border-radius: 4px; border: 1px solid var(--line); flex: 0 0 auto; }
.legende-calc { background: #eaf4fb; }
.legende-manuel { background: #d7ebf8; margin-left: 14px; }
.legende-note { color: var(--ink-3); flex: 1 1 320px; }

/* ---------------- colonne Document, reduite a l'essentiel ----------- */
.cell-doc { width: 1%; white-space: nowrap; }
.doc-lien { display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
            color: var(--blue-dark); font-weight: 700; font-size: 12.5px;
            border: 1px solid var(--line); border-radius: 999px; padding: 3px 11px 3px 8px;
            background: #fff; }
.doc-lien:hover { border-color: var(--blue); background: var(--blue-tint); }
.doc-icone { width: 15px; height: 15px; flex: 0 0 auto; fill: none;
             stroke: var(--blue); stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.doc-pages { white-space: nowrap; }

/* Texte reserve aux lecteurs d'ecran : une colonne d'actions n'a pas de
   titre visible, mais elle en a besoin d'un pour etre annoncee. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------------- robustesse sur ecran etroit ----------------------- */
/* Une reference de parcelle, une adresse web ou un nom de fichier sans
   espace ne doit jamais elargir la page : sur un telephone, un seul mot
   trop long fait deborder toute la mise en page et tout parait casse. */
.pub-texte, .chapo, .fiche-titre, .piece-detail, .lot-corps,
.entete-page-sous, .liste-infos dd { overflow-wrap: anywhere; }

/* Les images ne dépassent jamais leur conteneur, même si leurs attributs de
   dimensions disent le contraire. `height: auto` va avec : sans lui, une
   image bridée en largeur garde la hauteur de son attribut et se déforme. */
img { max-width: 100%; height: auto; }

/* ------------- taches de l'entreprise, cote client ------------------ */
/* En retrait et grisees : le client doit voir l'avancement du chantier
   sans croire une seconde qu'il a quelque chose a y faire. */
.todo-promo { opacity: .62; }
.todo-promo .todo-item { cursor: default; }
.todo-promo .check-ro { background: #f2f5f7; border-color: var(--line); }

/* ------------------- visionneuse de photos -------------------------- */
.shot-lien { display: block; cursor: zoom-in; border-radius: 10px; overflow: hidden; }
.shot-lien img { display: block; width: 100%; transition: transform .25s ease; }
.shot-lien:hover img { transform: scale(1.03); }

.visionneuse { border: 0; padding: 0; background: transparent; max-width: 94vw; max-height: 94vh; }
.visionneuse::backdrop { background: rgba(10, 20, 28, .88); }
.visionneuse img { display: block; max-width: 94vw; max-height: 84vh; width: auto;
                   border-radius: 10px; background: #0f1b24; }
.visionneuse-legende { color: #e8f1f7; font-size: 14px; margin: 10px 2px 0; text-align: center; }
.visionneuse-legende:empty { display: none; }
/* Au-dessus de l'image, et assez grand pour le pouce. */
.visionneuse-fermer { position: fixed; top: 14px; right: 16px; z-index: 2;
                      width: 42px; height: 42px; border-radius: 50%; cursor: pointer;
                      border: 0; background: rgba(255,255,255,.92); color: var(--ink);
                      font-size: 24px; line-height: 1; }
.visionneuse-fermer:hover { background: #fff; }

/* ------------- tache que le client vient de cocher ------------------ */
/* La barre du haut est collante : sans cette marge, l'ancre pose la ligne
   juste dessous, a moitie cachee. C'est ce qui donnait des sauts mal
   ajustes apres chaque clic. */
.todo-item { scroll-margin-top: calc(var(--bar-h) + 20px); }

/* Lueur bleue trente secondes, puis extinction. Animation CSS et non
   script : il n'y a rien a decider, juste une couleur qui s'en va. */
@keyframes lueur-tache {
    0%   { background: #cfe6f7; box-shadow: inset 3px 0 0 var(--blue); }
    80%  { background: #cfe6f7; box-shadow: inset 3px 0 0 var(--blue); }
    100% { background: transparent; box-shadow: inset 3px 0 0 transparent; }
}
.todo-item.vient-de-changer {
    border-radius: 8px;
    animation: lueur-tache 30s ease-out forwards;
}
/* Même lueur dans le back-office, où la liste est encore plus longue. */
tr.is-recent > td, .todo-item.vient-de-changer { }
@media (prefers-reduced-motion: reduce) {
    .todo-item.vient-de-changer { animation: none; background: #cfe6f7; }
}

/* =====================================================================
   Adaptatif — du téléphone au grand écran.

   Quatre familles de largeurs à tenir : téléphone (jusqu'à 759 px),
   tablette (760 à 1079), portable (1080 à 1439) et grand écran. Les blocs
   précédents réorganisent déjà les pages à ces seuils ; ce qui suit règle
   ce qu'une réorganisation ne règle pas — les largeurs plancher, les
   cibles trop petites pour un doigt, les mots trop longs, et la poignée
   d'endroits où un seul élément trop large faisait déborder toute la page.

   Un débordement horizontal ne se voit pas comme un défaut local : la page
   entière glisse sous le doigt et tout paraît cassé. C'est la raison
   d'être de la plupart des règles ci-dessous.
   ===================================================================== */

/* --- rien ne dépasse en largeur ------------------------------------- */
/* Les médias et les champs de saisie sont les deux coupables habituels :
   un `width=` en attribut, une largeur par défaut de `<input>`, et la
   page gagne deux cents pixels que personne n'a demandés. */
svg, video, iframe, canvas { max-width: 100%; }
input, select, textarea, button { max-width: 100%; }
/* Le champ de dépôt de fichier a une largeur intrinsèque considérable — le
   bouton du navigateur plus « Aucun fichier sélectionné ». Sans ce
   `min-width`, il impose cette largeur à tout ce qui l'entoure. */
input[type="file"] { min-width: 0; }
/* Une référence de parcelle, une adresse web ou un nom de fichier sans
   espace ne doit pas élargir une colonne au-delà du raisonnable. */
table.grid td, table.grid th { overflow-wrap: break-word; }
code, kbd, samp { overflow-wrap: anywhere; }

/* --- tableaux sur téléphone ------------------------------------------ */
/* Comprimé sous 375 px, un tableau de cinq colonnes ou plus ne se lit
   plus : chaque cellule tombe sur quatre lignes et les colonnes se
   confondent. On lui donne une largeur plancher et on le laisse glisser
   dans son cadre — l'information reste lisible, et c'est le tableau qui
   défile, pas la page.

   `:has()` compte les colonnes : les petits tableaux continuent de se
   replier tout seuls, sans jamais imposer de défilement. Les navigateurs
   qui ignorent `:has()` retrouvent le comportement d'avant — rien ne
   casse, le repli est simplement moins confortable. */
@media (max-width: 759px) {
    .card > .table-scroll { margin: 0 -20px; padding: 0 20px; }
    .table-scroll > table.grid:not(.en-cartes):has(thead th:nth-child(5))  { min-width: 540px; }
    .table-scroll > table.grid:not(.en-cartes):has(thead th:nth-child(8))  { min-width: 720px; }
    .table-scroll > table.grid:not(.en-cartes):has(thead th:nth-child(11)) { min-width: 900px; }
    /* Un tableau dont les colonnes secondaires se sont effacées n'en a plus
       que quatre ou cinq de visibles : son plancher descend d'autant, sinon
       on le ferait défiler pour des colonnes qui ne s'affichent plus. */
    .table-scroll > table.grid:not(.en-cartes):has(.col-option) { min-width: 460px; }
}

/* --- une liste devient une pile de fiches ---------------------------- */
/* Un tableau qui défile de côté sur un téléphone reste illisible : on ne
   voit jamais plus de deux colonnes, et la première — celle qui dit de
   quelle ligne il s'agit — sort de l'écran dès qu'on fait glisser. Sous
   700 px, les listes marquées `en-cartes` cessent donc d'être des
   tableaux : chaque ligne devient une fiche, chaque valeur sa propre
   ligne, précédée de son intitulé.

   L'intitulé vient de `data-label` par `content: attr()`. Le texte reste
   dans le gabarit, la mise en forme dans la feuille de style, et rien
   n'est écrit en ligne — la politique de sécurité l'interdirait.

   Les grilles denses (facturation, CFC) gardent le défilement : on y
   compare des montants d'une ligne à l'autre, et quarante fiches de
   douze lignes ne se comparent pas. */
@media (max-width: 699px) {
    table.en-cartes,
    table.en-cartes tbody,
    table.en-cartes tr,
    table.en-cartes td { display: block; width: auto; }

    /* L'en-tête ne disparaît pas : il reste lu par les lecteurs d'écran,
       qui s'appuient dessus pour annoncer chaque cellule. */
    table.en-cartes thead {
        position: absolute; width: 1px; height: 1px;
        overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
    }

    table.en-cartes tr {
        border: 1px solid var(--line); border-radius: 12px;
        padding: 13px 15px; margin-bottom: 10px; background: #fff;
    }
    table.en-cartes tr:last-child { margin-bottom: 0; }
    table.grid.en-cartes tbody tr:hover td { background: transparent; }

    table.en-cartes td {
        border: 0; padding: 5px 0; font-size: 14px; white-space: normal;
        display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
        text-align: right;
    }
    table.en-cartes td::before {
        content: attr(data-label);
        flex: 0 0 auto; text-align: left;
        font-size: 11px; font-weight: 600; letter-spacing: 0.07em;
        text-transform: uppercase; color: var(--ink-3);
    }
    /* Une cellule sans valeur n'a pas à occuper une ligne pour afficher
       son seul intitulé. */
    table.en-cartes td:empty { display: none; }

    /* La première colonne titre la fiche : pas d'intitulé, pleine
       largeur, et le poids typographique d'un titre. */
    table.en-cartes td:first-child {
        display: block; text-align: left; padding: 0 0 4px;
        font-size: 15.5px; font-weight: 700; line-height: 1.3;
    }
    table.en-cartes td:first-child::before { content: none; }

    /* Les boutons passent en bas de la fiche, à portée du pouce. */
    table.en-cartes td.cell-action,
    table.en-cartes td.actions-cell {
        display: block; width: auto; text-align: left;
        white-space: normal; padding: 10px 0 0;
    }
    table.en-cartes td.cell-action::before,
    table.en-cartes td.actions-cell::before { content: none; }
    table.en-cartes td.cell-action .btn { width: 100%; justify-content: center; }
    table.en-cartes td.actions-cell form { display: flex; gap: 8px; margin: 0 0 8px; }
    table.en-cartes td.actions-cell form:last-child { margin-bottom: 0; }
    /* Le tiret qui tient lieu de « rien à faire ici » dans une colonne
       d'actions n'a plus de colonne à remplir : en fiche, il flotte seul. */
    table.en-cartes td.actions-cell > .muted { display: none; }
    table.en-cartes td.actions-cell form > :first-child:not([type=hidden]) { flex: 1 1 auto; min-width: 0; }

    /* En fiche, le cadre de la fiche remplace celui du tableau. */
    .card > .table-scroll:has(.en-cartes) { margin: 0; padding: 0; overflow-x: visible; }
    .table-scroll > table.en-cartes { min-width: 0; }
}

/* --- colonnes secondaires -------------------------------------------- */
/* Marquée secondaire, une colonne s'efface sous 700 px : en fiche, elle
   économise une ligne sur quatre, et en tableau elle économise un
   défilement. L'information n'est pas perdue — elle est dans la fiche
   détaillée, à un clic.

   Sélecteur volontairement plus précis que celui des fiches ci-dessus :
   sans cela, le `display: flex` des cellules de fiche l'emporterait et
   la colonne masquée réapparaîtrait. */
@media (max-width: 699px) {
    .col-option,
    table.grid td.col-option,
    table.grid th.col-option { display: none; }
}

/* --- petits téléphones ------------------------------------------------ */
@media (max-width: 559px) {
    .content { padding: 14px; }
    .card { padding: 16px 14px; }
    .card > .table-scroll { margin: 0 -14px; padding: 0 14px; }
    .step { padding: 12px 13px; }
    /* Le retrait de 34 px alignait les tâches sous le numéro d'étape ;
       à cette largeur, il ne reste plus assez de place pour le libellé. */
    .todo, .step-desc { margin-left: 0; }
    .stat { padding: 12px 13px; }
    .stat-n { font-size: 21px; }
}

/* --- écrans d'identité, très petits téléphones ------------------------ */
@media (max-width: 420px) {
    .auth-wrap { padding: 14px; }
    .auth-card { padding: 24px 18px; }
    .code-input { letter-spacing: 6px; font-size: 20px; }
}

/* --- listes de définitions étroites ----------------------------------- */
/* « Étiquette à gauche, valeur à droite » tient jusqu'à ce que les deux se
   retrouvent sur quatre lignes chacune. On empile alors, comme le fait
   déjà la colonne latérale d'un dossier. */
@media (max-width: 480px) {
    .liste-infos { grid-template-columns: 1fr; }
    .liste-infos dt { padding: 10px 0 0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; }
    .liste-infos dd { text-align: left; padding: 0 0 10px; border-top: 0; }
    .liste-infos dt:first-of-type { border-top: 0; }
}

/* --- cibles tactiles --------------------------------------------------- */
/* Au doigt, une case de 20 px se rate une fois sur trois — et cocher une
   étape est précisément ce que l'acquéreur vient faire depuis son
   téléphone. On ne grossit que là où le pointeur est grossier : la densité
   du bureau ne change pas d'un pixel. */
@media (pointer: coarse) {
    .check { width: 28px; height: 28px; font-size: 15px; }
    .btn { padding: 11px 16px; }
    .btn-mini { padding: 8px 12px; font-size: 13px; }
    .btn-ouvrir { padding: 9px 14px; font-size: 13px; }
    th.tri a { padding: 13px 12px; }
    .todo-item { gap: 11px; }
    .galerie-vignettes button { width: 92px; height: 68px; }
}

/* --- téléphone tenu à l'horizontale ------------------------------------ */
/* En paysage, un téléphone fait 390 px de haut : un bandeau d'accueil de
   600 px de minimum y occupe une page et demie avant le premier mot. */
@media (orientation: landscape) and (max-height: 600px) {
    .hero { min-height: 0; height: auto; max-height: none; padding: 92px 0 54px; }
    .hero-nu { padding: 92px 0 54px; }
    .hero-points { bottom: 14px; }
    .entete-page { padding: 44px 0 38px; }
    .entete-fiche { padding: 40px 0 34px; }
}

/* --- colonne latérale d'un dossier ------------------------------------- */
/* Collante seulement si l'écran est assez haut pour qu'elle serve : sur un
   portable bas de plafond, une colonne figée qui défile toute seule à
   l'intérieur gêne plus qu'elle n'aide. */
@media (max-height: 740px) {
    .dossier-droite { position: static; max-height: none; overflow: visible; }
}

/* --- tablette ----------------------------------------------------------- */
@media (min-width: 760px) and (max-width: 1023px) {
    .deux-colonnes { gap: 28px; }
    .pub-pied-grille { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
    .bande { padding: 60px 0; }
}

/* --- visionneuse ------------------------------------------------------- */
/* Le bouton de fermeture ne doit pas se glisser sous l'encoche. */
.visionneuse-fermer { top: calc(14px + env(safe-area-inset-top, 0px)); }

/* ===================== vue client (usurpation) =======================
   Regarder l'application avec les yeux d'un acquéreur. Deux pièces : le
   sélecteur, dans la barre du haut, et le bandeau qui rappelle en
   permanence qu'on n'est pas chez soi.
   ==================================================================== */

/* --- le bandeau ------------------------------------------------------ */
/* Ambre, couleur qui n'existe nulle part ailleurs dans l'application : on
   ne doit pas pouvoir oublier une seconde où l'on se trouve. Collant en
   haut, au-dessus de la barre de titre, et jamais réductible. */
.bandeau-vue {
    position: sticky; top: 0; z-index: 15;
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    padding: 11px 24px;
    background: #8a5a12; color: #fff;
    font-size: 14px; font-weight: 600;
}
.bandeau-vue strong { color: #fff; }
.bandeau-vue .btn { padding: 7px 14px; font-size: 13px; }
/* La barre de titre glisse sous le bandeau, pas dessus. */
.bandeau-vue ~ .topbar { top: 46px; }

/* --- le sélecteur de compte ----------------------------------------- */
.bascule { position: relative; }
.pill-bouton { cursor: pointer; list-style: none; }
.pill-bouton::-webkit-details-marker { display: none; }
.pill-bouton::after { content: ' ▾'; opacity: .7; }
.pill-bouton:hover { background: #d7ebf8; }

.bascule-panneau {
    position: absolute; right: 0; top: calc(100% + 8px); z-index: 40;
    width: min(320px, calc(100vw - 32px));
    max-height: min(420px, 60vh); overflow-y: auto;
    background: var(--card); border: 1px solid var(--line); border-radius: 12px;
    box-shadow: 0 18px 44px rgba(18, 38, 52, 0.18);
    padding: 10px;
}
.bascule-titre {
    margin: 2px 6px 8px; font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3);
}
.bascule-panneau form { margin: 0; }
/* Un bouton, pas un lien : l'action change l'état du serveur et porte un
   jeton anti-CSRF. */
.bascule-choix {
    display: block; width: 100%; text-align: left;
    border: 0; background: none; cursor: pointer;
    padding: 9px 10px; border-radius: 8px;
    font: inherit; color: var(--ink);
}
.bascule-choix:hover { background: var(--blue-tint); }
.bascule-nom { display: block; font-weight: 600; font-size: 14px; }
.bascule-sous { display: block; font-size: 12.5px; color: var(--ink-3); margin-top: 1px; }
.bascule-note {
    margin: 10px 6px 2px; font-size: 12px; color: var(--ink-3);
    border-top: 1px solid var(--line); padding-top: 9px;
}

@media (max-width: 759px) {
    .bandeau-vue { padding: 10px 14px; font-size: 13px; }
    .bandeau-vue ~ .topbar { top: 0; }
    .bascule-panneau { right: -8px; }
}

/* ====================== rendez-vous ==================================
   Côté acquéreur, une carte en tête de page : c'est la question qu'il se
   pose en ouvrant son espace, et la seule qui appelle une action de sa
   part. Côté entreprise, une liste sobre dans la colonne de droite.
   ==================================================================== */

/* --- la carte, côté acquéreur --------------------------------------- */
.rdv {
    background: linear-gradient(120deg, var(--blue-dark) 0%, var(--blue) 100%);
    color: #fff; border-radius: 14px; padding: 20px 22px 22px; margin-bottom: 18px;
}
/* Le jour même, la carte change de couleur : ce n'est plus une date à
   noter, c'est un rendez-vous auquel on se rend. */
.rdv-aujourdhui { background: linear-gradient(120deg, #8a5a12 0%, #d98324 100%); }

.rdv-surtitre {
    margin: 0 0 4px; font-size: 12px; font-weight: 800;
    text-transform: uppercase; letter-spacing: .12em; color: rgba(255, 255, 255, .82);
}
.rdv-titre { margin: 0 0 14px; font-size: 21px; line-height: 1.25; color: #fff; }

.rdv-infos { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 18px; margin: 0; }
.rdv-infos dt {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
    color: rgba(255, 255, 255, .72); align-self: baseline; white-space: nowrap;
}
.rdv-infos dd { margin: 0; font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }

.rdv-lieu { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.rdv-lieu:hover { color: #fff; }
.rdv-lieu-note {
    display: block; font-size: 12px; font-weight: 600; text-decoration: none;
    color: rgba(255, 255, 255, .72); margin-top: 1px;
}
.rdv-info {
    margin: 16px 0 0; padding: 12px 14px; font-size: 14.5px; line-height: 1.55;
    background: rgba(255, 255, 255, .14); border-radius: 10px; overflow-wrap: anywhere;
}

.rdv-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 18px 0 0; }
/* Fond blanc sur fond bleu : le bouton d'appel doit être le point le plus
   clair de la carte. */
.rdv-actions .btn-primary { background: #fff; border-color: #fff; color: var(--blue-dark); }
.rdv-actions .btn-primary:hover { background: #eef7fd; border-color: #eef7fd; color: var(--blue-dark); }
.rdv-appel-note { font-size: 13px; color: rgba(255, 255, 255, .8); }

/* --- la liste, côté entreprise -------------------------------------- */
.rdv-liste { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.rdv-ligne { border-left: 3px solid var(--blue); padding: 2px 0 2px 12px; }
/* Un rendez-vous passé reste là — c'est l'historique des rencontres — mais
   il ne doit plus attirer l'œil. */
.rdv-ligne.est-passe { border-left-color: var(--line); opacity: .62; }
.rdv-ligne-tete { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.rdv-ligne-titre { font-weight: 700; font-size: 14.5px; }
.rdv-ligne-quand { font-size: 13px; color: var(--ink-2); margin-top: 1px; }
.rdv-ligne-lieu  { font-size: 13px; color: var(--ink-3); overflow-wrap: anywhere; }
.rdv-ligne-info  { font-size: 13px; color: var(--ink-2); margin-top: 4px; white-space: pre-line; }
.rdv-ligne-actions { margin-top: 6px; }

/* Date et heure côte à côte : elles se saisissent d'un même geste. */
.rdv-paire { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 12px; }

@media (max-width: 559px) {
    .rdv { padding: 17px 16px 18px; }
    .rdv-titre { font-size: 19px; }
    .rdv-infos { grid-template-columns: minmax(0, 1fr); gap: 0; }
    .rdv-infos dt { margin-top: 10px; }
    .rdv-actions .btn { width: 100%; justify-content: center; }
}

/* =============== édition au vol d'une cellule ========================
   Double-clic sur un montant, un taux ou une remarque. L'affordance doit
   se voir sans crier : un soulignement pointillé au survol suffit à dire
   « ça se modifie », là où une bordure permanente ferait du tableau un
   formulaire.
   ==================================================================== */
td.modifiable { cursor: cell; }
td.modifiable:hover {
    box-shadow: inset 0 -2px 0 var(--blue);
    background: #f4fafe;
}
/* Pas de soulignement sur les cellules déjà colorées par leur provenance :
   le fond dit d'où vient le montant, et deux signaux sur la même cellule
   n'en font plus qu'un, illisible. */
td.modifiable.val-manual:hover, td.modifiable.val-calc:hover { background: #cfe6f7; }

td.est-en-edition { padding: 2px 4px; background: #fff; }
.cellule-saisie {
    width: 100%; min-width: 70px; box-sizing: border-box;
    border: 1px solid var(--blue); border-radius: 6px;
    padding: 5px 7px; font: inherit; font-size: 12.5px;
    background: #fff; color: var(--ink);
}
.cellule-saisie:focus { outline: none; box-shadow: 0 0 0 3px rgba(1, 136, 204, .18); }
.cellule-saisie-num { text-align: right; font-variant-numeric: tabular-nums; }

/* Pendant l'aller-retour : la cellule pâlit, sans bouger d'un pixel. Un
   tableau qui se réorganise pendant qu'on le corrige fait perdre la ligne
   suivante. */
td.est-en-cours { opacity: .5; }

/* Refus : la valeur d'avant est remise, et la cellule le dit. Un chiffre
   faux qu'on croit enregistré est pire qu'une correction à refaire. */
td.est-refusee {
    background: #fbecec !important;
    box-shadow: inset 3px 0 0 var(--danger);
}

/* La remarque est du texte libre : elle respire, et elle se replie. */
table.grid-dense td[data-champ="comment"] {
    white-space: normal; max-width: 220px; color: var(--ink-2);
}

/* L'analyse approfondie se distingue des autres actions : elle coûte cinq
   fois plus cher et met plusieurs secondes. Un bouton qui se confond avec
   « relancer » se cliquerait par réflexe. */
.btn-poussee { font-weight: 800; color: var(--blue-dark); letter-spacing: -0.04em; }
.btn-poussee:hover { border-color: var(--blue); background: var(--blue-tint); }
