/* mlsign v7 — le rapport de diffusion.
   Sert /le-rapport/ : le document entier, plus les blocs de la page qui
   l'entoure (.document, .dedans, .tait, .arrivee). Chargé après mlsign.css,
   fonts.css, socle.css, zones.css, composants.css.

   .rapport--extrait est GARDÉ mais plus servi : l'accueil montrait un extrait du
   document, il renvoie maintenant vers cette page. Le modificateur reste parce
   qu'il ne coûte rien et qu'il est la seule façon correcte de remontrer un bout
   du document ailleurs — le MÊME objet, coupé, jamais un second design.

   TROIS LOIS DE CE FICHIER, chacune payée d'une reconstruction ailleurs :

   1. Zéro hex. Uniquement des var(--…) de css/mlsign.css. Une nuance manquante
      se fabrique en color-mix() contre un jeton, jamais en posant une valeur.
   2. Un seul chiffre apex : le temps de diffusion. Deux chiffres apex, et le
      lecteur ne sait plus ce qu'il a acheté.
   3. Aucun filet de tableau. Un seul, sous le <thead>. La densité vient du pas
      (44 px de ligne) et de l'alignement, pas du trait — « tables à filets » est
      un refus explicite.

   Le document est SOMBRE à l'écran et INVERSE à l'impression (DESIGN.md, loi 5).
   L'inversion se fait en rebindant les rôles sur .rapport, pas en repeignant
   chaque règle : voir le bloc @media print, tout en bas. */

/* ---------------------------------------------------------------- le canevas */

/* .rapport porte ses rôles LUI-MÊME plutôt que de les hériter d'une zone : le
   document est un objet, il doit rester lisible où qu'on le pose — page de nuit,
   extrait dans une section claire, ou fichier ouvert seul. C'est aussi la loi 4
   de DESIGN.md : sombre par défaut partout où du contenu diffusé apparaît. */
.rapport {
  color-scheme: dark;
  --fond: var(--nuit);
  --surface: var(--fosse);
  --carte: var(--tribune);
  /* Ajouté le 14.08 avec le second niveau de carte. Sans lui, une carte posée
     dans le document héritait du creux du JOUR (#F1F3F2) : un aplat quasi blanc
     au milieu d'un document sombre. Le document porte ses rôles lui-même
     précisément pour que ça n'arrive pas, la liste doit rester complète. */
  --carte-basse: var(--fosse);
  --survol: var(--gradins);
  --bordure: var(--acier);
  --texte: var(--craie);
  --texte-secondaire: var(--brume);
  --preuve: var(--projecteur);

  /* Gouttière de labels : la même mesure pour les titres de bloc et pour la
     colonne de dates de la frise, sinon le document perd son axe. */
  --gouttiere: 11rem;
  --frise-label: 11ch;
  --frise-piste: 28px;
  --frise-segment: 8px;
  --ligne: 44px;

  background: var(--fond);
  color: var(--texte);
  inline-size: min(100%, 78rem);
  margin-inline: auto;
  padding-inline: var(--gutter, 1.5rem);
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem);
}

/* La page du spécimen : le document occupe tout, le fond de page suit. */
.rapport-page { background: var(--nuit); color: var(--craie); min-block-size: 100svh; }
html:has(.rapport-page) { background-color: var(--nuit); }

/* Le lien d'évitement. Défini ici parce que cette page ne charge pas la feuille
   des composants du site : elle doit tenir seule. */
.rapport-page .saut {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  transform: translateY(-120%);
  z-index: 2;
  padding: 0.75rem 1rem;
  background: var(--craie);
  color: var(--nuit);
  text-decoration: none;
}
.rapport-page .saut:focus { transform: none; }

/* ------------------------------------------------------------- le spécimen */

.rapport__specimen {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
  margin-block-end: clamp(2rem, 1.5rem + 2vw, 3rem);
}

/* Étiqueté honnêtement, jamais déguisé en document officiel : pas de sceau, pas
   de signature, pas de numéro d'ordre. Cuir est le jeton d'attente et de badge ;
   il vit ici en FILET, pas en aplat — sur un aplat, aucun texte ne tient 4,5:1
   contre lui. Le texte reste en craie, à 11,99:1. */
.rapport__specimen-etiquette {
  border-radius: 4px;
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte);
  border: var(--hairline) solid var(--attente);
  padding: 0.35em 0.7em;
  white-space: nowrap;
}

