/* style.css — direction artistique du portfolio, appliquée à l'instrument.

   CE QUI A CHANGÉ, ET POURQUOI
   L'outil est né en thème clair « salle de métrologie ». Il vit désormais
   DANS le site de Sébastien Oger : il en reprend donc la palette et sa
   typographie, pour qu'on ne change pas d'univers en ouvrant l'application.
   Les jetons ci-dessous sont ceux de portfolio/assets/style.css, repris à
   l'identique. Ils ne se réinventent pas ici : si la palette du site bouge,
   c'est CETTE liste qu'on met à jour, et rien d'autre.

   CE QUI N'A PAS CHANGÉ
   Le calcul, les seuils, les statuts. Aucune valeur métier ne vit dans cette
   feuille. Le sémaphore reste réservé au statut, et un statut n'est JAMAIS
   porté par la seule couleur : libellé, glyphe et bordure le portent aussi.

   LE PIÈGE À NE PAS ROUVRIR
   Un rapport s'imprime sur du papier blanc. Le thème sombre est donc
   entièrement redéclaré en palette claire dans @media print, tout en bas de
   ce fichier. Sans cela, le rapport sortirait en texte pâle sur fond blanc.
   -------------------------------------------------------------------------- */

:root {
  /* Architecture — jetons du portfolio */
  --bg: #0E1A25;          /* --canvas du site */
  --surface: #192938;
  --surface-2: #1F3346;
  --ink: #EEF4F9;
  --ink-soft: #C3D3E0;
  --muted: #8FA6B8;
  --border: #2B4760;
  --border-strong: #3A5C79;

  /* Accent interactif — le bleu du site */
  --accent: #85C9F4;
  --accent-hover: #A3D7F8;
  --accent-deep: #4E9FD8;
  --accent-ink: #0A1622;  /* encre POSÉE SUR l'accent : fond sombre, pas clair */
  --accent-soft: color-mix(in srgb, var(--accent) 14%, var(--bg));

  /* Sémaphore de statut.
     --ok et --alert sont les jetons --good et --warn du site. L'ambre
     intermédiaire n'existait pas dans la palette du portfolio : il est créé
     ici, dans la même famille — clair, peu saturé, lisible sur fond sombre.
     Contrastes mesurés sur --surface : ok 10,2:1 · warn 8,9:1 · alert 4,6:1. */
  --ok: #B8E0C5;
  --warn: #F2C078;
  --alert: #FA584C;

  /* Les fonds de statut. En thème clair c'étaient des teintes pastel ; sur
     fond sombre ce sont des voiles, obtenus en noyant la teinte dans le
     canvas. Ils servent aux bandes ±2σ / ±3σ des cartes de contrôle, qui
     doivent se deviner sans jamais concurrencer les points de mesure. */
  --ok-soft: color-mix(in srgb, var(--ok) 13%, var(--bg));
  --warn-soft: color-mix(in srgb, var(--warn) 18%, var(--bg));
  --alert-soft: color-mix(in srgb, var(--alert) 19%, var(--bg));
  --neutral-soft: var(--surface-2);

  --radius: 14px;         /* --radius du site */
  --radius-sm: 9px;
  /* Sur fond sombre une ombre portée ne se voit pas : c'est la bordure qui
     détache une carte. L'ombre ne sert plus qu'à asseoir les grands blocs. */
  --shadow: 0 1px 2px rgb(0 0 0 / 0.30), 0 10px 30px rgb(0 0 0 / 0.26);
  --glow: 0 0 0 1px color-mix(in srgb, var(--accent) 38%, transparent);

  --font-ui: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Consolas", monospace;

  --step-0: 0.875rem;
  --step-1: 1rem;
  --step-2: 1.25rem;
  --step-3: 1.6rem;
  --step-4: 2.1rem;

  --z-sticky: 100;
  --z-tooltip: 600;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

/* Le maillage de fond. Deux dégradés radiaux fixés au viewport : un halo
   bleu très large en haut, et une trame de points de 1 px espacés de 34 px.
   Purement décoratif, posé en background-image du body pour qu'aucun élément
   supplémentaire n'entre dans le DOM — et donc qu'aucun lecteur d'écran n'ait
   à l'ignorer. Pour l'atténuer : baisser les deux pourcentages du halo, ou
   passer l'opacité du point sous 0.16. */
body {
  margin: 0;
  background-color: var(--bg);
  background-image:
    radial-gradient(1200px 520px at 50% -10%,
                    color-mix(in srgb, var(--accent) 9%, transparent), transparent 70%),
    radial-gradient(circle at 1px 1px,
                    color-mix(in srgb, var(--accent) 16%, transparent) 1px, transparent 0);
  background-size: 100% 100%, 34px 34px;
  background-attachment: fixed, fixed;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--step-1);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.2; text-wrap: balance; margin: 0; }
