/* LM Compliance — Design System central (charte graphique unique).
   Toute nouvelle page / composant DOIT utiliser les variables ci-dessous
   (couleurs, typographie, espacements). Ne pas coder de couleur ou de police
   en dur : référencer les tokens `--color-*`, `--font-*`, `--fw-*`, `--space-*`. */

/* IBM Plex Sans — police principale de TOUT le produit (interface + documents).
   Poids Regular 400, Medium 500, SemiBold 600, Bold 700, plus les italiques
   400 et 600. Ne JAMAIS remplacer par Arial/Helvetica/Roboto/Inter sans
   instruction explicite (Helvetica/Arial ne servent que de repli technique si
   IBM Plex est indisponible). Le logo conserve sa police Angelica.

   SERVIE DEPUIS CE SERVEUR, ET NON DEPUIS GOOGLE FONTS — point ouvert n° 7,
   soldé le 19 septembre 2026. Un `@import` vers les serveurs de Google faisait
   transmettre à Google l'adresse IP de chaque visiteur, à chaque page, sans
   base légale : c'est un manquement au RGPD qui a déjà valu des condamnations
   en Europe. Sans conséquence tant que l'application tourne sur le Mac de
   Julien ; inacceptable le jour de la mise en ligne. Cette dépendance bloquait
   aussi la politique de sécurité de contenu stricte prévue sur `app.` (D11) :
   une CSP stricte interdit un domaine tiers.

   Les fichiers sont dans `easa/static/fonts/`, au format woff2 (462 Ko pour
   les six graisses, contre 1,3 Mo en TTF). Ils viennent de la famille complète
   déposée dans `fonts/IBM_Plex_Sans/`, sous licence SIL Open Font License,
   dont le texte est recopié à côté des fichiers (`OFL.txt`) — la licence
   autorise l'auto-hébergement et impose de la joindre.

   `font-display: swap` conserve le comportement d'avant : le texte s'affiche
   immédiatement dans la police de repli, puis bascule. Rien ne clignote,
   rien n'attend.

   POUR LES PDF, la même famille est embarquée séparément par
   `services/fonts.py`, qui lit des TTF — pas ces woff2. Les deux chemins sont
   indépendants : ne pas supprimer le dossier `fonts/` à la racine en croyant
   qu'il fait doublon. */

/* Light (300) — ajoutée en U1 pour le style « Omoda » (titres et chiffres en
   graisse fine). Convertie du TTF de `fonts/IBM_Plex_Sans/static/`. */
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-SemiBoldItalic.woff2") format("woff2");
  font-weight: 600;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/static/fonts/IBMPlexSans-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── Typographie ─────────────────────────────────────────────────────── */
  --font-body: "IBM Plex Sans", "Helvetica Neue", "Arial", system-ui, sans-serif;
  --font-heading: "IBM Plex Sans", "Helvetica Neue", "Arial", system-ui, sans-serif;
  --fw-regular: 400;   /* corps de texte */
  --fw-medium: 500;
  --fw-semibold: 600;  /* sous-titres */
  --fw-bold: 700;      /* titres */

  /* ── Palette officielle LM Compliance ────────────────────────────────── */
  --color-primary: #0A1F3D;     /* bleu marine — navigation, titres, boutons */
  --color-primary-dark: #061331;
  --color-secondary: #7A9BAB;   /* bleu-gris — éléments secondaires, badges */
  --color-secondary-dark: #4f6a78;

  /* ── Couleurs fonctionnelles ─────────────────────────────────────────── */
  --color-text: #1A1A1A;        /* texte principal */
  --color-muted: #4B5563;       /* texte secondaire */
  --color-accent: var(--color-primary);
  --color-accent-soft: #EAF1FC;   /* bleu pâle : entrée active, bandeaux d'information */
  --color-ir: #1e3a8a;
  --color-amc: #0f5132;
  --color-gm: #6c4a00;
  --color-app: #5b21b6;
  --color-bg: #FFFFFF;          /* fond principal */
  --color-bg-soft: #f7f8fa;
  --color-border: #DDE2EA;
  --color-diff-add: #b91c1c;
  --color-status-ok: #0f5132;
  --color-status-warn: #b45309;
  --color-status-ko: #b91c1c;

  /* ── Charte U1 (Docs/37_CHARTE_INTERFACE.md) ─────────────────────────── */
  --color-brand: #387EE4;       /* bleu Aviocentra : SEUL accent — jamais pour du texte (3,9:1) */
  --color-link: #2563C9;        /* texte des liens (5,2:1 sur blanc) */
  --color-ink: #111827;         /* titres de page, texte fort */
  --color-table-head: #F3F5F8;  /* fond des en-têtes de tableau */
  --color-doc: #660B0B;         /* bordeaux des DOCUMENTS (aperçu de contrat) — pas de l'interface */
  --gutter-wide: clamp(16px, 3vw, 40px);
  /* Anciennes teintes de module (supprimées en U1) : conservées comme alias
     pour les règles qui les lisent encore — elles valent toutes le marine. */
  --mod: var(--color-primary);
  --mod-deep: var(--color-primary);
  --mod-soft: var(--color-accent-soft);

  /* ── Points de rupture responsive (socle A3) ─────────────────────────
     Les media queries ne peuvent PAS lire une variable CSS : ces trois
     valeurs sont donc écrites littéralement dans les `@media` de la feuille.
     Elles sont consignées ici pour qu'il n'y ait qu'UNE table de référence,
     et elles sont reprises dans DESIGN_SYSTEM.md § 6.
       --bp-sm  600px  téléphone            (une seule colonne, menu replié)
       --bp-md  900px  tablette portrait    (repli du menu du module)
       --bp-lg 1100px  largeur de contenu   (= max-width de <main>)
     N'EN AJOUTEZ PAS D'AUTRES en A4/A5 : trois seuils suffisent, et chaque
     seuil supplémentaire est un état de plus à tester sur chaque page. */
  --bp-sm: 600px;
  --bp-md: 900px;
  --bp-lg: 1100px;

  /* Gouttière latérale fluide : 16 px sur téléphone, 28 px sur grand écran,
     sans palier intermédiaire. Remplace les `padding: 0 28px` codés en dur,
     qui laissaient 28 px de chaque côté sur un écran de 390 px — soit 14 %
     de la largeur perdus. */
  --gutter: clamp(16px, 4vw, 28px);

  /* ── Rayons & ombres (sobres, sans effet décoratif) ──────────────────── */
  --radius: 8px;
  --shadow: 0 1px 3px rgba(0,0,0,.06);

  /* ── Échelle d'espacement (interlignage compact, sections aérées) ────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  color: var(--color-text);
  background: var(--color-bg-soft);
  font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Hiérarchie typographique du Design System : on hiérarchise d'abord par la
   GRAISSE (Regular / SemiBold / Bold), pas par de fortes variations de taille.
   Titres en couleur d'accent (primaire #0A1F3D par défaut ; teinte du module
   courant sur les pages de module — cf. bloc « Teinte par module »). */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  color: var(--color-accent);
  line-height: 1.25;
}
h1 { font-weight: var(--fw-bold); }
h2, h3, h4, h5, h6 { font-weight: var(--fw-semibold); }

/* Les contrôles de formulaire n'héritent PAS de la police par défaut selon les
   navigateurs : on force IBM Plex Sans (sauf les zones de code en monospace,
   stylées localement). Garantit notamment les écrans de création d'audit. */
input, select, textarea, button, optgroup, option {
  font-family: var(--font-body);
}

main { max-width: var(--bp-lg); margin: 28px auto; padding: 0 var(--gutter); }

/* Cards / panels */
.card {
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: 20px;
  margin-bottom: 16px; box-shadow: var(--shadow);
}

h2 {
  font-size: 20px; color: var(--color-accent);
  margin: 32px 0 12px; padding-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
}
h3 { font-size: 16px; margin: 18px 0 8px; }

/* Counters grid */
.counters { display: flex; flex-wrap: wrap; gap: 16px; margin: 18px 0; }
.counter {
  flex: 1 1 130px; background: var(--color-bg);
  border: 1px solid var(--color-border); border-radius: var(--radius);
  padding: 14px 18px; box-shadow: var(--shadow);
}
.counter strong { display: block; font-size: 26px; font-weight: 600; }
.counter .label { color: var(--color-muted); font-size: 13px; margin-top: 2px; }
.counter.ir strong { color: var(--color-ir); }
.counter.amc strong { color: var(--color-amc); }
.counter.gm strong { color: var(--color-gm); }
.counter.app strong { color: var(--color-app); }

/* Forms */
form .row { margin-bottom: 12px; }
form label { display: block; font-weight: 500; margin-bottom: 4px; font-size: 14px; }
form input[type=text], form input[type=number], form select, form textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--color-border);
  border-radius: var(--radius); font-family: inherit; font-size: 14px;
  background: var(--color-bg);
}
form textarea { min-height: 80px; resize: vertical; }
form .actions { display: flex; gap: 10px; margin-top: 16px; }
button, .btn {
  padding: 8px 16px; border: 1px solid var(--color-accent);
  background: var(--color-accent); color: white;
  border-radius: var(--radius); cursor: pointer; font-family: inherit;
  font-size: 14px; text-decoration: none; display: inline-block;
}
button.secondary, .btn.secondary {
  background: white; color: var(--color-accent);
}
button.danger, .btn.danger {
  background: white; color: var(--color-status-ko);
  border-color: var(--color-status-ko);
}

/* Tables */
table.data {
  width: 100%; border-collapse: collapse; background: var(--color-bg);
  border: 1px solid var(--color-border); border-radius: var(--radius);
}
table.data th, table.data td {
  border-bottom: 1px solid var(--color-border);
  padding: 8px 12px; text-align: left; vertical-align: top;
}
table.data th { background: var(--color-bg-soft); font-weight: 600; }
table.data tr:last-child td { border-bottom: none; }

/* EASA tables in body_html */
.easa-table {
  width: 100%; border-collapse: collapse; margin: 10px 0;
  font-size: 14px; background: var(--color-bg);
}
.easa-table td, .easa-table th {
  border: 1px solid var(--color-border); padding: 6px 10px; vertical-align: top;
}
.easa-table th { background: var(--color-bg-soft); font-weight: 600; }

/* Tables larges : défilement horizontal pour ne pas casser la mise en page */
.easa-table-wrap { overflow-x: auto; max-width: 100%; margin: 10px 0; }
.easa-table-wrap .easa-table { width: auto; min-width: 100%; margin: 0; }
.easa-table.compact {
  font-size: 12px;
  table-layout: fixed;     /* largeurs imposées par le colgroup, pas par le contenu */
  width: auto;
}
.easa-table.compact col.col-fstd { width: 200px; }
.easa-table.compact col.col-feat { width: 46px; }
.easa-table.compact td, .easa-table.compact th {
  padding: 3px 4px; text-align: center;
  white-space: normal;     /* "S interim" passe sur 2 lignes au lieu d'élargir */
  word-break: break-word; overflow: hidden;
}
/* Colonne FSTD reference : alignée à gauche + figée au défilement */
.easa-table.compact td.fstd-col, .easa-table.compact th.fstd-col {
  text-align: left;
  position: sticky; left: 0; background: var(--color-bg); z-index: 1;
}
.easa-table.compact th.fstd-col { background: var(--color-bg-soft); }

