/* ============================================================
   SUPERVIA — Système de design GTB / Supervision technique
   Fichier de référence partagé par les 4 blocs.
   Mode clair + sombre. Neutres légèrement chauds.
   Typo : Arial (police UNIQUE du projet, web-safe) — AUCUNE police
   externe chargée (contrôle total, rien ne vient « de nulle part »).
   ============================================================ */

/* -------- TOKENS : MODE CLAIR (défaut) -------- */
:root {
  /* Neutres légèrement chauds (hue ~80) */
  --bg:            oklch(0.968 0.004 80);
  --surface:       oklch(0.995 0.003 80);
  --surface-2:     oklch(0.982 0.004 80);
  --surface-sunk:  oklch(0.948 0.005 80);
  --border:        oklch(0.905 0.005 80);
  --border-strong: oklch(0.815 0.007 80);
  --text:          oklch(0.265 0.007 80);
  --text-2:        oklch(0.470 0.007 80);
  --text-muted:    oklch(0.610 0.006 80);
  --overlay:       oklch(0.20 0.01 80 / 0.45);

  /* Couleurs d'état — porteuses de sens, constantes partout */
  --ok:            oklch(0.555 0.135 150);
  --ok-fg:         oklch(0.500 0.135 150);
  --ok-soft:       oklch(0.955 0.035 150);
  --ok-line:       oklch(0.840 0.060 150);

  --warn:          oklch(0.720 0.150 72);
  --warn-fg:       oklch(0.560 0.120 62);
  --warn-soft:     oklch(0.960 0.045 80);
  --warn-line:     oklch(0.840 0.090 78);

  --alarm:         oklch(0.575 0.205 27);
  --alarm-fg:      oklch(0.540 0.205 27);
  --alarm-soft:    oklch(0.958 0.030 27);
  --alarm-line:    oklch(0.840 0.080 27);

  --idle:          oklch(0.640 0.008 80);
  --idle-fg:       oklch(0.560 0.008 80);
  --idle-soft:     oklch(0.945 0.004 80);
  --idle-line:     oklch(0.870 0.005 80);

  --info:          oklch(0.560 0.130 250);
  --info-fg:       oklch(0.530 0.130 250);
  --info-soft:     oklch(0.955 0.030 250);
  --info-line:     oklch(0.850 0.060 250);

  --accent:        oklch(0.560 0.130 250); /* accent système = bleu info, sobre */

  /* Couleurs de PROGRAMMES / RÉGIMES horaires — sémantique de planning,
     hues volontairement HORS des hues d'état (ok/warn/alarm/idle/info).
     SOURCE UNIQUE : consommées par l'Écran Calendrier (programmes par index
     --prog-N) ET par la fiche équipement / widget schedule (régimes). */
  --prog-0: oklch(0.585 0.110 250); --prog-0s: color-mix(in oklch, var(--prog-0) 22%, var(--surface));
  --prog-1: oklch(0.600 0.095 200); --prog-1s: color-mix(in oklch, var(--prog-1) 22%, var(--surface));
  --prog-2: oklch(0.580 0.120 320); --prog-2s: color-mix(in oklch, var(--prog-2) 22%, var(--surface));
  --prog-3: oklch(0.605 0.032 255); --prog-3s: color-mix(in oklch, var(--prog-3) 26%, var(--surface));
  --prog-4: oklch(0.560 0.090 270); --prog-4s: color-mix(in oklch, var(--prog-4) 22%, var(--surface));
  --prog-5: oklch(0.605 0.080 175); --prog-5s: color-mix(in oklch, var(--prog-5) 22%, var(--surface));
  --regime-confort: var(--accent);
  --regime-reduit:  oklch(0.70 0.07 250);
  --regime-arret:   var(--idle-line);
  --regime-horsgel: oklch(0.72 0.09 220);

  /* Élévation (très discrète, outil plat) */
  --shadow-pop: 0 6px 24px -8px oklch(0.20 0.02 80 / 0.28), 0 1px 2px oklch(0.20 0.02 80 / 0.10);

  color-scheme: light;
}

/* -------- TOKENS : MODE SOMBRE -------- */
[data-theme="dark"] {
  --bg:            oklch(0.198 0.005 80);
  --surface:       oklch(0.245 0.006 80);
  --surface-2:     oklch(0.285 0.006 80);
  --surface-sunk:  oklch(0.225 0.005 80);
  --border:        oklch(0.330 0.006 80);
  --border-strong: oklch(0.420 0.008 80);
  --text:          oklch(0.945 0.004 80);
  --text-2:        oklch(0.745 0.005 80);
  --text-muted:    oklch(0.600 0.005 80);
  --overlay:       oklch(0.12 0.01 80 / 0.60);

  --ok:            oklch(0.720 0.150 150);
  --ok-fg:         oklch(0.760 0.140 150);
  --ok-soft:       oklch(0.330 0.060 150);
  --ok-line:       oklch(0.420 0.080 150);

  --warn:          oklch(0.780 0.150 75);
  --warn-fg:       oklch(0.810 0.140 78);
  --warn-soft:     oklch(0.345 0.060 70);
  --warn-line:     oklch(0.460 0.090 72);

  --alarm:         oklch(0.660 0.200 27);
  --alarm-fg:      oklch(0.730 0.165 27);
  --alarm-soft:    oklch(0.335 0.090 27);
  --alarm-line:    oklch(0.460 0.130 27);

  --idle:          oklch(0.560 0.008 80);
  --idle-fg:       oklch(0.640 0.007 80);
  --idle-soft:     oklch(0.300 0.005 80);
  --idle-line:     oklch(0.400 0.006 80);

  --info:          oklch(0.680 0.130 250);
  --info-fg:       oklch(0.745 0.120 250);
  --info-soft:     oklch(0.330 0.070 250);
  --info-line:     oklch(0.450 0.100 250);

  --accent:        oklch(0.680 0.130 250);

  /* Programmes / régimes — variantes sombres (mêmes hues, plus claires) */
  --prog-0: oklch(0.660 0.120 250); --prog-0s: color-mix(in oklch, var(--prog-0) 26%, var(--surface));
  --prog-1: oklch(0.670 0.100 200); --prog-1s: color-mix(in oklch, var(--prog-1) 26%, var(--surface));
  --prog-2: oklch(0.660 0.125 320); --prog-2s: color-mix(in oklch, var(--prog-2) 26%, var(--surface));
  --prog-3: oklch(0.680 0.038 255); --prog-3s: color-mix(in oklch, var(--prog-3) 30%, var(--surface));
  --prog-4: oklch(0.640 0.100 270); --prog-4s: color-mix(in oklch, var(--prog-4) 26%, var(--surface));
  --prog-5: oklch(0.675 0.090 175); --prog-5s: color-mix(in oklch, var(--prog-5) 26%, var(--surface));
  --regime-confort: var(--accent);
  --regime-reduit:  oklch(0.70 0.07 250);
  --regime-arret:   var(--idle-line);
  --regime-horsgel: oklch(0.72 0.09 220);

  --shadow-pop: 0 8px 28px -8px oklch(0 0 0 / 0.55), 0 1px 2px oklch(0 0 0 / 0.40);

  color-scheme: dark;
}

/* -------- ÉCHELLE TYPOGRAPHIQUE -------- */
:root {
  /* Police UNIQUE du projet = Arial (web-safe, présente sur tout poste,
     rien à télécharger). --font-sans ET --font-mono pointent sur Arial :
     les chiffres restent alignés via font-variant-numeric:tabular-nums. */
  --font-sans: Arial, Helvetica, sans-serif;
  --font-mono: Arial, Helvetica, sans-serif;

  /* Polices CONFIGURABLES par dashboard — menu FERMÉ, web-safe : Arial · Times New Roman · Georgia.
     Deux emplacements ; SEULES les briques (Bloc 2) les consomment, via font-family
     posé APRÈS le raccourci `font:` des classes .w__*. Défaut = Arial (= chrome),
     donc un dashboard non personnalisé garde l'allure du produit ; l'éditeur change
     la valeur pour faire varier la typo des widgets partout (pas seulement l'aperçu). */
  --font-text:  var(--font-sans);   /* emplacement « Texte » : libellés, sous-titres de widget */
  --font-value: var(--font-mono);   /* emplacement « Valeurs » : mesures (chiffres tabulaires forcés au rendu) */

  --t-display: 600 2.25rem/1.05 var(--font-mono); /* valeur capteur géante */
  --t-value:   600 1.75rem/1.1  var(--font-mono); /* valeur principale widget */
  --t-value-sm:500 1.125rem/1.2 var(--font-mono); /* valeur secondaire */
  --t-title:   600 1.25rem/1.25 var(--font-sans); /* titre dashboard */
  --t-heading: 600 0.9375rem/1.3 var(--font-sans);/* titre de section */
  --t-label:   600 0.8125rem/1.3 var(--font-sans);/* libellé widget */
  --t-body:    400 0.875rem/1.45 var(--font-sans);
  --t-legend:  500 0.6875rem/1.3 var(--font-sans);/* légende */
  --t-micro:   500 0.6875rem/1.3 var(--font-mono);/* horodatage, unités */
}

/* -------- ESPACEMENT (base 4px) -------- */
:root {
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px; --s9: 56px;
}

/* -------- RAYONS & BORDURES (plat, sobre) -------- */
:root {
  --r-xs: 2px; --r-sm: 4px; --r-md: 6px; --r-lg: 8px; --r-pill: 999px;
  --r-diag-big: 24px; /* grand angle de la forme diagonale (le petit angle reste --r-lg) */
  --bw: 1px;
}

/* -------- FORME DIAGONALE DES CARTES (apparence générale) --------
   appearance.js pose [data-card-shape="diag"] sur la racine (écran produit) OU
   le conteneur d'aperçu (éditeur), + [data-card-diag] = diagonale qui porte le
   grand angle (tlbr défaut · trbl). Le petit angle reste --r-lg. Les couleurs
   d'état ne sont jamais touchées. */
[data-card-shape="diag"] .w,
[data-card-shape="diag"] .dhead,
[data-card-shape="diag"] .pk-panel,
[data-card-shape="diag"] .pk-statcard,
[data-card-shape="diag"] .pk-kpi {
  border-radius: var(--r-diag-big) var(--r-lg) var(--r-diag-big) var(--r-lg);
}
[data-card-shape="diag"][data-card-diag="trbl"] .w,
[data-card-shape="diag"][data-card-diag="trbl"] .dhead,
[data-card-shape="diag"][data-card-diag="trbl"] .pk-panel,
[data-card-shape="diag"][data-card-diag="trbl"] .pk-statcard,
[data-card-shape="diag"][data-card-diag="trbl"] .pk-kpi {
  border-radius: var(--r-lg) var(--r-diag-big) var(--r-lg) var(--r-diag-big);
}

/* -------- RESET LÉGER -------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font: var(--t-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1,h2,h3,h4,p { margin: 0; }
button { font-family: inherit; }
::selection { background: color-mix(in oklch, var(--accent) 28%, transparent); }

/* tabular numbers everywhere for mono values */
.mono, .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* -------- DIMENSIONNEMENT DES ICÔNES (défauts sûrs) -------- */
[data-ico] { display: inline-flex; align-items: center; justify-content: center; }
[data-ico] svg { width: 1em; height: 1em; }
.ts svg { width: 13px; height: 13px; flex: 0 0 auto; }
.w__label .ico { width: 16px; height: 16px; }
.w__label .ico svg { width: 16px; height: 16px; }
.pilot__q svg { width: 15px; height: 15px; flex: 0 0 auto; }
.pilot__foot svg { width: 13px; height: 13px; flex: 0 0 auto; }

/* ============================================================
   PASTILLES & PUCES D'ÉTAT (couleur + pastille + icône)
   ============================================================ */
.dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; display: inline-block; }
.dot--ok    { background: var(--ok); }
.dot--warn  { background: var(--warn); }
.dot--alarm { background: var(--alarm); }
.dot--idle  { background: var(--idle); }
.dot--info  { background: var(--info); }
.dot--pulse { box-shadow: 0 0 0 0 currentColor; animation: dotpulse 1.6s infinite; }
@keyframes dotpulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklch, var(--alarm) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px color-mix(in oklch, var(--alarm) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--alarm) 0%, transparent); }
}

.chip {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: 3px var(--s2) 3px 7px;
  border-radius: var(--r-sm);
  font: var(--t-legend);
  letter-spacing: 0.01em;
  border: var(--bw) solid transparent;
  white-space: nowrap;
}
.chip svg { width: 13px; height: 13px; flex: 0 0 auto; }
.chip--ok    { color: var(--ok-fg);    background: var(--ok-soft);    border-color: var(--ok-line); }
.chip--warn  { color: var(--warn-fg);  background: var(--warn-soft);  border-color: var(--warn-line); }
.chip--alarm { color: var(--alarm-fg); background: var(--alarm-soft); border-color: var(--alarm-line); }
.chip--idle  { color: var(--idle-fg);  background: var(--idle-soft);  border-color: var(--idle-line); }
.chip--info  { color: var(--info-fg);  background: var(--info-soft);  border-color: var(--info-line); }

/* ============================================================
   CARTE WIDGET — conteneur autonome de base
   ============================================================ */
.w {
  position: relative;
  background: var(--w-surface, var(--surface));
  border: var(--bw) solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  min-width: 0;
  overflow: hidden; /* le liseré d'état et le contenu suivent le coin (arrondi/diagonale) */
}
/* liseré d'état à gauche pour les cartes en alerte */
.w[data-state="warn"]  { border-color: var(--warn-line); }
.w[data-state="alarm"] { border-color: var(--alarm-line); background: color-mix(in oklch, var(--alarm-soft) 55%, var(--surface)); }
.w[data-state="alarm"]::before,
.w[data-state="warn"]::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  /* pas de rayon propre : la carte (overflow:hidden) le rogne au coin réel */
}
.w[data-state="warn"]::before  { background: var(--warn); }
.w[data-state="alarm"]::before { background: var(--alarm); }

.w__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
.w__label { font: var(--t-label); font-family: var(--font-text); color: var(--text); display: flex; align-items: center; gap: var(--s2); min-width: 0; }
.w__label .ico { color: var(--text-muted); flex: 0 0 auto; }
.w__sub { font: var(--t-legend); font-family: var(--font-text); color: var(--text-muted); }

.w__value { display: flex; align-items: baseline; gap: 6px; }
.w__value b { font: var(--t-value); font-family: var(--font-value); color: var(--text); letter-spacing: -0.01em; }
.w__value .unit { font: var(--t-micro); color: var(--text-2); }
.w[data-state="warn"]  .w__value b { color: var(--warn-fg); }
.w[data-state="alarm"] .w__value b { color: var(--alarm-fg); }

/* ============================================================
   MINI-JAUGE (barre + seuil)
   ============================================================ */
.gauge { display: flex; flex-direction: column; gap: 6px; }
.gauge__track {
  position: relative; height: 6px; border-radius: var(--r-pill);
  background: var(--surface-sunk); overflow: hidden;
}
.gauge__fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: var(--r-pill); }
.gauge__fill--ok    { background: var(--ok); }
.gauge__fill--warn  { background: var(--warn); }
.gauge__fill--alarm { background: var(--alarm); }
.gauge__fill--info  { background: var(--info); }
/* repère de seuil */
.gauge__thr { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--text-2); opacity: 0.55; }
.gauge__scale { display: flex; justify-content: space-between; font: var(--t-micro); color: var(--text-muted); }

