/* La feuille du site public.

   Deux thèmes, et l'un des deux n'est jamais un décor : sans choix explicite, c'est le réglage du
   système qui décide (`prefers-color-scheme`) ; avec un choix, l'attribut `data-theme` posé par le
   serveur l'emporte. Les deux chemins mènent aux mêmes variables — il n'y a qu'une palette, écrite
   une fois, et deux façons de la basculer.

   Aucune police téléchargée : la pile système. Une police distante bloque l'affichage derrière le
   Grand Firewall, et un texte qui n'arrive pas est pire qu'un texte pas tout à fait à la mode. */

:root {
  color-scheme: light;

  --fond: #ffffff;
  --fond-creux: #f4f5f7;
  --fond-carte: #ffffff;
  --trait: #e2e4e9;
  --trait-fort: #c8ccd4;
  --encre: #16181d;
  --encre-douce: #5d636e;
  --accent: #16181d;
  --accent-encre: #ffffff;
  /* Le jaune de la marque, repris du logo. Il ne sert qu'à souligner, jamais à porter du texte :
     sur fond blanc, il ne passe aucun contraste lisible. */
  --marque: #ffca2b;
  --ombre: 0 1px 2px rgba(16, 18, 22, .06), 0 8px 24px rgba(16, 18, 22, .05);

  --rayon: 12px;
  --pas: 8px;
  --colonne-lecture: 74ch;

  --police: system-ui, -apple-system, "Segoe UI", "Helvetica Neue", "Noto Sans",
            "Noto Sans SC", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
  --police-fixe: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                 "Liberation Mono", monospace;
}

/* Le thème sombre — d'abord par le réglage du système… */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --fond: #14161a;
    --fond-creux: #191c21;
    --fond-carte: #1c1f25;
    --trait: #2a2e36;
    --trait-fort: #3a3f49;
    --encre: #eceef2;
    --encre-douce: #a0a7b4;
    --accent: #eceef2;
    --accent-encre: #14161a;
    --ombre: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .28);
  }
}

/* …puis par le choix explicite, qui doit gagner DANS LES DEUX SENS : un visiteur au système
   sombre qui demande le thème clair doit l'obtenir, et réciproquement. */
:root[data-theme="clair"] {
  color-scheme: light;
  --fond: #ffffff;
  --fond-creux: #f4f5f7;
  --fond-carte: #ffffff;
  --trait: #e2e4e9;
  --trait-fort: #c8ccd4;
  --encre: #16181d;
  --encre-douce: #5d636e;
  --accent: #16181d;
  --accent-encre: #ffffff;
  --ombre: 0 1px 2px rgba(16, 18, 22, .06), 0 8px 24px rgba(16, 18, 22, .05);
}

:root[data-theme="sombre"] {
  color-scheme: dark;
  --fond: #14161a;
  --fond-creux: #191c21;
  --fond-carte: #1c1f25;
  --trait: #2a2e36;
  --trait-fort: #3a3f49;
  --encre: #eceef2;
  --encre-douce: #a0a7b4;
  --accent: #eceef2;
  --accent-encre: #14161a;
  --ombre: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .28);
}

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

body {
  margin: 0;
  padding: 0 calc(var(--pas) * 2) calc(var(--pas) * 6);
  background: var(--fond);
  color: var(--encre);
  font-family: var(--police);
  font-size: 16px;
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

a { color: inherit; }

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

.tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--pas);
  padding: calc(var(--pas) * 2) 0;
}

.marque {
  display: flex;
  align-items: center;
  gap: calc(var(--pas) * 1.5);
  text-decoration: none;
  min-width: 0;
}

.logo {
  /* Le logo est jaune sur toutes les surfaces : c'est la seule pièce colorée de la page, et elle
     tient son contraste sur les deux fonds. */
  height: 30px;
  width: auto;
  flex: none;
}

