/* =============================================================================
   Studio — design system "Montage sombre" (phase 6, refonte UI).
   Tout est self-hosted : aucune URL externe, aucun CDN. Servi par StaticFiles.

   Structure :
     1. Jetons de thème (charbon) + teinte de marque (accents seulement)
     2. Base + typographie
     3. Topbar
     4. Boutons / chips / champs
     5. Layout 2 volets + cartes
     6. Cartes de scène (accordéon + résumé)
     7. Galerie de presets
     8. Prévisu live (canvas ratio + texte + ruban garde-fou)
     9. Tiroir overlay (recherche + catégories + grille de vignettes)
    10. Vignettes : animations (Aa), effets (pastilles), transitions (A|B)
    11. Moteur d'animations (keyframes partagées prévisu/vignettes)
    12. Démos de transition (par famille)
    13. File de tâches vivante + pastilles de statut + quota
    14. Connexion
    15. Responsive + prefers-reduced-motion
   ========================================================================== */

/* ------------------------------------------------------------------ 1. jetons */
:root {
  color-scheme: dark;

  --bg:        #0d0f12;
  --surface:   #16191e;
  --surface-2: #1c2026;
  --surface-3: #232833;
  --line:      #2a2f37;
  --line-2:    #363c48;

  --text:      #e7eaee;
  --text-muted:#9aa2ad;
  --text-dim:  #6b7280;

  /* Accent : neutre par défaut, écrasé par la marque active (JS -> --accent). */
  --accent:        #6c8cff;
  --accent-2:      #8a6cff;
  --accent-ink:    #0b0d10;   /* texte lisible SUR l'accent */
  --accent-soft:   color-mix(in srgb, var(--accent) 16%, transparent);
  --accent-ring:   color-mix(in srgb, var(--accent) 55%, transparent);

  --ok:    #35c48a;
  --warn:  #e3b23c;
  --danger:#e5595b;
  --info:  #5a9bff;

  --radius:   14px;
  --radius-sm: 9px;
  --radius-xs: 6px;
  --gap:      16px;
  --shadow:   0 10px 30px -12px rgba(0,0,0,.6);
  --shadow-lg:0 24px 60px -18px rgba(0,0,0,.75);

  /* Couleurs de prévisu (palette de marque, injectées par JS ; défauts neutres). */
  --pv-bg:        #1c2026;
  --pv-surface:   #232833;
  --pv-primary:   #6c8cff;
  --pv-secondary: #8a6cff;
  --pv-accent:    #35c48a;
  --pv-text:      #f2f4f8;
  --pv-text-muted:#aab2c0;

  --ease-out: cubic-bezier(.215,.61,.355,1);
}

/* ------------------------------------------------------------------ 2. base */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background:
    radial-gradient(1200px 600px at 78% -8%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 60%),
    radial-gradient(900px 500px at -6% 4%, color-mix(in srgb, var(--accent-2) 7%, transparent), transparent 55%),
    var(--bg);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -.01em; }
::selection { background: var(--accent-soft); }
:focus-visible { outline: 2px solid var(--accent-ring); outline-offset: 2px; border-radius: 4px; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.small { font-size: .86rem; }
.mono { font-variant-numeric: tabular-nums; }
.hidden { display: none !important; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* amélioration progressive : .enh = seulement si JS ; .nojs = repli sans JS.
   On garde le display naturel de chaque élément (pas de revert cassant les flex). */
html:not(.js) .enh { display: none !important; }
html.js .nojs { display: none !important; }

/* ------------------------------------------------------------------ 3. topbar */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 12px 20px;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.brand-mark { display: flex; align-items: center; gap: 10px; font-weight: 800; font-size: 1.12rem; letter-spacing: -.02em; }
.brand-mark .logo {
  width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-ink); font-size: 1rem; box-shadow: 0 4px 14px -4px var(--accent);
}
.topbar .spacer { flex: 1 1 auto; }
.topbar .tb-group { display: flex; align-items: center; gap: 9px; }
.topbar .tb-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-dim); }
.usernav { display: flex; align-items: center; gap: 10px; font-size: .9rem; }
.avatar {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-3); border: 1px solid var(--line-2); font-weight: 700; font-size: .82rem;
  color: var(--text);
}

/* ------------------------------------------------------------------ 4. controls */
button, .btn { font: inherit; }
.btn {
  display: inline-flex; align-items: center; gap: 8px; justify-content: center;
  padding: 10px 16px; border-radius: var(--radius-sm); cursor: pointer;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text);
  transition: transform .12s ease, background .15s ease, border-color .15s ease, box-shadow .15s ease;
  font-weight: 600; text-decoration: none;
}
.btn:hover { background: var(--surface-3); border-color: var(--line-2); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-ink); border-color: transparent;
  box-shadow: 0 8px 22px -10px var(--accent);
}
.btn-primary:hover { filter: brightness(1.06); background: linear-gradient(135deg, var(--accent), var(--accent-2)); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
.btn-sm { padding: 7px 11px; font-size: .86rem; border-radius: var(--radius-xs); }
.btn-icon {
  width: 34px; height: 34px; padding: 0; border-radius: 9px; display: grid; place-items: center;
}
.btn svg { width: 1.05em; height: 1.05em; }

/* champs natifs (repli sans-JS + fond de secours) */
input[type="text"], input[type="number"], input[type="password"], select, textarea {
  width: 100%; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line-2); font: inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent-ring);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa2ad' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px;
  padding-right: 34px;
}
label.field-label {
  display: block; margin: 12px 0 6px; font-weight: 600; font-size: .82rem;
  color: var(--text-muted); letter-spacing: .01em;
}
input[type="range"] { accent-color: var(--accent); }

/* chip radiogroup (façade des <select> masqués) */
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text);
  font-size: .88rem; font-weight: 600; user-select: none;
  transition: border-color .15s ease, background .15s ease, transform .12s ease, color .15s ease;
}
.chip:hover { border-color: var(--line-2); background: var(--surface-3); transform: translateY(-1px); }
.chip[aria-checked="true"], .chip.is-active {
  border-color: var(--accent); background: var(--accent-soft); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--accent-ring);
}
.chip .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }

/* pastille "valeur courante" + bouton parcourir (ligne de banque) */
.axis-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.axis-row > .axis-name { min-width: 116px; font-size: .82rem; font-weight: 600; color: var(--text-muted); }
.value-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px 7px 10px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text);
  font-weight: 600; font-size: .88rem; cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.value-chip:hover { border-color: var(--accent-ring); background: var(--surface-2); }
.value-chip .mini { width: 26px; height: 18px; border-radius: 5px; overflow: hidden; flex: none;
  background: var(--surface-3); border: 1px solid var(--line); position: relative; }
.value-chip .caret { color: var(--text-dim); }

/* segmented / format chips */
.format-chips { display: inline-flex; gap: 6px; }
.fmt-chip {
  --w: 30px; --h: 20px;
  display: inline-flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 9px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text-muted);
  font-size: .7rem; font-weight: 700;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.fmt-chip .glyph { width: var(--w); height: var(--h); border-radius: 3px; background: var(--surface-3);
  border: 1px solid var(--line-2); }
.fmt-chip[data-fmt="9:16"] .glyph { --w: 13px; --h: 22px; }
.fmt-chip[data-fmt="1:1"] .glyph { --w: 20px; --h: 20px; }
.fmt-chip[aria-pressed="true"] { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.fmt-chip[aria-pressed="true"] .glyph { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 30%, var(--surface-3)); }

/* ------------------------------------------------------------------ 5. layout */
main { padding: 22px 0 60px; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 8px 2px 18px; flex-wrap: wrap; }
.page-head h1 { font-size: 1.5rem; }
.page-head p { margin: 4px 0 0; }

.editor-grid { display: grid; grid-template-columns: minmax(0,1fr) 400px; gap: 22px; align-items: start; }
.card {
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface) 96%, var(--accent) 4%), var(--surface));
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
}
.card-pad { padding: 18px; }
.section-title { display: flex; align-items: center; gap: 9px; font-size: 1.02rem; margin-bottom: 12px; }
.section-title .count { font-size: .74rem; font-weight: 700; color: var(--text-dim);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 2px 9px; }
.stack-col { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 16px; }

/* ------------------------------------------------------------------ 8. preview */
.preview-card { padding: 14px; }
.preview-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.preview-head .lbl { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-dim); }
.preview-stage { display: grid; place-items: center; background:
  repeating-conic-gradient(#000 0% 25%, #0b0d10 0% 50%) 50% / 18px 18px;
  border-radius: var(--radius-sm); padding: 14px; border: 1px solid var(--line); }
.canvas {
  --ratio: 16/9;
  aspect-ratio: var(--ratio);
  width: 100%; max-height: 340px; position: relative; overflow: hidden;
  border-radius: 8px; display: grid; place-items: center;
  background: var(--pv-bg); box-shadow: var(--shadow-lg);
}
.canvas.f-16-9 { --ratio: 16/9; width: 100%; }
.canvas.f-9-16 { --ratio: 9/16; width: auto; height: 340px; }
.canvas.f-1-1  { --ratio: 1/1;  width: auto; height: 320px; }
/* repli si aspect-ratio non supporté (moteurs anciens) : le 16:9 ne s'effondre pas */
@supports not (aspect-ratio: 1 / 1) {
  .canvas.f-16-9 { height: 0; padding-bottom: 56.25%; }
}
.canvas .bg-layer { position: absolute; inset: 0; }
.canvas .fx-layer { position: absolute; inset: 0; pointer-events: none; }
.canvas .safe {
  position: relative; width: 100%; height: 100%; display: grid; place-items: center;
  padding: 8.9%; text-align: center;
}
.canvas .pv-text { position: absolute; left: 8.9%; right: 8.9%; text-align: center; }
.canvas .pv-title { font-weight: 800; line-height: 1.05; color: var(--pv-text);
  text-shadow: 0 2px 8px rgba(0,0,0,.35); word-break: break-word; }
.canvas .pv-sub { font-weight: 500; color: var(--pv-text-muted); line-height: 1.15; }
.canvas .placeholder-note { color: var(--pv-text-muted); font-size: .8rem; opacity: .7; }

.token-ribbon {
  display: none;
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  background: color-mix(in srgb, var(--warn) 22%, #000); color: #ffdf9e;
  font-size: .68rem; font-weight: 600; padding: 4px 8px; text-align: center;
  border-top: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
}
body[data-unfilled="1"] .token-ribbon { display: block; }

.preview-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; gap: 10px; }
.scene-nav { display: flex; align-items: center; gap: 8px; font-size: .84rem; color: var(--text-muted); }
.scene-nav .sn-pos { min-width: 78px; text-align: center; font-weight: 600; color: var(--text); }
.preview-hint { font-size: .72rem; color: var(--text-dim); text-align: center; margin-top: 8px; }
.submit-row { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.submit-row .btn-primary { width: 100%; padding: 13px; font-size: .98rem; }

/* mètre de quota */
.quota { display: flex; align-items: center; gap: 8px; font-size: .82rem; color: var(--text-muted); }
.quota .bar { flex: 1; height: 7px; border-radius: 999px; background: var(--surface-3); overflow: hidden; border: 1px solid var(--line); }
.quota .bar > i { display: block; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-2)); border-radius: 999px; transition: width .4s ease; }
.quota.q-full .bar > i { background: linear-gradient(90deg, var(--warn), var(--danger)); }

