/* ------------------------------------------------------------ les caracteres
   Anton porte les titres et les noms, Lato tout le reste. Les deux sont
   servies par l'app elle-meme, en woff2 decoupe par alphabet : 96 Ko en tout,
   et rien a demander a un serveur exterieur -- l'app doit tourner sur un
   portable sans reseau comme sur le VPS. Les .ttf de `polices/` restent ou
   ils sont : ils servent au rendu des stories par PIL, pas au navigateur. */
@font-face{font-family:'Anton';font-style:normal;font-weight:400;font-display:swap;src:url('polices/Anton-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Anton';font-style:normal;font-weight:400;font-display:swap;src:url('polices/Anton-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Lato';font-style:normal;font-weight:300;font-display:swap;src:url('polices/Lato-300-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Lato';font-style:normal;font-weight:300;font-display:swap;src:url('polices/Lato-300-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url('polices/Lato-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Lato';font-style:normal;font-weight:400;font-display:swap;src:url('polices/Lato-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Lato';font-style:normal;font-weight:700;font-display:swap;src:url('polices/Lato-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Lato';font-style:normal;font-weight:700;font-display:swap;src:url('polices/Lato-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/* ------------------------------------------------------------------ jetons
   Noir sur gris neutre -- le code couleur d'Atelier. Le terracotta etait
   deja la sans jamais servir ; il ne marque plus que ce qui engage : creer,
   valider, detruire, et la lettre trouvee dans une proposition.
   `--creux` est le fond des surfaces vides (bande d'initiales, apercu sans
   image) : un cran sous le fond general, pour se lire comme un manque. */
:root{
  --fond:#f5f5f4; --carte:#ffffff; --encre:#111111; --gris:#77746f; --trait:#dcdcda;
  --creux:#ececeb; --sourd:#b6b4b0;
  --accent:#b8402f; --doute:#d9700f; --ok:#2f7d4f; --ok-pale:#e4efe8;
  --r:4px;
  --titre:"Anton",Impact,"Haettenschweiler",sans-serif;
}
/* Anton n'existe qu'en capitales : tout ce qui la porte est mis en capitales
   ICI, une fois, plutot que dans chaque regle qui l'appelle. */
.en-titre,h1,h2,h3,.carte>strong,.carte-client .dedans strong,button.fort,.bouton.fort{
  font-family:var(--titre);font-weight:400;text-transform:uppercase;
  letter-spacing:.04em}
*{box-sizing:border-box}
/* ⚠️ `hidden` doit gagner CONTRE nos propres regles. Toute regle de classe qui
   fixe `display` ressuscite un element cache : il reste invisible mais garde
   sa place et pousse ses voisins. Vu deux fois dans ce fichier --
   `.raz .confirmer` (plus bas, rustine locale conservee pour memoire) puis
   `.avatar-apercu img{display:block}`, qui chassait l'invite de la case
   d'avatar tout a droite derriere une image `hidden` large de 100 %. */
[hidden]{display:none!important}
body{margin:0;font:15px/1.55 "Lato",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
     background:var(--fond);color:var(--encre)}
a{color:inherit}
/* Le bandeau defile avec la page : il ne porte qu'une identite, pas une action.
   L'espace vertical va au feed, qui fait seize lignes. */
.bandeau{background:var(--carte);border-bottom:1px solid var(--trait);padding:14px 24px;
         display:flex;align-items:center;gap:18px}
.bandeau h1{font-size:19px;margin:0;letter-spacing:.09em}
.bandeau .fil{color:var(--gris);font-size:14px}
/* Le fil est un chemin, pas une etiquette : le nom du client y ramene a sa
   fiche depuis n'importe quelle page de shoot. Le soulignement discret est ce
   qui le distingue du texte mort qu'il etait. */
.bandeau .fil a{color:inherit;text-decoration:none;
  border-bottom:1px solid var(--trait);padding-bottom:1px}
.bandeau .fil a:hover{color:var(--encre);border-color:var(--encre)}
.bandeau .droite{margin-left:auto;color:var(--gris);font-size:13px}
main{max-width:1400px;margin:0 auto;padding:26px 24px 90px}
h2{font-size:28px;margin:0 0 4px;line-height:1.05}
.sous{color:var(--gris);margin:0 0 22px;font-size:14px;font-weight:300}
.carte{background:var(--carte);border:1px solid var(--trait);border-radius:var(--r);
       padding:18px 20px;margin-bottom:16px}
.grille-cartes{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}

/* ------------------------------------------------------ les volets d'un client
   NE PAS nommer ce bloc `.bloc` : ce nom appartient deja aux blocs du feed,
   plus bas. Une collision de nom passe tous les tests et ne se voit qu'a
   l'ecran -- c'est arrive avec `.tete`. */
.volet{background:var(--carte);border:1px solid var(--trait);border-radius:var(--r);
  margin-bottom:12px;overflow:hidden}
.volet>summary{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:14px 18px;cursor:pointer;list-style:none}
.volet>summary::-webkit-details-marker{display:none}
/* Le chevron est dessine plutot que pose en caractere : il tourne sans
   dependre d'une police, et suit l'encre du theme. */
.volet>summary::after{content:"";margin-left:auto;width:9px;height:9px;flex:none;
  border-right:2px solid var(--gris);border-bottom:2px solid var(--gris);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .15s}
.volet[open]>summary::after{transform:rotate(225deg) translate(-2px,-2px)}
.volet>summary:hover{background:var(--fond)}
.volet>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.volet-titre{font-family:var(--titre);font-weight:400;text-transform:uppercase;
  letter-spacing:.04em;font-size:19px}
/* Le resume est ce qui rend le pli supportable : ferme, le volet dit quand
   meme ce qu'il contient. */
.volet-resume{color:var(--gris);font-size:13px;font-weight:300}
.volet-resume.alerte-resume{color:var(--accent);font-weight:400}
.volet-corps{padding:0 18px 18px}
.volet-corps>label:first-child{margin-top:0}
/* L'avatar est dans le corps du volet : une vignette, pas une banniere
   pleine largeur -- le volet fait toute la page. */
#volet-infos .avatar-apercu{width:260px;max-width:100%;margin:0 0 6px}
/* L'invite de la case vide : trois lignes centrees, assez pales pour ne pas
   se lire comme un contenu, assez nettes pour qu'on sache ou cliquer. */
.avatar-invite{display:flex;flex-direction:column;align-items:center;gap:1px;
  font-family:var(--titre);text-transform:uppercase;letter-spacing:.07em;
  font-size:15px;color:var(--sourd);line-height:1.25}
.avatar-invite em{font-family:"Lato",sans-serif;font-style:normal;font-weight:300;
  text-transform:lowercase;letter-spacing:0;font-size:12px}
.avatar-apercu:hover .avatar-invite{color:var(--gris)}
/* Rien a dire, rien a montrer : sans ca, la ligne de retour laisserait un
   blanc permanent sous l'avatar. */
#avatar-etat:empty,#shoot-date-note:empty{display:none}
/* Le nom du client centre : la fiche est SA page, et les volets qui la
   composent sont tous alignes a gauche. Le titre centre les chapeaute au lieu
   de se confondre avec le premier d'entre eux. Classe dediee : `h2` sert sur
   les vingt gabarits, et ils n'ont pas a bouger. */
.titre-client{text-align:center;margin:6px 0 20px;font-size:34px}
.rangee-boutons{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:14px}
.shoot{padding:10px 0;border-top:1px solid var(--trait)}
.shoot:first-of-type{border-top:0}
.shoot-ligne{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* Le champ de correction s'ouvre DANS la ligne, juste apres le crayon. Il ne
   fait que la largeur d'une date : le `width:100%` general des champs le
   ferait pousser tout le reste a la ligne suivante. */
.shoot-corriger{display:flex;gap:6px;align-items:center}
.shoot-corriger input[type=date]{width:auto;max-width:165px;padding:5px 8px;font-size:13px}
.shoot-corriger button{padding:5px 12px;font-size:13px}
/* La suppression au bout de la ligne, toujours au meme endroit d'une ligne a
   l'autre : on ne la rencontre qu'en ayant depasse tout le reste. */
.supprimer-shoot{margin-left:auto;flex:none;padding:5px 13px;font-size:12px;
  font-family:var(--titre);text-transform:uppercase;letter-spacing:.09em;
  color:var(--accent);border:1px solid var(--accent);background:none;
  border-radius:var(--r);cursor:pointer}
.supprimer-shoot:hover{background:var(--accent);color:#fff}
/* Un bouton reduit a son signe : pas de fond, pas de cadre, tant qu'on ne le
   survole pas. Une ligne de shoot en porte deux, elles ne doivent pas peser
   autant que la date elle-meme. */
.icone{flex:none;width:30px;height:30px;padding:0;line-height:1;font-size:15px;
  border:1px solid transparent;background:none;color:var(--gris);
  display:grid;place-items:center;border-radius:var(--r);cursor:pointer}
.icone:hover{border-color:var(--trait);background:var(--fond);color:var(--encre)}
.icone.actif{border-color:var(--encre);color:var(--encre)}
.icone.risque{color:var(--gris);font-size:19px}
.icone.risque:hover{background:var(--accent);border-color:var(--accent);color:#fff}
/* Ce qui detruit se tient a l'ecart du reste, derriere un filet : on ne
   tombe dessus qu'en ayant traverse tout le volet. */
.zone-risque{display:flex;gap:12px;align-items:center;flex-wrap:wrap;
  margin-top:26px;padding-top:16px;border-top:1px solid var(--trait)}

/* La recherche de client, en tete de l'accueil. Champ large et seul sur sa
   ligne : c'est la premiere chose qu'on touche en arrivant, et il est la
   premiere chose qu'on touche en arrivant. */
/* La ligne d'acces de l'accueil : chercher a gauche, creer a droite. La
   creation reste repliee -- elle sert une fois par mois, la recherche vingt
   fois par jour.
   NE PAS rebaptiser ce bloc `.tete` : ce nom est deja celui des en-tetes de
   colonnes du feed, plus bas, qui centrent leur contenu. La collision passe
   tous les tests et ne se voit qu'a l'ecran. */
.barre-clients{margin:18px 0 20px}
.barre-clients .ligne{display:flex;gap:10px;align-items:stretch}
.barre-clients .nouveau{flex:none;white-space:nowrap}
.creation{margin-top:12px;max-width:520px}
.creation-ligne{display:flex;gap:10px;align-items:stretch}
.creation-ligne input{flex:1}
.creation-ligne button{flex:none}
.recherche{position:relative;flex:1;max-width:520px}
.recherche input[type=search]{width:100%;height:100%;padding:11px 14px;font:inherit;
  font-size:16px;border:1px solid var(--encre);border-radius:var(--r);
  background:var(--carte);-webkit-appearance:none}
.recherche input[type=search]:focus{outline:2px solid var(--accent);outline-offset:-1px}

/* La carte client porte une banniere a fleur de bord : le rembourrage passe
   donc sur un bloc interieur, et `overflow` coupe l'image aux coins arrondis.
   Surtout PAS de `display` ici -- il gagnerait contre l'attribut `hidden`,
   et les cartes filtrees par la recherche resteraient visibles. */
.carte-client{padding:0;overflow:hidden}
.banniere{aspect-ratio:16/9;background:var(--creux);border-bottom:1px solid var(--trait);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.banniere img{width:100%;height:100%;object-fit:contain;display:block}
/* Les initiales tiennent lieu d'image : grises et espacees, elles se lisent
   comme un marquage, pas comme un titre en double du nom juste en dessous. */
.banniere .initiales{font-family:var(--titre);font-size:30px;font-weight:400;
  letter-spacing:.08em;color:var(--sourd)}
.carte-client .dedans{padding:12px 15px 14px}
.carte-client .dedans strong{display:block;font-size:19px;line-height:1.1}
/* La ligne de shoots en capitales espacees : elle se lit comme une
   etiquette, pas comme une phrase qui doublerait le nom. */
.carte-client .note{font-size:10.5px;text-transform:uppercase;
  letter-spacing:.12em;margin-top:5px}
/* L'apercu de la fiche : meme cadre que dans la carte, pour qu'on voie
   exactement ce qui sera publie sur l'accueil. */
/* La zone d'avatar est un bouton : il faut donc lui retirer tout ce qu'un
   bouton apporte (fond, rembourrage, police) avant de la redessiner. */
.avatar-apercu{margin-top:10px;width:100%;padding:0;font:inherit;cursor:pointer;
  border:1px dashed var(--trait);border-radius:7px;
  overflow:hidden;aspect-ratio:16/9;background:var(--creux);
  display:flex;align-items:center;justify-content:center}
.avatar-apercu:hover{border-color:var(--encre)}
/* Pendant le survol d'un glisser : la zone se ferme et se teinte, pour dire
   que c'est ICI que le fichier tombera. */
.avatar-apercu.survol{border-style:solid;border-color:var(--accent);
  background:var(--fond)}
.avatar-apercu img{width:100%;height:100%;object-fit:contain;display:block}
.avatar-apercu .initiales{font-family:var(--titre);font-size:30px;font-weight:400;
  letter-spacing:.08em;color:var(--sourd)}
label{display:block;font-size:13px;color:var(--gris);margin:12px 0 4px}
input[type=text],input[type=date],input[type=number],select,textarea{
  width:100%;padding:9px 11px;border:1px solid var(--trait);border-radius:7px;
  font:inherit;background:#fff}
textarea{min-height:90px;resize:vertical}
/* Le focus porte la couleur de la DA, pas le bleu du navigateur -- qui
   n'appartient a aucune des deux et se voit sur chaque champ. */
input:focus-visible,select:focus-visible,textarea:focus-visible,
button:focus-visible,a:focus-visible,summary:focus-visible{
  outline:2px solid var(--accent);outline-offset:1px}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);
  outline-offset:-1px;border-color:var(--accent)}
button,.bouton{font:inherit;padding:9px 16px;border-radius:7px;border:1px solid var(--trait);
  background:#fff;cursor:pointer;text-decoration:none;display:inline-block}
button.fort,.bouton.fort{background:var(--encre);color:var(--carte);border-color:var(--encre);
  font-size:13.5px;padding:10px 17px}
button:disabled{opacity:.45;cursor:default}
/* Un bouton fort desactive doit se lire comme GRIS, pas comme un noir pali :
   le passage au noir est le signal que l'image est prete. */
button.fort:disabled,.bouton.fort:disabled{opacity:1;background:var(--sourd);
  border-color:var(--sourd);color:var(--carte)}
/* Ce qui detruit. Rouge mais pas plein : un bouton plein attire le clic, et
   c'est exactement ce qu'on ne veut pas ici. Il ne se remplit qu'au survol. */
button.risque{color:var(--accent);border-color:var(--accent)}
button.risque:hover{background:var(--accent);color:#fff}
/* Un geste secondaire, pose dans une ligne de reference : il ne doit pas
   peser autant que « Valider » ni bousculer la hauteur de la ligne. */
button.mince{padding:3px 9px;font-size:12px;margin-top:6px}
.rangee{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.rangee>*{flex:1;min-width:150px}
.etapes{display:flex;gap:6px;list-style:none;padding:0;margin:0 0 22px;flex-wrap:wrap}
.etapes li{font-size:12px;padding:5px 11px;border-radius:20px;background:#fff;
           border:1px solid var(--trait);color:var(--gris)}
.etapes li.faite{background:var(--ok);border-color:var(--ok);color:#fff}
/* Prete : le travail est sur le disque, personne ne l'a validee. Le meme vert,
   en fond pale -- la parente de couleur dit « c'est en route », le remplissage
   dit lequel des deux. Un enchainement produit sans valider, et sans cette
   nuance quatre etapes qui avaient travaille restaient blanches. */
.etapes li.prete{background:var(--ok-pale);border-color:var(--ok);color:var(--ok)}
/* Sautee n'est pas faite : rien n'a ete decide, il n'y avait rien a faire.
   Le style doit le dire -- un vert de validation mentirait. */
.etapes li.sautee{border-style:dashed;color:var(--gris);font-style:italic}
/* « ICI » = LA PAGE OUVERTE, en noir plein, par-dessus les trois etats. Le
   noir ne dit plus qu'une chose depuis qu'il suit l'etape REGARDEE et non
   l'etape courante du projet : « c'est celle-ci que tu as sous les yeux ».
   Une seule pastille le porte a la fois ; toutes les autres gardent la
   couleur de leur etat, et c'est la qu'on lit l'avancement. */
.etapes li.ici{background:var(--encre);border-color:var(--encre);color:#fff;
           font-weight:600}
.note{font-size:13px;color:var(--gris);font-weight:300}
.alerte{border-left:3px solid var(--accent);background:#fff;padding:12px 16px;
        border-radius:0 var(--r) var(--r) 0;margin:14px 0;font-size:14px}
.barre{height:6px;background:var(--trait);border-radius:4px;overflow:hidden;margin-top:8px}
.barre i{display:block;height:100%;background:var(--encre);width:0;transition:width .3s}

/* ---------- nommage ---------- */
.ref{display:flex;gap:16px;padding:14px 0;border-top:1px solid var(--trait)}
.ref:first-child{border-top:0}
.ref .gauche{width:190px;flex:none}
.ref .gauche img{width:150px;height:150px;object-fit:cover;border-radius:8px;
                 border:3px solid var(--encre)}
.ref .gauche .titre{margin-top:7px}
.ref .gauche input{font-weight:600;font-size:14px}
.zone{display:flex;flex-wrap:wrap;gap:8px;align-content:flex-start;flex:1;
      min-height:110px;padding:8px;border-radius:8px;border:2px dashed transparent}
.zone.survol{border-color:var(--encre);background:#fbfaf9}
.zone.vide::after{content:"aucune photo — ce plat n’a pas été shooté";color:var(--gris);
                  font-size:13px;align-self:center}
.vig{width:104px;position:relative;cursor:grab}
.vig img{width:104px;height:104px;object-fit:cover;border-radius:6px;display:block;
         border:2px solid transparent}
.vig.doute img{border-color:var(--accent);border-width:4px}
.vig b{display:block;font:11px/1.4 ui-monospace,monospace;color:var(--gris);margin-top:2px}
.vig.doute b{color:var(--accent)}
.vig.pris{opacity:.4}

/* ---------- noms imagines ---------- */
/* La croix TIENT DANS LA LIGNE DU CHAMP, pas au-dessous : c'est le pendant du
   nom, et un bouton pose sous le champ se lisait comme une action sur la zone
   de photos. */
.titre-nom{display:flex;gap:6px;align-items:center;margin-top:7px}
.titre-nom input{flex:1;min-width:0;font-weight:600;font-size:14px}
.croix-nom{flex:none;width:28px;height:28px;padding:0;line-height:1;font-size:17px;
  color:var(--gris);display:grid;place-items:center}
.croix-nom:hover{border-color:var(--accent);color:var(--accent)}
/* « ce plat n'a pas ete shoote » ne veut rien dire d'un nom qu'on vient
   d'ajouter : la zone attend une photo, elle ne signale pas un manque. */
#imagines .zone.vide::after{content:"aucune photo — glissez-en une ici"}
.ajout{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding-top:14px;
  border-top:1px solid var(--trait)}
.ajout input{width:260px;flex:none}
.ajout button.mince{margin-top:0}
.ajout .note{flex:1;min-width:200px}

/* ---------- nommage : le panneau « sans nom » ---------- */
/* `--haut` mesure la barre collante du feed ; le nommage n'en a pas, et la
   valeur de repli de 150 px laissait le panneau flotter loin sous son titre.
   62 px : juste sous le bandeau, que la poignee recouvrait -- elle est fixe et
   le bandeau, lui, defile. Les deux partagent la valeur pour que plier puis
   deplier ne fasse pas changer l'oeil de niveau. */
#atelier-nommage{--haut:62px}
#poignee-nommage{top:64px}
/* Le champ tient la largeur de la colonne : ces noms-la se tapent a la main,
   souvent longs, et il n'y a pas de photo de carte pour les rappeler. */
#imagines .ref .gauche{width:230px}
#panneau-sans .zone{min-height:80px;padding:8px 0}
/* « ce plat n'a pas ete shoote » ne veut rien dire ici : cette zone-la est la
   sortie, et vide elle annonce une bonne nouvelle. */
#sans.vide::after{content:"aucune photo sans nom"}

/* ---------- feed ---------- */
/* Le vivier est PERMANENT a droite, pas un panneau qu'on ouvre : on echange
   sans arret entre le feed et lui, et un panneau glissant obligerait a
   l'ouvrir a chaque geste. */
/* ⚠️ `min-width:0` sur la colonne de gauche. Sans lui, une colonne `1fr` prend
   `min-width:auto` et s'elargit a la taille de son contenu : en mode grilles,
   c'est TOUTE LA PAGE qui debordait au lieu du seul feed. */
.atelier{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px;
         align-items:start;transition:grid-template-columns .2s}
.atelier > *:first-child{min-width:0}
.atelier.replie{grid-template-columns:minmax(0,1fr) 0}
.atelier.replie .vivier{opacity:0;pointer-events:none;overflow:hidden;padding:0;border:0}
/* La barre d'outils et la selection COLLENT sous le bandeau : on s'en sert en
   permanence pendant qu'on fait defiler seize lignes de feed, et devoir
   remonter pour changer de vue ou declencher une variante casse le geste. */
/* Les deux rangees collent ENSEMBLE, dans un meme bloc : rendues collantes
   separement, chacune avec son `top`, la seconde glissait sous la premiere des
   que celle-ci depassait la hauteur prevue -- et le z-index superieur de la
   barre d'outils la masquait completement. */
.barres{position:sticky;top:0;z-index:16;background:var(--fond);
        padding-bottom:2px;margin-bottom:10px}
.barre-outils{display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  margin-bottom:8px}
.barre-outils .sep{flex:1}
.barre-outils .creer{display:flex;gap:6px;align-items:center}
.barre-outils .creer input{width:56px;text-align:center;padding:8px 4px}

/* Les onglets sont une NAVIGATION, pas des actions : plus petits, plus sobres,
   et sur leur propre rangee sous la barre d'outils. Les mettre au meme niveau
   que « Créer » ou « Annuler » faisait lire six variantes comme six boutons. */
.onglets-rangee{display:flex;gap:5px;flex-wrap:wrap;padding:0 2px 4px}
.onglet{font-size:12.5px;padding:4px 10px;border-radius:14px;text-decoration:none;
  color:var(--gris);border:1px solid transparent;cursor:pointer;user-select:none}
.onglet:hover{color:var(--encre);border-color:var(--trait);background:var(--carte)}
.onglet.actif{color:var(--encre);font-weight:600;background:var(--carte);
  border-color:var(--trait);box-shadow:inset 0 -2px 0 var(--encre)}
.plateau{transition:background .15s}
.plateau.sombre{background:#141210;border-color:#141210}
.plateau.sombre .tete,.plateau.sombre .titre-bloc{color:#8d857c}
.plateau.sombre .tete:hover{background:#241f1b;color:#fff}
.plateau{--zoom:1}
.entete-cols,.grille4{display:grid;grid-template-columns:22px repeat(3,1fr);gap:6px}
/* L'en-tete de colonnes colle aussi : figer une colonne doit rester possible
   quel que soit l'endroit du feed qu'on regarde. */
.entete-cols{width:calc(600px * var(--zoom));max-width:100%;margin-bottom:6px;position:sticky;
  top:var(--haut,150px);z-index:12;background:inherit;padding:4px 0}

.bloc .grille4{width:calc(600px * var(--zoom));max-width:100%}
.tete{display:grid;place-items:center;font:11px ui-monospace,monospace;
  color:var(--gris);cursor:pointer;border-radius:4px;user-select:none}
.tete:hover{background:var(--fond);color:var(--encre)}
.coin{cursor:default}
.case.vide{background:transparent;border:1px dashed var(--trait)}
.titre-bloc{display:none;font:12px/1 ui-monospace,monospace;color:var(--gris);
            padding:0 0 8px 24px}
/* Feed continu : les blocs s'empilent et la jonction garde le meme espacement
   que les lignes internes -- rien ne doit trahir le decoupage. */
.blocs .bloc + .bloc{margin-top:6px}
/* Grilles de 12 : les memes blocs, cote a cote sur une seule page, comme les
   decks clients presentent le feed. */
/* Seul le feed defile horizontalement, jamais la page. */
.blocs.par12{display:flex;gap:14px;align-items:flex-start;overflow-x:auto;
             padding-bottom:12px;max-width:100%}
.blocs.par12 .bloc + .bloc{margin-top:0}
.blocs.par12 .bloc{flex:none}
.blocs.par12 .bloc .grille4{width:calc(400px * var(--zoom));max-width:none}
.blocs.par12 .titre-bloc{display:block}
/* En mode grilles, l'en-tete de colonnes s'aligne sur le PREMIER bloc : il agit
   sur toute la colonne du feed, blocs compris, mais il doit se poser sur
   quelque chose. */
.plateau:has(.blocs.par12) .entete-cols{width:calc(400px * var(--zoom));max-width:none}
/* Aucune bordure ni numero tant qu'une case n'est pas figee : le feed doit se
   lire comme un feed, pas comme un tableau. Une bordure « transparente »
   n'aurait rien resolu -- elle laisse voir le fond de la case, donc un liseré
   clair autour de chaque photo.
   Le marquage se fait en `outline`, dessine PAR-DESSUS et hors flux : passer de
   non figee a figee ne decale donc aucune photo. */
/* ⚠️ 4:5 PARTOUT, feed comme legendes : c'est le format d'une PUBLICATION
   Instagram, et c'est ce que l'ecran doit montrer. A ne pas confondre avec le
   9:16 du PDF (`app/impression.py`), qui est le format de la PAGE -- un
   telephone -- et non celui des photos qu'elle porte. Le recadrage est centre
   (`object-fit:cover`), identique des deux cotes : changer ce ratio ici oblige
   a changer `PHOTO` la-bas. */
.case{position:relative;aspect-ratio:4/5;background:#ddd;border-radius:4px;overflow:hidden;
      cursor:pointer;border:0}
.case img{width:100%;height:100%;object-fit:cover;display:block}
.case.figee{outline:3px solid var(--accent);outline-offset:-3px}
.case .reel{position:absolute;left:4px;bottom:4px;color:#fff;font-size:10px;
  writing-mode:vertical-rl;transform:rotate(180deg);text-shadow:0 1px 3px #000;letter-spacing:.5px}
.case .num{display:none;position:absolute;right:4px;top:4px;color:#fff;
  font:10px ui-monospace,monospace;text-shadow:0 1px 3px #000;
  background:var(--accent);padding:1px 4px;border-radius:3px}
.case.figee .num{display:block}
/* La date de parution, en bas a droite : le seul coin libre -- l'etiquette de
   reel tient la gauche, le numero le haut. Fond plein et non ombre portee :
   une photo claire avalerait le texte, et ce calendrier se lit d'un coup d'oeil
   ou ne sert a rien. Cachee tant que le bouton Dates n'est pas enfonce. */
.case .date{display:none;position:absolute;right:4px;bottom:4px;color:#fbf9ea;
  font:10px/1 ui-monospace,monospace;background:rgba(0,0,0,.72);
  padding:2px 4px;border-radius:3px;letter-spacing:.2px}
.plateau.dates .case .date{display:block}
@media(max-width:980px){
  .atelier{grid-template-columns:1fr}
  .ref{flex-direction:column}.ref .gauche{width:auto}
}
.pied{position:fixed;left:0;right:0;bottom:0;background:var(--carte);
  border-top:1px solid var(--trait);padding:12px 24px;display:flex;gap:12px;
  align-items:center;z-index:25}
.pied .note{margin-right:auto}

/* ---------- loupe et choix de nom ---------- */
.voile{position:fixed;inset:0;background:rgba(20,18,16,.82);z-index:60;
       display:none;align-items:center;justify-content:center}
.voile.ouvert{display:flex}
/* La loupe passe AU-DESSUS de la fenetre de choix : c'est un agrandissement a
   la demande, jamais un arriere-plan. Meme z-index que la fenetre, c'est
   l'ordre du DOM qui tranchait -- et la fenetre gagnait. */
.voile.loupe{z-index:75}
.loupe img{max-width:92vw;max-height:92vh;border-radius:8px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
.loupe .legende{position:fixed;left:0;right:0;bottom:20px;text-align:center;color:#fff;
  font:13px ui-monospace,monospace;opacity:.85}

.choix{background:var(--carte);border-radius:12px;max-width:1180px;width:94vw;
       max-height:88vh;display:flex;overflow:hidden}
/* Le comparateur occupe la moitie gauche : la photo a nommer et la reference
   cliquee, cote a cote et a la meme taille. C'est la juxtaposition qui rend le
   verdict juste -- mesure sur le shooting du 8 juillet : en mosaique on se
   trompe, cote a cote on tranche. */
.choix .comparateur{flex:1;min-width:0;padding:16px;display:flex;gap:12px;
                    flex-direction:column;background:var(--fond)}
.choix .paire{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;gap:12px}
.choix .paire figure{margin:0;display:flex;flex-direction:column;min-height:0}
.choix .paire img{flex:1;min-height:0;width:100%;object-fit:contain;border-radius:8px;
                  background:#fff}
.choix .paire figcaption{font:12px ui-monospace,monospace;color:var(--gris);
                         text-align:center;padding-top:6px}
.choix .paire .attente{flex:1;border:2px dashed var(--trait);border-radius:8px;
  display:flex;align-items:center;justify-content:center;color:var(--gris);
  font-size:13px;text-align:center;padding:20px}
.choix .liste{width:340px;flex:none;overflow:auto;padding:6px;
              border-left:1px solid var(--trait)}
.choix .ligne{display:flex;gap:12px;align-items:center;padding:8px 12px;border-radius:8px;
              cursor:pointer}
.choix .ligne:hover{background:var(--fond)}
.choix .ligne.actuelle{background:var(--fond);box-shadow:inset 3px 0 0 var(--encre)}
/* Le curseur du clavier. Distinct de `.actuelle` : l'une dit « le nom que
   porte cette photo », l'autre « le nom que je regarde ». Les deux se
   superposent souvent, il faut pouvoir les lire separement. */
.choix .ligne.pointee{background:var(--fond);outline:2px solid var(--encre);
  outline-offset:-2px}
/* Le raccourci ne doit pas etre une surprise : le nom vers lequel haut/bas
   ramene se signale, discretement. */
.choix .ligne.dernier .nom::after{content:"↩";margin-left:7px;color:var(--gris);
  font-weight:400}

/* Cote Reels il n'y a pas de photo de reference a mettre en regard -- un titre
   est du texte. La photo occupe donc toute la largeur, et le titre auquel elle
   est rattachee se lit AU-DESSUS d'elle : c'est l'information qu'on vient
   verifier. */
.choix .paire.seule{grid-template-columns:1fr}
.choix .titre-actuel{font-weight:600;font-size:15px;padding:0 2px 10px;
  display:flex;gap:10px;align-items:baseline}
.choix .titre-actuel .etiq{font:12px ui-monospace,monospace;color:var(--gris);
  font-weight:400}
/* Une photo qu'aucun Reel n'a retenue : l'absence de titre doit se lire comme
   un etat, pas comme un titre manquant a l'affichage. */
.choix .titre-actuel .sans, .choix .titre-actuel span.sans{color:var(--gris);
  font-weight:400;font-style:italic}
.choix .paire img{cursor:zoom-in}
.choix .ligne img{width:52px;height:52px;object-fit:cover;border-radius:6px;
                  border:2px solid var(--encre);flex:none}
.choix .ligne .vide-ref{width:52px;height:52px;border-radius:6px;border:2px dashed var(--trait);
                        flex:none}
.choix .ligne .nom{flex:1;font-weight:600}
.choix .ligne .compte{color:var(--gris);font-size:13px}
/* Confirmation en place, sur la ligne elle-meme : la cible du clic est petite,
   on vise la vignette et on attrape la ligne. Une fenetre de confirmation
   par-dessus la fenetre ferait perdre le comparateur de vue -- or c'est lui
   qui permet de verifier qu'on range au bon endroit. */
.choix .ligne.armee{background:#fff;box-shadow:inset 3px 0 0 var(--accent),
                    0 0 0 1px var(--trait)}
.choix .ligne .confirmer{display:none;gap:6px;align-items:center}
.choix .ligne.armee .confirmer{display:flex}
.choix .ligne.armee .compte{display:none}
.choix .ligne .confirmer button{padding:5px 11px;font-size:13px}
.choix .ligne .confirmer .oui{background:var(--accent);border-color:var(--accent);color:#fff}
.choix .liste footer{padding:10px 6px 4px;color:var(--gris);font-size:12.5px}
@media(max-width:900px){
  .choix{flex-direction:column;max-height:92vh}
  .choix .liste{width:auto;border-left:0;border-top:1px solid var(--trait);max-height:44vh}
  .choix .comparateur{min-height:38vh}
}

/* ---------- contrôle des règles ---------- */
.controles{list-style:none;padding:0;margin:8px 0 16px}
.controles li{padding:7px 0 7px 12px;border-left:3px solid var(--ok);margin-bottom:6px}
.controles li.faute{border-left-color:var(--accent);background:#fff7f5}
.controles li b{font-size:13.5px;font-weight:600}
.controles li.ok b{color:var(--ok)}
.controles li.faute b{color:var(--accent)}
.controles .regle{font-size:12.5px;color:var(--gris);margin-top:4px;font-style:italic}

/* ---------- jours de publication ---------- */
.jours{display:flex;gap:6px}
.jours label{margin:0;cursor:pointer}
.jours input{position:absolute;opacity:0;pointer-events:none}
.jours span{display:grid;place-items:center;width:38px;height:38px;border-radius:8px;
  border:1px solid var(--trait);background:#fff;font-weight:600;font-size:14px;
  color:var(--gris);transition:.12s}
.jours input:checked + span{background:var(--encre);border-color:var(--encre);color:#fff}
.jours label:hover span{border-color:var(--encre)}
.jours input:focus-visible + span{outline:2px solid var(--accent);outline-offset:2px}

/* ---------- panneau de paramètres ---------- */
.reglages summary{cursor:pointer;list-style:none;display:flex;gap:8px;align-items:baseline}
.reglages summary::-webkit-details-marker{display:none}
.reglages summary::before{content:"▸";color:var(--gris);transition:.15s}
.reglages[open] summary::before{transform:rotate(90deg)}
.reglages[open] summary{margin-bottom:6px}

/* ---------- vivier permanent ---------- */
.vivier{position:sticky;top:var(--haut,150px);
        max-height:calc(100vh - var(--haut,150px) - 24px);overflow:auto}
/* L'en-tete colle EN HAUT DU VIVIER, qui defile pour son propre compte : le
   bouton de repli doit rester atteignable meme apres avoir fait descendre
   quarante vignettes. */
.vivier .entete{display:flex;align-items:center;gap:8px;position:sticky;top:0;
  z-index:2;background:var(--carte);padding:2px 0 8px;margin:-2px 0 0}
.vivier .replier{padding:0;width:26px;height:26px;line-height:1;flex:none;
  font-size:19px;color:var(--gris);display:grid;place-items:center}
.vivier .replier:hover{color:var(--encre);border-color:var(--encre)}
.vivier .grille{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:8px}
.vivier .famille-vivier{margin:12px 0 0;font-weight:600;color:var(--encre)}
.vivier .famille-vivier:first-child{margin-top:8px}
.vivier .grille img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:5px;
  cursor:grab}
.vivier .grille img:hover{outline:2px solid var(--encre);outline-offset:-2px}

/* ---------- vivier repliable ---------- */
.vivier{transition:opacity .18s}
/* La poignee se pose EXACTEMENT a la hauteur du chevron de repli, qui vit dans
   l'en-tete du vivier : plier puis deplier ne doit pas obliger l'oeil a
   changer de niveau, ni la souris a traverser l'ecran. */
.poignee{position:fixed;right:24px;top:calc(var(--haut,150px) + 2px);z-index:18;
  width:26px;height:26px;padding:0;border-radius:7px;
  border:1px solid var(--trait);background:var(--carte);cursor:pointer;
  color:var(--gris);font-size:19px;line-height:1;place-items:center;display:none}
.poignee:hover{color:var(--encre);border-color:var(--encre)}
.atelier.replie ~ .poignee,body.vivier-replie .poignee{display:grid}
.plateau .zoom{position:absolute;right:14px;top:14px;font:11px ui-monospace,monospace;
  color:var(--gris);opacity:0;transition:opacity .2s;pointer-events:none}
.plateau.zoome .zoom{opacity:1}
.plateau{position:relative}
.plateau .methode{position:absolute;left:14px;top:10px;font-size:11px;
  color:var(--gris);border:1px solid var(--trait);border-radius:9px;
  padding:2px 8px;background:var(--carte);cursor:help}
.plateau.sombre .methode{border-color:#3a332d;background:#1c1916;color:#8d857c}

/* ---------- barre de defilement du feed ----------
   La barre par defaut est presque invisible sur fond sombre : elle est dessinee
   dans la couleur du systeme, pas dans celle du conteneur. On la peint donc a
   la main, dans les deux fonds. */
.blocs.par12{scrollbar-width:thin;scrollbar-color:var(--gris) transparent}
.blocs.par12::-webkit-scrollbar{height:11px}
.blocs.par12::-webkit-scrollbar-track{background:var(--trait);border-radius:6px}
.blocs.par12::-webkit-scrollbar-thumb{background:var(--gris);border-radius:6px;
  border:2px solid var(--trait)}
.blocs.par12::-webkit-scrollbar-thumb:hover{background:var(--encre)}

.plateau.sombre .blocs.par12{scrollbar-color:#7d746a #2a2521}
.plateau.sombre .blocs.par12::-webkit-scrollbar-track{background:#2a2521}
.plateau.sombre .blocs.par12::-webkit-scrollbar-thumb{background:#7d746a;
  border-color:#2a2521}
.plateau.sombre .blocs.par12::-webkit-scrollbar-thumb:hover{background:#bdb3a7}

.vivier{scrollbar-width:thin;scrollbar-color:var(--gris) transparent}

/* ---------- renommer un onglet ---------- */
/* `input.onglet-edit` et non `.onglet-edit` : la regle generale `input[type=text]`
   a une specificite superieure (0,1,1 contre 0,1,0) et imposait `background:#fff`.
   Avec `color:inherit`, l'onglet actif -- texte blanc sur fond noir -- donnait
   donc du blanc sur blanc.
   On fixe les deux explicitement : champ clair, encre noire, lisible quel que
   soit l'onglet edite. */
input.onglet-edit{font:inherit;font-size:14px;padding:2px 6px;
  border:1px solid var(--accent);border-radius:5px;
  background:#fff;color:var(--encre);width:auto;min-width:110px;outline:0}
#onglets .bouton{user-select:none}

/* ---------- ligne de titre ---------- */
.titre-ligne{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
/* Le bouton de retour : une pastille ronde, de la meme famille que celles des
   etapes, assez grande pour se viser sans chercher -- c'est la seule sortie du
   pipeline vers le client. */
.retour{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;border:1px solid var(--trait);border-radius:50%;
  background:var(--carte);color:var(--gris);text-decoration:none;line-height:1}
.retour:hover{border-color:var(--encre);background:var(--fond);color:var(--encre)}
.retour:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* ⚠️ LA FLECHE SORT DANS LA MARGE, MAIS SEULEMENT S'IL Y EN A UNE. Elle est
   posee a gauche de la ligne de titre, hors du flux : le titre commence alors
   exactement a la verticale des pastilles d'etapes et de tout le reste de la
   page, au lieu d'etre pousse vers la droite. La fleche et son ecart pesent
   54px ; `main` est large de 1400px au plus, centre, plus 24px de padding --
   il faut donc 1508px de fenetre pour les loger. En dessous, la marge n'existe
   plus, la fleche sortirait de l'ecran : elle reprend sa place dans la rangee. */
@media (min-width:1520px){
  .titre-ligne{position:relative}
  .retour{position:absolute;right:calc(100% + 16px);top:50%;
          transform:translateY(-50%)}
}
.titre-ligne h2{margin:0}
.titre-ligne .note{flex:1;min-width:180px}
.titre-ligne form{flex:none}

/* ---------- couvertures de Reel ---------- */
.reel-ligne .gauche{width:220px}
.titre-reel{font-weight:650;font-size:15px;text-transform:uppercase;letter-spacing:.3px}
/* La poignee d'ordre. Elle se tient DANS la ligne du titre, discrete tant
   qu'on ne la cherche pas : l'ordre des deadlines est bon la plupart du temps,
   et un bouton franc inviterait a le defaire sans raison. */
.titre-reel .prise{display:inline-block;width:13px;margin-right:4px;
  color:var(--gris);opacity:.35;cursor:grab;
  font-weight:400;letter-spacing:0;user-select:none;transition:opacity .12s}
.reel-ligne:hover .titre-reel .prise{opacity:1}
.titre-reel .prise:active{cursor:grabbing}
/* La ligne en voyage s'efface : ce qu'on suit des yeux, c'est le REPERE, pas
   elle. Rien ne se deplace avant le lacher -- le repere dit ou ca tombera. */
.reel-ligne.voyage{opacity:.4}
.repere-ordre{height:3px;margin:3px 0;border-radius:2px;background:var(--accent)}
/* La couverture, c'est la PREMIERE vignette. Le rang porte l'information : pas
   de case a cocher, pas de champ -- deplacer en tete, c'est choisir. */

.pastille{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--accent);vertical-align:middle}


.vivier .entete .replier{margin-left:auto}
/* La croix ne se montre qu'au survol : seize vignettes barrees en permanence
   feraient un tableau de bord, pas une planche de photos. */
.vig .croix{position:absolute;right:2px;top:2px;width:19px;height:19px;padding:0;
  border-radius:50%;border:0;background:rgba(20,18,16,.72);color:#fff;font-size:14px;
  line-height:1;display:none;place-items:center;cursor:pointer}
.vig:hover .croix{display:grid}
.vig .croix:hover{background:var(--accent)}
/* Rien a retirer dans « sans nom » : c'est deja la sortie. La regle porte
   sur la ZONE et non sur la vignette, pour qu'elle suive les deplacements
   sans qu'on ait a repeindre quoi que ce soit. */
.zone[data-nom=""] .vig .croix{display:none}

/* ---------- mode selection ---------- */
.zone.active{background:#fbfaf9;box-shadow:inset 3px 0 0 var(--encre);border-radius:8px}
#tout.en-selection img{opacity:.42;transition:opacity .12s}
#tout.en-selection img.selectionnee{opacity:1;outline:3px solid var(--encre);
  outline-offset:-3px}
#tout img{cursor:pointer}
#b-terminer{margin-left:auto;padding:4px 10px;font-size:13px}
.vivier .entete .replier{margin-left:6px}

/* ---------- detail et verrou par titre ---------- */
.reel-ligne .gauche .detail{width:100%;margin-top:7px;padding:6px 9px;font-size:13px}
.reel-ligne .gauche .garder{display:inline-flex;gap:5px;align-items:center;margin:5px 0 0;
  font-size:12px;color:var(--gris);cursor:pointer}
.reel-ligne .gauche .garder input{width:auto;margin:0}
.reel-ligne .gauche .garder:hover{color:var(--encre)}

/* ---------- selection en pleine page, dans le flux ----------
   Le vivier ne recouvre RIEN : la liste des Reels s'efface le temps du geste et
   il prend sa place. Les vignettes sont dimensionnees en JS pour que les
   quatre-vingts photos tiennent d'un seul coup d'oeil -- devoir faire defiler
   obligerait a memoriser ce qu'on vient de voir. */
/* Le vivier recouvre la page pendant la selection : rien en dessous ne sert.
   La taille des vignettes est pilotee par --cote, calculee a l'ouverture pour
   que tout tienne, puis reglable a la molette. */
.fond-plein{position:fixed;inset:0;background:rgba(20,18,16,.55);z-index:55}
.vivier.plein{position:fixed;inset:16px;z-index:56;max-height:none;width:auto;
  display:flex;flex-direction:column;box-shadow:0 24px 70px rgba(0,0,0,.35)}
.vivier.plein .entete{padding-bottom:10px;border-bottom:1px solid var(--trait)}
.vivier.plein .replier{display:none}
.vivier.plein #tout{flex:1;min-height:0;overflow:auto;
  grid-template-columns:repeat(auto-fill,var(--cote,120px));
  justify-content:center;gap:6px;align-content:flex-start;padding-top:8px}
.vivier.plein #tout img{width:var(--cote,120px);height:calc(var(--cote,120px)*1.25)}
.etiquette-cote{font:11px ui-monospace,monospace;color:var(--gris);opacity:0;
  transition:opacity .2s}
.etiquette-cote.visible{opacity:1}
body.sans-defilement{overflow:hidden}
@media(max-width:820px){ .vivier.plein{inset:8px} }

/* ---------- remise a zero ---------- */
/* ⚠️ `[hidden]` doit rester prioritaire. Une regle `display:inline-flex` sur un
   element porteur de `hidden` ECRASE le `display:none` du navigateur : la
   confirmation restait affichee en permanence, alors que tout le JS la croyait
   masquee. */
.raz .confirmer{display:inline-flex;gap:6px;align-items:center;padding:0 8px;
  border-left:3px solid var(--accent)}
.raz .confirmer[hidden],.raz button[hidden]{display:none}
.raz .confirmer b{font-size:13px;color:var(--accent)}
.raz .confirmer button{padding:5px 10px;font-size:13px}
.raz .confirmer .oui{background:var(--accent);border-color:var(--accent);color:#fff}

/* ---------- voyant de travail ---------- */
.travail{position:fixed;left:50%;bottom:26px;transform:translate(-50%,14px);
  display:none;gap:10px;align-items:center;z-index:80;
  background:var(--encre);color:#fff;padding:11px 18px;border-radius:24px;
  font-size:13.5px;box-shadow:0 10px 34px rgba(0,0,0,.32);
  transition:transform .18s,opacity .18s;opacity:0;max-width:min(90vw,560px)}
.travail.visible{display:flex;transform:translate(-50%,0);opacity:1}
.travail .texte{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tourne{width:15px;height:15px;flex:none;border-radius:50%;
  border:2px solid rgba(255,255,255,.28);border-top-color:#fff;
  animation:tourner .8s linear infinite}
@keyframes tourner{to{transform:rotate(360deg)}}
body.occupe{cursor:progress}
body.occupe button[disabled]{opacity:.4}
@media(prefers-reduced-motion:reduce){ .tourne{animation-duration:2.4s} }
.travail .cmd{flex:none;background:rgba(255,255,255,.14);color:#fff;border:0;
  border-radius:50%;width:26px;height:26px;padding:0;font-size:11px;line-height:1;
  cursor:pointer;display:flex;align-items:center;justify-content:center}
.travail .cmd:hover{background:rgba(255,255,255,.3)}
.travail .cmd.stop:hover{background:#c0392b}
.travail .cmd[hidden]{display:none}
body.occupe .travail .cmd{opacity:1}

/* ---------- captions ---------- */
.communs .rangee{margin-top:4px}
.atelier-captions{display:grid;grid-template-columns:96px minmax(0,1fr);gap:14px;
  align-items:start}
.bande{display:flex;flex-direction:column;gap:6px;max-height:calc(100vh - 200px);
  overflow:auto;position:sticky;top:12px;padding-right:4px}
.onglet-post{position:relative;padding:0;border:0;background:none;cursor:pointer;
  border-radius:6px;overflow:hidden;flex:none}
.onglet-post img{width:84px;height:105px;object-fit:cover;display:block;opacity:.55}
.onglet-post.actif img{opacity:1;outline:3px solid var(--encre);outline-offset:-3px}
.onglet-post span{position:absolute;left:3px;top:2px;color:#fff;font:10px ui-monospace,
  monospace;text-shadow:0 1px 3px #000}
.onglet-post i{position:absolute;right:3px;top:3px;background:var(--accent);color:#fff;
  font:9px/1 sans-serif;font-style:normal;padding:2px 4px;border-radius:3px}

/* Deux colonnes, comme la page du deck : le texte a gauche, la photo a droite. */
.page-caption{display:grid;grid-template-columns:minmax(0,1fr) 42%;gap:22px;
  background:#111;color:#f2efeb;border-color:#111}
.texte-caption{display:flex;flex-direction:column;gap:12px;padding:6px 0 0 6px}
.entete-caption{display:flex;align-items:baseline;gap:16px}
.mot-caption{font-size:34px;letter-spacing:.16em;line-height:1}
.mot-reel{font-size:20px;letter-spacing:.1em;margin-left:auto;padding-right:8px}
.page-caption .date{font-weight:600;text-decoration:underline;font-size:14px}
.page-caption textarea{min-height:190px;background:#1b1b1b;color:#f2efeb;
  border-color:#333;line-height:1.6;resize:vertical}
.page-caption .fixe{font-size:13.5px;line-height:1.7;color:#c9c3bb;margin-top:auto}
.photo-caption{position:relative}
.photo-caption img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:4px;
  display:block;background:#222}
/* Le nom du Reel est vertical, a gauche de la photo -- releve sur le deck :
   x=972, rotation -90 degres. */
.photo-caption .vertical{position:absolute;left:-30px;bottom:8px;width:190px;
  transform:rotate(-90deg);transform-origin:left bottom;background:transparent;
  border:0;border-bottom:1px dashed #444;color:#f2efeb;font-size:12px;
  letter-spacing:.12em;padding:2px 4px;border-radius:0}
.photo-caption .vertical::placeholder{color:#5a5a5a}
@media(max-width:900px){
  .atelier-captions{grid-template-columns:1fr}
  .bande{flex-direction:row;max-height:none;position:static}
  .page-caption{grid-template-columns:1fr}
  .photo-caption .vertical{position:static;transform:none;width:100%;
    border:1px solid #333;border-radius:6px;margin-top:8px}
}

/* ---------- exemples de legendes ---------- */
#exemples .exemple{display:flex;gap:6px;align-items:flex-start;margin-bottom:6px}
#exemples textarea{min-height:64px}
#exemples .exemple button{flex:none;width:30px;height:30px;padding:0;font-size:16px;
  color:var(--gris)}
#exemples .exemple button:hover{color:var(--accent);border-color:var(--accent)}
.plus{font-size:13px;padding:6px 12px}

/* ---------- validation d'une legende ---------- */
.actions-caption{display:flex;gap:8px;align-items:center}
/* La coche alcool se pose a gauche des boutons, avant « Régénérer » : c'est une
   propriete de la legende, pas une action. */
.coche-alcool{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;
  color:var(--gris);white-space:nowrap;cursor:pointer;user-select:none}
.coche-alcool input{margin:0;cursor:pointer}
/* La mention legale se lit comme une mention, pas comme une ligne d'adresse :
   detachee du reste du pied et un cran plus discrete. */
.page-caption .fixe #l-alcool:not(:empty){margin-bottom:10px;font-size:12.5px;
  font-style:italic;line-height:1.5}
/* Plusieurs adresses tiennent dans un seul bloc, une par ligne : sans ca le
   texte se recollait bout a bout et l'apercu mentait sur ce qui sera publie. */
.page-caption .fixe #l-adresse{white-space:pre-line}
.onglet-post .coche{display:none;position:absolute;right:3px;bottom:3px;
  background:var(--ok);color:#fff;font-size:10px;width:16px;height:16px;
  border-radius:50%;line-height:16px;text-align:center}
.onglet-post.valide .coche{display:block}
.onglet-post.valide img{opacity:.85}
.page-caption.verrouillee textarea{opacity:.7;cursor:default}
/* Fond clair : les photos claires se lisent mal sur du noir, et l'inverse. */
.page-caption.clair{background:#fff;color:var(--encre);border-color:var(--trait)}
.page-caption.clair textarea{background:#fff;color:var(--encre);border-color:var(--trait)}
.page-caption.clair .fixe{color:var(--gris)}
.page-caption.clair .vertical{color:var(--encre);border-bottom-color:var(--trait)}

.versions{display:inline-flex;gap:4px;align-items:center;margin-right:auto;
  font:12px ui-monospace,monospace;color:var(--gris)}
.versions button{padding:3px 9px;font-size:14px;line-height:1}
.page-caption .versions{color:#9c948a}
.page-caption.clair .versions{color:var(--gris)}

/* --- Le cadre 4:5 d'une photo ------------------------------------------------
   Au-dessus de `.voile` (60) et de `.loupe` (75) : le recadrage s'ouvre depuis
   la page des captions et ne doit jamais passer sous elles. */
#recadreur{position:fixed;inset:0;z-index:80;background:rgba(20,18,16,.9);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px}
#recadreur[hidden]{display:none}
.cadreur-scene{display:flex;align-items:center;justify-content:center;
  max-width:92vw;max-height:76vh}
/* La boite epouse EXACTEMENT l'image : c'est elle qui sert de repere aux
   pourcentages du cadre. `inline-block` la fait se retracter sur son contenu,
   et l'image en `block` supprime la ligne de base qui ajouterait des pixels. */
.cadreur-boite{position:relative;display:inline-block;overflow:hidden;line-height:0}
.cadreur-boite img{display:block;max-width:92vw;max-height:76vh;
  user-select:none;-webkit-user-drag:none}
/* L'exterieur s'assombrit par une ombre portee geante plutot que par un second
   element a tenir synchronise avec le cadre. */
#cadreur-cadre{position:absolute;cursor:move;
  box-shadow:0 0 0 9999px rgba(12,11,10,.66);outline:2px solid #fff}
#cadreur-cadre i{position:absolute;width:22px;height:22px;background:#fff;
  border-radius:3px;box-shadow:0 1px 4px rgba(0,0,0,.5)}
#cadreur-cadre i[data-coin=nw]{left:-11px;top:-11px;cursor:nwse-resize}
#cadreur-cadre i[data-coin=ne]{right:-11px;top:-11px;cursor:nesw-resize}
#cadreur-cadre i[data-coin=sw]{left:-11px;bottom:-11px;cursor:nesw-resize}
#cadreur-cadre i[data-coin=se]{right:-11px;bottom:-11px;cursor:nwse-resize}
.cadreur-barre{display:flex;align-items:center;gap:12px;color:#c9c3bb;font-size:13px}
.cadreur-barre b{color:#fff;font-weight:600}
.cadreur-barre button{background:#2a2724;color:#f2efeb;border-color:#3d3835}
.cadreur-barre button.fort{background:#fff;color:#1a1a1a;border-color:#fff}

/* ---------- compteur de consommation IA ---------- */
/* Le bandeau ne montre que le montant ; il s'efface tant qu'aucun appel n'est
   au journal. L'etoile signale un modele hors grille tarifaire : le total
   affiche est alors un minimum. */
.conso{font:13px ui-monospace,monospace;color:var(--gris);background:none;
  border:1px solid var(--trait);border-radius:999px;padding:3px 10px;
  cursor:pointer;margin-left:12px}
.conso:hover{color:var(--encre);border-color:var(--gris)}
.conso-carte{background:var(--carte);border-radius:var(--r);padding:20px 24px;
  min-width:420px;max-width:92vw;box-shadow:0 20px 60px rgba(0,0,0,.35)}
.conso-carte h2{margin:0 0 12px;font-size:15px}
#conso-table{border-collapse:collapse;width:100%;font-size:13px}
#conso-table th{text-align:left;color:var(--gris);font-weight:500;
  border-bottom:1px solid var(--trait);padding:4px 12px 4px 0}
#conso-table td{padding:5px 12px 5px 0;font-variant-numeric:tabular-nums}
#conso-table td:nth-child(n+2),#conso-table th:nth-child(n+2){text-align:right}
#conso-table tr.total td{border-top:1px solid var(--trait);font-weight:600}
.note-conso{color:var(--gris);font-size:12px;margin:12px 0 0}

/* ---------- carrousel d'un post ---------- */
.photo-caption .b-carrousel{margin-top:10px;width:100%;font-size:13px}
.photo-caption .b-carrousel.actif{background:var(--encre);color:#fff;
  border-color:var(--encre)}
.onglet-post .pile{position:absolute;left:3px;bottom:3px;font:10px ui-monospace,monospace;
  font-style:normal;color:#fff;background:rgba(20,18,16,.75);padding:1px 5px;
  border-radius:8px}
/* La gestion du carrousel s'ouvre PAR-DESSUS la page. En bloc sous la caption
   elle tombait hors de l'ecran : on generait un carrousel et rien ne semblait
   se passer. Z-index 70 : au-dessus de la page, et SOUS `#recadreur` (80) --
   cliquer une vignette regle son cadre, et le cadreur s'ouvre depuis la modale
   qui doit donc rester derriere lui. */
.voile-carrousel{position:fixed;inset:0;z-index:70;background:rgba(20,18,16,.62);
  display:flex;align-items:center;justify-content:center;padding:24px}
.voile-carrousel[hidden]{display:none}
.modale-carrousel{width:min(1100px,94vw);max-height:88vh;display:flex;
  flex-direction:column;gap:10px;box-shadow:0 24px 70px rgba(0,0,0,.4)}
.tete-carrousel{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.croix-modale{padding:1px 10px;font-size:18px;line-height:1.2}
.gen-carrousel{margin-left:auto;display:flex;gap:8px;align-items:center;
  font-size:13px;color:var(--gris)}
.gen-carrousel input{width:60px;text-align:center}
/* C'est le CORPS qui defile, pas la modale : la tete, la notice et le pied
   restent en vue pendant qu'on fait glisser les vignettes. */
.corps-carrousel{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:18px;flex:1;min-height:0;overflow:auto}
.pied-carrousel{display:flex;justify-content:flex-end;
  border-top:1px solid var(--trait);padding-top:10px}
.bande-carrousel{display:flex;flex-wrap:wrap;gap:10px;align-content:flex-start;
  border:1.5px dashed var(--trait);border-radius:8px;padding:10px;min-height:152px}
.bande-carrousel.survol{border-color:var(--encre);background:#fbfaf9}
.vig-car{position:relative;width:104px;cursor:grab}
.vig-car img{width:104px;aspect-ratio:4/5;object-fit:cover;border-radius:5px;display:block}
.vig-car.tete img{outline:3px solid var(--encre);outline-offset:-3px}
/* Retiree du carrousel, la photo du feed ne disparait pas : elle reste a sa
   place, grisee, et un clic la remet. */
.vig-car.exclue img{opacity:.35;filter:grayscale(.8);outline-style:dashed;
  outline-color:var(--gris)}
.vig-car.exclue{cursor:pointer}
.vig-car.pris{opacity:.4}
.vig-car span{position:absolute;left:4px;top:3px;color:#fff;font:10px ui-monospace,monospace;
  background:rgba(20,18,16,.65);padding:1px 6px;border-radius:8px;pointer-events:none}
.vig-car .croix{position:absolute;right:2px;top:2px;width:19px;height:19px;padding:0;
  border-radius:50%;border:0;background:rgba(20,18,16,.72);color:#fff;font-size:14px;
  line-height:1;display:none;place-items:center;cursor:pointer}
.vig-car:hover .croix{display:grid}
.vig-car .croix:hover{background:var(--accent)}
.vivier-carrousel{display:flex;flex-direction:column;gap:14px;padding-right:4px}
.groupe-vivier b{display:block;font-size:12.5px;margin-bottom:6px;color:var(--gris);
  font-weight:600}
.groupe-vivier.courant b{color:var(--encre)}
.rangee-vivier{display:flex;flex-wrap:wrap;gap:8px}
.vig-viv{position:relative;width:76px;cursor:grab}
.vig-viv img{width:76px;height:76px;object-fit:cover;border-radius:5px;display:block}
.vig-viv.prise img{outline:2px solid var(--encre);outline-offset:-2px}
/* UNE PHOTO NE SERT QU'UNE FOIS dans le feed, carrousels compris : celle qui
   est deja prise ailleurs s'efface et ne se glisse plus. Elle reste visible --
   savoir qu'elle existe et qu'elle est prise vaut mieux que la faire
   disparaitre, on la chercherait. */
.vig-viv.occupee{cursor:not-allowed}
.vig-viv.occupee img{opacity:.28;filter:grayscale(1)}
.vig-viv i{position:absolute;right:2px;top:2px;font:10px ui-monospace,monospace;
  font-style:normal;color:#fff;background:var(--gris);padding:1px 5px;
  border-radius:8px;pointer-events:none}
/* Deux usages ou plus : une anomalie d'avant la regle, a corriger a la main. */
.vig-viv i.doublon{background:var(--accent)}
@media(max-width:900px){
  .voile-carrousel{padding:10px}
  .modale-carrousel{width:100%;max-height:94vh}
  .corps-carrousel{grid-template-columns:1fr}
}

/* Réglages du post Instagram sous la légende : comptes à identifier, lieu.
   Ils ne font pas partie du texte — la zone se lit comme un panneau de
   réglages, pas comme une ligne de la caption. */
.pub-caption{display:flex;flex-direction:column;gap:6px}
.pub-caption label{font-size:12px;color:#8a8580;margin:0}
.jetons{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.jetons .jeton{padding:4px 12px;font-size:13px;border-radius:999px;
  background:transparent;border:1px solid #57534d;color:#c9c3bb}
.jetons .jeton.actif{background:#f2efeb;color:#1a1a1a;border-color:#f2efeb;font-weight:600}
.jetons .jeton.maitre{border-style:dashed}
.jetons .jeton:disabled{opacity:.5;cursor:default}
.page-caption .pub-caption input{background:#1b1b1b;color:#f2efeb;border-color:#333}
.page-caption.clair .jetons .jeton{border-color:var(--trait);color:var(--gris)}
.page-caption.clair .jetons .jeton.actif{background:var(--encre);color:#fff;border-color:var(--encre)}
.page-caption.clair .pub-caption input{background:#fff;color:var(--encre);border-color:var(--trait)}
.page-caption.clair .pub-caption label{color:var(--gris)}

/* Les listes de publication de la fiche client : dépliables, une ligne par
   élément, ajout et retrait à la main avant « Enregistrer la fiche ». */
.liste-pliable{border:1px solid var(--trait);border-radius:8px;padding:10px 14px}
.liste-pliable summary{cursor:pointer;font-weight:600}
.liste-pliable .element{display:flex;gap:6px;margin-top:8px;align-items:center}
.liste-pliable .element input{margin:0}
.liste-pliable .element button{padding:6px 11px;flex:none}
.liste-pliable > button{margin-top:10px}
/* Une liste de zones repetees hors du bloc pliable. Classe a part plutot que
   de rallonger `.liste-pliable .element` : ces regles-la gagneraient par
   ordre de cascade et changeraient l'alignement des listes pliables. */
.elements-libres .element{display:flex;gap:6px;margin-top:8px;align-items:flex-start}
.elements-libres .element textarea{margin:0;flex:1;min-height:64px}
.elements-libres .element button{padding:6px 11px;flex:none}

/* ---------- rotation du carrousel sur la grande photo ---------- */
/* Les fleches vivent SUR la photo, a mi-hauteur ; le rang en haut a gauche
   (la croix et les badges occupent deja les droites ailleurs). Tout est
   cache quand le post n'a pas de carrousel. */
.scene-photo{position:relative}
.fleche-car{position:absolute;top:50%;transform:translateY(-50%);width:36px;height:36px;
  padding:0;border:0;border-radius:50%;background:rgba(20,18,16,.55);color:#fff;
  font-size:23px;line-height:1;cursor:pointer;display:grid;place-items:center}
.fleche-car:hover{background:rgba(20,18,16,.85)}
.fleche-car.gauche{left:8px}
.fleche-car.droite{right:8px}
.rang-car{position:absolute;left:8px;top:8px;font:11px ui-monospace,monospace;color:#fff;
  background:rgba(20,18,16,.65);padding:2px 8px;border-radius:10px;pointer-events:none}

/* ---------- page des modeles ---------- */
table.modeles { width: 100%; border-collapse: collapse; }
table.modeles th, table.modeles td { text-align: left; padding: 6px 8px; vertical-align: middle; }
table.modeles tr + tr td { border-top: 1px solid rgba(0,0,0,.08); }
table.modeles input[type=text] { width: 100%; min-width: 220px; }
/* Le bloc pose sur une page d'etape porte une colonne d'etat sur plusieurs
   lignes (« force », le reglage general, le bouton). Centre, elle flotte au
   milieu d'une rangee deux fois plus haute que les autres. */
.modeles-etape table.modeles td { vertical-align: top; }
.modeles-etape table.modeles td.note { font-size: 12px; line-height: 1.45; }

/* ---------- l'embranchement feed / stories ---------- */
.etapes-arbre{display:flex;align-items:flex-start;gap:10px;margin:0 0 22px}
.etapes-arbre .etapes{margin:0}
.etapes-arbre .branches{display:flex;flex-direction:column;gap:6px;
                        border-left:2px solid var(--trait);padding-left:10px}
.etapes li.libelle{border:none;background:transparent;color:var(--gris);
                   padding-left:0;font-style:italic}
.etapes li.action{border:none;background:transparent;padding:0;display:flex;gap:8px;align-items:center}
.etapes li.action button{font-size:12px;padding:5px 11px}

/* ---------- revue des stories ---------- */
.stories-grille{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:12px;margin-bottom:18px}
.story{background:#fff;border:1px solid var(--trait);border-radius:var(--r);padding:8px}
.story.approved{border-color:var(--ok)}
.story img{width:100%;aspect-ratio:9/16;object-fit:cover;border-radius:6px;display:block}
.story .vide{aspect-ratio:9/16;display:flex;align-items:center;justify-content:center;color:var(--gris);font-size:12px}
.story .legende{font-size:12px;margin-top:6px}
.story .a-verifier{font-size:11px;color:var(--accent);margin-top:4px}
.story .raison{font-size:11px;margin-top:4px;line-height:1.3}
/* La vignette de reference doit RESTER PETITE : `.story img` la mettrait en
   pleine largeur et on ne saurait plus laquelle des deux images est la story. */
.story .reference{display:flex;align-items:center;gap:6px;margin-top:6px}
.story .reference img{width:34px;flex:0 0 34px;aspect-ratio:9/16;object-fit:cover;border-radius:4px}
.story .reference .note{font-size:11px;line-height:1.3}
.story .boutons{display:flex;gap:6px;margin-top:8px}
.story .boutons button{font-size:12px;padding:4px 10px}

/* ---------- le nommage des stories ---------- */
.stories-noms{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.nom-photo{display:flex;flex-direction:column;gap:4px}
.nom-photo img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:6px;display:block}
.nom-photo select,.nom-photo input{font-size:12px;padding:3px 5px;width:100%;box-sizing:border-box}
.nom-photo.feed img{border:2px solid var(--trait)}
.nom-photo .legende{font-size:12px;line-height:1.3}

/* ---------- l'identite graphique d'un client ---------- */
table.polices{width:100%;border-collapse:collapse;margin-top:8px}
table.polices th{text-align:left;font-size:12px;color:var(--gris);font-weight:600;padding:4px 8px 4px 0}
table.polices td{padding:8px 8px 8px 0;border-top:1px solid var(--trait);vertical-align:top;font-size:13px}
table.polices tr.manquante td{background:#fff5f5}
table.polices tr.derogee td{background:#fffaf0}
.maillon{font-size:12px;padding:2px 6px;border-radius:4px;background:#eef3ee;white-space:nowrap}
.maillon.manquant{background:#ffe5e5;color:#a11}
.maillon.derogation{background:#ffefd6;color:#8a5a00}
.ligne-role{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:0}
.ligne-role select{max-width:220px}
button.petit{font-size:11px;padding:2px 7px}
.puce{display:inline-flex;gap:6px;align-items:center;margin:0;font-size:12px;
  border:1px solid var(--trait);border-radius:20px;padding:3px 6px 3px 10px}
.element.couleur{display:flex;gap:6px;align-items:center}
.pastille{width:13px;height:13px;border-radius:3px;border:1px solid var(--trait);display:inline-block}
.apercu-logo{max-width:150px;max-height:70px;object-fit:contain;padding:6px;border-radius:6px}
/* Un asset de charte peut etre de n'importe quelle teinte : le fond de
   l'apercu est moitie sombre, moitie clair, pour qu'un logo blanc comme un
   logo noir se voient tous les deux. */
.apercu-asset{background:linear-gradient(90deg,#111 50%,#f4f4f4 50%)}

pre.convention{background:var(--papier,#faf9f7);border:1px solid var(--trait);border-radius:6px;
  padding:10px 12px;font-size:12.5px;line-height:1.55;overflow-x:auto;white-space:pre-wrap;margin:8px 0}
pre.convention b{font-weight:600}

.cellule-modele{display:flex;flex-direction:column;gap:4px;min-width:210px}
.cellule-modele .modele-libre[hidden]{display:none}

/* le refus d'un lien saisi, sous le champ fautif */
.erreur { color: #b3261e; font-size: 13px; margin: 4px 0 0; }

/* --- explorateur Dropbox --- */
.db-choix { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.db-vu { font-size: 12px; opacity: .75; word-break: break-all; }
/* Le poids passe AVANT l'adresse et se lit en premier : c'est lui qui engage
   -- l'adresse, on l'a choisie, on la reconnait. Il porte donc l'encre pleine
   la ou le chemin est attenue, et ne s'enroule pas. */
.db-poids { font-size: 12px; font-weight: 600; white-space: nowrap;
            padding: 2px 8px; border-radius: 20px;
            background: var(--fond); border: 1px solid var(--trait); }
.db-panneau { position: fixed; inset: 0; background: rgba(0,0,0,.35);
              display: flex; align-items: center; justify-content: center;
              z-index: 50; }
.db-boite { background: #fff; border-radius: 10px; width: min(560px, 92vw);
            max-height: 80vh; display: flex; flex-direction: column;
            padding: 16px; }
.db-tete { display: flex; gap: 10px; align-items: center; }
.db-tete code { flex: 1; font-size: 12px; word-break: break-all; }
.db-boite ul { list-style: none; margin: 8px 0; padding: 0; overflow-y: auto; }
.db-boite li { padding: 6px 4px; border-bottom: 1px solid #eee; }
.db-pied { display: flex; justify-content: flex-end; padding-top: 8px; }

/* Un champ que l'application vient de remplir a la place de l'utilisateur --
   la feuille recopiee depuis le videaste choisi. Sans ce battement, la valeur
   change sous les yeux sans qu'on sache d'ou elle vient. */
.vient-de-changer {
  background: #fff8d6;
  transition: background .6s ease-out;
}

/* Le champ d'ajout et son bouton, sur une ligne : le « + » appartient au
   champ, il ne doit pas flotter en dessous. */
.ligne-ajout { display: flex; gap: 6px; align-items: center; }
.ligne-ajout input { flex: 1; }
.ligne-ajout button { padding: 6px 12px; font-weight: 700; }
/* Les lignes d'essai, sous la branche stories : meme grammaire que les etapes,
   en plus discret -- un essai n'est pas une etape du parcours, il est a cote. */
.etapes.essai .libelle{opacity:.65}
.etapes.essai li{font-size:12px}
.liste-essais{list-style:none;padding:0;margin:8px 0}
.liste-essais li{padding:4px 0}
/* La grille de selection des photos, en haut de l'etape « noms ». Les
   vignettes sont petites a dessein : on choisit, on ne relit pas. */
.grille-selection{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:6px;
  max-height:340px;overflow-y:auto}
.photo-choix{position:relative;display:block;cursor:pointer;border-radius:5px;overflow:hidden;
  border:2px solid transparent;opacity:.35;transition:opacity .1s}
.photo-choix.retenue{opacity:1;border-color:var(--ok)}
.photo-choix img{width:100%;aspect-ratio:4/5;object-fit:cover;display:block}
.photo-choix input{position:absolute;top:4px;left:4px;margin:0}
/* L'annotation de relecture : discrete tant qu'elle est vide, lisible des
   qu'on y a ecrit. Elle doit inviter sans encombrer la planche. */
.story .annotation{width:100%;margin-top:6px;font-size:11px;line-height:1.35;
  border:1px solid var(--trait);border-radius:5px;padding:4px 6px;resize:vertical;font-family:inherit}
.story .annotation:placeholder-shown{opacity:.5}
.story .annotation:focus{opacity:1;border-color:var(--accent)}
/* La vignette d'une story s'agrandit au clic : le curseur doit le dire, sinon
   personne ne devine qu'elle est cliquable. */
.story img.agrandir{cursor:zoom-in}
/* Le panneau des essais en deux temps : les deux images cote a cote, et sous
   elles le champ qui commande chacune. */
.panneau-corps{background:var(--carte);border-radius:12px;max-width:1100px;width:94vw;
  max-height:92vh;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:14px}
.panneau-images{display:flex;gap:14px;justify-content:center}
.panneau-images figure{margin:0;text-align:center;flex:1 1 0;min-width:0}
.panneau-images img{width:100%;max-height:52vh;object-fit:contain;border-radius:8px;
  background:#111;display:block}
.panneau-images figcaption{font-size:12px;color:var(--gris);margin-top:5px}
.panneau-champs{display:flex;flex-direction:column;gap:10px}
.panneau-champs label{font-size:13px;display:flex;flex-direction:column;gap:4px}
.panneau-champs textarea{width:100%;font:13px/1.4 inherit;padding:6px 8px;
  border:1px solid var(--trait);border-radius:6px;resize:vertical}
/* La poignee de deplacement, c'est l'en-tete lui-meme : il fige au clic et
   deplace au glisser. `.cible` marque l'en-tete survole pendant le glisser --
   sans lui on lache a l'aveugle, les en-tetes de ligne font 22 px de large. */
.tete[draggable]{cursor:grab}
.tete[draggable]:active{cursor:grabbing}
.tete.cible{background:var(--encre);color:var(--papier)}
.plateau.sombre .tete.cible{background:#fff;color:#141210}
.grille-refs{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px;
  max-height:56vh;overflow:auto;margin:12px 0}
.grille-refs .ref{display:block;text-align:center;cursor:pointer}
.grille-refs .ref img{width:100%;border-radius:6px;display:block}
.grille-refs .ref input{margin-bottom:4px}

/* --- Les calques de l'ecran identite ------------------------------------
   Meme motif que `.voile-carrousel` : un calque plein ecran, pose en fin de
   page et non dans la carte qui l'ouvre -- sinon il heriterait du pli de sa
   section. `[hidden]` porte deja `!important` (ligne 49), la bascule suffit.
   ⚠️ Ces calques-la s'ouvrent en RETIRANT `hidden`, pas en posant `.ouvert` :
   il leur faut donc `display:flex` par defaut. Ne JAMAIS le redonner a `.voile`
   tout court -- la regle gagnerait sur le `display:none` de la ligne 426 et
   TOUS les voiles de l'app (conso, loupe, choix de nom) resteraient ouverts,
   collant un ecran gris impossible a fermer par-dessus la page. D'ou `.calque`. */
.voile.calque{z-index:70;background:rgba(20,18,16,.62);display:flex;padding:24px}
/* Le panneau passe au-dessus des calques : sa regle vient donc APRES la leur,
   a specificite egale c'est l'ordre qui tranche. */
.voile.panneau{z-index:76}
.modale{width:min(760px,94vw);max-height:88vh;display:flex;flex-direction:column;
  gap:10px;box-shadow:0 24px 70px rgba(0,0,0,.4)}
.tete-modale{display:flex;align-items:center;gap:12px}
.tete-modale .croix-modale{margin-left:auto}
/* C'est le CORPS qui defile : le titre et la croix restent en vue. */
.corps-modale{overflow:auto;min-height:0}
.corps-modale>div:first-child{margin-top:0!important;border-top:0!important;padding-top:0!important}

.modale-image{position:relative;display:flex;flex-direction:column;align-items:center;gap:8px}
.modale-image .croix-modale{position:absolute;top:-6px;right:-6px;z-index:1}
.modale-image .note{color:#fff}
/* ⚠️ UN LOGO N'A PAS DE FOND. Pose a meme le voile sombre, une version
   blanche disparait ; sur un fond clair, c'est la version noire qui
   disparait. Le damier montre la transparence au lieu de la trahir. */
.damier{--c:rgba(0,0,0,.08);background-color:#fff;border-radius:8px;padding:18px;
  background-image:linear-gradient(45deg,var(--c) 25%,transparent 25%,transparent 75%,var(--c) 75%),
                   linear-gradient(45deg,var(--c) 25%,transparent 25%,transparent 75%,var(--c) 75%);
  background-size:22px 22px;background-position:0 0,11px 11px}
.damier img{display:block;max-width:min(680px,80vw);max-height:66vh;object-fit:contain}
.apercu-asset{cursor:zoom-in}

.ajout-police{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:14px}

/* --- le detail d'une story dans le panneau de revue ---------------------
   D'ou elle part, avec quoi elle a ete composee. Deux colonnes tant qu'il y
   a la place, l'une sous l'autre sur un ecran etroit. */
.pan-detail:empty{display:none}
.pan-detail{display:flex;gap:18px;flex-wrap:wrap;
  border-top:1px solid var(--trait);border-bottom:1px solid var(--trait);
  padding:12px 0;font-size:13px}
.pan-detail>div{flex:1 1 260px;min-width:0;display:flex;flex-direction:column;gap:4px}
.pan-nom{font-weight:600}
/* Les vignettes de reference defilent a l'horizontale : vingt references ne
   doivent pas pousser les champs de la modale hors de l'ecran. */
.bande-refs{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px}
.bande-refs figure{margin:0;width:72px;flex:0 0 auto;text-align:center}
.bande-refs img{width:72px;aspect-ratio:9/16;object-fit:cover;border-radius:4px;display:block}
.bande-refs figcaption{font-size:11px;word-break:break-word}
