/* ==========================================================================
   Repère Québec — Console interne
   Même système que reperequebec.ca v2, le scanner et l'espace client.
   La marque est identique, seule la densité change : c'est un outil de travail.
   Couleur : vert = Repère Québec · marine = la structure · or = ce qu'on a relevé
   ========================================================================== */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("/fonts/archivo-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/publicsans-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/plexmono-latin.woff2") format("woff2");
}

:root {
  /* ======================================================================
     1. LES DEUX SERVICES
     Un seul système, deux accents. Repère Québec = conformité Loi 25 ;
     Repère Sécurité = cybersécurité. Ils partagent tout sauf leur accent,
     leur blason et leur filet : cohérents, jamais confondus.
     ====================================================================== */

  /* Service A · Repère Québec */
  --qc-800: #123f2e;
  --qc-700: #17553d;
  --qc-600: #1F6A4E;
  --qc-500: #2c8564;
  --qc-100: #e7f1ec;
  --qc-050: #f3f9f6;

  /* Service B · Repère Sécurité.
     Indigo : même gravité que le vert, lecture « technique » plutôt que
     « conformité ». Volontairement distinct du bleu d'état « en cours »,
     pour que la couleur de service ne contredise jamais celle de l'état. */
  --sec-800: #212f52;
  --sec-700: #2C4068;
  --sec-600: #3B5488;
  --sec-500: #5570a5;
  --sec-100: #eaeff8;
  --sec-050: #f4f7fc;

  /* Service C · Repère Maintenance.
     Bronze : vert, indigo et bronze appartiennent à trois familles de teintes
     séparées, donc restent distinguables d'un coup d'œil dans une liste. Un
     sarcelle se serait logé entre les deux accents existants et aurait demandé
     une lecture attentive. Le registre évoque l'entretien et l'atelier ; il ne
     doit jamais glisser vers l'alerte. */
  --mnt-800: #523417;
  --mnt-700: #6d4620;
  --mnt-600: #8A5A2B;
  --mnt-500: #a6743f;
  --mnt-100: #f4ece2;
  --mnt-050: #faf6f1;

  /* L'accent courant. Les composants lisent --accent et ne savent rien du
     service qu'ils habillent ; c'est [data-service] qui le redéfinit. */
  --accent: var(--qc-600);
  --accent-fonce: var(--qc-700);
  --accent-voile: var(--qc-100);

  /* ======================================================================
     2. MARQUE ET CODE D'ÉTAT
     ====================================================================== */
  --marine: #0c1b2a;

  /* Vert Repère Québec. Alias historiques : tout le fichier les utilise. */
  --vert: var(--qc-600);
  --vert-fonce: var(--qc-700);
  --vert-clair: var(--qc-500);
  --vert-voile: var(--qc-100);

  --or: #d9a93c;
  --or-fonce: #7c5c12;
  --or-voile: #fbf3de;
  --surligneur: #fbe08f;
  --rouge: #c14b3a;
  --rouge-fonce: #8e2f21;
  --rouge-voile: #fbeae6;

  /* Bleu : « en cours / information ». La cinquième voix du code d'état,
     assez froide pour ne jamais se confondre avec le vert Repère. */
  --bleu: #2f5f80;
  --bleu-fonce: #21455d;
  --bleu-voile: #e6eef4;

  /* ======================================================================
     3. NEUTRES — un seul axe, légèrement froid, pour laisser respirer
     ====================================================================== */
  --n-025: #FAFBFB;
  --n-050: #F4F6F6;
  --n-100: #EBEFEF;
  --n-200: #DFE4E3;
  --n-300: #C6CFCD;
  --n-400: #9AA6A3;
  --n-500: #6C7A77;
  --n-600: #55625F;
  --n-700: #3D4A47;
  --n-900: #1B2523;

  --papier: var(--n-050);
  --blanc: #ffffff;
  --encre: #2c3b39;
  --gris: var(--n-500);
  --gris-clair: var(--n-400);
  --trait: var(--n-200);
  --trait-fort: var(--n-300);

  --sur-marine: #a7bac7;
  --sur-marine-fort: #dbe5eb;

  /* ======================================================================
     4. TYPOGRAPHIE
     Le tracking suit la taille : négatif sur les grands titres, neutre sur
     le texte courant, positif sur les capitales. Jamais une seule valeur.
     ====================================================================== */
  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --texte: "Public Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-xs: 0.6875rem;
  --t-s: 0.75rem;
  --t-m: 0.8125rem;
  --t-base: 0.875rem;
  --t-l: 0.9375rem;
  --t-xl: 1.0625rem;
  --t-2xl: 1.3125rem;
  --t-3xl: 1.75rem;
  --t-4xl: 2.25rem;

  /* ======================================================================
     5. ESPACEMENT — échelle de 4 px, pour que rien ne soit arbitraire
     ====================================================================== */
  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;
  --e-6: 24px;
  --e-8: 32px;
  --e-10: 40px;
  --e-12: 48px;
  --e-16: 64px;

  /* ======================================================================
     6. FORME
     ====================================================================== */
  --r-xs: 6px;
  --r-s: 9px;
  --r-m: 14px;
  --r-l: 22px;
  --r-full: 999px;

  /* ======================================================================
     7. MOUVEMENT
     Trois courbes, quatre durées. Les courbes natives du navigateur sont
     trop molles : celles-ci ont le mordant qui rend un geste intentionnel.
     Jamais d'ease-in sur de l'interface — il retarde l'instant précis où
     l'œil regarde.
     ====================================================================== */
  --sortie: cubic-bezier(0.23, 1, 0.32, 1);        /* entrées, sorties */
  --va-vient: cubic-bezier(0.77, 0, 0.175, 1);     /* déplacement à l'écran */
  --tiroir: cubic-bezier(0.32, 0.72, 0, 1);        /* tiroirs, panneaux */

  --d-1: 120ms;   /* survol, couleur */
  --d-2: 160ms;   /* appui */
  --d-3: 200ms;   /* menus, infobulles */
  --d-4: 260ms;   /* fenêtres, tiroirs */

  --barre: 262px;

  /* Élévation : trois hauteurs seulement, pour que rien ne flotte au hasard. */
  --ombre-1: 0 1px 2px rgba(12, 27, 42, 0.05);
  --ombre-2: 0 10px 26px rgba(12, 27, 42, 0.09);
  --ombre-3: 0 26px 64px rgba(12, 27, 42, 0.18);

  /* Plans : une seule échelle, déclarée une seule fois. */
  --z-contenu: 1;
  --z-collant: 20;
  --z-barre: 40;
  --z-menu: 60;
  --z-voile: 80;
  --z-modale: 100;
  --z-avis: 120;
}

/* L'accent bascule par service. La portée est volontairement limitée à la
   zone de contenu du service : une action globale (« Ajouter un client »)
   ne doit jamais prendre la couleur du service affiché. */
[data-service="quebec"] {
  --accent: var(--qc-600);
  --accent-fonce: var(--qc-700);
  --accent-voile: var(--qc-100);
}

[data-service="securite"] {
  --accent: var(--sec-600);
  --accent-fonce: var(--sec-700);
  --accent-voile: var(--sec-100);
}

[data-service="maintenance"] {
  --accent: var(--mnt-600);
  --accent-fonce: var(--mnt-700);
  --accent-voile: var(--mnt-100);
}

* {
  box-sizing: border-box;
}

html {
  color-scheme: light;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre);
  font-family: var(--texte);
  font-size: 14.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0;
  color: var(--marine);
  font-family: var(--display);
  font-stretch: 110%;
  letter-spacing: -0.015em;
}

p {
  margin: 0;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

.hidden {
  display: none !important;
}

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

.full {
  width: 100%;
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.sidebar :focus-visible {
  outline-color: var(--or);
}

/* Les boutons lisent --accent, pas --vert : hors d'une zone de service
   l'accent vaut le vert Repère Québec, donc rien ne change ; à l'intérieur
   d'un bloc [data-service], ils prennent la couleur du service affiché.
   C'est ce qui évite un « Assistant Soumission » vert en pleine section
   Repère Sécurité. */

/* --- Boutons -------------------------------------------------------------- */

.primary,
.secondary,
.ghost,
.danger {
  display: inline-flex;
  min-height: 40px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 17px;
  border: 1px solid transparent;
  border-radius: var(--r-s);
  font-family: var(--display);
  font-size: 0.87rem;
  font-stretch: 104%;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, transform 110ms var(--sortie);
}

/* L'appui répond à la pression, pas au relâchement : c'est ce qui donne le
   sentiment que l'interface écoute. `scale` met aussi le contenu à l'échelle
   — le texte et l'icône suivent, et l'objet s'enfonce vraiment. */
.primary:active,
.secondary:active,
.ghost:active,
.danger:active {
  transform: scale(0.97);
}

.primary {
  background: var(--accent);
  color: var(--blanc);
}

.primary:hover {
  background: var(--accent-fonce);
}

.secondary {
  border-color: var(--trait-fort);
  background: var(--blanc);
  color: var(--marine);
}

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

.ghost {
  background: transparent;
  color: var(--accent);
}

.ghost:hover {
  background: var(--accent-voile);
}

.danger {
  border-color: rgba(193, 75, 58, 0.4);
  background: var(--rouge-voile);
  color: var(--rouge-fonce);
}

.danger:hover {
  background: #f7ddd7;
}

.small {
  min-height: 34px;
  padding: 6px 12px;
  font-size: 0.8rem;
}

.icon-button {
  display: inline-flex;
  width: 38px;
  height: 38px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  color: var(--marine);
  font-size: 1rem;
  cursor: pointer;
}

.icon-button:hover {
  border-color: var(--accent);
}

/* --- Champs --------------------------------------------------------------- */

label {
  display: grid;
  gap: 6px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.84rem;
  font-stretch: 104%;
  font-weight: 700;
}

input,
select,
textarea {
  width: 100%;
  min-height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  color: var(--marine);
  font-family: var(--texte);
  font-size: 0.94rem;
  font-weight: 400;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

textarea {
  min-height: auto;
  resize: vertical;
}

input::placeholder,
textarea::placeholder {
  color: #9aa7a1;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--vert-clair);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-voile);
  outline: 0;
}

input[type="checkbox"],
input[type="radio"] {
  width: auto;
  min-height: auto;
  accent-color: var(--accent);
}

.form-error {
  min-height: 1.3em;
  margin: 0;
  color: var(--rouge-fonce);
  font-size: 0.86rem;
}

/* --- Connexion ------------------------------------------------------------ */

.login-shell {
  display: grid;
  min-height: 100vh;
  padding: 28px;
  place-items: center;
}

.login-card {
  display: grid;
  width: min(430px, 100%);
  padding: 38px 34px 32px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-l);
  background: var(--blanc);
  gap: 15px;
}

.login-logo {
  width: 118px;
  margin-bottom: 8px;
}

.login-card h1 {
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1.12;
}

.login-card > .muted {
  margin-bottom: 6px;
  font-size: 0.92rem;
}

/* --- Structure ------------------------------------------------------------ */

.app-shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: var(--barre) minmax(0, 1fr);
}

.sidebar {
  display: flex;
  position: sticky;
  top: 0;
  height: 100vh;
  padding: 22px 14px 18px;
  flex-direction: column;
  gap: 20px;
  overflow-y: auto;
  background: var(--marine);
  color: var(--sur-marine);
  scrollbar-width: thin;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  padding: 0 8px;
  gap: 11px;
}

.sidebar-logo {
  width: 36px;
  height: 36px;
}

.sidebar-brand strong {
  display: block;
  color: var(--blanc);
  font-family: var(--display);
  font-size: 0.96rem;
  font-stretch: 110%;
  font-weight: 700;
  line-height: 1.15;
}

.sidebar-brand small {
  color: var(--sur-marine);
  font-family: var(--mono);
  font-size: 0.68rem;
}

/* Navigation : six sections, une seule ouverte à la fois. Trente et un liens
   affichés en permanence, c'est un annuaire ; six, c'est un poste de commande.
   Pas d'icônes décoratives : un filet or marque la page active. */
.sidebar nav {
  display: grid;
  gap: 2px;
}

.nav-section {
  display: grid;
}

.nav-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 38px;
  padding: 8px 10px 8px 13px;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: transparent;
  color: var(--sur-marine-fort);
  font-family: var(--display);
  font-size: 0.8rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-align: left;
  cursor: pointer;
  gap: 8px;
  transition: background-color 140ms ease, color 140ms ease;
}

.nav-tete:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
}

/* Le filet de sélection prend la couleur du service, pas l'or.
   
   L'or veut dire « ce qu'on a trouvé » chez Repère Québec : l'employer pour
   marquer une position dans un menu lui faisait dire deux choses. Et le rail
   sait déjà de quel service il parle, par [data-service] — la sélection
   ignorait simplement cette information.
   
   Les accents de service sont calibrés pour un fond clair et s'éteignent sur
   le marine : le bronze tombe à 4,3:1 et le pétrole à 2,3:1. Ces trois
   variantes sont leurs équivalents lisibles sur le sombre, entre 6 et 9:1. Les
   sections sans service — CRM, Commercial, Administration — prennent un filet
   neutre plutôt qu'une couleur qui ne veut rien dire pour elles. */
.nav-section { --rail: #93a7b6; }
.nav-section[data-service="quebec"] { --rail: #4fb98a; }
.nav-section[data-service="securite"] { --rail: #7d9bd4; }
.nav-section[data-service="maintenance"] { --rail: #d3b491; }

.nav-section.contient > .nav-tete {
  border-left-color: var(--rail);
  color: var(--blanc);
}

.nav-tete svg {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  fill: none;
  opacity: 0.7;
  stroke: currentcolor;
  stroke-linecap: round;
  stroke-width: 2;
  transition: transform 160ms var(--sortie);
}

.nav-section.ouverte > .nav-tete svg {
  transform: rotate(180deg);
}

.nav-compte {
  display: inline-grid;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--or);
  color: var(--marine);
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 600;
  place-items: center;
}

.nav-liens {
  display: grid;
  gap: 1px;
  padding: 3px 0 8px;
}

.nav-section:not(.ouverte) > .nav-liens {
  display: none;
}

.sidebar nav .nav-liens button {
  padding: 6px 12px 6px 26px;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: transparent;
  color: var(--sur-marine);
  font-family: var(--texte);
  font-size: 0.87rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}

.sidebar nav .nav-liens button:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
}

/* L'entrée courante : le filet du service porte le signal, le fond ne fait que
   l'asseoir. Il était à 9 % — assez pour former un bloc gris qui se voyait plus
   que la sélection elle-même. À 6 %, il pose l'entrée sans la surcharger, et
   c'est la couleur qui dit où l'on est. */
.sidebar nav .nav-liens button.active {
  border-left-color: var(--rail);
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
}

/* Un seul lien de tête : pas de section à déplier pour le tableau de bord. */
.nav-seul .nav-tete {
  font-size: 0.87rem;
}

.sidebar-footer {
  display: grid;
  margin-top: auto;
  padding: 14px 8px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  gap: 10px;
}

.user-card {
  color: var(--sur-marine-fort);
  font-size: 0.85rem;
  line-height: 1.4;
}

.user-card strong {
  display: block;
  color: var(--blanc);
  font-family: var(--display);
  font-stretch: 104%;
  font-weight: 700;
}

.user-card small {
  color: var(--sur-marine);
  font-family: var(--mono);
  font-size: 0.7rem;
}

.sidebar-footer .ghost {
  color: var(--sur-marine);
}

.sidebar-footer .ghost:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--blanc);
}

/* --- Barre de titre : le filet du papier à en-tête du rapport ------------- */

.main {
  min-width: 0;
}

.topbar {
  display: flex;
  position: sticky;
  z-index: var(--z-barre);
  top: 0;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 32px 14px;

  /* La barre reste opaque sous le contenu : un dégradé qui commençait à
     s'effacer dès 78 % laissait le titre de la page transparaître à travers
     elle, et les deux titres se superposaient au défilement. La dissolution
     se fait maintenant juste en dessous de la barre, sur une bande courte
     (voir ::after), ce qui garde un bord doux sans jamais brouiller le texte.
     La couleur de fin était par ailleurs l'ancien papier codé en dur. */
  background: var(--papier);
}

.topbar::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: 100%;
  right: 0;
  left: 0;
  height: 14px;
  background: linear-gradient(var(--papier), transparent);
  pointer-events: none;
}

.topbar-titre {
  min-width: 0;
  flex: 1;
}

.topbar-crumb {
  margin-bottom: 3px;
  color: var(--vert);
  font-family: var(--display);
  font-size: 0.72rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.topbar h1 {
  font-size: 1.72rem;
  font-weight: 800;
  line-height: 1.08;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  padding-bottom: 2px;
}

.status-pill {
  padding: 5px 12px 6px;
  border-radius: 999px;
  background: var(--papier);
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.72rem;
  white-space: nowrap;
}

.status-pill.safe {
  background: var(--vert-voile);
  color: var(--vert-fonce);
}

.status-pill.on {
  background: var(--or-voile);
  color: var(--or-fonce);
}

#mobile-menu {
  display: none;
}

.icon-button svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: currentcolor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

/* --- Recherche globale : le raccourci qui remplace vingt menus ------------- */

.recherche-globale {
  position: relative;
  width: clamp(180px, 24vw, 300px);
}

.recherche-globale input {
  width: 100%;
  height: 38px;
  padding: 0 32px 0 34px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  font-size: 0.87rem;
}

.recherche-globale input::-webkit-search-cancel-button {
  display: none;
}

.recherche-glyphe {
  position: absolute;
  top: 11px;
  left: 11px;
  width: 16px;
  height: 16px;
  fill: none;
  pointer-events: none;
  stroke: var(--gris-clair);
  stroke-linecap: round;
  stroke-width: 1.8;
}

.recherche-touche {
  position: absolute;
  top: 10px;
  right: 9px;
  padding: 1px 6px;
  border: 1px solid var(--trait);
  border-radius: 5px;
  background: var(--papier);
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.68rem;
  pointer-events: none;
}

.recherche-globale input:focus + .recherche-touche {
  opacity: 0;
}

.recherche-resultats {
  display: grid;
  position: absolute;
  z-index: var(--z-menu);
  top: calc(100% + 8px);
  right: 0;
  left: 0;
  max-height: 62vh;
  padding: 6px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  box-shadow: var(--ombre-2);
  gap: 1px;
  overflow-y: auto;
}

.recherche-groupe {
  padding: 9px 10px 4px;
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.recherche-item {
  display: grid;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--marine);
  font-family: var(--texte);
  font-size: 0.87rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  gap: 1px;
}

.recherche-item span {
  color: var(--gris);
  font-size: 0.76rem;
  font-weight: 400;
}

.recherche-item:hover,
.recherche-item.vise {
  background: var(--vert-voile);
}

.recherche-vide {
  padding: 14px 10px;
  color: var(--gris);
  font-size: 0.85rem;
}

/* --- Voile du tiroir de navigation ---------------------------------------- */

.scrim {
  position: fixed;
  z-index: var(--z-voile);
  background: rgba(12, 27, 42, 0.5);
  inset: 0;
}

.content {
  padding: 4px 32px 64px;
}

.content::before {
  display: block;
  height: 2px;
  margin-bottom: 22px;
  background: var(--marine);
  content: "";
}

/* --- Le bilan : ce qui demande une intervention --------------------------- */

.bilan {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  flex-wrap: wrap;
  margin-bottom: 26px;
  padding: 20px 26px;
  border-radius: var(--r-l);
  background: var(--marine);
}

.bilan-titre {
  color: var(--blanc);
  font-family: var(--display);
  font-size: 1.08rem;
  font-stretch: 110%;
  font-weight: 700;
}

.bilan-titre span {
  display: block;
  margin-top: 3px;
  color: var(--sur-marine);
  font-family: var(--texte);
  font-size: 0.85rem;
  font-weight: 400;
}

