/* La coque : le squelette que toutes les vues habitent.
 *
 * Trois règles tiennent ce fichier, et elles viennent de COQUE.md §0 et §2.2 :
 *   1. Le téléphone d'abord. Tout est écrit pour 360-430 px ; ce qui suit à 900 px n'est
 *      qu'un élargissement (le menu devient une barre, le contenu se centre à 760 px).
 *   2. Une seule surface de défilement par vue. Le document, lui, ne défile jamais :
 *      `body` tient la hauteur de la fenêtre, chaque vue est posée entre l'en-tête et le
 *      pied et défile seule. C'est ce qui garde le champ de saisie sous le pouce.
 *   3. Aucun style en ligne (CSP `style-src 'self'`) : tout passe par une classe ou par
 *      une variable posée en CSSOM (`el.style.setProperty`), jamais par un attribut.
 *
 * Les jetons de §2.3 sont posés sur `:root` et sont les seules couleurs et espacements que
 * les autres modules emploient. `--pied` est écrit par `saisie.js` (hauteur réelle du pied) ;
 * `--decalage` est écrit par `coque.js` (largeur de la barre latérale quand elle est ouverte).
 *
 * Une grammaire visuelle, une seule (le reproche du 15 septembre : « des fois il y a des
 * bordures »). Aucun trait gris de 1 px dans le studio :
 *   — une SURFACE (carte, panneau, tiroir, pied) est blanche et posée par une ombre (`--ombre`,
 *     dont le premier terme est un anneau de 6 % qui la détache de l'ivoire) ;
 *   — une COMMANDE se dit par son fond : plein accent pour la principale, `--doux` pour la
 *     secondaire, rien du tout pour la discrète ; un interrupteur pressé prend `--accent-2` ;
 *   — un CHAMP est un creux neutre sans trait, et son focus est un anneau iris ;
 *   — une PASTILLE est un fond doux sans trait ;
 *   — seuls gardent un trait ceux qui disent quelque chose : la barre de 3 px d'une question,
 *     le pointillé d'une zone de dépôt, l'heure du fil.
 *
 * Classes utilitaires offertes aux autres modules :
 *   .bouton          un bouton lisible, 44 px de cible minimum, fond neutre doux
 *   .bouton-plein    le bouton d'action principale (fond accent)
 *   .bouton-discret  une action secondaire : pas de fond, texte accent
 *   .carte           un bloc blanc arrondi, posé par son ombre, qui porte une information
 *   .pastille        une puce d'état, courte, lisible sans couleur
 *   .badge           un compteur rond (messages non lus)
 *   .liste           une colonne de cartes régulièrement espacée
 *   .ligne           une rangée qui passe à la ligne quand la place manque
 *   .muted           un texte secondaire (gris, un cran plus petit)
 */

:root {
  /* §2.3 — les jetons du studio. */
  --fond: #f7f8f5;
  --fond-2: #ffffff;
  --encre: #17212b;
  --encre-2: #5b6774;
  --trait: #e1e6dc;
  --accent: #1f6b4f;
  --accent-2: #c4f594;
  --alerte: #b3261e;
  --bulle-moi: #e3f2e6;
  --bulle-lui: #ffffff;
  --rayon: 14px;
  --e1: 8px;
  --e2: 16px;
  --e3: 24px;
  --texte: 16px;
  --cible: 44px;
  --tete: 56px;
  --pied: 0px;             /* posé par saisie.js selon la hauteur réelle du pied */

  /* La grammaire visuelle, en quatre jetons. `studio.css` les reteinte sans les renommer :
   * un module n'a donc jamais à choisir une couleur de trait ni une ombre lui-même. */
  --doux: #eef0ea;         /* le fond d'une commande secondaire, d'une pastille, d'une étiquette */
  --doux-2: #e4e8df;       /* son survol */
  --anneau: 0 0 0 1px rgba(23, 33, 43, .06);            /* le seul contour d'un bloc blanc */
  --ombre: var(--anneau), 0 4px 16px rgba(23, 33, 43, .05);

  /* Ce que la coque ajoute pour sa mise en page. */
  --barre: 260px;          /* la barre latérale, à partir de 900 px */
  --lisible: 760px;        /* la largeur de lecture confortable */
  --decalage: 0px;         /* posé par coque.js quand la barre est ouverte */
  --haut: calc(var(--tete) + env(safe-area-inset-top, 0px));
  --bas: env(safe-area-inset-bottom, 0px);
}

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

