/* Revue du 01.10.2026 · contraste (WCAG AA, 4,5:1 pour le texte).
   --ink-3 (#93A1B5, 2,6:1 sur blanc) colore les libellés des champs, et sur le
   téléphone de l'état des lieux, dehors, ils ne se lisaient plus. Même chose
   pour l'orange d'avertissement employé comme texte (2,4:1 sur son fond).
   Corrigé ici, par-dessus les jetons du système de design, sans le modifier :
   #5E6D84 tient 4,6:1 sur les trois surfaces ; #8A5600 (déjà celui des
   titres d'alerte du système) 5,4:1 sur le fond d'avertissement. */
:root {
  --ink-3: #5E6D84;
  --warning-texte: #8A5600;
}
.badge--warn { color: var(--warning-texte); }

/**
 * frontendv1 · application-specific layout.
 *
 * design-system (`_ds/*`) supplies brand tokens and components (`.btn`,
 * `.tbl`, `.badge`, `.crumbs`, `.chip`…) — see design-system/readme.md and
 * cards/ui.css. This file only adds what design-system doesn't cover: the
 * application shell (sidebar, sticky top bar) and the login screen, drawn
 * from the prototype v3 (immopilot-v1-prototype-v3.vercel.app), not ported
 * from frontend/src/styles.css.
 */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
button { font-family: inherit; cursor: pointer; }

/* ─── Text utilities · not in design-system, defined once here ───────────── */
.t-h1 { font-family: var(--font-display); font-weight: var(--display-weight); font-size: var(--fs-h1); letter-spacing: var(--display-tracking); margin: 0; }
.t-h3 { font-family: var(--font-display); font-weight: var(--display-weight); font-size: var(--fs-h3); letter-spacing: var(--display-tracking); margin: 0; }
.t-body { font-size: var(--fs-body); color: var(--ink); margin: 0; }
.t-caption { font-size: var(--fs-caption); color: var(--ink-2); margin: 0; }
.t-eyebrow { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 0; }

/* ═══ Shell · sticky sidebar + sticky top bar ═══════════════════════════════ */

.shell { display: flex; height: 100vh; overflow: hidden; }

/* The bottom padding is for the feedback widget, which pins itself
   bottom-left and would otherwise sit on top of `.sidebar-footer` — the draft
   button and the profile link. The old frontend hit exactly this, bottom-right,
   where the button covered the confirm control of every dialog; measured with
   `elementFromPoint` on 13.08.2026, invisible on a screenshot.

   76px = the button (41px) plus its margin (20px), plus a gutter. */
.sidebar {
  width: 220px; flex: 0 0 220px;
  height: 100%; overflow-y: auto;
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  padding: var(--space-4) var(--space-3) 76px;
  transition: width .15s ease;
}
.shell--collapsed .sidebar { width: 64px; flex-basis: 64px; padding-inline: var(--space-2); }

.brand { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-2) var(--space-5); }
.brand-logo { flex: 0 0 auto; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: 17px; }
.brand-name b { color: var(--accent); font-weight: 700; }
.sidebar-toggle { margin-left: auto; background: none; border: none; color: var(--ink-3); width: 24px; height: 24px; border-radius: var(--radius-sm); display: grid; place-items: center; }
.sidebar-toggle:hover { background: var(--surface-2); color: var(--ink); }
.sidebar-toggle svg, .sidebar-toggle i { width: 15px; height: 15px; }

/* ⚠ 08.09.2026 · la flèche débordait du menu replié.
 *
 * Stan : « quand la barre de menu est collapse, on voit la petite flèche en
 * dehors du menu ; déplacer la flèche pour que ça soit dans le menu ». La
 * barre repliée fait 64 px ; la ligne de marque y aligne le logo (26 px), un
 * écart et la flèche (24 px) côte à côte, plus deux paddings de 8 px de chaque
 * côté — près de 90 px. `margin-left: auto` la poussait donc hors du cadre,
 * sur le contenu.
 *
 * Repliée, la ligne s'empile : le logo, puis la flèche dessous, tous deux
 * centrés. Rien ne dépasse, et la flèche reste au même endroit du regard —
 * en tête de la barre, là où on l'a laissée. */
.shell--collapsed .brand { flex-direction: column; gap: var(--space-3); padding-inline: 0; }
.shell--collapsed .sidebar-toggle { margin-left: 0; }