.bilan-chiffres {
  display: flex;
  gap: 30px;
  flex-wrap: wrap;
}

.chiffre {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.chiffre b {
  font-family: var(--display);
  font-size: 1.62rem;
  font-stretch: 112%;
  font-weight: 800;
  line-height: 1;
}

.chiffre.urgent b {
  color: #e0705c;
}

.chiffre.attention b {
  color: #e8bd5c;
}

.chiffre.calme b {
  color: var(--blanc);
}

.chiffre span {
  max-width: 96px;
  color: var(--sur-marine);
  font-size: 0.8rem;
  line-height: 1.25;
}

/* --- Sections et panneaux -------------------------------------------------- */

.panel {
  margin-bottom: 22px;
  padding: 20px 22px 22px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.panel-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 15px;
}

.panel-header h2 {
  font-size: 1.06rem;
  font-weight: 700;
}

.panel-header p {
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.85rem;
}

.section-intro {
  max-width: 78ch;
  margin-bottom: 16px;
  color: var(--gris);
  font-size: 0.9rem;
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  align-items: start;
}

.grid-2 > .panel {
  margin-bottom: 0;
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

.actions,
.row-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.edit-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* --- Mesures : peu nombreuses, jamais toutes affichées --------------------- */

.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: 1px;
  margin-bottom: 24px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--trait);
  overflow: hidden;
}

.metric-card {
  padding: 15px 18px 16px;
  background: var(--blanc);
}

.metric-card .label {
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.78rem;
  font-stretch: 104%;
  font-weight: 600;
}

.metric-card .value {
  margin: 5px 0 2px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.7rem;
  font-stretch: 112%;
  font-weight: 800;
  line-height: 1;
}

.metric-card .hint {
  color: var(--gris-clair);
  font-size: 0.78rem;
}

.module-card {
  padding: 14px 16px 15px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.module-card h3 {
  font-size: 0.94rem;
  font-weight: 700;
}

.module-card p {
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.84rem;
}

/* --- Tableaux --------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table th,
.data-table td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--trait);
  text-align: left;
  vertical-align: top;
}

.data-table th:first-child,
.data-table td:first-child {
  padding-left: 0;
}

.data-table th:last-child,
.data-table td:last-child {
  padding-right: 0;
}

.data-table th {
  border-bottom: 2px solid var(--marine);
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.78rem;
  font-stretch: 104%;
  font-weight: 600;
  white-space: nowrap;
}

.data-table td strong {
  color: var(--marine);
  font-family: var(--display);
  font-stretch: 104%;
  font-weight: 700;
}

.data-table tr.clickable {
  cursor: pointer;
}

.data-table tbody tr:hover {
  background: #f8faf7;
}

/* --- Fiches clients ---------------------------------------------------------- */

.client-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(252px, 1fr));
  gap: 12px;
}

.client-card {
  padding: 16px 18px 17px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  cursor: pointer;
  transition: border-color 150ms ease;
}

.client-card:hover {
  border-color: var(--vert-clair);
}

.client-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 13px;
}

.client-top > div { min-width: 0; }
.client-top .badge { flex-shrink: 0; }

.client-card h3 {
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.25;
}

.client-top p {
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.81rem;
}

.client-stats {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 9px;
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.73rem;
}

.progress {
  overflow: hidden;
  height: 7px;
  border-radius: 999px;
  background: #e2e7e1;
}

.progress > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* --- Journal d'activité ------------------------------------------------------- */

.timeline {
  display: grid;
  position: relative;
  gap: 0;
}

.timeline-item {
  display: grid;
  padding: 11px 0;
  border-bottom: 1px solid var(--trait);
  grid-template-columns: 16px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

.timeline-item:last-child {
  border-bottom: 0;
}

.timeline-dot {
  width: 7px;
  height: 7px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--vert-clair);
}

.timeline-item strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
}

.timeline-item p {
  margin-top: 2px;
  color: var(--gris);
  font-size: 0.82rem;
}

/* --- Pastilles d'état : les trois du rapport ---------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px 4px;
  border-radius: 999px;
  background: var(--papier);
  color: var(--gris);

  /* Le monospace vient du rapport, où il aligne des codes de contrôle. Un
     statut n'est pas un code : c'est un mot qu'on lit. La graisse et la
     casse suffisent à le distinguer du texte courant, sans la largeur fixe
     qui hache « Non applicable » en colonnes. */
  font-family: var(--texte);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.badge.done,
.badge.implemented,
.badge.accepted,
.badge.ready,
.badge.resolved,
.badge.reviewed,
.badge.low,
.badge.won,
.badge.active,
.badge.approved,
.badge.closed,
.badge.mitigated {
  background: var(--vert-voile);
  color: var(--vert-fonce);
}

.badge.in_review,
.badge.needs_review,
.badge.medium,
.badge.processing,
.badge.requested,
.badge.waiting_client,
.badge.sent,
.badge.submitted,
.badge.onboarding,
.badge.draft,
.badge.pending,
.badge.open,
.badge.negotiation,
.badge.proposal {
  background: var(--or-voile);
  color: var(--or-fonce);
}

.badge.high,
.badge.critical,
.badge.failed,
.badge.rejected,
.badge.overdue,
.badge.lost,
.badge.breach {
  background: var(--rouge-voile);
  color: var(--rouge-fonce);
}

/* Bloquée est un problème, pas un état neutre. En cours est du travail engagé. */
.badge.blocked { background: var(--rouge-voile); color: var(--rouge-fonce); }
.badge.in_progress { background: #e6ecf1; color: var(--marine); }

/* --- Encadré et état vide ------------------------------------------------------ */

.callout {
  margin-bottom: 18px;
  padding: 14px 18px;
  border-left: 3px solid var(--or);
  border-radius: var(--r-s);
  background: var(--or-voile);
  color: var(--or-fonce);
  font-size: 0.89rem;
}

.callout strong {
  color: var(--marine);
  font-family: var(--display);
  font-stretch: 104%;
  font-weight: 700;
}

.empty {
  padding: 18px 0 4px;
  border-top: 1px solid var(--trait);
}

.empty strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.98rem;
  font-stretch: 104%;
  font-weight: 700;
}

.empty p {
  max-width: 54ch;
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.88rem;
}

/* --- Fenêtre modale -------------------------------------------------------------- */

.modal-backdrop {
  display: grid;
  position: fixed;
  z-index: var(--z-modale);
  padding: 24px;
  inset: 0;
  background: rgba(7, 18, 29, 0.62);
  place-items: center;
}

.modal-card {
  display: flex;
  width: min(660px, 100%);
  max-height: min(86vh, 800px);
  flex-direction: column;
  border-radius: var(--r-l);
  background: var(--blanc);
  overflow: hidden;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 24px 15px;
  border-bottom: 2px solid var(--marine);
}

.modal-header h2 {
  font-size: 1.2rem;
  font-weight: 700;
}

.modal-form {
  display: grid;
  padding: 22px 24px 24px;
  gap: 15px;
  overflow-y: auto;

  /* La fenêtre est bornée en hauteur : sans cette ligne, la grille comprime
     ses rangées pour entrer dans l'espace disponible et les blocs se
     chevauchent. Chaque rangée prend la hauteur de son contenu ; c'est la
     fenêtre qui défile. */
  grid-auto-rows: min-content;

  /* Et bornée en largeur : sans `minmax(0, 1fr)`, un enfant large — la barre
     d'étapes de l'assistant, par exemple — élargit la colonne au-delà de la
     fenêtre, et tout le contenu se retrouve coupé à droite sur téléphone. */
  grid-template-columns: minmax(0, 1fr);
}

/* Grille de champs des formulaires en fenêtre. La règle manquait : les champs
   s'empilaient toujours sur une colonne, y compris sur grand écran, et la
   classe `.wide` n'avait aucun effet. */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.form-grid > .wide,
.form-grid > fieldset {
  grid-column: 1 / -1;
}

@media (max-width: 640px) {
  .form-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Un enfant en `overflow: hidden` perd son plancher de hauteur automatique.
   On lui rend son minimum de contenu. */
.modal-form > * {
  min-height: min-content;
}

/* Les actions restent visibles au bas de la fenêtre pendant qu'on fait
   défiler un long formulaire. */
.modal-form > .modal-actions {
  position: sticky;
  z-index: 2;
  bottom: -24px;
  margin: 0 -24px -24px;
  padding: 14px 24px;
  border-top: 1px solid var(--trait);
  background: var(--blanc);
}

.modal-form .wide {
  grid-column: 1 / -1;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 9px;
  margin-top: 6px;
}

/* --- Notification transitoire ----------------------------------------------------- */

.toast {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: var(--z-avis);
  max-width: min(370px, calc(100% - 44px));
  padding: 12px 17px;
  border-radius: var(--r-s);
  background: var(--marine);
  color: var(--blanc);
  font-weight: 600;
  box-shadow: 0 12px 30px rgba(12, 27, 42, 0.24);
}

.toast.error {
  background: var(--rouge-fonce);
}

/* --- Adaptations ------------------------------------------------------------------- */

/* 1280 px : la barre latérale se resserre avant que la mise en page ne cède. */
@media (max-width: 1320px) {
  :root {
    --barre: 232px;
  }

  .content,
  .topbar {
    padding-right: 24px;
    padding-left: 24px;
  }
}

@media (max-width: 1180px) {
  .grid-2 {
    grid-template-columns: 1fr;
  }
}

/* 1024 px : sous cette largeur, une barre fixe vole trop de place au travail.
   Elle devient un tiroir, appelé depuis la barre de titre. */
@media (max-width: 1024px) {
  .app-shell {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: fixed;
    z-index: var(--z-voile);
    top: 0;
    bottom: 0;
    left: 0;
    width: 274px;
    transform: translateX(-100%);
    transition: transform 200ms var(--sortie);
  }

  .sidebar.open {
    transform: translateX(0);
    box-shadow: var(--ombre-3);
  }

  #mobile-menu {
    display: inline-flex;
  }

  .topbar {
    align-items: center;
    padding: 16px 20px 12px;
  }

  .topbar h1 {
    font-size: 1.35rem;
  }

  .topbar-actions .status-pill {
    display: none;
  }

  .content {
    padding: 0 20px 52px;
  }
}

@media (max-width: 900px) {
  .recherche-globale {
    width: 190px;
  }

  .recherche-touche {
    display: none;
  }

  .bilan {
    align-items: flex-start;
    flex-direction: column;
    gap: 18px;
    padding: 18px 20px;
  }

  .bilan-chiffres {
    gap: 20px;
  }
}

/* Le bouton loupe ne sert que sur téléphone. */
#recherche-ouvrir { display: none; }

/* Sur téléphone, la barre de titre tient sur une seule rangée : menu, titre,
   loupe, action. La recherche ne s'affiche que lorsqu'on la demande — sinon
   elle vole une rangée entière sur chaque écran. */
@media (max-width: 700px) {
  .topbar {
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 16px 10px;
  }

  .topbar-titre {
    min-width: 0;
    flex: 1 1 auto;
  }

  .topbar h1 {
    font-size: 1.15rem;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .topbar-crumb {
    font-size: 0.66rem;
  }

  #mobile-menu,
  #recherche-ouvrir {
    flex: 0 0 auto;
  }

  #recherche-ouvrir {
    display: inline-flex;
  }

  .topbar-actions {
    gap: 8px;
  }

  .topbar-actions .primary {
    min-height: 38px;
    padding: 8px 13px;
    flex: 0 0 auto;
    font-size: 0.85rem;
  }

  /* Repliée par défaut, dépliée sur toute la rangée suivante quand on
     appuie sur la loupe. */
  .recherche-globale {
    display: none;
    order: 3;
    width: 100%;
  }

  .topbar.cherche .recherche-globale {
    display: block;
  }

  .topbar.cherche #recherche-ouvrir {
    border-color: var(--vert);
    background: var(--vert-voile);
    color: var(--vert-fonce);
  }

  .content {
    padding: 0 16px 48px;
  }
}

@media (max-width: 620px) {
  .metric-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .panel {
    padding: 17px 16px 18px;
  }

  .panel-header {
    align-items: flex-start;
    flex-direction: column;
    gap: 10px;
  }

  .toast {
    right: 14px;
    bottom: 14px;
    left: 14px;
    max-width: none;
  }
}

/* Mouvement réduit ne veut pas dire aucun mouvement : cela veut dire moins,
   et plus doux. On retire tout ce qui déplace ou met à l'échelle — c'est le
   déplacement qui provoque le mal des transports — mais on garde les
   transitions de couleur et d'opacité, qui aident à comprendre ce qui change.
   Couper `*` supprimait aussi ces repères-là. */
@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: var(--d-1) !important;
    animation-duration: var(--d-1) !important;
    animation-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Plus aucun déplacement, aucune mise à l'échelle, nulle part. */
  *,
  *::before,
  *::after {
    transition-property: color, background-color, border-color, box-shadow, opacity, fill, stroke !important;
  }

  *:active {
    transform: none !important;
  }

  .pipeline { scroll-behavior: auto; }
}

/* --- Grille de modules et fournisseurs (page Intelligence artificielle) ------ */

.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.ai-provider {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--trait);
}

.ai-provider:last-child {
  border-bottom: 0;
}

