/* assets/css/encre-lumiere.css
 * CHANTIER-IHM Phase 0 — les 6 primitives « Encre & Lumière ».
 * Préfixe el- : n'affecte AUCUNE page tant qu'elle n'adopte pas les classes.
 * Doctrine : docs/design/ENCRE-ET-LUMIERE.md
 * Tokens requis : css/design-tokens.css (v2, --el-*), chargé avant ce fichier.
 *
 * P1 shell      — page, wrap centré, sections, responsive
 * P2 kpi        — compteurs
 * P3 flux       — table/liste d'observation (sur l'encre)
 * P4 registre   — bloc de preuve (la lumière) + sceau
 * P5 verdict    — pastilles d'état sémantiques (2 mondes × 4 états)
 * P6 instrument — le score qui montre sa formule
 */

/* ============ P1 — SHELL ============ */
.el-page { font-family: var(--el-font-body); color: var(--el-ink-text); }
.el-wrap { max-width: var(--el-maxw); margin: 0 auto; }
.el-crumb { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--el-ink-text-3); }
.el-title { font-family: var(--el-font-title); font-weight: 800; font-size: 26px; margin: 6px 0 2px; color: var(--el-ink-white); }
.el-sub { color: var(--el-ink-text-2); max-width: 680px; }
.el-sec { display: flex; justify-content: space-between; align-items: baseline; margin: 22px 0 10px; }
.el-sec h2 { font-family: var(--el-font-title); font-weight: 700; font-size: 15px; color: var(--el-ink-white); margin: 0; }
.el-sec .el-tag { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--el-ink-text-3); }
.el-mono { font-family: var(--el-font-mono); }

/* ============ P2 — KPI ============ */
.el-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 24px 0; }
.el-kpi { background: var(--el-ink-surface); border: 1px solid var(--el-ink-line); border-radius: var(--el-radius); padding: 14px 16px; }
.el-kpi .el-lab { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--el-ink-text-3); }
.el-kpi .el-big { font-family: var(--el-font-title); font-weight: 800; font-size: 26px; margin-top: 4px; color: var(--el-ink-white); }
.el-kpi .el-det { font-size: 13px; color: var(--el-ink-text-3); margin-top: 3px; }
.el-kpi--gold { border-color: var(--el-gold-deep); }
.el-kpi--gold .el-lab { color: var(--el-gold-light); }

/* ============ P3 — FLUX (observation, sur l'encre) ============ */
.el-flux { background: var(--el-ink-surface); border: 1px solid var(--el-ink-line); border-radius: var(--el-radius); overflow: hidden; }
.el-flux-row { display: grid; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--el-ink-line); font-size: 13px; align-items: center; transition: background var(--el-t-interact), box-shadow var(--el-t-interact); }
.el-flux-row:last-child { border-bottom: none; }
.el-flux-row:hover { background: var(--el-interact-bg); box-shadow: inset 2px 0 0 var(--el-gold-light); }
.el-flux .el-ts { font-family: var(--el-font-mono); font-size: 13px; color: var(--el-ink-text-3); }
.el-flux .el-id { font-family: var(--el-font-mono); font-size: 13px; color: var(--el-ink-text-2); }
.el-flux .el-main { color: var(--el-ink-white); font-weight: 600; }
.el-flux .el-main .el-k { display: block; font-weight: 400; font-size: 13px; color: var(--el-ink-text-3); }
.el-flux .el-meta { font-family: var(--el-font-mono); font-size: 13px; color: var(--el-ink-text-2); }
/* RT-1b′ — variante « table » de P3. La vague pilote (Red Team) migre en iso-structure :
 * ses <table>/<thead>/<tr>/<td> sont conservés tels quels, aucune bascule en grille de div.
 * Cette variante applique donc le flux à une vraie table plutôt qu'à .el-flux-row.
 * Les cellules qui portent .el-id / .el-ts / .el-main / .el-meta gardent leur rendu P3. */