p { margin: 0; }

a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); }

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

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.wrap { width: min(1180px, 100% - 2.5rem); margin-inline: auto; }

/* Embarquée dans la page du projet, l'application n'a plus à se ménager ses
   propres marges : le cadre qui la porte est déjà posé dans la colonne de
   texte de la page. Sans cette règle, on additionnerait deux gouttières et
   l'outil paraîtrait rentré dans sa boîte.
   La classe est posée par app.js quand window.self !== window.top. */
.is-embedded .wrap { width: 100%; }
.is-embedded body { background-image: none; }   /* le maillage est celui de la page hôte */

/* Pas de barre de défilement propre au cadre : c'est la PAGE qui défile, et
   la hauteur du cadre suit celle de ce contenu (voir initHeightReporting).
   Une barre ici serait imbriquée dans celle de la page — l'aveu qu'on a collé
   un site dans un site.

   Pourquoi la règle porte sur .is-embedded et non sur html : cette classe est
   posée PAR app.js, au moment même où il met en route la mesure de hauteur.
   Si le script ne s'exécute pas, la classe n'existe pas, la barre reste, et
   le contenu demeure atteignable. On ne masque jamais un défilement dont on
   n'a pas remplacé la fonction. */
.is-embedded { overflow: hidden; }


/* ---------- Le badge de norme ----------
   Seul rescapé de l'ancienne en-tête : il sert encore en tête du rapport. */
.iso-mark {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--bg));
  border-radius: var(--radius-sm);
  padding: 0.12rem 0.4rem;
  white-space: nowrap;
}

.std-picker { display: flex; align-items: center; gap: 0.5rem; }
.std-picker label { font-size: var(--step-0); color: var(--muted); }
select {
  font: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.6rem;
}

/* ---------- Onglets ---------- */
.tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  margin-top: 1.4rem;
  overflow-x: auto;
  scrollbar-width: thin;
}
.tab {
  appearance: none;
  font: inherit;
  font-weight: 550;
  color: var(--muted);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.6rem 0.9rem;
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); }

.tabpanel { padding-block: 1.8rem 3rem; }
.tabpanel[hidden] { display: none; }

/* ---------- Verdict global ---------- */
.verdict {
  display: flex;
  gap: 1rem;
  align-items: center;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.verdict[data-status="ok"] { border-color: color-mix(in srgb, var(--ok) 42%, var(--border)); background: var(--ok-soft); }
.verdict[data-status="warning"] { border-color: color-mix(in srgb, var(--warn) 42%, var(--border)); background: var(--warn-soft); }
.verdict[data-status="alert"] { border-color: color-mix(in srgb, var(--alert) 48%, var(--border)); background: var(--alert-soft); }
.verdict .dot { width: 0.9rem; height: 0.9rem; border-radius: 50%; flex: none; }
.verdict[data-status="ok"] .dot { background: var(--ok); }
.verdict[data-status="warning"] .dot { background: var(--warn); }
.verdict[data-status="alert"] .dot { background: var(--alert); }
.verdict h2 { font-size: var(--step-2); }
.verdict p { color: var(--ink); font-size: var(--step-0); }

/* ---------- Curseur temporel ---------- */
.timescrub {
  flex: 1 1 22rem;          /* prend la place restante dans la barre */
  min-width: 0;
  padding: 0.5rem 0.9rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.timescrub[hidden] { display: none; }
.timescrub-row { display: flex; align-items: center; gap: 0.8rem; }
.timescrub-caption { font-size: 0.78rem; color: var(--muted); font-weight: 600; white-space: nowrap; }
.timescrub-now { font-size: var(--step-0); color: var(--accent); white-space: nowrap; min-width: 7rem; text-align: right; }
.timescrub input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  height: 5px;
  margin: 0;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  cursor: pointer;
}
.timescrub input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
  box-shadow: var(--shadow);
}
.timescrub input[type="range"]::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg);
}
.timescrub-ends { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 0.7rem; color: var(--muted); margin-top: 0.15rem; }
@media (max-width: 560px) {
  .timescrub-row { flex-wrap: wrap; }
  .timescrub input[type="range"] { flex-basis: 100%; order: 3; }
}