.nav-title { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); padding: var(--space-2) var(--space-2) var(--space-1); }
.nav-rule { border: none; border-top: 1px solid var(--border); margin: var(--space-3) 0; }
.nav-item {
  display: flex; align-items: center; gap: var(--space-3); padding: 9px var(--space-2);
  border-radius: var(--radius-sm); color: var(--ink-2); text-decoration: none; font-size: 14px; font-weight: 500;
}
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item--active { background: var(--accent-soft); color: var(--accent); }
.nav-icon { display: grid; place-items: center; width: 18px; height: 18px; flex: 0 0 auto; }
.nav-icon svg, .nav-icon i { width: 18px; height: 18px; }
.nav-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill { margin-left: auto; font-family: var(--font-mono); font-size: 11px; font-weight: 700; color: #fff; background: var(--warning); border-radius: var(--radius-pill); padding: 1px 7px; min-width: 18px; text-align: center; }
.pill--bad { background: var(--danger); }
/* US-4 / CA-2, US-5 / CA-1 · le compteur « à traiter » est posé sur l'icône,
 * déployée comme repliée : repliée, il n'y a plus qu'elle, et il doit y rester
 * visible. Dans le cadre de 18 px, débordant en haut à droite — la barre
 * repliée en fait 64, il ne sort pas du menu. */
.nav-icon { position: relative; }
.nav-count {
  position: absolute; top: -7px; right: -11px; margin: 0;
  font-size: 9.5px; line-height: 14px; padding: 0 4px; min-width: 15px;
  box-shadow: 0 0 0 2px var(--surface);
}
.pill--inert { color: var(--ink-3); background: none; }

.sidebar-footer { margin-top: auto; display: flex; flex-direction: column; gap: var(--space-3); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.sidebar-draft { width: 100%; justify-content: center; }
.sidebar-profile { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); text-decoration: none; color: var(--ink); }
/* ⚠ Le nom et le rôle portaient `text-overflow: ellipsis` sans effet : leur
   conteneur flex ne peut pas rétrécir sous son contenu sans `min-width: 0`.
   Une adresse un peu longue (`parcours@immopilotapp.com`) sortait donc de la
   barre, coupée net au bord.

   Poser l'ellipse a d'abord semblé suffire — et `ecrans.mjs` l'a refusée,
   à raison : une adresse en points de suspension reste une adresse qu'on ne
   peut pas lire. La garde était muette auparavant parce que le rognage avait
   lieu un niveau **au-dessus** de l'élément mesuré ; en le rendant local, mon
   correctif l'a rendu visible à la sonde.

   Le texte revient donc à la ligne. Le pied de la barre a la place, une
   identité se lit en entier, et rien n'est rogné. `anywhere` pour qu'une
   adresse sans espace se coupe malgré tout plutôt que de déborder.

   ⚠ Corrigé **dans** les règles d'origine ci-dessous, et non par un bloc
   posé au-dessus : mon premier essai déclarait le retour à la ligne avant
   elles, à spécificité égale — les dernières gagnaient et le correctif
   n'avait aucun effet. Deux règles qui se disputent la même propriété
   finissent toujours par ce silence-là. */
.sidebar-profile > span:not(.av) { min-width: 0; }
.sidebar-profile:hover { background: var(--surface-2); }
.sidebar-profile-name { display: block; font-size: 13.5px; font-weight: 700; overflow-wrap: anywhere; line-height: 1.25; }
.sidebar-profile-role { display: block; font-size: 11.5px; color: var(--ink-3); overflow-wrap: anywhere; line-height: 1.25; }
.sidebar-logout { width: 100%; justify-content: center; gap: var(--space-2); }

/* .av / .av--sm / .av--lg / .av--ghost all come from design-system's ui.css —
   redefining .av here once clobbered .av--ghost (equal-specificity, later
   source order wins per property), silently turning every "ghost" avatar
   solid blue. Not redefined again for that reason. */

/* ⚠ `position: relative` n'est pas cosmétique : c'est ce qui fait de `.main` le
   bloc conteneur de tout ce qui se positionne en absolu à l'intérieur.

   Sans lui, un `.sr-only` — `position: absolute` pour n'exister que pour les
   lecteurs d'écran — n'a aucun ancêtre positionné : son bloc conteneur est la
   fenêtre, et l'`overflow: auto` de `.main` ne le retient pas. Il se pose alors
   à sa position statique dans le flux, c'est-à-dire là où il serait sans être
   positionné. En lecture, ces spans vivent dans la barre du haut et personne ne
   les voit. En édition, l'éditeur de collections en pose un par ligne, tout en
   bas de la fiche, et le **document entier** s'étire jusqu'à lui : 3144 px sur
   une fenêtre de 958, la coquille qui part au défilement, deux écrans de vide
   sous la fiche.

   Signalé par Stan le 21.08.2026 (« problème d'affichage en mode édition »),
   mesuré et réduit le 01.09. Un conteneur qui défile doit être un bloc
   conteneur ; `ecrans.mjs` vérifie désormais que le document ne défile jamais. */
.main { flex: 1; min-width: 0; height: 100%; overflow-y: auto; display: flex; flex-direction: column; position: relative; }

/* The top bar · every list control lives here, sticky. */
.topbar {
  position: sticky; top: 0; z-index: 5;
  background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-5); min-height: 56px;
}
.topbar-context { display: flex; gap: var(--space-2); }
.topbar-tools { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); }
.locale-toggle { color: var(--ink-2); }
.locale-toggle svg, .locale-toggle i { width: 16px; height: 16px; }
.search { position: relative; }
.search-field { width: 220px; }
.select-wrap .select { min-width: 160px; }
.toggle { display: flex; align-items: center; gap: var(--space-2); font-size: 13.5px; color: var(--ink-2); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.content { padding: var(--space-5); flex: 1; }

/* ─── A list's title and qualified count ──────────────────────────────────── */
.list-header { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: var(--space-4); }
.list-title { font-family: var(--font-display); font-weight: var(--display-weight); font-size: 28px; letter-spacing: var(--display-tracking); margin: 0; }
.list-count { font-size: 13.5px; color: var(--ink-2); margin: 4px 0 0; }
.list-header-actions { flex: 0 0 auto; }

/* .btn-sm · design-system only ships one .btn size; a couple of screens
   (list-header actions, per-record "new" buttons) want a tighter one. */
.btn-sm { padding: 7px 12px; font-size: 13px; }

/* ─── Narrow-viewport guard ────────────────────────────────────────────────── */
.guard { min-height: 100vh; display: grid; place-items: center; background: var(--bg); padding: var(--space-5); }
.guard-card { max-width: 420px; text-align: center; }
.guard-card .t-h3 { margin-bottom: var(--space-3); }

/* ─── Library · grouped cards, not a table (matches the prototype) ────────── */
.lib-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); margin-bottom: var(--space-3); overflow: hidden;
}
.lib-card-head, .lib-sub-head {
  width: 100%; display: flex; align-items: center; gap: var(--space-3);
  padding: 15px var(--space-4); background: none; border: none; text-align: left; cursor: pointer;
}
.lib-card-head:hover, .lib-sub-head:hover { background: var(--surface-2); }
.lib-chevron { display: grid; place-items: center; color: var(--ink-3); flex: 0 0 auto; }
.lib-chevron svg, .lib-chevron i { width: 16px; height: 16px; }
.lib-card-title { font-family: var(--font-display); font-weight: 700; font-size: 15px; color: var(--ink); }
.lib-card-count { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.lib-card-body { border-top: 1px solid var(--border); }
.lib-subgroup:not(:last-child) { border-bottom: 1px solid var(--border); }
.lib-sub-head { padding-left: 36px; background: var(--bg); }
.lib-sub-title { font-family: var(--font-display); font-weight: 600; font-size: 14px; }

/* ─── Rent · custom grouped table — table.js's generic grouping doesn't
   support a per-group action button or a paid/pending footer summary, both
   of which the reference calls for here. ─────────────────────────────────── */
.rent-group { margin-bottom: 18px; }
.rent-group-head { display: flex; align-items: center; gap: var(--space-3); padding: 6px 2px; }
.rent-group-head .t-name { font-weight: 700; }
.rent-table-wrap {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); overflow: hidden;
}
.rent-row { display: flex; align-items: center; gap: var(--space-3); padding: 6px var(--space-4); border-top: 1px solid var(--border); }
.rent-row:first-child { border-top: none; }
.rent-row--head {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); background: var(--surface-2); padding: 8px var(--space-4); border-top: none;
}
.rent-cell-month { display: flex; gap: 8px; flex: 0 0 250px; }
.rent-cell-month .sel-wrap { flex: 1; }
.rent-cell-month .sel-wrap:first-child { flex: 1.5; }
.rent-cell-due {
  display: flex; align-items: center; gap: 7px; flex: 0 0 150px; color: var(--ink-2); font-size: 13.5px;
  border: var(--border-width) solid var(--border-strong); border-radius: var(--btn-radius);
  padding: 6px 13px; background: var(--surface);
}
.rent-cell-due svg, .rent-cell-due i { width: 14px; height: 14px; color: var(--ink-3); flex-shrink: 0; }
.rent-row--head .rent-cell-due { border-color: transparent; background: none; padding: 0; }
.rent-alert { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.rent-alert-flag { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; font-size: 12.5px; color: var(--danger); white-space: nowrap; }
.rent-cell-amount { flex: 0 0 110px; text-align: right; }
.rent-cell-status { flex: 0 0 150px; display: flex; justify-content: flex-end; }
.rent-cell-remove { flex: 0 0 auto; color: var(--ink-3); }
.rent-row--head .rent-cell-remove { width: 28px; }
.rent-row--overdue { background: var(--danger-soft); }

/* ─── "Generate rent deadlines" — a right-side panel (generate.js), not the
   centered form dialog other create flows use. ─────────────────────────── */
.gen-section-head {
  display: flex; align-items: center; gap: 10px; background: none; border: none;
  padding: 4px 2px 10px; cursor: pointer; width: 100%; text-align: left;
}
.gen-lease-list {
  max-height: 260px; overflow-y: auto; border: 1px solid var(--border-strong);
  border-radius: var(--radius); padding: 4px;
}
.gen-lease-row { padding: 9px 8px; border-radius: var(--radius-sm); }
.gen-lease-row:hover { background: var(--surface-2); }
.gen-choice-row { display: flex; gap: 10px; }
.gen-choice-btn {
  flex: 1; padding: 13px 10px; border: 1px solid var(--border-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); font-weight: 600; font-size: 14px; cursor: pointer;
  text-align: center; transition: border-color .12s, background .12s, color .12s;
}
.gen-choice-btn:hover { border-color: var(--accent); }
.gen-choice-btn.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
/* Selects inside a data row read compact — `.select`'s own 184px min-width
   is sized for a form, not a table cell. */
.rent-cell-month .sel-wrap select, .rent-cell-status .sel-wrap select { min-width: 0; width: 100%; padding: 6px 30px 6px 12px; }
.rent-cell-status .sel-wrap { min-width: 130px; }
.rent-cell-status .sel-wrap select:disabled { cursor: default; opacity: .85; }
.rent-group-foot { padding: 8px 4px; font-size: 12px; color: var(--ink-3); }

/* ─── MailBox · plain group headers over a .mail card — the prototype
   doesn't box these the way Library boxes its groups. ──────────────────── */
.mb-group-head {
  width: 100%; display: flex; align-items: center; gap: var(--space-3);
  padding: 9px 2px; background: none; border: none; text-align: left; cursor: pointer;
}
.mb-group-head:hover .t-name { color: var(--accent); }

.lib-row {
  display: flex; align-items: center; gap: var(--space-3); padding: 13px var(--space-4);
  border-top: 1px solid var(--border); cursor: pointer;
}
.lib-subgroup .lib-row { padding-left: 68px; }
.lib-row:hover { background: var(--surface-2); }
.lib-row-ic {
  width: 34px; height: 34px; border-radius: var(--radius-sm); background: var(--surface-2); color: var(--ink-3);
  display: grid; place-items: center; flex: 0 0 auto;
}
.lib-row-ic svg, .lib-row-ic i { width: 16px; height: 16px; }
.lib-row-ic--sm { width: 26px; height: 26px; background: var(--accent-soft); color: var(--accent); }
.lib-row-main { flex: 1; min-width: 0; }
.lib-row-title { font-family: var(--font-display); font-weight: 700; font-size: 14.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Signed-document mark, next to the title — separate from the status pill,
   matching the prototype (shown whenever statut === 'signe', regardless of
   which status label the pill itself carries). */
.lib-row-signed { display: inline-flex; color: var(--accent-2); margin-right: 4px; vertical-align: -2px; }
.lib-row-signed svg, .lib-row-signed i { width: 13px; height: 13px; }
/* "Formule officielle" — a neutral inline tag, not a colored badge, per the
   prototype's own styling of that marker. */
.tag-official {
  display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .08em; text-transform: uppercase; font-weight: 700; color: var(--ink-3);
  background: var(--surface-2); border-radius: 4px; padding: 1px 6px; margin-right: 6px;
}
.lib-row-cat { flex: 0 0 auto; }
.lib-row-status { flex: 0 0 auto; }
.lib-row-date { flex: 0 0 auto; min-width: 78px; text-align: right; }
.lib-row-chevron { display: grid; place-items: center; color: var(--ink-3); flex: 0 0 auto; }
.lib-row-chevron svg, .lib-row-chevron i { width: 15px; height: 15px; }

/* ─── Grouped table rows · not in design-system, posed once ────────────────── */
.grp-head td { background: var(--surface-2); padding: 0 !important; border-bottom: 1px solid var(--border); }
.grp-head--sub .grp-toggle { padding-left: 40px; background: var(--surface); font-weight: 500; }
.grp-toggle { width: 100%; display: flex; align-items: center; gap: var(--space-2); background: none; border: none; padding: 9px 16px; text-align: left; font-weight: 600; font-size: 13px; color: var(--ink); }
.grp-chevron { color: var(--ink-3); width: 14px; display: inline-block; }
.grp-count { margin-left: auto; font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); font-weight: 400; }
.grp--collapsed tr:not(.grp-head) { display: none; }

/* ═══ Login · drawn from the prototype v3 (Google + email, no functional
   password field — see app.js for why) ═══════════════════════════════════ */

.login { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-5); background: var(--bg); padding: var(--space-5); }
.login-brand { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.login-brand-name { font-family: var(--font-display); font-weight: 700; font-size: 20px; }
.login-brand-name b { color: var(--accent); }

.locale-toggle--corner { position: fixed; top: var(--space-4); right: var(--space-4); }

.login-card {
  width: 100%; max-width: 400px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); padding: var(--space-6);
}
.login-card .t-h3 { margin-bottom: var(--space-4); }