.el-flux--table { width: 100%; border-collapse: collapse; }
.el-flux--table thead th { padding: 8px 12px; text-align: left; font-size: 13px; font-weight: 500; color: var(--el-ink-text-3); border-bottom: 1px solid var(--el-ink-line); }
.el-flux--table tbody td { padding: 8px 12px; font-size: 13px; color: var(--el-ink-text); }
.el-flux--table tbody tr { border-bottom: 1px solid var(--el-ink-line); transition: background var(--el-t-interact), box-shadow var(--el-t-interact); }
.el-flux--table tbody tr:last-child { border-bottom: none; }
.el-flux--table tbody tr:hover { background: var(--el-interact-bg); box-shadow: inset 2px 0 0 var(--el-gold-light); }
/* RT-1c — le pendant clair de la variante ci-dessus, quand la table est servie
 * DANS le registre (compte rendu de preuve). Aucune primitive nouvelle : c'est
 * exactement l'idiome déjà employé par P5 (« .el-registre .el-vd--ok »), une
 * primitive existante déclinée par monde. */
.el-registre .el-flux--table thead th { color: var(--el-lum-dim); border-bottom-color: var(--el-lum-line); }
.el-registre .el-flux--table tbody td { color: var(--el-lum-ink); }
.el-registre .el-flux--table tbody tr { border-bottom-color: var(--el-lum-line); }
/* Sur la lumière, l'accent de survol prend l'or du registre — le même geste,
   décliné par monde (l'or de l'encre serait illisible sur l'ivoire). */
.el-registre .el-flux--table tbody tr:hover { background: var(--el-lum-ivory); box-shadow: inset 2px 0 0 var(--el-gold-deep); }

/* ============ P4 — REGISTRE (la lumière : ce qui fait foi) ============ */
.el-regmark { display: flex; align-items: center; gap: 10px; margin: 30px 0 10px; }
.el-regmark .el-rule { flex: 1; height: 1px; background: var(--el-gold-deep); opacity: .5; }
.el-regmark .el-t { font-family: var(--el-font-title); font-weight: 700; font-size: 13px; letter-spacing: .16em; color: var(--el-gold-light); text-transform: uppercase; }
.el-registre { background: var(--el-lum-ivory); border-radius: 12px; padding: 22px 24px; color: var(--el-lum-ink); box-shadow: 0 0 0 1px var(--el-gold-deep); font-family: var(--el-font-body); }
.el-registre h2, .el-registre .el-rtitle { font-family: var(--el-font-title); font-weight: 800; font-size: 17px; color: var(--el-lum-ink); margin: 0 0 2px; }
.el-registre .el-rsub { font-size: 13px; color: var(--el-lum-mut); margin-bottom: 16px; }
.el-registre .el-note { font-size: 13px; color: var(--el-lum-dim); font-style: italic; }
.el-card { background: var(--el-lum-white); border: 1px solid var(--el-lum-line); border-radius: var(--el-radius); padding: 12px 14px; }
.el-seal { display: inline-flex; align-items: center; gap: 5px; font-family: var(--el-font-mono); font-size: 13px; color: var(--el-gold-deep); }
.el-seal svg { flex-shrink: 0; }
.el-export { display: inline-block; font-family: var(--el-font-title); font-weight: 700; font-size: 13px; color: var(--el-lum-white); background: var(--el-lum-ink); padding: 8px 16px; border-radius: var(--el-radius-sm); text-decoration: none; cursor: pointer; border: none; }
.el-export span { color: var(--el-gold-light); }

/* ============ P5 — VERDICT (pastilles sémantiques, 2 mondes × 4 états) ============ */
.el-vd { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 20px; font-size: 13px; font-weight: 600; }
/* Sur l'encre */
.el-vd--ok   { background: var(--el-ok-ink-bg);  color: var(--el-ok-ink); }
.el-vd--ko   { background: var(--el-ko-ink-bg);  color: var(--el-ko-ink); }
.el-vd--warn { background: var(--el-warn-ink-bg); color: var(--el-warn-ink); }
.el-vd--un   { background: var(--el-un-ink-bg);  color: var(--el-un-ink); }
/* Sur la lumière (dans .el-registre) */
.el-registre .el-vd--ok   { background: var(--el-ok-bg); color: var(--el-ok); }
.el-registre .el-vd--ko   { background: var(--el-ko-bg); color: var(--el-ko); }
.el-registre .el-vd--warn { background: var(--el-gold-bg); color: var(--el-gold-deep); }
.el-registre .el-vd--un   { background: var(--el-un-bg); color: var(--el-un); }

