/* Le fil : des bulles, des cartes, une ligne d'activité et une ligne d'état.
 *
 * Toutes les couleurs et tous les espacements viennent des jetons de `coque.css` (COQUE.md
 * §2.3) : ce fichier n'en invente aucun, pour qu'un changement de palette se fasse à un seul
 * endroit. Aucune règle ne suppose une largeur d'écran : la colonne se centre côté coque.
 *
 * Quatre choix de forme méritent un mot :
 *   — les bulles s'arrêtent à 86 % de la largeur, pour qu'on voie toujours de quel côté on est ;
 *   — la vignette d'une livraison tient son ratio (16:9, ou 9:16 quand la vidéo est verticale)
 *     avec `aspect-ratio` : la hauteur est connue avant l'image, donc rien ne saute en fin de
 *     chargement — c'est ce qui permet de remonter le passé sans que la lecture se déplace ;
 *   — les étapes d'un tour vivent dans un `<details>` replié : présentes, jamais encombrantes.
 *     Son chapeau porte la dernière phrase vivante du tour, au-dessus de « N étapes · durée » ;
 *   — le drapeau « Signaler » n'a plus d'opacité : à 0,5 il tombait à 2,1 : 1 de contraste.
 *     `--encre-2` sur `--fond` mesure 5,4 : 1, et 5,8 : 1 sur `--fond-2` — au-dessus des 3 : 1
 *     exigés d'un élément d'interface, et la recette le vérifie dans le navigateur.
 */

/* ── La colonne ─────────────────────────────────────────────────────────────────────── */

.fil {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--e2);
  padding: var(--e2) var(--e2) var(--e3);
  color: var(--encre);
  font-size: var(--texte);
  line-height: 1.45;
}
.fil-sentinelle { flex: 0 0 auto; height: 1px; }

/* ── Les bulles ─────────────────────────────────────────────────────────────────────── */

.fil-bulle {
  max-width: 86%;
  padding: var(--e1) 12px;
  border-radius: var(--rayon);
  font-size: var(--texte);
  overflow-wrap: anywhere;
}
.fil-moi { align-self: flex-end; background: var(--bulle-moi); border-bottom-right-radius: 4px; }
.fil-lui { align-self: flex-start; background: var(--bulle-lui); box-shadow: var(--anneau); border-bottom-left-radius: 4px; }
.fil-bulle p { margin: 0 0 6px; }
.fil-bulle p:last-child { margin-bottom: 0; }
.fil-liste { margin: 0 0 6px; padding-left: 20px; }
.fil-liste:last-child { margin-bottom: 0; }
.fil-liste li { margin: 2px 0; }

.fil-mention { margin: 6px 0 0; color: var(--encre-2); font-size: 13px; }

/* Un accent grave du modèle ne s'affiche pas tel quel : il devient un code sobre. */
.fil-code { padding: 1px 5px; border-radius: 6px; background: var(--fond); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.92em; }

