/* 9-primitives.css — les primitives, en dernier parce qu'elles tranchent : exceptions de style, pastille
 * d'état, champ de saisie, carte.
 *
 * ── L'ORDRE COMPTE ─────────────────────────────────────────────────────────────────
 * Ce fichier est une TRANCHE de l'ancien app.css, découpé en neuf morceaux contigus. Le
 * chiffre en tête du nom est son rang de cascade, et ce n'est pas de la décoration : lus
 * dans l'ordre, les neuf fichiers valent exactement l'ancien, à l'octet près. Les intervertir
 * change ce qui l'emporte — et une cascade inversée ne se voit pas, elle se constate trois
 * jours plus tard sur un écran précis.
 *
 * Deux raisons de ne PAS regrouper par thème en réordonnant : les paires
 * `@media`/`@container` se redoublent (chacune doit rester APRÈS la @media qu'elle double),
 * et `container-type` définit l'unité de mesure de tout ce qu'il contient. Le découpage
 * contigu rend ces deux pièges impossibles au lieu de demander qu'on y pense.
 *
 * `tests/test_feuilles_css.py` vérifie que les quatre points de chargement listent bien ces
 * neuf fichiers, dans ce rang.
 */

/* — les exceptions de style —
 * Deux choix qu'aucun jeton ne saurait exprimer : ce ne sont pas des formes mais du contenu
 * (montrer ou non les libellés) et une inversion de traitement (le fond à la place du trait).
 * Elles se posent en classe sur le conteneur, donc l'aperçu entier bascule d'un coup. */

.st-menu-nu nav a span { display: none; }

/* L'aperçu porté par la feuille de style. Il existe parce que la vraie galerie est DERRIÈRE
 * elle : régler des angles sans voir d'angles revient à choisir dans le noir, fermer pour
 * regarder, rouvrir pour corriger. Quatre composants suffisent — une carte, un bouton, un
 * badge, un champ — ils portent à eux seuls le rayon, l'espacement et l'ombre. */
/* Segmenté : trois options côte à côte, une seule allumée.
 *
 * Ces règles ont existé pour l'avancement des jalons, et sont parties avec lui — l'ordre des
 * jalons dit désormais où on en est. Elles reviennent pour les réglages de style, qui posent
 * la même question : un choix parmi trois, tous visibles en même temps, parce qu'on compare
 * avant de choisir.
 *
 * L'option retenue est PLEINE et les autres vides. L'inverse a été essayé : les inactives
 * héritaient du fond d'accent des boutons d'action, et on lisait l'écran à l'envers. */
