/* =====================================================================
   styles.css — palette, typographie, écrans.
   Polices embarquées dans /fonts. Aucune ressource externe.
   ===================================================================== */

@font-face {
  font-family: 'Newsreader';
  src: url('fonts/Newsreader-Variable.ttf') format('truetype');
  font-weight: 200 800;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Newsreader';
  src: url('fonts/Newsreader-Italic-Variable.ttf') format('truetype');
  font-weight: 200 800;
  font-style: italic;
  font-display: block;
}
@font-face {
  font-family: 'Public Sans';
  src: url('fonts/PublicSans-Variable.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Public Sans';
  src: url('fonts/PublicSans-Italic-Variable.ttf') format('truetype');
  font-weight: 100 900;
  font-style: italic;
  font-display: block;
}

:root {
  --pierre: #EAE6E0;
  --surface: #FFFFFF;
  --encre: #1F2428;
  --olivier: #3F5245;
  --trait: #A39C8E;
  --ocre: #B07D2B;
  --rouge-profond: #8E2C24;

  --encre-2: #5B6166;          /* texte secondaire, contraste AA sur blanc */
  --olivier-clair: #E4E8E2;    /* fond léger pour l'état actif */
  --ocre-clair: #F4EBDB;
  --ocre-texte: #85601F;      /* ocre assombri pour le texte, contraste AA */
  --rouge-clair: #F3E4E2;
  --pierre-sombre: #E2DED8;

  /* Deux hairlines plus douces que --trait : la séparation intérieure d'un
     panneau n'a pas à peser autant que son contour. */
  --trait-doux: #B9B3A7;
  --trait-fin: #AFA89B;

  /* Ombres chaudes, jamais grises : le papier ne porte pas d'ombre bleue.
     Le premier terme est un liseré d'un pixel posé DANS l'ombre : il donne à
     chaque surface un bord net sans rouvrir le contour « 1px solid » que le
     système s'interdit — il vaut 5 % de noir chaud, il se voit sans se lire.
     C'est lui qui encadre, d'un coup, tous les composants de tous les écrans. */
  --ombre-1: 0 0 0 1px rgba(58, 48, 33, 0.055), 0 1px 1px rgba(58, 48, 33, 0.04), 0 3px 14px -5px rgba(58, 48, 33, 0.10);
  --ombre-2: 0 0 0 1px rgba(58, 48, 33, 0.07), 0 1px 2px rgba(58, 48, 33, 0.05), 0 14px 36px -18px rgba(58, 48, 33, 0.22);
  --geste: 160ms cubic-bezier(0.4, 0, 0.2, 1);

  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --sans: 'Public Sans', 'Segoe UI', Arial, sans-serif;

  /* Un seul rail : l'en-tête et la page partagent ce bord gauche. */
  --mesure: 1560px;
  --marge: clamp(22px, 3.4vw, 60px);
  --rail: max(var(--marge), (100% - var(--mesure)) / 2 + var(--marge));

  --largeur-legende: 250px;

  /* Le chevron des menus et des listes : dessiné, jamais celui du système.
     Il vit sur :root parce que les listes déroulantes ne sont pas toutes
     dans l'en-tête — le formulaire « Nouvelle bible » en porte une. */
  --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' fill='none' stroke='%235B6166' stroke-width='1.2'/%3E%3C/svg%3E");
  --chevron-haut: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 6l4.5-4.5L10 6' fill='none' stroke='%231F2428' stroke-width='1.4'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }
/* Le rail reste collé en haut : une ancre visée doit s'arrêter en dessous de
   lui plutôt que de se glisser derrière. */
html { font-size: 16px; scroll-padding-top: 74px; }
body {
  margin: 0;
  /* Le fond n'est pas un aplat : la lumière tombe du haut, comme sur du papier. */
  background: var(--pierre);
  background-image: linear-gradient(178deg, #F2EFEA 0%, var(--pierre) 32%);
  background-attachment: fixed;
  color: var(--encre);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
::selection { background: var(--olivier-clair); color: var(--encre); }
a { color: inherit; text-decoration: none; transition: color var(--geste); }
a:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
b, strong { font-weight: 600; }
h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 480;
  margin: 0;
  line-height: 1.14;
  letter-spacing: -0.012em;
  font-optical-sizing: auto;
}

/* Le surtitre : capitales étroites et espacées, la seule graisse haute du sans. */
.surtitre {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--encre-2);
}
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--olivier); outline-offset: 2px; }
.num, .id, dd, .statut-compte, .frise-fin, .journal-date, output, .brouillon-champ, .chiffres-liste { font-variant-numeric: tabular-nums; }
.secondaire { color: var(--encre-2); }
.vide { color: var(--encre-2); font-style: italic; }
.note { color: var(--encre-2); margin: 12px 0 0; font-size: 0.95rem; }

/* ---------- Structure ---------- */
.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 0;
  min-height: 100vh;
}
.app.assistant-ouvert { grid-template-columns: minmax(0, 1fr) 440px; }
.app > .principal { min-width: 0; }

