/* Berdin Dossiers — feuille de style (v6.0)
   Couleurs : fond gris-vert, encre, accent « bleu tampon ». Polices auto-hébergées. */

@font-face { font-family: "Archivo"; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; src: url(fonts/archivo-wdth.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/plex-sans-400.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url(fonts/plex-sans-500.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url(fonts/plex-sans-600.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 700; font-display: swap; src: url(fonts/plex-sans-700.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/plex-mono-400.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(fonts/plex-mono-500.woff2) format("woff2"); }

:root {
  color-scheme: light;
  --ground: #EEF1F1; --surface: #FFFFFF; --surface-2: #F6F8F8; --sunken: #E7ECED;
  --ink: #252C2F; --ink-strong: #161B1D; --muted: #5A666B; --faint: #606C71;   /* v9.47 (point 103, A9) : 4,5:1 au moins sur les fonds de page, de carte, du menu et « sunken » ; #7F8A8F n’en donnait que 3 */
  --line: #D7DDDF; --line-strong: #B6C0C3;
  --accent: #3A4A9F; --accent-hover: #2F3D86; --accent-ink: #FFFFFF; --accent-soft: #E8EBF7; --accent-line: #C3CAEA;
  --ok: #256F43; --ok-soft: #E1F0E6; --warn: #8F5409; --warn-soft: #FAEDD5; --crit: #AD2A20; --crit-soft: #F8E1DE; --info: #3F5C67; --info-soft: #E2EAED;
  --scrim: rgba(18,23,25,.48);
  --shadow-pop: 0 14px 40px -10px rgba(22,27,29,.38);
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-body: "IBM Plex Sans", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --nav-w: 216px;
  /* v6.13 — largeur de travail et densité (réglage « confortable / compact » dans le menu du compte) */
  --contenu-max: 1600px; --contenu-etroit: 980px; --pad-main: 20px 24px 40px;
  /* anciens noms, pour les pages de la demande de chiffrage */
  --primary: var(--accent); --primary-light: var(--accent-hover); --bg: var(--ground); --card: var(--surface);
  --border: var(--line); --text: var(--ink); --danger: var(--crit);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--ground); color: var(--ink); font-family: var(--font-body); font-size: 15px; line-height: 1.5; }
a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); }
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--ink-strong); font-stretch: 112%; line-height: 1.2; }
h1 { font-size: 1.45rem; font-weight: 780; letter-spacing: -.01em; margin: 0 0 14px; }
h2 { font-size: 1.1rem; font-weight: 720; margin: 0 0 10px; }
h3 { font-size: 1rem; font-weight: 700; margin: 0 0 8px; }
p { margin: 0 0 8px; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mono { font-family: var(--font-mono); font-size: .92em; font-variant-numeric: tabular-nums; }
.num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.muted, .t-sub { color: var(--muted); }
.t-sub { font-size: .8rem; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.eyebrow { font-family: var(--font-display); font-stretch: 118%; font-weight: 650; font-size: .72rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin: 0; }
[hidden] { display: none !important; }

/* ---------- coque de l'application ---------- */
.a-top { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 14px; padding: 9px 16px; background: var(--surface); border-bottom: 1px solid var(--line); }
.a-brand { display: flex; align-items: center; gap: 9px; font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: .98rem; color: var(--ink-strong); white-space: nowrap; text-decoration: none; min-width: calc(var(--nav-w) - 30px); }
.a-brand:hover { color: var(--ink-strong); }
.a-mark { width: 24px; height: 24px; flex: none; }
.a-search { flex: 1; max-width: 460px; position: relative; margin: 0; }
.a-top .a-search input[type=search] { width: 100%; padding: 7px 10px 7px 32px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2); font-size: .85rem; }
.a-search svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--faint); }
.a-top-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.a-avatar { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-size: .72rem; font-weight: 700; background: var(--accent-soft); color: var(--accent); flex: none; border: 1px solid var(--accent-line); }
.a-user { position: relative; }
.a-user summary { list-style: none; display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 3px 6px; border-radius: 8px; }
.a-user summary::-webkit-details-marker { display: none; }
.a-user summary:hover { background: var(--sunken); }
.a-user-txt { display: grid; line-height: 1.15; }
.a-user-txt b { font-size: .82rem; color: var(--ink-strong); }
.a-user-txt small { font-size: .7rem; color: var(--muted); }
.a-user-menu { position: absolute; right: 0; top: calc(100% + 6px); background: var(--surface); border: 1px solid var(--line-strong); border-radius: 9px; box-shadow: var(--shadow-pop); padding: 6px; min-width: 190px; display: grid; z-index: 50; }
.a-user-menu a, .a-user-menu button { padding: 7px 10px; border-radius: 6px; color: var(--ink); text-decoration: none; font-size: .85rem; text-align: left; background: none; border: 0; cursor: pointer; }
.a-user-menu a:hover, .a-user-menu button:hover { background: var(--sunken); color: var(--ink-strong); }

.a-shell { display: grid; grid-template-columns: var(--nav-w) minmax(0, 1fr); min-height: calc(100vh - 51px); align-items: start;
  background: linear-gradient(90deg, var(--surface-2) 0, var(--surface-2) calc(var(--nav-w) - 1px), var(--line) calc(var(--nav-w) - 1px), var(--line) var(--nav-w), var(--surface) var(--nav-w)); }
.a-nav { background: var(--surface-2); padding: 12px 10px; display: flex; flex-direction: column; gap: 2px; position: sticky; top: 51px; height: calc(100vh - 51px); overflow-y: auto; }
.a-nav-btn { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 7px 10px; border-radius: 7px; color: var(--muted); font-weight: 500; font-size: .875rem; text-decoration: none; }
.a-nav-btn svg { width: 17px; height: 17px; flex: none; }
.a-nav-btn:hover { background: var(--sunken); color: var(--ink-strong); }
.a-nav-btn[aria-current="page"] { background: var(--surface); color: var(--ink-strong); font-weight: 600; box-shadow: inset 0 0 0 1px var(--line); }
.a-nav-btn .count { margin-left: auto; font-size: .7rem; font-weight: 700; min-width: 20px; text-align: center; padding: 1px 6px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); }
.a-nav-btn .count.hot { background: var(--crit-soft); color: var(--crit); }
.a-nav-sep { height: 1px; background: var(--line); margin: 10px 6px; }
.a-nav-titre { font-size: .66rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); padding: 4px 10px 2px; font-family: var(--font-display); font-stretch: 118%; }
.a-nav-foot { margin-top: auto; font-size: .72rem; color: var(--faint); padding: 8px 10px; line-height: 1.4; }
.a-nav-foot a { color: inherit; }
.a-main { min-width: 0; padding: var(--pad-main); }
.a-main > .contenu { max-width: var(--contenu-max); margin: 0 auto; }
.a-main > .contenu.etroit { max-width: var(--contenu-etroit); }

/* ---------- boutons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: .8125rem; font-weight: 600; line-height: 1.2; border-radius: 6px; padding: 7px 12px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-strong); cursor: pointer; text-decoration: none; white-space: nowrap; font-family: var(--font-body); }
.btn:hover { background: var(--surface-2); border-color: var(--faint); color: var(--ink-strong); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-ink); }
.btn-secondary { background: var(--surface); }
.btn-ok { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn-ok:hover { background: #1d5a36; border-color: #1d5a36; color: #fff; }
.btn-danger { background: var(--surface); color: var(--crit); border-color: #e2b6b1; }
.btn-danger:hover { background: var(--crit-soft); color: var(--crit); border-color: var(--crit); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--sunken); border-color: transparent; color: var(--ink-strong); }
.btn-sm { padding: 4px 8px; font-size: .75rem; }
.btn-lg { font-size: .9375rem; padding: 10px 16px; border-radius: 7px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
/* v6.16 : un « bouton » qui est en fait un résumé dépliant porte une phrase — il tient sur deux lignes plutôt que de déborder */
summary.btn { white-space: normal; text-align: left; justify-content: flex-start; }
.inline-form { display: inline; margin: 0; }
.actions-ligne { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* ---------- en-têtes de vue ---------- */
.v-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 20px; margin-bottom: 18px; }
.v-title { font-size: 1.45rem; font-weight: 780; font-stretch: 115%; letter-spacing: -.01em; line-height: 1.15; margin: 0; }
.v-sub { color: var(--muted); margin: 4px 0 0; }
.v-tools { display: flex; flex-wrap: wrap; gap: 8px; }
.crumbs { display: flex; align-items: center; gap: 6px; font-size: .8125rem; color: var(--muted); margin-bottom: 8px; }
.crumbs a { font-weight: 500; text-decoration: none; }
.block-title { font-family: var(--font-display); font-stretch: 118%; font-size: .72rem; font-weight: 650; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin: 0 0 10px; }
.cols { display: grid; grid-template-columns: minmax(0, 1fr) 310px; gap: 24px; align-items: start; }
.cols-even { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
.panel { border: 1px solid var(--line); border-radius: 9px; background: var(--surface); padding: 14px 16px; }
.panel + .panel { margin-top: 14px; }
.cols-even > .panel + .panel { margin-top: 0; }
.empty { border: 1px dashed var(--line-strong); border-radius: 9px; padding: 20px; color: var(--muted); background: var(--surface-2); }
.empty strong { display: block; color: var(--ink-strong); margin-bottom: 4px; }
.legal { font-size: .75rem; color: var(--muted); margin-top: 10px; line-height: 1.45; }

/* ---------- pastilles ---------- */
.chip { display: inline-flex; align-items: center; gap: 5px; font-size: .72rem; font-weight: 600; line-height: 1.2; padding: 3px 8px; border-radius: 999px; white-space: nowrap; }
.sev-bloquant, .st-crit { background: var(--crit-soft); color: var(--crit); }
.sev-urgent, .st-warn { background: var(--warn-soft); color: var(--warn); }
.sev-decision { background: var(--accent-soft); color: var(--accent); }
.sev-afaire, .st-info { background: var(--info-soft); color: var(--info); }
.sev-info, .st-neutral, .st-neutre, .st-attente { background: var(--sunken); color: var(--muted); }   /* v9.16 : « st-neutre » et « st-attente », employés depuis la v7 (Préparé, Reçue, Rien de reçu), n'avaient aucune couleur */
.st-ok { background: var(--ok-soft); color: var(--ok); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.dchip { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; font-family: var(--font-mono); font-size: .72rem; font-weight: 500; letter-spacing: .02em; padding: 2px 7px; border-radius: 4px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-strong); text-decoration: none; white-space: nowrap; }
.dchip:hover { border-color: var(--accent); color: var(--accent); }
.dchip svg { width: 13px; height: 13px; vertical-align: -2px; }   /* une icône dans une pastille garde sa taille, même hors flex */
.badge { display: inline-block; color: #fff; font-size: .72rem; font-weight: 600; padding: 3px 9px; border-radius: 999px; white-space: nowrap; vertical-align: middle; }

/* ---------- actions ---------- */
.act-group + .act-group { margin-top: 22px; }
.acts { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.act { display: grid; grid-template-columns: 86px minmax(0, 1fr) auto; gap: 6px 16px; padding: 13px 0; border-bottom: 1px solid var(--line); align-items: start; }
.act-title { font-weight: 600; color: var(--ink-strong); font-size: .9375rem; line-height: 1.35; margin: 0; }
.act-why { color: var(--muted); margin: 3px 0 0; max-width: 78ch; }
.act-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 8px 0 0; font-size: .78rem; color: var(--muted); }
.act-cta { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.cols-even .act { grid-template-columns: 86px minmax(0, 1fr); }
.cols-even .act-cta { grid-column: 2; justify-content: flex-start; }
.deadlines { list-style: none; margin: 0; padding: 0; }
.deadlines li { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.deadlines li:last-child { border-bottom: 0; }
.dl-date { font-family: var(--font-mono); font-size: .78rem; color: var(--ink-strong); font-variant-numeric: tabular-nums; }
.dl-rel { display: block; font-family: var(--font-body); font-size: .7rem; color: var(--muted); }
.dl-rel.soon { color: var(--crit); font-weight: 600; }
.dl-txt { font-size: .8125rem; }
.mini-dossiers { list-style: none; margin: 0; padding: 0; }
.mini-dossiers li { border-bottom: 1px solid var(--line); }
.mini-dossiers li:last-child { border-bottom: 0; }
.mini-dossiers a { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 2px 8px; padding: 8px 0; color: inherit; text-decoration: none; }
.mini-dossiers .chip { align-self: start; max-width: 100%; }
.mini-dossiers a:hover .md-name { color: var(--accent); }
.md-name { font-weight: 600; color: var(--ink-strong); }
.md-sub { grid-column: 1; font-size: .75rem; color: var(--muted); }

/* ---------- filtres ---------- */
.filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.fchip, .filters a { font-size: .8125rem; font-weight: 500; padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink); cursor: pointer; text-decoration: none; }
.fchip:hover, .filters a:hover { border-color: var(--faint); color: var(--ink-strong); }
.fchip[aria-pressed="true"], .fchip[aria-current="true"], .filters a.active { background: var(--ink-strong); border-color: var(--ink-strong); color: var(--ground); }

/* ---------- tableaux ---------- */
.a-tbl-wrap { position: relative; overflow-x: auto; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); }
.a-tbl { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.a-tbl th { text-align: left; font-size: .68rem; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); padding: 9px 12px; border-bottom: 1px solid var(--line); background: var(--surface-2); white-space: nowrap; }
.a-tbl td { padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.a-tbl tr:last-child td { border-bottom: 0; }
.a-tbl tbody tr.row-link { cursor: pointer; }
.a-tbl tbody tr.row-link:hover td { background: var(--surface-2); }
.a-tbl .t-name { font-weight: 600; color: var(--ink-strong); min-width: 170px; }   /* v6.11 : un intitulé long fait défiler le tableau, il ne l'écrase plus */
.a-tbl a.t-name { text-decoration: none; }
.a-tbl .t-sub { font-size: .75rem; }
.a-tbl td.num, .a-tbl th.num { text-align: right; }

/* v7.19 — L'ATELIER DU MÉTRÉ : une grille qu'on remplit au clavier.
   La case de quantité est étroite et alignée à droite — un métreur la parcourt à la tabulation et
   lit une colonne de chiffres, pas une colonne de champs. « endormie » : une ligne sans quantité
   qui porte quand même un calcul ou une localisation. Elle se voit, sinon on croit ce travail
   perdu et on le ressaisit ailleurs. */
.a-tbl input.champ-q { width: 92px; text-align: right; padding: 5px 8px; font-size: .875rem; }
.a-tbl input.champ-loc { width: 100%; min-width: 96px; max-width: 160px; padding: 5px 8px; font-size: .8125rem; }
/* v9.40 — point 89 : la précision pour la commande, le « i » à côté du prix et le texte sous l'intitulé */
.i-precision { display: inline-grid; place-items: center; width: 20px; height: 20px; margin-left: 6px; padding: 0; vertical-align: 1px;
  border-radius: 999px; border: 1.5px solid var(--accent); background: transparent; color: var(--accent); font: 700 11px var(--font-mono); cursor: pointer; }
.i-precision:hover { background: var(--accent-soft); }
.i-precision.posee { background: var(--accent); color: var(--accent-ink, #fff); }
.precision-ligne { font-style: italic; color: var(--info, var(--muted)); }
.a-tbl tr.dedans td { background: var(--ok-soft); }
.a-tbl tr.endormie td { background: var(--surface-2); }
.a-tbl tr.endormie .c-lib, .a-tbl tr.endormie td:nth-child(2) { opacity: .75; }
@media (max-width: 680px) {
  /* v8.7 — `px-ligne` REJOINT SES VOISINS. Les 16 px ne sont pas cosmétiques : en dessous,
   iOS zoome la page à la mise au point du champ, et l'on ressort d'une saisie de prix avec
   un écran dézoomé à remettre en place. `plateformes.py` ne peut pas le voir. */
.tbl-cartes input.champ-q, .tbl-cartes input.champ-loc, .tbl-cartes input.px-ligne { width: 100%; max-width: none; font-size: 16px; }
}

/* v7.17 — Deux lignes qui ne sont pas des lignes de données.
   « tr-section » : le titre d'un chapitre au milieu d'un tableau — la bibliothèque des ouvrages en
   pose un par rupture. « tr-fille » : une ligne rattachée à celle du dessus (les composants d'un
   ensemble). Ni l'une ni l'autre ne se trie ni ne se filtre : elles n'apparaissent que dans les
   tableaux sans « tbl-triable ». */
.a-tbl tr.tr-section td { background: var(--surface-2); color: var(--muted); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; padding: 7px 12px; }
.a-tbl tr.tr-fille td { background: var(--sunken); padding-top: 6px; padding-bottom: 6px; }
.ministeps { display: flex; gap: 2px; margin-top: 5px; }
.ministeps i { display: block; width: 14px; height: 4px; border-radius: 2px; background: var(--line); }
.ministeps i.done { background: var(--ink-strong); }
.ministeps i.cur { background: var(--accent); }

/* ---------- cockpit dossier ---------- */
.cockpit-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.cockpit-title h1 { font-size: 1.6rem; font-weight: 800; font-stretch: 125%; letter-spacing: -.01em; margin: 0; }
.cockpit-title .who { color: var(--muted); }
.cartouche-app { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line-strong); border-radius: 8px; overflow: hidden; margin: 14px 0 18px; }
.cartouche-app > div { background: var(--surface); padding: 8px 11px; min-width: 0; }
.cartouche-app dt { font-size: .66rem; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.cartouche-app dd { margin: 2px 0 0; font-weight: 600; color: var(--ink-strong); font-size: .8125rem; overflow-wrap: anywhere; }
.cartouche-app dd.reserve { font-weight: 500; color: var(--faint); font-style: italic; }
.steps-wrap { overflow-x: auto; margin-bottom: 6px; }
.steps { display: grid; gap: 4px; list-style: none; margin: 0; padding: 0; }
.steps-8 { grid-template-columns: repeat(8, minmax(72px, 1fr)); min-width: 640px; }
.steps li { font-size: .72rem; color: var(--faint); padding-top: 8px; border-top: 4px solid var(--line); font-weight: 500; }
.steps li.done { border-top-color: var(--ink-strong); color: var(--muted); }
.steps li.cur { border-top-color: var(--accent); color: var(--accent); font-weight: 700; }
.steps li.stop { border-top-color: var(--crit); color: var(--crit); font-weight: 700; }
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); overflow-x: auto; margin: 18px 0; scrollbar-width: thin; }
.tab { padding: 9px 12px; border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--muted); font-weight: 600; font-size: .8125rem; white-space: nowrap; text-decoration: none; }
.tab:hover { color: var(--ink-strong); }
.tab[aria-selected="true"] { color: var(--ink-strong); border-bottom-color: var(--accent); }
.tab .count { font-size: .68rem; font-weight: 700; margin-left: 4px; padding: 0 5px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); }

.checks { list-style: none; margin: 0; padding: 0; }
.checks li { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; gap: 8px; align-items: start; padding: 7px 0; border-bottom: 1px solid var(--line); }
.checks li:last-child { border-bottom: 0; }
.ck { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; margin-top: 1px; }
.ck svg { width: 11px; height: 11px; }
.ck-ok { background: var(--ok-soft); color: var(--ok); }
.ck-crit { background: var(--crit-soft); color: var(--crit); }
.ck-warn { background: var(--warn-soft); color: var(--warn); }
.ck-todo { background: var(--sunken); color: var(--faint); }
.ck-run { background: var(--accent-soft); color: var(--accent); }
.ck-note { display: block; font-size: .75rem; color: var(--muted); margin-top: 1px; }
.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 14px; margin: 0; font-size: .8125rem; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; color: var(--ink-strong); font-weight: 500; }
.inline-list { margin: 6px 0 0; padding-left: 1.1em; display: grid; gap: 4px; }
.banner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; border: 1px solid var(--accent-line); background: var(--accent-soft); border-radius: 9px; padding: 11px 14px; margin-bottom: 14px; }
.banner p { color: var(--ink-strong); margin: 0; }
.banner.warn { border-color: transparent; background: var(--warn-soft); }
.banner.ok { border-color: transparent; background: var(--ok-soft); }
.banner.crit { border-color: transparent; background: var(--crit-soft); }