/* --- Vérification en deux étapes ------------------------------------------ */
.mfa-enrollment {
  display: grid;
  padding: 16px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--papier);
  gap: 10px;
}
.mfa-enrollment p,
.mfa-code-help { margin: 0; }
.mfa-secret {
  display: block;
  padding: 12px;
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  overflow-wrap: anywhere;
  background: var(--blanc);
  font-family: var(--mono);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
}
.login-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.button-link { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.recovery-codes {
  display: grid;
  padding: 14px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  background: var(--papier);
}
.recovery-codes code {
  font-family: var(--mono);
  font-size: 0.82rem;
}
@media (max-width: 520px) {
  .recovery-codes { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Pages CRM — Pipeline, Tâches, Activités
   Même grammaire que le reste de la console. Le motif commun est le filet :
   il porte un libellé et un compte (groupes de tâches, journées d'activité)
   et devient une mesure quand il représente une part du pipeline.
   Aucune règle de cette section ne modifie les autres modules.
   ========================================================================== */

:root {
  /* Fond de voie : un papier légèrement plus dense, pour que les fiches
     blanches se détachent sans ajouter d'ombre. */
  --voie: #e5eae2;
  --voie-trait: #ccd4ca;
  --rouge-filet: rgba(193, 75, 58, 0.34);
  --or-filet: rgba(217, 169, 60, 0.42);
}

/* --- En-tête de page --------------------------------------------------- */

.page-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.page-tete h2 {
  font-size: 1.2rem;
  font-weight: 800;
}

.page-tete p {
  max-width: 62ch;
  margin-top: 4px;
  color: var(--gris);
  font-size: 0.88rem;
}

.page-tete-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* Mesures : réutilise .metric-grid / .metric-card, avec un ton de valeur. */
.metric-card .value.ton-alerte { color: var(--rouge-fonce); }
.metric-card .value.ton-attention { color: var(--or-fonce); }
.metric-card .value.ton-bien { color: var(--vert); }
.metric-card .value.ton-neutre { color: var(--gris-clair); }

/* --- Filet de groupe : le motif commun aux trois pages ------------------ */

.filet-groupe {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 9px;
}

.filet-groupe h3 {
  font-size: 0.94rem;
  font-weight: 700;
  white-space: nowrap;
}

.filet-groupe .filet {
  height: 1px;
  flex: 1;
  background: var(--trait);
}

.filet-groupe .compte {
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.73rem;
  white-space: nowrap;
}

.filet-groupe.est-retard h3,
.filet-groupe.est-retard .compte { color: var(--rouge-fonce); }
.filet-groupe.est-retard .filet { background: var(--rouge-filet); }

.filet-groupe.est-aujourdhui h3,
.filet-groupe.est-aujourdhui .compte { color: var(--or-fonce); }
.filet-groupe.est-aujourdhui .filet { background: var(--or-filet); }

.filet-groupe.est-clos h3,
.filet-groupe.est-clos .compte { color: var(--gris-clair); }

/* --- 1. Pipeline commercial -------------------------------------------- */

/* Le bilan : la forme du pipeline, avant son détail. Même bloc marine que le
   bilan du tableau de bord — c'est la surface « vue d'ensemble » du système. */
.pipeline-bilan {
  margin-bottom: 22px;
  padding: 20px 24px 20px;
  border-radius: var(--r-l);
  background: var(--marine);
  color: var(--sur-marine);
}

.pipeline-bilan-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.pipeline-bilan-titre {
  color: var(--vert-clair);
  font-family: var(--display);
  font-size: 0.74rem;
  font-stretch: 104%;
  font-weight: 700;
}

.pipeline-bilan-valeur strong {
  display: block;
  margin: 3px 0 4px;
  color: var(--blanc);
  font-family: var(--display);
  font-size: 2.1rem;
  font-stretch: 112%;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.pipeline-bilan-sous {
  color: var(--sur-marine);
  font-size: 0.84rem;
}

.pipeline-bilan-cote {
  display: flex;
  align-items: flex-end;
  flex-direction: column;
  gap: 16px;
}

.pipeline-bilan-conclus {
  display: flex;
  gap: 30px;
  flex-wrap: wrap;
}

.pipeline-bilan-conclus > div,
.pipeline-bilan-conclus > button { text-align: right; }

.pipeline-bilan-perdues {
  padding: 3px 9px 4px;
  border: 1px solid transparent;
  border-radius: var(--r-s);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease;
}

.pipeline-bilan-perdues:hover { border-color: rgba(255, 255, 255, 0.24); }

.pipeline-bilan-perdues.actif {
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.09);
}

.pipeline-bilan-perdues b { color: var(--blanc); }
.pipeline-bilan-perdues span { display: block; }

.pipeline-bilan-conclus b {
  display: block;
  color: var(--blanc);
  font-family: var(--display);
  font-size: 1.35rem;
  font-stretch: 112%;
  font-weight: 800;
  line-height: 1.1;
}

.pipeline-bilan-conclus b.est-vert { color: var(--vert-clair); }

.pipeline-bilan-conclus span {
  color: var(--sur-marine);
  font-size: 0.78rem;
}

/* La barre : le filet qui mesurait une étape mesure ici tout le pipeline. */
.pipeline-barre {
  display: flex;
  height: 12px;
  gap: 3px;
  margin-bottom: 13px;
}

.pipeline-segment {
  min-width: 6px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  transition: filter 140ms ease, transform 140ms var(--sortie);
}


/* Une seule teinte qui s'affirme à mesure qu'on approche de la signature. */
.seg-1 { background: rgba(88, 164, 131, 0.32); }
.seg-2 { background: rgba(88, 164, 131, 0.52); }
.seg-3 { background: rgba(88, 164, 131, 0.74); }
.seg-4 { background: #7cc9a4; }

.pipeline-legende {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 4px;
}

.pipeline-legende-item {
  display: grid;
  padding: 6px 9px 7px;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  grid-template-columns: 9px minmax(0, 1fr);
  gap: 2px 9px;
  text-align: left;
  cursor: pointer;
  transition: background-color 140ms ease;
}

.pipeline-legende-item:hover { background: rgba(255, 255, 255, 0.07); }

.pipeline-puce {
  width: 9px;
  height: 9px;
  margin-top: 5px;
  border-radius: 2px;
  grid-row: 1 / 3;
}

.pipeline-legende-item b {
  color: var(--blanc);
  font-family: var(--display);
  font-size: 0.83rem;
  font-stretch: 104%;
  font-weight: 700;
}

.pipeline-legende-item span {
  color: var(--sur-marine);
  font-family: var(--mono);
  font-size: 0.71rem;
}

.pipeline {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding-bottom: 12px;
  overflow-x: auto;
  scroll-behavior: smooth;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
}

.pipeline-col {
  display: flex;
  min-width: 0;
  padding: 13px 12px 12px;
  border: 1px solid var(--voie-trait);
  border-radius: var(--r-m);
  background: var(--voie);
  flex: 0 0 286px;
  flex-direction: column;
  gap: 9px;
  scroll-snap-align: start;
}

/* Les dossiers conclus se consultent, ils ne se travaillent plus : moins large. */
.pipeline-col.est-terminal { flex: 0 0 262px; }

/* Gagnée et Perdue ne sont pas du travail en cours : la voie s'efface. */
.pipeline-col.est-terminal {
  border-color: var(--trait);
  background: transparent;
}

.pipeline-tete { display: grid; gap: 7px; }

.pipeline-tete-haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pipeline-tete h3 {
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.005em;
}

.pipeline-compte {
  display: inline-flex;
  min-width: 22px;
  height: 20px;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(12, 27, 42, 0.08);
  color: var(--marine);
  font-family: var(--mono);
  font-size: 0.71rem;
}

.pipeline-col.est-terminal .pipeline-compte {
  background: rgba(12, 27, 42, 0.06);
  color: var(--gris);
}

.pipeline-ajout {
  display: inline-flex;
  width: 24px;
  height: 24px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--gris);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}

.pipeline-ajout:hover {
  border-color: var(--vert-clair);
  background: var(--blanc);
  color: var(--vert-fonce);
}

.pipeline-valeur {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pipeline-valeur.est-vide {
  color: var(--gris-clair);
  font-size: 0.82rem;
  font-weight: 600;
}

/* Le filet devient une mesure : la part de cette étape dans le pipeline. */
.pipeline-part {
  overflow: hidden;
  height: 3px;
  border-radius: 999px;
  background: rgba(12, 27, 42, 0.1);
}

.pipeline-part > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.pipeline-fiches {
  display: grid;
  gap: 8px;
  min-height: 4px;
}

.deal-card {
  display: grid;
  padding: 12px 13px 10px;
  border: 1px solid var(--trait);
  border-left: 3px solid transparent;
  border-radius: var(--r-s);
  background: var(--blanc);
  gap: 0;
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease, transform 110ms var(--sortie);
}

.deal-card:hover {
  border-color: var(--trait-fort);
  border-left-color: var(--vert-clair);
  box-shadow: 0 3px 10px rgba(12, 27, 42, 0.07);
}

.deal-card:active { transform: translateY(1px); }

/* Un seul canal de signal, le même que le filet or de la navigation. */
.deal-card.est-retard { border-left-color: var(--rouge); }
.deal-card.est-bientot { border-left-color: var(--or); }
.deal-card.est-gagnee { border-left-color: var(--vert); }

.deal-card.est-terminal {
  border-color: var(--trait);
  background: rgba(255, 255, 255, 0.62);
}

.deal-nom {
  display: -webkit-box;
  overflow: hidden;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.28;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.deal-org {
  margin-top: 2px;
  overflow: hidden;
  color: var(--gris);
  font-size: 0.81rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.deal-chiffres {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 10px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.deal-montant {
  min-width: 0;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.12rem;
  font-stretch: 110%;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.deal-montant.est-vide {
  color: var(--gris-clair);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0;
}

.deal-proba {
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.74rem;
  white-space: nowrap;
}

.deal-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--trait);
}

.deal-echeance {
  overflow: hidden;
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.72rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.deal-echeance.est-retard { color: var(--rouge-fonce); }
.deal-echeance.est-bientot { color: var(--or-fonce); }

.deal-avancer {
  display: inline-flex;
  width: 26px;
  height: 26px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-xs);
  background: var(--blanc);
  color: var(--marine);
  font-size: 0.8rem;
  line-height: 1;
  flex-shrink: 0;
  cursor: pointer;
  opacity: 0;
  transition: opacity 140ms ease, border-color 140ms ease, background-color 140ms ease, color 140ms ease;
}

.deal-card:hover .deal-avancer,
.deal-avancer:focus-visible { opacity: 1; }

.deal-avancer:hover {
  border-color: var(--vert);
  background: var(--vert);
  color: var(--blanc);
}

.pipeline-vide {
  padding: 14px 6px 16px;
  color: var(--gris-clair);
  font-size: 0.81rem;
  text-align: center;
}

/* Le trait qui sépare le pipeline ouvert des dossiers conclus. */
.pipeline-separateur {
  width: 1px;
  min-height: 190px;
  margin: 0 6px;
  background: var(--trait-fort);
  align-self: stretch;
}

/* --- 2. Tâches ---------------------------------------------------------- */

.filtres {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 22px;
  padding: 14px 16px 15px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.filtre {
  display: grid;
  min-width: 158px;
  gap: 5px;
  flex: 1 1 158px;
  max-width: 230px;
}

.filtre > span {
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.73rem;
  font-stretch: 104%;
  font-weight: 700;
}

.filtre select {
  min-height: 38px;
  padding: 7px 10px;
  font-size: 0.88rem;
}

.filtres-fin {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  padding-bottom: 3px;
}

.filtres-compte {
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.74rem;
  white-space: nowrap;
}

.taches-wrap {
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow-x: auto;
}

.crm-table {
  width: 100%;
  min-width: 940px;
  border-collapse: collapse;
}

/* La colonne Tâche absorbe la place restante ; les autres se dimensionnent sur
   leur contenu. Un seul tableau : l'alignement entre groupes est natif. */
.crm-table .c-tache { width: 36%; }

/* Bande de groupe : le filet traverse toute la largeur du tableau. */
.crm-table tbody tr.groupe-ligne,
.crm-table tbody tr.groupe-ligne:hover { background: transparent; cursor: default; }

.crm-table tbody tr.groupe-ligne td {
  padding: 26px 14px 4px;
  border-bottom: 0;
  box-shadow: none;
}

.crm-table tbody tr.groupe-ligne:first-child td { padding-top: 12px; }
.crm-table tbody tr.groupe-ligne .filet-groupe { margin-bottom: 0; }

.crm-table th,
.crm-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--trait);
  text-align: left;
  vertical-align: middle;
}

.crm-table th {
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--trait-fort);
  background: #fbfcfa;
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.74rem;
  font-stretch: 104%;
  font-weight: 700;
  white-space: nowrap;
}

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

.crm-table tbody tr {
  cursor: pointer;
  transition: background-color 120ms ease;
}

.crm-table tbody tr:not(.groupe-ligne):hover { background: #f8faf7; }

/* Le signal de retard reprend le filet latéral, sans décaler la colonne. */
.crm-table tbody tr.est-retard td:first-child { box-shadow: inset 3px 0 0 var(--rouge); }
.crm-table tbody tr.est-aujourdhui td:first-child { box-shadow: inset 3px 0 0 var(--or); }
.crm-table tbody tr.est-close td { opacity: 0.72; }



.tache-titre {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.93rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}

.crm-table tbody tr:hover .tache-titre { color: var(--vert-fonce); }
.tache-titre:hover { text-decoration: underline; text-underline-offset: 2px; }

.tache-desc {
  display: -webkit-box;
  overflow: hidden;
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.82rem;
  line-height: 1.35;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}

.c-client {
  overflow: hidden;
  color: var(--encre);
  font-size: 0.87rem;
  text-overflow: ellipsis;
  /* Un nom d'entreprise cassé sur trois lignes est illisible en balayage. */
  white-space: nowrap;
}

.c-echeance { white-space: nowrap; }

.c-echeance strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.86rem;
  font-stretch: 104%;
  font-weight: 700;
}

.c-echeance span {
  display: block;
  margin-top: 1px;
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.71rem;
}

.c-echeance.est-retard strong,
.c-echeance.est-retard span { color: var(--rouge-fonce); }

.c-echeance.est-aujourdhui strong,
.c-echeance.est-aujourdhui span { color: var(--or-fonce); }

.c-source {
  overflow: hidden;
  color: var(--gris);
  text-overflow: ellipsis;
  font-family: var(--mono);
  font-size: 0.72rem;
  white-space: nowrap;
}

.c-actions { text-align: right; white-space: nowrap; }
.c-vide { color: var(--trait-fort); }



/* Priorité : lisible d'abord. Seule « Critique » est pleine. */
.prio {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px 5px;
  border-radius: 999px;
  gap: 7px;
  font-family: var(--display);
  font-size: 0.76rem;
  font-stretch: 104%;
  font-weight: 700;
  white-space: nowrap;
}

.prio::before {
  width: 4px;
  height: 11px;
  border-radius: 2px;
  background: currentColor;
  content: "";
}

.prio-critical { background: var(--rouge-fonce); color: var(--blanc); }
.prio-high { background: var(--rouge-voile); color: var(--rouge-fonce); }
.prio-medium { background: var(--or-voile); color: var(--or-fonce); }
.prio-low { background: var(--papier); color: var(--gris); }

/* --- 3. Activités CRM --------------------------------------------------- */

.filtres-type {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}

.puce {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border: 1px solid var(--trait-fort);
  border-radius: 999px;
  background: var(--blanc);
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.84rem;
  font-stretch: 104%;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.puce b {
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.71rem;
  font-weight: 500;
}

.puce:hover { border-color: var(--vert-clair); }

.puce.actif {
  border-color: var(--marine);
  background: var(--marine);
  color: var(--blanc);
}

.puce.actif b { color: var(--sur-marine); }

.journal { display: grid; gap: 26px; }

.jour-liste {
  display: grid;
  position: relative;
  gap: 2px;
}

/* Le rail : un filet vertical qui relie la journée. */
.jour-liste::before {
  position: absolute;
  z-index: 1;
  top: 30px;
  bottom: 30px;
  left: 17px;
  width: 1px;
  background: var(--trait);
  content: "";
}

.jour-liste.solo::before { display: none; }

.activite {
  display: grid;
  position: relative;
  padding: 11px 12px 12px 0;
  border-radius: var(--r-s);
  grid-template-columns: 36px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: start;
  transition: background-color 120ms ease;
}

.activite:hover { background: #f8faf7; }

.activite-glyphe {
  display: grid;
  position: relative;
  z-index: 2;
  width: 36px;
  height: 36px;
  border: 1px solid var(--trait-fort);
  border-radius: 50%;
  background: var(--blanc);
  color: var(--marine);
  place-items: center;
}

/* Le glyphe encode qui a produit l'activité, pas seulement son type. */
.activite-glyphe.est-humain { border-color: var(--vert-clair); color: var(--vert); }
.activite-glyphe.est-auto { border-color: var(--trait); color: var(--gris-clair); }

.activite-corps {
  min-width: 0;
  /* L'heure reste près de son titre plutôt qu'à l'autre bout de l'écran. */
  max-width: 82ch;
  padding-top: 2px;
}

.activite-haut {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}

.activite-haut strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.94rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.3;
}

.activite-heure {
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.72rem;
  white-space: nowrap;
  flex-shrink: 0;
}

.activite-meta {
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.82rem;
}

.activite-meta .lien-dossier {
  padding: 0;
  border: 0;
  background: none;
  color: var(--vert-fonce);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.activite-meta .lien-dossier:hover { color: var(--vert); }

.activite-resume {
  display: -webkit-box;
  overflow: hidden;
  max-width: 78ch;
  margin-top: 6px;
  color: var(--encre);
  font-size: 0.86rem;
  line-height: 1.45;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.activite-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-top: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 140ms ease;
}

.activite:hover .activite-actions,
.activite:focus-within .activite-actions { opacity: 1; }

/* --- État vide soigné --------------------------------------------------- */

.vide-soigne {
  display: grid;
  padding: 54px 28px 58px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  gap: 7px;
  justify-items: center;
  text-align: center;
}

.vide-glyphes {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
}

.vide-glyphes span {
  display: grid;
  width: 34px;
  height: 34px;
  border: 1px solid var(--trait);
  border-radius: 50%;
  color: var(--trait-fort);
  place-items: center;
}

.vide-soigne strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.06rem;
  font-stretch: 104%;
  font-weight: 700;
}

.vide-soigne p {
  max-width: 48ch;
  color: var(--gris);
  font-size: 0.89rem;
}

.vide-soigne .primary { margin-top: 12px; }

/* --- Adaptations -------------------------------------------------------- */

/* --- Clients : portefeuille -------------------------------------------- */

/* auto-fill (et non auto-fit) : un groupe d'un seul dossier garde la largeur
   d'une fiche au lieu de s'étirer sur toute la ligne. */
.groupe-clients .client-grid {
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: stretch;
}

.groupe-clients { margin-bottom: 26px; }
.groupe-clients:last-child { margin-bottom: 0; }

.client-card-plus {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.client-card-plus:focus-visible { border-color: var(--vert); }

.client-jauge { margin-top: auto; }

.client-jauge-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.client-jauge-tete span {
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.75rem;
  font-stretch: 104%;
  font-weight: 700;
}

.client-jauge-tete b {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.95rem;
  font-stretch: 110%;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.client-pied {
  display: flex;
  justify-content: space-between;
  gap: 4px 14px;
  flex-wrap: wrap;
  margin-top: 10px;
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.client-pied .est-actif { color: var(--gris); }
.client-pied .est-retard { color: var(--rouge-fonce); }

.client-actions {
  margin-top: 11px;
  padding-top: 8px;
  border-top: 1px solid var(--trait);
}

.client-actions .ghost { min-height: 30px; padding: 4px 10px; }

/* --- Contacts : répertoire ---------------------------------------------- */

.c-contact {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pastille-initiales {
  display: grid;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--vert-voile);
  color: var(--vert-fonce);
  font-family: var(--display);
  font-size: 0.78rem;
  font-stretch: 104%;
  font-weight: 700;
  flex-shrink: 0;
  place-items: center;
}

.c-contact-texte { min-width: 0; }

.c-lien a {
  color: var(--encre);
  font-size: 0.87rem;
  text-decoration: none;
}

.c-lien a:hover { color: var(--vert-fonce); text-decoration: underline; text-underline-offset: 2px; }

.filtre-large { flex: 2 1 260px; max-width: 340px; }
.filtre input[type="search"] { min-height: 38px; padding: 7px 10px; font-size: 0.88rem; }

@media (max-width: 900px) {
  .pipeline-col,
  .pipeline-col.est-terminal { flex: 0 0 min(84vw, 286px); }
  .pipeline-separateur { display: none; }

  .pipeline-bilan { padding: 18px 18px 18px; }
  .pipeline-bilan-valeur strong { font-size: 1.7rem; }
  .pipeline-bilan-conclus { gap: 22px; }

  .pipeline-bilan-cote {
    align-items: flex-start;
    width: 100%;
    flex-direction: column-reverse;
  }

  .pipeline-bilan-conclus > div { text-align: left; }

  .page-tete {
    align-items: flex-start;
    flex-direction: column;
    gap: 14px;
  }

  .filtre { max-width: none; }

  .filtres-fin {
    width: 100%;
    margin-left: 0;
    justify-content: space-between;
  }

  .activite {
    grid-template-columns: 36px minmax(0, 1fr);
    row-gap: 10px;
  }

  .activite-actions {
    grid-column: 2;
    opacity: 1;
  }
}

@media (max-width: 620px) {
  .filtres { padding: 13px 13px 14px; }
  .vide-soigne { padding: 40px 18px 44px; }
}

/* --- Commercial & onboarding -------------------------------------------- */
.onboarding-stepper{display:grid;grid-template-columns:repeat(5,minmax(120px,1fr));gap:10px;margin-bottom:20px}.onboarding-stepper>div{background:var(--blanc);border:1px solid var(--trait);border-radius:var(--r-m);padding:14px;display:flex;align-items:center;gap:10px}.onboarding-stepper b{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;background:var(--vert-voile);color:var(--vert)}.onboarding-stepper span{font-weight:700;font-size:.86rem}.commercial-list{display:grid;gap:12px}.commercial-card{border:1px solid var(--trait);border-radius:var(--r-m);padding:18px;background:var(--papier)}.commercial-card-main{display:flex;justify-content:space-between;gap:20px;align-items:flex-start}.commercial-card-title{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.commercial-card-title strong{font-size:1.05rem}.commercial-card p{margin:6px 0}.commercial-steps{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}.commercial-steps span{padding:5px 8px;border-radius:999px;border:1px solid var(--trait);font-size:.72rem;color:var(--gris)}.commercial-steps span.done{border-color:var(--vert);color:var(--vert);background:var(--vert-voile)}.commercial-actions{margin-top:15px;border-top:1px solid var(--trait);padding-top:14px}.commercial-form{margin-top:18px}.commercial-settings{max-width:1100px}.commercial-settings .callout{margin-top:16px}@media(max-width:900px){.onboarding-stepper{grid-template-columns:1fr 1fr}.commercial-card-main{display:block}.commercial-steps{justify-content:flex-start;margin-top:12px}}@media(max-width:560px){.onboarding-stepper{grid-template-columns:1fr}.commercial-actions>*{width:100%}}

/* --- Dossier client : en-tête et navigation premium ---------------------- */
.workspace-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  margin-bottom: 20px;
  padding: 4px 0 20px;
  border-bottom: 1px solid var(--trait);
}
.workspace-identity { min-width: 0; flex: 1; }
.workspace-kicker {
  margin-bottom: 7px;
  color: var(--vert);
  font-family: var(--display);
  font-size: 0.72rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: 0.075em;
}
.workspace-title-row { display: flex; align-items: center; gap: var(--e-5); }

/* Le bloc de texte prend la place disponible pour que l'anneau d'avancement
   se pose au bord et non contre le dernier mot de la ligne méta. */
.workspace-title-row > div:first-child { flex: 1; min-width: 0; }
.workspace-title-row h2 {
  margin-bottom: 5px;
  font-size: clamp(1.55rem, 2.2vw, 2rem);
  font-weight: 800;
  line-height: 1.05;
}
.workspace-meta {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  color: var(--gris);
  font-size: 0.88rem;
}
/* La puce de séparation est dessinée, pas écrite : elle disparaît proprement
   quand la ligne passe en pile sur téléphone. */
.workspace-meta > span + span::before {
  margin-right: 7px;
  color: var(--trait-fort);
  content: "•";
  font-size: 0.7rem;
}
.workspace-score {
  display: grid;
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
  padding: 4px;
  border-radius: 50%;
  background: conic-gradient(var(--vert) var(--score), var(--trait) 0);
  place-items: center;
}
.workspace-score > span {
  display: grid;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--blanc);
  text-align: center;
  place-content: center;
}
.workspace-score strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.9rem;
  font-stretch: 104%;
  line-height: 1;
}
.workspace-score small {
  margin-top: 3px;
  color: var(--gris-clair);
  font-size: 0.56rem;
  line-height: 1;
}
.workspace-actions {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
}
.workspace-action {
  min-height: 38px;
  padding: 8px 14px;
  border-radius: 10px;
  text-decoration: none;
}
.workspace-action small {
  padding: 2px 5px;
  border-radius: 5px;
  background: var(--papier);
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 600;
}
.workspace-nav {
  position: relative;
  z-index: 12;
  margin: 0 0 22px;
  border-bottom: 1px solid var(--trait);
}
.workspace-nav-scroll {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  overflow: visible;
}
.workspace-tab,
.workspace-more > summary {
  position: relative;
  min-height: 42px;
  padding: 10px 10px 11px;
  border: 0;
  border-radius: 8px 8px 0 0;
  background: transparent;
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.79rem;
  font-stretch: 104%;
  font-weight: 650;
  line-height: 1.1;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
}
.workspace-more > summary::-webkit-details-marker { display: none; }
.workspace-tab::after,
.workspace-more > summary::after {
  position: absolute;
  right: 10px;
  bottom: -1px;
  left: 10px;
  height: 2px;
  border-radius: 999px 999px 0 0;
  background: transparent;
  content: "";
}
.workspace-tab:hover,
.workspace-more > summary:hover { background: var(--vert-voile); color: var(--vert-fonce); }
.workspace-tab.active,
.workspace-more.active > summary { color: var(--marine); }
.workspace-tab.active::after,
.workspace-more.active > summary::after { background: var(--vert); }
.workspace-more { position: relative; flex: 0 0 auto; }
.workspace-more > summary span {
  display: inline-block;
  margin-left: 3px;
  color: var(--gris-clair);
  transition: transform 140ms ease;
}
.workspace-more[open] > summary span { transform: rotate(180deg); }
.workspace-more-menu {
  display: grid;
  position: absolute;
  z-index: 30;
  top: calc(100% + 7px);
  right: 0;
  width: 230px;
  padding: 7px;
  border: 1px solid var(--trait);
  border-radius: 12px;
  background: var(--blanc);
  box-shadow: 0 18px 45px rgba(12, 27, 42, 0.14);
  gap: 2px;
}
.workspace-more-menu::before {
  position: absolute;
  top: -5px;
  right: 22px;
  width: 9px;
  height: 9px;
  border-top: 1px solid var(--trait);
  border-left: 1px solid var(--trait);
  background: var(--blanc);
  content: "";
  transform: rotate(45deg);
}
.workspace-more-menu button {
  position: relative;
  z-index: 1;
  width: 100%;
  min-height: 35px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.79rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.workspace-more-menu button:hover { background: var(--papier); color: var(--marine); }
.workspace-more-menu button.active { background: var(--vert-voile); color: var(--vert-fonce); }
.workspace-content { min-width: 0; }

@media (max-width: 1180px) {
  .workspace-nav-scroll { padding-bottom: 2px; overflow-x: auto; scrollbar-width: thin; }
}
@media (max-width: 760px) {
  .workspace-head { align-items: stretch; flex-direction: column; gap: 16px; }
  .workspace-title-row { align-items: flex-start; justify-content: space-between; }
  .workspace-score { width: 58px; height: 58px; }
  .workspace-actions { width: 100%; }
  .workspace-actions > * { flex: 1 1 auto; }
  .workspace-action small { display: none; }
}


/* ==========================================================================
   V11 — Poste de commande Repère
   Le principe du système : l'application est un registre de travail, pas un
   tableau de bord. On garde le papier, les filets et la typographie de
   Repère Québec ; on ajoute ce qui manquait pour piloter deux métiers :
   un code d'état à cinq voix, une trame de page unique, et « le fil »,
   la seule pièce autorisée à être spectaculaire.
   ========================================================================== */

/* --- 1. Code d'état -------------------------------------------------------
   Cinq voix, jamais plus. Vert = fait. Or = attend. Rouge = urgent.
   Bleu = en cours. Gris = brouillon. Chaque état porte aussi un mot :
   la couleur seule ne dit jamais l'information.                             */

.etat {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px 4px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--display);
  font-size: 0.72rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.25;
  white-space: nowrap;
  gap: 6px;
}

.etat::before {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentcolor;
  content: "";
}

.etat-fait { border-color: #c3ddcd; background: var(--vert-voile); color: var(--vert-fonce); }
.etat-attente { border-color: #ecd7a1; background: var(--or-voile); color: var(--or-fonce); }
.etat-urgent { border-color: #eec4bb; background: var(--rouge-voile); color: var(--rouge-fonce); }
.etat-cours { border-color: #c3d5e2; background: var(--bleu-voile); color: var(--bleu-fonce); }
.etat-inactif { border-color: var(--trait); background: var(--papier); color: var(--gris); }

/* Sans pastille : pour les colonnes denses où le point ajoute du bruit. */
.etat.nu::before { display: none; }

/* --- 2. Trame de page -----------------------------------------------------
   Toutes les pages ouvrent pareil : mention de section, titre, une phrase
   qui dit à quoi sert la page, actions à droite. Rien d'autre au-dessus. */

.tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  margin-bottom: 24px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--trait);
}

.tete-texte { min-width: 0; max-width: 62ch; }

.tete-mention {
  margin-bottom: 6px;
  color: var(--vert);
  font-family: var(--display);
  font-size: 0.72rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.tete h2 {
  margin-bottom: 7px;
  font-size: clamp(1.5rem, 2.1vw, 1.95rem);
  font-weight: 800;
  line-height: 1.06;
}

.tete p {
  color: var(--gris);
  font-size: 0.93rem;
  line-height: 1.5;
}

.tete-actions {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  flex-wrap: wrap;
  gap: 9px;
}

/* --- 3. Le fil ------------------------------------------------------------
   La signature de l'application. Neuf stations, un filet continu, un chiffre
   réel par station. Ce n'est pas une décoration de processus : chaque station
   est un lien vers les dossiers qui s'y trouvent. C'est la seule pièce de
   l'interface qui a le droit d'occuper toute la largeur.                    */

.fil {
  position: relative;
  margin-bottom: 26px;
  padding: 26px 26px 22px;
  border-radius: var(--r-l);
  background: var(--marine);
  color: var(--sur-marine-fort);
  overflow: hidden;
}

.fil::after {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--vert) 0%, var(--or) 100%);
  content: "";
}

.fil-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 22px;
}

.fil-tete p {
  color: var(--or);
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.fil-tete span {
  color: var(--sur-marine);
  font-size: 0.84rem;
}

.fil-piste { position: relative; }

.fil-stations {
  display: grid;
  position: relative;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 0;
}

/* Le filet qui relie les stations : une seule ligne, derrière les jalons. */
.fil-stations::before {
  position: absolute;
  top: 13px;
  right: 6%;
  left: 6%;
  height: 1px;
  background: rgba(255, 255, 255, 0.18);
  content: "";
}

.fil-station {
  display: grid;
  position: relative;
  z-index: 1;
  padding: 0 6px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;
  gap: 7px;
  justify-items: center;
}

.fil-jalon {
  display: grid;
  width: 26px;
  height: 26px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  background: var(--marine);
  color: var(--sur-marine-fort);
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  place-items: center;
  transition: transform 160ms var(--sortie), background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}

/* Une station occupée s'allume ; une station vide reste un simple repère. */
.fil-station.occupee .fil-jalon {
  border-color: var(--or);
  background: var(--or);
  color: var(--marine);
}

.fil-station:hover .fil-jalon,
.fil-station:focus-visible .fil-jalon {
  transform: scale(1.14);
}

.fil-station.vide .fil-jalon { color: rgba(255, 255, 255, 0.4); }

.fil-station b {
  color: var(--blanc);
  font-family: var(--display);
  font-size: 0.79rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.2;
}

.fil-station.vide b { color: var(--sur-marine); }

.fil-station small {
  color: var(--sur-marine);
  font-size: 0.72rem;
}

.fil-pied {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  gap: 10px;
}

.fil-pied .primary { background: var(--or); border-color: var(--or); color: var(--marine); }
.fil-pied .primary:hover { background: #e8bd52; border-color: #e8bd52; }
.fil-pied .secondary {
  border-color: rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
}
.fil-pied .secondary:hover { background: rgba(255, 255, 255, 0.14); }

/* --- 4. La file : « qu'est-ce que je dois faire ensuite ? » ----------------
   Une ligne = un travail à faire. Le chiffre à gauche, l'action au centre,
   la flèche à droite. Rien d'autre : ni graphique, ni pourcentage.          */

.file {
  display: grid;
  gap: 0;
}

.file-ligne {
  display: grid;
  align-items: center;
  width: 100%;
  padding: 14px 14px 14px 0;
  border: 0;
  border-bottom: 1px solid var(--trait);
  border-left: 3px solid transparent;
  background: transparent;
  color: inherit;
  font: inherit;
  grid-template-columns: 54px minmax(0, 1fr) auto auto;
  text-align: left;
  cursor: pointer;
  gap: 14px;
  /* `padding-left` déclenche une remise en page à chaque image du survol.
     Le décalage passe donc par un `transform`, qui reste sur le GPU ;
     le filet de gauche, lui, ne change que de couleur. */
  transition: background-color var(--d-1) ease, border-color var(--d-1) ease, transform var(--d-1) var(--sortie);
}

.file-ligne:last-child { border-bottom: 0; }

.file-ligne:focus-visible {
  background: var(--accent-voile);
  border-left-color: var(--accent);
}

@media (hover: hover) and (pointer: fine) {
  .file-ligne:hover {
    background: var(--accent-voile);
    border-left-color: var(--accent);
    transform: translateX(6px);
  }
}

.file-nombre {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.7rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.file-ligne.urgent .file-nombre { color: var(--rouge-fonce); }
.file-ligne.attente .file-nombre { color: var(--or-fonce); }
.file-ligne.cours .file-nombre { color: var(--bleu); }

.file-texte { display: grid; min-width: 0; gap: 2px; }

.file-texte strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.98rem;
  font-stretch: 104%;
  font-weight: 700;
}

.file-texte span {
  color: var(--gris);
  font-size: 0.83rem;
}

.file-fleche {
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 1.05rem;
  transition: transform 150ms var(--sortie), color 150ms ease;
}

.file-ligne:focus-visible .file-fleche { color: var(--accent); }

@media (hover: hover) and (pointer: fine) {
  .file-ligne:hover .file-fleche { color: var(--accent); transform: translateX(3px); }
}

/* Le calme mérite d'être affiché aussi clairement qu'une alerte. */
.file-calme {
  display: grid;
  padding: 26px 20px;
  border: 1px dashed var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--vert-voile);
  gap: 4px;
  text-align: center;
}

.file-calme strong {
  color: var(--vert-fonce);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
}

.file-calme span { color: var(--vert-fonce); font-size: 0.87rem; opacity: 0.85; }

/* --- 5. Accueil : salutation et actions rapides ---------------------------- */

.accueil {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 26px;
  margin-bottom: 22px;
}

.accueil h2 {
  font-size: clamp(1.7rem, 2.6vw, 2.3rem);
  font-weight: 800;
  line-height: 1.04;
}

.accueil p {
  margin-top: 6px;
  color: var(--gris);
  font-size: 0.98rem;
}

.accueil-date {
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.76rem;
  text-align: right;
  white-space: nowrap;
}

.raccourcis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: 28px;
  gap: 10px;
}

.raccourci {
  display: grid;
  align-items: center;
  min-height: 52px;
  padding: 11px 15px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--blanc);
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.9rem;
  font-stretch: 104%;
  font-weight: 700;
  grid-template-columns: minmax(0, 1fr) auto;
  text-align: left;
  cursor: pointer;
  gap: 10px;
  box-shadow: var(--ombre-1);
  transition: border-color 140ms ease, transform 140ms var(--sortie), box-shadow 140ms ease;
}

.raccourci:hover {
  border-color: var(--vert);
  box-shadow: var(--ombre-2);
  transform: translateY(-2px);
}

.raccourci span {
  color: var(--gris-clair);
  font-family: var(--texte);
  font-size: 1.05rem;
  font-weight: 400;
}

.raccourci:hover span { color: var(--vert); }

/* --- 6. Les deux univers --------------------------------------------------
   Un registre par métier : libellé à gauche, valeur à droite, filet entre les
   lignes. La comptabilité d'une entreprise se lit comme ça depuis toujours. */

.univers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.registre {
  display: flex;
  flex-direction: column;
  padding: 22px 24px 20px;
  border: 1px solid var(--trait);
  border-top: 3px solid var(--vert);
  border-radius: var(--r-m);
  background: var(--blanc);
  box-shadow: var(--ombre-1);
}

/* Repère Sécurité porte son accent, pas la couleur de structure : le marine
   sert au châssis de l'application et ne peut pas identifier un service. */
.registre.securite { border-top-color: var(--sec-600); }

.registre-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.registre-tete h3 {
  font-size: 1.12rem;
  font-weight: 800;
}

.registre-tete p {
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.84rem;
}

.registre-lignes { display: grid; }

.registre-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  padding: 10px 0;
  border: 0;
  border-bottom: 1px solid var(--trait);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  gap: 14px;
}

.registre-ligne:last-child { border-bottom: 0; }
.registre-ligne:hover .registre-libelle { color: var(--vert-fonce); }
.registre-ligne:hover .registre-valeur { color: var(--vert); }

.registre-libelle {
  color: var(--encre);
  font-size: 0.89rem;
  transition: color 130ms ease;
}

/* Le filet de conduite : la ligne pointillée du registre comptable. */
.registre-conduite {
  min-width: 12px;
  flex: 1;
  border-bottom: 1px dotted var(--trait-fort);
  transform: translateY(-4px);
}

.registre-valeur {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-stretch: 104%;
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: color 130ms ease;
}

.registre-valeur.est-urgent { color: var(--rouge-fonce); }
.registre-valeur.est-attente { color: var(--or-fonce); }
.registre-valeur.est-calme { color: var(--gris-clair); font-weight: 600; }

.registre-pied {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 16px;
  gap: 9px;
}

/* --- 7. Tableaux de travail ----------------------------------------------
   Une application de travail se lit en lignes. Dense, mais aérée par des
   filets clairs ; en-tête collant dès qu'une liste dépasse l'écran.        */

.table-outil {
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow: hidden;
  box-shadow: var(--ombre-1);
}

.table-defile { max-height: none; overflow-x: auto; }

.table-outil table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.table-outil thead th {
  position: sticky;
  z-index: var(--z-collant);
  top: 0;
  padding: 11px 14px;
  border-bottom: 1px solid var(--trait-fort);
  background: var(--papier);
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.72rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
}

.table-outil tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--trait);
  vertical-align: middle;
}

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

.table-outil tbody tr {
  transition: background-color 120ms ease;
}

.table-outil tbody tr:hover { background: #f6f8f4; }

.table-outil .cellule-forte {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
}

.table-outil .cellule-note {
  display: block;
  margin-top: 2px;
  color: var(--gris);
  font-size: 0.79rem;
}

.table-outil .cellule-nombre {
  font-family: var(--mono);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.table-outil .cellule-action { text-align: right; white-space: nowrap; }

/* Une date se lit d'un bloc : jamais coupée entre le jour et le mois. */
.table-outil .cellule-date { white-space: nowrap; }
.table-outil td .etat { white-space: nowrap; }

/* L'action de ligne reste discrète jusqu'à ce qu'on s'approche de la ligne. */
.table-outil .action-ligne { opacity: 0.42; transition: opacity 120ms ease; }
.table-outil tr:hover .action-ligne,
.table-outil tr:focus-within .action-ligne { opacity: 1; }

@media (hover: none) {
  .table-outil .action-ligne { opacity: 1; }
}

/* --- 8. Barre de filtres -------------------------------------------------- */

.barre-filtres {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 16px;
  gap: 8px;
}

.filtre-jeton {
  padding: 7px 13px;
  border: 1px solid var(--trait-fort);
  border-radius: 999px;
  background: var(--blanc);
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.8rem;
  font-stretch: 104%;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 130ms ease, background-color 130ms ease, color 130ms ease;
}

.filtre-jeton:hover { border-color: var(--vert); color: var(--vert-fonce); }

.filtre-jeton.actif {
  border-color: var(--marine);
  background: var(--marine);
  color: var(--blanc);
}

.filtre-jeton b {
  margin-left: 5px;
  font-family: var(--mono);
  font-size: 0.74rem;
  font-weight: 600;
  opacity: 0.7;
}

.barre-filtres .recherche-liste {
  min-width: 200px;
  max-width: 300px;
  flex: 1;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  font-size: 0.86rem;
}

.barre-filtres-fin {
  display: flex;
  align-items: center;
  margin-left: auto;
  gap: 10px;
  color: var(--gris);
  font-size: 0.82rem;
}

/* --- 9. Dossier : la ligne dépliable des mandats -------------------------- */

.dossier {
  margin-bottom: 12px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow: hidden;
  box-shadow: var(--ombre-1);
}

.dossier-tete {
  display: grid;
  align-items: center;
  padding: 16px 20px;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto;
  gap: 18px;
}

.dossier-identite { min-width: 0; }

.dossier-identite strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-stretch: 104%;
  font-weight: 700;
}

.dossier-identite span {
  color: var(--gris);
  font-size: 0.82rem;
}

.dossier-suite {
  display: grid;
  gap: 3px;
}

.dossier-suite b {
  color: var(--or-fonce);
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 700;
}

.dossier-suite span {
  color: var(--gris);
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Le petit fil : la même grammaire que le grand, à l'échelle d'une ligne. */
.jalons {
  display: flex;
  align-items: center;
  padding: 0 20px 16px;
  gap: 0;
}

.jalon {
  display: grid;
  position: relative;
  flex: 1;
  gap: 6px;
  justify-items: center;
}

.jalon::before {
  position: absolute;
  z-index: 0;
  top: 7px;
  right: 50%;
  left: -50%;
  height: 2px;
  background: var(--trait);
  content: "";
}

.jalon:first-child::before { display: none; }
.jalon.est-fait::before { background: var(--vert); }

.jalon i {
  z-index: 1;
  width: 14px;
  height: 14px;
  border: 2px solid var(--trait-fort);
  border-radius: 50%;
  background: var(--blanc);
}

.jalon.est-fait i { border-color: var(--vert); background: var(--vert); }
.jalon.est-courant i {
  border-color: var(--or);
  background: var(--or);
  box-shadow: 0 0 0 4px var(--or-voile);
}

.jalon span {
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 0.71rem;
  font-weight: 700;
  text-align: center;
}

.jalon.est-fait span { color: var(--vert-fonce); }
.jalon.est-courant span { color: var(--marine); }

/* --- 10. Constats : trier par ce qui doit être corrigé en premier --------- */

.constat {
  display: grid;
  align-items: start;
  padding: 16px 18px 16px 0;
  border-bottom: 1px solid var(--trait);
  grid-template-columns: 5px minmax(0, 1fr) auto;
  gap: 16px;
}

.constat:last-child { border-bottom: 0; }

.constat-rang {
  align-self: stretch;
  min-height: 44px;
  border-radius: 0 3px 3px 0;
  background: var(--trait-fort);
}

.constat.critique .constat-rang { background: var(--rouge); }
.constat.elevee .constat-rang { background: #d98026; }
.constat.moyenne .constat-rang { background: var(--or); }
.constat.faible .constat-rang { background: var(--bleu); }
.constat.information .constat-rang { background: var(--trait-fort); }

.constat-corps { min-width: 0; }

.constat-haut {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 5px;
  gap: 8px;
}

.constat-haut h3 {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
}

.constat-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  color: var(--gris);
  font-size: 0.81rem;
  gap: 6px;
}

.constat-meta em {
  color: var(--trait-fort);
  font-style: normal;
}

.constat-impact {
  max-width: 78ch;
  margin-top: 7px;
  color: var(--encre);
  font-size: 0.87rem;
  line-height: 1.5;
}

.constat-correction {
  margin-top: 10px;
  padding: 10px 13px;
  border-left: 3px solid var(--vert);
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: var(--vert-voile);
}

.constat-correction strong {
  display: block;
  margin-bottom: 2px;
  color: var(--vert-fonce);
  font-family: var(--display);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.constat-correction p {
  color: var(--encre);
  font-size: 0.87rem;
  line-height: 1.5;
}

.constat-cote {
  display: grid;
  gap: 8px;
  justify-items: end;
}

.constat-reference {
  padding: 3px 7px;
  border: 1px solid var(--trait);
  border-radius: var(--r-xs);
  background: var(--papier);
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.72rem;
  white-space: nowrap;
}

/* --- 11. Livrables : la bibliothèque de rapports -------------------------- */

.livrables {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: 16px;
}

.livrable {
  display: flex;
  position: relative;
  flex-direction: column;
  padding: 20px 20px 18px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow: hidden;
  box-shadow: var(--ombre-1);
  transition: transform 150ms var(--sortie), box-shadow 150ms ease;
}


/* Le liseré : la tranche du document posé sur la table. */
.livrable::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 4px;
  background: var(--marine);
  content: "";
}

.livrable-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.livrable-type {
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.livrable h3 {
  margin-top: 4px;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
}

.livrable-client {
  margin-top: 4px;
  color: var(--gris);
  font-size: 0.83rem;
}

.livrable-note {
  display: flex;
  align-items: baseline;
  margin: 4px 0 14px;
  gap: 6px;
}

.livrable-note b {
  color: var(--marine);
  font-family: var(--display);
  font-size: 2rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.livrable-note span { color: var(--gris); font-size: 0.82rem; }

.livrable-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--trait);
  gap: 10px;
}

.livrable-pied small {
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.73rem;
}

/* --- 12. Suivi et retest : avant / après ---------------------------------- */

.suivi {
  display: grid;
  align-items: center;
  padding: 18px 20px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  margin-bottom: 12px;
  background: var(--blanc);
  grid-template-columns: minmax(0, 1.1fr) auto minmax(0, 1.4fr) auto;
  gap: 22px;
  box-shadow: var(--ombre-1);
}

.suivi-client strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
}

.suivi-client span { color: var(--gris); font-size: 0.82rem; }

.suivi-scores {
  display: flex;
  align-items: center;
  gap: 12px;
}

.suivi-score {
  display: grid;
  gap: 2px;
  text-align: center;
}

.suivi-score b {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.5rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.suivi-score small {
  color: var(--gris-clair);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.suivi-fleche { color: var(--trait-fort); font-size: 1.1rem; }
.suivi-score.est-attente b { color: var(--gris-clair); }

.suivi-compteurs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.compteur {
  display: grid;
  min-width: 84px;
  padding: 8px 11px;
  border-radius: var(--r-s);
  background: var(--papier);
  gap: 1px;
}

.compteur b {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.compteur span { color: var(--gris); font-size: 0.74rem; }
.compteur.est-urgent { background: var(--rouge-voile); }
.compteur.est-urgent b { color: var(--rouge-fonce); }
.compteur.est-fait { background: var(--vert-voile); }
.compteur.est-fait b { color: var(--vert-fonce); }

/* --- 13. Assistant Soumission : le parcours en sept étapes ---------------- */

.modal-card.assistant { width: min(880px, 100%); }
.modal-card.large { width: min(780px, 100%); }

.modal-kicker {
  margin-bottom: 3px;
  color: var(--vert);
  font-family: var(--display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.pas {
  display: flex;
  align-items: center;
  padding: 14px 24px;
  border-bottom: 1px solid var(--trait);
  background: var(--papier);
  gap: 0;
}

.pas-item {
  display: flex;
  position: relative;
  align-items: center;
  flex: 1;
  gap: 7px;
}

.pas-item::after {
  height: 1px;
  flex: 1;
  background: var(--trait-fort);
  content: "";
}

.pas-item:last-child { flex: 0 0 auto; }
.pas-item:last-child::after { display: none; }

.pas-item i {
  display: grid;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border: 1px solid var(--trait-fort);
  border-radius: 50%;
  background: var(--blanc);
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-style: normal;
  place-items: center;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}

.pas-item.fait i {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--blanc);
}

/* L'étape courante se distingue du franchi autrement que par la teinte :
   elle est cerclée et claire là où le franchi est plein, et elle garde son
   numéro là où le franchi porte une coche. Lisible sans percevoir la couleur. */
.pas-item.courant i {
  border-color: var(--accent);
  border-width: 2px;
  background: var(--accent-voile);
  color: var(--accent-fonce);
  font-weight: 700;
}

/* Le trait qui relie deux jalons franchis se colore aussi : la progression
   se lit d'un trait continu plutôt qu'en comptant les pastilles. */
.pas-item.fait::after { background: var(--accent); }

.pas-item b {
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

.pas-item.courant b { color: var(--marine); }
.pas-item.fait b { color: var(--vert-fonce); }

/* Le rang compact ne sert que sur téléphone : sept pastilles alignées y
   deviennent illisibles et imposent une largeur minimale à toute la fenêtre. */
.pas-compact { display: none; }

@media (max-width: 900px) {
  .pas-item b { display: none; }
  .pas-item:last-child { flex: 0 0 auto; }
  .pas-item { min-width: 0; }
}

@media (max-width: 620px) {
  .pas {
    display: grid;
    padding: 12px 16px;
    gap: 8px;
  }

  .pas-item { display: none; }

  .pas-compact {
    display: grid;
    gap: 7px;
  }

  .pas-compact b {
    color: var(--marine);
    font-family: var(--display);
    font-size: 0.82rem;
    font-stretch: 104%;
    font-weight: 700;
  }

  .pas-compact span {
    color: var(--gris);
    font-family: var(--mono);
    font-size: 0.72rem;
  }

  .pas-compact-tete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
  }

  .pas-jauge {
    height: 4px;
    border-radius: 999px;
    background: var(--trait);
    overflow: hidden;
  }

  .pas-jauge > i {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--vert);
    transition: width 220ms var(--sortie);
  }
}

.assistant-intro {
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--trait);
}

.assistant-intro h3 {
  margin-bottom: 5px;
  font-size: 1.18rem;
  font-weight: 800;
}

.assistant-intro p { color: var(--gris); font-size: 0.9rem; line-height: 1.5; }

/* Choix visuels : des cartes-radio, parce qu'on choisit une nature, pas une
   valeur dans une liste. */
.choix {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 9px;
}

.choix label {
  display: block;
  position: relative;
  padding: 13px 15px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--blanc);
  cursor: pointer;
  transition: border-color 130ms ease, background-color 130ms ease, box-shadow 130ms ease;
}

.choix label:hover { border-color: var(--vert-clair); }

.choix input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.choix b {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
}

.choix span {
  display: block;
  margin-top: 3px;
  color: var(--gris);
  font-family: var(--texte);
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.4;
}

.choix label:has(input:checked) {
  border-color: var(--vert);
  background: var(--vert-voile);
  box-shadow: inset 0 0 0 1px var(--vert);
}

.choix label:has(input:focus-visible) {
  outline: 3px solid var(--vert);
  outline-offset: 2px;
}

/* Cases à cocher de caractéristiques : deux colonnes, cible tactile pleine. */
.caracteristiques {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 0;
  border: 0;
  margin: 0;
  gap: 8px;
}

.caracteristiques legend {
  padding: 0;
  margin-bottom: 10px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.88rem;
  font-weight: 700;
}

.caracteristiques label {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 13px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  font-family: var(--texte);
  font-size: 0.87rem;
  font-weight: 500;
  cursor: pointer;
  gap: 10px;
  transition: border-color 130ms ease, background-color 130ms ease;
}

.caracteristiques label:has(input:checked) {
  border-color: var(--vert);
  background: var(--vert-voile);
  color: var(--vert-fonce);
  font-weight: 600;
}

.caracteristiques input { width: 17px; height: 17px; accent-color: var(--vert); }

/* La recommandation : le moment où le moteur parle. Il propose, il ne décide
   pas — d'où la mention explicite sous chaque chiffre. */
.recommandation {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  min-height: min-content;
  margin-bottom: 18px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow: hidden;
}

.recommandation > div {
  padding: 16px 17px;
  border-right: 1px solid var(--trait);
}

.recommandation > div:last-child { border-right: 0; }

.recommandation span {
  display: block;
  margin-bottom: 6px;
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.recommandation strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.32rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.recommandation small {
  display: block;
  margin-top: 4px;
  color: var(--gris);
  font-size: 0.78rem;
}

.recommandation .est-cle { background: var(--marine); }
.recommandation .est-cle span { color: var(--or); }
.recommandation .est-cle strong { color: var(--blanc); }
.recommandation .est-cle small { color: var(--sur-marine); }

.pourquoi {
  padding: 15px 17px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--papier);
}

.pourquoi strong {
  display: block;
  margin-bottom: 8px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 700;
}

.pourquoi ul {
  display: grid;
  padding: 0;
  margin: 0;
  gap: 5px;
  list-style: none;
}

.pourquoi li {
  position: relative;
  padding-left: 17px;
  color: var(--encre);
  font-size: 0.87rem;
  line-height: 1.45;
}

.pourquoi li::before {
  position: absolute;
  top: 7px;
  left: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--or);
  content: "";
}

/* Validation humaine : le prix retenu doit dominer le prix suggéré. */
.validation {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  min-height: min-content;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  overflow: hidden;
}

.validation-moteur {
  padding: 20px;
  border-right: 1px solid var(--trait);
  background: var(--papier);
}

.validation-moteur span,
.validation-humaine span {
  display: block;
  margin-bottom: 7px;
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.validation-moteur span { color: var(--gris); }

.validation-moteur b {
  color: var(--gris);
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.validation-moteur p {
  margin-top: 8px;
  color: var(--gris);
  font-size: 0.81rem;
  line-height: 1.45;
}

.validation-humaine {
  padding: 20px;
  border-left: 3px solid var(--or);
  background: var(--blanc);
}

.validation-humaine span { color: var(--or-fonce); }

.validation-humaine label {
  display: grid;
  gap: 6px;
}

.validation-humaine input {
  height: 56px;
  padding: 0 16px;
  border: 2px solid var(--marine);
  border-radius: var(--r-s);
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.validation-humaine p {
  margin-top: 9px;
  color: var(--gris);
  font-size: 0.81rem;
  line-height: 1.45;
}

/* Fin de parcours : une confirmation calme, pas une fanfare. */
.termine {
  display: grid;
  padding: 34px 24px;
  gap: 10px;
  text-align: center;
  justify-items: center;
}

.termine i {
  display: grid;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--vert-voile);
  color: var(--vert);
  font-size: 1.5rem;
  font-style: normal;
  place-items: center;
}

.termine h3 { font-size: 1.3rem; font-weight: 800; }
.termine p { max-width: 46ch; color: var(--gris); font-size: 0.92rem; line-height: 1.5; }

/* --- 14. Fiche client : les deux services en tête -------------------------- */

/* Trois services depuis que Repère Maintenance existe. `auto-fit` évite de
   figer le compte : une bande à deux cartes sur un dossier qui n'en montre
   que deux resterait équilibrée, et un quatrième service un jour n'obligera
   pas à revenir ici. */
.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  margin-bottom: 22px;
  gap: 14px;
}

.service {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border: 1px solid var(--trait);
  border-left: 4px solid var(--vert);
  border-radius: var(--r-m);
  background: var(--blanc);
  gap: 16px;
}

.service.entretien { border-left-color: var(--mnt-600); }
.service.securite { border-left-color: var(--marine); }
.service.inactif { border-left-color: var(--trait-fort); background: var(--papier); }

.service-nom {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.97rem;
  font-stretch: 104%;
  font-weight: 700;
}

.service-quoi { margin-top: 2px; color: var(--gris); font-size: 0.82rem; }

/* --- 15. Squelettes de chargement ----------------------------------------- */

.squelette {
  display: grid;
  gap: 12px;
}

.squelette-barre {
  height: 14px;
  border-radius: 999px;
  background: linear-gradient(90deg, #e6eae4 0%, #f1f4ef 50%, #e6eae4 100%);
  background-size: 200% 100%;
  animation: chargement 1.25s ease-in-out infinite;
}

.squelette-bloc {
  height: 96px;
  /* Cette gouttière vivait dans un attribut `style=` que la CSP ignore. Le
     bloc du squelette collait donc à la barre qui le précède. */
  margin-top: 10px;
  border-radius: var(--r-m);
  background: linear-gradient(90deg, #e6eae4 0%, #f1f4ef 50%, #e6eae4 100%);
  background-size: 200% 100%;
  animation: chargement 1.25s ease-in-out infinite;
}

.squelette-barre.court { width: 34%; }
.squelette-barre.moyen { width: 62%; }

@keyframes chargement {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .squelette-barre,
  .squelette-bloc { animation: none; }
}

/* --- 16. Infobulle -------------------------------------------------------- */

.infobulle {
  position: relative;
  border-bottom: 1px dotted var(--gris-clair);
  cursor: help;
}

.infobulle::after {
  position: absolute;
  z-index: var(--z-menu);
  bottom: calc(100% + 8px);
  left: 50%;
  width: max-content;
  max-width: 260px;
  padding: 8px 11px;
  border-radius: var(--r-s);
  background: var(--marine);
  color: var(--blanc);
  content: attr(data-infobulle);
  font-family: var(--texte);
  font-size: 0.79rem;
  font-weight: 400;
  line-height: 1.4;
  opacity: 0;
  pointer-events: none;
  text-transform: none;
  letter-spacing: 0;
  transform: translateX(-50%);
  transition: opacity 130ms ease;
  box-shadow: var(--ombre-2);
}

.infobulle:hover::after,
.infobulle:focus-visible::after { opacity: 1; }

/* --- 17. Reprises et compléments ------------------------------------------ */

.link-button {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--vert-fonce);
  font: inherit;
  font-family: var(--display);
  font-stretch: 104%;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  appearance: none;
}

.link-button:hover { color: var(--vert); text-decoration: underline; }

.secondary.small,
.primary.small,
.ghost.small {
  min-height: 32px;
  padding: 6px 11px;
  font-size: 0.79rem;
}

/* États hérités des vues Sécurité : reconduits sur le code d'état commun. */
.security-status,
.security-severity {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px 4px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}

.s-draft, .quote-draft, .quote-cancelled, .s-cancelled { border-color: var(--trait); background: var(--papier); color: var(--gris); }
.s-authorized, .s-completed, .quote-converted { border-color: #c3ddcd; background: var(--vert-voile); color: var(--vert-fonce); }
.s-queued, .s-running { border-color: #c3d5e2; background: var(--bleu-voile); color: var(--bleu-fonce); }
.s-failed { border-color: #eec4bb; background: var(--rouge-voile); color: var(--rouge-fonce); }
.quote-approved { border-color: #ecd7a1; background: var(--or-voile); color: var(--or-fonce); }
.sev-critical { border-color: #eec4bb; background: var(--rouge-voile); color: var(--rouge-fonce); }
.sev-high { border-color: #f0d3ae; background: #fdf1e2; color: #8f5310; }
.sev-medium { border-color: #ecd7a1; background: var(--or-voile); color: var(--or-fonce); }
.sev-low { border-color: #c3d5e2; background: var(--bleu-voile); color: var(--bleu-fonce); }
.sev-info { border-color: var(--trait); background: var(--papier); color: var(--gris); }

/* Grille secondaire à trois colonnes, utilisée par les vues d'ensemble. */
.grille-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.rangee-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.note-basse {
  margin-top: 14px;
  color: var(--gris);
  font-size: 0.82rem;
  line-height: 1.5;
}

/* Fiche de détail (Mon compte) : libellé à gauche, valeur à droite. La règle
   manquait ; les deux se touchaient. */
.detail-grid {
  display: grid;
  gap: 0;
}

.detail-grid > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--trait);
  gap: 18px;
}

.detail-grid > div:last-child { border-bottom: 0; }
.detail-grid span { color: var(--gris); font-size: 0.87rem; }
.detail-grid strong {
  color: var(--marine);
  font-family: var(--display);
  font-stretch: 104%;
  font-weight: 700;
  text-align: right;
}

/* --- 17b. Confirmation : son propre plan, au-dessus d'un formulaire ------- */

.confirm-backdrop { z-index: calc(var(--z-modale) + 10); }
.confirm-card { width: min(460px, 100%); }
.confirm-card .modal-header { border-bottom-width: 1px; border-bottom-color: var(--trait); }
.confirm-texte {
  color: var(--encre);
  font-size: 0.93rem;
  line-height: 1.55;
}

/* --- 18. Adaptations ------------------------------------------------------ */

@media (max-width: 1180px) {
  .raccourcis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* `minmax(0, 1fr)` et non `1fr` : sinon la colonne garde le plancher de
     largeur minimale de son contenu et le registre déborde de l'écran. */
  .univers { grid-template-columns: minmax(0, 1fr); }
  .recommandation { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .recommandation > div:nth-child(2) { border-right: 0; }
  .recommandation > div:nth-child(-n + 2) { border-bottom: 1px solid var(--trait); }
  .suivi { grid-template-columns: minmax(0, 1fr) auto; row-gap: 16px; }
}

@media (max-width: 1024px) {
  .fil-stations {
    grid-auto-flow: row;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px 8px;
  }

  .fil-stations::before { display: none; }
  .dossier-tete { grid-template-columns: minmax(0, 1fr); gap: 12px; }
}

@media (max-width: 760px) {
  .tete { align-items: stretch; flex-direction: column; gap: 16px; }
  .tete-actions > * { flex: 1 1 auto; }
  .accueil { align-items: flex-start; flex-direction: column; gap: 10px; }
  .accueil-date { text-align: left; }
  .services { grid-template-columns: 1fr; }
  .validation { grid-template-columns: 1fr; }
  .validation-moteur { border-right: 0; border-bottom: 1px solid var(--trait); }
  .constat { grid-template-columns: 5px minmax(0, 1fr); }
  .constat-cote { justify-items: start; grid-column: 2; }
  .suivi { grid-template-columns: 1fr; }
  .grille-3 { grid-template-columns: 1fr; }
  .jalons { overflow-x: auto; }
  .jalon { min-width: 78px; }

  /* Les tableaux denses deviennent des lignes empilées : chaque cellule
     reprend son libellé de colonne. On garde les mêmes données. */
  .table-outil.pliable thead { display: none; }
  .table-outil.pliable tbody tr {
    display: grid;
    padding: 14px 15px;
    border-bottom: 1px solid var(--trait);
    gap: 7px;
  }
  .table-outil.pliable tbody tr:last-child { border-bottom: 0; }
  .table-outil.pliable tbody td {
    display: grid;
    padding: 0;
    border: 0;
    grid-template-columns: 40% minmax(0, 1fr);
    gap: 12px;
  }
  .table-outil.pliable tbody td::before {
    color: var(--gris);
    content: attr(data-colonne);
    font-family: var(--display);
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  /* Tout le contenu de la cellule reste dans la colonne des valeurs, y compris
     la note secondaire qui suivrait la valeur principale. */
  .table-outil.pliable tbody td > * {
    grid-column: 2;
  }

  /* Une pastille d'état garde sa largeur de contenu : étirée, elle ressemble
     à un champ de saisie. */
  .table-outil.pliable tbody td > .etat,
  .table-outil.pliable tbody td > .security-status,
  .table-outil.pliable tbody td > .security-severity {
    justify-self: start;
  }
  .table-outil.pliable tbody td.cellule-nombre,
  .table-outil.pliable tbody td.cellule-action { text-align: left; }
  .table-outil.pliable tbody td.pleine { grid-template-columns: minmax(0, 1fr); }
  .table-outil.pliable tbody td.pleine::before { display: none; }

  /* Une cellule pleine largeur n'a qu'une colonne : ses enfants doivent y
     rester, sinon la règle générale les envoie dans une colonne implicite
     et l'action se retrouve décalée hors de son bloc. */
  .table-outil.pliable tbody td.pleine > * { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
  .raccourcis { grid-template-columns: 1fr; }
  .recommandation { grid-template-columns: 1fr; }
  .recommandation > div { border-right: 0; border-bottom: 1px solid var(--trait); }
  .recommandation > div:last-child { border-bottom: 0; }
  .caracteristiques { grid-template-columns: 1fr; }
  .livrables { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Téléphone — ce que le petit écran impose vraiment
   Sur 390 px, la place se compte. On enlève ce qui décore, on garde ce qui
   fait avancer un dossier, et on rend chaque cible atteignable au pouce.
   ========================================================================== */

@media (max-width: 620px) {
  /* --- Fenêtres : une feuille qui monte du bas, pas une carte flottante --- */
  .modal-backdrop {
    padding: 0;
    align-items: end;
  }

  .modal-card {
    width: 100%;
    max-height: 94vh;
    max-height: 94dvh;
    border-radius: var(--r-l) var(--r-l) 0 0;
  }

  .modal-header {
    padding: 16px 18px 13px;
  }

  .modal-header h2 { font-size: 1.08rem; }

  .modal-form {
    padding: 18px 18px 20px;
    gap: 13px;
  }

  .modal-form > .modal-actions {
    margin: 0 -18px -20px;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
  }

  /* L'action principale prend toute la première rangée ; les secondaires se
     partagent la seconde. Trois boutons empilés mangeraient la moitié de la
     feuille. */
  .modal-actions {
    flex-wrap: wrap;
    justify-content: stretch;
    gap: 8px;
  }

  .modal-actions > * {
    flex: 1 1 calc(50% - 4px);
    justify-content: center;
    min-height: 46px;
  }

  .modal-actions > [type="submit"],
  .modal-actions > .primary,
  .modal-actions > .danger-button {
    order: -1;
    flex: 1 1 100%;
  }

  /* --- En-tête de page : on arrive au contenu plus vite --- */
  .tete {
    margin-bottom: 18px;
    padding-bottom: 14px;
    gap: 14px;
  }

  .tete h2 {
    font-size: 1.32rem;
    margin-bottom: 5px;
  }

  .tete p { font-size: 0.88rem; }

  .tete-actions {
    width: 100%;
    gap: 8px;
  }

  .tete-actions > * {
    flex: 1 1 auto;
    min-height: 44px;
  }

  .accueil h2 { font-size: 1.55rem; }

  /* --- Le fil devient une piste qui défile, au lieu d'une grille très haute
     qui pousse tout le reste sous la ligne de flottaison. --- */
  .fil {
    padding: 18px 0 16px;
  }

  .fil-tete,
  .fil-pied {
    align-items: flex-start;
    flex-direction: column;
    gap: 6px;
    padding: 0 16px;
  }

  .fil-pied { gap: 8px; padding-top: 14px; margin-top: 16px; }
  .fil-pied > * { width: 100%; min-height: 44px; }

  /* Le fil défile ; un voile sur le bord droit dit qu'il continue. */
  .fil-piste {
    position: relative;
  }

  .fil-piste::after {
    position: absolute;
    z-index: 2;
    top: 0;
    right: 0;
    bottom: 8px;
    width: 34px;
    background: linear-gradient(90deg, rgba(12, 27, 42, 0), var(--marine));
    content: "";
    pointer-events: none;
  }

  .fil-stations {
    grid-auto-flow: column;
    grid-auto-columns: 92px;
    grid-template-columns: none;
    padding: 0 16px 6px;
    gap: 0;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }

  .fil-stations::-webkit-scrollbar { display: none; }

  .fil-stations::before {
    right: 16px;
    left: 16px;
    display: block;
  }

  .fil-station { scroll-snap-align: center; }

  /* --- Tableaux repliés : libellés plus courts, actions pleine largeur --- */
  .table-outil.pliable tbody td {
    grid-template-columns: minmax(88px, 34%) minmax(0, 1fr);
    gap: 10px;
  }

  .table-outil.pliable tbody td::before { font-size: 0.7rem; }

  .table-outil.pliable tbody td.cellule-action {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 4px;
  }

  /* Les actions de ligne s'empilent sur toute la largeur : au pouce, deux
     petits boutons côte à côte se manquent. Le style en ligne du gabarit
     (`justify-content: flex-end`) est neutralisé ici. */
  .table-outil.pliable tbody td .rangee-actions {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    justify-content: stretch !important;
    gap: 8px;
  }

  .table-outil.pliable tbody td .rangee-actions > button {
    width: 100%;
    min-height: 44px;
    font-size: 0.86rem;
  }

  /* --- Cibles tactiles : rien sous 40 px de haut --- */
  .filtre-jeton {
    min-height: 40px;
    padding: 8px 14px;
  }

  .secondary.small,
  .primary.small,
  .ghost.small {
    min-height: 40px;
    padding: 9px 13px;
    font-size: 0.84rem;
  }

  /* --- Fiches et rangées d'actions --- */
  .dossier-tete .rangee-actions,
  .suivi .rangee-actions,
  .livrable-pied .rangee-actions {
    width: 100%;
  }

  .dossier-tete .rangee-actions > button,
  .suivi .rangee-actions > button {
    flex: 1 1 auto;
  }

  .jalons {
    padding-bottom: 14px;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }

  .jalons::-webkit-scrollbar { display: none; }

  .constat { padding-right: 14px; gap: 12px; }
  .constat-haut h3 { font-size: 0.95rem; }
  .constat-cote { width: 100%; }
  .constat-cote > button { width: 100%; min-height: 44px; }

  .registre { padding: 18px 16px 16px; }
  .registre-pied > * { flex: 1 1 auto; min-height: 40px; }

  /* Une valeur longue passe à la ligne plutôt que de pousser la carte hors
     de l'écran ; le filet de conduite n'a plus de sens sur deux lignes. */
  .registre-ligne { align-items: baseline; gap: 12px; }
  .registre-libelle { flex: 0 1 auto; }
  .registre-conduite { display: none; }
  .registre-valeur {
    flex: 1 1 auto;
    text-align: right;
    white-space: normal;
  }

  .suivi { padding: 16px; gap: 14px; }
  .suivi-scores { justify-content: flex-start; }

  .validation-humaine input { height: 52px; font-size: 1.35rem; }

  /* --- Dossier client --- */
  .services { gap: 10px; }
  .service { padding: 13px 14px; }

  /* Les onglets défilent ; un voile sur le bord droit le dit. */
  .workspace-nav {
    position: relative;
  }

  .workspace-nav::after {
    position: absolute;
    z-index: 13;
    top: 0;
    right: 0;
    bottom: 1px;
    width: 30px;
    background: linear-gradient(90deg, transparent, var(--papier));
    content: "";
    pointer-events: none;
  }

  .workspace-nav-scroll {
    padding-bottom: 2px;
    scrollbar-width: none;
  }

  .workspace-nav-scroll::-webkit-scrollbar { display: none; }

  .workspace-head {
    margin-bottom: 16px;
    padding-bottom: 14px;
    gap: 14px;
  }

  .workspace-title-row {
    align-items: flex-start;
    gap: 12px;
  }

  .workspace-title-row h2 { font-size: 1.4rem; }

  /* Les puces de séparation sautent à la ligne et laissent des points
     orphelins en bout de ligne : sur téléphone, la méta se lit en pile. */
  .workspace-meta {
    align-items: flex-start;
    flex-direction: column;
    gap: 1px;
    font-size: 0.82rem;
  }

  .workspace-meta > span + span::before { display: none; }

  .workspace-score { width: 52px; height: 52px; }
  .workspace-score strong { font-size: 0.8rem; }

  .workspace-actions {
    flex-wrap: wrap;
    gap: 8px;
  }

  .workspace-actions > * {
    flex: 1 1 140px;
    justify-content: center;
    min-height: 44px;
  }

  /* Un reliquat de défilement latéral suffit à donner l'impression que la
     page « glisse ». `clip` le supprime sans créer de conteneur de
     défilement, donc sans casser les en-têtes collants. */
  .main { overflow-x: clip; }
}

/* ==========================================================================
   19. RETOUR AU TOUCHER
   Ajouté à la refonte visuelle. Deux manques se répétaient partout :

   1. Presque rien ne répondait à l'appui. Un bouton, une carte, une rangée
      cliquable doivent s'enfoncer sous le doigt — sinon l'interface paraît
      sourde. L'échelle reste discrète (0.97–0.99) et proportionnelle à la
      taille de l'objet : une grande carte s'enfonce moins qu'un bouton.

   2. Aucun état de survol n'était protégé. Sur tablette et téléphone, le
      navigateur déclenche `:hover` à la première touche et le laisse collé
      jusqu'au prochain toucher ailleurs. Tout ce qui bouge au survol est
      donc réservé aux vrais pointeurs.
   ========================================================================== */

.raccourci,
.client-card,
.registre-ligne,
.file-ligne,
.nav-tete,
.icon-button,
.deal-card,
.table-outil tbody tr[data-row],
.livrable {
  transition:
    background-color var(--d-1) ease,
    border-color var(--d-1) ease,
    color var(--d-1) ease,
    box-shadow var(--d-1) ease,
    transform var(--d-2) var(--sortie);
}

/* Les petits objets s'enfoncent nettement. */
.icon-button:active,
.registre-ligne:active,
.nav-tete:active {
  transform: scale(0.97);
}

/* Les grandes surfaces s'enfoncent à peine : au-delà, l'effet devient un
   soubresaut plutôt qu'un appui. */
.raccourci:active,
.file-ligne:active,
.deal-card:active,
.livrable:active {
  transform: scale(0.99);
}

.client-card:active,
.table-outil tbody tr[data-row]:active {
  transform: scale(0.995);
}

/* Le survol qui déplace ou met à l'échelle n'existe qu'au vrai pointeur. */
@media (hover: hover) and (pointer: fine) {
  .livrable:hover {
    box-shadow: var(--ombre-2);
    transform: translateY(-2px);
  }

  .pipeline-segment:hover {
    filter: brightness(1.18);
    transform: scaleY(1.25);
  }
}

/* Sans pointeur fin, ces mêmes règles ne doivent rien déplacer : on retombe
   sur l'état au repos plutôt que sur un survol collé. */
@media not all and (hover: hover) and (pointer: fine) {
  .livrable:hover,
  .pipeline-segment:hover {
    transform: none;
  }
}


/* ==========================================================================
   20. BASCULE DES SERVICES
   Un seul service occupe l'écran à la fois. Voir §19 pour l'appui et le survol.
   ========================================================================== */

.univers-bascule {
  margin-bottom: var(--e-5);
}

.bascule-tete {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-bottom: var(--e-3);
}

.bascule {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  background: var(--n-100);
}

.bascule-onglet {
  padding: 6px var(--e-4);
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--n-600);
  font-family: var(--display);
  font-size: 0.84rem;
  font-stretch: 104%;
  font-weight: 700;
  cursor: pointer;
  transition:
    background-color var(--d-1) ease,
    color var(--d-1) ease,
    transform var(--d-2) var(--sortie);
}

.bascule-onglet:active { transform: scale(0.97); }
.bascule-onglet:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .bascule-onglet:hover { color: var(--marine); }
}

.bascule-onglet.est-actif {
  background: var(--blanc);
  color: var(--accent-fonce);
  box-shadow: var(--ombre-1);
}

/* Le registre seul prend toute la largeur : ses lignes se rangent en deux
   colonnes au lieu de s'étirer sur 1 200 px. */
.univers-actif .registre-lignes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--e-8);
}

/* La bande du service au repos. Elle dit ce qui attend ailleurs sans jamais
   présenter ces actions comme appartenant au service affiché. */
.univers-dormant {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  width: 100%;
  margin-top: var(--e-3);
  padding: var(--e-3) var(--e-4);
  border: 1px dashed var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--n-025);
  color: var(--gris);
  font-size: 0.87rem;
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--d-1) ease,
    background-color var(--d-1) ease,
    transform var(--d-2) var(--sortie);
}

.univers-dormant:active { transform: scale(0.995); }
.univers-dormant:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .univers-dormant:hover {
    border-color: var(--accent);
    background: var(--accent-voile);
  }
}

.dormant-texte { margin-right: auto; }
.dormant-texte strong { color: var(--marine); font-weight: 700; }

.dormant-appel {
  color: var(--accent-fonce);
  font-family: var(--display);
  font-size: 0.82rem;
  font-weight: 700;
  white-space: nowrap;
}

/* --- Marque de service : l'étiquette qui empêche toute confusion ---------- */

.marque {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--r-xs);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.marque-quebec { background: var(--qc-100); color: var(--qc-700); }
.marque-securite { background: var(--sec-100); color: var(--sec-700); }
.marque-transverse { background: var(--or-voile); color: var(--or-fonce); }

@media (max-width: 900px) {
  .univers-actif .registre-lignes { grid-template-columns: 1fr; }
  .bascule { width: 100%; }
  .bascule-onglet { flex: 1; }
}

/* ==========================================================================
   21. CONTRÔLES LOI 25
   L'état gouverne l'ordre et la couleur. Voir `controlsTable` dans app.js
   pour le raisonnement : ce qui bloque monte, ce qui est réglé s'efface.
   ========================================================================== */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Le bandeau de conformité --------------------------------------------- */

.conformite {
  padding: var(--e-5) var(--e-6);
  margin-bottom: var(--e-5);
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.conformite-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-4);
  margin-bottom: var(--e-3);
}

.conformite-chiffre {
  font-family: var(--display);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--marine);
  font-variant-numeric: tabular-nums;
}

.conformite-mot {
  margin-left: 6px;
  color: var(--gris);
  font-size: 0.9rem;
}

.conformite-detail {
  color: var(--gris);
  font-size: 0.82rem;
}

/* Une seule barre, découpée en parts : la proportion se lit sans compter. */
.conformite-barre {
  display: flex;
  gap: 2px;
  height: 8px;
  margin-bottom: var(--e-3);
}

.conformite-part {
  height: 100%;
  border-radius: var(--r-full);
  min-width: 4px;
}

.conformite-part.est-conforme { background: var(--qc-600); }
.conformite-part.est-cours { background: var(--bleu); }
.conformite-part.est-attente { background: var(--or-fonce); }
.conformite-part.est-critique { background: var(--rouge); }
.conformite-part.est-neutre { background: var(--trait-fort); }

.conformite-legende {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2) var(--e-5);
  padding: 0;
  margin: 0;
  list-style: none;
}

.conformite-legende li {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--gris);
  font-size: 0.8rem;
}

.conformite-legende b {
  color: var(--marine);
  font-variant-numeric: tabular-nums;
}

.pastille {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  flex: none;
}

.pastille.est-conforme { background: var(--qc-600); }
.pastille.est-cours { background: var(--bleu); }
.pastille.est-attente { background: var(--or-fonce); }
.pastille.est-critique { background: var(--rouge); }
.pastille.est-neutre { background: var(--trait-fort); }
.pastille.est-efface { background: var(--trait-fort); }

/* --- Les groupes ----------------------------------------------------------- */

.controle-groupe { margin-bottom: var(--e-6); }

.controle-groupe-tete {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin-bottom: var(--e-2);
}

.controle-groupe-tete h3 {
  font-size: 0.92rem;
  font-weight: 700;
}

.controle-compte {
  padding: 1px 8px;
  border-radius: var(--r-full);
  background: var(--n-100);
  color: var(--gris);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.controle-liste {
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  overflow: hidden;
}

/* --- La rangée ------------------------------------------------------------- */

.controle {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--e-4);
  padding: var(--e-3) var(--e-4);
  border-bottom: 1px solid var(--n-100);
  border-left: 3px solid transparent;
  transition: background-color var(--d-1) ease, border-color var(--d-1) ease;
}

.controle:last-child { border-bottom: 0; }

@media (hover: hover) and (pointer: fine) {
  .controle:hover { background: var(--n-025); }
}

/* Le filet de gauche porte l'état : c'est le repère qu'on suit en balayant. */
.est-critique .controle { border-left-color: var(--rouge); }
.est-attente .controle { border-left-color: var(--or-fonce); }
.est-cours .controle { border-left-color: var(--bleu); }
.est-conforme .controle { border-left-color: var(--qc-600); }

/* Ce qui est réglé n'a plus besoin d'attirer l'œil. */
.est-conforme .controle-titre,
.est-efface .controle-titre { color: var(--gris); font-weight: 600; }
.est-efface .controle { opacity: 0.62; }

.controle-code {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--gris-clair);
  letter-spacing: 0.04em;
  margin-bottom: 1px;
}

.controle-titre {
  margin: 0 0 3px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
  letter-spacing: -0.006em;
}

.controle-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px var(--e-3);
  color: var(--gris);
  font-size: 0.78rem;
}

.controle-meta .est-manquant { color: var(--gris-clair); }
.controle-meta .est-actif { color: var(--bleu-fonce); font-weight: 600; }
.controle-meta .est-retard { color: var(--rouge-fonce); font-weight: 700; }

.controle-statut select {
  min-height: 34px;
  padding: 5px 10px;
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  background: var(--blanc);
  color: var(--marine);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--d-1) ease, box-shadow var(--d-1) ease;
}

@media (hover: hover) and (pointer: fine) {
  .controle-statut select:hover { border-color: var(--trait-fort); }
}

.controle-statut select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

@media (max-width: 620px) {
  .controle { grid-template-columns: 1fr; align-items: start; }
  .controle-statut select { width: 100%; }
  .conformite-tete { flex-direction: column; gap: var(--e-1); }
}

/* Filet de service dans la navigation : Repère Québec et Repère Sécurité se
   distinguent d'un coup d'œil, sans quitter le châssis marine commun. */
.nav-section[data-service] > .nav-tete {
  position: relative;
}

.nav-section[data-service] > .nav-tete::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  bottom: 10px;
  width: 2px;
  border-radius: var(--r-full);
  background: var(--accent);
}

/* Dans le rail marine, l'indigo doit s'éclaircir pour rester lisible. */
.nav-section[data-service="securite"] > .nav-tete::before { background: var(--sec-500); }
.nav-section[data-service="quebec"] > .nav-tete::before { background: var(--qc-500); }
.nav-section[data-service="maintenance"] > .nav-tete::before { background: var(--mnt-500); }

/* Deux mesures voisines qui ne mesurent pas la même chose finissent par se
   faire douter l'une l'autre. La conformité reste le chiffre principal ;
   l'avancement vient juste dessous, nommé, avec la raison de son écart. */
.conformite-nuance {
  margin: -4px 0 var(--e-3);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-s);
  background: var(--n-050);
  color: var(--gris);
  font-size: 0.8rem;
  line-height: 1.45;
}

.conformite-nuance b {
  color: var(--marine);
  font-weight: 700;
}

/* ==========================================================================
   22. LANCEMENT DU SCANNER
   Le scan tourne sur un service distinct et aucune route de suivi n'est
   exposée : il n'y a donc pas de progression réelle à afficher. Plutôt que
   d'inventer une barre qui avance toute seule — un délai qu'on ne connaît
   pas — on montre trois états honnêtes : demandé, parti, échoué.
   ========================================================================== */

.scanner-journal {
  border-left: 4px solid var(--trait-fort);
  transition: border-color var(--d-2) ease, background-color var(--d-2) ease;
}

.scanner-journal strong {
  display: block;
  margin-bottom: 3px;
}

.scanner-journal.est-cours {
  border-left-color: var(--bleu);
  background: var(--bleu-voile);
}

.scanner-journal.est-fait {
  border-left-color: var(--vert);
  background: var(--vert-voile);
}

.scanner-journal.est-erreur {
  border-left-color: var(--rouge);
  background: var(--rouge-voile);
}

/* Pendant l'appel, le bouton dit qu'il travaille et refuse un second clic. */
#run-scanner[disabled] {
  opacity: 0.7;
  cursor: progress;
}