.rapport__specimen-mention {
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}

/* --------------------------------------------------------------- l'en-tête */

.rapport__entete {
  display: grid;
  gap: 1.5rem;
  padding-block-end: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.rapport__marque { inline-size: auto; block-size: 2.25rem; }
.rapport__papier-seul { display: none; }

.rapport__titre {
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
  color: var(--texte);
  max-inline-size: 20ch;
}

/* L'identité de la campagne : quatre paires, en ligne tant qu'il y a de la
   place. Ce n'est pas un tableau — c'est l'en-tête d'une lettre. */
.rapport__ident {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.5rem;
}
.rapport__ident-ligne { display: grid; gap: 0.2rem; }
.rapport__ident dt {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
}
.rapport__ident dd { color: var(--texte); }

/* ---------------------------------------------------------------- le verdict */

/* Ce que le lecteur comprend en cinq secondes : combien de temps son visuel a
   été porté. Le sommet de l'échelle de luminance appartient au contenu (loi 2) :
   c'est le seul endroit du document qui touche le projecteur, avec les trois
   appuis, qui sont au quart du corps. */
.rapport__verdict {
  display: grid;
  gap: 0.5rem;
  padding-block: clamp(2rem, 1.5rem + 2vw, 3.5rem);
}

/* Fragment Mono a une chasse large et une espace pleine chasse : à 8 rem,
   « 20 h 49 » se disloque en trois blocs. On resserre l'espace, pas la lettre —
   les chiffres doivent garder leur largeur tabulaire. */
.rapport__verdict-chiffre {
  font-size: clamp(3.5rem, 12vw, 8rem);
  line-height: 0.95;
  color: var(--preuve);
  letter-spacing: -0.03em;
  word-spacing: -0.35em;
}

/* DEUX h2 QUI NE SONT PAS DES TITRES À L'ŒIL. Le document a besoin de sa
   hiérarchie de titres pour un lecteur d'écran, et il les compose en
   micro-étiquettes espacées : 12 px, capitales, graisse 700. Depuis que la
   serif porte les h2 (DESIGN.md, amendement du 14.08), ils la prenaient, et à
   12 px en capitales une serif éditoriale se lit comme une coquille. Pire, ils
   demandent --wght-titre : Instrument Serif n'a que le 400, donc le navigateur
   en synthétisait un faux gras sur le plus petit texte du document.
   La voix suit le rang, pas la balise : ces deux-là sont au rang de
   .etiquette, ils prennent sa famille. Même exception que .live__qr. */
.rapport__verdict-legende,
.rapport__titre-bloc {
  font-family: var(--font-texte);
}
.rapport__verdict-legende {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
}

.rapport__verdict-phrase {
  margin-block-start: 0.75rem;
  max-inline-size: 52ch;
  color: var(--texte-secondaire);
  font-size: var(--t-lead, 1.1rem);
  line-height: var(--lh-dossier, 1.45);
}

.rapport__appuis {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 3rem;
  margin-block-start: 1.75rem;
}
.rapport__appui { display: grid; gap: 0.15rem; }
.rapport__appui-chiffre {
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  color: var(--preuve);
  line-height: 1.1;
  letter-spacing: -0.02em;
  word-spacing: -0.2em;
}
.rapport__appui-label {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
}

/* ------------------------------------------------------------- les blocs */

/* Un axe, pas des boîtes : le titre part dans la gouttière de gauche dès qu'il y
   a de la place, le contenu garde sa mesure. Aucun encadré, aucune carte —
   l'espace sépare, le trait ne sert qu'une fois, sous les en-têtes de tableau. */
.rapport__bloc,
.rapport__ecarts,
.rapport__exposition,
.rapport__scans,
.rapport__methode,
.rapport__limites,
.rapport__csv {
  display: grid;
  gap: 1rem;
  padding-block: clamp(1.75rem, 1.25rem + 2vw, 2.75rem);
}

@media (width >= 60rem) {
  .rapport__bloc,
  .rapport__ecarts,
  .rapport__exposition,
  .rapport__scans,
  .rapport__methode,
  .rapport__limites,
  .rapport__csv {
    grid-template-columns: var(--gouttiere) minmax(0, 1fr);
    column-gap: 3rem;
    align-items: start;
  }
  .rapport__titre-bloc { grid-column: 1; }
  .rapport__bloc > :not(.rapport__titre-bloc),
  .rapport__ecarts > :not(.rapport__titre-bloc),
  .rapport__exposition > :not(.rapport__titre-bloc),
  .rapport__scans > :not(.rapport__titre-bloc),
  .rapport__methode > :not(.rapport__titre-bloc),
  .rapport__limites > :not(.rapport__titre-bloc),
  .rapport__csv > :not(.rapport__titre-bloc) { grid-column: 2; }
}

/* Le titre de rang 3, à l'intérieur d'un bloc. Il ne part PAS dans la gouttière :
   celle-ci porte le titre du bloc, et deux niveaux dans la même colonne se
   liraient comme deux blocs. */
.rapport__sous-titre {
  font-size: var(--t-petit, 0.9rem);
  font-weight: var(--wght-titre);
  color: var(--texte);
  margin-block-start: 0.75rem;
}

.rapport__titre-bloc {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte);
  padding-block-start: 0.35rem;
}