/* ---------- Compteurs ---------- */
.counters { display: flex; gap: 0.9rem; flex-wrap: wrap; margin-top: 1.2rem; }
.counter {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  min-width: 9.5rem;
  background: var(--surface);
}
.counter .num { font-family: var(--font-mono); font-size: var(--step-3); font-weight: 600; line-height: 1; }
.counter .lbl { font-size: var(--step-0); color: var(--muted); display: block; margin-top: 0.25rem; }
.counter[data-kind="warn"] .num { color: var(--warn); }
.counter[data-kind="alert"] .num { color: var(--alert); }
.counter-row { display: flex; align-items: baseline; gap: 0.3rem; }
.counter-icon { font-size: var(--step-2); line-height: 1; }
.counter[data-kind="warn"] .counter-icon { color: var(--warn); }
.counter[data-kind="alert"] .counter-icon { color: var(--alert); }
.counter-action { font-size: 0.75rem; font-weight: 600; color: var(--alert); display: block; margin-top: 0.15rem; letter-spacing: 0.01em; }
.verdict-date { color: var(--muted); font-size: 0.85em; }

/* ---------- Grille d'éléments ---------- */
.section-title { font-size: var(--step-1); color: var(--muted); font-weight: 600; margin: 2rem 0 0.8rem; }
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 0.7rem;
}
.el-card {
  text-align: left;
  appearance: none;
  font: inherit;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.95rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  transition: border-color 0.16s var(--ease), transform 0.16s var(--ease);
}
.el-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.el-card .el-top { display: flex; align-items: baseline; justify-content: space-between; }
.el-card .sym { font-size: var(--step-2); font-weight: 650; letter-spacing: -0.01em; }
.el-card .name { font-size: 0.78rem; color: var(--muted); }
.el-card .el-cert { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); }

.grid-legend {
  display: flex;
  gap: 1.4rem;
  flex-wrap: wrap;
  margin-top: 0.9rem;
  font-size: 0.78rem;
  color: var(--muted);
}
.grid-legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.lg-glyph { font-size: 0.7em; }
.lg-glyph-warn { color: var(--warn); }
.lg-glyph-ok { color: var(--ok); }

/* ---------- Badges de statut ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0.18rem 0.5rem;
  border-radius: 999px;
  border: 1px solid;
}
.badge .glyph { font-size: 0.7em; }
.badge[data-status="ok"] { color: var(--ok); background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 38%, var(--bg)); }
.badge[data-status="warning"] { color: var(--warn); background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 38%, var(--bg)); }
.badge[data-status="alert"] { color: var(--alert); background: var(--alert-soft); border-color: color-mix(in srgb, var(--alert) 45%, var(--bg)); }
.badge[data-status="insufficient_variance"],
.badge[data-status="invalid"] { color: var(--muted); background: var(--neutral-soft); border-color: var(--border-strong); }

/* ---------- Détail par élément ---------- */
.detail-head { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; justify-content: space-between; }
.detail-title { display: flex; align-items: baseline; gap: 0.7rem; }
.detail-title h2 { font-size: var(--step-4); letter-spacing: -0.02em; }
.detail-title .full { color: var(--muted); }
.detail-plain { max-width: 60ch; margin-top: 0.4rem; color: var(--ink); }

.chart-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 1rem 1rem 0.5rem;
  margin-top: 1.2rem;
  box-shadow: var(--shadow);
}
.chart-svg { width: 100%; height: auto; display: block; touch-action: none; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; padding: 0.6rem 0.3rem 0.4rem; font-size: 0.78rem; color: var(--muted); }
.chart-legend span { display: inline-flex; align-items: center; gap: 0.4rem; }
.lg-swatch { width: 1.1rem; height: 0; border-top-width: 2px; border-top-style: solid; display: inline-block; }

