/**
 * 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; }

.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); }
.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; }
.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; }
.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; }
.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; }

/* ─── 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); }
.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; }
}

@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); }

/* ─── 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); outline: none; }

/* 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; }