/* ------------------------------------------------------------------ 9. drawer */
.scrim {
  position: fixed; inset: 0; z-index: 60; background: rgba(4,6,10,.55);
  opacity: 0; visibility: hidden; transition: opacity .22s ease, visibility .22s ease;
  backdrop-filter: blur(2px);
}
.scrim.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 61; width: min(560px, 94vw);
  background: var(--surface); border-left: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg); transform: translateX(100%);
  /* `visibility: hidden` (comme .scrim) : hors écran ne suffit pas, les boutons du
     tiroir fermé resteraient dans l'ordre de tabulation — l'utilisateur clavier tomberait
     dans une grille invisible en bas de page. La transition la retarde jusqu'à la fin du
     glissement, l'animation de sortie est préservée. */
  visibility: hidden;
  transition: transform .26s cubic-bezier(.22,.61,.36,1), visibility .26s;
  display: flex; flex-direction: column;
}
.drawer.open { transform: translateX(0); visibility: visible; }
.drawer-head { padding: 16px 18px 12px; border-bottom: 1px solid var(--line); }
.drawer-head .dh-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.drawer-head h3 { font-size: 1.05rem; }
.drawer-search { position: relative; margin-top: 12px; }
.drawer-search input { padding-left: 36px; }
.drawer-search svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-dim); }
.drawer-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }
.drawer-tab {
  padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line-2); background: transparent;
  color: var(--text-muted); font-size: .8rem; font-weight: 600; cursor: pointer;
}
.drawer-tab[aria-pressed="true"] { background: var(--accent-soft); color: var(--text); border-color: var(--accent-ring); }
.drawer-body { padding: 16px 18px 24px; overflow-y: auto; flex: 1; }
.vgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; }
.vig {
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface-2);
  cursor: pointer; overflow: hidden; padding: 0; color: inherit; text-align: center;
  transition: border-color .15s ease, transform .12s ease, box-shadow .15s ease;
}
.vig:hover { border-color: var(--accent-ring); transform: translateY(-2px); box-shadow: var(--shadow); }
.vig[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.vig .demo { height: 74px; position: relative; overflow: hidden; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--surface-3), var(--surface)); }
.vig .vname { font-size: .76rem; font-weight: 600; padding: 7px 6px; border-top: 1px solid var(--line); }
.vig .vcat { font-size: .64rem; color: var(--text-dim); padding-bottom: 6px; margin-top: -4px; }
.drawer-empty { text-align: center; color: var(--text-muted); padding: 40px 0; }

/* ------------------------------------------------------------------ 10. vignettes */
/* animation : glyphe "Aa" qui rejoue le mouvement */
.demo-glyph { font-weight: 900; font-size: 1.5rem; color: var(--pv-text); letter-spacing: -.02em;
  will-change: transform, opacity; }
.vig .demo.anim-demo { background: linear-gradient(135deg, #202632, #171b22); }

/* effet : pastille de démonstration (fond + calque overlay) */
.fx-tile { width: 100%; height: 100%; position: relative;
  background:
    linear-gradient(135deg, #7c8cff 0%, #b06cff 45%, #ff8f6c 100%); }
.fx-tile .fx-photo { position: absolute; inset: 0;
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,.5), transparent 40%),
    radial-gradient(circle at 70% 68%, rgba(0,0,0,.35), transparent 45%),
    linear-gradient(135deg, #6d7cf0, #b464e6 55%, #f0925f); }
.fx-tile .fx-overlay { position: absolute; inset: 0; pointer-events: none; }

/* transition : deux demi-cadres A|B */
.tdemo { position: relative; width: 100%; height: 100%; overflow: hidden; }
.tdemo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ------------------------------------------------------------------ 11. anim engine */
/* fondu d'entrée partagé (opacité) */
@keyframes sFade { 0% { opacity: 0; } 35% { opacity: 1; } 100% { opacity: 1; } }
@keyframes sFadeSlow { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 1; } }
/* glissé générique : part de (--a-tx,--a-ty), rejoint 0 à ~35 % puis tient */
@keyframes sSlide {
  0%   { transform: translate(var(--a-tx,0), var(--a-ty,0)); }
  35%  { transform: translate(0,0); }
  100% { transform: translate(0,0); }
}
/* distances en em -> mêmes keyframes fidèles pour le petit glyphe et le grand titre */
@keyframes sBounceUp {
  0%{transform:translateY(.45em)}5%{transform:translateY(0)}12%{transform:translateY(.27em)}
  20%{transform:translateY(0)}27%{transform:translateY(.14em)}33%{transform:translateY(0)}
  39%{transform:translateY(.05em)}45%{transform:translateY(0)}100%{transform:translateY(0)}
}
@keyframes sBounceIn {
  0%{transform:translateX(.58em)}5%{transform:translateX(0)}12%{transform:translateX(.36em)}
  20%{transform:translateX(0)}27%{transform:translateX(.18em)}33%{transform:translateX(0)}
  39%{transform:translateX(.05em)}45%{transform:translateX(0)}100%{transform:translateX(0)}
}
@keyframes sElasticUp {
  0%{transform:translateY(.36em)}8%{transform:translateY(-.14em)}18%{transform:translateY(.09em)}
  28%{transform:translateY(-.05em)}38%{transform:translateY(.04em)}48%{transform:translateY(0)}100%{transform:translateY(0)}
}
@keyframes sElasticIn {
  0%{transform:translateX(.45em)}8%{transform:translateX(-.18em)}18%{transform:translateX(.09em)}
  28%{transform:translateX(-.05em)}38%{transform:translateX(.04em)}48%{transform:translateX(0)}100%{transform:translateX(0)}
}
@keyframes sDriftLeft { 0%{transform:translateX(.24em)} 100%{transform:translateX(-.24em)} }
@keyframes sDriftRight { 0%{transform:translateX(-.24em)} 100%{transform:translateX(.24em)} }
@keyframes sFloat { 0%{transform:translateY(-.16em)} 50%{transform:translateY(.16em)} 100%{transform:translateY(-.16em)} }

/* application : un élément .anim-run rejoue selon [data-anim] + custom props */
.anim-run { opacity: 1; }
.anim-run.play-fade      { animation: sFade var(--a-dur,2s) ease-in-out both; }
.anim-run.play-fadeslow  { animation: sFadeSlow var(--a-dur,3s) ease-in-out both; }
.anim-run.play-slide     { animation: sFade var(--a-dur,2s) ease-in-out both, sSlide var(--a-dur,2s) var(--a-ease, var(--ease-out)) both; }
.anim-run.play-bounce-up { animation: sFade 2s ease-in-out both, sBounceUp 2s linear both; }
.anim-run.play-bounce-in { animation: sFade 2s ease-in-out both, sBounceIn 2s linear both; }
.anim-run.play-elastic-up{ animation: sFade 2s ease-in-out both, sElasticUp 2s linear both; }
.anim-run.play-elastic-in{ animation: sFade 2s ease-in-out both, sElasticIn 2s linear both; }
.anim-run.play-drift-left { animation: sFade 2s ease-in-out both, sDriftLeft 3s linear infinite alternate; }
.anim-run.play-drift-right{ animation: sFade 2s ease-in-out both, sDriftRight 3s linear infinite alternate; }
.anim-run.play-float     { animation: sFloat 2s linear infinite alternate; }

/* ------------------------------------------------------------------ 12. tuiles de transition (phase 4)
   L'aperçu n'est plus une simulation CSS : chaque tuile est un .webp animé rendu
   par le MOTEUR lui-même (scripts/transitions-usine/fabriquer-serveur.sh — xfade
   réel pour les 45, fenêtre maskedmerge réelle pour les masques). Les tuiles
   bouclent en continu, comme le panneau du socle CapCut (EVALUATION-REPOS §5). */
.tdemo--tuile img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* repli VISIBLE si une tuile manque (le miroir a une épreuve, ceci est la ceinture) */
.tdemo--generic { display: grid; place-items: center; background: linear-gradient(135deg,#232a38,#171b22); }
.tdemo--generic .gicon { font-size: 1.4rem; opacity: .85; }

/* ------------------------------------------------------------------ 13. queue */
.tasks { margin-top: 26px; }
.tasks-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.tasks-head .live-dot { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; color: var(--text-muted); }
.tasks-head .live-dot i { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 0 var(--ok); animation: pulse 1.8s infinite; }
@keyframes pulse { 0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 60%,transparent)} 70%{box-shadow:0 0 0 7px transparent} 100%{box-shadow:0 0 0 0 transparent} }
.task-list { display: grid; gap: 10px; }
.task {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2);
}
.task .t-when { font-size: .82rem; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.task .t-main { min-width: 0; }
.task .t-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.task .t-brand { font-weight: 700; font-size: .9rem; }
.tag { font-size: .72rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line-2); color: var(--text-muted); }
.tag.preview { color: var(--info); border-color: color-mix(in srgb, var(--info) 40%, transparent); }
.tag.final { color: var(--accent); border-color: var(--accent-ring); }
/* Le format du TRAVAIL (déclinaison, chantier 6) : sans lui, trois « final » du même
   projet se ressemblent et on télécharge le mauvais. */
.tag.fmt { font-family: var(--mono, monospace); letter-spacing: .02em; }

/* --- choix des formats à l'export (chantier 6 : un travail par format) --- */
.export-wrap { position: relative; display: inline-flex; }
.export-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 70; width: 300px;
  padding: 14px 16px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface) 96%, var(--accent) 4%), var(--surface));
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.em-title { font-weight: 800; font-size: .95rem; margin-bottom: 10px; }
.em-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; cursor: pointer; }
.em-row input { accent-color: var(--accent); }
.em-note { font-size: .78rem; color: var(--text-dim); margin: 10px 0; }
.em-note.em-err { color: var(--danger); }
.em-go { width: 100%; }
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; }
.pill .sp { width: 9px; height: 9px; border-radius: 50%; }
.pill.st-done { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.pill.st-done .sp { background: var(--ok); }
.pill.st-running { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.pill.st-running .sp { background: var(--warn); animation: spin 1s linear infinite; border-radius: 2px; }
.pill.st-queued { background: color-mix(in srgb, var(--info) 16%, transparent); color: var(--info); }
.pill.st-queued .sp { background: var(--info); animation: pulse 1.6s infinite; }
.pill.st-failed, .pill.st-rejected { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.pill.st-failed .sp, .pill.st-rejected .sp { background: var(--danger); }
@keyframes spin { to { transform: rotate(360deg); } }
.task .t-actions { display: flex; align-items: center; gap: 8px; }
.task video { width: 190px; max-height: 240px; border-radius: 8px; display: block; background: #000; border: 1px solid var(--line); }
.task-expand { grid-column: 1 / -1; display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; padding-top: 4px; }
.task-empty { padding: 26px; text-align: center; color: var(--text-muted); border: 1px dashed var(--line-2); border-radius: var(--radius-sm); }
.error-note { color: var(--danger); font-size: .8rem; }

.banner-warn {
  display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warn) 12%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
  color: #ffe0a3; font-size: .88rem;
}
.banner-danger {
  display: flex; gap: 10px; align-items: flex-start; padding: 14px 16px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 12%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);
  color: #ffc9c9;
}

/* ------------------------------------------------------------------ 14. login */
.login-hero {
  max-width: 520px; margin: 8vh auto 0; text-align: center; padding: 40px 28px;
}
.login-hero .logo-xl {
  width: 74px; height: 74px; margin: 0 auto 22px; border-radius: 20px; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: var(--accent-ink);
  font-size: 2rem; box-shadow: 0 18px 50px -14px var(--accent);
}
.login-hero h1 { font-size: 2rem; margin-bottom: 10px; }
.login-hero p { color: var(--text-muted); margin: 0 auto 8px; max-width: 40ch; }
.login-hero .btn-primary { margin-top: 22px; padding: 13px 26px; font-size: 1rem; }
.login-hero .footnote { margin-top: 26px; font-size: .8rem; color: var(--text-dim); }

/* ------------------------------------------------------------------ 15. responsive + a11y */
@media (max-width: 900px) {
  .editor-grid { grid-template-columns: 1fr; }
  .stack-col { position: static; }
  .task { grid-template-columns: 1fr; align-items: flex-start; }
  .task .t-actions { flex-wrap: wrap; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* =============================================================================
   16. Éditeur de projet (chantier 1) — coque d'application
   -----------------------------------------------------------------------------
   L'éditeur n'est pas une page qui défile : c'est une coque de hauteur fixe.
   Seul le panneau de propriétés défile. C'est ce qui le sépare visuellement du
   formulaire de la phase 6, et ce qui garde l'aperçu toujours visible.
   ========================================================================== */
body.app-shell {
  height: 100dvh; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column;
}
:root { --topbar-h: 58px; --strip-h: 148px; --cmd-h: 56px; --props-w: 372px; }

.topbar-app {
  position: static; flex: none; height: var(--topbar-h);
  gap: 12px; padding: 0 13px; flex-wrap: nowrap; overflow: visible;
}
.logo-sq {
  width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex: none;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-ink); font-size: .95rem; text-decoration: none;
  box-shadow: 0 4px 14px -4px var(--accent);
}
.logo-sq:hover { text-decoration: none; filter: brightness(1.08); }
.tb-sep { width: 1px; height: 24px; background: var(--line); flex: none; }
.kindbadge {
  font-size: .68rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; flex: none;
  border: 1px solid var(--accent-ring); color: var(--text); background: var(--accent-soft);
  text-transform: uppercase; letter-spacing: .05em;
}
.badge-n {
  min-width: 17px; height: 17px; padding: 0 5px; border-radius: 999px; font-size: .68rem;
  font-weight: 800; display: inline-grid; place-items: center;
  background: var(--warn); color: #201803;
}

/* pastille de marque + menu */
.brand-pick { position: relative; flex: none; }
.brand-btn {
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px 6px 7px;
  border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface);
  color: var(--text); font-weight: 600; font-size: .86rem; cursor: pointer;
}
.brand-btn:hover { border-color: var(--accent-ring); }
.brand-btn[data-single="true"] { cursor: default; }
.bdot {
  width: 15px; height: 15px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--pv-primary), var(--pv-accent));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pv-primary) 30%, transparent);
}
.caret { color: var(--text-dim); font-size: .7rem; }
.menu {
  position: absolute; top: calc(100% + 8px); left: 0; min-width: 236px; z-index: 60;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 6px; display: none;
}
.menu.open { display: block; }
.menu .mi {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--radius-sm);
  color: var(--text); font-size: .88rem; text-decoration: none;
}
.menu .mi:hover { background: var(--surface-2); text-decoration: none; }
.menu .mi[aria-current="true"] { background: var(--accent-soft); font-weight: 700; }
.menu .mi .sw { width: 20px; height: 20px; border-radius: 6px; flex: none; border: 1px solid var(--line-2); }
.menu .mhead {
  padding: 8px 10px 4px; font-size: .69rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-dim);
}