/* Panneau experts */
details.expert {
  margin-top: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
details.expert > summary {
  cursor: pointer;
  padding: 0.7rem 1rem;
  font-weight: 600;
  font-size: var(--step-0);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
details.expert > summary::-webkit-details-marker { display: none; }
details.expert > summary::before { content: "▸"; color: var(--accent); transition: transform 0.18s var(--ease); }
details.expert[open] > summary::before { transform: rotate(90deg); }
.expert-body { padding: 0 1rem 1rem; }
.stat-row { display: flex; flex-wrap: wrap; gap: 1.4rem; padding-top: 0.4rem; }
.stat { font-size: var(--step-0); }
.stat .k { color: var(--muted); display: block; }
.stat .v { font-family: var(--font-mono); font-size: var(--step-1); }
.formula {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.8rem;
  margin-top: 0.8rem;
  color: var(--ink);
  overflow-x: auto;
}

/* ---------- Tableaux ---------- */
.table-scroll { overflow-x: auto; margin-top: 1.2rem; border: 1px solid var(--border); border-radius: var(--radius); }
table { border-collapse: collapse; width: 100%; font-size: var(--step-0); }
thead th {
  position: sticky; top: 0;
  background: var(--surface);
  text-align: right;
  font-weight: 600;
  color: var(--muted);
  padding: 0.55rem 0.8rem;
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}
thead th:first-child, tbody td:first-child { text-align: left; }
tbody td { padding: 0.5rem 0.8rem; text-align: right; border-bottom: 1px solid var(--border); white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
tbody td.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
tbody tr[data-status="warning"] { background: var(--warn-soft); }
tbody tr[data-status="alert"] { background: var(--alert-soft); }

/* ---------- Maintenance ---------- */
.maint-grid { display: grid; grid-template-columns: 1fr; gap: 2rem; }
@media (min-width: 880px) { .maint-grid { grid-template-columns: 1fr 1fr; } }

.plan-table td.freq { color: var(--muted); }
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 0.9rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--border);
}
.timeline li:last-child { border-bottom: none; }
.timeline .date { font-family: var(--font-mono); font-size: 0.82rem; color: var(--muted); }
.timeline .task { font-weight: 600; }
.timeline .notes { font-size: var(--step-0); color: var(--muted); }

/* ---------- Tooltip SVG ---------- */
.tooltip {
  position: fixed;
  z-index: var(--z-tooltip);
  pointer-events: none;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow);
  font-size: 0.76rem;
  line-height: 1.45;
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-sm);
  max-width: 16rem;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 0.12s var(--ease), transform 0.12s var(--ease);
}
.tooltip[data-show="true"] { opacity: 1; transform: translateY(0); }
.tooltip .tt-mono { font-family: var(--font-mono); }

/* ---------- États SVG (couleurs pilotées par classe) ---------- */
.pt-ok { fill: var(--ok); }
.pt-warning { fill: var(--warn); }
.pt-alert { fill: var(--alert); }
.pt-ok, .pt-warning, .pt-alert { stroke: var(--bg); stroke-width: 1; }
.band-2 { fill: var(--warn-soft); }
.band-3 { fill: var(--alert-soft); }
.axis-line { stroke: var(--border-strong); }
.grid-line { stroke: color-mix(in srgb, var(--border) 65%, transparent); }
.mean-line { stroke: var(--ink); stroke-width: 1.2; }
.limit-2 { stroke: var(--warn); stroke-dasharray: 4 3; stroke-width: 1; }
.limit-3 { stroke: var(--alert); stroke-dasharray: 2 3; stroke-width: 1; }
.errbar { stroke: var(--muted); stroke-width: 1; }
/* Les repères de maintenance sont un CONTEXTE, pas la mesure. En thème
   clair l'indigo était discret ; le bleu du site, lui, éclate sur fond
   sombre et passait devant les points. Il est donc noyé à 45 %. */
.maint-line { stroke: color-mix(in srgb, var(--accent) 45%, transparent); stroke-dasharray: 3 3; stroke-width: 1; }
.maint-hit { fill: transparent; cursor: pointer; }
.axis-text { fill: var(--muted); font-size: 10px; font-family: var(--font-mono); }

