/* Identité visuelle du portail.
 *
 * Le CDC : « Les couleurs sont définies comme variables CSS dans un seul
 * fichier. » C'est ce fichier. Les valeurs viennent du canvas de design,
 * relevées sur les maquettes, pas réinventées.
 *
 * Règle d'accessibilité qui traverse tout : « Chaque état est toujours
 * accompagné d'un libellé, jamais signalé par la seule couleur. » Toute
 * pastille d'état porte donc un texte, et les classes d'état ci-dessous
 * ne servent qu'à renforcer ce texte.
 */

:root {
  /* Palette du CDC */
  --accent: #c8406f; /* rose framboise : boutons, liens, assistant */
  --accent-fonce: #8f2a50; /* survol */
  --fond: #fbf5f8; /* blanc rosé */
  --nav: #2e1c31; /* prune */
  --texte: #2b1e27;
  --inventaire: #9a78cf; /* lavande : ce qui est déclaré */
  --temps-reel: #3aa592; /* menthe : ce qui est mesuré */
  --avertissement: #e0835a; /* pêche */
  --critique: #b5304b; /* framboise soutenue */
  --operationnel: #46a07a; /* sauge */

  /* Neutres dérivés, relevés sur les maquettes */
  --blanc: #ffffff;
  --bordure: #f0e2ea;
  --bordure-forte: #dcc3d0;
  --texte-doux: #6e5866;
  --texte-moyen: #503c4a;
  --fond-doux: #f7ecf2;
  --nav-actif: #4c3352;

  /* Teintes d'état, pour les fonds de pastilles */
  --critique-fond: #ffe8dd;
  --critique-texte: #783417;
  --inventaire-fond: #efe0f7;

  --rayon: 10px;
  --rayon-carte: 14px;
  --rayon-pastille: 999px;

  --police: "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --police-mono: "IBM Plex Mono", ui-monospace, monospace;
}

/* Le CDC impose le français et un thème clair ; pas de variante sombre
   pour l'instant. Si elle arrive, elle se déclare ici. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police);
  font-size: 14px;
  line-height: 1.5;
}

a {
  color: var(--accent);
}
a:hover {
  color: var(--accent-fonce);
}

/* Cibles tactiles d'au moins 44 px (WCAG 2.1 AA, exigé par le CDC).
   On l'obtient par la zone cliquable, pas en gonflant le dessin. */
button,
[role="button"],
nav a {
  min-height: 44px;
  font-family: inherit;
}

/* Un focus toujours visible : au clavier, c'est la seule indication de
   l'endroit où l'on se trouve. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* --- ossature ---------------------------------------------------------- */

.cockpit {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.rail {
  flex: 0 0 72px;
  background: var(--nav);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 16px 0;
}

.rail a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 56px;
  padding: 6px 0;
  border-radius: var(--rayon);
  color: #c9b0c1;
  text-decoration: none;
  font-size: 10px;
}

.rail a:hover {
  background: #3a2440;
  color: var(--blanc);
}

.rail a[aria-current="page"] {
  background: var(--nav-actif);
  color: var(--blanc);
}

.colonnes {
  flex: 1;
  display: flex;
  min-width: 0;
}

/* Les bases flexibles viennent des maquettes : les panneaux se
   rétrécissent avant la conversation, qui garde la place. */
.panneau-etat {
  flex: 1 1 260px;
  /* Plancher : en dessous, les libellés se coupent mot par mot et le
     panneau devient illisible avant d'être étroit. */
  min-width: 236px;
  max-height: 100%;
  overflow-y: auto;
  padding: 16px;
}

.conversation {
  flex: 999 1 480px;
  min-width: 0;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--blanc);
}

.panneau-focus {
  flex: 1 1 320px;
  min-width: 248px;
  max-height: 100%;
  overflow-y: auto;
  padding: 16px;
}

/* --- cartes ------------------------------------------------------------ */

.carte {
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-carte);
  padding: 14px;
  margin-bottom: 12px;
}

.carte h2,
.carte h3 {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

.titre-section {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texte-doux);
  margin: 18px 0 8px;
}

/* --- la distinction qui structure la fiche équipement ------------------ *
 *
 * Le CDC : « Inventaire et temps réel visuellement distincts ». Pointillé
 * lavande pour ce qui est déclaré, trait plein menthe pour ce qui est
 * mesuré. La bordure ne suffit pas à elle seule : chaque bloc porte aussi
 * son intitulé, « INVENTAIRE » ou « TEMPS RÉEL ».
 */