.pname { flex: 0 1 auto; min-width: 0; }
.pname input {
  border: 1px solid transparent; background: transparent; font-weight: 700; font-size: .98rem;
  padding: 5px 8px; border-radius: var(--radius-sm); width: 22ch; max-width: 24vw;
}
.pname input:hover { border-color: var(--line-2); background: var(--surface); }
.pname input:focus { border-color: var(--accent-ring); background: var(--surface); }

/* chips de format (aussi utilisées dans la fenêtre « nouveau projet ») */
.fmt { display: inline-flex; gap: 5px; flex: none; }
.fmt button, .fmtpick label {
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 4px 8px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text-muted);
  font-size: .66rem; font-weight: 700;
}
.fmt button .glyph, .fmtpick .glyph {
  width: 24px; height: 16px; border-radius: 3px; background: var(--surface-3);
  border: 1px solid var(--line-2); display: block;
}
.glyph.f-9-16 { width: 10px; height: 18px; }
.glyph.f-1-1  { width: 16px; height: 16px; }
.fmt button[aria-pressed="true"], .fmtpick label:has(input:checked) {
  border-color: var(--accent); color: var(--text); background: var(--accent-soft);
}
.fmt button[aria-pressed="true"] .glyph, .fmtpick label:has(input:checked) .glyph {
  border-color: var(--accent); background: color-mix(in srgb, var(--accent) 30%, var(--surface-3));
}
.fmtpick { display: flex; gap: 6px; }
.fmtpick input { position: absolute; opacity: 0; pointer-events: none; }

.savestate {
  display: inline-flex; align-items: center; gap: 6px; font-size: .79rem;
  color: var(--text-muted); min-width: 116px; flex: none;
}
.savestate .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); }
.savestate[data-state="saving"] .dot { background: var(--warn); animation: sv 1s infinite; }
.savestate[data-state="error"] .dot { background: var(--danger); }
.savestate[data-state="error"] { color: var(--danger); }
@keyframes sv { 0%{opacity:1} 50%{opacity:.25} 100%{opacity:1} }

/* ------------------------------------------------------------- corps de l'éditeur */
.editor {
  flex: 1 1 auto; min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--props-w);
  grid-template-rows: minmax(0, 1fr) var(--strip-h) var(--cmd-h);
  /* Repère de la réponse d'agent (.cmdreply), posée en surimpression au-dessus de la
     barre de commande plutôt qu'en quatrième rangée. */
  position: relative;
}
.stage {
  grid-column: 1; grid-row: 1; position: relative; display: grid; place-items: center;
  padding: 20px; min-height: 0;
  background: repeating-conic-gradient(#0a0c10 0% 25%, #0d1015 0% 50%) 50% / 20px 20px;
}
.stage-inner {
  display: flex; flex-direction: column; align-items: center; gap: 11px;
  height: 100%; min-height: 0; justify-content: center;
}
.stage-tools { position: absolute; right: 13px; top: 13px; display: flex; gap: 6px; z-index: 2; }
.stage-tools .btn-icon[aria-pressed="true"] { background: var(--accent-soft); color: var(--text); }
.stage-note { position: absolute; left: 13px; bottom: 9px; font-size: .69rem; color: var(--text-dim); }
.stage-foot { display: flex; align-items: center; gap: 12px; font-size: .83rem; color: var(--text-muted); flex: none; }
.stage-foot .pos { min-width: 108px; text-align: center; font-weight: 600; color: var(--text); }

/* le cadre de rendu */
.canvas {
  position: relative; overflow: hidden; border-radius: 10px; box-shadow: var(--shadow-lg);
  background: var(--pv-bg); flex: 0 1 auto; max-width: 100%;
}
.canvas[data-f="16:9"] { aspect-ratio: 16/9; width: auto;
  height: min(100%, calc((100vw - var(--props-w) - 80px) * .5625)); }
.canvas[data-f="9:16"] { aspect-ratio: 9/16; height: 100%; width: auto; }
.canvas[data-f="1:1"]  { aspect-ratio: 1/1;  height: 100%; width: auto; }
.canvas .bg { position: absolute; inset: 0; background-size: cover; background-position: center; }
.canvas #cvVideo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.canvas .fx, .canvas .scrimlayer { position: absolute; inset: 0; pointer-events: none; }
/* ZONE SÛRE — quatre bords distincts, posés par editor.js depuis `geometrie.pour_editeur()`.
   Ils étaient écrits `inset: 8.89%`, c'est-à-dire 96 px sur base 1080, et c'était faux de
   deux façons. D'abord un pourcentage se résout sur la LARGEUR à gauche et à droite, sur la
   HAUTEUR en haut et en bas : en 16:9 la marge horizontale valait 170,7 px pour 96 px au
   rendu. Ensuite ce nombre ignorait les réserves de plateforme de B3 : en 9:16 l'aperçu
   annonçait 170,7 px de réserve basse là où le rendu en garde 480. L'aperçu était donc plus
   permissif que le rendu, exactement là où le rendu protège le plus.
   Les valeurs de repli ci-dessous ne servent qu'au cas où le JS n'a pas encore peint. */
.canvas .safezone {
  position: absolute;
  top: var(--sz-h, 8.89%); right: var(--sz-d, 8.89%);
  bottom: var(--sz-b, 8.89%); left: var(--sz-g, 8.89%);
  border-radius: 4px; pointer-events: none; display: none;
  border: 1px dashed color-mix(in srgb, #fff 26%, transparent);
}
body[data-safe="on"] .canvas .safezone { display: block; }

/* RÉSERVE DE PLATEFORME — la bande que l'interface d'Instagram, TikTok ou Shorts recouvre
   (renderer/zones.py). Hachurée pour qu'on voie POURQUOI le bas d'un 9:16 remonte de 480 px :
   sans cette explication la contrainte paraît arbitraire, et une contrainte arbitraire finit
   par être contournée. Nulle en 16:9 et en 1:1 — ces formats n'ont pas de surcouche
   persistante — donc les hachures n'apparaissent qu'en vertical, ce qui est le message. */
.canvas .reserve { position: absolute; inset: 0; pointer-events: none; display: none; }
body[data-safe="on"] .canvas .reserve { display: block; }
.canvas .reserve span {
  position: absolute; display: block;
  /* `auto` et non l'héritage du conteneur : `pointer-events` s'hérite, et sans ceci le
     survol ne touchait jamais les bandes — l'infobulle qui explique la réserve (le seul
     texte qui dit POURQUOI le bas d'un 9:16 remonte de 480 px) était inatteignable. Coût
     assumé : en mode zone sûre, un clic dans une bande désélectionne au lieu d'atteindre
     un calque qui s'y trouverait — un calque dans la bande est précisément le problème. */
  pointer-events: auto;
  background: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--danger) 22%, transparent) 0 5px, transparent 5px 11px);
}