html { height: 100%; }

body {
  margin: 0;
  height: 100dvh;
  /* Le document ne défile pas : ce sont les vues qui défilent, chacune pour elle-même. */
  overflow: hidden;
  background: var(--fond);
  color: var(--encre);
  font: var(--texte)/1.5 system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  overflow-wrap: break-word;
  -webkit-text-size-adjust: 100%;
}

/* `.vue` et `#menu` posent un `display` : sans ce rappel, `hidden` ne cacherait plus rien. */
[hidden] { display: none !important; }

img, svg, video, canvas { max-width: 100%; }
button, input, textarea, select { font: inherit; color: inherit; }
a { color: var(--accent); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Tout ce que `#app` contient est fixé à la fenêtre : sans boîte à lui, il serait haut de
 * zéro pixel — invisible pour un lecteur d'écran comme pour un test. Il prend donc l'écran. */
#app { position: fixed; inset: 0; }

/* ---- L'en-tête, fixe, au-dessus de tout ---------------------------------------------- */

.coque-tete {
  position: absolute;
  top: 0;
  left: var(--decalage);
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--e1);
  height: var(--haut);
  padding: env(safe-area-inset-top, 0px) var(--e1) 0;
  background: var(--fond-2);
  box-shadow: 0 1px 2px rgba(23, 33, 43, .05);
}

/* Le nom de la vidéo, et sous lui ce qui la situe : son projet, son modèle vidéo. Deux
 * lignes qui tiennent dans la hauteur de l'en-tête, jamais un bloc qui pousse la page. */
.coque-titres { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; }

#titre {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.coque-contexte {
  margin: 0;
  color: var(--encre-2);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tete-bouton {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--cible);
  height: var(--cible);
  padding: 0;
  border: 0;
  border-radius: var(--rayon);
  background: none;
  color: var(--encre);
  cursor: pointer;
}
.tete-bouton:hover { background: var(--fond); }
.tete-bouton svg { width: 24px; height: 24px; }

/* « Hors ligne » : discret, mais toujours lisible sans couleur. La couleur d'alerte est
 * dans le texte ; le fond reste celui de toutes les autres pastilles. */
.pastille-hors {
  flex: none;
  color: var(--alerte);
}

/* ---- La machine (machine.js, EF-09) ----------------------------------------------------- */

/* La pastille de l'en-tête : un fond doux comme toutes les pastilles (§0), un point qui
 * respire pour dire qu'une machine tourne sans le crier. `prefers-reduced-motion` l'arrête
 * (règle générale, en bas de ce fichier). */
.pastille-machine {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--cible);
  border: 0;
  cursor: pointer;
}
.pastille-machine-point {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: machine-respire 2.4s ease-in-out infinite;
}
@keyframes machine-respire {
  0%, 100% { opacity: .45; transform: scale(.85); }
  50% { opacity: 1; transform: scale(1); }
}

/* Le panneau : feuille du bas sur téléphone, panneau à droite à partir de 900 px (§2.2). */
dialog.machine {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  width: 100%;
  max-width: none;
  max-height: min(70dvh, 520px);
  margin: 0;
  padding: var(--e2);
  padding-bottom: calc(var(--bas) + var(--e2));
  border: 0;
  border-radius: var(--rayon) var(--rayon) 0 0;
  background: var(--fond-2);
  color: var(--encre);
  font-size: var(--texte);
  box-shadow: var(--anneau), 0 -8px 24px rgba(23, 33, 43, .16);
  overflow-y: auto;
}
dialog.machine::backdrop { background: rgba(23, 33, 43, .4); }
@media (min-width: 900px) {
  dialog.machine {
    inset: 0 0 0 auto;
    width: min(360px, calc(100vw - 2 * var(--e1)));
    max-height: none;
    border-radius: 0;
  }
}
.machine-tete { display: flex; align-items: center; gap: var(--e1); margin-bottom: var(--e2); }
.machine-titre { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 600; }
.machine-corps { display: flex; flex-direction: column; gap: var(--e1); margin: 0 0 var(--e2); }
.machine-etat { margin: 0; font-weight: 600; }
.machine-ligne { margin: 0; color: var(--encre-2); font-size: 14px; }
.machine-actions, .machine-confirme { display: flex; flex-wrap: wrap; gap: var(--e1); }
.machine-question { flex: 1 1 200px; min-width: 0; margin: 0; font-size: 14px; }

