/* ============================================================================
   EditFast.AI — mobile.css  ·  ADAPTATION MOBILE & TABLETTE (< 1024 px)
   ----------------------------------------------------------------------------
   Chargé APRÈS tailwind.css et base.css sur TOUTES les pages : à spécificité
   égale, ses règles gagnent. On ne met !important QUE pour battre un
   !important existant (ex. .popup-settings-zone de base.css).

   Sur desktop (≥ 1024 px) ce fichier ne change RIEN — tout vit dans une
   media query — sauf la section 2 qui CACHE les éléments réservés au mobile
   (bouton du tiroir, en-tête du tiroir, liens de nav du menu profil).

   SOMMAIRE
     1. RÉGLAGES GÉNÉRAUX (toutes pages)
     2. ÉLÉMENTS « MOBILE UNIQUEMENT » (cachés sur desktop)
     3. HEADER « APP » + TIROIR DU MENU PROFIL (+ 3-bis : solde sous 640 px)
     4. TIROIR DES RÉGLAGES DU STUDIO             → .colonne-parametres
     5. STUDIO PLEIN ÉCRAN — GESTIONNAIRE DE SCÈNES
     6. CARTE DE SCÈNE (média → script → audios → boutons)
     7. MODALES — RÈGLE COMMUNE : PLEIN ÉCRAN
     8. POPUPS GÉANTES — APERÇU EN HAUT, RÉGLAGES EN DESSOUS
     8-bis. TIMELINE (Aperçu de la scène) — FAÇON APP DE MONTAGE
     9. MODALES SPÉCIFIQUES (médias, automatisations, projets…)
    10. TABLEAUX LARGES → UNE CARTE PAR LIGNE     → .table-cartes (< 640 px)
   ============================================================================ */


/* ============================================================================
   2. ÉLÉMENTS « MOBILE UNIQUEMENT » — cachés par défaut (desktop).
   La media query plus bas les affiche sous 1024 px. On les déclare ICI
   (hors media query) pour ne pas dépendre des utilitaires lg:hidden /
   sm:hidden, absents du tailwind.css compilé.
   ============================================================================ */

#fab-pile,
.tiroir-reglages-header,
.tiroir-profil-header,
#user-menu-backdrop,
.nav-mobile-item,
.timeline-ctrl-mobile,
.js-app-card,
.timeline-spacer { display: none; }