/* Les calques ne vivent PLUS dans la boîte de marge : `#cvLayers` couvre tout le cadre et
   chaque calque est positionné en pixels par `place()`, avec les formules d'ancrage du
   moteur (renderer/base.OV_ANCHORS / TX_ANCHORS). Le motif d'avant — une boîte en retrait
   plus des décalages en pourcentage — résolvait les décalages sur la BOÎTE alors que le
   moteur les compte sur le CADRE (`elements._anchor` : `off.x * W`), et il rendait
   impossible le bandeau, que le moteur dessine d'un bord à l'autre. */
.canvas .layerbox { position: absolute; inset: 0; }
.lay { position: absolute; cursor: pointer; }
.lay.sel { outline: 1px dashed var(--accent); outline-offset: 5px; border-radius: 3px; }
/* AUCUNE ombre portée : les deux moteurs n'en rendent une que si `style.shadow` est posé,
   et l'éditeur ne le pose jamais. L'ombre décorative d'avant rendait lisible à l'écran un
   texte clair sur fond clair que le rendu sortait illisible. L'interligne 1,07 vaut pour la
   VIDÉO (non mesuré contre drawtext — dette) ; un projet Visuel reçoit 1,18 par editor.js,
   la valeur exacte du moteur B. */
.lay-text { line-height: 1.07; word-break: break-word; }
/* Un logo ou une image est dimensionné par sa HAUTEUR, exactement comme le moteur
   (`elements.build_source_overlay` : `scale=-1:lh`) ; la largeur suit le rapport d'image
   réel du fichier. D'où un vrai <img> et non un fond CSS : le navigateur connaît ce rapport,
   on n'a pas à le deviner. L'éditeur posait une LARGEUR fixe — 96 px pour un logo, 360 px
   pour une image — si bien qu'un logo en bandeau large s'affichait quatre fois trop étroit
   et débordait la marge droite au rendu sans que rien ne l'annonce. */
img.lay-img { display: block; width: auto; object-fit: contain; border-radius: 4px; }
.lay-logoph, .lay-empty {
  display: grid; place-items: center; font-size: .6rem; font-weight: 700; color: var(--text-dim);
  border: 1px dashed var(--line-2); border-radius: 6px;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,.05), rgba(255,255,255,.05) 5px, transparent 5px, transparent 10px);
}
/* Le bandeau est un rectangle NET : un `drawbox` au moteur A, un `<div>` sans rayon au
   moteur B. Le rayon de 3 px d'avant était un ornement d'aperçu que ni l'un ni l'autre n'a
   jamais rendu. L'opacité 0,92 est le défaut commun aux deux moteurs.
   Sa GÉOMÉTRIE, elle, ne se règle pas ici : elle dépend du moteur qui rendra le projet et
   `editor.js` la pose en pixels, cas par cas. */
.lay-shape { border-radius: 0; opacity: .92; }

/* ------------------------------------------------------------- panneau propriétés */
.props {
  grid-column: 2; grid-row: 1 / 3; border-left: 1px solid var(--line);
  background: var(--surface); display: flex; flex-direction: column; min-height: 0;
}
.props-head {
  flex: none; padding: 11px 15px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.props-head h3 { font-size: .96rem; }
.props-tools { display: flex; gap: 4px; }
.props-body { flex: 1 1 auto; overflow-y: auto; padding: 11px 15px 24px; scrollbar-width: thin; }
.props-body::-webkit-scrollbar { width: 9px; }
.props-body::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 999px; }
.props-foot { flex: none; border-top: 1px solid var(--line); padding: 9px 15px; display: flex; gap: 8px; }
.props-foot .btn { flex: 1; }
.pgroup { border-top: 1px solid var(--line); margin-top: 15px; padding-top: 11px; }
.pgroup:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.pgroup-title {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-dim);
  margin: 0 0 8px; display: flex; align-items: center; gap: 8px;
}
.pgroup-title .lower { text-transform: none; letter-spacing: 0; margin-left: auto; font-size: .72rem; }
.charcount { float: right; font-size: .7rem; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.grad-note { font-size: .75rem; color: var(--text-dim); margin: 10px 0 0; }
.nolibre { margin-top: 8px; font-size: .71rem; color: var(--text-dim); display: flex; gap: 6px; align-items: flex-start; }
.nolibre svg { flex: none; margin-top: 2px; }

.seg4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; border: 1px solid var(--line-2);
  border-radius: 10px; padding: 3px; background: var(--surface-2); }