/* ---------- Callout d'interprétation (informatif, neutre) ---------- */
.callout {
  margin-top: 0.7rem;
  padding: 0.6rem 0.85rem;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--bg));
  border-radius: var(--radius-sm);
  font-size: var(--step-0);
  color: var(--ink);
  max-width: 65ch;
}
.callout-sm { font-size: 0.8rem; margin-top: 0.5rem; }
.bias-list { margin: 0.6rem 0 0; padding-left: 1.1rem; font-size: 0.82rem; }
.bias-list li { margin-bottom: 0.25rem; }

/* ---------- Rapport ---------- */
.report-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.6rem;
}
.btn-print {
  appearance: none;
  font: inherit;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.55rem 1.1rem;
  cursor: pointer;
  transition: background 0.16s var(--ease);
}
.btn-print:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.report { max-width: 940px; }
.report-head { display: flex; align-items: center; gap: 1rem; padding-bottom: 1rem; border-bottom: 2px solid var(--ink); }
.report-logo {
  width: 46px; height: 46px; flex: none;
  fill: none; stroke: var(--accent); stroke-width: 1.4;
}
.report-head h2 { font-size: var(--step-3); letter-spacing: -0.01em; }
.report-head p { font-size: var(--step-0); }

.report-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 1.2rem;
  margin: 1.1rem 0;
  font-size: var(--step-0);
}
.report-meta dt { color: var(--muted); }
.report-meta dd { margin: 0; }

.report-verdict {
  padding: 0.7rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--step-0);
  margin-bottom: 0.6rem;
}
.report-verdict[data-status="ok"] { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 42%, var(--border)); }
.report-verdict[data-status="warning"] { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 42%, var(--border)); }
.report-verdict[data-status="alert"] { background: var(--alert-soft); border-color: color-mix(in srgb, var(--alert) 48%, var(--border)); }

.report-charts { display: grid; grid-template-columns: 1fr; gap: 1.2rem; }
@media (min-width: 720px) { .report-charts { grid-template-columns: 1fr 1fr; } }
.report-chart { margin: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.6rem; }
.report-chart figcaption { font-size: 0.82rem; font-weight: 600; margin-bottom: 0.3rem; }
.report-chart svg { width: 100%; height: auto; }

.report-maint { margin: 0; padding-left: 1.1rem; font-size: var(--step-0); }
.report-maint li { margin-bottom: 0.3rem; }

.incidents { list-style: none; margin: 0 0 1rem; padding: 0; }
.incidents li {
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: 0.6rem;
  background: var(--surface);
}
.incidents li strong { display: block; margin-bottom: 0.2rem; }

.report-foot {
  margin-top: 2rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}

/* =========================================================================
   COMPOSITION — la couche ajoutée avec la direction artistique du site

   Tout ce qui suit est du réglage visuel : espacements, reliefs, et un seul
   composant nouveau, l'anneau de confiance. Aucune de ces règles ne change
   ce que l'outil calcule ni ce qu'il affiche comme statut.
   ========================================================================= */

/* --- L'anneau de confiance -----------------------------------------------
   Le geste d'ouverture de la vue d'ensemble : un taux déjà calculé par
   confidenceReport(), donné en grand.

   Le tracé utilise pathLength="100", exactement comme les liaisons du canvas
   de l'accueil : la longueur du cercle est renormalisée à 100, donc
   stroke-dasharray vaut directement le pourcentage. Aucune circonférence à
   calculer en JavaScript, et le rendu est identique à toutes les tailles.

   ATTENTION AU SENS DE CE CHIFFRE : il porte sur TOUTE la période suivie, et
   ne suit pas le curseur « remonter le temps » juste en dessous. C'est
   pourquoi le libellé le dit en toutes lettres. Ne pas le brancher sur la
   date butoir sans changer aussi ce libellé. */
.confidence {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 3vw, 2.2rem);
  flex-wrap: wrap;
  padding: clamp(1.1rem, 2.4vw, 1.7rem) clamp(1.2rem, 2.6vw, 1.9rem);
  margin-bottom: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background:
    radial-gradient(520px 200px at 0% 0%,
                    color-mix(in srgb, var(--accent) 7%, transparent), transparent 70%),
    var(--surface);
  box-shadow: var(--shadow);
}
.confidence[hidden] { display: none; }