.bouton {
  background: var(--surface);
  border: 1px solid var(--encre);
  border-radius: 0;
  padding: 8px 16px;
  cursor: pointer;
  line-height: 1.25;
  font-size: 0.95rem;
  letter-spacing: 0.012em;
  transition: background var(--geste), color var(--geste), border-color var(--geste), box-shadow var(--geste);
}
.bouton:hover { background: var(--encre); color: var(--pierre); }
.bouton:active { box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.16); }
.bouton-principal { background: var(--olivier); border-color: var(--olivier); color: #fff; }
.bouton-principal:hover { background: #33422F; border-color: #33422F; color: #fff; }
.bouton-petit { padding: 5px 11px; font-size: 0.9rem; }
.bouton[disabled] { opacity: 0.4; cursor: not-allowed; }
.bouton[disabled]:hover { background: var(--surface); color: inherit; }
#bouton-assistant[aria-expanded="true"] { background: var(--olivier); border-color: var(--olivier); color: #fff; }

/* Même rail que l'en-tête, et de l'air en bas : une page de dossier ne
   s'arrête pas au dernier pixel de contenu. */
main { padding: 44px var(--rail) 120px; }

.ecran-entete { margin-bottom: 30px; max-width: 92ch; }
.titre-ecran { font-size: clamp(2rem, 1.5rem + 1.5vw, 2.85rem); letter-spacing: -0.019em; }
.chapeau {
  margin: 14px 0 0; color: var(--encre-2);
  font-size: 1.08rem; line-height: 1.55; max-width: 74ch;
}
.chapeau .statut { color: var(--encre); white-space: nowrap; }

/* Une section s'ouvre par un filet fin et beaucoup d'air, pas par une boîte. */
.bloc { margin-top: 56px; padding-top: 24px; border-top: 1px solid var(--trait-doux); }
.bloc:first-child { margin-top: 0; }
.titre-bloc { font-size: 1.42rem; margin-bottom: 18px; }

/* ---------- Tableaux ---------- */
/* Un tableau se nomme pour qui ne le voit pas : le <caption> porte la phrase,
   le <h3> au-dessus la redit à l'œil. Le cacher évite de l'écrire deux fois. */
table caption {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
/* Pas de contour : une surface posee sur la pierre, tenue par son ombre.
   Les filets ne separent plus que les lignes entre elles. */
table.donnees {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  box-shadow: var(--ombre-1);
}
table.donnees th, table.donnees td { padding: 13px 18px; text-align: left; vertical-align: top; }
table.donnees th {
  font-weight: 600; color: var(--olivier);
  border-bottom: 1px solid var(--olivier);
  font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase;
  padding-top: 15px; padding-bottom: 11px; white-space: nowrap;
}
table.donnees td { border-bottom: 1px solid var(--trait-fin); }
table.donnees tbody tr:last-child td { border-bottom: none; }
table.donnees .num { text-align: right; white-space: nowrap; }
table.donnees th.num { text-align: right; }
table.donnees .id { white-space: nowrap; font-weight: 500; }
table.donnees tfoot td { border-top: 1px solid var(--olivier); border-bottom: none; font-weight: 600; background: #F8F6F3; }
table.donnees tr.cliquable { cursor: pointer; }
table.donnees tr.cliquable td { transition: background var(--geste); }
table.donnees tr.cliquable:hover td { background: var(--olivier-clair); }
table.donnees td.cause { max-width: 52ch; color: var(--encre-2); }
.tableau-risques tbody td { padding-top: 17px; padding-bottom: 17px; }

/* ---------- Les listes déroulantes ----------
   Une liste du système arrive bleue, arrondie, en police du système : trois
   écarts avec tout le reste, dans la fenêtre où l'on démontre. Le bouton
   fermé se tient donc comme les autres surfaces du projet — arêtes vives,
   ombre chaude, chevron dessiné. Seule la liste ouverte reste au système. */
select {
  appearance: none; -webkit-appearance: none;
  font: inherit; color: var(--encre);
  border: 0; border-radius: 0;
  padding: 9px 34px 9px 13px;
  background: var(--surface) var(--chevron) no-repeat right 12px center;
  box-shadow: var(--ombre-1);
  cursor: pointer; max-width: 100%;
}
select:focus-visible { outline: 2px solid var(--olivier); outline-offset: 2px; }

/* ---------- Pastilles de statut ---------- */
.statut { display: inline; }
.statut i { display: inline-block; width: 10px; height: 10px; margin-right: 8px; border: 1px solid var(--olivier); background: transparent; vertical-align: 0; }
.statut em { font-style: normal; color: var(--encre-2); }
.statut.s-commande i { background: transparent; }
.statut.s-expedie i { background: linear-gradient(90deg, var(--olivier) 50%, transparent 50%); }
.statut.s-livre-en-reserve i { background: var(--ocre); border-color: var(--ocre); }
.statut.s-controle-conforme i { background: var(--ocre-clair); border-color: var(--ocre); }
.statut.s-installe i { background: var(--olivier); }
.statut.s-cloture i { background: var(--encre); border-color: var(--encre); }
.statut.s-en-retard i { background: var(--ocre); border-color: var(--ocre); border-radius: 50%; }
.statut.s-en-circuit i { background: var(--ocre-clair); border-color: var(--ocre); }

.risque {
  display: inline-block;
  color: var(--rouge-profond);
  border: 1px solid var(--rouge-profond);
  padding: 2px 9px;
  font-size: 0.86rem; font-weight: 600; letter-spacing: 0.02em;
  white-space: nowrap;
}
tr.ligne-risque td:first-child { box-shadow: inset 3px 0 0 var(--rouge-profond); }

/* ---------- Écran 1 : frise ---------- */
.frise-bloc { border-top: none; padding-top: 0; }
.frise {
  position: relative;
  background: var(--surface);
  box-shadow: var(--ombre-1);
  padding: 0 28px 10px 0;
}
.frise-axe, .frise-ligne { display: grid; grid-template-columns: var(--largeur-legende) minmax(0, 1fr); }
.frise-axe { height: 60px; border-bottom: 1px solid var(--trait-doux); }
.frise-legende { padding: 13px 20px; display: flex; flex-direction: column; justify-content: center; gap: 3px; border-right: 1px solid var(--trait-fin); }
.frise-legende a { line-height: 1.25; }
.frise-legende span { color: var(--encre-2); font-size: 0.95rem; }
.frise-cadre { color: var(--encre-2); font-size: 0.95rem; }
.frise-piste { position: relative; min-height: 64px; }
.frise-piste::before, .frise-piste::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 0;
}
.frise-piste::before { left: var(--aujourdhui); border-left: 1px dashed var(--encre-2); }
.frise-piste::after { left: var(--reouverture); border-left: 3px solid var(--encre); margin-left: -1px; }
.frise-piste-axe { min-height: 0; height: 100%; }
.frise-piste-axe::before, .frise-piste-axe::after { top: 50px; }
.frise-mois {
  position: absolute; top: 32px; transform: translateX(-50%);
  font-size: 0.85rem; color: var(--encre-2);
}
.frise-mois::before { content: ''; position: absolute; top: -8px; left: 50%; height: 6px; border-left: 1px solid var(--trait); }
.frise-etiquette {
  position: absolute; top: 6px; font-size: 0.9rem; white-space: nowrap; padding: 1px 6px; background: var(--surface);
}
.etiquette-aujourdhui { transform: translateX(-100%); color: var(--encre-2); text-align: right; }
.etiquette-reouverture { transform: translateX(-100%); font-weight: 600; color: var(--encre); text-align: right; padding-right: 8px; }
/* La butée avancée par la marge de mise en scène. Repérée sur l'axe seul :
   un second trait dans les pistes entrerait en conflit avec « aujourd'hui ». */
.etiquette-butee {
  transform: translateX(-100%); text-align: right; padding-right: 8px;
  color: var(--ocre-texte); font-weight: 600;
  border-bottom: 2px dashed var(--ocre);
}
.frise-corps .frise-ligne { border-bottom: 1px solid var(--trait-fin); }
.frise-corps .frise-ligne:last-child { border-bottom: none; }
.frise-barre {
  position: absolute; top: 50%; height: 16px;
  transform: translateY(-50%) scaleX(0);
  transform-origin: left center;
  transition: transform 1.3s cubic-bezier(0.2, 0.7, 0.15, 1);
  transition-delay: calc(var(--i) * 0.18s + 0.2s);
}
.frise.deployee .frise-barre { transform: translateY(-50%) scaleX(1); }
.frise.deja-jouee .frise-barre { transition: none; }
/* Chaque bande est un bouton : elle se survole, se cible au clavier et
   ouvre sa fiche. Tout ce qu'un bouton apporte de natif est remis à plat,
   les fonds de .seg ci-dessous reprennent la main. */
.frise-barre .seg {
  position: absolute; top: 0; bottom: 0; display: block;
  -webkit-appearance: none; appearance: none;
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; min-width: 4px; cursor: pointer;
}
/* La bande ne fait que 16 px de haut : on lui donne une prise plus large
   que ce qu'elle montre, sinon elle se dérobe sous le curseur. */
.frise-barre .seg::after { content: ''; position: absolute; top: -10px; bottom: -10px; left: 0; right: 0; }
.frise-barre .seg:focus-visible { outline: 2px solid var(--olivier); outline-offset: 3px; }
.frise-barre .seg.montree { box-shadow: 0 0 0 2px var(--encre); }
.frise-barre .seg.etape.montree { box-shadow: inset 1px 0 0 #fff, 0 0 0 2px var(--encre); }
.seg.attente { background: repeating-linear-gradient(135deg, var(--trait) 0 3px, transparent 3px 8px); border: 1px solid var(--trait); }
.seg.delai { background: var(--olivier-clair); border: 1px solid var(--trait); }
.seg.etape { background: var(--olivier); box-shadow: inset 1px 0 0 #fff; }
.seg.depassement {
  background: var(--rouge-profond);
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.55) 0 2px, transparent 2px 6px);
}
.frise-fin {
  position: absolute; top: 50%; transform: translateY(-50%);
  margin-left: 10px; white-space: nowrap; font-size: 0.95rem; color: var(--encre-2);
  opacity: 0; transition: opacity 0.4s ease;
  transition-delay: calc(var(--i) * 0.18s + 1.4s);
}
.frise-fin b { color: var(--rouge-profond); }
.frise.deployee .frise-fin { opacity: 1; }
.frise.deja-jouee .frise-fin { transition: none; }
.frise-lecture { color: var(--encre-2); margin: 10px 0 0; font-size: 0.95rem; }
.frise-geste { color: var(--encre-2); margin: 4px 0 0; font-size: 0.88rem; font-style: italic; }
.frise-corps .frise-ligne:hover { background: #FBFAF8; }

/* ---------- Écran 1 : la fiche d'une bande ----------
   Une feuille posée sur la frise, pas une bulle : mêmes arêtes vives et
   même ombre chaude que les autres surfaces. */
.fiche-frise {
  position: absolute; z-index: 6;
  width: 340px; max-width: calc(100% - 16px);
  padding: 13px 16px 14px;
  background: var(--surface);
  box-shadow: var(--ombre-2);
  border-top: 2px solid var(--olivier);
  pointer-events: none;
}
.fiche-frise.epinglee { pointer-events: auto; border-top-color: var(--encre); }
.fiche-frise-genre {
  margin: 0; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--encre-2);
}
.fiche-frise-titre {
  margin: 3px 0 9px; font-family: 'Newsreader', Georgia, serif;
  font-size: 1.15rem; line-height: 1.2; color: var(--encre);
}
.fiche-frise-liste {
  margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: 3px 14px; font-size: 0.9rem;
}
.fiche-frise-liste dt { color: var(--encre-2); white-space: nowrap; }
.fiche-frise-liste dd { margin: 0; color: var(--encre); }
/* D'où sort la date : livraison constatée, date annoncée, délai calculé.
   La démonstration tient sur cette transparence-là, pas sur la date seule. */
.fiche-frise-precision { display: block; color: var(--encre-2); font-size: 0.82rem; line-height: 1.35; }
.fiche-frise-note {
  margin: 10px 0 0; padding-left: 9px; font-size: 0.9rem;
  color: var(--rouge-profond); border-left: 2px solid var(--rouge-profond);
}
.fiche-frise-lien { display: inline-block; margin-top: 11px; font-size: 0.9rem; font-weight: 600; }
.fiche-frise-epingle {
  margin: 9px 0 0; padding-top: 8px; border-top: 1px solid var(--trait-fin);
  font-size: 0.82rem; color: var(--encre-2);
}

/* ---------- Écran 1 : chiffres ---------- */
.chiffres-liste {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin: 0;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.chiffres-liste > div { padding: 22px 26px 24px; border-right: 1px solid var(--trait-fin); display: flex; flex-direction: column; gap: 0; }
.chiffres-liste > div:last-child { border-right: none; }
.chiffres-liste dt {
  color: var(--encre-2);
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
}
.chiffres-liste dd {
  margin: 13px 0 8px; font-family: var(--serif);
  font-size: clamp(2rem, 1.4rem + 1.1vw, 2.6rem); font-weight: 400;
  line-height: 1; letter-spacing: -0.022em;
}
.chiffres-liste small { color: var(--encre-2); font-size: 0.9rem; line-height: 1.4; }

/* ---------- Écran 1 : statuts ---------- */
.statuts { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px; align-items: start; }
.statuts-sequence {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(6, 1fr);
  background: var(--surface); box-shadow: var(--ombre-1);
}
.statut-case { padding: 18px 20px; border-right: 1px solid var(--trait-fin); position: relative; }
.statut-case:last-child { border-right: none; }
.statut-case::after { content: ''; position: absolute; right: -6px; top: 26px; width: 0; height: 0; border: 5px solid transparent; border-left-color: var(--trait); z-index: 1; }
.statut-case:last-child::after { display: none; }
.statut-compte { display: block; font-family: var(--serif); font-size: 1.95rem; font-weight: 400; line-height: 1.05; letter-spacing: -0.02em; }
.statut-case.zero .statut-compte { color: var(--encre-2); }
.statut-libelle { display: block; margin-top: 4px; }
.statuts-accolades { grid-column: 1; display: grid; grid-template-columns: repeat(6, 1fr); margin-top: -18px; font-size: 0.9rem; color: var(--encre-2); }
.accolade { border-top: 1px solid var(--olivier); padding-top: 4px; margin: 0 12px; text-align: center; }
.accolade-2 { grid-column: 3 / span 2; }
.accolade-4 { grid-column: 5 / span 2; }
.statuts-hors { grid-column: 2; grid-row: 1; list-style: none; margin: 0; padding: 0; display: grid; gap: 0; box-shadow: var(--ombre-1); background: var(--surface); }
.statuts-hors li { padding: 13px 20px; display: flex; align-items: baseline; gap: 14px; border-bottom: 1px solid var(--trait-fin); }
.statuts-hors li:last-child { border-bottom: none; }
.statuts-hors .statut-compte { font-size: 1.5rem; min-width: 1.4em; }
.statuts-hors li.zero .statut-compte { color: var(--encre-2); }

/* ---------- Écran 1 : à traiter ---------- */
.a-traiter { list-style: none; margin: 0; padding: 0; background: var(--surface); box-shadow: var(--ombre-1); }
.a-traiter-item { border-bottom: 1px solid var(--trait-fin); }
.a-traiter-item:last-child { border-bottom: none; }
.a-traiter-item a { display: grid; grid-template-columns: 3px 1fr; gap: 18px; padding: 16px 20px; transition: background var(--geste); }
.a-traiter-item a:hover { background: #F7F5F1; text-decoration: none; }
.a-traiter-item a::before { content: ''; background: var(--ocre); grid-row: 1 / span 2; }
.a-traiter-titre { display: block; font-weight: 500; }
.a-traiter-detail { display: block; grid-column: 2; color: var(--encre-2); margin-top: 2px; }

/* ---------- Sélecteurs ---------- */
.selecteur {
  display: flex; gap: 4px; align-items: center; flex-wrap: wrap;
  margin-bottom: 34px; padding-bottom: 18px;
  border-bottom: 1px solid var(--trait-doux);
}
/* Une boîte d'un pixel n'existe pas dans ce système : la surface se pose
   avec son ombre. Et la cible fait 44 px de haut, pas 38. */
.selecteur > a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 10px 16px; border: 0; border-radius: 0;
  background: var(--surface); box-shadow: var(--ombre-1);
  font-size: 0.95rem;
  transition: background var(--geste), color var(--geste);
}
.selecteur > a:hover { text-decoration: none; background: var(--olivier-clair); }
.selecteur > a.actif { background: var(--olivier); color: #fff; }
.selecteur > a span { color: inherit; opacity: 0.8; margin-left: 6px; }
.selecteur-ligne { gap: 16px; }
.selecteur-champ { display: inline-flex; align-items: center; gap: 8px; color: var(--encre-2); }
.selecteur-champ select { max-width: 380px; }
.selecteur-nav { display: inline-flex; gap: 12px; margin-left: auto; }
.selecteur-nav a, .retour { color: var(--olivier); }
.selecteur > a.retour { border: none; background: none; padding-left: 0; }

/* ---------- Écran 3 : graphe ---------- */
.graphe { display: grid; grid-template-columns: minmax(0, 1fr) 90px minmax(0, 1fr); gap: 0; align-items: stretch; margin-bottom: 20px; }
.graphe-colonne { display: grid; gap: 14px; }
.graphe-droite { align-content: center; }
.graphe-liens { width: 100%; height: 100%; min-height: 100%; }
.graphe-liens path { fill: none; stroke-width: 2px; }
.graphe-liens path.ok { stroke: var(--olivier); }
.graphe-liens path.bloque { stroke: var(--ocre); stroke-dasharray: 5 4; }
.carte-noeud { background: var(--surface); box-shadow: var(--ombre-1); border-left: 3px solid var(--trait); padding: 15px 20px; }
.carte-noeud.ok { border-left-color: var(--olivier); }
.carte-noeud.bloque { border-left-color: var(--ocre); }
.carte-noeud.attend { border-left-color: var(--trait); }
.noeud-titre { display: flex; justify-content: space-between; gap: 12px; }
.noeud-titre span { color: var(--encre-2); font-variant-numeric: tabular-nums; }
.noeud-objet { color: var(--encre-2); margin-top: 2px; }
.noeud-etat { margin-top: 8px; font-weight: 500; }
.carte-noeud.bloque .noeud-etat:not(.secondaire) { color: var(--ocre-texte); }
.noeud-etat.secondaire { font-weight: 400; margin-top: 2px; }

table.calcul tr.pivot td { background: var(--olivier-clair); font-weight: 500; }
table.calcul tr.bloque td:first-child { box-shadow: inset 3px 0 0 var(--ocre); }
table.calcul tr.ok td:first-child { box-shadow: inset 3px 0 0 var(--olivier); }
table.calcul tr.butee td { border-top: 1px solid var(--encre); font-weight: 500; }
table.calcul tr.depassement td { color: var(--rouge-profond); font-weight: 600; }
table.calcul tr.marge td { color: var(--olivier); font-weight: 600; }
/* La phrase qui conclut un calcul n'est pas du texte courant : c'est le
   résultat. Elle est posée sur sa propre feuille, avec le trait qui dit dans
   quel sens le résultat penche. */
.conclusion {
  font-family: var(--serif); font-size: 1.5rem; font-weight: 400;
  margin: 24px 0 0; line-height: 1.32; letter-spacing: -0.012em; max-width: 62ch;
  background: var(--surface); box-shadow: var(--ombre-1);
  border-left: 3px solid var(--olivier);
  padding: 20px 28px 22px 25px;
}
.conclusion-depassement { color: var(--rouge-profond); border-left-color: var(--rouge-profond); }
.type-doc { color: var(--encre-2); white-space: nowrap; }

/* ---------- Écran 4 : facturation ---------- */
.progression { margin-bottom: 24px; }
.progression-barre { display: flex; height: 68px; box-shadow: var(--ombre-1); background: var(--surface); }
.progression-seg { display: flex; flex-direction: column; justify-content: center; padding: 0 12px; border-right: 1px solid var(--surface); min-width: 0; overflow: hidden; white-space: nowrap; }
.progression-seg:last-child { border-right: none; }
.progression-seg.etat-réglée { background: var(--olivier); color: #fff; }
.progression-seg.etat-en-attente-de-validation { background: var(--ocre-clair); color: var(--encre); box-shadow: inset 0 5px 0 var(--ocre); }
.progression-seg.reste { background: repeating-linear-gradient(135deg, var(--trait) 0 3px, transparent 3px 9px); color: var(--encre); }
.progression-libelle { font-size: 0.95rem; opacity: 0.9; }
.progression-montant { font-weight: 600; font-variant-numeric: tabular-nums; }
.progression-jalons { position: relative; height: 30px; margin-top: 6px; font-size: 0.9rem; color: var(--encre-2); }
.progression-jalons span { position: absolute; transform: translateX(-100%); white-space: nowrap; padding-right: 6px; border-right: 1px solid var(--trait); line-height: 1.2; text-align: right; }
.progression-jalons b { display: block; color: var(--encre); }

.marche-grille { display: grid; grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); gap: 24px; align-items: start; }
.marche-etapes tr.reste td { color: var(--encre-2); }
.marche-etapes .secondaire { display: block; font-size: 0.95rem; }
.synthese { margin: 0; background: var(--surface); box-shadow: var(--ombre-1); }
.synthese > div { padding: 15px 20px; border-bottom: 1px solid var(--trait-fin); display: grid; grid-template-columns: 1fr auto; gap: 0 16px; align-items: baseline; }
.synthese > div:last-child { border-bottom: none; }
.synthese dt { color: var(--encre-2); }
.synthese dd { margin: 0; font-family: var(--serif); font-size: 1.55rem; font-weight: 400; text-align: right; letter-spacing: -0.015em; }
.synthese small { grid-column: 1 / -1; color: var(--encre-2); font-size: 0.9rem; }
.synthese .retenue { background: var(--pierre); }
.synthese .retenue dt { color: var(--encre); font-weight: 500; }
.controles { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 10px; }
.controles li { display: grid; grid-template-columns: 28px 1fr; gap: 8px; align-items: start; }
.controles .coche { font-weight: 700; color: var(--olivier); font-size: 1.2rem; line-height: 1.2; }
.controles li.ko .coche { color: var(--ocre-texte); }
.controle-libelle { display: block; }
.controle-detail { display: block; color: var(--encre-2); font-variant-numeric: tabular-nums; }

.etat-facture { display: inline; white-space: nowrap; }
.etat-facture i { display: inline-block; width: 10px; height: 10px; margin-right: 8px; border: 1px solid var(--olivier); vertical-align: 0; }
.etat-facture em { font-style: normal; color: var(--encre-2); }
.etat-facture.reglee i { background: var(--olivier); }
.etat-facture.attente i { background: var(--ocre); border-color: var(--ocre); }
.etat-facture.recue i { background: transparent; }
.etat-facture.doublon { color: var(--ocre-texte); font-weight: 600; }
.etat-facture.doublon i { background: var(--ocre); border-color: var(--ocre); border-radius: 50%; }
.etat-facture.proforma { color: var(--encre-2); font-style: italic; }
.etat-facture.proforma i { border-style: dashed; }
table.factures tr.doublon td { border-bottom: none; background: var(--ocre-clair); }
table.factures tr.alerte-ligne td { background: var(--ocre-clair); padding-top: 0; }
table.factures tr.proforma td { color: var(--encre-2); }
table.factures td.action { text-align: right; white-space: nowrap; }
.alerte-doublon { color: var(--encre); }

/* ---------- Écran 5 : service fait ---------- */
.fiche { max-width: 880px; }
.fiche-entete { margin-bottom: 18px; }
.fiche-alerte { background: var(--ocre-clair); border-left: 3px solid var(--ocre); box-shadow: var(--ombre-1); padding: 13px 18px; margin: 0 0 20px; }
.fiche-colonnes { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.fiche-colonne { background: var(--surface); box-shadow: var(--ombre-1); padding: 18px 22px; }
.fiche-colonne h3 { font-size: 1.2rem; margin-bottom: 10px; }
.fiche-colonne ul { margin: 0; padding-left: 18px; }
.fiche-colonne li { margin: 4px 0; }
.fiche-decision { margin-top: 24px; background: var(--surface); box-shadow: var(--ombre-1); padding: 24px; }
.fiche-boutons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.decision {
  min-height: 62px; border: 1px solid var(--encre); background: var(--surface); border-radius: 0;
  font-size: 1.1rem; font-weight: 500; cursor: pointer;
  transition: background var(--geste), color var(--geste), border-color var(--geste);
}
.decision-conforme { background: var(--olivier); border-color: var(--olivier); color: #fff; }
.decision-conforme:hover { background: #364639; }
.decision-reserve { border-color: var(--ocre); color: var(--ocre-texte); }
.decision-reserve:hover, .decision-reserve.choisie { background: var(--ocre-clair); }
.decision-refus:hover, .decision-refus.choisie { background: var(--pierre); }
.fiche-motif { margin-top: 14px; display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: end; }
.fiche-motif[hidden] { display: none; }
.fiche-motif label { display: grid; gap: 4px; color: var(--encre-2); }
.fiche-motif textarea { width: 100%; padding: 8px; border: 1px solid var(--trait-doux); border-radius: 0; resize: vertical; color: var(--encre); }
/* minmax(0, 1fr) et non 1fr : sans cela les deux champs refusent de
   descendre sous leur contenu minimal, et l'horodatage poussait la page
   de trois pixels vers la droite — assez pour une barre de défilement. */
.fiche-signature { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 16px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--trait); align-items: end; }
.fiche-signature label { display: grid; gap: 4px; color: var(--encre-2); font-size: 0.95rem; }
.fiche-signature select, .fiche-signature input { padding: 7px 9px; border: 1px solid var(--trait-doux); border-radius: 0; background: var(--surface); color: var(--encre); font-size: 1rem; }
.fiche-signature input[name="signature"] { font-family: var(--serif); font-style: italic; font-size: 1.45rem; border-bottom: 1px solid var(--encre); border-top: none; border-left: none; border-right: none; border-radius: 0; padding-left: 2px; }
.horodatage { display: grid; gap: 4px; color: var(--encre-2); font-size: 0.95rem; }
.horodatage output { color: var(--encre); font-size: 1rem; padding: 7px 0; }
.fiche-seuil { margin: 16px 0 0; padding: 13px 18px; background: #F7F5F1; border-left: 3px solid var(--olivier); }
.fiche-faite { margin-top: 24px; background: var(--olivier-clair); border-left: 3px solid var(--olivier); box-shadow: var(--ombre-1); padding: 15px 20px; }
.fiche-faite p { margin: 0; }
.journal { margin-top: 28px; }
.journal h3 { font-size: 1.25rem; margin-bottom: 10px; }
.journal-liste { list-style: none; margin: 0; padding: 0; background: var(--surface); box-shadow: var(--ombre-1); }
.journal-liste li { display: grid; grid-template-columns: 150px 1fr auto; gap: 16px; padding: 13px 20px; border-bottom: 1px solid var(--trait-fin); }
.journal-liste li:last-child { border-bottom: none; }
.journal-date { color: var(--encre-2); white-space: nowrap; }
.journal-par { color: var(--encre-2); white-space: nowrap; }

/* ---------- Écran 6 : assistant ---------- */
.assistant {
  border-left: 1px solid var(--trait-doux);
  box-shadow: -18px 0 40px -32px rgba(58, 48, 33, 0.45);
  background: var(--surface);
  position: sticky; top: 0;
  height: 100vh;
  display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto auto;
  min-width: 0;
}
.assistant[hidden] { display: none; }
.assistant-entete { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px 8px; }
.assistant-entete h2 { font-size: 1.4rem; }
.assistant-mention { margin: 0 20px 12px; color: var(--encre-2); font-size: 0.9rem; border-bottom: 1px solid var(--trait); padding-bottom: 12px; }
.assistant-conversation { overflow-y: auto; padding: 4px 20px 12px; display: grid; gap: 12px; align-content: start; }
.assistant-vide { color: var(--encre-2); font-style: italic; margin: 0; }
.message { padding: 12px 15px; border-radius: 0; max-width: 100%; }
.message p { margin: 0 0 8px; }
.message p:last-child { margin-bottom: 0; }
.message ul { margin: 6px 0 0; padding-left: 18px; }
.message li { margin: 6px 0; }
.message a { color: var(--olivier); text-decoration: underline; text-underline-offset: 3px; }
.message-question { background: var(--olivier-clair); justify-self: end; max-width: 90%; }
.message-reponse { background: var(--pierre); }
.message-refus { border-left: 4px solid var(--ocre); }
.assistant-questions { display: grid; gap: 6px; padding: 12px 20px; border-top: 1px solid var(--trait); }
.question { text-align: left; background: var(--surface); border: 1px solid var(--trait-doux); border-radius: 0; padding: 9px 13px; cursor: pointer; transition: background var(--geste), border-color var(--geste); }
.question:hover { background: var(--olivier-clair); border-color: var(--olivier); }
.assistant-saisie { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 0 20px 16px; }
.assistant-saisie input { padding: 8px 10px; border: 1px solid var(--trait-doux); border-radius: 0; min-width: 0; }
/* Le brouillon est une surface, pas une boîte : son bord vient de son
   ombre, comme toutes les autres. C'est l'écran du geste 6 de la
   démonstration, et c'était la dernière entorse à la règle. */
.brouillon { background: var(--surface); box-shadow: var(--ombre-1); padding: 14px 16px; margin-top: 4px; }
.brouillon-champ { display: grid; grid-template-columns: 56px 1fr; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--trait); }
.brouillon-champ span:first-child { color: var(--encre-2); }
.brouillon-corps { padding-top: 10px; }
.brouillon-corps p { margin: 0 0 10px; }
.brouillon-actions { display: flex; align-items: center; gap: 12px; margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--trait); }
.brouillon-mention { color: var(--encre-2); font-size: 0.9rem; }


/* ---------- Sous-onglets : les deux natures de validation ---------- */
.sous-onglets { display: flex; gap: 4px; margin-bottom: 26px; border-bottom: 1px solid var(--trait-doux); }
.sous-onglets a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 10px 16px;
  color: var(--encre);
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.sous-onglets a:hover { text-decoration: none; background: var(--pierre); }
.sous-onglets a.actif { color: var(--olivier); border-bottom-color: var(--olivier); font-weight: 600; }
/* Le compteur d'un onglet est un chiffre en exposant, pas une pastille.
   C'est la règle du rail principal ; le rail des bibles portait des
   pastilles pleines, et les deux se lisaient à soixante-dix pixels l'un
   de l'autre. Deux manières de compter sur la même image. */
.sous-onglets .pastille {
  display: inline; min-width: 0; padding: 0; margin-left: 5px;
  background: none; color: var(--ocre-texte);
  font-family: var(--serif); font-size: 0.88rem; font-weight: 500; line-height: 1;
  vertical-align: 0.45em; letter-spacing: 0;
}
.sous-onglets a.actif .pastille { font-weight: 600; }
.pastille {
  display: inline-block;
  min-width: 20px;
  padding: 0 6px;
  margin-left: 4px;
  /* Blanc sur --ocre ne vaut que 3,61:1 : sous le seuil AA d'un texte de
     0,74 rem. --ocre-texte est le même ocre, assombri, à 5,7:1. */
  background: var(--ocre-texte);
  color: #fff;
  border-radius: 0;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
  line-height: 1.7;
}

/* ---------- Écran 5 : le circuit de validation ----------
   Le circuit est UN composant, pas six boîtes empilées : une seule surface
   posée sur la pierre, des étapes séparées entre elles par un filet, et le
   trait de gauche qui reste le seul porteur d'état. */
.circuit {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 0;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.circuit-etape {
  border: 0;
  border-bottom: 1px solid var(--trait-fin);
  border-left: 3px solid var(--trait);
  background: transparent;
  padding: 16px 20px;
}
.circuit-etape:last-child { border-bottom: none; }
.circuit-etape.etape-valide { border-left-color: var(--olivier); }
.circuit-etape.etape-refuse { border-left-color: var(--rouge-profond); background: var(--rouge-clair); }
.circuit-etape.etape-attente { border-left-color: var(--ocre); background: var(--ocre-clair); }
.circuit-etape.etape-avenir, .circuit-etape.etape-ecartee { color: var(--encre-2); }
.circuit-tete { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.circuit-role { font-weight: 600; text-transform: lowercase; }
.circuit-role::first-letter { text-transform: uppercase; }
.circuit-qui { color: var(--encre-2); }
.circuit-etat { margin-left: auto; font-size: 0.9rem; padding: 1px 8px; border: 1px solid var(--trait-doux); border-radius: 0; white-space: nowrap; }
.circuit-etat.valide { color: var(--olivier); border-color: var(--olivier); }
.circuit-etat.refuse { color: var(--rouge-profond); border-color: var(--rouge-profond); font-weight: 600; }
.circuit-etat.attente { color: #fff; background: var(--ocre); border-color: var(--ocre); font-weight: 600; }
.circuit-etat.avenir { color: var(--encre-2); }
.circuit-objet { margin: 4px 0 0; color: var(--encre-2); }
.circuit-decisions { list-style: none; margin: 10px 0 0; padding: 0 0 0 14px; border-left: 2px solid var(--trait); display: grid; gap: 8px; }
.circuit-decisions li { display: grid; gap: 2px; }
.circuit-decisions li.refus { border-left: 2px solid var(--rouge-profond); margin-left: -16px; padding-left: 14px; }
.circuit-decision { font-weight: 500; }
.circuit-decisions em { font-style: italic; color: var(--encre-2); }
.circuit-relance { color: var(--rouge-profond); font-weight: 500; }

/* ---------- Écran 5 : inviter un validateur extérieur ---------- */
.invitation {
  display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap;
  margin-top: 14px; padding: 18px 22px 20px;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.invitation label { display: grid; gap: 4px; color: var(--encre-2); }
.invitation select, .invitation input {
  padding: 8px 10px; border: 1px solid var(--trait-doux); border-radius: 0;
  background: var(--surface); color: var(--encre); min-width: 240px;
}
.invitation-faite { background: var(--olivier-clair); border-left: 3px solid var(--olivier); box-shadow: var(--ombre-1); padding: 13px 18px; margin: 14px 0 8px; }
.invitation-lien { display: flex; gap: 10px; align-items: baseline; margin: 0; color: var(--encre-2); }
.invitation-lien code { font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; background: var(--pierre); padding: 2px 8px; border-radius: 0; color: var(--encre); }

/* ---------- Écran 6 : bibles, cartes de référence ---------- */
.cartes {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 24px;
  align-items: start;   /* une fiche s'arrête où son texte s'arrête */
}
.carte {
  background: var(--surface);
  box-shadow: var(--ombre-1);
  border-top: 2px solid var(--olivier);
  padding: 20px 22px 22px;
  transition: box-shadow var(--geste);
  display: grid;
  gap: 8px;
  align-content: start;
}
.carte.carte-sourcing { border-top-color: var(--rouge-profond); }
.carte-entete { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.carte-categorie {
  display: block;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--encre-2); margin-bottom: 3px;
}
.carte-entete h4 { font-family: var(--serif); font-size: 1.22rem; font-weight: 480; letter-spacing: -0.01em; margin: 0; }
.carte-designation { margin: 0; font-weight: 500; }
.carte-reference {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.84rem; letter-spacing: 0.01em;
  background: #F4F1EC; box-shadow: inset 0 0 0 1px var(--trait-fin);
  padding: 2px 8px; white-space: nowrap;
}
.carte-source, .carte-pose { margin: 0; color: var(--encre-2); }
.carte-champs { display: grid; gap: 6px; margin: 4px 0 0; padding: 10px 0 0; border-top: 1px solid var(--trait); }
.carte-champ { display: grid; grid-template-columns: 90px 1fr; gap: 10px; }
.carte-champ dt { color: var(--encre-2); }
.carte-champ dd { margin: 0; }
.carte-stock { margin: 4px 0 0; padding-top: 10px; border-top: 1px solid var(--trait); }
.carte-stock > span:first-child { color: var(--encre-2); }
.carte-stock em { font-style: italic; color: var(--ocre-texte); }
.carte-ligne { margin: 0; }
.carte-ligne a { color: var(--olivier); }
.carte-substituts { margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--trait); }
.carte-substituts h5 { margin: 0 0 6px; font-size: 0.95rem; color: var(--encre-2); font-weight: 600; }
.carte-substituts ul { margin: 0; padding-left: 18px; }
.carte-substituts li { margin: 4px 0; }
.carte-actions { margin-top: 4px; }

/* Disponibilité d'une référence. */
.stock { white-space: nowrap; font-size: 0.9rem; color: var(--encre-2); }
.stock i { display: inline-block; width: 10px; height: 10px; margin-right: 6px; border: 1px solid var(--olivier); vertical-align: 0; }
.stock.s-disponible i { background: var(--olivier); }
.stock.s-a-confirmer i { background: var(--ocre-clair); border-color: var(--ocre); }
.stock.s-epuise i { background: var(--ocre); border-color: var(--ocre); border-radius: 50%; }
.stock.s-arrete i { background: var(--rouge-profond); border-color: var(--rouge-profond); border-radius: 50%; }
.stock.s-epuise, .stock.s-arrete { color: var(--rouge-profond); font-weight: 500; }
/* Disponibilité jamais relevée : un carré creux, ni vert ni rouge. Ce
   n'est pas une alerte, c'est un manque, et il se lit comme tel. */
.stock.s-non-renseigne i { background: transparent; border-color: var(--trait); }
.stock.s-non-renseigne { color: var(--encre-2); }

/* ---------- Écran 6 : recherche d'approvisionnement ---------- */
.sourcing { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--trait); }
.sourcing h5 { margin: 0 0 8px; font-size: 0.95rem; font-weight: 600; }
.sourcing-etapes { margin: 0 0 12px; padding-left: 20px; display: grid; gap: 6px; color: var(--encre-2); }
.sourcing-etapes li::marker { color: var(--olivier); font-weight: 600; }

/* ---------- Écran 7 : budget ---------- */
/* Un tableau large reste lisible quand l’assistant prend la moitié de l’écran. */
.table-large { overflow-x: auto; }
.table-large table { min-width: 900px; }
/* Sous 1100 px, ces tableaux défilent DANS leur bloc plutôt que de pousser
   la page entière de côté. La barre qui l'annonce doit être discrète : un
   trait dans la palette, pas la barre grise du système posée en travers
   d'une carte. */
.table-large { scrollbar-width: thin; scrollbar-color: var(--trait) transparent; }
.table-large::-webkit-scrollbar { height: 8px; }
.table-large::-webkit-scrollbar-track { background: transparent; }
.table-large::-webkit-scrollbar-thumb { background: var(--trait); border-radius: 0; }
.table-large::-webkit-scrollbar-thumb:hover { background: var(--encre-2); }
.tableau-budget td:first-child a { color: var(--encre); }
.ecart-plus { color: var(--rouge-profond); font-weight: 600; }
.ecart-moins { color: var(--olivier); }
.ecart-plus em, .ecart-moins em { font-style: normal; font-weight: 400; color: var(--encre-2); }
.alerte-douce { border-left-color: var(--ocre) !important; }
.alerte-forte { background: var(--rouge-clair) !important; border-left-color: var(--rouge-profond) !important; }
.a-traiter-item.genre-budget-non-valide a::before,
.a-traiter-item.genre-budget-depassement a::before { background: var(--rouge-profond); }
.a-traiter-item.genre-budget-poste a::before { background: var(--rouge-profond); }
.a-traiter-item.genre-budget-marge a::before,
.a-traiter-item.genre-budget-ecart a::before { background: var(--ocre); }
.a-traiter-item.genre-engagement a::before { background: var(--olivier); }

/* ---------- Ce qu'une action vient de faire bouger ---------- */
tr.surlignee td { background: var(--ocre-clair); }
.frise-ligne.surlignee .frise-legende a { color: var(--ocre-texte); font-weight: 600; }

/* ---------- Assistant : actions ---------- */
.assistant-propositions { border-top: 1px solid var(--trait); overflow-y: auto; max-height: 42vh; }
.assistant-propositions h3 {
  margin: 0; padding: 12px 20px 0;
  font-family: var(--sans); font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--encre-2);
}
.assistant-propositions .assistant-mention { margin: 6px 20px 0; border-bottom: none; padding-bottom: 0; }
.assistant-propositions .assistant-questions { border-top: none; padding-top: 8px; }
.question-action { border-left: 3px solid var(--ocre); font-weight: 500; }
.question-action:hover { background: var(--ocre-clair); border-color: var(--trait); border-left-color: var(--ocre); }
.message-action { border-left: 4px solid var(--ocre); }
.tableau-action { margin: 8px 0 4px; background: var(--surface); }
.tableau-action th, .tableau-action td { padding: 6px 10px; font-size: 0.92rem; }
.message .brouillon { margin-top: 8px; }
.message .sourcing { border-top: none; padding-top: 4px; }


/* ---------- L'arrivée d'un écran ----------
   Une seule chose animée, courte, et rejouée à chaque navigation puisque
   app.js réécrit #ecran. Rien d'autre ne bouge dans la page.

   PIÈGE DE CAPTURE, payé le 23/09/2026. Pendant ces 420 ms, TOUT #ecran est
   translucide et se compose sur la pierre du fond : une capture prise au
   milieu rend des photos d'intérieur délavées, comme voilées de beige — et
   la mesure le confirme, le même alpha (0,57) sur les photos, sur les
   surfaces blanches et sur le texte. Ce n'est pas un filtre, pas une
   conversion d'image, pas un fond : c'est l'animation, prise trop tôt.
   Pour capturer : lancer le navigateur avec --force-prefers-reduced-motion
   (la règle plus bas coupe alors l'animation), ou lui donner de quoi
   terminer (--virtual-time-budget=8000). */
@keyframes pose {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}
/* Un écran ne rend qu'un seul enfant, div.ecran : les cinq délais qui
   suivaient étaient du code mort. Une seule pose, celle de la page. */
#ecran > * { animation: pose 420ms cubic-bezier(0.16, 0.7, 0.24, 1) backwards; }

.carte:hover { box-shadow: var(--ombre-2); }
.question:hover { background: #F7F5F1; border-color: var(--olivier); }
.decision-conforme:hover { background: #33422F; border-color: #33422F; }


/* ---------- En-tête : la composition de l'accueil ---------- */
.vues { display: inline-flex; align-items: center; gap: 8px; }
.vues-mot { color: var(--encre-2); font-size: 0.9rem; white-space: nowrap; }
.bouton-icone { padding: 6px 10px; font-size: 1.05rem; line-height: 1.3; text-decoration: none; }
.bouton-icone:hover { text-decoration: none; background: var(--pierre); }
.bouton-icone.actif { background: var(--olivier); border-color: var(--olivier); color: #fff; }

/* ---------- Accueil : cinq chiffres, dont un qui parle en euros ---------- */
.chiffres-cinq { grid-template-columns: repeat(5, 1fr); }
.chiffre-expose dd { color: var(--rouge-profond); }

.chapeau-marge { color: var(--ocre-texte); }

/* ---------- Accueil : « À traiter », chaque entrée dit sa règle ---------- */
.a-traiter-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: stretch; }
.a-traiter-item > a { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 14px; padding: 12px 16px; align-items: baseline; }
.a-traiter-item a::before { content: none; }
.a-traiter-quand {
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  padding-left: 12px; border-left: 3px solid var(--trait); color: var(--encre-2);
  white-space: nowrap;
}
.gravite-jour .a-traiter-quand { border-left-color: var(--rouge-profond); color: var(--rouge-profond); }
.gravite-semaine .a-traiter-quand { border-left-color: var(--ocre); color: var(--ocre-texte); }
.gravite-surveiller .a-traiter-quand { border-left-color: var(--trait); }
.a-traiter-corps { display: grid; gap: 2px; min-width: 0; }
.a-traiter-regle {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px 12px 20px; border-left: 1px solid var(--trait);
  color: var(--encre-2); font-size: 0.9rem; text-align: right; max-width: 300px;
}
.a-traiter-regle-mot {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--encre-2); white-space: nowrap;
}
.a-traiter-reglage {
  flex: none; width: 26px; height: 26px; display: grid; place-items: center;
  border: 1px solid var(--trait-doux); border-radius: 0; color: var(--encre-2); text-decoration: none;
}
.a-traiter-reglage:hover { background: var(--olivier-clair); border-color: var(--olivier); color: var(--olivier); text-decoration: none; }

/* ---------- Une ligne qui tombe dans la marge, pas au-delà de la butée ---------- */
.risque-marge { color: var(--ocre-texte); border-color: var(--ocre); font-weight: 500; }
.frise-fin-marge { color: var(--ocre-texte); }

/* ---------- Légende de la frise : ce que personne ne survole en visio ---------- */
.frise-legende-liste {
  display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center;
  list-style: none; margin: 10px 0 0; padding: 12px 0 0 var(--largeur-legende);
  border-top: 1px solid var(--trait); color: var(--encre-2); font-size: 0.9rem;
}
.frise-legende-liste li { display: inline-flex; align-items: center; gap: 8px; }
.frise-legende-liste i {
  display: inline-block; width: 26px; height: 12px; flex: none; border-radius: 0; position: static;
}
.frise-legende-titre { font-weight: 600; color: var(--encre); }

/* ---------- Écran Réglages ---------- */
.reglages { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.reglage {
  background: var(--surface); box-shadow: var(--ombre-1);
  border-left: 3px solid var(--trait-doux);
  padding: 16px 18px; display: grid; gap: 8px; align-content: start;
}
.reglage-vif { border-left-color: var(--olivier); }
.reglage-modifie { border-left-color: var(--ocre); background: var(--ocre-clair); }
.reglage-tete { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.reglage-nom { font-weight: 600; }
.reglage-etat { font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--encre-2); white-space: nowrap; }
.reglage-vif .reglage-etat { color: var(--olivier); }
.reglage-aide { margin: 0; color: var(--encre-2); font-size: 0.92rem; }
.reglage-pas { display: flex; align-items: center; gap: 12px; }
.pas {
  width: 34px; height: 34px; flex: none; font-size: 1.15rem; line-height: 1;
  background: var(--surface); border: 1px solid var(--encre); border-radius: 0; cursor: pointer;
}
.pas:hover { background: var(--olivier); border-color: var(--olivier); color: #fff; }
.reglage-valeur { font-family: var(--serif); font-size: 1.35rem; }
.reglage-valeur-fixe { margin: 0; color: var(--encre); }
.reglage-chemin {
  margin: 0; font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.82rem; color: var(--encre-2);
}
.reglages-consequence {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--ocre-clair); border-left: 4px solid var(--ocre); box-shadow: var(--ombre-1);
  padding: 12px 16px; margin: 14px 0 0;
}
.bloc-colonnes { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 28px; }
.liste-reglage {
  margin: 0 0 12px; padding: 14px 20px 15px 40px; display: grid; gap: 6px;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.liste-reglage-hors { list-style: none; padding-left: 20px; }
.souverainete {
  max-width: 74ch; margin: 0;
  background: var(--surface); box-shadow: var(--ombre-1);
  padding: 18px 24px 20px;
}
.emporter {
  width: 100%; max-width: 620px; font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.85rem; padding: 12px 14px; border: 1px solid var(--trait-doux); border-radius: 0;
  background: var(--pierre); color: var(--encre); resize: vertical;
}

/* ---------- L'objet visé par une entrée d'« À traiter » ---------- */
.vise { box-shadow: inset 0 0 0 2px var(--olivier); transition: box-shadow 1.6s ease-out; }

/* ---------- Mouvement réduit ---------- */
@media (prefers-reduced-motion: reduce) {
  /* Le mouvement, c'est aussi les 160 ms de --geste et la frise : qui
     demande moins de mouvement n'en veut nulle part. */
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  #ecran > * { animation: none; }
  .onglets a::after { transition: none; }
  .frise-barre, .frise-fin { transition: none !important; }
  .frise-barre { transform: translateY(-50%) scaleX(1); }
  .frise-fin { opacity: 1; }
  .app { transition: none; }
  .tete .tete-rappel { transition: none; }
}


/* ---------- Écrans de fiche sur grand écran ----------
   La fiche garde sa mesure de lecture ; le journal passe à côté d'elle au
   lieu de s'empiler dessous et de laisser la moitié droite vide. */
@media (min-width: 1500px) {
  .fiche {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 980px) minmax(320px, 400px);
    column-gap: 56px;
    align-content: start;
  }
  .fiche > * { grid-column: 1; }
  .fiche-entete { grid-column: 1 / -1; }
  .fiche .journal { grid-column: 2; grid-row: 2 / span 30; margin-top: 0; align-self: start; }
  .fiche .journal-liste li { grid-template-columns: 1fr; gap: 2px; padding: 13px 18px; }
  .fiche .journal-date { font-size: 0.9rem; }
  .fiche .journal-par { text-align: left; font-size: 0.9rem; }
}

/* ---------- Derniers réglages ---------- */
.selecteur-nav a, .retour { color: var(--olivier); font-size: 0.95rem; }
.fiche-entete { margin-bottom: 22px; }
.journal h3 { font-size: 1.3rem; margin-bottom: 12px; }
.journal { margin-top: 40px; }
.note { font-size: 0.92rem; line-height: 1.5; }
.frise-lecture { margin-top: 14px; }
.chiffres-liste + .note, .a-traiter + .note { margin-top: 14px; }
.titre-bloc + .table-large, .titre-bloc + table.donnees { margin-top: 2px; }

/* ---------- Largeurs ----------
   Le rail (--marge / --mesure) fait l'essentiel du travail : il suffit de le
   resserrer. Aucune règle ne redéfinit le padding de <main>, sinon l'en-tête
   et la page cesseraient de partager leur bord gauche. */

/* Très grand écran : la mesure s'élargit un peu, l'air augmente plus vite
   que le texte, et la page reste une page — pas un tableur étiré. */
@media (min-width: 1900px) {
  :root { --mesure: 1680px; --marge: 64px; --largeur-legende: 280px; }
  main { padding-top: 56px; }
}

@media (max-width: 1300px) {
  :root { --largeur-legende: 220px; }
  /* La date projetée s'écrit à droite de la barre : il lui faut sa marge. */
  .frise { padding-right: 92px; }
  main { padding-top: 34px; padding-bottom: 88px; }
  .app.assistant-ouvert { grid-template-columns: minmax(0, 1fr) 400px; }
  .bloc { margin-top: 44px; }
  .marche-grille { grid-template-columns: 1fr; }
}
@media (max-width: 1100px) {
  .chiffres-liste { grid-template-columns: repeat(2, 1fr); }
  .chiffres-liste > div:nth-child(2n) { border-right: none; }
  .chiffres-liste > div:nth-child(-n+2) { border-bottom: 1px solid var(--trait); }
  /* Cinq chiffres sur deux colonnes : le cinquième restait seul, une
     demi-rangée vide à sa droite et le filet du rang au-dessus qui
     s'arrêtait en l'air. Il prend le rang entier. */
  .chiffres-cinq > div:nth-child(3), .chiffres-cinq > div:nth-child(4) {
    border-bottom: 1px solid var(--trait);
  }
  .chiffres-cinq > div:nth-child(5) { grid-column: 1 / -1; }
  .statuts { grid-template-columns: 1fr; }
  .statuts-sequence { grid-template-columns: repeat(3, 1fr); }
  .statuts-accolades { display: none; }
  .fiche-colonnes { grid-template-columns: 1fr; }
  .graphe { grid-template-columns: 1fr; }
  .graphe-liens { display: none; }
  .cartes { grid-template-columns: 1fr; }
  .fiche-boutons { grid-template-columns: 1fr; }
}

/* =====================================================================
   Budget vertical de l'accueil

   L'écran d'accueil doit tenir sa promesse : les cinq chiffres, la frise
   et les premières tâches au-dessus de la ligne de flottaison, sur un
   portable de réunion à 1440 × 900. Ces règles resserrent ce qui coûtait
   de la hauteur sans rien apporter à la lecture.
   ===================================================================== */

main { padding-top: 22px; }
.ecran-entete { margin-bottom: 14px; }
.ecran-campagne .titre-ecran { font-size: 2.05rem; }
.ecran-campagne .chapeau { max-width: 92ch; margin-top: 6px; }

.chiffres-liste dd { font-size: 1.72rem; margin: 8px 0 5px; }
.chiffres-liste > div { padding-top: 14px; padding-bottom: 14px; }
.chiffres-cinq small { font-size: 0.86rem; }

.frise-piste { min-height: 52px; }
.frise-bloc { margin-bottom: 18px; }
.frise-legende-liste { margin-top: 8px; padding-top: 9px; }
.frise-lecture { margin-top: 8px; }

/* Une entrée d'« À traiter » : deux lignes, pas quatre. */
.a-traiter-item > a { padding-top: 10px; padding-bottom: 10px; }
.a-traiter-regle { padding-top: 10px; padding-bottom: 10px; }

/* L'accueil respire moins entre ses blocs : 80 px de séparation valaient une
   tâche visible de moins. Les autres écrans gardent leur souffle. */
.ecran-campagne .bloc { margin-top: 26px; padding-top: 17px; }
.ecran-campagne .titre-bloc { font-size: 1.3rem; margin-bottom: 12px; }
.frise-axe { height: 50px; }
.frise-piste-axe::before, .frise-piste-axe::after { top: 42px; }
.frise-mois { top: 26px; }
.frise-legende { padding-top: 8px; padding-bottom: 8px; }
.frise-piste { min-height: 46px; }
.frise-lecture { font-size: 0.88rem; }

/* Le détail d'une tâche se plaçait en colonne 2 du temps où l'entrée était
   une grille à deux colonnes. Il empile désormais sous son titre. */
.a-traiter-corps > .a-traiter-titre,
.a-traiter-corps > .a-traiter-detail { grid-column: 1; margin-top: 0; }
.a-traiter-item > a { grid-template-columns: 132px minmax(0, 1fr); gap: 16px; }
.a-traiter-regle {
  width: 250px; max-width: 250px; text-align: left;
  align-items: flex-start; gap: 10px; padding-left: 18px;
}
.a-traiter-regle > span:nth-child(2) { flex: 1; min-width: 0; }
.a-traiter-regle-mot { padding-top: 2px; }

/* L'engrenage, dessiné et non typographié : il rend pareil partout. */
.engrenage { width: 16px; height: 16px; display: block; fill: currentColor; }
.bouton-icone { display: inline-grid; place-items: center; padding: 8px 10px; }
.bouton-icone .engrenage { width: 17px; height: 17px; }
.a-traiter-reglage .engrenage { width: 14px; height: 14px; }

/* Le nom du paramètre passe en premier et occupe toute la largeur ; l'état
   se pose en dessous, comme une étiquette. Sur une carte de 300 px, les
   mettre côte à côte coupait le nom lettre par lettre. */
.reglage-tete { display: block; }
.reglage-nom { display: block; }
.reglage-etat {
  display: inline-block; margin-top: 4px; padding: 1px 8px;
  border: 1px solid var(--trait-doux); border-radius: 0;
  font-size: 0.72rem; letter-spacing: 0.07em;
}
.reglage-vif .reglage-etat { border-color: var(--olivier); }
.reglage-modifie .reglage-etat { border-color: var(--ocre); color: var(--ocre-texte); }


/* =====================================================================
   L'en-tête (5 septembre 2026)

   Un cartouche de journal posé sur le rail gauche, puis un rail d'onglets
   qui reste seul collé en haut quand la page défile.

   La règle du bloc : aucune boîte. Le sélecteur de propriété est un titre
   qui se déroule, les langues sont deux mots, les compteurs d'onglets sont
   des chiffres en exposant, la mention de démonstration est une ligne grise
   au lieu d'une barre noire. Un seul accent : le bouton « Demander »,
   olivier plein — c'est la seule chose de l'en-tête qui appelle le clic.
   ===================================================================== */
/* La colonne principale est un conteneur : l'en-tête se resserre quand
   l'assistant s'ouvre, pas seulement quand la fenêtre rétrécit. */
.app > .principal { container-type: inline-size; }

/* Le <header> ne dessine rien lui-même : ses deux blocs sont posés dans la
   colonne, sinon le rail d'onglets collerait au bas du <header> plutôt qu'au
   haut de la fenêtre.

   Essai abandonné le 5 septembre 2026 : rendre le <header> entier collant et
   replier le cartouche. Le cartouche est dans le flux — le replier raccourcit
   la page de 85 px, et tout le contenu saute vers le haut au premier cran de
   molette. Un en-tête qui se raccourcit ne doit jamais changer de hauteur DANS
   le flux ; il doit laisser le cartouche s'en aller de lui-même. */
.tete { display: contents; }

/* ---- Morceaux communs ---- */
.tete .tete-mention {
  margin: 0; min-width: 0;
  font-size: 0.74rem; color: var(--encre-2); letter-spacing: 0.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tete .tete-marque {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--encre); white-space: nowrap;
}
.tete .langues { display: flex; gap: 16px; border: 0; }
.tete .langues a {
  position: relative; padding: 2px 0; border: 0; line-height: 1.4;
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.16em; color: var(--encre-2);
  transition: color var(--geste);
}
.tete .langues a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
  border-bottom: 1px solid currentColor;
  transform: scaleX(0); transform-origin: left; transition: transform var(--geste);
}
.tete .langues a:hover, .tete .langues a.actif, .tete .langues a.actif:hover {
  background: none; color: var(--encre); text-decoration: none;
}
.tete .langues a.actif::after { transform: scaleX(1); }

.tete .fil { margin: 0; display: block; font-size: inherit; }
.tete #choix-propriete {
  appearance: none; -webkit-appearance: none;
  font-family: var(--serif); font-weight: 430; letter-spacing: -0.02em; color: var(--encre);
  border: 0; border-bottom: 1px solid transparent;
  padding: 0 30px 3px 0; margin: 0; line-height: 1.12; cursor: pointer; max-width: 100%;
  transition: border-color var(--geste);
}
.tete #choix-propriete:hover { border-bottom-color: var(--trait); background-color: transparent; }
/* Sur un écran de bible, le cartouche ne propose plus de choisir une
   propriété : il nomme la maison que l'écran montre. Même dessin que le
   sélecteur, sans le chevron ni le geste. */
.tete .tete-maison {
  display: inline-block; font-family: var(--serif); font-weight: 430;
  letter-spacing: -0.02em; color: var(--encre); line-height: 1.12; max-width: 100%;
}
.tete .tete-intitule {
  margin: 0; font-family: var(--serif); font-style: italic; font-weight: 420;
  color: var(--encre-2); letter-spacing: 0.002em; line-height: 1.3;
}
.tete .fil-mention {
  font-family: var(--sans); font-style: normal;
  font-size: 0.64rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--encre-2); margin-left: 12px; padding-left: 12px;
  border-left: 1px solid var(--trait-fin);
}

.tete #compte-a-rebours { color: var(--encre-2); white-space: nowrap; }
.tete #compte-a-rebours b {
  font-family: var(--serif); font-weight: 400; color: var(--encre);
  letter-spacing: -0.02em; margin: 0; font-variant-numeric: tabular-nums;
}
.tete .echeance-texte {
  display: block; font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
}

.tete .onglets { display: flex; gap: 30px; margin: 0; flex-wrap: nowrap; }
.tete .onglets a { padding: 15px 0 14px; font-size: 0.93rem; letter-spacing: 0.006em; color: var(--encre-2); }
.tete .onglets a::after { left: 0; right: 0; bottom: 0; border-bottom-width: 1.5px; }
.tete .onglets a:hover::after { transform: scaleX(0.34); }
.tete .onglets a.actif { color: var(--encre); font-weight: 600; }
.tete .onglets .pastille {
  display: inline; min-width: 0; padding: 0; margin-left: 5px;
  background: none; color: var(--ocre-texte);
  font-family: var(--serif); font-size: 0.88rem; font-weight: 500; line-height: 1;
  vertical-align: 0.45em; letter-spacing: 0;
}
.tete .onglets a.actif .pastille { font-weight: 600; }

.tete .tete-outils { display: flex; align-items: center; gap: 22px; flex: none; }
.tete .vues { gap: 10px; }
.tete .vues-mot { font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--encre-2); }
.tete #choix-vue {
  appearance: none; -webkit-appearance: none;
  border: 0; border-bottom: 1px solid var(--trait-fin); border-radius: 0;
  padding: 3px 20px 3px 0; font-size: 0.9rem; color: var(--encre); cursor: pointer;
  transition: border-color var(--geste);
}
.tete #choix-vue:hover { border-bottom-color: var(--encre); }
.tete .bouton-icone { border: 0; padding: 6px; color: var(--encre-2); background: transparent; }
.tete .bouton-icone:hover { background: transparent; color: var(--encre); }
.tete .bouton-icone.actif { background: transparent; color: var(--olivier); }
.tete #bouton-assistant {
  background: var(--olivier); border: 1px solid var(--olivier); color: #fff;
  padding: 9px 18px; line-height: 1.2;
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
}
.tete #bouton-assistant:hover { background: #33422F; border-color: #33422F; color: #fff; }
.tete #bouton-assistant[aria-expanded="true"] { background: var(--encre); border-color: var(--encre); color: #fff; }

/* ---- Les menus déroulants de l'en-tête ----
   Un <select> ouvre la liste du système : bleu vif, arêtes arrondies, police
   du système, hors d'atteinte du CSS. Ces deux menus-là sont vus à chaque
   séance ; la liste est donc écrite par app.js (menuDeroulant) et habillée
   ici, avec les arêtes vives et l'ombre chaude des autres surfaces. Le bouton
   ne change pas d'allure : ce sont les règles par id ci-dessus qui le tiennent,
   #choix-propriete en Newsreader, #choix-vue en texte courant. */
.menu { position: relative; display: inline-block; max-width: 100%; }
.menu-bouton {
  text-align: left; font-family: inherit;
  background: transparent var(--chevron) no-repeat right 2px center;
}
.menu-titre .menu-bouton { background-position: right 6px center; }
.menu-bouton[aria-expanded="true"] { background-image: var(--chevron-haut); border-bottom-color: var(--encre); }
.menu-liste {
  position: absolute; z-index: 45; top: calc(100% + 10px); left: 0;
  min-width: 100%; width: max-content; max-width: min(340px, 78vw);
  max-height: 60vh; overflow-y: auto;
  margin: 0; padding: 0; list-style: none;
  background: var(--surface); box-shadow: var(--ombre-2);
  border-top: 2px solid var(--olivier);
}
.menu-liste[hidden] { display: none; }
.menu-liste li {
  display: grid; gap: 2px;
  padding: 11px 18px 12px 15px;
  border-bottom: 1px solid var(--trait-fin);
  border-left: 3px solid transparent;
  cursor: pointer;
}
.menu-liste li:last-child { border-bottom: none; }
.menu-liste .menu-nom { font-family: var(--sans); font-size: 0.95rem; font-weight: 500; letter-spacing: 0; color: var(--encre); }
.menu-liste .menu-detail {
  font-family: var(--sans); font-size: 0.84rem; font-weight: 400; font-style: normal;
  line-height: 1.35; letter-spacing: 0; color: var(--encre-2);
}
.menu-liste li.visee { background: #F7F5F1; }
.menu-liste li.choisie { border-left-color: var(--olivier); background: var(--olivier-clair); }
.menu-liste li.choisie.visee { background: #DAE0D7; }
/* Le menu de composition tombe à droite : c'est le bord dont il est le plus
   près, et rien ne doit sortir du rail. */
.menu-vue .menu-liste { left: auto; right: 0; }

/* ---- Le cartouche, puis le rail ----
   Une ligne de marque, une ligne de titre où le nom de la propriété et le
   compte à rebours se répondent en Newsreader, puis le rail : le cartouche
   défile, la barre reste. */
.tete .tete-haut { background: var(--surface); padding: 15px var(--rail) 0; }
.tete .tete-ligne {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline; gap: 32px;
  padding-bottom: 12px; border-bottom: 1px solid var(--trait-fin);
}
.tete .tete-ligne .tete-mention { text-align: right; }
.tete .tete-identite {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 48px;
  padding: 24px 0 22px;
}
.tete .fil, .tete #choix-propriete { font-size: 2.35rem; }
.tete .tete-intitule { font-size: 1.1rem; margin-top: 9px; }
.tete .echeance { text-align: right; flex: none; }
.tete #compte-a-rebours b { display: block; font-size: 2.35rem; line-height: 1.12; }
.tete .echeance-texte { margin-top: 10px; }
.tete .tete-nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--surface);
  display: flex; align-items: center; justify-content: space-between; gap: 32px;
  padding: 0 var(--rail);
  border-top: 1px solid var(--trait-fin); border-bottom: 1px solid var(--trait-doux);
  box-shadow: 0 1px 0 rgba(58, 48, 33, 0.03), 0 6px 20px -18px rgba(58, 48, 33, 0.3);
}

/* ---- Le rappel : l'en-tête raccourci ----
   Le cartouche s'en va comme n'importe quel contenu, sans qu'aucune hauteur
   change ; le rail reste, et il gagne un titre courant — nom de propriété et
   J−137 — dès que le cartouche a passé le haut de la fenêtre. C'est de la
   peinture, pas de la mise en page : seules l'opacité et une largeur maximale
   varient, et le rappel est le terme du milieu d'un `space-between`, donc ni
   les onglets ni les outils ne bougent d'un pixel quand il paraît.

   La classe .compacte est posée par app.js (majCompacite) sur le bord bas
   réel du cartouche : plus de seuil en dur, plus d'hystérésis à régler. Rien
   ne peut osciller puisque paraître ne change aucune hauteur. */
.tete .tete-rappel {
  margin: 0; min-width: 0; flex: 0 1 auto;
  display: flex; align-items: baseline; gap: 13px;
  max-width: 0; opacity: 0; overflow: hidden;
  white-space: nowrap; pointer-events: none;
  transition: opacity var(--geste), max-width var(--geste);
}
.tete.compacte .tete-rappel { max-width: 460px; opacity: 1; }
/* Le rappel n'apparaît qu'une fois la page défilée, et il prend sa place aux
   onglets : sans ces deux resserrements, il ne restait plus que cent pixels
   pour un nom propre, et « Château Saint-Martin » se lisait « Château Sain… ».
   Rien ne bouge tant que la page est en haut. */
.tete.compacte .tete-nav { gap: 24px; }
.tete.compacte .onglets { gap: 24px; }
/* Un onglet ne se plie jamais entre son mot et son compteur. */
.tete .onglets a { white-space: nowrap; }
.tete .tete-rappel b {
  font-family: var(--serif); font-weight: 450; font-size: 1.12rem;
  letter-spacing: -0.015em; color: var(--encre);
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.tete .tete-rappel span {
  font-family: var(--serif); font-size: 1.04rem; color: var(--encre-2);
  font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
  padding-left: 13px; border-left: 1px solid var(--trait-fin); align-self: stretch;
}

/* C5 — le nom de la maison se lisait « Château Sain… ». Le rail compacté
   tient les onglets, le rappel et les outils sur une ligne : sous 1400 px
   de conteneur, les trois ne tiennent qu'en rognant le seul des trois qui
   soit un nom propre. Le compte à rebours s'efface le premier — il est dit
   en toutes lettres dans le cartouche, deux lignes plus haut. */
@container (max-width: 1400px) {
  .tete .tete-rappel span { display: none; }
  /* Et, pendant que le rappel est là, le mot « Composition » cède sa place
     au nom de la maison : le menu se lit tout seul, un nom propre coupé, non.
     C'est le même effacement qu'à 1140 px, une largeur plus tôt. */
  .tete.compacte .vues-mot { display: none; }
}

/* ---- Colonne étroite : assistant ouvert, ou fenêtre réduite ---- */
@container (max-width: 1140px) {
  /* Sous cette largeur, le rail ne tient plus les onglets, un nom propre et
     les outils sur une ligne : le rappel s’efface en entier plutôt que de
     couper le nom. Le cartouche, lui, porte toujours la maison. */
  .tete .tete-rappel, .tete.compacte .tete-rappel { display: none; }
  .tete .vues-mot { display: none; }
  .tete .onglets { gap: 20px; }
  .tete .onglets a { font-size: 0.88rem; }
  .tete .tete-outils { gap: 16px; }
  .tete .tete-mention { display: none; }
  .tete .fil, .tete #choix-propriete, .tete #compte-a-rebours b { font-size: 1.9rem; }
}
@container (max-width: 900px) {
  /* Les onglets prenaient leur ligne à eux en débordant SOUS les outils :
     « Validations 3 » passait sous le bouton « Demander » et l'ordre de
     lecture se rompait. Le rail se plie en deux rangs francs. */
  .tete .tete-nav { flex-wrap: wrap; gap: 0; padding-bottom: 8px; }
  .tete .onglets { flex-wrap: wrap; flex: 1 1 100%; padding-top: 4px; }
  .tete .tete-outils { flex: 1 1 100%; justify-content: flex-end; padding-top: 6px; }
  .tete .tete-identite { gap: 24px; }
  /* « PILOTE SUR UNE PROPRIÉTÉ » se coupait au milieu : la mention passe à
     la ligne entière plutôt que de se rompre. */
  .tete .tete-intitule { display: flex; flex-wrap: wrap; gap: 0 12px; }
  /* Sur sa propre ligne, le filet de séparation ne sépare plus rien : il
     ne restait qu'un trait vertical orphelin devant la mention. */
  .tete .fil-mention { flex: 1 1 100%; margin-left: 0; padding-left: 0; border-left: none; }
}

/* =====================================================================
   Les objets nommés, cliquables, et leur aperçu

   Un identifiant qui apparaît dans une phrase n'est pas décoratif :
   il mène à l'objet. On le signale par un soulignement pointillé,
   discret sur un tableau dense, franc au survol.
   ===================================================================== */
.lien-objet {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--trait);
  cursor: pointer;
}
.lien-objet:hover,
.lien-objet:focus-visible {
  color: var(--olivier);
  border-bottom-color: var(--olivier);
  border-bottom-style: solid;
  text-decoration: none;
}
td.id .lien-objet { border-bottom-color: var(--trait-fin); }
.lien-doc { font-weight: 500; }
.lien-discret { font-size: 0.88rem; color: var(--encre-2); }

/* Le cadre d'aperçu : une feuille posée sur la page, jamais une bulle. */
.apercu {
  position: fixed; z-index: 40;
  width: 340px; max-width: calc(100vw - 16px);
  padding: 13px 16px 14px;
  background: var(--surface);
  box-shadow: var(--ombre-2);
  border-top: 2px solid var(--olivier);
  pointer-events: none;
}
.apercu-genre {
  margin: 0; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--encre-2);
}
.apercu-titre {
  margin: 3px 0 9px; font-family: var(--serif);
  font-size: 1.12rem; line-height: 1.2; color: var(--encre);
}
.apercu-liste {
  margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: 3px 14px; font-size: 0.88rem;
}
.apercu-liste dt { color: var(--encre-2); white-space: nowrap; }
.apercu-liste dd { margin: 0; color: var(--encre); }
.apercu-note {
  margin: 10px 0 0; padding-left: 9px; font-size: 0.88rem; line-height: 1.4;
  color: var(--encre-2); border-left: 2px solid var(--trait);
}
.apercu-lien {
  margin: 10px 0 0; padding-top: 8px; border-top: 1px solid var(--trait-fin);
  font-size: 0.8rem; color: var(--encre-2);
}

/* =====================================================================
   Écran : une commande
   ===================================================================== */
.fil-ariane { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 0.92rem; }
.fil-ariane > * + *::before { content: '›'; margin-right: 8px; color: var(--trait); }
.fil-ariane b { font-weight: 600; }
.bloc-colonnes.deux { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.ccm-chaine { margin: 0 0 8px; }
.ccm-chaine > span:first-child { color: var(--encre-2); margin-right: 6px; }
.ccm-action { margin: 14px 0 0; }
.donnees tr.pivot td { font-weight: 600; background: var(--pierre); }

/* =====================================================================
   Écran : les prestataires
   ===================================================================== */
.table-prestataires td { vertical-align: top; }
.table-prestataires .secondaire { display: block; font-size: 0.85rem; }
.puce-espace {
  display: inline-block; margin: 0 4px 4px 0; padding: 1px 7px;
  background: var(--pierre); font-size: 0.82rem; letter-spacing: 0.03em;
  border-bottom: none;
}
.puce-espace:hover { background: var(--olivier-clair); }
.cartes-espaces .carte-espace { display: flex; flex-direction: column; }
.liste-presta { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 12px; }
.liste-presta li {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 12px;
  padding-bottom: 11px; border-bottom: 1px solid var(--trait-fin);
}
.liste-presta li:last-child { border-bottom: none; padding-bottom: 0; }
.presta-roles { display: flex; gap: 5px; justify-self: end; }
.presta-postes { grid-column: 1 / -1; color: var(--encre-2); font-size: 0.88rem; }
.role {
  padding: 1px 7px; font-size: 0.74rem; letter-spacing: 0.05em; text-transform: uppercase;
  background: var(--pierre); color: var(--encre-2);
}
.role-pose { background: var(--olivier-clair); color: var(--olivier); }
.specialites { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.specialites li { padding: 3px 9px; background: var(--pierre); font-size: 0.88rem; }
.synthese-fiche dd { font-size: 1.25rem; }
.synthese-fiche .dd-petit { font-size: 1rem; font-family: var(--sans); }

/* =====================================================================
   Écran 4 : facturation
   ===================================================================== */
/* Le filet entre les tuiles est le fond du conteneur, vu par la gouttière
   d'un pixel. Une case vide laisse donc voir ce fond EN GRAND : sous
   840 px, « auto-fit » posait trois colonnes pour quatre tuiles, et la
   quatrième laissait derrière elle un aplat taupe de deux cases. Le
   compte des colonnes divise désormais toujours celui des tuiles. */
.tuiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1px; background: var(--trait-fin); box-shadow: var(--ombre-1); }
@media (max-width: 900px) { .tuiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .tuiles { grid-template-columns: minmax(0, 1fr); } }
.tuile { display: flex; flex-direction: column; gap: 4px; padding: 16px 20px 18px; background: var(--surface); }
.tuile-libelle { font-size: 0.82rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--encre-2); }
.tuile-valeur { font-family: var(--serif); font-size: 1.75rem; font-weight: 400; letter-spacing: -0.015em; }
.tuile-detail { font-size: 0.88rem; color: var(--encre-2); }
.tuile-ok .tuile-valeur { color: var(--olivier); }
.tuile-alerte { background: var(--ocre-clair); }
.tuile-alerte .tuile-valeur { color: var(--ocre-texte); }

.jauge { display: flex; height: 12px; margin-top: 20px; background: var(--pierre-sombre); }
.jauge-part { display: block; height: 100%; }
.jauge-regle { background: var(--olivier); }
.jauge-attente { background: var(--ocre); }
.legende-jauge { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 24px; font-size: 0.9rem; color: var(--encre-2); }
.legende-jauge i { display: inline-block; width: 10px; height: 10px; margin-right: 7px; }
.legende-jauge b { font-weight: 600; color: var(--encre); }
.pastille-regle { background: var(--olivier); }
.pastille-attente { background: var(--ocre); }
.pastille-reste { background: var(--pierre-sombre); }

.demandes { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--trait-fin); box-shadow: var(--ombre-1); }
.demande { padding: 16px 20px 18px; background: var(--surface); border-left: 3px solid var(--trait); }
.demande-doublon { border-left-color: var(--rouge-profond); }
.demande-service-fait { border-left-color: var(--ocre); }
.demande-validation { border-left-color: var(--olivier); }
.demande-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; }
.demande-numero { font-weight: 600; letter-spacing: 0.02em; }
.demande-qui { color: var(--encre-2); }
.demande-montant { margin-left: auto; font-family: var(--serif); font-size: 1.2rem; }
.demande-motif { margin: 8px 0 0; }
.demande-geste { margin: 4px 0 0; color: var(--encre-2); }
.demande-geste > span { color: var(--encre); font-weight: 500; }
.demande-actions { margin: 13px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.bloc-marche { border-top: 2px solid var(--trait-doux); padding-top: 26px; }

/* =====================================================================
   Écran 5 : validations. Une file à gauche, la décision à droite.
   ===================================================================== */
.travail { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 30px; align-items: start; }
@media (max-width: 1000px) { .travail { grid-template-columns: 1fr; } }
.file { display: grid; gap: 26px; }
.file-groupe h3 { margin: 0 0 4px; font-size: 0.82rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--encre-2); }
.file-aide { margin: 0 0 10px; font-size: 0.88rem; color: var(--encre-2); }
.file-groupe ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--trait-fin); box-shadow: var(--ombre-1); }
.file-item a {
  display: grid; gap: 2px; padding: 12px 14px 13px;
  background: var(--surface); color: inherit; text-decoration: none;
  border-left: 3px solid transparent;
}
.file-item a:hover { background: var(--pierre); text-decoration: none; }
.file-item.actif a { border-left-color: var(--olivier); background: var(--olivier-clair); }
.file-nature { font-size: 0.72rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--encre-2); }
.file-titre { font-weight: 600; }
.file-qui { font-size: 0.88rem; color: var(--encre-2); }
.file-motif { font-size: 0.88rem; color: var(--ocre-texte); }
.file-item.actif .file-motif { color: var(--olivier); }
.file-faites summary {
  cursor: pointer; padding: 4px 0; font-size: 0.82rem; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--encre-2);
}
.file-faites[open] summary { margin-bottom: 10px; }
.file-faites .file-motif { color: var(--encre-2); }
.panneau-decision { min-width: 0; }