.seg4.seg5 { grid-template-columns: repeat(5, 1fr); }
.seg4 button {
  border: 0; background: transparent; color: var(--text-muted); padding: 6px 3px;
  border-radius: 7px; cursor: pointer; font-weight: 600; font-size: .77rem;
}
.seg4 button[aria-pressed="true"] {
  background: var(--accent-soft); color: var(--text); box-shadow: inset 0 0 0 1px var(--accent-ring);
}
.axis { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 9px; }
.axis .an { font-size: .8rem; color: var(--text-muted); }
.vchip {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text);
  font-weight: 600; font-size: .82rem; cursor: pointer;
}
.vchip:hover { border-color: var(--accent-ring); }
.durrow { display: flex; align-items: center; gap: 11px; }
.durval { min-width: 44px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.swatches { display: flex; gap: 7px; flex-wrap: wrap; }
.swatch {
  width: 32px; height: 32px; border-radius: 8px; cursor: pointer; position: relative;
  border: 2px solid var(--line-2); background: var(--sw, var(--surface-3));
  transition: transform .12s ease, border-color .15s ease;
}
.swatch:hover { transform: translateY(-2px); }
.swatch[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.swatch[aria-pressed="true"]::after {
  content: "✓"; position: absolute; inset: 0; display: grid; place-items: center;
  font-size: .78rem; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.8);
}

/* emplacement de média */
.mediaslot {
  display: flex; gap: 10px; align-items: center; padding: 8px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface-2);
}
.mediaslot .th {
  width: 62px; height: 44px; border-radius: 6px; flex: none; background: var(--surface-3) center/cover;
  border: 1px solid var(--line); display: grid; place-items: center; color: var(--text-dim); font-size: .7rem;
}
.mediaslot .mm { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.mediaslot .mn { font-size: .83rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mediaslot .dim { font-size: .71rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* les neuf ancres du moteur */
.anchors { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; width: 108px; }
.anchors button {
  aspect-ratio: 1.5; border: 1px solid var(--line-2); background: var(--surface-2);
  border-radius: 5px; cursor: pointer; padding: 0; position: relative;
}
.anchors button::after {
  content: ""; position: absolute; width: 5px; height: 5px; border-radius: 1px;
  background: var(--text-dim); top: 50%; left: 50%; transform: translate(-50%, -50%);
}
.anchors button[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }
.anchors button[aria-pressed="true"]::after { background: var(--accent); }

/* liste de calques : affichée du haut vers le fond, comme dans un logiciel de design.
   L'ordre du MODÈLE reste fond -> avant (z-order du moteur) ; seul l'affichage s'inverse. */
.layers { display: flex; flex-direction: column-reverse; gap: 5px; }
.lrow {
  display: flex; align-items: center; gap: 8px; padding: 7px 9px; border: 1px solid var(--line-2);
  border-radius: 8px; background: var(--surface-2); cursor: pointer; font-size: .84rem;
}
.lrow:hover { border-color: var(--accent-ring); }
.lrow[aria-selected="true"] { border-color: var(--accent); background: var(--accent-soft); }
.lrow .lt { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lrow .li {
  width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center; flex: none;
  background: var(--surface-3); border: 1px solid var(--line); color: var(--text-muted);
}
.lrow .li svg { width: 12px; height: 12px; }
.lrow .lb {
  width: 22px; height: 22px; border-radius: 5px; border: 0; background: transparent;
  color: var(--text-dim); cursor: pointer; display: grid; place-items: center; padding: 0; flex: none;
}
.lrow .lb:hover { background: var(--surface-3); color: var(--text); }
.lrow .lb svg { width: 13px; height: 13px; }
.addlayer { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; }
.addlayer button {
  font-size: .78rem; padding: 5px 9px; border-radius: 999px; border: 1px dashed var(--line-2);
  background: transparent; color: var(--text-muted); cursor: pointer; font-weight: 600;
}
.addlayer button:hover:not(:disabled) { border-color: var(--accent-ring); color: var(--text); background: var(--surface-2); }
.addlayer button:disabled { opacity: .4; cursor: not-allowed; }

/* ------------------------------------------------------------- bande de scènes */
.strip {
  grid-column: 1; grid-row: 2; border-top: 1px solid var(--line); background: var(--surface-2);
  display: flex; flex-direction: column; min-height: 0;
}
.strip-head {
  flex: none; display: flex; align-items: center; gap: 9px; padding: 6px 13px 3px;
  font-size: .78rem; color: var(--text-muted);
}
.strip-head .count {
  font-size: .69rem; font-weight: 700; color: var(--text-dim); background: var(--surface-3);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px;
}
.strip-rail {
  flex: 1 1 auto; display: flex; align-items: center; gap: 10px; overflow-x: auto;
  padding: 0 13px 11px; min-height: 0; scrollbar-width: thin;
}
.strip-rail::-webkit-scrollbar { height: 8px; }
.strip-rail::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 999px; }
.scard {
  flex: 0 0 auto; width: 126px; border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface); cursor: pointer; overflow: hidden; position: relative;
  transition: border-color .15s ease, transform .12s ease;
}
.scard:hover { transform: translateY(-2px); border-color: var(--accent-ring); }
.scard.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.scard.drag { opacity: .45; }
.scard.over { border-color: var(--accent); border-style: dashed; }
.scard .thumb { height: 70px; position: relative; overflow: hidden; }
.scard .thumb .tt {
  position: absolute; inset: 9%; display: grid; place-items: center; font-weight: 800;
  font-size: .58rem; line-height: 1.1; text-align: center; text-shadow: 0 1px 4px rgba(0,0,0,.65);
  overflow: hidden;
}
.scard .meta {
  display: flex; align-items: center; justify-content: space-between; gap: 5px;
  padding: 5px 7px; border-top: 1px solid var(--line); font-size: .69rem; color: var(--text-muted);
}
.scard .idx {
  width: 16px; height: 16px; border-radius: 5px; display: grid; place-items: center;
  background: var(--surface-3); border: 1px solid var(--line-2); font-weight: 800;
  font-size: .6rem; color: var(--text);
}
.scard.active .idx { background: var(--accent-soft); border-color: var(--accent); }
.scard .acts { position: absolute; top: 4px; right: 4px; display: flex; gap: 3px; opacity: 0; transition: opacity .15s; }
.scard:hover .acts, .scard.active .acts { opacity: 1; }
.scard .acts button {
  width: 21px; height: 21px; border-radius: 6px; border: 1px solid var(--line-2);
  background: color-mix(in srgb, #0b0d10 78%, transparent); color: var(--text);
  display: grid; place-items: center; cursor: pointer; padding: 0;
}
.scard .acts button:hover { background: var(--surface-3); }
.scard .acts svg { width: 11px; height: 11px; }
.scard .trans {
  position: absolute; left: -13px; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 19px; height: 19px; border-radius: 50%; display: grid; place-items: center;
  font-size: .56rem; font-weight: 800; background: var(--surface-3);
  border: 1px solid var(--line-2); color: var(--text-muted);
}
.addcard {
  flex: 0 0 auto; width: 126px; height: 100px; border: 1px dashed var(--line-2);
  border-radius: var(--radius-sm); background: transparent; color: var(--text-muted);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; cursor: pointer; font-size: .76rem; font-weight: 600;
}
.addcard:hover { border-color: var(--accent-ring); color: var(--text); background: var(--surface); }

/* ------------------------------------------------------------- barre de commande */
/* Chantier 3, activée. L'emplacement était réservé depuis le chantier 1 : la barre s'est
   allumée sans que la mise en page bouge sous les pieds de l'équipe. */
.cmdbar {
  grid-column: 1 / -1; grid-row: 3; border-top: 1px solid var(--line);
  background: var(--surface); display: flex; align-items: center; gap: 11px; padding: 0 15px;
}
.cmdbar input[type="text"] {
  flex: 1 1 auto; min-width: 0; border-radius: 999px; padding: 8px 14px; font-size: .89rem;
}
.cmdbar input[type="text"]:disabled { color: var(--text-dim); cursor: not-allowed; }

/* Pastille d'état du compte : « un indicateur discret montre quel compte est connecté »
   (STUDIO-UI.md §2). Discret veut dire une pastille, pas un bandeau. */
.cmdpill {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  font-size: .7rem; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--text-dim); text-decoration: none;
}
.cmddot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.cmdpill[data-state="on"]  { color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.cmdpill[data-state="off"] { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
a.cmdpill:hover { background: var(--surface-2); }

/* La réponse se pose EN SURIMPRESSION au-dessus de la barre, elle n'ajoute pas une
   quatrième rangée : la coque de l'éditeur est à hauteur fixe, et une rangée de plus
   comprimerait l'aperçu à chaque demande. */
.cmdreply {
  position: absolute; left: 0; right: 0; bottom: var(--cmd-h); z-index: 30;
  background: var(--surface); border-top: 1px solid var(--line-2);
  box-shadow: 0 -14px 34px rgba(0, 0, 0, .45);
  max-height: 46vh; overflow: auto; padding: 13px 15px;
}
.cmdreply.hidden { display: none; }
.cmdreply-head { display: flex; align-items: flex-start; gap: 11px; }
.cmdreply-txt { flex: 1 1 auto; min-width: 0; }
.cmdreply-txt p { margin: 3px 0 0; }
.cmdreply-actions { display: flex; gap: 8px; align-items: center; flex: none; }
.cmdreply-icon { width: 9px; height: 9px; border-radius: 50%; margin-top: 6px; flex: none; background: var(--text-dim); }
.cmdreply[data-state="run"]  .cmdreply-icon { background: var(--info); animation: cmdpulse 1.1s ease-in-out infinite; }
.cmdreply[data-state="ok"]   .cmdreply-icon { background: var(--ok); }
.cmdreply[data-state="bad"]  .cmdreply-icon { background: var(--danger); }
@keyframes cmdpulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* Aperçu de la proposition : des SCÈNES, jamais du texte d'agent qui défile. */
.b-model { background: color-mix(in srgb, var(--accent) 25%, transparent); }
.cmd-departs { display: flex; gap: 7px; margin-top: 7px; flex-wrap: wrap; }
.cmd-departs .chip { font-size: .68rem; }
.cmdscenes { display: flex; gap: 9px; margin-top: 11px; flex-wrap: wrap; }
.cmdscenes:empty { display: none; }
.cmdscene {
  width: 128px; border: 1px solid var(--line-2); border-radius: var(--radius-xs);
  background: var(--surface-2); padding: 8px 9px; font-size: .76rem; min-width: 0;
}
.cmdscene .n { color: var(--text-dim); font-weight: 700; font-size: .68rem; }
/* Diff de proposition (2026-08-19) : chaque scène dit son verdict, et sa case. */
.cmdscene input[type="checkbox"] { margin: 0 2px 0 0; accent-color: var(--accent); }
.cmdscene-etat { font-size: .62rem; padding: 1px 6px; border-radius: 8px;
  border: 1px solid var(--line); color: var(--text-dim); }
.cmdscene-modifiée { color: #e8b23e; border-color: color-mix(in srgb, #e8b23e 45%, var(--line)); }
.cmdscene-nouvelle { color: #6fcf8f; border-color: color-mix(in srgb, #6fcf8f 45%, var(--line)); }
.cmdscene-supprimée { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.cmdscene .t {
  margin-top: 3px; color: var(--text); display: -webkit-box; -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden;
}
.cmdscene .d { margin-top: 5px; color: var(--text-dim); font-size: .7rem; }

/* Journal REPLIABLE, et replié par défaut : « un journal repliable suffit pour le
   diagnostic » (STUDIO-UI.md §7). Ce n'est pas la sortie de l'agent, c'est son stderr. */
.cmdlog { margin-top: 11px; font-size: .76rem; }
.cmdlog.hidden { display: none; }
.cmdlog summary { cursor: pointer; color: var(--text-dim); }
.cmdlog pre {
  margin: 8px 0 0; padding: 9px; max-height: 190px; overflow: auto;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-xs);
  white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-muted);
}

/* ------------------------------------------------------------- liste de projets */
.filters { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 16px; }
.chip .d { width: 9px; height: 9px; border-radius: 50%; }
.pgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(244px, 1fr)); gap: 15px; }
.pcard {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
  overflow: hidden; transition: transform .14s ease, border-color .15s ease, box-shadow .15s ease;
}
.pcard:hover { transform: translateY(-3px); border-color: var(--accent-ring); box-shadow: var(--shadow); }
.pcard .pv { display: block; height: 122px; position: relative; overflow: hidden; text-decoration: none; }
.pcard .pv:hover { text-decoration: none; }
.pcard .pv .tt {
  position: absolute; inset: 10%; display: grid; place-items: center; font-weight: 800;
  font-size: .8rem; text-align: center; line-height: 1.15; text-shadow: 0 1px 6px rgba(0,0,0,.65);
  overflow: hidden;
}
.pcard .pv .badges { position: absolute; top: 7px; right: 7px; display: flex; gap: 4px; }
.pcard .pv .b {
  font-size: .62rem; font-weight: 800; padding: 2px 7px; border-radius: 999px;
  background: rgba(0,0,0,.58); color: #fff; border: 1px solid rgba(255,255,255,.18);
}
.pcard .body { padding: 10px 12px 12px; }
.pcard .nm {
  font-weight: 700; font-size: .93rem; color: var(--text); text-decoration: none;
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pcard .sub { display: flex; align-items: center; gap: 7px; margin-top: 4px; font-size: .75rem;
  color: var(--text-muted); flex-wrap: wrap; }
.pcard .bpill { display: inline-flex; align-items: center; gap: 5px; font-weight: 700; color: var(--text); }
.pcard .bpill .d { width: 8px; height: 8px; border-radius: 50%; }
.pcard .foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px;
  padding-top: 8px; border-top: 1px solid var(--line); font-size: .71rem; color: var(--text-dim);
}
.pcard .foot .acts { display: flex; gap: 2px; opacity: 0; transition: opacity .15s; }
.pcard:hover .foot .acts { opacity: 1; }
.pcard .foot .acts .btn-icon { width: 26px; height: 26px; }
.empty { padding: 48px 24px; text-align: center; color: var(--text-muted);
  border: 1px dashed var(--line-2); border-radius: var(--radius); }

/* ------------------------------------------------------------- fenêtres modales */
.modal {
  position: fixed; z-index: 71; top: 50%; left: 50%; transform: translate(-50%, -48%) scale(.98);
  width: min(520px, 94vw); max-height: 90vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 19px;
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s, transform .2s var(--ease-out);
}
.modal.open { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); }
.modal h3 { font-size: 1.08rem; }
.modal .dh-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.modal-row { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; }
.kindpick { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-top: 4px; }
.kindpick label {
  display: block; padding: 12px 11px; border-radius: var(--radius-sm); border: 1px solid var(--line-2);
  background: var(--surface-2); cursor: pointer;
}
.kindpick label:has(input:checked) {
  border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-ring);
}
.kindpick input { position: absolute; opacity: 0; pointer-events: none; }
.kindpick .kn { font-weight: 700; font-size: .9rem; display: flex; align-items: center; gap: 7px; }
.kindpick .kd { font-size: .74rem; color: var(--text-muted); margin-top: 3px; display: block; }

.pv-stage {
  margin: 12px auto 0; max-height: 54vh; background: #000; border-radius: 10px;
  border: 1px solid var(--line-2); display: grid; place-items: center; overflow: hidden;
}
.pv-stage img, .pv-stage video { width: 100%; height: 100%; object-fit: contain; display: block; }
.pv-wait { display: flex; align-items: center; gap: 10px; color: var(--text-muted); font-size: .88rem; }
.pv-wait .spin {
  width: 15px; height: 15px; border-radius: 50%; border: 2px solid var(--line-2);
  border-top-color: var(--accent); animation: spin .9s linear infinite;
}
.hint {
  display: flex; gap: 9px; align-items: flex-start; padding: 10px 12px; margin: 12px 0 0;
  border-radius: var(--radius-sm); font-size: .82rem; color: #cfe0ff;
  background: color-mix(in srgb, var(--info) 11%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--info) 30%, transparent);
}
.hint-error {
  color: #ffc9c9; background: color-mix(in srgb, var(--danger) 12%, var(--surface-2));
  border-color: color-mix(in srgb, var(--danger) 35%, transparent);
}
.conflict-banner {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 90;
  display: flex; gap: 10px; align-items: center; padding: 12px 16px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--warn) 16%, var(--surface)); color: #ffe0a3;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); box-shadow: var(--shadow-lg);
  max-width: min(680px, 92vw); font-size: .87rem;
}