/* Le bloc d'en-tête du dossier ne redit plus le nom du client (la barre de
   titre le porte, et elle reste visible au défilement). Il lui faut donc une
   étiquette discrète pour annoncer ce qu'il montre. */
.workspace-eyebrow {
  margin-bottom: 3px;
  color: var(--gris-clair);
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ==========================================================================
   23. ASSISTANT SOUMISSION — récapitulatif, erreurs, choix de suite
   ========================================================================== */

/* Le récapitulatif : une ligne par décision, chacune renvoyant à son étape.
   Densité volontairement serrée — on le parcourt en diagonale pour repérer
   une erreur, pas pour le lire. */
.recap {
  display: grid;
  gap: 1px;
  margin: 0;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--trait);
  overflow: hidden;
}

.recap-ligne {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--e-3);
  padding: 10px var(--e-4);
  background: var(--blanc);
}

.recap-ligne dt {
  color: var(--gris);
  font-size: 0.82rem;
}

.recap-ligne dd {
  margin: 0;
  color: var(--marine);
  font-size: 0.88rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* « Non renseigné » n'est pas une erreur : c'est une information à vérifier.
   L'ambre alerte sans bloquer, là où le rouge dirait « corrigez d'abord ». */
.recap-ligne dd.est-manquant {
  color: var(--or-fonce);
  font-weight: 400;
  font-style: italic;
}

.recap-modifier {
  padding: 2px 6px;
  border: 0;
  border-radius: var(--r-xs);
  background: none;
  color: var(--accent);
  font-family: var(--display);
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color var(--d-1) ease, transform var(--d-2) var(--sortie);
}

.recap-modifier:active { transform: scale(0.95); }
.recap-modifier:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

@media (hover: hover) and (pointer: fine) {
  .recap-modifier:hover { background: var(--accent-voile); }
}

.recap-suite {
  display: flex;
  align-items: baseline;
  gap: var(--e-3);
  flex-wrap: wrap;
  margin-top: var(--e-4);
  padding: var(--e-3) var(--e-4);
  border-radius: var(--r-m);
  background: var(--n-025);
}

.recap-suite p {
  color: var(--gris);
  font-size: 0.82rem;
  line-height: 1.45;
  flex: 1;
  min-width: 220px;
}

/* Le prix vient d'une personne, pas du moteur. Le dire explicitement est la
   seule façon d'empêcher la lecture « le robot a fixé le montant ». */
.sceau-humain {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: var(--r-full);
  background: var(--or-voile);
  color: var(--or-fonce);
  font-family: var(--display);
  font-size: 0.74rem;
  font-weight: 700;
  white-space: nowrap;
}

.sceau-humain::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: currentColor;
}