/* Un envoi en cours s'efface un peu ; en échec, il le dit et propose de renvoyer. */
.fil-bulle[data-etat='envoi'] { opacity: 0.7; }
.fil-appoint { display: flex; align-items: center; gap: var(--e1); margin-top: 4px; font-size: 13px; }
.fil-appoint-mot { color: var(--alerte); }
.fil-reessayer {
  min-height: var(--cible);
  padding: 0 var(--e1);
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* ── Une ligne du studio : rushs reçus, arrêt constaté ───────────────────────────────── */

.fil-systeme {
  align-self: center;
  max-width: 86%;
  margin: 0;
  color: var(--encre-2);
  font-size: 13px;
  text-align: center;
}

/* ── L'heure, et ce qu'on a manqué ───────────────────────────────────────────────────── */

/* Plus de cinq minutes entre deux messages : l'heure se pose entre eux, lisible sans survol. */
.fil-heure {
  align-self: center;
  margin: 0;
  color: var(--encre-2);
  font-size: 13px;
  letter-spacing: 0.04em;
}
/* Le trait du retour : ce qui s'est dit pendant qu'on regardait ailleurs commence ici. */
.fil-repere {
  align-self: stretch;
  margin: 0;
  padding: 2px 0;
  border-top: 1px solid var(--accent);
  color: var(--accent);
  font-size: 13px;
  text-align: center;
}

/* ── Le plan annoncé : voir « Travail en cours » à la fin du fichier ─────────────────── */

/* ── Le retour annoté ───────────────────────────────────────────────────────────────── */

.fil-retour .fil-vignettes { display: flex; flex-wrap: wrap; gap: var(--e1); margin-top: var(--e1); }
/* Taille fixe : la vignette occupe sa place avant d'être chargée, le fil ne saute pas. */
.fil-note { width: 88px; height: 50px; border-radius: 8px; box-shadow: var(--anneau); object-fit: cover; background: var(--fond); }

/* ── La carte de livraison ──────────────────────────────────────────────────────────── */

.fil-livraison {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  padding: var(--e1);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  box-shadow: var(--ombre);
}
.fil-livraison-mot { font-size: var(--texte); }
.fil-livraison-mot p { margin: 0 0 6px; }
.fil-livraison-mot p:last-child { margin-bottom: 0; }

.fil-vignette {
  width: 100%;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 10px;
  background: var(--encre);
  color: var(--accent-2);
  cursor: pointer;
}
/* Une vidéo verticale garde sa forme sans manger l'écran : elle se pose au centre de la carte. */
.fil-vignette[data-ratio='9-16'] { aspect-ratio: 9 / 16; width: 56%; max-width: 210px; align-self: center; }
.fil-vignette img { width: 100%; height: 100%; object-fit: cover; }
.fil-picto { width: 72px; max-width: 45%; height: auto; }
.fil-picto rect { fill: none; stroke: currentColor; stroke-width: 2; }
.fil-picto-lecture { fill: currentColor; stroke: none; }

/* Sur un écran large, une vignette pleine largeur ferait une affiche : la carte garde sa mesure. */
@media (min-width: 700px) {
  .fil-vignette[data-ratio='16-9'] { max-width: 420px; align-self: flex-start; }
}

.fil-livraison-corps { display: flex; flex-direction: column; gap: 4px; }
.fil-livraison-titre { margin: 0; font-size: 17px; line-height: 1.25; }
.fil-livraison-infos { margin: 0; color: var(--encre-2); font-size: 14px; }
.fil-livraison-resume { margin: 0; font-size: 14px; }
.fil-livraison-revue { margin: 0; color: var(--encre-2); font-size: 13px; }
.fil-livraison-revue[data-verdict='refaire'] { color: var(--alerte); }

/* La nature du rendu et ses étiquettes. Un master n'a pas de badge : il est la règle, et une
 * pastille sur chaque carte ne distinguerait plus rien. Les étiquettes restent grises : ce
 * sont des repères de rangement, pas un état. */
.fil-etiquettes { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 2px 0; }
.fil-categorie {
  padding: 2px 9px;
  border: 0;
  border-radius: 999px;
  background: var(--accent-2);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.fil-categorie[data-categorie='test'] { background: var(--doux); color: var(--encre-2); font-weight: 500; }
.fil-tag {
  padding: 2px 8px;
  border: 0;
  border-radius: 999px;
  background: var(--doux);
  color: var(--encre-2);
  font-size: 12px;
  white-space: nowrap;
}
/* D'où vient la vidéo quand ce n'est pas l'assistant du fil qui l'a posée. */
.fil-provenance { margin: 0; color: var(--encre-2); font-size: 13px; }

/* Ce qui a changé se lit une fois : replié, il ne double pas la hauteur de la carte. */
.fil-changements { margin: 2px 0 0; font-size: 14px; }
.fil-changements-chapeau {
  display: flex;
  align-items: center;
  min-height: var(--cible);
  color: var(--accent);
  list-style: none;
  cursor: pointer;
}
.fil-changements-chapeau::-webkit-details-marker { display: none; }
.fil-changements-chapeau::before { content: '›'; display: inline-block; margin-right: 6px; font-size: 18px; line-height: 1; transition: transform 0.15s ease; }
.fil-changements[open] > .fil-changements-chapeau::before { transform: rotate(90deg); }
.fil-changements-liste { margin: 0 0 4px; padding-left: 20px; }
.fil-changements-liste li { margin: 2px 0; }
/* Ce qu'il n'a pas obtenu : la ligne qui ne se dit nulle part ailleurs. */
.fil-nonfait { margin: 0; color: var(--alerte); font-size: 14px; }

.fil-livraison-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e1); margin-top: 4px; }
.fil-regarder {
  min-height: var(--cible);
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--fond-2);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
/* « Modifier » : montrer l'endroit sur l'image, en un geste au lieu de huit. Commande
 * secondaire de la même famille que « Regarder » : son fond est l'accent en clair. */