/* Un contrôle qui n'est pas encore exigible : ni coche, ni croix. */
.controles li.attendu .coche { color: var(--trait); }
.controles li.attendu .controle-detail { color: var(--encre-2); }

/* La fiche d'un prestataire n'est pas une fiche de décision : ses tableaux
   ont besoin de toute la largeur du rail. */
.fiche-large { max-width: none; }

/* =====================================================================
   Bibles riches : le cadre d'une image

   Trois niveaux, et chacun a une raison. Le CADRE porte le rapport de
   forme, calculé après rotation : c'est lui qui réserve la hauteur, sans
   quoi loading="lazy" ferait sauter la page image après image. Le PIVOT
   porte la rotation et le miroir : à 90 et 270 degrés il prend les côtés
   échangés du cadre, sinon l'image tournée déborderait. L'IMAGE porte les
   quatre formules, qui absorbent aussi bien un recadrage positif (elle
   déborde, le cadre la rogne) qu'un recadrage négatif (elle rétrécit, une
   marge apparaît) — et le classeur contient les deux.

   Arêtes vives, aucun contour : la surface est tenue par son ombre.
   ===================================================================== */
.media { margin: 0; display: grid; gap: 7px; align-content: start; }
.cadre {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--ar, 1);
  background: var(--surface);
  box-shadow: var(--ombre-1);
  border-radius: 0;
}
.cadre-pivot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(100% * var(--pl, 1));
  height: calc(100% * var(--ph, 1));
  transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scaleX(var(--mir, 1));
}
.cadre-pivot img {
  position: absolute;
  display: block;
  width:  calc(100% / (1 - var(--g, 0) - var(--d, 0)));
  height: calc(100% / (1 - var(--h, 0) - var(--b, 0)));
  left:   calc(-100% * var(--g, 0) / (1 - var(--g, 0) - var(--d, 0)));
  top:    calc(-100% * var(--h, 0) / (1 - var(--h, 0) - var(--b, 0)));
}
.media-legende {
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--encre-2);
}
.media-note { display: block; font-style: italic; margin-top: 2px; }
.media-mini { width: 76px; }
.media-vignette { width: 118px; }