.bloc-inventaire {
  border: 1.5px dashed var(--inventaire);
  border-radius: 12px;
  padding: 12px;
}

.bloc-temps-reel {
  border: 1.5px solid var(--temps-reel);
  border-radius: 12px;
  padding: 12px;
}

.etiquette-source {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.bloc-inventaire .etiquette-source {
  color: var(--inventaire);
}
.bloc-temps-reel .etiquette-source {
  color: var(--temps-reel);
}

/* --- compteurs et pastilles -------------------------------------------- */

.compteurs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

/* Les compteurs sont des `button` : un clic les ajoute comme contexte à
   la question (CDC), et un bouton se déclenche aussi au clavier. D'où la
   remise à plat des styles que le navigateur leur donne. */
.compteur {
  width: 100%;
  background: var(--blanc);
  border: 1px solid var(--bordure);
  border-radius: 12px;
  padding: 10px 8px;
  text-align: center;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
}

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

.compteur .valeur {
  display: block;
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.compteur .libelle {
  display: block;
  font-size: 11px;
  color: var(--texte-doux);
}

.pastille {
  display: inline-block;
  flex: none;
  padding: 2px 10px;
  border-radius: var(--rayon-pastille);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
}

.pastille-ok {
  background: #e3f3eb;
  color: #2a6b50;
}
.pastille-avertissement {
  background: var(--critique-fond);
  color: var(--critique-texte);
}
.pastille-critique {
  background: #fbe0ea;
  color: #8f2a50;
}
.pastille-neutre {
  background: var(--fond-doux);
  color: var(--texte-moyen);
}

.ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 0;
  border-bottom: 1px solid var(--bordure);
}
.ligne:last-child {
  border-bottom: none;
}

.mono {
  font-family: var(--police-mono);
  font-size: 12px;
}

/* --- fraîcheur ---------------------------------------------------------- *
 *
 * Critère d'acceptation du CDC : « Chaque valeur affichée indique sa
 * fraîcheur ». Discret mais toujours présent.
 */

.fraicheur {
  font-size: 11px;
  color: var(--texte-doux);
}

/* --- états vides et pannes ---------------------------------------------- */

.vide {
  padding: 14px;
  border: 1px dashed var(--bordure-forte);
  border-radius: 12px;
  color: var(--texte-doux);
  font-size: 13px;
}

.panne {
  padding: 12px 14px;
  border: 1px solid var(--avertissement);
  border-left-width: 4px;
  border-radius: var(--rayon);
  background: #fff8f4;
  font-size: 13px;
}

/* --- responsive ---------------------------------------------------------
 *
 * Le CDC : panneaux visibles dès 1 280 px ; sous 768 px la conversation
 * passe en plein écran et les panneaux s'ouvrent par onglets ; utilisable
 * dès 360 px.
 */

/* Le CDC garantit les deux panneaux à partir de 1 280 px. En dessous on
   ne les coupe pas d'un coup : le Focus se resserre d'abord, et ne
   disparaît qu'en dessous de 1 100 px, où il ne resterait plus assez de
   place pour la conversation. Un portable en 1 200 px garde donc les
   trois colonnes. */
@media (max-width: 1279px) {
  .panneau-focus {
    flex-basis: 250px;
  }
  .panneau-etat {
    flex-basis: 240px;
  }
}

@media (max-width: 1000px) {
  /* Le Focus cède en premier : il suit la conversation, il peut
     attendre, alors que l'état en direct porte l'incident. */
  .panneau-focus {
    display: none;
  }
}

@media (max-width: 767px) {
  .cockpit {
    flex-direction: column;
    height: auto;
    min-height: 100vh;
  }

  .rail {
    flex: none;
    flex-direction: row;
    width: 100%;
    justify-content: space-around;
    padding: 4px 8px;
    gap: 0;
    order: 2;
    position: sticky;
    bottom: 0;
  }

  .colonnes {
    flex-direction: column;
  }

  .panneau-etat,
  .panneau-focus {
    flex: none;
    max-height: none;
    overflow: visible;
  }

  /* Panneaux en onglets : chacun devient un <details> replié. */
  .onglet-panneau > summary {
    cursor: pointer;
    padding: 12px 16px;
    font-weight: 600;
    background: var(--blanc);
    border-bottom: 1px solid var(--bordure);
  }

  .conversation {
    min-height: 60vh;
  }
}

@media (min-width: 768px) {
  /* Au-delà du mobile, les panneaux ne sont plus repliables. */
  .onglet-panneau > summary {
    display: none;
  }
}

/* --- les écrans de navigation ------------------------------------------ *
 *
 * Tableau de bord, liste des équipements, fiche équipement. Ils
 * partagent l'ossature du cockpit (rail à gauche) mais pas sa contrainte
 * de hauteur : le cockpit tient dans la fenêtre parce que sa
 * conversation défile à l'intérieur, alors que ces pages sont longues et
 * défilent normalement. D'où `.page`, qui reprend le défilement là où
 * `.cockpit` l'avait coupé (`height: 100vh; overflow: hidden`).
 */

.page {
  flex: 1;
  overflow-y: auto;
  padding: 24px 28px 48px;
  max-width: 1280px;
}

.entete-page {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.entete-page h1 {
  margin: 0 0 2px;
  font-size: 22px;
}

/* Sélecteur de période : des liens, pas des boutons scriptés — ils
   fonctionnent sans JavaScript et l'URL obtenue se partage. */
.periodes {
  display: flex;
  gap: 4px;
}

.periode {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--bordure-forte);
  border-radius: var(--rayon-pastille);
  background: var(--blanc);
  color: var(--texte-moyen);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
}

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

.periode.active,
.periode[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--blanc);
}