.confidence-ring { position: relative; flex: none; width: 118px; height: 118px; }
.confidence-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-track {
  fill: none;
  stroke: var(--surface-2);
  stroke-width: 11;
}
.ring-value {
  fill: none;
  stroke: var(--ok);
  stroke-width: 11;
  stroke-linecap: round;
  stroke-dasharray: var(--pct, 0) 100;
  transition: stroke-dasharray 0.7s var(--ease);
}
.confidence[data-level="warning"] .ring-value { stroke: var(--warn); }
.confidence[data-level="alert"] .ring-value { stroke: var(--alert); }

.confidence-pct {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  line-height: 1;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.45rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.confidence-pct .pct-value { display: inline-block; }
.confidence-pct .pct-value span { font-size: 0.62em; color: var(--muted); margin-left: 0.08em; }

.confidence-text { min-width: 15rem; flex: 1; }
.confidence-kicker {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}
.confidence-title { font-size: var(--step-3); font-weight: 650; letter-spacing: -0.02em; margin-top: 0.15rem; }
.confidence-plain { font-size: var(--step-0); color: var(--ink-soft); max-width: 62ch; margin-top: 0.4rem; }
.confidence-scope { display: block; color: var(--muted); margin-top: 0.3rem; font-size: 0.78rem; }

/* --- La barre de contrôles -----------------------------------------------
   Les deux seules commandes de l'outil sur une même ligne, à hauteur d'œil,
   quel que soit l'onglet ouvert. Avant, le choix de l'échantillon vivait dans
   l'en-tête et le curseur de temps au milieu de la vue d'ensemble : deux
   commandes de même nature, à deux endroits, dont une qui bougeait.

   Le curseur prend la place restante (`flex: 1 1 22rem`) et repasse à la
   ligne sous environ 34 rem, parce qu'un curseur trop court ne se manipule
   plus au doigt. */
.controls {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.controls .std-picker { flex: none; }
.controls .back-link { margin-left: auto; }
.controls .back-link[hidden] { display: none; }

@media (max-width: 620px) {
  .controls { align-items: stretch; }
  .controls .std-picker { justify-content: space-between; }
  .controls .back-link { margin-left: 0; justify-content: center; }
}

/* --- Le retour au site ---------------------------------------------------
   Discret : on est dans un outil, pas dans une page de navigation. Il ne
   prend la place d'un onglet ni d'un menu, et disparaît à l'impression avec
   le reste de l'en-tête. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  white-space: nowrap;
  transition: color 0.16s var(--ease), border-color 0.16s var(--ease);
}
.back-link:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.back-link svg {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* --- La bascule FR/EN de l'outil -----------------------------------------
   Elle ne sert QUE lorsque l'application est ouverte seule a son adresse.
   Embarquee dans la page du projet, c'est le bouton FR/EN de la page qui
   commande : l'outil suit l'attribut lang du document parent, et ce bouton
   reste masque — deux bascules a trois centimetres l'une de l'autre poseraient
   la question de savoir laquelle fait foi.

   Meme forme que le lien de retour, meme grammaire que la bascule du site :
   les deux langues sont affichees, l'active est en accent. */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font: inherit;
  font-size: var(--step-0);
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.16s var(--ease), border-color 0.16s var(--ease);
}
.lang-switch:hover { color: var(--ink); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.lang-switch[hidden] { display: none; }
.lang-sep { opacity: 0.4; }
html[lang="fr"] .lang-opt[data-for="fr"],
html[lang="en"] .lang-opt[data-for="en"] { color: var(--accent); }

/* --- Onglets en pilules --------------------------------------------------
   Un soulignement se lit comme un sommaire de document ; une pilule se lit
   comme un sélecteur d'application. Le rôle ARIA, lui, ne bouge pas. */
.tabs { border-bottom: none; gap: 0.35rem; padding-bottom: 0.2rem; }
.tab {
  border-bottom: none;
  border-radius: 999px;
  padding: 0.5rem 1rem;
  border: 1px solid transparent;
}
.tab:hover { color: var(--ink); background: var(--surface); }
.tab[aria-selected="true"] {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 34%, var(--bg));
}

/* --- Reliefs et états ----------------------------------------------------
   Sur fond sombre, une carte ne se détache pas par son ombre : elle se
   détache par sa bordure. Le survol éclaire donc la bordure, il n'ajoute
   pas d'ombre. */
.verdict { padding: 1.25rem 1.4rem; box-shadow: var(--shadow); }
.verdict h2 { font-size: var(--step-3); letter-spacing: -0.02em; }
.verdict[data-status="ok"] .dot { box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 22%, transparent); }
.verdict[data-status="warning"] .dot { box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 22%, transparent); }
.verdict[data-status="alert"] .dot { box-shadow: 0 0 0 4px color-mix(in srgb, var(--alert) 22%, transparent); }