/* ============ P6 — INSTRUMENT (le score qui montre sa formule) ============ */
.el-inst { background: var(--el-lum-white); border: 1px solid var(--el-gold-light); border-radius: var(--el-radius); overflow: hidden; font-family: var(--el-font-body); color: var(--el-lum-ink); }
.el-inst .el-ihead { background: var(--el-gold-bg); padding: 11px 16px; display: flex; justify-content: space-between; align-items: center; }
.el-inst .el-ihead .el-it { font-family: var(--el-font-title); font-weight: 700; font-size: 13px; color: var(--el-gold-deep); }
.el-inst .el-ibody { padding: 14px 16px; }
.el-inst .el-formula { font-family: var(--el-font-mono); font-size: 13px; background: var(--el-lum-ivory); border: 1px solid var(--el-lum-line); border-radius: var(--el-radius-sm); padding: 9px 12px; text-align: center; }
.el-inst .el-dims { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 12px; }
.el-inst .el-dim { text-align: center; padding: 7px 4px; border: 1px solid var(--el-lum-line); border-radius: 8px; }
.el-inst .el-dim .el-v { font-family: var(--el-font-mono); font-weight: 600; font-size: 15px; }
.el-inst .el-dim .el-k { font-size: 13px; color: var(--el-lum-mut); }
.el-inst .el-replay { display: inline-block; margin-top: 12px; font-family: var(--el-font-title); font-weight: 700; font-size: 13px; color: var(--el-lum-white); background: var(--el-lum-ink); padding: 7px 14px; border-radius: var(--el-radius-sm); text-decoration: none; cursor: pointer; border: none; }
.el-inst .el-replay span { color: var(--el-gold-light); }
.el-inst .el-ifoot { padding: 10px 16px; border-top: 1px solid var(--el-lum-line); font-size: 13px; color: var(--el-lum-mut); }

/* ============ HIÉRARCHIE DES BOUTONS (IHM-GOLD-DISCIPLINE §4) ============
   Quatre rangs, un seul porte l'or. La règle qui tient l'ensemble :

     JAMAIS DEUX BOUTONS DORÉS SUR LE MÊME ÉCRAN.

   Un CTA de routine n'est jamais `.btn-authority` — l'or ne récompense pas la
   fréquence d'usage, il marque l'acte qui engage (sceller, mandater, rejouer un
   score). Le CTA courant est saillant par CONTRASTE (ivoire sur l'encre), pas
   par couleur : c'est ce qui laisse l'or disponible pour dire quelque chose. */
.btn-primary,
.btn-secondary,
.btn-authority,
.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 16px;
  border-radius: var(--el-radius-sm);
  font-family: var(--el-font-body);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  transition: background .15s, border-color .15s, color .15s;
}

/* Routine — Créer / Enregistrer / Exporter. Ivoire premium sur l'encre. */
.btn-primary          { background: var(--el-lum-ivory); color: var(--el-lum-ink); border: 1px solid var(--el-lum-ivory); }
.btn-primary:hover    { background: var(--el-lum-white); border-color: var(--el-lum-white); }

/* Support — Éditer / Annuler / Filtrer.
   IHM-CORRECTIF-STAGING item C : ce rang était `transparent`. Un contour gris
   sur l'encre ne se lit pas comme un bouton — le rang de support n'est pas le
   rang invisible. Il est désormais REMPLI (`--el-ink-action`, la valeur de
   `.ta-action-row`), toujours sans crier : le contraste avec le CTA ivoire
   ci-dessus reste entier, c'est le contraste avec le VIDE qui manquait. */
.btn-secondary        { background: var(--el-ink-action); border: 1px solid var(--el-ink-line); color: var(--el-ink-text); }
.btn-secondary:hover  { background: var(--el-ink-action-hover); border-color: var(--el-ink-text-3); color: var(--el-ink-white); }

/* Acte d'autorité — Sceller / Mandater / Rejouer un score. Le seul or cliquable. */
.btn-authority        { background: rgba(232, 200, 119, .10); border: 1px solid var(--el-gold-deep); color: var(--el-gold-light); }
.btn-authority:hover  { background: rgba(232, 200, 119, .18); border-color: var(--el-gold-light); }