/* ============================================================
   BOUTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font: var(--t-label); padding: 9px var(--s4); white-space: nowrap;
  border-radius: var(--r-md); border: var(--bw) solid var(--border-strong);
  background: var(--surface); color: var(--text); cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.btn:hover { background: var(--surface-2); border-color: var(--text-muted); }
.btn svg { width: 15px; height: 15px; }
.btn--ghost { border-color: transparent; background: transparent; color: var(--text-2); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }
.btn--primary { background: var(--accent); border-color: var(--accent); color: white; }
.btn--primary:hover { background: color-mix(in oklch, var(--accent) 88%, black); border-color: color-mix(in oklch, var(--accent) 88%, black); }

/* ============================================================
   BOUTON DE PILOTAGE (Marche/Arrêt avec confirmation)
   états : data-pilot = repos | confirm | actif | defaut
   ============================================================ */
.pilot {
  display: flex; flex-direction: column; gap: var(--s3);
}
.pilot__row { display: flex; align-items: center; gap: var(--s3); }
.pilot__btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font: var(--t-label); padding: 11px var(--s4); cursor: pointer;
  border-radius: var(--r-md); border: var(--bw) solid var(--border-strong);
  background: var(--surface-2); color: var(--text);
  transition: all .12s;
}
.pilot__btn:hover { border-color: var(--text-muted); }
.pilot__btn svg { width: 16px; height: 16px; }

.pilot[data-pilot="actif"]  .pilot__btn { background: var(--ok); border-color: var(--ok); color: white; }
.pilot[data-pilot="defaut"] .pilot__btn { background: var(--alarm-soft); border-color: var(--alarm-line); color: var(--alarm-fg); cursor: not-allowed; }

/* zone de confirmation */
.pilot__confirm { display: none; gap: var(--s2); }
.pilot[data-pilot="confirm"] .pilot__confirm { display: flex; }
.pilot[data-pilot="confirm"] .pilot__btn { display: none; }
.pilot__confirm .pilot__q { flex: 1; display: flex; align-items: center; gap: var(--s2); font: var(--t-label); color: var(--warn-fg); }
.cf-yes, .cf-no {
  padding: 9px var(--s4); border-radius: var(--r-md); cursor: pointer; font: var(--t-label);
  border: var(--bw) solid transparent;
}
.cf-yes { background: var(--ok); color: white; }
.cf-yes:hover { background: color-mix(in oklch, var(--ok) 88%, black); }
.cf-no  { background: var(--surface); border-color: var(--border-strong); color: var(--text-2); }
.cf-no:hover { color: var(--text); border-color: var(--text-muted); }

/* ============================================================
   CURSEUR / RÉGLAGE DE PARAMÈTRE
   ============================================================ */
.field { display: flex; flex-direction: column; gap: var(--s2); }
.range {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
  border-radius: var(--r-pill); background: var(--surface-sunk); outline: none; cursor: pointer;
}
.range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: grab;
  box-shadow: 0 1px 3px oklch(0 0 0 / 0.2);
}
.range::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: grab;
}
.stepper { display: inline-flex; align-items: stretch; border: var(--bw) solid var(--border-strong); border-radius: var(--r-md); overflow: hidden; }
.stepper button { width: 34px; border: none; background: var(--surface-2); color: var(--text); cursor: pointer; font-size: 16px; }
.stepper button:hover { background: var(--surface-sunk); }
.stepper input {
  width: 64px; border: none; border-left: var(--bw) solid var(--border); border-right: var(--bw) solid var(--border);
  text-align: center; background: var(--surface); color: var(--text);
  font: var(--t-value-sm); font-variant-numeric: tabular-nums;
}
.stepper input:focus { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ============================================================
   EN-TÊTE DE DASHBOARD
   ============================================================ */
.dhead {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s4) var(--s5); flex-wrap: wrap; row-gap: var(--s3);
  background: var(--surface); border: var(--bw) solid var(--border); border-radius: var(--r-lg);
}
.dhead__site { display: flex; align-items: center; gap: var(--s4); min-width: 0; flex: 1 1 240px; }
.dhead__titles { min-width: 0; }
.logo-slot {
  width: 116px; height: 44px; flex: 0 0 auto;
  border: 1px dashed var(--border-strong); border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center;
  font: var(--t-micro); color: var(--text-muted);
  background: repeating-linear-gradient(135deg, transparent 0 7px, var(--surface-2) 7px 8px);
  text-align: center; letter-spacing: 0.02em;
}
.dhead__titles h1 { font: var(--t-title); color: var(--text); }
.dhead__titles p { font: var(--t-legend); color: var(--text-muted); margin-top: 2px; }
.dhead__meta { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; row-gap: var(--s2); }
.dhead__stat { text-align: right; }
.dhead__stat .k { font: var(--t-legend); color: var(--text-muted); }
.dhead__stat .v { font: var(--t-value-sm); color: var(--text); }

/* --- En-tête PORTAIL (Accueil) : logo GTB · KPIs · identité client · logo client --- */
.dhead--portal { justify-content: flex-start; gap: var(--s5); align-items: stretch; flex-wrap: nowrap; min-height: 88px; padding: 0; }
.home__photo {
  background: repeating-linear-gradient(135deg, transparent 0 7px, var(--surface-2) 7px 8px), var(--surface);
  border: 1px dashed var(--border-strong);
}
/* Logos du bandeau : aucun cadre (transition fluide) ; l'éventuel fond blanc
   vient de `framebg` sur le slot rempli. Le logo client n'affiche jamais de
   placeholder cadré — il ne s'édite que via « Personnaliser l'accueil ». */
.dhead__logo { background: none; border: none; }
.dhead__logo::part(ring) { display: none; }
.dhead__logo::part(frame) { background: transparent; }
/* Pas d'invite de dépôt/parcours dans le bandeau : ces logos se règlent
   ailleurs (client → « Personnaliser l'accueil » ; GTB → perso Admin). */
.dhead__logo::part(empty) { display: none !important; }
/* Les deux logos : 15 % de la longueur du bandeau, toute sa hauteur. */
.dhead__integrator,
.dhead__clientlogo { flex: 0 0 15%; min-width: 0; display: flex; align-items: center; }
.dhead__clientlogo { justify-content: flex-end; }
.dhead__integrator .dhead__logo,
.dhead__clientlogo .dhead__logo { width: 100%; height: 100%; }
.dhead__by { font: var(--t-micro); color: var(--text-muted); letter-spacing: .03em; }
.dhead__kpis { flex: 1 1 auto; display: flex; gap: var(--s6); flex-wrap: nowrap; justify-content: center; align-items: center; }
.dhead__kpi { text-align: center; min-width: 72px; }
.dhead__kpi .v { font: var(--t-value-sm); color: var(--text); line-height: 1; }
.dhead__kpi .k { font: var(--t-micro); color: var(--text-muted); letter-spacing: .05em; margin-top: 5px; }
.dhead__kpi--alarm .v { color: var(--alarm-fg); }
.dhead__kpi--warn  .v { color: var(--warn-fg); }
.dhead__kpi--ok    .v { color: var(--ok-fg); }
.dhead__kpi--info  .v { color: var(--info-fg); }
.dhead__client { flex: 0 0 auto; display: flex; align-items: center; gap: var(--s4); }
/* Actions rapides du bandeau — crayon (personnaliser) + rôle — juste à gauche du nom. */
.dhead__acts { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; }
.dhead__act-role { display: flex; align-items: center; }
.dhead__act { display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; cursor: pointer; color: var(--text-2);
  background: var(--surface); border: var(--bw) solid var(--border); border-radius: var(--r-sm); }
.dhead__act:hover { color: var(--text); background: var(--surface-2); }
.dhead__act svg { width: 15px; height: 15px; }
.dhead__act[hidden] { display: none; }
.dhead__titles--right { text-align: right; flex: 0 0 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; }
.logo-slot--gtb    { width: 92px;  height: 34px; }
.logo-slot--client { width: 132px; height: 50px; }
.dhead__logo { display: block; border-radius: var(--r-sm); }
.dhead__logo--gtb    { width: 92px;  height: 34px; }
.dhead__logo--client { width: 132px; height: 50px; }
@media (max-width: 760px) {
  .dhead--portal { flex-wrap: wrap; }
  .dhead__integrator, .dhead__clientlogo { flex-basis: 22%; }
  .dhead__client { justify-content: space-between; }
  .dhead__titles--right { text-align: left; }
}

/* ============================================================
   PORTAIL ACCUEIL PERSONNALISABLE (2026-07-06) — accueil.js
   Bandeau de synthèse (tuiles choisies par le client) + image
   centrale (photo/animation) + drawer « Personnaliser ».
   ============================================================ */
/* Barre du bouton Personnaliser (les tuiles vivent dans le header) */
.home__bar { display: flex; align-items: center; justify-content: flex-end; gap: var(--s4); }
.home__cust {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer; white-space: nowrap;
  font: var(--t-label); font-weight: 600; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--r-pill); padding: 7px 14px;
}
.home__cust:hover { background: var(--surface-2); color: var(--text); }
.home__cust svg { width: 15px; height: 15px; }
.home__cust[hidden] { display: none; }

/* Tuiles de synthèse AU CENTRE DU BANDEAU (.dhead__kpis rempli par accueil.js).
   Compactes, séparées par un filet ; plafonnées à 4 pour un format constant. */
.dhead__kpis--syn { gap: 0; flex-wrap: wrap; }
.dsyn {
  display: flex; align-items: center; gap: 9px; min-width: 0;
  padding: 4px 16px; text-decoration: none; color: inherit; position: relative;
}
.dsyn + .dsyn { border-left: 1px solid var(--border); }
.dsyn__ico { flex: 0 0 auto; color: var(--text-muted); display: inline-flex; }
.dsyn__ico svg { width: 18px; height: 18px; }
.dsyn--ok .dsyn__ico    { color: var(--ok); }
.dsyn--warn .dsyn__ico  { color: var(--warn); }
.dsyn--alarm .dsyn__ico { color: var(--alarm); }
.dsyn__txt { display: flex; flex-direction: column; min-width: 0; }
.dsyn__v { font: var(--t-value-sm); line-height: 1.05; color: var(--text); white-space: nowrap; }
.dsyn__lab { font: var(--t-micro); color: var(--text-muted); white-space: nowrap; }
.dsyn--link { cursor: pointer; border-radius: var(--r-md); transition: background .12s; }
.dsyn--link:hover { background: var(--surface-2); }

/* Animations d'ambiance (alternatives à la photo) — sobres, sans donnée */
.home-anim { flex: 1 1 auto; width: 100%; min-height: 260px; border: var(--bw) solid var(--border); border-radius: var(--r-lg); overflow: hidden; position: relative; background: var(--surface-2); }
.home-anim--none { background: var(--surface); }
.home-anim--grille {
  background:
    radial-gradient(circle, var(--border-strong) 1px, transparent 1.4px) 0 0 / 26px 26px,
    var(--surface);
  animation: home-drift 26s linear infinite;
}
@keyframes home-drift { to { background-position: 26px 26px, 0 0; } }
.home-anim--ondes { display: grid; place-items: center; }
.home-anim--ondes span {
  position: absolute; width: 40px; height: 40px; border-radius: 50%;
  border: 1.5px solid var(--border-strong); opacity: 0; animation: home-ping 4.2s ease-out infinite;
}
.home-anim--ondes span:nth-child(2) { animation-delay: 1.4s; }
.home-anim--ondes span:nth-child(3) { animation-delay: 2.8s; }
@keyframes home-ping { 0% { transform: scale(1); opacity: .5; } 100% { transform: scale(9); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .home-anim--grille, .home-anim--ondes span { animation: none; } }

/* Logos du bandeau : NON éditables ici. Le logo client se règle via
   « Personnaliser l'accueil » ; le logo GTB se règle dans la partie
   personnalisée de l'Admin à la création du dashboard — jamais sur l'Accueil.
   La photo de fond (#accueil-photo) reste non éditable au Lecteur. */
html[data-role="lecteur"] #accueil-photo { pointer-events: none; }
.dhead__logo { pointer-events: none; }

/* Drawer « Personnaliser » */
.home-cust__backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.32); opacity: 0; pointer-events: none; transition: opacity .18s; z-index: 70; }
body.home-cust-open .home-cust__backdrop { opacity: 1; pointer-events: auto; }
.home-cust {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 92vw); z-index: 71;
  background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--shadow-pop);
  display: flex; flex-direction: column; transform: translateX(100%); transition: transform .2s ease;
}
body.home-cust-open .home-cust { transform: translateX(0); }
.home-cust__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s4); padding: var(--s5) var(--s5) var(--s4); border-bottom: 1px solid var(--border); }
.home-cust__head h2 { font: 700 1.1rem/1.2 var(--font-sans); color: var(--text); }
.home-cust__head p { font: var(--t-legend); color: var(--text-2); margin-top: 3px; max-width: 34ch; }
.home-cust__x { flex: 0 0 auto; border: none; background: var(--surface-2); border-radius: var(--r-md); width: 30px; height: 30px; display: grid; place-items: center; cursor: pointer; color: var(--text-2); transform: rotate(45deg); }
.home-cust__x:hover { background: var(--border); color: var(--text); }
.home-cust__x svg { width: 18px; height: 18px; }
.home-cust__body { overflow-y: auto; padding: var(--s5); display: flex; flex-direction: column; gap: var(--s6); }
.cust-sec__h { font: var(--t-label); font-weight: 700; color: var(--text); }
.cust-sec__hint { font: var(--t-legend); color: var(--text-muted); margin: 4px 0 var(--s3); }
.cust-sec__hint.is-cap { color: var(--alarm); }
.cust-list.is-full .cust-tog:not(.is-on) { opacity: .4; }
.cust-list { display: flex; flex-direction: column; gap: 5px; }
.cust-row { display: flex; align-items: center; gap: var(--s3); padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); }
.cust-row.is-drag { opacity: .5; }
.cust-row__grip { color: var(--text-muted); cursor: grab; display: inline-flex; }
.cust-row__grip svg { width: 16px; height: 16px; }
.cust-row__lab { flex: 1 1 auto; font: var(--t-label); color: var(--text); display: flex; align-items: center; gap: 8px; }
.cust-row__tag { font: var(--t-micro); text-transform: uppercase; letter-spacing: .05em; color: var(--warn-fg, var(--warn)); background: color-mix(in oklch, var(--warn) 14%, transparent); border-radius: var(--r-pill); padding: 1px 7px; }
.cust-tog { flex: 0 0 auto; width: 38px; height: 22px; border-radius: 999px; border: none; background: var(--border-strong); cursor: pointer; position: relative; transition: background .14s; }
.cust-tog span { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .14s; }
.cust-tog.is-on { background: var(--accent); }
.cust-tog.is-on span { left: 19px; }
.cust-media__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.cust-media { display: flex; flex-direction: column; gap: 7px; padding: 8px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); cursor: pointer; text-align: left; }
.cust-media.is-on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.cust-media__lab { font: var(--t-legend); font-weight: 600; color: var(--text); }
.cust-media__prev { height: 46px; border-radius: var(--r-sm); border: 1px solid var(--border); overflow: hidden; }
.cust-media__prev--photo { background: repeating-linear-gradient(135deg, transparent 0 7px, var(--surface-2) 7px 8px), var(--surface); }
.cust-media__prev--ondes { background: radial-gradient(circle at 50% 50%, var(--border-strong) 0 1px, transparent 2px), var(--surface-2); }
.cust-media__prev--grille { background: radial-gradient(circle, var(--border-strong) 1px, transparent 1.4px) 0 0 / 12px 12px, var(--surface); }
.cust-media__prev--aucun { background: var(--surface); }