/* ════════════════════════════════════════════════════════════════════════
   TOUT CE QUI SUIT NE S'APPLIQUE QUE SOUS 1024 px (= breakpoint lg de
   Tailwind : au-dessus, la mise en page desktop existante reprend la main).
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1023.98px) {

    /* 📱 Carte « Installer l'app » du profil (compte.html) : visible mobile only. */
    .js-app-card { display: block; }

    /* ========================================================================
       1. RÉGLAGES GÉNÉRAUX (toutes pages)
       ======================================================================== */

    html { -webkit-text-size-adjust: 100%; }

    /* iOS zoome automatiquement sur tout champ < 16px au focus : on force
       16px sur les champs de saisie (c'est aussi plus lisible au doigt). */
    input[type="text"],
    input[type="email"],
    input[type="password"],
    textarea,
    [contenteditable="true"] { font-size: 16px; }

    /* Les boutons révélés au survol (group-hover) n'ont pas de « survol »
       au tactile : on les affiche en permanence. */
    .opacity-0[class~="group-hover:opacity-100"] { opacity: 1; }

    /* 🚫 SÉLECTION DE TEXTE sur les CONTRÔLES : sur Android/iOS, un appui long
       (poignée de drag, bouton maintenu…) déclenche la sélection native du libellé —
       moche et déroutant dans une app. On l'interdit sur tout ce qui se TAPE
       (boutons, labels, pilules…) ; les zones de SAISIE (inputs, textarea,
       contenteditable) ne sont pas concernées et restent sélectionnables. */
    button, [role="button"], [onclick], label, summary, .pilule {
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
    }
    /* …mais un champ de saisie NICHÉ dans un contrôle (label, conteneur cliquable)
       ne doit jamais hériter du blocage : la saisie/sélection y reste normale. */
    input, textarea, [contenteditable="true"] {
        -webkit-user-select: text;
        user-select: text;
    }

    /* ▶ Bouton d'aperçu des voix (menu déroulant) : cible tactile confortable.
       Sans ça, le petit bouton (24px) est facile à rater → le tap tombe sur la
       ligne et SÉLECTIONNE la voix au lieu de l'écouter. On l'agrandit et on
       s'assure qu'il reste visible au doigt (pas de survol au tactile). */
    .btn-apercu-menu {
        width: 2.25rem;
        height: 2.25rem;
        opacity: 1;
    }
    .btn-apercu-menu svg { width: 0.9rem; height: 0.9rem; }


    /* ========================================================================
       3. HEADER « APP » + TIROIR DU MENU PROFIL
       ----------------------------------------------------------------------
       La barre ne garde que logo + solde + profil + langue : la nav
       horizontale disparaît, on retrouve TOUTES les pages dans le menu
       profil, devenu un tiroir plein hauteur qui glisse depuis la droite
       (même mécanique que .colonne-parametres : translateX + visibility).
       Fermeture : croix en haut à droite, tap sur le voile, ou n'importe
       quelle action du menu (logique dans header.js).
       ======================================================================== */

    /* Logo moins large pour laisser la place au solde + profil + langue. */
    #app-header h1 { font-size: 1.25rem; }

    /* Resserre les espacements de la barre. */
    #app-header .gap-6 { gap: 0.75rem; }

    /* Pastille du solde : plus compacte. */
    #app-header .header-solde { padding: 0.25rem 0.625rem; }

    /* La nav horizontale et son séparateur vertical laissent place au tiroir. */
    #app-header nav { display: none; }
    #app-header .w-px { display: none !important; }    /* bat le sm:block */

    /* ⚠️ backdrop-filter sur le <header> en ferait le « containing block »
       des descendants position:fixed : le tiroir serait piégé dans la barre
       de 56 px. On le retire sur mobile, fond quasi opaque à la place. */
    #app-header header {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: rgba(2, 6, 23, 0.97);
    }

    /* Voile sombre derrière le tiroir. Toujours rendu (display forcé, il bat
       le .hidden !important de base.css) : c'est l'opacité qui l'affiche,
       pour avoir un fondu synchronisé avec la glissade du tiroir.
       z-index 60/61 : internes au header (z-50), seuls ses enfants comptent. */
    #user-menu-backdrop {
        display: block !important;
        position: fixed;
        inset: 0;
        z-index: 60;
        background: rgba(2, 6, 23, 0.65);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.3s ease;
    }
    #user-menu-backdrop:not(.hidden) { opacity: 1; pointer-events: auto; }

    /* Le menu profil : plus une popup, un TIROIR plein hauteur à droite.
       .hidden ne le retire plus du rendu (sinon pas d'animation possible) :
       ce sont translateX + visibility qui le cachent. */
    #user-menu {
        display: flex !important;          /* bat .hidden (base.css) */
        flex-direction: column;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        width: min(20rem, 85vw);
        margin: 0;
        border: none;
        border-left: 1px solid #334155;    /* slate-700 */
        border-radius: 0;
        background: #0f172a;               /* slate-900 */
        box-shadow: -24px 0 60px rgba(0, 0, 0, 0.55);
        z-index: 61;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
        transform: translateX(105%);
        visibility: hidden;                /* pas de focus/tap quand fermé */
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1), visibility 0.3s;
    }
    #user-menu:not(.hidden) {
        transform: translateX(0);
        visibility: visible;
    }

    /* Rien ne s'écrase dans la colonne (piège flex-shrink). */
    #user-menu > * { flex-shrink: 0; }

    /* Entrées du tiroir : plus hautes et plus lisibles, confort au doigt. */
    #user-menu > a,
    #user-menu > button { padding: 0.9375rem 1.25rem; font-size: 0.9375rem; }

    /* 📱 Bloc « Connecté en tant que » : sur mobile on le descend tout en bas,
       juste au-dessus de la Déconnexion, pour former un pied de tiroir « compte »
       (façon Slack / Linear). Sur desktop il reste en haut (règle non appliquée ici).
       margin-top:auto colle ce bloc + la déconnexion au bas du tiroir ;
       border-top = séparateur au-dessus du groupe compte. Le border-bottom Tailwind
       du bloc sert de trait entre l'email et la Déconnexion. */
    #user-menu > .tiroir-profil-compte {
        order: 1;
        margin-top: auto;
        border-top: 1px solid #1e293b;
    }

    /* Déconnexion : ancrée tout en bas, sous le bloc compte (façon app). Ce n'est
       plus elle qui pousse vers le bas (le bloc compte s'en charge). */
    #user-menu > button:last-child { order: 2; margin-top: 0; border-top: none; }

    /* En-tête du tiroir : logo + croix de fermeture. Sticky : reste visible
       même quand le contenu du tiroir défile (petits écrans / paysage). */
    .tiroir-profil-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        position: sticky;
        top: 0;
        z-index: 10;
        padding: 0.75rem 0.75rem 0.75rem 1.25rem;
        border-bottom: 1px solid #1e293b;  /* slate-800 */
        background: rgba(2, 6, 23, 0.95);
        backdrop-filter: blur(4px);
    }
    .tiroir-profil-fermer {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 2.5rem;
        height: 2.5rem;
        border-radius: 9999px;
        color: #94a3b8;                    /* slate-400 */
        background: #1e293b;               /* slate-800 */
        border: 1px solid #334155;         /* slate-700 */
        transition: transform 0.15s, color 0.15s;
    }
    /* Le X est dessiné en CSS via --croix-icone (défini dans base.css) : même
       source que les modales .btn-fermer → changer la croix = 1 seul endroit.
       Le <button> n'a donc plus besoin de <svg> inline dans header.js. */
    .tiroir-profil-fermer::before {
        content: "";
        width: 1.25rem;
        height: 1.25rem;
        background: currentColor;
        -webkit-mask: var(--croix-icone) center / contain no-repeat;
                mask: var(--croix-icone) center / contain no-repeat;
    }
    .tiroir-profil-fermer:active { transform: scale(0.92); color: #fff; }

    /* Liens de nav (Studio / Mes Vidéos / Abonnement) visibles dans le tiroir. */
    .nav-mobile-item { display: flex; }

    /* Page courante mise en évidence : barre cyan à gauche + fond teinté
       (la classe est posée par actifMenu() dans header.js, texte déjà cyan). */
    #user-menu .menu-item-actif {
        background: linear-gradient(90deg, rgba(6, 182, 212, 0.14), rgba(6, 182, 212, 0) 70%);
        box-shadow: inset 3px 0 0 #22d3ee;   /* cyan-400 */
    }

    /* Tiroir ouvert → la page derrière ne défile plus (classe posée par header.js). */
    body.tiroir-profil-ouvert { overflow: hidden; }


    /* ========================================================================
       4. TIROIR DES RÉGLAGES DU STUDIO
       ----------------------------------------------------------------------
       La colonne de gauche (Montage / Voix IA / Sous-titres) devient un
       tiroir PLEIN ÉCRAN qui glisse depuis la gauche. Ouverture par le
       bouton flottant ; fermeture par la croix de son en-tête (js/mobile.js).
       z-index : header 50 < bouton 54 < tiroir 55 < modales 60+ (les modales
       ouvertes DEPUIS le tiroir passent bien devant lui).
       ======================================================================== */

    /* 📱 SPEED-DIAL des raccourcis (en bas à gauche). Deux icônes seulement
       (Vue d'ensemble + Réglages), affichées EN PERMANENCE : plus de bouton
       déplie/replie. */
    #fab-pile {
        position: fixed;
        left: 1rem;
        bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
        z-index: 54;
        display: flex;
    }

    /* 🗑️ Le bouton « Vue d'ensemble » du HEADER est redondant sur mobile (le
       speed-dial en bas à gauche fait déjà le dézoom) → masqué < 1024px. Il RESTE
       sur PC, où il est le seul accès au dézoom (pas de speed-dial là-bas). */
    #btn-toggle-compact { display: none; }

    /* Les 2 icônes, empilées à la verticale (1re du DOM = en haut). */
    #fab-actions {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.6rem;
    }

    /* Les pilules d'action : même langage que les boutons du header studio
       (ardoise + bordure), pour rester cohérent avec l'app. */
    .fab-action {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 3rem;
        height: 3rem;
        border-radius: 9999px;
        color: #cbd5e1;                       /* slate-300 : icône neutre par défaut */
        background: #1e293b;                  /* slate-800 */
        border: 1px solid #334155;            /* slate-700 */
        box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.6);
        transition: transform 0.15s, border-color .2s, color .2s, box-shadow .2s;
    }
    .fab-action svg { width: 1.5rem; height: 1.5rem; }

    /* Léger éclairage CYAN au survol ET au clic (cohérence avec tout le SaaS) —
       aucun état « allumé » qui persiste. */
    @media (hover: hover) {
        .fab-action:hover { color: #22d3ee; border-color: #06b6d4; }
    }
    .fab-action:active { transform: scale(0.92); color: #22d3ee; border-color: #06b6d4; }

    /* 🔽 Quand une fenêtre est ouverte (tiroir des réglages ou modale plein écran),
       les 2 icônes s'effacent : elles ne doivent JAMAIS flotter par-dessus une
       fenêtre. (Elles réapparaissent à la fermeture de la fenêtre.) */
    body.tiroir-ouvert #fab-pile,
    body.scroll-verrouille #fab-pile {
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
    }

    /* Le tiroir lui-même : la colonne existante, sortie du flux. C'est une PILE
       (flex column) qui occupe TOUT l'écran : en-tête en haut, puis les 3 cartes
       qui se PARTAGENT la hauteur restante (cf. règles .card-param plus bas).
       Le scroll vertical n'est qu'un filet de sécurité pour les très petits
       écrans : avec les espacements compacts, tout tient sans scroller. */
    .colonne-parametres {
        position: fixed;
        inset: 0;
        z-index: 55;
        display: flex;
        flex-direction: column;
        background: #020617;               /* slate-950 (fond de l'app) — espacements gérés par les margin-top plus bas */
        padding: 0 0.875rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
        overflow-x: hidden;
        overflow-y: auto;                   /* filet : on scrolle au lieu de couper */
        transform: translateX(-100%);
        visibility: hidden;                 /* pas de focus/tap quand fermé */
        transition: transform 0.3s ease, visibility 0.3s;
    }
    .colonne-parametres.is-open {
        transform: translateX(0);
        visibility: visible;
    }

    /* En-tête du tiroir : titre + croix. Hauteur fixe en haut de la pile
       (flex-shrink:0 → jamais écrasé par les cartes). */
    .tiroir-reglages-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex: 0 0 auto;
        margin: 0 -0.875rem;                /* pleine largeur malgré le padding */
        padding: 0.75rem 1.125rem;
        background: rgba(2, 6, 23, 0.95);
        border-bottom: 1px solid #1e293b;   /* slate-800 */
    }

    /* Les 3 cartes (Montage / Voix IA / Sous-titres) gardent leur hauteur
       NATURELLE (flex:0 0 auto) et s'empilent depuis le haut ; le surplus de
       hauteur reste EN BAS. Espacements FIXES via margin-top (ce sélecteur
       surclasse le space-y-6 de Tailwind) :
         · 20px entre deux cartes,
         · 15px sous l'en-tête (au-dessus de la 1re carte, règle ci-dessous). */
    .colonne-parametres.space-y-6 > :not([hidden]) ~ :not([hidden]) {
        margin-top: 20px;                   /* écart entre les cartes de réglages */
    }
    .colonne-parametres.space-y-6 > .tiroir-reglages-header + .card-param {
        margin-top: 15px;                   /* écart plus court sous l'en-tête (même spécificité, placé après → prioritaire) */
    }
    .colonne-parametres .card-param {
        flex: 0 0 auto;                     /* taille naturelle : ne s'étire jamais */
        display: flex;
        flex-direction: column;
        justify-content: flex-start;        /* contenu en haut de la carte */
        padding: 1rem 1.125rem;             /* p-6 desktop → trop gourmand en hauteur ici */
    }

    /* Espacements internes resserrés : c'est ce qui garantit que les 3 cartes
       tiennent sur un téléphone (≈ 660 px de contenu pour ~740 px visibles). */
    .colonne-parametres .card-param .card-header { margin-bottom: 0.75rem; }
    .colonne-parametres .card-param .mb-4 { margin-bottom: 0.75rem; }
    .colonne-parametres .card-param .btn-param { padding: 0.625rem; }
    .colonne-parametres .card-param .btn-param.mt-3 { margin-top: 0.5rem; }

    /* Écrans courts (petits téléphones ~660 px et moins) : on resserre encore
       d'un cran pour que les 3 cartes tiennent toujours sans scroller. */
    @media (max-height: 700px) {
        .colonne-parametres.space-y-6 > :not([hidden]) ~ :not([hidden]) { margin-top: 12px; }   /* écran court : cartes resserrées */
        .colonne-parametres.space-y-6 > .tiroir-reglages-header + .card-param { margin-top: 10px; }  /* écran court : sous l'en-tête */
        .colonne-parametres .card-param { padding: 0.7rem 1rem; }
        .colonne-parametres .card-param .card-header { margin-bottom: 0.5rem; }
        .colonne-parametres .card-param .mb-4 { margin-bottom: 0.5rem; }
        .colonne-parametres .tiroir-reglages-header { padding-top: 0.5rem; padding-bottom: 0.5rem; }
    }

    /* Pendant que le tiroir est ouvert, la page derrière ne scrolle pas. */
    body.tiroir-ouvert { overflow: hidden; }

    /* 🔒 MODALES : idem quand une pop-up est ouverte (classe posée par utils.js).
       Fond figé = plus propre (ne bouge pas sous le doigt) + moins de repaint.
       Les petits menus « pour choisir » ne posent pas cette classe → non bloqués. */
    body.scroll-verrouille { overflow: hidden; }


    /* ========================================================================
       5. STUDIO PLEIN ÉCRAN — GESTIONNAIRE DE SCÈNES
       ----------------------------------------------------------------------
       On « met à plat » les conteneurs : plus de grosse carte grise autour
       du gestionnaire, les scènes occupent toute la largeur de l'écran et
       défilent avec la page (plus de zone à hauteur bloquée).
       ======================================================================== */

    #layout-studio {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
        /* réserve en bas de page : les 2 icônes flottantes (empilées) ne
           recouvrent jamais « Assemblez toutes les scènes » en fin de scroll */
        padding-bottom: 8rem;
    }

    /* 🔎 Vue d'ensemble sur mobile : la carte-résumé reçoit un fond de carte
       (le .scene-block est mis à plat par la règle mobile ci-dessous) et
       s'aère un peu moins pour tenir sur les écrans étroits.
       → uniquement les cartes REPLIÉES : la scène dépliée garde l'apparence
       normale (bg-slate-900/80 + border-slate-700 du HTML). */
    #scenes-container.mode-compact .scene-wrapper:not(.scene-depliee) .scene-block {
        background: #0f172a;                 /* slate-900 : la carte redevient visible */
        border: 1px solid #1e293b;
        border-radius: 0.9rem;
    }
    #scenes-container.mode-compact .scene-resume { gap: 0.7rem; padding: 0.5rem 0.6rem; }
    #scenes-container.mode-compact .resume-miniature { width: 2.9rem; height: 2.9rem; }

    /* Le panneau qui enveloppait le gestionnaire disparaît visuellement. */
    #panneau-scenes {
        background: transparent;
        border: 0;
        box-shadow: none;
        padding: 0;
        border-radius: 0;
    }

    /* Les scènes défilent avec la page : plein écran, pas de hauteur bloquée. */
    #scenes-container { max-height: none; }

    /* ✍️ BANDEAU DE RELECTURE — IL SUIT LE DÉFILEMENT, EN HAUT.
       Il garde EXACTEMENT sa place — juste au-dessus de la première scène — mais
       il s'accroche en haut de l'écran dès qu'on descend relire : sans ça, il
       sortait par le haut au premier scroll, et le bouton qui lance les images
       avec lui — il fallait remonter toute la vidéo pour cliquer.

       `top: 8px` et pas « sous le header » : le header du site N'EST PAS réellement
       collant. Son `sticky top-0` vit dans #app-header, un conteneur qui fait
       exactement sa hauteur — un sticky ne dépasse jamais son parent, donc le
       header défile hors de l'écran comme le reste. Le caler à 3,9rem laissait
       un grand vide au-dessus du bandeau, qui semblait tomber au milieu de l'écran.
       Il n'y a rien au-dessus de lui une fois qu'on a descendu : 8 px suffisent.
       (Le bandeau se décroche vers scrollY ≈ 60, quand le header est déjà sorti :
       les deux ne se croisent pas.)

       z-index 45 : au-dessus des scènes qui défilent derrière, sous le header (50)
       et sous les fenêtres (60+).

       Le fond est déjà opaque (#0f172a dans le HTML) : indispensable, le contenu
       passe derrière. L'ombre portée dit qu'il flotte au-dessus du reste. */
    #ia-relecture {
        position: sticky;
        top: 0.5rem;
        z-index: 45;
        box-shadow: 0 10px 26px -12px rgba(0, 0, 0, .95);
    }

    /* Barre de titre : plus compacte pour tenir avec les 3 boutons d'action.
       (Elle reste dans le flux : une version sticky a été essayée puis retirée
       à la demande d'Alexy — rendu jugé bugué en haut de page.) */
    #panneau-scenes h2 { font-size: 1rem; }
    #save-status-text { display: none; }    /* la pastille de couleur suffit */

    /* Bouton final d'assemblage : hauteur tactile confortable, texte adapté. */
    #btn-assembler {
        font-size: 1.05rem;
        padding-top: 0.9rem;
        padding-bottom: 0.9rem;
    }

    /* ⚠️ Ce décalage n'a de sens QUE quand la barre d'action est EMPILÉE (< 640px).
       À partir de 640px, Tailwind la repasse en ligne (sm:flex-row) : le margin-top
       poussait alors le seul CTA vers le bas, si bien que l'aperçu et la corbeille
       flottaient plus haut que lui et n'avaient plus sa hauteur (bug vu sur écran
       moyen). En ligne, l'alignement et la hauteur commune viennent du flex, et
       l'espacement du gap-2 déjà porté par le conteneur. */
    @media (max-width: 639px) {
        #btn-assembler { margin-top: 0.5rem; }
    }


    /* ========================================================================
       6. CARTE DE SCÈNE — média → script → audios → boutons
       ----------------------------------------------------------------------
       La grille 2 colonnes (média | script) devient une pile verticale :
       1) média (aperçu + colonne d'icônes à sa droite)   2) script
       3) pilules audio + poubelle + seed voix   4) rangée Générer/Écouter
       puis Aperçu (classe .scene-actions)   5) sélecteur de transition aéré.
       ======================================================================== */

    .scene-wrapper { margin-bottom: 0.875rem; } /* respiration SOUS le sélecteur
                                                 de transition, égale à celle
                                                 au-dessus (cf. 5) */
    .scene-block { padding: 0.875rem; padding-top: 2rem; } /* le n° de scène
                                                 reste lisible en haut */

    /* La grille interne passe en pile. */
    .scene-block > .grid {
        display: flex;
        flex-direction: column;
        gap: 0.875rem;
    }
    .scene-block .col-span-4,
    .scene-block .col-span-8 { width: 100%; }

    /* 1) MÉDIA : l'aperçu garde toute la place à gauche, les 4 icônes
       (importer / recherche IA / image IA / réglages) s'empilent verticalement
       à droite. Le bouton image IA (✨ créer · ↻ refaire) est le 3e : il a un
       sens sur toute scène, contrairement à l'ancien ↻ qui ne savait que
       refaire et vivait pour ça dans le coin de l'aperçu. */
    .scene-block .col-span-4 {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 0.75rem;
        align-items: start;
    }
    .scene-block .col-span-4 > .h-6 { grid-column: 1 / -1; }
    /* NB : bien cibler div.flex (la rangée de boutons) — l'aperçu (label.preview-box)
       porte AUSSI flex + justify-center et serait attrapé par un sélecteur trop large. */
    /* Hauteur = EXACTEMENT la colonne des boutons à sa droite :
       4 × 2.75rem + 3 écarts de 0.625rem = 12.875rem (bloc média bien aligné).
       ⚠️ À recalculer si on ajoute ou retire un bouton de cette colonne — la
       formule est (n × 2.75) + ((n − 1) × 0.625) ; c'était 9.5rem quand ils
       étaient 3, avant que le bouton image IA rejoigne la barre. */
    .scene-block .preview-box {
        grid-column: 1;
        grid-row: 2;
        height: 12.875rem;
        margin-bottom: 0;
    }
    .scene-block .col-span-4 > div.flex.justify-center {
        grid-column: 2;
        grid-row: 2;
        flex-direction: column;
        justify-content: flex-start;
        gap: 0.625rem;
    }
    /* Boutons du média : taille tactile. */
    .scene-block .col-span-4 > div.flex.justify-center button {
        width: 2.75rem;
        height: 2.75rem;
    }

    /* (Le bouton image IA n'a plus de règle ici : il a rejoint la colonne des
       boutons média ci-dessus, donc il hérite déjà de leur taille tactile de
       2,75rem. Il vivait avant en pastille dans le coin de l'aperçu.) */

    /* 2) SCRIPT : plus de marge réservée à la poubelle (elle est plus haut). */
    .scene-block .col-span-8 { padding-right: 0; }

    /* Champ de saisie légèrement plus haut ; le padding du bas réserve la
       place de la barre d'outils : le texte ne passe JAMAIS derrière, il
       défile. (La barre de défilement est cachée par .sans-scrollbar, posée
       sur le champ dans le HTML — PC comme mobile.) */
    .scene-block .texte-input {
        height: 13.75rem;                   /* +2 lignes de texte (2 × 1.25rem) */
        padding-bottom: 3rem;
    }

    /* Masque du bas (cf. .script-fade dans base.css) adapté au mobile :
       la couleur composée diffère (le panneau devient transparent en mobile,
       donc scene-block slate-900/80 › body slate-950  ≈ rgb(21,31,49)). */
    .scene-block .script-fade {
        height: 2.75rem;                  /* < padding-bottom mobile (3rem) */
        background: linear-gradient(to top,
            rgb(21, 31, 49) 0%,
            rgb(21, 31, 49) 78%,
            rgba(21, 31, 49, 0) 100%);
    }

    /* La barre d'outils du script (Animation / Sons / Emotes) est CENTRÉE sur le
       champ de saisie et peut passer sur deux lignes sans recouvrir le texte.
       Boutons un peu plus gros qu'à la souris (cibles tactiles). */
    .scene-block .barre-outils-script { justify-content: center; }
    .scene-block .barre-outils-script .gap-4 {
        /* L'écart se resserre tout seul sur les petits téléphones : les 3 libellés
           tiennent alors sur UNE ligne même en espagnol (« Animación | Sonidos |
           Emotes », le plus long des 5 langues). Au-delà de 500px, plafond à 1.25rem. */
        gap: clamp(0.75rem, 4vw, 1.25rem);
        flex-wrap: wrap;
        justify-content: center;
    }
    .scene-block .barre-outils-script .gap-4 button { font-size: 0.6875rem; }   /* 11px (au lieu de 10) */
    .scene-block .barre-outils-script .gap-4 button svg { width: 1.125rem; height: 1.125rem; }

    /* 📋 « Copier le script » : au doigt, c'est une BULLE soudée au coin bas-droit du
       champ — même fond que le masque (.script-fade ci-dessus) et même bordure que le
       champ, seul le coin haut-gauche est arrondi : elle a l'air taillée dans le champ
       plutôt que posée dessus. Elle est sortie du flux pour ne pas décaler le groupe
       Animation/Sons/Emotes, et la barre lui réserve sa place à droite (padding) pour
       ne jamais recouvrir « Emotes ».
       Position : la barre est rentrée de 0,75rem (bottom-3 / right-3) ; on la lui
       retire pour atteindre le bord du champ, +1px pour rester DANS sa bordure. */
    .scene-block .barre-outils-script { padding-right: 2.25rem; }
    .scene-block .btn-copier-scene {
        position: absolute;
        right: calc(-0.75rem + 1px);
        bottom: calc(-0.75rem + 1px);
        width: 2.625rem;                              /* 42px : cible tactile, −5 % */
        height: 2.625rem;
        background: rgb(21, 31, 49);                  /* = bas du .script-fade mobile */
        border-top: 1px solid #334155;                /* slate-700, comme le champ */
        border-left: 1px solid #334155;
        border-radius: 0.9rem 0 0.7rem 0;             /* seul le coin intérieur s'arrondit ;
                                                         0.7rem épouse le rounded-xl du champ */
    }
    .scene-block .btn-copier-scene svg { width: 1.1875rem; height: 1.1875rem; }   /* 19px, −5 % */
    /* Quand on tape, le champ passe en bordure cyan (focus:border-cyan-400) : la bulle
       suit, sinon son trait gris trancherait au milieu du contour allumé. */
    .scene-block .texte-input:focus ~ .barre-outils-script .btn-copier-scene {
        border-color: #22d3ee;
    }
    /* Retour tactile (cf. base.css §17 : au doigt les :hover sont désactivés). */
    .scene-block .btn-copier-scene:active { background: #1e293b; color: #cbd5e1; }   /* = le survol souris */

    /* 3) LIGNE DES AUDIOS : pilules à leur taille d'origine, poubelle juste à
       côté — une seule ligne, espacement uniforme (le gap-2 du HTML ; le mr-2
       « en dur » du JS saute pour éviter le double espace). Le bouton seed de
       cette ligne est masqué : sa version mobile vit à côté de « Générer
       Audio » (cf. 4). Si vraiment trop étroit, ça passe à la ligne. */
    .scene-block div:has(> .zone-pilules) {
        margin-top: 0.625rem;
        flex-wrap: wrap;
    }
    .scene-block .zone-pilules { min-width: 0; }
    .scene-block .prise-audio-btn {
        flex: 0 0 auto;
        margin-right: 0;
        white-space: nowrap;
    }
    .scene-block button[onclick^="viderPrisesAudio"] { padding: 0.375rem; }
    .scene-block .btn-seed-voix { display: none; }

    /* 4) BOUTONS D'ACTION : la rangée Générer Audio / Écouter d'abord,
       le bouton Aperçu en dessous (column-reverse : l'ordre du HTML
       reste Aperçu → Générer, on inverse seulement l'affichage). */
    .scene-actions {
        flex-direction: column-reverse;
        align-items: stretch;
        gap: 0.75rem;
    }
    .scene-actions .btn-ajuster-timeline {
        width: 100%;
        justify-content: center;
    }
    .scene-actions > div {
        display: flex;
        width: 100%;
        gap: 0.75rem;
    }
    .scene-actions .btn-generer {
        flex: 1 1 0;
        justify-content: center;
    }
    /* « Écouter » disparaît : cliquer une pilule Audio 1/2/3 (re)joue la prise. */
    .scene-actions .btn-play { display: none; }
    /* 🎙️ Seed voix mobile (caché sur PC via .hidden) : carré, même hauteur
       que « Générer Audio ». Le !important est obligatoire pour « rallumer »
       un .hidden — lui-même en !important (interop Tailwind, cf. base.css). */
    .scene-actions .btn-seed-voix-action {
        display: flex !important;
        flex: 0 0 auto;
        align-self: stretch;
        width: 2.75rem;
    }

    /* 5) SÉLECTEUR DE TRANSITION : réintégré dans le flux (plus d'absolu) et
       centré entre les deux cartes — même respiration au-dessus et en dessous
       (0.875rem, cf. margin-bottom du wrapper plus haut). position:relative
       plutôt que static pour garder son z-[60] : le tiroir ouvert passe
       au-dessus de la scène suivante. */
    .scene-wrapper > .-bottom-5 {
        position: relative;
        bottom: auto;
        left: auto;
        transform: none;
        margin-top: 0.875rem;
    }


    /* ========================================================================
       7. MODALES — RÈGLE COMMUNE : PLEIN ÉCRAN
       ----------------------------------------------------------------------
       TOUTES les fenêtres pop-up (#…-modal) occupent tout l'écran : même
       gabarit partout, plus rien ne dépasse. Seule exception : la petite
       alerte de confirmation (#custom-alert-modal) reste une boîte centrée.
       Les !important battent les utilitaires arbitraires (w-[95vw], h-[85vh])
       et la .popup-unifiee (!important) de base.css.
       ======================================================================== */

    /* ⚡ #panneau-generateur est ajouté à la main : son id ne finit pas par « -modal »,
       il ratait donc la règle générique et restait la SEULE fenêtre du studio à flotter
       au milieu de l'écran. Elle perdait 32 px de largeur (le padding de son fond) sur
       un téléphone de 360 px — là où c'est le plus précieux. */
    div[id$="-modal"]:not(#custom-alert-modal) > div,
    #panneau-generateur > div {
        width: 100vw !important;
        max-width: none !important;
        height: 100vh !important;
        height: 100dvh !important;
        max-height: none !important;
        border-radius: 0 !important;
        border: 0 !important;
    }

    /* Le fond du générateur ne doit plus réserver de marge autour de sa carte. */
    #panneau-generateur { padding: 0 !important; }

    /* 🎨 GALERIE DES STYLES — la grille est en style INLINE dans le HTML
       (repeat(4, …)), d'où le !important : sans lui, l'inline gagne toujours.
       À 4 colonnes sur un téléphone, chaque vignette tombait à ~48-58 px : la
       taille d'un favicon, pour un choix qu'on fait justement AVEC LES YEUX.
       En plein écran + 3 colonnes on passe à ~95 px, et à ~140 px sur 2. */
    #galerie-styles { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }

    /* Les libellés (« Cinématique », « Minimaliste »…) tiennent alors sans se couper,
       y compris en allemand et en espagnol. */
    #galerie-styles .carte-style span { font-size: 0.66rem !important; }

    /* En-tête de modale plus compact (gagne de la hauteur d'écran). */
    .modal-header,
    .modal-header.is-lg { padding: 0.75rem 1rem; }

    /* Modales à contenu « simple » (une seule zone sous l'en-tête) : cette
       zone s'étire et scrolle — le bouton Valider reste accessible. */
    #voice-modal-content > div:last-child,
    #projects-modal-content > div:last-child,
    #perso-modal-content > div:last-child,
    #effect-anim-content > div:last-child {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
    }

    /* 🎭 Personnage redessiné : en plein écran, le portrait peut prendre la place
       qu'il mérite — c'est précisément ce qu'on est venu regarder. Les deux boutons
       restent visibles sous lui (la zone scrolle si l'écran est vraiment court). */
    #perso-modal-img { max-height: 62vh !important; }


    /* ========================================================================
       8. POPUPS GÉANTES — APERÇU EN HAUT, RÉGLAGES EN DESSOUS
       ----------------------------------------------------------------------
       Sous-titres, Éditeur de média, Master (animation) et Timeline : les
       deux colonnes (aperçu téléphone | réglages) s'empilent. L'aperçu garde
       40 % de la hauteur, les réglages prennent le reste et tout le corps
       scrolle d'un bloc.
       ======================================================================== */

    .popup-unifiee > .flex-row {
        flex-direction: column;
        overflow-y: auto;
    }

    .popup-preview-zone {
        flex: 0 0 auto;
        height: 40vh;
        height: 40dvh;
        padding: 0.75rem;
        border-right: none;
        border-bottom: 1px solid #1e293b;   /* slate-800 */
    }

    .popup-settings-zone,
    .popup-settings-timeline {
        width: 100% !important;
        height: auto;
        flex: 1 0 auto;
        overflow-y: visible;                /* c'est le corps qui scrolle */
        padding: 1rem;
    }

    /* Master (Créer une Animation) & Sous-titres : aperçu aussi grand que
       celui de la Timeline (47dvh), et réglages qui respirent MOINS sur les
       bords — conteneurs plus larges, plus de gros trou sous la ligne de
       séparation (demande d'Alexy 2026-07-06). */
    #sequence-master-content .popup-preview-zone,
    #subtitles-modal-content .popup-preview-zone {
        height: 47vh;
        height: 47dvh;
        padding: 0.625rem;
    }
    #sequence-master-content .popup-settings-zone,
    #subtitles-modal-content .popup-settings-zone {
        padding: 0.625rem 0.5rem;
    }
    /* Le Master a un wrapper interne p-5 qui DOUBLAIT le padding de la zone
       (2.25rem cumulés sur les bords) : neutralisé, la zone seule suffit.
       On garde juste un fond de padding en bas : il SÉPARE le bloc
       Entrée/Milieu/Sortie du pied « Mes animations » (fond slate-800). */
    #sequence-master-content .popup-settings-zone > .p-5 { padding: 0 0 0.875rem; }

    /* « Image de test » remonte contre la ligne de séparation : on annule le
       margin-top du space-y-4 (le petit espace restant = padding de la zone). */
    #sequence-master-content .popup-settings-zone > .p-5 > [id^="studio-type-"] { margin-top: 0; }

    /* 📱 Pas de coque de téléphone 3D sur mobile (elle mange la place) :
       l'aperçu devient un simple cadre au format sélectionné — portrait et
       paysage gardent leur aspect-ratio via actualiserFormatTelephones(). */
    .mockup-telephone,
    .mockup-telephone.portrait,
    .mockup-telephone.paysage {
        border: 1px solid #334155;          /* slate-700 */
        border-radius: 0.75rem;
        box-shadow: none;
    }
    .mockup-telephone::before,              /* bulle caméra */
    .mockup-telephone::after { content: none; }  /* liseré métallique */


    /* ========================================================================
       8-bis. TIMELINE (Aperçu de la scène) — FAÇON APP DE MONTAGE
       ----------------------------------------------------------------------
       · Aperçu FIXE (comme CapCut) : le téléphone ne change JAMAIS de taille,
         quel que soit le nombre de sons/animations — zéro re-layout de la
         vidéo, sous-titres toujours à l'échelle. Lecture + timecode à côté du
         téléphone (les contrôles de la colonne réglages et le play superposé
         au clip sautent).
       · Tête de lecture FIXE au centre : la timeline DÉFILE au doigt dessous
         (scroll horizontal natif avec inertie) ; pincer à 2 doigts = zoom de
         l'échelle de temps. Largeur de piste posée en px par le JS
         (timeline_avancee.js § 8 : durée × timelinePxParSec).
       · Les blocs SFX/FX se déplacent au doigt (Pointer Events). Leur hauteur
         est ADAPTATIVE : pleine taille jusqu'à 4 étages, compressée au-delà
         pour que tout tienne (hauteurEtageTimeline, timeline_avancee.js).
       ======================================================================== */

    /* Le corps de la modale ne scrolle plus d'un bloc : TOUT tient à l'écran —
       aperçu fixe en haut, timeline + bouton Valider en bas. */
    #timeline-modal-content > .flex-row { overflow-y: hidden; }

    /* L'aperçu prend LA PLACE RESTANTE au-dessus du panneau timeline. Comme
       ce panneau a une hauteur FIXE (ci-dessous), l'aperçu est lui aussi
       stable : il ne dépend plus du nombre de blocs posés. */
    #timeline-modal .popup-preview-zone {
        flex: 1 1 auto;
        height: auto;
        min-height: 6rem;
        padding: 0.5rem;
    }

    /* Panneau timeline à hauteur FIXE : la place de 4 étages pleins (2 sons +
       2 animations, 3 + 1…) est réservée d'office — 23rem = règle Audio +
       étiquettes + 200px de pistes + bouton Valider. Avec moins de blocs, le
       vide reste EN BAS des pistes (Valider ancré au fond) ; avec 5-6 étages,
       c'est la hauteur des étages qui se comprime (JS), pas l'aperçu. Le
       min() protège les écrans très courts (paysage) : l'aperçu garde ~6rem
       et, en tout dernier secours, le panneau scrolle en interne. */
    #timeline-modal .popup-settings-timeline {
        flex: 0 0 auto;
        height: min(23rem, calc(100% - 6.5rem));
        min-height: 0;
        overflow-y: auto;
    }
    /* Ancre le bouton Valider en bas du panneau (bat le margin-top:0.375rem
       de la règle de compactage « > * + * » plus bas). */
    #timeline-modal .popup-settings-timeline > .btn-valider { margin-top: auto; }

    /* Espace entre les contrôles (gauche) et le téléphone. */
    #timeline-modal .popup-preview-zone > div { gap: 0.875rem; }
    /* En 16:9 le mockup (flex-shrink:0 dans base.css) doit pouvoir se
       comprimer pour laisser la place aux contrôles à sa gauche. */
    #timeline-modal .popup-preview-zone .mockup-telephone {
        flex-shrink: 1;
        min-width: 0;
    }

    /* Play + timecode empilés. order:2 → toujours APRÈS le mockup : à droite
       en rangée (portrait) et en dessous en colonne (paysage). Leur placement
       fin dépend du format vidéo → voir les règles :has() plus bas. */
    .timeline-ctrl-mobile {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.5rem;
        flex: 0 0 auto;
        order: 2;
    }
    .timeline-ctrl-mobile button {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 3rem;
        height: 3rem;
        border-radius: 9999px;
        color: #fff;
        background: linear-gradient(135deg, #06b6d4, #0891b2);   /* cyan-500 → cyan-600 */
        box-shadow: 0 8px 20px -6px rgba(6, 182, 212, 0.6);
        transition: transform 0.15s;
    }
    .timeline-ctrl-mobile button:active { transform: scale(0.9); }
    #timeline-timecode-mobile {
        font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
        font-size: 0.625rem;
        font-weight: 900;
        letter-spacing: 0.05em;
        color: #22d3ee;                                          /* cyan-400 */
    }

    /* — PLACEMENT DES CONTRÔLES SELON LE FORMAT VIDÉO —
       Le JS (actualiserFormatTelephones) pose .paysage (16:9 YouTube) ou
       .portrait (9:16 TikTok) sur le mockup ; on s'y adapte via :has() sur
       la rangée flex de l'aperçu. */

    /* 🖥️ YouTube (16:9) : aperçu CENTRÉ EN HAUT, play juste EN DESSOUS.
       La rangée passe en colonne ; order:2 place les contrôles sous le mockup. */
    #timeline-modal .popup-preview-zone > div:has(.mockup-telephone.paysage) {
        flex-direction: column;
    }

    /* 📱 TikTok (9:16) : téléphone CENTRÉ, play FLOTTANT en bas à droite
       (position absolue → il ne pousse plus le téléphone hors du centre). */
    #timeline-modal .popup-preview-zone > div:has(.mockup-telephone.portrait) {
        position: relative;
    }
    #timeline-modal .popup-preview-zone > div:has(.mockup-telephone.portrait) .timeline-ctrl-mobile {
        position: absolute;
        right: 0.25rem;
        bottom: 0.25rem;
        z-index: 5;
    }

    /* Les contrôles de la colonne réglages sont remplacés par ceux de
       l'aperçu ; le play superposé sur le clip devient superflu. */
    .timeline-barre-lecture,
    #timeline-modal #btn-apercu-player { display: none; }

    /* — LA TIMELINE DÉFILANTE — */

    /* Le conteneur des pistes colle à son contenu (sinon flex-1 l'étire
       jusqu'au bouton Valider et la tête de lecture traverse tout l'écran). */
    #timeline-tracks-container { flex: 0 0 auto; }

    /* Le wrapper défile horizontalement, sans barre visible ; le pan reste
       horizontal (le pincement est intercepté en JS) et le geste ne déclenche
       jamais le « retour arrière » du navigateur en bord de piste. */
    #timeline-scroll-wrapper {
        overflow-x: auto;
        overflow-y: hidden;
        touch-action: pan-x;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    #timeline-scroll-wrapper::-webkit-scrollbar { display: none; }

    /* Espaces avant/après la piste : le temps 0 ET la fin peuvent rejoindre
       la tête de lecture, fixe au centre. flex-shrink:0 est vital : sinon le
       contenu débordant les écrase (cf. piège flex-shrink, en-tête du fichier). */
    .timeline-spacer {
        display: block;
        flex: 0 0 50%;
    }

    /* La piste elle-même : largeur en px fixée par le JS (durée × zoom). */
    #timeline-inner { flex: 0 0 auto; }

    /* — UN SEUL ENSEMBLE SOLIDAIRE, MAIS DES RANGÉES LISIBLES — */
    /* Les cadres arrondis d'origine glissaient avec le défilement : impression
       de décaler les pistes entières par rapport à la base de temps (le geste
       ne fait pourtant que déplacer le curseur de lecture). À la place :
       · un fond teinté UNIFORME sur toute la longueur de chaque piste
         (violet = animations, cyan = sons) → la rangée s'identifie d'un coup
         d'œil, même vide, sans que rien ne semble bouger ;
       · des étiquettes COLLANTES (sticky) : Audio, Animations et Sons restent
         lisibles au bord gauche pendant le défilement au lieu de partir avec
         le temps. */
    #timeline-inner label {
        display: inline-block;
        position: sticky;
        left: 0.25rem;
    }
    #timeline-ruler {
        background: transparent;
        border-bottom: none;
    }
    #track-fx {
        background: rgba(147, 51, 234, 0.12);                 /* violet-600 */
        border: none;
        border-top: 1px solid rgba(168, 85, 247, 0.4);        /* purple-400 */
        border-bottom: 1px solid rgba(168, 85, 247, 0.4);
        border-radius: 0;
    }
    #track-sfx {
        background: rgba(6, 182, 212, 0.10);                  /* cyan-500 */
        border: none;
        border-top: 1px solid rgba(34, 211, 238, 0.4);        /* cyan-400 */
        border-bottom: 1px solid rgba(34, 211, 238, 0.4);
        border-radius: 0;
    }
    /* overflow: visible est VITAL pour les étiquettes sticky : avec son
       overflow-y-auto d'origine, cette zone devient leur référence de
       défilement et elles glissent avec le contenu au lieu de coller au bord. */
    #timeline-scroll-area { overflow: visible; }

    /* — COMPACTAGE VERTICAL : dense mais encore aéré (on est sur mobile) —
       · au-dessus d'« Audio »      : le seul espace = padding-top de la zone ;
       · au-dessus d'« Animations »: le mb-2 de la règle passe à 0.375rem ;
       · au-dessus de « Sons »      : le space-y-4 (1rem) passe à 0.375rem. */
    #timeline-modal .popup-settings-timeline { padding: 0.375rem 0.75rem 0.75rem; }
    #timeline-modal .popup-settings-timeline > * + * { margin-top: 0.375rem; }
    #timeline-modal #timeline-tracks-container { margin-top: 0; }
    #timeline-modal #timeline-ruler { margin-bottom: 0.375rem; }
    #timeline-modal #timeline-scroll-area > * + * { margin-top: 0.375rem; }
    #timeline-modal #timeline-scroll-area { padding-bottom: 0.25rem; }

    /* Tête de lecture FIXE au centre, un poil plus épaisse pour le doigt.
       !important : bat la classe left-[0%] du HTML et tout style inline
       résiduel écrit par le mode desktop. */
    #timeline-playhead {
        left: 50% !important;
        width: 2px;
    }
    /* Le losange doit être CENTRÉ sur la ligne de 2px. Sans `left`, il se cale
       sur le bord GAUCHE de la ligne (le translateX(-50%) du HTML le centre sur
       x=0 → décalé d'1px). left:50% le pose au milieu de la ligne avant le
       translate → losange pile sur la ligne. */
    #timeline-playhead > div {
        left: 50%;
    }

    /* Déplacement des blocs SFX/FX au doigt : sans ça, le navigateur
       transforme le geste en défilement de la timeline et lâche le bloc
       en plein drag (pointercancel). La HAUTEUR des blocs est posée en px
       par le JS (adaptative selon le nombre d'étages, cf. reorganiser-
       BlocsTimeline) : rien à fixer ici. */
    .timeline-block { touch-action: none; }


    /* ========================================================================
       9. MODALES SPÉCIFIQUES
       ======================================================================== */

    /* 🔍 Recherche média : grille plus dense. */
    #media-results {
        padding: 0.75rem;
        gap: 0.5rem;
    }

    /* ⚙️ Automatisations : parcours guidé en 2 étapes.
       Les 2 colonnes (scènes | réglages) s'empilent et le corps scrolle,
       avec 3 aides mobiles (invisibles sur desktop) :
       - titres « ① Choisis tes scènes / ② Applique tes effets » ;
       - liste des scènes à hauteur bornée (scroll interne) pour que
         l'étape ② reste découvrable sans scroller 15 cartes ;
       - bouton Valider flottant en bas de l'écran, toujours accessible. */
    #automation-modal-content > .grid {
        display: flex;
        flex-direction: column;
        overflow-y: auto;
        padding: 0.875rem;
        gap: 1.25rem;
        /* réserve la place du bouton Valider flottant (padding > bouton + marge) */
        padding-bottom: 5.5rem;
    }
    #automation-modal-content > .grid > div {
        height: auto;
        min-height: 0;
        flex: 0 0 auto;     /* jamais comprimées : c'est le corps qui scrolle */
        border-right: none;
        padding: 0;
        overflow: visible;
    }
    /* Liste des scènes : hauteur bornée (scroll interne), UNE colonne de cartes
       COMPACTES (demande Alexy : en 2 colonnes, les 4 badges d'état + la poubelle
       ne tenaient pas dans l'en-tête ; en 1 colonne aplatie on affiche autant de
       scènes, tout à l'aise). On neutralise les marges Tailwind (space-y-3 sur le
       conteneur, mb-2 sur les cartes, mt-2 sur « Ajouter ») : c'est le gap qui espace. */
    #grille-sequence-container {
        flex: none;
        max-height: 42vh;
        max-height: 42dvh;
        overflow-y: auto;
        padding-right: 0.25rem;
        padding-bottom: 0;
        display: grid;
        grid-template-columns: 1fr;
        gap: 0.4rem;
        align-content: start;
    }
    #grille-sequence-container > * + * { margin-top: 0; }   /* annule space-y-3 */
    /* Les cartes sont compactes PAR CONSTRUCTION (titre + badges à gauche, carrés
       image/son + poubelle à droite — montage-1) : la zone gauche sert au scroll
       et à la sélection, loin des uploads. Ici on annule juste la marge Tailwind. */
    #grille-sequence-container .scene-card-auto { margin-bottom: 0; }
    #grille-sequence-container .scene-card-auto label {
        letter-spacing: 0.02em;
        white-space: nowrap;
    }
    /* Bouton « Ajouter un calque » : pleine largeur sous les cartes. */
    #grille-sequence-container > div:not(.scene-card-auto) {
        grid-column: 1 / -1;
        margin-top: 0;
    }
    /* Titres d'étape ① / ② : cachés sur desktop (classe .hidden dans le HTML).
       !important : bat le .hidden !important de base.css. */
    #automation-modal-content .auto-etape-titre {
        display: flex !important;
        align-items: baseline;
        gap: 0.5rem;
        flex-wrap: wrap;
        flex-shrink: 0;
        font-size: 0.85rem;
        font-weight: 900;
        color: #fff;
        letter-spacing: 0.02em;
        margin-bottom: 0.625rem;
    }
    /* Rappel de cible dans le titre ② (« Scène(s) : 1 - 3 ») : on ne perd
       jamais de vue à quoi s'appliquent les réglages en scrollant. */
    #automation-modal-content .auto-etape-cible {
        font-size: 0.65rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: #22d3ee; /* cyan-400, comme l'indicateur desktop */
    }
    /* Bouton Valider : barre flottante en bas (la modale est plein écran :
       même ancré sur l'ancêtre transformé, fixed = bas de l'écran). */
    #btn-save-automations {
        position: fixed;
        left: 0.875rem;
        right: 0.875rem;
        bottom: 0.875rem;
        width: auto;
        margin-top: 0;
        z-index: 60;
        box-shadow: 0 -6px 20px rgba(2, 6, 23, 0.6);
    }
    /* Pilules caméra / transitions : UNE seule ligne, largeurs égales
       (plus lisible qu'un wrap irrégulier ; les libellés sont courts). */
    #zone-auto-camera,
    #zone-auto-transitions { flex-wrap: nowrap; }
    #zone-auto-camera .pilule,
    #zone-auto-transitions .pilule {
        flex: 1 1 0;
        padding: 0.55rem 0.25rem;
        white-space: nowrap;
    }

    /* L'overlay « Sélectionnez au moins une scène » pointe vers le HAUT :
       sur mobile les scènes sont au-dessus, pas à gauche.
       !important : bat le .hidden !important de base.css. */
    #auto-disabled-overlay .auto-fleche-desktop { display: none; }
    #auto-disabled-overlay .auto-fleche-mobile { display: inline !important; }

    /* 🎭 GÉNÉRATEUR — ligne d'un personnage de référence : la corbeille et le bouton de
       dessin sont des cibles TACTILES, pas des boutons de souris. Le champ « Nom » peut
       se réduire (min-width:0 dans le HTML), eux non : ils gardent leur taille au doigt. */
    .perso-actions button {
        min-width: 2.5rem;
        min-height: 2.5rem;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* 🎯 GÉNÉRATEUR — LE BOUTON « GÉNÉRER » RESTE SOUS LE POUCE.
       Le panneau est long (sujet, nombre de scènes, emotes, images, moteur, style,
       précisions, personnages…) et la barre d'action vit tout en bas : sur téléphone
       il fallait redérouler tout le générateur pour lancer la génération, et surtout
       on ne voyait plus son solde en ⚡ au moment de décider.

       `sticky` et NON `fixed` : la barre reste À L'INTÉRIEUR de la fenêtre du
       générateur, donc elle se ferme avec elle. En `fixed` elle flotterait par-dessus
       le studio même panneau fermé, et se retrouverait sous le clavier virtuel dès
       qu'on tape le sujet de la vidéo.

       Les marges négatives annulent le padding de 1.25rem du conteneur pour que la
       barre file d'un bord à l'autre ; `env(safe-area-inset-bottom)` la garde au-dessus
       de la barre de gestes des iPhone (la page est en viewport-fit=cover). */
    #ia-actions {
        position: sticky;
        bottom: 0;
        z-index: 10;
        gap: 0.6rem;               /* plus serré que dans le flux : c'est une barre, pas une section */
        margin: 0 -1.25rem -1.25rem;
        padding: 0.75rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
        background: #1e293b;       /* même fond que la fenêtre : le contenu défile DERRIÈRE, pas au travers */
        border-top: 1px solid #334155;
        box-shadow: 0 -10px 18px -12px rgba(0, 0, 0, .9);
    }
}