/* L'erreur se pose là où elle se corrige. Insérée après son label, elle
   devient un enfant de la grille de champs : sans cette règle, elle occupe
   une colonne à côté du champ suivant au lieu de s'étendre sous le sien. */
.form-grid > .assistant-erreur { grid-column: 1 / -1; }

.assistant-erreur {
  margin: 8px 0 0;
  padding: 8px var(--e-3);
  border-left: 3px solid var(--rouge);
  border-radius: var(--r-xs);
  background: var(--rouge-voile);
  color: var(--rouge-fonce);
  font-size: 0.84rem;
  font-weight: 600;
}

[aria-invalid="true"] {
  border-color: var(--rouge) !important;
}

/* Le choix de la suite était un <select> : un embranchement majeur caché
   dans une liste déroulante, pendant que le bouton affichait l'un des deux
   chemins quoi qu'on choisisse. Deux options visibles, et le bouton suit. */
.choix-suite {
  margin: var(--e-5) 0 0;
  padding: 0;
  border: 0;
}

.choix-suite legend {
  padding: 0;
  margin-bottom: var(--e-2);
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 700;
}

.form-grid-espace { margin-top: var(--e-5); }
.aide-champ { font-weight: 400; }
.est-offre { font-size: 1.05rem; }
.caracteristiques { margin-top: var(--e-5); }