.grille-indicateurs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}

.grand-nombre {
  margin: 0;
  font-size: 30px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.grand-nombre .sur {
  font-size: 15px;
  font-weight: 400;
  color: var(--texte-doux);
}

/* Un écart non nul se voit, mais sans dramatiser : c'est une
   information, pas une alarme. La supervision dira si c'en est une. */
.grand-nombre.alerte,
.nombre.alerte {
  color: var(--avertissement);
}

.deux-colonnes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
  align-items: start;
}

/* --- tableaux ----------------------------------------------------------- */

.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.tableau th,
.tableau td {
  text-align: left;
  padding: 7px 8px;
  border-bottom: 1px solid var(--bordure);
  vertical-align: top;
}

.tableau thead th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--texte-doux);
  font-weight: 600;
}

.tableau tbody tr:last-child th,
.tableau tbody tr:last-child td {
  border-bottom: none;
}

.tableau .nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Une ligne de journal est du texte d'équipement : largeur bornée et
   césure forcée, sinon une seule ligne sans espace étire la page. */
.journal-ligne {
  font-family: var(--police-mono);
  font-size: 12px;
  color: var(--texte-moyen);
  max-width: 54ch;
  overflow-wrap: anywhere;
}

.tableau-journaux td {
  padding-top: 5px;
  padding-bottom: 5px;
}

/* --- filtres ------------------------------------------------------------ */

.filtres {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.filtres label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--texte-doux);
  margin-bottom: 3px;
}

.filtres input,
.filtres select {
  font-family: inherit;
  font-size: 13px;
  padding: 6px 8px;
  border: 1px solid var(--bordure-forte);
  border-radius: var(--rayon);
  background: var(--blanc);
  color: var(--texte);
  min-height: 34px;
}

.actions-filtres {
  display: flex;
  align-items: center;
  gap: 10px;
}

.lien-discret {
  font-size: 13px;
  color: var(--texte-doux);
}

/* --- fiche équipement --------------------------------------------------- */

.fil-ariane {
  font-size: 13px;
  color: var(--texte-doux);
  margin-bottom: 10px;
  display: flex;
  gap: 6px;
  align-items: center;
}

.lecture-page {
  margin: 0 0 14px;
  padding: 8px 12px;
  background: var(--fond-doux);
  border-radius: var(--rayon);
}

.definitions {
  margin: 10px 0 0;
  display: grid;
  grid-template-columns: minmax(120px, auto) 1fr;
  gap: 5px 14px;
  font-size: 13px;
}

.definitions dt {
  color: var(--texte-doux);
}

.definitions dd {
  margin: 0;
  font-weight: 500;
}

.choix-mesure {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: 8px 0 14px;
}

#graphe {
  min-height: 260px;
}