.rapport__note {
  display: block;
  font-size: var(--t-petit, 0.9rem);
  line-height: var(--lh-dossier, 1.45);
  color: var(--texte-secondaire);
  max-inline-size: 62ch;
}

/* ---------------------------------------------------------------- la frise */

/* La seule représentation spatiale que la donnée autorise : le produit tient des
   périodes dans le temps, pas une trace. Fenêtre fixe 06:00 → 02:00 sur toutes
   les pistes — une fenêtre par jour ferait mentir la comparaison d'une ligne à
   l'autre. Elle est redondante par construction : tout ce qu'elle montre est
   dans les tableaux. */
/* min-inline-size: 0 — sans lui, la taille minimale automatique d'un enfant de
   grille vaut sa taille min-content : la frise (34 rem de piste) élargirait la
   colonne et c'est le CORPS de la page qui défilerait, pas la frise. */
.rapport__frise {
  min-inline-size: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-block-end: 0.25rem;
}

/* LES TEINTES DE ZONE — la seule couleur du document, et le seul endroit du site
   où plusieurs jetons se côtoient. Elles ne décorent pas : elles rendent une
   piste lisible d'un coup d'œil, et la légende juste dessous les nomme. Toutes
   sur des segments de 8 px de haut, jamais un aplat (DESIGN.md, loi 3).
   Sur --fond nuit : halo 6,44 · halo-vif 10,75 · cuir 3,11 — au-dessus du 3:1
   que WCAG 1.4.11 demande à un élément graphique porteur de sens.

   ELLES ÉTAIENT DANS UN ATTRIBUT DE STYLE, ET LA CSP LES JETAIT. La liste des
   jetons admis est doublée dans scripts/specimen.mjs (TEINTES) : un secteur
   déclaré avec un jeton qui n'a pas sa règle ici fait échouer le build au lieu
   de sortir un segment transparent. Ajouter une teinte, c'est donc deux
   endroits, et c'est voulu — la couleur du document se décide dans une feuille
   qu'on relit, pas dans un fichier de données. */
.frise__creneau--halo,
.frise__puce--halo { --teinte: var(--halo); }
.frise__creneau--halo-vif,
.frise__puce--halo-vif { --teinte: var(--halo-vif); }
.frise__creneau--cuir,
.frise__puce--cuir { --teinte: var(--cuir); }

.frise__jours { display: grid; gap: 0.9rem; min-inline-size: 34rem; }

.frise__jour,
.frise__axe {
  display: grid;
  grid-template-columns: var(--frise-label) minmax(0, 1fr);
  column-gap: 1rem;
  align-items: center;
  min-inline-size: 34rem;
}

.frise__label {
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}

.frise__piste {
  position: relative;
  block-size: var(--frise-piste);
  /* La piste vide est une information : sans surface, un jour sans diffusion
     n'aurait rien à montrer, et l'absence deviendrait invisible. */
  background: var(--surface);
}

.frise__creneaux { position: absolute; inset: 0; }

.frise__creneau {
  position: absolute;
  inset-block-start: calc((var(--frise-piste) - var(--frise-segment)) / 2);
  inset-inline-start: var(--debut);
  inline-size: calc(var(--fin) - var(--debut));
  block-size: var(--frise-segment);
  background: var(--teinte);
}

/* Le non attribué n'a JAMAIS de teinte : il n'appartient à aucune zone. Creux
   et rayé, il se lit comme un manque, pas comme une catégorie de plus. */
.frise__creneau--nonattribue {
  background: var(--survol);
  outline: var(--hairline) dashed var(--bordure);
  outline-offset: calc(var(--hairline) * -1);
}