/* Zones de dépôt (logo / photo) dans le panneau « Personnaliser » */
.cust-drop { display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s2); }
.cust-drop[hidden] { display: none; }
.cust-drop__slot { width: 100%; display: block; }
.cust-drop__slot--logo { height: 92px; }
.cust-drop__slot--photo { height: 150px; }
.cust-drop__edit { align-self: flex-start; border: 1px solid var(--border); background: var(--surface);
  color: var(--text); border-radius: var(--r-md); padding: 7px 12px; cursor: pointer;
  font: var(--t-legend); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.cust-drop__edit:hover { background: var(--surface-2); }
.cust-drop__edit svg { width: 15px; height: 15px; }

/* Éditeur de recadrage plein écran (accueil.js) : centrer / rogner / zoomer */
.home-crop { position: fixed; inset: 0; z-index: 92; display: grid; place-items: center; padding: var(--s5);
  background: rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .18s; }
.home-crop.show { opacity: 1; pointer-events: auto; }
.home-crop__card { width: min(760px, 94vw); background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-pop); display: flex; flex-direction: column;
  max-height: 92vh; overflow: hidden; }
.home-crop__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s4) var(--s5); border-bottom: 1px solid var(--border); }
.home-crop__head h3 { font: 700 1.05rem/1.2 var(--font-sans); color: var(--text); }
.home-crop__x { border: none; background: var(--surface-2); border-radius: var(--r-md); width: 30px; height: 30px;
  display: grid; place-items: center; cursor: pointer; color: var(--text-2); }
.home-crop__x:hover { background: var(--border); color: var(--text); }
.home-crop__x svg { width: 18px; height: 18px; }
.home-crop__stage { padding: var(--s6) var(--s5) var(--s5); display: grid; place-items: center;
  background: var(--surface-sunk); overflow: auto; }
.home-crop__stage image-slot { max-width: 100%; }
.home-crop__hint { padding: var(--s3) var(--s5) 0; font: var(--t-legend); color: var(--text-muted); text-align: center; }
.home-crop__ctl { display: flex; align-items: center; gap: var(--s4); padding: var(--s4) var(--s5);
  border-top: 1px solid var(--border); margin-top: var(--s3); }
.home-crop__zoom { display: flex; align-items: center; gap: var(--s3); flex: 1 1 auto;
  font: var(--t-legend); color: var(--text-2); }
.home-crop__zoom input { flex: 1 1 auto; accent-color: var(--accent); }
.home-crop__reset { border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  border-radius: var(--r-md); padding: 7px 12px; cursor: pointer; font: var(--t-legend); font-weight: 600; }
.home-crop__reset:hover { background: var(--surface-2); color: var(--text); }
.home-crop__done { border: none; background: var(--accent); color: #fff; border-radius: var(--r-md);
  padding: 8px 18px; cursor: pointer; font: var(--t-label); font-weight: 700; }
.home-crop__done:hover { filter: brightness(1.06); }

/* ---- Coquille SPA (shell.js) : scène centrale + panneau flottant -------- */
.shell__stage { position: relative; flex: 1 1 auto; min-height: 440px; border-radius: var(--r-lg); overflow: hidden; }
.shell__stage #hero, .shell__stage .home__hero { position: absolute; inset: 0; min-height: 0; display: block; }
.shell__stage .home__photo, .shell__stage .home-anim { width: 100%; height: 100%; min-height: 0; border: 0; border-radius: 0; }
/* Fond assombri quand un onglet est ouvert → focus sur le contenu */
.shell__stage.has-panel::after { content: ""; position: absolute; inset: 0; background: rgba(12,17,26,.24); pointer-events: none; }
/* Panneau flottant : conteneur de l'iframe. Transparent — les widgets
   « flottent » directement sur le fond d'écran (plus de surface blanche
   intermédiaire). On garde inset + border-radius pour la géométrie/clip. */
.shell__panel { position: absolute; inset: 12px; z-index: 1; display: flex;
  background: transparent; border: 0; border-radius: var(--r-lg);
  box-shadow: none; overflow: hidden; }
.shell__panel[hidden] { display: none; }
.shell__frame { flex: 1 1 auto; width: 100%; height: 100%; border: 0; background: transparent; }
/* Bouton ⋮ : options de l'onglet courant (menu : actions de l'écran + Fermer) */
.shell__menu-btn { position: absolute; z-index: 3; top: 20px; right: 34px; width: 32px; height: 32px;
  border-radius: 50%; border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-pop); }
.shell__menu-btn[hidden] { display: none; }
.shell__menu-btn svg { width: 18px; height: 18px; }
.shell__menu-btn:hover, .shell__menu-btn[aria-expanded="true"] { background: var(--surface-2); color: var(--text); }
.shell__menu { position: absolute; z-index: 4; top: 58px; right: 34px; min-width: 210px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-pop); padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.shell__menu[hidden] { display: none; }
.shell__menu-item { display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: left;
  border: none; background: none; cursor: pointer; padding: 9px 10px; border-radius: var(--r-sm);
  font: var(--t-label); color: var(--text); }
.shell__menu-item:hover { background: var(--surface-2); }
.shell__menu-ico { display: grid; place-items: center; width: 18px; height: 18px; color: var(--text-muted); flex: 0 0 auto; }
.shell__menu-ico svg { width: 17px; height: 17px; }
.shell__menu-item--close { color: var(--text-2); }
.shell__menu-sep { height: 1px; background: var(--border); margin: 4px 2px; }

/* Onglet actif « flottant » (variante centrée du portail) */
.appnav--center .appnav__tabs a.is-active { box-shadow: var(--shadow-pop); }

/* ---- Mode EMBARQUÉ : un écran chargé dans l'iframe de la coquille masque
   son propre chrome (la coquille le porte déjà) — voir nav.js. ---------- */
html.is-embed .themebar,
html.is-embed .appnav,
html.is-embed .sv-chrome,
html.is-embed .rolemenu { display: none !important; }
html.is-embed body { padding-left: 0 !important; padding-right: 0 !important; }
/* Fond transparent en embarqué : le fond d'écran de la coquille est visible
   à travers l'iframe, les widgets « flottent » dessus (plus de fond blanc). */
html.is-embed, html.is-embed body { background: transparent !important; }
/* Titre d'écran redondant masqué en embarqué : l'onglet actif est visible dans
   la barre de la coquille juste au-dessus. On garde chapôs + contrôles. */
/* Titre + chapô/sous-titre redondants masqués en embarqué : l'onglet actif est
   visible dans la barre de la coquille juste au-dessus. */
html.is-embed .pk-masthead__title,
html.is-embed .pk-masthead__sub,
html.is-embed .pk-lede,
html.is-embed .viewbar h1,
html.is-embed .viewbar .sub { display: none !important; }
/* Contenu placé plus haut : l'écran embarqué n'a plus besoin de la marge du
   haut (la coquille porte déjà le cadre + les onglets au-dessus). */
html.is-embed .page { padding-top: var(--s4) !important; }
/* Contrôles remontés dans le menu ⋮ de la coquille : masqués dans l'écran. */
html.is-embed [data-shell-hide-embed] { display: none !important; }
/* En embarqué, l'en-tête est vidé (titre/chapô masqués) : on collapse ses
   marges et tout trait de séparation (ex. Calendrier) pour remonter le contenu. */
html.is-embed .pk-masthead { margin-bottom: var(--s4) !important; padding-bottom: 0 !important; border-bottom: 0 !important; }

/* --- Barre d'onglets CENTRÉE, en flux (variante Accueil/portail) --- */
.appnav--center {
  position: static; justify-content: center; border-bottom: none;
  background: transparent; height: auto; padding: var(--s2) var(--s4);
}
.appnav--center .appnav__brand { display: none; }
.appnav--center .appnav__tabs {
  background: var(--surface); border: var(--bw) solid var(--border);
  border-radius: var(--r-pill); padding: 4px; gap: 2px; box-shadow: var(--shadow-pop);
}
.appnav--center .appnav__tabs a {
  border-bottom: none; border-radius: var(--r-pill); height: auto; padding: 9px var(--s4);
}
.appnav--center .appnav__tabs a:hover { background: var(--surface-2); }
.appnav--center .appnav__tabs a.is-active { background: var(--surface-2); color: var(--text); border-bottom: none; }

/* ============================================================
   SPARKLINE (tendance énergie)
   ============================================================ */
.spark { width: 100%; height: 46px; display: block; }
.spark path.line { fill: none; stroke: var(--accent); stroke-width: 1.75; }
.spark path.area { fill: color-mix(in oklch, var(--accent) 14%, transparent); stroke: none; }