.login-google {
  width: 100%; justify-content: center; gap: var(--space-2);
  background: var(--surface); color: var(--ink); border-color: var(--border-strong);
}
.login-magic { width: 100%; justify-content: center; gap: var(--space-2); margin-top: var(--space-2); }
.login-magic svg { width: 16px; height: 16px; }
.login-magic-help { text-align: center; margin: var(--space-1) 0 var(--space-2); }
.login-separator { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-4) 0; color: var(--ink-3); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.login-separator::before, .login-separator::after { content: ''; flex: 1; height: 1px; background: var(--border); }

.login-card form { display: flex; flex-direction: column; gap: var(--space-3); }
.login-options { display: flex; align-items: center; justify-content: space-between; font-size: 13px; margin: 2px 0 var(--space-1); }
.login-options a { color: var(--accent); text-decoration: none; }
.login-options a:hover { text-decoration: underline; }

.login-submit { width: 100%; justify-content: center; }

/* ─── Demo-account picker · visual match only, see app.js ─────────────────── */
.demo-card {
  width: 100%; max-width: 400px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); padding: var(--space-4) var(--space-5);
}
.demo-card .t-eyebrow { padding-bottom: var(--space-2); }
.demo-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0; border-top: 1px dashed var(--border); }
.demo-row:first-of-type { border-top: none; }
.demo-row .t-sub { font-size: 12.5px; color: var(--ink-2); margin-top: 1px; }
.demo-chevron { margin-left: auto; color: var(--ink-3); display: grid; place-items: center; }
.demo-chevron svg, .demo-chevron i { width: 16px; height: 16px; }

/* ─── Overlays · veil + centered box, and toast stack ─────────────────────── */
.veil { position: fixed; inset: 0; background: rgba(19, 35, 59, .45); display: grid; place-items: center; z-index: 50; padding: var(--space-5); }
.overlay-box { max-width: 640px; width: 100%; max-height: 90vh; overflow-y: auto; }
/* En bas à droite (recette du 03.09.2026) · à gauche, les toasts recouvraient
   le bouton du widget de retours puis le pied de la barre latérale. */
#toast-host { position: fixed; right: var(--space-5); bottom: var(--space-5); max-width: 420px; z-index: 60; display: flex; flex-direction: column; gap: var(--space-2); }

/* ─── Content reader · a right-side drawer ─────────────────────────────────── */
.veil--right { justify-content: flex-end; padding: 0; align-items: stretch; }
body.drawer-open { overflow: hidden; }
.drawer {
  width: min(760px, 92vw); height: 100vh; background: var(--surface);
  display: flex; flex-direction: column; box-shadow: var(--shadow-pop);
  animation: drawer-in .18s ease-out;
}
@keyframes drawer-in { from { transform: translateX(24px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
.drawer-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); flex: 0 0 auto; }
.drawer-brand { font-family: var(--font-display); font-weight: 700; font-size: 15px; }
.drawer-brand b { color: var(--accent); }
.drawer-eyebrow { margin-left: var(--space-3); font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.drawer-head .btn-ico { margin-left: auto; }
.drawer-body { padding: var(--space-5) var(--space-6) var(--space-6); overflow-y: auto; flex: 1; display: flex; flex-direction: column; min-height: 0; }
/* ─── Le panneau « Nouvel email » · SLK-597, Stan, 05.10.2026 ──────────────────
   Trois étages : le haut (engagements, « À », « Cci », objet) ne rétrécit
   jamais — c'est son écrasement qui faisait passer « À » sur « Cci » au
   troisième engagement ; le corps et les pièces défilent ; la barre et le
   pied restent en place. « Rédiger le message » est dans l'entête. Sur un
   écran trop court pour les trois, c'est le panneau entier qui défile, et
   l'étage du corps garde de quoi écrire. */
.composeur-corps { padding: 0; }
.composeur-corps > * { flex-shrink: 0; }
.composeur-corps > .composeur-cadre {
  flex: 1 1 0; min-height: 320px;
  border-radius: 0; border-left: none; border-right: none; border-bottom: none; box-shadow: none;
}
.composeur-cadre > * { flex-shrink: 0; }
.composeur-cadre > .composeur-defile { flex: 1 1 0; min-height: 120px; overflow-y: auto; }
.drawer-head .composeur-rediger { margin-left: auto; }
.drawer-head .composeur-rediger + .btn-ico { margin-left: var(--space-2); }
/* La preview prend toute la hauteur qui reste · Stan, 14.09.2026 (7f70ef0f).
   Le cadre était borné à 400px ; un acte A4 s'y lisait par le haut, et la
   page débordait à droite. Le tiroir s'élargit pour une feuille. */
.drawer--feuille { width: min(1040px, 96vw); }
.drawer-content { flex: 1; display: flex; flex-direction: column; min-height: 0; }
/* 02.10.2026 · la sonde de 7f70ef0f l'a revu : la ligne d'actions (Archiver,
   Télécharger, Mettre en signature) et « Figé le » ont repoussé la feuille,
   qui ne prenait plus que 55 % du tiroir. Elle garde au moins 72 % de l'écran ;
   le tiroir défile un peu plutôt que de rapetisser l'acte. */
.drawer-content .apercu { flex: 1; min-height: max(520px, 72vh); }
.drawer-content .apercu-corps { min-height: 0; padding: 0; align-items: stretch; }
.drawer-content .apercu-pdf { height: 100%; min-height: 0; display: block; }
.drawer-top-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); }
.drawer-category { display: flex; flex-direction: column; gap: 5px; }
.drawer-category select { min-width: 160px; font-family: var(--font-mono); letter-spacing: .04em; }
.drawer-title { font-family: var(--font-display); font-weight: var(--display-weight); font-size: 26px; letter-spacing: var(--display-tracking); margin: 0 0 4px; }
.drawer-toolbar { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-4) 0; padding: var(--space-3) 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.drawer-toolbar .sp { flex: 1; }
.drawer-content { margin-top: var(--space-4); }

