/* PAT Gestionnaire — Standalone stylesheet */

:root {
  --bg: #f4f2ef;
  --panel: #fdfcfa;
  --ink: #1e2228;
  --muted: #6b7280;
  --line: #d5d3cf;
  --accent: #2563a8;
  --accent-soft: #dbeafe;
  --accent-ink: #1e40af;
  /* BLEU DE LA MARQUE (site marketing pat.treklair.fr, `--color-ink`) : une
     ENCRE de fond réservée à la barre du haut, qui est le seul endroit où le
     soft porte l'identité du site, à l'en-tête du panneau IA (même bande,
     séparée par un liseré), et à ce qui NOMME : le titre de la page, le nom
     du client et l'entrée active du menu de gauche (« où je suis », pas « où
     je peux aller » : les autres liens restent --muted). Jamais sur un lien
     ni un bouton de page : la famille « c'est cliquable » reste --accent. */
  --brand: #0f1f3d;
  --on-brand: #f7f5f1;          /* crème du site, texte et icônes sur --brand */
  --on-brand-muted: #b9c0cf;    /* idem, atténué (engrenage, nom d'utilisateur) */
  /* ACTION DISCRÈTE (rôle, pas une teinte — arbitrage opérateur 2026-07-17) :
     les gestes secondaires qu'on ne vient PAS faire sur la page mais qui doivent
     rester actionnables — <summary> qui révèle un formulaire (« + Ajouter »,
     plis « ▸ Rattacher une source ? »), liens d'action de second plan.
     MÊME TEINTE que --accent (212° = la famille « c'est cliquable »), mais 30 %
     de saturation au lieu de 64 % : ce qui « crie » est la saturation, pas le
     contraste. Tient AA partout (5.13:1 sur --panel, 4.95 sur --bg-subtle,
     4.65 sur --pill-bg) — plus de marge que --muted (4.72).
     ⚠ NE JAMAIS mettre --muted sur un élément interactif : le gris dit
     « information » ou « pas disponible » (recette désactivé de l'app :
     --muted + cursor:not-allowed + opacity .45, cf. onglet « Contrats »). */
  --action-quiet: #4f6e92;
  --warn: #b45a2f;
  --error: #9d2f2f;
  --success: #0f7b5f;
  --success-soft: #d1fae5;
  --warn-soft: #fff3e0;       /* tint orangé visible pour cartes alternatives/new (texte AAA préservé) */
  --warn-ink: #8a3f15;        /* orange sombre lisible pour textes/pills sur fond clair */
  --success-ink: #0b5a45;     /* vert sombre lisible pour textes sur fond clair */
  --danger: #9d2f2f;          /* alias rouge pour textes/pills "danger" (= --error) */
  --pill-bg: #f1f1ef;         /* gris très clair neutre pour pills à texte coloré */
  --bg-subtle: #f7f8fa;       /* tint neutre pour bandeaux/headers de section */
  --shadow: 0 10px 26px rgba(30, 34, 40, 0.06);
  --nav-width: 220px;
  /* Hauteur unique de la BANDE d'en-tête (R11) : flèche retour, 1re ligne du
     H1 et TOUS les boutons d'action la partagent → tops alignés (flex-start)
     donc centres alignés, sans dépendre de la hauteur intrinsèque de chaque
     bouton. En changer ici recale la flèche, le titre et les actions d'un
     coup, sur toutes les pages. Voir docs/DESIGN-SYSTEM.md R11. */
  --header-ctl-h: 32px;
  /* Respiration GARANTIE et CONSTANTE sous la bande d'en-tête (R11) : aucune
     page ne colle son premier bloc (toolbar, panneau) au titre. Le seul
     contrevenant historique était `.kbi-rappro-header` (4px) — supprimé. */
  --header-gap: 24px;
  /* Largeurs des colonnes ferrées à droite (montant / action) partagées par
     tout contenu tabulaire — voir .row-grid et docs/UI-CONVENTIONS.md. SSOT :
     en changer ici réaligne tous les blocs (tables ET formulaires) d'un coup. */
  --col-amount: 132px;
  --col-action: 120px;
  /* Champ de barre de filtres — métrique UNIQUE partagée par la toolbar
     Situation (`.kbi-toolbar`) et le listing documents (`.doc-filters--framed`)
     pour que les deux barres aient la même hauteur de champ. SSOT. */
  --toolbar-field-pad: 6px 9px;
  --toolbar-field-radius: 8px;
  --toolbar-field-fs: 13px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Avenir Next", "Gill Sans", "Trebuchet MS", sans-serif;
  background: var(--bg);
  color: var(--ink);
  padding-top: 56px;
}

/* ── Top bar ─────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 40;
  padding: 0 28px;
  height: 56px;
  background: var(--brand);
  color: var(--on-brand);
  border-bottom: 1px solid var(--brand);
  box-shadow: 0 1px 3px rgba(15, 31, 61, 0.25);
}

.topbar-menu {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(247, 245, 241, 0.28);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.topbar-menu:hover {
  border-color: var(--on-brand);
  background: rgba(247, 245, 241, 0.1);
}

.topbar-menu-panel {
  display: block;
  width: 5px;
  height: 18px;
  border-radius: 999px;
  background: var(--on-brand);
  opacity: 0.82;
}

.topbar-menu-lines {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.topbar-menu-lines span {
  display: block;
  width: 13px;
  height: 2px;
  border-radius: 999px;
  background: var(--on-brand);
}

.topbar-brand {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--on-brand);
}

.topbar-nav {
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: fixed;
  top: 56px;
  bottom: 0;
  left: 0;
  z-index: 35;
  width: var(--nav-width);
  padding: 16px 14px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  box-shadow: 1px 0 4px rgba(0, 0, 0, 0.03);
  transform: translateX(-100%);
  transition: transform 0.18s ease;
}

body.nav-open .topbar-nav {
  transform: translateX(0);
}

.topbar-nav a,
.topbar-nav .context-nav-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  transition: all 0.15s ease;
}

.topbar-nav-ai svg {
  color: var(--accent);
  flex: none;
}

.topbar-nav a:hover {
  color: var(--ink);
  background: var(--accent-soft);
}

.topbar-nav a.active {
  color: var(--brand);
  background: var(--accent-soft);
  font-weight: 700;
}

.context-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.context-nav-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 2px 8px;
}

.context-nav-title > span {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.context-nav-title a {
  justify-content: flex-start;
  padding: 0;
  color: var(--brand);
  font-size: 16px;
  font-weight: 800;
}

.context-nav-title a:hover {
  background: transparent;
  color: var(--accent-ink);
}

.context-nav-link {
  min-height: 36px;
}

.context-nav-link-child {
  min-height: 30px;
  margin-left: 16px;
  padding: 7px 10px 7px 14px !important;
  border-left: 2px solid var(--line);
  border-radius: 0 8px 8px 0 !important;
  font-size: 13px !important;
}

.context-nav-link-child.active {
  border-left-color: var(--brand);
}

.context-nav-children {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: -2px 0 4px;
}

.context-nav-badge {
  min-width: 18px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--warn-soft);
  color: var(--warn-ink);
  font-size: 11px;
  font-weight: 800;
  text-align: center;
}

.context-nav-count {
  color: inherit;
  opacity: 0.72;
  font-weight: 600;
}

.topbar-nav .disabled {
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.45;
}

.topbar-meta {
  margin-left: auto;
}

.topbar-link-tech {
  font-size: 12px;
  color: var(--on-brand-muted);
  text-decoration: none;
  opacity: 0.6;
  transition: opacity 0.15s;
}

.topbar-link-tech:hover { opacity: 1; }

.topbar-user {
  font-size: 13px;
  color: var(--on-brand-muted);
}

.topbar-meta {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* ── Content area ────────────────────────────────── */

.content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 28px;
  transition: margin-left 0.18s ease;
}

/* Phase 98-03 (§15, règle de largeur) : « la largeur suit la nature de la
   surface ». Surfaces de TRAVAIL SUR DONNÉES → fluide sous plafond 1680
   (à 1680, une moitié = 840px ≥ une page A4 à 96dpi : le document se lit à
   taille réelle). Opt-in par vue ({% block content_class %}) — le défaut
   1200 reste pour les pages mixtes/lecture/formulaires. */
.content--wide {
  max-width: 1680px;
}

/* Le composant searchable est fluide (width:100%) — dans une barre de filtres
   il se borne, sinon il avale la rangée (filtre Types du listing documents). */
.doc-filters .ss-wrapper { flex: 0 1 340px; min-width: 220px; }

body.nav-open .content {
  margin-left: var(--nav-width);
  margin-right: auto;
}

/* Bande d'en-tête (R11) : flèche, titre et actions hangent du HAUT de la bande
   (flex-start), tous calés sur --header-ctl-h → centres alignés, robuste à un
   titre qui passe sur 2 lignes (les lignes en trop poussent vers le BAS, elles
   ne décalent pas le haut de la bande). */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: var(--header-gap);
}

.page-header h1 {
  margin: 0;
  font-size: 26px;
  line-height: var(--header-ctl-h);
  color: var(--brand);
}

.page-header .subtitle {
  color: var(--muted);
  font-size: 13px;
}

/* ── Cards & panels ──────────────────────────────── */

.card, .panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px;
  box-shadow: var(--shadow);
}