/* vignettes de médias et de Ken Burns dans le tiroir */
.vig .demo.media-demo { background-size: cover; background-position: center; }
.kb-tile { width: 100%; height: 100%; overflow: hidden; position: relative; }

/* ------------------------------------------------------------- responsive */
@media (max-width: 1180px) { :root { --props-w: 320px; } }
@media (max-width: 900px) {
  /* En dessous, la coque à panneaux n'a plus de sens : on empile, et on laisse défiler. */
  body.app-shell { height: auto; overflow: auto; }
  .editor { grid-template-columns: 1fr; grid-template-rows: auto auto auto auto; }
  .stage { grid-column: 1; grid-row: 1; height: 58vh; }
  .props { grid-column: 1; grid-row: 3; border-left: 0; border-top: 1px solid var(--line); max-height: none; }
  .strip { grid-column: 1; grid-row: 2; height: var(--strip-h); }
  .cmdbar { grid-row: 4; }
  .canvas[data-f="16:9"] { height: auto; width: 100%; }
  .topbar-app { flex-wrap: wrap; height: auto; padding: 8px 12px; }
}

/* =============================================================================
   16. Écran « Marque » (A1, chantier 2)

   Le seul écran de l'application qui ouvre un sélecteur de couleur. Ailleurs on
   pioche dans la charte ; ici on la pose.
   ========================================================================== */
.brand-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; align-items: start; }
.brand-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.brand-side { min-width: 0; }

/* --- champs de jeton --- */
.tokfields { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 12px; }
.tokfield { min-width: 0; }
.tokfield-wide { grid-column: span 2; }
.tokrow { display: flex; gap: 8px; align-items: center; }
.tokcolor {
  width: 38px; height: 38px; flex: none; padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--line-2); border-radius: var(--radius-xs);
}
.tokcolor::-webkit-color-swatch-wrapper { padding: 3px; }
.tokcolor::-webkit-color-swatch { border: none; border-radius: 4px; }
.tokcolor::-moz-color-swatch { border: none; border-radius: 4px; }
.tokhex, .toktext { width: 100%; min-width: 0; }
.tokfield.is-bad input { border-color: var(--danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent); }

/* --- dépôts de fichier --- */
.uploads { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; margin: 14px 0 4px; }
.upl { min-width: 0; }
.upl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 7px; font-size: .9rem; }
.upl-head .pill { background: var(--accent-soft); color: var(--text); }
.upl-head .pill.dim { background: var(--surface-2); color: var(--text-dim); }
.upl-drop {
  display: grid; place-items: center; padding: 16px 12px; text-align: center; cursor: pointer;
  border: 1px dashed var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text-muted); font-size: .84rem;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.upl-drop:hover, .upl-drop.is-over { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
.upl.is-busy { opacity: .5; pointer-events: none; }
.upl:has(input:disabled) .upl-drop { cursor: not-allowed; opacity: .55; }

.logo-zone { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.logo-prev {
  width: 132px; height: 132px; flex: none; display: grid; place-items: center; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: repeating-conic-gradient(#000 0% 25%, #0b0d10 0% 50%) 50% / 14px 14px;
}
.logo-prev img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* --- aperçu de charte --- */
.brandprev {
  --bp-bg: #1c2026; --bp-surface: #232833; --bp-primary: #6c8cff; --bp-accent: #35c48a;
  --bp-text: #f2f4f8; --bp-muted: #aab2c0; --bp-radius: 0px;
  --bp-title-size: 22px; --bp-sub-size: 12px;
  --bp-font-display: inherit; --bp-font-body: inherit;
  border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden;
}
.bp-stage {
  background: var(--bp-bg); color: var(--bp-text); padding: 22px 18px 20px;
  display: flex; flex-direction: column; gap: 9px; min-height: 190px;
}
.bp-logo { height: 30px; display: flex; align-items: center; }
.bp-logo img { max-height: 30px; max-width: 130px; object-fit: contain; }
.bp-title { font-family: var(--bp-font-display); font-size: var(--bp-title-size); font-weight: 800; line-height: 1.15; }
.bp-sub { font-family: var(--bp-font-body); font-size: var(--bp-sub-size); color: var(--bp-muted); }
.bp-cta {
  align-self: flex-start; margin-top: 4px; padding: 7px 14px; font-size: .78rem; font-weight: 700;
  background: var(--bp-accent); color: var(--bp-bg); border-radius: var(--bp-radius);
}

/* --- journal --- */
.bevents { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: .82rem; }
.bevents li { padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.bevents li:last-child { border-bottom: 0; padding-bottom: 0; }
.dim { color: var(--text-dim); }

@media (max-width: 1080px) {
  .brand-grid { grid-template-columns: 1fr; }
  .tokfield-wide { grid-column: span 1; }
}

.head-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* Note sous un emplacement de média (téléversement vers la banque). Posée hors du DOM
   que paint() réécrit : un message d'erreur ne doit pas disparaître au rafraîchissement. */
.bank-note { margin-top: 10px; }
.bank-note[hidden] { display: none; }

/* ============================================================ Réglages → Mon compte
   (chantier 3). Un écran d'ÉTAT : il montre qu'un credential existe, jamais sa valeur. */
.wrap-narrow { max-width: 780px; }
.sub-title { margin: 18px 0 6px; font-size: .94rem; font-weight: 650; }

/* Pastille d'état. Trois couleurs pour trois situations réellement distinctes — la
   troisième (« purge en cours ») existe parce qu'annoncer « déconnecté » sur un volume
   qui n'a pas encore été supprimé serait un mensonge. */
.acct-state {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px; border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface);
}
.acct-state > div { flex: 1; min-width: 0; }
.acct-state p { margin: 4px 0 0; }
.acct-dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; flex: none; }
.acct-state[data-state="on"]    .acct-dot { background: var(--ok); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 20%, transparent); }
.acct-state[data-state="off"]   .acct-dot { background: var(--text-dim); }
.acct-state[data-state="purge"] .acct-dot { background: var(--warn); box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 20%, transparent); }

.btn-danger { border-color: color-mix(in srgb, var(--danger) 55%, var(--line-2)); color: var(--danger); }
.btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 14%, transparent); }

.steps { margin: 10px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; font-size: .9rem; }
.steps code.cmd {
  display: inline-block; margin-top: 4px; padding: 7px 10px;
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--radius-xs); font-size: .82rem;
}
/* La commande porte un identifiant OIDC : elle est longue et ne doit pas déborder. */
.cmd-wrap { display: block; overflow-wrap: anywhere; white-space: pre-wrap; }

.tokform { margin-top: 16px; }
.quota-line { margin: 6px 0 0; font-size: 1.05rem; }

/* ============================================================ Sous-titres (B4, C4) */
.subs-form select { max-width: 560px; }
.subs-list { display: flex; flex-direction: column; }
.subs-row {
  display: flex; align-items: center; gap: 12px; padding: 11px 4px; text-decoration: none;
  color: var(--text); border-bottom: 1px solid var(--line);
}
.subs-row:last-child { border-bottom: 0; }
.subs-row:hover { background: var(--surface-2); }
.subs-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.subs-title { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Une ligne = un temps (en lecture) et un texte (modifiable). Le temps N'EST PAS un champ :
   le calage vient de la transcription, et un champ désactivé invite quand même à essayer. */
.seglist { display: flex; flex-direction: column; gap: 8px; }
.segrow { display: flex; align-items: flex-start; gap: 11px; }
.segtime {
  flex: none; width: 132px; padding-top: 10px; font-size: .76rem; color: var(--text-dim);
  user-select: all;
}
.segtext { flex: 1 1 auto; min-width: 0; resize: vertical; line-height: 1.35; }
.segrow.is-touched .segtext { border-color: color-mix(in srgb, var(--accent) 55%, var(--line-2)); }

#pvStage video { width: 100%; max-height: 70vh; border-radius: var(--radius-sm); background: #000; }

/* --- Clips courts (C2, chantier 5) --- */
.cliplist { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.cliprow {
  display: flex; align-items: center; gap: 12px; padding: 11px 12px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface-2);
}
.cliprow .num { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid;
  place-items: center; font-size: .74rem; font-weight: 700;
  background: var(--surface); border: 1px solid var(--line-2); color: var(--text-dim); }
.clipmain { flex: 1 1 auto; min-width: 0; }
.clipmain strong { display: block; }
.clipmain .acc { color: var(--text-dim); font-size: .8rem; }
.cliptime { flex: none; font-size: .76rem; color: var(--text-dim); }
.clipact { flex: none; display: flex; gap: 6px; align-items: center; }

/* ============================================================ Livres (phase 9) */
/* La modale d'aperçu affiche un PDF entier, pas une vignette 9:16 : elle est large, et
   l'iframe laisse le lecteur PDF du navigateur faire son travail (zoom, pages). */
.modal-livre { width: min(940px, 96vw); }
.modal-livre #pvStage {
  margin-top: 12px; background: var(--surface-2); border-radius: 10px;
  border: 1px solid var(--line-2); min-height: 120px; display: grid; place-items: center;
}
.modal-livre #pvStage iframe {
  width: 100%; height: min(72vh, 980px); border: 0; display: block; border-radius: 10px;
  background: #fff;
}