.marque-texte { display: flex; flex-direction: column; min-width: 0; }
.marque-texte strong { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.marque-texte small { color: var(--encre-douce); font-size: 12.5px; }

.reglages { display: flex; align-items: center; gap: 4px; }

.langues { display: flex; align-items: center; gap: 2px; }

.langue {
  padding: 5px 9px;
  border-radius: 8px;
  font-size: 13px;
  text-decoration: none;
  color: var(--encre-douce);
}

.langue:hover { background: var(--fond-creux); color: var(--encre); }

/* La langue en cours est marquée par `aria-current`, pas par une classe de plus : ce que l'œil
   voit et ce qu'un lecteur d'écran annonce viennent alors de la MÊME source. */
.langue[aria-current] { background: var(--fond-creux); color: var(--encre); font-weight: 600; }

.bascule {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-left: 4px;
  border: 1px solid var(--trait);
  border-radius: 9px;
  color: var(--encre-douce);
  text-decoration: none;
}

.bascule:hover { color: var(--encre); border-color: var(--trait-fort); }

/* Une seule des deux bascules s'affiche : celle qui mène à l'AUTRE thème que celui en cours.
   Défaut (aucun choix, système clair) → on propose le sombre. */
.vers-clair { display: none; }

@media (prefers-color-scheme: dark) {
  .vers-sombre { display: none; }
  .vers-clair { display: inline-flex; }
}

/* Le choix explicite reprend la main, y compris contre le média ci-dessus. */
:root[data-theme="clair"] .vers-sombre { display: inline-flex; }
:root[data-theme="clair"] .vers-clair { display: none; }
:root[data-theme="sombre"] .vers-sombre { display: none; }
:root[data-theme="sombre"] .vers-clair { display: inline-flex; }

/* --- Les onglets ------------------------------------------------------------------------------ */

.onglets {
  display: flex;
  gap: calc(var(--pas) * 3);
  border-bottom: 1px solid var(--trait);
  margin-bottom: calc(var(--pas) * 4);
}

.onglets a {
  padding: 10px 0;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  color: var(--encre-douce);
  font-size: 14px;
  text-decoration: none;
}

.onglets a:hover { color: var(--encre); }
.onglets a[aria-current] { color: var(--encre); border-bottom-color: var(--encre); font-weight: 600; }

/* --- La recherche ----------------------------------------------------------------------------- */

/* Des cartes bornées qui se rangent d'elles-mêmes : on remplit la largeur en AJOUTANT des
   colonnes, jamais en gonflant les champs. Sur un téléphone, il n'en reste qu'une. */
.recherche {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 320px));
  align-items: start;
  gap: calc(var(--pas) * 2);
  margin: 0 0 calc(var(--pas) * 3);
}

.champ { display: flex; flex-direction: column; gap: 5px; min-width: 0; }

.champ label { font-size: 13px; font-weight: 600; }

.champ input {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--trait-fort);
  border-radius: 10px;
  background: var(--fond-carte);
  color: var(--encre);
  /* 16px : en dessous, un iPhone zoome tout seul au premier appui dans le champ — et l'atelier
     se retrouve avec une page à faire glisser d'une main. */
  font-size: 16px;
  font-family: var(--police-fixe);
}

.champ input:focus-visible { outline: 2px solid var(--encre); outline-offset: 1px; }

.champ small { color: var(--encre-douce); font-size: 12px; }

button {
  align-self: end;
  min-height: 44px; /* la cible tactile d'un doigt ganté */
  padding: 11px 22px;
  border: 0;
  border-radius: 10px;
  background: var(--accent);
  color: var(--accent-encre);
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

button:disabled { opacity: .55; cursor: default; }

/* --- Le résultat ------------------------------------------------------------------------------ */

.resultat { display: block; }

.bobine, .echec {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: calc(var(--pas) * 3);
  max-width: 640px;
  padding: calc(var(--pas) * 2.5);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--fond-carte);
  box-shadow: var(--ombre);
}

.attente { margin: 0; color: var(--encre-douce); font-size: 14px; }

/* Ne s'affiche que si le script n'a pas tourné : un avertissement, pas une alarme. */
.sans-script {
  max-width: var(--colonne-lecture);
  margin: 0 0 calc(var(--pas) * 3);
  padding: calc(var(--pas) * 1.5) calc(var(--pas) * 2);
  border: 1px solid var(--trait-fort);
  border-radius: 10px;
  background: var(--fond-creux);
  color: var(--encre-douce);
  font-size: 14px;
}

.echec { display: block; max-width: var(--colonne-lecture); }
.echec h2 { margin: 0 0 6px; font-size: 16px; }
.echec p { margin: 0; color: var(--encre-douce); font-size: 14px; }

/* LA pastille : la couleur mesurée, en grand, parce que c'est ce qu'on est venu voir. Le damier
   dessous n'est pas décoratif — il rend visible une couleur presque blanche sur fond blanc. */
.pastille {
  flex: none;
  width: 108px;
  height: 108px;
  border-radius: 10px;
  border: 1px solid var(--trait-fort);
  background-color: var(--fond-creux);
  background-image:
    linear-gradient(45deg, var(--trait) 25%, transparent 25%, transparent 75%, var(--trait) 75%),
    linear-gradient(45deg, var(--trait) 25%, transparent 25%, transparent 75%, var(--trait) 75%);
  background-size: 14px 14px;
  background-position: 0 0, 7px 7px;
}

.faits { flex: 1 1 240px; min-width: 0; }

.produit { margin: 0; color: var(--encre-douce); font-size: 13px; }

.couleur { margin: 2px 0 calc(var(--pas) * 2); font-size: 21px; letter-spacing: -.01em; }