/* Une édition ne rejoue pas l'animation d'entrée : app.js pose cette
   classe sur #ecran avant de réécrire la page après une correction. */
#ecran.sans-pose > * { animation: none; }

/* ---------- Bibles riches : une suite ---------- */
/* Un mot du classeur, tel quel, espaces finales comprises : c'est ce qui
   fait que le client reconnaît sa propre feuille. Chasse fixe, pas de bord. */
.brut {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  color: var(--encre-2);
  background: #F4F1EC;
  padding: 1px 7px;
  white-space: pre-wrap;
}
.selecteur-bibles { margin-top: -12px; }
.selecteur-bibles > a { font-weight: 500; }

.piece-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.piece-tete .titre-bloc { margin-bottom: 0; }
.piece-mesure { margin: 0; color: var(--encre-2); display: flex; align-items: baseline; gap: 10px; }

.vues-piece { display: flex; flex-wrap: wrap; gap: 16px; margin: 18px 0 26px; }
.vues-piece .media-vue { width: 260px; }

.fiche-courte { margin-top: 26px; }
.fiche-courte-titre {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 0 0 8px; font-family: var(--serif); font-size: 1.12rem; font-weight: 480;
}
.fiche-courte-titre a { color: var(--encre); }
.liste-elements { list-style: none; margin: 0; padding: 0; background: var(--surface); box-shadow: var(--ombre-1); }
.liste-elements li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: baseline;
  gap: 4px 14px;
  padding: 11px 18px;
  border-bottom: 1px solid var(--trait-fin);
}
.liste-elements li:last-child { border-bottom: none; }
.liste-elements li > a { font-weight: 500; }
.element-compte { white-space: nowrap; font-size: 0.9rem; }
.element-statut { white-space: nowrap; font-size: 0.9rem; color: var(--encre-2); }
.element-statut em { font-style: italic; color: var(--ocre-texte); }