@media (max-width: 620px) {
  .recap-ligne { grid-template-columns: 1fr auto; }
  .recap-ligne dt { grid-column: 1 / -1; }
}

/* ==========================================================================
   24. TABLEAUX DE RESSOURCE
   Un seul système pour les neuf routes génériques. Le rôle d'une colonne
   décide de son poids : voir `roleColonne` dans app.js.
   ========================================================================== */

.ressource-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--e-5);
  flex-wrap: wrap;
  margin-bottom: var(--e-4);
  padding-bottom: var(--e-3);
  border-bottom: 1px solid var(--trait);
}

.ressource-titre p {
  color: var(--gris);
  font-size: 0.85rem;
  max-width: 68ch;
}

.ressource-outils {
  display: flex;
  align-items: center;
  gap: var(--e-3);
}

.ressource-recherche {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  width: min(260px, 42vw);
  padding: 6px var(--e-3);
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  background: var(--blanc);
  transition: border-color var(--d-1) ease, box-shadow var(--d-1) ease;
}

.ressource-recherche svg {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: var(--gris-clair);
  stroke-width: 1.8;
}

.ressource-recherche input {
  min-height: auto;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0.86rem;
}

.ressource-recherche input:focus { outline: 0; box-shadow: none; }
.ressource-recherche:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-voile); }

