/* ============================================================
   Sparkclip — Liquid Glass (iOS 26/27)
   ============================================================ */

@layer tokens, base, glass, layout, components, motion;

@layer tokens {
  :root {
    /* Interface strictement noir / gris / blanc.
       La couleur est reservee aux sous-titres et a leurs apercus. */
    --tint-1: 0 0% 78%;
    --tint-2: 0 0% 58%;
    --tint-3: 0 0% 42%;
    --tint-4: 0 0% 68%;

    --accent: hsl(var(--tint-1));
    --accent-2: hsl(var(--tint-2));

    /* Surfaces de verre */
    --glass-bg: rgba(255, 255, 255, 0.07);
    --glass-bg-strong: rgba(255, 255, 255, 0.105);
    --glass-bg-hover: rgba(255, 255, 255, 0.11);
    --glass-stroke: rgba(255, 255, 255, 0.14);
    --glass-stroke-hi: rgba(255, 255, 255, 0.38);
    --glass-blur: 44px;
    --glass-sat: 190%;

    /* Texte */
    --ink: rgba(255, 255, 255, 0.96);
    --ink-2: rgba(255, 255, 255, 0.68);
    --ink-3: rgba(255, 255, 255, 0.42);

    /* Rayons squircle */
    --r-xs: 12px;
    --r-sm: 18px;
    --r-md: 26px;
    --r-lg: 34px;
    --r-xl: 44px;
    --r-pill: 999px;

    /* Ombres */
    --shadow-glass:
      0 1px 0 0 var(--glass-stroke-hi) inset,
      0 -1px 0 0 rgba(255, 255, 255, 0.06) inset,
      0 24px 60px -20px rgba(0, 0, 0, 0.65),
      0 4px 14px -6px rgba(0, 0, 0, 0.5);
    --shadow-float:
      0 1px 0 0 var(--glass-stroke-hi) inset,
      0 40px 90px -24px rgba(0, 0, 0, 0.8);

    /* Ressorts */
    --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

    --sidebar-w: 296px;
  }
}

@layer base {
  * { box-sizing: border-box; }

  html, body {
    height: 100%;
    margin: 0;
    overflow: hidden;
  }

  body {
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display",
      "Segoe UI Variable Display", "Segoe UI", Inter, system-ui, sans-serif;
    font-size: 14px;
    letter-spacing: -0.011em;
    color: var(--ink);
    background: var(--sur-fort);
    -webkit-font-smoothing: antialiased;
  }

  /* Fond vivant : nappes de gris qui derivent lentement */
  .aurora {
    position: fixed;
    inset: -30%;
    z-index: 0;
    filter: blur(110px);
    opacity: 0.68;
    pointer-events: none;
  }
  /* Voile sombre : garde le verre lisible et evite que la couleur ne domine */
  .aurora::after {
    content: "";
    position: fixed;
    inset: 0;
    background:
      radial-gradient(130% 100% at 50% 8%, transparent 28%, rgba(4, 5, 11, 0.5) 100%),
      linear-gradient(180deg, rgba(4, 5, 11, 0.1), rgba(4, 5, 11, 0.34));
  }
  .aurora span {
    position: absolute;
    display: block;
    border-radius: 50%;
    mix-blend-mode: screen;
    animation: drift 34s var(--ease) infinite alternate;
  }
  .aurora span:nth-child(1) {
    width: 46vw; height: 46vw; left: 4%; top: 6%;
    background: radial-gradient(circle, hsl(var(--tint-1) / 0.75), transparent 70%);
  }
  .aurora span:nth-child(2) {
    width: 40vw; height: 40vw; right: 2%; top: 22%;
    background: radial-gradient(circle, hsl(var(--tint-2) / 0.6), transparent 70%);
    animation-duration: 42s; animation-delay: -8s;
  }
  .aurora span:nth-child(3) {
    width: 38vw; height: 38vw; left: 26%; bottom: 2%;
    background: radial-gradient(circle, hsl(var(--tint-3) / 0.5), transparent 70%);
    animation-duration: 50s; animation-delay: -18s;
  }
  .aurora span:nth-child(4) {
    width: 30vw; height: 30vw; right: 24%; bottom: 8%;
    background: radial-gradient(circle, hsl(var(--tint-4) / 0.4), transparent 70%);
    animation-duration: 38s; animation-delay: -26s;
  }
  /* Grain fin : evite le banding sur les grands degrades */
  body::after {
    content: "";
    position: fixed; inset: 0; z-index: 1; pointer-events: none;
    opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  ::-webkit-scrollbar { width: 10px; height: 10px; }
  ::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.14);
    border-radius: var(--r-pill);
    border: 3px solid transparent;
    background-clip: content-box;
  }
  ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.26); background-clip: content-box; }
  ::-webkit-scrollbar-track { background: transparent; }
}

@layer glass {
  /* Le materiau de base : flou + saturation + double liseré speculaire */
  .glass {
    position: relative;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    border: 1px solid var(--glass-stroke);
    box-shadow: var(--shadow-glass);
    border-radius: var(--r-md);
  }

  /* Reflet speculaire qui glisse sur le bord superieur */
  .glass::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(
      145deg,
      rgb(var(--voile) / 0.5),
      rgb(var(--voile) / 0.06) 34%,
      transparent 62%,
      rgb(var(--voile) / 0.16)
    );
    -webkit-mask:
      linear-gradient(#000 0 0) content-box,
      linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
  }

  .glass-strong { background: var(--glass-bg-strong); }
}

@layer layout {
  #app {
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    height: 100vh;
    gap: 14px;
    padding: 14px;
  }

  /* ---------------- Barre laterale ---------------- */
  .sidebar {
    display: flex;
    flex-direction: column;
    border-radius: var(--r-lg);
    overflow: hidden;
    min-height: 0;
  }

  .brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 22px 20px 18px;
  }
  .brand-mark {
    width: 38px; height: 38px;
    border-radius: 13px;
    display: grid; place-items: center;
    font-size: 19px;
    color: var(--sur-fort);
    background: linear-gradient(180deg, var(--fort), #c9c9d0);
    box-shadow: 0 8px 22px -10px rgb(var(--voile) / 0.5),
                0 1px 0 rgb(var(--voile) / 0.9) inset;
  }
  .brand h1 {
    margin: 0; font-size: 17px; font-weight: 650; letter-spacing: -0.02em;
  }
  .brand small { display: block; color: var(--ink-3); font-size: 11px; font-weight: 500; }

  .side-scroll { flex: 1; overflow-y: auto; padding: 4px 12px 12px; min-height: 0; }

  .side-label {
    padding: 14px 8px 8px;
    font-size: 11px; font-weight: 620;
    text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--ink-3);
  }

  .proj {
    display: flex; gap: 11px; align-items: center;
    padding: 9px; margin-bottom: 5px;
    border-radius: var(--r-sm);
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 0.25s var(--ease), border-color 0.25s var(--ease),
                transform 0.4s var(--spring);
  }
  .proj:hover { background: var(--glass-bg-hover); }
  .proj.active {
    background: var(--glass-bg-strong);
    border-color: var(--glass-stroke);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.28) inset;
  }
  .proj-thumb {
    width: 46px; height: 46px; flex: none;
    border-radius: 12px; object-fit: cover;
    background: rgba(255, 255, 255, 0.07);
  }
  .proj-meta { min-width: 0; flex: 1; }
  .proj-title {
    font-size: 12.5px; font-weight: 560;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .proj-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }

  .side-footer { padding: 12px; border-top: 1px solid var(--glass-stroke); }

  /* ---------------- Zone principale ---------------- */
  .main {
    display: flex; flex-direction: column;
    min-width: 0; min-height: 0; gap: 14px;
  }

  .topbar {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px;
    border-radius: var(--r-lg);
    flex: none;
  }

  .content {
    flex: 1;
    overflow-y: auto;
    border-radius: var(--r-lg);
    padding: 22px;
    min-height: 0;
  }
}