/* ---- Le menu : tiroir sur téléphone, barre sur grand écran ----------------------------- */

#menu {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  width: min(280px, 84vw);
  padding: calc(env(safe-area-inset-top, 0px) + var(--e2)) var(--e2) calc(var(--bas) + var(--e2));
  overflow-y: auto;
  background: var(--fond-2);
  box-shadow: 1px 0 2px rgba(23, 33, 43, .05);
}
#menu:not([hidden]) { animation: coque-glisse .18s ease-out; }
@keyframes coque-glisse { from { transform: translateX(-100%); } }

.menu-lien {
  display: block;
  width: 100%;
  min-height: var(--cible);
  padding: var(--e1) var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: none;
  color: var(--encre);
  text-align: left;
  cursor: pointer;
}
.menu-lien:hover { background: var(--fond); }
.menu-lien[aria-current='page'] { background: var(--fond); font-weight: 600; }
/* « Compte » ferme le menu : il s'assoit en bas, et l'écart le détache — pas un filet gris. */
#menu > [data-aller='compte'] { margin-top: auto; }
.menu-lien-fort {
  margin-bottom: var(--e1);
  background: var(--accent);
  color: var(--fond-2);
  font-weight: 600;
  text-align: center;
}
.menu-lien-fort:hover { background: var(--encre); }
/* Ceinture et bretelles : `coque.js` ne pose plus `aria-current` sur une action, mais si un
 * jour il le reposait, le fond accent doit gagner — blanc sur blanc ne se lit pas (§6, 3). */
.menu-lien.menu-lien-fort[aria-current='page'] { background: var(--accent); color: var(--fond-2); }

/* Le fond assombri du tiroir : il ferme le menu au premier doigt posé à côté. */
.coque-voile {
  position: absolute;
  inset: 0;
  z-index: 40;
  border: 0;
  padding: 0;
  background: rgba(23, 33, 43, .45);
}

/* ---- Les vues -------------------------------------------------------------------------- */

.vue {
  position: absolute;
  top: var(--haut);
  left: var(--decalage);
  right: 0;
  bottom: 0;
  display: block;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding: var(--e2) var(--e2) calc(var(--bas) + var(--e3));
  -webkit-overflow-scrolling: touch;
}

/* La conversation s'arrête au-dessus du pied : c'est la hauteur que `saisie.js` annonce. */
#vue-conversation {
  bottom: var(--pied);
  padding: var(--e2) var(--e1) var(--e2);
}
/* Un fichier glissé sur la conversation : le pointillé dit où il tombera. */
#vue-conversation[data-depot='oui'] { outline: 2px dashed var(--accent); outline-offset: -6px; }

/* Le pied de saisie, fixé en bas, sous le pouce, et suivi par `saisie.js` au clavier. */
#saisie {
  position: absolute;
  left: var(--decalage);
  right: 0;
  bottom: 0;
  z-index: 20;
  padding-bottom: calc(var(--bas) + var(--e1));
  background: var(--fond-2);
  box-shadow: 0 -1px 2px rgba(23, 33, 43, .05);
}

/* « Nouveau message ↓ » flotte au-dessus du pied, au centre de la colonne de lecture. */
.fil-nouveau {
  position: fixed;
  left: calc(50% + var(--decalage) / 2);
  bottom: calc(var(--pied) + var(--e2));
  z-index: 25;
  transform: translateX(-50%);
}

/* Le mot de la coque : une seule ligne, au-dessus du pied, effacée d'elle-même. */
#status {
  position: absolute;
  left: calc(50% + var(--decalage) / 2);
  bottom: calc(var(--pied) + var(--e3));
  z-index: 60;
  transform: translateX(-50%);
  max-width: min(92vw, 520px);
  margin: 0;
  padding: var(--e1) var(--e2);
  border-radius: var(--rayon);
  background: var(--encre);
  color: var(--fond-2);
  font-size: 15px;
  text-align: center;
}
#status:empty { display: none; }