/* mini-graphe avec axes : conso (ordonnée) en fonction du temps (abscisse) */
.chart__periods { display: flex; gap: 3px; padding: 3px; background: var(--surface-sunk); border: 1px solid var(--border); border-radius: var(--r-pill); align-self: flex-start; }
.chart__period-btn { border: none; background: transparent; cursor: pointer; font: var(--t-micro); color: var(--text-2); padding: 4px 11px; border-radius: var(--r-pill); }
.chart__period-btn:hover { color: var(--text); }
.chart__period-btn[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-pop); }
.energy-chart:empty { display: none; }
.chart { display: grid; grid-template-columns: auto minmax(0,1fr); grid-template-rows: 1fr auto; column-gap: 8px; row-gap: 5px; }
.chart__y { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; font: var(--t-micro); color: var(--text-muted); }
.chart__plot { grid-column: 2; grid-row: 1; position: relative; min-height: 56px; }
.chart__svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.chart__x { grid-column: 2; grid-row: 2; display: flex; justify-content: space-between; font: var(--t-micro); color: var(--text-muted); }
.chart__grid { stroke: var(--border); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart__svg path.line { fill: none; stroke: var(--accent); stroke-width: 1.75; vector-effect: non-scaling-stroke; }
.chart__svg path.area { fill: color-mix(in oklch, var(--accent) 14%, transparent); stroke: none; }

/* ============================================================
   UTILITAIRES
   ============================================================ */
.row { display: flex; align-items: center; gap: var(--s3); }
.col { display: flex; flex-direction: column; }
.between { justify-content: space-between; }
.grow { flex: 1; }
.muted { color: var(--text-muted); }
.ts { font: var(--t-micro); color: var(--text-muted); display: inline-flex; align-items: center; gap: 5px; }
.kbd { font: var(--t-micro); padding: 1px 5px; border: 1px solid var(--border-strong); border-radius: var(--r-xs); color: var(--text-2); background: var(--surface-2); }

/* barre d'outils flottante de thème, partagée */
.themebar {
  position: fixed; top: 14px; right: 14px; z-index: 50;
  display: inline-flex; align-items: center; gap: 2px; padding: 3px;
  background: var(--surface); border: var(--bw) solid var(--border); border-radius: var(--r-pill);
  box-shadow: var(--shadow-pop);
}
.themebar button {
  display: inline-flex; align-items: center; gap: 6px; border: none; cursor: pointer;
  background: transparent; color: var(--text-2); font: var(--t-legend);
  padding: 6px 12px; border-radius: var(--r-pill);
}
.themebar button svg { width: 14px; height: 14px; }
.themebar button[aria-pressed="true"] { background: var(--surface-sunk); color: var(--text); }

/* ============================================================
   BARRE D'ONGLETS APPLICATIVE (coquille des Écrans)
   Relie les pages : Accueil · Calendrier · Alertes · Historique
   ============================================================ */
.appnav {
  display: flex; align-items: stretch; gap: var(--s6);
  height: 58px; padding: 0 var(--s6);
  background: var(--surface); border-bottom: var(--bw) solid var(--border);
  position: sticky; top: 0; z-index: 40;
}
.appnav__brand { display: flex; align-items: center; gap: var(--s3); flex: 0 0 auto; }
.appnav__brand .mark {
  width: 28px; height: 28px; border-radius: var(--r-sm);
  background: var(--text); color: var(--surface);
  display: grid; place-items: center; font: 700 13px/1 var(--font-mono);
}
.appnav__brand b { font: 700 0.95rem/1 var(--font-sans); letter-spacing: 0.04em; color: var(--text); }
.appnav__tabs { display: flex; align-items: stretch; }
.appnav__tabs a {
  display: inline-flex; align-items: center; gap: 8px; height: 100%;
  padding: 0 var(--s4); color: var(--text-2); text-decoration: none;
  font: var(--t-label); border-bottom: 2px solid transparent;
  transition: color .12s, background .12s, border-color .12s;
}
.appnav__tabs a:hover { color: var(--text); background: var(--surface-2); }
.appnav__tabs a.is-active { color: var(--text); border-bottom-color: var(--accent); }
.appnav__tabs a svg { width: 16px; height: 16px; }
/* Barre haute : les onglets peuvent défiler horizontalement si trop nombreux,
   et on réserve une gouttière à droite pour la barre de thème flottante. */
.appnav:not(.appnav--rail) .appnav__tabs {
  flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none;
}
.appnav:not(.appnav--rail) .appnav__tabs::-webkit-scrollbar { display: none; }
/* Gouttière droite : réservée à la barre de thème flottante (~159px + marges).
   Doit rester ≥ largeur .themebar sinon elle chevauche le dernier onglet.
   EXCLUT la barre centrée (portail) : elle doit rester centrée sur l'écran. */
.appnav:not(.appnav--rail):not(.appnav--center) { padding-right: 195px; }
.appnav__tabs a { flex: 0 0 auto; white-space: nowrap; }
.appnav__badge {
  font: var(--t-micro); background: var(--alarm); color: #fff;
  border-radius: var(--r-pill); padding: 1px 6px; min-width: 17px; text-align: center;
}
.appnav__right { margin-left: auto; display: flex; align-items: center; gap: var(--s4); }
.appnav__site { text-align: right; }
.appnav__site .k { font: var(--t-micro); color: var(--text-muted); }
.appnav__site .v { font: var(--t-label); color: var(--text); }
@media (max-width: 640px) {
  .appnav { gap: var(--s3); padding: 0 var(--s3); }
  .appnav__brand b, .appnav__right { display: none; }
  .appnav__tabs a { padding: 0 var(--s3); }
}

/* --- Rail vertical : position « gauche » ou « droite » (choix client) ---
   La barre quitte le haut et devient une colonne pleine hauteur.
   Le <body> reçoit un padding pour libérer la place. */
.appnav--rail {
  position: fixed; top: 0; bottom: 0; height: 100vh; width: 212px;
  flex-direction: column; align-items: stretch; gap: var(--s4);
  padding: var(--s5) var(--s4); border-bottom: none; z-index: 50;
}
.appnav--rail.appnav--left  { left: 0; right: auto; border-right: 1px solid var(--border); }
.appnav--rail.appnav--right { right: 0; left: auto;  border-left: 1px solid var(--border); }
.appnav--rail .appnav__brand { padding: var(--s2) var(--s3) var(--s4); }
.appnav--rail .appnav__tabs { flex-direction: column; align-items: stretch; gap: 3px; }
.appnav--rail .appnav__tabs a {
  height: auto; padding: 10px var(--s3); border-bottom: none; border-radius: var(--r-md);
}
.appnav--rail .appnav__tabs a.is-active {
  background: var(--surface-2); color: var(--text);
  border-bottom: none; box-shadow: inset 3px 0 0 var(--accent);
}
.appnav--rail .appnav__tabs a .appnav__badge { margin-left: auto; }
.appnav--rail .appnav__right { margin: auto 0 0; }
.appnav--rail .appnav__site { text-align: left; }
body.has-rail-left  { padding-left: 212px; }
body.has-rail-right { padding-right: 212px; }
@media (max-width: 640px) {
  .appnav--rail { position: sticky; top: 0; bottom: auto; height: auto; width: auto;
    flex-direction: row; align-items: stretch; padding: 0 var(--s3);
    border: none; border-bottom: 1px solid var(--border); }
  body.has-rail-left, body.has-rail-right { padding-left: 0; padding-right: 0; }
}

/* ============================================================
   BARRE D'ONGLETS ADMIN (.adminnav) — outils de l'intégrateur.
   Composant PARTAGÉ monté par adminnav.js, embarqué dans la barre
   haute de chaque page outil (Parc/Créer/Atelier/Bibliothèque/Accès)
   → même navigation partout, elle ne « bouge » plus d'une page à
   l'autre. Même langage visuel que .appnav (icône + libellé + accent).
   ============================================================ */
.adminnav { display: flex; align-items: center; gap: var(--s3); flex: 0 1 auto; min-width: 0; }
.adminnav__tabs { display: flex; align-items: center; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.adminnav__tabs::-webkit-scrollbar { display: none; }
.adminnav__tabs a {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; flex: 0 0 auto;
  font: var(--t-label); color: var(--text-2); text-decoration: none;
  padding: 8px 10px; border-radius: var(--r-md); border: 1px solid transparent;
  transition: color .12s, background .12s, box-shadow .12s;
}
.adminnav__tabs a:hover { color: var(--text); background: var(--surface-2); }
.adminnav__tabs a.is-active { color: var(--text); background: var(--surface-2); box-shadow: inset 0 -2px 0 var(--accent); }
.adminnav__tabs a svg { width: 15px; height: 15px; }
.adminnav__right { display: flex; align-items: center; flex: 0 0 auto; padding-left: var(--s2); }
.adminnav__super {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  font: var(--t-label); color: var(--accent); text-decoration: none;
  padding: 8px 12px; border-radius: var(--r-md);
  border: 1px solid color-mix(in oklch, var(--accent) 32%, var(--border));
}
.adminnav__super:hover { background: color-mix(in oklch, var(--accent) 8%, var(--surface)); }
.adminnav__super svg { width: 15px; height: 15px; }
@media (max-width: 1040px) {
  .adminnav__super-lb { display: none; }
}
/* Variante BANDEAU pleine largeur : la barre admin est sa PROPRE rangée en
   haut de chaque page outil (placement identique partout, en-tête inchangé).
   La barre est vide dans le HTML puis remplie par adminnav.js — on RÉSERVE
   dès le CSS la hauteur EXACTE des deux rangées (120px = bande ~61 + rangée
   client ~59) ET son fond bi-ton (bande sombre + rangée client plus sombre)
   pour éviter le flash blanc, le saut de contenu ET le changement de couleur
   au chargement de chaque page. Doit rester égal au min-height de
   .adminnav--atelier (sinon micro-saut quand le JS pose la classe). */
.adminbar { gap: var(--s4); padding: 0; min-height: 120px; flex: 0 0 auto;
  background: linear-gradient(to bottom, oklch(0.32 0.055 264) 0 61px, oklch(0.28 0.05 264) 61px);
  border-bottom: 1px solid oklch(0.2 0.04 264); }
.adminbar .adminnav__tabs { flex: 0 1 auto; }
.adminbar .adminnav__right { margin-left: auto; padding-left: var(--s4); }

/* ============================================================
   PEAU « ATELIER » (2026-07-02) — frontière nette Admin ↔ Superviseur.
   Les 5 écrans OUTILS de l'intégrateur (Parc/Créer/Atelier/Bibliothèque/
   Accès) portent un bandeau « établi » sombre + accent ambre, nettement
   distinct du produit client (supervision, neutre aux couleurs du client).
   Deux rangées : (1) .adminnav__band = badge « Atelier » + contexte client
   + sélecteur d'espace (Superviser ⇄ Atelier) ; (2) .adminnav__tabs = les
   outils. La classe .adminnav--atelier est posée par adminnav.js.
   ============================================================ */
.adminnav--atelier {
  --at-band: oklch(0.32 0.055 264);
  --at-band-2: oklch(0.28 0.05 264);
  --at-ink: oklch(0.96 0.01 264);
  --at-ink-2: oklch(0.78 0.03 264);
  --at-accent: oklch(0.74 0.13 88);
  --at-face: var(--surface);
  /* min-height ÉGAL à .adminbar : la classe est posée par JS après coup ;
     garder la même hauteur réservée évite tout saut au montage. */
  display: block; padding: 0; min-height: 120px;
  flex: 0 0 auto;   /* le <body> est en flex column : ne pas laisser le bandeau 2 rangées s'écraser */
  background: var(--at-band-2);
  border-bottom: 1px solid color-mix(in oklch, black 30%, var(--at-band-2));
}
html[data-theme="dark"] .adminnav--atelier { --at-face: oklch(0.24 0.02 264); }
.adminnav--atelier .adminnav__band {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 20px; background: var(--at-band); color: var(--at-ink);
}
.adminnav--atelier .adminnav__badge {
  display: inline-flex; align-items: center; gap: 8px; padding: 5px 11px; border-radius: var(--r-pill);
  background: color-mix(in oklch, var(--at-accent) 24%, transparent);
  border: 1px solid color-mix(in oklch, var(--at-accent) 55%, transparent);
  color: var(--at-ink); font: var(--t-micro); font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}
.adminnav--atelier .adminnav__badge svg { width: 14px; height: 14px; color: var(--at-accent); }
.adminnav--atelier .adminnav__ctx { font: var(--t-legend); color: var(--at-ink-2); }
.adminnav--atelier .adminnav__ctx b { color: var(--at-ink); font-weight: 700; margin-left: 6px; }
.adminnav--atelier .adminnav__switch {
  margin-left: auto; display: inline-flex; gap: 3px; padding: 4px;
  background: color-mix(in oklch, black 22%, transparent); border-radius: var(--r-pill);
}
.adminnav--atelier .adminnav__switch .seg {
  display: inline-flex; align-items: center; gap: 7px; padding: 7px 14px; border-radius: var(--r-pill);
  font: var(--t-label); font-weight: 600; color: var(--at-ink-2); text-decoration: none; cursor: pointer;
}
.adminnav--atelier .adminnav__switch .seg svg { width: 15px; height: 15px; }
.adminnav--atelier .adminnav__switch a.seg:hover { color: var(--at-ink); background: color-mix(in oklch, white 8%, transparent); }
.adminnav--atelier .adminnav__switch .seg.is-on {
  background: var(--at-face); color: oklch(0.28 0.05 264); box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.adminnav--atelier .adminnav__switch .seg.is-on svg { color: var(--at-accent); }
/* Rangée GÉNÉRALE (dans la bande) : nav globale Parc · Bibliothèque.
   Rangée CLIENT : outils scopés, sous le sélecteur de client. Les deux
   familles partagent le même langage d'onglet (icone + libellé + accent). */
.adminnav--atelier .adminnav__gnav { display: flex; align-items: center; gap: 3px; min-width: 0; }
.adminnav--atelier .adminnav__tabs {
  display: flex; align-items: center; gap: 3px; padding: 8px 16px; min-width: 0;
  overflow-x: auto; scrollbar-width: none;
}
.adminnav--atelier .adminnav__tabs::-webkit-scrollbar { display: none; }
.adminnav--atelier .adminnav__tabs a,
.adminnav--atelier .adminnav__gnav a {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; flex: 0 0 auto;
  padding: 8px 13px; border-radius: var(--r-md); font: var(--t-label); font-weight: 600;
  color: var(--at-ink-2); text-decoration: none; box-shadow: none; background: none;
}
.adminnav--atelier .adminnav__tabs a svg,
.adminnav--atelier .adminnav__gnav a svg { width: 15px; height: 15px; }
.adminnav--atelier .adminnav__tabs a:hover,
.adminnav--atelier .adminnav__gnav a:hover { background: color-mix(in oklch, white 8%, transparent); color: var(--at-ink); }
.adminnav--atelier .adminnav__tabs a.is-active,
.adminnav--atelier .adminnav__gnav a.is-active {
  background: var(--at-face); color: oklch(0.28 0.05 264); box-shadow: inset 0 -2px 0 var(--at-accent);
}
html[data-theme="dark"] .adminnav--atelier .adminnav__switch .seg.is-on,
html[data-theme="dark"] .adminnav--atelier .adminnav__tabs a.is-active,
html[data-theme="dark"] .adminnav--atelier .adminnav__gnav a.is-active { color: var(--at-ink); }

/* RANGÉE 2 — CONTEXTE CLIENT (2026-07-06). Fond légèrement plus sombre que
   la bande générale : sous-niveau visible. « Je travaille dans CE client. »
   Le sélecteur de client est le garde-fou (on lit/change en permanence pour
   QUI on configure) ; les onglets scopés le suivent. */
.adminnav--atelier .adminnav__crow {
  display: flex; align-items: center; gap: 14px; min-width: 0;
  padding: 7px 20px; background: var(--at-band-2);
  border-top: 1px solid color-mix(in oklch, black 22%, transparent);
}
.adminnav--atelier .adminnav__crow .adminnav__tabs { padding: 0; }
.adminnav--atelier .adminnav__crow-div {
  width: 1px; height: 22px; flex: 0 0 auto;
  background: color-mix(in oklch, white 12%, transparent);
}
/* --- CONTEXTE CLIENT dans le bandeau Atelier (2026-07-06) ---
   Outils scopés = sélecteur de client (.adminnav__client). Parc = état neutre
   « Tous les clients » (.adminnav__scope). Le sélecteur est le garde-fou :
   on lit et on change en permanence pour QUEL client on configure. */
.adminnav--atelier .adminnav__scope {
  display: inline-flex; align-items: center; gap: 8px;
  font: var(--t-legend); color: var(--at-ink-2);
  padding: 6px 12px; border-radius: var(--r-pill);
  background: color-mix(in oklch, black 16%, transparent);
}
.adminnav--atelier .adminnav__scope svg { width: 15px; height: 15px; color: var(--at-ink-2); }

.adminnav--atelier .adminnav__client { position: relative; }
.adminnav--atelier .anc-btn {
  display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  padding: 5px 11px 5px 12px; border-radius: var(--r-md);
  background: color-mix(in oklch, black 20%, transparent);
  border: 1px solid color-mix(in oklch, var(--at-accent) 26%, transparent);
  color: var(--at-ink); text-align: left;
}
.adminnav--atelier .anc-btn:hover { background: color-mix(in oklch, black 30%, transparent); border-color: color-mix(in oklch, var(--at-accent) 48%, transparent); }
.adminnav--atelier .anc-btn > svg { width: 16px; height: 16px; color: var(--at-accent); flex: 0 0 auto; }
.adminnav--atelier .anc-txt { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.adminnav--atelier .anc-cap { font: var(--t-micro); letter-spacing: .06em; text-transform: uppercase; color: var(--at-ink-2); }
.adminnav--atelier .anc-txt b { font: var(--t-label); font-weight: 700; color: var(--at-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.adminnav--atelier .anc-chev svg { width: 15px; height: 15px; color: var(--at-ink-2); transition: transform .14s; }
.adminnav--atelier .adminnav__client[data-open="true"] .anc-chev svg { transform: rotate(180deg); }

.adminnav--atelier .adminnav__client-menu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
  min-width: 300px; max-width: 360px; padding: 6px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: 0 12px 40px rgba(0,0,0,.28);
}
.adminnav--atelier .anc-menu-h {
  font: var(--t-micro); letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); padding: 7px 10px 6px;
}
.adminnav--atelier .anc-item {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  padding: 9px 10px; border: none; background: none; border-radius: var(--r-md);
  text-align: left; color: var(--text);
}
.adminnav--atelier .anc-item:hover { background: var(--surface-2); }
.adminnav--atelier .anc-item.is-sel { background: color-mix(in oklch, var(--accent) 10%, var(--surface)); }
.adminnav--atelier .anc-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.adminnav--atelier .anc-dot--alarm { background: var(--alarm); }
.adminnav--atelier .anc-dot--warn  { background: var(--warn); }
.adminnav--atelier .anc-dot--ok    { background: var(--ok); }
.adminnav--atelier .anc-lab { display: flex; flex-direction: column; line-height: 1.2; flex: 1; min-width: 0; }
.adminnav--atelier .anc-lab b { font: var(--t-label); font-weight: 600; color: var(--text); }
.adminnav--atelier .anc-lab span { font: var(--t-micro); color: var(--text-muted); }
.adminnav--atelier .anc-ck { margin-left: auto; color: var(--accent); display: inline-flex; }
.adminnav--atelier .anc-ck svg { width: 16px; height: 16px; }

@media (max-width: 720px) {
  .adminnav--atelier .adminnav__ctx { display: none; }
  .adminnav--atelier .anc-cap { display: none; }
  .adminnav--atelier .adminnav__band { gap: 10px; padding: 9px 14px; }
}


/* ============================================================
   SÉLECTEUR DE MODE (segmenté) — Auto / Manu / Arrêt, etc.
   Changement = confirmation (équipement sensible).
   ============================================================ */
.modeseg { display: flex; flex-direction: column; gap: var(--s3); }
.modeseg__row { display: inline-flex; background: var(--surface-sunk); border: var(--bw) solid var(--border); border-radius: var(--r-md); padding: 3px; gap: 2px; }
.modeseg__btn { flex: 1; border: none; background: transparent; cursor: pointer; font: var(--t-label); color: var(--text-2); padding: 9px 12px; border-radius: var(--r-sm); transition: background .12s, color .12s; }
.modeseg__btn:hover { color: var(--text); }
.modeseg__btn[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-pop); }
.modeseg__confirm { display: none; align-items: center; gap: var(--s2); }
.modeseg.confirming .modeseg__confirm { display: flex; }
.modeseg__q { flex: 1; display: inline-flex; align-items: center; gap: var(--s2); font: var(--t-label); color: var(--warn-fg); }
.modeseg__q svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* ============================================================
   INTERRUPTEUR SIMPLE (toggle) — niveau « courant »
   Action directe + confirmation simple, sans mode édition.
   ============================================================ */
.switchrow { display: flex; align-items: center; gap: var(--s3); }
.switch { width: 46px; height: 26px; flex: 0 0 auto; padding: 0; position: relative; cursor: pointer;
  border-radius: var(--r-pill); border: var(--bw) solid var(--border-strong); background: var(--surface-sunk);
  transition: background .15s, border-color .15s; }
.switch__knob { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 2px oklch(0 0 0 / 0.25); transition: left .15s; }
.switch[aria-checked="true"] { background: var(--ok); border-color: var(--ok); }
.switch[aria-checked="true"] .switch__knob { left: 22px; }
.switch__state { font: var(--t-label); color: var(--text-2); }
.switchrow[data-on="1"] .switch__state { color: var(--ok-fg); }
.switch__confirm { display: none; align-items: center; gap: var(--s2); margin-left: auto; }
.switch__confirm .ts { color: var(--warn-fg); }
.switchrow.confirming .switch__confirm { display: flex; }
.switchrow.confirming .switch__state { display: none; }

/* ============================================================
   ÉTAT « DONNÉE PÉRIMÉE / HORS-LIGNE » (perte de communication)
   Jamais de fausse valeur : la carte est grisée + hachurée.
   ============================================================ */
.w[data-stale="1"] {
  border-color: var(--border-strong);
  background: repeating-linear-gradient(135deg, var(--surface) 0 9px, var(--surface-2) 9px 10px);
}
.w[data-stale="1"] .w__value b { color: var(--text-muted); }
.w[data-stale="1"] .w__label .ico { color: var(--text-muted); }
.w[data-stale="1"] .gauge__fill { background: var(--idle); opacity: 0.5; }
.w[data-stale="1"] .spark path.line { stroke: var(--idle); }
.w[data-stale="1"] .spark path.area { fill: color-mix(in oklch, var(--idle) 12%, transparent); }
.w[data-stale="1"] .chart__svg path.line { stroke: var(--idle); }
.w[data-stale="1"] .chart__svg path.area { fill: color-mix(in oklch, var(--idle) 12%, transparent); }

/* ============================================================
   COMPOSANTS DE PAGE  (préfixe .pk-)
   Briques cataloguées d'ASSEMBLAGE des écrans (au-delà des
   widgets autonomes) : en-tête de page, barre d'outils, filtre
   segmenté, recherche, filtre Lieu×Type, cartes de synthèse,
   indicateurs, ligne d'alerte, journal, état vide, panneau.
   Fabriquées par pagekit.js — JAMAIS de markup ad hoc en page.
   Préfixe pk- = zéro collision avec les pages « Bloc ».
   ============================================================ */

/* En-tête de page (titre + chapô, slot optionnel à droite) */
.pk-masthead { display:flex; align-items:flex-end; justify-content:space-between; gap:var(--s5); margin-bottom:var(--s6); flex-wrap:wrap; }
.pk-masthead__main { min-width:0; }
.pk-masthead__title { font:700 1.5rem/1.1 var(--font-sans); letter-spacing:-0.01em; color:var(--text); }
.pk-masthead__lede { max-width:64ch; font:var(--t-body); color:var(--text-2); margin-top:var(--s3); }
/* Chapô repliable : clampé à 1 ligne par défaut, dépliable via « En savoir plus ».
   Allège la densité en usage quotidien tout en gardant l'aide accessible. */
.pk-lede { max-width:64ch; margin-top:var(--s3); }
.pk-lede__tx { font:var(--t-body); color:var(--text-2); margin:0; }
.pk-lede:not(.is-open) .pk-lede__tx {
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:1; overflow:hidden;
}
.pk-lede__more {
  margin-top:2px; padding:0; border:none; background:none; cursor:pointer;
  font:var(--t-label); font-weight:600; color:var(--accent);
}
.pk-lede__more:hover { text-decoration:underline; }
.pk-masthead__sub { font:var(--t-legend); color:var(--text-muted); margin-top:4px; }
.pk-masthead__aside { flex:0 0 auto; }

/* Barre d'outils (rangée de filtres / actions) */
.pk-toolbar { display:flex; align-items:center; gap:var(--s4); margin-bottom:var(--s5); flex-wrap:wrap; }
.pk-toolbar__end { margin-left:auto; }

/* Filtre segmenté */
.pk-seg { display:inline-flex; background:var(--surface-sunk); border:1px solid var(--border); border-radius:var(--r-md); padding:3px; gap:2px; }
.pk-seg__btn { border:none; background:transparent; cursor:pointer; font:var(--t-label); color:var(--text-2); padding:7px 13px; border-radius:var(--r-sm); display:inline-flex; align-items:center; gap:7px; }
.pk-seg__btn:hover { color:var(--text); }
.pk-seg__btn[aria-pressed="true"] { background:var(--surface); color:var(--text); box-shadow:var(--shadow-pop); }
.pk-seg__dot { width:8px; height:8px; border-radius:50%; flex:0 0 auto; }

/* Recherche */
.pk-search { position:relative; }
.pk-search input { font:var(--t-body); color:var(--text); background:var(--surface); border:1px solid var(--border-strong); border-radius:var(--r-md); padding:8px 12px 8px 32px; width:220px; }
.pk-search input:focus { outline:2px solid var(--accent); outline-offset:-1px; }
.pk-search svg { position:absolute; left:10px; top:50%; transform:translateY(-50%); color:var(--text-muted); width:15px; height:15px; }

/* Barre de filtres encadrée (Lieu × Type × période…) */
.pk-filterbar { display:flex; align-items:flex-end; gap:var(--s4); flex-wrap:wrap; padding:var(--s4) var(--s5); background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); margin-bottom:var(--s5); }
.pk-field { display:flex; flex-direction:column; gap:6px; }
.pk-field > label { font:var(--t-micro); color:var(--text-muted); letter-spacing:0.05em; text-transform:uppercase; display:flex; align-items:center; gap:6px; }
.pk-field > label svg { width:13px; height:13px; }
.pk-select { appearance:none; -webkit-appearance:none; font:var(--t-label); color:var(--text); background:var(--surface-2); border:1px solid var(--border-strong); border-radius:var(--r-md); padding:9px var(--s6) 9px var(--s4); cursor:pointer; min-width:200px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>"); background-repeat:no-repeat; background-position:right 12px center; }
.pk-fseg { display:inline-flex; gap:2px; padding:3px; background:var(--surface-sunk); border:1px solid var(--border-strong); border-radius:var(--r-pill); }
.pk-fseg button { border:none; cursor:pointer; background:transparent; color:var(--text-2); font:var(--t-legend); padding:8px 14px; border-radius:var(--r-pill); white-space:nowrap; }
.pk-fseg button[aria-pressed="true"] { background:var(--surface); color:var(--text); box-shadow:var(--shadow-pop); }
.pk-ftoggle { display:inline-flex; align-items:center; gap:var(--s2); cursor:pointer; font:var(--t-label); color:var(--text-2); user-select:none; padding-bottom:9px; }
.pk-ftoggle input { position:absolute; opacity:0; pointer-events:none; }
.pk-ftoggle .sw { width:38px; height:22px; border-radius:var(--r-pill); background:var(--surface-sunk); border:1px solid var(--border-strong); position:relative; flex:0 0 auto; transition:background .15s; }
.pk-ftoggle .sw::after { content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:var(--text-muted); transition:left .15s, background .15s; }
.pk-ftoggle input:checked + .sw { background:color-mix(in oklch, var(--accent) 30%, transparent); border-color:var(--accent); }
.pk-ftoggle input:checked + .sw::after { left:18px; background:var(--accent); }
.pk-filterbar__spacer { flex:1; }

/* Cartes de synthèse (compteur + libellé) */
.pk-statcards { display:grid; grid-template-columns:repeat(var(--pk-cols,3),1fr); gap:var(--s4); margin-bottom:var(--s6); }
@media (max-width:640px){ .pk-statcards { grid-template-columns:1fr; } }
.pk-statcard { background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:var(--s4) var(--s5); display:flex; align-items:center; gap:var(--s4); }
.pk-statcard__n { font:var(--t-display); font-size:2rem; line-height:1; font-variant-numeric:tabular-nums; }
.pk-statcard__lab { font:var(--t-legend); color:var(--text-muted); }
.pk-statcard--alarm { border-color:var(--alarm-line); } .pk-statcard--alarm .pk-statcard__n { color:var(--alarm-fg); }
.pk-statcard--warn  { border-color:var(--warn-line); }  .pk-statcard--warn  .pk-statcard__n { color:var(--warn-fg); }
.pk-statcard--ok    .pk-statcard__n { color:var(--ok-fg); }
.pk-statcard--idle  .pk-statcard__n { color:var(--idle-fg); }
.pk-statcard--info  .pk-statcard__n { color:var(--info-fg); }

/* Indicateurs (KPI : libellé + valeur + sous-texte + delta) */
.pk-kpis { display:grid; grid-template-columns:repeat(var(--pk-cols,4),1fr); gap:var(--s4); margin-bottom:var(--s5); }
@media (max-width:860px){ .pk-kpis { grid-template-columns:repeat(2,1fr); } }
.pk-kpi { background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:var(--s4) var(--s5); }
.pk-kpi__k { display:flex; align-items:center; gap:var(--s2); font:var(--t-legend); color:var(--text-muted); }
.pk-kpi__k svg { width:15px; height:15px; }
.pk-kpi__v { margin-top:var(--s2); font:var(--t-value); color:var(--text); font-variant-numeric:tabular-nums; }
.pk-kpi__v .u { font:var(--t-label); color:var(--text-muted); margin-left:4px; }
.pk-kpi__sub { margin-top:4px; font:var(--t-legend); color:var(--text-muted); }
.pk-kpi__delta { display:inline-flex; align-items:center; gap:4px; font:var(--t-label); }
.pk-kpi__delta svg { width:14px; height:14px; }
.pk-kpi__delta.up { color:var(--warn-fg); }
.pk-kpi__delta.down { color:var(--ok-fg); }

/* Ligne d'alerte (état à gauche, icône, message, acquittement + confirmation) */
.pk-alerts { display:flex; flex-direction:column; gap:var(--s3); }
.pk-alert { display:flex; align-items:center; gap:var(--s4); background:var(--surface); border:1px solid var(--border); border-left-width:3px; border-radius:var(--r-lg); padding:var(--s4) var(--s5); }
.pk-alert[data-st="alarm"] { border-left-color:var(--alarm); background:color-mix(in oklch, var(--alarm-soft) 45%, var(--surface)); }
.pk-alert[data-st="warn"]  { border-left-color:var(--warn); }
.pk-alert[data-st="ack"]   { border-left-color:var(--idle-line); opacity:0.7; }
.pk-alert__ico { width:34px; height:34px; border-radius:var(--r-md); display:grid; place-items:center; flex:0 0 auto; }
.pk-alert__ico svg { width:18px; height:18px; }
.pk-alert[data-st="alarm"] .pk-alert__ico { background:var(--alarm-soft); color:var(--alarm-fg); }
.pk-alert[data-st="warn"]  .pk-alert__ico { background:var(--warn-soft); color:var(--warn-fg); }
.pk-alert[data-st="ack"]   .pk-alert__ico { background:var(--surface-sunk); color:var(--text-muted); }
.pk-alert__body { flex:1; min-width:0; }
.pk-alert__name { font:var(--t-label); color:var(--text); }
.pk-alert__msg { font:var(--t-legend); color:var(--text-2); margin-top:2px; }
.pk-alert__msg .num { color:var(--text); }
.pk-alert__right { display:flex; align-items:center; gap:var(--s4); flex:0 0 auto; }
.pk-alert__time { font:var(--t-micro); color:var(--text-muted); text-align:right; white-space:nowrap; }
.pk-alert__act { display:flex; gap:var(--s2); align-items:center; }
.pk-btn-ack { font:var(--t-label); padding:8px 14px; border-radius:var(--r-md); border:1px solid var(--border-strong); background:var(--surface); color:var(--text); cursor:pointer; white-space:nowrap; }
.pk-btn-ack:hover { border-color:var(--text-muted); background:var(--surface-2); }
.pk-ackmark { font:var(--t-legend); color:var(--idle-fg); display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.pk-ackmark svg { width:14px; height:14px; }
.pk-alert__act .cf { display:none; gap:var(--s2); align-items:center; }
.pk-alert__act.confirming .cf { display:flex; } .pk-alert__act.confirming .pk-btn-ack { display:none; }
.pk-alert__act .cf span { font:var(--t-legend); color:var(--text-2); }
.pk-alert__act .cf .y { background:var(--ok); color:#fff; border:none; padding:8px 12px; border-radius:var(--r-md); cursor:pointer; font:var(--t-label); }
.pk-alert__act .cf .n { background:var(--surface); border:1px solid var(--border-strong); color:var(--text-2); padding:8px 12px; border-radius:var(--r-md); cursor:pointer; font:var(--t-label); }
/* En-tête de ligne : nom + pastille de criticité côte à côte */
.pk-alert__nm-row { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap; }
/* Champ de NOTE d'acquittement (facultatif), apparaît à la confirmation */
.pk-alert__act .cf { flex-wrap:wrap; justify-content:flex-end; }
.cfnote { font:var(--t-legend); padding:7px 10px; border:1px solid var(--border-strong); border-radius:var(--r-md); background:var(--surface); color:var(--text); width:210px; max-width:46vw; }
.cfnote::placeholder { color:var(--text-muted); }
/* Note d'acquittement affichée sous une alerte acquittée */
.pk-alert__acknote { font:var(--t-micro); color:var(--text-2); margin-top:4px; font-style:italic; }
.pk-alert__acknote b { font-style:normal; color:var(--text-muted); }

/* Pastille de NIVEAU d'alarme (criticité) — axe distinct de l'état.
   Réutilise les hues sémantiques par INTENSITÉ : critique=rouge,
   haute=ambre, basse=gris. Toujours doublée d'un libellé (pas que la couleur). */
.pk-prio { font:var(--t-micro); font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:2px 8px; border-radius:var(--r-pill); border:1px solid var(--border);
  white-space:nowrap; display:inline-flex; align-items:center; gap:5px; flex:0 0 auto; }
.pk-prio::before { content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex:0 0 auto; }
.pk-prio--critique { color:var(--alarm-fg); background:var(--alarm-soft); border-color:var(--alarm-line); }
.pk-prio--haute    { color:var(--warn-fg);  background:var(--warn-soft);  border-color:var(--warn-line); }
.pk-prio--basse    { color:var(--idle-fg);  background:var(--idle-soft);  border-color:var(--idle-line); }

/* ------------------------------------------------------------------
   BANDEAU D'ALARME CRITIQUE — chrome transversal monté par nav.js.
   Persistant et visible depuis TOUS les écrans tant qu'une alarme
   ACTIVE de priorité « critique » existe. Sticky en tête ; décale la
   barre d'onglets et la barre de thème sous lui (variable --critbar-h).
   ------------------------------------------------------------------ */
.pk-critbar {
  display: flex; align-items: center; gap: var(--s4);
  min-height: 46px; padding: 0 var(--s5);
  background: var(--alarm); color: #fff;
  border-bottom: 1px solid color-mix(in oklch, var(--alarm) 65%, black);
}
.pk-critbar__dot { width:10px; height:10px; border-radius:50%; background:#fff; flex:0 0 auto;
  animation: critpulse 1.5s infinite; }
@keyframes critpulse {
  0%   { box-shadow:0 0 0 0 rgba(255,255,255,.6); }
  70%  { box-shadow:0 0 0 8px rgba(255,255,255,0); }
  100% { box-shadow:0 0 0 0 rgba(255,255,255,0); }
}
.pk-critbar__ic { display:inline-flex; flex:0 0 auto; }
.pk-critbar__ic svg { width:18px; height:18px; }
.pk-critbar__tx { font:var(--t-label); min-width:0; flex:1 1 auto;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pk-critbar__tx b { font-weight:700; }
.pk-critbar__tx .sep { opacity:.55; margin:0 6px; }
.pk-critbar__tx .det { font-weight:500; opacity:.92; }
.pk-critbar__cta { margin-left:auto; flex:0 0 auto; font:var(--t-label); font-weight:600; white-space:nowrap;
  color:#fff; text-decoration:none; background:rgba(255,255,255,.18);
  border:1px solid rgba(255,255,255,.45); padding:6px 14px; border-radius:var(--r-pill);
  display:inline-flex; align-items:center; gap:6px; cursor:pointer; }
.pk-critbar__cta:hover { background:rgba(255,255,255,.30); }
.pk-critbar__cta svg { width:14px; height:14px; }
@media (prefers-reduced-motion: reduce) { .pk-critbar__dot { animation:none; } }
/* Empilement du chrome transversal (bandeaux critique + dérogations) :
   nav.js les place dans un wrapper .sv-chrome, mesure sa hauteur
   (→ --sv-chrome-h) et pose body.has-chrome pour décaler onglets + thème. */
.sv-chrome { position: sticky; top: 0; z-index: 60; box-shadow: var(--shadow-pop); }
.sv-chrome:empty { display: none; box-shadow: none; }
body.has-chrome .appnav:not(.appnav--rail) { top: var(--sv-chrome-h, 0px); }
body.has-chrome .appnav--rail { top: var(--sv-chrome-h, 0px); height: calc(100vh - var(--sv-chrome-h, 0px)); }
body.has-chrome .themebar { top: calc(var(--sv-chrome-h, 0px) + 14px); }
@media (max-width: 640px) {
  .pk-critbar { padding: 0 var(--s3); gap: var(--s3); }
  .pk-critbar__tx .det { display:none; }
}

/* ------------------------------------------------------------------
   Bande de notifications UNIFIÉE (A1, 2026-07-01) : une seule ligne,
   segment rouge (alarmes critiques) et/ou segment ambre (dérogations).
   Remplace l'empilement pk-critbar + pk-ovrbar.
   ------------------------------------------------------------------ */
.pk-notice { display:flex; align-items:stretch; min-height:46px;
  font:var(--t-label); border-bottom:1px solid var(--border); }
.pk-notice.is-crit { background:var(--alarm); color:#fff;
  border-bottom-color:color-mix(in oklch, var(--alarm) 65%, black); }
.pk-notice.is-ovr  { background:var(--warn-soft); color:var(--warn-fg);
  border-bottom-color:var(--warn-line); }
.pk-notice__seg { display:flex; align-items:center; gap:var(--s4); padding:0 var(--s5); min-width:0; }
.pk-notice__seg--crit { flex:1 1 auto; }
.pk-notice__seg--ovr  { flex:0 1 auto; }
.pk-notice.is-crit .pk-notice__seg--ovr { border-left:1px solid rgba(255,255,255,.30); }
.pk-notice__dot { width:10px; height:10px; border-radius:50%; background:#fff; flex:0 0 auto;
  animation:critpulse 1.5s infinite; }
.pk-notice__ic { display:inline-flex; flex:0 0 auto; }
.pk-notice__ic svg { width:18px; height:18px; }
.pk-notice__tx { min-width:0; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.pk-notice__seg--crit .pk-notice__tx { flex:1 1 auto; overflow:hidden; }
.pk-notice__tx b { font-weight:700; }
.pk-notice__tx .sep { opacity:.55; margin:0 4px; }
.pk-notice__tx .det { font-weight:500; opacity:.92; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.pk-notice__chip { font:var(--t-micro); border-radius:var(--r-pill); padding:2px 9px;
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.pk-notice.is-crit .pk-notice__chip { background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.35); }
.pk-notice.is-ovr  .pk-notice__chip { background:color-mix(in oklch, var(--warn) 16%, transparent); border:1px solid var(--warn-line); }
.pk-notice__chip .cd { font-variant-numeric:tabular-nums; }
.pk-notice__cta { flex:0 0 auto; font:var(--t-label); font-weight:600; padding:5px 13px; white-space:nowrap;
  border-radius:var(--r-pill); cursor:pointer; display:inline-flex; align-items:center; gap:6px; text-decoration:none; }
.pk-notice__seg--crit .pk-notice__cta { margin-left:auto; }
.pk-notice.is-crit .pk-notice__cta { color:#fff; background:rgba(255,255,255,.18); border:1px solid rgba(255,255,255,.45); }
.pk-notice.is-crit .pk-notice__cta:hover { background:rgba(255,255,255,.30); }
.pk-notice.is-ovr  .pk-notice__cta { color:var(--warn-fg); background:transparent; border:1px solid var(--warn-line); }
.pk-notice.is-ovr  .pk-notice__cta:hover { background:color-mix(in oklch, var(--warn) 12%, transparent); }
.pk-notice__cta svg { width:14px; height:14px; }
@media (prefers-reduced-motion: reduce) { .pk-notice__dot { animation:none; } }
@media (max-width: 760px) {
  .pk-notice { flex-wrap:wrap; }
  .pk-notice__seg { padding:0 var(--s3); gap:var(--s3); }
  .pk-notice__tx .det { display:none; }
  .pk-notice__chip { display:none; }
  .pk-notice.is-crit .pk-notice__seg--ovr { border-left:none; border-top:1px solid rgba(255,255,255,.30); width:100%; }
}

/* Journal (groupé par jour + ligne d'événement) */
.pk-daygroup { margin-bottom:var(--s6); }
.pk-daygroup__t { font:var(--t-legend); color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em; padding-bottom:var(--s2); border-bottom:1px solid var(--border); margin-bottom:var(--s2); }
.pk-event { display:flex; align-items:flex-start; gap:var(--s4); padding:var(--s3) var(--s2); border-radius:var(--r-md); }
.pk-event:hover { background:var(--surface-2); }
.pk-event__dot { width:9px; height:9px; border-radius:50%; margin-top:6px; flex:0 0 auto; }
.pk-event__body { flex:1; min-width:0; }
.pk-event__act { font:var(--t-label); color:var(--text); font-weight:500; }
.pk-event__meta { font:var(--t-micro); color:var(--text-muted); margin-top:2px; }
.pk-event__meta b { color:var(--text-2); font-weight:600; }
.pk-event__tag { font:var(--t-micro); padding:2px 8px; border-radius:var(--r-pill); border:1px solid var(--border); color:var(--text-2); background:var(--surface-2); flex:0 0 auto; }
.pk-event__time { font:var(--t-micro); color:var(--text-muted); flex:0 0 auto; white-space:nowrap; }

/* Pastilles d'état réutilisables (point coloré par état) */
.pk-dot--ok{background:var(--ok)} .pk-dot--warn{background:var(--warn)} .pk-dot--alarm{background:var(--alarm)}
.pk-dot--idle{background:var(--idle-line)} .pk-dot--info{background:var(--info)}
.pk-dot--edit{background:var(--info)} .pk-dot--cmd{background:var(--ok)}

/* État vide */
.pk-empty { text-align:center; padding:var(--s8); color:var(--text-muted); font:var(--t-body); }

/* Panneau (carte de contenu : graphe, tableau, liste) */
.pk-panel { background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:var(--s5); margin-bottom:var(--s5); }
.pk-panel__head { display:flex; align-items:baseline; gap:var(--s3); margin-bottom:var(--s4); flex-wrap:wrap; }
.pk-panel__head h2 { font:var(--t-heading); font-size:1.0625rem; color:var(--text); }
.pk-panel__head .hint { font:var(--t-legend); color:var(--text-muted); margin-left:auto; }
.pk-panel__head .pk-panel__action { margin-left:auto; align-self:center; }
.pk-panel__head .hint ~ .pk-panel__action { margin-left:var(--s3); }
/* segment de bascule de vue dans l'en-tête d'un panneau */
.tviewseg { display:flex; gap:3px; padding:3px; background:var(--surface-sunk); border:1px solid var(--border); border-radius:var(--r-pill); }
.tviewseg button { border:none; background:transparent; cursor:pointer; font:var(--t-micro); color:var(--text-2); padding:4px 11px; border-radius:var(--r-pill); }
.tviewseg button:hover { color:var(--text); }
.tviewseg button[aria-pressed="true"] { background:var(--surface); color:var(--text); box-shadow:var(--shadow-pop); }
.pk-cols2 { display:grid; grid-template-columns:1fr 1fr; gap:var(--s5); margin-bottom:var(--s5); }
@media (max-width:860px){ .pk-cols2 { grid-template-columns:1fr; } }
.pk-cols2 .pk-panel { margin-bottom:0; }
.pk-legend { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); margin-top:var(--s3); }
.pk-legend .it { display:inline-flex; align-items:center; gap:6px; font:var(--t-legend); color:var(--text-2); }
.pk-legend .sw { width:11px; height:11px; border-radius:3px; flex:0 0 auto; display:inline-block; }

/* Toast (confirmation d'action, partagé) */
.pk-toast { position:fixed; left:50%; bottom:24px; transform:translateX(-50%) translateY(20px); opacity:0; pointer-events:none; transition:all .2s; background:var(--text); color:var(--surface); font:var(--t-label); padding:10px 16px; border-radius:var(--r-pill); display:flex; align-items:center; gap:8px; box-shadow:var(--shadow-pop); z-index:80; }
.pk-toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
.pk-toast svg { width:15px; height:15px; }

/* ============================================================
   MOTEUR DE GRAPHES  (préfixe .cx-)
   Style de la brique « graphe » produite par analytics.js
   (aires empilées + infobulle, courbes température/humidité,
   barres classées). Partagé par les écrans Énergie et Confort.
   Les hauteurs de graphe restent page-locales.
   ============================================================ */
.cx-sw { width:10px; height:10px; border-radius:3px; flex:0 0 auto; display:inline-block; }
.cx-sw--t { background:oklch(0.62 0.18 25); border-radius:50%; }
.cx-box { position:relative; width:100%; }
.cx-svg { width:100%; height:300px; display:block; overflow:visible; }
.cx-grid { stroke:var(--border); stroke-width:1; vector-effect:non-scaling-stroke; }
.cx-axis { stroke:var(--border-strong); stroke-width:1; vector-effect:non-scaling-stroke; }
.cx-ylab, .cx-xlab { fill:var(--text-muted); font:500 11px/1 var(--font-mono); }
.cx-templine { fill:none; stroke:oklch(0.62 0.18 25); stroke-width:2; vector-effect:non-scaling-stroke; stroke-dasharray:1 0; }
.cx-tline { fill:none; stroke-width:1.75; vector-effect:non-scaling-stroke; }
.cx-comfort { fill:color-mix(in oklch, var(--ok) 12%, transparent); }

/* COURBES COMPARÉES (« explorateur ») — halo + isolation d'une source */
.cx-curves { position:relative; }
.cx-casing { stroke:var(--surface); stroke-width:5.5; vector-effect:non-scaling-stroke; stroke-linecap:round; stroke-linejoin:round; }
.cx-cline { transition:opacity .16s ease; }
.cx-curves.isolate .cx-cline { opacity:.14; }
.cx-curves.isolate .cx-cline.on { opacity:1; }
/* légende rendue interactive côté écran (hover = isoler) */
.cx-leg-int .it { cursor:pointer; padding:2px 8px; margin:-2px 0; border-radius:var(--r-pill); transition:background .14s; }
.cx-leg-int .it:hover { background:var(--surface-sunk); }
.cx-leg-int.dimmed .it:not(.on) { opacity:.45; }

/* TEMPÉRATURE — petits multiples (une vignette lisible par zone) */
.tsm-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(186px,1fr)); gap:var(--s3); }
.tsm { border:1px solid var(--border); border-radius:var(--r-md); padding:var(--s3); background:var(--surface-2); display:flex; flex-direction:column; gap:6px; }
.tsm[data-st="warn"]  { border-color:var(--warn-line); }
.tsm[data-st="alarm"] { border-color:var(--alarm-line); background:color-mix(in oklch, var(--alarm-soft) 50%, var(--surface)); }
.tsm__top { display:flex; align-items:center; gap:6px; }
.tsm__lab { font:var(--t-label); color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.tsm__chip { margin-left:auto; font:var(--t-micro); padding:2px 7px; border-radius:var(--r-pill); white-space:nowrap; }
.tsm__chip--ok    { color:var(--ok-fg);    background:var(--ok-soft); }
.tsm__chip--warn  { color:var(--warn-fg);  background:var(--warn-soft); }
.tsm__chip--alarm { color:var(--alarm-fg); background:var(--alarm-soft); }
.tsm__row { display:flex; align-items:baseline; gap:8px; }
.tsm__val { font:600 1.4rem/1 var(--font-mono); color:var(--text); }
.tsm__u { font:var(--t-micro); color:var(--text-2); margin-left:2px; }
.tsm__set { font:var(--t-micro); color:var(--text-muted); margin-left:auto; }
.tsm__spark { width:100%; height:52px; display:block; }
.tsm-comfort { fill:color-mix(in oklch, var(--ok) 12%, transparent); }

/* TEMPÉRATURE — enveloppe min/max + moyenne */
.tenv-band { fill:color-mix(in oklch, var(--text-muted) 16%, transparent); stroke:none; }
.tenv-mean { stroke:var(--accent); stroke-width:2.25; vector-effect:non-scaling-stroke; stroke-linecap:round; stroke-linejoin:round; }
.cx-cursor { position:absolute; top:0; bottom:30px; width:1px; background:var(--text-muted); opacity:.5; pointer-events:none; transform:translateX(-0.5px); }
.cx-tip { position:absolute; top:8px; z-index:5; background:var(--surface); border:1px solid var(--border-strong); border-radius:var(--r-md); box-shadow:var(--shadow-pop); padding:var(--s3) var(--s4); min-width:150px; pointer-events:none; }
.cx-tip__h { font:var(--t-label); color:var(--text); margin-bottom:6px; }
.cx-tip__r { display:flex; align-items:center; gap:var(--s2); font:var(--t-legend); color:var(--text-2); margin-top:3px; }
.cx-tip__r b { margin-left:auto; color:var(--text); font-variant-numeric:tabular-nums; }
.cx-tip__l { white-space:nowrap; }
.cx-tip__tot { margin-top:6px; padding-top:6px; border-top:1px solid var(--border); color:var(--text); }
.cx-bar { margin-bottom:var(--s4); }
.cx-bar:last-child { margin-bottom:0; }
.cx-bar__top { display:flex; align-items:baseline; justify-content:space-between; gap:var(--s3); margin-bottom:5px; }
.cx-bar__lab { display:inline-flex; align-items:center; gap:7px; font:var(--t-label); color:var(--text); }
.cx-bar__val { font:var(--t-legend); color:var(--text-muted); white-space:nowrap; }
.cx-bar__val b { color:var(--text); font-variant-numeric:tabular-nums; }
.cx-bar__cost { color:var(--text-2); margin-left:6px; padding-left:7px; border-left:1px solid var(--border); }
.cx-bar__track { height:9px; border-radius:var(--r-pill); background:var(--surface-sunk); overflow:hidden; }
.cx-bar__fill { display:block; height:100%; border-radius:var(--r-pill); }
.cx-bar__share { font:var(--t-micro); color:var(--text-muted); margin-top:4px; }
.cx-empty { padding:var(--s7) var(--s5); text-align:center; color:var(--text-muted); font:var(--t-legend); }

/* ============================================================
   FICHE ÉQUIPEMENT  (drawer — fiche.js)
   Point d'accès « Détails » sur un widget + panneau latéral.
   ============================================================ */
/* point d'accès sur le widget (révélé au survol) */
.w--fiche { position:relative; }
.w__fiche {
  position:absolute; top:8px; right:8px; z-index:3;
  display:inline-flex; align-items:center; gap:5px;
  font:var(--t-micro); color:var(--text-2);
  background:var(--surface); border:1px solid var(--border-strong);
  border-radius:var(--r-pill); padding:4px 9px; cursor:pointer;
  opacity:0; transform:translateY(-2px);
  transition:opacity .12s, transform .12s, color .12s, border-color .12s;
  box-shadow:var(--shadow-pop);
}
.w__fiche svg { width:13px; height:13px; }
.w--fiche:hover .w__fiche, .w--fiche:focus-within .w__fiche { opacity:1; transform:none; }
.w__fiche:hover { color:var(--text); border-color:var(--text-muted); }
@media (hover:none) { .w__fiche { opacity:1; transform:none; padding:4px 7px; } .w__fiche span { display:none; } }

/* A7 : actions de carte (Forcer + Détails) groupées au coin, révélées au survol.
   Utilisé uniquement pour les équipements forçables (chrome, pas la brique). */
.w__actions { position:absolute; top:8px; right:8px; z-index:3; display:flex; gap:6px; }
.w__actions .w__fiche { position:static; }
.w__forc { display:inline-flex; align-items:center; gap:5px; cursor:pointer;
  opacity:0; transform:translateY(-2px); transition:opacity .15s ease, transform .15s ease;
  font:var(--t-micro); color:var(--accent); background:var(--surface);
  border:1px solid var(--accent); border-radius:var(--r-pill); padding:5px 10px; box-shadow:var(--shadow-pop); }
.w__forc svg { width:13px; height:13px; }
.w--fiche:hover .w__forc, .w--fiche:focus-within .w__forc { opacity:1; transform:none; }
.w__forc:hover { background:color-mix(in oklch, var(--accent) 10%, var(--surface)); }
@media (hover:none) { .w__forc { opacity:1; transform:none; } .w__forc span { display:none; } }
/* Lecteur : pas de forçage rapide (cohérent avec le gating des actions). */
html[data-role="lecteur"] .w__forc { display:none; }
/* Surbrillance de la dérogation quand la fiche s'ouvre via « Forcer ». */
.ovr.is-focus { box-shadow:0 0 0 2px var(--accent); border-radius:var(--r-md); transition:box-shadow .2s ease; }

/* scrim + panneau */
.pk-drawer-scrim { position:fixed; inset:0; background:color-mix(in oklch, #000 46%, transparent); opacity:0; pointer-events:none; transition:opacity .2s; z-index:90; }
.pk-drawer-scrim.show { opacity:1; pointer-events:auto; }
.pk-drawer {
  position:fixed; top:0; right:0; bottom:0; width:min(444px, 93vw);
  background:var(--bg); border-left:1px solid var(--border);
  box-shadow:-14px 0 44px rgba(0,0,0,.20);
  transform:translateX(100%); transition:transform .24s cubic-bezier(.4,0,.2,1);
  z-index:95; display:flex; flex-direction:column;
}
.pk-drawer.open { transform:none; }
.pk-drawer__head { display:flex; align-items:center; gap:var(--s3); padding:var(--s4) var(--s5); border-bottom:1px solid var(--border); flex:0 0 auto; }
.pk-drawer__kind { flex:1; font:var(--t-micro); letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted); }
.pk-drawer__close { width:30px; height:30px; border-radius:var(--r-md); border:1px solid var(--border); background:var(--surface); color:var(--text-2); cursor:pointer; display:grid; place-items:center; }
.pk-drawer__close svg { width:18px; height:18px; transform:rotate(45deg); } /* icône « plus » tournée à 45° = croix de fermeture */
.pk-drawer__close:hover { color:var(--text); border-color:var(--text-muted); }
.pk-drawer__body { flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; padding:var(--s5); display:flex; flex-direction:column; gap:var(--s6); }

/* en-tête de fiche */
.fiche-hero { display:flex; gap:var(--s4); align-items:flex-start; }
.fiche-hero__ico { width:44px; height:44px; border-radius:var(--r-md); background:var(--surface-2); color:var(--text-2); display:grid; place-items:center; flex:0 0 auto; }
.fiche-hero__ico svg { width:23px; height:23px; }
.fiche-hero__main { min-width:0; }
.fiche-hero__nm { font:var(--t-heading); font-size:1.0625rem; color:var(--text); }
.fiche-hero__loc { font:var(--t-legend); color:var(--text-muted); margin-top:2px; }
.fiche-hero__row { display:flex; align-items:center; gap:var(--s3); margin-top:var(--s3); flex-wrap:wrap; }
.fiche-hero__val { font:var(--t-value-sm); color:var(--text); }
.fiche-hero__val .u { font:var(--t-label); color:var(--text-muted); margin-left:3px; }

/* sections */
.fiche-sec__t { font:var(--t-micro); letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); margin-bottom:var(--s3); }
.fiche-readonly { display:flex; align-items:center; gap:var(--s2); font:var(--t-legend); color:var(--text-muted); padding:var(--s4); background:var(--surface-sunk); border:1px solid var(--border); border-radius:var(--r-md); }
.fiche-readonly svg { width:15px; height:15px; }
.fiche-ctrl .w { background:var(--surface-sunk); }

/* mini-courbe */
.pk-spark { width:100%; height:64px; display:block; background:var(--surface-sunk); border:1px solid var(--border); border-radius:var(--r-md); }
.pk-spark__ax { display:flex; justify-content:space-between; font:var(--t-micro); color:var(--text-muted); margin-top:5px; }

/* planning d'équipement */
.pk-sched__bar { display:flex; height:26px; border-radius:var(--r-sm); overflow:hidden; border:1px solid var(--border); }
.pk-sched__seg { display:block; height:100%; }
.pk-sched__ticks { display:flex; justify-content:space-between; font:var(--t-micro); color:var(--text-muted); margin-top:5px; }
.pk-sched__legends { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); margin-top:var(--s3); }
.pk-sched__leg, .pk-sched__day { display:inline-flex; align-items:center; gap:6px; font:var(--t-legend); color:var(--text-2); }
.pk-sched__leg i, .pk-sched__day i { width:11px; height:11px; border-radius:3px; flex:0 0 auto; }
.pk-sched__sub { font:var(--t-micro); letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); margin:var(--s4) 0 var(--s2); }
.pk-sched__week { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); }
.pk-sched__note { display:flex; align-items:center; gap:6px; font:var(--t-micro); color:var(--text-muted); margin-top:var(--s3); padding-top:var(--s3); border-top:1px solid var(--border); }
.pk-sched__note svg { width:12px; height:12px; }
.pk-events { display:flex; flex-direction:column; gap:2px; }

/* ============================================================
   WIDGET SCHEDULE (vignette compacte, W.schedule — widgets.js)
   Couleurs de programmes = tokens partagés --prog-N.
   ============================================================ */
.schedw__today { display:flex; align-items:center; gap:var(--s2); font:var(--t-label); color:var(--text-2); }
.schedw__today b { color:var(--text); }
.schedw__sw { width:11px; height:11px; border-radius:3px; flex:0 0 auto; }
.schedw__week { display:grid; grid-template-columns:repeat(7,1fr); gap:4px; }
.schedw__day { font:var(--t-micro); color:var(--text-2); text-align:center; padding:5px 0; border:1px solid; border-radius:var(--r-sm); }
.schedw__day.is-today { outline:2px solid var(--accent); outline-offset:-1px; }
.schedw__legend { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); }
.schedw__leg { display:inline-flex; align-items:center; gap:6px; font:var(--t-legend); color:var(--text-2); }
.schedw__leg i { width:11px; height:11px; border-radius:3px; flex:0 0 auto; }

/* ============================================================
   BANDEAU « DÉROGATIONS ACTIVES » (chrome transversal, nav.js)
   Forçages temporaires en cours, empilé sous le bandeau critique.
   Couleur AMBRE (info d'action en cours) — distincte du rouge alarme.
   ============================================================ */
.pk-ovrbar { display:flex; align-items:center; gap:var(--s4); min-height:44px; padding:7px var(--s5);
  background:var(--warn-soft); color:var(--warn-fg); border-bottom:1px solid var(--warn-line); }
.pk-ovrbar__ic { display:inline-flex; flex:0 0 auto; }
.pk-ovrbar__ic svg { width:17px; height:17px; }
.pk-ovrbar__tx { font:var(--t-label); min-width:0; flex:1 1 auto; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.pk-ovrbar__tx b { font-weight:700; }
.pk-ovrbar__chip { font:var(--t-micro); background:color-mix(in oklch,var(--warn) 16%, transparent);
  border:1px solid var(--warn-line); border-radius:var(--r-pill); padding:2px 9px;
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.pk-ovrbar__chip .cd { font-variant-numeric:tabular-nums; }
.pk-ovrbar__cta { margin-left:auto; flex:0 0 auto; font:var(--t-label); font-weight:600; color:var(--warn-fg);
  background:transparent; border:1px solid var(--warn-line); padding:5px 13px; border-radius:var(--r-pill);
  cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.pk-ovrbar__cta:hover { background:color-mix(in oklch,var(--warn) 12%, transparent); }
.pk-ovrbar__cta svg { width:14px; height:14px; }
@media (max-width:640px){ .pk-ovrbar__chip { display:none; } .pk-ovrbar { padding:7px var(--s3); gap:var(--s3); } }

/* ============================================================
   MODALE GÉNÉRIQUE centrée — gestion des dérogations & rapport export
   ============================================================ */
.sv-modal-scrim { position:fixed; inset:0; z-index:80; background:oklch(0 0 0 / .42);
  display:grid; place-items:center; padding:var(--s5); opacity:0; pointer-events:none; transition:opacity .16s; }
.sv-modal-scrim.show { opacity:1; pointer-events:auto; }
.sv-modal { background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--shadow-pop); width:min(560px,96vw); max-height:90vh; display:flex; flex-direction:column;
  transform:translateY(8px); transition:transform .16s; }
.sv-modal-scrim.show .sv-modal { transform:none; }
.sv-modal--wide { width:min(820px,96vw); }
.sv-modal__head { display:flex; align-items:center; gap:var(--s3); padding:var(--s4) var(--s5); border-bottom:1px solid var(--border); }
.sv-modal__head .ic { display:inline-flex; color:var(--text-2); }
.sv-modal__head .ic svg { width:18px; height:18px; }
.sv-modal__head h2 { font:var(--t-heading); color:var(--text); flex:1; min-width:0; }
.sv-modal__close { width:30px; height:30px; flex:0 0 auto; border:1px solid var(--border); background:var(--surface);
  border-radius:var(--r-md); color:var(--text-2); cursor:pointer; display:grid; place-items:center; }
.sv-modal__close:hover { background:var(--surface-2); color:var(--text); }
.sv-modal__close svg { width:15px; height:15px; transform:rotate(45deg); }
.sv-modal__body { padding:var(--s5); overflow:auto; }
.sv-modal__foot { padding:var(--s4) var(--s5); border-top:1px solid var(--border); display:flex; gap:var(--s3); justify-content:flex-end; align-items:center; flex-wrap:wrap; }
.sv-btn { font:var(--t-label); padding:9px var(--s4); border-radius:var(--r-md); border:1px solid var(--border-strong);
  background:var(--surface); color:var(--text); cursor:pointer; display:inline-flex; align-items:center; gap:7px; white-space:nowrap; }
.sv-btn:hover { background:var(--surface-2); }
.sv-btn svg { width:15px; height:15px; }
.sv-btn--primary { background:var(--accent); border-color:var(--accent); color:#fff; }
.sv-btn--primary:hover { filter:brightness(1.06); background:var(--accent); }
.sv-btn--ghost { border-color:transparent; background:transparent; color:var(--text-2); }
.sv-btn--ghost:hover { background:var(--surface-2); color:var(--text); }

/* Liste des dérogations actives dans la modale de gestion */
.ovrlist { display:flex; flex-direction:column; gap:var(--s3); }
.ovrlist__empty { font:var(--t-body); color:var(--text-muted); text-align:center; padding:var(--s6) 0; }
.ovrrow { display:flex; align-items:center; gap:var(--s3); padding:var(--s3) var(--s4);
  border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface-2); }
.ovrrow__ic { width:34px; height:34px; flex:0 0 auto; border-radius:var(--r-md); display:grid; place-items:center;
  background:var(--warn-soft); color:var(--warn-fg); border:1px solid var(--warn-line); }
.ovrrow__ic svg { width:17px; height:17px; }
.ovrrow__main { flex:1; min-width:0; }
.ovrrow__nm { font:var(--t-label); color:var(--text); }
.ovrrow__nm b { color:var(--warn-fg); }
.ovrrow__meta { font:var(--t-micro); color:var(--text-muted); margin-top:2px; }
.ovrrow__meta .cd { color:var(--text-2); font-variant-numeric:tabular-nums; }
.ovrrow__cancel { flex:0 0 auto; font:var(--t-legend); padding:6px 11px; border-radius:var(--r-md);
  border:1px solid var(--border-strong); background:var(--surface); color:var(--text-2); cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.ovrrow__cancel:hover { border-color:var(--alarm-line); color:var(--alarm-fg); background:var(--alarm-soft); }
.ovrrow__cancel svg { width:13px; height:13px; }

/* ============================================================
   CONSIGNE DEMANDÉE vs MESURÉE (section de fiche — diagnostic CVC)
   ============================================================ */
.fiche-cm { display:grid; grid-template-columns:1fr 1fr 1fr; gap:var(--s2); }
.fiche-cm__cell { padding:var(--s3); border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface-2); text-align:center; }
.fiche-cm__k { font:var(--t-micro); color:var(--text-muted); letter-spacing:.04em; text-transform:uppercase; }
.fiche-cm__v { font:var(--t-value-sm); color:var(--text); margin-top:4px; line-height:1; }
.fiche-cm__v .u { font:var(--t-micro); color:var(--text-muted); margin-left:2px; }
.fiche-cm__cell--gap.is-ok    { background:var(--ok-soft);    border-color:var(--ok-line); }
.fiche-cm__cell--gap.is-warn  { background:var(--warn-soft);  border-color:var(--warn-line); }
.fiche-cm__cell--gap.is-alarm { background:var(--alarm-soft); border-color:var(--alarm-line); }
.fiche-cm__cell--gap.is-ok    .fiche-cm__v { color:var(--ok-fg); }
.fiche-cm__cell--gap.is-warn  .fiche-cm__v { color:var(--warn-fg); }
.fiche-cm__cell--gap.is-alarm .fiche-cm__v { color:var(--alarm-fg); }
.fiche-cm__diag { display:flex; align-items:flex-start; gap:8px; margin-top:var(--s3); font:var(--t-legend); color:var(--text-2); line-height:1.45; }
.fiche-cm__diag svg { width:15px; height:15px; flex:0 0 auto; margin-top:1px; }
.fiche-cm__diag.is-ok svg { color:var(--ok-fg); }
.fiche-cm__diag.is-warn svg { color:var(--warn-fg); }
.fiche-cm__diag.is-alarm svg { color:var(--alarm-fg); }
.fiche-cm__diag b { color:var(--text); }

/* ============================================================
   DÉROGATION / FORÇAGE TEMPORAIRE (section de fiche — pilotage)
   ============================================================ */
.ovr { border:1px solid var(--border); border-radius:var(--r-md); padding:var(--s3) var(--s4); background:var(--surface-2); }
.ovr__lab { font:var(--t-legend); color:var(--text-2); display:flex; align-items:center; gap:7px; margin-bottom:var(--s3); }
.ovr__lab svg { width:15px; height:15px; color:var(--text-muted); }
.ovr__group { font:var(--t-micro); color:var(--text-muted); letter-spacing:.04em; text-transform:uppercase; margin:0 0 6px; }
.ovr__seg { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:var(--s3); }
.ovr__seg button { font:var(--t-legend); padding:8px var(--s3); border-radius:var(--r-md); border:1px solid var(--border-strong);
  background:var(--surface); color:var(--text-2); cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.ovr__seg button svg { width:14px; height:14px; }
.ovr__seg button:hover { color:var(--text); border-color:var(--text-muted); }
.ovr__seg button[aria-pressed="true"] { background:var(--accent); border-color:var(--accent); color:#fff; }
.ovr__apply { width:100%; justify-content:center; margin-top:2px; font:var(--t-label); padding:10px var(--s4);
  border-radius:var(--r-md); border:1px solid var(--warn-line); background:var(--warn-soft); color:var(--warn-fg);
  cursor:pointer; display:inline-flex; align-items:center; gap:8px; }
.ovr__apply:hover { filter:brightness(0.98); background:color-mix(in oklch,var(--warn) 16%, transparent); }
.ovr__apply svg { width:16px; height:16px; }
.ovr__apply[disabled] { opacity:.5; cursor:not-allowed; }
.ovr__note { font:var(--t-micro); color:var(--text-muted); margin-top:8px; display:flex; align-items:flex-start; gap:6px; }
.ovr__note svg { width:13px; height:13px; flex:0 0 auto; margin-top:1px; }
/* État actif : forçage en cours pour cet équipement */
.ovr--active { border-color:var(--warn-line); background:var(--warn-soft); }
.ovr__active-row { display:flex; align-items:center; gap:var(--s3); }
.ovr__active-ic { width:34px; height:34px; flex:0 0 auto; border-radius:var(--r-md); display:grid; place-items:center;
  background:color-mix(in oklch,var(--warn) 18%, transparent); color:var(--warn-fg); }
.ovr__active-ic svg { width:17px; height:17px; }
.ovr__active-main { flex:1; min-width:0; }
.ovr__active-nm { font:var(--t-label); color:var(--text); }
.ovr__active-nm b { color:var(--warn-fg); }
.ovr__active-cd { font:var(--t-micro); color:var(--text-2); margin-top:2px; font-variant-numeric:tabular-nums; }
.ovr__cancel { flex:0 0 auto; font:var(--t-legend); padding:7px 12px; border-radius:var(--r-md);
  border:1px solid var(--border-strong); background:var(--surface); color:var(--text-2); cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.ovr__cancel:hover { border-color:var(--alarm-line); color:var(--alarm-fg); background:var(--alarm-soft); }
.ovr__cancel svg { width:14px; height:14px; }

/* ============================================================
   SÉLECTEUR DE RÔLE (chrome) + GATING DES ACTIONS PAR RÔLE
   data-role sur <html> : 'operateur' (défaut) | 'lecteur' | 'admin'.
   Le rôle ne masque pas de PAGE — il borne les ACTIONS (Phase 9).
   ============================================================ */
.roleswitch { display:inline-flex; align-items:center; gap:2px; padding:3px;
  background:var(--surface); border:var(--bw) solid var(--border); border-radius:var(--r-pill); box-shadow:var(--shadow-pop); }
.roleswitch button { display:inline-flex; align-items:center; gap:6px; border:none; background:transparent; cursor:pointer;
  font:var(--t-legend); color:var(--text-2); padding:6px 11px; border-radius:var(--r-pill); white-space:nowrap; }
.roleswitch button svg { width:14px; height:14px; }
.roleswitch button:hover { color:var(--text); }
.roleswitch button[aria-pressed="true"] { background:var(--surface-2); color:var(--text); box-shadow:inset 0 0 0 1px var(--border); }
.roleswitch__lab { font:var(--t-micro); color:var(--text-muted); padding-left:8px; }
@media (max-width:760px){ .roleswitch button span { display:none; } .roleswitch__lab { display:none; } }

/* Menu de rôle compact (A1, 2026-07-01) : bouton discret + popover, au lieu
   d'un dock permanent à 3 boutons. */
.rolemenu { position:fixed; left:14px; bottom:14px; z-index:55;
  display:flex; flex-direction:column; align-items:flex-start; gap:8px; }
.rolemenu__trigger { display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  font:var(--t-legend); color:var(--text-2); padding:7px 13px;
  background:var(--surface); border:var(--bw) solid var(--border);
  border-radius:var(--r-pill); box-shadow:var(--shadow-pop); }
.rolemenu__trigger:hover { color:var(--text); }
.rolemenu__trigger svg { width:15px; height:15px; }
.rolemenu__pop { display:none; flex-direction:column; gap:2px; min-width:190px; padding:6px;
  background:var(--surface); border:var(--bw) solid var(--border);
  border-radius:var(--r-lg); box-shadow:var(--shadow-pop); }
.rolemenu.open .rolemenu__pop { display:flex; }
.rolemenu__lab { font:var(--t-micro); color:var(--text-muted); padding:4px 8px 6px; }
.rolemenu__pop button { display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  border:none; background:transparent; font:var(--t-legend); color:var(--text-2);
  padding:8px 10px; border-radius:8px; white-space:nowrap; text-align:left; }
.rolemenu__pop button svg { width:15px; height:15px; }
.rolemenu__pop button:hover { background:var(--surface-2); color:var(--text); }
.rolemenu__pop button[aria-pressed="true"] { background:var(--surface-2); color:var(--text); box-shadow:inset 0 0 0 1px var(--border); }
/* Entrée ATELIER dans le menu (Admin only) : passer de la supervision à la
   configuration. Accent ambre « établi » pour rappeler la peau de l'Atelier. */
.rolemenu__atelier { display:inline-flex; align-items:center; gap:8px; text-decoration:none;
  font:var(--t-legend); font-weight:600; color:var(--text); padding:9px 10px; border-radius:8px;
  box-shadow:inset 0 0 0 1px color-mix(in oklch, oklch(0.74 0.13 88) 45%, var(--border)); }
.rolemenu__atelier svg { width:15px; height:15px; }
.rolemenu__atelier > svg:first-child { color:oklch(0.62 0.13 88); }
.rolemenu__atelier .rolemenu__go { margin-left:auto; color:var(--text-muted); display:inline-flex; }
.rolemenu__atelier:hover { background:color-mix(in oklch, oklch(0.74 0.13 88) 12%, var(--surface)); }
.rolemenu__div { height:1px; background:var(--border); margin:6px 2px; }
/* Variante EN-TÊTE (Accueil) : le menu de rôle est monté dans le bandeau, à
   gauche du nom du site (à côté du crayon). Déclencheur = icône seule ; popover
   ancré SOUS le déclencheur (le bandeau est en haut de l'écran). */
.rolemenu--inline { position:relative; left:auto; bottom:auto; inset:auto; align-items:center; gap:0; }
.rolemenu--inline .rolemenu__trigger { width:30px; height:30px; padding:0; gap:0;
  justify-content:center; border-radius:var(--r-sm); box-shadow:none;
  background:var(--surface); border:var(--bw) solid var(--border); color:var(--text-2); }
.rolemenu--inline .rolemenu__trigger:hover { background:var(--surface-2); color:var(--text); }
.rolemenu--inline .rolemenu__trigger span { display:none; }
.rolemenu--inline .rolemenu__pop { position:absolute; top:calc(100% + 6px); right:0; z-index:60; }

/* Gating des ACTIONS par CAPACITÉ (A3-ter, 01/07). `data-caps` sur <html>
   (posé par nav.js) : Lecteur = aucune · Opérateur = borné par l'Admin ·
   Admin = toutes. Une action non accordée reste VISIBLE mais neutralisée
   (non cliquable) — même traitement que l'ancienne « lecture seule ». Le
   gating est côté affichage ; l'application réelle des droits est serveur (Phase 9). */
html:not([data-caps~="pilotage"]) .pilot,
html:not([data-caps~="pilotage"]) .modeseg,
html:not([data-caps~="pilotage"]) .switch,
html:not([data-caps~="acquittement"]) .pk-btn-ack,
html:not([data-caps~="derogation"]) .ovr__seg button,
html:not([data-caps~="derogation"]) .ovr__apply,
html:not([data-caps~="derogation"]) .ovr__cancel,
html:not([data-caps~="derogation"]) .ovrrow__cancel,
html:not([data-caps~="derogation"]) .pk-ovrbar__cta,
html:not([data-caps~="derogation"]) .pk-notice__seg--ovr .pk-notice__cta,
html:not([data-caps~="derogation"]) .w__forc,
html:not([data-caps~="calendrier"]) #gate-btn,
html:not([data-caps~="pilotage"]) [data-cap="pilotage"],
html:not([data-caps~="calendrier"]) [data-cap="calendrier"],
html:not([data-caps~="derogation"]) [data-cap="derogation"],
html:not([data-caps~="acquittement"]) [data-cap="acquittement"] {
  pointer-events: none !important; opacity: .45 !important; cursor: not-allowed !important;
}
/* Éléments réservés opérateur+ / admin : masqués sinon. */
[data-req-op], [data-req-admin] { }
html[data-role="lecteur"] [data-req-op],
html[data-role="lecteur"] [data-req-admin],
html[data-role="operateur"] [data-req-admin] { display:none !important; }
/* Repère « lecture seule » (posé par les écrans/fiche.js via .role-ro). */
.role-ro { display:none; align-items:center; gap:6px; font:var(--t-legend); color:var(--text-muted);
  border:1px dashed var(--border-strong); border-radius:var(--r-md); padding:7px var(--s3); background:var(--surface-2); }
.role-ro svg { width:14px; height:14px; }
html[data-role="lecteur"] .role-ro { display:inline-flex; }

/* ============================================================
   SANTÉ DE COMMUNICATION — liste des BUS (écran Réseau, PK.bus)
   ============================================================ */
.pk-buslist { display:flex; flex-direction:column; gap:var(--s3); }
.pk-bus { display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:var(--s4);
  padding:var(--s4) var(--s5); border:1px solid var(--border); border-left-width:3px; border-radius:var(--r-md); background:var(--surface); }
.pk-bus[data-st="ok"]    { border-left-color:var(--ok); }
.pk-bus[data-st="warn"]  { border-left-color:var(--warn); }
.pk-bus[data-st="alarm"] { border-left-color:var(--alarm); }
.pk-bus[data-st="idle"]  { border-left-color:var(--idle); }
.pk-bus__led { width:40px; height:40px; flex:0 0 auto; border-radius:var(--r-md); display:grid; place-items:center; position:relative;
  background:var(--surface-2); border:1px solid var(--border); color:var(--text-2); }
.pk-bus__led svg { width:19px; height:19px; }
.pk-bus__led::after { content:""; position:absolute; right:-4px; top:-4px; width:11px; height:11px; border-radius:50%;
  border:2px solid var(--surface); background:var(--idle); }
.pk-bus[data-st="ok"]    .pk-bus__led::after { background:var(--ok); }
.pk-bus[data-st="warn"]  .pk-bus__led::after { background:var(--warn); animation:critpulse 1.6s infinite; }
.pk-bus[data-st="alarm"] .pk-bus__led::after { background:var(--alarm); animation:critpulse 1.4s infinite; }
.pk-bus__main { min-width:0; }
.pk-bus__nm { font:var(--t-label); color:var(--text); display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.pk-bus__proto { font:var(--t-micro); color:var(--text-2); background:var(--surface-sunk); border:1px solid var(--border);
  border-radius:var(--r-sm); padding:1px 7px; }
.pk-bus__role { font:var(--t-legend); color:var(--text-muted); margin-top:3px; }
.pk-bus__addr { font:var(--t-micro); color:var(--text-muted); }
.pk-bus__metrics { display:flex; gap:var(--s5); flex:0 0 auto; text-align:right; }
.pk-bus__metric .v { font:var(--t-label); color:var(--text); font-variant-numeric:tabular-nums; }
.pk-bus__metric .v.is-warn { color:var(--warn-fg); }
.pk-bus__metric .k { font:var(--t-micro); color:var(--text-muted); margin-top:2px; }
.pk-bus__note { grid-column:1 / -1; font:var(--t-legend); color:var(--warn-fg); display:flex; align-items:center; gap:7px;
  padding-top:var(--s2); border-top:1px dashed var(--warn-line); margin-top:2px; }
.pk-bus__note svg { width:14px; height:14px; flex:0 0 auto; }
@media (max-width:640px){ .pk-bus { grid-template-columns:auto 1fr; } .pk-bus__metrics { grid-column:1 / -1; justify-content:flex-start; } }

/* ============================================================
   RAPPORT D'EXPORT (PDF) — feuille imprimable rendue dans la modale
   ============================================================ */
.report { font:var(--t-body); color:var(--text); }
.report__head { display:flex; align-items:flex-start; justify-content:space-between; gap:var(--s4); padding-bottom:var(--s4); border-bottom:2px solid var(--text); }
.report__brand .t { font:700 1.05rem/1.2 var(--font-sans); letter-spacing:.04em; color:var(--text); }
.report__brand .s { font:var(--t-legend); color:var(--text-muted); margin-top:3px; }
.report__meta { text-align:right; font:var(--t-legend); color:var(--text-2); line-height:1.6; }
.report__meta b { color:var(--text); }
.report__title { font:var(--t-h2, 700 1.25rem/1.25 var(--font-sans)); color:var(--text); margin:var(--s5) 0 2px; }
.report__period { font:var(--t-legend); color:var(--text-muted); margin-bottom:var(--s4); }
.report__kpis { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s3); margin-bottom:var(--s5); }
.report__kpi { border:1px solid var(--border); border-radius:var(--r-md); padding:var(--s3); }
.report__kpi .v { font:var(--t-value-sm); color:var(--text); line-height:1; }
.report__kpi .k { font:var(--t-micro); color:var(--text-muted); margin-top:5px; text-transform:uppercase; letter-spacing:.04em; }
.report__sec { font:var(--t-heading); color:var(--text); margin:var(--s4) 0 var(--s2); }
.report table { width:100%; border-collapse:collapse; font:var(--t-legend); }
.report th, .report td { text-align:left; padding:7px 10px; border-bottom:1px solid var(--border); }
.report th { font:var(--t-micro); color:var(--text-muted); text-transform:uppercase; letter-spacing:.04em; }
.report td.num { text-align:right; font-variant-numeric:tabular-nums; }
.report__foot { margin-top:var(--s5); padding-top:var(--s3); border-top:1px solid var(--border);
  font:var(--t-micro); color:var(--text-muted); display:flex; justify-content:space-between; gap:var(--s4); }

/* Impression : ne garder QUE la feuille de rapport (Enregistrer en PDF). */
@media print {
  body > *:not(.sv-modal-scrim) { display:none !important; }
  .sv-modal-scrim { position:static; inset:auto; background:none; padding:0; opacity:1; display:block; }
  .sv-modal { box-shadow:none; border:none; width:100%; max-height:none; border-radius:0; }
  .sv-modal__head, .sv-modal__foot { display:none !important; }
  .sv-modal__body { padding:0; overflow:visible; }
  .report__kpi, .pk-bus, .report__head { break-inside:avoid; }
}