/* Le compteur suit la recherche : « 3 sur 18 » dit à la fois ce qu'on voit
   et ce qui est masqué. */
.ressource-compte {
  color: var(--gris);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- La grille ------------------------------------------------------------ */

.table-ressource { width: 100%; }

.table-ressource th {
  padding: 8px var(--e-3);
  border-bottom: 1px solid var(--trait);
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}

.table-ressource td {
  padding: 10px var(--e-3);
  border-bottom: 1px solid var(--n-100);
  font-size: 0.86rem;
  vertical-align: middle;
}

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

/* Le rôle décide du poids. La colonne principale porte le regard ; les
   secondaires s'effacent pour ne pas lui disputer l'attention. */
.table-ressource .col-principal {
  color: var(--marine);
  font-weight: 600;
}

.table-ressource td.col-secondaire { color: var(--gris); }

.table-ressource .col-date,
.table-ressource .col-mesure {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.table-ressource td.col-date { color: var(--gris); font-size: 0.82rem; }
.table-ressource .col-statut { width: 1%; white-space: nowrap; }
.table-ressource .col-actions { width: 1%; text-align: right; white-space: nowrap; }

.table-ressource tbody tr {
  cursor: pointer;
  transition: background-color var(--d-1) ease, transform var(--d-2) var(--sortie);
}

.table-ressource tbody tr:active { transform: scale(0.998); }
.table-ressource tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

@media (hover: hover) and (pointer: fine) {
  .table-ressource tbody tr:hover { background: var(--n-025); }
}

/* --- Actions de ligne ------------------------------------------------------ */

.ligne-actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  justify-content: flex-end;
}

/* Les actions ne s'affichent qu'au survol sur pointeur fin : au repos, une
   ligne ne doit montrer que de l'information. Elles restent permanentes au
   toucher, où il n'y a pas de survol pour les révéler. */
@media (hover: hover) and (pointer: fine) {
  .ligne-actions { opacity: 0; transition: opacity var(--d-1) ease; }
  tr:hover .ligne-actions,
  tr:focus-within .ligne-actions { opacity: 1; }
}

.menu-ligne { position: relative; }

.menu-ligne summary {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--r-s);
  color: var(--gris);
  font-size: 1rem;
  cursor: pointer;
  list-style: none;
  transition: background-color var(--d-1) ease;
}

.menu-ligne summary::-webkit-details-marker { display: none; }
.menu-ligne summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

@media (hover: hover) and (pointer: fine) {
  .menu-ligne summary:hover { background: var(--n-100); color: var(--marine); }
}

/* Le menu s'ouvre depuis son déclencheur, pas depuis le centre : la
   provenance du panneau doit être évidente. */
.menu-ligne-liste {
  position: absolute;
  right: 0;
  z-index: var(--z-menu);
  display: grid;
  min-width: 190px;
  padding: 5px;
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  background: var(--blanc);
  box-shadow: var(--ombre-2);
  transform-origin: top right;
  animation: menu-ouvre var(--d-3) var(--sortie);
}

@keyframes menu-ouvre {
  from { opacity: 0; transform: scale(0.96) translateY(-2px); }
}

.menu-ligne-liste button {
  padding: 7px var(--e-3);
  border: 0;
  border-radius: var(--r-xs);
  background: none;
  color: var(--marine);
  font-size: 0.84rem;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--d-1) ease;
}

@media (hover: hover) and (pointer: fine) {
  .menu-ligne-liste button:hover { background: var(--accent-voile); color: var(--accent-fonce); }
}

@media (prefers-reduced-motion: reduce) {
  .menu-ligne-liste { animation: none; }
}

/* --- Téléphone : des fiches, pas un tableau compressé ---------------------
   Un tableau de six colonnes réduit à 500 px n'est pas lisible, et le faire
   défiler latéralement oblige à naviguer pour lire une seule ligne. Chaque
   rangée devient une fiche, l'intitulé de chaque valeur venant du
   `data-libelle` posé au rendu. Les colonnes secondaires disparaissent :
   sur téléphone on cherche, on n'inventorie pas.
   ------------------------------------------------------------------------- */
@media (max-width: 620px) {
  .table-ressource thead { display: none; }
  .table-ressource,
  .table-ressource tbody,
  .table-ressource tr,
  .table-ressource td { display: block; width: auto; }

  .table-ressource tbody tr {
    margin-bottom: var(--e-3);
    padding: var(--e-3) var(--e-4);
    border: 1px solid var(--trait);
    border-radius: var(--r-m);
    background: var(--blanc);
  }

  .table-ressource td {
    padding: 3px 0;
    border: 0;
    text-align: left;
  }

  /* Les colonnes secondaires restent affichées en mode fiche. Les masquer
     paraissait logique — « le secondaire s'efface sur petit écran » — mais
     sur Questionnaires, la colonne secondaire est le client : six fiches
     devenaient rigoureusement identiques. Une colonne discrète n'est pas une
     colonne superflue ; elle porte souvent ce qui distingue une ligne d'une
     autre. Étiquetées et empilées, elles restent lisibles. */

  .table-ressource td.col-principal {
    font-family: var(--display);
    font-size: 0.98rem;
    margin-bottom: 2px;
  }

  /* Chaque valeur reprend son intitulé, sauf la principale qui se suffit. */
  .table-ressource td:not(.col-principal):not(.col-actions)::before {
    content: attr(data-libelle) " · ";
    color: var(--gris-clair);
    font-size: 0.76rem;
  }

  .table-ressource td.col-date,
  .table-ressource td.col-mesure { text-align: left; }

  .table-ressource td.col-actions { margin-top: var(--e-2); text-align: left; }
  .ligne-actions { opacity: 1; }
  .ressource-tete { flex-direction: column; align-items: stretch; }
  .ressource-recherche { width: 100%; }
}

/* --- Dossier commercial : une action suivante, le reste replié ------------ */

.commercial-card-corps { min-width: 0; }

.commercial-prix {
  margin-top: 3px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.012em;
}

.commercial-prix span {
  color: var(--gris);
  font-family: var(--texte);
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0;
}

/* La phrase qui dit où en est le dossier et ce qu'il attend. Sans elle, il
   fallait déduire l'étape du badge et de la frise. */
.commercial-suite {
  margin-top: 8px;
  color: var(--gris);
  font-size: 0.82rem;
}

.commercial-suite b { color: var(--marine); font-weight: 700; }

.commercial-card .ligne-actions {
  margin-top: var(--e-3);
  justify-content: flex-start;
  opacity: 1;
}

/* L'annulation est irréversible : elle se distingue dans le menu. */
.menu-ligne-liste .est-danger { color: var(--rouge-fonce); }

@media (hover: hover) and (pointer: fine) {
  .menu-ligne-liste .est-danger:hover { background: var(--rouge-voile); color: var(--rouge-fonce); }
}

/* ==========================================================================
   25. DOSSIER CLIENT — l'index de conformité et les groupes

   Vingt-trois onglets à plat sont devenus sept groupes. « Conformité Loi 25 »
   ouvre un index plutôt qu'une sous-page : voir `sommaireConformite` dans
   app.js pour le raisonnement.
   ========================================================================== */

.zones-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: var(--e-3);
}

.zone-carte {
  display: grid;
  gap: 5px;
  padding: var(--e-4);
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--d-1) ease,
    background-color var(--d-1) ease,
    transform var(--d-2) var(--sortie);
}

.zone-carte:active { transform: scale(0.995); }
.zone-carte:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .zone-carte:hover { border-color: var(--trait-fort); background: var(--n-025); }
}

.zone-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
}

.zone-carte strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.94rem;
  font-stretch: 104%;
}

.zone-carte small { color: var(--gris); font-size: 0.8rem; }

/* Entrer dans une zone sans pouvoir en ressortir serait un cul-de-sac : le
   retour est la première chose de l'écran. */
.retour-groupe {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 4px 10px 4px 6px;
  margin-bottom: var(--e-3);
  border: 0;
  border-radius: var(--r-s);
  background: none;
  color: var(--accent);
  font-family: var(--display);
  font-size: 0.83rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color var(--d-1) ease, transform var(--d-2) var(--sortie);
}

.retour-groupe:active { transform: scale(0.97); }
.retour-groupe:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .retour-groupe:hover { background: var(--accent-voile); }
}

/* Trois ou quatre zones homogènes n'ont pas besoin d'un index : une bande
   de segments suffit, et elle tient sur une ligne. */
.groupe-segments {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  padding-bottom: var(--e-3);
  margin-bottom: var(--e-4);
  border-bottom: 1px solid var(--trait);
}

.groupe-segment {
  padding: 5px var(--e-3);
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: var(--blanc);
  color: var(--gris);
  font-size: 0.82rem;
  white-space: nowrap;
  cursor: pointer;
  transition:
    border-color var(--d-1) ease,
    background-color var(--d-1) ease,
    color var(--d-1) ease,
    transform var(--d-2) var(--sortie);
}

.groupe-segment:active { transform: scale(0.97); }
.groupe-segment:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (hover: hover) and (pointer: fine) {
  .groupe-segment:hover { border-color: var(--trait-fort); color: var(--marine); }
}

.groupe-segment.est-actif {
  border-color: var(--accent);
  background: var(--accent-voile);
  color: var(--accent-fonce);
  font-weight: 700;
}

.etat-calme { background: var(--n-100); color: var(--gris); }

/* Remplace l'ancien `style="margin-top:20px"` du tableau de bord, que la CSP
   bloquait — il n'a donc jamais produit d'espace. */
.panel-espace { margin-top: var(--e-5); }

/* ==========================================================================
   26. MATRICE DES RISQUES
   Deux axes rendus à deux axes. Voir `matriceRisques` dans app.js.
   ========================================================================== */

.matrice {
  padding: var(--e-5) var(--e-6);
  margin-bottom: var(--e-5);
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.matrice-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e-4);
  margin-bottom: var(--e-4);
}

.matrice-tete h3 { font-size: 0.98rem; }
.matrice-tete p { color: var(--gris); font-size: 0.82rem; margin-top: 2px; }

/* Les deux légendes d'axe encadrent la grille : sans elles, une matrice
   n'est qu'un damier coloré. */
.matrice-grille {
  display: grid;
  grid-template-columns: auto minmax(0, max-content);
  gap: var(--e-2) var(--e-3);
  align-items: center;
  justify-content: start;
}

.matrice-axe-y {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  justify-self: center;
  color: var(--gris);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.matrice-axe-x {
  grid-column: 2;
  color: var(--gris);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
}

.matrice-table { border-collapse: separate; border-spacing: 3px; }

.matrice-table th {
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  padding: 2px;
}

.matrice-case {
  width: 46px;
  height: 40px;
  border-radius: var(--r-xs);
  background: var(--n-050);
  text-align: center;
  vertical-align: middle;
}

/* Une case vide reste très pâle : c'est l'absence de risque, pas une donnée.
   Seules les cases occupées prennent la couleur de leur niveau. */
.matrice-case.est-occupee.est-calme    { background: var(--qc-100); }
.matrice-case.est-occupee.est-cours    { background: var(--bleu-voile); }
.matrice-case.est-occupee.est-attente  { background: var(--or-voile); }
.matrice-case.est-occupee.est-critique { background: var(--rouge-voile); }

.matrice-nombre {
  font-family: var(--display);
  font-size: 0.94rem;
  font-weight: 700;
  color: var(--marine);
  font-variant-numeric: tabular-nums;
}

.matrice-case.est-occupee.est-critique .matrice-nombre { color: var(--rouge-fonce); }
.matrice-case.est-occupee.est-attente  .matrice-nombre { color: var(--or-fonce); }

@media (max-width: 620px) {
  .matrice { padding: var(--e-4); }
  .matrice-case { width: 38px; height: 34px; }
}

/* ==========================================================================
   27. REPÈRE MAINTENANCE — file, fiche et conversation

   Une demande d'entretien n'est pas un incident. Le rouge doit vouloir dire
   que quelque chose ne va pas, et une demande normale ne va jamais mal : on
   n'en trouvera donc aucun ici, pas même sur « Annulée » ou « Refusée », qui
   sont les jetons les plus gris de la série.

   La question qu'un dirigeant se pose en ouvrant l'écran n'est pas « quel est
   le statut » mais « est-ce qu'on attend quelque chose de moi ». Un seul
   statut y répond oui : « En attente client » porte l'accent, les six autres
   restent calmes. C'est la seule hiérarchie de la série.

   Chaque jeton porte aussi une pastille dont la forme varie — pleine, creuse,
   barrée. La couleur n'est donc jamais la seule porteuse de l'information.
   ========================================================================== */

.jeton-etat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 10px 4px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--papier);
  color: var(--gris);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.jeton-etat::before {
  content: "";
  inline-size: 7px;
  block-size: 7px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  background: currentColor;
  flex: none;
}

/* Reçue et Planifiée n'ont encore rien produit : pastille creuse. */
.jeton-etat.received::before,
.jeton-etat.planned::before { background: transparent; }

.jeton-etat.in_progress {
  background: var(--sec-100);
  color: var(--sec-700);
}

/* Le seul état qui demande quelque chose au client. */
.jeton-etat.waiting_client {
  background: var(--mnt-100);
  color: var(--mnt-700);
  border-color: var(--mnt-500);
  font-weight: 680;
}

.jeton-etat.done {
  background: var(--qc-100);
  color: var(--qc-700);
}

/* Annulée et Refusée sortent du flux : pastille barrée, aucun rouge. */
.jeton-etat.cancelled,
.jeton-etat.declined {
  background: var(--n-100, var(--papier));
  color: var(--gris);
}
.jeton-etat.cancelled::before,
.jeton-etat.declined::before {
  background: transparent;
  border-radius: 0;
  block-size: 1.5px;
  border: 0;
  background: currentColor;
}

/* Priorité : un mot, pas une alarme. « Élevée » se distingue par la graisse
   et un filet, jamais par un aplat qui volerait l'attention au statut. */
.jeton-priorite {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--gris);
  white-space: nowrap;
}
.jeton-priorite::before {
  content: "";
  inline-size: 3px;
  block-size: 11px;
  border-radius: 2px;
  background: var(--filet-fort, #c3ccc9);
  flex: none;
}
.jeton-priorite.high { color: var(--encre); font-weight: 680; }
.jeton-priorite.high::before { background: var(--mnt-600); block-size: 14px; }
.jeton-priorite.low::before { block-size: 7px; }

/* --- Barre de filtres ---------------------------------------------------- */

.mnt-filtres {
  display: grid;
  grid-template-columns: minmax(220px, 2fr) repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  align-items: end;
  margin-bottom: 20px;
}
.mnt-filtres label {
  display: grid;
  gap: 5px;
  font-size: 0.75rem;
  font-weight: 620;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gris);
}
.mnt-filtres input,
.mnt-filtres select {
  inline-size: 100%;
  min-block-size: 40px;
}
.mnt-filtres-pied {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.mnt-filtres-compte {
  font-size: 0.85rem;
  color: var(--gris);
  font-variant-numeric: tabular-nums;
}

/* --- Référence ----------------------------------------------------------- */

.mnt-ref {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--gris);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* --- Fiche --------------------------------------------------------------- */

.mnt-fiche {
  display: grid;
  grid-template-columns: minmax(0, 1.65fr) minmax(280px, 1fr);
  gap: 22px;
  align-items: start;
}

.mnt-entete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 16px;
  margin-bottom: 6px;
}

.mnt-faits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px 22px;
  padding: 18px 0;
  border-block: 1px solid var(--filet);
  margin-bottom: 22px;
}
.mnt-fait {
  display: grid;
  gap: 4px;
  min-inline-size: 0;
}
.mnt-fait dt {
  font-size: 0.7rem;
  font-weight: 660;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gris);
}
.mnt-fait dd {
  margin: 0;
  font-size: 0.92rem;
  color: var(--encre);
  overflow-wrap: anywhere;
}