/* --- ce qui n'est pas encore là ----------------------------------------- *
 *
 * Dire ce qui manque plutôt que laisser un blanc : le client voit que
 * l'écran est complet pour aujourd'hui, et non qu'il est cassé.
 */
.note-attente {
  margin: 18px 0 0;
  font-size: 12px;
  color: var(--texte-doux);
  font-style: italic;
}

.bandeau-erreur {
  border-color: var(--avertissement);
  background: var(--critique-fond);
  color: var(--critique-texte);
  margin-bottom: 14px;
}

.bandeau-erreur ul {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 13px;
}

.pastille-absente {
  background: var(--fond-doux);
  color: var(--texte-doux);
}

@media (max-width: 767px) {
  .page {
    padding: 16px 14px 36px;
  }

  .filtres {
    flex-direction: column;
    align-items: stretch;
  }

  /* Un tableau large ne se plie pas : il défile dans son propre cadre
     plutôt que d'étirer la page. */
  .tableau {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }

  .journal-ligne {
    white-space: normal;
    max-width: 40ch;
  }
}

/* --- sources d'une réponse ---------------------------------------------- *
 *
 * Critère d'acceptation du CDC : « Chaque réponse affiche ses sources
 * sous forme de puces cliquables ». Elles sont discrètes — la réponse
 * reste le sujet — mais toujours là, et toujours actionnables : un clic
 * ouvre le détail dans le panneau Focus.
 */

.sources {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--bordure);
}

.source-puce {
  padding: 3px 11px;
  border: 1px solid var(--bordure-forte);
  border-radius: var(--rayon-pastille);
  background: var(--blanc);
  color: var(--texte-moyen);
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}

.source-puce:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Le volume est une précision, pas le nom de la source : il s'efface
   d'un ton pour que l'œil attrape « Journaux » avant « 31 lignes ». */
.source-volume {
  color: var(--texte-doux);
  font-weight: 400;
}

/* --- contexte, clic et épinglage ---------------------------------------- *
 *
 * Deux critères d'acceptation du CDC : « un clic sur un bâtiment, un
 * compteur ou un ticket l'ajoute comme contexte dans la zone de saisie »
 * et « un élément de réponse de l'assistant peut être épinglé dans le
 * panneau Focus ».
 */

.contexte {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}

/* `display: flex` l'emporte sur l'attribut `hidden`, qui ne pose qu'un
   `display: none` de feuille par défaut. Sans cette règle, la pastille
   de contexte et la section « Épinglé » restent visibles alors qu'elles
   sont marquées cachées — vu au navigateur, invisible sur le HTML seul. */
[hidden] {
  display: none !important;
}

/* Une ligne cliquable — un bâtiment — reste une ligne : même gabarit que
   `.ligne`, plus ce qu'il faut pour qu'un `button` n'en ait pas l'air. */
.ligne-cliquable {
  width: 100%;
  background: none;
  border: none;
  border-bottom: 1px solid var(--bordure);
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.ligne-cliquable:hover {
  color: var(--accent);
}

.en-parler,
.epingler,
.lien-discret {
  padding: 3px 10px;
  border: 1px solid var(--bordure-forte);
  border-radius: var(--rayon-pastille);
  background: var(--blanc);
  color: var(--texte-moyen);
  font-family: inherit;
  font-size: 11px;
  white-space: nowrap;
  cursor: pointer;
}

.en-parler:hover,
.epingler:hover,
.lien-discret:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Le bouton « Épingler » ferme la rangée de sources, à droite. */
.epingler {
  margin-left: auto;
}

.retirer {
  padding: 0 6px;
  border: none;
  background: none;
  color: var(--texte-doux);
  font-family: inherit;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.retirer:hover {
  color: var(--accent);
}

.epingle {
  position: relative;
  margin-bottom: 8px;
  padding: 8px 24px 8px 10px;
  border-left: 2px solid var(--accent);
  background: var(--fond-doux);
  border-radius: var(--rayon);
  font-size: 12px;
}

.epingle .retirer {
  position: absolute;
  top: 4px;
  right: 2px;
}

.epingle:last-child {
  margin-bottom: 0;
}

/* Une puce épinglée n'ouvre plus rien : elle le montre. */
.source-puce-inerte {
  display: inline-block;
  padding: 3px 11px;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-pastille);
  color: var(--texte-doux);
  font-size: 11px;
  cursor: default;
}