/* ---- Les classes utilitaires ----------------------------------------------------------- */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e1);
  min-height: var(--cible);
  min-width: var(--cible);
  padding: var(--e1) var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: var(--doux);
  color: var(--encre);
  text-decoration: none;
  cursor: pointer;
}
.bouton:hover { background: var(--doux-2); }
.bouton[disabled] { opacity: .5; cursor: default; }
.bouton-plein {
  background: var(--accent);
  color: var(--fond-2);
  font-weight: 600;
}
.bouton-plein:hover { background: var(--encre); }
.bouton-discret {
  background: none;
  color: var(--accent);
}
.bouton-discret:hover { background: var(--accent-2); }
/* Révoquer, Forcer l'arrêt, Fermer l'atelier : la couleur est dans le mot, pas dans un cadre. */
.bouton-alerte { color: var(--alerte); font-weight: 600; }

.carte {
  display: block;
  width: 100%;
  padding: var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  color: var(--encre);
  text-align: left;
  box-shadow: var(--ombre);
}

.pastille {
  display: inline-block;
  max-width: 100%;
  padding: 2px var(--e1);
  border: 0;
  border-radius: 999px;
  background: var(--doux);
  color: var(--encre-2);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pastille-active { background: var(--accent-2); color: var(--accent); font-weight: 600; }

.badge {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--fond-2);
  font-size: 13px;
  font-weight: 600;
}

.liste { display: flex; flex-direction: column; gap: var(--e2); margin: 0; padding: 0; list-style: none; }
/* Une carte qui est aussi une liste (jetons, revues, vidéos) garde sa marge : `.liste` la lui
 * retirait, et ses boutons venaient toucher ses bords. */
.carte.liste { padding: var(--e2); }
.ligne { display: flex; align-items: center; flex-wrap: wrap; gap: var(--e1); }
/* `overflow-wrap` seul (pas de coupe) : une adresse ou un mot sans espace ne pousse jamais la
 * page en large, sans rien cacher — le filet de sécurité de tout texte libre du studio (EF-11). */
.muted { color: var(--encre-2); font-size: 14px; overflow-wrap: anywhere; }

/* ---- Ce que la coque dessine dans ses propres vues -------------------------------------- */

/* Dans une page comme dans une carte, c'est l'écart du conteneur qui espace : les marges
 * par défaut des titres et des paragraphes s'y ajouteraient deux fois. */
.page { display: flex; flex-direction: column; gap: var(--e2); }
.page > h2 { font-size: 20px; }
.page > h3 { font-size: 17px; }
.page > h2, .page > h3, .page > p, .carte > * { margin: 0; }

/* La carte d'une vidéo : son aperçu, son nom, ce qui l'attend. Un seul bouton, et tout ce
 * qui compte dedans. Sur téléphone l'aperçu passe au-dessus : à 390 px, le texte à côté
 * n'aurait plus de place — mais la zone garde sa forme, la carte ne saute jamais. */
/* `minmax(0, 1fr)`, même sous 560 px (une seule colonne implicite) : une colonne `auto` se
 * dimensionne sur son contenu et peut dépasser la carte quand un nom ou un dernier message est
 * trop long (EF-11) — `minmax(0, 1fr)` la force à tenir dans la largeur réelle du bouton. */