/* jalons */
.jalons { list-style: none; margin: 4px 0 0 8px; padding: 0; border-left: 2px solid var(--line); }
.jalons li { position: relative; padding: 0 0 16px 20px; }
.jalons li:last-child { padding-bottom: 0; }
.jalons li::before { content: ""; position: absolute; left: -8px; top: 3px; width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--line-strong); }
.jalons li.done::before { background: var(--ok); border-color: var(--ok); }
.jalons li.cur::before { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.jalons li.late::before { border-color: var(--crit); box-shadow: 0 0 0 3px var(--crit-soft); }
.j-head { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.j-name { font-weight: 600; color: var(--ink-strong); }
.j-dates { font-family: var(--font-mono); font-size: .72rem; color: var(--muted); }
.j-dates .late { color: var(--crit); font-weight: 600; }
.j-note { font-size: .78rem; color: var(--muted); margin-top: 2px; white-space: pre-wrap; }
.j-actions { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; }
.j-photos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.j-photos a { display: block; width: 58px; height: 58px; border-radius: 6px; overflow: hidden; border: 1px solid var(--line); background: var(--sunken); }
.j-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
.j-photos a.j-piece { display: flex; align-items: center; justify-content: center; font-size: .72rem; font-weight: 600; color: var(--muted); text-decoration: none; }   /* v9.50 : une pièce qui n'est pas une image, parmi les photos d'une demande SAV */
.progress { display: flex; gap: 2px; margin-top: 6px; max-width: 220px; }
.progress i { flex: 1; height: 5px; border-radius: 2px; background: var(--line); }
.progress i.done { background: var(--ok); }
.progress i.cur { background: var(--accent); }

/* journal */
.journal { list-style: none; margin: 0; padding: 0; }
.journal > li { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.journal > li:last-child { border-bottom: 0; }
.j-ico { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; background: var(--sunken); color: var(--muted); }
.j-ico svg { width: 15px; height: 15px; }
.j-ico.in { background: var(--accent-soft); color: var(--accent); }
.j-ico.out { background: var(--ok-soft); color: var(--ok); }
.j-ico.visit, .j-ico.jalon { background: var(--warn-soft); color: var(--warn); }
.j-top { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 12px; }
.j-title { font-weight: 600; color: var(--ink-strong); }
.j-meta { font-size: .72rem; color: var(--muted); font-family: var(--font-mono); white-space: nowrap; }
.j-body { margin: 3px 0 0; font-size: .8125rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.j-src { font-size: .72rem; color: var(--faint); margin: 3px 0 0; }
.j-pieces { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
details.j-plus summary { cursor: pointer; font-size: .75rem; color: var(--accent); font-weight: 600; margin-top: 4px; list-style: none; }
details.j-plus summary::-webkit-details-marker { display: none; }
.copy-addr { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; border: 1px dashed var(--accent-line); background: var(--accent-soft); border-radius: 8px; padding: 9px 12px; font-size: .8125rem; color: var(--ink-strong); margin-bottom: 14px; }
.copy-addr code { font-family: var(--font-mono); font-size: .78rem; background: var(--surface); border: 1px solid var(--accent-line); border-radius: 5px; padding: 2px 6px; }

/* garanties, points, calendrier */
.garanties { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 9px; overflow: hidden; }
.garanties > div { background: var(--surface); padding: 10px 12px; min-width: 0; }
.g-name { font-size: .72rem; font-weight: 600; color: var(--muted); margin: 0; }
.g-date { font-family: var(--font-mono); font-size: .8125rem; color: var(--ink-strong); margin: 2px 0 0; }
.points { list-style: none; margin: 0; padding: 0; }
.points li { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 6px 12px; padding: 10px 0; border-bottom: 1px solid var(--line); align-items: start; }
.points li:last-child { border-bottom: 0; }
.p-src { font-family: var(--font-mono); font-size: .7rem; color: var(--muted); margin-top: 2px; display: block; }
.p-btns { display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.p-btns .btn { padding: 4px 8px; font-size: .72rem; }
.p-btns .btn[aria-pressed="true"] { background: var(--ink-strong); color: var(--ground); border-color: var(--ink-strong); }
.cal { list-style: none; margin: 0; padding: 0; }
.cal li { display: grid; grid-template-columns: 86px minmax(0, 1fr); gap: 10px; padding: 7px 0; border-bottom: 1px dashed var(--line); font-size: .8125rem; }
.cal li:last-child { border-bottom: 0; }
.cal .c-date { font-family: var(--font-mono); font-size: .75rem; color: var(--muted); }
.cal li.s-done .c-txt { color: var(--muted); }
.cal li.s-next .c-date, .cal li.s-next .c-txt { color: var(--ink-strong); font-weight: 600; }
.cal li.s-next .c-date { color: var(--accent); }
.cal li.s-late .c-date, .cal li.s-late .c-txt { color: var(--crit); font-weight: 600; }
.cal li.s-later .c-txt { color: var(--muted); }
.pieces-list { list-style: none; margin: 0; padding: 0; }
.pieces-list li { display: grid; grid-template-columns: 150px minmax(0, 1fr) auto; gap: 4px 14px; padding: 9px 0; border-bottom: 1px solid var(--line); align-items: start; }
.pieces-list li:last-child { border-bottom: 0; }
/* v7.7 — LA CATÉGORIE NE MANGE PLUS LE NOM DU FICHIER. La première piste est FIXE (150 px, 110 px
   pour .pieces-compact) : elle ne grandit pas, c'est au contenu de tenir dedans. Or sous
   « white-space: nowrap » (ligne 128), la largeur min-content d'une pastille vaut sa largeur
   max-content : le shrink-to-fit ne peut RIEN ramener, et c'est la pastille entière — fond
   compris — qui sortait de sa piste et se posait par-dessus le nom du fichier. On lui rend le
   droit de passer à la ligne ; tronquer le libellé d'une catégorie dans une liste qu'on lit PAR
   catégorie serait pire. Le pire cas n'était pas l'onglet Documents mais l'onglet PLANS, où
   « EXE 03A · Maçonnerie vide sanitaire / sous-sol » recouvrait le nom de 92 px. */
.pieces-list li > *:first-child .chip { white-space: normal; max-width: 100%; text-align: left; }
.p-name { font-weight: 500; color: var(--ink-strong); overflow-wrap: anywhere; text-decoration: none; }
.p-date { font-family: var(--font-mono); font-size: .72rem; color: var(--muted); text-align: right; white-space: nowrap; }
.kpis { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 9px; overflow: hidden; margin-bottom: 16px; }
/* v7.28 — `minmax(0, 1fr)` et non `1fr` : les enfants d'une grille ont `min-width: auto`, donc un
   texte long les élargit AU-DELÀ de la tuile au lieu de s'y plier. La valeur « Maçonnerie Duval et
   Fils » mesurait 218 px dans une tuile de 167. */
.kpi { background: var(--surface); padding: 10px 12px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; text-align: left; color: inherit; text-decoration: none; align-content: start; }
a.kpi:hover { background: var(--surface-2); color: inherit; }
.kpi[aria-pressed="true"] { background: var(--accent-soft); box-shadow: inset 0 -2px 0 var(--accent); }
.k-label { font-size: .7rem; font-weight: 600; color: var(--muted); letter-spacing: .03em; }
/* Le `white-space: nowrap` d'origine ne protégeait RIEN qu'il fallait protéger : montant() sépare
   les milliers par U+202F et colle le € par U+00A0, deux espaces INSÉCABLES — « 1 234,56 € » tient
   sur une ligne sans lui. Il ne servait donc qu'à faire déborder les valeurs TEXTUELLES : un nom
   d'entreprise, un libellé de lot. On le retire et on autorise la coupure des mots trop longs. */
.k-val { font-family: var(--font-display); font-stretch: 112%; font-weight: 800; font-size: 1.2rem; color: var(--ink-strong); font-variant-numeric: tabular-nums; line-height: 1.15; overflow-wrap: anywhere; }
.k-sub { font-size: .72rem; color: var(--muted); }
.kpi.crit .k-val { color: var(--crit); }

/* ---------- formulaires ---------- */
.q { margin-bottom: 16px; }
.q > label.q-label, .q-label { display: block; font-weight: 600; margin-bottom: 5px; font-size: .875rem; color: var(--ink-strong); }
.q .req, .req { color: var(--crit); }
.aide { color: var(--muted); font-size: .8rem; margin: -1px 0 6px; }
input[type=text], input[type=number], input[type=date], input[type=email], input[type=password], input[type=search], input[type=tel], input[type=datetime-local], input[type=time], textarea, select {
  width: 100%; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 7px; font-size: .9rem; background: var(--surface); color: var(--ink-strong);
}
textarea { min-height: 80px; resize: vertical; line-height: 1.45; }
input:focus, textarea:focus, select:focus { outline: 2px solid var(--accent-line); outline-offset: 0; border-color: var(--accent); }
.choice { display: flex; align-items: flex-start; gap: 10px; padding: 6px 2px; }
.choice input { width: 18px; height: 18px; margin-top: 2px; flex-shrink: 0; accent-color: var(--accent); }
.choice label { cursor: pointer; }
.autre-input { margin: 4px 0 0 30px; }
.autre-input input { max-width: 400px; }
.form-grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.form-grille-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 14px; }
.field { display: grid; gap: 4px; font-size: .78rem; color: var(--muted); font-weight: 600; min-width: 0; }
.field.large { grid-column: 1 / -1; }
.field input, .field select, .field textarea { font-weight: 400; }
.check-line { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; font-size: .8125rem; color: var(--ink-strong); font-weight: 500; min-width: 0; }
.check-line > * { min-width: 0; }
.check-line input[type=checkbox], .check-line input[type=radio] { flex: none; }
.check-line .mono { overflow-wrap: anywhere; }   /* une adresse longue coupe plutôt que de pousser la ligne hors de l'écran */
.check-line input { width: 15px; height: 15px; accent-color: var(--accent); }
/* ===== v7.7 — LA CARTE DE QUALIFICATION ================================================== */
/* L'onglet montrait quinze accordéons fermés : pour savoir ce qu'on savait de la maison, il fallait
   les ouvrir un par un. Il montre maintenant les quatre-vingt-dix-neuf faits d'un coup, en trois
   états — su, repris du standard, manque — et le formulaire d'une section s'ouvre en tiroir à
   l'endroit même où on l'a demandé. Rien ici ne touche .field, .check-line ni .q-label : ce sont
   des classes de toute l'application (526 usages dans 48 fichiers pour la première). */
.carte-jauge { display: flex; height: 4px; border-radius: 999px; background: var(--line); overflow: hidden; margin: 2px 0 6px; }
.carte-jauge .j-su { background: var(--accent); }
.carte-jauge .j-std { background: var(--line-strong); }
.carte-legende { font-size: .78rem; color: var(--muted); margin: 0 0 10px; }
.carte-legende strong { color: var(--ink-strong); }
.carte-etat { font-size: .8rem; color: var(--ok); margin: 0 0 8px; min-height: 0; }
.carte-etat:empty { display: none; }
.carte-recherche { max-width: 220px; font-size: .78rem; padding: 4px 8px; }
.carte-connu { background: var(--surface-2); border-left: 2px solid var(--accent); border-radius: 0 8px 8px 0; padding: 9px 12px; margin-bottom: 12px; font-size: .82rem; }
.carte-connu p { margin: 0 0 7px; }
.connu-fait { display: inline-block; margin-right: 10px; color: var(--ink-strong); font-weight: 500; }
.carte-bloc { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 10px; scroll-margin-top: 70px; }
.carte-bloc:first-of-type { border-top: 0; }
.bloc-tete { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 7px; }
.bloc-titre { font-size: .9rem; font-weight: 600; color: var(--ink-strong); margin: 0; }
.bloc-tete .bloc-completer { margin-left: auto; }
.carte-faits { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 2px 14px; }
.fait { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px 10px; align-items: baseline; padding: 4px 6px; border-radius: 6px; text-decoration: none; color: inherit; min-height: 30px; }
.fait:hover { background: var(--surface-2); }
.fait-q { font-size: .78rem; color: var(--muted); overflow-wrap: anywhere; }
.fait-v { font-size: .82rem; color: var(--ink-strong); font-weight: 600; overflow-wrap: anywhere; }
.fait--std .fait-v { color: var(--muted); font-weight: 400; }
.fait--manque .fait-v { color: var(--accent); font-weight: 400; font-style: italic; }
.fait--essentiel .fait-q { box-shadow: -6px 0 0 -4px var(--accent); }
.fait-std { font-size: .66rem; font-weight: 600; letter-spacing: .04em; color: var(--muted); border: 1px solid var(--line-strong); border-radius: 3px; padding: 0 3px; }
/* v9.20 — la description d'une ligne relue par l'assistant (planche C) */
.ligne-description-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ligne-ia-gestes { margin-left: auto; display: inline-flex; gap: 6px; flex-wrap: wrap; }
.btn-accent-contour { border-color: var(--accent); color: var(--accent); }
.ligne-ia-proposition { margin-top: 8px; border: 2px solid var(--accent); border-radius: 10px; background: var(--accent-soft); padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.ligne-ia-tete { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; color: var(--accent); }
.ligne-ia-diff { font-size: .9rem; line-height: 1.6; color: var(--ink); }
.ligne-ia-diff ins { background: var(--ok-soft); color: var(--ok); text-decoration: none; border-radius: 3px; padding: 0 2px; }
.ligne-ia-diff del { background: var(--crit-soft); color: var(--crit); border-radius: 3px; padding: 0 2px; }
/* v9.20 — les lots qu'exerce une entreprise, dans leur section en tête de la fiche (planche A) */
.lots-phase { margin: 10px 0 2px; font-weight: 600; color: var(--ink); }
ul.lots-exerces { list-style: none; margin: 0; padding: 0; }
ul.lots-exerces li { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
ul.lots-exerces li > .mono { width: 34px; }
ul.lots-exerces li > strong { flex: 1 1 14rem; }
ul.lots-exerces .lots-usage { min-width: 11rem; }
.lots-ajout { margin-top: 12px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }
.metiers-cases { max-height: 34vh; overflow: auto; border: 1px solid var(--line); border-radius: 9px; padding: 4px; background: var(--surface); margin-top: 8px; }
.metiers-cases [data-deja] { color: var(--muted); }
/* v9.21 — les attestations lues par l'assistant et les documents d'une entreprise (planches B et B2) */
.ent-onglets { margin: 4px 0 14px; }
.depot-attestations { margin-top: 10px; border: 2px dashed var(--accent); border-radius: 12px; background: var(--accent-soft); padding: 14px; display: flex; flex-direction: column; gap: 6px; align-items: center; text-align: center; }
.depot-attestations strong { color: var(--accent); }
.verif-attestations { border: 2px solid var(--accent); }
.verif-tbl input[type=date] { min-width: 9.5rem; }
.verif-tbl input[type=text] { width: 100%; min-width: 8rem; margin-bottom: 4px; }
.verif-tbl select { min-width: 13rem; max-width: 18rem; }
.docs-outils { margin-bottom: 10px; }
.verif-actions { justify-content: flex-end; margin-top: 8px; }
.verif-actions #verif-enregistrer { order: 2; }   /* premier dans la page (Entrée l'actionne), à droite à l'écran */
.verif-tbl tr.verif-a-reprendre td { background: var(--warn-soft); }
/* v9.20 — l'éditeur des options d'une question, une ligne par option et sa case « par défaut » (planche D) */
.options-tete { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.options-lignes { border: 1px solid var(--line-strong); border-radius: 9px; margin: 6px 0; }
.option-ligne { display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-bottom: 1px solid var(--line); }
.option-ligne:last-child { border-bottom: 0; }
.option-ligne input[type=text] { flex: 1 1 auto; min-width: 0; }
.option-defaut { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; font-size: .82rem; color: var(--muted); }
details.standards-replies > summary { cursor: pointer; padding: 2px 0; }
/* v9.20 — la réponse par défaut d'une question, pas encore confirmée (planche D) */
.q-defaut { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.q-options > .q-defaut { margin: 0 0 4px 26px; }   /* la marque suit l'option cochée d'un choix unique */
.tiroir { margin: 6px 0 4px; padding: 12px; background: var(--surface-2); border-radius: 9px; }
.tiroir-pied { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tiroir-etat { font-size: .78rem; color: var(--muted); }
.tiroir-alerte { grid-column: 1 / -1; background: var(--warn-soft); color: var(--warn); border-radius: 7px; padding: 8px 10px; font-size: .82rem; }
.q-champ { display: grid; gap: 3px; align-content: start; min-width: 0; font-size: .78rem; color: var(--muted); font-weight: 600; }
.q-champ--large { grid-column: 1 / -1; }
.q-champ--court input { max-width: 230px; }
.q-champ input, .q-champ select, .q-champ textarea { font-weight: 400; }
.q-titre { font-size: .8125rem; font-weight: 600; color: var(--ink-strong); }
.q-aide { font-size: .74rem; color: var(--muted); font-weight: 400; }
.q-options { display: grid; gap: 1px; }
.q-champ--vise { background: var(--accent-soft); border-radius: 7px; box-shadow: 0 0 0 6px var(--accent-soft); }
.bloc-attente { opacity: .55; pointer-events: none; }
details.section { background: var(--surface); border: 1px solid var(--line); border-radius: 9px; margin-bottom: 12px; overflow: hidden; }
details.section > summary { cursor: pointer; padding: 12px 16px; font-weight: 700; font-size: .95rem; background: var(--surface-2); list-style: none; display: flex; justify-content: space-between; align-items: center; color: var(--ink-strong); font-family: var(--font-display); font-stretch: 108%; }
details.section > summary::-webkit-details-marker { display: none; }
details.section > summary::after { content: "▸"; color: var(--muted); transition: transform .15s; }
details.section[open] > summary::after { transform: rotate(90deg); }
details.section .section-body { padding: 16px; }
summary .count { font-size: .75rem; color: var(--muted); font-weight: 400; margin-left: 8px; font-family: var(--font-body); }
.actions-bar { position: sticky; bottom: 0; background: rgba(255,255,255,.96); padding: 12px 0; display: flex; gap: 10px; flex-wrap: wrap; border-top: 1px solid var(--line); z-index: 5; }

/* ---------- pages de la demande de chiffrage (anciennes classes) ---------- */
.container { max-width: 100%; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 16px 18px; margin-bottom: 16px; }
.card h2 { margin-top: 0; }
.flash { padding: 10px 14px; border-radius: 8px; margin-bottom: 12px; font-size: .875rem; }
.flash-ok { background: var(--ok-soft); color: var(--ok); }
.flash-err { background: var(--crit-soft); color: var(--crit); }
.flash-info { background: var(--info-soft); color: var(--info); }
.fiche-list { display: flex; flex-direction: column; gap: 8px; }
.fiche-item { background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 11px 16px; text-decoration: none; color: var(--ink); display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.fiche-item:hover { border-color: var(--accent-line); color: var(--ink); }
.fiche-item .title { font-weight: 600; color: var(--ink-strong); }
.fiche-item .meta { color: var(--muted); font-size: .8rem; margin-top: 2px; }
.fiche-item .right { text-align: right; flex-shrink: 0; }
.detail-table { width: 100%; border-collapse: collapse; }
.detail-table th, .detail-table td { text-align: left; padding: 7px 10px; vertical-align: top; border-bottom: 1px solid var(--line); font-size: .85rem; }
.detail-table th { width: 45%; color: var(--muted); font-weight: 500; }
.detail-table tr:last-child th, .detail-table tr:last-child td { border-bottom: none; }
.section-title { font-family: var(--font-display); font-stretch: 118%; font-size: .75rem; font-weight: 650; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 22px 0 8px; border-bottom: 1.5px solid var(--ink-strong); padding-bottom: 4px; }
.file-list { list-style: none; padding: 0; margin: 0; }
.file-list li { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: .85rem; flex-wrap: wrap; }
.file-list li:last-child { border-bottom: none; }
.file-list .size { color: var(--muted); font-size: .75rem; }
.retour-box { border: 1px solid transparent; border-radius: 9px; padding: 16px 18px; background: var(--ok-soft); margin-bottom: 16px; }
.retour-box h2 { margin-top: 0; color: var(--ok); }
.prix { font-family: var(--font-display); font-stretch: 112%; font-size: 1.6rem; font-weight: 800; color: var(--ok); }
table.users { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--line); border-radius: 9px; overflow: hidden; }
table.users th, table.users td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--line); font-size: .85rem; vertical-align: top; }
table.users th { background: var(--surface-2); font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }

/* connexion */
.login-page { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.login-box { width: min(400px, 100%); margin: 8vh auto; }
.login-box h1 { text-align: center; font-size: 1.35rem; margin-bottom: 18px; }
.login-box .marque-login { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 18px; font-family: var(--font-display); font-stretch: 125%; font-weight: 800; font-size: 1.15rem; color: var(--ink-strong); }
.login-box .marque-login svg { width: 30px; height: 30px; }
.login-box .q { margin-bottom: 14px; }
.login-box .btn { width: 100%; padding: 10px; font-size: .9rem; }

/* attente, modales */
.overlay-attente { display: none; position: fixed; inset: 0; z-index: 1000; background: rgba(22,27,29,.86); color: #fff; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 24px; gap: 18px; }
.overlay-attente .spinner { width: 52px; height: 52px; border-radius: 50%; border: 5px solid rgba(255,255,255,.25); border-top-color: #fff; animation: rotation-attente 1s linear infinite; }
@keyframes rotation-attente { to { transform: rotate(360deg); } }
.overlay-attente h2 { margin: 0; font-size: 1.25rem; color: #fff; }
.overlay-attente p { margin: 0; color: #d9e0e2; max-width: 440px; font-size: .9rem; }
dialog.modal { width: min(640px, calc(100vw - 24px)); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); padding: 0; border: 1px solid var(--line-strong); border-radius: 12px; box-shadow: var(--shadow-pop); background: var(--surface); color: var(--ink); }
dialog.modal::backdrop { background: var(--scrim); }
.m-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 16px 20px 12px; border-bottom: 1px solid var(--line); }
.m-head h2 { font-size: 1.15rem; font-weight: 780; font-stretch: 115%; margin: 0; }
.m-head p { color: var(--muted); margin: 3px 0 0; font-size: .85rem; }
.m-body { padding: 16px 20px; display: grid; gap: 14px; }
.m-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; padding: 12px 20px 16px; border-top: 1px solid var(--line); }
.m-foot .m-foot-note { margin-right: auto; font-size: .75rem; color: var(--muted); max-width: 44ch; }
.x-btn { border: 0; background: none; color: var(--muted); cursor: pointer; padding: 4px; border-radius: 6px; line-height: 0; }
.x-btn:hover { background: var(--sunken); color: var(--ink-strong); }
.x-btn svg { width: 18px; height: 18px; }
.drop { border: 1.5px dashed var(--line-strong); border-radius: 9px; padding: 14px; text-align: center; color: var(--muted); background: var(--surface-2); display: grid; gap: 6px; justify-items: center; }
.drop.over { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.mail-draft textarea { min-height: 280px; font-size: .875rem; }
.spinner-inline { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--accent-line); border-top-color: var(--accent); display: inline-block; vertical-align: -3px; animation: rotation-attente .8s linear infinite; }

/* Markdown (analyses IA) */
.md { font-size: .875rem; line-height: 1.55; }
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md h3, .md h4, .md h5 { margin: 16px 0 6px; line-height: 1.3; color: var(--ink-strong); border-bottom: 1px solid var(--line); padding-bottom: 3px; }
.md h3 { font-size: 1rem; } .md h4 { font-size: .95rem; } .md h5 { font-size: .875rem; border-bottom: none; padding-bottom: 0; }
.md p { margin: 0 0 8px; }
.md ul, .md ol { margin: 4px 0 10px; padding-left: 22px; }
.md li { margin-bottom: 3px; }
.md code { background: var(--sunken); padding: 1px 5px; border-radius: 4px; font-size: .8rem; font-family: var(--font-mono); }
.md hr { border: none; border-top: 1px solid var(--line); margin: 12px 0; }
.md .md-table { border-collapse: collapse; width: 100%; margin: 6px 0 12px; font-size: .8rem; }
.md .md-table th, .md .md-table td { border: 1px solid var(--line); padding: 5px 8px; text-align: left; }
.md .md-table th { background: var(--surface-2); }

.pied { text-align: center; color: var(--faint); font-size: .72rem; padding: 26px 0 0; }
.pied a { color: inherit; }

/* ---------- annuaire, lots et achats (v6.1) ---------- */
.recherche-ligne { display: flex; gap: 8px; margin-bottom: 12px; max-width: 640px; }
.recherche-ligne input[type=search] { flex: 1; }
.select-chip { width: auto; padding: 4px 28px 4px 10px; border-radius: 999px; font-size: .8125rem; }
.cartes { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.carte { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding: 12px 14px; display: grid; gap: 6px; align-content: start; }
.carte-lien { display: grid; gap: 1px; text-decoration: none; color: inherit; }
.carte-lien:hover .carte-titre { color: var(--accent); }
.carte-titre { font-weight: 700; color: var(--ink-strong); font-size: .95rem; }
.carte-sous { font-size: .78rem; color: var(--muted); }
.carte-metiers { font-size: .78rem; color: var(--ink); margin: 0; }
.carte-chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 0; }
.carte-contact { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 2px 0 0; font-size: .8rem; color: var(--muted); }
.carte-contact svg, .lot-entreprise svg, .v-tools .btn svg { width: 14px; height: 14px; }
.histo { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: .8125rem; }
.histo li { line-height: 1.45; }
.obs-liste { list-style: none; margin: 0; padding: 0; }
.obs-liste li { padding: 9px 0; border-bottom: 1px solid var(--line); }
.obs-liste li:last-child { border-bottom: 0; }
.obs-tete { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.obs-texte { margin: 4px 0 0; white-space: pre-wrap; font-size: .875rem; }
.kpis.kpis-1 { grid-template-columns: 1fr; }
.kpis.kpis-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kpis.kpis-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpis.kpis-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.kpis.kpis-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.kpis.kpis-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.lots-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lot-carte { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding: 11px 14px; }
.lot-carte.lot-sans-objet { opacity: .62; }
.lot-tete { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start; }
.lot-tete > div:first-child { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.lot-nom { font-weight: 700; color: var(--ink-strong); }
.lot-corps { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: 4px 16px; margin-top: 6px; align-items: center; }
.lot-entreprise { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; min-width: 0; }
.lot-entreprise form.attribuer select { width: auto; max-width: 100%; padding: 5px 8px; font-size: .8125rem; }
.lot-dates { text-align: right; }
.lot-pieces { grid-column: 1 / -1; list-style: none; margin: 4px 0 0; padding: 0; border-top: 1px dashed var(--line); }
.lot-pieces li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 10px; padding: 6px 0; border-bottom: 1px dashed var(--line); }
.lot-pieces li:last-child { border-bottom: 0; }
.lot-pieces a { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; text-decoration: none; color: var(--ink); min-width: 0; flex: 1; }
.lot-pieces a:hover .lp-type { color: var(--accent); }
.lp-type { font-weight: 600; color: var(--ink-strong); font-size: .8125rem; }
.lp-montant { margin-left: auto; font-size: .8125rem; }
.lot-vide { grid-column: 1 / -1; margin: 2px 0 0; }
.lot-corps .j-note { grid-column: 1 / -1; }
.colonnes-cases { columns: 2; column-gap: 20px; }
.colonnes-cases .check-line { margin: 0 0 7px; break-inside: avoid; }
.sous-form { border: 1px dashed var(--line-strong); border-radius: 8px; padding: 10px; background: var(--surface-2); }
.depot-ignorer { margin-top: 10px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.suivi { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; counter-reset: suivi; }
.suivi li { position: relative; padding: 0 0 12px 26px; font-size: .875rem; color: var(--faint); }
.suivi li::before { content: ""; position: absolute; left: 4px; top: 4px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--line-strong); background: var(--surface); }
.suivi li::after { content: ""; position: absolute; left: 9px; top: 18px; bottom: 0; width: 2px; background: var(--line); }
.suivi li:last-child::after { display: none; }
.suivi li.done { color: var(--muted); }
.suivi li.done::before { background: var(--ok); border-color: var(--ok); }
.suivi li.cur { color: var(--ink-strong); font-weight: 600; }
.suivi li.cur::before { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.suivi li.warn { color: var(--warn); font-weight: 600; }
.suivi li.warn::before { border-color: var(--warn); background: var(--warn-soft); }

.j-photos.photos-grandes a { width: 96px; height: 96px; }
.envois-liste { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.envoi-ligne .mono { word-break: break-all; }
.envoi-ligne { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; background: var(--surface-2); }
.envoi-tete { align-items: flex-start; font-size: .875rem; }
.envoi-tete input { margin-top: 3px; }
.envoi-deja { margin: 4px 0 0 22px; color: var(--warn); }
.envoi-detail { display: grid; gap: 6px; margin: 8px 0 0 22px; }
.envoi-detail .field { max-width: 420px; }
.visites-liste { list-style: none; margin: 0; padding: 0; }
.visites-liste li { border-top: 1px solid var(--line); }
.visites-liste li:first-child { border-top: 0; }
.visites-liste a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; padding: 9px 0; color: inherit; text-decoration: none; }
.visites-liste a:hover .vl-titre { color: var(--accent); }
.vl-titre { font-weight: 600; color: var(--ink-strong); font-size: .875rem; }
.vl-meta { grid-column: 1; font-size: .78rem; color: var(--muted); }
.vl-chips { grid-row: 1 / span 2; grid-column: 2; display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; align-items: center; }
.intervenants { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.intervenants li { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 4px 10px; padding: 7px 0; border-top: 1px solid var(--line); font-size: .8125rem; }
.intervenants li:first-child { border-top: 0; }
.intervenants .lot-nom { font-size: .8125rem; }
.tel-lien { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.tel-lien svg { width: 13px; height: 13px; }

.btn svg { width: 15px; height: 15px; flex: none; }
.late { color: var(--crit); font-weight: 600; }
@media (max-width: 680px) {
  .chip { white-space: normal; }
  .kv dd.num { white-space: normal; }
  .tbl-cartes thead { display: none; }
  .tbl-cartes, .tbl-cartes tbody, .tbl-cartes tr, .tbl-cartes td { display: block; width: 100%; }
  .tbl-cartes tr { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding: 8px 12px; margin-bottom: 10px; }
  .tbl-cartes td { border: 0 !important; padding: 5px 0 !important; }
  .tbl-cartes td[data-label]:not(:first-child)::before { content: attr(data-label); display: block; font-size: .68rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); margin-bottom: 1px; }
  .tbl-cartes .tbl-actions .btn { min-height: 40px; padding: 8px 12px; font-size: .8125rem; }
  /* Une cellule d'actions se replie : plusieurs boutons sur une variante débordaient de l'écran. */
  .tbl-cartes td.tbl-actions { display: flex; flex-wrap: wrap; gap: 6px; }
  .tbl-cartes td.m-hide { display: none; }   /* v6.5 : colonnes secondaires masquées sur téléphone */
  .a-tbl-wrap:has(.tbl-cartes) { border: 0; background: transparent; overflow: visible; }
  /* v7.17 — Sur téléphone, un tableau devient des cartes : le titre de chapitre redevient un
     intertitre, et la ligne fille se colle à la carte qu'elle complète. */
  .tbl-cartes tr.tr-section { border: 0; background: transparent; padding: 10px 0 2px; margin-bottom: 0; }
  .tbl-cartes tr.tr-fille { margin-top: -8px; border-top-left-radius: 0; border-top-right-radius: 0; background: var(--sunken); }
}

.visite-rapide { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding: 10px 14px 12px; margin-bottom: 16px; }
.visite-rapide .block-title { margin-bottom: 8px; }
.visite-rapide-liste { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
.visite-rapide-liste .btn { min-height: 42px; flex: none; }

/* ---------- visite de chantier sur le téléphone (v6.1) ---------- */
.vc-body { background: var(--ground); min-height: 100vh; min-height: 100dvh; }
.vc-body input[type=text], .vc-body input[type=date], .vc-body input[type=datetime-local], .vc-body textarea, .vc-body select { font-size: 16px; padding: 10px 12px; }   /* 16 px : pas de zoom automatique sur iPhone */
.vc-app svg, dialog.vc-feuille svg, dialog.vc-visionneuse svg, .vc-annonce svg { width: 18px; height: 18px; flex: none; }
.vc-app .late { color: var(--crit); font-weight: 600; }
.vc-barre { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 8px; padding: 8px 12px; padding-top: calc(8px + env(safe-area-inset-top)); background: var(--surface); border-bottom: 1px solid var(--line); }
.vc-retour { display: grid; place-items: center; width: 40px; height: 40px; margin-left: -6px; border-radius: 10px; color: var(--ink-strong); flex: none; }
.vc-retour:hover { background: var(--sunken); color: var(--ink-strong); }
.vc-retour svg { width: 22px; height: 22px; }
.vc-barre-titre { min-width: 0; flex: 1; display: grid; line-height: 1.2; }
.vc-barre-titre strong { font-family: var(--font-display); font-stretch: 112%; font-size: 1rem; color: var(--ink-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vc-barre-titre span { font-size: .78rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vc-remarque { flex: none; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--surface); color: var(--ink-strong); font: inherit; font-size: .78rem; font-weight: 600; padding: 6px 11px; min-height: 36px; cursor: pointer; white-space: nowrap; }
.vc-remarque svg { width: 17px; height: 17px; flex: none; }
.vc-remarque:hover { border-color: var(--accent); color: var(--accent); }
/* Au téléphone, la bulle seule : le libellé mangeait le titre de la visite. Son nom reste pour les lecteurs d'écran. */
@media (max-width: 520px) { .vc-remarque { width: 40px; height: 40px; padding: 0; justify-content: center; } .vc-remarque span { display: none; } }
.vc-fenetre-tete .vc-remarque-fiche { width: 36px; height: 36px; min-height: 36px; padding: 0; justify-content: center; margin-left: auto; }
.vc-fenetre-tete .vc-remarque-fiche svg { width: 17px; height: 17px; }
.vc-pastille { flex: none; font-size: .75rem; padding: 5px 10px; }
.vc-pastille.vc-anime::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: vc-pulse 1s ease-in-out infinite; }
@keyframes vc-pulse { 50% { opacity: .25; } }
.vc-contenu { max-width: 720px; margin: 0 auto; padding: 12px 12px 28px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
body.vc-avec-actions .vc-contenu { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
.vc-chargement { text-align: center; color: var(--muted); padding: 48px 0; }
.vc-carte { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px; min-width: 0; }
.vc-carte h2 { font-size: 1.02rem; margin: 0; }
.vc-carte-tete { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.vc-carte-tete .count, .vc-intervenants summary .count, .vc-carte h2 .count { font-family: var(--font-body); font-size: .72rem; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); vertical-align: 2px; }
.vc-carte-calme { padding: 10px 14px; }
.vc-carte-calme .vc-aide { margin: 0; }
.vc-sous-titre { font-size: .95rem; margin: 18px 0 6px; }
.vc-label { display: block; font-weight: 600; font-size: .8125rem; color: var(--muted); margin: 14px 0 6px; }
.vc-aide { color: var(--muted); font-size: .8125rem; margin: 0 0 8px; }
.vc-aide svg { width: 16px; height: 16px; vertical-align: -3px; margin-right: 4px; }
.vc-alerte { color: var(--crit); font-weight: 600; margin: 8px 0 0; }
.vc-lien-discret { display: inline-flex; align-items: center; gap: 4px; font-size: .8125rem; font-weight: 600; text-decoration: none; }
.vc-lien-discret svg { width: 15px; height: 15px; }
.vc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.vc-chip { min-height: 40px; padding: 8px 13px; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--surface); color: var(--ink-strong); font-weight: 600; font-size: .875rem; cursor: pointer; line-height: 1.1; }
.vc-chip[aria-pressed=true] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.vc-ligne-date { display: flex; align-items: center; gap: 8px; margin: 12px 0 4px; font-weight: 600; color: var(--ink-strong); }
.vc-ligne-date svg { width: 17px; height: 17px; color: var(--muted); }
.vc-date-texte { flex: 1; }
/* v9.19 — DE L'AIR ENTRE LES GESTES (registre, point 50 : « des boutons semblent collés les uns aux autres »). Soudés,
   « Toujours à faire » et « Levé » se touchaient sur toute leur hauteur : au pouce, sur un chantier, on appuie sur le
   voisin. Chaque bouton a désormais son cadre, à huit pixels du suivant. */
.vc-seg { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; margin-top: 8px; }
.vc-seg button { min-height: 44px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--surface); color: var(--ink-strong); font-weight: 600; font-size: .875rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 5px; padding: 6px 4px; line-height: 1.15; }
.vc-seg button[aria-pressed=true] { background: var(--ink-strong); color: #fff; }
.vc-seg .vc-seg-ok[aria-pressed=true] { background: var(--ok); }
.vc-seg-niveaux button { font-size: .8125rem; }
.vc-seg-niveaux .vc-niv-a_reprendre[aria-pressed=true] { background: var(--warn); }
.vc-seg-niveaux .vc-niv-urgent[aria-pressed=true], .vc-seg-niveaux .vc-niv-securite[aria-pressed=true] { background: var(--crit); }
.vc-seg-niveaux .vc-niv-info[aria-pressed=true] { background: var(--info); }
.vc-points { list-style: none; margin: 0; padding: 0; }
.vc-point { padding: 12px 0 12px 10px; border-top: 1px solid var(--line); border-left: 3px solid transparent; margin-left: -14px; padding-left: 11px; }
.vc-point:first-child { border-top: 0; padding-top: 4px; }
.vc-point.levee { border-left-color: var(--ok); }
.vc-point-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.vc-point-qui { font-size: .8125rem; font-weight: 600; color: var(--ink-strong); }
.vc-point-texte { margin: 6px 0 2px; white-space: pre-wrap; }
.vc-point-meta { font-size: .78rem; color: var(--muted); margin: 0; }
.vc-point-photo { display: block; width: 110px; height: 82px; object-fit: cover; border-radius: 8px; margin-top: 8px; background: var(--sunken); }
.vc-note { margin-top: 8px; }
.vc-obs-liste { list-style: none; margin: 0 0 4px; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
.vc-obs { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 10px; width: 100%; text-align: left; border: 1px solid var(--line); border-radius: 10px; padding: 8px; background: var(--surface-2); color: var(--ink); font: inherit; cursor: pointer; align-items: start; }
.vc-obs:hover { border-color: var(--line-strong); }
.lecture .vc-obs { cursor: default; }
.vc-obs-photos { position: relative; width: 64px; height: 64px; border-radius: 8px; overflow: hidden; background: var(--sunken); display: grid; place-items: center; }
.vc-obs-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vc-obs-nb { position: absolute; right: 3px; bottom: 3px; font-size: .68rem; font-weight: 700; padding: 1px 5px; border-radius: 999px; background: rgba(22,27,29,.78); color: #fff; }
.vc-obs-corps { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px; min-width: 0; }
.vc-obs-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.vc-obs-qui { font-size: .78rem; font-weight: 600; color: var(--ink-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; min-width: 0; flex: 1 1 auto; }
.vc-obs-texte { font-size: .875rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; white-space: pre-wrap; }
.vc-obs-texte.vide { color: var(--faint); font-style: italic; }
.vc-obs-meta { font-size: .75rem; color: var(--muted); }
.vc-vignette-vide { display: grid; place-items: center; width: 100%; height: 100%; color: var(--faint); }
.vc-vignette-vide svg { width: 24px; height: 24px; }
.vc-boutons { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-top: 10px; }
.vc-boutons .btn { min-height: 44px; padding: 10px 14px; font-size: .9rem; position: relative; }
.vc-boutons .btn.btn-sm { min-height: 40px; padding: 8px 12px; font-size: .8125rem; }
.vc-boutons-colonne { flex-direction: column; align-items: stretch; margin-top: 14px; }
.vc-btn-photo { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.vc-btn-photo:hover { background: var(--accent-line); color: var(--accent-hover); }
label.btn { cursor: pointer; position: relative; overflow: hidden; }
.vc-fichier { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; pointer-events: none; }
.vc-photos { display: flex; flex-wrap: wrap; gap: 8px; }
.vc-photos:empty { display: none; }
.vc-vignette { position: relative; width: 78px; height: 78px; padding: 0; border: 1px solid var(--line); border-radius: 9px; overflow: hidden; background: var(--sunken); cursor: pointer; }
.vc-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vc-vignette.refusee { border: 2px solid var(--crit); }
.vc-vignette-alerte { position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--crit); color: #fff; font-size: .7rem; font-weight: 800; display: grid; place-items: center; }
.vc-intervenants summary { cursor: pointer; font-family: var(--font-display); font-stretch: 112%; font-weight: 720; color: var(--ink-strong); list-style: none; display: flex; align-items: center; gap: 6px; }
.vc-intervenants summary::-webkit-details-marker { display: none; }
.vc-intervenants summary::after { content: "▸"; margin-left: auto; color: var(--muted); transition: transform .15s; }
.vc-intervenants[open] summary::after { transform: rotate(90deg); }
.vc-intervenants ul { list-style: none; margin: 10px 0 0; padding: 0; }
.vc-intervenants li { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 6px 10px; padding: 9px 0; border-top: 1px solid var(--line); }
.vc-intervenants li > div:first-child { display: grid; min-width: 0; }
.vc-intervenants strong { font-size: .875rem; color: var(--ink-strong); }
.vc-intervenants span, .vc-intervenants small { font-size: .8rem; color: var(--muted); }
.vc-tels { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.vc-intervenants .vc-tels { margin-top: 0; }
.vc-tel { display: inline-flex; align-items: center; gap: 5px; min-height: 36px; padding: 6px 12px; border: 1px solid var(--line-strong); border-radius: 999px; font-weight: 600; font-size: .8125rem; text-decoration: none; color: var(--ink-strong); background: var(--surface); }
.vc-tel svg { width: 14px; height: 14px; color: var(--ok); }
.vc-fin { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; justify-items: center; padding: 6px 0 4px; }
.vc-large { width: 100%; min-height: 52px; font-size: 1rem; border-radius: 10px; }
.vc-actions { position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 6px 8px calc(6px + env(safe-area-inset-bottom)); background: rgba(255,255,255,.97); border-top: 1px solid var(--line); box-shadow: 0 -6px 20px -12px rgba(22,27,29,.25); }
.vc-action { position: relative; display: grid; place-items: center; gap: 1px; min-height: 56px; border: 0; border-radius: 10px; background: transparent; color: var(--ink-strong); font: inherit; font-size: .75rem; font-weight: 700; cursor: pointer; overflow: hidden; }
.vc-action:active { background: var(--sunken); }
.vc-action svg { width: 24px; height: 24px; }
.vc-action-photo { color: var(--accent); }
.vc-action-fin { color: var(--ok); }
dialog.vc-feuille { width: 100%; max-width: 100%; height: 100%; max-height: 100%; margin: 0; padding: 0; border: 0; background: var(--surface); color: var(--ink); }
dialog.vc-feuille[open] { display: flex; flex-direction: column; }
dialog.vc-feuille::backdrop, dialog.vc-visionneuse::backdrop { background: var(--scrim); }
.vc-fenetre-tete { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; padding: 12px 14px 10px 16px; padding-top: calc(12px + env(safe-area-inset-top)); border-bottom: 1px solid var(--line); }
.vc-fenetre-tete h2 { font-size: 1.1rem; margin: 0; }
.vc-fenetre-tete p { color: var(--muted); font-size: .8125rem; margin: 2px 0 0; }
.vc-fenetre-tete .x-btn { padding: 8px; margin: -4px -4px 0 0; }
.vc-fenetre-tete .x-btn svg { width: 22px; height: 22px; }
.vc-fenetre-corps { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 12px 16px 20px; }
.vc-fenetre-pied { display: flex; gap: 8px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: var(--surface); }
.vc-fenetre-pied .btn { flex: 1; min-height: 48px; font-size: .9375rem; }
.btn-danger-ghost { background: transparent; border-color: transparent; color: var(--crit); }
.btn-danger-ghost:hover { background: var(--crit-soft); border-color: transparent; color: var(--crit); }
dialog.vc-visionneuse { width: 100%; max-width: 100%; height: 100%; max-height: 100%; margin: 0; padding: 0; border: 0; background: #0d1011; color: #fff; }
dialog.vc-visionneuse[open] { display: flex; flex-direction: column; }
.vc-visionneuse-image { flex: 1; min-height: 0; display: grid; place-items: center; padding: 12px; }
.vc-visionneuse-image img { max-width: 100%; max-height: 100%; object-fit: contain; }
.vc-visionneuse-image .vc-aide { color: #c9d1d4; }
.vc-visionneuse-pied { display: flex; gap: 8px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); }
.vc-visionneuse-pied .btn { flex: 1; min-height: 48px; }
.vc-visionneuse-pied .btn-danger-ghost { color: #ffb4ab; }
.vc-etat { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
.vc-etat:empty { display: none; }
.vc-bandeau { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; font-size: .875rem; background: var(--sunken); color: var(--ink-strong); text-align: left; }
.vc-bandeau p { margin: 0; flex: 1; }
.vc-bandeau svg { width: 20px; height: 20px; }
.vc-bandeau.warn { background: var(--warn-soft); }
.vc-bandeau.warn svg { color: var(--warn); }
.vc-bandeau.crit { background: var(--crit-soft); }
.vc-bandeau.info { background: var(--info-soft); }
.vc-bandeau.ok { background: var(--ok-soft); }
.vc-bandeau.ok svg { color: var(--ok); }
.vc-bilan { list-style: none; margin: 0 0 6px; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.vc-bilan li { background: var(--surface-2); border-radius: 10px; padding: 8px 4px; text-align: center; font-size: .72rem; color: var(--muted); line-height: 1.2; }
.vc-bilan strong { display: block; font-family: var(--font-display); font-stretch: 112%; font-size: 1.35rem; color: var(--ink-strong); }
.vc-dests { list-style: none; margin: 0; padding: 0; }
.vc-dests li { border-bottom: 1px solid var(--line); }
.vc-dests label { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; cursor: pointer; }
.vc-dests input { width: 22px; height: 22px; margin-top: 1px; accent-color: var(--accent); flex: none; }
.vc-dests strong { display: block; color: var(--ink-strong); }
.vc-dests small { display: block; font-size: .78rem; color: var(--muted); }
.vc-dests .vc-emails { word-break: break-all; }
.vc-dests .sans-email { opacity: .65; }
.vc-autres { margin: 8px 0 4px; }
.vc-autres summary { cursor: pointer; font-weight: 600; font-size: .875rem; padding: 8px 0; color: var(--accent); }
.vc-fenetre-corps .check-line { margin: 12px 0 10px; font-size: .875rem; align-items: flex-start; }
.vc-fenetre-corps .check-line input { width: 20px; height: 20px; flex: none; }
.vc-terminee { text-align: center; }
.vc-terminee h2 { font-size: 1.2rem; margin: 8px 0 4px; }
.vc-rond-ok, .vc-rond-info { display: inline-grid; place-items: center; width: 58px; height: 58px; border-radius: 50%; background: var(--ok-soft); color: var(--ok); margin-top: 4px; }
.vc-rond-ok svg, .vc-rond-info svg { width: 30px; height: 30px; }
.vc-rond-info { background: var(--info-soft); color: var(--info); }
.vc-bilan-envoi { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; margin-top: 12px; }
.vc-bilan-envoi .btn { min-height: 44px; font-size: .9rem; }
.vc-envoi-ligne { display: flex; gap: 8px; align-items: flex-start; font-size: .875rem; text-align: left; margin: 0; }
.vc-envoi-ligne svg { width: 16px; height: 16px; margin-top: 3px; color: var(--accent); }
.vc-liste { list-style: none; margin: 0; padding: 0; }
.vc-liste li { border-top: 1px solid var(--line); }
.vc-liste li:first-child { border-top: 0; }
.vc-liste a { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 0; color: inherit; text-decoration: none; }
.vc-liste a > span:first-child { display: grid; min-width: 0; }
.vc-liste strong { color: var(--ink-strong); }
.vc-liste small { color: var(--muted); font-size: .78rem; }
.vc-annonce { position: fixed; left: 12px; right: 12px; bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 120; max-width: 560px; margin: 0 auto; background: var(--ink-strong); color: #fff; padding: 12px 14px; border-radius: 10px; font-size: .875rem; box-shadow: var(--shadow-pop); }
.vc-annonce.crit { background: var(--crit); }
.vc-annonce.warn { background: var(--warn); }
.vc-traitement { position: fixed; left: 50%; top: calc(64px + env(safe-area-inset-top)); transform: translateX(-50%); z-index: 130; background: var(--ink-strong); color: #fff; padding: 9px 14px; border-radius: 999px; font-size: .8125rem; font-weight: 600; box-shadow: var(--shadow-pop); white-space: nowrap; }
@media (min-width: 760px) {
  .vc-contenu { padding: 20px 16px 40px; gap: 14px; }
  body.vc-avec-actions .vc-contenu { padding-bottom: 40px; }
  .vc-actions { display: none; }
  .vc-carte { padding: 16px 18px; }
  dialog.vc-feuille { width: min(640px, calc(100vw - 32px)); height: auto; max-height: calc(100vh - 48px); margin: auto; border: 1px solid var(--line-strong); border-radius: 14px; box-shadow: var(--shadow-pop); }
  .vc-annonce { bottom: 24px; }
}
/* v9.19 — quatre niveaux espacés tiennent en une ligne au-dessus de 440 px ; en dessous, deux lignes de deux (relecture :
   « Information » débordait à 390 px). Les filets de l'ancien bloc soudé n'ont plus d'objet. */
@media (max-width: 440px) {
  .vc-seg-niveaux { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 380px) {
  .vc-bilan { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- impression ---------- */
@media print {
  .no-print, .a-top, .a-nav, .actions-bar, .filters, .tabs, .v-tools { display: none !important; }
  .a-shell { display: block; }
  .a-main { padding: 0; }
  body { background: #fff; font-size: 12px; }
  .card, details.section, .panel { border: none; padding: 0; }
}

/* ---------- écrans étroits ---------- */
/* v7.2 — La colonne latérale tombait sous le contenu dès 1100 px, alors que le menu de gauche, lui,
   tient jusqu'à 820. Sur une tablette en paysage (1024) on avait donc les deux : 216 px de menu, et
   le total de la proposition relégué sous trente lignes de tableau. La bascule attend 980. */
@media (max-width: 980px) {
  .cols { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 1100px) {
  .kpis.kpis-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .garanties { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .cols-even, .form-grille-3 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 820px) {
  .a-shell { grid-template-columns: minmax(0, 1fr); background: var(--surface); }
  .a-nav { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); padding: 6px 8px; gap: 4px; position: sticky; top: 51px; height: auto; z-index: 30; }
  .a-nav-btn { width: auto; white-space: nowrap; padding: 7px 10px; }
  .a-nav-sep, .a-nav-foot, .a-nav-titre { display: none; }
  .a-nav details.a-nav-groupe, .a-nav details.a-nav-groupe > summary { display: contents; }
  .a-brand { min-width: 0; }
  .a-main { padding: 16px 14px 28px; }
  .cartouche-app { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
  /* v7.7 — la carte au téléphone : une colonne de faits, des cibles de 40 px, et le pied du
     tiroir collé en bas pour qu'« Enregistrer » ne soit pas douze questions plus loin. */
  .carte-faits { grid-template-columns: minmax(0, 1fr); }
  .fait { min-height: 40px; grid-template-columns: minmax(0, 1fr); gap: 0; padding: 6px; }
  .carte-recherche { max-width: 100%; }
  .tiroir .check-line { align-items: flex-start; }
  .tiroir .check-line input { width: 20px; height: 20px; }
  .tiroir-pied { position: sticky; bottom: 0; background: var(--surface-2); padding-top: 8px; }
  .a-search { display: none; }
  /* v7.28 — .kpis-3 ET .kpis-5 NE SE RÉDUISAIENT JAMAIS SUR TÉLÉPHONE. La règle générale
     « .kpis { repeat(2, …) } » plus bas est d'une spécificité inférieure à « .kpis.kpis-3 », qui
     restait donc à TROIS colonnes de 126 px sur un écran de 390 — avec un montant en `white-space:
     nowrap` dedans. Le débordement ne s'est vu que le jour où les écrans du module Déboursé sont
     entrés dans tools/plateformes.py : quatre versions d'écrans n'y étaient pas. */
  .kpis.kpis-3, .kpis.kpis-4, .kpis.kpis-5, .kpis.kpis-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* v9.42 — sur deux colonnes, la dernière tuile d'un nombre impair restait seule, à côté d'une case grise : elle s'étire. */
  .kpis.kpis-3 > :last-child:nth-child(odd), .kpis.kpis-5 > :last-child:nth-child(odd) { grid-column: span 2; }
  .lot-corps { grid-template-columns: minmax(0, 1fr); }
  .lot-dates { text-align: left; }
  .colonnes-cases { columns: 1; }
  .cartes { grid-template-columns: minmax(0, 1fr); }
  .a-user-txt { display: none; }
  .a-top-right .btn-primary { padding: 6px 9px; }
  .act { grid-template-columns: minmax(0, 1fr); }
  .act-cta { justify-content: flex-start; }
  .form-grille { grid-template-columns: minmax(0, 1fr); }
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .points li, .pieces-list li { grid-template-columns: minmax(0, 1fr); }
  .p-btns { justify-content: flex-start; }
  .p-date { text-align: left; }
  .fiche-item { flex-direction: column; align-items: flex-start; }
  .fiche-item .right { text-align: left; }
  .detail-table th { width: 40%; }
}

/* ------------------------------------------------------------------ */
/* v6.3 — progression du dépôt des pièces                               */
/* ------------------------------------------------------------------ */
.prog-tete { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.prog-barre { height: 10px; margin: 0 0 10px; }
.prog-barre i { background: var(--accent); transition: width .4s ease; }
.prog-liste { list-style: none; margin: 0; padding: 0; }
.prog-liste li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; align-items: start; padding: 7px 0; border-bottom: 1px solid var(--line); }
.prog-liste li:last-child { border-bottom: 0; }
.prog-liste .prog-nom { display: block; font-weight: 600; color: var(--ink-strong); overflow-wrap: anywhere; }
.prog-liste li.e-encours .prog-nom { color: var(--accent); }
.prog-liste li.e-echec .ck-note { color: var(--crit); }
.prog-envoi { width: min(360px, 80vw); display: grid; gap: 6px; justify-items: center; }
.prog-envoi .prog-barre { width: 100%; margin: 0; background: rgba(255,255,255,.25); }
.prog-envoi .prog-barre i { background: #fff; }
.prog-envoi span { color: #fff; }

/* v6.3 — ouvrages, tarifs, métré */
.t-warn { color: var(--warn); }
.t-ok { color: var(--ok); }
.tbl-saisie input[type="text"], .tbl-saisie select { width: 100%; min-width: 0; padding: 4px 6px; font-size: .8125rem; }
.tbl-saisie input.qte, .tbl-saisie input.pu { width: 84px; text-align: right; font-variant-numeric: tabular-nums; }
.tbl-saisie input.phase { width: 110px; }
.tbl-saisie select[data-statut-sel], .tbl-saisie select[data-choix-prix] { min-width: 108px; }
.tbl-saisie input.obs { min-width: 120px; }
.tbl-saisie tr.commandee td { background: var(--surface-2); }
.tbl-saisie tr.l-option td .t-name, .tbl-saisie tr.l-non_compris td .t-name { color: var(--muted); font-weight: 500; }
.tbl-saisie tr.l-non_compris td { text-decoration: line-through; text-decoration-color: var(--faint); }
.tbl-saisie tr.l-non_compris td input, .tbl-saisie tr.l-non_compris td select { text-decoration: none; }
.tbl-saisie tr.m-lot-tete td { background: var(--sunken); font-weight: 700; color: var(--ink-strong); font-family: var(--font-display); font-stretch: 112%; }
.tbl-saisie tr.m-lot-pied td { font-weight: 600; border-bottom: 2px solid var(--line); }
.tbl-saisie tr.modifiee td { box-shadow: inset 3px 0 0 var(--accent); }
.metre-totaux { position: sticky; bottom: 0; background: var(--surface); border-top: 1px solid var(--line); padding: 10px 0 6px; display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: baseline; z-index: 3; }
.metre-totaux b { font-size: 1.05rem; color: var(--ink-strong); font-variant-numeric: tabular-nums; }
.metre-totaux .sep { flex: 1 1 auto; }
.recherche-ouvrage { position: relative; }
.recherche-ouvrage .suggestions { position: absolute; left: 0; right: 0; top: 100%; z-index: 20; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.12); max-height: 280px; overflow: auto; margin: 2px 0 0; padding: 4px 0; list-style: none; }
.recherche-ouvrage .suggestions li { padding: 6px 10px; cursor: pointer; display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 8px; font-size: .8125rem; align-items: baseline; }
.recherche-ouvrage .suggestions li:hover, .recherche-ouvrage .suggestions li[aria-selected="true"] { background: var(--accent-soft); }
.recherche-ouvrage .suggestions .s-lot { grid-column: 2; font-size: .72rem; color: var(--muted); }
.recherche-ouvrage .suggestions .s-prix { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ecart-pos { color: var(--crit); } .ecart-neg { color: var(--ok); }
.lots-metre { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }
.lot-metre { border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 14px; align-items: center; }
.lot-metre.fait { background: var(--surface-2); }
.lot-metre .lm-titre { font-weight: 700; color: var(--ink-strong); }
.lot-metre .lm-sub { font-size: .78rem; color: var(--muted); }
.lot-metre .lm-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 680px) { .lot-metre { grid-template-columns: 1fr; } .lot-metre .lm-actions { justify-content: flex-start; } }

/* v6.4 — budget du métré et marge */
.budget-panel { margin-bottom: 14px; border-left: 4px solid var(--accent); }
.budget-panel .kpis { margin-bottom: 8px; }
.budget-alertes { margin: 6px 0 0; }
.budget-alertes li { font-size: .8125rem; }
.tbl-budget tr.lot-sans-objet td { color: var(--faint); }
.tbl-budget tfoot td { font-weight: 600; border-top: 2px solid var(--line); }
.overlay-attente .prog-envoi { margin-top: -6px; }

/* ------------------------------------------------------------------ */
/* v6.2 — phases du dossier, préparation du bureau d'études, déroulé   */
/* ------------------------------------------------------------------ */
.phases { display: grid; grid-template-columns: repeat(4, minmax(120px, 1fr)); gap: 6px; list-style: none; margin: 0; padding: 0; min-width: 560px; }
.phases li { border-top: 4px solid var(--line); padding-top: 7px; color: var(--faint); min-width: 0; }
.phases li b { display: block; font-family: var(--font-display); font-stretch: 112%; font-size: .8rem; font-weight: 700; }
.phases li small { display: block; font-size: .72rem; line-height: 1.35; color: var(--faint); }
.phases li.done { border-top-color: var(--ink-strong); color: var(--muted); }
.phases li.cur { border-top-color: var(--accent); color: var(--accent); }
.phases li.cur small { color: var(--ink); }
.phases li.stop { border-top-color: var(--crit); color: var(--crit); }
.phases small .ph-ici { color: var(--accent); font-weight: 700; }
.phases small .ph-fait { color: var(--muted); }
.t-crit { color: var(--crit); }

.prep-panel { margin-bottom: 14px; }
.prep-dates { display: flex; gap: 8px; flex-wrap: wrap; }
.prep-dates > div { border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; display: grid; min-width: 150px; background: var(--surface-2); }
.prep-dates span { font-size: .66rem; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.prep-dates b { font-size: 1rem; color: var(--ink-strong); }
.prep-dates small { font-size: .72rem; color: var(--muted); }
.prep-barre { height: 6px; border-radius: 3px; background: var(--sunken); overflow: hidden; margin: 6px 0 4px; }
.prep-barre i { display: block; height: 100%; background: var(--ok); border-radius: 3px; }
.prep-groupe { font-family: var(--font-display); font-stretch: 112%; font-weight: 700; font-size: .85rem; color: var(--ink-strong); margin: 16px 0 2px; }
.prep-liste { list-style: none; margin: 0; padding: 0; }
.prep-etape { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto auto; gap: 4px 10px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--line); scroll-margin-top: 110px; }
.prep-etape:last-child { border-bottom: 0; }
.prep-etape:target { background: var(--accent-soft); box-shadow: -8px 0 0 var(--accent-soft), 8px 0 0 var(--accent-soft); }
.prep-lib { font-weight: 600; color: var(--ink-strong); }
.prep-etape.e-sans_objet .prep-lib { color: var(--muted); font-weight: 500; text-decoration: line-through; text-decoration-color: var(--line-strong); }
.prep-etape.e-fait .prep-lib { font-weight: 500; color: var(--ink); }
.prep-date { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; font-size: .78rem; white-space: nowrap; }
.prep-etape.e-retard .prep-date .mono { color: var(--crit); font-weight: 600; }
.prep-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; align-items: flex-start; }
.prep-actions .inline-form { display: inline; }
.prep-saisie { position: relative; }
.prep-saisie > summary { list-style: none; }
.prep-saisie > summary::-webkit-details-marker { display: none; }
.prep-saisie[open] > summary { background: var(--sunken); }
.prep-form { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; width: min(420px, 86vw); background: var(--surface); border: 1px solid var(--line-strong); border-radius: 9px; box-shadow: var(--shadow-pop); padding: 12px; }

.deroule { list-style: none; margin: 0; padding: 0; position: relative; }
.deroule li { display: grid; grid-template-columns: 14px 92px minmax(0, 1fr); gap: 10px; align-items: baseline; padding: 6px 0; font-size: .85rem; }
.deroule li::before { content: ""; width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--line-strong); background: var(--surface); transform: translateY(1px); }
.deroule li.done::before { background: var(--ink-strong); border-color: var(--ink-strong); }
.deroule li.next::before { border-color: var(--accent); background: var(--accent-soft); }
.deroule li.late::before { border-color: var(--crit); background: var(--crit-soft); }
.deroule .d-date { font-family: var(--font-mono); font-size: .78rem; color: var(--muted); }
.deroule li.next .d-date, .deroule li.next .d-txt { color: var(--accent); font-weight: 600; }
.deroule li.late .d-date, .deroule li.late .d-txt { color: var(--crit); font-weight: 600; }
.deroule .d-txt small { color: var(--muted); font-weight: 400; margin-left: 4px; }

.cs-liste { list-style: none; margin: 0; padding: 0; }
.cs-liste > li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.cs-liste > li:first-child { padding-top: 2px; }
.cs-lib { margin: 0 0 6px; font-weight: 600; color: var(--ink-strong); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.cs-champs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 10px; }
.cs-champs .large { grid-column: 1 / -1; }

.tbl-prep { min-width: 110px; }
.tbl-prep .prep-barre { margin: 4px 0 0; height: 5px; }

@media (max-width: 680px) {
  .phases { grid-template-columns: repeat(4, minmax(96px, 1fr)); min-width: 420px; }
  .prep-etape { grid-template-columns: 20px minmax(0, 1fr); }
  .prep-date { grid-column: 2; flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: wrap; }
  .prep-actions { grid-column: 2; justify-content: flex-start; }
  .prep-form { position: static; width: auto; margin-top: 6px; box-shadow: none; }
  .prep-dates > div { min-width: 0; flex: 1 1 130px; }
}
@media (max-width: 480px) {
  .cs-champs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cs-champs .cs-etat { grid-column: 1 / -1; }
}

/* ------------------------------------------------------------------ */
/* v6.5 — interface allégée : cartouche compact, volets et sous-onglets,  */
/* blocs repliés sur téléphone, navigation par profil                    */
/* ------------------------------------------------------------------ */
.meta-strip { margin: 10px 0 14px; }
.meta-strip-summary { display: none; }
.meta-strip-liste { display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 0; padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); font-size: .8125rem; }
.meta-strip-liste > div { display: flex; gap: 6px; align-items: baseline; min-width: 0; }
.meta-strip-liste dt { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 600; white-space: nowrap; }
.meta-strip-liste dd { margin: 0; font-weight: 600; color: var(--ink-strong); overflow-wrap: anywhere; }
.meta-strip-liste dd.reserve { font-weight: 500; color: var(--faint); font-style: italic; }
.tabs { margin: 14px 0 0; }
.subtabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0 0; }
.subtab { font-size: .8125rem; font-weight: 500; padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink); text-decoration: none; white-space: nowrap; }
.subtab:hover { border-color: var(--faint); color: var(--ink-strong); }
.subtab[aria-current="page"] { background: var(--ink-strong); border-color: var(--ink-strong); color: var(--ground); }
.subtab .count { font-size: .68rem; font-weight: 700; margin-left: 5px; padding: 0 5px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); }
.subtab[aria-current="page"] .count { background: rgba(255,255,255,.22); color: #fff; }
.tabs + .subtabs, .tabs + [role="tabpanel"], .subtabs + [role="tabpanel"] { margin-top: 14px; }
/* v9.12 — le gabarit fixe du dossier (planche A1) */
.subtab-fantome { visibility: hidden; pointer-events: none; }
.synthese-phases { margin: 0 0 18px; }
.meta-strip-outil { margin-left: auto; }
.meta-strip-replier { border: 0; background: none; padding: 0; font: inherit; font-size: .75rem; color: var(--muted); cursor: pointer; }
.meta-strip-replier:hover { color: var(--ink-strong); }
.meta-strip-rappel { font-weight: 500; color: var(--muted); }
@media (min-width: 681px) {
  .meta-strip:not([open]) .meta-strip-summary { display: block; padding: 6px 12px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); font-size: .8125rem; font-weight: 600; color: var(--ink-strong); cursor: pointer; }
  .meta-strip:not([open]) .meta-strip-summary::before { content: "▸ "; color: var(--faint); }
}
[role="tabpanel"] { margin-top: 16px; }
.act-why { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.act.deplie .act-why { display: block; -webkit-line-clamp: unset; }
.act-why[data-long] { cursor: pointer; }
.a-nav details.a-nav-groupe > summary { list-style: none; cursor: pointer; }
.a-nav details.a-nav-groupe > summary::-webkit-details-marker { display: none; }
.a-nav details.a-nav-groupe > summary .a-nav-titre { display: flex; align-items: center; justify-content: space-between; }
.a-nav details.a-nav-groupe > summary .a-nav-titre::after { content: "▾"; font-size: .7rem; }
.a-nav details.a-nav-groupe[open] > summary .a-nav-titre::after { content: "▴"; }
/* v6.12 — Menu latéral : sections repliables (total des alertes visible quand la section est fermée) et masquage complet */
.a-nav details.a-nav-groupe > summary:hover .a-nav-titre { color: var(--ink-strong); }
.a-nav details.a-nav-groupe > summary .a-nav-titre .count { margin-left: auto; margin-right: 6px; font-size: .7rem; font-weight: 700; min-width: 20px; text-align: center; padding: 1px 6px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); letter-spacing: 0; text-transform: none; }
.a-nav details.a-nav-groupe > summary .a-nav-titre .count.hot { background: var(--crit-soft); color: var(--crit); }
.a-nav details.a-nav-groupe[open] > summary .a-nav-titre .count { display: none; }
.a-nav-bascule { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; flex: none; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2); color: var(--muted); cursor: pointer; }
.a-nav-bascule:hover { background: var(--sunken); color: var(--ink-strong); }
.a-nav-bascule svg { width: 17px; height: 17px; }
html.nav-masquee .a-shell { grid-template-columns: minmax(0, 1fr); background: var(--surface); }
html.nav-masquee .a-nav { display: none; }
html.nav-masquee .a-brand { min-width: 0; }
@media (max-width: 820px) { .a-nav-bascule { display: none; } }
/* v6.12 — Annotation d'une photo (flèches, cercles, texte dessinés sur l'image) */
.an-dlg { width: min(1100px, 96vw); max-width: 96vw; padding: 0; }
.an-barre { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--surface-2); position: sticky; top: 0; z-index: 2; }
.an-groupe { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.an-outil[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.an-couleur { width: 26px; height: 26px; border-radius: 999px; border: 2px solid var(--line); cursor: pointer; padding: 0; }
.an-couleur[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--ink-strong); }
.an-cadre { display: flex; justify-content: center; align-items: center; padding: 12px; background: #1b1f22; min-height: 220px; }
.an-toile { touch-action: none; cursor: crosshair; max-width: 100%; background: #fff; border-radius: 4px; }
.an-pied { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 10px 14px; border-top: 1px solid var(--line); background: var(--surface); }
.an-etat { margin: 0 auto 0 0; font-size: .8rem; color: var(--muted); }
.photo-annot { display: inline-block; vertical-align: top; }
.photo-annot .an-image { position: relative; display: inline-block; vertical-align: top; line-height: 0; max-width: 100%; }
.photo-annot .an-marque { position: absolute; left: 4px; bottom: 4px; background: rgba(27,31,34,.78); color: #fff; font-size: .64rem; font-weight: 600; padding: 1px 6px; border-radius: 999px; letter-spacing: .02em; pointer-events: none; }
.j-photos .an-actions { display: flex; gap: 4px; margin-top: 3px; }
.photo-annot .an-actions { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
/* v6.15 — le crayon est posé sur la vignette : on voit qu'une photo s'annote sans avoir à l'ouvrir */
.photo-annot .an-crayon { position: absolute; right: 4px; top: 4px; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 999px; background: rgba(27,31,34,.72); color: #fff; cursor: pointer; }
.photo-annot .an-crayon svg { width: 15px; height: 15px; }
.photo-annot .an-crayon:hover { background: var(--accent); }
.photo-annot .an-crayon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: none) { .photo-annot .an-crayon { width: 30px; height: 30px; } }
.vc-vignette-cadre { position: relative; display: inline-block; }
.vc-crayon { position: absolute; right: 3px; top: 3px; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 999px; background: rgba(27,31,34,.74); color: #fff; cursor: pointer; }
.vc-crayon svg { width: 16px; height: 16px; }
.vc-crayon:active { background: var(--accent); }
@media (max-width: 680px) { .an-barre { gap: 6px 8px; padding: 8px 10px; } .an-cadre { padding: 6px; } }

/* v6.12 — Annuaire en liste : coordonnées cliquables dans la cellule Contact */
.tbl-liens { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: .8rem; }
.tbl-liens a { color: var(--accent); }
/* Blocs repliables sur téléphone : le titre devient un bouton, seul le premier bloc de la page reste ouvert */
.panel-replie > .block-title, .panel-replie > .v-head { cursor: pointer; margin-bottom: 0; }
.panel-replie > *:not(.block-title):not(.v-head):not(.v-tools) { display: none !important; }
.panel[data-replie-titre] > .block-title::after, .panel[data-replie-titre] > .v-head > .block-title::after { content: " ▾"; color: var(--faint); font-weight: 400; }
.panel-replie[data-replie-titre] > .block-title::after, .panel-replie[data-replie-titre] > .v-head > .block-title::after { content: " ▸"; }
@media (max-width: 680px) {
  .no-mobile { display: none !important; }
  .meta-strip { border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
  .meta-strip-summary { display: block; padding: 8px 12px; font-size: .8125rem; font-weight: 600; color: var(--ink-strong); cursor: pointer; }
  .meta-strip:not([open]) .meta-strip-summary::after { content: " ▸"; color: var(--faint); }
  .meta-strip[open] .meta-strip-summary::after { content: " ▾"; color: var(--faint); }
  .meta-strip-liste { border: 0; border-top: 1px solid var(--line); border-radius: 0; flex-direction: column; gap: 6px; }
  /* Sur téléphone la bande passe en colonne, mais chaque ligne restait un flex dont l'étiquette ne
     se coupe pas : une adresse de chantier un peu longue sortait de l'écran. Elle passe maintenant
     sous son étiquette plutôt que de déborder. */
  .meta-strip-liste > div { flex-wrap: wrap; }
  .cockpit-title h1 { font-size: 1.3rem; }
  .crumbs { display: none; }
  .v-head { margin-bottom: 8px; }
  .v-tools { gap: 6px; }
  .v-tools .btn { padding: 7px 10px; font-size: .8125rem; }
  .tabs { position: sticky; top: 51px; z-index: 25; background: var(--ground); margin-top: 8px; }
  .subtabs { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
  .kpis, .kpis.kpis-3, .kpis.kpis-4, .kpis.kpis-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kpi b, .kpis b { font-size: 1.05rem; }
  .panel { padding: 12px 12px; }
  .banner { padding: 8px 12px; font-size: .8125rem; }
  .pied { font-size: .72rem; }
  /* Jalons : sur téléphone, seuls le jalon en cours (ou en retard) et les jalons validés récents gardent leurs boutons ;
     un appui sur un jalon affiche les siens */
  .jalons:not(.tout) li:not(.cur):not(.late):not(.ouvert) .j-actions { display: none; }
  .jalons li { padding-bottom: 12px; }
}

/* v6.6 — prospects : pipeline en colonnes */
.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(230px, 1fr); gap: 10px; overflow-x: auto; padding-bottom: 8px; align-items: start; -webkit-overflow-scrolling: touch; }
.kb-col { background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 10px; min-height: 120px; }
.kb-tete { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 4px; }
.kb-n { font-family: var(--font-mono); font-size: .78rem; color: var(--muted); }
.kb-aide { font-size: .72rem; color: var(--faint); margin: 0 0 8px; line-height: 1.3; }
.kb-carte { display: grid; gap: 2px; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; text-decoration: none; color: inherit; }
.kb-carte:hover { border-color: var(--faint); }
.kb-carte.kb-retard { border-left: 3px solid var(--crit); }
.kb-nom { font-weight: 700; color: var(--ink-strong); }
.kb-sub { font-size: .75rem; color: var(--muted); }
/* v7.8 — À qui est le projet se lit sous son nom, pas à sa place. */
.kb-client { color: var(--ink); font-weight: 500; }
.kb-action { font-size: .78rem; font-weight: 600; margin-top: 2px; }
@media (max-width: 680px) { .kanban { grid-auto-columns: minmax(82vw, 1fr); } }
.v-tools form.inline-form select, .v-tools form.inline-form input[type="search"], .v-tools form.inline-form input[type="date"] { width: auto; min-width: 0; padding: 6px 8px; font-size: .8125rem; }

/* v6.7 — Tableaux triables et saisie avec recherche (Entreprises du chantier) */
.th-tri { all: unset; cursor: pointer; font: inherit; color: inherit; display: inline-flex; align-items: center; gap: 4px; }
.th-tri::after { content: '↕'; font-size: .72rem; color: var(--faint); }
/* « all: unset » remet outline-style à none et écrase la règle globale :focus-visible, déclarée plus
   haut à spécificité égale : les en-têtes de tri n'avaient aucun anneau de focus au clavier. */
.th-tri:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
th[aria-sort=ascending] .th-tri::after { content: '↑'; color: var(--accent); }
th[aria-sort=descending] .th-tri::after { content: '↓'; color: var(--accent); }
.th-tri:hover { color: var(--accent); }
tr.lot-sans-objet td { opacity: .55; }
tr.lot-sans-objet td.tbl-actions { opacity: 1; }
.dates-lot { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.dates-lot input[type=date] { width: auto; font-size: .78rem; padding: 3px 5px; }
button.lien { all: unset; cursor: pointer; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; font: inherit; }
button.lien:hover { color: var(--accent-hover); }
.combo { position: relative; width: 100%; max-width: 100%; }
.combo .combo-select { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; left: 0; top: 0; }
.combo .combo-input { width: 100%; }
.combo-liste { position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 3px); margin: 0; padding: 4px; list-style: none; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 8px; box-shadow: var(--shadow-pop); max-height: 260px; overflow: auto; }
.combo-liste li { padding: 7px 9px; border-radius: 6px; cursor: pointer; font-size: .88rem; line-height: 1.3; }
.combo-liste li.actif, .combo-liste li:hover { background: var(--accent-soft); color: var(--accent-hover); }
.combo-liste li.choisi { font-weight: 650; }
.combo-liste li.combo-special { color: var(--muted); font-style: italic; }
.combo-liste li.combo-vide { color: var(--faint); cursor: default; }
dialog .combo-liste { max-height: 200px; }
.tbl-cartes td.tbl-actions { text-align: right; }
@media (max-width: 680px) {
  .th-tri::after { display: none; }
  .tbl-cartes td.tbl-actions { text-align: left; }
}

/* v6.8 — Navigation du téléphone : barre d'onglets en bas (l'essentiel du profil) et volet « Plus » */
.m-tabs, .m-sheet { display: none; }
@media (max-width: 820px) {
  .a-nav { display: none; }
  .a-main { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }
  .m-tabs { position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); background: var(--surface); border-top: 1px solid var(--line); padding: 4px 4px calc(4px + env(safe-area-inset-bottom)); box-shadow: 0 -6px 20px -14px rgba(22,27,29,.35); }
  .m-tab { all: unset; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 52px; padding: 5px 2px; border-radius: 9px; color: var(--muted); font-size: .66rem; font-weight: 600; letter-spacing: .01em; text-align: center; cursor: pointer; position: relative; -webkit-tap-highlight-color: transparent; }
  .m-tab svg { width: 22px; height: 22px; }
  .m-tab span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .m-tab[aria-current="page"] { color: var(--accent); background: var(--accent-soft); }
  .m-tab:active { background: var(--sunken); }
  .m-count { position: absolute; top: 2px; left: calc(50% + 6px); font-size: .62rem; font-weight: 700; min-width: 17px; height: 17px; line-height: 17px; padding: 0 5px; border-radius: 999px; background: var(--sunken); color: var(--ink-strong); text-align: center; }
  .m-count.hot { background: var(--crit); color: #fff; }
  .m-sheet { display: block; position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: 100%; max-height: 88vh; max-height: 88dvh; border: 0; border-radius: 16px 16px 0 0; padding: 0 0 calc(10px + env(safe-area-inset-bottom)); background: var(--surface); box-shadow: 0 -20px 50px -20px rgba(22,27,29,.5); overflow: auto; }
  .m-sheet:not([open]) { display: none; }
  .m-sheet::backdrop { background: rgba(22,27,29,.45); }
  .m-sheet-tete { position: sticky; top: 0; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px 8px; background: var(--surface); border-bottom: 1px solid var(--line); }
  .m-sheet-tete h2 { margin: 0; font-size: 1rem; }
  .m-sheet-tete h2 small { display: block; font-size: .75rem; font-weight: 500; color: var(--muted); font-family: var(--font-body); font-stretch: normal; }
  .m-sheet-recherche { position: relative; margin: 10px 14px 4px; }
  .m-sheet-recherche svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--faint); }
  .m-sheet-recherche input[type=search] { width: 100%; padding: 10px 10px 10px 32px; font-size: 16px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--surface-2); }
  .m-sheet-liste { display: grid; padding: 4px 8px; }
  .m-sheet-titre { font-size: .66rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); padding: 12px 8px 4px; margin: 0; font-family: var(--font-display); }
  .m-sheet-btn { display: flex; align-items: center; gap: 12px; padding: 11px 10px; border-radius: 9px; color: var(--ink); text-decoration: none; font-size: .95rem; min-height: 44px; }
  .m-sheet-btn svg { width: 19px; height: 19px; color: var(--muted); flex: none; }
  .m-sheet-btn[aria-current="page"] { background: var(--accent-soft); color: var(--accent-hover); font-weight: 600; }
  .m-sheet-btn .m-count { position: static; margin-left: auto; }
  .a-top { padding: 9px 12px; }
}

/* v7.17 — LA MÊME BARRE, POUR UNE LISTE FILTRÉE PAR LE SERVEUR.
   « liste-outils » n'est pas une mise en forme : c'est un CONTRAT avec app.js, qui promet un
   tableau filtré dans le navigateur et qui EXIGE « data-cible ». L'employer pour son seul aspect
   coûtait deux fois : document.querySelector('') levait une SyntaxError qui tuait tout le
   JavaScript câblé après elle — sur les sept tailles d'écran —, et sur téléphone la règle qui
   replie les sélecteurs derrière un bouton « Filtres » posé PAR app.js les faisait disparaître
   sans laisser de moyen de les rouvrir. Une classe de mise en forme a donc son propre nom. */
.barre-filtres { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.barre-filtres input[type=search] { width: auto; min-width: 200px; flex: 1 1 220px; max-width: 360px; padding: 7px 10px; font-size: .875rem; }
.barre-filtres select { width: auto; padding: 7px 28px 7px 10px; font-size: .85rem; max-width: 100%; }
.barre-filtres .lo-compte { font-size: .8rem; color: var(--muted); margin-left: auto; white-space: nowrap; }
@media (max-width: 680px) {
  .barre-filtres input[type=search], .barre-filtres select { flex: 1 1 100%; min-width: 0; max-width: none; font-size: 16px; }
  .barre-filtres .lo-compte { margin-left: 0; flex: 1 1 100%; }
}

/* v6.8 — Barre d'outils d'une liste : recherche instantanée, filtres, tri (téléphone), compteur */
.liste-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.liste-outils input[type=search] { width: auto; min-width: 200px; flex: 1 1 220px; max-width: 360px; padding: 7px 10px; font-size: .875rem; }
.liste-outils select { width: auto; padding: 7px 28px 7px 10px; font-size: .85rem; }
.liste-outils select[data-tri] { display: none; }
.liste-outils select[data-tri].lo-tri-cartes { display: block; }
.liste-outils .lo-compte { font-size: .8rem; color: var(--muted); margin-left: auto; white-space: nowrap; }
.liste-outils .btn-sm[data-raz] { padding: 5px 9px; }
.liste-outils .lo-filtres { display: none; }
.liste-vide { color: var(--muted); font-size: .9rem; padding: 14px 4px; }
@media (max-width: 680px) {
  .liste-outils { position: sticky; top: 51px; z-index: 20; background: var(--surface); padding: 8px 0; margin: -6px 0 10px; border-bottom: 1px solid var(--line); flex-wrap: nowrap; }
  .liste-outils input[type=search] { flex: 1 1 auto; min-width: 0; max-width: none; font-size: 16px; }
  /* v6.9 — filtres et tri repliés derrière le bouton « Filtres (n) » ; le compteur reste discret à côté */
  .liste-outils .lo-filtres { display: inline-flex; flex: 0 0 auto; white-space: nowrap; }
  .liste-outils .lo-filtres.lo-actif { border-color: var(--accent, #1E3A5F); color: var(--accent, #1E3A5F); font-weight: 600; }
  /* v7.2 : « .lo-filtres ~ .lo-compte » masquait le compteur DANS TOUS LES CAS — le bouton « Filtres »
     est inséré par app.js juste après la recherche, donc le compteur en est toujours un frère suivant.
     On filtrait deux cents contacts au doigt sans jamais savoir combien il en restait, et la règle
     qui le restylait ligne suivante était morte. Seuls les SÉLECTEURS se replient. */
  .liste-outils select, .liste-outils [data-raz] { display: none; }
  .liste-outils .lo-compte { margin-left: 0; white-space: nowrap; }
  .liste-outils.lo-ouvert { flex-wrap: wrap; }
  .liste-outils.lo-ouvert select { display: block; flex: 1 1 40%; font-size: 16px; }
  .liste-outils.lo-ouvert [data-raz] { display: inline-flex; }
  .liste-outils.lo-ouvert .lo-compte { display: block; margin-left: 0; flex: 1 1 100%; }
  .liste-outils.lo-ouvert select[data-tri] { display: block; }
  .v-sub { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .m-sheet-btn { color: var(--ink); }
}

/* v6.9 — proposition commerciale : totaux */
.tot-ligne { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; border-bottom: 1px solid var(--line); font-size: .875rem; }
.tot-ligne:last-child { border-bottom: 0; }
.tot-total { font-weight: 700; font-size: 1rem; border-top: 2px solid var(--ink); border-bottom: 0; margin-top: 2px; }

/* v6.9 — onglet Documents : dépôt en tête, groupes par catégorie */
.depot-doc { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(220px, 1fr); gap: 16px; align-items: start; }
.depot-doc-cote { display: grid; gap: 8px; }
.depot-doc-cote .btn { justify-self: start; }
.docs-groupes { display: grid; gap: 10px; }
.docs-groupe { border: 1px solid var(--line); border-radius: 9px; background: var(--surface); }
.docs-groupe > summary { display: flex; align-items: center; gap: 10px; padding: 10px 14px; cursor: pointer; font-weight: 600; list-style: none; }
.docs-groupe > summary::-webkit-details-marker { display: none; }
.docs-groupe > summary::before { content: '›'; display: inline-block; width: 12px; color: var(--muted); transition: transform .15s; }
.docs-groupe[open] > summary::before { transform: rotate(90deg); }
.docs-groupe > summary .count { margin-left: auto; font-size: .75rem; color: var(--muted); background: var(--surface-2); border-radius: 999px; padding: 2px 8px; }
.docs-groupe > .pieces-list { padding: 0 14px 6px; border-top: 1px solid var(--line); }
@media (max-width: 680px) { .depot-doc { grid-template-columns: 1fr; } }

/* v6.9 — onglet Assistant */
.assist-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.assist-grille > .panel { margin: 0; }
.assist-carte { display: flex; flex-direction: column; gap: 8px; }
.assist-carte .btn { align-self: flex-start; }
/* v7.5 — deux entrées, deux moitiés. La grille « auto-fill » était taillée pour cinq cartes : avec
   deux, elle les serrait à gauche sur un tiers de l'écran et laissait les deux autres colonnes
   vides. Les paragraphes des deux cartes se lisent, ils ne se survolent pas. */
.assist-deux { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }   /* « min(…, 100%) » : sous 352 px, la piste suit l'écran au lieu de le déborder */
.assist-deux > .panel { justify-content: space-between; }
.assist-deux .assist-carte > p:last-child { margin-top: auto; }
.assist-docs { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.assist-docs li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: .85rem; }
.assist-docs li .btn { margin-left: auto; }

/* v6.10 — glisser-déposer du pipeline */
.kb-carte[draggable] { cursor: grab; }
.kb-carte.kb-glisse { opacity: .5; }
.kb-carte.kb-attente { opacity: .6; pointer-events: none; }
.kb-col.kb-cible { outline: 2px dashed var(--accent); outline-offset: -4px; background: var(--accent-soft); }

/* v6.10 — fiche prospect : pièces compactes */
.pieces-compact li { grid-template-columns: 110px minmax(0, 1fr) auto; padding: 7px 0; }
/* v7.7 — Cette piste de 110 px l'emportait sur le repli en une colonne de la ligne 773 : même
   spécificité, déclarée plus loin, c'est l'ordre du fichier qui tranche. Sur téléphone, le nom du
   fichier n'avait donc plus que 119 px. Le repli se pose ici, et pas là-haut, pour la même raison. */
@media (max-width: 680px) { .pieces-compact li { grid-template-columns: minmax(0, 1fr); } }
/* v9.11 — dans une barre latérale (la proposition, 310 px) : une seule colonne, les boutons sous le nom. */
.t-ok { color: var(--ok, #2f7d4f); }

/* v6.11 — séries de propositions sur la fiche prospect */
.prop-serie + .prop-serie { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
/* v9.19 — la tête d'une proposition est un seul lien (point 54) : elle se montre cliquable, comme la ligne d'une étude. */
.prop-tete { display: block; color: inherit; text-decoration: none; border-radius: 8px; padding: 6px 8px; margin: -6px -8px 2px; border: 1px solid transparent; }
.prop-tete:hover, .prop-tete:focus-visible { background: var(--surface-2); border-color: var(--line); color: inherit; }
.prop-tete:hover .dchip, .prop-tete:focus-visible .dchip { border-color: var(--accent); color: var(--accent); }

/* v6.11 — facturation prévisionnelle : encaissements attendus par mois */
.prevb { display: flex; align-items: flex-end; gap: 6px; height: 150px; padding-top: 6px; overflow-x: auto; }
.prevb-col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 4px; min-width: 62px; flex: 1 1 0; height: 100%; }
.prevb-val { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.prevb-barre { display: block; width: 100%; max-width: 46px; background: var(--accent); border-radius: 4px 4px 0 0; min-height: 4px; }
.prevb-mois { font-size: .72rem; text-align: center; color: var(--ink); }

/* v6.11 — diagramme de Gantt (planning du chantier et vue générale).
   Tout est positionné en « jours » : --g-jour (largeur d'un jour) change au zoom et l'affichage suit sans recalcul. */
.gantt { --g-jour: 10px; --g-lib: 208px; --g-jours: 60; --g-offset: 0; --g-today: -99;
  position: relative; margin-top: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.g-scroll { position: relative; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; }
.g-fond { position: absolute; top: 0; bottom: 0; left: var(--g-lib); width: calc(var(--g-jours) * var(--g-jour)); z-index: 0; pointer-events: none;
  background-image: repeating-linear-gradient(to right, transparent 0 calc(var(--g-jour) * 5), var(--sunken) calc(var(--g-jour) * 5) calc(var(--g-jour) * 7));
  background-position: calc(var(--g-offset) * var(--g-jour)) 0; }
.g-fond i { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); left: calc(var(--o) * var(--g-jour)); }
.g-fond b { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--crit); opacity: .5; left: calc(var(--g-today) * var(--g-jour)); }
.g-ligne { position: relative; z-index: 1; display: flex; align-items: stretch; min-height: 32px; border-top: 1px solid var(--line);
  width: calc(var(--g-lib) + var(--g-jours) * var(--g-jour)); }   /* largeur réelle du contenu : sans quoi la colonne des libellés ne peut pas rester collée à gauche */
.g-lib { position: sticky; left: 0; z-index: 3; flex: 0 0 var(--g-lib); width: var(--g-lib); min-width: 0; padding: 5px 10px;
  display: flex; flex-direction: column; justify-content: center; gap: 1px; font-size: .8rem; line-height: 1.25;
  background: var(--surface); border-right: 1px solid var(--line); }
.g-lib a { text-decoration: none; font-weight: 500; }
.g-lib .t-sub { font-size: .7rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-piste { position: relative; flex: 0 0 calc(var(--g-jours) * var(--g-jour)); min-width: calc(var(--g-jours) * var(--g-jour)); }
.g-groupe { position: sticky; left: 0; z-index: 4; padding: 6px 10px; background: var(--surface-2); border-top: 1px solid var(--line);
  font-size: .74rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.g-groupe a { text-decoration: none; }
.g-groupe .t-sub { text-transform: none; letter-spacing: 0; font-weight: 500; }
.g-entete { min-height: 40px; background: var(--surface-2); }
.g-entete .g-lib { background: var(--surface-2); font-weight: 700; font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.g-ech-mois { position: absolute; top: 3px; left: calc(var(--o) * var(--g-jour)); width: calc(var(--w) * var(--g-jour));
  padding-left: 5px; border-left: 1px solid var(--line-strong); font-size: .72rem; font-weight: 600; color: var(--ink);
  overflow: hidden; white-space: nowrap; }
.g-ech-jour { position: absolute; bottom: 2px; left: calc(var(--o) * var(--g-jour)); width: calc(var(--g-jour)); text-align: center; font-size: .62rem; color: var(--faint); }
.g-ech-jour.g-we { color: var(--line-strong); }
.g-barre { position: absolute; top: 4px; bottom: 4px; left: calc(var(--o) * var(--g-jour)); width: calc(var(--w) * var(--g-jour)); min-width: 9px;
  display: flex; align-items: center; padding: 0 7px; border: 1px solid var(--accent-line); border-radius: 5px; background: var(--accent-soft);
  font-size: .73rem; color: var(--ink-strong); white-space: nowrap; user-select: none; touch-action: pan-y;
  cursor: grab; transition: box-shadow .12s ease; }
/* le texte est rogné dans la barre (et non la barre elle-même) : le rond de liaison dépasse à droite */
.g-barre .g-texte { min-width: 0; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }
.g-barre.g-encours { background: var(--ok-soft); border-color: var(--ok); }
.g-barre.g-sansent { background: var(--surface-2); border-style: dashed; color: var(--muted); }
.g-barre.g-conflit { background: var(--crit-soft); border-color: var(--crit); }
.g-barre.g-fixe { cursor: default; }
.g-barre:not(.g-fixe):hover { box-shadow: 0 2px 8px -2px rgba(22,27,29,.35); }
.g-barre.g-glisse { cursor: grabbing; z-index: 6; box-shadow: var(--shadow-pop); }
.g-barre.g-attente { opacity: .55; }
.g-barre:focus-visible, .g-jalon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.g-poignee { position: absolute; top: 0; right: 0; bottom: 0; width: 10px; cursor: ew-resize; }
.g-barre:not(.g-fixe):hover .g-poignee::before { content: ''; position: absolute; top: 50%; right: 3px; width: 2px; height: 12px; margin-top: -6px; border-radius: 2px; background: var(--line-strong); }
.g-jalon { position: absolute; top: 50%; left: calc(var(--o) * var(--g-jour)); width: 13px; height: 13px; margin: -7px 0 0 -7px;
  background: var(--accent); border: 1px solid var(--accent-hover); border-radius: 3px; transform: rotate(45deg); cursor: grab; touch-action: pan-y; }
.g-jalon.g-fait { background: var(--ok); border-color: var(--ok); }
.g-jalon.g-fixe { cursor: default; }
.g-jalon.g-glisse { z-index: 6; box-shadow: var(--shadow-pop); }
.g-jalon.g-attente { opacity: .55; }
/* v7.4 — « à planifier » COLLE à la colonne de gauche. Posé au début de la frise, il se retrouvait
   hors écran dès qu'on cadrait sur aujourd'hui : sur un chantier non daté, la seule chose à cliquer
   de toute la zone était invisible. Il suit maintenant le défilement. */
.g-vide { position: sticky; left: calc(var(--g-lib) + 6px); z-index: 2; display: inline-block;
  margin: 6px 0 0 6px; font-size: .72rem; font-style: italic; color: var(--faint); }
button.g-vide { font-family: inherit; font-style: normal; cursor: pointer; color: var(--accent);
  background: var(--accent-soft); border: 1px dashed var(--accent-line); border-radius: 4px; padding: 2px 9px; }
button.g-vide:hover { background: #DDE2F5; }
/* v7.4 — La fenêtre des lots Progemi : une grille à trois colonnes, et non un flex où le libellé
   bascule sous le numéro dès que la colonne se resserre. */
.lots-outils { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding-bottom: 10px;
  margin-bottom: 10px; border-bottom: 1px solid var(--line); }
.lots-outils input[type="search"] { flex: 1 1 180px; min-width: 0; }
.lots-phase { margin: 14px 0 5px; padding-bottom: 3px; border-bottom: 1px solid var(--line);
  font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.lots-phase:first-child { margin-top: 0; }
.lot-ligne { display: grid; grid-template-columns: auto 1fr auto; gap: 0 10px; align-items: baseline;
  padding: 5px 4px; border-radius: 4px; cursor: pointer; }
.lot-ligne:hover { background: var(--surface-2); }
.lot-ligne input { align-self: center; margin: 0; }
.lot-ligne .lot-nom { min-width: 0; }
.lot-ligne.lot-deja { opacity: .5; cursor: default; }
.lot-ligne.lot-deja:hover { background: transparent; }
@media (max-width: 460px) {
  .lot-ligne { grid-template-columns: auto 1fr; row-gap: 1px; }
  .lot-ligne .t-sub { grid-column: 2; }
}

/* v7.4 — Une chaîne rompue se voit. Nom distinct de .g-conflit, qui dit déjà « cette entreprise est
   sur deux chantiers à la fois » dans la vue générale : deux sens pour une même bordure rouge
   deviendraient illisibles le jour où les deux tombent sur la même barre. */
.g-barre.g-chaine-rompue { outline: 2px solid var(--crit); outline-offset: 1px; }
.g-liens path.g-lien-rompu { stroke: var(--crit); stroke-width: 2; }
.g-liens path.g-fleche.g-lien-rompu { fill: var(--crit); }

/* v7.4 — Plein écran DANS la page : l'API du navigateur ne s'applique pas à un élément sur iPhone,
   et c'est le conducteur sur tablette qui en a le plus besoin. Rester dans la page garde les
   formulaires, les fenêtres et les envois intacts. */
.g-plein-titre { display: none; align-items: center; gap: 12px; margin: 0 0 10px; padding-bottom: 8px;
  border-bottom: 1px solid var(--line); }
#g-zone.g-plein { position: fixed; inset: 0; z-index: 60; background: var(--ground); padding: 14px 16px;
  display: flex; flex-direction: column; overflow: auto; }
#g-zone.g-plein .g-plein-titre { display: flex; }
.g-plein-titre strong { flex: 1 1 auto; min-width: 0; }
.g-plein-outils { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
#g-zone.g-plein .gantt { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
#g-zone.g-plein .g-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }   /* point 93a : des lignes plus hautes — la dernière ne se coupe plus */
.g-bulle { position: fixed; z-index: 60; pointer-events: none; padding: 4px 9px; border-radius: 6px; background: var(--ink-strong); color: #fff;
  font-size: .74rem; white-space: nowrap; box-shadow: var(--shadow-pop); }
.g-etat { min-height: 20px; margin: 8px 0 0; font-size: .8rem; color: var(--muted); }
.g-etat.ok { color: var(--ok); }
.g-etat.err { color: var(--crit); }
.g-zoom { display: inline-flex; }
.g-zoom .btn { border-radius: 0; margin-left: -1px; }
.g-zoom .btn:first-child { border-radius: 7px 0 0 7px; margin-left: 0; }
.g-zoom .btn:last-child { border-radius: 0 7px 7px 0; }
.g-zoom .btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
@media (max-width: 680px) {
  .gantt { --g-lib: 132px; }
  .g-lib { padding: 5px 7px; font-size: .74rem; }
}

/* v6.11 — tableau de bord (cockpit) */
.entonnoir { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.entonnoir li { display: grid; grid-template-columns: 122px minmax(0, 1fr) 44px; align-items: center; gap: 10px; }
.ent-lib { font-size: .82rem; color: var(--ink); }
.ent-barre { height: 14px; border-radius: 7px; background: var(--sunken); overflow: hidden; }
.ent-barre i { display: block; height: 100%; background: var(--accent); border-radius: 7px; min-width: 2px; }
.ent-val { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; text-decoration: none; }
.mini-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.mini-liste li { font-size: .84rem; line-height: 1.35; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.mini-liste li:last-child { padding-bottom: 0; border-bottom: 0; }
.mini-liste .t-sub { display: block; font-size: .74rem; }
.tb-jauge { width: 110px; max-width: 100%; margin: 2px 0 0; }
@media (max-width: 700px) { .entonnoir li { grid-template-columns: 96px minmax(0, 1fr) 38px; } }


/* ---------- v6.13 : densité compacte ----------
   Le réglage vit dans le navigateur de chacun (menu du compte), comme le menu masqué.
   Il resserre les espacements sans rien changer à la structure : mêmes blocs, mêmes colonnes. */
html.densite-compacte { --pad-main: 12px 18px 28px; }
html.densite-compacte body { font-size: 14px; }
html.densite-compacte h1 { font-size: 1.3rem; margin-bottom: 10px; }
html.densite-compacte h2 { font-size: 1.02rem; margin-bottom: 8px; }
html.densite-compacte .panel { padding: 10px 12px; }
html.densite-compacte .panel + .panel { margin-top: 10px; }
html.densite-compacte .card { padding: 11px 13px; margin-bottom: 11px; }
html.densite-compacte .a-tbl th { padding: 6px 9px; }
html.densite-compacte .a-tbl td { padding: 6px 9px; }
html.densite-compacte .kpi { padding: 7px 10px; }
html.densite-compacte .kpis { margin-bottom: 11px; }
html.densite-compacte .a-nav { padding: 8px 8px; }
html.densite-compacte .a-nav-btn { padding: 5px 9px; }
html.densite-compacte .block-title { margin-bottom: 7px; }
html.densite-compacte .cols { gap: 12px; }
html.densite-compacte .act { padding-top: 9px; padding-bottom: 9px; }

/* ---------- v6.13 : éditeur de message ---------- */
.editeur { border: 1px solid var(--line-strong); border-radius: 8px; background: var(--surface); overflow: hidden; }
.editeur:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.ed-barre { display: flex; flex-wrap: wrap; gap: 2px; padding: 5px 6px; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.ed-outil { min-width: 30px; min-height: 30px; padding: 3px 7px; border: 1px solid transparent; border-radius: 6px; background: none; color: var(--ink); font-size: .85rem; cursor: pointer; }
.ed-outil:hover { background: var(--sunken); border-color: var(--line); }
.ed-zone { min-height: 190px; max-height: 46vh; overflow-y: auto; padding: 10px 12px; font-size: .9rem; line-height: 1.55; outline: none; }
.ed-zone p { margin: 0 0 9px; }
.ed-zone ul, .ed-zone ol { margin: 0 0 9px; padding-left: 22px; }
.ed-zone li { margin-bottom: 3px; }
.ed-zone:empty::before { content: attr(data-vide); color: var(--faint); }
.ed-assistant { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.ed-assistant .t-sub { flex: 1 1 100%; }
@media (max-width: 680px) { .ed-zone { min-height: 150px; } .ed-outil { min-width: 38px; min-height: 38px; } }
.lien-bouton { background: none; border: 0; padding: 0; color: var(--accent); font: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.lien-bouton:hover { color: var(--accent-hover); }

/* ---------- v6.13 : liens entre lots du Gantt ---------- */
/* v6.14 — Lier deux lots à la souris : le rond au bout d'une barre se tire jusqu'au lot qui doit suivre */
.g-attache { position: absolute; top: 50%; right: -7px; width: 13px; height: 13px; margin-top: -6.5px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: crosshair; opacity: 0; transition: opacity .12s ease; touch-action: none; z-index: 7; }
.g-barre:hover .g-attache, .g-barre:focus-within .g-attache, .gantt.g-liaison .g-attache { opacity: 1; }
.gantt.g-liaison { cursor: crosshair; }
.gantt.g-liaison .g-barre { cursor: crosshair; }
.g-barre.g-cible { outline: 2px solid var(--accent); outline-offset: 2px; }
.g-trait { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 8; overflow: visible; }
.g-trait path { fill: none; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 4; }
.g-liens { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 2; overflow: visible; }
.g-liens path { fill: none; stroke: var(--accent); stroke-width: 1.4; opacity: .75; }
.g-liens path.g-fleche { fill: var(--accent); stroke: none; opacity: .75; }
.g-lib-btn { background: none; border: 0; padding: 0 0 0 6px; color: var(--accent); font: inherit; font-size: .7rem; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.g-lib-btn:hover { color: var(--accent-hover); }
.j-riche p { margin: 0 0 7px; }
.j-riche ul, .j-riche ol { margin: 0 0 7px; padding-left: 20px; }
.j-riche > :last-child { margin-bottom: 0; }

/* ---------- v6.15 — Lecteur PDF (assets/lecteur.js, rendu par PDF.js hébergé) ---------- */
.pdf-lecteur { display: flex; flex-direction: column; min-height: 0; background: var(--sunken); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.pdf-lecteur.pdf-plein { height: calc(100vh - 168px); min-height: 420px; }
.pdf-barre { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding: 7px 10px; background: var(--surface); border-bottom: 1px solid var(--line); }
.pdf-groupe { display: flex; align-items: center; gap: 4px; }
.pdf-groupe.pdf-fin { margin-left: auto; }
.pdf-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--muted); cursor: pointer; }
.pdf-btn:hover { border-color: var(--line-strong); color: var(--ink); background: var(--surface-2); }
.pdf-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pdf-pagination { display: inline-flex; align-items: center; gap: 4px; font-size: .82rem; color: var(--muted); }
/* v9.32 — LA LOUPE SUR LE TEXTE (point 80, remontée n° 34). « input[type=search] » et « input[type=text] » (plus haut, 0,1,1)
   l'emportaient sur « .pdf-q » et « .pdf-page » (0,1,0) : le champ perdait la marge de sa loupe, qui recouvrait le texte, et
   le numéro de page prenait la hauteur d'un champ de formulaire. On les nomme dans leur groupe (0,2,0). */
.pdf-pagination .pdf-page { width: 44px; padding: 3px 5px; text-align: center; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); font-family: var(--font-mono); font-size: .78rem; }
.pdf-zoom-valeur { min-width: 48px; text-align: center; font-size: .76rem; color: var(--muted); }
.pdf-recherche { flex: 1 1 200px; max-width: 380px; min-width: 0; position: relative; }
.pdf-recherche .pdf-loupe { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: var(--faint); pointer-events: none; display: flex; }
.pdf-recherche .pdf-q { flex: 1 1 auto; min-width: 0; padding: 5px 8px 5px 30px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); font-size: .82rem; }
.pdf-recherche .pdf-q:focus { outline: none; border-color: var(--accent); }
.pdf-compte { font-size: .74rem; white-space: nowrap; min-width: 62px; text-align: right; }
.pdf-compte:empty { min-width: 0; }   /* rien de cherché : pas de blanc entre le champ et ses flèches */
.pdf-pages { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 14px 0 24px; text-align: center; scroll-behavior: auto; }
.pdf-pages:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pdf-page-cadre { position: relative; display: inline-block; margin: 0 auto 14px; background: #fff; box-shadow: 0 2px 10px -2px rgba(22,27,29,.35); }
.pdf-page-cadre canvas { display: block; width: 100%; height: 100%; }
.pdf-page-cadre.pdf-page-erreur::after { content: "Page illisible"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--crit); background: var(--crit-soft); font-size: .82rem; }
.pdf-etat { padding: 40px 20px; color: var(--muted); font-size: .88rem; }
.pdf-page-cadre { --scale-factor: 1; --total-scale-factor: 1; }
.pdf-texte { position: absolute; inset: 0; overflow: clip; opacity: 1; line-height: 1; text-align: initial; forced-color-adjust: none; transform-origin: 0 0; caret-color: CanvasText; -webkit-text-size-adjust: none; text-size-adjust: none; }
.pdf-texte :is(span, br) { position: absolute; white-space: pre; color: transparent; cursor: text; transform-origin: 0 0; }
.pdf-texte ::selection { background: rgba(58,74,159,.32); }
.pdf-texte span[role="img"] { user-select: none; }
.pdf-surlignes { position: absolute; inset: 0; pointer-events: none; }
.pdf-surligne { position: absolute; background: rgba(255,196,0,.42); border-radius: 2px; }
.pdf-surligne-courant { background: rgba(255,140,0,.62); outline: 1px solid rgba(173,42,32,.6); }
/* Côte à côte : le document à gauche, la vérification à droite (voir lecteur_cote_a_cote()) */
.cote-a-cote { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.cote-a-cote > .pdf-volet { position: sticky; top: 12px; }
.cote-a-cote .pdf-lecteur { height: calc(100vh - 130px); min-height: 380px; }
.pdf-volet-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.cote-a-cote-plie { grid-template-columns: 1fr; }
.cote-a-cote-plie .pdf-lecteur { display: none; }
.cote-a-cote-plie .pdf-volet { position: static; }
.cote-a-cote-plie .pdf-volet-tete { margin-bottom: 0; }
/* La colonne de vérification est moitié moins large : ses blocs à deux colonnes se remettent sur une seule */
.cote-a-cote .cote-droite .cols-even { grid-template-columns: 1fr; }
/* Barre d'outils à l'étroit : la recherche passe sur sa propre ligne */
.cote-a-cote .pdf-recherche { order: 9; flex-basis: 100%; max-width: none; }
@media (max-width: 1100px) {
  .cote-a-cote { grid-template-columns: 1fr; }
  .cote-a-cote > .pdf-volet { position: static; }
  .cote-a-cote .pdf-lecteur { height: 60vh; min-height: 320px; }
}
@media (max-width: 700px) {
  .pdf-barre { gap: 5px 8px; padding: 6px; }
  .pdf-groupe.pdf-fin { margin-left: 0; }
  .pdf-recherche { order: 9; flex-basis: 100%; }
  .pdf-lecteur.pdf-plein { height: calc(100vh - 190px); }
}
@media print {
  .pdf-lecteur { border: 0; }
  .pdf-barre { display: none; }
}

/* v7.6 — Les huit règles du « dépôt de pièces sur la demande de chiffrage » (v6.17) sont parties
   avec l'écran qu'elles habillaient : .zone-depot, #listeAjouts et leurs sœurs n'avaient plus un
   seul porteur dans le dépôt. Une feuille de style qui décrit un écran disparu le fait revivre la
   prochaine fois qu'on cherchera « à quoi ressemble un dépôt de pièces ». */

/* ------------------------------------------------------------------ */
/* v7.2 — Le bloc commercial au doigt                                  */
/* ------------------------------------------------------------------ */
/* Cinq écrans de liste, onze dialogues, et un métier qui travaille debout sur un chantier. Ces
   règles ne changent aucune mise en page : elles rendent atteignable ce qui l'était mal. */

/* La barre de filtres d'une liste : ce qui était recopié en style dans chaque écran. */
.filtres-form { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* Un compteur qui s'aligne sur ses voisins, dans la colonne étroite d'une liste .checks. Il portait
   « width:44px » en ligne, dans une colonne de grille de 20 px : il débordait sur le libellé. */
.checks-chiffres li { grid-template-columns: 46px minmax(0, 1fr) auto; }
.checks .tab-num { font-variant-numeric: tabular-nums; text-align: right; justify-self: end; }

@media (max-width: 680px) {
  /* Sous 16 px, Safari iOS AGRANDIT la page au premier appui dans un champ — et n'y revient jamais.
     La modale sort du cadre, son pied part hors écran, et la page reste décalée. La maison le savait
     déjà pour la visite de chantier (.vc-body, plus haut) : la règle n'avait jamais atteint le reste. */
  input[type=text], input[type=number], input[type=date], input[type=email], input[type=password],
  input[type=search], input[type=tel], input[type=datetime-local], input[type=time],
  textarea, select { font-size: 16px; }
  .v-tools form.inline-form select, .v-tools form.inline-form input[type=search] { font-size: 16px; }
  /* Les champs qui portent leur propre taille, plus spécifique que la règle générale : le zoom ne
     se déclenche que sur une SAISIE de texte, donc on reprend celles-là nommément. */
  .mail-draft textarea, .tbl-saisie input[type="text"], .dates-lot input[type=date],
  .liste-outils input[type=search], .ed-zone, .pdf-recherche .pdf-q, .pdf-pagination .pdf-page { font-size: 16px; }

  /* Le pied d'un dialogue défilait avec son contenu : clavier ouvert, « Enregistrer » devenait
     inatteignable sur les dialogues longs (Nouveau projet : 11 champs ; Produit : 15). */
  .m-foot { position: sticky; bottom: 0; background: var(--surface); }

  /* Une cible de 24 px ne se touche pas avec le pouce. On n'élargit rien : on épaissit. */
  .btn-sm { min-height: 40px; }
  .fchip, .filters a, .subtab { padding: 9px 13px; }
  .x-btn { min-width: 40px; min-height: 40px; display: inline-grid; place-items: center; padding: 0; }
  .dchip { padding: 7px 10px; }

  /* Les deux barres du haut empilaient jusqu'à ~530 px de filtres avant la première ligne de liste.
     Elles défilent maintenant à l'horizontale, comme les sous-onglets le font déjà. */
  /* .filters occupe toute la largeur du contenu : elle peut mordre sur la gouttière et défiler
     jusqu'au bord, comme les sous-onglets le font déjà. */
  .filters {
    /* « position: relative » n'est pas décoratif : sans lui, un descendant en position ABSOLUE —
       l'étiquette « sr-only » d'un sélecteur de filtre, invisible mais bien dans le flux — prend
       pour référence un ancêtre placé plus haut, échappe au conteneur qui défile, et tire la PAGE
       entière jusqu'à sa position. Mesuré sur l'annuaire : 375 px de contenu, 597 px de page. */
    position: relative;
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    margin-inline: -14px; padding-inline: 14px; padding-bottom: 4px;
  }
  /* La barre de filtres d'une liste : sur téléphone elle DÉFILE au lieu de s'empiler. Elle est un
     ÉLÉMENT de .v-tools, donc pas de marge négative — elle saignerait hors de son parent au lieu de
     défiler dedans. Elle défile chez elle, et elle accepte de rétrécir (min-width: 0, sans quoi un
     conteneur flex refuse de passer sous sa taille de contenu). */
  /* Un élément de conteneur flex porte « min-width: auto », c'est-à-dire la largeur MINIMALE de son
     contenu : tant que .v-tools la garde, la barre qui défile impose sa taille au parent au lieu de
     rétrécir, et c'est le parent qui sort de l'écran. Les deux vont ensemble. */
  .v-head > .v-tools { min-width: 0; max-width: 100%; }
  .filtres-form {
    position: relative;   /* même raison que .filters ci-dessus : retenir un enfant absolu */
    flex: 1 1 100%;       /* une ligne à elle, qu'elle remplit sans la dépasser */
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    max-width: 100%; min-width: 0; padding-bottom: 4px;
  }

  /* « m-hide » ne valait que sur une cellule de tableau. Une aide qui ne sert qu'à la souris — le
     mode d'emploi du glisser-déposer — doit pouvoir se retirer aussi. */
  .m-hide { display: none; }

  /* En mode carte, l'étiquette d'une cellule de nombre héritait de l'alignement à droite : elle et
     sa valeur étaient les seules de la carte à fuir vers la marge. .tbl-actions a sa correction
     depuis la v6.13 ; .num ne l'avait pas. */
  .tbl-cartes td.num { text-align: left; }
}

/* La barre d'action de la demande de chiffrage passait SOUS la barre d'onglets du téléphone : les
   deux sont collées en bas, et celle du bas est plus haute dans la pile. « Transmettre au bureau
   d'études » était recouvert pendant tout le défilement. */
@media (max-width: 820px) {
  .actions-bar { bottom: calc(60px + env(safe-area-inset-bottom)); }
}

/* ===== v7.8 — LE VOLET IDENTITÉ DE LA FICHE CONTACT ======================================= */
/* Dix-huit champs se saisissaient dans la colonne de 310 px : 276 px utiles, deux colonnes de
   131 px, 109 px de texte visible. « SCI LES TILLEULS » — l'exemple même du champ — y mesure 116 px
   et s'affichait « SCI LES TILLEUL ». Le volet prend la colonne large et se plafonne à la mesure
   d'un formulaire : deux colonnes de 366 px, 344 px de texte.
   Et « large » posé sur autre chose qu'un .field ne correspond à AUCUNE règle de cette feuille :
   seuls « .field.large » et « .cs-champs .large » existent. Les deux blocs pleine largeur de ce
   formulaire nomment donc leur propre classe plutôt que de s'appuyer sur une classe qui ne fait
   rien — six autres endroits du dépôt s'y appuient pourtant, et c'est une version à elle seule. */
.volet-identite { max-width: 780px; }
.volet-identite .bloc-morale,
.volet-identite .ligne-enregistrer { grid-column: 1 / -1; }
.volet-identite .bloc-morale { margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--line); }

/* ------------------------------------------------------------------ */
/* v7.11 — La saisie d'une ligne de proposition, dans le tableau        */
/* ------------------------------------------------------------------ */
/* La dernière ligne de chaque section est un formulaire, pas une fenêtre. Elle se distingue par un
   fond et un trait discontinu : on doit voir qu'elle attend, sans qu'elle se confonde avec une
   ligne vendue. */
.ligne-saisie > td { background: var(--surface-2); border-top: 1px dashed var(--line-strong); }
.ligne-saisie .saisie-form { position: relative; margin: 0; }
.saisie-libelle,
.saisie-cellule {
  width: 100%; box-sizing: border-box; font: inherit;
  padding: 7px 9px; border: 1px solid var(--line-strong); border-radius: 7px; background: var(--surface);
}
.saisie-cellule { font-family: var(--font-mono); text-align: right; }
.saisie-libelle:focus, .saisie-cellule:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
/* Un prix d'achat qui manque se voit sans qu'on le cherche. */
.saisie-cellule.manque { border-color: var(--warn); background: var(--warn-soft); }
.ligne-alerte > td { background: var(--warn-soft); }

.saisie-propositions {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 2px);
  background: var(--surface); border: 1px solid var(--accent); border-radius: 9px;
  box-shadow: var(--shadow-pop); overflow: hidden; max-height: 19rem; overflow-y: auto;
}
.saisie-choix {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 9px 12px; border: 0; border-bottom: 1px solid var(--sunken); background: var(--surface);
  font: inherit; color: var(--ink); cursor: pointer;
}
.saisie-choix:last-child { border-bottom: 0; }
.saisie-choix { -webkit-user-select: none; user-select: none; }
.saisie-choix:hover, .saisie-choix.est-actif { background: var(--accent-soft); }
.saisie-choix-gauche { flex: 1 1 auto; min-width: 0; }
.saisie-choix-droite { flex: 0 0 auto; text-align: right; }
.saisie-choix-nom { display: block; font-weight: 600; }
.saisie-choix-sub { display: block; font-size: .82rem; color: var(--muted); }
.saisie-choix-prix { display: block; font-family: var(--font-mono); font-weight: 600; }
.saisie-choix-achat { display: block; font-family: var(--font-mono); font-size: .78rem; color: var(--muted); }
.saisie-choix-achat.manque { color: var(--warn); }

/* Sur téléphone, la ligne de saisie se déplie comme les autres cartes du tableau — AU MÊME SEUIL
   que `.tbl-cartes` (680 px). Le premier jet coupait à 760 : entre 681 et 760 px, le tableau était
   encore un tableau tandis que les cellules de la saisie se croyaient déjà en cartes, et les quatre
   `<td>` se rassemblaient dans une cellule anonyme. Deux seuils pour une même bascule n'en font
   jamais qu'un troisième état que personne n'a dessiné. */
@media (max-width: 680px) {
  .tbl-cartes .ligne-saisie > td { display: block; width: auto; }
  .tbl-cartes .ligne-saisie > td:empty { display: none; }   /* les cellules de calage n'ont rien à déplier */
  .saisie-propositions { position: static; margin-top: 6px; max-height: 14rem; }
}

/* v7.11 — Une ligne qui n'entre pas dans le total du bloc (option proposée, coût annexe) se lit
   comme telle : on doit voir d'un coup d'œil pourquoi l'addition des lignes ne fait pas le total. */
.ligne-hors-total > td { color: var(--faint); }
.ligne-hors-total > td strong { font-weight: 500; }
/* Le bouton d'enregistrement d'un prix d'achat reste discret, et s'allume dès qu'on touche la case. */
.saisie-valider { opacity: .35; transition: opacity .12s; }
.saisie-cellule:focus ~ .saisie-valider, .saisie-valider:focus, .saisie-valider.est-actif { opacity: 1; }

/* v7.13 — LE ✓ SE RANGE DANS LA CASE. La vue Déboursé porte désormais CINQ cases saisissables par
   ligne : cinq boutons posés à côté d'elles se coinçaient entre les colonnes, brouillaient la
   lecture des chiffres et rognaient la désignation au point qu'un nom de maison tenait sur trois
   lignes. Le bouton passe donc À L'INTÉRIEUR du champ, contre son bord droit, et ne se montre que
   lorsqu'il y a quelque chose à enregistrer — la case a le focus, ou sa valeur a changé.
   Il reste ATTEIGNABLE AU CLAVIER en permanence (`:focus-within` le révèle) : un bouton qu'on ne
   peut pas tabuler n'existe pas pour qui n'a pas de souris. */
.cellule-form { position: relative; display: block; }
/* La place du ✓ n'est prise QUE quand il est là. Réservée en permanence, elle coupait les nombres
   par la droite — « 150 000,00 » se lisait « 150 000, » — c'est-à-dire qu'on rognait la donnée pour
   loger un bouton invisible. */
.cellule-form:focus-within .saisie-cellule,
.cellule-form.modifiee .saisie-cellule { padding-right: 2.2em; }
.cellule-form .saisie-valider {
  position: absolute; right: 3px; top: 50%; transform: translateY(-50%);
  opacity: 0; pointer-events: none; padding: 2px 6px; min-height: 0; line-height: 1;
}
.cellule-form:focus-within .saisie-valider,
.cellule-form.modifiee .saisie-valider { opacity: 1; pointer-events: auto; }
.cellule-form.modifiee .saisie-cellule { border-color: var(--accent); }

/* ------------------------------------------------------------------ */
/* v7.12 — Les outils d'une ligne de proposition, et la poignée       */
/* ------------------------------------------------------------------ */
/* Les boutons se rangeaient n'importe comment : « Modifier ↑ » sur une ligne, « ↓ Retirer » sur
   la suivante, les flèches loin du bouton auquel elles se rapportent. Ils tiennent désormais sur
   une seule ligne, et les deux flèches forment un groupe qu'on lit comme un seul objet. */
.ligne-outils { white-space: nowrap; }
.ligne-outils .inline-form { display: inline-flex; align-items: center; gap: 2px; vertical-align: middle; }
.ligne-outils > .btn, .ligne-outils > span { vertical-align: middle; }
/* v7.13 : les flèches ↑↓ ont disparu — la poignée les remplace, souris ET clavier. */

/* La poignée : discrète au repos, franche au survol. Elle reste `hidden` tant que le script ne
   l'a pas découverte — une prise annoncée qui ne prend pas est pire qu'une prise absente. */
.ligne-poignee {
  display: inline-block; cursor: grab; color: var(--faint); padding: 2px 6px;
  font-size: 1.05rem; line-height: 1; user-select: none; -webkit-user-select: none;
  border: 0; background: transparent; font-family: inherit;
}
/* Elle s'atteint au clavier : le focus doit se voir, sans quoi on ne sait pas qu'on la tient. */
.ligne-poignee:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; color: var(--accent); border-radius: 5px; }
.ligne-poignee:hover { color: var(--ink); }
tr.ligne-prise { opacity: .45; }
tr.ligne-prise .ligne-poignee { cursor: grabbing; }
tr.ligne-cible > td { box-shadow: inset 0 2px 0 var(--accent); }

/* v7.13 — LES FLÈCHES NE DISPARAISSENT QUE LÀ OÙ LA POIGNÉE PREND LE RELAIS.
   Thibaud les a jugées inutiles, et elles le sont — À LA SOURIS, SUR UN ÉCRAN LARGE, AVEC LE SCRIPT.
   Un premier jet les a donc retirées partout, et deux capacités sont tombées en silence avec elles :
   sur téléphone, où la poignée est masquée (on ne glisse pas une carte) ; et sans JavaScript, où la
   poignée n'est jamais découverte. Dans les deux cas il ne restait AUCUN moyen de réordonner.
   On les garde donc dans le HTML, et c'est le SCRIPT qui les efface une fois la poignée en place :
   ce qui disparaît est ce qui a été remplacé, jamais ce qui n'a pas de remplaçant. */
.tbl-poignee-active .btn-fleche { display: none; }
.ligne-outils .btn-fleche { padding: 4px 7px; min-width: 0; font-family: var(--font-mono); line-height: 1; }
/* v7.13 (relecture) — ET LE CRITÈRE EST LE POINTEUR, PAS LA LARGEUR. Le premier jet ne rendait les
   flèches que sous 680 px. Or l'incapacité n'est pas d'être étroit : c'est de n'avoir que le doigt.
   Le glisser-déposer HTML5 ne se déclenche pas au toucher — le commentaire ci-dessus le dit
   lui-même — et le seul code tactile pose `draggable`, sans aucun `touchmove`. Entre 681 px et le
   bureau il ne restait donc RIEN pour réordonner : ni sur iPad, ni sur tablette Android, ni sur un
   téléphone tourné en paysage pour lire un tableau à sept colonnes — le geste même qu'on fait
   devant ce tableau. `tools/plateformes.py` range d'ailleurs les deux tailles de tablette parmi les
   appareils tactiles. */
@media (hover: none), (pointer: coarse) {
  .ligne-poignee { display: none; }
  .tbl-poignee-active .btn-fleche { display: inline-block; }
}
@media (max-width: 680px) {
  .ligne-poignee { display: none; }
  .tbl-poignee-active .btn-fleche { display: inline-block; }   /* la poignée est masquée ici : elles reprennent la main */
  .ligne-outils { white-space: normal; }
}

/* v7.12 — Renommer un projet depuis son titre : discret au repos, franc au survol. Le crayon ne
   doit pas rivaliser avec le titre, seulement se laisser trouver par qui le cherche. */
.btn-renommer {
  border: 0; background: transparent; color: var(--faint); cursor: pointer;
  font: inherit; font-size: .95rem; line-height: 1; padding: 2px 6px; border-radius: 6px; text-decoration: none;
}
.btn-renommer:hover { color: var(--accent); background: var(--accent-soft); }
.btn-renommer:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* v7.12 — L'unité d'un prix s'écrit DANS la cellule, en permanence. Un `placeholder` disparaît à
   la première frappe, et la colonne « Vente HT » attend en réalité un prix TTC : sans ce repère,
   rien de visible ne contredisait l'en-tête, et l'on saisissait du HT là où le serveur lit du TTC. */
.saisie-avec-unite { position: relative; display: block; }
.saisie-avec-unite .saisie-cellule { padding-right: 2.8em; }
.saisie-unite {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-size: .68rem; font-weight: 650; letter-spacing: .04em; color: var(--faint);
  pointer-events: none; user-select: none; -webkit-user-select: none;
}


/* v7.13 — La vue Déboursé porte cinq cases de saisie par ligne, et la mise en page automatique du
   tableau les servait en premier : la DÉSIGNATION tombait à sept caractères, un nom de maison
   s'étalait sur trois lignes et l'invite de la ligne vide se coupait à nouveau. On lui garantit
   donc une largeur, et les colonnes de chiffres se partagent le reste. */
/* Une largeur GARANTIE à la désignation, et rien d'imposé aux colonnes de chiffres : leur imposer
   un minimum à elles aussi poussait la colonne Actions — la poignée, « Modifier », « Retirer » —
   hors de l'écran, derrière un défilement horizontal. Gagner de la place sur un côté en la perdant
   sur l'autre n'est pas gagner de la place. */
.tbl-debourse th:first-child, .tbl-debourse td:first-child { min-width: 9.5rem; }
/* Et une largeur aux CASES elles-mêmes : le navigateur dimensionne une colonne sur son en-tête, pas
   sur ce que ses champs contiennent. « VENTE HT » fait huit signes, « 200 000,00 » en fait dix — le
   dernier chiffre se coupait, et un montant tronqué se lit comme un autre montant. On resserre les
   marges intérieures plutôt que d'élargir le tableau, qui pousserait la colonne Actions dehors. */
.tbl-debourse .saisie-cellule { min-width: 6rem; padding-left: 4px; padding-right: 6px; font-size: .82rem; }
/* SAUF là où une unité est écrite dans la case. Le resserrement ci-dessus reprenait la place que
   « TTC » et « HT » occupent, et les deux se superposaient au nombre : on lisait « 0T00 ». Une
   règle de largeur ne doit pas manger un repère posé par une autre.
   (Une ligne `.tbl-debourse:focus-within .saisie-cellule { padding-right: 7px }` traînait ici. Elle
   portait le `:focus-within` sur le TABLEAU et non sur la case : dès qu'un élément quelconque du
   tableau prenait le focus, elle écrasait les trois règles ci-dessus pour TOUTES les cases — le ✓
   se posait sur les derniers chiffres, et « 0T00 » revenait deux lignes après le commentaire qui
   dit le corriger. Une règle plus tardive à spécificité égale gagne, et celle-là ne servait à rien
   que la précédente ne fasse déjà.) */
.tbl-debourse .saisie-avec-unite .saisie-cellule { padding-right: 2.7em; }
@media (max-width: 1100px) {
  .tbl-debourse th:first-child, .tbl-debourse td:first-child { min-width: 8rem; }
  .tbl-debourse .saisie-cellule { min-width: 5.6rem; }
}

/* v9.13 — le bloc « Pièces jointes de la rubrique » (v7.14) est parti : une pièce se dépose sur sa question. */

/* Le choix qui ne se devine pas : deux cartes cochables, et celle qui détruit le dit. */
.choix-carte { display: flex; gap: 11px; align-items: flex-start; padding: 12px 14px; margin-bottom: 8px;
  border: 1px solid var(--line); border-radius: 9px; cursor: pointer; }
.choix-carte:has(input:checked) { border: 2px solid var(--accent); background: var(--accent-soft); padding: 11px 13px; }
.choix-carte input { margin-top: 3px; width: 16px; height: 16px; flex: none; accent-color: var(--accent); }
.choix-carte > span { display: flex; flex-direction: column; gap: 3px; }
.choix-carte .t-sub { line-height: 1.45; }

/* La pastille des pièces, sur la tête d'un bloc de la carte. */
.chip-pieces { display: inline-flex; align-items: center; gap: 4px; }
.chip-pieces svg { width: 12px; height: 12px; }

/* ---------- v8.1 — l'atelier du métré : les lots à gauche, sur grand écran ----------
   Un métré se fait lot par lot, et changer de lot est le geste de la journée. Le menu déroulant
   demandait trois gestes et ne montrait ni où on en était, ni ce qui restait à faire. Le rail
   montre les cinquante-neuf lots, leur montant et leurs trous, en permanence — et il se replie en
   dessous de 1180 px, où le menu déroulant reprend la main : le rail y volerait la moitié de la
   largeur de la grille de saisie, qui est le seul endroit où le travail se fait. */
.metre-atelier { margin-top: 14px; }
.metre-rail { display: none; }
@media (min-width: 1180px) {
  .metre-atelier { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 16px; align-items: start; }
  .metre-atelier .barre-filtres .champ-lot { display: none; }
  .metre-rail { display: flex; flex-direction: column; position: sticky; top: 63px; max-height: calc(100vh - 78px);
            border: 1px solid var(--line); border-radius: 9px; background: var(--surface-2); overflow: hidden; }
}
.rail-tete { display: flex; flex-direction: column; gap: 7px; padding: 9px 10px; border-bottom: 1px solid var(--line); }
.rail-titre { margin: 0; font-size: .68rem; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.rail-titre span { color: var(--faint); font-weight: 500; letter-spacing: 0; }
.rail-filtre { width: 100%; padding: 5px 8px; font-size: .8rem; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); }
.rail-segments { display: flex; gap: 2px; padding: 2px; background: var(--sunken); border-radius: 7px; }
.rail-segments button { flex: 1; border: 0; background: transparent; border-radius: 5px; padding: 4px 2px; cursor: pointer;
                     font: inherit; font-size: .72rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.rail-segments button[aria-pressed="true"] { background: var(--surface); color: var(--ink-strong); box-shadow: 0 1px 2px rgba(0, 0, 0, .08); }
.rail-liste { flex: 1; overflow-y: auto; padding: 5px; }
.rail-lot { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 7px; align-items: center;
         padding: 6px 8px; border-radius: 7px; border-left: 3px solid transparent; text-decoration: none; color: inherit; }
.rail-lot:hover { background: var(--sunken); color: inherit; }
.rail-lot[aria-current="true"] { background: var(--accent-soft); border-left-color: var(--accent); }
.rail-lot-n { font-family: var(--font-mono); font-size: .72rem; color: var(--muted); }
.rail-lot[aria-current="true"] .rail-lot-n { color: var(--accent); }
.rail-lot-t { font-size: .78rem; font-weight: 600; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-lot-pied { grid-column: 1 / -1; display: flex; gap: 7px; align-items: baseline;
              font-family: var(--font-mono); font-size: .68rem; color: var(--muted); }
.rail-lot-trous { color: var(--warn); font-weight: 600; }
.rail-vide { margin: 0; padding: 16px 12px; font-size: .78rem; color: var(--faint); text-align: center; line-height: 1.5; }
/* Une quantité qu'on ne sait pas lire se voit AVANT l'envoi : le serveur la refuserait ligne par
   ligne, et la faute se découvrirait après le rechargement, en haut d'une page de deux cents lignes. */
.a-tbl tr.illisible td { background: var(--crit-soft); }
.metre-modifie { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; color: var(--warn); font-weight: 600; }
.metre-modifie::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--warn); flex: none; }

/* ---------- v8.2 — ranger une liste en glissant ----------
   La poignée est le SEUL endroit qui démarre un glissement : rendre la ligne entière draggable
   empêchait de sélectionner un libellé pour le copier, et rendait le clic sur un bouton hasardeux. */
.poignee-rang { cursor: grab; color: var(--faint); user-select: none; width: 1%; padding-right: 0 !important; letter-spacing: -1px; }
.poignee-rang:hover { color: var(--muted); }
.poignee-rang:active { cursor: grabbing; }
.a-tbl tr.en-vol td { background: var(--accent-soft); opacity: .6; }
.a-tbl tr[data-rang]:hover .poignee-rang { color: var(--accent); }

/* ---------- v8.2 — choisir les lots d'un métré ---------- */
.lot-a-retenir { display: grid; grid-template-columns: auto 42px minmax(0, 1fr) auto; gap: 9px; align-items: center;
                 padding: 5px 11px; cursor: pointer; font-size: .82rem; }
.lot-a-retenir:hover { background: var(--sunken); }
.lot-a-retenir input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.lot-a-retenir.pris span:nth-of-type(2) { font-weight: 600; color: var(--ink-strong); }

/* v8.6 — LA LOCALISATION QUI NE PARTIRA PAS. La case du métré est libre : on y écrit « Local
   technique nord » sans permission. Mais seul ce qui est au référentiel part sur un marché, et
   l'écran le dit à la frappe plutôt que de le faire découvrir sur un document déjà envoyé.
   Discrète : c'est une information, pas un reproche — la ligne s'enregistre quand même. */
.loc-hors { display:block; margin-top:2px; font-size:.68rem; line-height:1.3; color:var(--warn, #8F5409); }

/* v8.7 — LA COLONNE DES PRIX SE TAPE. Le champ doit rester lisible comme un montant : aligné à
   droite, chiffres à chasse fixe, et assez étroit pour que la colonne ne pousse pas le tableau. */
/* `input.px-ligne` ET NON `.px-ligne` : la règle générique `input[type=text]` pose `width: 100%`
   et pèse autant qu'une classe seule — le champ occupait toute la colonne. Il faut la même
   spécificité et venir après. */
input.px-ligne { width: 108px; text-align: right; font-family: var(--font-mono); font-size: .875rem;
    font-variant-numeric: tabular-nums; padding: 5px 8px; }
.px-ligne::placeholder { color: var(--faint); }
.px-barre { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }

/* v9.0 — LA LIGNE SUR LAQUELLE ON EST. Le métreur a quarante lignes à l'écran et suivait du doigt :
   « voir sur quelle ligne on est ». Aucun JavaScript n'est nécessaire — `:focus-within` est vrai sur
   la ligne dont un champ a le focus, et il s'éteint tout seul quand on en sort. Léger, comme demandé :
   un liseré et un fond à peine posé, pour ne pas concurrencer le vert des lignes déjà chiffrées. */
/* POINT 82 (25/09/2026) — ELLE NE S'ALLUMAIT PRESQUE JAMAIS. Thibaud : « quand je suis sur la saisie d'une ligne la
   couleur de toute la ligne change légèrement pour voir sur quoi je suis », comme dans la bibliothèque des ouvrages.
   La règle visait `#tbl-metre` : d'un seul tenant, chaque lot a son tableau (`tbl-metre-<lot>`), et rien ne s'allumait ;
   par lot, le vert des cellules d'une ligne chiffrée (`.a-tbl tr.dedans td`) recouvrait le fond posé sur la LIGNE, et
   seul le liseré se voyait. Elle vise donc la CLASSE de tous les tableaux du métré, et pose le fond sur les CELLULES —
   plus spécifique que le vert, qu'elle remplace le temps de la saisie ; le liseré, sur la première. */
/* RELECTURE : ni sur une ligne dont la quantité est ILLISIBLE — son rouge (`.a-tbl tr.illisible td`) se voit avant
   l'envoi, pendant la frappe, et le bleu le cachait —, ni sur un TITRE de chapitre, dont le bouton prend le focus quand
   on le replie. Et au téléphone, où la ligne devient une carte, c'est la carte entière qui se colore. */
table.tbl-metre tbody tr:not(.tr-section):not(.illisible):focus-within > td { background-color: var(--accent-soft); }
table.tbl-metre tbody tr:not(.tr-section):focus-within > td:first-child { box-shadow: inset 3px 0 0 0 var(--accent); }
@media (max-width: 680px) {
  table.tbl-metre.tbl-cartes tbody tr:not(.tr-section):focus-within { box-shadow: inset 3px 0 0 0 var(--accent); }
  table.tbl-metre.tbl-cartes tbody tr:not(.tr-section):not(.illisible):focus-within { background-color: var(--accent-soft); }
  table.tbl-metre.tbl-cartes tbody tr:not(.tr-section):focus-within > td:first-child { box-shadow: none; }
}
/* L'ÉTAT DE L'ÉCRITURE, ligne par ligne : c'est lui qui remplace le bouton « Enregistrer ». */
.q-etat { font-size: 11.5px; color: var(--faint); white-space: nowrap; }
.q-etat[data-etat="vol"], .q-etat[data-etat="modifie"] { color: var(--warn); }
.q-etat[data-etat="echec"] { color: var(--crit); font-weight: 600; }
.q-etat[data-etat="ecrit"] { color: var(--ok); }

/* v9.0 — LE TÉLÉPHONE N'A PAS DE PLACE POUR LA COLONNE DU CHEVRON. Elle faisait déborder l'écran
   des marchés de 40 px à 390 px, et elle n'y sert à rien : les cartes empilées portent déjà les
   NUMÉROS des pièces, chacun lié à sa page. Le dépliage est un confort de grand écran. */
@media (max-width: 640px) {
  #tbl-marches td:first-child, #tbl-marches th:first-child { display: none; }
  #tbl-marches .tr-detail .piece-ligne { flex-wrap: wrap; }
}
/* Le détail d'un lot : ses pièces, en ligne, lisibles d'un coup d'œil. */
.piece-ligne { display: flex; align-items: center; gap: 10px; padding: 5px 0; flex-wrap: wrap; }
.piece-ligne .t-sub { flex-grow: 1; }

/* v9.3 — LE GUIDE UTILISATEUR (point 20, maquette validée le 23/09/2026). */
.guide-volets { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; margin: 10px 0; }
.guide-volet { display: flex; flex-direction: column; gap: 3px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
.guide-volet span { font-size: 12px; color: var(--muted); line-height: 1.4; }
.guide-liens { margin: 10px 0 0; padding-left: 18px; }
.guide-metiers { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; margin: 8px 0 10px; }
.guide-metier { display: flex; flex-direction: column; gap: 6px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 16px; text-decoration: none; color: var(--ink); }
.guide-metier:hover { border-color: var(--accent-line); }
.guide-metier-moi { background: var(--accent-soft); border: 2px solid var(--accent); padding: 15px; }
.guide-metier-nom { font-weight: 600; color: var(--ink-strong); }
.guide-vous { font-size: 11px; font-weight: 600; color: var(--accent-ink); background: var(--accent); border-radius: 999px; padding: 2px 8px; margin-left: 4px; }
.guide-page { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 28px; margin-top: 14px; }
.guide-sommaire { display: flex; flex-direction: column; gap: 2px; }
.guide-sommaire a { font-size: 13.5px; color: var(--ink); text-decoration: none; padding: 6px 9px; border-radius: 5px; }
.guide-sommaire a:hover { background: var(--surface-2); }
.guide-sommaire a[aria-current="page"] { font-weight: 600; color: var(--accent); background: var(--accent-soft); }
.guide-groupe { display: flex; flex-direction: column; gap: 2px; }
.guide-groupe + .guide-groupe { margin-top: 14px; }
.guide-rubrique { font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; color: var(--faint); margin: 0 0 4px; }
.guide-hors { margin: 0; padding: 0 8px; font-size: .8rem; line-height: 1.5; color: var(--muted); }
.guide-chapitre { min-width: 0; max-width: 820px; }
.guide-chapitre h2 { font-family: var(--font-display); font-size: 22px; margin: 0 0 12px; color: var(--ink-strong); }
.guide-texte { font-size: 14.5px; line-height: 1.6; }
.guide-texte h3 { font-size: 16px; margin: 20px 0 6px; color: var(--ink-strong); }
.guide-texte ol, .guide-texte ul { padding-left: 22px; display: flex; flex-direction: column; gap: 6px; }
.guide-texte code { background: var(--sunken); padding: 1px 5px; border-radius: 4px; font-size: .8rem; font-family: var(--font-mono); }
.guide-encadre { background: var(--info-soft); border-left: 3px solid var(--info); border-radius: 0 8px 8px 0; padding: 10px 14px; margin: 14px 0; }
.guide-encadre p { margin: 0; }
.guide-capture { margin: 0 0 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.guide-capture img { display: block; width: 100%; height: auto; }
.guide-capture figcaption { display: flex; justify-content: space-between; gap: 12px; padding: 8px 14px; border-top: 1px solid var(--line); font-size: 12px; color: var(--faint); }
@media (max-width: 1200px) {
  .guide-volets { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .guide-volets { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .guide-metiers { grid-template-columns: minmax(0, 1fr); }
  .guide-page { grid-template-columns: minmax(0, 1fr); }
}

/* ---- v9.4 — Les remontées : le bouton, la fenêtre, le tableau (point 22) ---- */
.rem-bouton { position: fixed; right: 22px; bottom: 22px; z-index: 40; display: inline-flex; align-items: center; gap: 8px; background: var(--ink-strong); color: #FFFFFF; border: 0; border-radius: 999px; padding: 10px 16px 10px 13px; font: inherit; font-size: .84rem; font-weight: 600; box-shadow: 0 6px 18px rgba(22,27,29,.22); cursor: pointer; }
.rem-bouton:hover { background: var(--accent); }
.rem-bouton svg { flex-shrink: 0; }
@media (max-width: 820px) { .rem-bouton { bottom: calc(68px + env(safe-area-inset-bottom)); right: 14px; padding: 10px 13px; } .rem-bouton span { display: none; } }
@media print { .rem-bouton { display: none; } }
.rem-dialog { width: min(560px, calc(100vw - 24px)); }
.rem-types { display: flex; gap: 8px; }
.rem-type { flex: 1; display: flex; align-items: center; gap: 8px; border: 1px solid var(--line-strong); border-radius: 8px; padding: 9px 12px; font-size: .88rem; cursor: pointer; }
.rem-type:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.rem-captures { display: flex; gap: 14px; align-items: flex-start; }
.rem-apercus { display: flex; gap: 8px; flex-wrap: wrap; }
/* v9.11 — le bouton de remontée dans le pied d'une fenêtre, à gauche, loin de ses boutons à elle. */
.m-foot .rem-depuis { margin-right: auto; color: var(--muted); }
/* relecture v9.11 : un pied qui porte déjà sa note la garde à gauche, le bouton se range devant elle */
.m-foot:has(.m-foot-note) .rem-depuis { margin-right: 0; }
.rem-apercus:empty { display: none; }
.rem-apercu { position: relative; width: 120px; height: 80px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--surface-2); }
/* v9.9 — L'IMAGE ENTIÈRE, PAS RECADRÉE (point 35). « cover » remplissait la vignette en coupant ce
   qui débordait : une capture de 388 × 32 — la barre « Vous partagez tout votre écran » de Firefox —
   devenait un ruban gris de texte, et personne ne pouvait voir avant d'envoyer qu'elle était fausse. */
.rem-apercu img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Sur toute la largeur de la fenêtre : dans la grille de la fenêtre, « large » ne s'étend que sur un champ. */
.rem-alerte { grid-column: 1 / -1; padding: 10px 12px; border: 1px solid var(--crit); background: var(--crit-soft); color: var(--crit); border-radius: 8px; font-size: .88rem; line-height: 1.45; }
.rem-apercu button { position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: 999px; border: 0; background: var(--ink-strong); color: #FFFFFF; font-size: 14px; line-height: 1; cursor: pointer; }
.rem-captures-boutons { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.rem-contexte { margin: 0; background: var(--surface-2); border-radius: 8px; padding: 9px 12px; line-height: 1.5; }
.rem-kanban { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; align-items: start; }
.rem-colonne { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.rem-colonne-tete { display: flex; justify-content: space-between; align-items: baseline; padding: 0 2px; }
.rem-colonne-tete h2 { margin: 0; font-size: .72rem; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); }
.rem-colonne-a_trier .rem-colonne-tete h2 { color: var(--warn); }
.rem-colonne-retenue .rem-colonne-tete h2 { color: var(--ok); }
.rem-colonne-en_cours .rem-colonne-tete h2 { color: var(--accent); }
.rem-colonne-vide { margin: 0; font-size: .78rem; color: var(--faint); border: 1px dashed var(--line); border-radius: 9px; padding: 12px; }
.rem-carte { background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 11px 13px; display: flex; flex-direction: column; gap: 7px; }
.rem-colonne-livree .rem-carte, .rem-colonne-refusee .rem-carte { background: var(--surface-2); }
.rem-carte-tete { display: flex; justify-content: space-between; align-items: center; }
.rem-carte-titre { font-size: .88rem; font-weight: 600; color: var(--ink-strong); text-decoration: none; line-height: 1.4; }
.rem-carte-titre:hover { color: var(--accent); }
.rem-carte-meta { font-size: .74rem; color: var(--faint); line-height: 1.5; }
.rem-carte-motif { font-size: .78rem; color: var(--muted); line-height: 1.5; border-left: 3px solid var(--line-strong); padding-left: 9px; }
.rem-carte-actions { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 2px; }
.rem-export-liste { display: flex; flex-direction: column; gap: 8px; }
.rem-export-ligne { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px; font-size: .88rem; cursor: pointer; }
.rem-export-ligne input { margin-top: 3px; }
.rem-export-note { margin: 4px 0 0; }
.rem-detail-puces { margin: 0 0 6px; display: flex; gap: 6px; }
.rem-detail-texte { white-space: normal; line-height: 1.6; margin: 0; }
.rem-detail-captures { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-top: 14px; }
.rem-detail-captures img { width: 100%; height: auto; border: 1px solid var(--line); border-radius: 8px; display: block; }
.rem-detail-contexte { margin-top: 14px; }
.rem-dl { display: grid; grid-template-columns: 90px minmax(0, 1fr); gap: 4px 12px; margin: 0; font-size: .88rem; }
.rem-dl dt { color: var(--faint); }
.rem-dl dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 1200px) { .rem-kanban { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .rem-kanban { grid-template-columns: minmax(0, 1fr); } .rem-captures { flex-direction: column; } }

/* v9.9 — LES CHAPITRES SE REPLIENT (point 34). Le titre du chapitre est le bouton ; replié, ses lignes
   se cachent — sauf pendant qu'on cherche (`filtre-actif`) : on ne cherche jamais dans un chapitre
   fermé. */
table:not(.filtre-actif) tr.chap-cache { display: none; }
.filtre-actif .chap-compte, .filtre-actif .chap-signe { visibility: hidden; }
.chap-bascule { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: transparent;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.chap-bascule:hover { color: var(--ink-strong); }
.chap-bascule:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.chap-signe { display: inline-block; width: 12px; font-family: var(--font-mono); }
.chap-compte { margin-left: 8px; text-transform: none; letter-spacing: 0; font-size: .78rem; color: var(--muted); }
.chap-outils { display: flex; justify-content: flex-end; margin: 10px 0 6px; }

/* v9.9 — LE TARIF SE SAISIT COMME LE MÉTRÉ (point 33) : la ligne où l'on est se voit, et une case
   refusée se voit aussi. L'état d'un refus peut être long (« « 0,97,6 » n'est pas un prix ») : il se
   plie sur sa ligne au lieu d'élargir le tableau. */
#tbl-ouvrages tbody tr:focus-within { background: var(--accent-soft); box-shadow: inset 3px 0 0 0 var(--accent); }
/* POINT 79 — la liste des ensembles s'ouvre d'un clic sur la ligne ; celui dont la composition est ouverte se marque. */
#tbl-ensembles tbody tr[data-href] { cursor: pointer; }
#tbl-ensembles tbody tr[data-href]:hover td, #tbl-ensembles tbody tr.actif-courant td { background: var(--accent-soft); }
#tbl-ensembles tbody tr.actif-courant td:first-child { box-shadow: inset 3px 0 0 0 var(--accent); }
#tbl-composition input.comp-q[aria-invalid="true"] { border-color: var(--crit); box-shadow: 0 0 0 1px var(--crit); }
[data-px-etat] { white-space: normal; }
input.px-ligne[aria-invalid="true"] { border-color: var(--crit); box-shadow: 0 0 0 1px var(--crit); }

/* v9.12 — l'onglet Entreprises : les vues par famille, les phases, l'écriture à la volée (planche A2) */
.vues-lots { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; margin: 0 0 10px; }
.vues-lots .filters { margin: 0; }
.a-tbl tr.lot-filtre, .a-tbl tr.tr-section.chap-vide { display: none; }
/* Point 85, E2 A : l'enregistrement vit sous le champ de l'entreprise, et prend la place de « affecté par … » tant qu'il compte. */
.enregistrement { margin-top: 3px; }
.enregistrement:empty { display: none; }
td:has(> .enregistrement:not(:empty)) .affecte-par { display: none; }
/* Point 85, E1 A : la famille sous le nom du lot. */
.lot-famille { margin-top: 4px; }
/* Point 85, E3 A : le tableau recomposé, jusqu'à la tablette — la répartition de la maquette. Le lot et l'entreprise en %,
   l'état et les gestes à largeur fixe (leurs pastilles et leurs boutons ne passent pas à la ligne : « Sans objet »,
   « Supprimer » demandent 100 px), la pièce le reste. Laissé à lui-même, le tableau donnait 152 px au champ à 1 224 px et
   102 à la tablette ; ainsi 270 et 195. En dessous de 700 px de tableau (menu ouvert sur une petite fenêtre), il défile
   dans son cadre comme avant, plutôt que de laisser une pastille chevaucher sa voisine (relecture). Au téléphone, les
   lignes sont des cartes : rien à répartir. La CLASSE de la table, pas son id : la bibliothèque (ouvrages.php) a aussi un
   `#tbl-lots`, et ce bloc la déformait (seconde relecture). */
@media (min-width: 681px) {
  .tbl-lots-phases { table-layout: fixed; min-width: 700px; }
  .tbl-lots-phases td { overflow-wrap: anywhere; }
  .tbl-lots-phases thead th:nth-child(1) { width: 21%; }
  .tbl-lots-phases thead th:nth-child(2) { width: 32%; }
  .tbl-lots-phases thead th:nth-child(3) { width: 6.5rem; }
  .tbl-lots-phases thead th:nth-child(5) { width: 6.5rem; }
  .tbl-lots-phases td[data-label="Pièce"] .btn { white-space: normal; text-align: left; }
}
@media (min-width: 681px) and (max-width: 1100px) {
  .tbl-lots-phases thead th:nth-child(1) { width: 20%; }
  .tbl-lots-phases thead th:nth-child(2) { width: 30.5%; }
}
.enr-ok { color: var(--ok); }
.enr-refus { color: var(--crit); }
.combo-input[aria-invalid="true"] { border-color: var(--crit); background: var(--crit-soft); }

/* v9.13 — les études d'un projet (planche B1) : l'état se choisit dans une puce, les gestes rares dans « ⋯ » */
.chip-select { appearance: none; -webkit-appearance: none; border: 0; border-radius: 999px; font: inherit; font-size: .72rem; font-weight: 600; line-height: 1.2;
  padding: 3px 22px 3px 9px; cursor: pointer; background-repeat: no-repeat; background-position: right 7px center; background-size: 8px 5px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23666'/%3E%3C/svg%3E"); }
.chip-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tbl-etudes .etude-nom { font-weight: 600; font-size: .95rem; }
.menu-points { position: relative; display: inline-block; }
.menu-points > summary { list-style: none; cursor: pointer; }
.menu-points > summary::-webkit-details-marker { display: none; }
.menu-points-liste { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 12rem; display: flex; flex-direction: column; padding: 6px;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.12); text-align: left; }
.menu-points-liste > a, .menu-points-liste > button, .menu-points-liste form button { display: block; width: 100%; text-align: left; padding: 7px 10px; border: 0; border-radius: 6px;
  background: none; font: inherit; font-size: .85rem; color: var(--ink); text-decoration: none; cursor: pointer; }
.menu-points-liste > a:hover, .menu-points-liste > button:hover, .menu-points-liste form button:hover { background: var(--surface-2); }
.menu-points-liste .menu-danger { color: var(--crit); }

/* v9.13 — la fiche client se modifie sur place (planche B2) */
.fiche-client { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 460px); gap: 16px; align-items: start; }
.fiche-client > .panel { margin: 0; }
@media (max-width: 980px) { .fiche-client { grid-template-columns: minmax(0, 1fr); } }
.kv-sur-place dd { min-width: 0; }
.sur-place { display: inline-flex; align-items: center; gap: 8px; width: 100%; max-width: 30rem; }
.sp-champ { flex: 1 1 auto; min-width: 8rem; width: 100%; font: inherit; color: var(--ink-strong); padding: 3px 7px; margin-left: -8px; border: 1px solid transparent; border-radius: 6px; background: transparent; }
select.sp-champ { cursor: pointer; }
textarea.sp-champ { resize: vertical; }
.sp-champ:hover { border-color: var(--line); }
.sp-champ:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent); }
.sp-champ::placeholder { color: var(--accent); opacity: .85; }
.sp-champ[aria-invalid="true"] { border-color: var(--crit); background: var(--crit-soft); }
.sp-unite { color: var(--muted); font-size: .85rem; }
.sp-etat { font-size: .75rem; white-space: nowrap; color: var(--muted); }
.sp-etat.sp-ok { color: var(--ok); }
.sp-etat.sp-refus { color: var(--crit); white-space: normal; }
.autres-renseignements { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.autres-renseignements > summary { cursor: pointer; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.note-sur-place { margin: 12px 0 0; padding: 10px 12px; border: 1px dashed var(--line-strong); border-radius: 8px; background: var(--surface-2); font-size: .8125rem; color: var(--ink); }

/* v9.13 — les formulaires (planche B3) : pièces et photos comme questions, oui / non sur une ligne,
   rubriques repliables, « Enregistrer » toujours visible */
.q-champ--pieces .q-pieces { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.q-pieces--piece { border: 1px dashed var(--line-strong); border-radius: 8px; padding: 10px; }
.q-vignette img { width: 64px; height: 48px; object-fit: cover; border-radius: 6px; display: block; background: var(--surface-2); }
.q-fichier { font-size: .85rem; }
.q-depot { position: relative; overflow: hidden; cursor: pointer; }
.q-depot input[type=file] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.q-depot-envoyer { display: none; }
.q-options--boutons { display: flex; flex-wrap: wrap; gap: 6px; }
.q-options--boutons .check-line { border: 1px solid var(--line-strong); border-radius: 999px; padding: 5px 14px; margin: 0; cursor: pointer; }
.q-options--boutons .check-line input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.q-options--boutons .check-line:has(input:checked) { background: var(--ink-strong); border-color: var(--ink-strong); color: var(--ground); }
.q-options--boutons .check-line:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.bloc-bascule { border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; display: inline-flex; gap: 6px; align-items: baseline; }
.carte-bloc.bloc-replie:not(.bloc-filtre) .carte-faits, .carte-bloc.bloc-replie .tiroir { display: none; }
.tiroir-pied { grid-column: 1 / -1; position: sticky; bottom: 0; z-index: 5; background: var(--surface-2); padding: 10px 0; border-top: 1px solid var(--line); }   /* toute la largeur du tiroir, sur son fond (captures v9.13) */
.q-piece { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.q-retirer { border: 0; background: var(--surface); color: var(--muted); border-radius: 999px; width: 20px; height: 20px; font-size: .7rem; line-height: 1; cursor: pointer; }
.q-piece .q-vignette + .q-retirer { position: absolute; top: -6px; right: -6px; box-shadow: 0 1px 3px rgba(0,0,0,.2); }
.q-retirer:hover { color: var(--crit); }

/* v9.13 (relecture) — le téléphone : le pied du tiroir au-dessus de la barre d'onglets, la saisie sur place qui passe à la
   ligne plutôt que de déborder, des cibles à la taille du doigt ; le focus du dépôt, la place d'un lâcher de fichier. */
@media (max-width: 820px) { .tiroir-pied { bottom: calc(62px + env(safe-area-inset-bottom)); padding-right: 64px; } }   /* la place du bouton « Une remarque ? » */
.sur-place { flex-wrap: wrap; }
.sp-lien { font-size: .75rem; white-space: nowrap; }
.sp-champ::placeholder { color: var(--faint); font-style: italic; opacity: 1; }
.sp-champ[placeholder="à demander"]::placeholder { color: var(--accent); font-style: normal; opacity: .85; }
.q-depot:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.q-verrou { display: inline-flex; align-items: center; color: var(--faint); }
.q-verrou svg { width: 13px; height: 13px; }
.q-pieces.q-lacher { outline: 2px dashed var(--accent); outline-offset: 3px; border-radius: 6px; }
@media (max-width: 680px) {
  .sp-champ { min-width: 6rem; }
  .q-retirer { width: 32px; height: 32px; font-size: .85rem; }
  .chip-select { min-height: 32px; padding-top: 6px; padding-bottom: 6px; }
}
/* v9.13 (captures) — LE CHAMP SUR PLACE SE LIT COMME UN TEXTE (planche B2) : la règle générale des champs — une bordure,
   toute la largeur — l'emportait sur .sp-champ, plus faible ; et le « € » passait sous son champ. */
.sur-place input.sp-champ, .sur-place select.sp-champ, .sur-place textarea.sp-champ { width: auto; flex: 1 1 10rem; min-width: 0; padding: 3px 7px; border: 1px solid transparent; background: transparent; font-size: inherit; }
.sur-place input.sp-champ:hover, .sur-place select.sp-champ:hover, .sur-place textarea.sp-champ:hover { border-color: var(--line); }
.sur-place .sp-champ:focus { outline: none; border-color: var(--accent); background: var(--surface); }
.sur-place .sp-champ[aria-invalid="true"] { border-color: var(--crit); background: var(--crit-soft); }
.sur-place .sp-unite { flex: none; }
/* v9.14 — « Pour quoi ? » : trois choix en tuiles, chacun sa porte (planche C2). Le volet d'un choix
   non retenu est caché ET désactivé : ses champs ne partent pas, et ne sont pas exigés. */
.choix-tuiles { border: 0; margin: 0 0 14px; padding: 0; min-width: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.choix-tuiles legend { padding: 0; margin-bottom: 6px; font-size: .8125rem; font-weight: 600; color: var(--ink-strong); }
.choix-tuile { position: relative; display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--surface); cursor: pointer; font-size: .8125rem; line-height: 1.35; color: var(--muted); }
.choix-tuile b { font-size: .875rem; color: var(--ink-strong); }
.choix-tuile input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choix-tuile:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.choix-tuile:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.volet { border: 0; margin: 0; padding: 0; min-width: 0; }
.volet-note { grid-column: 1 / -1; margin: -4px 0 0; font-size: .8125rem; color: var(--muted); }
@media (max-width: 640px) { .choix-tuiles { grid-template-columns: minmax(0, 1fr); } }
/* v9.14 — L'onglet Documents d'une proposition (planche C1) : un bouton, et la zone où glisser, sur une ligne. */
.drop-ligne { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 8px 12px; text-align: left; padding: 10px 12px; }
.tbl-pieces .p-name { overflow-wrap: anywhere; }
.tbl-pieces td[data-label="Actions"] .actions-ligne { display: inline-flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
/* v9.14 — La description d'une ligne de proposition (planche C3) : l'éditeur des emails, en plus court ; et
   à l'écran, la mise en forme telle que le client la lira. */
.ligne-description .editeur { font-weight: 400; color: var(--ink); }
.ligne-description .ed-zone { min-height: 96px; max-height: 32vh; }
.ligne-desc.j-riche { margin-top: 2px; }
.ligne-desc.j-riche ul, .ligne-desc.j-riche ol { margin: 2px 0 4px; padding-left: 18px; }
.ligne-desc.j-riche p { margin: 0 0 4px; }
/* v9.14 (relecture) — le focus du dépôt se voit sur son bouton ; en contraste forcé, la tuile choisie garde un contour. */
.drop-ligne:has(input:focus-visible) label.btn { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (forced-colors: active) { .choix-tuile:has(input:checked) { outline: 3px solid Highlight; } }
/* v9.14 (captures) — LE PIED D'UNE FENÊTRE RESTE EN VUE SUR ORDINATEUR AUSSI, comme au téléphone : la ligne de
   proposition, avec son éditeur, dépasse un écran de portable, et « Enregistrer » ne se trouvait qu'en faisant
   défiler la fenêtre. */
dialog.modal .m-foot { position: sticky; bottom: 0; z-index: 2; background: var(--surface); }

/* v9.16 — LES GRILLES DE PRIX RANGÉES PAR FAMILLE (planche D3) : trois blocs l'un sous l'autre, le tarif en
   vigueur en tête, les gestes rares dans « ⋯ ». */
.grilles-famille { margin-bottom: 14px; }
.grilles-famille .v-head { margin-bottom: 10px; gap: 10px; }
.grilles-famille .liste-outils { margin: 0; }
.grilles-famille .liste-outils input[type=search] { width: 14rem; }
.grille-ligne { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; padding: 8px 12px; border-radius: 8px; }
.grille-ligne + .grille-ligne { border-top: 1px solid var(--line); border-radius: 0; }
.grille-en-tete { background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); padding: 12px; margin-bottom: 6px; }
.grille-en-tete .grille-nom strong { font-size: .95rem; }
.grille-nom { flex: 1 1 22rem; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.grille-nom .t-sub { overflow-wrap: anywhere; }
.grille-gestes { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.grilles-anciennes { margin-top: 6px; }
.grilles-anciennes > summary { cursor: pointer; padding: 6px 12px; color: var(--muted); font-size: .85rem; }
#tbl-bordereaux td.tbl-actions { text-align: right; }

/* v9.16 — les vues d'achats (planche D1) : des filtres en puces dans la barre d'outils, qui ne rechargent pas. */
.vue-achats-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; justify-content: space-between; }
.filtre-puces { display: flex; flex-wrap: wrap; gap: 6px; }
.vue-achats-outils input[type=search] { width: 16rem; max-width: 100%; }
#livraisons-a-pointer, #livraisons-pointees { margin-bottom: 14px; }
#livraisons-pointees .v-head { gap: 10px; }
#livraisons-pointees .liste-outils { margin: 0; }
@media (max-width: 680px) {
  /* relecture v9.16 — six puces font trois rangs à 375 px, collés en haut de l'écran : elles se replient
     derrière « Filtres », avec le menu de tri, comme les menus des autres listes. */
  .liste-outils .filtre-puces { display: none; }
  .liste-outils.lo-ouvert .filtre-puces { display: flex; flex-basis: 100%; }
  .liste-outils.lo-ouvert select[data-tri] { display: block; }
}
/* v9.16 (captures) — un numéro de pièce et une référence de dossier ne se coupent pas ; une pastille garde sa police dans une cellule chiffrée. */
#tbl-pieces-achat td[data-label="N°"] a, #tbl-a-pointer td[data-label="Commande"] a, #tbl-pointees td[data-label="Commande"] a,
#tbl-pieces-achat td[data-label="Chantier"] .mono, #tbl-a-pointer td[data-label="Chantier"] .mono, #tbl-pointees td[data-label="Chantier"] .mono { white-space: nowrap; }
.a-tbl td.mono .chip { font-family: var(--font-body); }

/* v9.17 — LA MARGE EN TEMPS RÉEL (planches D2 et D2b). */
.marge-gestes { display: flex; gap: 8px; justify-content: flex-end; margin: -6px 0 10px; }
.marge-engagement { margin: -8px 0 10px; font-size: .8125rem; color: var(--muted); }
.marge-engagement strong { color: var(--ink-strong); }
.marge-regle { border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); background: var(--accent-soft); border-radius: 10px; padding: 10px 14px; font-size: .8125rem; line-height: 1.55; color: var(--ink); }
.tbl-marge .tbl-marge-groupes th { font-size: .66rem; color: var(--faint); border-bottom: 0; padding-bottom: 0; }
.tbl-marge .tbl-marge-groupes th:not(:empty) { border-bottom: 1px solid var(--line); }
.tbl-marge tr.lot-assurances > td { color: var(--muted); background: var(--surface-2); }
.tbl-marge .form-cloture .check-line { margin: 0; gap: 4px 6px; flex-wrap: wrap; }
/* ONZE COLONNES DANS LA LARGEUR DE L'ÉCRAN, comme la planche D2b : les titres passent sur deux lignes, les marges
   intérieures se resserrent, le commentaire se contente de neuf caractères de large avant de passer à la ligne. */
.tbl-marge thead th, .tbl-marge tfoot th { white-space: normal; vertical-align: bottom; }
.tbl-marge > thead > tr > th, .tbl-marge > tbody > tr > td, .tbl-marge > tfoot > tr > th { padding-left: 7px; padding-right: 7px; }
.tbl-marge td.marge-commentaire { min-width: 9rem; max-width: 16rem; }
.tbl-marge td.num .chip { font-family: var(--font-body); }
@media (max-width: 680px) { .tbl-marge .tbl-marge-groupes { display: none; } }
@media print {
  .marge-gestes, .no-print, .tbl-marge .x-btn, #dlg-marge-enregistrer, #dlg-note-marge { display: none !important; }
  .tbl-marge tr.tr-detail { display: none !important; }
}
.finances-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-bottom: 12px; }
.finances-outils select, .finances-outils input { width: auto; padding: 6px 10px; font-size: .85rem; }
.finances-outils input[type=search] { min-width: 12rem; }
.finances-outils .filtre-colonne { display: inline-flex; gap: 6px; align-items: center; }
.finances-outils .filtre-colonne input { width: 7rem; }
.finances-outils .lo-compte { margin-left: auto; font-size: .8rem; color: var(--muted); }
.tbl-finances th.col-entreprises { background: color-mix(in srgb, var(--info-soft) 60%, var(--surface-2)); }
.tbl-finances th.col-client { background: color-mix(in srgb, var(--ok-soft) 60%, var(--surface-2)); }
/* DOUZE COLONNES CHIFFRÉES DANS LA LARGEUR, comme la planche D2 : les titres passent sur deux ou trois lignes, les marges
   intérieures se resserrent, et la pastille du taux descend sous la marge plutôt que d'élargir la colonne. */
.tbl-finances thead th { white-space: normal; vertical-align: bottom; line-height: 1.25; }
.tbl-finances > thead > tr > th, .tbl-finances > tbody > tr > td, .tbl-finances > tfoot > tr > th { padding-left: 7px; padding-right: 7px; }
.tbl-finances tfoot th { font-weight: 600; white-space: nowrap; }
.tbl-finances tfoot th[data-total="titre"], .tbl-finances tfoot tr.fin-moyenne th:first-child { white-space: normal; }
.tbl-finances td.fin-marge { white-space: normal; }
.tbl-finances td.fin-marge .chip { margin-top: 2px; }
.tbl-finances tfoot tr.fin-moyenne th { font-weight: 500; color: var(--muted); }
.tbl-finances td { white-space: nowrap; }
.tbl-finances td[data-label="Dossier"] { white-space: normal; min-width: 8.5rem; }
@media print { .finances-outils { display: none !important; } }
@media (max-width: 680px) {
  /* relecture v9.17 — un pied de tableau ne passe pas en cartes : l'onglet a ses tuiles, et Finances empile ses totaux. */
  .tbl-marge tfoot { display: none; }
  .tbl-finances tfoot, .tbl-finances tfoot tr { display: block; }
  .tbl-finances tfoot th { display: flex; justify-content: space-between; gap: 8px; white-space: normal; border: 0; padding: 3px 8px; }
  .tbl-finances tfoot th:empty { display: none; }
  .tbl-finances tfoot th[data-label]::before { content: attr(data-label); color: var(--muted); font-weight: 500; }
  /* Une carte par dossier, l'étiquette et le chiffre sur la même ligne : douze chiffres empilés sous leur étiquette
     faisaient un écran entier par dossier. */
  .tbl-marge tbody td.num[data-label], .tbl-marge tbody td[data-label="Clôturé"] { display: flex !important; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 10px; padding: 3px 0 !important; }
  .tbl-marge tbody td.num[data-label]::before, .tbl-marge tbody td[data-label="Clôturé"]::before { margin: 0 auto 0 0; }
  .tbl-finances tbody td[data-label]:not(:first-child) { display: flex !important; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 10px; padding: 3px 0 !important; }
  .tbl-finances tbody td[data-label]:not(:first-child)::before { margin: 0 auto 0 0; }   /* la valeur et son complément, groupés à droite */
}
/* ---- v9.18 — Le métré d'un seul tenant, et le métré seul (registre, point 49) -------------------------
 * « une vue pour visualiser tout le métré dans une page avec tous les lots et les chapitres et leur ouvrage et
 * le sous total par lot mais on pourrait le parcourir sans changer de lot » — et « ouvrir le métré dans une
 * fenêtre grand écran sans les menus de l'application ». La hauteur de la barre du haut est une variable : le
 * bandeau de chaque lot et le rail se calent dessous, et le cadre seul la remplace par sa bande. */
:root { --haut-barre: 51px; }
body.cadre-seul { --haut-barre: 52px; }
.lecture-bascule { display: inline-flex; flex-wrap: wrap; gap: 0; }
.lecture-bascule .btn { border-radius: 0; margin-left: -1px; }
.lecture-bascule > :first-child .btn, .lecture-bascule > .btn:first-child { border-radius: 8px 0 0 8px; margin-left: 0; }
.lecture-bascule > :last-child .btn, .lecture-bascule > .btn:last-child { border-radius: 0 8px 8px 0; }
.lecture-bascule .btn[aria-pressed="true"] { background: var(--ink-strong); border-color: var(--ink-strong); color: var(--ground); position: relative; z-index: 1; }

/* Le cadre seul : ni barre, ni menu ; la page prend toute la largeur, et une bande sombre dit où l'on est. */
.cadre-seul .a-shell { grid-template-columns: minmax(0, 1fr); min-height: 100vh; }
.cadre-seul .a-main { padding-top: 0; }
.cadre-seul .a-main > .contenu { max-width: none; }
.bande-seul { position: sticky; top: 0; z-index: 40; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  min-height: var(--haut-barre); margin: 0 -24px 12px; padding: 7px 24px;
  background: var(--ink-strong); color: var(--ground); font-size: .84rem; }
.bande-seul .bande-retour { color: var(--ground); text-decoration: none; border: 1px solid rgba(255,255,255,.35); border-radius: 7px; padding: 3px 10px; white-space: nowrap; }
.bande-seul .bande-retour:hover { background: rgba(255,255,255,.1); color: var(--ground); }
.bande-seul .bande-nom { min-width: 0; }
.bande-seul .bande-nom span { opacity: .75; }
.bande-seul .bande-total { margin-left: auto; white-space: nowrap; opacity: .9; }
.bande-seul .bande-total strong { opacity: 1; margin-left: 4px; }
.bande-seul .lecture-bascule .btn { background: transparent; color: var(--ground); border-color: rgba(255, 255, 255, .35); }
.bande-seul .lecture-bascule .btn[aria-pressed="true"] { background: var(--ground); color: var(--ink-strong); border-color: var(--ground); }
.cadre-seul .metre-rail { top: calc(var(--haut-barre) + 12px); max-height: calc(100vh - var(--haut-barre) - 24px); }

/* D'un seul tenant : un bloc par lot, son bandeau collé sous la barre tant qu'on est dedans. */
.tenant-barre { flex-wrap: wrap; align-items: center; }
.lot-bloc { margin-top: 16px; scroll-margin-top: calc(var(--haut-barre) + 8px); }
.lot-bloc:first-of-type { margin-top: 10px; }
.lot-tete { position: sticky; top: var(--haut-barre); z-index: 6; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
  padding: 8px 12px; background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: 8px; }
.lot-tete-n { color: var(--accent); font-weight: 600; font-size: .82rem; }
.lot-tete-t { color: var(--ink-strong); font-size: .9rem; }
.lot-tete-d { margin-left: auto; display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.lot-tete-d strong { color: var(--ink-strong); }
[data-lot-montant].en-cours { color: var(--warn); }
.lot-bloc .a-tbl-wrap { margin-top: 4px; }
/* Un lot sans ligne métrée, en « Ce qui est métré » : son bandeau seul, plus serré, et « Le saisir ». */
.lot-saisir { display: none; }
.lot-bloc.lot-rien { margin-top: 6px; }
.lot-bloc.lot-rien .lot-tete { position: static; background: var(--surface-2); border-color: var(--line); padding: 5px 12px; }
.lot-bloc.lot-rien .lot-tete-t { font-weight: 500; color: var(--muted); }
.lot-bloc.lot-rien [data-lot-compte] { color: var(--warn); }
.lot-bloc.lot-rien .lot-saisir { display: inline-flex; }
.lot-bloc.lot-rien .lot-sans-ouvrage, .lot-bloc.lot-rien .lot-pied { display: none; }
.lot-sans-ouvrage { margin: 4px 0 0; padding: 6px 12px; }
.lot-pied { display: flex; justify-content: flex-end; align-items: baseline; gap: 10px; padding: 6px 12px 2px; font-size: .8rem; color: var(--muted); }
.lot-pied strong { color: var(--ink-strong); border-top: 2px solid var(--ink-strong); padding-top: 2px; }
.a-tbl tr.hors-filtre { display: none; }
.metre-tenant input.champ-q, .metre-tenant input.champ-loc { scroll-margin-top: calc(var(--haut-barre) + 64px); scroll-margin-bottom: 140px; }   /* v9.27 : le pied porte une rangée de plus */
/* Le pied — l'état des écritures, l'annulation, la précision — reste en vue : d'un seul tenant, on saisit loin du haut. */
.metre-tenant .metre-pied-bloc { position: sticky; bottom: 0; z-index: 7; background: var(--surface); border-top: 1px solid var(--line);
  margin-top: 12px; padding: 0 12px 8px; box-shadow: 0 -8px 18px -16px rgba(22, 27, 29, .45); }
@media (max-width: 820px) { body:not(.cadre-seul) .metre-tenant .metre-pied-bloc { bottom: calc(60px + env(safe-area-inset-bottom)); } }
.metre-tenant .metre-pied-bloc .metre-pied { margin-top: 8px !important; }
.metre-pied-total { margin-left: auto; white-space: nowrap; font-size: .85rem; color: var(--muted); }
.metre-pied-total strong { color: var(--ink-strong); margin-left: 4px; }

/* L'actualisé : la précision de la saisie, et le journal regroupé par saisie. */
.saisie-panneau { margin-top: 10px; padding: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.saisie-panneau textarea { min-height: 52px; }
#saisie-preciser[aria-expanded="true"] { background: var(--accent-soft); border-color: var(--accent); }
.journal-saisies { display: grid; gap: 12px; }
.saisie { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); overflow: hidden; }
.saisie.courante { border-color: var(--accent); }
.saisie-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 8px 12px; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.saisie.courante .saisie-tete { background: var(--accent-soft); }
.saisie-texte { margin: 0; padding: 8px 12px; border-bottom: 1px solid var(--line); color: var(--ink); }
.saisie-texte.vide { color: var(--faint); font-style: italic; }
.saisie .a-tbl-wrap { border: 0; border-radius: 0; margin: 0; }
/* Les colonnes du journal s'alignent d'une saisie à l'autre. */
.tbl-journal { table-layout: fixed; width: 100%; }
.tbl-journal th:nth-child(2), .tbl-journal th:nth-child(3) { width: 130px; }
.tbl-journal th:nth-child(4) { width: 170px; }
html.densite-compacte .bande-seul { margin: 0 -18px 12px; padding: 7px 18px; }

/* ---- v9.22 — Les remontées : chercher, glisser, archiver (registre, points 52 et 60) ------------------------------------- */
.rem-recherche { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 4px 0 12px; }
.rem-recherche input[type=search] { flex: 1 1 280px; max-width: 460px; }
.rem-de { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--muted); white-space: nowrap; flex: none; }   /* « De : » ne se coupe pas (vu sur capture) */
.rem-aide-glisser { margin: -4px 0 10px; }
.rem-kanban { grid-template-columns: repeat(5, minmax(0, 1fr)) minmax(120px, max-content); }
.rem-archives { background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px; width: 130px; }
.rem-archives[open] { width: 250px; }
.rem-archives > summary { list-style: none; cursor: pointer; }
.rem-archives > summary::-webkit-details-marker { display: none; }
.rem-archives > summary h2::before { content: '▸ '; }
.rem-archives[open] > summary h2::before { content: '▾ '; }
.rem-archives-aide { margin: 0; font-size: .74rem; }
.rem-archives > summary { flex-wrap: wrap; }
.rem-archives-dit { white-space: normal; }
.rem-archives[open] .rem-archives-dit { display: none; }
.rem-carte[draggable="true"] { cursor: grab; }
.rem-carte.rem-glisse { opacity: .55; }
.rem-colonne.rem-cible { outline: 2px dashed var(--line-strong); outline-offset: 4px; border-radius: 10px; }
.rem-colonne.rem-survol { outline-color: var(--ok); background: color-mix(in srgb, var(--ok-soft) 60%, transparent); }
.rem-colonne.rem-interdite { opacity: .55; }
@media (max-width: 1200px) { .rem-kanban { grid-template-columns: repeat(3, minmax(0, 1fr)); } .rem-archives, .rem-archives[open] { width: auto; } }
@media (max-width: 900px) { .rem-kanban { grid-template-columns: minmax(0, 1fr); } }

/* v9.23 — LA VISITE DE CHANTIER AU BUREAU (registre, point 51 ; maquette « Remontées du 25 septembre », planche A).
   À gauche la saisie — l'en-tête de la visite, puis les observations en tableau, une ligne chacune ; à droite ce qu'on
   consulte en saisissant — les points à reprendre, le compte rendu. Sous 1280 px, la droite passe dessous. */
.vb-tete { align-items: flex-start; }
.vb-types, .vb-choix-groupe { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.vb-choix { font: inherit; font-size: .78rem; font-weight: 600; padding: 4px 11px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted); cursor: pointer; }
.vb-choix:hover { color: var(--ink); border-color: var(--accent-line); }
.vb-choix[aria-checked="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.vb-choix:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vb-petit-ecran { display: none; }
@media (max-width: 1023px) { .vb-petit-ecran { display: flex; } }
.vb { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 14px; align-items: start; }
.vb-saisie, .vb-cote { display: grid; gap: 14px; min-width: 0; }
.vb-cote { position: sticky; top: calc(var(--haut-barre, 56px) + 12px); }
@media (max-width: 1280px) { .vb { grid-template-columns: minmax(0, 1fr); } .vb-cote { position: static; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); } }
.vb-carte { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }   /* sans quoi la carte prend la largeur du tableau, et la page défile au téléphone (vu par les tailles d'écran) */
.vb-ligne-champs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.vb-quand { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.vb-quand input { font: inherit; font-weight: 500; padding: 5px 8px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface); color: var(--ink); }
.vb-meteo { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; font-size: .85rem; color: var(--muted); }
.vb-etape { display: inline-flex; align-items: center; gap: 8px; font-size: .85rem; color: var(--muted); }
.vb-etape select { max-width: 320px; }
.vb-label { font-size: .78rem; color: var(--muted); margin-bottom: -4px; }
#vb-avancement { width: 100%; min-height: 64px; resize: vertical; font: inherit; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface); color: var(--ink); }
.vb-aide { font-size: .78rem; color: var(--muted); margin: 0; }
.vb-depot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; border: 1.5px dashed var(--line-strong); border-radius: 8px; padding: 10px 12px; font-size: .85rem; color: var(--muted); }
.vb-depot.vb-survol, .vb-ligne.vb-survol td { background: var(--accent-soft); border-color: var(--accent); }
.vb-choisir { color: var(--accent); text-decoration: underline; cursor: pointer; }
.vb-vignettes { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.vb-vignette { position: relative; display: inline-block; width: 44px; height: 44px; border-radius: 5px; overflow: hidden; background: var(--sunken); border: 1px solid var(--line); flex: none; }
.vb-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vb-vignette.attente img { opacity: .55; }
.vb-vignette-vide { display: grid; place-items: center; width: 100%; height: 100%; color: var(--faint); }
.vb-vignette-x { position: absolute; top: 1px; right: 1px; width: 17px; height: 17px; padding: 0; border: 0; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; font-size: 12px; line-height: 17px; cursor: pointer; opacity: 0; }
.vb-vignette:hover .vb-vignette-x, .vb-vignette-x:focus-visible { opacity: 1; }
.vb-titre { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.vb-titre-aide { text-transform: none; letter-spacing: 0; font-weight: 500; }
.vb-table-cadre { overflow-x: auto; margin: 0 -4px; }
.vb-table-cadre.a-tbl-wrap { border: 0; border-radius: 0; background: transparent; }   /* le cadre qui défile, sans la bordure des tableaux : il est déjà dans sa carte */
.vb-obs { width: 100%; border-collapse: collapse; table-layout: fixed; min-width: 760px; }
.vb-obs th { text-align: left; font-size: .72rem; font-weight: 600; color: var(--muted); padding: 4px 4px 6px; border-bottom: 1px solid var(--line); }
.vb-obs td { padding: 4px; border-bottom: 1px solid var(--line); vertical-align: top; }
.vb-obs .vb-c-lot { width: 17%; } .vb-obs .vb-c-ent { width: 16%; } .vb-obs .vb-c-niveau { width: 13%; }
.vb-obs .vb-c-echeance { width: 140px; } .vb-obs .vb-c-photos { width: 14%; } .vb-obs .vb-c-retirer { width: 30px; }
.vb-obs select, .vb-obs input, .vb-obs textarea { width: 100%; font: inherit; font-size: .85rem; padding: 5px 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--ink); }
.vb-obs textarea { resize: none; overflow: hidden; line-height: 1.35; min-height: 30px; }
.vb-obs select:hover, .vb-obs input:hover, .vb-obs textarea:hover { border-color: var(--line); }
.vb-obs select:focus, .vb-obs input:focus, .vb-obs textarea:focus { border-color: var(--accent); background: var(--surface); outline: none; }
.vb-photos-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.vb-deposer { font-size: .75rem; color: var(--muted); text-decoration: none; padding: 5px 4px; }
.vb-deposer:hover { color: var(--accent-ink); text-decoration: underline; }
.vb-ligne.vb-attente td { background: var(--surface-2); }
.vb-ligne.vb-attente textarea::placeholder { color: var(--faint); }
.vb-retirer { width: 24px; height: 24px; margin-top: 3px; padding: 0; border: 0; border-radius: 5px; background: transparent; color: var(--faint); font-size: 16px; cursor: pointer; }
.vb-retirer:hover { background: var(--crit-soft); color: var(--crit); }
.vb-ligne.vb-attente .vb-retirer { visibility: hidden; }
.vb-point { display: grid; gap: 4px; padding: 9px 0; border-top: 1px solid var(--line); font-size: .85rem; }
.vb-point:first-child { border-top: 0; padding-top: 0; }
.vb-point-qui { font-size: .76rem; color: var(--muted); }
.vb-point-qui b { color: var(--ink); }
.vb-point-echeance { font-size: .76rem; color: var(--muted); }
.vb-point-echeance.late { color: var(--crit); }
.vb-point.repris .vb-point-texte { color: var(--muted); }
.vb-seg { display: inline-flex; gap: 6px; }
.vb-seg button { font: inherit; font-size: .78rem; font-weight: 600; padding: 4px 10px; border-radius: 6px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted); cursor: pointer; }
.vb-seg button[aria-pressed="true"] { background: var(--warn-soft); border-color: var(--warn); color: var(--ink); }
.vb-seg button.vb-seg-ok[aria-pressed="true"] { background: var(--ok-soft); border-color: var(--ok); }
.vb-point-note { font: inherit; font-size: .82rem; padding: 5px 8px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface); color: var(--ink); }
.vb-cr .btn-primary { justify-self: start; }
.vb-cr-texte { margin: 0; font-size: .86rem; }
.vb-etat { margin: 0; font-size: .8rem; color: var(--muted); min-height: 1.2em; }
.vb-etat.ok { color: var(--ok); }
.vb-etat.err { color: var(--crit); }
.vb.vb-arretee .vb-saisie { opacity: .6; }
.vb.vb-fin { opacity: .75; }
.vb.vb-fin { cursor: progress; }
.vb-sous-titre { font-size: .82rem; margin: 6px 0 2px; }
.vb-dests { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.vb-dest label { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; cursor: pointer; }
.vb-dest label > span { display: grid; gap: 1px; }
.vb-dest small { color: var(--muted); font-size: .76rem; }
.vb-dest.sans-email label { opacity: .6; cursor: default; }
.vb-emails { word-break: break-all; }
.vb-autres summary { cursor: pointer; font-size: .82rem; color: var(--muted); margin: 4px 0; }
#dlg-vb-fin .m-body { display: grid; gap: 10px; }
/* v9.27 — le pied de l'atelier du métré (point 6) : ses deux lectures, l'aide-clavier, et les deux fenêtres larges */
dialog.modal.modal-large { width: min(940px, calc(100vw - 24px)); }
.metre-vues { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin-top: 10px; }
.aide-clavier { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-left: auto; font-size: .78rem; color: var(--muted); }
.aide-clavier kbd { font-family: var(--font-mono); font-size: .72rem; background: var(--surface-2); border: 1px solid var(--line); border-radius: 4px; padding: 0 4px; color: var(--ink); }
.cmd-cadre { max-height: min(58vh, 520px); overflow: auto; }
.cmd-cadre tr.cmd-lot td { position: sticky; top: 0; z-index: 1; background: var(--surface-2); font-weight: 700; font-size: .76rem; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.lot-de { display: inline-block; margin-left: 6px; font-size: .7rem; font-weight: 600; border-radius: 999px; padding: 0 7px; background: var(--info-soft); color: var(--info); vertical-align: middle; }
.encart-metre { margin: 10px 0 0; font-size: .82rem; color: var(--muted); }
.cmd-resume { margin: 0 0 10px; }
@media (max-width: 720px) { .aide-clavier { display: none; } }

/* v9.28 — LA VUE « MÉTRÉS », REVUE COMME FINANCES (point 45, planche A) : une ligne par affaire, qui ouvre son métré. */
.tbl-metres tbody tr[data-href] { cursor: pointer; }
.tbl-metres tbody tr[data-href]:hover td { background: var(--accent-soft); }
.tbl-metres .metre-lien { font-weight: 600; }
.tbl-metres .metre-seul { padding: 0 6px; min-height: 0; line-height: 1.5; margin-left: 4px; }
.tbl-metres .metres-mv, .tbl-metres .metres-ecart { font-size: .82rem; }
.tbl-metres .metres-ecart .t-ok { color: var(--ok); }
.tbl-metres .metres-ecart .t-crit { color: var(--crit); }
.tbl-metres tfoot th { background: var(--surface-2); font-weight: 700; text-transform: none; letter-spacing: 0; font-size: .82rem; color: var(--ink-strong); }
.tbl-metres tfoot th[data-total="ecart"] { white-space: normal; font-family: var(--font-body); }   /* « +370 vendus en plus · 2 595 de dérapage » ne tient pas la colonne en otage */
.tbl-metres td.mono .t-sub { font-family: var(--font-body); white-space: normal; }   /* « rien n’est chiffré » se replie : le chiffre, lui, reste d’un tenant */
/* Sans bouger depuis plus de sept jours : un trait à gauche, et la puce « dort depuis » le dit. Pas de fond : celui du pied
   est déjà gris, et le tri par défaut met les lignes qui dorment juste au-dessus. */
.tbl-metres tr.metres-dort td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
/* La colonne Métré porte un intitulé d'étude et une phrase d'attente : sans largeur, elle passe à la ligne mot par mot ;
   le bouton de « Ce qui attend » se replie plutôt que de sortir du tableau. */
@media (min-width: 681px) {
  .tbl-metres td[data-label="Métré"] { min-width: 10.5rem; }
  .tbl-metres td[data-label="Dernier mouvement"] { min-width: 7rem; }
  /* et le tableau tient un portable (1 280 px, menu compris) sans rejeter « Ce qui attend » hors de vue : les titres
     passent à la ligne, les cellules se resserrent comme celles de Finances */
  .tbl-metres > thead > tr > th { white-space: normal; vertical-align: bottom; letter-spacing: .03em; }
  .tbl-metres .t-name { min-width: 9.5rem; }
  .tbl-metres > thead > tr > th, .tbl-metres > tbody > tr > td, .tbl-metres > tfoot > tr > th { padding-left: 7px; padding-right: 7px; }
}
/* Sur téléphone, le pied s'empile comme celui de Finances : l'étiquette et le total sur une ligne. */
@media (max-width: 680px) {
  .tbl-metres tfoot, .tbl-metres tfoot tr { display: block; }
  .tbl-metres tfoot th { display: flex; justify-content: space-between; gap: 8px; white-space: normal; border: 0; padding: 3px 8px; }
  .tbl-metres tfoot th:empty { display: none; }
  .tbl-metres tfoot th[data-label]::before { content: attr(data-label); color: var(--muted); font-weight: 500; font-family: var(--font-body); }
}
.tbl-metres td[data-label="Ce qui attend"] .btn { white-space: normal; text-align: center; max-width: 9rem; }

/* ===== Point 92 — la notice descriptive détaillée : son éditeur, au gabarit des notices de Maisons Berdin ===== */
table.nd { table-layout: fixed; }
table.nd col.nd-c-num { width: 72px; }
table.nd col.nd-c-cmi { width: 96px; }
table.nd col.nd-c-cout { width: 112px; }
table.nd col.nd-c-geste { width: 108px; }
table.nd th.nd-cmi { text-align: center; line-height: 1.25; white-space: normal; }
table.nd td { vertical-align: top; overflow-wrap: anywhere; }
table.nd tr.nd-lot td { background: #23407A; color: #fff; font-family: var(--font-display); font-weight: 800; font-size: .86rem; letter-spacing: .02em; text-transform: none; }
table.nd tr.nd-lot td .t-sub { color: #C9D4EC; }
table.nd tr.nd-lot .chap-bascule { color: #fff; font: inherit; }
table.nd tr.nd-chap td { background: var(--accent-soft); color: var(--ink-strong); font-weight: 700; font-size: .74rem; letter-spacing: .05em; text-transform: uppercase; padding: 6px 10px; }
table.nd td.nd-num { color: var(--muted); font-size: .78rem; white-space: nowrap; }
table.nd td.nd-cmi { text-align: center; }
table.nd .nd-lib, table.nd .nd-texte, table.nd .nd-champs { display: block; width: 100%; border: 1px solid transparent; border-radius: 5px; background: transparent; padding: 3px 6px; font: inherit; color: var(--ink); resize: none; }
table.nd .nd-lib { font-weight: 600; color: var(--ink-strong); }
table.nd .nd-champs { font-size: .8rem; color: var(--muted); }
table.nd .nd-lib:hover, table.nd .nd-texte:hover, table.nd .nd-champs:hover { border-color: var(--line); }
table.nd .nd-lib:focus, table.nd .nd-texte:focus, table.nd .nd-champs:focus { border-color: var(--accent); background: var(--surface); outline: none; }
table.nd .nd-compris, table.nd .nd-cout { width: 100%; max-width: 96px; font-family: var(--font-mono); font-size: .82rem; text-align: center; padding: 4px 5px; }
table.nd .nd-cout { text-align: right; }
table.nd .nd-cout.nd-manque { border-color: var(--crit); background: var(--crit-soft); }
table.nd .nd-cout.nd-manque::placeholder { color: var(--crit); }
table.nd input[aria-invalid="true"], table.nd textarea[aria-invalid="true"] { border-color: var(--crit); background: var(--crit-soft); }
table.nd .nd-lib-lu { font-weight: 600; color: var(--ink-strong); }
table.nd .nd-texte-lu { white-space: pre-line; margin-top: 2px; }
table.nd .nd-champs-lus { margin: 3px 0 0; padding: 0; list-style: none; font-size: .8rem; color: var(--muted); }
table.nd .nd-adef { color: var(--warn); background: var(--warn-soft); border-radius: 4px; padding: 0 5px; }
table.nd .nd-origine { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
table.nd .nd-gestes { white-space: nowrap; text-align: right; }
table.nd .nd-gestes .inline-form { display: inline; }
table.nd tr.nd-sous-titre .nd-lib, table.nd tr.nd-sous-titre .nd-lib-lu { font-family: var(--font-display); font-weight: 700; }
table.nd tr.nd-ecartee > td { opacity: .55; }
table.nd tr.nd-hors > td:first-child { box-shadow: inset 3px 0 0 0 var(--warn); }
/* La ligne en cours se voit — la règle de l'atelier du métré (point 82). */
table.nd tbody tr.nd-ligne:focus-within > td { background-color: var(--accent-soft); }
table.nd tbody tr.nd-ligne:focus-within > td:first-child { box-shadow: inset 3px 0 0 0 var(--accent); }
table.nd tr.nd-ajout td { padding: 4px 10px 8px; }
table.nd .nd-ajouter { display: flex; flex-wrap: wrap; gap: 6px; }
table.nd tr.nd-total td { font-weight: 700; color: var(--ink-strong); background: var(--surface-2); }
.nd-pied { position: sticky; bottom: 0; z-index: 3; display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; justify-content: space-between; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 10px; padding: 10px 14px; margin-top: 12px; box-shadow: 0 -10px 24px -18px rgba(0,0,0,.35); }
.nd-pied .nd-totaux { display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: center; font-size: .82rem; color: var(--muted); }
.nd-pied .nd-totaux b { color: var(--ink-strong); }
ul.nd-controle { margin: 0; padding: 0; list-style: none; display: grid; gap: 5px; font-size: .86rem; }
ul.nd-controle li { padding-left: 22px; position: relative; }
ul.nd-controle li::before { position: absolute; left: 0; top: 1px; width: 16px; height: 16px; border-radius: 999px; display: grid; place-items: center; font: 700 10px var(--font-mono); }
ul.nd-controle li.nd-bloque::before { content: "!"; background: var(--crit-soft); color: var(--crit); }
ul.nd-controle li.nd-afaire::before { content: "·"; background: var(--warn-soft); color: var(--warn); }
ul.nd-controle li.nd-info::before { content: "i"; background: var(--sunken); color: var(--muted); }
ul.nd-controle li.nd-ok::before { content: "✓"; background: var(--ok-soft); color: var(--ok); }
details.nd-garde > summary { cursor: pointer; }
details.nd-garde .form-grille { margin-top: 10px; }
.enr-etat.enr-ok { color: var(--ok); }
.enr-etat.enr-refus { color: var(--crit); }
fieldset.nd-fiche { border: 1px solid var(--accent-line, var(--line)); border-radius: 8px; padding: 10px 12px; display: grid; gap: 8px; }
fieldset.nd-fiche legend { font-weight: 700; color: var(--ink-strong); padding: 0 4px; }
fieldset.nd-fiche .case-ligne { display: block; font-size: .86rem; }
@media (max-width: 680px) {
  table.nd { table-layout: auto; }
  table.nd .nd-compris, table.nd .nd-cout { max-width: none; text-align: left; }
  table.nd .nd-gestes { text-align: left; }
  table.nd tbody tr.nd-ligne:focus-within > td:first-child { box-shadow: none; }
  .nd-pied { position: static; }
}

/* ------------------------------------------------------------------ */
/* Point 93a — le planning du conducteur : un tableau et sa frise       */
/* (maquette « Marchés, commandes et planning », écrans C et D)          */
/* ------------------------------------------------------------------ */
.gantt.gantt-tableau { --g-lib: 700px; }
/* Une ligne du tableau est haute (le lot, sa nature, ses enchaînements) : la barre garde sa hauteur de barre, au milieu. */
.gantt-tableau .g-lot .g-barre { top: 50%; bottom: auto; height: 26px; margin-top: -13px; }
.gantt-tableau .g-lot .g-repere { top: calc(50% - 22px); }
.gantt-tableau .g-lot .g-fenetre { top: calc(50% + 16px); }
.gantt-tableau .g-lib { justify-content: center; }
.g-grille { display: grid; grid-template-columns: 22px minmax(0, 1.45fr) minmax(0, 1.25fr) 124px 52px 72px minmax(0, 1fr); gap: 2px 8px; align-items: center; }
.g-entete .g-grille { font-size: .68rem; }
.g-ligne.g-lot { min-height: 46px; }
.g-c-num { color: var(--faint); text-align: right; }
.g-c-lot { min-width: 0; display: flex; flex-direction: column; }
.g-c-lot .g-nom { font-weight: 600; color: var(--ink-strong); }
.g-c-lot .t-sub, .g-apres { font-size: .68rem; }
.g-apres { color: var(--faint); white-space: normal; }
.g-lien-rompu { color: var(--crit); font-weight: 600; }
.g-retirer { border: 0; background: none; color: var(--muted); cursor: pointer; padding: 0 3px; font: inherit; }
.g-retirer:hover { color: var(--crit); }
/* Deux classes : la règle commune des champs (input[type=date], input[type=number]) pèse plus qu'une seule, et rendait
   14 px et 10 px de marge — l'année d'un début et le second chiffre d'une durée étaient coupés (capture de la livraison). */
.gantt-tableau .g-sous-traitant, .gantt-tableau .g-case { width: 100%; min-width: 0; font-size: .76rem; padding: 3px 5px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface); color: var(--ink); }
.gantt-tableau .g-sous-traitant:focus, .gantt-tableau .g-case:focus { border-color: var(--accent); }   /* la case active se voit : ↵ passe à la suivante */
.g-case { font-family: var(--font-mono); }
.g-case[disabled] { opacity: .6; }
.g-c-fin { font-size: .76rem; color: var(--muted); }
.g-c-mar .chip, .g-c-mar .t-sub { font-size: .68rem; }
.gantt-tableau .g-c-mar .t-sub { white-space: normal; overflow-wrap: anywhere; }   /* « un marché … existe avec … » passe à la ligne */
.g-ligne.g-a-affecter .g-lib { background: linear-gradient(90deg, var(--warn-soft), var(--surface) 75%); }
.g-ligne.g-a-affecter .g-sous-traitant { border-style: dashed; border-color: var(--warn); color: var(--warn); font-weight: 600; }
.g-ligne.g-fourn { min-height: 24px; }   /* la piste reste transparente : la trame, la fermeture et les traits passent dessous */
.g-ligne.g-fourn .g-lib { background: var(--surface-2); }
.g-grille-fourn { flex-direction: row !important; justify-content: flex-start !important; align-items: baseline; gap: 6px; padding-left: 38px !important; font-size: .72rem; color: var(--muted); white-space: normal; }
.g-grille-fourn strong { color: var(--ink); font-weight: 600; }
.g-grille-fourn .chip { font-size: .66rem; }
.g-grille-fourn .coude { color: var(--faint); font-family: var(--font-mono); }
.g-repere { position: absolute; top: 3px; left: calc(var(--o) * var(--g-jour)); width: 10px; height: 10px; margin-left: -5px; transform: rotate(45deg);
  border: 2px solid var(--info); background: var(--surface); border-radius: 2px; z-index: 2; pointer-events: auto; }
.g-fenetre { position: absolute; top: 2px; height: 4px; left: calc(var(--o) * var(--g-jour)); width: calc(var(--w) * var(--g-jour)); border-radius: 2px; background: var(--info); opacity: .5; z-index: 2; }
.g-legende { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center; }
.g-legende i { display: inline-block; vertical-align: middle; margin-right: 6px; }
.g-legende .l-barre { width: 24px; height: 10px; border-radius: 3px; background: var(--accent-soft); border: 1px solid var(--accent); }
.g-legende .l-sans { width: 24px; height: 10px; border-radius: 3px; border: 1px dashed var(--line-strong); background: var(--surface-2); }
.g-legende .l-repere { width: 9px; height: 9px; transform: rotate(45deg); border: 2px solid var(--info); background: var(--surface); border-radius: 2px; }
.g-legende .l-fenetre { width: 22px; height: 4px; border-radius: 2px; background: var(--info); opacity: .5; }
.g-fond .g-ferme, .g-legende .l-ferme { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--muted) 30%, transparent) 0 4px, transparent 4px 8px); }
.g-fond .g-ferme { position: absolute; top: 0; bottom: 0; left: calc(var(--o) * var(--g-jour)); width: calc(var(--w) * var(--g-jour)); text-decoration: none; }
.g-fond .g-ouv { position: absolute; top: 0; bottom: 0; width: 0; left: calc(var(--o) * var(--g-jour)); border-left: 2px solid var(--ok); text-decoration: none; }
.g-legende .l-ferme { width: 22px; height: 12px; border: 1px solid var(--line); }
.g-legende .l-ouv { width: 0; height: 14px; border-left: 2px solid var(--ok); }
.echeance-bandeau { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; margin-top: 10px; padding: 10px 14px; border-radius: 10px; }
.echeance-bandeau.conducteur { background: var(--ok-soft); border: 1px solid color-mix(in srgb, var(--ok) 35%, transparent); }
.echeance-bandeau.conducteur.depasse { background: var(--crit-soft); border-color: color-mix(in srgb, var(--crit) 45%, transparent); }
.echeance-bandeau.depasse .reste { color: var(--crit); }
.g-num-carte { display: none; }
.g-qualifier { display: block; font-size: .68rem; margin-top: 2px; }
.echeance-bandeau .quand { font-family: var(--font-display); font-weight: 800; font-size: 1rem; color: var(--ink-strong); }
.echeance-bandeau .reste { font: 700 .74rem var(--font-mono); border-radius: 999px; padding: 2px 9px; background: var(--surface); color: var(--ink-strong); }
.echeance-bandeau p { margin: 0; font-size: .82rem; flex: 1 1 340px; }
/* Un écran moyen : la fin se lit sur la barre, le marché passe sous le lot. */
@media (max-width: 1500px) {
  .gantt.gantt-tableau { --g-lib: 540px; }
  .g-grille { grid-template-columns: 22px minmax(0, 1.4fr) minmax(0, 1.2fr) 122px 50px; }
  .g-c-fin { display: none; }
  .g-c-mar { grid-column: 2; grid-row: 2; }
  .g-entete .g-c-mar { display: none; }
}
/* Au téléphone, la frise se tait : chaque lot devient une carte (écran D). */
@media (max-width: 900px) {
  .gantt.gantt-tableau { --g-lib: 100%; border: 0; background: transparent; }
  .gantt-tableau .g-scroll { overflow: visible; }
  .gantt-tableau .g-fond, .gantt-tableau .g-piste, .gantt-tableau .g-entete, .gantt-tableau .g-liens { display: none; }
  .gantt-tableau .g-ligne { width: auto; display: block; border: 0; margin-bottom: 8px; }
  .gantt-tableau .g-lib { position: static; width: auto; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
  .gantt-tableau .g-ligne.g-fourn { margin: -6px 0 8px; }
  .gantt-tableau .g-ligne.g-fourn .g-lib { border-top: 1px dashed var(--line); border-radius: 0 0 10px 10px; padding-left: 12px !important; }
  .g-grille { grid-template-columns: 1fr 1fr 1fr; gap: 6px; }
  .g-c-num { display: none; }
  .g-c-lot { grid-column: 1 / -1; }
  .g-c-ent { grid-column: 1 / -1; }
  .g-c-fin { display: block; align-self: center; }
  .g-c-mar { grid-column: 1 / -1; grid-row: auto; }
  /* Les cases à 16 px : en dessous, iOS agrandit la page à chaque case touchée (la leçon de la v8.7). */
  .gantt-tableau .g-case, .gantt-tableau .g-sous-traitant { font-size: 16px; }
  /* La carte dit ce qu'est chaque case, puisque l'en-tête du tableau se tait ; et son numéro, comme la maquette. */
  .gantt-tableau .g-lot .g-c-deb::before { content: 'début'; }
  .gantt-tableau .g-lot .g-c-dur::before { content: 'durée'; }
  .gantt-tableau .g-lot .g-c-fin::before { content: 'fin'; }
  .gantt-tableau .g-lot .g-c-deb::before, .gantt-tableau .g-lot .g-c-dur::before, .gantt-tableau .g-lot .g-c-fin::before {
    display: block; font-size: .66rem; color: var(--muted); font-family: var(--font-body, inherit); }
  .gantt-tableau .g-num-carte { display: inline; }
  .gantt-tableau .g-retirer, .gantt-tableau .g-lib-btn { padding: 6px 8px; }
  .g-seulement-frise { display: none !important; }
  /* « La carte d'un lot à affecter passe en tête » — ses fournitures la suivent. */
  .gantt-tableau .g-scroll { display: flex; flex-direction: column; }
  .gantt-tableau .g-ligne.g-a-affecter, .gantt-tableau .g-ligne.g-suit-a-affecter { order: -1; }
}
/* Point 93a — la fiche d'un lot, au planning */
fieldset.lot-planning { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
fieldset.lot-planning legend { font-weight: 700; font-size: .8rem; padding: 0 4px; }
.lot-fournitures { max-height: 220px; overflow-y: auto; display: grid; gap: 2px; border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; background: var(--surface-2); }
.lot-fournitures .case-ligne { display: flex; align-items: center; gap: 6px; font-size: .8rem; }
.lot-fournitures select { margin-left: auto; font-size: .74rem; padding: 1px 4px; }