/* Minuit est une GRADUATION, pas un dégradé : un filet pleine hauteur. Ça dit
   « la vacation a franchi minuit » plus fort qu'un fond qui change, et ça
   survit à l'impression en noir et blanc. */
.frise__minuit {
  position: absolute;
  inset-block: 0;
  inset-inline-start: var(--t);
  inline-size: var(--hairline);
  background: var(--bordure);
}

.frise__axe { margin-block-start: 0.4rem; }

/* Les graduations vivent dans leur propre boîte, calée sur la colonne des
   pistes : positionnées dans la grille, leurs pourcentages compteraient la
   gouttière des dates et l'axe glisserait d'un demi-centimètre. */
.frise__graduations {
  position: relative;
  display: block;
  block-size: 1.1rem;
}

.frise__heure {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: var(--t);
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-micro, 0.75rem);
  line-height: 1;
  color: var(--texte-secondaire);
}
/* Les deux graduations de bout rentrent au lieu de déborder : centrée, la
   dernière se faisait couper en deux par le conteneur défilant, et « 02 »
   s'affichait « 0 ». */
.frise__heure:first-child { transform: none; }
.frise__heure:last-child { transform: translateX(-100%); }

/* L'étiquette de minuit est plus claire que ses voisines : c'est la seule
   graduation qui dit quelque chose du produit. */
.frise__heure--minuit { color: var(--texte); }

.frise__legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}
.frise__puce { display: flex; align-items: center; gap: 0.5rem; }
.frise__puce::before {
  content: "";
  inline-size: 1.75rem;
  block-size: var(--frise-segment);
  background: var(--teinte);
  flex: none;
}
.frise__puce--nonattribue::before {
  background: var(--survol);
  outline: var(--hairline) dashed var(--bordure);
  outline-offset: calc(var(--hairline) * -1);
}
.frise__puce--minuit::before {
  inline-size: var(--hairline);
  block-size: 1.1rem;
  background: var(--bordure);
  margin-inline: calc((1.75rem - var(--hairline)) / 2);
}

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

/* Même garde que pour la frise : un tableau à en-têtes insécables déborderait
   la colonne au lieu de défiler dans sa boîte. */
.rapport__defile { min-inline-size: 0; overflow-x: auto; overscroll-behavior-x: contain; }

.rapport__table {
  inline-size: 100%;
  border-collapse: collapse;
  text-align: start;
}

/* LE SEUL FILET DU DOCUMENT. Zéro filet vertical, zéro cellule encadrée, zéro
   fond alterné : la séparation vient du pas de 44 px et de l'alignement des
   nombres à droite. */
.rapport__table thead th {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
  text-align: start;
  padding-block: 0 0.6rem;
  padding-inline-end: 1.5rem;
  border-block-end: var(--hairline) solid var(--bordure);
  white-space: nowrap;
}

.rapport__table td {
  block-size: var(--ligne);
  padding-block: 0.5rem;
  padding-inline-end: 1.5rem;
  color: var(--texte);
  vertical-align: middle;
}
.rapport__table th:last-child,
.rapport__table td:last-child { padding-inline-end: 0; }

.rapport__table .n { text-align: end; }

@media (hover: hover) {
  .rapport__table tbody tr:hover { background: var(--surface); }
}

/* L'attribution se dit, elle ne se déduit pas d'une couleur : une zone déclarée
   n'est jamais présentée comme une mesure GPS. */
.rapport__source {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
  white-space: nowrap;
}

/* Un zéro s'affiche toujours. Un jour écoulé sans preuve porte la mention,
   jamais un trou : c'est ce comportement qui rend le reste crédible. */
.rapport__vide {
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}

/* ---------------------------------------------------------------- les écarts */

/* Ce qui n'a PAS été compté. Les chiffres sont en secondaire, jamais en preuve :
   ils ne sont pas de la preuve, ils en sont le complément. */
.rapport__ecarts dl { display: grid; gap: 1.5rem; }
.rapport__ecart {
  display: grid;
  gap: 0.35rem;
  max-inline-size: 62ch;
}
.rapport__ecart dt {
  font-size: var(--t-petit, 0.9rem);
  font-weight: var(--wght-titre);
  color: var(--texte);
}
.rapport__ecart dd { display: grid; gap: 0.35rem; }
.rapport__ecart-chiffre {
  font-size: clamp(1.25rem, 1.1rem + 0.8vw, 1.6rem);
  color: var(--texte-secondaire);
  line-height: 1.1;
}