.conv { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e1); cursor: pointer; }
.conv:hover { box-shadow: var(--anneau), 0 6px 18px rgba(23, 33, 43, .10); }
.conv-corps { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; min-width: 0; }
.conv-art { width: 100%; }
@media (min-width: 560px) {
  .conv { grid-template-columns: 148px minmax(0, 1fr); align-items: start; }
}
.conv-tete { display: flex; align-items: baseline; gap: var(--e1); }
.conv-nom { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-quand { flex: none; }
.conv-mot {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.vide { color: var(--encre-2); }

/* La carte d'une vidéo livrée, dans la vue Vidéos : un titre écrit par l'assistant (ou un nom
 * de projet recopié) n'a ni longueur ni ponctuation garanties — deux lignes au plus, ellipsées,
 * et `overflow-wrap` casse même un mot sans espace (EF-11). */
.livree-titre {
  margin: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  font-size: 16px;
}
.livree-infos { margin: 0; }
/* Une description ou un résumé libres (résumé de livraison, description de projet) : même
 * traitement que le titre, sur la classe `.muted` qui les porte déjà. */
.descr-clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* Le tiroir des versions précédentes, des jetons, des dépenses. */
details.repli { border: 0; border-radius: var(--rayon); background: var(--fond-2); box-shadow: var(--ombre); }
details.repli > summary {
  display: flex;
  align-items: center;
  min-height: var(--cible);
  padding: var(--e1) var(--e2);
  cursor: pointer;
  font-weight: 600;
}
details.repli > .repli-corps { display: flex; flex-direction: column; gap: var(--e2); padding: 0 var(--e2) var(--e2); }

/* Le petit menu de la conversation : renommer, fichiers, vidéos. */
.panneau {
  position: absolute;
  top: calc(var(--haut) + 4px);
  right: var(--e1);
  z-index: 45;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  width: min(320px, calc(100vw - 2 * var(--e1)));
  max-height: calc(100dvh - var(--haut) - var(--e3));
  overflow-y: auto;
  padding: var(--e1);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  box-shadow: var(--anneau), 0 8px 24px rgba(23, 33, 43, .16);
}
/* Renommer : un creux neutre dans le panneau blanc, comme tous les champs du studio. */
.panneau input[type='text'] {
  width: 100%;
  min-height: var(--cible);
  padding: var(--e1) var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: var(--doux);
}

/* Un rush : son nom, son état. Prêt, il s'ouvre dans le dialogue vidéo. */
.rush { display: flex; align-items: center; gap: var(--e1); width: 100%; text-align: left; }
.rush-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Le jeton MCP, montré une seule fois : on le lit, on le copie, il disparaît. */
.jeton-clair { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; word-break: break-all; }
.jeton-config { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; white-space: pre-wrap; word-break: break-all; }

/* ---- L'écran de connexion --------------------------------------------------------------- */

#login {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  overflow-y: auto;
  padding: var(--e2);
  background: var(--fond);
}
.login-carte {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  width: min(420px, 100%);
  padding: var(--e3);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  box-shadow: var(--ombre);
  text-align: center;
}
.login-carte h1 { margin: 0; font-size: 24px; }
.login-carte p { margin: 0; color: var(--encre-2); }
.login-sur-titre { color: var(--accent); font-size: 13px; font-weight: 600; letter-spacing: .12em; }
.login-google { justify-content: center; font-weight: 600; }
.login-marque { flex: none; }
.login-proprietaire { font-size: 14px; }
#login-status:empty { display: none; }

/* ---- Grand écran : la barre latérale et la colonne de lecture ---------------------------- */

@media (min-width: 900px) {
  /* La barre ouverte décale tout ce qui est fixé : l'en-tête, les vues, le pied, le mot. */
  body[data-barre='oui'] { --decalage: var(--barre); }
  /* La barre ne glisse pas : elle est là. Même sélecteur que le tiroir, sinon il l'emporte. */
  #menu, #menu:not([hidden]) {
    width: var(--barre);
    animation: none;
  }
  /* Le contenu se centre à 760 px : c'est la largeur où une phrase se lit d'un trait. */
  .vue > *, #fil { max-width: var(--lisible); margin-inline: auto; }
  .vue { padding: var(--e3) var(--e3) calc(var(--bas) + var(--e3)); }
  #vue-conversation { padding: var(--e3) var(--e2) var(--e2); }
  #saisie > * { max-width: var(--lisible); margin-inline: auto; }
  /* Le panneau s'aligne sur le bord droit de la colonne de lecture, pas sur celui de l'écran. */
  .panneau { right: max(var(--e1), calc((100vw - var(--decalage) - var(--lisible)) / 2)); }
}

/* ---- Mouvement : seulement si la personne en veut ---------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- Les rendus livrés : nature, étiquettes, provenance, et le dernier en tête ----------- */

/* Trois mots pour ranger ce qu'un projet accumule — master, aperçu, essai (RETOUR.md §0 c).
 * Un master ne porte 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, pas un état. */