/* --- Conversation -------------------------------------------------------- */

.mnt-fil {
  display: grid;
  gap: 14px;
  margin-bottom: 24px;
}

.mnt-message {
  display: grid;
  gap: 6px;
  padding: 14px 16px;
  border: 1px solid var(--filet);
  border-radius: 4px;
  background: var(--blanc, #fff);
}
.mnt-message-tete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  font-size: 0.78rem;
  color: var(--gris);
}
.mnt-message-tete strong { color: var(--encre); font-size: 0.85rem; }
.mnt-message p {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Le message de l'équipe se décale et prend l'accent : on voit d'un coup
   d'œil qui parle, sans lire les noms. */
.mnt-message.equipe {
  border-left: 3px solid var(--accent);
  background: var(--accent-voile);
}

/* Une note interne doit être impossible à confondre avec une réponse au
   client, et ce n'est pas une nuance de fond qui y suffit.

   Elle prend donc le parti inverse de la réponse publique : là où celle-ci
   porte l'accent du service — la couleur de « ceci est parti chez le
   client » —, la note reste en neutre froid, filet tireté, décalée du fil.
   Elle se lit comme un aparté posé à côté de la conversation plutôt que
   comme un tour de parole. La mention en toutes lettres reste le signal
   principal ; la forme ne fait que la confirmer. */
.mnt-message.interne {
  border: 1px dashed var(--n-300);
  border-left: 3px solid var(--n-500);
  background: var(--n-050);
  margin-inline-start: 18px;
}
.mnt-interne-marque {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Le parent est une grille : `align-self` ne retient pas la largeur, seul
     `justify-self` empêche la mention de s'étirer en bandeau. */
  justify-self: start;
  padding: 2px 8px;
  border-radius: 3px;
  background: var(--n-700);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.mnt-interne-note {
  font-size: 0.76rem;
  color: var(--n-600);
}

/* --- Deux façons d'écrire, jamais confondues ----------------------------- */

.mnt-repondre {
  display: grid;
  gap: 12px;
  padding: 18px;
  border: 1px solid var(--filet);
  border-radius: 4px;
}
/* Le mode note interne repeint la boîte entière : au moment d'écrire, la
   destination du texte doit être évidente sans relire l'étiquette du bouton. */
.mnt-repondre[data-mode="interne"] {
  background: var(--mnt-050);
  border-color: var(--mnt-500);
}
.mnt-modes {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 4px;
  background: var(--papier);
}
.mnt-modes button {
  min-block-size: 34px;
  padding-inline: 14px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--gris);
  font-size: 0.82rem;
  font-weight: 620;
  cursor: pointer;
  transition: background 160ms var(--sortie, ease-out), color 160ms var(--sortie, ease-out);
}
.mnt-modes button[aria-pressed="true"] {
  background: var(--blanc, #fff);
  color: var(--encre);
  box-shadow: 0 1px 2px rgb(12 27 42 / 12%);
}
.mnt-modes button:active { transform: scale(0.97); }
.mnt-repondre[data-mode="interne"] .mnt-modes button[aria-pressed="true"] {
  color: var(--mnt-800);
}
.mnt-destinataire {
  font-size: 0.8rem;
  color: var(--gris);
}
.mnt-repondre[data-mode="interne"] .mnt-destinataire {
  color: var(--mnt-700);
  font-weight: 620;
}

/* --- Pièces jointes ------------------------------------------------------ */

.mnt-jointes { display: grid; gap: 8px; }
.mnt-jointe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--filet);
  border-radius: 4px;
}
.mnt-jointe-nom { display: grid; gap: 2px; min-inline-size: 0; }
.mnt-jointe-nom strong { font-size: 0.9rem; overflow-wrap: anywhere; }
.mnt-jointe-meta { font-size: 0.76rem; color: var(--gris); }

/* --- Mobile -------------------------------------------------------------- */

@media (max-width: 900px) {
  .mnt-fiche { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  .mnt-filtres { grid-template-columns: 1fr 1fr; }
  .mnt-filtres label:first-child { grid-column: 1 / -1; }
  .mnt-faits { grid-template-columns: 1fr 1fr; gap: 14px 16px; }
}

@media (max-width: 480px) {
  .mnt-message.interne { margin-inline-start: 0; }
  .mnt-filtres { grid-template-columns: 1fr; }
  .mnt-faits { grid-template-columns: 1fr; }
  .mnt-modes { inline-size: 100%; }
  .mnt-modes button { flex: 1; }
  .mnt-jointe { align-items: flex-start; flex-direction: column; }
}

/* Un appui doit s'entendre, mais l'écran se consulte des dizaines de fois par
   jour : le retour reste sous le seuil de la perception consciente. */
@media (prefers-reduced-motion: reduce) {
  .mnt-modes button { transition-duration: 1ms; }
  .mnt-modes button:active { transform: none; }
}

/* ==========================================================================
   28. REPÈRE MAINTENANCE — sites, interventions et consommation

   La jauge de forfait est la seule mesure de cet écran. Elle dit d'abord ce
   qui reste, parce que c'est la question qu'on se pose, et jamais en rouge :
   dépasser un forfait est une information commerciale, pas une avarie.
   ========================================================================== */

.mnt-indicateurs {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 18px;
}
.mnt-indicateur {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid var(--filet);
  border-radius: 3px;
  background: var(--n-025, #fff);
}
.mnt-indicateur b {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--encre);
  font-variant-numeric: tabular-nums;
}
.mnt-indicateur span { font-size: 0.84rem; color: var(--gris); }

.mnt-jauge { display: grid; gap: 10px; margin-bottom: 18px; }
.mnt-jauge-tete { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.mnt-jauge-tete strong {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--encre);
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}
.mnt-jauge-tete span { font-size: 0.86rem; color: var(--gris); }
.mnt-jauge-pied { margin: 0; font-size: 0.82rem; color: var(--gris); }
.mnt-jauge-vide { margin: 0; font-size: 0.9rem; color: var(--gris); }
.mnt-jauge-vide span { font-size: 0.84rem; }

.mnt-barre {
  block-size: 8px;
  border-radius: 999px;
  background: var(--n-100, #ebefef);
  overflow: hidden;
}
.mnt-barre > span {
  display: block;
  block-size: 100%;
  inline-size: 0;
  border-radius: inherit;
  background: var(--mnt-600);
  /* La largeur est posée par le CSSOM après rendu : la CSP interdit les
     attributs style=, et une barre sans largeur se peindrait pleine. */
  transition: inline-size 320ms var(--sortie, ease-out);
}
/* Le dépassement se dit par une trame, pas par du rouge. */
.mnt-barre > span.depasse {
  background: repeating-linear-gradient(
    135deg,
    var(--mnt-600) 0 6px,
    var(--mnt-500) 6px 12px
  );
}

.mnt-pleine {
  inline-size: 100%;
  justify-content: center;
  margin-block: 4px 20px;
}

/* Une intervention masquée au client se signale en toutes lettres : c'est la
   seule information de cette liste qu'on ne peut pas déduire du reste. */
.mnt-prive {
  color: var(--mnt-700);
  font-weight: 620;
}

button.mnt-jointe {
  inline-size: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: none;
  transition: border-color 160ms var(--sortie, ease-out);
}
@media (hover: hover) and (pointer: fine) {
  button.mnt-jointe:hover { border-color: var(--filet-fort); }
}
button.mnt-jointe:active { transform: scale(0.995); }

@media (max-width: 700px) {
  .mnt-indicateurs { display: grid; grid-template-columns: 1fr 1fr; }
  .mnt-indicateur { justify-content: space-between; }
}
@media (max-width: 480px) {
  .mnt-indicateurs { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .mnt-barre > span { transition-duration: 1ms; }
  button.mnt-jointe { transition-duration: 1ms; }
  button.mnt-jointe:active { transform: none; }
}

/* --- Chiffrier Maintenance -------------------------------------------------
   Outil interne de tarification. Une colonne de saisie, une colonne de
   résultat : on remplit à gauche, on lit à droite, et le formulaire ne
   disparaît pas quand le résultat arrive — corriger une réponse et recalculer
   est le geste courant. */

.mnt-groupe {
  margin: 26px 0 12px;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texte-doux);
}
.mnt-groupe:first-child { margin-top: 0; }

.mnt-case {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.mnt-case input { inline-size: auto; margin: 0; }

/* Le verdict : cinq mesures, lisibles d'un coup d'œil et sans hiérarchie
   artificielle entre elles. */
.mnt-verdict {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 18px;
  padding: 20px 0;
  border-block: 1px solid var(--bordure);
}
.mnt-verdict div { display: grid; gap: 4px; }
.mnt-verdict span { font-size: 0.78rem; }
.mnt-verdict strong { font-size: 1.05rem; }

.mnt-alerte {
  margin: 16px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--avertissement-fond, #fdf3e3);
  color: var(--avertissement-texte, #6b4a12);
  font-size: 0.9rem;
}

.mnt-pourquoi { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.mnt-pourquoi li { display: flex; gap: 10px; align-items: baseline; font-size: 0.92rem; }
.mnt-plus,
.mnt-zero {
  flex: none;
  inline-size: 34px;
  padding: 2px 0;
  border-radius: 6px;
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  font-weight: 700;
  text-align: center;
}
.mnt-plus { background: var(--accent-voile, #eef3f0); color: var(--accent-fort, #1f6a4e); }
.mnt-zero { background: var(--fond-doux, #f2f2f0); color: var(--texte-doux); }

/* Les pondérations d'un critère à tranches : le libellé une fois, puis une
   case par tranche. Aligner les cases évite de relire le libellé à chaque
   ligne. */
.mnt-tranches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.mnt-tranches > span {
  grid-column: 1 / -1;
  font-size: 0.85rem;
}

/* --- Banques d'heures ------------------------------------------------------
   Le résumé passe avant le tableau : quatre mesures, dont deux appellent une
   action. Celles-là se signalent par un liseré et par leur libellé, jamais par
   la couleur seule. */

.mnt-resume {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.mnt-resume > div {
  display: grid;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--bordure);
  border-radius: 12px;
}
.mnt-resume span { font-size: 0.78rem; }
.mnt-resume strong { font-size: 1.4rem; font-variant-numeric: tabular-nums; }
.mnt-resume .mnt-attention { border-inline-start: 3px solid var(--avertissement-bord, #c08a2e); }

/* La jauge double le chiffre, elle ne le remplace pas : la barre se lit de
   loin, le nombre se vérifie. */
.mnt-jauge {
  inline-size: 120px;
  block-size: 8px;
  margin-bottom: 6px;
  border-radius: 999px;
  background: var(--fond-doux, #f2f2f0);
  overflow: hidden;
}
.mnt-jauge-part {
  display: block;
  block-size: 100%;
  border-radius: inherit;
  background: var(--accent-fort, #1f6a4e);
}

.mnt-nombre { font-variant-numeric: tabular-nums; }
td.mnt-attention { color: var(--avertissement-texte, #6b4a12); font-weight: 600; }


/* ==========================================================================
   Mesures : ce que les attributs `style=` prétendaient faire

   Même défaut que dans le portail, même cause. La CSP posée dans
   `src/http/http.ts` vaut pour toute réponse du serveur, console comprise :
   `style-src 'self'`, sans `unsafe-inline`, bloque aussi les attributs
   `style=` du balisage. Or tout le rendu de la console passe par
   `innerHTML`. Dix-neuf de ces attributs vivaient ici sans avoir jamais rien
   fait, et rien ne le signalait : la page restait valide, seulement composée
   autrement que ce que le code annonçait.
   ========================================================================== */

/* Trois rangées d'actions sur huit poussent leurs boutons à droite ; les cinq
   autres les veulent à gauche. C'est donc un modificateur, pas un défaut. */
.rangee-actions.a-droite { justify-content: flex-end; }

/* `.recommandation` est dessinée pour des chiffres : 1,32 rem, graisse 800,
   chiffres tabulaires. Une cellule qui porte un nom de client ou un libellé
   de statut y tenait mal, et les chiffres tabulaires n'ont rien à y faire. */
.recommandation strong.est-libelle {
  font-size: 1rem;
  font-stretch: 100%;
  font-variant-numeric: normal;
}

/* Le cadrage d'un audit oppose ce qui est autorisé à ce qui ne l'est pas.
   Sans sa teinte, le bloc des exclusions était identique à celui du périmètre
   et se lisait donc comme une permission de plus. */
.pourquoi.est-exclusion { background: var(--rouge-voile); }

/* La phrase de repli d'un bloc de cadrage se tient sous la taille des listes
   qu'elle remplace. */
.pourquoi p.muted { font-size: 0.87rem; }

/* Un panneau qui suit immédiatement une barre de filtres n'a pas besoin de sa
   gouttière haute entière : les deux se touchent presque. */
.panel.serre { padding-top: 6px; }

/* Deux éléments posés au pied d'une carte, à l'intérieur de ses bords : ils
   reprennent la gouttière de la carte, pas celle du flux. */
.note-basse.en-carte,
.suivi-compteurs.en-carte { padding: 0 20px 16px; }
.note-basse.en-carte { margin: 0; }

/* Une note en tête de modale n'a rien au-dessus d'elle à espacer. */
.note-basse.sans-marge { margin-top: 0; }

/* Même écart que dans le portail, entre la clé TOTP et le champ du code. */
.mfa-activation { margin-top: 18px; }

/* Le texte d'une version de politique est saisi avec ses retours à la ligne.
   Sans `pre-wrap` ils étaient avalés et la politique s'affichait d'un seul
   bloc : c'est le seul de ces dix-neuf attributs dont la perte changeait le
   sens de ce qu'on lisait. */
.texte-version {
  margin-top: 8px;
  font-size: 0.88rem;
  line-height: 1.55;
  white-space: pre-wrap;
}

/* ==========================================================================
   REPÈRE SÉCURITÉ — DOSSIER D'AUDIT
   Un dossier d'audit se lit comme un dossier, pas comme un tableau de bord.
   Les composants ci-dessous lisent --accent : ils s'habillent du service qui
   les affiche, et n'ont aucune couleur en propre.
   ========================================================================== */

/* La frise situe, elle ne mesure pas. Strix ne fournit aucune progression
   fiable, donc rien ici ne prétend en afficher une. */
.frise-audit {
  display: flex;
  align-items: flex-start;
  gap: 0;
  margin: 0 0 var(--e-5);
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.frise-etape {
  position: relative;
  flex: 1;
  padding-top: var(--e-4);
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--gris);
  text-align: center;
}

/* Le filet passe derrière les puces et s'arrête au bord du bloc, sans
   dépasser à gauche de la première ni à droite de la dernière. */
.frise-etape::before {
  content: "";
  position: absolute;
  top: 6px;
  left: -50%;
  width: 100%;
  height: 2px;
  background: var(--trait);
}

.frise-etape:first-child::before { display: none; }

.frise-puce {
  position: absolute;
  top: 0;
  left: 50%;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  border: 2px solid var(--trait-fort);
  border-radius: 50%;
  background: var(--blanc);
}

.frise-etape.est-faite { color: var(--encre); }
.frise-etape.est-faite::before { background: var(--accent); }
.frise-etape.est-faite .frise-puce {
  border-color: var(--accent);
  background: var(--accent);
}

.frise-etape.est-courante {
  font-weight: 600;
  color: var(--encre);
}

.frise-etape.est-courante .frise-puce {
  border-color: var(--accent);
  background: var(--blanc);
  box-shadow: 0 0 0 4px var(--accent-voile);
}

.frise-audit.est-bloquee .frise-etape.est-courante .frise-puce {
  border-color: #b4342f;
  box-shadow: 0 0 0 4px rgba(180, 52, 47, 0.14);
}

/* « Qu'est-ce que je dois faire ensuite ? » — la question à laquelle cet
   écran répond avant toute autre, donc le premier bloc après la frise. */
.bandeau-suite {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
  padding: var(--e-4) var(--e-5);
  margin-bottom: var(--e-5);
  border: 1px solid var(--trait);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.bandeau-suite .eyebrow { margin: 0 0 2px; }

.suite-texte {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--encre);
}

/* L'état du worker. Une pastille et une phrase : un opérateur doit savoir en
   un regard s'il attend ou s'il intervient. */
.panneau-worker {
  padding: var(--e-4) var(--e-5);
  margin-bottom: var(--e-5);
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--papier);
}

.worker-tete {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  font-size: 0.98rem;
}

.panneau-worker p {
  margin: var(--e-2) 0 0 22px;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--gris);
}

.worker-pastille {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--gris-clair);
  flex: none;
}

.panneau-worker.est-cours   .worker-pastille { background: #2f6f9f; }
.panneau-worker.est-fait    .worker-pastille { background: var(--accent); }
.panneau-worker.est-attente .worker-pastille { background: #b8842c; }
.panneau-worker.est-urgent  .worker-pastille { background: #b4342f; }

.panneau-worker.est-urgent { border-color: rgba(180, 52, 47, 0.35); }

.worker-erreur {
  margin-top: var(--e-3) !important;
  margin-left: 22px !important;
  padding: var(--e-3);
  border-radius: 8px;
  background: rgba(180, 52, 47, 0.06);
  font-family: var(--mono);
  font-size: 0.8rem !important;
  color: var(--n-700) !important;
  word-break: break-word;
}

.worker-erreur strong {
  display: block;
  margin-bottom: 4px;
  font-family: inherit;
  color: #8f2a26;
}

.duo-panneaux {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--e-4);
}

@media (max-width: 720px) {
  .duo-panneaux { grid-template-columns: 1fr; }
  .frise-etape { font-size: 0.68rem; }
  .bandeau-suite { flex-direction: column; align-items: stretch; }
}

/* Les détails techniques restent repliés : ils servent au diagnostic, pas à
   la conduite du dossier. Le monospace est réservé à ce qui est réellement
   technique — des empreintes, des codes. */
.details-techniques {
  margin-top: var(--e-5);
  border-top: 1px solid var(--trait);
  padding-top: var(--e-4);
}

.details-techniques summary {
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--n-700);
}

.details-techniques summary::marker { color: var(--gris-clair); }

.grille-technique {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--e-3) var(--e-4);
  margin: var(--e-4) 0 0;
}

.grille-technique dt {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gris);
}

.grille-technique dd {
  margin: 2px 0 0;
  font-size: 0.9rem;
  color: var(--encre);
}

.grille-technique code {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--n-700);
}

/* ---- Constats ---------------------------------------------------------- */

.constat-description {
  margin: var(--e-2) 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--n-700);
}

.constat-revue {
  margin: var(--e-3) 0 0;
  font-size: 0.8rem;
  color: var(--gris);
  font-style: italic;
}

.constat-cvss {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid var(--trait-fort);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--n-700);
}

/* ---- Moteur de sécurité ------------------------------------------------ */

.moteur-liste { margin: 0; }

.moteur-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-4);
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--trait);
}

.moteur-ligne:last-child { border-bottom: none; }

.moteur-ligne dt {
  font-size: 0.85rem;
  color: var(--gris);
}

.moteur-ligne dd {
  margin: 0;
  text-align: right;
  font-size: 0.92rem;
  color: var(--encre);
}

.moteur-ligne dd small {
  display: block;
  margin-top: 2px;
  font-size: 0.76rem;
  font-weight: 400;
  color: var(--gris);
}

.moteur-pastille {
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
}

.moteur-pastille.est-enligne {
  background: var(--accent-voile);
  color: var(--accent-fonce);
}

.moteur-pastille.est-horsligne {
  background: var(--n-100);
  color: var(--gris);
}

.callout.est-sobre {
  margin-top: var(--e-4);
  border-left: 2px solid var(--trait-fort);
  background: transparent;
}

.callout.est-sobre strong { color: var(--n-700); }