@media (max-width: 800px) {
  .liste-elements li { grid-template-columns: minmax(0, 1fr); }
  .vues-piece .media-vue { width: 100%; }
}

/* =====================================================================
   Les cartes posées — arbitrage du 22 septembre 2026

   « Les encadrés manquent », « les sections se touchent » : une section de
   bible s'ouvrait par un filet de 1,11:1 sur la pierre, c'est-à-dire par
   rien. Elle devient une surface blanche posée sur le fond teinté, tenue
   par son ombre, à arêtes vives, avec beaucoup d'air entre elles.

   La règle ne vaut QUE pour les écrans de bible. Les écrans historiques
   plaisent et restent l'étalon : ils gardent leurs filets et leur air.

   Une seule ombre par niveau : ce qui vit DANS une carte — un tableau, une
   liste d'éléments, un constat, un composant — perd la sienne et se sépare
   par un filet ou par de l'espace.
   ===================================================================== */
.ecran-bibles .bloc {
  margin-top: 26px;
  padding: 26px 30px 30px;
  border-top: none;
  background: var(--surface);
  box-shadow: var(--ombre-1);
}
.ecran-bibles .bloc .titre-bloc { margin-bottom: 20px; }

/* Ce qui vit dans une carte n'en est pas une autre. */
.ecran-bibles .bloc table.donnees,
.ecran-bibles .bloc .liste-elements,
.ecran-bibles .bloc .cartouche,
.ecran-bibles .bloc .synthese,
.ecran-bibles .bloc .constats { box-shadow: none; background: none; }
.ecran-bibles .bloc .cartouche { padding: 0; }
.ecran-bibles .bloc .liste-elements { background: none; }
.ecran-bibles .bloc .constats { gap: 0; }
.ecran-bibles .bloc .constat { border-bottom: 1px solid var(--trait-fin); }
.ecran-bibles .bloc .constat:last-child { border-bottom: none; }
/* Un tableau large garde sa barre de défilement DANS la carte, et son
   premier filet d'en-tête sert de bord haut. */