.livree-etiquettes { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.livree-badge {
  display: inline-block;
  padding: 2px 9px;
  border: 0;
  border-radius: 999px;
  background: var(--accent-2);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.livree-badge[data-categorie='test'] { background: var(--doux); color: var(--encre-2); font-weight: 500; }
.livree-tag {
  display: inline-block;
  padding: 2px 8px;
  border: 0;
  border-radius: 999px;
  background: var(--doux);
  color: var(--encre-2);
  font-size: 12px;
  white-space: nowrap;
}
.livree-provenance { margin: 0; color: var(--encre-2); font-size: 13px; }

/* La rangée de filtres de la vue Vidéos : quatre boutons pleins, pas des onglets — on peut
 * les atteindre au doigt comme au clavier, et celui qui tient dit `aria-pressed`. */
.livree-filtres { display: flex; flex-wrap: wrap; gap: var(--e1); }
.livree-filtre {
  min-height: var(--cible);
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--doux);
  color: var(--encre);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.livree-filtre:hover { background: var(--doux-2); }
/* Un interrupteur qui tient : fond accent-2, texte accent, gras. C'est la forme de tous les
 * interrupteurs du studio — filtres des vidéos, onglets des Styles, outils du lecteur. */
.livree-filtre[aria-pressed='true'] { background: var(--accent-2); color: var(--accent); font-weight: 600; }

/* « Dernier rendu » : la vidéo la plus récente, posée là où le regard tombe en arrivant. */
.livree-dernier {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--e1) var(--e2);
  align-items: start;
  padding: var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  box-shadow: var(--ombre);
}
.livree-dernier-chapeau { grid-column: 1 / -1; margin: 0; font-size: 13px; font-weight: 600; color: var(--encre-2); }
.livree-dernier-vignette {
  width: 124px;
  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;
}
.livree-dernier-vignette img { width: 100%; height: 100%; object-fit: cover; }
.livree-picto { width: 56px; max-width: 50%; height: auto; }
.livree-picto rect { fill: none; stroke: currentColor; stroke-width: 2; }
.livree-picto-lecture { fill: currentColor; stroke: none; }
.livree-dernier-corps { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.livree-dernier-corps > h4 { margin: 0; font-size: 16px; }
.livree-dernier-corps > p { margin: 0; }

/* ---- Les projets : les pilules et le tiroir de rangement (§2.10, §2.11) ------------------ */

/* Un « projet » ici, c'est ce qui range les vidéos : une chaîne, un client, une série. La
 * rangée de pilules filtre la liste ; celle qui tient prend la forme de tous les
 * interrupteurs du studio — fond `--accent-2`, texte accent, gras — et aucune ne porte de
 * trait : c'est le fond qui les dit. */
.projets-chips { display: flex; flex-wrap: wrap; gap: var(--e1); }
/* Le nom d'un projet est libre (EF-11) : sans ça, un nom trop long ou sans espace débordait de
 * son propre bouton, invisiblement coupé par le `overflow-x: hidden` de la vue plutôt que
 * proprement ellipsé — la même leçon que `.pastille` un peu plus haut. `min()` l'empêche aussi
 * de prendre toute la rangée à lui seul quand il est le seul mot long. */
.projets-chip {
  min-height: var(--cible);
  max-width: min(260px, 100%);
  padding: 0 var(--e2);
  border: 0;
  border-radius: 999px;
  background: var(--doux);
  color: var(--encre);
  font: inherit;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}
.projets-chip:hover { background: var(--doux-2); }
.projets-chip[aria-pressed='true'] { background: var(--accent-2); color: var(--accent); font-weight: 600; }

/* La carte d'un projet : une surface blanche posée par son ombre, comme toutes les autres. */
.projet-carte > h3 { margin: 0; }
.projet-style { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }

/* Ce que l'assistant a retenu : une ligne par souvenir, sa date et de quoi l'oublier. */
.projet-souvenir { display: flex; flex-direction: column; gap: 6px; }
.projet-souvenir > p { margin: 0; }

/* Le formulaire d'un nouveau projet, et celui qui modifie une carte en place. */
.projet-nouveau, .projet-form { display: flex; flex-direction: column; gap: var(--e1); }
.projet-nouveau > h3, .projet-form-titre { margin: 0; font-size: 17px; font-weight: 600; }
.projet-nouveau label { font-size: 14px; color: var(--encre-2); }

/* Une question posée dans le bouton lui-même (« Confirmer ») : la couleur d'alerte suffit,
 * un cadre rouge de plus ne dirait rien que le mot ne dise déjà. */
.confirme { color: var(--alerte); font-weight: 600; }

/* ---- Ranger la vidéo depuis le petit menu ----------------------------------------------- */

.panneau-titre { margin: var(--e1) var(--e1) 0; color: var(--encre-2); font-size: 14px; }
.panneau-radios { display: flex; flex-direction: column; gap: 2px; }
/* Un choix est une commande discrète tant qu'il n'est pas pris ; pris, il prend la forme de
 * l'interrupteur du studio. La coche est un rond plein, pas une bordure. */
.panneau-radio {
  display: flex;
  align-items: center;
  gap: var(--e1);
  width: 100%;
  min-height: var(--cible);
  padding: var(--e1) var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: none;
  color: var(--encre);
  text-align: left;
  cursor: pointer;
}
.panneau-radio:hover { background: var(--fond); }
.panneau-radio::before {
  content: '';
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--doux-2);
}
.panneau-radio[aria-checked='true'] { background: var(--accent-2); color: var(--accent); font-weight: 600; }
.panneau-radio[aria-checked='true']::before { background: var(--accent); }


/* ---- Les zones d'aperçu : une carte garde sa forme, image ou pas ------------------------- */

/* Une vignette manquante ne doit pas faire sauter la grille : la zone a toujours le même
 * rapport (16/10), et le pictogramme s'y pose au centre quand il n'y a pas de planche. */
.apercu {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 10;
  max-width: 100%;
  overflow: hidden;
  border-radius: 10px;
  background: var(--encre);
  color: var(--accent-2);
}
.apercu img { width: 100%; height: 100%; object-fit: cover; }
.apercu-picto { width: 56px; max-width: 45%; height: auto; }
.apercu-picto rect { fill: none; stroke: currentColor; stroke-width: 2; }
.apercu-picto-lecture { fill: currentColor; stroke: none; }

/* ---- La galerie des vidéos ---------------------------------------------------------------- */

/* Une galerie, pas une colonne de texte : une vidéo se reconnaît à son image (audit §4.9).
 * Une colonne sous 768 px, deux jusqu'à 1024, trois au-delà. */
.videos-grille { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e2); }
@media (min-width: 768px) { .videos-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .videos-grille { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.video-carte { display: flex; flex-direction: column; gap: var(--e1); }
.video-vignette {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.video-conv {
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  color: var(--encre-2);
}
/* L'état vide d'une galerie : une phrase et, quand il y en a une, la porte de sortie. */
.videos-vide { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e2); }

/* ---- Le tiroir de rangement des projets ---------------------------------------------------- */

/* Organiser ses projets est rare ; créer une vidéo est quotidien. Le rangement attend donc
 * replié, et garde à l'intérieur exactement la vue d'avant. */
.projets-organiser > summary { color: var(--encre); }

/* ---- Le dialogue « Dans quelle vidéo ? » ---------------------------------------------------- */

/* Utiliser une création demande une cible. Quand la coque n'en connaît pas, elle la demande
 * ici — jamais dans une fenêtre du navigateur. Échap ferme et ne choisit rien. */
.coque-choix {
  width: min(460px, calc(100vw - 2 * var(--e2)));
  max-height: min(80dvh, 620px);
  padding: var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: var(--fond-2);
  color: var(--encre);
}
.coque-choix::backdrop { background: rgba(23, 33, 43, .45); }
.coque-choix[open] { display: flex; flex-direction: column; gap: var(--e1); }
.coque-choix-titre { margin: 0 0 var(--e1); font-size: 18px; }
.coque-choix-liste { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
.coque-choix-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  min-height: var(--cible);
  padding: var(--e1) var(--e2);
  border: 0;
  border-radius: var(--rayon);
  background: none;
  color: var(--encre);
  text-align: left;
  cursor: pointer;
}
.coque-choix-item:hover { background: var(--fond); }
.coque-choix-nom { font-weight: 600; }

/* ---- Les avis IA dans le petit menu --------------------------------------------------------- */

/* Un avis se lit à côté de sa vidéo, pas dans une page où il faut retrouver de qui il parle. */
.panneau-avis { display: flex; flex-direction: column; gap: 6px; padding: var(--e1); }
.panneau-avis > p { margin: 0; }
.panneau-remarques { margin: 0; padding-left: 20px; }
.panneau-remarques li { margin: 2px 0; }

/* ---- Coûts et Journal (couts.js, vue Compte, admin) --------------------------------------- */

/* Une marge ou un montant négatif se lit à sa couleur, jamais à un attribut `style` (CSP). */
.couts-negatif {
  color: var(--alerte);
  font-weight: 600;
}
/* Le bandeau d'alertes : une pastille pleine par sujet, contrairement à `.pastille` (fond doux)
 * — elle doit se voir avant même d'être lue. */
.pastille-attention {
  background: var(--alerte);
  color: var(--fond-2);
  font-weight: 600;
}
.couts-alertes {
  margin-bottom: var(--e1);
}
/* Owner, ref et détail JSON sont de longueur variable : ils passent à la ligne plutôt que de
 * déborder à 390 px (`overflow-wrap` se transmet aux paragraphes du tiroir). */
.couts-texte-libre {
  overflow-wrap: anywhere;
}