/* Kind badges */
.kind-badge {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.5px;
  margin-right: 6px; vertical-align: middle;
}
.kind-IR  { background: var(--color-accent-soft); color: var(--color-ir); }
.kind-AMC { background: #d1e7dd; color: var(--color-amc); }
.kind-GM  { background: #fff3cd; color: var(--color-gm); }
.kind-Appendix { background: #ede9fe; color: var(--color-app); }

/* Article view */
.article-header h2 { margin-top: 0; }
.article-meta {
  font-size: 13px; color: var(--color-muted);
  display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 16px;
}
.article-meta span { padding: 2px 8px; background: var(--color-bg-soft); border-radius: 4px; }

.article-body p { margin: 10px 0; }
.related-section { margin-top: 28px; }
.related-section h3 { color: var(--color-accent); }
.related-item {
  padding: 10px 14px; margin-bottom: 6px;
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
/* Retouche du 16 oct. 2026 (Julien) : plus de barre latérale colorée — le
   badge AMC / GM / Appendix dit déjà la nature du lien. */
.related-item .ref { font-weight: 600; }
.related-item .title { color: var(--color-muted); margin-left: 8px; }

/* Search results */
.search-result {
  padding: 12px 16px; margin-bottom: 8px;
  background: var(--color-bg); border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
.search-result .ref { font-weight: 600; color: var(--color-accent); }
.search-result .title { margin-left: 6px; }
.search-result .snippet { color: var(--color-muted); font-size: 13px; margin-top: 4px; }
.search-result mark { background: #fef3c7; padding: 0 2px; }

/* TOC */
.toc-tree { list-style: none; padding-left: 0; }
.toc-tree li { padding: 3px 0; }
.toc-tree summary {
  cursor: pointer; font-weight: 500; padding: 4px 8px;
  border-radius: 4px;
}
.toc-tree summary:hover { background: var(--color-accent-soft); }
.toc-tree details { margin-left: 16px; }
.toc-tree .item-link {
  display: inline-block; padding: 2px 8px; font-size: 14px;
  border-radius: 3px; color: var(--color-text);
}
.toc-tree .item-link:hover { background: var(--color-accent-soft); text-decoration: none; }

/* Enfants AMC/GM/Appendix sous un IR/Appendix parent */
ul.toc-children {
  list-style: none; padding-left: 28px; margin: 2px 0 6px;
  border-left: 2px solid var(--color-accent-soft);
}
ul.toc-children li { padding: 1px 0; }
.toc-tree .child-link { font-size: 13px; padding: 1px 8px; }

.orphans-block { margin-top: 8px; padding-left: 12px; }

/* Status badges */
.status {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 12px; font-weight: 500;
}
.status.compliant      { background: #d1e7dd; color: var(--color-status-ok); }
.status.partial        { background: #fff3cd; color: var(--color-status-warn); }
.status.not_assessed   { background: #e5e7eb; color: var(--color-muted); }
.status.non_compliant  { background: #f8d7da; color: var(--color-status-ko); }

/* Misc */
.muted { color: var(--color-muted); }
.empty-state { text-align: center; padding: 40px 20px; color: var(--color-muted); }
ins { color: var(--color-diff-add); text-decoration: none; }
del { color: var(--color-muted); text-decoration: line-through; }
code { background: var(--color-accent-soft); padding: 1px 5px; border-radius: 3px; font-size: 90%; }

/* Scroll vers une ancre sans être masqué par le header sticky */
.search-result-card, tr.matrix-row { scroll-margin-top: 100px; }
.search-result-card:target {
  animation: flash-result 1.2s ease-out;
  border-color: var(--color-accent) !important;
}
tr.matrix-row:target td {
  animation: flash-row 1.4s ease-out;
}
@keyframes flash-result {
  0%   { background-color: #fff3cd; }
  100% { background-color: #fff; }
}
@keyframes flash-row {
  0%   { background-color: #fff3cd; }
  100% { background-color: transparent; }
}

/* Retouche du 16 oct. 2026 (Julien) : un filet fin tout autour, comme
   `.lm-alert` — plus de barre de 4 px à gauche. */
.flash {
  padding: 10px 16px; margin-bottom: 16px; border-radius: var(--radius);
  border: 1px solid;
}
.flash.success { background: #d1e7dd; border-color: #A7D3BF; }
.flash.error { background: #f8d7da; border-color: #F1B5B5; }
.flash.warn { background: #fff3cd; border-color: #F0D98B; }

/* Diff coloré */
.diff-container { font-family: ui-monospace, "SF Mono", Monaco, Consolas, monospace; font-size: 13px; }
.diff-header {
  background: var(--color-bg-soft); padding: 10px 14px;
  border-bottom: 1px solid var(--color-border);
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
}
.diff-summary { margin-left: auto; }
.diff-body { background: white; }
.diff-line {
  padding: 2px 14px; white-space: pre-wrap; word-wrap: break-word;
}
.diff-line.diff-same { color: var(--color-muted); }
.diff-line.diff-add { background: #f0fdf4; }
.diff-line.diff-add ins { color: var(--color-diff-add); font-weight: 600; text-decoration: none; }
.diff-line.diff-del { background: #fef2f2; }
.diff-line.diff-del del { color: #991b1b; text-decoration: line-through; }

/* Revue d'amendements */
.amendment-card.amendment-accepted { background: #f0fdf4; }
.amendment-card.amendment-rejected { background: #fef2f2; opacity: 0.7; }
.amendment-card.amendment-applied { background: #eef2ff; }
.action-tag {
  display: inline-block; padding: 2px 10px; border-radius: 10px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.5px;
  vertical-align: middle; margin-right: 6px;
}
.action-replace { background: #fff3cd; color: #b45309; }
.action-add { background: #d1fae5; color: #0f5132; }
.action-delete { background: #fee2e2; color: #b91c1c; }
.action-complex { background: #e5e7eb; color: #6b7280; }
pre.text-block {
  background: #f9fafb; border: 1px solid var(--color-border);
  border-radius: 4px; padding: 10px 14px;
  white-space: pre-wrap; word-wrap: break-word; font-size: 13px;
  font-family: ui-monospace, "SF Mono", Monaco, Consolas, monospace;
  max-height: 400px; overflow-y: auto;
}
pre.text-old { background: #fef2f2; border-color: #fca5a5;
              text-decoration: line-through; color: #991b1b; }
pre.text-new { background: #fff7ed; border-color: #fdba74; color: #9a3412; }
pre.text-add { background: #f0fdf4; border-color: #86efac; color: #166534; }
pre.text-strike { background: #fef2f2; border-color: #fca5a5;
                  text-decoration: line-through; color: #991b1b; }

/* Tags de niveau de risque */
.risk-tag {
  display: inline-block; padding: 1px 8px; border-radius: 10px;
  font-size: 11px; font-weight: 600;
}
.risk-low      { background: #d1e7dd; color: #0f5132; }
.risk-medium   { background: #fff3cd; color: #b45309; }
.risk-high     { background: #fed7aa; color: #c2410c; }
.risk-critical { background: #fee2e2; color: #b91c1c; }

/* Bandeau "à revoir" */
.review-banner {
  background: #fff3cd; color: #6c4a00; padding: 12px 16px;
  border: 1px solid #F0D98B;
  border-radius: var(--radius); margin-bottom: 16px;
}
.review-banner a { color: #6c4a00; font-weight: 600; }

/* ─── Module Audit ─────────────────────────────────────────────────────── */
.badge-lock {
  display: inline-block; margin-left: 8px; padding: 2px 10px;
  background: #fef3c7; color: #7a5b00; border: 1px solid #f0c14b;
  border-radius: 10px; font-size: 12px; font-weight: 600; vertical-align: middle;
}

/* En-tête d'audit : titre à gauche, logos à droite */
.audit-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; flex-wrap: wrap; }
.audit-logos { display: flex; gap: 18px; }
.logo-slot { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.logo-slot img { max-width: 120px; max-height: 60px; object-fit: contain; border: 1px solid var(--color-border); border-radius: 4px; padding: 3px; background: #fff; }
.logo-upload { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.logo-upload input[type=file] { font-size: 11px; width: 130px; }

/* Deux colonnes (auditeurs / personnes entendues) */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
@media (max-width: 720px) { .two-col { grid-template-columns: 1fr; } }
ul.people { list-style: none; padding: 0; margin: 0 0 10px; }
ul.people li { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; border-bottom: 1px solid var(--color-bg-soft); font-size: 14px; }
.inline-add { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 8px; }
.inline-add input[type=text] { flex: 1; min-width: 100px; width: auto; }

/* Boutons discrets */
button.tiny, .btn.tiny { padding: 4px 10px; font-size: 12px; }
button.link-danger {
  background: none; border: none; color: var(--color-status-ko);
  cursor: pointer; font-size: 12px; padding: 2px 6px; text-decoration: underline;
  display: inline; width: auto;
}

/* Grille d'infos (audit verrouillé) */
dl.info-grid { display: grid; grid-template-columns: 200px 1fr; gap: 6px 16px; margin: 0; }
dl.info-grid dt { font-weight: 600; color: var(--color-muted); }
dl.info-grid dd { margin: 0; }

/* ─── Constats ─────────────────────────────────────────────────────────── */
.finding { margin-bottom: 18px; border: 1px solid var(--color-border); border-radius: 10px; overflow: hidden; scroll-margin-top: 100px; }
.finding-banner {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: nowrap;
  padding: 9px 16px; color: #fff; border-radius: 10px 10px 0 0;
  /* Couleur du type de constat, passée en donnée : style="--band: #660B0B". */
  background: var(--band, var(--color-primary));
}
.finding-banner .finding-type { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.9; white-space: nowrap; }
.finding-banner .finding-sep { font-size: 10px; opacity: 0.7; }
.finding-banner .finding-num { font-size: 10px; font-weight: 600; opacity: 0.95; font-variant-numeric: tabular-nums; white-space: nowrap; }
.finding-banner .finding-title { font-size: 10px; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.finding-body-wrap { padding: 14px 16px; background: #fff; }
.reg-ref { margin: 0 0 6px; color: var(--color-accent); }
.reg-text { white-space: pre-wrap; background: var(--color-bg-soft); border: 1px solid var(--color-border); border-radius: 6px; padding: 8px 12px; font-size: 13px; margin: 6px 0; }
.amc-gm summary { cursor: pointer; font-size: 13px; color: var(--color-muted); margin: 4px 0; }
.finding-text { white-space: pre-wrap; margin: 10px 0; }
.finding-images { display: flex; gap: 12px; flex-wrap: wrap; margin: 10px 0; }
.finding-images figure { margin: 0; max-width: 220px; text-align: center; }
.finding-images img { max-width: 220px; max-height: 180px; object-fit: contain; border: 1px solid var(--color-border); border-radius: 6px; }
.finding-images figcaption { font-size: 12px; color: var(--color-muted); margin-top: 3px; }
.finding-meta { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 10px 0; font-size: 13px; }
.finding-edit summary { cursor: pointer; color: var(--color-accent); font-size: 13px; font-weight: 500; }

/* Pastilles de statut de constat */
.status-pill { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 12px; font-weight: 600; }
.status-open { background: #e0e7ff; color: #3730a3; }
.status-in_progress { background: #fff3cd; color: #b45309; }
.status-closed { background: #d1e7dd; color: #0f5132; }
.status-overdue { background: #fee2e2; color: #b91c1c; }

/* Pastilles de statut CAP */
.cap-not_started { background: #e5e7eb; color: #374151; }
.cap-in_progress { background: #fff3cd; color: #b45309; }
.cap-completed { background: #d1e7dd; color: #0f5132; }
.cap-overdue { background: #fee2e2; color: #b91c1c; }

/* Bloc CAP affiché sous un constat */
.cap-list { margin: 10px 0 4px; display: flex; flex-direction: column; gap: 10px; }
.cap-item { background: var(--color-accent-soft, #eef2ff); border: 1px solid var(--color-accent); border-radius: 8px; padding: 12px 14px; }
.cap-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.cap-head .cap-label { font-weight: 600; color: var(--color-accent); }
.cap-grid { grid-template-columns: 160px 1fr; }
.cap-actions { margin-top: 10px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.cap-edit summary { cursor: pointer; color: var(--color-accent); font-size: 13px; font-weight: 500; }
.cap-add { border-top: 1px dashed var(--color-border); padding-top: 10px; }
.cap-add > label { font-weight: 600; color: var(--color-accent); }

/* Case à cocher alignée avec son libellé (ex. « CMM effectif ») */
label.checkbox-line { display: flex; align-items: center; gap: 8px; font-weight: 500; margin-bottom: 0; cursor: pointer; }
label.checkbox-line input[type=checkbox] { width: auto; margin: 0; }

/* Recherche réglementaire pour ajout de constat */
.reg-results { margin: 10px 0; max-height: 320px; overflow-y: auto; border: 1px solid var(--color-border); border-radius: 6px; }
.reg-result { padding: 8px 12px; border-bottom: 1px solid var(--color-bg-soft); }
.reg-result-head a { color: var(--color-text); }
.reg-paras { margin-top: 5px; display: flex; gap: 4px; flex-wrap: wrap; }
.para-chip { font-size: 11px; padding: 1px 7px; border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-accent); background: var(--color-bg-soft); }
.para-chip:hover { background: var(--color-accent-soft); text-decoration: none; }
.selection-box { background: var(--color-accent-soft); border: 1px solid var(--color-accent); border-radius: 6px; padding: 10px 14px; margin-bottom: 12px; font-size: 14px; }
#add-finding { scroll-margin-top: 100px; }

/* ─── Suivi transversal des constats / CAP ─────────────────────────────── */
.track-kpis { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.track-kpis .kpi {
  flex: 1; min-width: 110px; text-align: center;
  background: var(--color-bg-soft); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: 12px 10px;
}
.track-kpis .kpi-num { display: block; font-size: 26px; font-weight: 700; line-height: 1.1; color: var(--color-accent); font-variant-numeric: tabular-nums; }
.track-kpis .kpi-lbl { display: block; font-size: 12px; color: var(--color-muted); margin-top: 2px; }
.track-kpis .kpi-alert { background: #fee2e2; border-color: #f5b5b5; }
.track-kpis .kpi-alert .kpi-num { color: var(--color-status-ko); }
.track-kpis .kpi-soon { background: #ffedd5; border-color: #fcc89b; }
.track-kpis .kpi-soon .kpi-num { color: #c2410c; }
/* Indicateurs cliquables : conservent le style .kpi mais deviennent des liens */
.track-kpis a.kpi { text-decoration: none; color: inherit; cursor: pointer;
  transition: box-shadow .12s ease, transform .12s ease, border-color .12s ease; }
.track-kpis a.kpi:hover { box-shadow: 0 2px 10px rgba(0,0,0,.12);
  transform: translateY(-1px); border-color: var(--color-accent); }
.track-kpis a.kpi:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

.track-filters { display: flex; gap: 12px; flex-wrap: wrap; align-items: end; }
.track-filters > div { display: flex; flex-direction: column; min-width: 150px; }
.track-filters label { font-size: 12px; color: var(--color-muted); margin-bottom: 3px; }
.track-filters-actions { flex-direction: row !important; gap: 8px; align-items: center; }

/* Chips de statut (constat + CAP) — réutilise les couleurs existantes */
.status-chip {
  display: inline-block; padding: 2px 9px; border-radius: 10px;
  font-size: 11px; font-weight: 600; margin: 1px 2px; white-space: nowrap;
}
.status-not_started { background: #e5e7eb; color: #374151; }
.status-completed { background: #d1e7dd; color: #0f5132; }
.status-soon { background: #ffedd5; color: #c2410c; }

/* Tableau de suivi */
.track-table td { vertical-align: top; }
.track-table .track-title { font-size: 12px; margin-top: 2px; max-width: 280px; }
.track-table .track-ref { font-size: 11px; margin-top: 1px; }
.ftype-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  margin-right: 6px; vertical-align: middle;
  /* Couleur passée en donnée par le gabarit : style="--dot: #660B0B". */
  background: var(--dot, var(--color-muted));
}

/* Alerte visuelle des retards — « ZONE RÉGLEMENTÉE » (retouche du 16 oct.
   2026, variante A arbitrée par Julien). Plus de barre latérale : la ligne en
   retard est HACHURÉE comme une zone réglementée sur une carte VAC — fin et
   serré, en rouge ; la ligne bientôt due (≤ 5 jours), hachurée large, en
   ambre. Le motif est posé sur la LIGNE (<tr>), pas sur chaque cellule : il la
   traverse ainsi d'un seul tenant. Aucune couleur nouvelle : le rouge et
   l'ambre de la charte, en transparence. Le signal tient en noir et blanc. */
:root {
  --hachure-retard: repeating-linear-gradient(135deg,
      rgba(185, 28, 28, .13) 0 1.5px, transparent 1.5px 7px);
  --hachure-bientot: repeating-linear-gradient(135deg,
      rgba(180, 83, 9, .12) 0 1.5px, transparent 1.5px 12px);
}
.row-overdue { background: var(--hachure-retard), #fff; }
.row-soon { background: var(--hachure-bientot), #fff; }
.row-overdue td, .row-soon td { background: transparent; box-shadow: none; }
.delay-alert { color: var(--color-status-ko); font-weight: 700; white-space: nowrap; }
.delay-soon { color: #c2410c; font-weight: 700; white-space: nowrap; }
.delay-ok { color: var(--color-status-ok); white-space: nowrap; }


/* Titre principal d'un dashboard de module. Depuis U1, plus de couleur de
   module : c'est un titre de page comme un autre (charte § 3). */
.module-dashboard-title {
  color: var(--mod, var(--lm-navy));
  font-size: 22px; font-weight: 700;
  margin: 0 0 6px 0;
  letter-spacing: 0.3px;
  border-bottom: 2px solid var(--mod, var(--lm-navy));
  padding-bottom: 8px;
  display: inline-block;
}

/* Cartes de KPI sobres réutilisables sur les dashboards modules */
.lm-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin: 16px 0 4px;
}
.lm-kpi {
  background: #ffffff;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 14px 16px;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  text-decoration: none; color: inherit;
}
.lm-kpi:hover { text-decoration: none; border-color: var(--lm-navy); }
.lm-kpi .lm-kpi-num {
  font-size: 26px; font-weight: 700; color: var(--lm-ink); line-height: 1.1;
}
.lm-kpi .lm-kpi-lbl {
  font-size: 12px; color: var(--color-muted);
  margin-top: 4px; text-transform: uppercase; letter-spacing: 0.5px;
}
.lm-kpi.is-placeholder .lm-kpi-num { color: #9ca3af; }
.lm-kpi.is-placeholder { border-style: dashed; background: #fafafa; }

/* Bloc « actions rapides » */
.lm-actions {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 12px 0;
}
.lm-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px;
  background: var(--lm-navy);
  color: #ffffff;
  border-radius: 6px;
  font-weight: 600; font-size: 14px;
  text-decoration: none;
  border: 1px solid var(--lm-navy-dark);
  cursor: pointer;
}
.lm-btn:hover { background: var(--lm-navy-dark); text-decoration: none; }
.lm-btn.secondary {
  background: #ffffff; color: var(--lm-ink);
  border-color: var(--color-border);
}
.lm-btn.secondary:hover { background: var(--lm-beige); }

/* Placeholder propre pour sections en cours de développement */
.lm-placeholder {
  background: #fffdf7;
  border: 1px dashed var(--lm-rule);
  border-radius: 8px;
  padding: 28px 24px;
  text-align: center;
  color: var(--color-muted);
}
.lm-placeholder h3 {
  margin: 0 0 8px; color: var(--lm-ink);
}
.lm-placeholder .badge {
  display: inline-block;
  font-size: 11px; text-transform: uppercase; letter-spacing: 1px;
  background: #fde68a; color: #78350f;
  padding: 3px 10px; border-radius: 99px;
  margin-bottom: 14px; font-weight: 700;
}

/* Zone de recherche rapide */
.lm-quick-search {
  display: flex; gap: 8px; flex-wrap: wrap;
  background: #ffffff;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 12px;
  margin: 12px 0;
}
.lm-quick-search input[type=text],
.lm-quick-search select {
  flex: 1 1 180px;
  padding: 8px 10px; font-size: 14px;
  border: 1px solid var(--color-border);
  border-radius: 5px;
  font-family: inherit;
}
.lm-quick-search button {
  padding: 8px 14px; background: var(--lm-navy);
  color: white; border: none; border-radius: 5px; cursor: pointer;
  font-weight: 600;
}


/* ════════════════════════════════════════════════════════════════════════
   MODULE CONTRATS — Identité visuelle (Phase 4)
   Tout est scopé sous `body.mod-contrats` pour ne PAS toucher au Hub,
   au module Audit ni aux autres modules. Couleur module : #660B0B.
   Police : IBM Plex Sans (Regular 400 / SemiBold 600).
   ════════════════════════════════════════════════════════════════════════ */

body.mod-contrats {
  font-family: "IBM Plex Sans", var(--font-body);
}
/* Titres de l'interface contrats en SemiBold. */
body.mod-contrats h1,
body.mod-contrats h2,
body.mod-contrats h3,
body.mod-contrats .module-title,
body.mod-contrats .lm-btn,
body.mod-contrats table.data th {
  font-family: "IBM Plex Sans", var(--font-body);
  font-weight: 600;
}
body.mod-contrats,
body.mod-contrats p,
body.mod-contrats td,
body.mod-contrats input,
body.mod-contrats select,
body.mod-contrats textarea {
  font-weight: 400;
}

/* ── Filtres (liste contrats / modèles) ─────────────────────────────────── */
.mod-contrats .ct-filters {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end;
  margin-top: 14px;
}
.mod-contrats .ct-filter { display: flex; flex-direction: column; gap: 4px; }
.mod-contrats .ct-filter label { font-size: 12px; color: var(--color-muted); font-weight: 600; }
.mod-contrats .ct-filter-grow { flex: 1 1 220px; }
.mod-contrats .ct-filter-grow input { width: 100%; }
.mod-contrats .ct-filter-check { justify-content: flex-end; }
.mod-contrats .ct-filter-check label { font-size: 13px; color: var(--color-text); }
.mod-contrats .ct-filter-actions { flex-direction: row; gap: 8px; }

/* ── En-tête de liste (compteur + bouton créer) ─────────────────────────── */
.mod-contrats .ct-list-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px;
}

/* ── Tableaux contrats ──────────────────────────────────────────────────── */
.mod-contrats .ct-table code { font-size: 12px; color: var(--mod-deep); }
.mod-contrats .ct-row-actions a { margin-right: 10px; white-space: nowrap; }
.mod-contrats .ct-row-inactive { opacity: 0.6; }

/* ── Pastilles de statut / état ─────────────────────────────────────────── */
.mod-contrats .ct-status,
.mod-contrats .ct-pill {
  display: inline-block; padding: 2px 9px; border-radius: 11px;
  font-size: 11.5px; font-weight: 600; line-height: 1.5;
  border: 1px solid var(--mod-soft); background: var(--mod-soft); color: var(--mod-deep);
}
.mod-contrats .ct-status-sent      { background: #fff3cd; border-color: #f0d98b; color: #8a6d00; }
.mod-contrats .ct-status-signed    { background: #d1e7dd; border-color: #a7d3bf; color: #0f5132; }
.mod-contrats .ct-status-refused,
.mod-contrats .ct-status-expired   { background: #f8d7da; border-color: #e7a9af; color: #b91c1c; }
.mod-contrats .ct-status-archived,
.mod-contrats .ct-status-replaced  { background: #e9ecef; border-color: #ced4da; color: #495057; }
.mod-contrats .ct-pill-on       { background: #d1e7dd; border-color: #a7d3bf; color: #0f5132; }
.mod-contrats .ct-pill-off      { background: #e9ecef; border-color: #ced4da; color: #495057; }
.mod-contrats .ct-pill-default  { background: var(--mod-soft); border-color: var(--mod-deep); color: var(--mod-deep); }
.mod-contrats .ct-var {
  display: inline-block; margin: 0 4px 4px 0; padding: 1px 7px;
  background: var(--mod-soft); border-radius: 5px; font-size: 12px; color: var(--mod-deep);
}

/* ── Vue détaillée ──────────────────────────────────────────────────────── */
.mod-contrats .ct-view-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap;
}
.mod-contrats .ct-meta-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mod-contrats .ct-view-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.mod-contrats .ct-locked-note { font-size: 13px; }
.mod-contrats .ct-detail th { width: 200px; }

/* ── Formulaires ────────────────────────────────────────────────────────── */
.mod-contrats .ct-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.mod-contrats .ct-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.mod-contrats .ct-check-row label { font-weight: 400; }
.mod-contrats .req { color: var(--color-status-ko); }
.mod-contrats .ct-body-input {
  font-family: ui-monospace, "SF Mono", Monaco, Consolas, monospace;
  font-size: 13px; line-height: 1.4;
}
@media (max-width: 720px) {
  .mod-contrats .ct-grid-2,
  .mod-contrats .ct-grid-3 { grid-template-columns: 1fr; }
}

/* ════════════════════════════════════════════════════════════════════════
   APERÇU DU CONTRAT — rendu sobre, dense, professionnel.
   Texte courant 9,5 pt · interligne 1,08 · espace après paragraphe 4–5 pt.
   Sous-titres : même taille que le texte courant, en SemiBold.
   Pas de Montserrat ; IBM Plex Sans uniquement.
   ════════════════════════════════════════════════════════════════════════ */
.contract-preview {
  font-family: var(--font-body);
  font-size: 8.5pt;            /* police plus petite (demande Julien) */
  line-height: 1.2;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 22px 26px;
  max-width: 820px;
  /* Mise en page : texte justifié + césure automatique (FR). */
  text-align: justify;
  text-justify: inter-word;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.contract-preview p { margin: 0 0 4.5pt; font-weight: var(--fw-regular); }
.contract-preview h1,
.contract-preview h2,
.contract-preview h3,
.contract-preview h4 {
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  line-height: 1.14;
  color: var(--color-doc);     /* titres colorés : bordeaux du DOCUMENT (charte U1 § 2) */
  border: none;
  margin: 8pt 0 3pt;
  text-align: left;          /* les titres ne sont pas justifiés */
  hyphens: none;
}
/* Les numéros de points « x.y » en gras restent NON colorés (noir). */
.contract-preview p strong,
.contract-preview li strong { color: var(--color-text); }
/* Titre principal du contrat : volontairement contenu (pas de très grand titre). */
.contract-preview h1 { font-size: 11pt; }
.contract-preview h2 { font-size: 10pt; }
.contract-preview h3 { font-size: 9pt; }
/* Sous-titres : même taille que le texte courant, en SemiBold. */
.contract-preview h4 { font-size: 8.5pt; }
.contract-preview ul,
.contract-preview ol { margin: 0 0 4.5pt; padding-left: 20px; }
.contract-preview li { margin: 0 0 2pt; }
.contract-preview table { border-collapse: collapse; width: 100%; margin: 4pt 0 6pt; }
.contract-preview th,
.contract-preview td {
  border: 1px solid var(--color-border);
  padding: 3px 6px;
  font-size: 8.5pt;
  text-align: left;          /* cellules non justifiées */
  hyphens: none;
}

/* ───────────────────────────────────────────────────────────────────────
   Refonte création contrat — étapes, sous-menus, dossier.
   Tous les styles réfèrent les tokens du Design System (--font-*, --color-*,
   --mod*, --space-*, --fw-*) ; aucune couleur ni police codée en dur.
   ─────────────────────────────────────────────────────────────────────── */
body.mod-contrats fieldset.ct-step {
  font-family: var(--font-body);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4);
}
body.mod-contrats fieldset.ct-step > legend {
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  color: var(--mod);
  padding: 0 var(--space-2);
  font-size: 0.98em;
}
body.mod-contrats fieldset.ct-submenu {
  background: var(--mod-soft);
}
body.mod-contrats .ct-warn {
  background: var(--color-bg-soft);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  border-radius: 6px;
  padding: var(--space-2) var(--space-3);
  margin: var(--space-2) 0;
  font-size: 0.92em;
}
body.mod-contrats .ct-mode-help { color: var(--color-muted); margin: var(--space-1) 0 0; }
body.mod-contrats .ct-check {
  display: flex; align-items: center; gap: var(--space-2); font-weight: var(--fw-regular);
}
body.mod-contrats .ct-check input[type="checkbox"] { width: auto; }
body.mod-contrats select.ct-multi { min-height: 120px; }
body.mod-contrats .ct-client-summary { margin-top: var(--space-3); }
body.mod-contrats .ct-dossier-item {
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  margin: 0 0 var(--space-3);
}
body.mod-contrats fieldset.ct-signature { background: var(--mod-soft); }
body.mod-contrats fieldset.ct-signature code {
  font-family: var(--font-body); font-size: 0.78em; color: var(--mod-deep);
}
body.mod-contrats .ct-priority-banner {
  background: var(--mod-soft);
  color: var(--mod-deep);
  border-radius: 6px;
  padding: var(--space-2) var(--space-3);
  font-size: 0.95em;
}
body.mod-contrats .signature-block td { vertical-align: top; }
/* Espace de signature dans le document : zone vide à signer (Yousign, manuscrit…). */
.contract-preview .signature-line,
.contract-body .signature-line {
  border-bottom: 0.6pt solid var(--color-muted, #4B5563);
  min-height: 30px;
  margin-top: 6pt;
}
.contract-preview .signature-space,
.contract-body .signature-space { margin-top: 12pt; }
/* Séparateur visuel cadre ↔ annexe RGPD fusionnée (aperçu web ; saut de page en PDF). */
.contract-preview .annex-page-break {
  border-top: 2px dashed var(--color-border);
  margin: 18pt 0 12pt;
}
.contract-preview .annex-page-break::after {
  content: "— Annexe —";
  display: block;
  text-align: center;
  color: var(--color-muted);
  font-size: 8pt;
  margin-top: 4pt;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SOCLE RESPONSIVE — session A3
   ───────────────────────────────────────────────────────────────────────────
   Ce bloc établit LE MODÈLE que les sessions A4 (Conformité, Audit) et A5
   (Contrats, Organisations) appliqueront aux ~50 gabarits restants.

   Trois seuils, et trois seulement (cf. `:root` en tête de feuille) :
     ≤ 600 px  téléphone           · une colonne, contrôles tactiles
     ≤ 900 px  tablette portrait   · menu du module replié derrière ☰
     ≤ 1100 px largeur de contenu  · gouttière fluide, pas de seuil dédié

   Règle N6 : un gabarit ne doit ni contenir de chaîne française visible, ni
   supposer un écran large. Le script `scripts/check_ui.py` vérifie les deux.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Utilitaires de socle ────────────────────────────────────────────────── */

/* Texte réservé aux lecteurs d'écran. Ne JAMAIS utiliser `display:none` pour
   cela : le contenu disparaîtrait aussi pour les technologies d'assistance. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Rien ne déborde de sa colonne : images, iframes, et surtout les longues
   références réglementaires du type « ORA.ATO.210(a)(1)(ii) » qui, sans
   césure, élargissent leur conteneur et font défiler toute la page. */
img, svg, video, iframe { max-width: 100%; height: auto; }
body { overflow-wrap: break-word; }
/* `break-word` ne coupe pas un mot au milieu si l'espace suffit ailleurs ;
   il n'abîme donc pas la lecture d'un texte normal. */

/* Conteneur de défilement pour tout tableau plus large que son parent.
   C'est LE mécanisme générique du socle : en A4 et A5, tout tableau de données
   s'enveloppe dans <div class="table-wrap">…</div>.
   NB : la stratégie fine pour les tableaux Easy Access Rules à 14 colonnes
   (R4) se tranche en session A4 — voir § 10 du document d'architecture. Ici on
   pose seulement de quoi ne rien casser en attendant. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
  margin: var(--space-3) 0;
  /* Ombres de bord : une ombre apparaît à droite tant qu'il reste du contenu
     à faire défiler, et disparaît en fin de course. Sans elle, un tableau
     coupé au bord de l'écran a l'air tronqué, pas défilable — c'est ce qu'on
     a constaté sur la première capture téléphone.
     Mécanique : deux dégradés « voile » attachés au contenu (`local`) et deux
     ombres attachées au cadre (`scroll`) ; le voile recouvre l'ombre quand on
     est en butée. Aucun JavaScript. */
  background:
    linear-gradient(to right, var(--color-bg) 30%, rgba(255, 255, 255, 0)) left center,
    linear-gradient(to left,  var(--color-bg) 30%, rgba(255, 255, 255, 0)) right center,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .16), rgba(0, 0, 0, 0)) left center,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .16), rgba(0, 0, 0, 0)) right center;
  background-repeat: no-repeat;
  background-size: 36px 100%, 36px 100%, 13px 100%, 13px 100%;
  background-attachment: local, local, scroll, scroll;
}
.table-wrap > table { margin: 0; }

/* ── Première colonne figée au défilement (arbitrage A4) ──────────────────── */
/* R4 (fidélité visuelle aux Easy Access Rules) et R2 (téléphone) sont en
   tension directe : le corpus contient un tableau de 17 colonnes sur 142
   lignes et seize tableaux de 10 colonnes allant jusqu'à 909 lignes. Aucun ne
   tiendra jamais sur 390 px.

   Arbitrage rendu en session A4 : on NE TRANSFORME PAS le tableau — ni fiches
   empilées, ni colonnes masquées. On le fait défiler, et on fige sa première
   colonne, celle qui porte la clé de lecture de la ligne (« 1.1 »,
   « 010 01 01 00 », la référence de l'exigence, le nom de l'audit). Sans elle,
   arrivé à la sixième colonne, on lit une valeur sans savoir de quelle ligne.
   Même règle pour TOUS les tableaux, réglementaires et applicatifs, sans
   exception : un seul comportement à apprendre, un seul état à vérifier.

   Conséquence assumée : la fidélité R4 est intégrale, mais lire une ligne
   entière demande de faire défiler. C'est le compromis retenu. */
.table-wrap table th:first-child:not([colspan]),
.table-wrap table td:first-child:not([colspan]) {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--color-bg);
  /* Sous `border-collapse: collapse`, le trait vertical appartient à la
     cellule voisine : pendant le défilement il passe SOUS la cellule figée et
     la colonne semble flotter. On redessine donc ce trait en ombre portée,
     qui, elle, appartient à la cellule figée et la suit. */
  box-shadow: 1px 0 0 var(--color-border);
}
.table-wrap table th:first-child:not([colspan]) {
  background: var(--color-bg-soft);
  z-index: 3;                /* l'en-tête figé passe au-dessus des cellules */
}
/* `:not([colspan])` : une cellule de titre de section qui couvre toute la
   largeur (« Section 1 — Flight » dans l'Appendix 9) ne doit pas être figée,
   sinon elle glisse au-dessus des colonnes suivantes au lieu de rester en
   place. */

/* Les lignes en retard (rouge) et à échéance proche (orange) posent leur
   repère de couleur en ombre INTERNE sur la première cellule — exactement la
   propriété que la colonne figée utilise pour sa bordure. Sans la règle
   ci-dessous, la plus spécifique écrase l'autre et le repère de retard
   disparaît du suivi des constats. On cumule les deux ombres, et on repose le
   fond de la ligne : une cellule figée doit être opaque, sinon le contenu
   défile visiblement dessous. */
.table-wrap .row-overdue td:first-child:not([colspan]) {
  background: var(--hachure-retard), #fff;
  box-shadow: 1px 0 0 var(--color-border);
}
.table-wrap .row-soon td:first-child:not([colspan]) {
  background: var(--hachure-bientot), #fff;
  box-shadow: 1px 0 0 var(--color-border);
}

/* ── Classes utilitaires des gabarits (A4) ────────────────────────────────── */
/* Le Design System interdit les attributs `style=` en dur (§ 5, règle 5). Les
   mêmes trois déclarations revenaient dans presque tous les gabarits : l'en-tête
   de carte, son titre et sa rangée de boutons. Une classe les remplace partout
   au lieu de cinquante copies — et rend le motif modifiable en un point. */
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.card-title { margin-top: 0; border: none; padding: 0; }
.btn-row { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.inline-form { display: inline; }
.card-flush { padding: 0; overflow: hidden; }

@media (max-width: 600px) {
  /* Même parti qu'en A3 pour `.actions` : sur téléphone, un bouton occupe la
     largeur. Viser un bouton de 90 px au pouce, en haut d'écran, est la
     première cause de faux clics. */
  .btn-row { flex-direction: column; align-items: stretch; width: 100%; }
  .btn-row > .btn,
  .btn-row > button,
  .btn-row > form > button { width: 100%; justify-content: center; }
}

/* ── ≤ 600 px : téléphone ────────────────────────────────────────────────── */
@media (max-width: 600px) {
  main { margin: var(--space-4) auto; }

  /* Sous 16 px, iOS zoome automatiquement sur le champ à la mise au point puis
     laisse la page décalée. On remonte donc les contrôles à 16 px sur
     téléphone — c'est la seule raison de ce réglage, purement défensive. */
  input, select, textarea,
  form input[type=text], form input[type=number], form select, form textarea {
    font-size: 16px;
  }

  /* Cibles tactiles : boutons et liens d'action pleine largeur, hauteur 44 px. */
  button, .btn, .lm-btn {
    min-height: 44px;
    padding: 10px 16px;
  }
  form .actions,
  .lm-actions { flex-direction: column; align-items: stretch; }
  form .actions > *,
  .lm-actions > .lm-btn { width: 100%; justify-content: center; }

  /* Tableaux de données : padding resserré et défilement si nécessaire.
     `display:block` sur le <table> n'est PAS utilisé — il casse l'association
     en-tête/cellule pour les lecteurs d'écran. On fait défiler le conteneur. */
  table.data { font-size: 14px; }
  table.data th, table.data td { padding: 6px 8px; }

  /* Grilles : une seule colonne. */
  .counters { gap: var(--space-3); }
  .counter { flex: 1 1 100%; }
  .lm-kpi-grid { grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .two-col { grid-template-columns: 1fr; }

  /* Titres : la hiérarchie du Design System repose sur la graisse, pas sur la
     taille — on réduit donc peu, juste de quoi éviter les coupures. */
  h1 { font-size: 22px; }
  h2 { font-size: 18px; margin-top: var(--space-5); }
  .module-dashboard-title { font-size: 19px; }

}

/* ── Classes de remplacement des `style=` des gabarits Conformité (A4) ────── */
/* Chacune reprend EXACTEMENT les déclarations de l'attribut qu'elle remplace :
   la traduction et le responsive ne doivent pas changer l'apparence des pages
   au passage, sans quoi la relecture par `git diff` devient impossible. */

/* Formulaire de filtre en ligne (sommaire, comparaison de versions). */
.toc-filter,
.inline-fields {
  display: flex;
  gap: var(--space-3);
  align-items: end;
  flex-wrap: wrap;
}
.toc-filter .row,
.inline-fields .row { margin-bottom: 0; }

.orphans-label { margin: var(--space-2) 0 var(--space-1); }
.details-form { margin-top: var(--space-3); }
.form-section { margin: 18px 0 var(--space-2); }
.hint { font-size: 12px; }
.tag-kind { font-size: 12px; }
.btn-sm { font-size: 12px; }
.inline-details { display: inline-block; }
.intro { margin: var(--space-3) 0 0; }

/* Mini-formulaire d'édition ouvert dans une cellule de tableau. La largeur
   d'origine (`min-width: 300px`) est bornée à celle de l'écran : sur un
   téléphone de 390 px, une largeur minimale fixe déborde (§ 5, règle 2). */
.popover-form {
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--color-bg-soft);
  border-radius: 4px;
  min-width: min(300px, 100%);
}

/* Compteurs colorés du tableau des mises à jour. */
.count-accepted { color: var(--color-status-ok); }
.count-rejected { color: var(--color-status-ko); }
.count-applied  { color: #1e3a8a; }

/* Couple « texte + date » sur une ligne, empilé sur téléphone. */
.field-pair { display: flex; gap: var(--space-3); }
.field-pair > input[type="text"] { flex: 2; }
.field-pair > input[type="date"] { flex: 1; }
@media (max-width: 600px) {
  .field-pair { flex-direction: column; }
}

/* Bloc de présentation d'un règlement (base réglementaire). */
.reg-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: var(--space-3);
  box-shadow: var(--shadow);
}
.reg-code { font-size: 15px; color: var(--lm-ink); }
.reg-title { font-size: 13px; }
.reg-meta { font-size: 12px; margin-top: 2px; }
.reg-count { font-size: 13px; color: var(--color-muted); text-align: right; }
.reg-count-num { color: var(--lm-ink); font-size: 18px; }
.reg-count-detail { font-size: 11px; margin-top: 2px; }
.reg-empty { margin: var(--space-3) 0 0; font-size: 13px; }
/* Deux colonnes d'annexes sur grand écran, une seule sur téléphone : `columns`
   sur 390 px de large donne deux colonnes de 180 px, illisibles. */
.reg-annexes {
  margin: var(--space-3) 0 0;
  padding-left: 18px;
  columns: 2;
  column-gap: var(--space-5);
}
.reg-annexes > li { break-inside: avoid; }
@media (max-width: 600px) {
  .reg-annexes { columns: 1; }
  .reg-count { text-align: left; }
}

/* ── Revue des liens et revue d'amendements (A4) ──────────────────────────── */
/* Boutons d'action colorés : les mêmes trois couleurs revenaient en `style=`
   sur une dizaine de boutons. Vert = décision favorable, bleu = écriture en
   base, rouge = `.danger`, qui existait déjà. */
.btn-ok { background: var(--color-status-ok); border-color: var(--color-status-ok); }
.btn-apply { background: #1e3a8a; border-color: #1e3a8a; }
.btn-block { width: 100%; }
.text-amber { color: var(--color-status-warn); }
.status-pending { color: var(--color-muted); }
.code-para { background: #fff3cd; }
.counter-warn { background: #fff3cd; border-color: var(--color-status-warn); }
.counter-warn strong { color: var(--color-status-warn); }

/* Champ occupant toute la largeur, libellé compact. */
.field-label {
  display: block; font-weight: 500; font-size: 13px; margin-bottom: var(--space-1);
}
.row-block { display: block; }
.label-block { display: block; margin-bottom: 6px; }
.hint-tight { margin: -4px 0 var(--space-3) 0; }

/* Zone de saisie du texte réglementaire : police à chasse fixe, hauteur
   confortable. `min-height` en `vh` plutôt qu'en pixels : 500 px fixes
   occupent tout l'écran d'un téléphone et le formulaire devient impraticable. */
.code-editor {
  width: 100%; box-sizing: border-box; display: block;
  font-family: ui-monospace, "SF Mono", Monaco, Consolas, monospace;
  font-size: 13px; line-height: 1.5; padding: var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius);
  resize: vertical; min-height: min(500px, 60vh);
}

/* Encadré gris des formulaires de décision et des blocs d'historique. */
.panel {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--color-bg-soft);
  border-radius: var(--radius);
}
.panel-line { margin: var(--space-1) 0; }
.panel-actions { margin-top: 6px; }
.panel textarea, .panel select { width: 100%; font-size: 13px; }

/* Deux colonnes côte à côte sur grand écran, empilées sur téléphone. Ces deux
   grilles étaient écrites `grid-template-columns: 1fr 2fr` en dur : sur 390 px,
   la colonne étroite tombait à 110 px et le menu déroulant devenait illisible. */
.decide-grid {
  display: grid; grid-template-columns: 1fr 2fr;
  gap: var(--space-3); margin-bottom: var(--space-3);
}
.split-2 {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 14px; margin-top: 14px;
}
@media (max-width: 900px) {
  .decide-grid, .split-2 { grid-template-columns: 1fr; }
}

/* Fiche de revue d'un lien manuel ↔ article. */
/* Retouche du 16 oct. 2026 (Julien) : plus de barre latérale par décision. */
/* `min-width` borné à la largeur de l'écran (§ 5, règle 2). */
.review-main { flex: 1; min-width: min(280px, 100%); }
.review-chapter { margin: var(--space-1) 0; }
.review-impacted { margin: 6px 0; }
.review-verdict { text-align: right; min-width: min(140px, 100%); }
.review-date { font-size: 11px; }

/* Fiche d'amendement. */
.amend-main { flex: 1; min-width: min(280px, 100%); }
.amend-title { margin: var(--space-1) 0; }
.amend-rationale { font-size: 13px; font-style: italic; margin: 6px 0; }
.amend-actions {
  display: flex; flex-direction: column; gap: var(--space-1);
  min-width: min(170px, 100%);
}
.amend-status { font-size: 11px; text-align: right; }
.amend-section { margin: 14px 0 6px; }
.amend-section-apply { color: #1e3a8a; }
.amend-section-ok { color: var(--color-status-ok); }
.amend-section-ko { color: var(--color-status-ko); }
@media (max-width: 600px) {
  .review-verdict, .amend-status { text-align: left; }
  .amend-actions { width: 100%; }
}

/* ── Matrices, modèles et fiche article (A4) ──────────────────────────────── */
/* Toutes les largeurs fixes sont bornées par `min(…, 100%)` : une largeur de
   200 px dans une cellule tient sur un écran large, pas dans un tableau qui
   défile sur 390 px (Design System § 5, règle 2). */

.link-list { padding-left: 18px; margin: var(--space-2) 0; }
.th-wide { width: 240px; }
.th-path { width: 140px; }
.article-title { margin: 6px 0; }
.tag-external { font-size: 11px; }
.details-spaced { margin-top: var(--space-3); }

/* Ligne « libellé + actions » d'un élément lié (AMC, GM, Appendix). */
.related-row {
  display: flex; justify-content: space-between;
  align-items: center; gap: var(--space-2); flex-wrap: wrap;
}

/* Carte de résultat de recherche dans les écrans matrice et modèle. */
.search-result-card {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  margin-bottom: var(--space-2);
  padding: var(--space-3);
  background: var(--color-bg);
}
.result-line { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.result-title { flex: 1 1 180px; font-size: 13px; }

/* Liste des paragraphes d'un article, indentée par niveau. L'indentation est
   une DONNÉE (le niveau du paragraphe) : elle passe donc par une variable CSS,
   seule forme de `style=` que le Design System tolère (§ 5, règle 5). */
.para-block { margin-top: var(--space-2); }
.para-summary { font-size: 12px; cursor: pointer; }
.para-list {
  margin-top: 6px;
  border-left: 2px solid var(--color-accent-soft);
  padding-left: var(--space-3);
}
.para-form {
  display: flex; align-items: center; gap: var(--space-2);
  padding: 3px 0; font-size: 13px; flex-wrap: wrap;
}
.para-indent { padding-left: var(--indent, 0); }
.para-excerpt { flex: 1 1 160px; }

/* Rangée de champs alignés horizontalement (recherche, ajout en masse). */
.search-row { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }
.search-row > input[type="text"] { flex: 1 1 160px; width: auto; }
@media (max-width: 600px) {
  .search-row { flex-direction: column; align-items: stretch; }
  .search-row > input[type="text"] { flex: 1 1 auto; }
}

/* Cellules de tableau : extrait de texte et colonne d'actions. */
.cell-excerpt { max-width: min(300px, 100%); font-size: 12px; color: #374151; }
.cell-excerpt-narrow { max-width: min(240px, 100%); }
.cell-actions { white-space: nowrap; }
.move-btns { display: inline-flex; flex-direction: column; gap: 2px; }
.move-btns form { margin: 0; }
.btn-tiny { font-size: 10px; padding: 2px 6px; }

/* Champs de saisie des lignes de matrice (hors balise <form>, donc non
   couverts par les règles générales de formulaire). */
.note-field,
.field-means { width: min(200px, 100%); font-size: 12px; }
.field-chapter { width: min(180px, 100%); font-size: 12px; }
.field-extref,
.field-comment { width: min(140px, 100%); font-size: 12px; }
.field-status { font-size: 12px; }

/* Titre de section portant un bouton poussé à droite. */
.matrix-rows-title {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.push-right { margin-left: auto; }
.actions-right { margin-top: 14px; text-align: right; }
/* Confirmation d'enregistrement d'une ligne : posée par une classe et non par
   `element.style`, pour que la couleur reste dans la feuille de style. */
.btn-saved { background: var(--color-status-ok); border-color: var(--color-status-ok); }
@media (max-width: 600px) {
  .push-right { margin-left: 0; }
  .actions-right { text-align: left; }
}

/* ── Module Audit : gabarits traduits en A4 ───────────────────────────────── */
/* Le module Audit est scellé côté code (règles P2 et P3) ; seuls ses gabarits
   changent. Les classes ci-dessous remplacent les 128 attributs `style=` de
   `audit_view.html` — même déclarations, aucune modification d'apparence
   voulue, hormis les largeurs minimales bornées pour le téléphone. */

/* Rangée de champs de formulaire. Les gabarits d'origine écrivaient
   `flex:1;min-width:220px` (ou 200, 180, 160, 140, 120…) sur chaque colonne :
   autant de valeurs arbitraires. Deux classes suffisent — `field` et
   `field-wide` — et la base `min(…, 100%)` garantit qu'aucune colonne
   n'impose une largeur supérieure à l'écran. */
.field-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.field-row > .field { flex: 1 1 min(170px, 100%); }
.field-row > .field-wide { flex: 2 1 min(220px, 100%); }

/* Utilitaires d'espacement — ils remplacent les `style="margin-top:8px"` et
   consorts. Volontairement peu nombreux : au-delà, c'est le Design System
   qu'il faut compléter, pas la liste d'utilitaires qu'il faut allonger. */
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: 14px; }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: var(--space-1); }
.mb-3 { margin-bottom: var(--space-3); }
.pre-wrap { white-space: pre-wrap; }
.text-ko { color: var(--color-status-ko); }
.label-small { font-size: 12px; display: block; }
.subtitle-inline { font-weight: var(--fw-regular); font-size: 14px; }
.subtitle-small { font-weight: var(--fw-regular); font-size: 12px; }
.group-count { font-size: 13px; }
.card-head-baseline { align-items: baseline; }
.audit-block { margin-top: 14px; border-top: 1px solid var(--color-border); padding-top: var(--space-3); }
.no-deadline { margin: 6px 0 0; font-size: 13px; }
.cell-desc { max-width: min(340px, 100%); }
.checkbox-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.field-comment-wide { min-width: min(240px, 100%); }
.flash-locked { background: #fef3c7; color: #7a5b00; border: 1px solid #f0c14b; }

/* Bloc RGPD : rangée d'anonymisation. */
.anonymise-form {
  display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center;
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-3); padding-top: var(--space-3);
}

/* ── Signature du rapport d'audit ─────────────────────────────────────────
   Le pavé de signature utilise les Pointer Events et fonctionne déjà au doigt
   et à l'Apple Pencil : A4 ne touche pas à sa mécanique, seulement à sa mise
   en page et à ses libellés. */
.sig-box { margin: 14px 0; padding: 14px; border: 1px solid var(--color-border); background: #fafafa; }
.sig-step { margin: 0 0 var(--space-2); font-size: 14px; }
.sig-img {
  max-height: 120px; max-width: min(300px, 100%);
  border: 1px solid var(--color-border); border-radius: 6px;
  padding: var(--space-1); background: var(--color-bg);
}
.sig-img-small { max-height: 90px; max-width: min(280px, 100%); }
.sig-current { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-1); }
.sig-cols { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start; }
.sig-col-draw { flex: 1 1 min(360px, 100%); }
.sig-col-file { flex: 1 1 min(260px, 100%); }
.sigpad-frame { position: relative; border: 1px dashed #cbd5e1; border-radius: 6px; background: var(--color-bg); }
.sigpad {
  display: block; width: 100%; height: 200px;
  cursor: crosshair; touch-action: none;     /* indispensable au tracé tactile */
  background: var(--color-bg); border-radius: 6px;
}
.sigpad-hint {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  pointer-events: none; font-size: 13px; text-align: center; width: 90%;
}
.sig-file-note {
  padding: var(--space-2); background: var(--color-bg-soft);
  border: 1px solid var(--color-border); border-radius: 6px; font-size: 13px;
}
.req-star { color: var(--color-status-ko); }
.checkbox-confirm {
  display: flex; gap: var(--space-2); align-items: flex-start;
  cursor: pointer; font-weight: var(--fw-regular);
}
.checkbox-confirm input[type="checkbox"] { width: auto; margin-top: 3px; }
.hash-code {
  display: block; word-break: break-all; font-size: 12px;
  background: var(--color-bg-soft); border: 1px solid var(--color-border);
  border-radius: 6px; padding: var(--space-2); margin-top: var(--space-1);
}

/* Sur téléphone, la grille « libellé / valeur » à colonne fixe de 200 px ne
   laisse plus que 150 px à la valeur : elle passe en une colonne. */
@media (max-width: 600px) {
  dl.info-grid { grid-template-columns: 1fr; gap: 2px 0; }
  dl.info-grid dt { margin-top: var(--space-2); }
  .audit-logos { width: 100%; justify-content: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   A5 — Grands formulaires : sections repliables
   ═══════════════════════════════════════════════════════════════════════════

   Arbitrage de Julien, session A5. Le formulaire de création de contrat
   (12 blocs) et la fiche Organisation (75 champs, 13 sections) mesurent
   respectivement 4 000 et 5 500 px de haut. Le problème n'est pas la largeur
   — ces écrans sont mono-colonne depuis A3 — mais la LONGUEUR : on ne sait
   jamais dans quelle section on se trouve.

   La mécanique retenue est le pendant exact de l'arbitrage A4 sur les
   tableaux. Là, « le tableau défile, sa première colonne reste » ; ici,
   « le formulaire défile, le titre de sa section reste ». Une seule
   métaphore à apprendre pour tout le produit.

   Trois propriétés, et pas une de plus :

   1. `<details>` NATIF, sans JavaScript. Un champ replié demeure dans le DOM
      et part avec le formulaire : aucune route n'est touchée, un seul envoi,
      aucune donnée intermédiaire à gérer.
   2. Les sections sont OUVERTES par défaut (`open` dans le gabarit). Julien
      édite les contrats depuis un Mac ou un iPad : à ces largeurs, un
      formulaire qui s'ouvre replié ferait perdre du temps à chaque fois. Le
      repli est une commodité offerte à l'utilisateur, pas un état imposé.
   3. Sous 900 px, le `<summary>` devient COLLANT. C'est ce qui remplace le
      repli automatique : en défilant sur un téléphone ou sur un iPad en
      portrait, on garde en permanence sous les yeux le titre de la section
      où l'on écrit. Le repli manuel reste disponible pour escamoter ce qui
      est déjà rempli. */

.form-fold {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin-bottom: var(--space-3);
  background: var(--color-bg);
}

/* Le chevron est dessiné par nous : le marqueur natif diffère d'un navigateur
   à l'autre (triangle sur Safari, flèche sur Firefox) et ne se dimensionne
   pas. `list-style: none` le retire sur les navigateurs modernes, le
   pseudo-élément WebKit sur les plus anciens. */
.form-fold > summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  font-weight: var(--fw-semibold);
  color: var(--color-primary);
  list-style: none;
  border-radius: var(--radius);
}
.form-fold > summary::-webkit-details-marker { display: none; }
.form-fold > summary::after {
  content: "▾";
  margin-left: auto;
  font-size: 12px;
  color: var(--color-muted);
}
.form-fold:not([open]) > summary::after { content: "▸"; }
.form-fold > summary:hover { background: var(--color-bg-soft); }

/* Repère de focus visible au clavier : un summary est un contrôle, il doit
   se voir quand on l'atteint par Tab. */
.form-fold > summary:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

.form-fold[open] > summary {
  border-bottom: 1px solid var(--color-border);
  border-radius: var(--radius) var(--radius) 0 0;
}
.form-fold-body { padding: var(--space-3); }

/* Sous-titre d'aide dans le summary — reste lisible sans concurrencer le
   titre, et disparaît sur téléphone où la place manque. */
.form-fold-note { font-weight: var(--fw-regular); font-size: 12px; color: var(--color-muted); }

/* Le titre de section reste visible pendant la saisie. `top: 0` suffit :
   aucun bandeau de l'application n'est collant. Le fond doit être opaque,
   exactement comme une cellule figée de tableau — sans quoi les champs
   défilent visiblement dessous. */
@media (max-width: 900px) {
  .form-fold[open] > summary {
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--color-bg);
    box-shadow: 0 1px 0 var(--color-border);
  }
  .form-fold-note { display: none; }
}

/* ── Cibles tactiles : 44 px à TOUTES les largeurs ────────────────────────
   Le Design System impose 44 px sous 600 px. Or un iPad est tactile à
   1 080 px de large, où cette règle ne s'appliquerait pas, et c'est l'un des
   deux supports principaux du module Contrats. Plutôt qu'une media query sur
   le type de pointeur — un état de plus à vérifier sur chaque page —, on
   dimensionne les contrôles de ces formulaires à 44 px partout. Sur un Mac,
   un champ de 44 px de haut est confortable et non encombrant. */
.form-touch input[type="text"],
.form-touch input[type="date"],
.form-touch input[type="number"],
.form-touch input[type="email"],
.form-touch input[type="password"],
.form-touch select,
.form-touch button,
.form-touch .lm-btn,
.form-touch .btn {
  min-height: 44px;
}
.form-touch input[type="checkbox"],
.form-touch input[type="radio"] { width: 20px; height: 20px; }
/* Une case à cocher seule ne fait que 20 px : c'est son ÉTIQUETTE qui porte
   la cible tactile, puisque cliquer le texte bascule la case. */
.form-touch label > input[type="checkbox"],
.form-touch label > input[type="radio"] { margin-right: var(--space-2); }
.form-touch .row > label:has(> input[type="checkbox"]),
.form-touch .row > label:has(> input[type="radio"]) {
  display: flex; align-items: center; min-height: 44px;
}

/* Rangée d'actions en pied de formulaire : boutons pleine largeur sur
   téléphone, où deux boutons côte à côte tombent sous les 44 px utiles. */
@media (max-width: 600px) {
  .form-touch .actions { flex-direction: column; align-items: stretch; }
  .form-touch .actions > * { width: 100%; text-align: center; }
}

/* Encadré « éléments prévus » des deux pages d'attente (Contrats et
   Organisations). Une classe plutôt que six attributs `style=` répétés à
   l'identique dans deux gabarits. `max-width` et non `width` : sur un
   téléphone de 390 px, une largeur fixe de 520 px déborderait (§ 5, règle 2). */
.placeholder-list {
  max-width: 520px;
  margin: var(--space-4) auto 0;
  text-align: left;
  background: var(--color-bg);
  border: 1px solid var(--lm-rule);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
}
.placeholder-list strong { color: var(--lm-ink); }
.placeholder-list ul { margin: var(--space-2) 0 0; padding-left: 18px; }

/* Liste à puces d'un encadré : remplace `style="padding-left:18px"`. */
.bullet-list { margin: 0; padding-left: 18px; }

/* Aide contextuelle sous un sélecteur (type de modèle documentaire). */
.ct-hint { font-size: 12px; color: var(--color-muted); margin: var(--space-1) 0 0; }

/* Tableau « étiquette / valeur » d'une fiche en lecture (fiche Organisation).
   Remplace les trois attributs `style=` que portait la macro `line()` :
   l'étiquette ne se coupe pas, la valeur respecte les retours à la ligne
   saisis par l'utilisateur. */
.kv-table th {
  text-align: left; white-space: nowrap; vertical-align: top;
  width: min(240px, 40%);
}
.kv-table td { white-space: pre-line; }

/* Cellule d'un tableau qui héberge un mini-formulaire sur toute la largeur
   (registre des documents d'organisation) : remplace
   `style="padding:0 8px 10px"`. */
.cell-form { padding: 0 var(--space-2) var(--space-2); }

/* Liste d'alertes d'une organisation (page de suivi administratif). */
.alert-list { margin: 0 0 var(--space-3); padding-left: 18px; }
.alert-list li { margin: var(--space-1) 0; }
.alert-list li.alert-warn { color: #8a1a12; }

/* Formulaire détaché du contenu qui le précède par un filet. */
.form-divider { border-top: 1px solid var(--color-border); padding-top: var(--space-3); }

/* Champ occupant toute la largeur d'une rangée `.field-row` : zones de texte
   et adresses, qu'il serait absurde de mettre côte à côte avec un code postal. */
.field-row > .field-full { flex: 1 1 100%; }

/* ==========================================================================
   Pastille d'information « i » (ajoutée le 18 septembre 2026)
   --------------------------------------------------------------------------
   Un rond bleu marine portant un « i », placé après le libellé d'un champ qui
   demande une notion à expliquer. L'explication s'affiche au survol ET au
   focus clavier : sur iPad, une pression place le focus, donc l'infobulle
   s'ouvre aussi au toucher. Aucun JavaScript.

   Le texte vit dans l'attribut `data-tip` du gabarit ; `aria-label` porte le
   même contenu pour un lecteur d'écran.

   ⚠️ L'infobulle est ancrée sur le LIBELLÉ (`.lm-label-info`), pas sur la
   pastille : elle occupe la largeur du libellé et ne peut donc jamais
   dépasser du formulaire. Ancrée sur la pastille, elle ajoutait 260 px de
   défilement horizontal à 390 px de large — le symptôme n° 1 d'un responsive
   raté (§ 5 du Design System), et cela même infobulle fermée, car un
   pseudo-élément `visibility: hidden` occupe quand même la place.
   ========================================================================== */
.lm-label-info { position: relative; display: block; }
.lm-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; min-width: 16px;
  margin-left: 6px; vertical-align: middle;
  border-radius: 50%;
  background: var(--color-primary); color: #fff;
  font-size: 11px; font-weight: 600; font-style: normal; line-height: 1;
  cursor: help; user-select: none;
}
.lm-info:focus-visible { outline: 2px solid var(--color-secondary); outline-offset: 2px; }
.lm-info::after {
  content: attr(data-tip);
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 30;
  max-width: 420px;
  padding: var(--space-3);
  background: var(--color-primary); color: #fff;
  border-radius: var(--radius); box-shadow: 0 4px 14px rgba(10, 31, 61, .28);
  font-size: 12px; font-weight: 400; line-height: 1.45; text-align: left;
  white-space: normal;
  opacity: 0; visibility: hidden; transition: opacity .12s ease;
}
.lm-info:hover::after, .lm-info:focus::after { opacity: 1; visibility: visible; }
/* U2 (30 sept. 2026) : la pastille porte elle-même l'ancrage de sa bulle. Avant,
   la bulle se plaçait sous le libellé parent, qui devait porter
   `.lm-label-info` ; désormais une pastille se pose n'importe où (titre,
   <summary>, cellule) sans toucher aux balises voisines. Largeur bornée pour
   tenir dans un écran de téléphone. Ni couleur ni police nouvelles. */
.lm-info { position: relative; text-transform: none; letter-spacing: normal; }
.lm-info::after {
  left: -8px; right: auto; width: min(360px, 72vw);
  text-transform: none; letter-spacing: normal;
}

/* Aperçu d'un PDF importé, avant validation (page de signature, 18/09/2026).
   Hauteur en vh : le document doit se lire sans quitter la page, y compris sur
   un iPad en portrait, où 70 vh laisse la place aux boutons sous l'aperçu. */
.pdf-preview {
  display: block; width: 100%; height: 70vh; min-height: 320px;
  border: 1px solid var(--color-border); border-radius: var(--radius);
  background: var(--color-bg-soft);
}

/* ═══════════════════════════════════════════════════════════════════════════
   AUTHENTIFICATION — session B2, 21 septembre 2026
   ═══════════════════════════════════════════════════════════════════════════ */

/* Les pages de connexion, d'invitation et de mot de passe n'appartiennent à
   aucun module : elles s'affichent seules au milieu de l'écran. La largeur est
   bornée en `ch` plutôt qu'en pixels — un formulaire de deux champs étalé sur
   un écran large se lit mal, et `ch` suit la taille de police du visiteur.
   Pas de largeur fixe : sur téléphone, `width: 100%` gagne (règle N6). */
.auth-card {
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
}

/* ── B4 — droits appliqués (26 septembre 2026) ─────────────────────────────
   `main.lecture-seule` : la page affiche des données que l'utilisateur lit
   sans pouvoir les modifier. On masque les formulaires d'écriture (méthode
   POST) et tout élément marqué `.ecriture-seulement`. C'est un confort
   d'affichage, PAS une protection (règle N4) : chaque route d'écriture refuse
   d'elle-même avec un 403. Les formulaires de recherche et de filtre sont en
   GET : ils restent visibles. */
main.lecture-seule form[method="post"],
main.lecture-seule form[method="POST"],
main.lecture-seule .ecriture-seulement { display: none !important; }
.flash.info { background: #e7f0fa; border-color: var(--lm-navy, #0A1F3D); }

/* ═══════════════════════════════════════════════════════════════════════════
   U1 — CHARTE DE L'INTERFACE (30 septembre 2026) — STYLE « OMODA »
   ═══════════════════════════════════════════════════════════════════════════
   Application de `Docs/37_CHARTE_INTERFACE.md`. Julien a d'abord retenu une
   variante claire (C2, commit f2c9378), puis, le même jour, la variante
   « Omoda » — d'après le site du constructeur automobile qu'il a donné en
   référence : en-tête NOIR, bandeau sombre en dégradé, capitales espacées,
   chiffres en graisse FINE, boutons rectangulaires, tableaux dépouillés à
   lignes alternées. Les classes sont celles de C2 : seul le style a changé.

   Ce bloc est placé EN FIN de feuille à dessein : à spécificité égale, il
   l'emporte sur les règles plus anciennes. Quand une règle ancienne et une
   règle de ce bloc se contredisent, c'est celle-ci qui dit la charte.

   LA POLICE. IBM Plex Sans, toujours — la règle du projet l'impose. Le style
   repose sur sa graisse LIGHT (300), ajoutée pour U1 (`IBMPlexSans-Light.woff2`)
   : sans ce fichier, le navigateur « imite » le fin à partir du Regular, et
   le résultat est pâteux. Les capitales espacées n'habillent que les titres,
   les onglets, les étiquettes et les boutons — JAMAIS les données : un
   tableau de 15 colonnes en capitales ne se lit plus.

   Aucun JavaScript : le menu se replie par un formulaire (mémoire serveur)
   sur grand écran, et par une case à cocher CSS sous 900 px.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --color-accent: #111111;      /* titres et boutons : noir d'encre (style Omoda) */
  --color-ink: #111111;
  --color-link: #111111;
  --color-night: #0B0C10;       /* en-tête et départ du dégradé du bandeau */
  --color-line: #E4E4E7;
  --color-row-alt: #F6F6F7;     /* ligne paire des tableaux */
  --radius: 2px;                /* angles presque droits */
  --caps: 0.14em;               /* espacement des capitales */
  --fw-light: 300;
  /* Anciennes variables du bloc « Hub » (retiré en U1), encore lues par des
     composants conservés (.lm-btn, .lm-quick-search, .placeholder-list…).
     Rétablies en ALIAS vers la charte : sans elles, ces règles perdaient
     silencieusement leur bordure ou leur fond (constaté en U1). */
  --lm-navy: var(--color-ink);
  --lm-navy-dark: var(--color-ink);
  --lm-ink: var(--color-ink);
  --lm-rule: var(--color-line);
  --lm-beige: var(--color-row-alt);
}

/* ── Base ──────────────────────────────────────────────────────────────── */
a { color: var(--color-link); }
a:hover { color: var(--color-brand); }
/* Un lien DANS un texte se souligne : en noir, il se confondrait sinon. */
main p a:not(.btn):not(.lm-btn) {
  text-decoration: underline; text-underline-offset: 3px;
}
:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

h1 {
  font-size: 26px; font-weight: var(--fw-light); color: var(--color-ink);
  text-transform: uppercase; letter-spacing: 0.08em;
}
h2 {
  font-size: 15px; font-weight: var(--fw-medium); color: var(--color-ink);
  text-transform: uppercase; letter-spacing: 0.1em;
  border-bottom-color: var(--color-line);
}
h3 {
  font-size: 13px; font-weight: var(--fw-semibold); color: var(--color-ink);
  text-transform: uppercase; letter-spacing: 0.1em;
}

body.app {
  min-height: 100vh;
  display: flex; flex-direction: column;
  background: #FFFFFF;
}
.icone { display: block; flex-shrink: 0; }
/* Dans un bouton ou un lien de texte, l'icône suit la ligne. */
.btn > .icone { display: inline-block; vertical-align: -3px; margin-right: 6px; }

/* ── En-tête noir (charte § 4) ─────────────────────────────────────────── */
/* Trois zones : marque à gauche, onglets au centre, utilisateur à droite.
   Sous 1 100 px les onglets passent sur une seconde rangée (zones nommées :
   on déplace une zone, on ne réécrit pas le HTML). */
.site-header { background: var(--color-night); color: #FFFFFF; }
.site-header-top {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "brand tabs user";
  align-items: center;
  column-gap: var(--space-4);
  min-height: 72px;
  padding: 0 var(--gutter-wide);
}
.site-brand {
  grid-area: brand; justify-self: start;
  display: flex; align-items: center; gap: 12px;
  text-decoration: none;
}
.site-brand:hover { text-decoration: none; }
.site-brand-symbole { width: 30px; height: auto; display: block; }
.site-brand-texte { display: flex; flex-direction: column; line-height: 1.15; }
.site-brand-nom {
  font-size: 15px; font-weight: var(--fw-medium);
  letter-spacing: 0.32em; color: #FFFFFF;
}
.site-brand-by { font-size: 9px; letter-spacing: 0.32em; color: rgba(255, 255, 255, .55); }

.site-tabs {
  grid-area: tabs;
  display: flex; justify-content: center; align-self: stretch;
}
.site-tabs a {
  display: flex; align-items: center;
  min-height: 72px; padding: 0 16px;
  text-transform: uppercase; letter-spacing: 0.18em;
  font-size: 12px; font-weight: var(--fw-regular);
  color: rgba(255, 255, 255, .62); text-decoration: none; white-space: nowrap;
}
.site-tabs a:hover { color: #FFFFFF; text-decoration: none; }
.site-tabs a.active {
  color: #FFFFFF; font-weight: var(--fw-medium);
  box-shadow: inset 0 -2px 0 var(--color-brand);
}

/* Nom de l'utilisateur, et « Sign out » DESSOUS (point n° 52). */
.site-user {
  grid-area: user; justify-self: end;
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 2px; line-height: 1.3;
}
.site-user-name {
  font-size: 13px; font-weight: var(--fw-medium);
  color: #FFFFFF; text-decoration: none;
}
a.site-user-name:hover { color: #FFFFFF; text-decoration: underline; }
.site-signout { margin: 0; }
.site-signout button {
  background: none; border: none; padding: 0; min-height: 0;
  color: rgba(255, 255, 255, .6); font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.18em;
  cursor: pointer;
}
.site-signout button:hover { color: #FFFFFF; background: none; filter: none; }

/* ── Bandeau sombre sous l'en-tête ─────────────────────────────────────── */
/* Réduit à la demande de Julien : ~110 px sans chiffres, ~190 px avec. */
.page-band {
  background: linear-gradient(120deg, var(--color-night) 0%, #14203A 70%, #1B3358 100%);
  color: #FFFFFF;
  padding: 26px var(--gutter-wide) 28px;
  display: flex; flex-direction: column; gap: 22px;
}
.page-band-sur {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--color-brand);
}
.page-band-titre {
  margin: 4px 0 0;
  font-size: 28px; font-weight: var(--fw-light); line-height: 1.15;
  text-transform: uppercase; letter-spacing: 0.12em; color: #FFFFFF;
  border: none; padding: 0;
}
/* Les chiffres clés des tableaux de bord (`lm-kpi-grid`, déplacée dans le
   bloc `bandeau_chiffres` du gabarit) : graisse fine, séparateurs verticaux. */
.page-band .lm-kpi-grid {
  display: flex; flex-wrap: wrap; gap: 14px 0;
  margin: 0 0 0 calc(-1 * var(--space-5));
}
.page-band .lm-kpi {
  background: none; border: none; box-shadow: none; border-radius: 0;
  padding: 0 var(--space-5);
  border-left: 1px solid rgba(255, 255, 255, .18);
  color: #FFFFFF;
}
.page-band .lm-kpi:first-child { border-left: none; }
.page-band .lm-kpi:hover { border-color: rgba(255, 255, 255, .18); }
.page-band .lm-kpi:hover .lm-kpi-num { color: var(--color-brand); }
.page-band .lm-kpi-num {
  font-size: 30px; font-weight: var(--fw-light); line-height: 1.05;
  color: #FFFFFF; font-variant-numeric: tabular-nums;
}
.page-band .lm-kpi-lbl {
  margin-top: 6px;
  font-size: 10px; letter-spacing: 0.18em; color: rgba(255, 255, 255, .6);
}
/* Correctif U1 (30 sept. 2026, relevé par Julien en U2) : `border-style: solid`
   rendait visibles les quatre bords, en blanc et à l'épaisseur par défaut du
   navigateur (3 px). Seul le filet de gauche doit exister : on éteint les trois
   autres, le filet de gauche restant réglé par `.page-band .lm-kpi`. */
.page-band .lm-kpi.is-placeholder {
  background: none; border-top: none; border-right: none; border-bottom: none;
}
.page-band .lm-kpi.is-placeholder .lm-kpi-num { color: rgba(255, 255, 255, .4); }

/* ── Zone centrale : [menu du module] [contenu] ───────────────────────── */
.page-layout {
  flex: 1 0 auto;
  width: 100%; max-width: 1440px;
  box-sizing: border-box;
  margin: 0 auto;
  padding: 36px var(--gutter-wide) 48px;
  display: flex; gap: 40px; align-items: flex-start;
}
/* <main> prend ce que le menu laisse. `min-width: 0` est indispensable : sans
   lui, un tableau large élargit <main> au lieu de défiler dans `.table-wrap`. */
main { max-width: none; margin: 0; padding: 0; flex: 1 1 auto; min-width: 0; }
.page-layout.sans-menu main { max-width: 1200px; margin: 0 auto; }

/* ── Menu du module, repliable par ☰ (charte § 5) ─────────────────────── */
.module-menu {
  width: 210px; flex-shrink: 0;
  position: sticky; top: var(--space-4);
}
.module-menu-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: var(--space-3);
}
.menu-toggle-form { margin: 0; display: flex; }
/* Le ☰ est SEUL, sans cadre ni fond (demande de Julien, 30 sept. 2026) :
   la zone cliquable garde 40 px, seul le dessin change. */
.menu-burger {
  width: 40px; height: 40px; min-height: 0; padding: 0;
  display: inline-flex; align-items: center; justify-content: flex-start;
  border: none; background: none; color: var(--color-ink);
  cursor: pointer;
}
.menu-burger:hover { background: none; color: var(--color-brand); filter: none; }
.menu-burger-etroit { display: none; }
.module-menu-title {
  font-size: 11px; font-weight: var(--fw-medium);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: #6B7280;
}
.module-menu-links { display: flex; flex-direction: column; }
.module-menu-links a {
  display: flex; align-items: center;
  min-height: 40px; padding: 6px 0 6px 14px;
  color: #6B7280; font-size: 13px; font-weight: var(--fw-regular);
  text-decoration: none;
}
.module-menu-links a:hover { color: var(--color-ink); text-decoration: none; }
.module-menu-links a.active {
  color: var(--color-ink); font-weight: var(--fw-semibold);
}
/* Replié (cookie `ui_menu=closed`) : il ne reste que le ☰. */
.menu-replie .module-menu { width: 40px; }
.menu-replie .module-menu-title,
.menu-replie .module-menu-links { display: none; }

/* Case à cocher du menu déroulant : masquée mais focusable. */
.menu-deroulant {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; margin: 0; pointer-events: none;
}
.menu-deroulant:focus-visible ~ .module-menu-head .menu-burger-etroit {
  outline: 2px solid var(--color-brand); outline-offset: 2px;
}

/* ── Pied de page (charte § 6) ─────────────────────────────────────────── */
.site-footer {
  flex-shrink: 0;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: var(--space-3);
  padding: 14px var(--gutter-wide);
  background: #FFFFFF; border-top: 1px solid var(--color-line);
  font-size: 11px; color: #6B7280;
  text-transform: uppercase; letter-spacing: var(--caps);
}
.site-footer-logo { display: flex; justify-self: start; }
.site-footer-logo img { height: 40px; width: auto; display: block; }
.site-footer-links { display: flex; gap: 28px; }
.site-footer-links a { color: #6B7280; font-size: 11px; text-decoration: none; }
.site-footer-links a:hover { color: var(--color-ink); }
.site-footer-version { justify-self: end; }

/* ── Composants (charte § 7) ───────────────────────────────────────────── */
.card {
  border-color: var(--color-line); border-radius: var(--radius);
  box-shadow: none;
}
/* Boutons : rectangulaires, en capitales. Le principal est noir. La COULEUR
   d'un bouton reste celle de sa classe (variantes vertes et bleues d'A4). */
button, .btn, .lm-btn {
  border-radius: var(--radius);
  padding: 10px 18px;
  font-size: 12px; font-weight: var(--fw-medium);
  text-transform: uppercase; letter-spacing: var(--caps);
}
button:hover, .btn:hover { filter: brightness(1.25); text-decoration: none; }
button.link-danger { text-transform: none; letter-spacing: 0; }
button.link-danger:hover { filter: none; }
button.secondary, .btn.secondary, .lm-btn.secondary {
  background: #FFFFFF; color: var(--color-ink); border-color: var(--color-ink);
}
button.secondary:hover, .btn.secondary:hover, .lm-btn.secondary:hover {
  filter: none; background: var(--color-ink); color: #FFFFFF;
}
button.danger, .btn.danger, .lm-btn.danger {
  background: #FFFFFF; color: var(--color-status-ko); border-color: var(--color-status-ko);
}
button.danger:hover, .btn.danger:hover, .lm-btn.danger:hover {
  filter: none; background: var(--color-status-ko); color: #FFFFFF;
}
button.tiny, .btn.tiny, .btn-sm, .btn-tiny { padding: 6px 12px; font-size: 11px; }
.lm-btn { background: var(--color-ink); border: 1px solid var(--color-ink); color: #FFFFFF; }
.lm-btn:hover { filter: brightness(1.25); color: #FFFFFF; text-decoration: none; }
.lm-kpi { border-radius: var(--radius); box-shadow: none; }
.lm-kpi:hover { border-color: var(--color-ink); }
.lm-kpi-num { font-weight: var(--fw-light); }
.module-dashboard-title {
  display: block; color: var(--color-ink);
  font-size: 22px; font-weight: var(--fw-light);
  border-bottom: none; padding-bottom: 0;
}

/* Champs : cadre fin, angles presque droits ; le focus passe au noir. */
form input[type=text], form input[type=number], form input[type=email],
form input[type=password], form input[type=date], form input[type=search],
form select, form textarea {
  border-color: #D4D4D8; border-radius: var(--radius);
  padding: 8px 12px;
}
form input:focus, form select:focus, form textarea:focus {
  border-color: var(--color-ink); outline: none;
}
form input[type=text], form input[type=number], form input[type=email],
form input[type=password], form input[type=date], form input[type=search],
form select { min-height: 40px; }
/* Les champs e-mail, mot de passe et recherche n'avaient pas de largeur : seuls
   `text` et `number` occupaient la ligne (constaté en U1, page de connexion). */
form input[type=email], form input[type=password], form input[type=search] { width: 100%; }
form label {
  font-size: 11px; font-weight: var(--fw-medium); color: #6B7280;
  text-transform: uppercase; letter-spacing: 0.1em;
}
/* Une case à cocher porte une PHRASE, pas une étiquette : pas de capitales. */
form label.checkbox-inline, form label.checkbox-line, form label.checkbox-confirm,
form .ct-check, form label:has(> input[type=checkbox]), form label:has(> input[type=radio]) {
  font-size: 14px; font-weight: var(--fw-regular); color: var(--color-text);
  text-transform: none; letter-spacing: 0;
}

/* Tableaux : pas de cadre, en-tête en capitales souligné d'un filet noir,
   lignes alternées. Les lignes « en retard » et « bientôt » gardent leur
   couleur : elles sont exclues de l'alternance. */
table.data { border: none; border-radius: 0; background: none; }
table.data th {
  background: none;
  font-size: 11px; font-weight: var(--fw-medium); color: #6B7280;
  text-transform: uppercase; letter-spacing: var(--caps);
  border-bottom: 1px solid var(--color-ink);
  padding: 10px 16px;
}
table.data td { padding: 13px 16px; font-size: 14px; border-bottom: none; }
table.data tbody tr:nth-child(even):not(.row-overdue):not(.row-soon) td { background: var(--color-row-alt); }
.table-wrap table.data tbody tr:nth-child(even):not(.row-overdue):not(.row-soon) td:first-child:not([colspan]) {
  background: var(--color-row-alt);
}
.table-wrap table th:first-child:not([colspan]) { background: #FFFFFF; }

/* Bandeaux : `.flash` (existant) et `.lm-alert` (authentification et
   administration). `.lm-alert` était utilisé depuis B2 SANS AUCUNE règle de
   style — cause du point n° 59. */
.flash { border-radius: var(--radius); }
.flash.info { background: var(--color-accent-soft); border-color: var(--color-brand); }
.flash.notice { display: flex; align-items: center; gap: 10px; }
.lm-alert {
  margin: 0 0 var(--space-3); padding: 10px 14px;
  border: 1px solid; border-radius: var(--radius);
  font-size: 14px;
}
.lm-alert.success { background: #DDEFE5; border-color: #A7D3BF; color: #0F5132; }
.lm-alert.info    { background: var(--color-accent-soft); border-color: #C9DAF6; color: var(--color-ink); }
.lm-alert.warn    { background: #FDF1D8; border-color: #F0D98B; color: #7A4A00; }
.lm-alert.danger  { background: #FBE4E4; border-color: #F1B5B5; color: var(--color-status-ko); }

/* ── Hub (page d'accueil) ─────────────────────────────────────────────── */
.hub-intro { color: #6B7280; margin: 0 0 var(--space-5); }
.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
  gap: 20px;
}
.hub-card {
  display: flex; flex-direction: column; gap: 12px;
  min-height: 180px; padding: 24px;
  background: #FFFFFF;
  border: 1px solid var(--color-line); border-radius: var(--radius);
  color: var(--color-text); text-decoration: none;
  transition: border-color .15s ease;
}
.hub-card:hover { border-color: var(--color-ink); color: var(--color-text); text-decoration: none; }
.hub-card-icon { color: var(--color-ink); }
.hub-card-name {
  font-size: 14px; font-weight: var(--fw-medium); color: var(--color-ink);
  text-transform: uppercase; letter-spacing: var(--caps);
}
.hub-card-tag { flex: 1; font-size: 14px; color: #6B7280; }
.hub-card-status {
  font-size: 10px; text-transform: uppercase; letter-spacing: .16em;
  color: #6B7280;
}
.hub-card.is-placeholder .hub-card-status::before { content: "● "; color: #C98A0B; }
.hub-card.is-active .hub-card-status::before { content: "● "; color: #1F9D55; }
.hub-settings-link { margin: var(--space-5) 0 0; }
.hub-settings-link a { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }

/* ── Pages d'authentification : 1/3 sombre, 2/3 formulaire (charte § 8) ── */
body.auth {
  min-height: 100vh; margin: 0;
  display: flex; background: #FFFFFF;
}
.auth-panel {
  position: relative; overflow: hidden;
  flex: 0 0 33.333%;
  box-sizing: border-box;
  padding: 56px 48px;
  background: linear-gradient(160deg, var(--color-night) 0%, #14203A 75%, #1B3358 100%);
  display: flex; flex-direction: column; justify-content: flex-end;
}
/* Le logo EN TRANSPARENCE (demande de Julien) : la silhouette blanche du
   symbole, très grande et presque effacée, derrière le nom. */
.auth-panel-filigrane {
  position: absolute; left: 50%; top: 42%;
  width: 78%; max-width: 440px; height: auto;
  transform: translate(-50%, -50%);
  opacity: .07; pointer-events: none;
}
.auth-panel-brand { position: relative; display: flex; flex-direction: column; gap: 12px; }
.auth-panel-nom {
  font-size: 34px; font-weight: var(--fw-light);
  letter-spacing: 0.28em; color: #FFFFFF;
}
.auth-panel-by { font-size: 11px; letter-spacing: 0.32em; color: rgba(255, 255, 255, .6); }
.auth-panel-trait { width: 48px; height: 2px; background: var(--color-brand); margin-top: 14px; }
.auth-side { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.auth-main {
  flex: 1 0 auto;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 40px var(--gutter-wide);
}
.auth-main > * { width: 100%; max-width: 420px; }
.auth-main .card { border: none; box-shadow: none; background: none; padding: 0; margin: 0; }
.auth-main h1, .auth-main h2 {
  font-size: 30px; font-weight: var(--fw-light); color: var(--color-ink);
  text-transform: uppercase; letter-spacing: 0.14em;
  border: none; margin: 0 0 var(--space-4);
}
/* Champs soulignés, comme sur la référence : un simple filet noir. */
.auth-main form input[type=text], .auth-main form input[type=email],
.auth-main form input[type=password] {
  min-height: 48px; font-size: 15px; padding: 10px 2px;
  border: none; border-bottom: 1px solid var(--color-ink); border-radius: 0;
  background: transparent;
}
.auth-main form input[aria-invalid="true"] { border-bottom-color: var(--color-status-ko); }
.auth-main form .row { margin-bottom: 18px; }
.auth-main form .actions { flex-direction: column; align-items: stretch; gap: 16px; margin-top: 8px; }
.auth-main form .actions button { min-height: 52px; font-size: 12px; }
.auth-main form .actions .btn { text-align: center; }
.auth-link {
  align-self: center;
  font-size: 11px; font-weight: var(--fw-medium);
  text-transform: uppercase; letter-spacing: var(--caps);
  color: var(--color-ink); text-decoration: none;
  border-bottom: 1px solid var(--color-ink); padding-bottom: 2px;
}
/* Le message d'erreur de connexion : rouge, petit, AU-DESSUS du bouton (n° 59). */
.auth-error {
  display: flex; align-items: center; gap: var(--space-2);
  margin: 0; font-size: 12px; color: var(--color-status-ko);
}
.auth-footer { padding: 14px var(--gutter-wide); }
.auth-footer .site-footer-logo img { height: 40px; width: auto; display: block; }

/* ── Interface client (charte § 9) — posée en U1, ACTIVÉE en U4 ─────────
   `base.html` pose la classe `espace-client` sur <body> pour un compte du
   client (`voit.espace_client`, easa/affichage.py). Aucune couleur hors
   charte : cyan #1CBBD0 sur fond sombre, cyan profond #0B3A40 → #0E7C8A,
   cyan foncé #0E7C8A pour le texte sur blanc, cyan très pâle #E3F4F6
   (accord de Julien du 5 oct. 2026, charte § 2 et § 13). En-tête noir
   (variante A des maquettes) : seuls le bandeau et l'accent changent. */
body.espace-client {
  --color-brand: #1CBBD0;       /* cyan du logo : sur fond sombre, lisible */
  --color-accent-soft: #E3F4F6;
}
body.espace-client .page-band {
  background: linear-gradient(120deg, var(--color-night) 0%, #0B3A40 70%, #0E7C8A 100%);
}
/* Deux logos (R6) : Aviocentra, un filet vertical, puis l'organisation — son
   nom, en attendant son logo (D1). Même zone de grille que la marque. */
.site-brand-client {
  grid-area: brand; justify-self: start;
  margin-left: 232px; padding-left: 20px;
  border-left: 1px solid rgba(255, 255, 255, .28);
  font-size: 12px; letter-spacing: .24em; text-transform: uppercase;
  color: #FFFFFF; white-space: nowrap; line-height: 32px;
  max-width: 320px; overflow: hidden; text-overflow: ellipsis;
}
/* Le nom mène à l'espace « Organisation » ; souligné de cyan quand on y est. */
body.espace-client a.site-user-name.active { box-shadow: inset 0 -2px 0 var(--color-brand); }

/* L'espace « Organisation » (variante A : sans cadres). */
.org-section { padding: 26px 0; border-top: 1px solid var(--color-line); }
.org-section:first-of-type { border-top: none; padding-top: 0; }
.org-section h2 { margin: 0 0 14px; }
.org-titre-ligne { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.org-kv { display: grid; grid-template-columns: 220px 1fr; gap: 8px 24px; margin: 0; }
.org-kv dt { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: #6B7280; }
.org-kv dd { margin: 0; font-size: 14px; white-space: pre-line; }
.org-note { font-size: 13px; color: #6B7280; margin: 12px 0 0; }
.org-note a { color: var(--color-ink); text-decoration: underline; }
.org-actions { display: flex; gap: 12px; align-items: center; margin-top: 18px; }
.org-seats { font-variant-numeric: tabular-nums; }
.org-table td, .org-table th { vertical-align: middle; }
.org-table select { min-height: 0; padding: 4px 8px; font-size: 13px; }
.org-ligne-form { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-top: 18px; }
.org-ligne-form label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: #6B7280;
}
.org-ligne-form input, .org-ligne-form select { min-width: 220px; }
/* La phrase sous le titre de la demande, collée à lui (n° 110 : était un
   `style="margin-top:0"` en dur dans le gabarit). */
.org-demande h2 + .org-note { margin-top: 0; }
.org-demande .org-ligne-form label { flex: 1; }
.org-demande .org-ligne-form input { min-width: 0; width: 100%; }
.form-touch + .org-section { margin-top: 34px; border-top: 1px solid var(--color-line); padding-top: 26px; }
.org-ligne-form :is(.btn, input, select):disabled { opacity: .45; cursor: not-allowed; }
.lien-cyan { color: #0E7C8A; text-decoration: underline; }
.lien-cyan .icone { display: inline-block; vertical-align: -2px; margin-right: 4px; }
.lien-invitation { display: block; margin-top: 8px; word-break: break-all; }
.pastille { display: inline-block; padding: 2px 8px; border-radius: 2px; font-size: 11px; letter-spacing: .08em; }
.pastille.fait { background: #DDEFE5; color: #0F5132; }
.pastille.attente { background: #FDF1D8; color: #7A4A00; }
main .btn-croix { border: none; background: none; color: var(--color-status-ko); padding: 4px; min-height: 0; }
main .btn-lien {
  border: none; background: none; padding: 0; min-height: 0; color: var(--color-ink);
  font-size: 13px; text-decoration: underline; text-underline-offset: 4px; cursor: pointer;
  text-transform: none; letter-spacing: 0;
}
@media (max-width: 700px) {
  .site-brand-client { display: none; }
  .org-kv { grid-template-columns: 1fr; gap: 2px 0; }
  .org-kv dd { margin-bottom: 10px; }
}

/* ── Contact ──────────────────────────────────────────────────────────── */
.contact-form { max-width: 640px; }
.contact-form textarea { min-height: 180px; }

/* ── ≤ 1 100 px : les onglets passent sous la marque ───────────────────── */
@media (max-width: 1100px) {
  .site-header-top {
    grid-template-columns: 1fr auto;
    grid-template-areas: "brand user" "tabs tabs";
    min-height: 0; padding-top: 14px;
  }
  .site-tabs {
    justify-content: flex-start; overflow-x: auto;
    margin: 0 calc(-1 * var(--gutter-wide)); padding: 0 var(--gutter-wide);
  }
  .site-tabs a { min-height: 48px; }
}

/* ── ≤ 900 px : iPad portrait et téléphone ─────────────────────────────── */
@media (max-width: 900px) {
  /* En colonne, `align-items: stretch` est INDISPENSABLE : avec `flex-start`,
     <main> prend la largeur de son contenu au lieu de celle de l'écran, et un
     tableau large fait défiler toute la page — constaté en U1 sur téléphone. */
  .page-layout { flex-direction: column; align-items: stretch; gap: var(--space-4); padding-top: var(--space-5); }
  /* Le ☰ passe AU-DESSUS du titre, et le menu se déroule vers le bas, par-
     dessus le contenu (demande de Julien, maquette C2 iPad). */
  .module-menu,
  .menu-replie .module-menu { width: auto; position: relative; top: auto; z-index: 20; }
  .menu-replie .module-menu-title { display: inline; }
  .menu-toggle-form { display: none; }
  .menu-burger-etroit { display: inline-flex; }
  .module-menu-links,
  .menu-replie .module-menu-links {
    display: none;
    position: absolute; top: 48px; left: 0;
    width: min(320px, 100%); box-sizing: border-box;
    padding: var(--space-2) var(--space-3);
    background: #FFFFFF;
    border: 1px solid var(--color-line); border-radius: var(--radius);
    box-shadow: 0 16px 36px rgba(11, 12, 16, .18);
  }
  .menu-deroulant:checked ~ .module-menu-links { display: flex; }
  .module-menu-links a { min-height: 44px; font-size: 15px; }

  body.auth { flex-direction: column; }
  .auth-panel { flex: none; padding: var(--space-5) var(--gutter); }
  .auth-panel-filigrane { width: 180px; left: auto; right: -30px; top: 50%; transform: translateY(-50%); }
  .auth-panel-nom { font-size: 22px; }
  .auth-panel-trait { display: none; }
  .auth-main .auth-error { justify-content: flex-start; text-align: left; }

  /* Rapport d'audit : la colonne « image de signature » dépassait de 2 px sur
     téléphone. CSS seul : le gabarit d'audit n'est pas touché (P3). */
  .sig-cols > * { min-width: 0; }
  .sig-col-file input[type=file] { max-width: 100%; }
}

/* ── ≤ 600 px : téléphone ─────────────────────────────────────────────── */
@media (max-width: 600px) {
  .site-brand-by { display: none; }
  .site-brand-nom { font-size: 13px; letter-spacing: 0.26em; }
  .site-tabs a { font-size: 11px; padding: 0 12px; }
  .site-signout button { min-height: 32px; }
  .page-band { padding: 20px var(--gutter) 22px; gap: 16px; }
  .page-band-titre { font-size: 21px; }
  .page-band .lm-kpi { padding: 0 var(--space-4); }
  .page-band .lm-kpi-num { font-size: 24px; }
  .site-footer { grid-template-columns: auto 1fr auto; }
  .site-footer-links { justify-content: center; gap: 14px; }
  .page-layout { padding: var(--space-4) var(--gutter) var(--space-6); }
  .module-dashboard-title, h1 { font-size: 20px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   U1b — ICÔNES ET ALLÈGEMENT (2 octobre 2026)
   ═══════════════════════════════════════════════════════════════════════════
   Application de la charte § 7 et § 10 révisés en U1b, sur arbitrages de
   Julien : chaque pictogramme choisi parmi cinq propositions, chaque page
   allégée selon la variante qu'il a retenue sur maquette.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Icônes dans le texte (charte § 10) ───────────────────────────────── */
/* Dans le contenu, une icône suit la ligne de texte qui la porte, à gauche
   de son texte ; `apres` la place à droite (« Review » puis le chevron). */
main .icone { display: inline-block; vertical-align: -3px; }
main :is(a, button, summary, strong, span, label, p, li, h3) > .icone:not(.apres) { margin-right: 6px; }
main .icone.apres { margin: 0 0 0 6px; }
/* Bouton fait d'une icône seule (« × » de suppression, monter, descendre) :
   pas de marge, une cible carrée. Son nom est porté par `aria-label`. */
main .btn-icone { display: inline-flex; align-items: center; justify-content: center; }
main .btn-icone .icone { margin: 0; }
main button.btn-icone:not(.btn-sm):not(.btn-tiny):not(.lm-btn) { padding: 8px; }
main .badge-lock[aria-label] .icone { margin: 0; }
main .badge-lock { display: inline-flex; align-items: center; }
/* Matrice — « enregistrer cette ligne » : le script existant pose
   `btn-saved` 1,2 s après l'enregistrement ; on montre alors la coche. */
.etat-fait { display: none; }
.btn-saved .etat-a-faire { display: none; }
.btn-saved .etat-fait { display: inline; }

/* Sections repliables : le chevron retenu (18 A) remplace ▾ et ▸ — dessiné
   par un masque SVG, en couleur du texte, sans toucher au HTML. */
.form-fold > summary::after {
  content: ""; width: 16px; height: 16px; flex-shrink: 0;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.form-fold:not([open]) > summary::after { content: ""; transform: rotate(-90deg); }

/* ── Allègement (charte § 7) — `data-allegement` posé sur <main> ──────── */
/* Une page déclare sa variante par `{% set allegement = "A" %}` (base.html).
   A · sans cadres : les cartes, les sections de formulaire et les tuiles
       perdent leur boîte ; un filet fin et l'espace séparent les blocs.
   B · A, plus : les actions de ligne deviennent des liens, et un tableau
       « libellé / valeur » se lit libellé AU-DESSUS de la valeur. */
main[data-allegement] .card { border: none; background: none; box-shadow: none; padding: 0; margin: 0 0 36px; }
main[data-allegement] .card + .card { border-top: 1px solid var(--color-line); border-radius: 0; padding-top: 26px; }
main[data-allegement] .lm-quick-search { border: none; padding: 0; background: none; }
/* Tableaux « libellé / valeur » (Change tracking, Latest events…) : ni
   filets ni alternance. Les vrais tableaux de données ne changent pas. */
main[data-allegement] table.data tbody th { border-bottom: none; padding-left: 0; }
main[data-allegement] table.data tbody tr:has(> th) td { background: none; }
/* Tuiles de chiffres restées dans le contenu (alertes d'Assignments) :
   chiffres fins, séparés par des filets, comme dans le bandeau. */
main[data-allegement] .lm-kpi-grid { gap: 0; }
main[data-allegement] .lm-kpi {
  border: none; background: none; box-shadow: none; border-radius: 0;
  border-left: 1px solid var(--color-line); padding: 2px 20px;
}
main[data-allegement] .lm-kpi:first-child { border-left: none; padding-left: 0; }
main[data-allegement] .lm-kpi-num { font-weight: var(--fw-light); }
/* Formulaires : chaque section garde son titre, souligné d'un filet ; les
   champs gardent leur cadre fin (choix de Julien : A, pas les champs soulignés). */
main[data-allegement] :is(fieldset, .form-section, .form-fold, .ct-step) {
  border: none; background: none; box-shadow: none; padding-left: 0; padding-right: 0;
}
main[data-allegement] :is(fieldset, .form-section, .form-fold, .ct-step) + :is(fieldset, .form-section, .form-fold, .ct-step) {
  border-top: 1px solid var(--color-line); border-radius: 0;
}
main[data-allegement] .form-fold > summary { padding-left: 0; padding-right: 0; }
main[data-allegement] legend { padding: 0; }

/* B — actions de ligne en liens ; la suppression, une croix rouge seule. */
main[data-allegement="b"] table.data td :is(a.btn, .lm-btn, button):not(.danger):not(.link-danger),
main[data-allegement="b"] .card-head :is(.btn, .lm-btn).secondary {
  border: none; background: none; color: var(--color-ink);
  padding: 4px 6px; min-height: 0; font-size: 11px;
  text-decoration: underline; text-underline-offset: 4px;
}
main[data-allegement="b"] table.data td :is(button, .btn).danger {
  border: none; background: none; color: var(--color-status-ko); padding: 4px; min-height: 0;
}
main[data-allegement="b"] table.data td form { display: inline; }
main[data-allegement="b"] table.data tbody tr:has(> th) { display: flex; flex-direction: column; padding-bottom: 14px; }
main[data-allegement="b"] table.data tbody tr:has(> th) :is(th, td) { padding: 0; }

/* Hub (A) : plus de boîte autour des modules, un filet au-dessus. */
main[data-allegement] .hub-card {
  border: none; border-top: 1px solid var(--color-line); border-radius: 0;
  padding: 22px 4px 8px; min-height: 0;
}
main[data-allegement] .hub-card:hover { border-top-color: var(--color-ink); }

/* n° 91 : les alertes d'Assignments n'écrivent plus « • » devant chaque
   ligne d'une liste qui a déjà ses puces ; une alerte « warn » porte
   l'icône « attention ». */
.alert-list .icone { color: var(--color-status-ko); }

/* ═══════════════════════════════════════════════════════════════════════════
   B3 — DOUBLE AUTHENTIFICATION (5 octobre 2026)
   ═══════════════════════════════════════════════════════════════════════════
   Les maquettes 1 à 5, retenues telles quelles par Julien. AUCUNE couleur ni
   police nouvelle : filet `--color-line`, gris #6B7280, encre — tous dans la
   charte (§ 2). Pas de police à chasse fixe (la charte n'en a pas) : la clé
   et les codes s'écrivent en IBM Plex Sans, chiffres tabulaires et lettres
   espacées, pour se recopier sans erreur. */
.mfa-sous { font-size: 14px; margin: 0 0 18px; }
.mfa-etapes { list-style: none; margin: 0 0 8px; padding: 0; counter-reset: etape; }
.mfa-etapes > li { counter-increment: etape; padding: 18px 0; border-top: 1px solid var(--color-line); }
.mfa-etapes > li:first-child { border-top: none; padding-top: 4px; }
.mfa-etapes > li > h3::before { content: counter(etape) " · "; color: #6B7280; }
.mfa-qr { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
/* Le SVG de `segno` est exprimé en modules, avec une viewBox : c'est ici que
   se fixe sa taille, et il reste net à toute taille. */
.mfa-qr-image svg { display: block; width: 172px; height: 172px; border: 1px solid var(--color-line); padding: 8px; background: #fff; }
.mfa-cle { font-size: 15px; letter-spacing: .12em; font-variant-numeric: tabular-nums; word-spacing: .3em; margin: 4px 0 0; }
.mfa-legende { font-size: 13px; color: #6B7280; margin: 0; }
/* La règle des pages d'authentification (`.auth-main form input[type=text]`) est
   plus précise : on la nomme aussi, sinon le champ retombe à la taille commune. */
.form-touch input.mfa-code, .auth-main form input.mfa-code { font-size: 22px; letter-spacing: .3em; font-variant-numeric: tabular-nums; max-width: 12ch; }
.form-touch input.mfa-code-secours, .auth-main form input.mfa-code-secours { max-width: 14ch; letter-spacing: .14em; }
.mfa-codes { display: grid; grid-template-columns: repeat(2, max-content); gap: 10px 48px; margin: 18px 0; padding: 18px 22px; border: 1px solid var(--color-line); list-style: none; }
.mfa-codes li { font-size: 16px; letter-spacing: .14em; font-variant-numeric: tabular-nums; }
.mfa-autre { margin-top: 18px; font-size: 13px; }
.mfa-autre a { color: var(--color-ink); text-decoration: underline; text-underline-offset: 4px; }
/* « Sign out » sur la page d'activation : un vrai formulaire POST (la
   déconnexion n'est jamais un lien), habillé comme le lien `.auth-link`. */
.mfa-sortie { display: flex; justify-content: center; margin-top: 8px; }
.auth-card button.auth-link { background: none; border: none; border-bottom: 1px solid var(--color-ink); border-radius: 0; padding: 0 0 2px; min-height: 0; width: auto; cursor: pointer; }
.mfa-gestes { margin-top: 18px; }
.mfa-compte { margin: 10px 0; }
.mfa-historique { margin: 0; padding-left: 18px; font-size: 14px; }
@media (max-width: 600px) {
  .mfa-codes { grid-template-columns: 1fr; }
  .mfa-qr-image svg { width: 150px; height: 150px; }
}
/* Retouche du 7 oct. 2026 : un seul code de secours — une colonne, centré. */
.mfa-codes.mfa-code-unique { grid-template-columns: 1fr; justify-items: center; }
.mfa-codes.mfa-code-unique li { font-size: 20px; }

/* ═══════════════════════════════════════════════════════════════════════════
   B3b — PASSKEYS (9 octobre 2026), maquettes 1A, 4, 5 v2 et 7 retenues par
   Julien. Aucune couleur ni police nouvelle : le gris #6B7280 et le filet
   existants. Le bloc passkey est caché par défaut (attribut `hidden`) et
   montré par passkey.js ; la règle ci-dessous garantit qu'un `hidden` l'emporte
   sur un `display` posé par une autre règle (`.auth-error` est en flex).
   ═══════════════════════════════════════════════════════════════════════════ */
.pk-bloc[hidden], .pk-bloc [hidden], [data-passkey][hidden], [data-passkey-erreur][hidden],
[data-sans-passkey][hidden] { display: none !important; }
/* Retouche du 15 oct. 2026 (Julien) : à la connexion, un carré à l'empreinte à
   droite de « Sign in with password ». L'image est le dessin de Julien, avec son
   propre fond #14203A (couleur du dégradé du panneau, § 2) : le bouton n'a donc
   ni fond, ni bordure, ni marge — il EST l'image. */
.auth-main form .actions .pk-ligne { display: flex; gap: 10px; align-items: stretch; }
.auth-main form .actions .pk-ligne > button.secondary { flex: 1; }
.auth-main form .actions .pk-ligne > button.pk-carre { width: 52px; min-width: 52px; height: 52px;
  min-height: 52px; flex: 0 0 52px; padding: 0; border: 0; border-radius: 0; background: none; cursor: pointer; }
.auth-main form .actions .pk-ligne > button.pk-carre img { display: block; width: 52px; height: 52px; }
.auth-main form .actions .pk-ligne > button.pk-carre:hover { opacity: .85; }
.pk-ou { display: flex; align-items: center; gap: 12px; margin: 22px 0 6px; color: #6B7280;
         font-size: 12px; text-transform: uppercase; letter-spacing: .12em; }
.pk-ou::before, .pk-ou::after { content: ""; flex: 1; border-top: 1px solid var(--color-line); }

/* ═══════════════════════════════════════════════════════════════════════════
   B5 — journal de sécurité (15-16 oct. 2026, maquette 1B). Aucune couleur,
   aucune police : la date et l'heure ne se coupent pas.
   ═══════════════════════════════════════════════════════════════════════════ */
.journal-securite td:first-child { white-space: nowrap; }
/* Sur une page SANS menu de module, <main> reçoit `margin: 0 auto` ; sous
   900 px la mise en page passe en colonne, et une marge automatique y annule
   l'étirement : <main> prend la largeur de son plus large tableau, et la page
   déborde (défaut préexistant, vu aussi sur « Accounts » : point ouvert n° 115).
   Borné à cette page : `width: 100%` rétablit l'étirement. */
main:has(.journal-securite), main:has(.sessions-ouvertes) { width: 100%; }

/* ═══════════════════════════════════════════════════════════════════════════
   B6 — accès d'urgence, carnet des documents (18 oct. 2026) ; B6b — les
   personnes et leurs accès (maquette v3, 18 oct. 2026).
     · l'URGENCE hachurée « zone réglementée » rouge, le PROVISOIRE en ambre
       (les hachures du § 7) ; le NOTAM du client, au même motif ;
     · la boîte de CONFIRMATION par l'attribut HTML `popover` — sans une ligne
       de JavaScript (P1, n° 109) ;
     · B6b : les « strips » de B6 sont parties avec le mandat société.
   Aucune couleur, aucune police nouvelles ; aucune barre latérale.
   ═══════════════════════════════════════════════════════════════════════════ */
.pastille.urgence { background: #FBE4E4; color: #B91C1C; }
/* Le NOTAM — au-dessus du contenu, sur toutes les pages du client_admin. */
.notam { border: 1px solid #D9A0A0; border-radius: var(--radius); background: var(--hachure-retard), #fff;
         padding: 10px 14px; margin: 0 0 16px; display: grid; grid-template-columns: minmax(0, 1fr) auto;
         gap: 10px 18px; align-items: center; }
.notam-titre { display: block; font-size: 11px; font-weight: 600; letter-spacing: var(--caps);
               text-transform: uppercase; color: var(--color-status-ko); margin-bottom: 3px; }
.notam pre { margin: 0; font-family: ui-monospace, "SF Mono", Monaco, Consolas, monospace; font-size: 12.5px;
             line-height: 1.55; color: var(--color-ink); white-space: pre-wrap; overflow-wrap: anywhere; }
/* La boîte de confirmation : attribut `popover`, aucun script. */
[popover].dialogue { border: 1px solid var(--color-ink); border-radius: var(--radius); padding: 20px 22px;
                     max-width: 440px; width: calc(100% - 32px); background: #fff; color: var(--color-ink); }
[popover].dialogue::backdrop { background: rgba(11, 12, 16, .45); }
[popover].dialogue.urgence { background: var(--hachure-retard), #fff; border-color: var(--color-status-ko); }
.dialogue h2 { font-size: 15px; font-weight: 600; margin: 0 0 8px; text-transform: none; letter-spacing: 0; }
.dialogue p { margin: 0 0 14px; }
.dialogue form { display: grid; gap: 12px; }
.dialogue-champ { display: grid; gap: 4px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: #6B7280; }
.dialogue .aide { font-size: 12px; color: #6B7280; margin: 0; }
.dialogue .actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
/* « Deactivate » à la taille du badge « Active » (retouche du 18 oct. 2026). */
main .btn-badge { font-size: 11px; letter-spacing: .08em; padding: 2px 8px; min-height: 0; line-height: 1.4; }
/* Le carnet d'un document. */
.carnet { margin: 0 0 18px; padding-top: 8px; border-top: 1px solid var(--color-line); }
.carnet > summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
                    list-style: none; font-size: 13px; }
.carnet > summary::-webkit-details-marker { display: none; }
.carnet-etiquette { font-size: 11px; letter-spacing: var(--caps); text-transform: uppercase; color: #6B7280; }
.carnet-lien { text-decoration: underline; text-underline-offset: 3px; font-size: 12px; }
.carnet-defile { overflow-x: auto; }
.carnet table { margin-top: 8px; }
.carnet td { vertical-align: top; }
.carnet .carnet-chez { display: block; font-size: 11px; color: #6B7280; }
main:has(.carnet), main:has(.personnes) { width: 100%; }
@media (max-width: 760px) {
  .notam { grid-template-columns: 1fr; }
}
/* Retouche du 18 oct. 2026 — une pastille (i) DANS une boîte de confirmation :
   sa bulle s'ancre sur la boîte (qui est positionnée), pleine largeur sous le
   titre, au lieu de partir vers la droite et d'être rognée par la boîte. */
[popover].dialogue { overflow: visible; }
.dialogue .lm-info { position: static; }
.dialogue .lm-info::after { left: 0; right: 0; width: auto; top: auto; bottom: calc(100% + 6px); }

/* ═══════════════════════════════════════════════════════════════════════════
   B6b — LES PERSONNES ET LEURS ACCÈS (18 oct. 2026, maquette v3 arbitrée).
   Demandes de Julien : « plus SaaS, moins logiciel technique » —
     · titres et boutons en CASSE DE PHRASE (« Add a person », « Send ») ; les
       capitales restent aux petites étiquettes (en-têtes de tableau, WORKSPACE,
       PERMISSIONS). Pour B6 SEULEMENT : `.personnes` et `.invitation` bornent
       l'exception (charte § 13, ligne du 18 oct. 2026) ;
     · plus de chasse fixe pour les accès : des pastilles « Matrices · Write » ;
     · des tableaux PLUS BAS « d'un tiers au moins » : une ligne par personne,
       cellules de 4 px (58 → 30 px mesurés sur la maquette).
   Aucune couleur ni police nouvelle.
   ═══════════════════════════════════════════════════════════════════════════ */
.personnes { display: grid; gap: 28px; }
.personnes > section, .personnes-deux > *, .personnes-deux > div > section { min-width: 0; }
.personnes h2, .dialogue.personnes h2 {
  text-transform: none; letter-spacing: 0; font-size: 16px; font-weight: var(--fw-semibold);
  color: var(--color-ink); margin: 0 0 4px; border: none; padding: 0;
}
.personnes .compte { color: #6B7280; font-weight: var(--fw-regular); }
.personnes .sous-titre { margin: 0 0 12px; color: #6B7280; font-size: 13px; }
.personnes-tete { display: flex; justify-content: space-between; align-items: flex-end;
                  gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.personnes-tete .sous-titre { margin: 0; }
.personnes .btn, .personnes button.btn, .personnes button.secondary,
.invitation button, .invitation .btn {
  text-transform: none; letter-spacing: 0; font-size: 13px; font-weight: var(--fw-medium);
}
.personnes .btn-sm { padding: 6px 12px; }
.personnes-deux { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
                  gap: 28px; align-items: start; }
.personnes-deux > div { display: grid; gap: 28px; }

/* Tableaux compacts */
.personnes table.data.compacte th { padding: 4px 10px; font-size: 10.5px; letter-spacing: .08em; }
.personnes table.data.compacte td { padding: 4px 10px; font-size: 13px; line-height: 1.35;
                                    vertical-align: middle; }
.personnes table.data.compacte td.nom { font-weight: var(--fw-semibold); color: var(--color-ink); white-space: nowrap; }
.personnes table.data.compacte td.date { font-variant-numeric: tabular-nums; white-space: nowrap; }
.personnes table.data.compacte td.droite { text-align: right; white-space: nowrap; }
.personnes table.data.compacte select { font-size: 12.5px; padding: 1px 4px; min-height: 0;
                                        border: 1px solid #D4D4D8; border-radius: var(--radius); }
.personnes table.data.compacte .pastille { font-size: 10.5px; padding: 0 6px; line-height: 16px; }
.personnes .inline-form { display: inline; }

/* Les accès, en mots */
.perms { display: inline-flex; flex-wrap: nowrap; gap: 4px; }
.perm { display: inline-flex; gap: 5px; align-items: baseline; border: 1px solid var(--color-line);
        border-radius: var(--radius); background: #FFFFFF; padding: 0 6px; font-size: 12px;
        line-height: 18px; color: var(--color-text); white-space: nowrap; }
.perm em { font-style: normal; color: #6B7280; font-size: 11.5px; }
.perm.w em { color: var(--color-ink); font-weight: var(--fw-semibold); }
.perm.tout { border-color: #D9A0A0; color: var(--color-status-ko); }
button.perms-bouton { background: none; border: 0; padding: 0; min-height: 0; cursor: pointer;
                      text-transform: none; letter-spacing: 0; }
button.perms-bouton:hover { filter: none; }
button.perms-bouton:hover .perm { border-color: var(--color-ink); }

/* Un bouton qui se lit comme un lien : Remove, Resend, Cancel, End access, Extend */
button.lien-btn { background: none; border: 0; padding: 0; min-height: 0; font-size: 12.5px;
                  font-weight: var(--fw-regular); color: #6B7280; text-transform: none; letter-spacing: 0;
                  text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
button.lien-btn:hover { filter: none; color: var(--color-ink); }
button.lien-btn.ko { color: var(--color-status-ko); }
button.lien-btn + .inline-form, .inline-form + .inline-form, .inline-form + button.lien-btn { margin-left: 10px; }

/* La grille None / Read / Write — des boutons radio, aucun script */
.grille { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 18px; align-items: center; }
.grille-nom { font-size: 14px; color: var(--color-text); text-transform: none; letter-spacing: 0; }
.seg { display: inline-flex; border: 1px solid #C9CCD3; border-radius: var(--radius); overflow: hidden; width: max-content; }
.seg label { display: block; position: relative; cursor: pointer; margin: 0; }
.seg input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.seg span { display: block; min-width: 58px; padding: 4px 12px; text-align: center; font-size: 12.5px;
            font-weight: var(--fw-medium); color: #374151; border-left: 1px solid var(--color-line);
            text-transform: none; letter-spacing: 0; }
.seg label:first-child span { border-left: 0; }
.seg input:checked + span { background: var(--color-ink); color: #FFFFFF; }
.seg input:focus-visible + span { outline: 2px solid var(--color-brand); outline-offset: -2px; }
.seg .seg-off { cursor: not-allowed; }
.seg .seg-off span { color: #9CA3AF; }
.seg .seg-off input:checked + span { background: #6B7280; color: #FFFFFF; }

/* Les formulaires : « Add a person », « Assign someone », la boîte « Edit access » */
.ajout { display: grid; gap: 16px; max-width: 720px; border: 1px solid var(--color-line);
         border-radius: var(--radius); padding: 18px 20px; }
.ajout-ligne { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 14px; align-items: end; }
.ajout-ligne.trois { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
form.ajout-ligne { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; }
.personnes .champ, .dialogue.personnes .champ { display: grid; gap: 5px; min-width: 0;
  font-size: 13px; font-weight: var(--fw-medium); color: var(--color-ink);
  text-transform: none; letter-spacing: 0; }
.personnes .champ.etroit { max-width: 260px; }
.personnes .champ input:not([type=radio]), .personnes .champ select { width: 100%; min-width: 0; }
.personnes .aide { font-size: 12px; font-weight: var(--fw-regular); color: #6B7280; }
.personnes .actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; margin: 0; }
.personnes details.exterieur > summary { cursor: pointer; font-size: 13px; color: #6B7280; }
.personnes details.exterieur[open] > summary { margin-bottom: 10px; }
.dialogue.personnes form { display: grid; }

@media (max-width: 760px) {
  .ajout { padding: 14px; }
  .ajout-ligne, .ajout-ligne.trois, form.ajout-ligne { grid-template-columns: 1fr; }
  .grille { grid-template-columns: 1fr; gap: 4px; }
  .grille .seg { margin-bottom: 8px; }
}

/* L'invitation (« You've been invited », « Join workspace ») */
.invitation h1 { text-transform: none; letter-spacing: 0; font-size: 26px;
                 font-weight: var(--fw-medium); margin: 0 0 6px; }
.invitation .sous { margin: 0 0 18px; color: #6B7280; }
.invitation .recap { border: 1px solid var(--color-line); border-radius: var(--radius);
                     padding: 2px 16px; margin: 0 0 22px; }
.invitation .recap > div { display: grid; gap: 4px; padding: 12px 0; border-bottom: 1px solid var(--color-line); }
.invitation .recap > div:last-child { border-bottom: 0; }
.invitation .recap dt { font-size: 11px; letter-spacing: var(--caps); text-transform: uppercase; color: #6B7280; }
.invitation .recap dd { margin: 0; }
.invitation .recap .ws { font-weight: var(--fw-semibold); color: var(--color-ink); font-size: 15px; }
.invitation .liste-perms { display: grid; gap: 3px; }
.invitation .liste-perms span { display: flex; justify-content: space-between; gap: 12px; }
.invitation .liste-perms em { font-style: normal; color: #6B7280; }
.invitation .connecte { display: flex; gap: 10px; align-items: center; font-size: 13px; color: #374151; margin: 0 0 16px; }
.invitation .avatar { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
                      background: #ECEEF1; font-weight: var(--fw-semibold); font-size: 11px; color: var(--color-ink); }
.invitation .deux-champs { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.auth-main .invitation form label { text-transform: none; letter-spacing: 0; font-size: 13px;
                                    font-weight: var(--fw-medium); color: var(--color-ink); }
.auth-main .invitation form.actions { display: flex; flex-direction: column; align-items: stretch; margin-top: 12px; }
.auth-main .invitation .actions button, .auth-main .invitation .actions .btn { min-height: 48px; font-size: 13px; text-align: center; }
@media (max-width: 600px) { .invitation .deux-champs { grid-template-columns: 1fr; } }
/* Une boîte `popover` FERMÉE reste cachée, quelle que soit la classe qui lui
   donne sa mise en page (`.personnes` est une grille) : sans cette règle, la
   classe l'emporte sur la feuille du navigateur et la boîte s'affiche. */
[popover].dialogue:not(:popover-open) { display: none; }

/* B6b, retouche du 18 oct. 2026 (Julien, scénario ㊴ sous Safari : « une page
   tout en hauteur ») — UNE PETITE BOÎTE, CENTRÉE, QUEL QUE SOIT LE NAVIGATEUR.
   La feuille du navigateur place une boîte `popover` par `inset: 0` et une
   hauteur `fit-content` ; si cette hauteur n'est pas tenue, la boîte s'étire
   du haut au bas de l'écran. On ne s'en remet plus à elle : la boîte est
   posée au centre, à sa hauteur naturelle, et défile si l'écran est trop bas.
   Ouverte, elle est un simple bloc (pas la grille de `.personnes`). */
[popover].dialogue:popover-open {
  display: block; position: fixed; inset: auto; top: 50%; left: 50%;
  transform: translate(-50%, -50%); margin: 0;
  height: auto; max-height: calc(100vh - 32px); overflow-y: auto;
}
.dialogue.personnes { max-width: 400px; padding: 18px 20px; }
.dialogue.personnes h2 { font-size: 15px; margin: 0 0 2px; }
.dialogue.personnes .sous-titre { margin: 0 0 12px; font-size: 12.5px; }
.dialogue.personnes form { gap: 12px; }
.dialogue.personnes .grille { gap: 6px 14px; }
.dialogue.personnes .grille-nom { font-size: 13px; }
.dialogue.personnes .seg span { min-width: 50px; padding: 3px 10px; font-size: 12px; }
.dialogue.personnes .champ input { min-height: 34px; padding: 5px 8px; font-size: 13px; }
.dialogue.personnes .actions { margin-top: 2px; }
.dialogue.personnes .actions .btn { min-height: 0; padding: 6px 14px; }
/* Un navigateur qui ne connaît pas `popover` (Safari avant 17) montrerait
   toutes les boîtes dans la page : on les cache. Les gestes restent sans boîte
   sur ce navigateur — à mettre à jour plutôt qu'à contourner par un script. */
@supports not selector(:popover-open) { [popover] { display: none; } }
/* B6b — la page Maintenance : le nombre de liens cassés, en rouge. */
.personnes td.casse { color: var(--color-status-ko); font-weight: var(--fw-semibold); }

/* ═══════════════════════════════════════════════════════════════════════════
   B7 — POUR LE COMPTE DE QUI L'ON AGIT (R52, 18 oct. 2026)
   Planche « B7 — sélecteur et portefeuille », arbitrée par Julien. Aucune
   couleur, police ni icône nouvelles (`descendre`, `valider`, `engrenage`
   existent) ; aucune barre latérale ; aucun JavaScript (P1) : le menu est un
   <details>, la boîte de confirmation un `popover` (§ 7).
   ═══════════════════════════════════════════════════════════════════════ */

/* Le bandeau de LM : « Acting for », le nom du client et son ▾. Le menu
   s'ancre sur la ligne du surtitre (et non sur le bouton) : sur téléphone, il
   part du bord gauche et ne déborde pas. */
.bascule-sur { position: relative; display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; }
.bascule > summary {
  list-style: none; display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .32); border-radius: var(--radius);
  padding: 4px 8px 4px 10px; min-height: 28px;
  color: #FFFFFF; font-size: 12px; font-weight: var(--fw-medium);
  letter-spacing: .16em; text-transform: uppercase;
}
.bascule > summary::-webkit-details-marker { display: none; }
.bascule > summary:hover, .bascule[open] > summary { border-color: #FFFFFF; background: rgba(255, 255, 255, .08); }
.bascule[open] > summary .icone { transform: rotate(180deg); }
.bascule-seule { color: #FFFFFF; font-size: 12px; font-weight: var(--fw-medium); letter-spacing: .16em; }
/* L'owner chez un client sans désignation : il lit, il n'écrit pas — dit en mots. */
.bascule-lecture {
  border: 1px solid rgba(255, 255, 255, .55); border-radius: var(--radius);
  padding: 2px 8px; color: #FFFFFF; font-size: 10px; letter-spacing: .16em;
}

/* La liste : une petite boîte blanche, filet noir (comme les boîtes de B6). */
.bascule-menu, .menu-nom-liste {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0;
  display: flex; flex-direction: column;
  width: 340px; max-width: calc(100vw - 2 * var(--gutter-wide));
  max-height: 60vh; overflow-y: auto;
  background: #FFFFFF; border: 1px solid var(--color-ink); border-radius: var(--radius);
  padding: 6px 0; color: var(--color-ink);
  font-size: 14px; text-transform: none; letter-spacing: 0; text-align: left; line-height: 1.3;
}
.bascule-titre { padding: 4px 12px 6px; font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: #6B7280; }
.bascule-filet { display: block; height: 1px; background: var(--color-line); margin: 6px 0; }
.bascule-entree {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%; min-height: 36px; box-sizing: border-box;
  background: none; border: 0; border-radius: 0; padding: 6px 12px;
  font: inherit; font-size: 14px; font-weight: var(--fw-regular);
  color: var(--color-ink); text-align: left; text-transform: none; letter-spacing: 0;
  text-decoration: none; cursor: pointer;
}
button.bascule-entree:hover, a.bascule-entree:hover {
  background: var(--color-row-alt); color: var(--color-ink); filter: none; text-decoration: none;
}
.bascule-entree.courante { background: var(--color-row-alt); cursor: default; }
.bascule-entree strong { font-weight: var(--fw-medium); }
.bascule-nom-entree { display: inline-flex; align-items: center; gap: 8px; }
button.bascule-entree .bascule-nom-entree { padding-left: 22px; }
a.bascule-entree { justify-content: flex-start; gap: 10px; }
.bascule-detail { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: #6B7280; white-space: nowrap; }
/* Les organisations « à part » de l'owner : repliées, il faut les ouvrir. */
.bascule-autres > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
  min-height: 32px; padding: 4px 12px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: #6B7280;
}
.bascule-autres > summary::-webkit-details-marker { display: none; }
.bascule-autres > summary::before {
  content: ""; width: 5px; height: 5px; margin: 0 4px 0 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
}
.bascule-autres[open] > summary::before { transform: rotate(45deg); }
.bascule-autres .bascule-nom-entree { color: #6B7280; }

/* Le client à plusieurs organisations : son nom ouvre le menu (« Settings »,
   puis ses organisations et son rôle). Le menu s'ouvre vers la gauche. */
.menu-nom { position: relative; }
.menu-nom > summary { list-style: none; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.menu-nom > summary::-webkit-details-marker { display: none; }
.menu-nom > summary:hover { text-decoration: underline; }
.menu-nom[open] > summary .icone { transform: rotate(180deg); }
.menu-nom-liste { left: auto; right: 0; top: calc(100% + 10px); width: 300px; max-width: calc(100vw - 32px); }
.espace-client .menu-nom-liste .courante .icone { color: #0E7C8A; }

/* La page de choix, à la connexion : des tuiles (initiales, nom, rôle). */
.auth-main > .choix-org { max-width: 720px; }
.choix-org { display: flex; flex-direction: column; align-items: center; gap: 24px; text-align: center; }
.choix-org h1 { margin: 0; }
.choix-org-qui { margin: -14px 0 0; font-size: 14px; color: #6B7280; }
.choix-org-tuiles { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin: 0; }
.choix-org-tuile {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  width: 200px; min-height: 0; box-sizing: border-box;
  background: #FFFFFF; border: 1px solid var(--color-line); border-radius: var(--radius);
  padding: 22px 16px 18px; color: var(--color-ink);
  font: inherit; text-transform: none; letter-spacing: 0; cursor: pointer;
}
.choix-org-tuile:hover, .choix-org-tuile:focus-visible { border-color: var(--color-ink); background: #FFFFFF; color: var(--color-ink); filter: none; }
.choix-org-mono {
  display: flex; align-items: center; justify-content: center; width: 88px; height: 88px;
  background: var(--color-row-alt); border: 1px solid var(--color-line); border-radius: var(--radius);
  font-size: 30px; font-weight: var(--fw-light); letter-spacing: .08em;
}
.choix-org-nom { font-size: 15px; font-weight: var(--fw-medium); line-height: 1.3; }
.choix-org-role { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #6B7280; }
.choix-org-sortie { margin: 0; }
@media (max-width: 600px) {
  .choix-org-tuile { width: 100%; flex-direction: row; align-items: center; gap: 14px; padding: 12px; text-align: left; }
  .choix-org-mono { width: 56px; height: 56px; font-size: 20px; flex: none; }
  .choix-org-role { margin-left: auto; }
}

/* Le portefeuille : tableaux compacts (mêmes mesures que B6b), hachures § 7. */
main:has(.portefeuille) { width: 100%; }
.portefeuille { display: grid; grid-template-columns: minmax(0, 1fr); gap: 30px; }
.portefeuille > section { min-width: 0; }
.portefeuille h2 { margin: 0 0 10px; }
.portefeuille table.data.compacte th { padding: 4px 10px; font-size: 10.5px; letter-spacing: .08em; white-space: nowrap; }
.portefeuille table.data.compacte td { padding: 4px 10px; font-size: 13px; line-height: 1.35; vertical-align: middle; }
.portefeuille td.nom { font-weight: var(--fw-semibold); color: var(--color-ink); white-space: nowrap; }
.portefeuille .droite { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.portefeuille td.date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.portefeuille-autres { margin-top: 12px; border-top: 1px solid var(--color-line); padding-top: 10px; }
.portefeuille-autres > summary { cursor: pointer; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: #6B7280; }
.portefeuille-autres table { margin-top: 8px; }
/* « Sign out » de la page de choix : un lien, hors d'un bloc `.actions` (où la
   règle des boutons d'authentification ne l'atteint pas). */
.choix-org-sortie button.auth-link {
  background: none; border: 0; border-bottom: 1px solid var(--color-ink); border-radius: 0;
  min-height: 0; padding: 0 0 2px; color: var(--color-ink);
}
.choix-org-sortie button.auth-link:hover { background: none; filter: none; color: var(--color-ink); }
/* B7 (remarque de Julien du 18 oct. 2026) — dans une rangée de filtres, le
   bouton « Filter » s'aligne sur les CHAMPS, pas sur leurs libellés : son bloc
   descend en bas de la rangée, et le bouton prend la hauteur d'un champ.
   Audit list et Security log ; aucun gabarit touché (P3). */
.field-row > div:has(> button[type=submit]:only-child) { align-self: flex-end; }
.field-row > div:has(> button[type=submit]:only-child) > button { min-height: 40px; }

/* B7 (remarque de Julien du 18 oct. 2026) — LA PAGE DE REFUS NE MONTRE RIEN.
   Elle renvoie aussitôt à la page précédente (en-tête `Refresh`, balise
   `refresh`) ; tant qu'elle part, elle reste blanche et invisible — le
   navigateur garde donc à l'écran la page d'où l'on venait. Si la redirection
   n'a pas lieu (un navigateur qui l'ignore), le refus et son lien de retour
   apparaissent au bout de deux secondes. Aucun script (P1). */
body.refus { margin: 0; background: #FFFFFF; font-family: var(--font-body); color: var(--color-text); }
.refus-cadre { max-width: 520px; margin: 18vh auto 0; padding: 0 var(--gutter); }
.refus-cadre p { margin: 0 0 14px; }
.refus-en-partance .refus-cadre { opacity: 0; animation: refus-apparait 0s 2s forwards; }
@keyframes refus-apparait { to { opacity: 1; } }

/* B7 (remarque de Julien du 18 oct. 2026) — LES LISTES DÉROULANTES ONT LE
   GRAPHISME DES CHAMPS LIBRES, PARTOUT. Sous Safari, un <select> qui garde
   l'apparence du système ignore la hauteur et le cadre qu'on lui donne : il
   s'affichait en pilule arrondie de 22 px à côté de champs de 40 px aux angles
   droits. `appearance: none` rend la main : même cadre fin, mêmes angles de
   2 px, même hauteur, bord noir au focus. Le chevron est dessiné par deux
   dégradés (aucune image, aucune icône nouvelle, rien que la politique de
   sécurité de C2 aurait à autoriser). Les listes à choix multiples gardent la
   leur. En attendant le remplacement des listes décidé le 16 oct. (n° 118). */
select:not([multiple]) {
  -webkit-appearance: none; appearance: none;
  box-sizing: border-box; min-height: 40px;
  padding: 8px 34px 8px 12px;
  border: 1px solid #D4D4D8; border-radius: var(--radius);
  background-color: #FFFFFF;
  background-image:
    linear-gradient(45deg, transparent 50%, #6B7280 50%),
    linear-gradient(135deg, #6B7280 50%, transparent 50%);
  background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--color-text); font-family: var(--font-body); font-size: 14px; line-height: 1.4;
  cursor: pointer;
}
select:not([multiple]):focus { border-color: var(--color-ink); outline: none; }
select:not([multiple]):disabled { background-color: var(--color-row-alt); cursor: not-allowed; }
/* Les filtres rapides avaient des angles de 5 px : ceux de la charte. */
.lm-quick-search input[type=text], .lm-quick-search select { border-radius: var(--radius); }
/* Les petites listes des tableaux compacts gardent leur taille, avec la place
   du chevron. */
.org-table select:not([multiple]) { min-height: 0; padding: 4px 28px 4px 8px; font-size: 13px;
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%; }
.personnes table.data.compacte select:not([multiple]) { min-height: 0; padding: 1px 24px 1px 6px;
  background-position: calc(100% - 13px) 52%, calc(100% - 8px) 52%; }
@media (max-width: 600px) {
  /* Le 16 px qui empêche iOS de zoomer sur le champ (§ « ≤ 600 px »). */
  select:not([multiple]) { font-size: 16px; }
}
/* Dans les formulaires « tactiles » (Contrats : champs et boutons à 44 px),
   les listes prennent la même hauteur que leurs voisins. */
.form-touch select:not([multiple]) { min-height: 44px; }
/* Les boutons des rangées de filtres prennent la hauteur des champs (40 px) :
   Finding tracking, CAP tracking. */
.track-filters-actions > button, .track-filters-actions > .btn,
.lm-quick-search > button[type=submit] { min-height: 40px; border-radius: var(--radius); }

/* B7 (demande de Julien du 19 oct. 2026) — LE ☰ FAIT GLISSER LE MENU, sans
   recharger la page (`menu.js`, seconde exception à P1). Au-dessus de 900 px :
   la colonne passe de 210 à 40 px en 0,3 s, le contenu suit, et le titre et les
   entrées s'effacent en glissant vers la gauche (ils restent dans la page,
   cachés et hors de la tabulation). Sous 900 px, rien ne change (le menu se
   déroule par sa case à cocher). Sans mouvement si le système le demande. */
@media (min-width: 901px) {
  .module-menu { transition: width .3s ease; overflow: hidden; }
  .module-menu-title, .module-menu-links {
    white-space: nowrap;
    transition: opacity .22s ease, transform .3s ease, visibility 0s linear 0s;
  }
  .menu-replie .module-menu-title { display: inline; }
  .menu-replie .module-menu-links { display: flex; }
  .menu-replie .module-menu-title, .menu-replie .module-menu-links {
    opacity: 0; transform: translateX(-16px); visibility: hidden; pointer-events: none;
    transition: opacity .18s ease, transform .3s ease, visibility 0s linear .3s;
  }
}
@media (prefers-reduced-motion: reduce) {
  .module-menu, .module-menu-title, .module-menu-links { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   B8 — LES RÔLES DE PLATEFORME SUR « ACCOUNTS » (19 oct. 2026, planche B
   arbitrée par Julien) : le tableau compact « LM staff », les rôles en
   pastilles, la boîte « Edit roles » (cases noires), la rangée de filtres.
   Aucune couleur, aucune police nouvelles : l'encre, le filet gris, et les
   hachures ambre de la charte (§ 7) pour une proposition en attente.
   ═══════════════════════════════════════════════════════════════════════════ */
main:has(.equipe-lm) { width: 100%; }
.roles { display: inline-flex; gap: 6px; flex-wrap: wrap; vertical-align: middle; }
.role-pastille { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid #D4D4D8; border-radius: var(--radius); padding: 0 6px; line-height: 18px;
  color: var(--color-ink); white-space: nowrap; }
.role-pastille.attente { background: var(--hachure-bientot), #fff; }
table.data.compacte.equipe-lm th { padding: 4px 10px; font-size: 10.5px; letter-spacing: .08em; }
table.data.compacte.equipe-lm td { padding: 4px 10px; font-size: 13px; line-height: 1.35; vertical-align: middle; }
table.data.compacte.equipe-lm td.nom { font-weight: var(--fw-semibold); white-space: nowrap; }
table.data.compacte.equipe-lm td.droite { text-align: right; white-space: nowrap; }
table.data.compacte.equipe-lm button.lien-btn { font-size: 13px; }
.cases-roles { display: grid; gap: 10px; margin: 4px 0 2px; }
.cases-roles label { display: grid; grid-template-columns: 18px 1fr; gap: 2px 10px; align-items: start;
  font-size: 13.5px; text-transform: none; letter-spacing: 0; color: var(--color-ink); }
.cases-roles input[type=checkbox] { accent-color: var(--color-ink); margin-top: 3px; }
.cases-roles label .aide { grid-column: 2; font-size: 12px; color: #6B7280; }
.cases-roles label.grise { color: #9CA3AF; }
.propositions-roles { display: grid; gap: 8px; margin: 0 0 12px; }
.propositions-roles .lm-alert { display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  justify-content: space-between; margin: 0; }
.propositions-roles form { display: inline; }
.comptes-filtres { margin: 0; }
/* B8, retouche du 19 oct. 2026 — le numéro client : chiffres tabulaires, sans
   coupure, pour qu'il se lise et se dicte d'un bloc. Aucune couleur nouvelle. */
.numero-client-valeur { font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: .02em; }
.numero-client .numero-client-valeur { font-size: 20px; font-weight: 300; /* Light, la graisse des chiffres (charte § 1, principe 3) */ color: var(--color-ink); }