.counter .num { color: var(--accent); }
.counter[data-kind="warn"] .num { color: var(--warn); }
.counter[data-kind="alert"] .num { color: var(--alert); }

.el-card:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--border));
  box-shadow: var(--glow);
}
.el-card .sym { color: var(--ink); }
.el-card:hover .sym { color: var(--accent); }

.chart-card { box-shadow: var(--shadow); }
.table-scroll { background: var(--surface); }
.timeline li:hover .task { color: var(--accent); }

/* Le rapport reste sur une surface à part : à l'écran il annonce déjà qu'il
   est destiné au papier. */
.report { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: clamp(1.1rem, 2.5vw, 2rem); }

/* Sur téléphone, le chiffre doit rétrécir en même temps que son anneau :
   sinon il déborde du cercle et se lit par-dessus le tracé. */
@media (max-width: 560px) {
  .confidence { gap: 1rem; }
  .confidence-ring { width: 88px; height: 88px; }
  .confidence-pct { font-size: 1.05rem; }
  .confidence-text { min-width: 0; }
  .confidence-title { font-size: var(--step-2); }
}

/* ---------- Impression ----------
   LE PIÈGE ANNONCÉ EN TÊTE DE FICHIER.

   L'écran est sombre ; le papier est blanc. Imprimer le thème de l'écran
   donnerait de l'encre pâle sur du blanc, c'est-à-dire un rapport illisible —
   et un rapport est précisément ce qu'un laboratoire accrédité archive.

   Toute la palette est donc REDÉCLARÉE en clair pour l'impression. C'est le
   jeu de jetons d'origine de l'outil, celui qui avait été calibré pour le
   papier. Comme tout le reste de la feuille passe par ces variables, aucune
   autre règle n'a besoin d'être réécrite ici : seules les décorations qui
   n'ont pas de sens sur papier — maillage de fond, ombres, halos — sont
   neutralisées.

   Pour vérifier après une modification : onglet Rapport, Ctrl+P, et regarder
   l'aperçu. Un fond sombre qui apparaît dans l'aperçu est un défaut. */
@media print {
  :root {
    --bg: #fff;
    --surface: #F7F9FB;
    --surface-2: #EFF3F7;
    --ink: #16222E;
    --ink-soft: #3A4956;
    --muted: #5A6B7A;
    --border: #D3DDE6;
    --border-strong: #B4C3CF;

    --accent: #2C6E9B;
    --accent-hover: #24597D;
    --accent-ink: #fff;
    --accent-soft: #EAF2F8;

    /* Sémaphore calibré pour le papier : des encres franches, pas les
       teintes claires de l'écran, qui passeraient pour du gris. */
    --ok: #1E7A45;
    --warn: #9A6B10;
    --alert: #B32D22;
    --ok-soft: #EAF6EE;
    --warn-soft: #FBF3E3;
    --alert-soft: #FBECEA;
    --neutral-soft: #F1F4F7;

    --shadow: none;
    --glow: none;
  }

  body {
    background: #fff;
    background-image: none;   /* le maillage n'a rien à faire sur du papier */
    color: var(--ink);
  }
  .controls, .tabs, .report-bar, .tooltip { display: none !important; }
  .confidence, .chart-card, .counter, .el-card, .verdict { box-shadow: none !important; }
  .tabpanel { display: none !important; padding: 0; }
  #panel-report { display: block !important; }
  #panel-report[hidden] { display: block !important; }
  .wrap { width: 100%; }
  .report { max-width: 100%; background: #fff; border: none; border-radius: 0; padding: 0; }
  .report-chart, tr, .report-head, table { break-inside: avoid; }
  .report-charts { grid-template-columns: 1fr 1fr; }
  a { color: var(--ink); text-decoration: underline; }
  @page { margin: 14mm; }
}

@media (max-width: 560px) {
  .verdict { flex-direction: column; align-items: flex-start; }
}