.block { padding: 10px 0; }
.block-title { font-family: var(--font-display); font-weight: 700; font-size: 15px; margin: 0 0 6px; }
.block-text { margin: 0; }
.block-value { background: var(--accent-soft); color: var(--ink); border-radius: var(--radius-sm); padding: 1px 5px; font-weight: 600; }
.block--open { background: var(--surface-2); border-radius: var(--radius); padding: 12px 14px; margin: 6px 0; }
.block-input { width: 100%; resize: vertical; font-family: var(--font-body); }
.prov-vigilance { color: var(--ink-2); font-style: italic; }

/* Signed-document mark, next to the reader's title — same idea as the
   library row's .lib-row-signed, sized for a 26px heading instead of a
   14.5px row title. */
.drawer-signed { display: inline-flex; color: var(--accent-2); margin-right: 5px; vertical-align: -3px; }
.drawer-signed svg, .drawer-signed i { width: 19px; height: 19px; }

/* ─── Reader · "paper" view — a converted or signed act rendered as a page,
   not as on-screen prose. Bleeds to the drawer's edges against a neutral
   backdrop, the way a page sits on a desk. ─────────────────────────────── */
.paper-frame {
  background: #5a6675; margin: 0 calc(-1 * var(--space-6)) calc(-1 * var(--space-6));
  padding: 28px 0 32px; display: flex; justify-content: center;
}
.paper-page { width: min(620px, 90%); background: #fff; border-radius: 2px; box-shadow: 0 6px 24px rgba(0, 0, 0, .22); overflow: hidden; }
.paper-head { display: flex; align-items: center; gap: 9px; padding: 22px 48px 16px; border-bottom: 1.5px solid rgba(0, 0, 0, .12); }
.paper-brand { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.02em; font-size: 15px; color: #111; }
.paper-brand b { color: var(--accent); font-weight: 600; }
.paper-meta { margin-left: auto; font-family: Georgia, serif; font-size: 10px; color: #5a5a4a; text-align: right; line-height: 1.4; }
.paper-body { padding: 30px 48px 8px; }
.paper-title { font-family: Georgia, serif; font-weight: 700; font-size: 18px; color: #111; text-align: center; margin-bottom: 24px; }
.paper-block { margin-bottom: 15px; }
.paper-block-title { font-family: Georgia, serif; font-weight: 700; font-size: 13px; color: #111; margin-bottom: 4px; }
.paper-text { font-family: Georgia, serif; font-size: 13px; line-height: 1.85; color: #1a1a1a; text-align: justify; white-space: pre-wrap; margin: 0; }
.paper-sig { margin-top: 30px; max-width: 220px; }
.paper-sig-line { border-bottom: 1px solid #999; margin-top: 30px; }
.paper-sig-cap { font-family: Georgia, serif; font-size: 10.5px; color: #555; margin-top: 5px; }
.paper-foot { display: flex; align-items: center; gap: 8px; padding: 12px 48px; border-top: 1.5px solid #e2e2e2; font-family: Georgia, serif; font-size: 9.5px; color: #999; }

/* ─── Reader · upload/reference placeholder — a deposited or platform file
   has no body to render; say so plainly instead of faking a preview. ────── */
.upload-tile { display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; padding: 64px 24px; border: 1px dashed var(--border-strong); border-radius: 16px; }
.upload-tile-ic { width: 52px; height: 52px; border-radius: 12px; background: var(--danger-soft); color: var(--danger); display: grid; place-items: center; }
.upload-tile-ic svg, .upload-tile-ic i { width: 24px; height: 24px; }
.upload-tile-name { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--ink); }

.badge--info { background: var(--accent-soft); color: var(--accent); }
.badge--info .dot { background: var(--accent); }

/* ─── Related-record list · not in design-system, posed once ─────────────── */
.rec-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; position: relative; }
.rec-list li { padding: 10px 0; border-bottom: 1px dashed var(--border); }
.rec-list li:last-child { border-bottom: none; }
.rec-list a { color: var(--accent); text-decoration: none; font-weight: 600; font-size: 14px; }
.rec-list a:hover { text-decoration: underline; }
/* Un bouton qui a l'allure d'un lien · il ouvre un panneau, il ne navigue pas.
   Même allure que `.rec-list a` ci-dessus, pour que deux choses qui se
   ressemblent à l'écran se ressemblent aussi dans la feuille. */
.lien { appearance: none; background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; color: var(--accent); font-weight: 700; font-size: 14px; text-align: left; }
.lien:hover { text-decoration: underline; }
.lien:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
/* A numbered variant (preferences) — an index column, and a line that can
   carry its own remove button since one preference is retirable on the
   spot, outside "Modifier" (US-23 / CA-3). */
.rec-list .ix { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); margin-right: 8px; }

/* ─── Textes légaux · l'accordéon des articles ──────────────────────────────
   Retour f49d2d89 : « on peut voir le doc en court que l'on peut expand ou
   collapse ». La tête reste une ligne de liste ordinaire — le recueil se
   parcourt d'abord des yeux — et le corps ne paraît que déplié.

   Le texte garde ses alinéas : la source les porte en sauts de ligne, et les
   écraser changerait ce qu'on relit d'un article de droit. D'où `pre-wrap`,
   et une mesure de ligne bornée pour que 37 articles restent lisibles. */
.rulv-tete { display: flex; align-items: baseline; gap: 10px; width: 100%; }
.rulv-tete .rulv-id { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); flex-shrink: 0; }
.rulv-tete .rulv-titre { color: var(--ink); font-weight: 600; flex: 1; }
.rulv-tete:hover { text-decoration: none; }
.rulv-tete:hover .rulv-titre { text-decoration: underline; }
.rulv-chevron { color: var(--ink-3); display: inline-flex; flex-shrink: 0; }
.rulv-chevron i { width: 16px; height: 16px; }
.rulv-corps { padding: 10px 0 4px 26px; }
.rulv-texte {
  white-space: pre-wrap;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 78ch;
  margin: 0;
}
.rulv-actions { display: flex; gap: 8px; margin-top: 12px; }
.rec-list li.pref { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

/* ─── Property record · inline edit (properties.js, collections.js) ───────
   "Modifier" turns the whole sheet editable in place, not a separate form:
   the header's stat cells become inputs, and each repeatable collection
   (rooms, amenities, extras, appliances, insurance) becomes a stack of
   rows, each with its own columns and a remove button, plus an "add a row"
   control underneath. */
.meta-item .input, .meta-item .select { width: 100%; padding: 6px 10px; font-size: 13.5px; }
.lns { display: flex; flex-direction: column; position: relative; }
.ln { display: flex; align-items: flex-end; gap: 10px; padding: 10px 0; border-bottom: 1px dashed var(--border); }
.ln:last-child { border-bottom: none; }
.ln-col { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.ln-col span { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.ln-col--date { flex: 0 0 160px; }
.ln-remove { flex: 0 0 auto; margin-bottom: 1px; }

/* La ligne d'ajout d'une collection · retour de Stan du 08.09.2026.
 *
 * « Problème d'affichage du bouton Ajouter, qui s'affiche au-dessus du champ
 * N° ». `.ln` ne s'enveloppe pas de lui-même, mais ses colonnes en `flex: 1`
 * poussaient le bouton hors de la largeur utile ; il finissait par déborder et
 * se replier. La ligne d'ajout garde donc son bouton entier — c'est le seul
 * élément de la ligne qu'on ne peut ni rétrécir ni couper — et les colonnes
 * cèdent avant lui. */
.ln--ajout { flex-wrap: nowrap; }
.ln--ajout > .btn { flex: 0 0 auto; white-space: nowrap; }
/* ⚠ 14.09.2026 · Stan, quatre retours : dans les éléments à bien plaire et
 * les annexes d'un engagement, le N°, le prix, la croix et « Ajouter » se
 * chevauchaient à droite. La colonne avait bien sa largeur (`flex: 0 0 90px`)
 * mais le champ dedans non : `.input` (ui.css) n'a pas de largeur, un `<input>`
 * garde donc sa taille intrinsèque (~180 px) et débordait de sa colonne sous
 * la croix — la colonne ne « rétrécit » pas un enfant qu'on ne lui a pas dit
 * de suivre. Chaque champ épouse sa colonne, et les colonnes fixes ont un nom
 * plutôt qu'une largeur inscrite dans chaque écran : la première colonne prend
 * le reste (`.ln-col` est en `flex: 1`, `min-width: 0`). */
.ln-col > .input, .ln-col > .select { width: 100%; min-width: 0; box-sizing: border-box; }
.ln-col--num { flex: 0 0 110px; }
.ln-col--prix { flex: 0 0 140px; }
.coll-add-btn { margin-top: 10px; }
/* A field carrying extra weight — the person record's email (signature
   key) and current address (drives lease prep) in edit mode, per the
   prototype. */
.input--highlight { background: var(--accent-soft); border-color: var(--accent); }

/* ─── Property-creation wizard, step 2 "Pieces" (screens/properties.js) ───
   A seeded room ("Séjour", "Chambre 1"…) reads as plain text until
   touched — border and background only appear on hover/focus — with its
   type as a fixed chip (design-system's `.chip`) and a remove button
   alongside; `.fld-note` is a label's trailing aside (e.g. Canton's "·
   manages the legal framework…"), reset out of `.fld label`'s
   uppercase/mono styling since it's prose, not a field name. */
.fld-note { text-transform: none; letter-spacing: normal; font-weight: 400; font-family: var(--font-body); font-size: 11.5px; color: var(--ink-3); }
.piece-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px dashed var(--border); }
.piece-row:last-child { border-bottom: none; }
.piece-row .piece-name {
  flex: 1; min-width: 0; border: var(--border-width) solid transparent; background: transparent;
  font-family: var(--font-body); font-weight: 600; font-size: 14px; color: var(--ink);
  padding: 5px 7px; border-radius: var(--btn-radius);
}
.piece-row .piece-name:hover { border-color: var(--border); }
.piece-row .piece-name:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: var(--focus-ring); }
.piece-row .chip { flex-shrink: 0; }
/* US-17 / CA-3 · une pièce retirée du gabarit reste visible, barrée et
   estompée, pour qu'on la distingue d'une pièce jamais proposée et qu'on la
   rétablisse — dans l'assistant, sur la fiche en édition comme en lecture. */
.piece-row--retiree .piece-name,
.ln--retiree .ln-col > .input,
.ln--retiree .ln-col > .select,
.ln--retiree .chip-txt { text-decoration: line-through; color: var(--ink-3); }
.piece-row--retiree .chip,
.ln--retiree .chips,
.ln--retiree .chip-add { opacity: .55; }
.ln-retiree-note { flex: 0 0 auto; align-self: center; }
.piece-retiree { color: var(--ink-3); }

/* ─── Clause catalog overlay (catalogue.js) ────────────────────────────── */
.clause-theme { margin-bottom: 18px; }
.clause-theme:last-child { margin-bottom: 0; }
.clause-theme-title { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.clause-theme-count { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); background: var(--surface-2); border-radius: var(--radius-pill); padding: 1px 7px; }
.clause-list { list-style: none; margin: 0; padding: 0; }
.clause { padding: 8px 0; border-bottom: 1px dashed var(--border); display: flex; align-items: flex-start; gap: 10px; }
.clause:last-child { border-bottom: none; }
.clause .ck { align-items: flex-start; flex: 1; }
.clause-text { font-size: 13.5px; line-height: 1.5; }

/* ─── Type cards and pick-lists · draft.js's write wizard, and the
   property-creation wizard's object-type step (screens/properties.js) ──── */
.type-card-row { display: flex; gap: 12px; flex-wrap: wrap; }
.type-card {
  flex: 1; min-width: 120px; text-align: left; padding: 16px; border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius); background: var(--surface); cursor: pointer;
  display: flex; flex-direction: column; gap: 8px; font-family: inherit; color: inherit;
}
.type-card:hover { border-color: var(--accent); }
.type-card .ic { width: 34px; height: 34px; border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; }
.type-card .ic svg, .type-card .ic i { width: 18px; height: 18px; }
.type-card .tt { font-family: var(--font-display); font-weight: 700; font-size: 15px; }
.type-card .dsc { font-size: 12.5px; color: var(--ink-2); line-height: 1.4; }
.type-card .note { font-size: 11.5px; color: var(--ink-3); display: flex; align-items: center; gap: 5px; margin-top: auto; padding-top: 8px; border-top: 1px dashed var(--border); }
/* Persistent selection (property wizard's object-type cards pick one and
   stay picked, unlike draft.js's cards which each just navigate onward)
   and a disabled state for the types not offered at creation yet
   (Parking, Commercial unit — see openCreatePropertyWizard's doc). */
.type-card.on { border-color: var(--accent); background: var(--accent-soft); }
.type-card.disabled { cursor: not-allowed; opacity: .55; }
.type-card.disabled:hover { border-color: var(--border-strong); }
.type-card .soon { font-size: 11.5px; color: var(--ink-3); font-style: italic; }
.pick-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px;
  border: var(--border-width) solid var(--border); border-radius: var(--radius); margin-bottom: 8px;
  cursor: pointer; background: var(--surface); text-align: left; width: 100%; font-family: inherit; color: inherit;
}
.pick-row:hover { border-color: var(--accent); background: var(--surface-2); }
/* Retenu pour une campagne · US-52. La bordure d'accent seule ne suffisait
   pas : au survol, une ligne retenue et une ligne survolée se ressemblaient. */
.pick-row.sel { border-color: var(--accent); background: var(--accent-soft); }
.pick-row.sel .tt { color: var(--accent); }
.pick-row .tt { display: block; font-weight: 700; font-size: 14px; }
.pick-row .sub { display: block; font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }
.pick-group-title { font-family: var(--font-mono); font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); margin: 18px 0 8px; }
.pick-group-title:first-child { margin-top: 0; }

/* ─── Write wizard · verification panel's staged checklist (draft.js) ────── */
.check-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.check-list-item { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--ink-2); animation: check-in .25s ease; }
.check-list-item .ic { color: var(--positive); display: grid; place-items: center; flex: 0 0 auto; }
/* Un contrôle non satisfait ne porte pas une coche verte · US-49. La couleur
   de l'icône était fixée à `--positive` pour tous, parce que la liste ne
   servait qu'à une animation où tout réussissait toujours. */
.check-list-item--warn .ic { color: var(--warning-texte); }
.check-list-item--warn > span:last-child { color: var(--ink); }
.check-list-item .ic svg, .check-list-item .ic i { width: 15px; height: 15px; }
@keyframes check-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }

/* design-system doesn't style a disabled `.btn-ico` (only `.pager button`
   does) — compose.js's attach button needs it (inert until exactly one
   lease is picked), so posed once here, same opacity rule. */
.btn-ico:disabled { opacity: .4; cursor: default; }
.btn-ico:disabled:hover { background: none; color: var(--ink-3); }

@media print {
  .sidebar, .topbar-tools { display: none; }
  /* US-101 · imprimer un écran (revue du 06.10.2026) : ni le fil d'Ariane,
     ni les onglets, ni la barre de recherche et de filtres n'ont de sens sur
     papier ; un champ de saisie s'imprime comme sa valeur, sans cadre ; et
     l'entête d'un tableau se répète à chaque page. */
  /* Portées sous `.shell` : la feuille de l'application ne redéfinit aucun
     sélecteur du design system (styles.mjs). */
  .shell .crumbs, .shell .tabs, .shell .locale-toggle, .shell .tbl-bar { display: none !important; }
  .shell .input, .shell .select, .shell textarea { border: none !important; background: none !important; box-shadow: none !important; padding-left: 0 !important; }
  .shell .sel-wrap svg { display: none !important; }
  .shell thead { display: table-header-group; }
  .shell tr, .shell .field { break-inside: avoid; }
  .shell .main, .shell .content { margin: 0 !important; padding: 0 !important; }
}

@media print {
  /* The feedback widget mounts itself into `#myapi-feedback` at the end of
     `body`, outside our layout. Named by its real id rather than a supposed
     attribute: the old frontend first targeted `[data-feedback-widget]`, which
     does not exist, and the button printed at the foot of every sheet. */
  #myapi-feedback { display: none !important; }
}

/* ─── Retours de recette du 21.08.2026 · SLK-283 ─────────────────────────────
 *
 * En **mode édition**, un champ est rendu dans `.field > b`, pas dans `.fld`.
 * La règle `.fld input{width:100%}` du design system ne s'y applique donc pas,
 * et l'input retombe sur `.input{min-width:180px}` — sans largeur. D'où des
 * champs de 200 px dans un conteneur qui en offre 900, et « Copropriété
 * Grancy 41, con » tronqué faute de place.
 *
 * Signalé six fois, sur six écrans : c'était un seul défaut.
 *
 * La règle vit ici plutôt que dans le design system parce que c'est la façon
 * dont *cette* application rend l'édition d'une fiche — `.field` reste ce
 * qu'il est ailleurs.
 */
.field b .input,
.field b .select,
.field b textarea { width: 100%; }

/* Et le bloc de description, qui n'est pas dans un `.field` mais directement
 * dans son panneau — c'est le signalement de 08:41, distinct des cinq autres
 * bien qu'il se lise pareil à l'écran. Un `textarea` remplit toujours son
 * conteneur ici : il n'existe aucun cas où on en veuille un étroit. */
textarea.input { width: 100%; }

/* Le suffixe (« m³ ») passait déjà sous le champ avant ce correctif : rien ne
 * change pour lui, il reste sur sa propre ligne. */
.field b .t-caption { display: inline-block; margin-top: 4px; }

/* ─── SLK-285 · les listes se ressemblent enfin ──────────────────────────────
 *
 * Deux écarts signalés par Stan, tous deux en comparant les tableaux à la
 * bibliothèque : la ligne cliquable ne le disait pas, et son survol était un
 * gris neutre là où le reste du produit tourne au bleu ImmoPilot.
 *
 * Le jaune signature (`--accent-2`) sur le chevron au survol est ce qu'il
 * demande mot pour mot — « fond bleu immopilot et icon en jaune immopilot ».
 */
.tbl th.tbl-chev, .tbl td.tbl-chev { width: 34px; padding-left: 0; padding-right: 10px; text-align: right; }
.tbl td.tbl-chev svg { width: 16px; height: 16px; color: var(--ink-3); vertical-align: middle; }

.tbl tbody tr[data-href]:hover { background: var(--accent-soft); }
.tbl tbody tr[data-href]:hover td.tbl-chev svg { color: var(--accent-2); }

/* ─── SLK-293 · les baux liés · le loyer sous le nom, l'état à droite ────────
 *
 * Les trois tenaient sur une ligne séparés par des points médians, ce qui les
 * faisait lire comme une phrase — alors que le nom, le montant et l'état sont
 * de natures différentes. Le prototype les hiérarchise ; l'écran ne le faisait
 * pas.
 */
.rel-lease { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.rel-lease-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rel-lease-main .t-caption { font-variant-numeric: tabular-nums; }

/* ─── SLK-287 · les notes de section, repliées derrière un « i » ─────────────
 *
 * Le marqueur est un `<details>` natif : le clavier et les lecteurs d'écran le
 * connaissent, et il ne demande aucun câblage. Le triangle par défaut est
 * retiré, remplacé par un « i » cerclé qui suit le libellé.
 */
.field-note { display: inline-block; margin-left: 6px; vertical-align: middle; }
.field-note > summary {
  list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%;
  border: 1px solid var(--border-strong); color: var(--ink-3);
  font-family: var(--font-body); font-size: 10px; font-weight: 600;
  font-style: italic; line-height: 1; text-transform: none; letter-spacing: 0;
}
.field-note > summary::-webkit-details-marker { display: none; }
.field-note > summary:hover { border-color: var(--accent); color: var(--accent); }
.field-note > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.field-note[open] > summary { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.field-note > p {
  margin: 8px 0 2px; padding: 10px 12px;
  background: var(--accent-soft); border-radius: var(--radius);
  font-family: var(--font-body); font-size: 12.5px; line-height: 1.5;
  color: var(--ink-2); text-transform: none; letter-spacing: 0; font-weight: 400;
  max-width: 62ch;
}

/* SLK-288 · la ligne d'un document porte ses actions à droite. */
.doc-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.doc-row-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }

/* ─── SLK-286 · les caractéristiques, une par puce ───────────────────────────
 *
 * La puce elle-même vient du design system — `.chip` et son `.x` existent déjà,
 * et `compose.js` s'en sert. Les redéfinir ici les aurait repeints partout,
 * puisque cette feuille est chargée après : trois écrans que je n'ai pas
 * touchés auraient changé d'allure. On n'ajoute donc que ce que le design
 * system n'a pas : le conteneur qui empile, et la ligne d'ajout.
 *
 * Disposition verticale demandée : les puces s'empilent et l'ajout reste sous
 * elles. La colonne prend toute la largeur disponible — c'est là que l'ancien
 * champ unique devenait illisible.
 */
.ln-col--chips { min-width: 0; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.chips:empty { display: none; }
/* Le texte d'une puce ne se rogne pas : une caractéristique tronquée en
 * « parquet chêne, balcon… » ne se lit plus, et c'est précisément ce qu'on
 * voulait rendre lisible. Une valeur longue déborde donc sur deux lignes
 * plutôt que de disparaître — relevé à toutes les résolutions par la passe
 * d'épreuve, qui comparait `scrollWidth` et `clientWidth`. */
.chips .chip { max-width: 100%; align-items: flex-start; }
.chips .chip-txt { white-space: normal; overflow-wrap: anywhere; }

/* `.ln-col span` habille les **libellés** de colonne : mono, 10,5 px,
 * majuscules. La règle vise tous les descendants, donc elle attrapait aussi le
 * texte des puces — « parquet chêne » s'affichait « PARQUET CHÊNE », en petit.
 * Une caractéristique se lit comme elle a été saisie ; on rend donc aux puces
 * la typographie que le design system leur donne. */
.ln-col .chips span {
  font-family: var(--font-body); font-size: 13px;
  letter-spacing: normal; text-transform: none; color: var(--ink);
}
.chips .x { font-family: var(--font-body); font-size: 14px; line-height: 1; }
.chips .x:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.chip-add { display: flex; gap: 6px; align-items: center; }
.chip-add .input { flex: 1; min-width: 0; }

/* ─── Le sens d'un message · US-76 / CA-1 ───────────────────────────────────
 *
 * « Les messages se succèdent dans l'ordre, en distinguant l'entrant du
 * sortant. » Rien ne les distinguait : chaque message était un `.msg`
 * identique, et il fallait savoir de mémoire qui est le locataire et qui est
 * le bailleur — dans un fil qui sert en cas de litige.
 *
 * Un rail, pour balayer le fil du regard. Le sens est **aussi** écrit dans
 * l'entête du message, et la pastille change de ton : la couleur seule n'est
 * une distinction pour personne qui ne la perçoit pas.
 */
.msg--entrant { border-left: 3px solid var(--border-strong); }
.msg--sortant { border-left: 3px solid var(--accent); }
/* 81a6b11e · Stan, 08.10.2026 · un courriel reçu se lit en paragraphes, et
   l'historique cité se replie sous la réponse. */
.msg .msg-body p + p { margin-top: 8px; }
.msg .msg-cite { margin-top: 10px; }
.msg .msg-cite > summary { cursor: pointer; color: var(--ink-2); font-size: 13px; }
.msg .msg-cite > p { margin: 6px 0 0; padding-left: 10px; border-left: 2px solid var(--border-strong); color: var(--ink-2); }

/* ─── Une clause retenue au catalogue · US-23 ────────────────────────────────
 *
 * ⚠ Le code posait `clause--on`, une classe qui n'existe nulle part : cocher
 * une clause ne produisait aucun retour sur sa ligne, seulement la coche
 * elle-même. Sur un catalogue de plusieurs dizaines d'entrées repliées par
 * thème, on perdait de vue ce qu'on avait retenu.
 *
 * `.on` seul ne dessinait rien non plus — dans le système de design il n'existe
 * que composé (`.seg button.on`, `.tb.on`). La règle manquait, elle est ici.
 */
.clause.on { background: var(--accent-soft); border-radius: var(--radius-sm); }
.clause.on .clause-text { color: var(--ink); }

/* Un champ refusé sur une fiche (profil) · même signal que dans les assistants,
 * dont l'enveloppe est `.fld` (ui.css) alors que celle des fiches est `.field`.
 * Recette du 03.09.2026. */
.field.err input, .field.err .input, .field.err select, .field.err textarea { border-color: var(--danger); }

/* Calendrier · mois et année au choix direct (retour de Stan du 02.09.2026). */
.cal .mo { display: inline-flex; gap: 4px; }
.cal-sel { font: inherit; font-weight: 600; border: 1px solid transparent; border-radius: 6px; background: transparent; padding: 2px 4px; cursor: pointer; }
.cal-sel:hover, .cal-sel:focus { border-color: var(--line, #c9d6e5); }
.cal-sel:focus-visible, .cal-d:focus-visible { outline: 2px solid var(--accent, #2b5fd9); outline-offset: 1px; }

/* Caractéristiques d'une pièce · retour de Stan du 02.09.2026 : le champ de
 * saisie faisait 40 px et les puces tenaient sur une ligne étroite. Les
 * caractéristiques passent sous « Type de pièce / Libellé », une par ligne,
 * et le champ d'ajout en dessous, large. */
.ln-col--chips { flex-basis: 100%; }
.ln-col--chips .chips { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.ln-col--chips .chip-add .input { min-width: 260px; }
.ln:has(.ln-col--chips) { flex-wrap: wrap; }
.ln:has(.ln-col--chips) > .ln-col:not(.ln-col--chips) { flex: 1 1 220px; }
.ln:has(.ln-col--chips) > .ln-remove { order: 1; }
.ln:has(.ln-col--chips) > .ln-col--chips { order: 2; }

/* ─── Retours de Stan du 04.09.2026 ─────────────────────────────────────── */
/* Badge de statut dans une fiche · `.field span` (ui.css) l'étirait en bloc,
   capitales et mono. Le badge reprend sa forme : taille au contenu, à gauche,
   sentence case, police du produit. */
.field .badge { display: inline-flex; width: auto; text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-size: 12px; margin: 0; }
.field .badge .dot { display: inline-block; margin: 0; }
/* Unité à côté d'un champ (m², m³) · pas un intitulé. */
.field .field-unit { display: inline; text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-size: 12.5px; color: var(--ink-3); margin: 0 0 0 6px; }
/* Lignes de collection · le sélecteur de date faisait 200 px dans une colonne
   de 160, et débordait sous la croix. */
.ln { gap: 12px; }
.ln-col--date { flex: 0 0 200px; }
.ln-col--date .datefield { min-width: 0; width: 100%; }
.ln-remove { margin-left: 4px; }
/* Copier · à gauche de la valeur, à la taille du texte. */
.copiable { display: inline-flex; align-items: center; gap: 8px; }
.copiable .btn-copy { width: 22px; height: 22px; border-color: var(--border); }
.copiable .btn-copy svg { width: 13px; height: 13px; }
/* Échéancier en mode Modifier · la cellule porte déjà un cadre, le sélecteur
   de date n'en ajoute pas un second. */
.rent-cell-due .datefield { border: 0; padding: 0; min-width: 0; background: none; flex: 1; }
/* En-tête de groupe · l'adresse sur sa ligne, les parties dessous. */
.rent-group-head .mb-group-head { align-items: flex-start; }
.rent-group-lines { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; min-width: 0; }
.rent-group-sub { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.rent-group-actions { display: flex; gap: 8px; align-items: center; margin-left: auto; }
.rent-cell-pick { flex: 0 0 22px; display: flex; align-items: center; }
.rent-cell-pick input { margin: 0; }

/* ── L'écran du signataire ──────────────────────────────────────────────────
 *
 * Il ne partage rien avec le reste de l'application, et c'est voulu : pas de
 * coquille, pas de navigation, pas de portefeuille. Un locataire arrive par un
 * lien, lit un acte, signe, et s'en va.
 *
 * ⚠ Il doit tenir sur un téléphone · c'est là qu'on ouvre un courriel. La
 * garde de largeur du reste de l'application ne s'applique pas ici.
 */
body.mode-signature { background: var(--bg, #F4F7FC); }

/**
 * ⚠ Le widget de recette est masqué chez le signataire.
 *
 * Il est posé par un `<script>` global dans la page d'entrée, donc il
 * s'affichait aussi devant le locataire — « Donner un retour », l'outil de
 * recette d'ImmoPilot, sur un écran où quelqu'un signe un bail. Vu sur la
 * première capture, le 25.09.
 *
 * On masque large et sans savoir ce qu'il injecte : tout élément de premier
 * niveau que l'application n'a pas posé elle-même. `#app` et les nœuds du
 * produit sont nommés ; ce qui reste vient d'ailleurs.
 */
body.mode-signature > *:not(#app):not(script):not(style):not(link) { display: none !important; }

.signer-page { max-width: 560px; margin: 0 auto; padding: 32px 18px 56px; }
.signer-page--large { max-width: 860px; }

.signer-carte {
  background: #fff; border: 1px solid var(--border, #D8DEE9); border-radius: 12px;
  padding: 28px 26px; text-align: center; margin-top: 48px;
}
.signer-carte h1 { font-size: 19px; margin: 0 0 8px; }
.signer-carte p { margin: 0; color: var(--ink-2, #5B6B85); line-height: 1.6; }
.signer-carte--fait { border-color: #BFE0CA; background: #F5FBF7; }
.signer-carte--attente { border-color: #EBD9A8; background: #FFFBF0; }

.signer-tete {
  display: flex; align-items: baseline; gap: 12px;
  padding-bottom: 12px; margin-bottom: 18px; border-bottom: 1px solid var(--border, #D8DEE9);
}
.signer-marque { font-weight: 700; color: var(--accent, #2456D6); letter-spacing: -.2px; }
.signer-titre { color: var(--ink-2, #5B6B85); font-size: 14px; }

/* La feuille · un cadre isolé, et une hauteur qui donne envie de lire plutôt
   que de faire défiler à l'aveugle. */
.signer-feuille {
  background: #fff; border: 1px solid var(--border, #D8DEE9); border-radius: 10px;
  overflow: hidden; margin-bottom: 20px;
}
.signer-feuille iframe { display: block; width: 100%; height: 460px; border: 0; }

.signer-acte {
  background: #fff; border: 1px solid var(--border, #D8DEE9); border-radius: 10px;
  padding: 22px 22px 20px;
}
.signer-acte h2 { font-size: 15px; margin: 0 0 14px; }

.signer-qui { margin: 0 0 16px; font-weight: 600; }
.signer-qui span {
  display: block; font-weight: 400; font-size: 12.5px;
  color: var(--ink-2, #5B6B85); margin-top: 3px;
}

.signer-consent { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 16px; cursor: pointer; }
.signer-consent input { margin-top: 3px; width: 17px; height: 17px; flex: 0 0 auto; }

.signer-moyens { display: flex; gap: 8px; margin-bottom: 12px; }
.signer-onglet {
  flex: 1; padding: 9px 12px; border: 1px solid var(--border, #D8DEE9);
  background: #fff; border-radius: 8px; cursor: pointer; font: inherit; font-size: 13.5px;
}
.signer-onglet.on { border-color: var(--accent, #2456D6); background: var(--accent-soft, #E2EAFB); font-weight: 600; }

.signer-champ {
  width: 100%; padding: 11px 13px; font: inherit; font-size: 17px;
  border: 1px solid var(--border, #D8DEE9); border-radius: 8px;
}
.signer-champ:focus { outline: 2px solid var(--accent, #2456D6); outline-offset: -1px; }

[data-role="toile"] {
  width: 100%; height: 180px; background: #fff; touch-action: none;
  border: 1px dashed #B9C4D6; border-radius: 8px; cursor: crosshair;
}
.signer-effacer {
  margin-top: 6px; border: 0; background: none; padding: 2px 0;
  color: var(--ink-2, #5B6B85); font: inherit; font-size: 13px;
  text-decoration: underline; cursor: pointer;
}

.signer-etat { min-height: 18px; margin: 12px 0 0; font-size: 13.5px; color: #9B1C1C; }

.signer-valider {
  width: 100%; margin-top: 10px; padding: 13px;
  background: var(--accent, #2456D6); color: #fff; border: 0; border-radius: 9px;
  font: inherit; font-size: 15.5px; font-weight: 600; cursor: pointer;
}
.signer-valider:disabled { background: #C3CCDC; cursor: not-allowed; }

.signer-note {
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--border, #D8DEE9);
  font-size: 12.3px; line-height: 1.55; color: var(--ink-2, #5B6B85);
}

@media (max-width: 620px) {
  .signer-page { padding: 18px 14px 40px; }
  .signer-feuille iframe { height: 320px; }
  .signer-moyens { flex-direction: column; }
}

/* ⚠ 30.09.2026 · Stan (8fbbd245, 9f50b253, 0552cd75) · « ajuster la taille de
   police avec les autres titres ». Les entêtes de colonne — « LOYER NET »,
   « TYPE », « DÉBUT » — sortaient à 11 px en capitales mono, sous la légende
   (12 px) et loin du corps : trois retours sur trois écrans. On les remonte à
   13 px, sur toutes les listes à la fois, pour qu'aucun écran ne diffère d'un
   autre. La règle vit ici et non dans `design-system/`, qui se régénère depuis
   sa source. */
.tbl thead th, .rent-row.rent-row--head, .ln-col span {
  font-size: 13px; letter-spacing: .04em;
}

/* ─── Le module État des lieux · livrable 3 ──────────────────────────────────
   Mobile d'abord : un seul écran, qui s'élargit sur ordinateur. Préfixes
   `edlm-` (l'écran) et `edlp-` (la page imprimée) · aucun sélecteur du design
   system n'est redéfini ici. */
.edlm { display: flex; flex-direction: column; gap: 14px; max-width: 860px; }
.edlm--mobile { max-width: none; }
.edlm-barre { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.edlm-tete { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.edlm-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.edlm-retour { display: inline-flex; align-items: center; gap: 4px; color: var(--accent); text-decoration: none; font-size: 14px; }
.edlm-filtres { display: grid; grid-template-columns: 1fr; gap: 8px; }
.edlm-coche { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.edlm-liste { display: flex; flex-direction: column; gap: 10px; }
.edlm-carte { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-md, 10px);
  background: var(--surface); color: inherit; text-decoration: none; }
.edlm-carte:hover { border-color: var(--accent); }
.edlm-carte--archive { opacity: .65; }
.edlm-carte-tete { display: flex; justify-content: space-between; gap: 8px; align-items: center; }
.edlm-vide { padding: 24px 0; text-align: center; }
.edlm-dialogue { width: min(560px, calc(100vw - 24px)); }
.edlm-choix { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.edlm-choix .btn { justify-content: flex-start; padding: 14px 16px; font-size: 15px; }
.edlm-baux { display: flex; flex-direction: column; gap: 6px; max-height: 50vh; overflow-y: auto; margin-top: 8px; }
.edlm-bail { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface); cursor: pointer; font: inherit; color: inherit; }
.edlm-bail:hover { border-color: var(--accent); }
.edlm-champ { display: flex; flex-direction: column; gap: 4px; }
.edlm-champ .input { width: 100%; font-size: 16px; }
.edlm-lib { font-size: 13px; color: var(--ink-3); }
.edlm-sous { display: flex; justify-content: space-between; align-items: baseline; margin-top: 8px; }
.edlm-corps { display: flex; flex-direction: column; gap: 12px; }
.edlm-pieces { display: flex; flex-direction: column; gap: 12px; }
.edlm-piece { display: flex; flex-direction: column; gap: 8px; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.edlm-piece-tete { display: flex; gap: 6px; align-items: center; }
.edlm-piece-nom { flex: 1; min-width: 0; font-weight: 600; font-size: 16px; }
.edlm-piece-actions { display: flex; gap: 2px; }
.edlm-note { display: flex; align-items: center; gap: 12px; }
.edlm-note input[type="range"] { flex: 1; height: 32px; accent-color: var(--accent); }
.edlm-note--vide { opacity: .45; }
.edlm-note output { min-width: 110px; font-size: 14px; font-weight: 600; }
.edlm-bornes { display: flex; justify-content: space-between; margin-top: -6px; }
.edlm-photos { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.edlm-photo { position: relative; margin: 0; width: 96px; height: 96px; border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.edlm-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.edlm-photo-retirer { position: absolute; top: 2px; right: 2px; background: rgba(255,255,255,.9); border-radius: 50%; }
.edlm-photo-ajout { cursor: pointer; position: relative; overflow: hidden; }
/* Revue du 01.10.2026 · l'entrée de fichier était `hidden` : le libellé se
   cliquait, mais ne se rejoignait pas au clavier. Elle couvre désormais le
   bouton, transparente, et prend le focus ; l'anneau se voit sur le bouton. */
.edlm-photo-ajout input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.edlm-photo-ajout:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.edlm-remise { display: grid; grid-template-columns: minmax(0, 1fr) 120px auto; gap: 6px; align-items: center; margin-bottom: 6px; }
.edlm-remise > .input { min-width: 0; width: 100%; box-sizing: border-box; }
.edlm-montant { text-align: right; }
.edlm-mentions { padding: 12px 14px; border-radius: 8px; background: var(--surface-2); font-size: 14px; line-height: 1.5; }
.edlm-mentions--attente { border: 1px dashed var(--border-strong, var(--border)); color: var(--ink-3); font-style: italic; }
.edlm-deux { display: grid; grid-template-columns: 1fr; gap: 12px; }
.edlm-signes { padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.edlm-sig { display: flex; flex-direction: column; gap: 4px; }
.edlm-sig-trace { width: 100%; max-width: 260px; height: auto; }
.edlm-lecture { padding: 16px; border: 1px solid var(--border); border-radius: 10px; background: #fff; max-height: 60vh; overflow-y: auto; }
.edlm-signer-bloc { display: flex; flex-direction: column; gap: 8px; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.edlm-signer-bloc .input { font-size: 16px; }
.edlm-toile { border: 1px dashed var(--border-strong, var(--border)); border-radius: 8px; background: #fff; touch-action: none; }
.edlm-toile canvas { display: block; width: 100%; height: auto; aspect-ratio: 640 / 180; touch-action: none; }
.edlm-valider { align-self: stretch; padding: 14px; font-size: 16px; }
@media (min-width: 720px) {
  .edlm-filtres { grid-template-columns: 2fr 1fr 1fr auto; align-items: center; }
  .edlm-deux { grid-template-columns: 1fr 1fr; }
}

/* Le module seul, sur téléphone · un bandeau, puis le module. */
.edlm-app { min-height: 100vh; background: var(--bg, var(--surface-2)); }
.edlm-bandeau { position: sticky; top: 0; z-index: 5; display: flex; justify-content: space-between; align-items: center;
  padding: 10px 16px; background: var(--surface); border-bottom: 1px solid var(--border); }
/* En bas, la place du bouton flottant « Donner un retour » · sans elle, il
   recouvrait le bouton qui valide les signatures (vu sur le banc, 390 px). */
.edlm-contenu { padding: 16px 16px 96px; }

/* La page imprimée · A4, photos comprises. Hors impression elle ne se montre
   que dans l'écran de signature (`.edlp-ecran`). */
.edlp { display: none; }
.edlp-ecran h1, .edlp h1 { font-size: 20px; margin: 8px 0 12px; }
.edlp-ecran h3, .edlp h3 { font-size: 15px; margin: 12px 0 4px; }
.edlp-ecran h3 span, .edlp h3 span { font-weight: 400; color: #5B6472; }
.edlp-tete { display: flex; justify-content: space-between; font-size: 12px; color: #5B6472; border-bottom: 1px solid #C9CED6; padding-bottom: 6px; }
.edlp-piece { break-inside: avoid; border-top: 1px solid #E3E6EA; padding: 6px 0; }
.edlp-photos { display: flex; flex-wrap: wrap; gap: 6px; }
.edlp-photos img { width: 48mm; height: 36mm; object-fit: cover; border: 1px solid #E3E6EA; }
.edlp-table { width: 100%; border-collapse: collapse; margin: 6px 0; font-size: 14px; }
.edlp-table th, .edlp-table td { border-bottom: 1px solid #E3E6EA; padding: 5px 4px; text-align: left; vertical-align: top; }
.edlp-table th { width: 38%; font-weight: 600; }
.edlp-montant { text-align: right; white-space: nowrap; }
.edlp-signes, .edlp-manuscrites { break-inside: avoid; margin-top: 14px; }
.edlp-deux { display: grid; grid-template-columns: 1fr 1fr; gap: 12mm; }
.edlp-sig svg { width: 100%; max-width: 70mm; height: auto; display: block; }
.edlp-ligne { border-bottom: 1px solid #13233B; height: 18mm; display: flex; align-items: flex-end; font-size: 12px; color: #5B6472; }
.edlp-brouillon { color: #A33; font-style: italic; }
@media print {
  @page { size: A4; margin: 14mm; }
  body.edlp-impression { background: #fff !important; }
  body.edlp-impression > *:not(.edlp) { display: none !important; }
  body.edlp-impression .edlp { display: block; color: #13233B; font: 11pt/1.45 ui-sans-serif, system-ui, sans-serif; }
}

/* Profil · le code QR des états des lieux (SLK-171 / US-11 CA-4). Le SVG
   peint lui-même son fond blanc et sa zone de silence : le thème sombre ne
   l'inverse pas, il reste lisible par un téléphone. */
.profil-edl-qr { display: flex; align-items: center; gap: 16px; margin: 16px 0 0; }
.profil-edl-qr svg { flex: none; width: 120px; height: 120px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.profil-edl-qr figcaption { max-width: 22ch; }