.ecran-bibles .bloc .table-large { margin: 0 -30px; padding: 0 30px; }

/* Le composant devient une rangée de la carte de l'élément, et non plus
   une dalle blanche à bord perdu collée par une marge d'un pixel. */
.ecran-bibles .bloc-element .composant {
  background: none; box-shadow: none;
  margin: 0; padding: 20px 0 22px;
  border-top: 1px solid var(--trait-fin);
}
.ecran-bibles .bloc-element .composant + .composant { border-top: 1px solid var(--trait-fin); }
.ecran-bibles .bloc-element .element-tete + .composant { border-top: 1px solid var(--trait-doux); }
.ecran-bibles .bloc-element .composant-enfant {
  margin-left: 24px; padding-left: 22px;
  border-left: 3px solid var(--olivier-clair);
}

/* Deux colonnes dès 1100 px : le corps à gauche, les vignettes et les
   adresses de cellule à droite, dans une colonne qui ne descend jamais
   sous 300 px — les légendes tombaient en colonnes de deux mots. */
.ecran-fiche .composant { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1100px) {
  .ecran-fiche .composant { grid-template-columns: minmax(0, 1fr) minmax(300px, 0.4fr); }
}
.ecran-bibles .composant-vignettes { justify-content: flex-start; gap: 16px; }
/* Une vignette se calait sur sa HAUTEUR — 180 px —, et la largeur suivait
   le rapport de forme. Le recadrage de la frange du canapé est trois fois
   plus large que haut : 542 px dans une colonne de 300, donc une image qui
   sortait de la carte et une BARRE DE DÉFILEMENT HORIZONTALE DE PAGE.
   Même rangée justifiée que les vues d'une pièce : la largeur est celle de
   la colonne, la hauteur suit le rapport de forme, rien ne déborde. */
.ecran-bibles .composant-vignettes .media { min-width: 0; }
.ecran-bibles .composant-vignettes .media-vignette {
  flex: var(--ar, 1) 1 0;
  min-width: 118px; max-width: 100%;
}
.ecran-bibles .composant-vignettes .media-vignette .cadre { height: auto; width: 100%; }
/* G3 — la légende d'une vignette n'est plus bornée à 250 px : elle tombait
   en colonnes de deux à trois mots sur huit lignes. Elle prend la largeur
   de la colonne qui la porte, laquelle ne descend jamais sous 300 px. */
.ecran-bibles .composant-vignettes .media-legende,
.ecran-suite .vues-piece .media-legende { max-width: none; }
.media-note { font-size: 0.84rem; }

/* G4 — les vues d'une pièce tenaient dans 260 px, puis dans une hauteur
   commune de 300 px, et laissaient jusqu'à 440 px de beige à droite.
   La rangée se justifie : chaque vue grandit à la mesure de son rapport de
   forme, les deux gardent la même hauteur, et la rangée remplit la carte.
   C'est « --ar », posé sur la figure par cadreMedia, qui fait la répartition
   — sans quoi un portrait et un paysage ne peuvent pas se partager une
   ligne sans que l'un des deux devienne une affiche. */
.ecran-suite .vues-piece {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 20px; margin: 20px 0 30px;
}
.ecran-suite .vues-piece .media { min-width: 0; }
.ecran-suite .vues-piece .media-vue {
  flex: var(--ar, 1) 1 0;
  min-width: 260px; max-width: 100%;
}
.ecran-suite .vues-piece .media-vue .cadre { height: auto; width: 100%; }
/* La répartition par « --ar » donne deux hauteurs égales tant que chaque
   vue reçoit la largeur que sa forme demande. Sous ~1060 px, la largeur
   minimale de 260 px reprend la main sur le portrait, le paysage rétrécit
   pour compenser, et il restait sous lui un trou blanc de trois cents
   pixels au milieu de la carte. À cette largeur, les vues s'empilent. */