.faits dl { display: flex; flex-wrap: wrap; gap: calc(var(--pas) * 3); margin: 0; }
.faits dt { color: var(--encre-douce); font-size: 12px; }
.faits dd { margin: 2px 0 0; font-size: 15px; font-weight: 600; }
.hex { font-family: var(--police-fixe); }

.verdict {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: calc(var(--pas) * 2) 0 0;
  font-size: 13px;
  color: var(--encre-douce);
}

/* Une pastille d'état, FIXE. Pas de clignotement : un état n'est pas un événement. */
.verdict::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--trait-fort);
}

.verdict[data-valide="oui"]::before { background: #1a9c5b; }
.verdict[data-valide="non"]::before { background: var(--marque); }

.verdict-detail { margin: 4px 0 0; color: var(--encre-douce); font-size: 12.5px; max-width: 46ch; }
.verdict[data-valide="oui"] ~ .verdict-detail { display: none; }

/* --- La documentation -------------------------------------------------------------------------- */

/* Un fil de lecture : là, et seulement là, la colonne se borne. Un paragraphe qui court d'un bord
   à l'autre d'un écran large ne se lit pas. */
.doc { max-width: var(--colonne-lecture); }

.doc h1 { font-size: 24px; margin: 0 0 6px; letter-spacing: -.02em; }
.doc h2 { font-size: 16px; margin: calc(var(--pas) * 5) 0 var(--pas); }
.doc p { margin: 0 0 var(--pas); }
.chapeau { color: var(--encre-douce); margin-bottom: calc(var(--pas) * 3); }

.doc pre {
  margin: 0 0 var(--pas);
  padding: calc(var(--pas) * 2);
  border: 1px solid var(--trait);
  border-radius: 10px;
  background: var(--fond-creux);
  /* Un bloc large défile DANS son cadre : la page, elle, ne part jamais de travers. */
  overflow-x: auto;
}

.doc code { font-family: var(--police-fixe); font-size: 13px; }

.champs { width: 100%; border-collapse: collapse; font-size: 14px; }
.champs th { text-align: left; font-size: 12px; color: var(--encre-douce); font-weight: 600; }
.champs th, .champs td { padding: 9px 12px 9px 0; border-bottom: 1px solid var(--trait); vertical-align: top; }
.champs td:first-child { white-space: nowrap; }

.refus dt { margin-top: var(--pas); }
.refus dd { margin: 2px 0 0; color: var(--encre-douce); font-size: 14px; }

/* --- La roue chromatique ------------------------------------------------------------------------
   Un outil de contrôle, pas une page de dépannage : on y lit un nuage et un tableau de chiffres.
   Le tracé est BORNÉ (il ne s'étire pas sur un écran large — un nuage de points étalé sur 2000 px
   ne se lit pas mieux), et le tableau prend la largeur qui reste. */

.roue-titre { font-size: 24px; margin: 0 0 6px; letter-spacing: -.02em; }
.roue-intro { margin: 0 0 calc(var(--pas) * 3); color: var(--encre-douce); max-width: var(--colonne-lecture); }

.roue-bloc {
  margin-top: calc(var(--pas) * 3);
  padding: calc(var(--pas) * 2.5);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--fond-carte);
  box-shadow: var(--ombre);
}

.roue-entete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(var(--pas) * 2);
}

.roue-entete h2 { margin: 0; font-size: 19px; letter-spacing: -.01em; }
.roue-chiffres { display: flex; gap: calc(var(--pas) * 3); margin: 0; }
.roue-chiffres dt { color: var(--encre-douce); font-size: 12px; }
.roue-chiffres dd { margin: 2px 0 0; font-size: 17px; font-weight: 600; }

/* Ce que la vue ne montre pas, dit d'un ton neutre : ce n'est pas une erreur, c'est un fait. */
.roue-avis {
  margin: calc(var(--pas) * 2) 0 0;
  max-width: 46ch;
  padding: 10px 12px;
  border-left: 3px solid var(--marque);
  background: var(--fond-creux);
  border-radius: 0 8px 8px 0;
  color: var(--encre-douce);
  font-size: 13px;
}

.roue-plan {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: calc(var(--pas) * 3);
  margin-top: calc(var(--pas) * 2.5);
}

.roue-plan svg {
  /* Borné, et carré : les deux axes portent la même échelle Lab, une case rectangulaire
     déformerait le nuage et ferait paraître une dispersion plus grande qu'une autre. */
  flex: 0 1 420px;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1;
  border: 1px solid var(--trait);
  border-radius: 10px;
  background: var(--fond-creux);
}

/* Les axes : une aide à la lecture, pas une donnée. */
[data-forme="axe"] { stroke: var(--trait-fort); stroke-width: .4; }