/* Irréversible — Révoquer / Kill / Quarantaine. */
.btn-danger           { background: var(--el-ko-ink-bg); border: 1px solid rgba(207, 90, 72, .5); color: #e08978; }
.btn-danger:hover     { background: rgba(207, 90, 72, .26); border-color: var(--el-ko-ink); }

/* Correspondance avec les classes déjà en place dans les 54 écrans. Les
   primitives ci-dessus sont la cible pour tout NOUVEAU bouton ; les classes
   historiques ont été repointées sur les mêmes quatre palettes par la passe
   IHM-GOLD-DISCIPLINE, sans toucher à leur géométrie. Ne pas créer un
   cinquième rang : si un bouton ne rentre dans aucun des quatre, c'est le
   bouton qu'il faut requalifier, pas la palette qu'il faut étendre.

     .btn-primary    ← .id-btn-primary · .p0-modal-confirm
     .btn-secondary  ← .id-btn · .p0-action-btn · .ta-action-row · .mm-btn · .td-btn-sm
     .btn-authority  ← .el-export · .el-inst .el-replay   (registre : sceau, rejeu)
     .btn-danger     ← .id-btn-danger · .p0-action-danger · .p0-modal-confirm.danger

   `.chip` est SORTI de ce mapping (IHM-CORRECTIF-STAGING item C) : une puce de
   filtre n'est pas un bouton d'action. Son état de repos est légitimement vide
   — c'est la SÉLECTION qui la remplit — alors que le rang secondaire, lui, doit
   se voir au repos. Les confondre est ce qui avait rendu l'un et l'autre
   transparents. */

.btn-primary[disabled],
.btn-secondary[disabled],
.btn-authority[disabled],
.btn-danger[disabled],
/* FIX-E2E-LOT5-2-DISABLED-STYLE (E2E-2) — .p0-action-btn est repointée sur la
   palette .btn-secondary (mapping ci-dessus) mais la classe elle-même n'est
   jamais ajoutée au DOM : le sélecteur [disabled] doit la cibler directement,
   sinon un bouton disabled reste visuellement identique à un bouton actif. */
.p0-action-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Sur le registre (monde lumière) : le contraste s'inverse. */
.el-registre .btn-primary,
.d7-inst .btn-primary   { background: var(--el-lum-ink); color: var(--el-lum-white); border-color: var(--el-lum-ink); }
.el-registre .btn-secondary,
.d7-inst .btn-secondary { border-color: var(--el-lum-sand); color: var(--el-lum-mut); }
.el-registre .btn-authority,
.d7-inst .btn-authority { background: var(--el-gold-bg); border-color: var(--el-gold-deep); color: var(--el-gold-deep); }

/* IHM-COHERENCE-LOT1 item C — les contrôles natifs suivent leur monde.
   `:root` porte `color-scheme: dark` (design-tokens.css) parce que la console
   est majoritairement l'encre. Sur le registre et les instruments, le fond est
   ivoire : un calendrier ou un `select` rendu sombre y serait exactement le
   défaut qu'on vient de corriger, dans l'autre sens. Même raisonnement que
   l'anneau de focus juste en dessous — le geste ne change pas, la teinte suit
   son monde. */
.el-registre,
.el-inst,
.d7-inst { color-scheme: light; }

/* Focus sur la lumière : l'anneau prend l'or profond. Le geste est le même,
   la teinte suit son monde — l'or clair de l'encre disparaîtrait sur l'ivoire,
   et un anneau qu'on ne voit pas ne vaut pas mieux qu'un focus absent (§5). */
.el-registre :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
.el-inst :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--el-focus-ring-lum);
}

/* ============ P7 — SKELETON (IHM-VITALITE) ============
   Le « Chargement… » en texte dit qu'on attend ; le skeleton montre CE QU'ON
   attend — la page se dessine avant d'arriver, l'œil n'a pas à se replacer au
   render. Trois barres de largeurs inégales : une liste, pas un bloc.

   Le shimmer parcourt un dégradé, il ne fait pas clignoter : un clignotement
   attire l'attention sur l'attente, un balayage la fait passer. Le mouvement
   s'arrête sous `prefers-reduced-motion` (règle globale, sidebar.css) — la
   surface reste alors visible, donc l'information « ça charge » ne dépend
   jamais de l'animation seule. */
.el-skeleton { display: block; }
.el-skeleton .el-sk-line {
  height: 12px;
  margin: 10px 0;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    var(--el-ink-surface) 0%,
    var(--el-ink-surface-2) 50%,
    var(--el-ink-surface) 100%);
  background-size: 200% 100%;
  animation: elShimmer 1.4s ease-in-out infinite;
}
.el-skeleton .el-sk-line:nth-child(1) { width: 62%; }
.el-skeleton .el-sk-line:nth-child(2) { width: 88%; }
.el-skeleton .el-sk-line:nth-child(3) { width: 74%; }
/* Le libellé reste dans le DOM pour les lecteurs d'écran : le skeleton est un
   effet visuel, il ne doit pas retirer l'information « chargement en cours ». */