@media (max-width: 1060px) {
  .ecran-suite .vues-piece .media-vue { flex: 1 1 100%; min-width: 0; }
}

/* La hiérarchie des titres : quatre niveaux dont les deux derniers étaient
   indiscernables. Le titre de fiche remonte, celui de composant descend. */
.ecran-bibles .titre-ecran { font-size: 2.1rem; }
.ecran-bibles .titre-bloc { font-size: 1.34rem; }
.ecran-suite .fiche-courte { margin-top: 30px; }
.ecran-suite .fiche-courte-titre {
  font-family: var(--sans); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--encre-2);
}
.ecran-suite .fiche-courte-titre a { color: var(--encre-2); }
.ecran-bibles .composant-titre { font-size: 1rem; font-family: var(--sans); font-weight: 600; }

/* Le tableau des matières : les en-têtes ne se figent plus en une ligne,
   et chaque colonne reçoit la place que son contenu demande — « Matière »
   et « Employée par » cassaient sur trois lignes à toutes les largeurs
   pendant que « Laize » gardait de l'air. */
.table-matieres { table-layout: fixed; }
/* Sept colonnes, dont trois en-têtes d'un seul mot long : sous mille
   pixels, « DISPONIBILITÉ » mordait sur sa voisine. Le tableau défile
   dans son bloc — il ne se comprime pas au point de mentir. */
.table-large .table-matieres { min-width: 1010px; }
.table-matieres th { white-space: normal; }
/* La dernière colonne porte « 3 composants · 1 pièce · 1 lieu » : sous
   24 %, le mot « lieu » tombait seul à la ligne sur presque chaque rang.
   Les trois points de comptage tiennent désormais sur une ligne. */
.table-matieres th:nth-child(1) { width: 8%; }
.table-matieres th:nth-child(2) { width: 18%; }
.table-matieres th:nth-child(3) { width: 11%; }
.table-matieres th:nth-child(4) { width: 12%; }
.table-matieres th:nth-child(5) { width: 14%; }
.table-matieres th:nth-child(6) { width: 12%; }
.table-matieres th:nth-child(7) { width: 25%; }
.matiere-nom { display: inline; font-weight: 500; }

/* « Ajouter un composant » était un <a href="#"> nu posé sur le beige. */
.ajout-hote { margin-top: 16px; }
.ajout-hote > a {
  display: inline-block; padding: 8px 16px; min-height: 40px; line-height: 24px;
  background: var(--surface); box-shadow: var(--ombre-1);
  color: var(--olivier); font-size: 0.92rem;
}
.ajout-hote > a:hover { text-decoration: none; background: var(--olivier-clair); }

/* ---------- Le cartouche d'un écran de bible ----------
   Une surface blanche posée sous le rail : elle dit où l'on est — maison,
   bible, pièce, fiche — et l'état du calque de corrections. C'est le seul
   endroit de la partie Bibles où l'on retrouve, d'un coup d'œil, le chemin
   par lequel on est arrivé et celui par lequel on repart. */
.cartouche-ecran {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 10px 28px; justify-content: space-between;
  margin-bottom: 32px; padding: 14px 22px 15px;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.cartouche-ecran-fil { display: grid; gap: 12px; min-width: 0; }
/* Les pièces d'une suite : des chips plats, sans bord d'un pixel, dans le
   cartouche — et non plus un troisième rang de boîtes avant le titre. */
.selecteur-pieces {
  margin: 0; padding: 0; border-bottom: none; gap: 6px;
}
.selecteur-pieces > a {
  border: 0; box-shadow: none; padding: 9px 14px; min-height: 44px;
  background: var(--pierre); font-size: 0.92rem;
}
.selecteur-pieces > a:hover { background: var(--olivier-clair); }
.selecteur-pieces > a.actif { background: var(--olivier); color: #fff; }
.cartouche-ecran:empty { display: none; }
.fil-ariane ol {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 10px;
}
.fil-ariane li { display: flex; align-items: baseline; gap: 10px; font-size: 0.92rem; }
.fil-ariane li + li::before { content: '›'; color: var(--encre-2); }
.fil-ariane li:last-child span { font-weight: 600; }
.fil-ariane a { color: var(--encre-2); }
.fil-ariane a:hover, .fil-ariane a:focus-visible { color: var(--olivier); }

/* Le titre « Nouvelle bible » est un h2 et non un h4 : le tableau des
   bibles n'a pas de niveau intermédiaire à sauter. */
.ajout .ajout-titre {
  margin: 0; font-family: var(--sans); font-size: 0.72rem;
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 600; color: var(--encre-2);
}

/* L'écran prend le foyer à chaque changement de route, pour que le clavier
   reparte de la page et non du haut du document. Ce foyer-là s'annonce,
   il ne se dessine pas : le contour reste aux éléments qu'on manipule. */
#ecran:focus { outline: none; }

/* ---------- Bibles riches : une fiche ----------
   Une seule colonne : la condition réelle de démonstration est deux
   fenêtres côte à côte, 700 à 960 px. Le composant a sa surface ; le
   cartouche, l'élément et la section n'en ont pas. */
/* Le mortier d'un pixel laissait voir son fond gris partout où la dernière
   rangée n'était pas pleine : huit champs sur cinq colonnes font toujours
   une case en trop. Une seule surface, et de l'air entre les champs. */
.cartouche {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 20px 34px;
  margin: 0;
  padding: 22px 26px;
  background: var(--surface);
  box-shadow: var(--ombre-1);
}
.cartouche-champ { display: grid; gap: 2px; padding: 0; }
.cartouche-champ dt { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--encre-2); }
.cartouche-champ dd { margin: 0; font-weight: 500; }
.cartouche-champ small { color: var(--encre-2); font-size: 0.8rem; }

.element-tete { margin-bottom: 14px; }
.element-tete .titre-bloc { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.element-ligne { margin: 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }

.composant {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 18px;
  align-items: start;
  padding: 16px 20px 18px;
  margin-top: 1px;
  background: var(--surface);
  box-shadow: var(--ombre-1);
}
/* Le passepoil, le tissu et la frange pendent de la structure : le lien de
   parenté se lit d'un coup d'œil, sans indentation à l'infini. */
.composant-enfant { margin-left: 26px; border-left: 3px solid var(--olivier-clair); }
.composant-corps { display: grid; gap: 7px; min-width: 0; }
.composant-titre {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 0; font-family: var(--serif); font-size: 1.1rem; font-weight: 480;
}
.composant-designation { margin: 0; }
.composant-reference, .composant-matiere, .composant-societes { margin: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.composant-matiere a { color: var(--olivier); font-weight: 500; }
.composant-societes { gap: 14px; }
.societe { display: inline-flex; align-items: baseline; gap: 6px; }
.societe em { font-style: italic; }
.composant-mesures { display: grid; gap: 7px; margin: 2px 0 0; padding-top: 9px; border-top: 1px solid var(--trait-fin); }
/* L'adresse de cellule suit la valeur ; elle était rejetée à 900 px de là,
   à l'extrémité droite de la dalle, et on ne reliait plus les deux. */
/* Deux corrections dans la même ligne, et elles vont ensemble :
   — la colonne de la valeur passe de « auto » à « minmax(0, auto) », sinon
     elle ne descend jamais sous sa largeur minimale et une liste de
     dimensions pousse tout le reste hors de la rangée ;
   — la colonne de l'adresse passe de « minmax(0, 1fr) » à
     « minmax(min-content, 1fr) », sinon la valeur lui prend toute la place
     et l'adresse, réduite à zéro, débordait de 22 px SOUS la vignette
     voisine. Mesuré : 150 / 583 / 0 avant, 150 / 561 / 22 après. */
.composant-mesures > div { display: grid; grid-template-columns: 150px minmax(0, auto) minmax(min-content, 1fr); gap: 10px 14px; align-items: baseline; }
.composant-mesures .cellule { justify-self: start; }
.composant-mesures dt { color: var(--encre-2); }
.composant-mesures dd { margin: 0; font-variant-numeric: tabular-nums; }
.composant-vignettes { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

/* L'adresse d'une cellule : en chasse fixe, toujours, pour qu'on la
   retrouve dans le classeur sans la relire deux fois. */
.cellule {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.78rem; color: var(--encre-2); white-space: nowrap;
}
.cellules { margin-top: 4px; }
.cellules summary {
  cursor: pointer; padding: 3px 0;
  font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--encre-2);
}
.cellules[open] summary { margin-bottom: 7px; }
.cellules-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.cellules-liste li { display: grid; grid-template-columns: 58px 160px minmax(0, 1fr); gap: 10px; align-items: baseline; color: var(--encre-2); }
.cellules-liste .cellule-libelle { font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; font-size: 0.78rem; }
/* La valeur est montrée telle quelle, guillemets compris : une espace
   finale doit se voir, c'est souvent elle le constat. */
.cellules-liste .cellule-valeur { white-space: pre-wrap; color: var(--encre); }

.photo-situation { display: grid; gap: 16px; margin-bottom: 26px; }
.photo-situation .media-large { max-width: 760px; }
.aussi-visible h4 { margin: 0 0 6px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--encre-2); }
.aussi-visible ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 10px; }
.aussi-visible li a { color: var(--olivier); }
.note-diffusion { color: var(--ocre-texte); }

@media (max-width: 820px) {
  .composant { grid-template-columns: minmax(0, 1fr); }
  .composant-vignettes { justify-content: flex-start; }
  .composant-mesures > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .cellules-liste li { grid-template-columns: 58px minmax(0, 1fr); }
}

/* ---------- Bibles riches : les matières ---------- */
/* Les colonnes sont étroites et les noms de maison sont longs. En
   coupure libre, « Passementeries » devenait « Passementeri / es » ;
   la césure de la langue de l'écran coupe où il faut. */
.table-matieres td { vertical-align: top; hyphens: auto; }
/* La colonne du visuel est en PIXELS, pas en pourcentage : la vignette
   mesure 76 px quoi qu'il arrive, et sous 1100 px une colonne en
   pourcentage passait sous les 76 px — l'image débordait alors sur le
   nom de la matière, dont la première lettre disparaissait dessous. */
.table-matieres .cellule-vignette { padding-top: 10px; padding-bottom: 10px; }
.table-matieres .cellule-vignette .cadre,
.table-matieres .cellule-vignette .media-mini { width: 68px; max-width: 100%; }
.matiere-nom { font-weight: 500; }
.table-matieres .secondaire { display: block; font-size: 0.85rem; }
/* La colonne Laize est une colonne de nombres, donc insécable — mais
   « non renseignée » n'est pas un nombre : il débordait sur la colonne
   voisine au lieu de passer à la ligne. */
.table-matieres td.num .secondaire { white-space: normal; }
/* La contradiction se voit sans se lire : une valeur, l'autre, et la cellule
   où elle a été vue. La machine ne tranche pas à la place de qui sait. */
.ecart-laize[hidden] { display: none; }
.ecart-laize {
  display: block;
  /* Sans borne, la phrase rouge etire la colonne Laize de cent soixante
     pixels et pousse « Employee par » hors du cadre vers 1020 px. */
  max-width: 20ch;
  /* L'adresse de la cellule est un seul mot de vingt caractères, et la
     colonne des laizes est insécable : sans ces deux lignes, la phrase
     rouge sortait du tableau au lieu de passer à la ligne. */
  white-space: normal;
  overflow-wrap: break-word;
  margin-top: 3px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--rouge-profond);
}
/* Le référentiel est commun à TOUS LES LIEUX, et ça doit se voir : sous le
   compte, les lieux où la matière est employée, chacun menant à un emploi
   dans ce lieu-là. Des liens en file, sans boîte ni liseré : la colonne est
   déjà dense. */
.emplois-compte { display: block; }
.emplois-lieux { display: block; margin-top: 3px; font-size: 0.85rem; }
.emplois-lieux .emploi-lieu { display: block; color: var(--encre-2); }
.emplois-lieux .emploi-lieu + .emploi-lieu { margin-top: 1px; }
/* Une matière qui traverse plus d'un lieu est le cas qui vend : elle se
   distingue par un filet couché à l'ocre, comme la ligne à risque se
   distingue par le sien, sans jamais poser de liseré d'un pixel. */
tr.ligne-partagee td:last-child { box-shadow: inset 3px 0 0 var(--ocre); }
tr.ligne-partagee .emplois-compte { font-weight: 500; }
tr.ligne-partagee .emplois-lieux .emploi-lieu { color: var(--ocre-texte); }

/* ---------- Bibles riches : à vérifier ---------- */
.constats { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--trait-fin); box-shadow: var(--ombre-1); }
.constat {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 4px 20px;
  padding: 13px 18px;
  background: var(--surface);
  border-left: 3px solid var(--trait);
}
.constat-haute { border-left-color: var(--rouge-profond); }
.constat-moyenne { border-left-color: var(--ocre); }
.constat-basse { border-left-color: var(--encre-2); }
.constat-clos { color: var(--encre-2); }
.constat-cible { margin: 0; display: grid; gap: 1px; }
.constat-cible a { font-weight: 500; }
.constat-cible .secondaire { font-size: 0.85rem; }
.constat-dit { margin: 0; }
.constat-trace { grid-column: 2; margin: 2px 0 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; font-size: 0.88rem; }
/* L'état est l'information de l'écran : deux chips du même gris ne la
   donnaient pas. Ouvert se tient en ocre, traité et relu s'effacent en
   olivier, sans suite se range dans la pierre. */
.constat .role { background: var(--ocre-clair); color: var(--ocre-texte); }
.constat-clos .role { background: var(--olivier-clair); color: var(--olivier); }
.constat[data-etat="sans suite"] .role { background: var(--pierre); color: var(--encre-2); }

/* Les trois gestes d'un constat ouvert. Ils se posent sous la trace, dans
   la colonne du texte : la première colonne dit ce qui est visé, la seconde
   ce qu'on en fait. Ni boîte, ni bord : des mots soulignés et, quand il y a
   une valeur à corriger, la valeur elle-même. */
.constat-gestes {
  grid-column: 2; margin: 9px 0 0;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 22px;
  font-size: 0.9rem;
}
.constat-gestes[hidden] { display: none; }
.constat-corriger { display: inline-flex; align-items: baseline; gap: 9px; }
.constat-mot { color: var(--encre-2); }
/* La cible tactile des deux décisions vaut celle des onglets. */
.constat-gestes .bouton-lien { min-height: 26px; padding: 3px 0; }
.constat-clos .constat-gestes { display: none; }
.completude dd { font-variant-numeric: tabular-nums; }

@media (max-width: 820px) {
  .constat { grid-template-columns: minmax(0, 1fr); }
  .constat-trace, .constat-gestes { grid-column: 1; }
}

/* =====================================================================
   L'édition en place : corriger une valeur sans quitter l'écran.

   Une valeur corrigeable n'est pas une boîte : c'est le texte lui-même,
   qui gagne un crayon au survol et un champ à la même taille au clic.
   Aucun bord d'un pixel, aucune arête arrondie, aucune animation neuve :
   @keyframes pose reste la seule chose qui bouge dans la page.
   ===================================================================== */