/* ════════════════════════════════════════════════════════════════════════
   3-bis. TÉLÉPHONE (< 640 px) — la pastille du solde se compacte encore.
   (La nav est déjà dans le tiroir du profil dès 1024 px, section 3.)
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639.98px) {

    /* Pastille du solde : on ne garde que le montant (le libellé saute). */
    #app-header .header-solde > span:first-child { display: none; }
}


/* ════════════════════════════════════════════════════════════════════════
   10. TABLEAUX LARGES → UNE CARTE PAR LIGNE  (téléphone, < 640 px)
   ------------------------------------------------------------------------
   Les tableaux du tableau de bord admin font 56 à 60 rem de large : sur un
   téléphone ils obligeaient à faire défiler l'écran de gauche à droite pour
   lire une seule ligne — donc à perdre de vue le nom du client dès la
   deuxième colonne. Ici chaque <tr> devient une carte empilée : le premier
   <td> fait le titre, les suivants deviennent « libellé … valeur ».

   Le libellé vient de l'attribut data-libelle posé sur chaque <td> par le JS
   (admin.js) : l'en-tête <thead> est masqué, sans lui la carte ne serait
   qu'une colonne de chiffres anonymes.

   Spécificité : `.table-cartes td` (0,1,1) bat les utilitaires Tailwind
   `.px-2` / `.text-right` (0,1,0) — aucun !important n'est nécessaire.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639.98px) {

    /* Le min-w-[60rem] du desktop doit sauter, sinon la carte reste large. */
    .table-cartes,
    .table-cartes tbody,
    .table-cartes tr,
    .table-cartes td { display: block; width: auto; min-width: 0; }

    .table-cartes thead { display: none; }

    .table-cartes tr {
        background: rgba(2, 6, 23, .5);      /* slate-950/50, comme les autres cartes */
        border: 1px solid #1e293b;           /* slate-800 */
        border-radius: .75rem;
        padding: .5rem .9rem .65rem;
        margin-bottom: .6rem;
    }

    /* Ligne d'état vide (« Aucun client ne correspond. ») : un simple texte,
       pas une carte à en-têtes. */
    .table-cartes tr:has(> td[colspan]) {
        background: none;
        border: 0;
        padding: 0;
    }

    .table-cartes td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 1rem;
        padding: .3rem 0;
        text-align: right;
        border: 0;
    }

    .table-cartes td::before {
        content: attr(data-libelle);
        flex: 0 0 auto;
        font-size: 10px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .06em;
        color: #64748b;                      /* slate-500 */
        text-align: left;
    }

    /* Première cellule = le titre de la carte (email du client, code du
       revendeur, nom de l'action) : pleine largeur, souligné, sans libellé. */
    .table-cartes td:first-child,
    .table-cartes td[colspan] {
        display: block;
        text-align: left;
        padding: .1rem 0 .5rem;
    }
    .table-cartes td:first-child { border-bottom: 1px solid #1e293b; margin-bottom: .35rem; }
    .table-cartes td:first-child::before,
    .table-cartes td[colspan]::before { content: none; }

    /* Les deux boutons d'action d'un revendeur : une rangée à eux seuls. */
    .table-cartes td.td-actions {
        justify-content: flex-end;
        gap: .5rem;
        padding-top: .6rem;
    }

    /* L'email tronqué à 14/16 rem déborderait d'un écran de 320 px. */
    .table-cartes td .truncate { max-width: 100%; }


    /* ── Espace revendeur : « Ce que tu gagnes » ────────────────────────────
       Trois cartes côte à côte laissent ~40 px de contenu sur un écran de
       320 px : « 13,48 € » en font-black débordait. Sur téléphone on empile
       (offre à gauche, montant à droite), ce qui laisse aussi la place à la
       ligne « X € si tu t'abonnes ». */
    .grille-gains { grid-template-columns: 1fr; }

    .grille-gains > div {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        text-align: left;
        padding: .6rem .9rem;
    }
    .grille-gains > div > :last-child { text-align: right; margin-top: 0; }
}