.el-skeleton .el-sk-sr {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
@keyframes elShimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* ============ P8 — VIVANT (IHM-LIVENESS) ============
   Le mouvement DIT le réel : un pouls parce que le worker répond, un tracé qui
   se dessine parce que la courbe vient d'arriver, une ligne qui glisse parce
   qu'un événement vient de se produire. Trois gestes, trois faits. Rien ici ne
   boucle pour décorer — sauf le pouls, qui boucle parce que le battement EST
   l'information (un cœur qui bat une fois ne dit rien).

   Tout est coupé par la règle globale `prefers-reduced-motion` de sidebar.css.
   Chaque animation est écrite pour que son état d'ARRIVÉE soit l'état correct :
   `forwards` partout, et le tracé pose sa longueur en dur — coupée à .01ms,
   l'animation saute donc à la valeur finale au lieu de figer un état
   intermédiaire (un tracé invisible aurait été le pire des deux mondes). */

/* — Le pouls du pipeline. Un point plein, et une onde qui part de lui. — */
.el-hb { position: relative; display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: currentColor; }
.el-hb::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: currentColor;
  animation: elPulse 2.4s ease-out infinite;
}
/* Sans pouls : le point reste, l'onde ne part pas. C'est la forme que prend un
   pipeline en retard — le bandeau dit déjà « retard », un battement le
   contredirait. */
.el-hb--still::after { content: none; }
@keyframes elPulse {
  0%   { transform: scale(1);   opacity: .55; }
  70%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}

/* — Le tracé qui se dessine. La longueur vient du JS (Liveness.polylineLength),
     posée en `--el-draw-len` : exacte, donc le trait finit AVEC l'animation. — */
.el-draw {
  stroke-dasharray: var(--el-draw-len, 1200);
  stroke-dashoffset: var(--el-draw-len, 1200);
  animation: elDraw 1.6s ease-out forwards;
}
@keyframes elDraw { to { stroke-dashoffset: 0; } }
/* L'aire suit le trait — elle ne le précède jamais : une surface remplie sous
   une courbe pas encore tracée se lit comme un bug de rendu. */
.el-draw-area { opacity: 0; animation: elFadeIn 1s ease-out .8s forwards; }
@keyframes elFadeIn { to { opacity: 1; } }

/* — La ligne qui vient d'arriver. Posée par Liveness.prepend, sur elle seule. — */
.el-slidein { animation: elSlideIn .45s ease-out; }
@keyframes elSlideIn {
  from { opacity: 0; translate: 0 -8px; }
  to   { opacity: 1; translate: none; }
}

/* — Le flux en direct : une liste courte, bornée, qui ne pousse pas la page. — */
.el-live { background: var(--el-ink-surface); border: 1px solid var(--el-ink-line); border-radius: var(--el-radius); overflow: hidden; }
.el-live-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--el-ink-line); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--el-ink-text-3); }
.el-live-body { display: flex; flex-direction: column; }
.el-live-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; padding: 8px 14px; border-bottom: 1px solid var(--el-ink-line); font-size: 13px; transition: background var(--el-t-interact); }
.el-live-row:last-child { border-bottom: none; }
.el-live-row:hover { background: var(--el-interact-bg); }
.el-live-row .el-live-who { font-family: var(--el-font-mono); color: var(--el-ink-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.el-live-row .el-live-ts { font-family: var(--el-font-mono); font-size: 13px; color: var(--el-ink-text-3); white-space: nowrap; }
.el-live-row .el-live-what { grid-column: 1 / -1; font-size: 13px; color: var(--el-ink-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.el-live-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-right: 7px; vertical-align: middle; background: var(--el-un-ink); }
.el-live-dot--ok { background: var(--el-ok-ink); }
.el-live-dot--warn { background: var(--el-warn-ink); }
.el-live-dot--ko { background: var(--el-ko-ink); }

/* ============ RESPONSIVE (breakpoints de référence : 1024 / 900 / 760) ============ */
@media (max-width: 1024px) {
  .el-kpis { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 900px) {
  .el-wrap { padding: 0; }
}
@media (max-width: 760px) {
  .el-kpis { grid-template-columns: 1fr 1fr; gap: 10px; }
  .el-registre { padding: 16px 14px; }
  .el-inst .el-dims { grid-template-columns: 1fr 1fr; }
}