.fil-modifier {
  min-height: var(--cible);
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--accent-2);
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.fil-telecharger {
  display: inline-flex;
  align-items: center;
  min-height: var(--cible);
  padding: 0 var(--e1);
  color: var(--encre-2);
  font-size: 14px;
}

.fil-souci { margin: 0; padding: var(--e1); border-radius: var(--rayon); background: var(--fond-2); color: var(--alerte); font-size: 14px; }
.fil-souci[hidden] { display: none; }

/* ── Signaler un problème ───────────────────────────────────────────────────────────── */

/* Un drapeau sous la livraison : sous chaque bulle, il occupait 13 % du fil. Il porte son mot — « ⚑ Un problème ? » — parce qu'une icône
 * seule ne se lit pas, et il n'a plus d'opacité : à 0,5 son contraste tombait à 2,1 : 1.
 * Le formulaire n'apparaît qu'une fois ouvert, et jamais dans une région vive. */
.fil-signal { align-self: stretch; display: block; }
.fil-signal[hidden] { display: none; }
.fil-signaler {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: var(--cible);
  min-height: var(--cible);
  padding: 0;
  border: 0;
  background: none;
  color: var(--encre-2);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.fil-signaler-mot { padding: 0 var(--e1); }
.fil-signaler:hover, .fil-signaler:focus-visible { color: var(--encre); text-decoration: underline; text-underline-offset: 3px; }
.fil-signaler svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.fil-signal-champ { display: block; }
.fil-signal-mot { display: block; margin-bottom: 4px; color: var(--encre-2); font-size: 13px; }
.fil-signal-texte {
  display: block;
  width: 100%;
  padding: var(--e1);
  border: 0;
  border-radius: 10px;
  background: var(--doux);
  color: var(--encre);
  font: inherit;
  font-size: 15px;
  resize: vertical;
}
.fil-signal-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e1); margin-top: 4px; }
.fil-signal-envoyer {
  min-height: var(--cible);
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--accent-2);
  color: var(--accent);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.fil-signal-envoyer[disabled] { opacity: 0.6; cursor: default; }
.fil-signal-annuler {
  min-height: var(--cible);
  padding: 0 var(--e1);
  border: 0;
  background: none;
  color: var(--encre-2);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.fil-signal-erreur { color: var(--alerte); font-size: 13px; }
.fil-signal-merci { margin: 0; color: var(--encre-2); font-size: 13px; }

/* ── « Nouveau message ↓ » : au-dessus du pied, jamais à la place du contenu ─────────── */

.fil-nouveau {
  position: fixed;
  left: 50%;
  bottom: calc(var(--pied, 0px) + var(--e2));
  z-index: 5;
  transform: translateX(-50%);
  min-height: var(--cible);
  max-width: calc(100% - 2 * var(--e2));
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--fond-2);
  color: var(--encre);
  font: inherit;
  font-size: 14px;
  box-shadow: var(--anneau), 0 2px 10px rgba(23, 33, 43, 0.14);
  cursor: pointer;
}
.fil-nouveau[hidden] { display: none; }