/* ---------------------------------------------------- le potentiel d'exposition */

/* LE SEUL CHIFFRE DU DOCUMENT QUI NE SOIT PAS UNE PREUVE, et la feuille le dit
   avec la seule chose qu'un lecteur croit sans réfléchir : la lumière.
   La fourchette et le compteur de scans ont EXACTEMENT la même géométrie — même
   clamp, même graisse, même interlignage. Un seul écart entre eux, la luminance :
   les scans tiennent --preuve, la fourchette tient --texte-secondaire. Le lecteur
   voit lequel des deux engage sans qu'on le lui écrive, et il le verra encore
   imprimé en noir et blanc.
   C'est la même décision que .rapport__ecart-chiffre juste au-dessus : ce qui
   n'est pas de la preuve ne touche pas le blanc du projecteur. */
.rapport__estime {
  display: grid;
  gap: 0.35rem;
  max-inline-size: 62ch;
}

.rapport__fourchette {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}

.rapport__borne {
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  color: var(--texte-secondaire);
  line-height: 1.1;
  letter-spacing: -0.02em;
  word-spacing: -0.2em;
}

/* Le mot qui joint les deux bornes n'est PAS un nombre : Switzer, pas Fragment
   Mono. En mono il aurait la chasse d'un chiffre et la fourchette se lirait
   comme un nombre à trois blocs. */
.rapport__joint {
  font-family: var(--font-texte);
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}

.rapport__estime-legende {
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}

/* « Une estimation, pas un comptage. » Elle est COLLÉE à la fourchette par la
   structure (même bloc dans le gabarit) et elle est en TEXTE COURANT, jamais en
   secondaire : une mention qui qualifie un chiffre ne peut pas être moins lisible
   que le chiffre qu'elle qualifie, sinon elle devient une clause de bas de page
   et le nombre repart tout seul dans une présentation client. */
.rapport__estime-mention {
  color: var(--texte);
  font-size: var(--t-petit, 0.9rem);
  font-weight: var(--wght-titre);
}

.rapport__presence { display: grid; max-inline-size: 62ch; }
.rapport__presence-chiffre {
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  color: var(--texte-secondaire);
  line-height: 1.2;
}
.rapport__presence dd { display: grid; gap: 0.3rem; }

/* Les signaux sont nommés, la formule ne l'est pas. Une liste sans puce : la
   puce en ferait un inventaire de fonctionnalités, alors que c'est une
   déclaration de provenance. */
.rapport__signaux {
  display: grid;
  gap: 0.6rem;
  max-inline-size: 62ch;
  color: var(--texte-secondaire);
  line-height: var(--lh-dossier, 1.45);
}
.rapport__signaux li {
  padding-inline-start: 1.25rem;
  border-inline-start: var(--hairline) solid var(--bordure);
}

/* Le niveau de confiance se dit, il ne se code pas en couleur : une zone
   extrapolée n'est pas une zone en alerte, et lui donner une teinte la ferait
   lire comme un défaut. Même micro-étiquette que l'attribution du tableau
   « Où », parce que c'est la même nature d'information. */
.rapport__confiances {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2rem;
}
.rapport__confiance { display: grid; gap: 0.2rem; }
.rapport__confiance-zone { color: var(--texte); font-size: var(--t-petit, 0.9rem); }
.rapport__confiance-niveau {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
  white-space: nowrap;
}

/* Le renvoi vers la page de méthode. Il porte sa couleur ICI et non par .lien de
   css/composants.css : le document doit rester lisible où qu'on le pose, y
   compris ouvert seul, et une feuille de composants qu'il ne charge pas ne peut
   pas tenir un lien qui lui appartient. Même traitement que les liens du pied. */
.rapport__renvoi { font-size: var(--t-petit, 0.9rem); }
.rapport__renvoi a { color: var(--texte); text-underline-offset: 0.25em; }

/* ------------------------------------------------------------------ les scans */

/* LE SEUL FAIT du document. Il tient --preuve, à la même échelle que les trois
   appuis du verdict : c'est un fait, il a le droit au blanc, mais il n'est pas
   ce que le client a acheté — un seul chiffre apex dans tout le document, et
   c'est le temps de diffusion (loi 2 de ce fichier). */