.states {
  display: flex;
  gap: var(--s0);
  padding: var(--s0);
  background: var(--panel2);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.states button {
  flex: 1;
  min-height: var(--tap-min);
  padding: 0 var(--s2);
  border-radius: 999px;
  color: var(--mist);
  font: var(--w-moyen) var(--t2)/var(--lh-plat) var(--font-body);
  white-space: nowrap;
}

.states button.on {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: var(--w-gras);
}

.st-vu {
  display: grid;
  gap: var(--s3);
  margin-bottom: var(--s4);
  padding: var(--s4);
  background: var(--panel2);
  border-radius: var(--radius);
}

.st-champ-rempli .field,
.st-champ-rempli .champ input,
.st-champ-rempli .champ select,
.st-champ-rempli .champ textarea {
  background: var(--panel2);
  border-color: transparent;
}

/* La vignette d'une forme de bouton, dans la feuille de choix : un vrai `.btn` dessiné avec
 * le rayon proposé. Le conteneur fige la largeur pour que les quatre propositions
 * s'alignent — sinon « Action » en pilule est plus large qu'en carré, et la liste ondule. */
.btn-demo { flex: 0 0 auto; display: grid; place-items: center; width: 96px; }
.btn-demo .btn { min-height: var(--tap-min); padding: 0 var(--s3); font-size: var(--t3); }

/* La proposition retenue : une bordure d'accent, comme partout ailleurs où l'on montre un
 * choix courant. */
.preset.on { border-color: var(--accent); }

.btn.soft { background: var(--accent-bg); border: 1px solid var(--accent); color: var(--accent-ink); }

/* — L'état, en pastille — */
.badge-state {
  display: inline-block;
  padding: 4px var(--s3);
  /* Le rayon du bouton et non 999px en dur : un badge qui reste en pilule pendant que tout
   * le reste passe au carré est le détail qui fait qu'une charte « ne va pas », sans qu'on
   * arrive à dire lequel. */
  border-radius: var(--btn-radius, 999px);
  background: var(--panel2);
  color: var(--mist);
  font: var(--w-fort) var(--t2)/var(--lh-ui) var(--font-body);
}

.badge-state.ok { background: var(--ok-bg); color: var(--ok); }
.badge-state.warn { background: var(--warn-bg); color: var(--warn); }
.badge-state.err { background: var(--error-bg); color: var(--error); }

/* — Le champ de saisie — */
.field {
  width: 100%;
  padding: var(--s3) var(--s4);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: var(--w-normal) var(--t-saisie)/var(--lh-ui) var(--font-body);
}

.field:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* — La carte — */
.card {
  padding: var(--s4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.card > b { display: block; font: var(--w-fort) var(--t5)/var(--lh-ui) var(--font-body); }
.card > small { color: var(--mist); font-size: var(--t3); }

/* Les réglages de publication réutilisent la carte d'identité : même structure, donc rien
 * de nouveau à apprendre d'un onglet à l'autre. */
.ds .field { margin-top: var(--s0); }
.ds-row small { margin-top: var(--s0); }

/* La galerie porte les jetons du produit prévisualisé, posés sur elle et non sur la page.
 * Elle peint donc son propre fond : sans ça, elle emprunterait celui du back-office et
 * l'aperçu mentirait sur le contraste réel. */
lane-gallery { display: block; background: var(--ground); border-radius: var(--radius); }

/* Les maquettes de menu et d'en-tête.
 *
 * `nav` et `header` sont stylés par des sélecteurs d'ÉLÉMENT, pas par des classes — c'est ce
 * qui permet à la galerie de les montrer avec leurs vraies couleurs et leurs vraies tailles,
 * sans en recopier une ligne. Le prix à payer est ici : rendus tels quels, ils se colleraient
 * à la fenêtre par-dessus la page, exactement comme les vrais.
 *
 * C'est donc la seule règle que la galerie possède en propre, et elle ne peint rien : elle
 * annule une position. Tout le reste — couleurs, tailles, état actif — reste partagé avec
 * l'application, ce qui est toute la valeur de cette galerie. */
.gal-chrome { position: relative; overflow: hidden; border-radius: var(--radius-sm); }
.gal-chrome nav, .gal-chrome header { position: static; }


/* Une chose surveillée. UNE seule règle pour toutes les lignes de l'écran, quel que soit
 * leur domaine — le temps de réponse d'un site, une suite de tests, un certificat, une unité
 * systemd, une source à brancher. C'est ce qui permet d'en ajouter une trentaine sans que
 * l'écran change de nature : une mesure de plus coûte une ligne de données, pas une forme
 * de plus à apprendre à lire.
 *
 * Elle remplace `.verdict` (une carte), `.vitaux` (une rangée de tuiles) et le détournement
 * de `.ds` (une liste de sources) : trois dessins pour une seule question. */
.surveille { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }

.surveille li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  /* Alignées sur la PREMIÈRE ligne, pas centrées : une carte qui porte une annonce et un
   * bouton fait trois fois la hauteur d'une carte verte, et une marque centrée s'y retrouve
   * à mi-hauteur, loin du titre qu'elle qualifie. */
  align-items: start;
  gap: var(--s2) var(--s3);
  padding: var(--s3) var(--s4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--lv, var(--line));
  border-radius: var(--radius);
  min-width: 0;
}

/* La marque porte la couleur de l'état. Une CLASSE, jamais un `style=` : la politique de
 * sécurité interdit les styles en ligne, et son échec est trompeur — la page s'affiche
 * normalement, mais toutes les couleurs d'état retombent sur leur défaut. */
.surveille .s-mark {
  color: var(--lv, var(--mist));
  font-size: var(--t3);
  /* Calée sur la ligne de base du titre, à la main : `align-items: start` colle la marque
   * en haut de la cellule, deux pixels au-dessus du texte. */
  line-height: var(--lh-corps);
}

.surveille > li > div { min-width: 0; }
.surveille b { display: block; font: var(--w-fort) var(--t4)/var(--lh-ui) var(--font-body); }
.surveille small { display: block; color: var(--text); font-size: var(--t2); }

/* Ce que le clic va faire. Une ligne, discrète, SANS encadré : `.muted` est ailleurs un
 * état vide (fond, marges, coins arrondis), et l'emprunter donnait une annonce qui
 * ressemblait à un champ de saisie — on cherchait à écrire dedans. */
.surveille .s-note {
  color: var(--mist);
  font-size: var(--t1);
  font-style: italic;
  margin-top: var(--s0);
}

/* Un état qu'on ne sait pas lire n'est pas une bonne nouvelle : il est gris, et le dit. Le
 * confondre avec un vert ferait passer une sonde morte pour une machine saine. */
.surveille li.lv-unknown b { color: var(--mist); }

/* Le bouton passe sous la ligne quand la fenêtre est étroite — même repli que `.ds-row`,
 * et pour la même raison : à trois colonnes sur 390 px, la phrase se réduit à deux mots par
 * ligne et devient illisible. */
@media (max-width: 620px) {
  .surveille li { grid-template-columns: auto 1fr; }
  .surveille li > button { grid-column: 2; justify-self: start; }
}

/* Le journal des réparations. Ce n'est pas une liste de travail : rien n'y est cliquable,
 * tout y est déjà fait. C'est ce qui rend l'infrastructure invisible SANS la rendre
 * opaque — on peut vérifier que quelque chose a veillé. */
.journal { list-style: none; margin: 0 0 var(--s5); padding: 0; display: grid; gap: var(--s2); }

.journal li {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s3);
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--lv, var(--line));
  border-radius: var(--radius);
}