/* ── L'avis d'une revue, sous la carte vidéo (EF-01 c) ───────────────────────────────── */

.fil-livraison-avis { display: flex; flex-direction: column; gap: 2px; }
.fil-livraison-remarques { margin: 0; padding-left: 18px; color: var(--encre-2); font-size: 13px; }
.fil-livraison-remarques li { margin: 2px 0; }

/* ── L'aperçu en direct (F2) : une carte du fil comme les autres (mêmes jetons que
   .fil-livraison), un en-tête qui dit qu'elle est vivante, une scène 9:16 plafonnée en hauteur
   pour ne pas flotter seule sur un grand écran. ─────────────────────────────────────────── */

.apercu-carte {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  padding: var(--e1);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  box-shadow: var(--ombre);
}
.apercu-entete { display: flex; align-items: center; gap: var(--e1); }
.apercu-entete-texte { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.apercu-titre { margin: 0; font-size: var(--texte); font-weight: 600; color: var(--encre); }
.apercu-sous-titre { margin: 0; font-size: 13px; color: var(--encre-2); min-height: 16px; }
/* La pastille « en direct » : neutre en chargement, iris et animée en direct, éteinte à l'arrêt —
   le seul accent du studio, jamais une couleur inventée. */
.apercu-direct { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--trait); }
.apercu-direct[data-etat='direct'] { background: var(--accent); animation: apercu-pulser 2.4s ease-in-out infinite; }
.apercu-direct[data-etat='direct'].apercu-direct--pulse { animation: apercu-pulser-fort .5s ease-out; }
@keyframes apercu-pulser { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(.8); } }
@keyframes apercu-pulser-fort { 0% { opacity: 1; transform: scale(1); } 40% { opacity: .5; transform: scale(1.9); } 100% { opacity: 1; transform: scale(1); } }

/* Hauteur plafonnée dès le premier rendu (chargement, en direct ou arrêtée) : rien ne saute
   (CLS 0), et sur un grand écran l'aperçu ne s'étire pas en portrait géant. */
.apercu-scene {
  position: relative;
  height: min(70vh, 640px);
  max-width: 100%;
  aspect-ratio: 9 / 16;
  margin: 0 auto;
  overflow: hidden;
  border-radius: 10px;
  background: var(--doux);
}
.apercu-cadre { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; opacity: 0; transition: opacity 0.18s ease; }
.apercu-cadre--pret { opacity: 1; }

/* Chargement : un squelette neutre et un reflet qui glisse (transform seul). */
.apercu-squelette {
  position: absolute; inset: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center; padding: var(--e1); text-align: center;
}
.apercu-reflet {
  position: absolute; inset: 0; width: 55%;
  background: linear-gradient(90deg, transparent, var(--fond-2), transparent);
  transform: translateX(-140%);
  animation: apercu-glisse 1.6s ease-in-out infinite;
}
@keyframes apercu-glisse { to { transform: translateX(240%); } }
.apercu-texte { position: relative; margin: 0; font-size: var(--texte); color: var(--encre-2); }

/* Arrêtée : une icône, un titre, une phrase d'aide — jamais un mot technique. */
.apercu-arret {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: var(--e2); text-align: center; color: var(--encre-2);
}
.apercu-icone { width: 40px; height: auto; color: var(--encre-2); }
.apercu-arret-titre { margin: 0; font-size: var(--texte); font-weight: 600; color: var(--encre); }
.apercu-arret-aide { margin: 0; font-size: 13px; color: var(--encre-2); }

/* ── Mouvement réduit : rien ne bouge, tout reste lisible ────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .apercu-cadre { transition: none; }
  .apercu-direct[data-etat='direct'] { animation: none; }
  .apercu-direct[data-etat='direct'].apercu-direct--pulse { animation: none; opacity: .75; }
  .apercu-reflet { animation: none; opacity: .4; }
}

/* ── EF-10 : l'estimation avant de louer une machine, le coût réel après ─────────────── */