.lv-list { display: flex; flex-direction: column; margin-top: 10px; }
.lv-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 2px;
  border-bottom: 1px solid var(--line); font-size: .88rem;
}
.lv-row:last-child { border-bottom: 0; }
.lv-row .num {
  flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid;
  place-items: center; background: var(--surface-2); border: 1px solid var(--line-2);
  font-size: .72rem; color: var(--text-muted);
}
.lv-nom { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.lv-act { flex: none; display: flex; gap: 6px; align-items: center; }
.lv-chap { display: inline-flex; align-items: center; gap: 5px; margin-right: 4px; cursor: pointer; }

.fiche-badge {
  padding: 9px 12px; border-radius: var(--radius-sm); font-size: .85rem; font-weight: 600;
  margin: 0 0 10px;
}
.fiche-badge.ok { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
.fiche-badge.bad { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.fiche-grille {
  display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; margin: 10px 0;
  font-size: .85rem;
}
.fiche-grille dt { color: var(--text-muted); }
.fiche-grille dd { margin: 0; }
.fiche-polices, .fiche-alertes { margin-top: 10px; display: flex; flex-direction: column; gap: 3px; }
.fiche-alertes {
  padding: 10px 12px; border: 1px dashed var(--line-2); border-radius: var(--radius-sm);
}

/* --------------------------------------------- composition libre (lot 6)
   L'éditeur ne dessine pas une page HTML d'agent : il le DIT. Pas d'iframe — le
   navigateur a le réseau que le conteneur de rendu n'a pas, l'aperçu montrerait donc
   autre chose que la sortie. La carte couvre le canevas pour qu'aucun fond ni calque
   résiduel ne laisse croire à un rendu. */
.compo-note {
  position: absolute; inset: 0; z-index: 6;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 18px; text-align: center;
  background: repeating-linear-gradient(135deg, #14161d 0 12px, #171a22 12px 24px);
  color: var(--text-muted); font-size: .74rem; line-height: 1.5;
}
.compo-note strong { color: var(--text); font-size: .92rem; }
.cmdmode {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: .78rem; color: var(--text-muted); cursor: pointer; user-select: none;
}
.cmdmode input { accent-color: var(--accent); cursor: pointer; }

/* ------------------------------------------------------------------ 21. coquille (phase 1)
   Onglets de navigation et sélecteur de marque active — la topbar unique (topbar.html). */
.tabs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.tab {
  padding: 7px 13px; border-radius: var(--radius-sm); font-size: .92rem; font-weight: 600;
  color: var(--text-muted); border: 1px solid transparent; text-decoration: none;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.tab:hover { color: var(--text); background: var(--surface-2); }
.tab[aria-current="page"] {
  color: var(--text); background: var(--surface-3); border-color: var(--line-2);
  box-shadow: inset 0 -2px 0 var(--accent);
}
/* Onglet annoncé mais pas encore livré : visible, muet, et il DIT pourquoi (title). */
.tab-off { color: var(--text-dim); cursor: not-allowed; opacity: .55; }
.tab-off:hover { background: none; color: var(--text-dim); }

/* Sélecteur de marque active — <details> natif : fonctionne sans JavaScript. */
.brandsel { position: relative; }
.brandsel > summary {
  list-style: none; display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 7px 12px; border-radius: var(--radius-sm); font-size: .9rem; font-weight: 600;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text);
  transition: background .15s ease, border-color .15s ease;
}
.brandsel > summary::-webkit-details-marker { display: none; }
.brandsel > summary:hover { background: var(--surface-3); }
.brandsel[open] > summary { border-color: var(--accent); }
.brandsel .d { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.brandsel-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; min-width: 220px;
  padding: 6px; border-radius: var(--radius-sm); border: 1px solid var(--line-2);
  background: var(--surface); box-shadow: 0 12px 34px -12px rgba(0, 0, 0, .55);
}
.brandsel-menu form { margin: 0; }
.brandsel-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 8px 10px; border-radius: 7px; border: 0; background: none; cursor: pointer;
  color: var(--text); font: inherit; font-size: .9rem; text-decoration: none;
}
.brandsel-item:hover { background: var(--surface-2); }
.brandsel-item[aria-current="true"] { background: var(--surface-3); font-weight: 700; }
.brandsel-edit { margin-top: 4px; border-top: 1px solid var(--line); border-radius: 0 0 7px 7px; color: var(--text-muted); }
.brandsel-edit:hover { color: var(--text); }

/* Sortie (déconnexion) : discrète, au bout de la barre. */
.tb-out { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; color: var(--text-dim); }
.tb-out:hover { color: var(--text); background: var(--surface-2); }

/* ------------------------------------------------------------------ 22. écran Banque (phase 1, lot 3) */
.bq-bar { display: flex; align-items: center; gap: 14px; margin: 18px 0 14px; }
.bq-bar input[type="search"] {
  flex: 0 1 340px; padding: 9px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text); font: inherit;
}
.bq-bar input[type="search"]:focus { outline: none; border-color: var(--accent); }
.bgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px;
}
.bcard {
  border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--line);
  background: var(--surface-2); display: flex; flex-direction: column;
}
.bcard:hover { border-color: var(--line-2); }
.bthumb { position: relative; display: block; aspect-ratio: 4 / 3; background: #000; }
.bthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bthumb .badges { position: absolute; left: 8px; bottom: 8px; display: flex; gap: 5px; }
.bthumb .b {
  font-size: .62rem; font-weight: 800; letter-spacing: .06em; padding: 3px 7px;
  border-radius: 6px; background: rgba(0, 0, 0, .62); color: #fff; backdrop-filter: blur(4px);
}
.bbody { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
/* Tuile audio (phase 5a) : pas de vignette possible, un glyphe à la place. */
.bthumb-audio {
  display: flex; align-items: center; justify-content: center;
  font-size: 2.4rem; color: var(--text-muted); background: var(--surface-3);
  text-decoration: none;
}
.baudio { width: 100%; height: 34px; padding: 0 6px 8px; }

/* Bande son de l'éditeur (phase 5a) : panneau topbar + son de la scène. */
.th-audio {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05rem; color: var(--text-muted);
}
.au-ecoute { width: 100%; height: 32px; margin: 8px 0 2px; }
.au-fades { display: flex; gap: 8px; }
.au-fades input {
  width: 72px; padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text);
  font: inherit; font-size: .85rem;
}
.au-check {
  display: flex; align-items: center; gap: 8px; margin: 9px 0 0;
  font-size: .85rem; cursor: pointer;
}
.au-check input { accent-color: var(--accent); }

/* --- voix off générée (B5, phase 5a) : générer → écouter → poser --- */
.vo-gen { display: grid; gap: 6px; margin-top: 4px; }
.vo-gen textarea { resize: vertical; min-height: 58px; font-size: .85rem; }
.vo-gen-row { display: flex; align-items: center; gap: 8px; }
.vo-gen-row .dim { flex: 1; text-align: center; }
.vo-gen audio { width: 100%; height: 34px; }
.tag.voix { color: var(--info); border-color: color-mix(in srgb, var(--info) 40%, transparent); }
.bname {
  flex: 1; min-width: 0; font-size: .85rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bq-pages { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 22px 0 8px; }

/* ------------------------------------------------------------------ 23. connexion CLI (phase 1, lot 4) */
.steps li { position: relative; margin: 10px 0; }
.step-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  background: var(--surface-3); border: 1px solid var(--line-2); margin-right: 8px;
}
li[data-etat="actif"] .step-dot { background: var(--warn); border-color: var(--warn); }
li[data-etat="fait"] .step-dot { background: var(--ok, #35c48a); border-color: transparent; }
#loginEnCours .tokrow { display: inline-flex; gap: 8px; margin-left: 8px; }
#loginEnCours .tokrow input { min-width: 240px; }
#loginUrl { margin-left: 8px; }

/* ------------------------------------------------------------------ 24. écran Image (phase 2) */
/* L'attribut `hidden` doit GAGNER sur les display posés par classe (.img-row en flex,
   .bgrid en grid, .banner-warn en flex, .img-plan en flex) — sans cette règle, tout le
   conditionnel est mort et la mention DA-5.1 s'affiche même pour l'opération locale.
   Élargie au palier C : la première version, scopée à .img-form, a laissé la MÊME
   faille remordre sur .img-plan (deux revues adverses du 2026-08-08, même leçon). */
.img-form [hidden], .img-form[hidden], .img-agent [hidden], .img-plan[hidden],
#imgN[hidden] { display: none !important; }
.img-form {
  display: flex; flex-direction: column; gap: 12px; padding: 16px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); margin-bottom: 22px;
}
.img-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.img-row > label { flex: 0 0 150px; font-size: .85rem; color: var(--text-muted); }
.img-row select, .img-row input[type="text"] {
  padding: 8px 12px; border-radius: var(--radius-sm); border: 1px solid var(--line-2);
  background: var(--surface); color: var(--text); font: inherit;
}
.img-row input[type="text"] { flex: 1 1 320px; }
.img-row input[type="text"]:focus, .img-row select:focus { outline: none; border-color: var(--accent); }
.img-src { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.img-picker { width: 100%; max-height: 300px; overflow-y: auto; padding: 6px 2px; }
.img-picker .img-pick { cursor: pointer; text-align: left; font: inherit; color: inherit; padding: 0; }
.img-mention { margin: 0; }
.img-actions { justify-content: flex-start; }
.img-galerie { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
/* Filtres de galerie (2026-08-19) : purs masquages CSS pilotés par data-attrs — la
   réconciliation par data-id du polling n'est jamais dérangée. */
.img-filtres { display: flex; gap: 8px; align-items: center; margin: 18px 0 10px; flex-wrap: wrap; }
.img-galerie[data-filtre="retenus"] .img-card:not([data-retenu="1"]) { display: none; }
.img-galerie[data-filtre="miens"] .img-card:not(.is-moi) { display: none; }
.img-galerie[data-echecs="masques"] .img-card[data-statut="failed"],
.img-galerie[data-echecs="masques"] .img-card[data-statut="rejected"] { display: none; }
.img-card {
  border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden;
  background: var(--surface-2); display: flex; flex-direction: column;
}
.img-card[data-statut="failed"], .img-card[data-statut="rejected"] { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.img-paire { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); }
.img-paire figure { margin: 0; background: var(--surface-2); }
.img-paire figcaption { font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); padding: 6px 9px 3px; }
.img-paire img { width: 100%; aspect-ratio: 1 / 1; object-fit: contain; display: block; background: #000; }
.img-vide { display: grid; place-items: center; aspect-ratio: 1 / 1; color: var(--text-dim); font-size: .8rem; }
.img-card[data-statut="running"] .img-vide::after { content: "…"; animation: img-pulse 1.2s infinite; }
@keyframes img-pulse { 50% { opacity: .25; } }
.img-meta { display: flex; align-items: center; gap: 10px; padding: 8px 12px; flex-wrap: wrap; }
.img-meta .b-op { font-size: .74rem; font-weight: 700; letter-spacing: .04em; padding: 3px 8px; border-radius: 6px; background: var(--surface-3); }
.img-acts { padding-top: 0; }
.img-src-preview { height: 52px; width: 52px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line-2); background: #000; }
.img-charte-opt { display: flex; align-items: center; gap: 8px; font-size: .85rem; color: var(--text-muted); }

/* ------------------------------------------------------------------ 25. palier C : agent image */
.img-agent {
  display: flex; flex-direction: column; gap: 10px; padding: 16px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
  border-radius: var(--radius-sm); background: var(--surface-2); margin-bottom: 16px;
}
.img-agent input[type="text"] {
  flex: 1 1 380px; padding: 9px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text); font: inherit;
}
.img-agent input[type="text"]:focus { outline: none; border-color: var(--accent); }
.img-suggestions { gap: 8px; }
.img-suggestions .img-sugg { font-size: .78rem; }
.img-plan { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; }
.img-plan-op { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; background: var(--surface); }
.img-plan-op details { margin-top: 6px; }
.img-plan-op summary { cursor: pointer; font-size: .8rem; color: var(--text-muted); }
.img-plan-op pre { white-space: pre-wrap; font-size: .8rem; color: var(--text-muted); margin: 6px 0 0; max-height: 180px; overflow-y: auto; }

/* palier C — images jointes au brief + progression */
.img-jointes { display: flex; flex-wrap: wrap; gap: 8px; }
.img-jointe { position: relative; display: inline-block; }
.img-jointe img { height: 56px; width: 56px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line-2); background: #000; }
.img-jointe-x {
  position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 50%;
  border: none; background: var(--danger, #e5484d); color: #fff; font-size: 12px; line-height: 1;
  cursor: pointer; display: grid; place-items: center; padding: 0;
}
.img-spin {
  display: inline-block; width: 15px; height: 15px; border-radius: 50%; vertical-align: -2px;
  border: 2px solid var(--line-2); border-top-color: var(--accent); animation: img-rot 0.8s linear infinite; margin-right: 8px;
}
@keyframes img-rot { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ 26. module B : clips Veo */
/* L'écran Vidéo IA réutilise les classes img-* (formulaire, galerie, cartes) ; seul le
   résultat diffère — une <video>, pas une paire avant/après. */
.vid-fig { margin: 0; background: #000; }
.vid-fig video { display: block; width: 100%; max-height: 420px; background: #000; }
.vid-vide { display: grid; place-items: center; aspect-ratio: 16 / 9; color: var(--text-dim); font-size: .8rem; padding: 0 16px; text-align: center; }
.img-card[data-statut="running"] .vid-vide::after { content: "…"; animation: img-pulse 1.2s infinite; }
.vid-amorce { height: 40px; width: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line-2); background: #000; }
.img-src-preview { cursor: pointer; }

/* ------------------------------------------------------------------ 27. Design (phase 3) */
/* Penpot encapsulé, plein cadre sous la topbar — même parti que l'éditeur (hauteur
   fixe, pas de <main> qui défile). Le body porte .screen-design pour figer la page. */
/* Colonne flex sur toute la hauteur : la topbar de coquille (.topbar) enveloppe et
   n'a PAS de hauteur fixe (elle passe à deux lignes en fenêtre étroite) — l'iframe
   prend ce qui reste, quelle que soit cette hauteur (revue Opus 5 : un inset calé
   sur --topbar-h recouvrait Penpot dès que la topbar s'enroulait). */
body.screen-design { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
body.screen-design > .topbar { flex: none; }
.design-frame { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
                background: var(--surface-2, #12141a); }
.design-frame iframe { flex: 1 1 auto; min-height: 0; width: 100%; border: 0; }
.design-fallback { padding: 24px; color: var(--text-muted); }

/* --- couleur libre + pipette (révision 2026-08-11, STUDIO-UI §2) --- */
input.swatch-libre { padding: 0; overflow: hidden; appearance: none; -webkit-appearance: none; background: conic-gradient(red, yellow, lime, cyan, blue, magenta, red); }
input.swatch-libre::-webkit-color-swatch-wrapper { padding: 3px; }
input.swatch-libre::-webkit-color-swatch { border: none; border-radius: 5px; }
input.swatch-libre[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.swatch-pipette { display: grid; place-items: center; font-size: 15px; background: var(--surface-3); }
.lay { cursor: grab; }
.lay:active { cursor: grabbing; }
.lay-shape { cursor: pointer; }
.design-aide { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; padding: 6px 14px; border-bottom: 1px solid var(--line-2); background: var(--surface); }
.design-aide .dim { flex: 1 1 200px; }

/* --- poignées de redimensionnement du calque (chantier montage vidéo) --- */
.poignee { position: absolute; width: 12px; height: 12px; border-radius: 50%;
  background: #fff; border: 2px solid var(--accent); z-index: 5; touch-action: none; }
.poignee.p-nw { top: -6px; left: -6px; cursor: nwse-resize; }
.poignee.p-ne { top: -6px; right: -6px; cursor: nesw-resize; }
.poignee.p-sw { bottom: -6px; left: -6px; cursor: nesw-resize; }
.poignee.p-se { bottom: -6px; right: -6px; cursor: nwse-resize; }

/* ------------------------------------------------------------------ 26. reprise Bloom : écran Image prompt-first (2026-08-19) */
/* La zone de dépôt : le premier geste de l'écran. */
.img-drop {
  border: 1.5px dashed var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface); padding: 18px; transition: border-color .15s, background .15s;
}
.img-drop.is-survole { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.img-drop-vide { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.img-drop-icone { font-size: 1.6rem; opacity: .8; }
.img-drop-choisie { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.img-src-apercu { max-height: 110px; max-width: 180px; object-fit: contain; border-radius: 8px;
  border: 1px solid var(--line-2); background: #000; }

/* La barre de consigne — l'action centrale, dimensionnée comme telle. */
.img-promptbar { display: flex; gap: 10px; }
.img-promptbar input[type="text"] {
  flex: 1; padding: 12px 15px; font-size: 1rem; border-radius: var(--radius-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text); font-family: inherit;
}
.img-promptbar input[type="text"]:focus { outline: none; border-color: var(--accent); }
.img-promptbar input[type="text"]:disabled { opacity: .55; }

/* Les chips d'actions : la classe .chip existante, en rangée. */
.img-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.img-chips .chip small { font-size: .68rem; color: var(--text-dim); margin-left: 4px; }
.img-chips .chip.is-off { opacity: .45; cursor: not-allowed; }
.img-ratio { font-size: .78rem; }

/* Le pinceau de masque de la gomme. */
.img-masque { display: flex; flex-direction: column; gap: 8px; padding: 10px;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--surface); }
.img-masque-tete { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.img-masque-scene { position: relative; align-self: center; max-width: 100%; }
.img-masque-scene img { display: block; max-width: 100%; max-height: 420px; }
.img-masque-scene canvas { position: absolute; inset: 0; cursor: crosshair; touch-action: none; }

/* Le curseur avant/après des cartes. */
.img-compare { position: relative; aspect-ratio: 1 / 1; background: #000; overflow: hidden; }
.img-compare .cmp-img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; }
.img-compare .cmp-ligne { position: absolute; top: 0; bottom: 0; width: 2px;
  background: color-mix(in srgb, #fff 75%, transparent); pointer-events: none; transform: translateX(-1px); }
/* Le range couvre TOUTE l'image : attraper la ligne n'importe où fait glisser la
   comparaison — la bande basse de 28 px était introuvable (revue adverse 2026-08-19). */
.img-compare .cmp-range { position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; }
.img-compare::after { content: "avant | après"; position: absolute; top: 6px; left: 8px;
  font-size: .66rem; letter-spacing: .06em; text-transform: uppercase;
  color: color-mix(in srgb, #fff 65%, transparent); pointer-events: none; }

/* Le fil de versions : le lien discret, et l'éclair sur la carte retrouvée. */
.img-fil { font-size: .76rem; }
.img-card.is-flash { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Passe « Bloom vibe » (2026-08-19) : options en pastilles, gabarits marketing, zone
   de dépôt compactée — l'agencement en longues phrases cochables était imbuvable. */
.img-options .img-opt, .img-gabarits .img-gab { font-size: .78rem; }
.img-drop { padding: 14px; }
.img-drop-vide { gap: 6px; }
.img-row textarea {
  flex: 1 1 320px; padding: 8px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--text);
  font: inherit; resize: vertical;
}
.img-row textarea:focus { outline: none; border-color: var(--accent); }
/* Vignettes de format (retour utilisateur : « un aperçu du format ») : chaque cadre à
   sa proportion réelle, l'usage en libellé. Le composant .fmt-chip vient de l'éditeur. */
.img-fmts { flex-wrap: wrap; }
.fmt-chip[data-fmt=""] .glyph { border-style: dashed; }
.fmt-chip[data-fmt="16:9"] .glyph { --w: 30px; --h: 17px; }
.fmt-chip[data-fmt="4:5"] .glyph { --w: 18px; --h: 22px; }
.fmt-chip[data-fmt="3:4"] .glyph { --w: 17px; --h: 22px; }
.fmt-chip[data-fmt="2:3"] .glyph { --w: 15px; --h: 22px; }
.fmt-chip[data-fmt="3:2"] .glyph { --w: 30px; --h: 20px; }
.fmt-chip[data-fmt="4:3"] .glyph { --w: 28px; --h: 21px; }
.fmt-chip[data-fmt="5:4"] .glyph { --w: 26px; --h: 21px; }
.fmt-chip[data-fmt="21:9"] .glyph { --w: 34px; --h: 15px; }
.vid-selbox { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