.valeur { position: relative; display: inline-block; }
.valeur-bouton {
  font: inherit; color: inherit; background: none;
  border: 0; border-radius: 0; padding: 0; margin: 0;
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 5px 4px; margin: -5px -4px;
  text-align: left; cursor: pointer;
}
.valeur-bouton:hover { background: var(--pierre); }
/* display: inline-flex l'emporte sur l'attribut hidden : sans cette ligne,
   la valeur resterait lisible à côté du champ qui la remplace. */
.valeur-bouton[hidden] { display: none; }
.valeur-bouton:focus-visible { outline: 2px solid var(--olivier); outline-offset: 2px; }
.valeur-crayon {
  width: 12px; height: 12px; flex: none; color: var(--encre-2);
  /* Invisible au repos, une valeur corrigeable est typographiquement
     identique à une valeur figée : personne dans la salle ne voit que
     quelque chose était modifiable. Le crayon se devine, puis se donne. */
  opacity: 0.45; transition: opacity var(--geste);
}
.valeur-bouton:hover .valeur-crayon,
.valeur-bouton:focus-visible .valeur-crayon { opacity: 1; }
.valeur-saisie {
  font: inherit; color: inherit; background: var(--surface);
  border: 0; border-radius: 0; box-shadow: var(--ombre-1);
  padding: 1px 6px; min-width: 52px;
}
.valeur-saisie:focus { outline: 2px solid var(--olivier); outline-offset: 0; }
.valeur-mention { display: block; font-size: 0.85rem; color: var(--encre-2); }
.valeur-ecart { display: block; font-size: 0.85rem; color: var(--rouge-profond); }
.valeur-mention:empty, .valeur-ecart:empty { display: none; }
/* Le bandeau POUSSE le flux, il ne se pose plus dessus : en position
   absolue il recouvrait le composant suivant et, dans un tableau, débordait
   sur deux colonnes à gauche de la valeur qu'il commente. */
.valeur-bandeau {
  display: block; margin: 7px 0 0;
  padding: 9px 13px; max-width: 48ch;
  background: var(--surface); box-shadow: var(--ombre-2);
  font-size: 0.88rem; line-height: 1.4; color: var(--encre-2); text-align: left;
}
/* Le cartouche du calque : un état, pas une alerte. Il vivait dans
   l'en-tête, qui défile : sur une bible, le geste d'export se retrouvait
   hors champ. Il vit désormais dans le cartouche de l'écran. */
.tete-calque {
  margin: 0; display: flex; flex-wrap: wrap; gap: 14px;
  align-items: baseline; font-size: 0.85rem; color: var(--encre-2);
}
.tete-calque .en-attente { color: var(--ocre-texte); }
.bouton-lien {
  font: inherit; color: var(--olivier); background: none;
  border: 0; border-radius: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.bouton-lien:hover { color: var(--encre); }
/* Le panneau d'export : une feuille posée sur la page, au-dessus de l'aperçu. */
.export {
  position: fixed; right: 24px; bottom: 24px; z-index: 50;
  width: min(560px, calc(100vw - 48px)); max-height: calc(100vh - 48px);
  overflow: auto; display: grid; gap: 12px;
  padding: 20px 22px 22px;
  background: var(--surface); box-shadow: var(--ombre-2);
  border-top: 2px solid var(--olivier);
}
.export[hidden] { display: none; }
.export h2 { margin: 0; font-size: 1.2rem; }
.export p { margin: 0; font-size: 0.92rem; color: var(--encre-2); }
.export p.export-alerte { color: var(--ocre-texte); }
.export summary {
  cursor: pointer; padding: 4px 0; font-size: 0.82rem;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--encre-2);
}
.export textarea {
  width: 100%; min-height: 200px; margin-top: 8px; padding: 10px 12px;
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; font-size: 0.8rem;
  border: 0; border-radius: 0; box-shadow: var(--ombre-1); resize: vertical;
  background: var(--pierre); color: var(--encre);
}
.export-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* =====================================================================
   Les maisons citées par les bibles.

   Une maison n'est pas une fiche de prestataire : pas de surface, pas de
   pastilles d'action, rien qui laisse croire qu'on peut lui passer
   commande. Une ligne, un filet, et ce qu'elle fournit.
   ===================================================================== */
.maisons { list-style: none; margin: 0; padding: 0; }
.maison { padding: 14px 0; background: linear-gradient(var(--trait), var(--trait)) top / 100% 1px no-repeat; }
.maison:first-child { background: none; }
.maison-nom { font-family: "Newsreader", Georgia, serif; font-size: 1.05rem; }
.maison-metier {
  margin-left: 10px; font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--encre-2);
}
.maison-note { margin: 6px 0 0; color: var(--encre-2); max-width: 70ch; }
.maison-detail { margin: 6px 0 0; font-size: 0.92rem; }
.maison-detail > span:first-child {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--encre-2); margin-right: 8px;
}
.liste-simple { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }

/* Le tableau des bibles : une ligne par bible, pas de surface par
   ligne. Le filet sépare, l'ombre porte l'ensemble. */
.table-bibles { width: 100%; border-collapse: collapse; background: var(--surface); box-shadow: var(--ombre-1); }
.table-bibles th, .table-bibles td { text-align: left; padding: 10px 14px; vertical-align: top; }
.table-bibles thead th {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--encre-2); font-weight: 400;
}
/* Le filet par un dégradé d'un pixel : une ombre intérieure sur une
   cellule laisse deviner ses flancs à certains zooms. */
.table-bibles tbody tr + tr td { background: linear-gradient(var(--trait), var(--trait)) top / 100% 1px no-repeat; }
.table-bibles th:nth-child(n + 4), .table-bibles td:nth-child(n + 4) { text-align: right; font-variant-numeric: tabular-nums; }
/* Les trois premières colonnes portent des NOMS — « Villa Le Ponant »,
   « Hôtel du Cap-Eden-Roc » —, les six autres des nombres courts. Sans
   cette répartition, les noms se coupaient en deux pendant que les
   chiffres gardaient du mou. */
.table-bibles th:nth-child(1) { width: 15%; }
.table-bibles th:nth-child(2) { width: 17%; }
.table-bibles th:nth-child(3) { width: 11%; }
.table-bibles td:nth-child(-n + 3) { hyphens: auto; }

/* La carte vierge d'un composant neuf. Une surface, pas une boîte ;
   arêtes vives ; aucune animation propre. */
.ajout {
  background: var(--surface); box-shadow: var(--ombre-1); padding: 14px 16px;
  margin-top: 10px; display: grid; gap: 10px;
}
.ajout h4 {
  margin: 0; font-size: 0.72rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--encre-2); font-weight: 400;
}
.ajout label { display: grid; grid-template-columns: 120px 1fr; gap: 10px; align-items: center; }
.ajout label > span { font-size: 0.9rem; color: var(--encre-2); }
/* Des surfaces, pas des creux gris : trois rectangles de pierre vides ne
   ressemblaient à rien d'autre dans le démonstrateur. */
.ajout input, .ajout select {
  font: inherit; color: var(--encre); padding: 9px 12px;
  border: 0; border-radius: 0;
  background: var(--surface); box-shadow: var(--ombre-1);
}
.ajout select { padding-right: 34px; background: var(--surface) var(--chevron) no-repeat right 12px center; }
.ajout input:focus, .ajout select:focus { outline: 2px solid var(--olivier); outline-offset: 0; }
.ajout-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ajout-mention { color: var(--encre-2); font-size: 0.9rem; }
.ajout-hote { margin-top: 10px; font-size: 0.92rem; }
/* La phrase dite au lecteur d’écran après un ajout : hors du flux. */
.annonce { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Les poignées de cadrage. Elles vivent sous l'image, à côté du <figure>
   que chaque cran réécrit : rien à rebrancher après un rendu. */
.cadrage-hote { margin-top: 8px; }
.cadrage { display: grid; gap: 6px; margin-top: 8px; font-size: 0.85rem; }
.cadrage label { display: grid; grid-template-columns: 62px 1fr; gap: 8px; align-items: center; }
.cadrage label > span { color: var(--encre-2); }
.cadrage input[type=range] { width: 100%; accent-color: var(--olivier); }
.cadrage-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.export-alerte { color: var(--rouge-profond); margin: 10px 0 4px; }
.export-assume { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }

/* « Reprise, à confirmer » : du gris, pas une alerte. Ce n'est pas une
   faute, c'est une valeur qui attend son humain. */
.repris {
  display: inline-flex; align-items: baseline; gap: 8px; margin-left: 10px;
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--encre-2);
}

/* =====================================================================
   L'écran d'import : reprendre un classeur existant

   Le même système que le reste de la partie Bibles — des cartes blanches
   posées sur le fond teinté, tenues par leur ombre, arêtes vives, un seul
   rail. Ce qui vit DANS une carte n'en est pas une autre : le déroulé, les
   listes et les groupes de constats se séparent par un filet, jamais par
   une seconde ombre.

   Rien ne bouge ici que @keyframes pose, et le déroulé ne la rejoue pas :
   il s'allonge par ajout au DOM, sans que l'écran soit redessiné.
   ===================================================================== */

/* La zone de dépôt. Deux voies, et le bouton est VISIBLE : le glisser ne
   marche pas partout — écran partagé, machine distante, tablette. */
.import-depot { text-align: center; padding: 56px 30px 48px; }
.import-depot.survol { background: var(--olivier-clair); }
.import-depot-titre {
  margin: 0; font-family: var(--serif); font-size: 1.7rem; font-weight: 420;
  letter-spacing: -0.01em;
}
.import-depot-ou {
  margin: 14px 0 12px; color: var(--encre-2);
  font-size: 0.76rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.import-depot-choix { margin: 0; }
.import-depot .note { margin-top: 18px; }
/* Le champ reste dans le flux et reste focalisable : c'est le <label> qui
   porte l'apparence, et le foyer du champ se voit SUR le label. */
.import-fichier {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%);
}
.import-depot label[for="import-fichier"] { cursor: pointer; }
.import-fichier:focus-visible + label {
  outline: 2px solid var(--encre); outline-offset: 2px;
}

/* Le fichier déposé, sa voie de décompression, ses durées. */
.import-fichier-nom {
  margin: 0 0 6px; font-family: var(--serif); font-size: 1.25rem; font-weight: 460;
}
.import-voie { margin: 0; color: var(--encre-2); font-size: 0.95rem; }

/* Le déroulé : une rangée par onglet, séparée par un filet. */
.import-deroule { list-style: none; margin: 20px 0 0; padding: 0; }
.import-onglet {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3px 24px; padding: 12px 0; border-top: 1px solid var(--trait-fin);
}
.import-onglet:first-child { border-top: 1px solid var(--trait-doux); }
.import-onglet p { margin: 0; }
.import-onglet-nom { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; }
.import-onglet-rang {
  min-width: 26px; text-align: right; color: var(--encre-2);
  font-variant-numeric: tabular-nums; font-size: 0.88rem;
}
.import-onglet-lu { grid-column: 2; grid-row: 1; color: var(--encre-2); font-size: 0.9rem; }
.import-onglet-compte {
  grid-column: 1 / -1;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 18px;
  padding-left: 36px; font-size: 0.9rem; color: var(--encre-2);
}
.import-onglet-compte .import-oui { color: var(--olivier); }
.import-onglet-compte .import-non { color: var(--ocre-texte); }
.import-onglet-compte .import-points { color: var(--rouge-profond); }

/* Le bilan : les comptes du journal, en grand, et rien de recalculé.
   Huit chiffres empilés font une liste qu'on ne lit pas ; posés en rangée,
   ils se comparent d'un coup d'œil. Le filet passe alors entre les colonnes
   comme entre les rangées, et la dernière n'en porte pas. */
.import-comptes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.import-comptes > div { border-bottom: none; border-top: 1px solid var(--trait-fin); }
.import-comptes dd { font-variant-numeric: tabular-nums; }
.import-comptes small { min-height: 1.4em; }

/* Les constats, par gravité puis par type. La barre de gauche est la même
   que sur l'écran « À vérifier » : rouge profond, ocre, encre. */
.import-gravite { margin-top: 22px; padding-left: 16px; border-left: 3px solid var(--trait); }
.import-gravite-haute { border-left-color: var(--rouge-profond); }
.import-gravite-moyenne { border-left-color: var(--ocre); }
.import-gravite-basse { border-left-color: var(--encre-2); }
.import-gravite-titre {
  margin: 0 0 10px; font-family: var(--sans); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--encre-2);
}
.import-type { padding: 10px 0; border-top: 1px solid var(--trait-fin); }
.import-type:first-of-type { border-top: none; padding-top: 0; }
.import-type-nom {
  margin: 0 0 5px; display: flex; align-items: baseline; gap: 10px; font-weight: 600;
}
.import-listes { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.import-listes li {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 5px 14px;
  font-size: 0.95rem;
}
.import-dit { min-width: 0; }

/* Le rapprochement au référentiel partagé. Une matière n'existe qu'une
   fois : ce bloc montre celles que le référentiel connaissait déjà, et,
   à part, celles dont la machine doute. Même trame que les constats —
   un rail à gauche pour le doute, des rangs séparés par un trait fin,
   aucune boîte. */
.import-rapprochement .import-listes { margin-top: 16px; }
.import-rapprochement .import-listes li {
  padding: 7px 0; border-top: 1px solid var(--trait-fin);
}
.import-rapprochement .import-listes li:first-child { border-top: none; padding-top: 0; }
/* Trois colonnes qui s'alignent d'un rang à l'autre : ce qui est écrit
   dans le classeur, la matière du référentiel, et ce qu'on en dit. En
   vrac, l'œil ne peut pas comparer deux graphies. */
.import-rapprochees li {
  display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 0.8fr) minmax(0, 1.05fr);
  gap: 3px 18px; align-items: baseline;
}
.import-rapprochees .brut,
.import-rapprochees .lien-objet { justify-self: start; min-width: 0; }
.import-rapprochement .import-dit { color: var(--encre-2); }
.import-doute {
  margin-top: 24px; padding-left: 16px; border-left: 3px solid var(--ocre);
}
.import-doute .vide { margin: 0; }
.import-doute .import-listes li {
  display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.75fr);
  gap: 3px 18px; align-items: baseline;
}
.import-doute .brut { justify-self: start; }
.import-rap-neuves { margin: 20px 0 0; color: var(--encre-2); }

/* Sous 980 px, les colonnes s'empilent : la graphie lue, le nom retenu,
   puis ce qu'on en dit. Au-dessus, elles restent côte à côte, et l'œil
   compare une graphie à l'autre d'un rang au suivant. */
@media (max-width: 980px) {
  .import-rapprochees li,
  .import-doute .import-listes li { grid-template-columns: minmax(0, 1fr); }
}

/* Ce qui n'a pas été compris. C'est la moitié de l'argument : rien n'est
   deviné, et ce qui n'est pas rangé est montré tel qu'il est écrit. */
.import-nonreconnu .import-listes { margin-top: 14px; }

/* Les deux gestes de fin. */
.import-actions {
  margin: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px;
}
.import-posee {
  margin: 0 0 16px; font-family: var(--serif); font-size: 1.3rem; font-weight: 460;
}
.import-echec-dit { margin: 10px 0 18px; max-width: 76ch; }

@media (max-width: 820px) {
  .import-onglet { grid-template-columns: minmax(0, 1fr); }
  .import-onglet-lu { grid-column: 1; grid-row: auto; }
  .import-onglet-compte { padding-left: 0; }
  .import-depot { padding: 36px 22px 30px; }
  .import-comptes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