@layer components {
  /* ---------------- Boutons ---------------- */
  .btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 7px;
    padding: 9px 17px;
    font: inherit; font-size: 13px; font-weight: 560;
    color: var(--ink);
    background: var(--glass-bg-strong);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.3) inset,
                0 6px 18px -10px rgb(var(--ombre) / 0.8);
    cursor: pointer;
    white-space: nowrap;
    transition: transform 0.42s var(--spring), background 0.25s var(--ease),
                box-shadow 0.25s var(--ease), opacity 0.2s;
  }
  .btn:hover { background: var(--glass-bg-hover); transform: translateY(-1.5px); }
  .btn:active { transform: scale(0.965); }
  .btn:disabled { opacity: 0.38; pointer-events: none; }

  .btn-primary {
    color: var(--sur-fort);
    background: linear-gradient(180deg, var(--fort), #d9d9de);
    border-color: rgb(var(--voile) / 0.9);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.9) inset,
                0 12px 30px -14px rgb(var(--voile) / 0.5);
  }
  .btn-primary:hover { background: linear-gradient(180deg, var(--fort), #e9e9ee); }
  .btn-ghost { background: transparent; box-shadow: none; border-color: transparent; }
  .btn-ghost:hover { background: var(--glass-bg-hover); }
  .btn-sm { padding: 6px 12px; font-size: 12px; }
  .btn-icon { padding: 8px; width: 34px; height: 34px; border-radius: var(--r-pill); }

  /* ---------------- Champs ---------------- */
  .field {
    display: flex; align-items: center; gap: 10px;
    padding: 4px 6px 4px 18px;
    background: rgb(var(--ombre) / 0.24);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.16) inset;
    transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
  }
  .field:focus-within {
    border-color: rgb(var(--voile) / 0.6);
    box-shadow: 0 0 0 4px rgb(var(--voile) / 0.1),
                0 1px 0 rgb(var(--voile) / 0.2) inset;
  }
  .field input, .field textarea {
    flex: 1; min-width: 0;
    padding: 9px 0;
    background: none; border: none; outline: none;
    color: var(--ink); font: inherit; font-size: 13.5px;
  }
  .field input::placeholder { color: var(--ink-3); }

  textarea.flat {
    width: 100%; resize: vertical; min-height: 88px;
    padding: 12px 14px;
    background: rgb(var(--ombre) / 0.24);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-sm);
    color: var(--ink); font: inherit; font-size: 13px; line-height: 1.55;
    outline: none;
  }
  textarea.flat:focus { border-color: rgb(var(--voile) / 0.6); }

  /* Meme habillage pour les champs d'une ligne : sans cette regle, un
     <input class="flat"> restait le champ blanc brut du navigateur. */
  input.flat, select.flat {
    width: 100%;
    padding: 9px 12px;
    background: rgb(var(--ombre) / 0.24);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-sm);
    color: var(--ink); font: inherit; font-size: 12.5px;
    outline: none;
    transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
  }
  input.flat::placeholder { color: var(--ink-3); }
  input.flat:hover, select.flat:hover { background: rgb(var(--ombre) / 0.32); }
  select.flat { cursor: pointer; }
  select.flat option { background: var(--sur-fort); color: var(--ink); }
  input.flat:focus {
    border-color: rgb(var(--voile) / 0.55);
    background: rgb(var(--ombre) / 0.38);
  }

  /* ---------------- Controle segmente ---------------- */
  .seg {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    background: rgb(var(--ombre) / 0.28);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    position: relative;
  }
  .seg button {
    position: relative; z-index: 1;
    padding: 7px 15px;
    font: inherit; font-size: 12.5px; font-weight: 560;
    color: var(--ink-2);
    background: none; border: none; border-radius: var(--r-pill);
    cursor: pointer;
    transition: color 0.22s var(--ease);
  }
  .seg button.on {
    color: var(--ink);
    background: var(--glass-bg-strong);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.34) inset,
                0 4px 12px -6px rgb(var(--ombre) / 0.7);
  }

  /* ---------------- Grille de clips ---------------- */
  /* En-tete de sequence : titre renommable a gauche, actions a droite. */
  .seq-entete {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: 13px; flex-wrap: wrap;
  }
  .seq-entete > strong { font-size: 14px; letter-spacing: -0.01em; }
  .renommable {
    cursor: text; border-radius: var(--r-sm);
    padding: 2px 6px; margin: -2px -6px;
    border: 1px solid transparent;
  }
  .renommable:hover {
    background: var(--glass-bg); border-color: var(--glass-stroke);
  }
  .champ-renommage {
    font: inherit; color: inherit;
    background: var(--glass-bg); border: 1px solid var(--accent);
    border-radius: var(--r-sm); padding: 2px 6px;
    min-width: 220px; max-width: 100%;
  }

  .clips-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
    gap: 16px;
  }

  .clip-card {
    border-radius: var(--r-md);
    overflow: hidden;
    cursor: pointer;
    transition: transform 0.5s var(--spring), box-shadow 0.4s var(--ease);
  }
  .clip-card:hover {
    transform: translateY(-5px) scale(1.014);
    box-shadow: var(--shadow-float);
  }
  .clip-preview {
    position: relative;
    aspect-ratio: 9 / 16;
    background: rgba(0, 0, 0, 0.42);
    overflow: hidden;
  }
  .clip-preview img, .clip-preview video {
    width: 100%; height: 100%; object-fit: cover; display: block;
  }
  .clip-preview .placeholder {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-size: 30px; opacity: 0.3;
  }
  .clip-rank {
    position: absolute; top: 10px; left: 10px;
    padding: 4px 10px;
    font-size: 11px; font-weight: 680;
    border-radius: var(--r-pill);
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, 0.2);
  }
  .clip-dur {
    position: absolute; bottom: 10px; right: 10px;
    padding: 3px 9px;
    font-size: 11px; font-variant-numeric: tabular-nums;
    border-radius: var(--r-pill);
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
  }
  /* Toutes les cartes ont EXACTEMENT la meme hauteur : un titre sur une ligne
     laissait la carte plus courte que sa voisine, et la grille montrait un
     trou sous les plus petites. On reserve donc la place de deux lignes de
     titre et d'une seule rangee de mots-cles, remplies ou non. */
  .clip-card { display: flex; flex-direction: column; }
  .clip-body {
    padding: 12px 13px 14px;
    flex: 1; display: flex; flex-direction: column;
  }
  .clip-title {
    font-size: 12.5px; font-weight: 620; line-height: 1.35;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(2 * 1.35em);
  }
  .clip-tags {
    margin-top: 8px; display: flex; gap: 5px;
    /* Une seule rangee : un clip a trois mots-cles, un autre un seul, et la
       carte changeait de hauteur pour si peu. */
    flex-wrap: nowrap; overflow: hidden; height: 22px; align-items: center;
  }
  .clip-tags .tag { flex: 0 0 auto; }
  .tag {
    padding: 3px 8px;
    font-size: 10.5px; font-weight: 520;
    color: var(--ink-2);
    background: rgb(var(--voile) / 0.07);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
  }

  /* Etat du rendu, en bas a gauche de la vignette */
  .clip-state {
    position: absolute;
    bottom: 10px; left: 10px;
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 9px;
    font-size: 10.5px; font-weight: 560;
    color: var(--ink-2);
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
  .clip-state.err { color: #fff; border-color: rgba(255, 255, 255, 0.5); }
  .clip-state .ico { width: 11px; height: 11px; }

  /* Anneau de score */
  .score-ring {
    position: absolute; top: 10px; right: 10px;
    width: 46px; height: 46px;
    display: grid; place-items: center;
    filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.7));
  }
  .score-ring svg { position: absolute; inset: 0; transform: rotate(-90deg); }
  .score-ring b { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }

  /* ---------------- Progression ---------------- */
  .progress-wrap { padding: 40px 8px; max-width: 560px; margin: 0 auto; text-align: center; }
  .progress-bar {
    height: 8px; margin: 18px 0 10px;
    background: rgb(var(--ombre) / 0.35);
    border-radius: var(--r-pill);
    overflow: hidden;
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.14) inset;
  }
  .progress-fill {
    height: 100%;
    border-radius: var(--r-pill);
    background: linear-gradient(90deg, #8a8a92, var(--fort), #8a8a92);
    background-size: 200% 100%;
    animation: shimmer 2.4s linear infinite;
    transition: width 0.6s var(--ease);
    box-shadow: 0 0 20px rgb(var(--voile) / 0.35);
  }

  /* ---------------- Editeur ---------------- */
  .sheet-backdrop {
    position: fixed; inset: 0; z-index: 40;
    background: rgba(3, 4, 9, 0.55);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    display: grid; place-items: center;
    padding: 22px;
    animation: fade 0.3s var(--ease);
  }
  .sheet {
    width: min(1180px, 100%);
    max-height: calc(100vh - 44px);
    border-radius: var(--r-xl);
    display: grid;
    grid-template-columns: minmax(300px, 386px) 1fr;
    /* minmax(0,1fr) : sans cela la ligne prend la hauteur du contenu et le
       panneau de droite deborde au lieu de defiler. */
    grid-template-rows: minmax(0, 1fr);
    overflow: hidden;
    animation: rise 0.5s var(--spring);
    box-shadow: var(--shadow-float);
  }
  .sheet-panel { padding: 20px 22px; overflow-y: auto; min-height: 0; }

  .stage {
    position: relative;
    aspect-ratio: 9 / 16;
    border-radius: var(--r-md);
    overflow: hidden;
    background: #000;
    box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9),
                0 0 0 1px rgba(255, 255, 255, 0.09);
    flex: none;
  }
  .stage video {
    position: absolute; top: 50%; left: 50%;
    height: 100%; width: auto; max-width: none;
    transform: translate(-50%, -50%);
    /* Tant que le cadrage n'a pas ete pose par le premier rendu d'apercu, la
       video s'afficherait centree - donc non recadree - le temps d'une image.
       C'est ce bref "flash" que l'on voyait a l'ouverture. */
    visibility: hidden;
  }
  .stage video.placed { visibility: visible; }
  /* Le rendu final occupe le cadre tel quel : il est deja au format 9:16. */
  .stage video#prevFinal {
    visibility: visible;
    width: 100%; height: 100%;
    object-fit: contain;
    transform: translate(-50%, -50%);
  }

  .stage .cap-layer {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    pointer-events: none;
  }
  /* Le calque libass : il couvre exactement la scene et ne prend jamais la
     souris - les poignees de deplacement restent dans .cap-layer, en dessous. */
  /* La video precedente reste regardable pendant qu'on en fabrique une
     nouvelle : on le signale discretement au lieu de tout faire disparaitre. */
  .clip-state.maj { background: rgba(20, 120, 255, .28); }
  .point-maj {
    width: 7px; height: 7px; border-radius: 50%;
    background: #64b5ff; display: inline-block; margin-right: 5px;
    animation: pulseMaj 1.1s ease-in-out infinite;
  }
  @keyframes pulseMaj { 0%, 100% { opacity: .35 } 50% { opacity: 1 } }

  /* Boite d'export : posee sur la scene, elle reprend les memes pastilles que
     les onglets de reglage pour qu'il n'y ait rien de nouveau a apprendre. */
  .boite-export {
    /* Fenetre centree plutot que posee sur la scene : la scene fait 9:16, une
       boite a cote la recouvrait entierement et on ne voyait plus ce qu'on
       s'appretait a exporter. */
    position: fixed; inset: 0; z-index: 120;
    display: grid; place-items: center;
    background: rgba(6, 7, 12, .62);
    backdrop-filter: blur(3px);
  }
  .boite-export > .exp-fenetre {
    width: min(360px, calc(100vw - 32px));
    max-height: calc(100vh - 64px); overflow: auto;
    padding: 16px 17px 15px; border-radius: 18px;
    display: flex; flex-direction: column; gap: 13px;
    box-shadow: 0 24px 64px rgb(var(--ombre) / .6);
  }
  .boite-export header {
    display: flex; align-items: center; justify-content: space-between;
  }
  .exp-bloc { display: flex; flex-direction: column; gap: 6px; }
  .exp-bloc > span { font-size: 12px; opacity: .7; }
  .exp-bloc .hint { margin: 2px 0 0; }
  .exp-video {
    width: 100%; border-radius: 12px; background: #000;
    max-height: 52vh; object-fit: contain;
  }
  .exp-actions {
    display: flex; gap: 8px; align-items: center; justify-content: flex-end;
    flex-wrap: wrap;
  }
  /* "Changer les reglages" est un RETOUR, pas une action de meme rang que le
     telechargement : le mettre sur la meme rangee faisait deborder les trois
     boutons de la fenetre et coupait le premier. */
  .lien-retour {
    align-self: center;
    background: none; border: 0; padding: 4px 6px;
    color: var(--ink-2); font: inherit; font-size: 12px;
    display: inline-flex; align-items: center; gap: 6px;
    cursor: pointer; border-radius: var(--r-sm);
  }
  .lien-retour:hover { color: var(--ink); background: var(--glass-bg); }
  .lien-retour .ico { width: 14px; height: 14px; }
  .ed-scene { position: relative; }

  .cap-canvas {
    position: absolute; inset: 0; width: 100%; height: 100%;
    pointer-events: none; z-index: 3;
  }
  /* Quand libass est aux commandes, le texte HTML ne sert plus qu'a recevoir
     les clics et les glissers : il garde sa place et sa surface sensible, seul
     son rendu disparait. On masque le SPAN de texte et non le bloc : une
     opacite nulle sur le bloc emporterait aussi les poignees, et une
     visibilite nulle lui retirerait les clics. */
  .stage.libass .cap-line > .txt,
  .stage.libass .title-chip > .txt { opacity: 0; }
  .stage.libass .cap-line,
  .stage.libass .title-chip {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
  }

  .cap-line {
    position: absolute; left: 50%;
    /* libass centre le bloc de texte sur \pos (tag n5), verticalement
       comme horizontalement : on centre donc aussi, sinon le sous-titre
       descend des qu il passe sur deux lignes. La hauteur de ligne est
       imposee en pixels par le script (= Fontsize, mesure dans libass). */
    transform: translate(-50%, -50%);
    width: 88%; text-align: center;
    /* libass ne replie que lorsque la ligne DEPASSE la largeur. `balance`
       repartissait le texte sur plusieurs lignes courtes : l apercu montrait
       4 lignes la ou le rendu n en trace qu une. */
    text-wrap: wrap;
    /* Le conteneur de l'apercu ignore la souris : on la redonne a la ligne
       pour pouvoir cliquer dessus et corriger le texte. */
    pointer-events: auto;
    cursor: text;
  }
  .cap-line span { display: inline-block; transition: none; }
  /* Le mot actif rejoue l'animation choisie (memes keyframes que les
     pastilles de selection), mais UNE seule fois, pas en boucle. */
  .cap-line span[class^="sa-"] {
    animation-iteration-count: 1;
    animation-fill-mode: none;
  }
  .title-chip {
    position: absolute; left: 50%; transform: translate(-50%, -50%);
    border-radius: 12px;
    font-weight: 800; text-align: center;
  }

  .transport { display: flex; align-items: center; gap: 10px; }
  .scrub {
    flex: 1; height: 5px; appearance: none;
    background: rgba(255, 255, 255, 0.16);
    border-radius: var(--r-pill); outline: none; cursor: pointer;
  }
  .scrub::-webkit-slider-thumb {
    appearance: none; width: 15px; height: 15px; border-radius: 50%;
    background: #fff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
  }

  .panel-section { margin-bottom: 22px; }
  .panel-section > h3 {
    margin: 0 0 11px;
    font-size: 11px; font-weight: 640;
    text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--ink-3);
  }

  .chip-row { display: flex; flex-wrap: wrap; gap: 7px; }
  .chip {
    padding: 8px 14px;
    font-size: 12.5px; font-weight: 540;
    color: var(--ink-2);
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    cursor: pointer;
    transition: transform 0.4s var(--spring), background 0.22s var(--ease), color 0.22s;
  }
  .chip:hover { background: var(--glass-bg-hover); transform: translateY(-1px); }
  .chip.on {
    color: var(--sur-fort);
    background: linear-gradient(180deg, var(--fort), #dcdce1);
    border-color: rgb(var(--voile) / 0.9);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.9) inset;
  }

  /* ---------------- Apercu du lien colle ---------------- */

  .url-card {
    display: flex;
    gap: 13px;
    align-items: center;
    padding: 11px;
    margin-bottom: 14px;
    border-radius: var(--r-sm);
    animation: rise 0.4s var(--spring);
  }
  .url-card img,
  .url-thumb-empty {
    width: 148px;
    aspect-ratio: 16 / 9;
    flex: none;
    object-fit: cover;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.06);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  }
  .url-thumb-empty { display: grid; place-items: center; color: var(--ink-3); }
  .url-meta { min-width: 0; flex: 1; }
  .url-title {
    font-size: 13.5px; font-weight: 600; line-height: 1.35;
    margin-bottom: 3px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* ---------------- Suppression depuis la liste ---------------- */

  .proj { position: relative; }
  .proj-del {
    position: absolute;
    top: 50%; right: 8px;
    transform: translateY(-50%) scale(0.85);
    width: 28px; height: 28px;
    display: grid; place-items: center;
    padding: 0;
    color: var(--ink-2);
    background: rgb(var(--ombre) / 0.55);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-pill);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s var(--ease), transform 0.35s var(--spring),
                color 0.2s, background 0.2s;
  }
  .proj:hover .proj-del,
  .proj-del:focus-visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(-50%) scale(1);
  }
  .proj-del:hover { color: var(--fort); background: rgb(var(--voile) / 0.18); }
  .proj-del .ico { width: 14px; height: 14px; }
  .proj-thumb { display: grid; place-items: center; color: var(--ink-3); }
  .proj-thumb .ico { width: 18px; height: 18px; }

  /* ---------------- Cartes d'apercu (styles & formats) ---------------- */

  .style-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
    gap: 9px;
  }

  .style-card,
  .layout-card {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 7px;
    padding: 8px;
    border-radius: var(--r-sm);
    text-align: center;
    overflow: hidden;
  }

  .style-card .demo {
    display: grid;
    place-items: center;
    min-height: 52px;
    padding: 6px 8px;
    border-radius: 12px;
    /* Damier sombre : evoque une image video sans distraire du texte */
    background:
      linear-gradient(135deg, rgba(255, 255, 255, 0.11), rgba(0, 0, 0, 0.4)),
      #17171f;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
  }
  .style-card .demo > span {
    line-height: 1.18;
    white-space: nowrap;
    font-weight: 800;
  }

  .style-card .label,
  .layout-card .label {
    font-size: 11.5px;
    font-weight: 560;
    color: var(--ink-2);
  }
  .style-card.on .label,
  .layout-card.on .label { color: var(--fort); }

  /* Les cartes gardent le fond verre : l'etat actif est un liseré, pas un aplat,
     sinon le degrade violet fausse la lecture des couleurs de sous-titres. */
  .style-card.on,
  .layout-card.on {
    color: var(--ink);
    background: var(--glass-bg-strong);
    border-color: rgb(var(--voile) / 0.92);
    box-shadow: 0 0 0 2px rgb(var(--voile) / 0.32),
                0 1px 0 rgb(var(--voile) / 0.34) inset;
  }

  .layout-card { width: 86px; flex: none; }

  .lay-frame {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 9 / 16;
    border-radius: 9px;
    overflow: hidden;
    background: #0d0d13;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  }
  .lay-frame i { position: absolute; display: block; }

  .lay-vid {
    background: linear-gradient(145deg, #9a9aa2, #4d4d55 55%, #303036);
  }
  .lay-blur { filter: blur(4px) saturate(130%); opacity: 0.62; }
  /* Le cartouche net doit se detacher du fond floute */
  .lay-inset {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5),
                0 3px 8px rgba(0, 0, 0, 0.6);
  }
  .lay-broll {
    background: repeating-linear-gradient(135deg,
      rgba(255, 255, 255, 0.26) 0 5px, rgba(255, 255, 255, 0.13) 5px 10px);
  }
  .lay-bg { inset: 0; background: #0a0a0f; }
  .lay-face {
    left: 50%; top: 30%;
    width: 26%; aspect-ratio: 1;
    transform: translateX(-50%);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.25);
  }
  .lay-cap {
    left: 50%; transform: translateX(-50%);
    width: 72%; height: 7%;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.9);
  }

  /* Piste a telecharger : liseré pointille pour la distinguer des installees */
  .chip-dl:hover { color: var(--ink); }
  .chip-dl .ico { width: 12px; height: 12px; }

  /* ---------------- Propositions d'accroche ---------------- */

  .hooks { display: grid; gap: 5px; }

  .hook {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    font: inherit;
    font-size: 12.5px;
    font-weight: 560;
    text-align: left;
    color: var(--ink-2);
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease),
                transform 0.35s var(--spring);
  }
  .hook:hover { background: var(--glass-bg-hover); transform: translateX(2px); }

  .hook.on {
    color: var(--fort);
    background: var(--glass-bg-strong);
    border-color: rgb(var(--voile) / 0.85);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.3) inset;
  }

  /* Pastille de selection facon bouton radio */
  .hook-dot {
    width: 15px; height: 15px;
    flex: none;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1.5px rgb(var(--voile) / 0.35);
    transition: box-shadow 0.2s var(--ease);
  }
  .hook.on .hook-dot {
    background: var(--fort);
    box-shadow: inset 0 0 0 4px var(--sur-fort), 0 0 0 1.5px var(--fort);
  }

  .hook-txt { flex: 1; min-width: 0; line-height: 1.35; }

  /* Raison de la note, sous le titre */
  .hook-why {
    display: block;
    margin-top: 2px;
    font-size: 10.5px;
    font-style: normal;
    font-weight: 500;
    color: var(--ink-3);
  }

  /* Note de viralite de l'accroche */
  .hook-score {
    flex: none;
    min-width: 26px;
    font-size: 13px;
    font-weight: 700;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }

  /* Barre d'action collee en bas du panneau.
     L'ancien degrade noir debordait en une large bande horizontale : on la
     remplace par une surface de verre nette avec un simple filet superieur. */

  /* Choix d'animation de sous-titre : le mot joue l'effet en continu,
     comme pour les emojis - on choisit en voyant, pas en lisant. */
  .sub-anim {
    display: inline-flex;
    align-items: center;
    gap: 7px;
  }
  .sa-word {
    display: inline-block;
    min-width: 30px;
    padding: 1px 5px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.07);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    will-change: transform, opacity, filter;
  }
  .sa-pop        { animation: sa-pop        1.6s var(--ease)  infinite; }
  .sa-default    { animation: sa-pop        1.6s var(--ease)  infinite; }
  .sa-bounce     { animation: sa-bounce     1.8s var(--ease)  infinite; }
  .sa-punch      { animation: sa-punch      1.7s var(--ease)  infinite; }
  .sa-glow       { animation: sa-glow       1.8s ease-in-out  infinite; }
  .sa-shake      { animation: sa-shake      1.6s ease-in-out  infinite; }
  .sa-fade       { animation: sa-fade       1.8s ease-in-out  infinite; }
  .sa-typewriter { animation: sa-typewriter 1.6s steps(1)     infinite; }
  .sa-karaoke    { animation: sa-karaoke    2.0s linear       infinite; }
  .sa-slide      { animation: sa-slide      1.7s var(--ease)  infinite; }
  .sa-zoomout    { animation: sa-zoomout    1.7s var(--ease)  infinite; }
  .sa-wobble     { animation: sa-wobble     1.9s ease-in-out  infinite; }
  .sa-stretch    { animation: sa-stretch    1.7s var(--ease)  infinite; }
  .sa-drop       { animation: sa-drop       1.7s var(--ease)  infinite; }
  .sa-neon       { animation: sa-neon       1.9s ease-in-out  infinite; }
  .sa-flash      { animation: sa-flash      1.6s var(--ease)  infinite; }
  .sa-none       { animation: none; }

  @keyframes sa-slide {
    0%        { transform: translateY(45%) scaleY(0.6); opacity: 0; }
    22%       { transform: translateY(0) scaleY(1.08); opacity: 1; }
    32%, 100% { transform: translateY(0) scaleY(1); opacity: 1; }
  }
  @keyframes sa-zoomout {
    0%        { transform: scale(1.75); opacity: 0.45; }
    26%, 100% { transform: scale(1); opacity: 1; }
  }
  @keyframes sa-wobble {
    0%   { transform: rotate(-4deg); }
    30%  { transform: rotate(4deg); }
    60%  { transform: rotate(-2deg); }
    85%, 100% { transform: rotate(0); }
  }
  @keyframes sa-stretch {
    0%        { transform: scale(0.6, 1.18); }
    24%       { transform: scale(1.12, 0.96); }
    36%, 100% { transform: scale(1, 1); }
  }
  @keyframes sa-drop {
    0%        { transform: scaleY(1.3); opacity: 0.5; }
    20%       { transform: scaleY(0.92); opacity: 1; }
    34%       { transform: scaleY(1.06); }
    46%, 100% { transform: scaleY(1); }
  }
  @keyframes sa-neon {
    0%, 100% { filter: drop-shadow(0 0 1px currentColor); }
    24%      { filter: drop-shadow(0 0 8px currentColor); }
    52%      { filter: drop-shadow(0 0 2px currentColor); }
    74%      { filter: drop-shadow(0 0 6px currentColor); }
  }
  @keyframes sa-flash {
    0%        { transform: scale(1.24); filter: blur(3px); }
    18%, 100% { transform: scale(1); filter: blur(0); }
  }

  @keyframes sa-pop {
    0%, 60%, 100% { transform: scale(1); }
    12%           { transform: scale(1.22); }
    26%           { transform: scale(1); }
  }
  @keyframes sa-bounce {
    0%, 70%, 100% { transform: scale(1) translateY(0); }
    10%           { transform: scale(1.25) translateY(-2px); }
    22%           { transform: scale(0.95) translateY(1px); }
    34%           { transform: scale(1.05) translateY(0); }
  }
  @keyframes sa-punch {
    0%          { transform: scale(1.5); opacity: 0; }
    9%          { transform: scale(1); opacity: 1; }
    16%         { transform: scale(1.1); }
    24%, 100%   { transform: scale(1); opacity: 1; }
  }
  @keyframes sa-glow {
    0%, 100% { filter: none; }
    45%      { filter: drop-shadow(0 0 5px rgb(var(--voile) / 0.95)); }
  }
  @keyframes sa-shake {
    0%, 40%, 100%   { transform: rotate(0deg); }
    8%              { transform: rotate(-5deg); }
    16%             { transform: rotate(4deg); }
    24%             { transform: rotate(-3deg); }
    32%             { transform: rotate(2deg); }
  }
  @keyframes sa-fade {
    0%        { opacity: 0.25; }
    35%, 100% { opacity: 1; }
  }
  @keyframes sa-typewriter {
    0%, 45%  { opacity: 0; }
    50%, 100%{ opacity: 1; }
  }
  @keyframes sa-karaoke {
    0%   { background-size: 0% 100%; }
    100% { background-size: 100% 100%; }
  }
  .sa-karaoke {
    background-image: linear-gradient(rgb(var(--voile) / 0.30),
                                      rgb(var(--voile) / 0.30));
    background-repeat: no-repeat;
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-word { animation: none !important; }
  }

  /* Choix d'animation d'emoji : le glyphe montre l'effet */
  .emoji-anim {
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }
  /* Chaque pastille joue en continu SON animation, avec un vrai emoji :
     on choisit un mouvement en le voyant, pas en lisant son nom. */
  .ea-glyph {
    font-size: 17px;
    line-height: 1;
    display: inline-block;
    width: 20px;
    text-align: center;
    will-change: transform;
  }
  .ea-pop   { animation: ea-pop   1.5s var(--spring) infinite; }
  .ea-float { animation: ea-float 2.4s ease-in-out    infinite; }
  .ea-pulse { animation: ea-pulse 1.1s ease-in-out    infinite; }
  .ea-spin  { animation: ea-spin  2.2s linear         infinite; }
  .ea-shake { animation: ea-shake 0.9s ease-in-out    infinite; }
  .ea-swing   { animation: ea-swing   1.8s ease-in-out infinite; }
  .ea-drop    { animation: ea-drop    1.6s var(--spring) infinite; }
  .ea-slidein { animation: ea-slidein 1.8s var(--ease)  infinite; }
  .ea-zoom    { animation: ea-zoom    1.6s var(--ease)  infinite; }
  .ea-none  { animation: none; }

  @keyframes ea-swing {
    0%, 100% { transform: rotate(-17deg); }
    50%      { transform: rotate(17deg); }
  }
  @keyframes ea-drop {
    0%        { transform: translateY(-90%); opacity: 0; }
    30%, 100% { transform: translateY(0); opacity: 1; }
  }
  @keyframes ea-slidein {
    0%        { transform: translateX(140%); opacity: 0; }
    28%, 78%  { transform: translateX(0); opacity: 1; }
    100%      { transform: translateX(-140%); opacity: 0; }
  }
  @keyframes ea-zoom {
    0%        { transform: scale(2.1); opacity: 0.4; }
    30%, 100% { transform: scale(1); opacity: 1; }
  }

  @keyframes ea-pop {
    0%       { transform: scale(0.4); }
    22%      { transform: scale(1.28); }
    38%      { transform: scale(0.94); }
    50%, 92% { transform: scale(1); }
    100%     { transform: scale(0.4); }
  }
  @keyframes ea-float {
    0%, 100% { transform: translateY(3px); }
    50%      { transform: translateY(-4px); }
  }
  @keyframes ea-pulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.3); }
  }
  @keyframes ea-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }
  @keyframes ea-shake {
    0%, 100%      { transform: translateX(0) rotate(0deg); }
    20%, 60%      { transform: translateX(-3px) rotate(-9deg); }
    40%, 80%      { transform: translateX(3px) rotate(9deg); }
  }

  /* Un utilisateur qui a demande moins d'animation ne subit pas la demo. */
  @media (prefers-reduced-motion: reduce) {
    .ea-glyph { animation: none !important; }
  }

  /* Poignee d'angle : apparait au survol de l'element concerne */
  .grip {
    position: absolute;
    right: -9px; bottom: -9px;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.6);
    cursor: nwse-resize;
    opacity: 0;
    pointer-events: none;
    transform: scale(0.7);
    transition: opacity 0.18s var(--ease), transform 0.3s var(--spring);
  }
  .grip::after {
    content: "";
    position: absolute; inset: 4px;
    border-right: 2px solid rgba(0, 0, 0, 0.55);
    border-bottom: 2px solid rgba(0, 0, 0, 0.55);
    border-radius: 1px;
  }
  .title-chip:hover .grip,
  .cap-line:hover .grip,
  .stage.dragging .grip {
    opacity: 1;
    pointer-events: auto;
    transform: scale(1);
  }
  .title-chip, .cap-line { position: absolute; }

  /* Emojis de l'apercu : positionnes comme dans le rendu ffmpeg */
  /* Signale que l'apercu n'a pas encore le vrai cadrage. */
  .stage-badge {
    position: absolute;
    top: 10px; left: 50%;
    transform: translateX(-50%);
    z-index: 4;
    padding: 5px 11px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.2px;
    white-space: nowrap;
    color: rgba(255, 255, 255, 0.92);
    background: rgba(10, 10, 14, 0.72);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    border: 1px solid var(--glass-stroke);
    pointer-events: none;
  }

  .stage-emoji {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    line-height: 1;
    pointer-events: none;
    display: none;
    filter: drop-shadow(0 3px 8px rgba(0, 0, 0, .6));
  }

  /* ---------------- Elements deplacables sur la video ---------------- */

  .stage .draggable {
    pointer-events: auto;
    cursor: grab;
    border-radius: 8px;
    transition: box-shadow 0.2s var(--ease);
  }
  .stage .draggable:hover {
    box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.6),
                0 0 0 4px rgba(255, 255, 255, 0.15);
  }
  .stage.dragging .draggable { cursor: grabbing; }
  .stage.dragging { cursor: grabbing; }
  /* La couche de sous-titres laisse passer les clics sauf sur les elements
     deplacables eux-memes. */
  .stage .cap-layer { pointer-events: none; }

  .drag-hint {
    position: absolute; left: 50%; bottom: 8px;
    transform: translateX(-50%);
    padding: 4px 10px;
    font-size: 10.5px; color: var(--ink-2);
    background: rgba(0, 0, 0, 0.6);
    border-radius: var(--r-pill);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    pointer-events: none;
    opacity: 0; transition: opacity 0.25s var(--ease);
  }
  .stage:hover .drag-hint { opacity: 1; }

  /* Apercu de style de titre */
  .demo-title { align-content: center; }
  .demo-title > span { display: inline-block; max-width: 100%; }

  /* ---------------- Section repliable ---------------- */

  details.adv > summary {
    cursor: pointer;
    list-style: none;
    padding: 9px 0;
    font-size: 11px; font-weight: 640;
    text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--ink-3);
    display: flex; align-items: center; gap: 7px;
  }
  details.adv > summary::-webkit-details-marker { display: none; }
  details.adv > summary::before {
    content: "";
    width: 6px; height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform 0.25s var(--ease);
  }
  details.adv[open] > summary::before { transform: rotate(45deg); }
  details.adv > summary:hover { color: var(--ink-2); }

  /* ---------------- Curseurs de reglage ---------------- */

  .ctl {
    display: grid;
    grid-template-columns: 76px 1fr 48px;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
  }
  .ctl > span:first-child { font-size: 11.5px; color: var(--ink-2); }
  .ctl > b {
    font-size: 11.5px; font-weight: 560; text-align: right;
    color: var(--ink-2); font-variant-numeric: tabular-nums;
  }

  input[type="color"].swatch::-webkit-color-swatch-wrapper { padding: 2px; }
  input[type="color"].swatch::-webkit-color-swatch { border: none; border-radius: 7px; }

  /* ---------------- Barre de decoupe ---------------- */

  .trim { user-select: none; }
  .trim-handle:hover { transform: scaleX(1.35); }

  .word {
    padding: 3px 8px; font-size: 12px;
    border-radius: 8px; cursor: text;
    background: rgba(255, 255, 255, 0.055);
    border: 1px solid transparent;
    outline: none;
  }
  .word:focus { border-color: rgba(255, 255, 255, 0.7); background: rgba(255, 255, 255, 0.14); }
  .word.live { background: rgba(255, 255, 255, 0.3); color: #fff; }

  .meter { display: grid; gap: 8px; }
  .meter-row { display: grid; grid-template-columns: 74px 1fr 32px; align-items: center; gap: 10px; }
  .meter-row span:first-child { font-size: 11.5px; color: var(--ink-2); }

  .toast-stack {
    position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
    z-index: 90; display: flex; flex-direction: column; gap: 9px; align-items: center;
  }
  .toast {
    padding: 12px 20px;
    border-radius: var(--r-pill);
    font-size: 13px; font-weight: 540;
    animation: rise 0.45s var(--spring);
    max-width: 70vw;
  }
  .toast.err { border-color: rgb(var(--voile) / 0.55); }
  .toast.ok { border-color: rgb(var(--voile) / 0.3); }

  .empty {
    display: grid; place-items: center; gap: 14px;
    padding: 70px 20px; text-align: center; color: var(--ink-3);
  }
  .empty .big { font-size: 46px; opacity: 0.55; }

  .badge {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px; font-size: 11px; font-weight: 560;
    border-radius: var(--r-pill);
    background: rgb(var(--voile) / 0.07);
    border: 1px solid var(--glass-stroke);
  }
  .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3); }
  /* Sans couleur, l'etat se lit a la forme : plein = actif, creux = inactif. */
  .dot.ok { background: var(--fort); box-shadow: 0 0 9px rgb(var(--voile) / 0.8); }
  .dot.err {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px rgb(var(--voile) / 0.55);
  }

  /* Icones SVG : elles heritent de la couleur du texte */
  .ico {
    width: 1em; height: 1em;
    flex: none;
    display: inline-block;
    vertical-align: -0.125em;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .ico-lg { width: 42px; height: 42px; stroke-width: 1.2; opacity: 0.55; }
  .brand-mark .ico { width: 20px; height: 20px; stroke-width: 1.9; }
  .clip-preview .placeholder .ico { width: 30px; height: 30px; }

  .spacer { flex: 1; }
  .row { display: flex; align-items: center; gap: 10px; }

  /* Texte d'explication discret sous un titre de section */
  .hint {
    margin: 0 0 8px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--ink-3);
  }
  /* ---- onglets du panneau de reglages ----
     Sans eux le panneau faisait 3000 px de haut dans 650 px de fenetre :
     cinq ecrans de defilement pour atteindre un reglage. */
  .onglets {
    display: flex;
    gap: 3px;
    margin: -4px -4px 14px;
    padding: 3px;
    border-radius: var(--r-pill);
    background: rgb(var(--voile) / 0.05);
    border: 1px solid var(--glass-stroke);
    position: sticky; top: -4px; z-index: 4;
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
  }
  .onglets button {
    flex: 1;
    padding: 7px 2px;
    border-radius: var(--r-pill);
    font-size: 11px; font-weight: 600;
    color: var(--ink-3);
    background: none; border: 0; cursor: pointer;
    transition: color 0.15s var(--ease), background 0.15s var(--ease);
    white-space: nowrap;
  }
  .onglets button:hover { color: var(--ink-2); }
  .onglets button.on {
    color: var(--sur-fort);
    background: linear-gradient(180deg, var(--fort), #e2e2e8);
  }
  .onglet-page > .panel-section:first-child { margin-top: 0; }

  /* ---- editeur plein ecran (montage) ----------------------------------
     Une fenetre modale ne laisse pas la place a une timeline utilisable :
     on prend tout l'ecran, comme un logiciel de montage. */
  /* L'editeur occupe la zone de contenu : meme fenetre, meme habillage. */
  /* En mode editeur le contenu ne defile plus : c'est la grille interne qui
     se repartit la hauteur (apercu, reglages, timeline). */
  .content.content-editeur {
    padding: 0;
    overflow: hidden;
    display: flex;
    min-height: 0;
  }
  .content.content-editeur > .ed-grille { flex: 1; min-height: 0; }
  .ed-grille {
    display: grid;
    height: 100%;
    min-height: 0;
    /* Le panneau recoit la place perdue autour de l'apercu 9:16 :
       345 px etaient inutilises a cote de lui. */
    grid-template-columns: minmax(0, 1fr) minmax(360px, 440px);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }
  .ico.rot90 { transform: rotate(90deg); }
  .ed-head {
    grid-column: 1 / -1;
    display: flex; align-items: center; gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--glass-stroke);
    background: rgb(var(--ombre) / 0.28);
  }
  .ed-head .titre {
    font-size: 13.5px; font-weight: 650;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .ed-head .pousse { margin-left: auto; }
  .ed-scene {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 12px;
    min-height: 0;
    padding: 16px;
    background: rgba(0, 0, 0, 0.24);
  }
  .ed-scene .stage {
    height: 100%;
    max-height: calc(100vh - 320px);
    width: auto;
    aspect-ratio: 9/16;
  }
  .ed-scene .transport { width: min(100%, 520px); }
  .ed-panneau {
    border-left: 1px solid var(--glass-stroke);
    overflow-y: auto;
    /* marge basse : la barre d'action est collee en bas, sans elle elle
       masquerait le dernier reglage. */
    padding: 16px 18px 72px;
    min-height: 0;
  }

  /* ---- timeline ---- */
  .ed-timeline {
    grid-column: 1 / -1;
    border-top: 1px solid var(--glass-stroke);
    background: rgba(0, 0, 0, 0.34);
    padding: 10px 16px 14px;
    user-select: none;
  }
  .tl-outils {
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 9px;
    font-size: 11.5px; color: var(--ink-3);
  }
  .tl-outils .pousse { margin-left: auto; }
  /* Deux pistes empilees, comme dans un logiciel de montage : les images en
     haut, le texte en dessous. Les surcouches (bornes, coupes, tete de
     lecture) sont sur un calque qui recouvre les deux. */
  .tl-pistes {
    position: relative;
    display: flex; flex-direction: column; gap: 3px;
    cursor: text;
  }
  .tl-pistes.mode-coupe { cursor: crosshair; }
  .tl-calque { position: absolute; inset: 0; pointer-events: none; }
  .tl-calque .tl-poignee, .tl-calque .tl-coupe .x { pointer-events: auto; }

  /* `position: relative` est indispensable : sans elle les mots, en position
     absolue, se calent sur le conteneur et retombent sur la piste image. */
  .tl-texte {
    position: relative;
    height: 34px;
    border-radius: 7px;
    background-color: rgba(255, 255, 255, 0.05);
    overflow: hidden;
  }
  /* On affiche les LIGNES de sous-titres, pas les mots un par un : 250 mots
     sur 1000 px donnaient 4 px chacun, illisibles. */
  .tl-ligne {
    position: absolute; top: 4px;
    height: 26px;
    display: flex; align-items: center;
    padding: 0 7px;
    border-radius: 5px;
    font-size: 11px; line-height: 1;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    background: rgba(255, 255, 255, 0.16);
    color: var(--ink-2);
    border-left: 2px solid rgba(255, 255, 255, 0.45);
    /* Cliquable : c'est par la qu'on corrige le texte d'une ligne. */
    pointer-events: auto;
    cursor: text;
  }
  .tl-ligne:hover { background: rgba(255, 255, 255, 0.28); color: var(--ink); }
  .tl-ligne.dehors { opacity: 0.3; }
  .tl-ligne.coupe {
    background: rgba(255, 90, 90, 0.3);
    border-left-color: rgba(255, 120, 120, 0.8);
    text-decoration: line-through;
  }
  .tl-ligne.active {
    background: rgba(255, 255, 255, 0.3);
    color: var(--ink);
  }

  .tl-video {
    height: 68px;
    border-radius: 9px;
    background-color: rgba(255, 255, 255, 0.045);
    /* `auto 100%` conserve le rapport des vignettes ; la bande est
       calculee pour couvrir exactement la largeur de la piste. */
    background-size: auto 100%;
    background-repeat: no-repeat;
    overflow: hidden;
    cursor: text;
  }
  .tl-coupe.en-cours { pointer-events: none; }
  .tl-outils .sep {
    width: 1px; height: 16px;
    background: var(--glass-stroke);
    margin: 0 2px;
  }
  /* Les mots se posent SUR les images : fond assombri pour rester lisibles. */
  .tl-mot.dehors { opacity: 0.25; }
  .tl-mot.coupe { background: rgba(255, 90, 90, 0.3); text-decoration: line-through; }
  /* Zone conservee : tout ce qui est en dehors est grise. */
  .tl-hors { position: absolute; top: 0; bottom: 0; background: rgba(0, 0, 0, 0.55); }
  .tl-coupe {
    position: absolute; top: 0; bottom: 0;
    background: repeating-linear-gradient(45deg,
      rgba(255, 80, 80, 0.28) 0 6px, rgba(255, 80, 80, 0.14) 6px 12px);
    border-left: 1px solid rgba(255, 120, 120, 0.7);
    border-right: 1px solid rgba(255, 120, 120, 0.7);
  }
  .tl-coupe .x {
    position: absolute; top: 3px; right: 3px;
    width: 15px; height: 15px; line-height: 14px;
    border-radius: 4px; text-align: center; font-size: 11px;
    background: rgba(0, 0, 0, 0.6); cursor: pointer; color: #fff;
  }
  .tl-poignee {
    position: absolute; top: 0; bottom: 0; width: 11px;
    background: #fff; cursor: ew-resize; z-index: 3;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
  }
  .tl-poignee::after {
    content: ''; position: absolute; left: 4px; top: 50%;
    width: 3px; height: 20px; margin-top: -10px;
    border-radius: 2px; background: rgba(0, 0, 0, 0.4);
  }
  .tl-tete {
    position: absolute; top: 0; bottom: 0; width: 2px;
    background: var(--ink); z-index: 4; pointer-events: none;
  }
  .tl-tete::before {
    content: ''; position: absolute; top: 0; left: -4px;
    border-left: 5px solid transparent; border-right: 5px solid transparent;
    border-top: 7px solid var(--ink);
  }
  .tl-regle {
    position: relative; height: 15px; margin-top: 5px;
    font-size: 9.5px; color: var(--ink-3);
  }
  .tl-regle span { position: absolute; transform: translateX(-50%); }

  /* ---- templates de reglages ---- */
  .preset-save .btn { gap: 6px; white-space: nowrap; }
  .preset-save .btn .ico { width: 13px; height: 13px; }

  /* Une sequence trop longue est publiee en plusieurs parties : le lecteur
     doit voir tout de suite qu'un clip en est la suite d'un autre. */
  .clip-part {
    position: absolute;
    left: 9px; bottom: 9px;
    padding: 3px 8px;
    border-radius: var(--r-pill);
    font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.2px;
    color: #0a0a0c;
    background: rgba(255, 255, 255, 0.92);
  }

  .preset-list { display: flex; flex-direction: column; gap: 7px; }

  .preset {
    display: flex; align-items: stretch;
    border-radius: 11px;
    background: rgb(var(--voile) / 0.045);
    border: 1px solid var(--glass-stroke);
    overflow: hidden;
    transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
  }
  .preset:hover { background: rgb(var(--voile) / 0.085); }
  .preset.is-default { border-color: rgb(var(--voile) / 0.32); }

  /* Ces boutons ne portent pas la classe .btn : sans remise a zero ils
     heritent du fond clair par defaut du navigateur, et le texte blanc
     disparait dessus. */
  .preset-main, .preset-all, .preset-del {
    appearance: none;
    background: none;
    border: 0;
    font: inherit;
    cursor: pointer;
  }

  .preset-main {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: 9px;
    padding: 10px 12px;
    text-align: left;
    color: var(--ink);
    font-size: 12.5px; font-weight: 600;
  }
  .preset-main .ico { width: 15px; height: 15px; flex: none; opacity: 0.75; }
  .preset-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .preset-meta {
    margin-left: auto;
    font-size: 10.5px; font-weight: 500;
    color: var(--ink-3);
    white-space: nowrap;
  }

  .preset-all, .preset-del {
    flex: none;
    display: flex; align-items: center; justify-content: center;
    padding: 0 11px;
    color: var(--ink-3);
    font-size: 11px; font-weight: 600;
    border-left: 1px solid var(--glass-stroke);
    transition: color 0.15s var(--ease), background 0.15s var(--ease);
  }
  .preset-all:hover, .preset-del:hover {
    color: var(--ink);
    background: rgb(var(--voile) / 0.1);
  }
  .preset-del .ico { width: 14px; height: 14px; }

  .preset-empty {
    display: flex; align-items: center; gap: 8px;
    margin: 0;
    padding: 13px;
    border-radius: 11px;
    border: 1px dashed var(--glass-stroke);
    color: var(--ink-3);
    font-size: 11.5px; line-height: 1.45;
  }
  .preset-empty .ico { width: 16px; height: 16px; flex: none; }

  /* Bloc de creation : champ + action reunis dans un meme cadre, pour qu'on
     lise "nommer puis enregistrer" comme une seule chose. */
  .preset-save {
    display: flex; gap: 6px; align-items: stretch;
    margin-top: 12px;
    padding: 6px;
    border-radius: 12px;
    background: rgb(var(--voile) / 0.04);
    border: 1px dashed var(--glass-stroke);
  }
  .preset-save input.flat {
    border-color: transparent;
    background: rgb(var(--ombre) / 0.28);
  }
  .preset-save .flat { flex: 1; min-width: 0; }

  .switch-row {
    display: flex; align-items: center; gap: 8px;
    margin-top: 10px;
    font-size: 11.5px; color: var(--ink-3);
    cursor: pointer;
  }
  .switch-row input { accent-color: var(--fort); width: 14px; height: 14px; }
  .switch-row:hover { color: var(--ink-2); }

  .chip.preset { padding-right: 6px; }
  .chip-x:hover { opacity: 1; background: rgb(var(--voile) / 0.12); }
  .chip-x .ico { width: 13px; height: 13px; }
  .muted { color: var(--ink-3); font-size: 12px; }
}