/* Un point porte SA couleur mesurée en remplissage ; son état se lit à sa FORME et à son trait.
   Coder l'état par une couleur reviendrait à repeindre la donnée qu'on est venu regarder. */
.roue-plan .point { stroke: var(--encre); stroke-width: .7; }
[data-forme="a_valider"] { stroke-dasharray: 1.6 1.2; }
[data-forme="suspecte"] { stroke-width: 1.5; }

[data-forme="cible"] circle { fill: none; stroke: var(--encre); stroke-width: 1.1; }
[data-forme="cible"] path { fill: none; stroke: var(--encre); stroke-width: .6; }
[data-forme="baseline"] { stroke: var(--encre); stroke-width: 1.3; }

/* Un point ramené au bord n'est PLUS à ses coordonnées : il se montre autrement, sinon le tracé
   affirmerait une position qu'il n'a pas mesurée. */
[data-hors-cadre] { opacity: .75; stroke-dasharray: 1.2 1; }

/* La colonne de droite : la légende, puis ce que le tracé ne montre pas. Sur un écran large,
   cette bande restait vide à côté d'un tracé borné — c'est pourtant là qu'on lit. */
.roue-cote { flex: 1 1 200px; min-width: 0; }

.roue-legende {
  list-style: none;
  margin: 0;
  padding: 0;
  color: var(--encre-douce);
  font-size: 13px;
}

.roue-legende li { display: flex; align-items: center; gap: 8px; padding: 3px 0; }

.marque-cible, .marque-baseline, .marque-etat {
  flex: none;
  width: 12px;
  height: 12px;
  border: 1.5px solid var(--encre);
}

.marque-cible { border-radius: 50%; }
.marque-etat { border-radius: 50%; background: var(--encre-douce); }
.marque-etat[data-etat="a_valider"] { border-style: dashed; background: none; }
.marque-etat[data-etat="suspecte"] { border-radius: 0; transform: rotate(45deg); background: none; }

.roue-tableau {
  width: 100%;
  margin-top: calc(var(--pas) * 3);
  border-collapse: collapse;
  font-size: 14px;
}

.roue-tableau th {
  text-align: left;
  font-size: 12px;
  color: var(--encre-douce);
  font-weight: 600;
}

.roue-tableau th, .roue-tableau td {
  padding: 8px 12px 8px 0;
  border-bottom: 1px solid var(--trait);
  white-space: nowrap;
}

.roue-tableau .lot, .roue-tableau .hex, .roue-tableau .ecart { font-family: var(--police-fixe); font-size: 13px; }
.roue-tableau td:last-child { text-align: right; padding-right: 0; }

.pastille-point {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 8px;
  border: 1px solid var(--trait-fort);
  border-radius: 3px;
  vertical-align: -2px;
}

.etiquette-etat { color: var(--encre-douce); }
.etiquette-etat[data-etat="suspecte"] { color: var(--encre); font-weight: 600; }

.roue-limites {
  margin-top: calc(var(--pas) * 3);
  padding-top: calc(var(--pas) * 2);
  border-top: 1px solid var(--trait);
  color: var(--encre-douce);
  font-size: 12.5px;
  max-width: var(--colonne-lecture);
}

.roue-limites p { margin: 0 0 6px; }
.roue-limites p:last-child { margin-bottom: 0; }

/* --- Le pied ----------------------------------------------------------------------------------- */

.pied {
  margin-top: calc(var(--pas) * 6);
  padding-top: calc(var(--pas) * 2);
  border-top: 1px solid var(--trait);
  color: var(--encre-douce);
  font-size: 12.5px;
}

.pied p { margin: 0; }

/* --- Le téléphone -------------------------------------------------------------------------------
   L'usage RÉEL de cette page : debout devant une imprimante, une main sur la bobine. */

@media (max-width: 560px) {
  body { padding: 0 var(--pas) calc(var(--pas) * 5); }
  .marque-texte small { display: none; }
  .recherche { grid-template-columns: 1fr; gap: calc(var(--pas) * 1.5); }
  button { align-self: stretch; }
  .bobine { gap: calc(var(--pas) * 2); }
  .pastille { width: 84px; height: 84px; }
  .doc h1 { font-size: 21px; }
  .roue-titre { font-size: 21px; }
  .roue-bloc { padding: calc(var(--pas) * 1.5); }
  /* Le tableau garde ses colonnes et défile DANS son cadre : la page, elle, ne part jamais de
     travers — un tableau qui déborde emmène tout le reste avec lui. */
  .roue-tableau { display: block; overflow-x: auto; white-space: nowrap; }
}

/* Le mouvement n'est jamais décoratif ici — il n'y en a aucun à réduire. Cette règle existe pour
   le jour où l'un s'ajoutera : il sera déjà encadré. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