.journal .j-mark { color: var(--lv, var(--mist)); font-size: var(--t3); }
.journal .j-when { color: var(--mist); font-size: var(--t2); font-variant-numeric: tabular-nums; }
.journal b { display: block; font: var(--w-fort) var(--t4)/var(--lh-ui) var(--font-body); }
.journal small { display: block; color: var(--mist); font-size: var(--t2); }

/* Les noms déjà pris : présents, lisibles, mais visiblement hors course. Les cacher
 * laisserait croire qu'on n'a pas cherché ; les présenter comme les autres ferait cliquer
 * dessus. */
.dom-h {
  margin: var(--s5) 0 var(--s2);
  font: var(--w-fort) var(--t2)/var(--lh-plat) var(--font-body);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--mist);
}

.dom-pris {
  list-style: none;
  margin: 0 0 var(--s4);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.dom-pris li {
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--mist);
  font-size: var(--t3);
  text-decoration: line-through;
  text-decoration-color: var(--line);
}

.dom-pris small { text-decoration: none; opacity: .8; }

/* Les canaux de diffusion. Une carte par canal, et le pli est ce qui rend l'écran lisible :
 * une carte ÉTEINTE ne montre que son nom et son interrupteur. Quatre cartes dépliées d'un
 * coup, c'est trois écrans de téléphone à faire défiler pour trouver celle qui parle. */
.canaux { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s3); }

.canal {
  padding: var(--s3) var(--s4);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* La barre de couleur ne s'allume que sur un canal allumé : sur un canal éteint, elle
   * signalerait un problème là où il n'y a qu'un choix. */
  border-left: 3px solid transparent;
}

.canal.on { border-left-color: var(--lv, var(--line)); }

/* Un canal que lane ne sait pas encore tenir. Assez présent pour dire qu'il existe, assez
 * discret pour qu'on ne l'attende pas. */
.canal.futur { opacity: .62; }

.canal-tete { display: flex; align-items: center; gap: var(--s3); }
.canal-tete > div { flex: 1; min-width: 0; }
.canal-tete b { display: block; font: var(--w-fort) var(--t5)/var(--lh-ui) var(--font-head); }
.canal-tete small { display: block; color: var(--mist); font-size: var(--t2); }

/* Ce que le canal rapporte, à hauteur de son nom : c'est la question qu'on se pose en
 * ouvrant l'écran, pas une note de bas de carte. */
.canal-aud {
  flex: 0 0 auto;
  font: var(--w-fort) var(--t4)/var(--lh-plat) var(--font-head);
  color: var(--mist);
}

.canal-futur { flex: 0 0 auto; font-size: var(--t2); color: var(--mist); }

.canal-etat { margin: var(--s3) 0 0; font-size: var(--t3); }
.canal-etat b { color: var(--lv, var(--text)); }
.canal-etat span { display: block; color: var(--mist); font-size: var(--t2); }

.canal-reglages { list-style: none; margin: var(--s3) 0 0; padding: 0; display: grid; gap: var(--s2); }
.canal-reglages label { display: block; font-size: var(--t2); color: var(--mist); margin-bottom: var(--s0); }
.canal-reglages small { display: block; color: var(--mist); font-size: var(--t2); margin-top: var(--s0); }

.canal-bascules { margin-top: var(--s3); }

/* Ce qui manque, COMPTÉ. Les diagnostics eux-mêmes vivent dans Tâches, avec leurs boutons —
 * les répéter ici donnerait deux endroits pour le même geste. */
.canal-manque { list-style: none; margin: var(--s3) 0 0; padding: 0; display: grid; gap: var(--s1); }

.canal-manque li {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  font-size: var(--t3);
  color: var(--mist);
}

.canal-manque .n {
  flex: 0 0 auto;
  min-width: 20px;
  font: var(--w-fort) var(--t3)/var(--lh-plat) var(--font-head);
  color: var(--text);
}

/* Ce qui reste à CONSTRUIRE se distingue de ce qui s'entretient : le premier attend une
 * décision, le second se répare tout seul. Les afficher pareil ferait attendre un bouton
 * devant un travail déjà en cours. */
.canal-manque .bati .n { color: var(--warn); }

.canal-manque small { color: var(--mist); opacity: .8; }

.canal-actions {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s3);
  flex-wrap: wrap;
}

.canal-actions small { flex: 1; min-width: 0; color: var(--mist); font-size: var(--t2); }

.canal-sources { margin-top: var(--s3); }