.rapport__scans-total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
}
.rapport__scans-chiffre {
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  color: var(--preuve);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.rapport__scans-legende {
  font-size: var(--t-micro, 0.75rem);
  font-weight: var(--wght-titre);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-secondaire);
}
.rapport__scans-fait {
  max-inline-size: 62ch;
  color: var(--texte);
  line-height: var(--lh-dossier, 1.45);
}

/* --------------------------------------------------------------- la méthode */

.rapport__methode dl { display: grid; gap: 1.5rem; max-inline-size: 62ch; }
.rapport__entree { display: grid; gap: 0.3rem; }
.rapport__entree dt {
  font-size: var(--t-petit, 0.9rem);
  font-weight: var(--wght-titre);
  color: var(--texte);
}
.rapport__entree dd {
  color: var(--texte-secondaire);
  line-height: var(--lh-dossier, 1.45);
}

/* --------------------------------------------------------------- les limites */

/* EN :where(), ET C'EST LE POINT. À (0,1,1) cette règle battait
   .rapport__frontiere (0,1,0) juste dessous : la phrase qui trace la limite
   entre preuve de diffusion et audience, la plus engageante du document,
   demandait --texte et sortait en secondaire depuis toujours. Personne ne
   l'avait vu parce que TOUT sortait en secondaire.
   À (0,0,1) la règle fait ce que son nom dit : elle donne sa teinte au bloc
   des limites, et une ligne qui se nomme reprend la main. */
:where(.rapport__limites) p {
  color: var(--texte-secondaire);
  line-height: var(--lh-dossier, 1.45);
  max-inline-size: 62ch;
}

/* La frontière preuve de diffusion / audience. Un filet, jamais un encadré :
   la phrase se distingue sans se transformer en avertissement légal. */
.rapport__frontiere {
  border-inline-start: var(--hairline) solid var(--bordure);
  padding-inline-start: 1.25rem;
  color: var(--texte);
}

/* ------------------------------------------------------------------- le CSV */

.rapport__csv p { color: var(--texte-secondaire); line-height: var(--lh-dossier, 1.45); max-inline-size: 62ch; }

.rapport__colonnes-legende {
  font-size: var(--t-petit, 0.9rem);
}

.rapport__colonnes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  font-size: var(--t-petit, 0.9rem);
}
.rapport__colonnes li {
  background: var(--surface);
  color: var(--texte);
  padding: 0.25em 0.6em;
}

.rapport__csv-ligne { display: grid; gap: 0.4rem; }

/* Sur un spécimen, le fichier n'existe pas : c'est un <span>, jamais un <a>. Un
   href mort détruirait exactement la confiance qu'on essaie de construire. */
.rapport__csv-inerte {
  justify-self: start;
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
  border: var(--hairline) dashed var(--bordure);
  padding: 0.35em 0.7em;
}

/* ------------------------------------------------------------------- le pied */

.rapport__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 2rem;
  margin-block-start: clamp(2rem, 1.5rem + 2vw, 3rem);
  padding-block-start: 1.25rem;
  border-block-start: var(--hairline) solid var(--bordure);
  font-size: var(--t-petit, 0.9rem);
  color: var(--texte-secondaire);
}
.rapport__pied-marque { color: var(--texte); }
/* La mention qui dit ce qu'est le document. Elle est bornée : sans mesure, une
   phrase un peu longue poussait les deux liens hors de la ligne et le pied
   passait sur trois rangs pour trois éléments. */
.rapport__pied-mention { max-inline-size: 48ch; }
.rapport__pied-liens { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-inline-start: auto; }
.rapport__pied a { color: var(--texte); text-underline-offset: 0.25em; }

/* ---------------------------------------------------------------- l'extrait */

/* Le one-pager montre le MÊME objet, coupé. Un modificateur, pas un second
   design — sinon le lien « voir un rapport complet » trahit. */
/* exposition et scans sont masqués comme methode, limites, csv et pied : l'extrait
   de l'accueil montre la FORME du document, pas son contenu entier, et le
   déroulé complet des vingt-trois scans y ferait un mur au milieu d'un one-pager.
   L'accueil garde donc exactement la longueur qu'il avait avant ces deux blocs.
   Si page-accueil veut y montrer la fourchette — c'est le seul chiffre du
   document que la concurrence ne publie pas — il suffit de retirer une ligne
   ici, et l'extrait restera le même objet. */