@layer motion {
  @keyframes drift {
    0%   { transform: translate(0, 0) scale(1); }
    100% { transform: translate(7%, -9%) scale(1.18); }
  }
  @keyframes shimmer {
    0% { background-position: 0% 50%; }
    100% { background-position: 200% 50%; }
  }
  @keyframes rise {
    from { opacity: 0; transform: translateY(22px) scale(0.975); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }
  @keyframes fade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes pop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.17); }
    100% { transform: scale(1); }
  }
  @keyframes spin { to { transform: rotate(360deg); } }

  .spinner {
    width: 15px; height: 15px;
    border: 2px solid rgb(var(--voile) / 0.25);
    border-top-color: var(--fort);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      transition-duration: 0.01ms !important;
    }
  }
}

@media (max-width: 1080px) {
  #app { grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .sheet { grid-template-columns: 1fr; }
}

  /* ---------- onglet Publier ---------- */
  .mini-label {
    display: block;
    margin: 13px 0 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-3);
  }
  .mini-label:first-child { margin-top: 0; }
  .pub-compte {
    margin-left: 6px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-3);
  }
  .pub-compte.trop { color: #ff7a6b; }
  .vide-mini { font-size: 12px; color: var(--ink-3); }
  /* Un hashtag decoche reste lisible mais visiblement exclu. */
  #pubCorps .chip:not(.on) { opacity: 0.42; text-decoration: line-through; }

  /* ---------- bornes de coupe explicites ---------- */
  .coupe-barre {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 4px;
    font-size: 12px;
    color: var(--ink-2);
    white-space: nowrap;
  }
  .coupe-barre[hidden] { display: none; }
  input.flat.tc {
    width: 74px;
    padding: 5px 7px;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    text-align: center;
  }

  /* ---------- pistes emojis et titre ---------- */
  .tl-emoji, .tl-titre {
    position: relative;
    height: 24px;
    border-radius: 7px;
    background-color: rgba(255, 255, 255, 0.05);
    overflow: hidden;
  }
  .tl-emo {
    position: absolute; top: 2px;
    height: 20px; min-width: 20px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 5px;
    font-size: 13px; line-height: 1;
    background: rgba(255, 255, 255, 0.14);
    pointer-events: auto; cursor: pointer;
    overflow: hidden;
  }
  .tl-emo:hover { background: rgba(255, 255, 255, 0.3); }
  .tl-titre-bloc {
    position: absolute; top: 2px;
    height: 20px;
    display: flex; align-items: center;
    padding: 0 8px;
    border-radius: 5px;
    font-size: 11px; line-height: 1;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    background: rgba(120, 180, 255, 0.26);
    border-left: 2px solid rgba(150, 200, 255, 0.8);
    color: var(--ink);
    pointer-events: auto; cursor: pointer;
  }
  .tl-titre-bloc:hover { background: rgba(120, 180, 255, 0.4); }
  .tl-vide {
    position: absolute; left: 9px; top: 50%;
    transform: translateY(-50%);
    font-size: 10.5px; color: var(--ink-3);
  }

  /* ---------- barre d'edition d'un sous-titre ---------- */
  .edligne {
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 8px;
    padding: 7px 9px;
    border-radius: 11px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--glass-stroke);
  }
  .edligne[hidden] { display: none; }
  .edligne-l {
    font-size: 10.5px; font-weight: 600;
    letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--ink-3);
  }
  .edligne input.flat { flex: 1; }

  /* ---------- etat du rendu affiche ---------- */
  .etat-rendu {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px; font-weight: 600;
    letter-spacing: 0.01em;
  }
  .etat-rendu::before {
    content: ''; width: 6px; height: 6px; border-radius: 50%;
    background: currentColor;
  }
  .etat-rendu.ok { color: #7ee0a5; background: rgba(126, 224, 165, 0.12); }
  .etat-rendu.attente { color: #e8c46a; background: rgba(232, 196, 106, 0.12); }
  .etat-rendu.encours { color: #8ab8f0; background: rgba(138, 184, 240, 0.14); }
  .etat-rendu.encours::before { animation: pulseDot 1s ease-in-out infinite; }
  @keyframes pulseDot { 50% { opacity: 0.25; } }

  /* ---------- palette d'emojis ---------- */
  .tl-emoji { overflow: visible; }          /* la palette deborde de la piste */
  .tl-emo.pose { box-shadow: inset 0 0 0 1px rgba(150, 200, 255, 0.7); }
  .palette-emo {
    position: absolute; bottom: 28px; left: 50%;
    transform: translateX(-50%);
    z-index: 40;
    width: min(430px, 92vw);
    padding: 10px;
    border-radius: 14px;
    background: rgba(24, 24, 28, 0.97);
    border: 1px solid var(--glass-stroke);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
  }
  .palette-grille {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 3px;
    max-height: 150px; overflow-y: auto;
  }
  .palette-grille button {
    padding: 4px 0;
    font-size: 17px; line-height: 1.1;
    background: none; border: 0; border-radius: 6px;
    cursor: pointer;
  }
  .palette-grille button:hover { background: rgb(var(--voile) / 0.14); }
  .palette-bas {
    display: flex; gap: 6px; justify-content: flex-end;
    margin-top: 9px; padding-top: 8px;
    border-top: 1px solid var(--glass-stroke);
  }

  /* ---------- recadrage a la souris ---------- */
  .stage { cursor: grab; }
  .stage.recadrage { cursor: grabbing; }
  .stage.recadrage video { transition: none; }

  /* ---------- liste des raccourcis ---------- */
  .raccourcis {
    display: flex; flex-wrap: wrap; gap: 6px 14px;
    font-size: 11.5px; color: var(--ink-2);
  }
  .raccourcis span { display: inline-flex; align-items: center; gap: 4px; }
  .raccourcis kbd {
    padding: 1px 6px;
    border-radius: 5px;
    background: rgb(var(--voile) / 0.1);
    border: 1px solid var(--glass-stroke);
    font-family: inherit; font-size: 10.5px; font-weight: 600;
    color: var(--ink);
  }

  /* ---------- barre de tri et de filtres ---------- */
  .barre-filtres {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 18px;
  }
  .barre-filtres .muted { font-size: 11px; }
  .seg.seg-mini button { padding: 4px 9px; font-size: 11px; }
  .select-mini {
    width: auto; padding: 5px 9px;
    font-size: 11.5px;
  }
  .coche {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; color: var(--ink-2);
    cursor: pointer;
  }

  /* ---------- retirer une accroche ---------- */
  .hook { position: relative; }
  .hook-x {
    position: absolute; right: 4px; top: 4px;
    width: 18px; height: 18px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 5px;
    font-size: 11px; font-style: normal; line-height: 1;
    color: var(--ink-3);
    opacity: 0; transition: opacity 0.12s var(--ease);
    cursor: pointer;
  }
  .hook:hover .hook-x { opacity: 1; }
  .hook-x:hover { background: rgb(var(--voile) / 0.14); color: var(--ink); }

  .tl-emo.titre {
    background: rgba(120, 180, 255, 0.26);
    box-shadow: inset 0 0 0 1px rgba(150, 200, 255, 0.6);
  }
  .transport-aide { font-size: 11px; margin-left: auto; }
  .transport-aide kbd {
    padding: 1px 5px; border-radius: 4px;
    background: rgb(var(--voile) / 0.1);
    border: 1px solid var(--glass-stroke);
    font: inherit; font-size: 10px; color: var(--ink-2);
  }

  /* La palette du titre s'ouvre sous la pastille, pas au-dessus d'une piste. */
  .palette-titre { bottom: auto; top: 32px; left: 0; transform: none; }
  #chipEmojiTitre { position: relative; }
  #apercuEmojiTitre img, #apercuEmojiTitre { vertical-align: -3px; }

  /* ---------- apercu et rendu final, cote a cote ---------- */
  .scenes {
    display: flex;
    align-items: stretch; justify-content: center;
    gap: 14px;
    flex: 1 1 auto;
    min-height: 0; width: 100%;
  }
  /* `flex: 1 1 0` est indispensable : sans lui la colonne se dimensionnait sur
     un contenu de largeur indecidable (une boite en aspect-ratio), tombait a
     150 px, et les deux videos de 268 px se chevauchaient. */
  .scene-col {
    display: flex; flex-direction: column; align-items: center;
    gap: 7px;
    /* Une seule scene desormais : elle se cale sur la hauteur disponible et
       garde son rapport 9:16, au lieu de s'etirer sur toute la largeur. */
    flex: 0 1 auto;
    min-width: 0; min-height: 0;
  }
  .scene-titre {
    font-size: 10.5px; font-weight: 600;
    letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--ink-3);
    white-space: nowrap;
  }
  .scene-titre em { font-style: normal; font-weight: 500; opacity: 0.75; }
  .ed-scene .scene-col .stage {
    flex: 1 1 auto;
    min-height: 0; height: auto;
    max-height: none;
    width: auto; max-width: 100%;
    aspect-ratio: 9/16;
  }
  /* Pas encore genere : un cadre explicite plutot qu'un rectangle noir muet. */
  #stageFinal.vide::after {
    content: 'Pas encore généré';
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-size: 11.5px; color: var(--ink-3);
    background: repeating-linear-gradient(45deg,
      rgb(var(--voile) / 0.02) 0 12px, rgb(var(--voile) / 0.05) 12px 24px);
  }

  /* ---------- voile de generation, pose sur la video ---------- */
  .voile-rendu {
    position: absolute; inset: 0; z-index: 6;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 11px;
    padding: 0 18px;
    background: rgba(8, 8, 10, 0.72);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    font-size: 12px; color: var(--ink);
    text-align: center;
  }
  .voile-rendu[hidden] { display: none; }
  .voile-barre {
    width: min(78%, 210px); height: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    overflow: hidden;
  }
  .voile-barre i {
    display: block; height: 100%; width: 2%;
    border-radius: 999px;
    background: linear-gradient(90deg, #8ab8f0, #fff);
    transition: width 0.3s var(--ease);
  }

  /* Les onglets masquent ce qui defile dessous : translucides, les reglages
     passaient derriere et se melangeaient a la barre. */
  .onglets { background: rgba(20, 20, 24, 0.97); }
  .onglet-page { position: relative; z-index: 1; }

  /* L'apercu et le rendu occupent toute la hauteur laissee par la timeline. */
  .ed-scene { justify-content: flex-start; }
  .ed-scene > .scenes { width: 100%; }

  /* ---------- apercu et rendu en verre ---------- */
  .scene-col .stage {
    background: rgba(10, 10, 13, 0.55);
    border: 1px solid var(--glass-stroke);
    box-shadow: 0 1px 0 0 var(--glass-stroke-hi) inset,
                0 22px 55px -22px rgba(0, 0, 0, 0.95);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
  .scene-titre {
    padding: 3px 11px;
    border-radius: var(--r-pill);
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    backdrop-filter: blur(14px) saturate(150%);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
  }

  /* ---------- les commandes restantes passent au verre ---------- */
  .seg {
    background: var(--glass-bg);
    backdrop-filter: blur(16px) saturate(160%);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.16) inset;
  }
  input.flat, select.flat, textarea.flat {
    background: var(--glass-bg);
    backdrop-filter: blur(16px) saturate(160%);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.14) inset;
  }
  input.flat:hover, select.flat:hover, textarea.flat:hover {
    background: var(--glass-bg-hover);
  }
  .edligne, .palette-emo {
    background: rgba(20, 20, 25, 0.72);
    backdrop-filter: blur(26px) saturate(170%);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
    box-shadow: 0 1px 0 0 var(--glass-stroke-hi) inset,
                0 18px 44px -18px rgba(0, 0, 0, 0.9);
  }
  .onglets {
    background: rgba(18, 18, 23, 0.78);
    backdrop-filter: blur(26px) saturate(170%);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
  }
  .voile-rendu {
    background: rgba(10, 10, 13, 0.62);
    backdrop-filter: blur(16px) saturate(150%);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
  }
  .raccourcis kbd, .transport-aide kbd {
    background: var(--glass-bg);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.16) inset;
  }
  .tl-emo, .tl-ligne, .tl-titre-bloc {
    backdrop-filter: blur(10px) saturate(140%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
  }

  /* ---------- sous-titres "Verre" : panneau derriere la ligne ---------- */
  /* Memes valeurs que le panneau dessine au rendu : surface claire et liseré
     lumineux. Un voile sombre sur une image sombre ne se voit pas. */
  .cap-line.verre {
    padding: 0.30em 0.46em;
    border-radius: 0.34em;
    background: rgba(234, 240, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.42);
    box-shadow: 0 10px 30px -14px rgba(0, 0, 0, 0.9);
    backdrop-filter: blur(16px) saturate(150%);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
    /* En position absolue avec left:50% et sans right, la largeur disponible
       n est que la MOITIE de la scene : le panneau se retrouvait a 131 px sur
       264 et le texte se cassait en deux. max-content le dimensionne sur son
       contenu reel, le max-width le borne. */
    width: max-content; max-width: 84%;
    /* `balance` repartit le texte sur plusieurs lignes meme quand il tient sur
       une seule : l apercu montrait 3 lignes la ou le rendu n en fait qu une. */
    text-wrap: wrap;
  }

  /* Fleches de navigation entre clips : meme verre que les autres boutons,
     mais carrees pour rester discretes a cote du bouton "Clips". */
  .btn-fleche {
    padding: 6px 0;
    width: 30px;
    font-size: 16px; line-height: 1;
  }

  /* ---------- barre de deplacement de la timeline ---------- */
  .tl-defil {
    display: flex; align-items: center; gap: 10px;
    margin-top: 6px;
  }
  .tl-defil .scrub { flex: 1; }
  .tl-defil .muted {
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    min-width: 92px; text-align: right;
  }
  /* Rien a faire defiler quand toute la video tient dans la fenetre : la barre
     reste visible mais s'efface, pour ne pas laisser croire a une panne. */
  .tl-defil.inactif { opacity: 0.4; }
  .tl-defil.inactif .scrub { pointer-events: none; }

  /* Bande d'images en cours de remplacement : l'ancienne reste visible, on la
     signale simplement par une legere attenuation. */
  .tl-video.charge { opacity: 0.72; transition: opacity 0.15s var(--ease); }

  /* Croix et fleches sont de vraies icones : on les dimensionne comme telles. */
  .hook-x .ico { width: 11px; height: 11px; }
  .tl-coupe .x .ico { width: 11px; height: 11px; }
  .btn-fleche .ico { width: 13px; height: 13px; }

  /* ---------- verre applique aux boutons qui l'avaient perdu ---------- */
  .proj-del, .hook, .preset-main, .preset-all, .preset-del,
  .palette-grille button {
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    backdrop-filter: blur(16px) saturate(160%);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.16) inset;
    transition: background 0.2s var(--ease), transform 0.35s var(--spring);
  }
  .proj-del:hover, .hook:hover, .preset-main:hover, .preset-all:hover,
  .preset-del:hover, .palette-grille button:hover {
    background: var(--glass-bg-hover);
  }
  .proj-del:active, .hook:active, .preset-main:active,
  .preset-all:active, .preset-del:active { transform: scale(0.97); }
  /* L'accroche retenue reste bien plus lumineuse que les autres. */
  .hook.on {
    background: var(--glass-bg-strong);
    border-color: var(--glass-stroke-hi);
  }
  .palette-grille button { border-radius: 7px; }
  /* Une ligne de modele : trois boutons colles, un seul liseré exterieur. */
  .preset { gap: 4px; }
  .preset-main { border-radius: var(--r-sm) 4px 4px var(--r-sm); }
  .preset-del { border-radius: 4px var(--r-sm) var(--r-sm) 4px; }
  .preset-all { border-radius: 4px; }
  /* Icone de plateforme dans l'onglet Publier. */
  #pubCorps ~ .chip-row .chip .ico, .chip[data-plat] .ico {
    width: 13px; height: 13px; margin-right: 1px;
  }

  /* Pastilles d'animation d'emoji : on montre le DESSIN Apple, pas le glyphe
     de la police systeme - sinon l'exemple ne ressemble pas au rendu. */
  .ea-glyph {
    height: 20px;
    background-image: url("/media/assets/emoji/apple_1f631.png");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
  }

  /* ---------- carte de clip : tout se fait depuis la grille ---------- */
  .clip-preview { cursor: pointer; }
  .clip-preview video { width: 100%; height: 100%; object-fit: contain; background: #000; }
  .clip-play {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    color: #fff;
    opacity: 0.85;
    transition: opacity 0.18s var(--ease), transform 0.3s var(--spring);
    pointer-events: none;
  }
  .clip-play .ico {
    width: 42px; height: 42px;
    padding: 11px;
    border-radius: 50%;
    background: rgba(10, 10, 13, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(14px) saturate(160%);
    -webkit-backdrop-filter: blur(14px) saturate(160%);
    fill: currentColor; stroke: none;
  }
  .clip-card:hover .clip-play { opacity: 1; transform: scale(1.06); }
  /* La rangee d'actions doit TENIR dans la carte. Mesure : elle reclamait
     242 px pour 233 disponibles, et le bouton Publier se retrouvait coupe par
     l'arrondi de la carte. */
  .clip-actions {
    display: flex; gap: 5px; align-items: center;
    margin-top: auto; padding-top: 10px;
  }
  .clip-actions .btn {
    padding: 5px 7px; font-size: 11px;
    min-width: 0; white-space: nowrap;
  }
  /* Les deux boutons a texte se partagent la place restante ; la case a cocher
     et "Publier", qui n'ont qu'une icone, gardent leur taille. */
  .clip-actions .btn:not(:last-child) { flex: 1 1 auto; }
  .clip-actions .btn:last-child { flex: 0 0 auto; }
  .clip-actions .ico { flex: 0 0 auto; }

  /* Case de selection d'un clip pour une action groupee. */
  .clip-coche {
    display: inline-flex; align-items: center;
    padding: 4px 6px;
    border-radius: var(--r-sm);
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    cursor: pointer;
  }
  .clip-coche:hover { background: var(--glass-bg-hover); }
  .clip-coche input { cursor: pointer; }

  /* ---------- interrupteurs de l'onglet Titre ---------- */
  .switch-row {
    display: flex; align-items: center; gap: 10px;
    margin-top: 8px;
    padding: 10px 12px;
    border-radius: var(--r-sm);
    background: var(--glass-bg);
    border: 1px solid var(--glass-stroke);
    backdrop-filter: blur(16px) saturate(160%);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    box-shadow: 0 1px 0 rgb(var(--voile) / 0.16) inset;
    font-size: 12.5px; color: var(--ink-2);
    cursor: pointer;
    transition: background 0.2s var(--ease);
  }
  .switch-row:hover { background: var(--glass-bg-hover); color: var(--ink); }
  /* Vrai interrupteur plutot qu'une case a cocher du systeme. */
  .switch-row input[type="checkbox"] {
    appearance: none; -webkit-appearance: none;
    position: relative;
    width: 34px; height: 19px; margin: 0; flex: none;
    border-radius: 999px;
    background: rgb(var(--ombre) / 0.4);
    border: 1px solid var(--glass-stroke);
    cursor: pointer;
    transition: background 0.25s var(--ease);
  }
  .switch-row input[type="checkbox"]::after {
    content: ''; position: absolute;
    top: 2px; left: 2px;
    width: 13px; height: 13px;
    border-radius: 50%;
    background: var(--ink-3);
    transition: transform 0.28s var(--spring), background 0.25s var(--ease);
  }
  .switch-row input[type="checkbox"]:checked {
    background: linear-gradient(180deg, var(--fort), #d8d8e0);
    border-color: var(--glass-stroke-hi);
  }
  .switch-row input[type="checkbox"]:checked::after {
    transform: translateX(15px);
    background: var(--sur-fort);
  }
