        /* --- 1. VARIABLES ET FONDATIONS --- */
        body { 
            margin: 0; display: flex; flex-direction: column; height: 100vh; 
            overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
            background: #1e1e1e; color: #eee; 
        }
        
        #mobile-title {
            display: none; text-align: center; padding: 15px; margin: 0;
            background: #2d2d30; color: #f2f2f2; font-size: clamp(13px, 3.56vw, 16px); font-weight: 800;
            box-shadow: 0 2px 10px rgba(0,0,0,0.5); z-index: 20; flex-shrink: 0;
        }
        /* Lot D (22/09/2026) : le lien reprend le titre de marque, plus de transformation
           uppercase forcée (incompatible avec le lockup "Adelio Lab" du site principal). */
        #mobile-title .mobile-title-link {
            color: inherit;
            text-decoration: none;
        }
        #mobile-title .mobile-title-link:hover,
        #mobile-title .mobile-title-link:focus-visible {
            text-decoration: underline;
        }

        /* Etape 5 (25/09/2026) : selecteur de langue FR/EN du sous-domaine, meme style
           visuel que le selecteur du header du site principal (classes .lang-link /
           .lang-active / .lang-separator reprises a l'identique - voir Adelio SITE
           DOMAIN ok V3/css/navbar.css). Deux instances : desktop (au-dessus du titre,
           colonne gauche, masquee sous 450px) et mobile (dans #mobile-title, alignee
           a droite du titre, seule visible sous 450px car #mobile-title lui-meme est
           masque au-dessus de ce seuil). */
        .subdomain-lang-selector-desktop,
        .subdomain-lang-selector-mobile {
            display: flex;
            align-items: center;
            font-family: Arial, sans-serif;
            font-weight: bold;
        }
        .subdomain-lang-selector-desktop {
            justify-content: center;
            font-size: 0.8rem;
            margin-bottom: 4px;
        }
        .subdomain-lang-selector-mobile {
            font-size: 0.7em;
            flex-shrink: 0;
        }
        .lang-link {
            text-decoration: none;
            color: #a0a0a0;
            letter-spacing: 2px;
            transition: color 0.3s ease;
        }
        .lang-link:hover {
            color: #7DDCFF;
        }
        .lang-link.lang-active {
            color: #7DDCFF;
        }
        .lang-separator {
            margin: 0 3px;
            color: #a0a0a0;
            font-weight: normal;
        }
        
        #main-layout { 
            display: flex; flex-direction: row; flex-grow: 1; 
            overflow: hidden; width: 100%; 
        }
        
        .panel { 
            padding: 20px; background: #2d2d30; overflow-y: auto; 
            box-sizing: border-box; display: flex; flex-direction: column; 
            gap: 20px; flex-shrink: 0; 
        }
        
        /* --- 2. ARCHITECTURE DES PANNEAUX (DESKTOP PAR DÉFAUT) --- */
        #ui-left, #ui-right { 
            width: clamp(250px, 25vw, 300px); 
            z-index: 10; box-shadow: 0 0 10px rgba(0,0,0,0.5); 
        }
        
        #ui-center { 
            display: flex; flex-direction: column; flex-grow: 1; 
            min-width: 0; position: relative; overflow: hidden; 
        }
        
        /* Le wrapper protège le canvas et force le respect de l'espace disponible */
        #canvas-wrapper {
            flex: 1 1 auto; min-height: 0; width: 100%;
            display: flex; align-items: center; justify-content: center;
            padding: 15px; box-sizing: border-box;
        }

        /* Le Carré Parfait Inviolable */
        #canvas-container { 
            aspect-ratio: 1 / 1; 
            max-width: 100%; max-height: 100%; width: 100%; 
            background: transparent; cursor: grab; position: relative; 
            touch-action: none;
        }
        #canvas-container:active { cursor: grabbing; }
        
        /* Bouclier contre l'engrenage WebGL */
        #canvas-container canvas {
            position: absolute !important;
            top: 0; left: 0; width: 100% !important; height: 100% !important;
        }
        
        #ui-bottom { 
            flex: 0 0 auto; background: #252526; display: flex; flex-direction: row; 
            align-items: center; justify-content: center; gap: 30px; 
            padding: 20px; box-shadow: 0 -2px 10px rgba(0,0,0,0.5); 
            z-index: 10; flex-wrap: wrap; width: 100%; box-sizing: border-box;
        }
        
        /* --- 3. COMPOSANTS INTERNES --- */
        .section { background: #3e3e42; padding: 15px; border-radius: 6px; flex-shrink: 0; }
        .section h3 { margin: 0 0 15px 0; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; color: #007acc; }

        /* Bordure dynamique liée à la couleur choisie (Étape 5, roadmap Chantier 1) : entoure
           tout le bloc (confirmé — chevron + titre inclus), pas seulement le panneau de réglages.
           La couleur elle-même (transparent ici) est posée en style inline par JS
           (syncBubbleSparkleBorderColor), synchronisée sur #color-picker-face/#color-picker-bevel
           — transparent tant que le JS n'a pas encore tourné, plutôt qu'une couleur en dur qui
           clignoterait avant la synchronisation. Indépendante de la bordure orange fixe du bouton
           marche/arrêt (Étape 3), qui reste sur ce petit bouton uniquement. box-sizing: border-box
           pour que la bordure ne fasse pas grandir la carte au-delà de la colonne.*/
        #section-bubble-sparkle-facade, #section-bubble-sparkle-bevel {
            border: 4px solid transparent;
            box-sizing: border-box;
        }

        /* Zone "Exporter votre logo" (ex-"Exportation Universelle") — spec UI validée le
           17/09/2026. Pas de bordure sur le cadre global (#section-export-logo reste un .section
           standard, sans bordure) — seule la bordure orange 2px de chaque bouton marque l'accent
           visuel, comme demandé par le user pour éviter "trop de orange". */
        #section-export-logo h3 { color: #FF9500; }

        .export-action { margin-bottom: 15px; }
        .export-action-button {
            border: 2px solid #FF9500;
            box-sizing: border-box;
        }
        .export-action-button:disabled {
            opacity: 0.4;
            cursor: default;
            background: #444;
        }
        /* Clignotement pendant l'export vidéo (capture + encodage) — demandé par le user le
           18/09/2026, en complément de la vraie pause technique ajoutée côté JS
           (yieldToBrowser(), js/app.js) pour que le fil principal ne bloque plus jamais assez
           longtemps pour déclencher "cette page ne répond plus" sur les animations longues
           (ex. Animation 4). Sélecteur à 3 niveaux pour l'emporter sur la règle :disabled
           ci-dessus (même nombre de classes/pseudo-classes sinon, l'ordre deviendrait fragile).
           opacity oscille dans une plage encore bien visible (0.55 à 1) — jamais aussi terne que
           le 0.4 fixe du bouton simplement désactivé, pour bien distinguer "en cours" de "désactivé". */
        @keyframes export-action-button-pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.55; }
        }
        .export-action-button.is-exporting:disabled {
            opacity: 1;
            cursor: progress;
            background: #444;
            animation: export-action-button-pulse 1.1s ease-in-out infinite;
        }
        /* Étape B1 (21/09/2026) : variante "secondaire" pour l'action alternative (pas conseillée
           mais jamais bloquée) de la pop-up d'avertissement "aucune animation sélectionnée" —
           bordure grise neutre au lieu de la bordure orange de .export-action-button, pour que le
           bouton conseillé ("Ajouter une animation") reste visuellement le plus marquant sans que
           l'autre choix ait l'air désactivé ou pénalisé. */
        .export-action-button-secondary {
            border: 2px solid #666;
            box-sizing: border-box;
            background: #3c3c40;
            color: #ddd;
        }
        .export-action-button-secondary:hover {
            background: #47474c;
        }
        .export-action-meta {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            margin-top: 6px;
        }
        .export-action-tagline {
            display: inline-block;
            padding: 2px 8px;
            border: 1px solid #666;
            border-radius: 999px;
            font-size: 11px;
            color: #ccc;
            background: #333;
        }
        .export-action-price {
            font-size: 13px;
            font-weight: bold;
            color: #FF9500;
            white-space: nowrap;
        }
        .export-action-caption {
            display: block;
            color: #aaa;
            font-size: 11px;
            margin: 4px 0 0 0;
        }


        /* --- Colonne gauche : ossature Modèles / Styles (UI E2) --- */
        #creative-presets-shell {
            padding: 14px;
            background: #2d2d30;
            border: 1px solid #444;
        }
        /* Titre de marque : sorti de #creative-presets-shell le 16/09/2026 (Étape 1 — roadmap
           Chantier 1), placé au-dessus du cadre, donc dé-scopé pour rester applicable. Taille
           réduite de 10% (16px -> 14.4px) ; "by" conserve le même rapport de taille qu'avant
           (11/16 = 0.6875 -> 14.4 * 0.6875 ≈ 9.9px). */
        .creative-brand-title {
            margin: 0;
            color: #f2f2f2;
            font-size: 14.4px;
            font-weight: 800;
            line-height: 1.25;
            letter-spacing: 0.7px;
            text-align: center;
        }
        /* Lot D (22/09/2026) : le titre devient un lien vers la page de présentation
           du site principal ; couleur héritée pour le texte neutre ("3D Logo Pro"). */
        .creative-brand-title a {
            color: inherit;
            text-decoration: none;
        }
        .creative-brand-title a:hover,
        .creative-brand-title a:focus-visible {
            text-decoration: underline;
        }
        .creative-brand-title .creative-brand-by {
            font-size: 9.9px;
            font-weight: 500;
            letter-spacing: 0.2px;
            color: #aaa;
            text-transform: none;
        }
        /* Lot D (22/09/2026) : lockup "Adelio Lab" repris à l'identique du site principal
           (couleurs/polices vérifiées sur adeliolab.com), légèrement agrandi pour ressortir
           du texte neutre environnant. Classes partagées avec #mobile-title. */
        .creative-brand-title .creative-brand-name {
            display: inline-flex;
            align-items: baseline;
            gap: 3px;
            vertical-align: baseline;
        }
        .brand-name-adelio {
            color: #7DDCFF;
            font-family: "Playfair Display", serif;
            font-size: 15px;
            font-weight: 700;
            letter-spacing: normal;
        }
        .brand-name-lab {
            color: #FF3CAC;
            font-family: Arial, sans-serif;
            font-size: 12px;
            font-weight: 400;
            letter-spacing: normal;
        }
        #mobile-title .creative-brand-by {
            font-size: 0.6875em;
            font-weight: 500;
            letter-spacing: 0.2px;
            color: #aaa;
            text-transform: none;
        }
        #mobile-title .brand-name-adelio {
            font-size: 1.15em;
        }
        #mobile-title .brand-name-lab {
            font-size: 0.85em;
        }
        #creative-presets-shell .creative-preset-block {
            padding-top: 11px;
            margin-top: 11px;
            border-top: 1px solid #444;
        }
        /* Étape A (batch A/B/C/D, 17/09/2026) : évite le cumul avec le padding-top du
           cadre #creative-presets-shell avant le premier bloc ("Modèles"), en reprenant
           le pattern déjà utilisé ailleurs (.lighting-group:first-of-type). Le second
           bloc ("Styles") garde sa séparation visuelle intacte. */
        #creative-presets-shell .creative-preset-block:first-of-type {
            padding-top: 0;
            margin-top: 0;
            border-top: none;
        }
        #creative-presets-shell .creative-preset-heading {
            margin: 0 0 3px 0;
            color: #007acc;
            font-size: 12px;
            font-weight: 800;
            letter-spacing: 0.9px;
            text-transform: uppercase;
        }
        #creative-presets-shell .creative-preset-help {
            margin: 0 0 9px 0;
            color: #aaa;
            font-size: 11px;
            line-height: 1.35;
        }
        #creative-presets-shell .creative-preset-grid {
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            gap: 5px;
        }
        #creative-presets-shell .creative-preset-grid button {
            min-width: 0;
            margin: 0;
            padding: 8px 4px;
            font-size: 11px;
        }
        #creative-presets-shell .creative-preset-grid button[role="radio"] {
            background: #555;
            color: #fff;
            border: 1px solid #666;
        }
        #creative-presets-shell .creative-preset-grid button[role="radio"][aria-checked="true"] {
            background: #0062A3;
            border-color: #00b7ff;
        }
        #creative-presets-shell .creative-preset-grid button[role="radio"]:not(:disabled):hover {
            background: #0098ff;
        }
        #creative-presets-shell .creative-preset-grid button[role="radio"]:disabled {
            opacity: 0.38;
            cursor: default;
            background: #444;
            border-color: #555;
            color: #aaa;
        }
        #creative-presets-shell .creative-preset-grid.is-structure-only {
            min-height: 0;
        }
        /* #btn-reset-defaults ("Recette") vit maintenant dans #global-preset-grid, à côté des
           boutons radio M-2..M-13. Il n'a pas role="radio" (ce n'est pas une sélection persistante)
           donc il hérite par défaut du bleu global `button{background:#007acc}` : on lui donne ici
           un look gris/blanc cohérent avec ses voisins, avec un hover volontairement différent du
           hover bleu clair (#0098ff) des radios pour ne pas laisser croire à une sélection active. */
        #creative-presets-shell .creative-preset-grid #btn-reset-defaults {
            background: #555;
            color: #fff;
            border: 1px solid #666;
        }
        #creative-presets-shell .creative-preset-grid #btn-reset-defaults:hover {
            background: #666;
        }
        /* Rescopé depuis #creative-presets-shell le 16/09/2026 (Étape 1) : ce titre appartient
           maintenant à la nouvelle carte #creative-source-mode-shell ("Créez votre propre logo"),
           plus au bloc Modèles/Styles. Vérifié : .creative-source-heading n'est utilisé nulle part
           ailleurs dans le HTML. */
        /* Couleur et taille mises à jour le 16/09/2026 (Étape 2, roadmap Chantier 1) : orange
           #CC7A29 (même teinte que la bordure .is-active-mode ci-dessous) + taille +20%
           (12px → 14.4px). */
        #creative-source-mode-shell .creative-source-heading {
            margin: 0 0 8px 0;
            color: #FF9500;
            font-size: 14.4px;
            font-weight: 700;
            line-height: 1.3;
        }
        /* Remplace l'ancienne règle .creative-source-mode-bridge button (div wrapper supprimée du
           HTML le 16/09/2026, Étape 1 — ses enfants sont maintenant directement dans
           #creative-source-mode-shell) : cible précisément les deux boutons de bascule de mode
           sans dépendre d'un conteneur qui n'existe plus, et sans toucher aux boutons d'alignement
           du mode Texte (#btn-align-left/center/right), qui restent sur le style global .btn-group. */
        #btn-mode-image, #btn-mode-text {
            margin-bottom: 0;
            color: #FF9500;
        }
        /* Bordure orange 4px sur le bouton de mode actif (Étape 2, roadmap Chantier 1). La classe
           s'ajoute en parallèle du changement de couleur inline existant (btnModeImage/
           btnModeText.style.background, géré en JS) qui reste la source de vérité pour l'état
           actif/inactif — impossible de cibler un style inline directement en CSS, d'où cette
           classe dédiée posée en même temps par le JS. box-sizing: border-box pour que l'ajout de
           la bordure ne fasse pas grandir le bouton par rapport à son voisin inactif. */
        #btn-mode-image.is-active-mode, #btn-mode-text.is-active-mode {
            box-sizing: border-box;
            border: 4px solid #CC7A29;
        }

        /* Patron générique "sous-groupe à chevron repliable" (titre + zone dépliable via [hidden]).
           Dé-scopé de #section-lighting le 16/09/2026 (Étape 0 — roadmap Chantier 1) pour être
           réutilisable ailleurs (blocs Aspect Façade/Épaisseur, chevron principal "Éclairage
           Personnalisé") : vérifié au préalable qu'aucune de ces classes n'était utilisée hors de
           la section Éclairage, donc ce dé-scopage ne change rien au rendu existant. */
        .lighting-group {
            border-top: 1px solid #555;
            margin-top: 12px;
            padding-top: 12px;
        }
        .lighting-group:first-of-type {
            border-top: none;
            margin-top: 0;
            padding-top: 0;
        }
        .lighting-group-header {
            display: flex;
            align-items: center;
            justify-content: flex-start;
            gap: 10px;
            margin-bottom: 10px;
        }
        .lighting-group-title {
            margin: 0;
            font-size: 12px;
            line-height: 1.25;
            text-transform: uppercase;
            letter-spacing: 0.8px;
            color: #00b7ff;
        }
        .lighting-toggle {
            width: 24px;
            min-width: 24px;
            height: 22px;
            padding: 0;
            margin: 0;
            border-radius: 3px;
            background: #555;
            font-size: 0;
            line-height: 1;
            flex: 0 0 auto;
            transform: scale(1.2);
            transform-origin: center;
        }
        .lighting-toggle::before {
            content: '';
            display: block;
            width: 8px;
            height: 8px;
            margin: auto;
            border-right: 2px solid #fff;
            border-bottom: 2px solid #fff;
            transform: rotate(45deg) translate(-1px, -1px);
            transform-origin: center;
        }
        .lighting-toggle[aria-expanded="false"]::before {
            transform: rotate(-45deg) translate(-1px, 1px);
        }
        .lighting-toggle:hover { background: #666; }

        /* Chevron "principal" de la carte 2 Éclairage (Étape 8, roadmap Chantier 1) : même
           géométrie/mécanisme que .lighting-toggle (classe combinée, ne remplace rien), mais
           style visuellement distinct pour marquer qu'il est "au-dessus" des 4 chevrons internes
           qu'il englobe. Replié : fond blanc, bordure bleue, flèche bleue. Déplié : même fond/
           bordure, flèche orange (#CC7A29, même teinte que le reste du chantier). Les règles de
           couleur de flèche ne touchent que border-*-color, pas border-*-width/style (hérités de
           .lighting-toggle::before), donc la forme/taille du chevron reste identique. */
        .lighting-toggle-main {
            box-sizing: border-box;
            background: #fff;
            border: 2px solid #007acc;
        }
        .lighting-toggle-main:hover {
            background: #eef7ff;
        }
        .lighting-toggle-main::before {
            border-right-color: #CC7A29;
            border-bottom-color: #CC7A29;
        }
        .lighting-toggle-main[aria-expanded="false"]::before {
            border-right-color: #007acc;
            border-bottom-color: #007acc;
        }
        .lighting-quick-actions {
            margin-bottom: 10px;
        }
        .lighting-quick-actions button {
            background: #f5f5f5;
            color: #222;
            flex: 1 1 0;
            min-width: 0;
        }
        .lighting-quick-actions button:hover {
            background: #ffffff;
        }
        .lighting-quick-actions button.is-active {
            background: #0062A3;
            color: #fff;
        }
        .lighting-quick-actions button.is-active:hover {
            background: #0098ff;
        }
        .lighting-group-content[hidden] { display: none; }

        /* Bouton marche/arrêt de l'effet Bubble 3D (façade + épaisseur), Étape 3 — roadmap
           Chantier 1. Remplace l'ancienne case à cocher ; placé sur la même ligne que le chevron
           et le titre (.lighting-group-header, display:flex), aligné à droite via margin-left:
           auto. État OFF (par défaut) : fond blanc, texte noir. État ON (.is-on) : fond gris-brun
           sombre #3D2E20, bordure 4px et texte orange #CC7A29 (même teinte que .is-active-mode et
           .creative-source-heading). box-sizing: border-box pour que la bordure de l'état ON ne
           fasse pas grandir le bouton par rapport à l'état OFF. */
        #toggle-facade, #toggle-bevel, #toggle-animation-master {
            width: auto;
            flex: 0 0 auto;
            margin: 0 0 0 auto;
            padding: 4px 12px;
            box-sizing: border-box;
            background: #fff;
            color: #000;
            font-size: 11px;
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            border: 1px solid #999;
        }
        #toggle-facade:hover, #toggle-bevel:hover, #toggle-animation-master:hover {
            background: #eee;
        }
        #toggle-facade.is-on, #toggle-bevel.is-on, #toggle-animation-master.is-on {
            background: #3D2E20;
            color: #CC7A29;
            border: 4px solid #CC7A29;
        }
        #toggle-facade.is-on:hover, #toggle-bevel.is-on:hover, #toggle-animation-master.is-on:hover {
            background: #4a3826;
        }
        /* Bloc A/B/C/D-2 (17/09/2026) : en-tête "Animation Auto" avec bouton marche/arrêt général,
           même patron que .lighting-group-header (titre à gauche, bouton aligné à droite via le
           margin-left:auto déjà porté par #toggle-animation-master ci-dessus). Par défaut sur ON
           (comportement historique inchangé : les animations restent disponibles tant qu'on ne
           clique pas explicitement sur OFF). */
        .animation-auto-header {
            display: flex;
            align-items: center;
            justify-content: flex-start;
            gap: 10px;
            margin-bottom: 15px;
        }
        .animation-auto-header h3 {
            margin: 0;
        }

        /* Chantier C (séquenceur) — panneau repliable, même patron visuel que les sous-groupes
           d'Éclairage Global ci-dessus (bouton flèche + contenu masqué via [hidden]), scopé à sa
           propre section pour ne rien changer aux styles existants. */
        #section-sequencer .sequencer-panel-header {
            display: flex;
            align-items: center;
            gap: 10px;
            margin-bottom: 10px;
        }

        /* Étape D : fenêtre interne flottante (position: fixed), déplaçable par sa barre de titre
           et redimensionnable (resize: both natif). Remplace l'ancien panneau replié en ligne dans
           la colonne latérale #ui-right — beaucoup trop étroite (clamp 250-300px) pour afficher les
           5 champs numériques de chaque étape de façon lisible. Repli en ligne conservé sous 750px
           de largeur de viewport (voir la media query dédiée, section 4). */
        .sequencer-floating-panel {
            position: fixed;
            z-index: 100;
            display: flex;
            flex-direction: column;
            min-width: 460px;
            min-height: 320px;
            background: #2d2d30;
            border: 1px solid #555;
            border-radius: 6px;
            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.6);
            resize: both;
            overflow: auto;
        }
        .sequencer-floating-panel[hidden] { display: none; }
        .sequencer-floating-panel-titlebar {
            flex: 0 0 auto;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            padding: 8px 10px;
            background: #3c3c40;
            border-bottom: 1px solid #555;
            border-radius: 6px 6px 0 0;
            font-size: 13px;
            font-weight: bold;
            color: #eee;
            cursor: move;
            user-select: none;
            touch-action: none;
        }
        .sequencer-floating-panel-close {
            flex: 0 0 auto;
            width: 22px;
            height: 22px;
            min-width: 22px;
            padding: 0;
            margin: 0;
            line-height: 1;
            background: #663333;
            color: #fff;
            border-radius: 3px;
            cursor: pointer;
        }
        .sequencer-floating-panel-close:hover { background: #884444; }
        .sequencer-floating-panel-body {
            flex: 1 1 auto;
            overflow-y: auto;
            padding: 12px;
            box-sizing: border-box;
        }

        /* Roadmap "prochaines étapes" (17/09/2026), Étape A — pop-up de réassurance/achat.
           Vraie fenêtre modale (centrée, fond assombri, non déplaçable/non redimensionnable),
           contrairement au panneau flottant du séquenceur ci-dessus — décision actée dans la spec
           UI "Exporter votre logo" (jugé plus adapté à un futur paiement). Style visuel (carte,
           barre de titre, bouton fermer) volontairement repris à l'identique du panneau flottant
           pour la cohérence graphique de l'interface. */
        .purchase-modal-backdrop {
            position: fixed;
            inset: 0;
            z-index: 200;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.6);
            padding: 16px;
            box-sizing: border-box;
        }
        .purchase-modal-backdrop[hidden] { display: none; }
        .purchase-modal-card {
            display: flex;
            flex-direction: column;
            width: 420px;
            max-width: 100%;
            max-height: 100%;
            background: #2d2d30;
            border: 1px solid #555;
            border-radius: 6px;
            box-shadow: 0 8px 30px rgba(0, 0, 0, 0.6);
            overflow: auto;
        }
        .purchase-modal-titlebar {
            flex: 0 0 auto;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            padding: 8px 10px;
            background: #3c3c40;
            border-bottom: 1px solid #555;
            border-radius: 6px 6px 0 0;
            font-size: 13px;
            font-weight: bold;
            color: #eee;
        }
        .purchase-modal-close {
            flex: 0 0 auto;
            width: 22px;
            height: 22px;
            min-width: 22px;
            padding: 0;
            margin: 0;
            line-height: 1;
            background: #663333;
            color: #fff;
            border-radius: 3px;
            cursor: pointer;
        }
        .purchase-modal-close:hover { background: #884444; }
        .purchase-modal-body {
            flex: 1 1 auto;
            overflow-y: auto;
            padding: 16px;
            box-sizing: border-box;
            font-size: 13px;
        }

        /* Chantier C — Étape B : liste d'étapes éditable. */
        #section-sequencer .sequencer-stage-list {
            max-height: 260px;
            overflow-y: auto;
            border: 1px solid #505055;
            border-radius: 4px;
            padding: 4px;
            margin-top: 6px;
        }
        #section-sequencer .sequencer-stage-row {
            display: flex;
            align-items: center;
            gap: 4px;
            padding: 3px 0;
        }
        #section-sequencer .sequencer-stage-row + .sequencer-stage-row {
            border-top: 1px solid #444448;
        }
        #section-sequencer .sequencer-stage-checkbox {
            flex: 0 0 16px;
            width: 16px;
            height: 16px;
            min-width: 16px;
            margin: 0;
            cursor: pointer;
        }
        #section-sequencer .sequencer-stage-index {
            flex: 0 0 20px;
            font-size: 11px;
            color: #aaa;
            text-align: right;
        }
        #section-sequencer .stage-field {
            flex: 1 1 0;
            min-width: 50px;
            width: 100%;
            box-sizing: border-box;
            background: #1e1e1e;
            color: #d4d4d4;
            border: 1px solid #555;
            border-radius: 3px;
            font-size: 11px;
            padding: 2px 3px;
        }
        #section-sequencer .btn-duplicate-stage {
            flex: 0 0 auto;
            width: 20px;
            height: 20px;
            min-width: 20px;
            padding: 0;
            margin: 0;
            line-height: 1;
            background: #2d5f7a;
            color: #fff;
            border-radius: 3px;
            font-size: 11px;
        }
        #section-sequencer .btn-duplicate-stage:hover { background: #3a7a9e; }
        #section-sequencer .btn-sequencer-view-stage {
            flex: 0 0 auto;
            width: 20px;
            height: 20px;
            min-width: 20px;
            padding: 0;
            margin: 0;
            line-height: 1;
            background: #555;
            color: #fff;
            border-radius: 3px;
            font-size: 11px;
        }
        #section-sequencer .btn-sequencer-view-stage:hover { background: #6a6a6a; }
        #section-sequencer .btn-remove-stage {
            flex: 0 0 auto;
            width: 20px;
            height: 20px;
            min-width: 20px;
            padding: 0;
            margin: 0;
            line-height: 1;
            background: #663333;
            color: #fff;
            border-radius: 3px;
        }
        #section-sequencer .btn-remove-stage:hover { background: #884444; }
        #section-sequencer .btn-remove-stage:disabled { opacity: 0.4; cursor: default; }

        /* Lot 6 (21/09/2026) : message permanent (jamais inséré/retiré du DOM, donc jamais de
           décalage de layout) — gris au repos ; la couleur clignotante orange/rouge est appliquée
           directement en style inline par triggerSequencerDurationCapWarning (js/app.js), retirée
           après 3 s pour laisser cette couleur de repos reprendre la main. */
        #section-sequencer .sequencer-duration-cap-hint {
            margin-top: 8px;
            font-size: 11px;
            color: #888888;
        }

        /* Barre d'outils de sélection multiple (Étape D), au-dessus de la liste d'étapes. */
        #section-sequencer .sequencer-stage-list-toolbar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            flex-wrap: wrap;
            gap: 8px;
            margin-top: 6px;
        }
        #section-sequencer .sequencer-select-all-label {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            color: #ccc;
            cursor: pointer;
        }
        #section-sequencer .sequencer-select-all-label input[type="checkbox"] {
            width: auto;
            margin: 0;
            cursor: pointer;
        }
        #section-sequencer #btn-sequencer-duplicate-selection {
            width: auto;
            flex: 0 0 auto;
            font-size: 12px;
            padding: 6px 10px;
            margin: 0;
        }
        #section-sequencer #btn-sequencer-duplicate-selection:disabled { opacity: 0.4; cursor: default; }

        /* Lot 12 : bouton "Inverser l'ordre" — même gabarit que "Dupliquer la sélection" juste
           au-dessus, avec une bordure orange (sourde au repos, vive au survol) pour rester dans le
           même langage visuel que le reste de la barre d'outils (Lots 9-11). Simple action ponctuelle
           (pas de mode persistant comme "Édition simultanée" ou "Copier/Coller"), donc pas d'état
           .is-active : le survol suffit à signaler l'interactivité. */
        #section-sequencer #btn-sequencer-reverse-selection {
            width: auto;
            flex: 0 0 auto;
            font-size: 12px;
            padding: 6px 10px;
            margin: 0;
            border: 2px solid #b8730f;
        }
        #section-sequencer #btn-sequencer-reverse-selection:hover { border-color: #ff9800; }

        /* Lot 4 : bouton bascule "Édition simultanée" — n'apparaît que si au moins une ligne est
           cochée (voir updateSequencerSelectionToolbarState). État repos : gris clair (nettement
           plus clair que le gris #555 des boutons Modèles M-1/M-2/M-3), bordure orange vive, texte
           noir gras. État actif (.is-active) : fond orange doux/mat, bordure toujours vive. */
        #section-sequencer #btn-sequencer-multi-edit {
            width: auto;
            flex: 0 0 auto;
            font-size: 12px;
            padding: 6px 10px;
            margin: 0;
            background: #8f8f8f;
            color: #111;
            font-weight: bold;
            border: 2px solid #ff9800;
        }
        #section-sequencer #btn-sequencer-multi-edit:hover { background: #a0a0a0; }
        #section-sequencer #btn-sequencer-multi-edit.is-active {
            background: #c98a4a;
            color: #111;
        }
        #section-sequencer #btn-sequencer-multi-edit.is-active:hover { background: #d59a5c; }

        /* Lot 11 : bouton "Copier / Coller la sélection" — même habillage que "Édition simultanée"
           juste au-dessus (gris clair au repos, bordure orange vive, texte noir gras), pour rester
           dans le même langage visuel de boutons-bascule de la barre d'outils. État actif (.is-active,
           = collage en attente, libellé passé à "Coller la sélection") : même teinte active que
           l'Édition simultanée, pour signaler "un mode spécial est en cours" de façon cohérente. */
        #section-sequencer #btn-sequencer-copy-selection {
            width: auto;
            flex: 0 0 auto;
            font-size: 12px;
            padding: 6px 10px;
            margin: 0;
            background: #8f8f8f;
            color: #111;
            font-weight: bold;
            border: 2px solid #ff9800;
        }
        #section-sequencer #btn-sequencer-copy-selection:hover { background: #a0a0a0; }
        #section-sequencer #btn-sequencer-copy-selection.is-active {
            background: #c98a4a;
            color: #111;
        }
        #section-sequencer #btn-sequencer-copy-selection.is-active:hover { background: #d59a5c; }

        /* Lot 11 : champ + flèches inline pour choisir la position de collage (n'apparaît qu'en
           attente de collage, voir updateSequencerSelectionToolbarState). */
        #section-sequencer .sequencer-paste-index-field {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            color: #ccc;
        }
        #section-sequencer .sequencer-paste-index-field input[type="number"] {
            width: 52px;
            box-sizing: border-box;
            background: #1e1e1e;
            color: #d4d4d4;
            border: 1px solid #ff9800;
            border-radius: 3px;
            font-size: 11px;
            padding: 3px 4px;
        }

        /* Lot 4 : pendant l'Édition simultanée, les champs des lignes cochées passent d'une bordure
           grise à une bordure orange — teinte "dim" par défaut, et teinte "vive" (plus soutenue)
           sur la colonne avec laquelle l'utilisateur interagit actuellement (clic/focus, flèches du
           champ number, ou survol). Ne s'applique jamais aux placeholders/aperçus en lecture seule
           (ils n'ont pas d'attribut data-field). */
        #section-sequencer .sequencer-stage-list.sequencer-multi-edit-active .sequencer-stage-row.sequencer-row-multi-selected .stage-field[data-field] {
            border-color: #b8730f;
            transition: border-color 0.12s;
        }
        #section-sequencer .sequencer-stage-list.sequencer-multi-edit-active .stage-field.sequencer-multi-edit-vivid[data-field] {
            border-color: #ff9800;
        }

        /* En-tête de colonnes du tableau d'étapes (Lot 1) : réutilise exactement la même
           structure flex que .sequencer-stage-row pour rester aligné avec les lignes réelles ;
           les colonnes icônes (case à cocher, œil, dupliquer, supprimer) restent muettes. */
        #section-sequencer .sequencer-stage-list-header {
            padding: 0 0 4px 0;
            margin-top: 4px;
            border-bottom: 1px solid #505055;
        }
        #section-sequencer .sequencer-stage-header-label {
            flex: 1 1 0;
            min-width: 50px;
            font-size: 10px;
            font-weight: bold;
            text-transform: uppercase;
            letter-spacing: 0.3px;
            color: #999;
            text-align: center;
            padding: 2px 3px;
            box-sizing: border-box;
        }
        #section-sequencer .sequencer-stage-icon-spacer {
            flex: 0 0 20px;
            width: 20px;
            min-width: 20px;
        }

        /* Lot 3 : case "Time (ms)" de la toute première étape — inutilisée par le moteur pour
           l'Intro (non bouclée), et remplacée pour la Boucle par le contrôle dédié tout en bas du
           tableau (.sequencer-stage-summary-row) : dans les deux cas, un simple repère visuel plutôt
           qu'un champ modifiable, pour ne jamais avoir deux endroits différents qui éditent la
           même valeur. */
        #section-sequencer .stage-field-first-row-placeholder {
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            cursor: default;
        }

        /* Lot 3 : ligne récapitulative en bas du tableau — "Retour vers l'étape 1" (Boucle) ou
           "Transition vers la Boucle" (Intro). Légèrement teintée pour se distinguer visuellement
           des étapes normales de la liste, avec une légende au-dessus. */
        #section-sequencer .sequencer-stage-summary-caption {
            margin-top: 8px;
            font-size: 10px;
            font-weight: bold;
            color: #6bb3e0;
            text-transform: uppercase;
            letter-spacing: 0.3px;
        }
        #section-sequencer .sequencer-stage-summary-row {
            background: rgba(0, 122, 204, 0.10);
            border-radius: 3px;
            margin-top: 2px;
            padding: 2px 0;
        }

        /* Lot 11 : repère visuel de collage — un bloc orange à la taille d'une ligne du tableau,
           inséré en direct à la position choisie dans le champ "Coller à la position" (voir
           renderSequencerStageList). Même principe que .sequencer-stage-summary-row (teinte de fond
           + légende), en orange plutôt qu'en bleu pour ne pas se confondre avec la ligne récapitulative,
           et avec la même teinte "vive" que la bordure des boutons de lecture (Lot 9). */
        #section-sequencer .sequencer-stage-paste-marker-row {
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 24px;
            background: rgba(255, 152, 0, 0.18);
            border: 1px dashed #ff9800;
            border-radius: 3px;
            margin: 2px 0;
            padding: 3px 0;
            font-size: 11px;
            font-weight: bold;
            color: #ff9800;
            text-align: center;
        }
        #section-sequencer .stage-field-readonly {
            background: #26262b;
            color: #9db4c2;
            font-style: italic;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: default;
        }

        /* Lot 2 : trois boutons de lecture partielle (Intro seule / Boucle seule / Intro→Boucle),
           remplaçant l'unique bouton Play/Stop. Hauteur fixe (padding inclus via border-box) pour
           que le passage ▶ (2x) -> ■ (3x) au clic ne redimensionne jamais le bouton.
           Lot 9 : 56px -> 60px — la bordure de 2px (ajoutée aux 2 états, voir
           updateSequencerPlaybackButtonsUI) réduit l'espace interne disponible (box-sizing:
           border-box) de 4px au total (2px haut + 2px bas), ce qui suffisait à faire dépasser
           l'ancien minimum de 56px à l'état actif (icône ■ à 3em) sans le dépasser à l'état au
           repos (icône ▶ à 2em) — l'invariant "hauteur fixe" se brisait donc précisément à cause
           de la bordure. +4px restaure une hauteur strictement identique dans les 2 états. */
        #section-sequencer .sequencer-playback-button {
            box-sizing: border-box;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
            min-height: 60px;
        }
        #section-sequencer .sequencer-playback-button:disabled { opacity: 0.4; cursor: default; }
        #section-sequencer .sequencer-playback-icon {
            display: inline-block;
            line-height: 1;
            font-size: 2em;
        }
        #section-sequencer .sequencer-playback-label { line-height: 1.2; }

        /* Lot 2 : bascule Intro / Boucle au-dessus du tableau d'étapes — mêmes boutons "actifs en
           bleu" que les préréglages ci-dessus (état géré en JS, voir setSequencerActiveEditSegment). */
        #section-sequencer .sequencer-segment-toggle button { font-size: 12px; }

        /* Lot 2 : indication discrète quand le segment Intro est vide (aucune étape). */
        #section-sequencer .sequencer-stage-list-empty-hint {
            font-size: 11px;
            font-style: italic;
            color: #999;
            padding: 8px 2px;
        }

        /* UI E6 : le mode Image/Texte inactif est totalement retiré de la mise en page. */
        .mode-inactive { display: none !important; }

        /* UI E7 : upload principal plus visible, sans changer le contrôle natif. */
        #upload-image {
            width: 100%;
            box-sizing: border-box;
            padding: 4px;
            margin-bottom: 10px;
            color: #d4d4d4;
            background: #1e1e1e;
            border: 1px solid #555;
            border-radius: 7px;
            font-size: 12px;
        }
        #upload-image::file-selector-button {
            margin-right: 10px;
            padding: 7px 11px;
            color: #fff;
            background: #007acc;
            border: 4px solid #CC7A29;
            border-radius: 5px;
            box-shadow: 0 0 7px rgba(0, 183, 255, 0.42);
            font: inherit;
            font-weight: 700;
            cursor: pointer;
            transition: background 0.2s, box-shadow 0.2s;
        }
        #upload-image:hover::file-selector-button,
        #upload-image:focus::file-selector-button {
            background: #0098ff;
            box-shadow: 0 0 10px rgba(0, 183, 255, 0.58);
        }

        /* UI E7 : la liste verticale de polices devient un sélecteur compact. */
        #font-choice-select {
            width: 100%;
            box-sizing: border-box;
            margin-bottom: 5px;
            padding: 8px 9px;
            color: #d4d4d4;
            background: #1e1e1e;
            border: 1px solid #555;
            border-radius: 4px;
            font-size: 13px;
            cursor: pointer;
        }
        #font-choice-select:focus { border-color: #007acc; }

        /* Lot 7 : même style compact que #font-choice-select, pour le sélecteur d'import de preset
           vers un emplacement Utilisateur du séquenceur. */
        #select-sequencer-import-preset {
            width: 100%;
            box-sizing: border-box;
            margin-top: 6px;
            padding: 8px 9px;
            color: #d4d4d4;
            background: #1e1e1e;
            border: 1px solid #555;
            border-radius: 4px;
            font-size: 13px;
            cursor: pointer;
        }
        #select-sequencer-import-preset:focus { border-color: #007acc; }
        #btn-sequencer-import-preset:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        /* UI E8 : Zoom / Seuil / Épaisseur regroupés en contrôles compacts (slider Tolérance
           supprimé le 16/09/2026, Étape 2 — roadmap Chantier 1). Le conteneur
           #compact-logo-controls et son <h3> ont été supprimés le 17/09/2026 (batch A/B/C/D) :
           les deux sliders vivent maintenant directement dans #creative-source-mode-shell. */
        .compact-control-item {
            margin: 0;
        }
        .compact-control-item + .compact-control-item {
            margin-top: 8px;
            padding-top: 8px;
            border-top: 1px solid #505055;
        }
        .compact-control-label {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 8px;
            margin: 0 0 3px 0;
            font-size: 12px;
            line-height: 1.25;
        }
        .compact-control-label .compact-control-value {
            color: #c8c8c8;
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }
        .compact-control-item input[type="range"] {
            display: block;
            margin: 0;
        }
        #block-image .compact-image-zoom-control {
            margin-top: 8px;
            padding-top: 8px;
            border-top: 1px solid #505055;
        }
        
        label { display: block; margin-bottom: 5px; font-size: 13px; }
        input[type="range"] { width: 100%; margin-bottom: 10px; cursor: pointer; }
        input[type="color"] { width: 100%; height: 40px; border: none; cursor: pointer; background: transparent; margin-bottom: 10px; }
        input[type="file"] { width: 100%; font-size: 12px; margin-bottom: 10px; }
        
        button { background: #007acc; color: white; border: none; padding: 10px; border-radius: 4px; cursor: pointer; width: 100%; font-weight: bold; margin-bottom: 5px; transition: background 0.2s; }
        button:hover { background: #0098ff; }
        .btn-group { display: flex; gap: 5px; flex-wrap: wrap; }
        .btn-group button { flex: 1; min-width: 30%; font-size: 12px; }

        /* Presets métalliques redesignés (Étape 7, roadmap Chantier 1) : classe dédiée, séparée
           de .btn-group (réutilisée ailleurs — Grid/Jitter/Flakes, actions rapides Éclairage) pour
           ne rien changer à son rendu existant. Les 4 boutons sur une ligne, forme carrée
           (aspect-ratio), padding: 0 pour laisser l'aperçu couleur occuper tout le bouton.
           box-sizing: border-box + bordure transparente réservée par défaut (comme .is-active-mode
           et #toggle-facade/#toggle-bevel.is-on aux Étapes 2-3) pour que l'apparition de la
           bordure orange ne fasse jamais bouger/grandir le bouton. */
        .metal-preset-group {
            display: flex;
            flex-wrap: nowrap;
            gap: 6px;
            margin-bottom: 10px;
        }
        .metal-preset-button {
            flex: 1 1 0;
            min-width: 0;
            aspect-ratio: 1 / 1;
            padding: 0;
            border-radius: 4px;
            box-sizing: border-box;
            border: 4px solid transparent;
        }
        /* Aperçu "reflet/bubble" en CSS pur : dégradé radial clair superposé à la couleur de base
           réelle de chaque preset (mêmes valeurs que setMetalPreset, `app.js`) — Acier #888888,
           Argent #E0E0E0, Or #FFD700, Bronze #CD7F32. Sélecteurs par id (spécificité la plus
           élevée) : gagnent face à `button:hover` sans règle de survol dédiée à écrire. */
        #btn-metal-steel-face, #btn-metal-steel-bevel {
            background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.55), rgba(255,255,255,0) 55%), #888888;
        }
        #btn-metal-silver-face, #btn-metal-silver-bevel {
            background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.65), rgba(255,255,255,0) 55%), #E0E0E0;
        }
        #btn-metal-gold-face, #btn-metal-gold-bevel {
            background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.55), rgba(255,255,255,0) 55%), #FFD700;
        }
        #btn-metal-bronze-face, #btn-metal-bronze-bevel {
            background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.5), rgba(255,255,255,0) 55%), #CD7F32;
        }
        /* Bordure orange conditionnelle (Étape 7) : posée/retirée en JS (classList) selon que les
           réglages actuels correspondent exactement à ce preset — voir updateMetalPresetActiveBorder
           dans app.js. Sélecteur composé (2 classes) pour gagner face à .metal-preset-button sans
           dépendre de l'ordre des règles dans la feuille de style. */
        .metal-preset-button.is-matching-preset {
            border-color: #CC7A29;
        }

        textarea { width: 100%; background: #1e1e1e; color: #d4d4d4; border: 1px solid #555; padding: 10px; font-family: inherit; font-size: 14px; resize: none; margin-bottom: 10px; box-sizing: border-box; border-radius: 4px; }
        #code-snippet { height: 150px; font-family: monospace; font-size: 11px; margin-top: 10px; }
        .embed-control-row { margin-top: 10px; }
        .embed-control-row input[type="text"],
        .embed-control-row input[type="number"] {
            width: 100%; box-sizing: border-box; background: #1e1e1e; color: #d4d4d4;
            border: 1px solid #555; border-radius: 4px; padding: 8px; font-size: 12px;
        }
        .embed-inline-option {
            display: flex; align-items: center; gap: 8px; margin: 10px 0; cursor: pointer;
        }
        .embed-inline-option input { margin: 0; }
        .slider-group { display: flex; flex-direction: column; width: 200px; }


        /* --- Contrôles Bubble 3D + Paillettes --- */
        .bubble-sparkle-subsection-title {
            margin-top: 15px; margin-bottom: 10px; color: #ccc; font-size: 12px;
            border-bottom: 1px solid #555; padding-bottom: 5px;
            text-transform: uppercase; font-weight: bold;
        }
        .bubble-sparkle-highlight-label {
            color: #007acc; font-weight: bold; font-size: 11px;
            margin-top: -5px; margin-bottom: 10px; display: block;
        }
        .bubble-sparkle-disabled-settings {
            opacity: 0.5; pointer-events: none; transition: opacity 0.2s ease;
        }
        .surface-effect-mode-group {
            display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: 6px; margin-bottom: 12px;
        }
        .surface-effect-mode-option {
            position: relative;
            display: flex; align-items: center; justify-content: center; gap: 6px;
            min-height: 36px; margin: 0; padding: 6px 8px; box-sizing: border-box;
            border: 1px solid #555; border-radius: 4px; background: #2a2a2a;
            color: #ddd; cursor: pointer; text-align: center; font-size: 12px;
        }
        .surface-effect-mode-option.is-active {
            border-color: #007acc; background: #123b55; color: #fff;
        }
        /* Point radio natif masqué (Étape 4, roadmap Chantier 1) : même rendu visuel que les
           boutons "Animation 1/2/3..." (fond/bordure/texte déjà gérés ci-dessus par .is-active,
           en JS, indépendamment du radio natif) — seul le petit point bleu du navigateur doit
           disparaître. `position: absolute` + taille nulle sortent le radio du flux flex du label
           (sans ça, le `gap: 6px` laisserait un espace vide avant le texte, qui ne serait plus
           centré) ; `opacity: 0` (pas `display: none`/`visibility: hidden`) pour qu'il reste
           focusable au clavier et cliquable via le <label> englobant, donc sans rien retirer du
           DOM ni casser `role="radiogroup"`. Ne change pas la taille du bouton lui-même. */
        .surface-effect-mode-option input[type="radio"] {
            position: absolute;
            width: 0;
            height: 0;
            margin: 0;
            padding: 0;
            opacity: 0;
            appearance: none;
            -webkit-appearance: none;
            pointer-events: none;
        }
        .surface-effect-relief-placeholder {
            display: none; padding: 10px; margin-bottom: 10px;
            border: 1px solid #555; border-radius: 4px; color: #ccc;
            background: #242424; font-size: 11px; line-height: 1.4;
        }
        .relief-texture-preset-group {
            display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 6px; margin-bottom: 12px;
        }
        .relief-texture-preset-button {
            margin: 0; padding: 8px 6px; background: #555; color: #fff;
            font-size: 12px; font-weight: normal;
        }
        .relief-texture-preset-button.is-active { background: #0062A3; }
        .relief-texture-help {
            display: block; margin: -2px 0 10px; color: #888; font-size: 10px;
        }
        .relief-texture-import-block {
            padding-top: 10px; margin-top: 10px; border-top: 1px solid #444;
        }
        .relief-texture-import-status {
            display: block; margin: -3px 0 10px; color: #888; font-size: 10px;
            overflow-wrap: anywhere;
        }
        .relief-texture-import-status.is-active { color: #ccc; }
        .relief-texture-import-status.is-error { color: #ff7777; }
        @media (max-width: 450px) {
            .surface-effect-mode-group { grid-template-columns: 1fr; }
            .surface-effect-mode-option { justify-content: flex-start; }
        }

        /* --- 4. MEDIA QUERIES (FLUIDITÉ CSS SANS JAVASCRIPT) --- */

        /* Étape D : sous 750px de largeur, une fenêtre flottante déplaçable/redimensionnable n'est
           pas adaptée (écran trop petit, pas de souris) — on repasse le panneau du séquenceur en
           bloc statique dans le flux normal de la page, comme avant l'Étape D. Le !important
           l'emporte sur les styles inline de position/taille posés par le JS de drag/resize. */
        @media (max-width: 750px) {
            .sequencer-floating-panel {
                position: static !important;
                width: 100% !important;
                height: auto !important;
                min-width: 0;
                resize: none;
                box-shadow: none;
                margin-top: 10px;
            }
            .sequencer-floating-panel-titlebar { cursor: default; }
        }

        /* TABLETTE (2 Colonnes - Le Panneau Droit est injecté dans le Gauche via JS) */
        @media (min-width: 451px) and (max-width: 750px) {
            #ui-left { width: clamp(250px, 35vw, 350px); }
            #ui-left #ui-right { width: 100%; padding: 0; box-shadow: none; overflow: visible; }
        }

        /* MOBILE (1 Colonne - Viseur Fixe et Sliders Embarqués) */
        @media (max-width: 450px) {
            #mobile-title {
                display: flex; align-items: center; justify-content: space-between; gap: 8px;
            }
            #mobile-title .mobile-title-link {
                min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
            }
            .subdomain-lang-selector-desktop { display: none; }
            /* Lot D (22/09/2026) : évite le doublon avec #mobile-title, désormais seul
               titre de marque affiché sous 450px. */
            .creative-brand-title { display: none; }
            #main-layout { flex-direction: column; }
            
            #ui-center { flex: 0 0 auto; max-height: 45vh; background: #1e1e1e; z-index: 5; }
            
            #ui-left { width: 100%; flex: 1 1 auto; min-height: 0; }
            
            #ui-left #ui-right { width: 100%; padding: 0; box-shadow: none; overflow: visible; }
            #ui-left #ui-bottom { 
                padding: 15px 0; background: transparent; 
                box-shadow: none; flex-direction: column; gap: 15px; 
            }
            #ui-left #ui-bottom .slider-group { width: 100%; }
        }