.rapport--extrait [data-rapport-bloc="exposition"],
.rapport--extrait [data-rapport-bloc="scans"],
.rapport--extrait [data-rapport-bloc="methode"],
.rapport--extrait [data-rapport-bloc="limites"],
.rapport--extrait [data-rapport-bloc="csv"],
.rapport--extrait [data-rapport-bloc="pied"] { display: none; }

.rapport--extrait { padding-block-end: 0; }

/* ------------------------------------------------------- la page /le-rapport/ */

/* La bande qui porte le document sur /le-rapport/. Elle ne l'habille pas : le
   rapport tient sa largeur, ses marges et ses rôles tout seul, et c'est ce qui
   permet de le poser ici comme dans un mail ou dans un PDF.
   Elle existe pour UNE raison : donner à la nuit toute la largeur de l'écran. En
   zone-jour, on verrait une colonne sombre de 78 rem posée sur du papier, avec
   deux gouttières claires — le document aurait l'air d'une capture d'écran, ce
   qui est exactement l'objet que cette page refuse d'être.
   .dedans, .tait et .arrivee n'ont volontairement pas de CSS : .dossier,
   .dossier__grille et .bloc les habillent déjà (css/composants.css). Elles
   nomment la page, comme .slot__* sur /le-slot/. */
.document {
  border-radius: var(--radius); display: grid; }

/* QUATRE ITEMS, JAMAIS TROIS PLUS UN. .dossier__grille répartit en auto-fit et
   pose trois colonnes à la largeur du site : le quatrième tombait seul sur une
   deuxième ligne, et un bloc titré « Quatre sections » se lisait « trois, plus
   une ». Le titre annonce un compte, la grille doit le tenir. Deux paliers
   explicites plutôt qu'un auto-fit plus fin : l'auto-fit ne peut pas garantir
   l'absence d'orphelin, il ne connaît pas le nombre d'items.
   Le bloc « ce qu'on ne met pas dedans » en a trois : l'auto-fit lui suffit, il
   n'orpheline pas, et il garde donc la règle commune. */