.card h3, .panel h3 {
  margin: 0 0 10px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* Liseré d'accent à gauche d'un panneau (étape clé du parcours). */
.panel-accent-success { border-left: 4px solid #166534; }
.panel-accent-warn { border-left: 4px solid #b45309; }
.panel-accent-error { border-left: 4px solid #9d2f2f; }
.doc-ingest-error-cause { margin: 0 0 10px; overflow-wrap: anywhere; }
.doc-ingest-error-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0; }
.doc-row-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 4px; }
.doc-ingest-banner .doc-row-actions { display: inline-flex; margin: 0 0 0 12px; }
/* Retour opérateur 2026-10-24 : dans la colonne STATUT d'une liste, l'état et
   ses gestes tiennent sur UNE ligne (« En cours · Pause · Annuler l'import ») ;
   ils ne passent dessous que si la colonne manque de place. */
td[data-doc-status] .status-pill-group,
td[data-doc-status] .doc-row-actions { display: inline-flex; vertical-align: middle; }
td[data-doc-status] .doc-row-actions { margin: 0 0 0 8px; }
td[data-doc-status] .status-pill-group:empty + .doc-row-actions { margin-left: 0; }
.doc-row-action { margin: 0; display: inline; }
.doc-action-btn { font: inherit; font-size: 12px; line-height: 1; padding: 4px 8px; border: 1px solid #c9d3cf; border-radius: 6px; background: #fff; color: #1e2925; cursor: pointer; }
.doc-action-btn:hover { background: #eef3f1; }
.doc-action-btn--danger { color: #9d2f2f; border-color: #e3b5b5; }
.doc-action-btn--danger:hover { background: #fbeeee; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.big {
  font-size: 28px;
  font-weight: 700;
}

.muted { color: var(--muted); }

/* ── Search bar ──────────────────────────────────── */

.search-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.search-bar input {
  flex: 1;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  background: var(--panel);
  color: var(--ink);
}

.search-bar input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.search-bar button {
  padding: 10px 18px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
}

.search-bar button:hover {
  background: var(--accent);
  color: #fff;
}

/* ── Client list ─────────────────────────────────── */

.client-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.client-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  text-decoration: none;
  color: var(--ink);
  transition: all 0.15s ease;
}

.client-row:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 8px rgba(37, 99, 168, 0.08);
  transform: translateY(-1px);
}

.client-name {
  font-weight: 600;
  font-size: 15px;
  flex: 1;
}

/* Phase 100 : membre du foyer non conseillé par le cabinet, au milieu d'un nom
   en gras (listing, menu client). Graisse normale, MÊME couleur — jamais
   --muted : le nom est un lien (cf. tête de fichier). */
.household-unadvised {
  font-weight: 400;
}

.client-meta {
  font-size: 13px;
  color: var(--muted);
}

/* ── Completeness badge ──────────────────────────── */

.completeness-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.completeness-badge.complete {
  background: var(--success-soft);
  color: var(--success);
}

.completeness-badge.partial {
  background: #fef3c7;
  color: #92400e;
}

.completeness-badge.unknown {
  background: #f3f4f6;
  color: var(--muted);
}

/* ── Tabs ────────────────────────────────────────── */

.tabs {
  display: flex;
  gap: 2px;
  border-bottom: 2px solid var(--line);
  margin-bottom: 20px;
}

.tab {
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: all 0.15s;
  white-space: nowrap;
}

.tab:hover { color: var(--ink); }

.tab.active {
  color: var(--accent-ink);
  border-bottom-color: var(--accent);
  font-weight: 700;
}

.tab.disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Client detail header ────────────────────────── */

.client-header {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 24px;
}

.client-header h1 {
  margin: 0;
  font-size: 26px;
  color: var(--brand);
}

body.nav-open .client-header {
  display: none;
}

.client-contact {
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}

/* ── Document table ──────────────────────────────── */

.doc-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

.doc-table th {
  text-align: left;
  padding: 10px 12px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  border-bottom: 2px solid var(--line);
}

.doc-table td {
  padding: 12px 12px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  vertical-align: middle;
}

.doc-table tr:last-child td { border-bottom: 0; }

.doc-table .doc-type-cell {
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.doc-table tr:hover td { background: #f9f8f6; }

.doc-table a {
  color: var(--accent);
  text-decoration: none;
}

.doc-table a:hover { text-decoration: underline; }

.doc-thumbnail {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  object-fit: cover;
  border: 1px solid var(--line);
}

/* ── Contenu tabulaire aligné « par construction » (.row-grid) ──────
   Primitive de layout UNIQUE pour des blocs visuellement parallèles (une
   table de lignes ET un formulaire d'ajout, par ex.) qui doivent aligner
   leurs colonnes ferrées à droite (montant / action) SANS nombre magique ni
   dépendance au padding de cellule. Chaque bloc déclare le même gabarit qui
   se termine par `… minmax(0,1fr) var(--col-amount) var(--col-action)` : les
   colonnes fixes étant ancrées à droite avec une largeur identique (tokens),
   elles tombent à la même abscisse quel que soit le contenu de gauche.
   Voir docs/UI-CONVENTIONS.md. */
.row-grid {
  display: grid;
  grid-template-columns: var(--row-grid-cols);
  /* Le gap doit être porté par le conteneur (et pas seulement les sous-grids) :
     sinon le gutter rogne les pistes du sous-grid (montant 132→116) alors que le
     formulaire d'ajout (grille simple) garde 132 → désalignement entre blocs. */
  column-gap: 16px;
}
/* Chaque ligne est un sous-grid : les cellules héritent des colonnes du bloc
   (en-tête, corps et pied restent alignés colonne par colonne). */
.row-grid > .row-grid-head,
.row-grid > .row-grid-row,
.row-grid > .row-grid-foot {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  align-items: center;
  column-gap: 16px;
}
.row-grid-head {
  padding-bottom: 10px;
  border-bottom: 2px solid var(--line);
}
.row-grid-row {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.row-grid-row:last-of-type { border-bottom: 0; }
.row-grid-foot {
  padding-top: 12px;
}
/* Cellule d'action ferrée à droite (icône corbeille, bouton « + Ajouter »…),
   en-tête comme corps. */
.rg-action {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
/* Pied : libellé étalé jusqu'à la colonne montant + total dans la colonne
   montant (lignes négatives → robuste au nombre de colonnes de gauche). */
.row-grid-foot .rg-foot-label {
  grid-column: 1 / -3;
  text-align: right;
}
.row-grid-foot .rg-foot-amount {
  grid-column: -3 / -2;
  text-align: right;
}

/* Variante « formulaire d'ajout » : une seule ligne (pas de sous-grid) dont les
   cellules empilent label + champ. align-items:end → les champs s'alignent par
   le bas même si un label passe sur 2 lignes. Même gabarit --row-grid-cols que
   les tables sœurs → colonnes montant/action alignées. */
.row-grid-form {
  display: grid;
  grid-template-columns: var(--row-grid-cols);
  align-items: end;
  column-gap: 16px;
}
.rg-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
/* Le searchable impose min-height 38 px (confort hors grille) : dans un
   formulaire d'ajout en ligne, il retombe à la hauteur des champs voisins
   (montant, liste courte) pour que les libellés restent sur une même ligne
   — même patron que la barre de filtres (.doc-filters--framed). Un libellé
   long passe encore sur plusieurs lignes (height:auto). */
.row-grid-form .ss-control {
  min-height: 32px;
  padding: 4px 10px;
}

/* Annotation discrète dans un en-tête/label (ex. « (interne) ») — dégraisse
   sans casser l'uppercase hérité du parent. */
.lbl-note {
  font-weight: 400;
  color: var(--muted);
}

/* En-tête de colonne — token typographique (= rendu des <th> de .doc-table).
   Utilisable hors table (label de formulaire, div de grille…). */
.col-head {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* Champ montant — input ferré à droite (chiffres à droite) + suffixe « € »
   persistant + séparateur de milliers (formatage JS au repos/blur). Rendu
   identique quel que soit le contexte (cellule de table OU form-group). Le JS
   cible les classes .montant-input / .volet-montant-input portées par l'input
   (hooks comportementaux), le style vient d'ici. */
.field-amount {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 100%;
}
.field-amount input {
  width: 100%;
  box-sizing: border-box;
  text-align: right;
  padding: 7px 20px 7px 8px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 14px;
}
.field-amount input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
/* `.field-input` (texte, date) partage la même boîte : un formulaire en ligne
   (ex. assemblage du dossier d'adéquation) s'aligne sur les boutons de 32 px.
   Liste native courte dans une grille (R5 : énumération courte, pas de
   recherche — ex. « Souscripteur(s) » du hub d'offre). Même boîte que
   `.field-amount input` → s'aligne avec le champ montant voisin. */
.field-select,
.field-input {
  width: 100%;
  box-sizing: border-box;
  height: 32px;           /* = .field-amount input (7 + 16 + 7 + 2) */
  padding: 0 8px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
}
.field-select:focus,
.field-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.field-amount-suffix {
  position: absolute;
  right: 8px;
  color: var(--muted);
  pointer-events: none;
  font-size: 13px;
}

/* ── Status pill ─────────────────────────────────── */

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.status-pill.done {
  background: var(--success-soft);
  color: var(--success);
}

.status-pill.processing {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

.status-pill.error {
  background: #fbcaca;
  color: var(--error);
  font-size: 13px;
  border: 1px solid #f3a6a6;
  padding: 4px 12px;
}

.status-pill.pending {
  background: #f3f4f6;
  color: var(--muted);
}

.status-pill.warning {
  background: #fff4d8;
  color: #8a5a00;
}

.status-pill-group {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ── Category group ──────────────────────────────── */

.category-group {
  margin-bottom: 28px;
}

.category-group h3 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
}

/* ── Empty state ─────────────────────────────────── */

.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: var(--muted);
}

.empty-state .icon {
  font-size: 48px;
  margin-bottom: 12px;
  opacity: 0.3;
}

.empty-state p {
  font-size: 15px;
  margin: 0;
}

/* ── Document filters ─────────────────────────────── */

.doc-filters {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 20px;
  margin-bottom: 20px;
}

.doc-search-input {
  flex: 1;
  min-width: 180px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  background: var(--panel);
  color: var(--ink);
}

.doc-search-input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.doc-filters select {
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 13px;
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
}

.doc-filters select:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.doc-filters button {
  padding: 9px 16px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
}

.doc-filters button:hover {
  background: var(--accent);
  color: #fff;
}

.filter-reset {
  font-size: 12px;
  color: var(--muted);
  text-decoration: none;
}

.filter-reset:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* ── Listing documents : air de famille de la Situation (Phase 98-04) ──
   Le listing `?tab=documents` adopte l'anatomie de la surface Situation
   (`?tab=infos`) — toolbar en carte + catégories repliables en bandeau —
   SANS en porter la grammaire sommable (un document n'a pas de total). Le
   modifieur `--framed` n'est posé que par le form du listing client : les
   5 autres listings `.doc-filters` gardent la barre plate. */
.doc-filters--framed {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fcfcfd;
  padding: 10px 12px;
  gap: 12px;
  align-items: end;
  position: sticky;
  top: 66px;
  z-index: 5;
}
.doc-filter-group { display: flex; flex-direction: column; gap: 4px; }
.doc-filter-group > label {
  font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.doc-filter-grow { flex: 1 1 200px; }
.doc-filter-grow .doc-search-input { width: 100%; }
/* Le searchable est fluide : borné par son groupe, largeur 100%. En contexte
   colonne (le groupe est un flex vertical), un flex-basis deviendrait une
   HAUTEUR — d'où `flex: none` + `width: 100%` (piège rencontré au mockup). */
.doc-filter-type { flex: 0 0 300px; }
.doc-filter-type .ss-wrapper { flex: none; width: 100%; min-width: 0; }
.doc-filter-spacer { flex: 1; }
.doc-filter-actions { flex-direction: row; align-items: center; gap: 12px; }
/* Champs à la MÊME hauteur que la toolbar Situation (métrique SSOT
   `--toolbar-field-*`) — le searchable `.ss-control` inclus (il portait sa
   propre métrique : radius 4, font 16 → aligné ici). */
.doc-filters--framed .doc-search-input,
.doc-filters--framed select,
.doc-filters--framed .ss-control {
  padding: var(--toolbar-field-pad);
  border-radius: var(--toolbar-field-radius);
  font-size: var(--toolbar-field-fs);
}
/* Le searchable force `min-height:38px` (confort tactile hors barre) : neutralisé
   ici pour qu'il retombe à la hauteur de champ commune de la barre. */
.doc-filters--framed .ss-control { min-height: 0; }
/* Le bouton × d'effacement du searchable est un <button> : la règle partagée
   `.doc-filters button` (Filtrer : bordure accent, fond, radius, padding) le
   transformait en pavé qui déformait le champ Type quand une valeur est choisie
   (bug opérateur). On restaure le × nu (même blindage que le sélecteur de vue). */
.doc-filters--framed .ss-clear {
  border: 0; background: transparent; border-radius: 0;
  padding: 0 4px; font-weight: 400; min-height: 0; transition: none;
}
.doc-filters--framed .ss-clear:hover { background: transparent; color: #333; }
/* Sélecteur de vue (repli/dépli des catégories) — même primitive que la
   Situation (`.kbi-ed-viewlevel`), calé à la hauteur de champ. Les boutons sont
   BLINDÉS contre la règle partagée `.doc-filters button` (destinée au seul
   « Filtrer » : radius 10, fond accent-soft, hover accent) qui, à égale
   spécificité, débordait sur eux. */
.doc-filters--framed .kbi-ed-viewlevel button {
  padding: var(--toolbar-field-pad); font-size: var(--toolbar-field-fs);
  border-radius: 0; font-weight: 400; background: #fff; transition: none;
}
.doc-filters--framed .kbi-ed-viewlevel button.is-active {
  background: var(--accent-ink); color: #fff; font-weight: 600;
}
.doc-filters--framed .kbi-ed-viewlevel button:hover:not(.is-active) {
  background: var(--bg-subtle); color: var(--ink);
}

/* Catégorie de documents repliable — MÊME anatomie que le bandeau FAMILLE de
   la Situation (chevron + bandeau bleu foncé `--accent-ink`), nature
   DIFFÉRENTE : le slot droit porte un COMPTE (« N documents »), jamais un
   total (un catalogue plat ne se somme pas). Doctrine : DESIGN-SYSTEM R9. */
details.doc-cat { margin-bottom: 14px; }
details.doc-cat > summary { list-style: none; cursor: pointer; }
details.doc-cat > summary::-webkit-details-marker { display: none; }
.doc-cat-bandeau {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  background: var(--accent-ink);
  color: #fff;
  border-radius: 6px;
  padding: 9px 14px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
/* ⚠ Chevron : glyphe LITTÉRAL suivi d'une espace littérale (comme toute la
   grammaire Situation) — surtout PAS l'échappement hexadécimal `\25B8 `, où
   l'espace finale est mangée comme terminateur de l'échappement (chevron collé
   au texte). Convention DESIGN-SYSTEM (Token 8). */
.doc-cat-bandeau .doc-cat-chev::before {
  content: "▸ "; color: rgba(255, 255, 255, 0.75); font-weight: 400;
}
details.doc-cat[open] > summary .doc-cat-chev::before { content: "▾ "; }
/* Compte de documents = TEXTE (muted, non tabulaire) — se distingue par
   nature d'un total € : jamais de €, jamais de séparateur de milliers. */
.doc-cat-count {
  text-transform: none; letter-spacing: 0; font-weight: 500;
  font-size: 12px; color: rgba(255, 255, 255, 0.85); white-space: nowrap;
}
.doc-cat-body { padding: 2px 2px 0; }
/* Lien discret dans un bandeau (ex. ↗ fiche fournisseur) — sur fond bleu foncé.
   Le clic navigue (quitte la page) : le toggle du <details> est sans effet. */
.doc-cat-link { color: rgba(255, 255, 255, 0.8); text-decoration: none;
  font-weight: 400; margin-left: 4px; }
.doc-cat-link:hover { color: #fff; }
/* Rythme de lignes cohérent avec la Situation (rangées un cran plus serrées). */
details.doc-cat .doc-table td { padding: 10px 12px; }

/* ── Chat icon ───────────────────────────────────── */

.chat-icon {
  font-size: 18px;
  opacity: 0.3;
  cursor: default;
  transition: opacity 0.15s;
}

.chat-icon:hover {
  opacity: 0.6;
}

.chat-icon-client {
  font-size: 22px;
  opacity: 0.7;
  cursor: pointer;
  transition: opacity 0.15s;
  margin-left: auto;
}

.chat-icon-client:hover {
  opacity: 1;
}

.chat-icon-link {
  transition: opacity 0.15s;
}

.chat-icon-link:hover {
  opacity: 1 !important;
}

/* ── Chat panel ─────────────────────────────────── */

.chat-panel {
  position: fixed;
  right: 0; top: 0; bottom: 0;
  width: 420px;
  background: #fff;
  border-left: 1px solid #ddd;
  display: flex;
  flex-direction: column;
  z-index: 100;
  box-shadow: -2px 0 8px rgba(0,0,0,0.08);
}

.chat-panel-header {
  padding: 12px 16px;
  border-bottom: 1px solid #eee;
  display: flex;
  align-items: center;
  gap: 8px;
}

.chat-panel-header h3 {
  flex: 1;
  margin: 0;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-header-btn {
  background: none;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
  padding: 2px 8px;
  color: #666;
}

.chat-header-btn:hover {
  background: #f0f0f0;
  color: #333;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}

.chat-msg {
  margin-bottom: 12px;
}

.chat-msg-user .chat-msg-content {
  background: #e8f0fe;
  padding: 8px 12px;
  border-radius: 8px;
  white-space: pre-wrap;
}

.chat-msg-assistant .chat-msg-content {
  background: #f5f5f5;
  padding: 8px 12px;
  border-radius: 8px;
  white-space: pre-wrap;
  line-height: 1.5;
}

.chat-msg-content.chat-error {
  color: #c62828;
  background: #fce4ec;
}

.chat-sources {
  margin-top: 8px;
  padding: 8px 12px;
  background: #fafafa;
  border: 1px solid #eee;
  border-radius: 4px;
  font-size: 12px;
  color: #666;
}

.chat-sources summary {
  cursor: pointer;
  font-weight: 700;
}

.chat-sources-content {
  margin-top: 4px;
}

.chat-source-item {
  margin-top: 4px;
  line-height: 1.4;
}

.chat-input-form {
  display: flex;
  padding: 12px;
  border-top: 1px solid #eee;
  gap: 8px;
}

.chat-input-form input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 14px;
}

.chat-input-form input:focus {
  outline: none;
  border-color: #1a73e8;
}

.chat-input-form button {
  padding: 8px 16px;
  background: #1a73e8;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.chat-input-form button:hover {
  background: #1565c0;
}

.chat-input-form button:disabled {
  background: #ccc;
  cursor: not-allowed;
}

/* ── Forms ────────────────────────────────────────── */

.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 6px;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  background: var(--bg);
  color: var(--ink);
  box-sizing: border-box;
}

.form-group textarea {
  font-family: inherit;
  resize: vertical;
  min-height: 60px;
}

.form-group input[type="checkbox"] {
  width: auto;
  padding: 0;
  margin: 0;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.form-row {
  display: flex;
  gap: 12px;
}

/* Modificateur : aligner les colonnes par le bas quand les étiquettes sont de
   hauteurs inégales (une qui passe sur 2 lignes ne doit pas décaler son champ
   vers le bas). À réserver aux rangées de champs homogènes (inputs/selects) —
   pas aux rangées mêlant textarea et input (le champ court se collerait au bas
   du textarea). */
.form-row-baseline {
  align-items: flex-end;
}

.form-group-checkbox {
  margin-top: 6px;
}

.checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 0;
  color: var(--ink);
  cursor: pointer;
}

.form-error {
  display: block;
  font-size: 12px;
  color: var(--error);
  margin-top: 4px;
}

.form-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 24px;
}

.form-actions button {
  padding: 10px 24px;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
}

.form-actions button:hover { filter: brightness(1.1); }

.form-cancel {
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
}

.form-cancel:hover { text-decoration: underline; }

/* ── Trash button ────────────────────────────────── */

/* Cellule <td> hôte : garde display:table-cell (donc sa border-bottom),
   le flex est porté par le <div.doc-actions> interne. */
.doc-table td.doc-actions-cell {
  text-align: right;
}

.doc-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.trash-form { display: inline; }

.trash-btn {
  background: none;
  border: none;
  padding: 4px;
  font-size: 16px;
  opacity: 0.3;
  cursor: pointer;
  transition: opacity 0.15s;
}

.trash-btn:hover { opacity: 0.8; }

/* ── Navigation retour + fil d'ariane (Phase 84, SSOT) ── */

.page-nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 12px;
  margin-bottom: 16px;
  font-size: 13px;
}

/* Bouton retour : icône seule (← ), cadre discret, pas de libellé. Calé sur la
   hauteur de bande (R11) pour co-centrer avec le titre et les boutons. */
.page-nav-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--header-ctl-h);
  height: var(--header-ctl-h);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--muted);
  text-decoration: none;
  font-size: 16px;
  line-height: 1;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.page-nav-back:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--panel);
}

/* Pipe de séparation entre le bouton retour et le fil. */
.page-nav-sep {
  width: 1px;
  height: 18px;
  background: var(--line);
}

.page-nav-trail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.page-nav-crumb {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
}

.page-nav-crumb + .page-nav-crumb::before {
  content: "›";
  margin-right: 10px;
  color: var(--muted);
  opacity: 0.45;
}

.page-nav-crumb a {
  color: var(--muted);
  text-decoration: none;
}

.page-nav-crumb a:hover { color: var(--accent); }

.page-nav-crumb > span { color: var(--ink); }

/* Crumb « entité » (nom client/produit/fournisseur) = repère principal. */
.page-nav-crumb.is-entity a,
.page-nav-crumb.is-entity > span {
  color: var(--accent-ink);
  font-weight: 600;
}

body.nav-open .page-nav-sep,
body.nav-open .page-nav-trail {
  display: none;
}

body.nav-open .page-nav:not(:has(.page-nav-back)) {
  display: none;
}

body.nav-open .page-nav:has(.page-nav-back) {
  float: left;
  margin: 0 14px 0 0;
}

/* Burger ouvert : le fil d'ariane est masqué (la sidebar porte le contexte) et
   la flèche seule flotte à gauche, à côté du H1 (look compact « ← Titre »). Le
   reste de l'alignement est porté par la BANDE d'en-tête générique (R11) :
   `.page-header` est déjà en flex-start avec tout calé sur --header-ctl-h, donc
   la flèche flottante (elle aussi --header-ctl-h, top:0) co-centre avec le
   titre et les boutons SANS override spécifique au burger. `.page-header` DOIT
   rester un sibling DIRECT de `.page-nav` pour que le clearfix s'applique (cf.
   `_kbi_editor_surface.html`, dont le .page-header est délibérément hors
   wrapper). Le clearfix garantit que le contenu SOUS l'en-tête (bandeaux,
   toolbar…) revient à l'aplomb de la flèche, pas ferré sur le H1. */
body.nav-open .page-nav:has(.page-nav-back) + .page-header::after {
  content: "";
  display: block;
  clear: both;
}

/* Alias rétro-compat : les pages d'édition KBI utilisaient cette classe. */
.kbi-edit-breadcrumb { font-size: 13px; }
.kbi-edit-breadcrumb a { color: var(--muted); text-decoration: none; }
.kbi-edit-breadcrumb a:hover { color: var(--accent); }

/* Zone danger en bas de la page d'édition document (Phase 84-01). */
.danger-zone {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.danger-zone .danger-hint {
  color: var(--muted);
  font-size: 12px;
  margin: 0 0 8px;
}

.btn-trash-inline {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: #8b3a3a;
  cursor: pointer;
  text-decoration: underline;
}

.btn-trash-inline:hover { color: #6f2c2c; }

/* ── Action button (header) ──────────────────────── */

.btn-new {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  /* line-height:1 comme .btn-edit/.btn-danger : sans lui, `normal` (~1.4) rend
     le bouton ~5px plus haut que ses voisins — la boîte doit être identique
     pour TOUS les boutons d'action (règle R11 / cohérence globale). */
  line-height: 1;
  text-decoration: none;
  transition: all 0.15s;
}

.btn-new:hover { filter: brightness(1.1); }

/* Variantes de bouton — modificateurs posés SUR .btn-new (réutilisent sa boîte :
   padding, rayon, graisse). N'override que la couleur. Évite les
   style="background:#…" inline. Voir docs/UI-CONVENTIONS.md.
   - (défaut)        primaire bleu   = .btn-new seul
   - .btn-secondary  neutre ardoise  (action secondaire : enregistrer un brouillon…)
   - .btn-warn       orange          (action réversible sensible : repasser en brouillon…) */
.btn-new.btn-secondary {
  background: #374151;
  border-color: #374151;
}
.btn-new.btn-warn {
  background: var(--warn);
  border-color: var(--warn);
}
/* État désactivé (slot « à venir »). .btn-new[disabled] garde la couleur mais
   atténue ; .btn-teaser (+ disabled) grise complètement (fonctionnalité lointaine). */
.btn-new:disabled,
.btn-new[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}
.btn-new.btn-teaser {
  background: #9ca3af;
  border-color: #9ca3af;
}
.btn-new.btn-teaser[disabled] {
  opacity: 0.45;
}

/* Bouton « lien » d'action destructrice (corbeille) — sans fond ni bordure.
   Auto-suffisant (ne dépend pas d'un .btn-link de base) pour remplacer les
   resets inline (background:none; border:none; …). .btn-icon = icône seule. */
.btn-danger-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: #8b3a3a;
  cursor: pointer;
  text-decoration: none;
}
.btn-danger-link:hover {
  color: #6f2c2c;
  text-decoration: underline;
}
.btn-icon {
  font-size: 16px;
  line-height: 1;
}

.btn-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  transition: all 0.15s;
}

.btn-edit:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ── Thumbnail placeholder ───────────────────────── */

.thumbnail-placeholder {
  width: 200px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border: 2px dashed var(--line);
  border-radius: 8px;
  color: #999;
  font-size: 13px;
}

.btn-action.disabled {
  opacity: 0.4;
  pointer-events: none;
  cursor: default;
}

/* ── Missing required field (red row) ────────────── */

.doc-info-missing {
  background: #fef2f2;
  border-left: 3px solid #dc2626;
  padding-left: 13px;
  margin-left: -16px;
  padding-right: 0;
}

.doc-info-missing .doc-info-label {
  color: #dc2626;
}

.doc-info-expired {
  background: #fef2f2;
  border-left: 3px solid #dc2626;
  padding-left: 13px;
  margin-left: -16px;
  padding-right: 0;
}

.doc-info-expired .doc-info-label {
  color: #dc2626;
}

/* ── Source stamp (OCR/manual) ────────────────────── */

.source-stamp {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 4px;
  background: #f0f0ed;
  color: #999;
  font-weight: 600;
  vertical-align: middle;
  margin-left: 4px;
}

/* ── Document detail ──────────────────────────────── */

.doc-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.doc-detail-grid > .panel:first-child {
  grid-column: 1 / -1;
}

/* Variante mono-colonne : tous les panneaux empilés (ex. fiche produit). */
.doc-detail-grid--stacked {
  grid-template-columns: 1fr;
}

/* Phase 53-08 follow-up : colonnes explicites — gauche = main_info+parties, droite = KBI+aperçu. */
.doc-detail-col-left,
.doc-detail-col-right {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.doc-info-list {
  display: flex;
  flex-direction: column;
}

.doc-info-row {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}

.doc-info-row:last-child { border-bottom: 0; }

.doc-info-label {
  color: var(--muted);
  font-size: 13px;
}

.doc-parties {
  margin: 0;
  padding-left: 18px;
  font-size: 14px;
}

.doc-parties li {
  padding: 4px 0;
}

.btn-action {
  padding: 8px 16px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: all 0.15s;
}

.btn-action:hover {
  background: var(--accent);
  color: #fff;
}

@media (max-width: 768px) {
  .doc-detail-grid { grid-template-columns: 1fr; }
}

/* ── Alertes (Phase 107) ─────────────────────────── */

/* Pages « Intégrer » / « Tout intégrer » (retour opérateur 2026-10-24) : le
   squelette du mode validation (P12, `.dv-sbs` + panneau document partagé) ;
   à droite, des blocs `.ai-block` sous des en-têtes `.dv-reads-head`. */
.ai-reads form { margin: 0; }
.ai-block { padding: 14px 16px; border-bottom: 1px solid var(--border, #e2e8f0); }
.ai-reads .dv-card.ai-block { cursor: default; }
.ai-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin-top: 10px; }
.ai-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ai-field label { margin-bottom: 0; }
.ai-field select { padding: 6px 8px; border: 1px solid var(--border, #cbd5e1); border-radius: 6px; font: inherit; font-size: 13px; }
.ai-hint { font-size: 11.5px; color: var(--muted, #64748b); }
.ai-current-value { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; margin-bottom: 2px; }
.ai-current .muted { font-size: 13px; }
.ai-warn { margin-top: 8px; font-size: 13px; color: var(--warn-ink); }
.ai-history { margin-top: 10px; }
.ai-history > summary { font-size: 12px; font-weight: 600; color: var(--muted, #64748b); }
.ai-history-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.ai-history-val { font-weight: 600; font-variant-numeric: tabular-nums; margin-right: 6px; }
.ai-acts { display: flex; gap: 10px; align-items: center; padding: 14px 16px; }
.ai-acts .ai-dismiss { margin-left: auto; }
.ai-bundle-vals { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 13px; margin: 6px 0 2px; font-variant-numeric: tabular-nums; }
.ai-k { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted, #64748b); margin-right: 4px; }
.ai-new { color: var(--warn-ink); font-weight: 600; }
.ai-reason { font-size: 13px; color: var(--warn-ink); margin: 4px 0 2px; }
.ai-row-fix { display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 600; }
.ai-bundle-row--aside { background: #fcfbf8; }
@media (max-width: 1100px) { .ai-fields { grid-template-columns: 1fr; } }
/* Carte d'alerte : le bord gauche porte la sévérité (--warn = à décider,
   gris = information). Compacte sur /app/ (lecture), gestes sur la fiche. */
/* La carte d'alerte (P17, Phase 107) a été retirée le 2026-10-27 : toutes les
   surfaces d'alertes sont des lignes `.row-grid` (.action-row). */
.alert-group { margin: 14px 0 18px; }
.alert-group-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin: 0 0 6px; }
.alert-group-title { font-weight: 600; }
.alert-group-acts { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.alert-counts { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 10px; font-size: 13px; }
.alert-count-chip { background: #f3f4f6; border-radius: 999px; padding: 2px 10px; }
.alert-filter-band { border-left: 4px solid var(--warn); background: var(--warn-soft); margin-bottom: 12px; }
.alert-empty { text-align: center; padding: 40px 24px; }
.alert-ignored-fold { margin-top: 18px; }
.alert-ignored-row { display: flex; justify-content: space-between; gap: 12px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.alert-ignored-row:last-child { border-bottom: 0; }
/* /app/ : une ligne par dossier (récapitulatif + lien), grille partagée. */
.alert-recap-cols { --row-grid-cols: minmax(180px, 0.6fr) minmax(0, 1.4fr) var(--col-action); }
/* Le trait de sévérité est un ombrage intérieur (3 px) : la ligne et son
   en-tête gardent une gouttière à gauche pour qu'il ne morde pas le texte
   (retour opérateur 2026-10-26). */
.alert-recap-cols .row-grid-head, .alert-recap-row, .vigilance-cols .row-grid-head { padding-left: 12px; }
.alert-recap-row { align-items: center; }
.alert-recap-row--urgent { box-shadow: inset 3px 0 0 #b91c1c; }
.alert-recap-urgent { color: #b91c1c; font-weight: 600; }
/* Phase 122 — tableaux de bord en LIGNES (refonte 2026-10-27) : une seule
   primitive (.row-grid), une seule marque de sévérité (.sev-dot), les gestes
   secondaires dans un pli « … » (.row-more). */
.action-cols { --row-grid-cols: minmax(0, 1fr) minmax(110px, auto) auto; }
.queue-cols { --row-grid-cols: minmax(160px, 0.55fr) minmax(0, 1.45fr) minmax(90px, auto) var(--col-action); }
.vigilance-cols { --row-grid-cols: minmax(0, 1.4fr) minmax(160px, 0.8fr) auto; }
.action-row { align-items: center; }
.action-row--info .action-title { font-weight: 500; color: var(--muted); }
.action-title { font-weight: 600; }
.action-detail { font-size: 12.5px; margin-top: 1px; }
.action-date { font-size: 12.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.action-cta { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.sev-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #b91c1c; margin-right: 8px; vertical-align: 1px; }
.row-more { position: relative; }
.row-more > summary { list-style: none; cursor: pointer; padding: 0 8px; font-weight: 700; letter-spacing: .1em; }
.row-more > summary::-webkit-details-marker { display: none; }
.row-more-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 300px; background: var(--panel, #fff); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,.08); padding: 6px; display: flex; flex-direction: column; }
.row-more-menu form { margin: 0; }
.row-more-item { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 7px 10px; font: inherit; font-size: 13px; color: var(--ink); border-radius: 6px; cursor: pointer; text-decoration: none; }
.row-more-item:hover { background: #f3f4f6; }
.row-more--single .row-more-menu { position: static; min-width: 0; background: none; border: 0; box-shadow: none; padding: 0; flex-direction: row; }
.row-more--single .row-more-item { padding: 4px 8px; color: var(--muted); }
.row-more--single .row-more-item:hover { background: none; color: var(--ink); text-decoration: underline; }
.row-more-remind { display: flex; gap: 6px; align-items: center; padding: 4px 10px; font-size: 12.5px; }
.row-more-remind label { display: flex; gap: 6px; align-items: center; color: var(--muted); white-space: nowrap; }
.row-more-remind input[type=date] { font: inherit; padding: 1px 4px; border: 1px solid var(--line); border-radius: 4px; }
.row-more-remind .row-more-item { width: auto; padding: 4px 8px; }
.dash-block { margin: 0 0 18px; }
/* Concordance (refonte 2026-10-27) : une ligne par candidat, proposé / en place côte à côte. */
.concordance-cols { --row-grid-cols: minmax(0, 1.3fr) minmax(150px, 0.7fr) minmax(150px, 0.7fr) auto; }
.concordance-group .page-section-title h2 { font-size: 15px; }
.amount-cell { font-variant-numeric: tabular-nums; }
.dash-block .page-section-title { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.dash-followup { margin-top: 4px; }
.vigilance-acts { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 900px) {
  .queue-cols { --row-grid-cols: minmax(0, 1fr) var(--col-action); }
  .queue-cols .row-grid-head > :nth-child(2), .queue-cols .row-grid-head > :nth-child(3), .queue-cols .action-row > :nth-child(2), .queue-cols .action-row > :nth-child(3) { grid-column: 1 / -1; }
}
/* Fiche produit › Cycle de vie : formulaire d'ajout en ligne canonique
   (.row-grid-form). Événement et source prennent la place, date et certitude
   ont une largeur fixe, l'action ferrée à droite (--col-action). */
/* « Lieu et date » de l'acte (aperçu des documents générés : conformité, lettre). */
.acte-edit-cols { --row-grid-cols: minmax(0, 240px) 200px var(--col-action); }
.acte-edit > summary { cursor: pointer; color: var(--accent); font-size: 13px; }
.acte-sign-table { width: 100%; border-collapse: collapse; table-layout: fixed; margin-top: 10px; }
.acte-sign-table th, .acte-sign-table td { border: 1px solid var(--line); padding: 6px 12px; text-align: left; vertical-align: top; font-size: 13px; }
.acte-sign-table td { height: 70px; }
.lifecycle-add-cols { --row-grid-cols: minmax(0, 1fr) 160px 140px minmax(0, 1fr) var(--col-action); margin-top: 12px; row-gap: 12px; }
@media (max-width: 900px) {
  .lifecycle-add-cols { --row-grid-cols: minmax(0, 1fr) minmax(0, 1fr); }
  .lifecycle-add-cols .rg-action { grid-column: 1 / -1; }
}
.filter-banner { display: flex; gap: 12px; align-items: center; justify-content: space-between; padding: 10px 14px; margin: 0 0 12px; }
.page-section-title h2 { font-size: 16px; margin: 8px 0 10px; }
.upload-profile-choice { display: flex; flex-direction: column; gap: 4px; margin: 12px 0 6px; font-size: 13px; }
.upload-profile-choice span { font-weight: 600; }
@media (max-width: 900px) {
  .alert-recap-cols { --row-grid-cols: minmax(0, 1fr) var(--col-action); }
  .alert-recap-cols .row-grid-head > :nth-child(2), .alert-recap-row > :nth-child(2) { grid-column: 1 / -1; order: 3; }
}

/* ── Responsive ──────────────────────────────────── */

/* ── Badge catalogue produit ──────────────────────────────────────────── */
.catalogue-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  vertical-align: middle;
  margin-left: 6px;
}
.catalogue-badge.validated {
  background: #d1fae5;
  color: var(--success);
}
.catalogue-badge.pending {
  background: #fef3c7;
  color: var(--warn);
}

/* ── Login page ──────────────────────────────────── */

.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.login-box {
  width: 100%;
  max-width: 380px;
  padding: 36px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
}

.login-box h1 {
  margin: 0 0 6px;
  font-size: 24px;
  text-align: center;
}

.login-box .subtitle {
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  margin-bottom: 28px;
}

.login-box label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 6px;
}

.login-box input[type="text"],
.login-box input[type="password"] {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  background: var(--bg);
  color: var(--ink);
  margin-bottom: 16px;
}

.login-box input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.login-box button {
  width: 100%;
  padding: 12px;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.15s;
}

.login-box button:hover {
  filter: brightness(1.1);
}

.login-error {
  background: #fde2e2;
  color: var(--error);
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  margin-bottom: 16px;
  text-align: center;
}

/* ── Utility classes ─────────────────────────────── */

/* Phase 98-03 : SLOT UNIQUE d'actions de page-header (fusion de l'ex
   .doc-header-actions — mêmes propriétés robustes pour tous). */
.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Colle les actions au bord droit dans les 2 états du burger (float × flex :
     space-between laissait un écart avec le bouton retour floaté). */
  margin-left: auto;
}

.page-header:has(.header-actions) {
  gap: 0;
}

/* R11 : tout contrôle d'action de l'en-tête est calé sur --header-ctl-h. Ils
   ont déjà tous la même boîte (inline-flex, padding, radius) ; on FIGE la
   hauteur (border-box) pour immuniser l'alignement contre les écarts de
   line-height / d'icône. Un nouveau bouton d'en-tête = l'ajouter ici, ou
   réutiliser une des classes canoniques.
   Rétabli le 2026-10-26 : ces deux règles avaient disparu au nettoyage de la
   Phase 107 (d0b10e55, seuls les commentaires restaient) — les boutons
   d'en-tête se cassaient sur deux lignes et mordaient sur le titre. */
.header-actions .btn-new,
.header-actions .btn-edit,
.header-actions .btn-secondary,
.header-actions .btn-danger,
.header-actions .dv-btn-read {
  height: var(--header-ctl-h);
}
/* Un bouton d'en-tête ne rétrécit jamais et ne se casse jamais sur deux
   lignes (icône au-dessus du texte) : quand la place manque, c'est le texte
   d'information qui passe à la ligne — sous-titre à gauche ; une mention
   d'état (« ⚠ Incomplet : … », `.header-actions-note`) se range SOUS les
   boutons, alignée à droite. Les <form> inline qui
   portent un bouton suivent la même règle. */
.header-actions .btn-new,
.header-actions .btn-edit,
.header-actions .btn-secondary,
.header-actions .btn-danger,
.header-actions .dv-btn-read,
.header-actions > form,
.header-actions > a {
  flex-shrink: 0;
  white-space: nowrap;
}
/* La colonne du titre prend le reste et passe à la ligne (min-width:0). */
.page-header > div:first-child { min-width: 0; }
.header-actions:has(.header-actions-note) {
  position: relative;
}
/* Hors flux : la mention ne compte pas dans la largeur des actions (sinon
   elle pousse un bouton à la ligne sur 13" / 1024 px). */
.header-actions .header-actions-note {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 4px;
  white-space: nowrap;
  font-size: 12px;
  line-height: 1.3;
}

.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;  /* boîte identique aux autres boutons d'action (R11). */
  text-decoration: none;
  transition: all 0.15s;
}

.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.supplier-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dashed var(--muted);
}

.supplier-link:hover {
  border-bottom-color: var(--accent);
  color: var(--accent);
}

.inline-form { display: inline; }

.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid rgba(157, 47, 47, 0.28);
  border-radius: 10px;
  background: rgba(157, 47, 47, 0.08);
  color: var(--error);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: all 0.15s;
}

.btn-danger:hover {
  border-color: var(--error);
  background: rgba(157, 47, 47, 0.14);
}

.btn-danger-confirm {
  font-size: 14px;
  padding: 8px 20px;
  border: 1px solid var(--error);
  border-radius: 8px;
  background: var(--error);
  color: #fff;
  cursor: pointer;
  transition: all 0.15s;
}

.btn-danger-confirm:hover {
  filter: brightness(1.15);
}

.alert-warning {
  margin: 16px 0;
  padding: 12px 16px;
  background: #fef3c7;
  border: 1px solid #f59e0b;
  border-radius: 8px;
  color: #92400e;
  font-size: 13px;
  line-height: 1.5;
}

.alert {
  margin: 0 0 16px;
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.5;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.alert strong {
  font-weight: 700;
}

.alert a {
  margin-left: auto;
  font-weight: 600;
}

.alert-error {
  background: #fde2e2;
  border: 1px solid #ef9a9a;
  color: #9d2f2f;
}

.alert-error a {
  color: #9d2f2f;
  text-decoration: underline;
}

.alert-error a:hover {
  color: #6b1f1f;
}

/* Bande « traitement en cours » de la page document (voir doc_ingest_poll.js).
   Bleu = information neutre, pas un problème : le pipe travaille, c'est normal.
   L'orange et le rouge restent réservés à ce qui demande une action. */
.alert-info {
  background: var(--accent-soft, #e6efff);
  border: 1px solid var(--accent, #2563eb);
  color: var(--accent-ink, #1e3a8a);
}

.doc-ingest-spinner {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  animation: doc-ingest-spin 0.8s linear infinite;
  flex: 0 0 auto;
}
/* Retour opérateur 2026-10-24 : la même roue, en petit, dans la pastille
   « En cours » des listes de documents (traitement qui tourne vraiment). */
.status-pill .status-pill-spinner { display: inline-block; width: 9px; height: 9px; border-width: 1.5px; margin-right: 5px; vertical-align: -1px; }

@keyframes doc-ingest-spin { to { transform: rotate(360deg); } }

/* Une animation permanente est une gêne réelle pour qui y est sensible. */
@media (prefers-reduced-motion: reduce) {
  .doc-ingest-spinner { animation: none; }
  .speak-typing span { animation: none; opacity: .6; }
}

.form-panel-narrow { max-width: 560px; }

.flex-1 { flex: 1; }
.flex-2 { flex: 2; }

/* Bandeau « libellé à gauche / statut à droite ». */
.flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
/* Rangée de boutons d'action alignés horizontalement. */
.flex-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.missing-panel {
  margin-bottom: 20px;
  border-left: 3px solid var(--warn);
}

.missing-list {
  margin: 0;
  padding-left: 18px;
  font-size: 14px;
}

/* (Phase 98-03 : .doc-header-actions fusionné dans .header-actions — slot
   unique, cf. plus haut.) */

.doc-preview-panel {
  margin-top: 16px;
  display: inline-block;
}

.doc-preview-img {
  max-width: 300px;
  border-radius: 8px;
  border: 1px solid var(--line);
}

.doc-preview-actions {
  margin-top: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.doc-preview-actions .btn-action {
  min-width: 150px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.ocr-preview-content {
  max-height: 70vh;
  overflow: auto;
  font-size: 14px;
  line-height: 1.5;
}

.ocr-preview-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 10px 0 16px;
  font-size: 13px;
  display: block;
  overflow-x: auto;
}

.ocr-preview-content th,
.ocr-preview-content td {
  border: 1px solid var(--line);
  padding: 6px 8px;
  text-align: left;
  vertical-align: top;
}

.ocr-preview-content th {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: 700;
}

.ocr-preview-content h1,
.ocr-preview-content h2,
.ocr-preview-content h3,
.ocr-preview-content h4 {
  margin-top: 0;
}

.ocr-preview-modal {
  position: fixed;
  inset: 0;
  z-index: 1200;
  background: rgba(30, 34, 40, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.ocr-preview-modal-content {
  width: min(900px, 100%);
  max-height: 85vh;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ocr-preview-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  position: sticky;
  top: 0;
  background: var(--panel);
  z-index: 1;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}

.ocr-preview-modal-header h3 {
  margin: 0;
  color: var(--accent);
}

.ocr-preview-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.ocr-page-count,
.ocr-page-jump-label {
  font-size: 12px;
  color: var(--muted);
}

.ocr-page-jump {
  height: 32px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 8px;
  background: var(--panel);
  color: var(--ink);
}

.ocr-preview-content .ocr-page-heading {
  color: var(--accent);
}

.ocr-preview-close {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--muted);
  border-radius: 10px;
  width: 34px;
  height: 34px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.ocr-preview-close:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ── Key Infos Panel ──────────────────────────────── */

.key-infos-section {
  margin-top: 24px;
}

.key-infos-panel {
  margin-bottom: 16px;
}

.key-infos-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.key-infos-header h3 {
  margin: 0;
}

.btn-sm {
  padding: 4px 12px;
  font-size: 12px;
}

.key-info-subcategory {
  font-size: 11px;
  font-weight: 700;
  color: var(--accent-ink);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin: 20px 0 4px;
  padding: 4px 10px;
  background: var(--accent-soft);
  border-radius: 4px;
}

.key-info-value-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.key-info-value {
  font-weight: 600;
}

.key-info-empty {
  color: var(--muted);
}

.key-info-instance-label {
  font-weight: 600;
  color: var(--ink);
}

.key-info-date-valeur {
  font-size: 11px;
  color: var(--muted);
}

.key-info-source-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  vertical-align: middle;
  /* Quand rendu comme <button> (cliquable pour modifier) */
  border: none;
  font-family: inherit;
  cursor: pointer;
}

.key-info-source-badge:hover {
  filter: brightness(0.95);
}

/* manuel : statut factuel neutre → gris muted */
.key-info-source-badge.manual {
  background: var(--pill-bg);
  color: var(--muted);
}

/* IA validée : statut validé → vert (réservé à ce statut) */
.key-info-source-badge.extracted {
  background: var(--success-soft);
  color: var(--success);
}

/* ── Key Infos Edit Form ──────────────────────────── */

.key-infos-edit-overlay {
  margin-top: 16px;
}

.key-infos-edit-form {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px;
}

.key-info-edit-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.key-info-edit-row:last-of-type {
  border-bottom: none;
}

.key-info-edit-group {
  margin-bottom: 4px;
}

.key-info-edit-code-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0 2px;
}

.key-info-edit-code-header .key-info-edit-code {
  font-size: 13px;
  color: var(--muted);
}

.btn-keyinfo-add,
.btn-keyinfo-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid currentColor;
  background: none;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0;
  flex-shrink: 0;
}

.btn-keyinfo-add {
  color: var(--accent);
}

.btn-keyinfo-add:hover {
  background: var(--accent);
  color: #fff;
}

.btn-keyinfo-remove {
  color: var(--muted);
  margin-left: 8px;
}

.btn-keyinfo-remove:hover {
  color: var(--danger, #c0392b);
  border-color: var(--danger, #c0392b);
}

.key-info-edit-row label,
.key-info-edit-code {
  flex: 0 0 200px;
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
}

.key-info-label-input {
  flex: 0 0 200px !important;
}

.key-info-value-input {
  flex: 1;
}

.key-info-edit-inputs {
  display: flex;
  gap: 8px;
  flex: 1;
  flex-wrap: nowrap;
  align-items: center;
}

.key-info-input {
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  background: var(--bg);
  color: var(--ink);
  min-width: 0;
}

.key-info-label-input {
  flex: 2 1 220px !important;
}

.key-info-value-input {
  flex: 1 1 100px !important;
}

.key-info-devise-hint {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--muted);
  font-weight: 600;
  padding: 0 2px;
}

.key-info-input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.key-info-date-input {
  flex: 0 0 140px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 13px;
  background: var(--bg);
  color: var(--ink);
}

.key-info-date-input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

.key-infos-edit-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  justify-content: flex-end;
}

.btn-cancel-keyinfos {
  background: transparent;
  border: 1px solid var(--line);
  cursor: pointer;
}

/* ── Key business info — refonte 39-04 (lecture/édition) ── */

.key-info-pill-pending {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  background: #f59e0b;
  border-radius: 10px;
  text-decoration: none;
  vertical-align: middle;
  line-height: 1.4;
}
.key-info-pill-pending:hover {
  background: #d97706;
  text-decoration: none;
}

.key-info-pending-count {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  background: #f59e0b;  /* même orange que .key-info-pill-pending — code couleur "à faire" */
  border-radius: 8px;
}

/* ── Edit page : Infos clés (refonte UX) ─────────── */

.kbi-edit-page {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.kbi-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: end;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fcfcfd;
  position: sticky;
  top: 66px;
  z-index: 5;
}

.kbi-toolbar-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.kbi-toolbar-group label {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.kbi-toolbar input,
.kbi-toolbar select {
  min-width: 180px;
  padding: var(--toolbar-field-pad);
  border: 1px solid var(--line);
  border-radius: var(--toolbar-field-radius);
  font-size: var(--toolbar-field-fs);
}

.kbi-group-details,
.kbi-subgroup-details,
.kbi-edit-code-section {
  margin: 0;
}

.kbi-group-details > summary,
.kbi-subgroup-details > summary,
.kbi-edit-code-section > summary {
  list-style: none;
  cursor: pointer;
}

.kbi-group-details > summary::-webkit-details-marker,
.kbi-subgroup-details > summary::-webkit-details-marker,
.kbi-edit-code-section > summary::-webkit-details-marker {
  display: none;
}

.kbi-group-details > summary,
.kbi-subgroup-details > summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #f6f8fb;
  margin-top: 10px;
}

.kbi-group-title,
.kbi-subgroup-title {
  font-weight: 700;
  color: var(--ink);
}

.kbi-group-meta,
.kbi-subgroup-meta,
.kbi-code-summary-meta {
  font-size: 12px;
  color: var(--muted);
}

.kbi-subgroup-details {
  margin-left: 10px;
}

.kbi-code-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 8px;
}

.kbi-code-summary-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.kbi-code-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* .kbi-edit-breadcrumb : définie plus haut (alias rétro-compat Phase 84). */

.kbi-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  align-self: flex-start;
  padding: 6px 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 999px;
  font-size: 13px;
  color: var(--accent-ink);
}

.kbi-filter-chip-label {
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.kbi-filter-chip-value {
  font-weight: 700;
}

.kbi-filter-chip-clear {
  color: var(--accent-ink);
  text-decoration: none;
  font-size: 12px;
  font-weight: 600;
  border-left: 1px solid var(--accent);
  padding-left: 10px;
  opacity: 0.75;
}

.kbi-filter-chip-clear:hover { opacity: 1; }

.kbi-edit-code-section {
  /* Hérite de .panel : bg, border, radius 14px, padding 18px, shadow */
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.kbi-code-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.kbi-code-title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
  text-transform: none;
  letter-spacing: normal;
}

.kbi-code-breadcrumb {
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}

.kbi-pending-count {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: #f59e0b;  /* identique aux autres badges "action à prendre" */
  border-radius: 999px;
  white-space: nowrap;
}

.kbi-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.kbi-section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 700;
}

.kbi-validated-list .doc-info-row {
  padding: 8px 0;
}

/* ── Candidate / Suggestion IA card ───────────── */

.kbi-candidate-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg);
  overflow: hidden;
}

.kbi-candidate-card + .kbi-candidate-card {
  margin-top: 10px;
}

.kbi-candidate-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: #fdfcfa;
  border-bottom: 1px solid var(--line);
}

.kbi-candidate-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.kbi-confidence-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Phase 39-04 follow-up : confiance en texte coloré sur bg neutre (gris très clair).
   Vert réservé au statut "validé" — confiance ≥90 → ink neutre, 70-89 → warn-ink, <70 → danger. */
.kbi-confidence-badge.high   { background: var(--pill-bg); color: var(--ink); }
.kbi-confidence-badge.medium { background: var(--pill-bg); color: var(--warn-ink); }
.kbi-confidence-badge.low    { background: var(--pill-bg); color: var(--danger); }

/* Phase 39-04 follow-up : block nesting fort.
   - Code section header renforcé (bg tinté, border-bottom 2px)
   - Item card : conteneur englobant (valeur validée + ses alternatives)
   - Alternatives nestées DANS le conteneur, indentation + dashed border-left + tint
   - Divider net "Nouvelles suggestions" puis cartes standalone */

.kbi-edit-code-section + .kbi-edit-code-section {
  margin-top: 32px; /* gap fort entre 2 sections de code (Immobilier ≠ AV) */
}

.kbi-code-section-header {
  padding: 16px 20px;
  margin: -18px -18px 16px; /* étend sur toute la largeur du panel (qui a padding 18) */
  background: var(--bg-subtle);
  border-bottom: 2px solid var(--line);
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
}

.kbi-code-section-header .kbi-code-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* ── Item Card : conteneur englobant (valeur validée + alternatives) ── */

.kbi-item-cards-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.kbi-item-card {
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 20px;
  background: var(--panel);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

/* Annule l'ancien rythme vertical : c'est désormais le gap du parent qui gère */
.kbi-validated-block + .kbi-validated-block {
  margin-top: 0;
}

.kbi-item-card__validated-value {
  /* La zone du haut : la valeur validée, occupe la zone haute de la carte */
}

.kbi-item-card__alternatives-block {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
}

.kbi-item-card__alternatives-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 10px;
}

/* Override de l'ancienne wrap (compat) : pas de border-left/indent ici,
   le marquage filiation est porté par chaque .kbi-card--alternative */
.kbi-item-card__alternatives-block.kbi-alternatives-wrap {
  margin: 16px 0 0 0;
  padding-left: 0;
  border-left: none;
}

/* ── Nested alternative card (à l'intérieur d'une item card) ── */

.kbi-card--alternative {
  font-size: 13px;
  margin-left: 16px;            /* indentation visible */
  border: 1px solid var(--line);
  border-left: 2px dashed var(--warn);
  border-radius: 8px;
  background: var(--warn-soft);
}

.kbi-card--alternative + .kbi-card--alternative {
  margin-top: 8px;
}

.kbi-card--alternative .kbi-candidate-header {
  padding: 8px 12px;
  background: transparent;
}

.kbi-card--alternative .kbi-candidate-title {
  font-size: 13px;
  font-weight: 500; /* normal vs bold sur la valeur parente */
}

.kbi-card--alternative .kbi-candidate-body {
  padding: 8px 12px;
  font-size: 13px;
}

.kbi-card--alternative .kbi-candidate-fields .doc-info-row {
  padding: 4px 0;
}

.kbi-card--alternative .kbi-candidate-footer {
  padding: 8px 12px;
  background: transparent;
}

/* ── Validated row dans une item card ── */

.kbi-section--validated .kbi-validated-row.kbi-card--validated {
  position: relative;
  padding-left: 12px;
  border-left: 3px solid var(--success);
  background: transparent;
}

/* ── Divider "Nouvelles suggestions (N)" ── */

.kbi-new-suggestions-divider {
  margin: 24px 0 14px;
  padding-top: 14px;
  border-top: 2px solid var(--line);
  text-align: left;
}

.kbi-new-suggestions-divider--standalone {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.kbi-new-suggestions-divider > span {
  display: inline-block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 700;
}

/* ── Standalone new suggestion cards (sous le divider) ── */

.kbi-section--suggestions .kbi-candidate-card.kbi-card--suggestion {
  border-left: 3px solid var(--warn); /* solide vs dashed pour les alternatives */
  background: var(--warn-soft);
}

/* Une alternative au sein de la suggestion-section garde son style nested
   (dashed left, indenté). Re-précise pour éviter qu'elle hérite du style ci-dessus. */
.kbi-section--suggestions .kbi-candidate-card.kbi-card--alternative.kbi-card--suggestion {
  border-left-style: dashed;
  border-left-width: 2px;
}

.kbi-section-title--validated { color: var(--success); }
.kbi-section-title--suggestions { color: var(--warn); }

.kbi-section-title .kbi-section-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
  margin-right: 6px;
  vertical-align: middle;
}

.kbi-section-title .kbi-section-icon {
  display: inline-block;
  margin-right: 6px;
  font-size: 12px;
  line-height: 1;
  vertical-align: middle;
}

/* Pills "Nouveau" / "Alternative à X" sur header carte suggestion */
.kbi-kind-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

.kbi-kind-pill--new {
  background: var(--pill-bg);
  color: var(--muted);
}

.kbi-kind-pill--alt {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

/* Phase 39-04 follow-up : badge "À vérifier" si validation_warnings non vide.
   Action à faire → orange. Dimensions standardisées. */
.kbi-warn-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: #fff1e6;
  color: var(--warn);
  border: 1px solid var(--warn);
  margin-left: 6px;
}

.kbi-candidate-body {
  padding: 12px 14px;
  font-size: 14px;
}

.kbi-candidate-fields .doc-info-row {
  padding: 6px 0;
}

.kbi-sub-empty {
  color: #b3b3b3;
}

.kbi-candidate-source {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  font-size: 12px;
  align-items: center;
}

.kbi-source-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}

.kbi-source-link:hover { text-decoration: underline; }

.kbi-candidate-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: #fdfcfa;
}

/* ── Edit mode (inputs) ───────────────────────── */

.kbi-edit-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px 14px;
}

.kbi-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
}

.kbi-field > span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.kbi-field input {
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  box-sizing: border-box;
}

.kbi-field input:focus {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
  border-color: var(--accent);
}

/* ── Ghost buttons ─────────────────────────────── */

.btn-ghost {
  padding: 8px 14px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
}

.btn-ghost:hover {
  color: var(--ink);
  background: rgba(0, 0, 0, 0.04);
}

.btn-ghost-danger {
  padding: 8px 14px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--error);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  opacity: 0.75;
}

.btn-ghost-danger:hover {
  opacity: 1;
  background: rgba(157, 47, 47, 0.08);
}

/* ── Saisie manuelle (collapsible) ────────────── */

.kbi-manual-details {
  border-top: 1px dashed var(--line);
  padding-top: 12px;
}

.kbi-manual-details > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  list-style: none;
  padding: 4px 0;
  user-select: none;
}

.kbi-manual-details > summary::-webkit-details-marker { display: none; }

.kbi-manual-details > summary:hover { color: var(--accent); }

.kbi-manual-details[open] > summary { color: var(--ink); }

.kbi-manual-form {
  margin-top: 10px;
  padding: 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ── Phase 39-04 follow-up : hiérarchie typo + boutons d'action ── */

/* Fix 2 — hiérarchie typo sur item-card (valeur validée + sub_fields) */
.kbi-item-card .kbi-validated-read .doc-info-label {
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}

.kbi-item-card .kbi-validated-read .key-info-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--ink);
}

/* Sub_fields lignes (doc-info-row hors le bloc validated-read) :
   label muted 14 / valeur ink 14. Hérite du body si pas override. */
.kbi-item-card .kbi-candidate-fields .doc-info-row .doc-info-label {
  font-size: 14px;
  font-weight: 400;
  color: var(--muted);
}

.kbi-item-card .kbi-candidate-fields .doc-info-row > span:last-child {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
}

/* Cartes alternative nestées : écart de rang vs le parent (label 14 / valeur 16 / sub 13) */
.kbi-item-card .kbi-card--alternative .kbi-candidate-title {
  font-size: 14px;
  font-weight: 500;
}

.kbi-item-card .kbi-card--alternative .kbi-candidate-fields .doc-info-row .doc-info-label {
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}

.kbi-item-card .kbi-card--alternative .kbi-candidate-fields .doc-info-row > span:last-child {
  font-size: 13px;
  font-weight: 400;
}

.kbi-item-card .kbi-card--alternative .kbi-candidate-fields .doc-info-row > span:last-child .key-info-value,
.kbi-item-card .kbi-card--alternative .kbi-candidate-body > .kbi-candidate-fields > .doc-info-row:first-child > span:last-child {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}

/* Cartes new standalone : valeur principale 18 / label 16 / sub 13 (pas de réduction parent) */
.kbi-section--suggestions .kbi-card--suggestion:not(.kbi-card--alternative) .kbi-candidate-title {
  font-size: 16px;
  font-weight: 600;
}

.kbi-section--suggestions .kbi-card--suggestion:not(.kbi-card--alternative) .kbi-candidate-fields .doc-info-row:first-child > span:last-child {
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
}

.kbi-section--suggestions .kbi-card--suggestion:not(.kbi-card--alternative) .kbi-candidate-fields .doc-info-row .doc-info-label {
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}

/* Fix 5 — hiérarchie d'action sur les boutons.
   Variants normalisés ; les classes legacy (.btn-action / .btn-edit / .btn-ghost-danger / .btn-ghost) restent en place. */

/* primary plein : .btn-action existant (utilisé sur new standalone, ajouter manuel) */
.kbi-btn--primary,
.kbi-card--suggestion:not(.kbi-card--alternative) .kbi-candidate-footer button[type="submit"].btn-action {
  /* style hérité de .btn-action (primary plein) — confirmé pour les "new" */
}

/* Sur les cartes alternative nestées : Valider perd le fill plein → outline secondaire */
.kbi-card--alternative .kbi-candidate-footer button.btn-action {
  background: transparent;
  color: var(--accent-ink);
  border: 1px solid var(--accent);
}
.kbi-card--alternative .kbi-candidate-footer button.btn-action:hover {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

/* Sur les cartes alternative : Modifier devient ghost-accent (texte accent sans border) */
.kbi-card--alternative .kbi-candidate-footer .btn-edit {
  background: transparent;
  border-color: transparent;
  color: var(--accent);
}
.kbi-card--alternative .kbi-candidate-footer .btn-edit:hover {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent-ink);
}

/* ── Responsive ──────────────────────────────────── */

@media (max-width: 768px) {
  .topbar { padding: 0 16px; gap: 16px; }
  .topbar-brand { font-size: 16px; }
  .topbar-meta { gap: 8px; }
  .topbar-user { display: none; }
  .topbar-nav { width: min(82vw, var(--nav-width)); }
  .content { padding: 16px; }
  body.nav-open .content { margin-left: auto; }
  .page-header h1 { font-size: 22px; }
  .client-row { padding: 12px 14px; }
  .doc-table { font-size: 13px; }
  .doc-table th, .doc-table td { padding: 8px; }
  .key-info-edit-row { flex-wrap: wrap; gap: 4px; }
  .key-info-edit-code { flex: 0 0 100%; }
  .key-info-edit-inputs { flex-wrap: wrap; }
}

/* ── Bulk actions sur page édition Infos clés ─────────── */
.kbi-bulk-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 32px;
  padding: 16px 20px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.kbi-bulk-actions .kbi-bulk-label {
  flex: 1;
  font-size: 13px;
}

.kbi-bulk-actions .inline-form {
  display: inline-block;
}

/* ══════════════════════════════════════════════════════════════════════════
   Phase 94 (lot 4) — éditeur de situation patrimoniale, grammaire v6.
   FAMILLE = bandeau · DOMAINE = seule boîte · LIGNE = rangée de grille ·
   DÉTAIL = inset pleine largeur, 4 sections titrées repliables (un seul
   détail interactif ouvert à la fois). Une colonne montant unique
   (--col-amount). Profondeur visuelle max 3.
   ══════════════════════════════════════════════════════════════════════════ */

.kbi-ed-famille { display: block; }
.kbi-ed-famille > summary { list-style: none; cursor: pointer; }
.kbi-ed-famille > summary::-webkit-details-marker { display: none; }
.kbi-ed-famille > summary .kbi-ed-chev::before { content: "▸ "; color: rgba(255, 255, 255, 0.75); font-weight: 400; }
.kbi-ed-famille[open] > summary .kbi-ed-chev::before { content: "▾ "; }

.kbi-ed-famille-bandeau {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--col-amount);
  align-items: baseline;
  background: var(--accent-ink);
  color: #fff;
  border-radius: 6px;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-top: 10px;
}
.kbi-ed-famille-suffix { font-weight: 400; font-size: 11px; text-transform: none; }

.kbi-ed-amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-weight: 600;
}

/* Niveau 2 : le DOMAINE — la seule boîte de la page. */
.kbi-ed-domaine {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-left: 16px;
  /* PAS d'overflow:hidden : il clippait le dropdown searchable du formulaire
     d'ajout (il passait « sous » le bandeau famille suivant). */
  overflow: visible;
  scroll-margin-top: 140px; /* la toolbar sticky ne recouvre plus les ancres */
}
.kbi-ed-famille > .kbi-ed-domaine { margin-top: 8px; }
.kbi-ed-domaine > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--col-amount);
  align-items: baseline;
  padding: 9px 14px;
  font-weight: 600;
  background: var(--bg-subtle);
  border-bottom: 1px solid transparent;
  border-radius: 9px 9px 0 0; /* l'arrondi n'est plus porté par overflow:hidden */
}
.kbi-ed-domaine:not([open]) > summary { border-radius: 9px; }
.kbi-ed-domaine[open] > summary { border-bottom-color: var(--line); }
.kbi-ed-domaine > summary::-webkit-details-marker { display: none; }
.kbi-ed-domaine > summary .kbi-ed-chev::before { content: "▸ "; color: var(--muted); font-weight: 400; }
.kbi-ed-domaine[open] > summary .kbi-ed-chev::before { content: "▾ "; }
.kbi-ed-domaine-body { padding: 4px 14px 12px; }
/* Phase 97 (feedback opérateur) : nombre de lignes du domaine, discret. */
.kbi-ed-domaine-count { font-weight: 400; font-size: 12px; }
/* Résumé replié du domaine (Phase 98) : même gradation --warn que le bouton de
   ligne (P6) — plein = des documents attendent un arbitrage (prioritaire),
   doux = valeur périmée. Le compteur est le SEUL support : pas de pastille en
   plus, sinon on rajoute de l'UI pour dire ce que le chiffre dit déjà. */.kbi-ed-domaine-count--stale { color: var(--warn-ink, #b45309); font-weight: 600; cursor: help; }

/* Niveau 3 : la LIGNE minimale — nom · ⚠ · action · montant. */
.kbi-ed-ligne-wrap { border-bottom: 1px solid #eef0f3; scroll-margin-top: 140px; }
.kbi-ed-ligne-wrap:last-child { border-bottom: none; }
/* Phase 113-03 — contenance : ligne hébergée sous son enveloppe (retrait), montant
   grisé quand il est déjà dans le total déclaré de l'enveloppe. */
.kbi-ed-ligne-wrap--hosted .kbi-ed-ligne .kbi-ed-nom { padding-left: 22px; }
.kbi-ed-hosted-mark { color: #94a3b8; }
.kbi-ed-hosted-note { font-size: 12px; font-weight: normal; }
.kbi-ed-amount--not-counted { color: #94a3b8; text-decoration: line-through dotted; }
/* Phase 100-02 — titulaire d'un élément (foyer à deux membres) : chip discrète après le nom. */
.kbi-ed-holder-chip { display: inline-block; margin-left: 6px; padding: 0 7px; border-radius: 10px; font-size: 11px; font-weight: 500; line-height: 18px; background: #e0e7ff; color: #3730a3; vertical-align: 1px; }
.kbi-ed-holder-chip--common { background: #f1f5f9; color: #475569; }
.kbi-holder-totals { margin: 12px 0; padding: 10px 14px; }
.kbi-holder-table { margin: 0; }
.kbi-holder-table th.num, .kbi-holder-table td.num { text-align: right; white-space: nowrap; }
.kbi-holder-note { font-size: 12px; margin-top: 6px; }
/* Phase 113-06 — seconde ligne discrète sous un montant (« net X € », « dettes X € »). */
.kbi-ed-net-note { font-size: 12px; font-weight: normal; white-space: nowrap; }
/* Phase 113-07 — supports logés listés dans le détail d'un contrat. */
.kbi-ed-supports-list { margin: 0 0 10px 18px; padding: 0; }
.kbi-ed-form-add-support { margin-top: 6px; }
.kbi-ed-ligne {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto var(--col-amount);
  align-items: center;
  column-gap: 12px;
  padding: 8px 0 8px 16px;
  cursor: pointer;
}
.kbi-ed-ligne:hover { background: #f8fafc; }
.kbi-ed-nom { font-weight: 500; }
.kbi-ed-nom .kbi-ed-chev::before { content: "▸ "; color: #cbd5e1; font-weight: 400; }
.kbi-ed-ligne-wrap.open .kbi-ed-nom .kbi-ed-chev::before { content: "▾ "; }
.kbi-ed-warn { color: var(--warn); cursor: pointer; }
.kbi-ed-warn-text { color: var(--warn); }
.kbi-ed-info { color: var(--accent-ink); font-size: 13px; font-weight: 400; }
.kbi-ed-actions { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.kbi-ed-ligne--ghost .kbi-ed-nom,
.kbi-ed-ligne--closed .kbi-ed-nom { color: var(--muted); font-weight: 400; }
.kbi-ed-ligne--ghost, .kbi-ed-ligne--closed { cursor: default; }
.kbi-ed-ligne--ghost:hover, .kbi-ed-ligne--closed:hover { background: transparent; }

/* Niveau 4 : le DÉTAIL — inset pleine largeur, sections titrées.
   24px inter-sections / 14px titre→contenu (valeurs validées sur maquette). */
.kbi-ed-detail {
  background: var(--bg-subtle);
  border-left: 3px solid #94a3b8;
  margin: 4px 0 8px 16px;
  padding: 4px 18px 8px;
  border-radius: 0 8px 8px 0;
  cursor: default;
}
.kbi-ed-sec { padding: 24px 0; }
.kbi-ed-sec + .kbi-ed-sec { border-top: 1px solid #e6eaf0; }
.kbi-ed-sec-title {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #334155;
  margin-bottom: 14px;
}
details.kbi-ed-sec > summary.kbi-ed-sec-title { list-style: none; cursor: pointer; margin-bottom: 0; }
details.kbi-ed-sec[open] > summary.kbi-ed-sec-title { margin-bottom: 14px; }
details.kbi-ed-sec > summary.kbi-ed-sec-title::-webkit-details-marker { display: none; }
details.kbi-ed-sec > summary.kbi-ed-sec-title .kbi-ed-chev::before { content: "▸ "; color: var(--muted); }
details.kbi-ed-sec[open] > summary.kbi-ed-sec-title .kbi-ed-chev::before { content: "▾ "; }
.kbi-ed-sec-count { font-weight: 400; color: var(--muted); letter-spacing: normal; text-transform: none; }
.kbi-ed-sec-body { margin-left: 16px; display: grid; gap: 10px; justify-items: start; }
.kbi-ed-sec-body--wide { justify-items: stretch; }
.kbi-ed-sec-danger > summary.kbi-ed-sec-title { color: #8b3a3a; }

.kbi-ed-metaline { font-size: 13px; color: var(--muted); line-height: 1.7; }
.kbi-ed-metaline b { color: var(--ink); font-size: 15px; }
.kbi-ed-subfields { font-size: 12px; display: flex; flex-wrap: wrap; gap: 4px 16px; }

/* Formulaires du détail : contrôles d'une même rangée = même hauteur/typo.
   ⚠ font: inherit DANS un label stylé hérite graisse/casse → re-préciser. */
.kbi-ed-form-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }
/* [hidden] doit TOUJOURS gagner sur les display de classe (flex/grid) —
   piège vu 2× en réel : blocs sub-fields par type, formulaire Corriger. */
/* (PAS .kbi-ed-detail ici : le niveau 4 force display:block sur les détails
   [hidden] pour le mode revue — un !important le casserait.) */
.kbi-ed-form-row[hidden],
.kbi-ed-form-maj[hidden],
.kbi-ed-form-add[hidden],
.kbi-ed-form-correct[hidden],
.kbi-ed-form-carac[hidden] { display: none !important; }
.kbi-ed-form-maj, .kbi-ed-form-add, .kbi-ed-form-correct, .kbi-ed-form-carac { display: grid; gap: 14px; justify-items: start; }
.kbi-ed-form-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 700;
}
.kbi-ed-form-row input, .kbi-ed-form-row select {
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  padding: 0 10px;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: 6px;
  min-width: 150px;
  background: #fff;
}
.kbi-ed-form-row input[type="date"] { font-variant-numeric: tabular-nums; }
/* Retour opérateur 2026-10-20 : une liste à recherche (type, type de support,
   « Logé dans », « Bien financé »…) prend la largeur de son libellé — sans
   plancher, elle se réduit au texte « — Choisir — » et ses options passent
   sur deux ou trois lignes. Plancher de largeur + panneau plus large. */
.kbi-ed-form-row label:has(select[data-searchable]) { min-width: 280px; }
.kbi-ed-form-row .ss-panel { min-width: 320px; }
.kbi-ed-form-row .btn-new, .kbi-ed-form-row .btn-ghost { height: 36px; }
.kbi-ed-input-val { text-align: right; }

/* Utilitaire de l'ACTION DISCRÈTE, pour les plis qui n'ont pas de classe à eux
   (sinon chaque template re-tombe sur .muted, qui dit « pas cliquable »). */
.action-quiet { color: var(--action-quiet); cursor: pointer; }
/* Phase 107 : sur un <button> (« Ignorer » d'une carte d'alerte), l'action
   discrète perd le chrome natif — sinon le navigateur dessine un bouton gris
   (= `--muted` interdit sur un interactif, et une boîte qui jure à côté des
   .btn-edit.btn-sm). Même corps que .btn-sm, sans boîte. */
button.action-quiet {
  background: none; border: 0; padding: 4px 0; margin: 0;
  font: inherit; font-size: 12px; font-weight: 600; line-height: 1;
}
.action-quiet:hover { color: var(--accent); text-decoration: underline; }
.action-quiet:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
}

/* Plis « ▸ Rattacher une source ? » : archétype de l'ACTION DISCRÈTE — ils
   passent de --accent-ink (71 % de saturation, le bleu le plus fort de la
   charte) à --action-quiet, comme « + Ajouter » qui est le même widget.
   Ils y gagnent : contraste toujours AA, moitié moins de saturation. */
.kbi-ed-pli { font-size: 12px; }
.kbi-ed-pli > summary { list-style: none; cursor: pointer; color: var(--action-quiet); }
.kbi-ed-pli > summary:hover { color: var(--accent); text-decoration: underline; }
.kbi-ed-pli > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
}
.kbi-ed-pli > summary::-webkit-details-marker { display: none; }
.kbi-ed-pli > summary::before { content: "▸ "; }
.kbi-ed-pli[open] > summary::before { content: "▾ "; }
.kbi-ed-pli-body {
  display: flex; flex-direction: column; gap: 4px; margin: 8px 0 0 14px;
  font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.03em; font-weight: 700; align-items: flex-start;
}
.kbi-ed-pli-body input, .kbi-ed-pli-body select {
  font: inherit; font-size: 13.5px; font-weight: 400; letter-spacing: normal;
  text-transform: none; color: var(--ink); padding: 0 10px; height: 34px;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; min-width: 280px;
}
.kbi-ed-close-item > summary { color: var(--action-quiet); }
.kbi-ed-close-item form { display: flex; gap: 8px; align-items: center; flex-direction: row; }

.kbi-ed-correct-title { font-size: 12.5px; font-weight: 600; }
.kbi-ed-form-correct {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
  margin-top: 8px;
}

.kbi-ed-form-note { font-size: 12px; text-transform: none; letter-spacing: normal; font-weight: 400; align-self: center; }

/* Suggestions IA re-logées dans la boîte domaine (flux inchangé, A2.6). */
.kbi-ed-suggestions { margin: 6px 0 10px 16px; }
.kbi-ed-suggestions-title {
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--warn-ink); margin-bottom: 6px;
}

/* Éléments sortis du patrimoine : repliés par défaut, par domaine. */
.kbi-ed-closed-fold { margin: 6px 0 4px 16px; }
.kbi-ed-closed-fold > summary { list-style: none; cursor: pointer; font-size: 12px; color: var(--muted); }
.kbi-ed-closed-fold > summary::-webkit-details-marker { display: none; }
.kbi-ed-closed-fold > summary::before { content: "▸ "; }
.kbi-ed-closed-fold[open] > summary::before { content: "▾ "; }
.kbi-ed-closed-badge {
  display: inline-block; font-size: 10px; padding: 1px 8px; border-radius: 8px;
  background: var(--pill-bg); color: var(--muted); vertical-align: 1px;
}
.kbi-ed-closed-histo { margin-left: 16px; }

/* « + Ajouter » : LIEN discret, pas un bouton plein (retour opérateur
   2026-07-17 — exception assumée à la règle d'or « action = bouton canonique »,
   cf. UI-CONVENTIONS § P8). Sur cette vue, l'information d'ordre 1 est le nom
   des éléments et leurs montants ; l'ajout se répète 5-6 fois par écran et
   n'est pas ce qu'on vient y faire. Il reprend son poids une fois déplié. */
.kbi-ed-add { margin: 4px 0 2px 16px; }
.kbi-ed-add > summary { list-style: none; display: inline-block; cursor: pointer; }
.kbi-ed-add > summary::-webkit-details-marker { display: none; }
/* Action discrète (--action-quiet) : « + Ajouter » ouvre un formulaire, c'est
   le MÊME widget que les plis ci-dessous — même rôle, même token. Le gris
   --muted a été essayé puis écarté : visuellement au bon niveau, mais dans la
   grammaire il dit « pas cliquable / pas dispo » (opérateur 2026-07-17). */
.kbi-ed-add-btn {
  color: var(--action-quiet);
  font-weight: 500;
  font-size: 12px;
  padding: 2px 0;
}
.kbi-ed-add > summary.kbi-ed-add-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
/* ⚠ `.kbi-ed-add-btn` est PORTÉ PAR le <summary> — pas un enfant. Le
   `> summary:hover .kbi-ed-add-btn` d'origine ne matchait rien (règle morte,
   invisible tant que le bouton plein avait son propre retour visuel). */
.kbi-ed-add > summary.kbi-ed-add-btn:hover { color: var(--accent); text-decoration: underline; }
/* (Le « déplié = --muted » d'il y a une heure sautait : un summary ouvert reste
   cliquable — c'est le formulaire dessous qui dit l'état, pas un gris.) */
.kbi-ed-form-add {
  margin-top: 10px;
  background: var(--bg-subtle);
  border-left: 3px solid #94a3b8;
  border-radius: 0 8px 8px 0;
  padding: 14px 18px;
}

/* Toolbar v6 : contrôle segmenté 3 niveaux. */
/* Sélecteur de VUE (token, Phase 98-06) — segmented « 1 · X / 2 · Y » qui
   pilote un niveau de dépliage. `.view-toggle` est le nom canonique ;
   `.kbi-ed-viewlevel` (Situation, origine) et `.doc-viewlevel` (listings)
   sont ses alias historiques — même règle, on ne renomme pas le markup. */
.view-toggle, .kbi-ed-viewlevel { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.view-toggle button, .kbi-ed-viewlevel button {
  border: none; background: #fff; padding: 6px 12px; font-size: 12.5px;
  cursor: pointer; color: var(--ink); border-right: 1px solid var(--line);
}
.view-toggle button:last-child, .kbi-ed-viewlevel button:last-child { border-right: none; }
.view-toggle button.is-active, .kbi-ed-viewlevel button.is-active { background: var(--accent-ink); color: #fff; font-weight: 600; }

/* Vue 4 niveaux = un cran par niveau de hiérarchie (arbitrage opérateur).
   Niveau 1 (« Familles ») : les <details> famille sont simplement repliés. */

/* Niveau 4 (« + Détails ») : chaque ligne montre sa section-sommaire en
   LECTURE ; le détail interactif complet reste mono-ouvert (clic ligne). */
#kbi-ed-root[data-view-level="4"] .kbi-ed-detail[hidden] { display: block; }
#kbi-ed-root[data-view-level="4"] .kbi-ed-detail[hidden] .kbi-ed-sec { display: none; }
#kbi-ed-root[data-view-level="4"] .kbi-ed-detail[hidden] .kbi-ed-sec-first { display: block; padding: 12px 0; }

/* Masquage par recherche/filtre (les totaux serveur ne changent pas). */
.kbi-ed-hidden { display: none !important; }

/* ══ Phase 98 — Rapprochement documentaire ═══════════════════════════════
   Primitive « expérience » (swap du bandeau toolbar), sections ⎘/⊘ du
   détail d'élément, lignes fantômes E1/E4, carte d'identité, bouton de
   ligne 2 états. Palette : orange « à faire » (--warn/--warn-soft/
   --warn-ink), bleu accent pour la bande formulaire. Spec visuelle :
   maquette passB2-fiche-reelle.html v2.12 (Phase 98). */

/* Boutons de page (header-actions).
   2026-07-19 : `.kbi-rappro-header { margin-bottom: 4px }` RETIRÉ — il écrasait
   la respiration standard sous l'en-tête (R11 : --header-gap), collant la
   toolbar Situation au titre. La bande d'en-tête est générique, sa marge basse
   aussi : aucune page ne la surcharge. */
/* Expérience = swap du bandeau toolbar : les 4 groupes disparaissent,
   remplacés par le stepper orange (rapprochement) ou la bande bleue
   (formulaire client) — même slot sticky. */
.kbi-toolbar--experience .kbi-toolbar-group { display: none !important; }
.kbi-rappro-b {
  display: inline-block;
  border: 1px solid #d0d7de;
  background: #fff;
  border-radius: 7px;
  padding: 5px 11px;
  font-size: 12.5px;
  cursor: pointer;
  color: inherit;
  text-decoration: none;
  font-family: inherit;
  line-height: 1.35;
}
.kbi-rappro-b.pri { background: #1a7f37; border-color: #1a7f37; color: #fff; font-weight: 600; }
.kbi-rappro-b.sub { color: #57606a; }
.kbi-form-band {
  display: flex;
  flex: 1 1 100%;
  width: 100%;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: var(--accent-soft);
  color: var(--accent-ink);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 12.5px;
}
.kbi-form-band .kbi-rappro-b { border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.kbi-form-band-note { width: 100%; font-size: 11px; opacity: .8; }

/* Section « ⎘ Propositions des documents » du détail d'élément */
/* Panneau « ↪ Réattribuer… » inline */
/* Pied épinglé « créer » du composant searchable_select (slot ss-create) */
.ss-panel .ss-create {
  border-top: 1px solid var(--line);
  padding: 8px 12px;
  color: var(--accent-ink);
  font-weight: 600;
  cursor: pointer;
  background: #fbfdff;
  font-size: 12.5px;
}
.ss-panel .ss-create:hover { background: #eef4fb; }

/* Pli « ⊘ Propositions écartées » */
/* Lignes fantômes E1 (nouvel élément, bleu) / E4 (attendu, ambre) *//* MONO : valeur inline en gras dans l'en-tête (info n°1, vue tôt) ; chiffres
   tabulaires pour l'alignement d'une pile de ghosts. *//* Multi-candidats E1 : lignes empilées (N documents proposent le MÊME nouvel
   élément) — flex-basis 100% pour passer sous l'en-tête. Chaque ligne = pastille
   (radio + valeur) + SOURCE CLIQUABLE + tag « défaut », même anatomie que les
   candidats d'E2 (.kbi-rappro-cand) : la source hors du <label> pour rester
   cliquable sans (dé)cocher le radio. */
/* Carte d'identité de l'élément (remplace la section titrée) */
.kbi-ed-idcard > .kbi-ed-sec-title { display: none; }
.kbi-ed-idcard > .kbi-ed-sec-body {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 12px 16px;
  box-shadow: 0 1px 2px rgba(30, 34, 40, .05);
}
.kbi-ed-idcard { padding-bottom: 6px; margin-bottom: 4px; }
.kbi-ed-idcard-val { font-size: 18px; }
.kbi-ed-confline { color: #6b7280; font-size: 12px; margin-top: 5px; }
.kbi-ed-idcard .kbi-ed-subfields {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px solid #eceff1;
}

/* Bouton de ligne, 3 ÉTATS (gradation du signal — retour opérateur) :
   « ⎘ N propositions » orange PLEIN (des documents attendent un arbitrage)
   ⇄ « ⏳ Mettre à jour » orange CONTOUR (périmée, aucun document n'attend)
   ⇄ « Mettre à jour » neutre. Même famille --warn, intensité différente. */
/* Les 3 états partagent la MÊME boîte : « Mettre à jour » ne doit jamais
   passer sur 2 lignes quand la colonne se resserre (34px vs 22px). *//* L'icône native (15px) dépasse la typo du bouton (13px) et gonflait sa
   boîte : les 2 états du MÊME bouton doivent avoir la même hauteur. */.kbi-ed-btn-maj--stale {
  color: var(--warn-ink);
  border-color: var(--warn);
  background: var(--warn-soft);
}
.kbi-ed-btn-maj--stale:hover {
  border-color: var(--warn-ink);
  color: var(--warn-ink);
}
/* Le glyphe emoji a des métriques natives plus hautes qu'une ligne de
   texte : le borner explicitement pour qu'il n'étire pas le bouton. */
.kbi-ed-btn-hourglass {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  line-height: 1;
}
.kbi-ed-neant { color: #6b7280; font-style: italic; }

/* Expérience : masquage + focus */
/* Flash toast (placeholders formulaire client) *//* [hidden] doit gagner sur display:flex (rangées du panneau Réattribuer). *//* Rangée « Créer » du panneau Réattribuer : type + libellé côte à côte. */
/* ── Historique SCD : rangée à 4 infos + 2 plis (retour opérateur 98) ───────
   La rangée ne porte que ce qui distingue une version : depuis quand, combien.
   Le reste (arrêté, source, saisie) descend dans 👁 ; les actions dans ✏️. */
.kbi-history-table { margin-top: 6px; max-width: 720px; font-size: 12px; }
.kbi-histo-when { white-space: nowrap; width: 1%; }
.kbi-histo-val { font-variant-numeric: tabular-nums; white-space: nowrap; width: 1%; }
.kbi-histo-acts { white-space: nowrap; text-align: right; }
.kbi-histo-acts .btn-xs + .btn-xs { margin-left: 4px; }
.kbi-histo-panel[hidden] { display: none !important; }
.kbi-histo-panel > td {
  background: var(--surface-2, #f8fafc);
  padding: 10px 12px;
  border-top: 0;
}

/* 👁 — faits de la version, en paires libellé/valeur alignées. */
.kbi-histo-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 14px;
  margin: 0;
  font-size: 12px;
}
.kbi-histo-facts dt {
  color: var(--muted);
  text-transform: uppercase;
  font-size: 10.5px;
  letter-spacing: 0.03em;
  font-weight: 700;
  padding-top: 1px;
}
.kbi-histo-facts dd { margin: 0; }

/* ✏️ — le pli d'édition empile : corriger / source / ↩ proposition / retirer. */
.kbi-histo-panel .kbi-ed-form-correct { margin-top: 0; }
.kbi-histo-src, .kbi-histo-revert, .kbi-histo-danger {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.kbi-histo-revert .btn-sm, .kbi-histo-danger .btn-sm { white-space: nowrap; }/* Le libellé du champ source reste collé à son dropdown (pas de flex qui
   pousserait le bouton à la ligne) ; seules les NOTES explicatives des deux
   gestes de retrait prennent la place restante. */
.kbi-histo-revert .muted, .kbi-histo-danger .muted { flex: 1 1 240px; }
.kbi-histo-src .ss-wrapper { width: 260px; }

/* ══════════════════════════════════════════════════════════════════════════
   Phase 98 pass A — MODE VALIDATION des extractions (page document)
   Side-by-side « Le document » ↔ « Ce qui en a été extrait ».
   Spec : maquette passA2-fiche-reelle.html (98-rapprochement-documentaire).
   ══════════════════════════════════════════════════════════════════════════ */

.dv-glyph { width: 15px; height: 15px; flex: 0 0 auto; }

/* La bande de séquençage (P1 : même grammaire que le stepper Rapprochement,
   palette --warn-soft / --warn-ink / bord --warn). Sur la page du doc il n'y a
   pas de toolbar à masquer : la bande S'AJOUTE, sticky. */
.dv-band { display: flex; align-items: center; gap: 14px; background: var(--warn-soft, #fef3c7);
  border: 1px solid var(--warn, #f59e0b); color: var(--warn-ink, #92400e); border-radius: 8px;
  padding: 9px 14px; margin: 0 0 16px; font-size: 13px; position: sticky; top: 8px; z-index: 30; }
.dv-band-title { font-weight: 700; }
.dv-band-sp { flex: 1; }
.dv-b { background: #fff; border: 1px solid var(--warn, #f59e0b); color: var(--warn-ink, #92400e);
  border-radius: 6px; padding: 4px 10px; font-size: 12.5px; cursor: pointer; text-decoration: none; }
.dv-b[aria-disabled="true"] { opacity: .45; cursor: default; }
.dv-tag { background: #eff6ff; border: 1px solid #bfdbfe; color: #1e40af; border-radius: 4px;
  padding: 1px 6px; font-size: 10.5px; font-weight: 600; }

/* ⚠ minmax(0,…) OBLIGATOIRE : `1fr` vaut `minmax(auto,1fr)` et `auto` >= min-content
   → un contenu large (tableau, <pre>) fait exploser la colonne HORS du conteneur
   .content (max-width:1200px) et écrase la voisine. Bug vu en revue le 17/07
   sur 24" ET 13" : ce n'était pas une histoire de taille d'écran. */
/* Phase 98-03 : largeurs UNIFIÉES page ↔ mode (1fr/1fr) — le panneau document
   est partagé (_doc_viewer_panel.html), le mode ne change que la colonne de
   données. */
.dv-sbs { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px; align-items: start; }
/* Sous 1100px (tablette 11"), le side-by-side est un mensonge : 2×500px ne
   montrent ni un document ni des extractions. On empile. */
@media (max-width: 1100px) { .dv-sbs { grid-template-columns: minmax(0, 1fr); } }

.dv-doc, .dv-reads { background: #fff; border: 1px solid var(--border, #e2e8f0); border-radius: 12px; }
.dv-doc { position: sticky; top: 60px; }

/* Phase 98-03 — PLI CANONIQUE de fiche : <details class="panel|dv-doc fold-panel">
   avec chevron ▸/▾ (glyphe de la Situation). Le triangle natif meurt — il
   disparaît de toute façon dès qu'un summary passe en flex. */
.fold-panel > summary { list-style: none; cursor: pointer; }
.fold-panel > summary::-webkit-details-marker { display: none; }
.fold-panel > summary::before { content: "▸"; color: var(--muted, #9ca3af);
  font-size: 13px; flex: 0 0 auto; margin-right: 2px; }
.fold-panel[open] > summary::before { content: "▾"; }
.fold-count { font-size: 12px; color: var(--muted, #6b7280); font-weight: 400; white-space: nowrap; }
/* Phase 98-06 — FICHE en fold-panels + sélecteur Vue. Une fiche a beaucoup de
   blocs : on décharge à l'ouverture (table des matières) ou on navigue à vue.
   PAS de bandeau bleu (R9 : le bleu = collection sommable) — chevron gris,
   Token 7. Barre Vue en tête ; 1er bloc ouvert par défaut. */
.fiche-vue-bar { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }
.fiche-vue-bar > label { font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; }
/* Le bloc `.panel.fiche-fold` : le h3 vit dans le summary (chevron ::before du
   fold-panel), le corps est le reste. Replié → seul le titre ; padding du panel
   conservé. */
details.fiche-fold > summary.fold-head { margin: 0; }
details.fiche-fold > summary.fold-head h3 { margin: 0; }
details.fiche-fold:not([open]) > summary.fold-head { margin-bottom: 0; }
/* Le segment « N à valider » du compteur replié porte le signal (P6) — orange AA. */
.fold-count .count-todo { color: var(--warn-ink, #92400e); font-weight: 700; }

/* ── Journal du traitement (pli de la fiche document) ────────────────────────
   Du détail technique volontairement discret : il ne doit jamais concurrencer
   les informations métier de la colonne (doctrine « le poids visuel suit
   l'ordre de lecture »). Le déroulé est borné en hauteur et défile. */
.doc-journal-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 8px 0 4px;
}
.doc-journal-step {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  background: var(--bg);
}
.doc-journal-step.is-failed {
  border-color: var(--error);
  color: var(--error);
  font-weight: 600;
}
.doc-journal-step-time { font-variant-numeric: tabular-nums; }

.doc-journal-lines {
  margin: 8px 0 0;
  padding: 10px 12px 10px 28px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--ink);
}
.doc-journal-lines li { margin: 0 0 2px; }
.doc-journal-stage {
  display: inline-block;
  min-width: 108px;
  margin-right: 8px;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.doc-journal-text { overflow-wrap: anywhere; }

.doc-journal-error {
  margin: 10px 0 0;
  padding: 10px 12px;
  background: #fde2e2;
  border: 1px solid #ef9a9a;
  border-radius: 8px;
  color: #9d2f2f;
  font-size: 13px;
}
.doc-journal-note { font-size: 12px; margin: 8px 0 0; }
/* ✏️ Modifier vit EN BAS du contenu déplié, jamais dans le summary. */
.fold-actions { display: flex; justify-content: flex-end; margin: 10px 0 2px; }
/* Phase 98-05 — rangée d'actions avec note discrète à gauche + boutons. */
.fold-actions--center { align-items: center; gap: 8px; }
/* Tampon de relecture : bouton CANONIQUE (.btn-edit.btn-sm porte la boîte),
   seule la couleur varie (variante warn) — retour maquette : même taille que
   le ✏️ Modifier voisin. */
.dmi-review-btn { border-color: #d97706; color: #92400e; background: #fff; }
.dmi-review-btn:hover { background: #fef3c7; border-color: #d97706; color: #92400e; }
/* « relues le … par … » = texte discret (jamais une pastille verte — RAS = rien). */
.dmi-reviewed-note { color: var(--muted, #6b7280); font-size: 11.5px;
  font-style: italic; margin-right: auto; }
/* Phase 98-attentes-peuplement (Lot B) — statut par champ. P6 : une seule
   alerte affichée, « à compléter » (attendu `toujours` resté vide). Chip orange
   AA (même famille --warn que le compteur replié). « néant » = déclaration
   assumée, jamais une alerte → texte discret gris (pas un chip). */
.dmi-todo {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  font-size: 11px; font-weight: 700; line-height: 1.5;
  color: var(--warn-ink, #92400e); background: var(--warn-soft, #fff3e0);
  border: 1px solid var(--warn, #b45a2f); border-radius: 999px; white-space: nowrap;
}
.dmi-neant { color: var(--muted, #6b7280); font-style: italic; }
/* Lot D — note interne : textarea pleine largeur dans le pli dédié. */
.dmi-note-textarea { width: 100%; box-sizing: border-box; resize: vertical;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px;
  font: inherit; font-size: 13px; }
/* Slot du pli « Autres informations » sous les cartes du mode validation. */
.dv-dmi-slot { margin-top: 14px; }
/* Footer de la page d'édition : « + Ajouter » à gauche, les 3 sorties à droite
   (primaire en dernier). Self-contained (pas .kbi-candidate-footer, chargé de
   règles KBI) → tous les boutons partagent la MÊME boîte (R11 : btn-new /
   btn-edit portent line-height:1). */
/* Phase 98-attentes-peuplement lot C — page d'édition = inventaire FERMÉ : le
   label est GRAVÉ par la taxo (lecture seule, pas un input), la valeur est
   corrigeable, une case « néant » par ligne. Plus de Supprimer/Ajouter.
   Le champ de valeur suit le TOKEN canonique `--toolbar-field-*` (celui de la
   toolbar Situation / éditeur KBI) — pas de style inline ad-hoc ; le label est
   centré verticalement sur la boîte de valeur (flex min-height = hauteur du
   champ ; les deux cellules démarrent au même y en vertical-align top). */
/* Table PLEINE LARGEUR : la colonne valeur prend tout l'espace restant (utile
   pour une réponse longue — adresse, prénoms multiples). Le label est une vraie
   cellule (JAMAIS `display:flex` sur un <td> — ça le sort du modèle de colonnes
   et écrase la largeur) : le flex de centrage vit sur un <span> INTERNE dont la
   min-height = hauteur du champ (les deux cellules démarrent au même y en
   vertical-align top → centres alignés). Label sur une seule ligne. */
/* Intro de la page d'édition : note discrète (la consigne, pas un titre). */
.dmi-edit-hint { font-size: 12px; color: var(--muted, #6b7280); margin: 4px 0 14px; }
/* « * » = champ attendu (`presence_expectation='toujours'`). Marqueur SOBRE
   (pas un chip P6) ; l'alerte « à compléter » n'apparaît, elle, que si vide. */
.dmi-req { color: var(--warn-ink, #92400e); font-weight: 700; }
.dmi-edit-table { width: 100%; }
.dmi-edit-table td { vertical-align: top; padding: 6px; }
.dmi-edit-label { width: 1%; white-space: nowrap; }
.dmi-edit-label-text { display: flex; align-items: center; min-height: 32px;
  font-weight: 600; color: var(--ink); font-size: 13px; }
.dmi-value-input { width: 100%; box-sizing: border-box; line-height: 1.4;
  padding: var(--toolbar-field-pad); border: 1px solid var(--line);
  border-radius: var(--toolbar-field-radius); font: inherit;
  font-size: var(--toolbar-field-fs); background: var(--bg); color: var(--ink); }
.dmi-value-input:focus { outline: 2px solid var(--accent-soft); outline-offset: 1px;
  border-color: var(--accent); }
.dmi-neant-toggle { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
  font-size: 12px; color: var(--muted, #6b7280); cursor: pointer; user-select: none; }
.dmi-neant-toggle input { margin: 0; cursor: pointer; }
/* Rangée « néant » : valeur estompée (elle ne compte plus), déclaration assumée. */
.dmi-row--absent .dmi-value-input { opacity: 0.5; background: var(--panel-alt, #f3f4f6); }
.dmi-row--absent .dmi-neant-toggle { color: var(--ink); font-weight: 600; }
.dmi-edit-add { margin-top: 16px; }
.dmi-edit-footer { display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; margin-top: 12px; padding-top: 14px; border-top: 1px solid var(--line); }
/* Libellés longs : jamais de wrap interne (sinon boîtes de hauteurs inégales, R11). */
.dmi-edit-footer .btn-edit, .dmi-edit-footer .btn-new { white-space: nowrap; }
/* « Annuler » = lien discret (pas un bouton) — sort sans écrire, jamais
   « Quitter » (ambigu). */
.dmi-cancel-link { color: var(--muted, #6b7280); font-size: 13px; text-decoration: none; }
.dmi-cancel-link:hover { color: var(--ink); text-decoration: underline; }
/* En-tête de pli : titre + spacer + compteur (le summary est en flex → le
   chevron ::before devient le 1er item de la rangée). */
.fold-head { display: flex; align-items: baseline; gap: 8px; }
.fold-head h3 { margin: 0; }
.fold-spacer { flex: 1; }

/* Phase 98-03 — page document : squelette famille document. GAUCHE = viewer
   partagé (.dv-doc) ; DROITE = pile de blocs repliables. */
.doc-page-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.page-h1-date { font-weight: 400; color: var(--muted, #6b7280); }
.page-subtitle { color: var(--muted, #6b7280); font-size: 13px; margin-top: 4px; }
.dv-doc-actions { display: flex; gap: 8px; padding: 10px 16px;
  border-top: 1px solid var(--border, #e2e8f0); }

/* Lignes du bloc « Informations extraites (N) » (page document). */
.ki-instance { color: var(--muted, #6b7280); font-size: 12px; font-weight: 400; }
.ki-carac { color: var(--muted, #6b7280); font-size: 11.5px; margin-top: 2px; font-weight: 400; }
.ki-cell { display: inline-flex; align-items: center; gap: 10px; justify-content: flex-end; }
.ki-val { font-variant-numeric: tabular-nums; min-width: 78px; text-align: right;
  font-weight: 600; white-space: nowrap; }
.ki-empty { font-weight: 400; color: var(--muted, #6b7280); }
.ki-date { color: var(--muted, #6b7280); font-size: 12px; min-width: 104px;
  white-space: nowrap; text-align: right; }
.ki-chip { border-radius: 10px; padding: 2px 10px; font-size: 11px; font-weight: 700;
  white-space: nowrap; min-width: 78px; text-align: center; text-decoration: none; }
.ki-chip--integrated { background: #dcfce7; color: #166534; }
.ki-chip--validated { background: #cffafe; color: #155e75; }
.ki-chip--todo { background: #fef3c7; color: #92400e; }
a.ki-chip--todo:hover { text-decoration: underline; }
/* Provenance d'une valeur = TEXTE DISCRET (P11), jamais une pill. */
.ki-prov { color: var(--muted, #6b7280); font-size: 11.5px; font-style: italic; }
.ki-foot { margin-top: 14px; font-size: 12px; }

/* Bascule « texte reconnu » du panneau document (page hors mode) — action
   discrète (token --action-quiet), remplace la défunte modale Preview OCR. */
.dv-toggle { background: none; border: none; padding: 0; font-size: 11.5px;
  color: var(--action-quiet, #4f6e92); cursor: pointer; }
.dv-toggle:hover { color: var(--accent, #2563a8); text-decoration: underline; }
/* ⚠ [hidden] battu par un display de classe (piège connu) : gardes explicites. */
.dv-text[hidden] { display: none !important; }
.dv-doc-body iframe[hidden], .dv-doc-body img[hidden] { display: none !important; }
.dv-doc-head, .dv-reads-head { padding: 12px 16px; border-bottom: 1px solid var(--border, #e2e8f0);
  display: flex; align-items: center; gap: 10px; }
.dv-doc-head h3, .dv-reads-head h3 { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .5px;
  color: var(--muted, #64748b); text-transform: uppercase; }
.dv-doc-body { height: 640px; overflow: auto; }
.dv-doc-body iframe { width: 100%; height: 100%; border: 0; display: block; }
.dv-prov { font-size: 11.5px; color: var(--muted, #64748b); margin-left: auto; }
.dv-warn-doc { background: #fef2f2; border-top: 1px solid #fecaca; color: #b91c1c;
  padding: 8px 16px; font-size: 12px; }

/* Zoom image : une photo d'avis fait 3024 px de large — « ajustée » dans un
   panneau de ~590 px elle est ILLISIBLE. Et un zoom sans déplacement ne sert à
   rien (macOS masque les barres de scroll) : cliquer-glisser obligatoire, et le
   zoom garde le CENTRE de la vue (doc_validation.js). */
.dv-zoom { display: flex; align-items: center; gap: 4px; margin-left: 10px; }
.dv-z { border: 1px solid var(--border, #cbd5e1); background: #fff; color: #334155;
  border-radius: 5px; width: 24px; height: 22px; font-size: 13px; line-height: 1; cursor: pointer; }
.dv-z.dv-z-fit { width: auto; padding: 0 8px; font-size: 11.5px; }
.dv-z[aria-pressed="true"] { background: var(--accent-soft, #eff6ff); border-color: var(--accent, #2563eb);
  color: var(--accent-ink, #1e40af); font-weight: 600; }
#dv-img.dv-grab { cursor: grab; }
#dv-doc-body.dv-grabbing #dv-img { cursor: grabbing; }
#dv-doc-body.dv-grabbing { user-select: none; }

/* Le texte : le HTML RENDU par l'app (ocr_content_html) — le CGP lit un
   document, jamais du markdown. Contenu tabulaire = overflow-x, jamais de wrap. */
.dv-text { padding: 18px 20px; font-size: 13px; line-height: 1.6; color: #334155; }
.dv-text table { width: 100%; border-collapse: collapse; margin: 10px 0 16px; font-size: 12px;
  display: block; overflow-x: auto; }
.dv-text th, .dv-text td { border: 1px solid var(--line, #e2e8f0); padding: 5px 7px;
  text-align: left; vertical-align: top; white-space: nowrap; }
.dv-text th { background: var(--accent-soft, #eff6ff); color: var(--accent-ink, #1e40af); font-weight: 700; }
.dv-text h1, .dv-text h2, .dv-text h3, .dv-text h4 { margin: 14px 0 6px; font-size: 13.5px; }
.dv-text p { margin: 6px 0; }

/* « Du jaune partout → j'ai mis du temps à retrouver le 1er item » (opérateur).
   Tout surligner = ne rien surligner : UNE marque à la fois, celle de
   l'extraction au FOCUS. */
.dv-text mark { background: #fde68a; color: #713f12; padding: 1px 3px; border-radius: 3px;
  outline: 2px solid #f59e0b; }
.dv-card.dv-active { background: #fffbeb; box-shadow: inset 3px 0 0 var(--warn, #f59e0b); }

/* La carte d'extraction. */
.dv-card { padding: 14px 16px; border-bottom: 1px solid var(--border, #e2e8f0); cursor: pointer; }
.dv-card:last-child { border-bottom: 0; }
.dv-card.dv-settled { opacity: .6; }
.dv-code { font-size: 12px; color: var(--muted, #64748b); }
.dv-sub { margin-top: 3px; }
.dv-label { font-size: 13.5px; font-weight: 600; color: #0f172a; margin-top: 1px; }
.dv-val { font-size: 19px; font-weight: 700; color: #0f172a; margin-top: 5px; }
.dv-meta { font-size: 12px; color: var(--muted, #64748b); margin-left: 8px; font-weight: 400; }
.dv-anchor { margin-top: 8px; padding: 7px 10px; background: #f8fafc; border-left: 3px solid #cbd5e1;
  border-radius: 0 4px 4px 0; font-size: 12px; color: #475569; }
.dv-anchor:hover { background: #f1f5f9; border-left-color: var(--accent, #2563eb); }
.dv-anchor-hint { color: #94a3b8; }
.dv-anchor-none { margin-top: 8px; font-size: 11.5px; color: #94a3b8; font-style: italic; }
.dv-warn-line { margin-top: 7px; font-size: 11.5px; color: #b91c1c; }

/* Actions — chaque action porte sur SA carte. */
.dv-acts { display: flex; gap: 7px; margin-top: 11px; flex-wrap: wrap; align-items: center; }
.dv-acts .inline-form { display: inline-flex; }
/* Les 3 actions sont de natures HTML différentes (2 <button>, « Corriger » =
   <summary>) : sans normaliser line-height + police + box-sizing, elles ne font
   pas la même hauteur. inline-flex centré + line-height fixe = même boîte. */
.dv-a { box-sizing: border-box; border-radius: 6px; padding: 5px 11px;
  font-size: 12.5px; font-family: inherit; line-height: 1.4; margin: 0; cursor: pointer;
  border: 1px solid var(--border, #cbd5e1); background: #fff; color: #334155;
  display: inline-flex; align-items: center; }
/* `.dv-a`'s display: inline-flex écrase la règle UA [hidden]{display:none} :
   sans ceci, un bouton .dv-a masqué par l'attribut `hidden` (ex. promotion en
   mode « Attendus ») reste visible. On rend `hidden` autoritaire. */
.dv-a[hidden] { display: none; }
.dv-a-ok { background: var(--accent, #1e40af); border-color: var(--accent, #1e40af); color: #fff; font-weight: 600; }
.dv-verdict { margin-top: 10px; font-size: 12.5px; font-weight: 600; }
.dv-verdict.ok { color: var(--success-ink, #166534); }
.dv-verdict.no { color: #b91c1c; }
.dv-verdict .inline-form { display: inline; }
.dv-undo { background: none; border: 0; color: var(--action-quiet, #4f6e92); font-size: 12px;
  cursor: pointer; text-decoration: underline; padding: 0; margin-left: 8px; }

/* ✏️ Corriger : pli inline (R6, jamais de modale). Le <summary> a l'habit d'un
   bouton d'action de carte. */
.dv-fix-fold { display: inline-block; }
.dv-fix-fold > summary { list-style: none; }
.dv-fix-fold > summary::-webkit-details-marker { display: none; }
.dv-fix { margin-top: 10px; padding: 11px; background: #f8fafc; border: 1px solid var(--border,#e2e8f0);
  border-radius: 8px; cursor: default; min-width: 280px; }
.dv-fix label { display: block; font-size: 11.5px; color: var(--muted,#64748b); margin-bottom: 3px; }
.dv-fix input { width: 100%; padding: 6px 8px; border: 1px solid var(--border,#cbd5e1);
  border-radius: 6px; font-size: 13px; margin-bottom: 8px; box-sizing: border-box; }
.dv-fix-note { font-size: 11.5px; color: var(--muted,#64748b); margin-bottom: 9px; }

/* Les ARCHIVES vivent dans des plis — patron pass B. La liste de travail ne
   montre QUE ce qui reste à faire : elle rétrécit à mesure qu'on avance. */
.dv-fold { border-top: 1px solid var(--border, #e2e8f0); }
.dv-fold > summary { padding: 10px 16px; cursor: pointer; font-size: 12.5px;
  color: var(--action-quiet, #4f6e92); list-style: none; }
.dv-fold > summary::-webkit-details-marker { display: none; }
.dv-fold > summary::before { content: '▸ '; }
.dv-fold[open] > summary::before { content: '▾ '; }
.dv-fold > summary:hover { background: #f8fafc; }
.dv-done-all { padding: 26px 20px; text-align: center; font-size: 13px;
  color: var(--success-ink, #166534); background: var(--success-soft, #dcfce7); }
.dv-empty { padding: 30px 20px; text-align: center; color: var(--muted,#64748b); font-size: 13px; }

/* Geste (a) — « ＋ Ajouter une information lue » (bas de la colonne extractions). */
.dv-add { border-top: 1px solid var(--border, #e2e8f0); }
.dv-add > summary { padding: 12px 16px; cursor: pointer; font-size: 12.5px;
  font-weight: 600; color: var(--accent, #1e40af); list-style: none; }
.dv-add > summary::-webkit-details-marker { display: none; }
.dv-add > summary:hover { background: #f8fafc; }
.dv-add-form { padding: 4px 16px 16px; display: flex; flex-direction: column; gap: 4px; }
.dv-add-form label { font-size: 11.5px; color: var(--muted, #64748b); margin-top: 6px; }
.dv-add-form .dv-add-opt { font-weight: 400; opacity: .8; }
.dv-add-form select, .dv-add-form input { padding: 7px 9px; border: 1px solid var(--border, #cbd5e1);
  border-radius: 6px; font-size: 13px; width: 100%; box-sizing: border-box; }
.dv-add-scope { display: flex; gap: 16px; margin: 2px 0 8px; }
.dv-add-scope label { display: inline-flex; align-items: center; gap: 5px; margin: 0;
  font-size: 12px; color: var(--ink, #334155); cursor: pointer; }
.dv-add-scope input { width: auto; }
.dv-add-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.dv-add-form .dv-add-actions button { margin-top: 0; }
/* Geste (b) = OPTION de l'ajout : case à cocher (décochée par défaut) au-dessus
   du bouton, mode « tous les codes » seulement. `[hidden]` autoritaire (spécificité
   classe+attribut > classe). */
.dv-add-promote { display: flex; align-items: flex-start; gap: 7px; margin: 12px 0 0;
  padding: 9px 11px; border-radius: 7px; background: #fffbf5; border: 1px solid #fde3c4;
  font-size: 12px; color: #9a3412; line-height: 1.45; cursor: pointer; }
.dv-add-promote[hidden] { display: none; }
.dv-add-promote input { width: auto; margin: 2px 0 0; flex: none; }
.dv-add-hint { margin: 10px 0 0; font-size: 11px; color: var(--muted, #64748b); line-height: 1.5; }

/* « Relancer l'extraction » (édition) — chaque aide est COLLÉE à sa case (le
   <p> suit sa case dans le DOM), la respiration est AVANT le titre suivant.
   Le 1er hint est l'intro générale du fieldset (sous la légende). */
.reprocess-fieldset .reprocess-checkbox { display: block; margin-top: 15px; }
.reprocess-fieldset .reprocess-hint { margin: 3px 0 0; }


/* ── Phase 106-02 — panneau « À résoudre » du formulaire réimporté ─────────
   Grille de champs CANONIQUES (.form-group) : mêmes boîtes que le reste du
   site ; la catégorie (searchable) est assez large pour rester lisible. */
.form-res-grid {
  display: grid;
  grid-template-columns: minmax(200px, 1.1fr) minmax(200px, 1.6fr) minmax(150px, 1.1fr)
    minmax(100px, 0.7fr) minmax(115px, 0.8fr) minmax(115px, 0.8fr) auto;
  gap: 14px 16px;
  align-items: end;
}
.form-res-grid .form-group { margin: 0; min-width: 0; }
.form-res-grid .form-group label {
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.form-res-apply { display: inline-flex; align-items: center; gap: 6px;
  font-weight: 600; white-space: nowrap; padding-bottom: 10px; }
@media (max-width: 1200px) {
  .form-res-grid { grid-template-columns: 1fr 1fr; }
  .form-res-grid .form-group label { white-space: normal; overflow: visible; }
}

/* Phase 100 (retour opérateur 2026-10-22) — formulaire de création d'un
   client : blocs « Personne » / « Conjoint » / « Foyer » et pli
   « + Ajouter un conjoint » (summary = action discrète, --action-quiet). */
.form-section-title {
  font-size: 13px;
  font-weight: 700;
  margin: 18px 0 10px;
  color: var(--ink);
}
.form-section-title:first-of-type { margin-top: 0; }
.form-fold { margin: 4px 0 6px; }
.form-fold > summary { list-style: none; display: inline-block; font-size: 13px; font-weight: 600; }
.form-fold > summary::-webkit-details-marker { display: none; }
.form-fold[open] > summary { display: none; }
.form-fold-body {
  border-left: 3px solid var(--line);
  padding-left: 14px;
  margin: 6px 0 4px;
}
.form-check { display: flex; align-items: center; gap: 8px; font-weight: 600; }

/* Phase 107 : glyphe « remettre en proposition » de l'historique. */
.kbi-histo-revert .revert-icon { height: 12px; width: auto; margin-right: 3px; vertical-align: -2px; }

/* Phase 107 : traitement des documents à l'arrêt pour tous (bandeau global). */
.ingest-blocker-banner {
  border-left: 4px solid #b91c1c; background: #fef2f2; color: #7f1d1d;
  padding: 12px 16px; border-radius: 8px; margin: 0 0 16px; font-size: 14px; line-height: 1.45;
}
.ingest-blocker-admin { display: block; margin-top: 4px; font-size: 13px; color: #991b1b; }

/* Phase 129 (DP6) — bandeau permanent de l'instance de démonstration publique
   (rendu seulement quand l'application `demo/` est chargée). */
.demo-banner {
  border-left: 4px solid #b45309; background: #fffbeb; color: #78350f;
  padding: 10px 16px; border-radius: 8px; margin: 0 0 16px; font-size: 14px; line-height: 1.45;
}
.login-box .demo-banner { margin: 0 0 14px; text-align: left; }
.demo-terms h2 { font-size: 20px; margin: 0 0 8px; }
.demo-terms h3 { font-size: 16px; margin: 16px 0 6px; }
.demo-terms blockquote, .demo-terms p { margin: 0 0 10px; }
.demo-terms ul { margin: 0 0 10px 18px; }

/* Phase 107 (D20) — pli « Informations patrimoniales extraites » de la fiche :
   une proposition se décide sur sa ligne (Intégrer… / Ignorer), le paquet en
   tête du groupe, les ignorées dans un sous-pli restaurable. */
.ki-group-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ki-group-head .key-info-subcategory { flex: 1 1 auto; }
.ki-group-acts { display: inline-flex; gap: 8px; align-items: center; }
.ki-acts { display: inline-flex; gap: 8px; align-items: center; margin-left: 6px; }
.ki-ignored { margin-top: 10px; }
.ki-ignored > summary { cursor: pointer; font-size: 12px; font-weight: 600; color: var(--muted, #64748b); }

/* Phase 107 (D22) — résumé de la concordance sur le Tableau de bord du client :
   un bloc, un lien ; la décision vit sur la page Concordance (Situation). */
.concordance-summary { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.concordance-summary-title { font-weight: 700; margin-bottom: 2px; }

/* Panneau du chat (menu « IA », 2026-10-29) — primitive documentée dans
   docs/DESIGN-SYSTEM.md. Fixe à droite sous la barre du haut ; la page se
   décale de sa largeur (on garde la fiche sous les yeux) ; « agrandir » le
   passe sur toute la largeur ; plein écran d'office sur un téléphone. */
.pat-chat-drawer {
  position: fixed; top: 56px; right: 0; bottom: 0;
  width: var(--pat-chat-w, 440px);
  z-index: 45;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-left: 1px solid #e2e8f0;
  box-shadow: -4px 0 16px rgba(15, 23, 42, 0.06);
}
.pat-chat-drawer[hidden] { display: none; }
.pat-chat-drawer.is-expanded { left: 0; width: auto; }
.pat-chat-drawer.is-resizing .pat-chat-frame { pointer-events: none; }
.pat-chat-drawer.is-resizing { user-select: none; }
body.pat-chat-open .content { margin-right: var(--pat-chat-w, 440px); }
body.pat-chat-open.nav-open .content { margin-right: var(--pat-chat-w, 440px); }
.pat-chat-resize {
  position: absolute; left: -4px; top: 0; bottom: 0; width: 8px;
  cursor: col-resize; z-index: 1;
}
.pat-chat-resize:hover, .pat-chat-drawer.is-resizing .pat-chat-resize { background: rgba(37, 99, 168, 0.18); }
.pat-chat-drawer.is-expanded .pat-chat-resize { display: none; }
.pat-chat-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 8px 14px; font-size: 14px;
  /* Même bande que la barre du haut, séparée d'elle par un liseré clair
     (le panneau commence juste sous la barre : sans liseré, les deux
     fusionneraient en un seul bloc). */
  background: var(--brand); color: var(--on-brand);
  border-top: 1px solid rgba(247, 245, 241, 0.28);
  border-bottom: 1px solid rgba(247, 245, 241, 0.28);
}
.pat-chat-head .muted { color: var(--on-brand-muted); }
.pat-chat-ctx { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.pat-chat-actions { margin-left: auto; display: inline-flex; gap: 4px; flex: none; }
.pat-chat-btn {
  /* Même patron que le bouton retour (`.page-nav-back`) : carré bordé, gris
     atténué, accent au survol. */
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--header-ctl-h); height: var(--header-ctl-h); padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: none; cursor: pointer;
  color: var(--muted); text-decoration: none; line-height: 1;
}
.pat-chat-btn:hover { color: var(--accent); border-color: var(--accent); background: var(--panel); }
.pat-chat-head .pat-chat-btn { color: var(--on-brand-muted); border-color: rgba(247, 245, 241, 0.28); }
.pat-chat-head .pat-chat-btn:hover { color: var(--on-brand); border-color: var(--on-brand); background: rgba(247, 245, 241, 0.1); }
.pat-chat-ico { flex: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.pat-chat-drawer .ico-collapse,
.pat-chat-drawer.is-expanded .ico-expand { display: none; }
.pat-chat-drawer.is-expanded .ico-collapse { display: block; }
.pat-chat-stale {
  padding: 8px 14px; font-size: 13px; background: #fffbeb; border-bottom: 1px solid #fde68a;
}
.pat-chat-stale[hidden] { display: none; }
.pat-chat-reload {
  border: 1px solid #d97706; background: #fff; color: #92400e; border-radius: 6px;
  padding: 2px 8px; cursor: pointer; font-size: 13px;
}
.pat-chat-frame { flex: 1; width: 100%; border: 0; background: var(--bg); }
@media (max-width: 768px) {
  .pat-chat-drawer { left: 0; width: auto; }
  .pat-chat-resize, #pat-chat-expand { display: none; }
  body.pat-chat-open .content { margin-right: auto; }
}

/* Réponse de l'assistant en Markdown simple (chat, panneau et page). */
.speak-md p { margin: 0 0 8px; }
.speak-md p:last-child, .speak-md ul:last-child, .speak-md ol:last-child { margin-bottom: 0; }
.speak-md ul, .speak-md ol { margin: 0 0 8px; padding-left: 20px; }
.speak-md li { margin: 2px 0; }
.speak-md code { font-size: 0.92em; background: rgba(15, 23, 42, 0.06); padding: 0 3px; border-radius: 3px; }
.speak-md a { color: var(--accent, #2563a8); text-decoration: underline; }

/* Plis d'une réponse de l'assistant : Réflexion, Outils utilisés (le travail,
   masqués par défaut — case « Afficher la réflexion et les outils »), Sources
   lues (toujours visibles). Hauteur bornée : un pli ouvert ne repousse jamais
   la réponse hors de vue. */
.speak-fold { font-size: 12px; color: #6b7280; margin: 0 0 6px; }
.speak-fold-sources { margin: 8px 0 0; }
.speak-fold > summary { cursor: pointer; outline: none; }
.speak-fold-body { padding: 6px 0; line-height: 1.6; max-height: 220px; overflow-y: auto; }
.speak-fold-reasoning .speak-fold-body { white-space: pre-wrap; color: #94a3b8; }
.speak-fold-sources ul { margin: 0; padding-left: 18px; }
.speak-fold-sources a { color: var(--accent, #2563a8); }
#speak-messages.hide-work .speak-fold-work { display: none; }
/* Trois points qui pulsent dans la bulle tant que l'agent travaille : la
   réponse arrive (réflexion et outils peuvent être masqués). */
.speak-typing { display: inline-flex; gap: 4px; padding: 4px 0; }
.speak-typing span { width: 6px; height: 6px; border-radius: 50%; background: #94a3b8; animation: speak-typing 1.2s infinite ease-in-out; }
.speak-typing span:nth-child(2) { animation-delay: .15s; }
.speak-typing span:nth-child(3) { animation-delay: .3s; }
@keyframes speak-typing { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

.speak-no-read { font-size: 11px; color: #92400e; margin-top: 6px; }
.speak-no-read::before { content: '⚠ '; }

/* Séparation « Vous êtes maintenant sur … » : changement de page entre deux
   messages du chat. */
.speak-note.speak-note-context { border-style: solid; background: #f1f5f9; font-weight: 500; }

/* Confirmation dans la page (confirm_inline.js, R3) : la question remplace le
   bouton sur la même ligne — pas de modale (R6). */
.pat-confirm { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 6px 10px;
  border: 1px solid #f0b4b4; border-radius: 6px; background: #fdf2f2; color: #7f1d1d; font-size: 13px; }
.pat-confirm-msg { max-width: 60ch; }
.pat-confirm-yes { background: #b91c1c; color: #fff; border: 0; border-radius: 5px; padding: 5px 12px; cursor: pointer; font: inherit; }
.pat-confirm-yes:hover { background: #991b1b; }
.pat-confirm-no { background: transparent; color: #7f1d1d; border: 1px solid #e5a3a3; border-radius: 5px; padding: 4px 10px; cursor: pointer; font: inherit; }