/* Une ligne discrète, comme .fil-systeme, mais avec sa pièce et sa forme en pilule : le montant
 * est annoncé, jamais mis en avant comme le reste de la conversation. */
.fil-estimation {
  display: flex;
  align-items: center;
  gap: 8px;
  align-self: center;
  max-width: 86%;
  margin: 0;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--fond-2);
  color: var(--encre-2);
  font-size: 13px;
}
.fil-estimation-picto { width: 16px; height: 16px; flex: none; }
.fil-estimation-picto circle { fill: none; stroke: currentColor; stroke-width: 1.6; }
.fil-estimation-mot { overflow-wrap: anywhere; }

/* Le coût réel d'une vidéo livrée, sous la vignette : une ligne de plus parmi les autres
 * mentions discrètes de la carte (même forme que .fil-provenance). */
.fil-livraison-cout { margin: 0; color: var(--encre-2); font-size: 13px; }

/* ── EF-12 : le lecteur déplié dans la carte, au lieu d'un écran vidéo à part ────────────
 *
 * Le même `<dialog id="video">` que le mode plein écran (`video.js`, COQUE.md §2.7) est
 * déplacé ici par `fil/lecteur.js` et ouvert avec `.show()` : ces règles annulent sa position
 * fixe et son fond assombri pour le poser dans le flux normal de la carte. Spécificité plus
 * grande que `dialog.video` de `video.css` (deux classes contre une) : elle gagne quel que
 * soit l'ordre des feuilles de style, sans `!important`.
 *
 * La hauteur se déplie par `grid-template-rows: 0fr → 1fr` (jamais `height`) : une seule
 * propriété animée, un seul repaint par image, pas de `max-height` à deviner. */
.fil-lecteur {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 280ms ease;
}
.fil-lecteur-ouvert { grid-template-rows: 1fr; }
.fil-lecteur-boite { overflow: hidden; min-height: 0; }

.fil-lecteur dialog.video {
  position: static;
  inset: auto;
  width: 100%;
  max-width: none;
  height: min(64vh, 560px);
  max-height: none;
  margin: var(--e1) 0 0;
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
}
/* `.show()` (non modal) n'en pose pas, mais rien n'empêche qu'on referme la porte. */
.fil-lecteur dialog.video::backdrop { display: none; }

/* « Fermer » est la sortie principale d'une carte dépliée — pas un bouton neutre parmi
 * d'autres comme dans le dialogue plein écran, où `--doux` se détachait déjà mal du blanc de
 * `.video-tete`. Même recette que « Modifier » juste au-dessus (interrupteur pressé,
 * COQUE.md §2.3) : lisible, reconnaissable, jamais confondu avec les commandes discrètes. */
.fil-lecteur .video-retour { background: var(--accent-2); color: var(--accent); font-weight: 600; }

@media (min-width: 700px) {
  /* « largeur de lecture confortable » : la carte peut faire 760 px (COQUE.md §2.2), le
   * lecteur reste sous cette largeur plutôt que de s'étirer bord à bord. */
  .fil-lecteur dialog.video { max-width: 640px; margin: var(--e1) auto 0; height: min(70vh, 680px); }
}

@media (min-width: 900px) {
  /* `video.css` bascule à deux colonnes (image + panneau de 360 px) dès 900 px de VIEWPORT —
   * une largeur que pense au plein écran, pas à cette carte plafonnée à 640 px : au-delà, le
   * panneau ne laissait plus que ~280 px à l'image. Le lecteur inline reste à une colonne,
   * quelle que soit la taille de l'écran ; seule la largeur de la carte compte ici. */
  .fil-lecteur .video-cadre { display: flex; flex-direction: column; }
  .fil-lecteur .video-bas {
    grid-column: auto;
    max-height: 45%;
    height: auto;
    box-shadow: 0 -1px 2px rgba(23, 33, 43, .06);
    border-radius: 0 0 var(--rayon) var(--rayon);
    padding: var(--e1);
    gap: var(--e1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .fil-lecteur { transition: none; }
}