@media (width >= 40rem) {
  .dedans .dossier__grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (width >= 72rem) {
  .dedans .dossier__grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ------------------------------------------------ la frise sur un téléphone */

/* Sous 40rem, le défilement horizontal de la frise n'a aucune prise visible et
   la fenêtre coupée à mi-course faisait dire aux pistes que la vacation
   s'arrête à 16 h : sur un document de preuve, c'est un mensonge de mise en
   page. La frise renonce donc à sa largeur minimale et tient la colonne
   entière ; les graduations respirent en cachant une heure sur deux, les deux
   bouts et minuit restent. Les tableaux perdent le tiers du pas horizontal qui
   les faisait déborder de 10 px dans le vide (l'overflow-x: clip du html
   avalait la fin des durées sans aucun signe). */
@media (width < 40rem) {
  .frise__jours, .frise__jour, .frise__axe { min-inline-size: 0; }
  .frise__jour, .frise__axe { column-gap: 0.6rem; }
  .frise__label { font-size: var(--t-micro, 0.75rem); }
  .frise__heure:nth-child(even):not(.frise__heure--minuit):not(:last-child) { display: none; }
  /* Minuit et 02 ne sont qu'à 2 h l'un de l'autre : à cette largeur, seule une
     graduation plus petite les empêche de se toucher. */
  .frise__heure { font-size: 0.65rem; }
  .rapport__table thead th { white-space: normal; letter-spacing: 0.08em; }
  /* `thead th` et pas `th` : la règle qui pose 1.5rem plus haut vise
     `.rapport__table thead th`, soit (0,1,2). Écrite en `th`, celle-ci pèse
     (0,1,1) et PERD malgré le média — l'en-tête gardait ses 24 px, mesuré au
     navigateur. Une règle qui ne peint rien est pire qu'une règle absente :
     elle fait croire que le palier est traité. */
  .rapport__table thead th,
  .rapport__table td { padding-inline-end: 1rem; }
}

/* -------------------------------------------------------------- l'impression */

/* Le papier inverse, la loi reste : la preuve tient les extrêmes du contraste
   (DESIGN.md, loi 5). On rebinde les rôles sur .rapport plutôt que de repeindre
   chaque règle — une seule liste à relire, et rien ne peut diverger.
   Le vrai livrable plateforme est déjà en registre papier : l'impression du
   spécimen ressemble au rapport que le client recevra. */
@media print {
  @page { margin: 16mm; }

  html:has(.rapport-page), .rapport-page { background: var(--papier); color: var(--nuit); }

  /* LA BANDE DE NUIT DE /le-rapport/ PASSE AU PAPIER. Sans cette règle, le
     document s'inverse correctement (bloc ci-dessous) et reste encadré d'un
     aplat sombre pleine page : une cartouche dépensée pour un cadre qui ne dit
     rien, et un rapport imprimé qui ne ressemble plus à celui qu'on envoie.
     On rebinde les rôles plutôt que de repeindre, comme .rapport juste après :
     une seule liste à relire, et rien ne peut diverger.
     Elle gagne contre .zone-nuit à spécificité égale (0,1,0) par l'ordre de
     source — zones.css est chargée avant cette feuille. */
  .document {
    color-scheme: light;
    --fond: var(--papier);
    --texte: var(--nuit);
    background: var(--fond);
    color: var(--texte);
  }

  .rapport {
    color-scheme: light;
    --fond: var(--papier);
    /* acier sur papier : 7,0:1. Le seul jeton existant qui tienne le texte
       secondaire à l'encre sans inventer une couleur. */
    --texte: var(--nuit);
    --texte-secondaire: var(--acier);
    --preuve: var(--nuit);
    --bordure: color-mix(in srgb, var(--acier) 45%, var(--papier));
    /* La piste vide et les pastilles de colonnes ne se peignent pas à
       l'imprimante : un aplat sombre coûte de l'encre et ne dit rien. */
    --surface: color-mix(in srgb, var(--acier) 12%, var(--papier));
    --survol: color-mix(in srgb, var(--acier) 22%, var(--papier));
    inline-size: 100%;
    padding: 0;
  }

  /* La preuve tient l'extrême : sur papier, c'est l'encre pleine et la graisse.
     Fragment Mono n'a qu'un 400 — la graisse est synthétisée, volontairement.
     Les scans sont dans cette liste et la fourchette n'y est PAS : l'écart de
     luminance qui sépare le fait de l'estimation doit survivre à l'imprimante,
     sinon le document imprimé ment là où l'écran disait vrai. */
  .rapport__verdict-chiffre,
  .rapport__appui-chiffre,
  .rapport__scans-chiffre { color: var(--nuit); font-weight: var(--wght-titre); }

  .rapport__ecran-seul { display: none !important; }
  .rapport__papier-seul { display: block; }

  /* Les teintes de zone de la frise sont conservées : c'est la clé de lecture
     de la piste, pas de la décoration. */
  .frise__creneau, .frise__puce::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  .rapport__bloc, .rapport__ecarts, .rapport__methode,
  .rapport__limites, .rapport__csv, .rapport__verdict,
  .frise__jour, .rapport__table tr { break-inside: avoid; }

  /* La fourchette et sa mention ne se séparent JAMAIS d'un saut de page : un
     chiffre seul en bas de feuille, sa qualification en haut de la suivante, et
     le document a menti sans qu'une ligne ait changé. C'est la seule raison pour
     laquelle .rapport__estime est un élément.
     Le bloc des scans, lui, N'EST PAS en break-inside: avoid : vingt-trois lignes
     ne tiennent pas toujours sur une page, et forcer l'insécable pousserait le
     tableau entier sur une feuille à moitié vide. Ce sont les lignes qui sont
     protégées, une par une, par la règle ci-dessus. */
  .rapport__estime, .rapport__exposition { break-inside: avoid; }
  .rapport__scans-total, .rapport__scans-fait { break-after: avoid; }

  .rapport__frise, .rapport__defile { overflow: visible; }
  .frise__jours, .frise__jour, .frise__axe { min-inline-size: 0; }

  .rapport__table tbody tr:hover { background: none; }
}

/* Contraste renforcé : le secondaire remonte au texte courant. Rien d'autre ne
   bouge — les extrêmes sont déjà tenus. */
@media (prefers-contrast: more) {
  .rapport { --texte-secondaire: var(--craie); }
  @media print {
    .rapport { --texte-secondaire: var(--nuit); }
  }
}

/* Couleurs forcées : on rend la main au système et on garde les frontières. */
@media (forced-colors: active) {
  .frise__piste { border: 1px solid CanvasText; background: Canvas; }
  .frise__creneau { background: CanvasText; }
  .frise__creneau--nonattribue { background: Canvas; outline: 1px dashed CanvasText; }
  .frise__minuit { background: CanvasText; }
}
